Index: test/cctest/compiler/test-instruction-selector-arm.cc |
diff --git a/test/cctest/compiler/test-instruction-selector-arm.cc b/test/cctest/compiler/test-instruction-selector-arm.cc |
index f2d8524778cd9b36aec15be338a52add8a842338..5ed0819c07d0f53a237f535839e77afc0dc312f8 100644 |
--- a/test/cctest/compiler/test-instruction-selector-arm.cc |
+++ b/test/cctest/compiler/test-instruction-selector-arm.cc |
@@ -225,6 +225,363 @@ TEST(InstructionSelectorDPIAndShiftImm) { |
} |
+TEST(InstructionSelectorInt32AddWithOverflowP) { |
+ { |
+ InstructionSelectorTester m; |
+ Node* ovf; |
+ m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), NULL, &ovf); |
+ m.Return(ovf); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val; |
+ m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), &val, NULL); |
+ m.Return(val); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val, *ovf; |
+ m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), &val, &ovf); |
+ m.Return(m.Word32Equal(val, ovf)); |
+ m.SelectInstructions(); |
+ CHECK_LE(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(2, m.code[0]->OutputCount()); |
+ } |
+} |
+ |
+ |
+TEST(InstructionSelectorInt32AddWithOverflowImm) { |
+ Immediates immediates; |
+ for (Immediates::const_iterator i = immediates.begin(); i != immediates.end(); |
+ ++i) { |
+ int32_t imm = *i; |
+ { |
+ InstructionSelectorTester m; |
+ Node* ovf; |
+ m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), NULL, &ovf); |
+ m.Return(ovf); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* ovf; |
+ m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), NULL, &ovf); |
+ m.Return(ovf); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val; |
+ m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), &val, NULL); |
+ m.Return(val); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val; |
+ m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), &val, NULL); |
+ m.Return(val); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val, *ovf; |
+ m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), &val, &ovf); |
+ m.Return(m.Word32Equal(val, ovf)); |
+ m.SelectInstructions(); |
+ CHECK_LE(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
+ CHECK_EQ(2, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val, *ovf; |
+ m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), &val, &ovf); |
+ m.Return(m.Word32Equal(val, ovf)); |
+ m.SelectInstructions(); |
+ CHECK_LE(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(2, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
+ CHECK_EQ(2, m.code[0]->OutputCount()); |
+ } |
+ } |
+} |
+ |
+ |
+TEST(InstructionSelectorInt32AddWithOverflowAndShiftP) { |
+ Shifts shifts; |
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { |
+ Shift shift = *i; |
+ { |
+ InstructionSelectorTester m; |
+ Node* ovf; |
+ m.Int32AddWithOverflow( |
+ m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), |
+ NULL, &ovf); |
+ m.Return(ovf); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* ovf; |
+ m.Int32AddWithOverflow( |
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), |
+ NULL, &ovf); |
+ m.Return(ovf); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val; |
+ m.Int32AddWithOverflow( |
+ m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), |
+ &val, NULL); |
+ m.Return(val); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val; |
+ m.Int32AddWithOverflow( |
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), |
+ &val, NULL); |
+ m.Return(val); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val, *ovf; |
+ m.Int32AddWithOverflow( |
+ m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), |
+ &val, &ovf); |
+ m.Return(m.Word32Equal(val, ovf)); |
+ m.SelectInstructions(); |
+ CHECK_LE(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(2, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val, *ovf; |
+ m.Int32AddWithOverflow( |
+ m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), |
+ &val, &ovf); |
+ m.Return(m.Word32Equal(val, ovf)); |
+ m.SelectInstructions(); |
+ CHECK_LE(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(2, m.code[0]->OutputCount()); |
+ } |
+ } |
+} |
+ |
+ |
+TEST(InstructionSelectorInt32AddWithOverflowAndShiftImm) { |
+ Shifts shifts; |
+ for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { |
+ Shift shift = *i; |
+ for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { |
+ { |
+ InstructionSelectorTester m; |
+ Node* ovf; |
+ m.Int32AddWithOverflow( |
+ m.Parameter(0), |
+ m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), NULL, |
+ &ovf); |
+ m.Return(ovf); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* ovf; |
+ m.Int32AddWithOverflow( |
+ m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), |
+ m.Parameter(1), NULL, &ovf); |
+ m.Return(ovf); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val; |
+ m.Int32AddWithOverflow( |
+ m.Parameter(0), |
+ m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), &val, |
+ NULL); |
+ m.Return(val); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val; |
+ m.Int32AddWithOverflow( |
+ m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), |
+ m.Parameter(1), &val, NULL); |
+ m.Return(val); |
+ m.SelectInstructions(); |
+ CHECK_EQ(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
+ CHECK_EQ(1, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val, *ovf; |
+ m.Int32AddWithOverflow( |
+ m.Parameter(0), |
+ m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), &val, |
+ &ovf); |
+ m.Return(m.Word32Equal(val, ovf)); |
+ m.SelectInstructions(); |
+ CHECK_LE(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
+ CHECK_EQ(2, m.code[0]->OutputCount()); |
+ } |
+ { |
+ InstructionSelectorTester m; |
+ Node* val, *ovf; |
+ m.Int32AddWithOverflow( |
+ m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), |
+ m.Parameter(1), &val, &ovf); |
+ m.Return(m.Word32Equal(val, ovf)); |
+ m.SelectInstructions(); |
+ CHECK_LE(1, m.code.size()); |
+ CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); |
+ CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
+ CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
+ CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
+ CHECK_EQ(3, m.code[0]->InputCount()); |
+ CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
+ CHECK_EQ(2, m.code[0]->OutputCount()); |
+ } |
+ } |
+ } |
+} |
+ |
+ |
TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) { |
{ |
InstructionSelectorTester m; |