Index: test/cctest/test-assembler-ia32.cc |
diff --git a/test/cctest/test-assembler-ia32.cc b/test/cctest/test-assembler-ia32.cc |
index b68cbec0370a141b1cfc0d55e61d84c0cb49ecba..46592a05d18fe7aa5adb686a0b5a84391db46736 100644 |
--- a/test/cctest/test-assembler-ia32.cc |
+++ b/test/cctest/test-assembler-ia32.cc |
@@ -1043,4 +1043,100 @@ TEST(AssemblerX64FMA_ss) { |
F10 f = FUNCTION_CAST<F10>(code->entry()); |
CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f)); |
} |
+ |
+ |
+TEST(AssemblerIa32JumpTables1) { |
+ // Test jump tables with forward jumps. |
+ CcTest::InitializeVM(); |
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); |
+ HandleScope scope(isolate); |
+ Assembler assm(isolate, nullptr, 0); |
+ |
+ const int kNumCases = 512; |
+ int values[kNumCases]; |
+ isolate->random_number_generator()->NextBytes(values, sizeof(values)); |
+ Label labels[kNumCases]; |
+ |
+ Label done, table; |
+ __ mov(eax, Operand(esp, 4)); |
+ __ jmp(Operand::JumpTable(eax, times_4, &table)); |
+ __ ud2(); |
+ __ bind(&table); |
+ for (int i = 0; i < kNumCases; ++i) { |
+ __ dd(&labels[i]); |
+ } |
+ |
+ for (int i = 0; i < kNumCases; ++i) { |
+ __ bind(&labels[i]); |
+ __ mov(eax, Immediate(values[i])); |
+ __ jmp(&done); |
+ } |
+ |
+ __ bind(&done); |
+ __ ret(0); |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+#ifdef OBJECT_PRINT |
+ OFStream os(stdout); |
+ code->Print(os); |
+#endif |
+ F1 f = FUNCTION_CAST<F1>(code->entry()); |
+ for (int i = 0; i < kNumCases; ++i) { |
+ int res = f(i); |
+ ::printf("f(%d) = %d\n", i, res); |
+ CHECK_EQ(values[i], res); |
+ } |
+} |
+ |
+ |
+TEST(AssemblerIa32JumpTables2) { |
+ // Test jump tables with backward jumps. |
+ CcTest::InitializeVM(); |
+ Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); |
+ HandleScope scope(isolate); |
+ Assembler assm(isolate, nullptr, 0); |
+ |
+ const int kNumCases = 512; |
+ int values[kNumCases]; |
+ isolate->random_number_generator()->NextBytes(values, sizeof(values)); |
+ Label labels[kNumCases]; |
+ |
+ Label done, table; |
+ __ mov(eax, Operand(esp, 4)); |
+ __ jmp(Operand::JumpTable(eax, times_4, &table)); |
+ __ ud2(); |
+ |
+ for (int i = 0; i < kNumCases; ++i) { |
+ __ bind(&labels[i]); |
+ __ mov(eax, Immediate(values[i])); |
+ __ jmp(&done); |
+ } |
+ |
+ __ bind(&table); |
+ for (int i = 0; i < kNumCases; ++i) { |
+ __ dd(&labels[i]); |
+ } |
+ |
+ __ bind(&done); |
+ __ ret(0); |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+#ifdef OBJECT_PRINT |
+ OFStream os(stdout); |
+ code->Print(os); |
+#endif |
+ F1 f = FUNCTION_CAST<F1>(code->entry()); |
+ for (int i = 0; i < kNumCases; ++i) { |
+ int res = f(i); |
+ ::printf("f(%d) = %d\n", i, res); |
+ CHECK_EQ(values[i], res); |
+ } |
+} |
+ |
#undef __ |