Index: test/cctest/compiler/test-run-native-calls.cc |
diff --git a/test/cctest/compiler/test-run-native-calls.cc b/test/cctest/compiler/test-run-native-calls.cc |
index 9ab15c4578bd660f83dea977cbc5115bbc135130..f9ef44b084302c006f57ba7177ef308df97a24c8 100644 |
--- a/test/cctest/compiler/test-run-native-calls.cc |
+++ b/test/cctest/compiler/test-run-native-calls.cc |
@@ -984,3 +984,131 @@ TEST(Float64StackParamsToStackParams) { |
Run_Computation<float64>(desc, Build_Select_With_Call<float64, 1>, |
Compute_Select<float64, 1>, 1099); |
} |
+ |
+ |
+void MixedParamTest(int start) { |
+ if (DISABLE_NATIVE_STACK_PARAMS) return; |
+ if (RegisterConfiguration::ArchDefault()->num_double_registers() < 2) return; |
+#ifdef V8_TARGET_ARCH_MIPS64 |
+ // TODO(titzer): MIPS stack doubles can be misaligned. |
+ if (true) return; |
+#endif |
+ |
+// TODO(titzer): mix in 64-bit types on all platforms when supported. |
+#if V8_TARGET_ARCH_32_BIT |
+ static MachineType types[] = { |
+ kMachInt32, kMachFloat32, kMachFloat64, kMachInt32, kMachFloat64, |
+ kMachFloat32, kMachFloat32, kMachFloat64, kMachInt32, kMachFloat32, |
+ kMachInt32, kMachFloat64, kMachFloat64, kMachFloat32, kMachInt32, |
+ kMachFloat64, kMachInt32, kMachFloat32}; |
+#else |
+ static MachineType types[] = { |
+ kMachInt32, kMachInt64, kMachFloat32, kMachFloat64, kMachInt32, |
+ kMachFloat64, kMachFloat32, kMachInt64, kMachFloat64, kMachInt32, |
+ kMachFloat32, kMachInt32, kMachFloat64, kMachFloat64, kMachInt64, |
+ kMachInt32, kMachFloat64, kMachInt32, kMachFloat32}; |
+#endif |
+ |
+ Isolate* isolate = CcTest::InitIsolateOnce(); |
+ |
+ // Build machine signature |
+ MachineType* params = &types[start]; |
+ const int num_params = static_cast<int>(arraysize(types) - start); |
+ |
+ // Build call descriptor |
+ int parray[] = {0, 1}; |
+ int rarray[] = {0}; |
+ Allocator palloc(parray, 2, parray, 2); |
+ Allocator ralloc(rarray, 1, rarray, 1); |
+ RegisterConfig config(palloc, ralloc); |
+ |
+ for (int which = 0; which < num_params; which++) { |
+ Zone zone; |
+ HandleScope scope(isolate); |
+ MachineSignature::Builder builder(&zone, 1, num_params); |
+ builder.AddReturn(params[which]); |
+ for (int j = 0; j < num_params; j++) builder.AddParam(params[j]); |
+ MachineSignature* sig = builder.Build(); |
+ CallDescriptor* desc = config.Create(&zone, sig); |
+ |
+ Handle<Code> select; |
+ { |
+ // build the select. |
+ Zone zone; |
+ Graph graph(&zone); |
+ RawMachineAssembler raw(isolate, &graph, desc); |
+ raw.Return(raw.Parameter(which)); |
+ select = CompileGraph("Compute", desc, &graph, raw.Export()); |
+ } |
+ |
+ { |
+ // call the select. |
+ Handle<Code> wrapper = Handle<Code>::null(); |
+ int32_t expected_ret; |
+ char bytes[kDoubleSize]; |
+ char output[kDoubleSize]; |
+ int expected_size = 0; |
+ CSignature0<int32_t> csig; |
+ { |
+ // Wrap the select code with a callable function that passes constants. |
+ Zone zone; |
+ Graph graph(&zone); |
+ CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); |
+ RawMachineAssembler raw(isolate, &graph, cdesc); |
+ Unique<HeapObject> unique = |
+ Unique<HeapObject>::CreateUninitialized(select); |
+ Node* target = raw.HeapConstant(unique); |
+ Node** args = zone.NewArray<Node*>(num_params); |
+ int64_t constant = 0x0102030405060708; |
+ for (int i = 0; i < num_params; i++) { |
+ MachineType param_type = sig->GetParam(i); |
+ Node* konst = nullptr; |
+ if (param_type == kMachInt32) { |
+ int32_t value[] = {static_cast<int32_t>(constant)}; |
+ konst = raw.Int32Constant(value[0]); |
+ if (i == which) memcpy(bytes, value, expected_size = 4); |
+ } |
+ if (param_type == kMachInt64) { |
+ int64_t value[] = {static_cast<int64_t>(constant)}; |
+ konst = raw.Int64Constant(value[0]); |
+ if (i == which) memcpy(bytes, value, expected_size = 8); |
+ } |
+ if (param_type == kMachFloat32) { |
+ float32 value[] = {static_cast<float32>(constant)}; |
+ konst = raw.Float32Constant(value[0]); |
+ if (i == which) memcpy(bytes, value, expected_size = 4); |
+ } |
+ if (param_type == kMachFloat64) { |
+ float64 value[] = {static_cast<float64>(constant)}; |
+ konst = raw.Float64Constant(value[0]); |
+ if (i == which) memcpy(bytes, value, expected_size = 8); |
+ } |
+ CHECK_NOT_NULL(konst); |
+ |
+ args[i] = konst; |
+ constant += 0x1010101010101010; |
+ } |
+ |
+ Node* call = raw.CallN(desc, target, args); |
+ Node* store = raw.StoreToPointer(output, sig->GetReturn(), call); |
+ USE(store); |
+ expected_ret = static_cast<int32_t>(constant); |
+ raw.Return(raw.Int32Constant(expected_ret)); |
+ wrapper = CompileGraph("Select-mixed-wrapper-const", cdesc, &graph, |
+ raw.Export()); |
+ } |
+ |
+ CodeRunner<int32_t> runnable(isolate, wrapper, &csig); |
+ CHECK_EQ(expected_ret, runnable.Call()); |
+ for (int i = 0; i < expected_size; i++) { |
+ CHECK_EQ(static_cast<int>(bytes[i]), static_cast<int>(output[i])); |
+ } |
+ } |
+ } |
+} |
+ |
+ |
+TEST(MixedParams_0) { MixedParamTest(0); } |
+TEST(MixedParams_1) { MixedParamTest(1); } |
+TEST(MixedParams_2) { MixedParamTest(2); } |
+TEST(MixedParams_3) { MixedParamTest(3); } |