Home | History | Annotate | Download | only in arm
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <limits>
      6 
      7 #include "test/unittests/compiler/instruction-selector-unittest.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 namespace compiler {
     12 
     13 namespace {
     14 
     15 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
     16 
     17 
     18 // Data processing instructions.
     19 struct DPI {
     20   Constructor constructor;
     21   const char* constructor_name;
     22   ArchOpcode arch_opcode;
     23   ArchOpcode reverse_arch_opcode;
     24   ArchOpcode test_arch_opcode;
     25 };
     26 
     27 
     28 std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
     29   return os << dpi.constructor_name;
     30 }
     31 
     32 
     33 const DPI kDPIs[] = {
     34     {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst},
     35     {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr},
     36     {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq},
     37     {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn},
     38     {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
     39 
     40 
     41 // Floating point arithmetic instructions.
     42 struct FAI {
     43   Constructor constructor;
     44   const char* constructor_name;
     45   MachineType machine_type;
     46   ArchOpcode arch_opcode;
     47 };
     48 
     49 
     50 std::ostream& operator<<(std::ostream& os, const FAI& fai) {
     51   return os << fai.constructor_name;
     52 }
     53 
     54 
     55 const FAI kFAIs[] = {{&RawMachineAssembler::Float32Add, "Float32Add",
     56                       MachineType::Float32(), kArmVaddF32},
     57                      {&RawMachineAssembler::Float64Add, "Float64Add",
     58                       MachineType::Float64(), kArmVaddF64},
     59                      {&RawMachineAssembler::Float32Sub, "Float32Sub",
     60                       MachineType::Float32(), kArmVsubF32},
     61                      {&RawMachineAssembler::Float64Sub, "Float64Sub",
     62                       MachineType::Float64(), kArmVsubF64},
     63                      {&RawMachineAssembler::Float32Mul, "Float32Mul",
     64                       MachineType::Float32(), kArmVmulF32},
     65                      {&RawMachineAssembler::Float64Mul, "Float64Mul",
     66                       MachineType::Float64(), kArmVmulF64},
     67                      {&RawMachineAssembler::Float32Div, "Float32Div",
     68                       MachineType::Float32(), kArmVdivF32},
     69                      {&RawMachineAssembler::Float64Div, "Float64Div",
     70                       MachineType::Float64(), kArmVdivF64}};
     71 
     72 
     73 // Data processing instructions with overflow.
     74 struct ODPI {
     75   Constructor constructor;
     76   const char* constructor_name;
     77   ArchOpcode arch_opcode;
     78   ArchOpcode reverse_arch_opcode;
     79 };
     80 
     81 
     82 std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
     83   return os << odpi.constructor_name;
     84 }
     85 
     86 
     87 const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
     88                         "Int32AddWithOverflow", kArmAdd, kArmAdd},
     89                        {&RawMachineAssembler::Int32SubWithOverflow,
     90                         "Int32SubWithOverflow", kArmSub, kArmRsb}};
     91 
     92 
     93 // Shifts.
     94 struct Shift {
     95   Constructor constructor;
     96   const char* constructor_name;
     97   int32_t i_low;          // lowest possible immediate
     98   int32_t i_high;         // highest possible immediate
     99   AddressingMode i_mode;  // Operand2_R_<shift>_I
    100   AddressingMode r_mode;  // Operand2_R_<shift>_R
    101 };
    102 
    103 
    104 std::ostream& operator<<(std::ostream& os, const Shift& shift) {
    105   return os << shift.constructor_name;
    106 }
    107 
    108 
    109 const Shift kShifts[] = {{&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32,
    110                           kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R},
    111                          {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31,
    112                           kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R},
    113                          {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32,
    114                           kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R},
    115                          {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31,
    116                           kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}};
    117 
    118 
    119 // Immediates (random subset).
    120 const int32_t kImmediates[] = {
    121     std::numeric_limits<int32_t>::min(), -2147483617, -2147483606, -2113929216,
    122     -2080374784, -1996488704, -1879048192, -1459617792, -1358954496,
    123     -1342177265, -1275068414, -1073741818, -1073741777, -855638016, -805306368,
    124     -402653184, -268435444, -16777216, 0, 35, 61, 105, 116, 171, 245, 255, 692,
    125     1216, 1248, 1520, 1600, 1888, 3744, 4080, 5888, 8384, 9344, 9472, 9792,
    126     13312, 15040, 15360, 20736, 22272, 23296, 32000, 33536, 37120, 45824, 47872,
    127     56320, 59392, 65280, 72704, 101376, 147456, 161792, 164864, 167936, 173056,
    128     195584, 209920, 212992, 356352, 655360, 704512, 716800, 851968, 901120,
    129     1044480, 1523712, 2572288, 3211264, 3588096, 3833856, 3866624, 4325376,
    130     5177344, 6488064, 7012352, 7471104, 14090240, 16711680, 19398656, 22282240,
    131     28573696, 30408704, 30670848, 43253760, 54525952, 55312384, 56623104,
    132     68157440, 115343360, 131072000, 187695104, 188743680, 195035136, 197132288,
    133     203423744, 218103808, 267386880, 268435470, 285212672, 402653185, 415236096,
    134     595591168, 603979776, 603979778, 629145600, 1073741835, 1073741855,
    135     1073741861, 1073741884, 1157627904, 1476395008, 1476395010, 1610612741,
    136     2030043136, 2080374785, 2097152000};
    137 
    138 }  // namespace
    139 
    140 
    141 // -----------------------------------------------------------------------------
    142 // Data processing instructions.
    143 
    144 
    145 typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest;
    146 
    147 
    148 TEST_P(InstructionSelectorDPITest, Parameters) {
    149   const DPI dpi = GetParam();
    150   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    151                   MachineType::Int32());
    152   m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
    153   Stream s = m.Build();
    154   ASSERT_EQ(1U, s.size());
    155   EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
    156   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    157   EXPECT_EQ(2U, s[0]->InputCount());
    158   EXPECT_EQ(1U, s[0]->OutputCount());
    159 }
    160 
    161 
    162 TEST_P(InstructionSelectorDPITest, Immediate) {
    163   const DPI dpi = GetParam();
    164   TRACED_FOREACH(int32_t, imm, kImmediates) {
    165     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    166     m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
    167     Stream s = m.Build();
    168     ASSERT_EQ(1U, s.size());
    169     EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
    170     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    171     ASSERT_EQ(2U, s[0]->InputCount());
    172     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    173     EXPECT_EQ(1U, s[0]->OutputCount());
    174   }
    175   TRACED_FOREACH(int32_t, imm, kImmediates) {
    176     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    177     m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
    178     Stream s = m.Build();
    179     ASSERT_EQ(1U, s.size());
    180     EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
    181     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    182     ASSERT_EQ(2U, s[0]->InputCount());
    183     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    184     EXPECT_EQ(1U, s[0]->OutputCount());
    185   }
    186 }
    187 
    188 
    189 TEST_P(InstructionSelectorDPITest, ShiftByParameter) {
    190   const DPI dpi = GetParam();
    191   TRACED_FOREACH(Shift, shift, kShifts) {
    192     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    193                     MachineType::Int32(), MachineType::Int32());
    194     m.Return((m.*dpi.constructor)(
    195         m.Parameter(0),
    196         (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
    197     Stream s = m.Build();
    198     ASSERT_EQ(1U, s.size());
    199     EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
    200     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    201     EXPECT_EQ(3U, s[0]->InputCount());
    202     EXPECT_EQ(1U, s[0]->OutputCount());
    203   }
    204   TRACED_FOREACH(Shift, shift, kShifts) {
    205     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    206                     MachineType::Int32(), MachineType::Int32());
    207     m.Return((m.*dpi.constructor)(
    208         (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
    209         m.Parameter(2)));
    210     Stream s = m.Build();
    211     ASSERT_EQ(1U, s.size());
    212     EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
    213     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    214     EXPECT_EQ(3U, s[0]->InputCount());
    215     EXPECT_EQ(1U, s[0]->OutputCount());
    216   }
    217 }
    218 
    219 
    220 TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
    221   const DPI dpi = GetParam();
    222   TRACED_FOREACH(Shift, shift, kShifts) {
    223     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    224       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    225                       MachineType::Int32());
    226       m.Return((m.*dpi.constructor)(
    227           m.Parameter(0),
    228           (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
    229       Stream s = m.Build();
    230       ASSERT_EQ(1U, s.size());
    231       EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
    232       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    233       ASSERT_EQ(3U, s[0]->InputCount());
    234       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    235       EXPECT_EQ(1U, s[0]->OutputCount());
    236     }
    237   }
    238   TRACED_FOREACH(Shift, shift, kShifts) {
    239     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    240       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    241                       MachineType::Int32());
    242       m.Return((m.*dpi.constructor)(
    243           (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
    244           m.Parameter(1)));
    245       Stream s = m.Build();
    246       ASSERT_EQ(1U, s.size());
    247       EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
    248       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    249       ASSERT_EQ(3U, s[0]->InputCount());
    250       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    251       EXPECT_EQ(1U, s[0]->OutputCount());
    252     }
    253   }
    254 }
    255 
    256 
    257 TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
    258   const DPI dpi = GetParam();
    259   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    260                   MachineType::Int32());
    261   RawMachineLabel a, b;
    262   m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
    263   m.Bind(&a);
    264   m.Return(m.Int32Constant(1));
    265   m.Bind(&b);
    266   m.Return(m.Int32Constant(0));
    267   Stream s = m.Build();
    268   ASSERT_EQ(1U, s.size());
    269   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    270   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    271   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    272   EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    273 }
    274 
    275 
    276 TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
    277   const DPI dpi = GetParam();
    278   TRACED_FOREACH(int32_t, imm, kImmediates) {
    279     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    280     RawMachineLabel a, b;
    281     m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
    282              &b);
    283     m.Bind(&a);
    284     m.Return(m.Int32Constant(1));
    285     m.Bind(&b);
    286     m.Return(m.Int32Constant(0));
    287     Stream s = m.Build();
    288     ASSERT_EQ(1U, s.size());
    289     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    290     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    291     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    292     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    293   }
    294   TRACED_FOREACH(int32_t, imm, kImmediates) {
    295     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    296     RawMachineLabel a, b;
    297     m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
    298              &b);
    299     m.Bind(&a);
    300     m.Return(m.Int32Constant(1));
    301     m.Bind(&b);
    302     m.Return(m.Int32Constant(0));
    303     Stream s = m.Build();
    304     ASSERT_EQ(1U, s.size());
    305     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    306     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    307     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    308     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    309   }
    310 }
    311 
    312 
    313 TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
    314   const DPI dpi = GetParam();
    315   TRACED_FOREACH(Shift, shift, kShifts) {
    316     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    317                     MachineType::Int32(), MachineType::Int32());
    318     RawMachineLabel a, b;
    319     m.Branch((m.*dpi.constructor)(
    320                  m.Parameter(0),
    321                  (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
    322              &a, &b);
    323     m.Bind(&a);
    324     m.Return(m.Int32Constant(1));
    325     m.Bind(&b);
    326     m.Return(m.Int32Constant(0));
    327     Stream s = m.Build();
    328     ASSERT_EQ(1U, s.size());
    329     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    330     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    331     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    332     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    333   }
    334   TRACED_FOREACH(Shift, shift, kShifts) {
    335     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    336                     MachineType::Int32(), MachineType::Int32());
    337     RawMachineLabel a, b;
    338     m.Branch((m.*dpi.constructor)(
    339                  (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
    340                  m.Parameter(2)),
    341              &a, &b);
    342     m.Bind(&a);
    343     m.Return(m.Int32Constant(1));
    344     m.Bind(&b);
    345     m.Return(m.Int32Constant(0));
    346     Stream s = m.Build();
    347     ASSERT_EQ(1U, s.size());
    348     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    349     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    350     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    351     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    352   }
    353 }
    354 
    355 
    356 TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
    357   const DPI dpi = GetParam();
    358   TRACED_FOREACH(Shift, shift, kShifts) {
    359     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    360       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    361                       MachineType::Int32());
    362       RawMachineLabel a, b;
    363       m.Branch((m.*dpi.constructor)(m.Parameter(0),
    364                                     (m.*shift.constructor)(
    365                                         m.Parameter(1), m.Int32Constant(imm))),
    366                &a, &b);
    367       m.Bind(&a);
    368       m.Return(m.Int32Constant(1));
    369       m.Bind(&b);
    370       m.Return(m.Int32Constant(0));
    371       Stream s = m.Build();
    372       ASSERT_EQ(1U, s.size());
    373       EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    374       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    375       ASSERT_EQ(5U, s[0]->InputCount());
    376       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    377       EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    378       EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    379     }
    380   }
    381   TRACED_FOREACH(Shift, shift, kShifts) {
    382     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    383       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    384                       MachineType::Int32());
    385       RawMachineLabel a, b;
    386       m.Branch((m.*dpi.constructor)(
    387                    (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
    388                    m.Parameter(1)),
    389                &a, &b);
    390       m.Bind(&a);
    391       m.Return(m.Int32Constant(1));
    392       m.Bind(&b);
    393       m.Return(m.Int32Constant(0));
    394       Stream s = m.Build();
    395       ASSERT_EQ(1U, s.size());
    396       EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    397       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    398       ASSERT_EQ(5U, s[0]->InputCount());
    399       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    400       EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    401       EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    402     }
    403   }
    404 }
    405 
    406 
    407 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
    408   const DPI dpi = GetParam();
    409   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    410                   MachineType::Int32());
    411   RawMachineLabel a, b;
    412   m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
    413                          m.Int32Constant(0)),
    414            &a, &b);
    415   m.Bind(&a);
    416   m.Return(m.Int32Constant(1));
    417   m.Bind(&b);
    418   m.Return(m.Int32Constant(0));
    419   Stream s = m.Build();
    420   ASSERT_EQ(1U, s.size());
    421   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    422   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    423   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    424   EXPECT_EQ(kEqual, s[0]->flags_condition());
    425 }
    426 
    427 
    428 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
    429   const DPI dpi = GetParam();
    430   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    431                   MachineType::Int32());
    432   RawMachineLabel a, b;
    433   m.Branch(
    434       m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
    435                        m.Int32Constant(0)),
    436       &a, &b);
    437   m.Bind(&a);
    438   m.Return(m.Int32Constant(1));
    439   m.Bind(&b);
    440   m.Return(m.Int32Constant(0));
    441   Stream s = m.Build();
    442   ASSERT_EQ(1U, s.size());
    443   EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    444   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    445   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    446   EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    447 }
    448 
    449 
    450 TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
    451   const DPI dpi = GetParam();
    452   TRACED_FOREACH(int32_t, imm, kImmediates) {
    453     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    454     RawMachineLabel a, b;
    455     m.Branch(m.Word32Equal(
    456                  (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
    457                  m.Int32Constant(0)),
    458              &a, &b);
    459     m.Bind(&a);
    460     m.Return(m.Int32Constant(1));
    461     m.Bind(&b);
    462     m.Return(m.Int32Constant(0));
    463     Stream s = m.Build();
    464     ASSERT_EQ(1U, s.size());
    465     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    466     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    467     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    468     EXPECT_EQ(kEqual, s[0]->flags_condition());
    469   }
    470   TRACED_FOREACH(int32_t, imm, kImmediates) {
    471     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    472     RawMachineLabel a, b;
    473     m.Branch(m.Word32Equal(
    474                  (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
    475                  m.Int32Constant(0)),
    476              &a, &b);
    477     m.Bind(&a);
    478     m.Return(m.Int32Constant(1));
    479     m.Bind(&b);
    480     m.Return(m.Int32Constant(0));
    481     Stream s = m.Build();
    482     ASSERT_EQ(1U, s.size());
    483     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    484     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    485     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    486     EXPECT_EQ(kEqual, s[0]->flags_condition());
    487   }
    488 }
    489 
    490 
    491 TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
    492   const DPI dpi = GetParam();
    493   TRACED_FOREACH(int32_t, imm, kImmediates) {
    494     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    495     RawMachineLabel a, b;
    496     m.Branch(m.Word32NotEqual(
    497                  (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
    498                  m.Int32Constant(0)),
    499              &a, &b);
    500     m.Bind(&a);
    501     m.Return(m.Int32Constant(1));
    502     m.Bind(&b);
    503     m.Return(m.Int32Constant(0));
    504     Stream s = m.Build();
    505     ASSERT_EQ(1U, s.size());
    506     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    507     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    508     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    509     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    510   }
    511   TRACED_FOREACH(int32_t, imm, kImmediates) {
    512     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    513     RawMachineLabel a, b;
    514     m.Branch(m.Word32NotEqual(
    515                  (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
    516                  m.Int32Constant(0)),
    517              &a, &b);
    518     m.Bind(&a);
    519     m.Return(m.Int32Constant(1));
    520     m.Bind(&b);
    521     m.Return(m.Int32Constant(0));
    522     Stream s = m.Build();
    523     ASSERT_EQ(1U, s.size());
    524     EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
    525     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    526     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    527     EXPECT_EQ(kNotEqual, s[0]->flags_condition());
    528   }
    529 }
    530 
    531 
    532 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
    533                         ::testing::ValuesIn(kDPIs));
    534 
    535 
    536 // -----------------------------------------------------------------------------
    537 // Data processing instructions with overflow.
    538 
    539 
    540 typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
    541 
    542 
    543 TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
    544   const ODPI odpi = GetParam();
    545   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    546                   MachineType::Int32());
    547   m.Return(
    548       m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
    549   Stream s = m.Build();
    550   ASSERT_EQ(1U, s.size());
    551   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    552   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    553   EXPECT_EQ(2U, s[0]->InputCount());
    554   EXPECT_LE(1U, s[0]->OutputCount());
    555   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    556   EXPECT_EQ(kOverflow, s[0]->flags_condition());
    557 }
    558 
    559 
    560 TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
    561   const ODPI odpi = GetParam();
    562   TRACED_FOREACH(int32_t, imm, kImmediates) {
    563     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    564     m.Return(m.Projection(
    565         1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
    566     Stream s = m.Build();
    567     ASSERT_EQ(1U, s.size());
    568     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    569     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    570     ASSERT_EQ(2U, s[0]->InputCount());
    571     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    572     EXPECT_LE(1U, s[0]->OutputCount());
    573     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    574     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    575   }
    576   TRACED_FOREACH(int32_t, imm, kImmediates) {
    577     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    578     m.Return(m.Projection(
    579         1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
    580     Stream s = m.Build();
    581     ASSERT_EQ(1U, s.size());
    582     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    583     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    584     ASSERT_EQ(2U, s[0]->InputCount());
    585     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    586     EXPECT_LE(1U, s[0]->OutputCount());
    587     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    588     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    589   }
    590 }
    591 
    592 
    593 TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
    594   const ODPI odpi = GetParam();
    595   TRACED_FOREACH(Shift, shift, kShifts) {
    596     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    597                     MachineType::Int32(), MachineType::Int32());
    598     m.Return(m.Projection(
    599         1, (m.*odpi.constructor)(
    600                m.Parameter(0),
    601                (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
    602     Stream s = m.Build();
    603     ASSERT_EQ(1U, s.size());
    604     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    605     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    606     EXPECT_EQ(3U, s[0]->InputCount());
    607     EXPECT_LE(1U, s[0]->OutputCount());
    608     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    609     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    610   }
    611   TRACED_FOREACH(Shift, shift, kShifts) {
    612     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    613                     MachineType::Int32(), MachineType::Int32());
    614     m.Return(m.Projection(
    615         1, (m.*odpi.constructor)(
    616                (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
    617                m.Parameter(0))));
    618     Stream s = m.Build();
    619     ASSERT_EQ(1U, s.size());
    620     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    621     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    622     EXPECT_EQ(3U, s[0]->InputCount());
    623     EXPECT_LE(1U, s[0]->OutputCount());
    624     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    625     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    626   }
    627 }
    628 
    629 
    630 TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
    631   const ODPI odpi = GetParam();
    632   TRACED_FOREACH(Shift, shift, kShifts) {
    633     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    634       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    635                       MachineType::Int32());
    636       m.Return(m.Projection(
    637           1, (m.*odpi.constructor)(m.Parameter(0),
    638                                    (m.*shift.constructor)(
    639                                        m.Parameter(1), m.Int32Constant(imm)))));
    640       Stream s = m.Build();
    641       ASSERT_EQ(1U, s.size());
    642       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    643       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    644       ASSERT_EQ(3U, s[0]->InputCount());
    645       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    646       EXPECT_LE(1U, s[0]->OutputCount());
    647       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    648       EXPECT_EQ(kOverflow, s[0]->flags_condition());
    649     }
    650   }
    651   TRACED_FOREACH(Shift, shift, kShifts) {
    652     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    653       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    654                       MachineType::Int32());
    655       m.Return(m.Projection(
    656           1, (m.*odpi.constructor)(
    657                  (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
    658                  m.Parameter(0))));
    659       Stream s = m.Build();
    660       ASSERT_EQ(1U, s.size());
    661       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    662       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    663       ASSERT_EQ(3U, s[0]->InputCount());
    664       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    665       EXPECT_LE(1U, s[0]->OutputCount());
    666       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    667       EXPECT_EQ(kOverflow, s[0]->flags_condition());
    668     }
    669   }
    670 }
    671 
    672 
    673 TEST_P(InstructionSelectorODPITest, ValWithParameters) {
    674   const ODPI odpi = GetParam();
    675   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    676                   MachineType::Int32());
    677   m.Return(
    678       m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
    679   Stream s = m.Build();
    680   ASSERT_EQ(1U, s.size());
    681   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    682   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    683   EXPECT_EQ(2U, s[0]->InputCount());
    684   EXPECT_LE(1U, s[0]->OutputCount());
    685   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
    686 }
    687 
    688 
    689 TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
    690   const ODPI odpi = GetParam();
    691   TRACED_FOREACH(int32_t, imm, kImmediates) {
    692     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    693     m.Return(m.Projection(
    694         0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
    695     Stream s = m.Build();
    696     ASSERT_EQ(1U, s.size());
    697     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    698     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    699     ASSERT_EQ(2U, s[0]->InputCount());
    700     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    701     EXPECT_LE(1U, s[0]->OutputCount());
    702     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
    703   }
    704   TRACED_FOREACH(int32_t, imm, kImmediates) {
    705     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    706     m.Return(m.Projection(
    707         0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
    708     Stream s = m.Build();
    709     ASSERT_EQ(1U, s.size());
    710     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    711     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    712     ASSERT_EQ(2U, s[0]->InputCount());
    713     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    714     EXPECT_LE(1U, s[0]->OutputCount());
    715     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
    716   }
    717 }
    718 
    719 
    720 TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
    721   const ODPI odpi = GetParam();
    722   TRACED_FOREACH(Shift, shift, kShifts) {
    723     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    724                     MachineType::Int32(), MachineType::Int32());
    725     m.Return(m.Projection(
    726         0, (m.*odpi.constructor)(
    727                m.Parameter(0),
    728                (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
    729     Stream s = m.Build();
    730     ASSERT_EQ(1U, s.size());
    731     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    732     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    733     EXPECT_EQ(3U, s[0]->InputCount());
    734     EXPECT_LE(1U, s[0]->OutputCount());
    735     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
    736   }
    737   TRACED_FOREACH(Shift, shift, kShifts) {
    738     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    739                     MachineType::Int32(), MachineType::Int32());
    740     m.Return(m.Projection(
    741         0, (m.*odpi.constructor)(
    742                (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
    743                m.Parameter(0))));
    744     Stream s = m.Build();
    745     ASSERT_EQ(1U, s.size());
    746     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    747     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    748     EXPECT_EQ(3U, s[0]->InputCount());
    749     EXPECT_LE(1U, s[0]->OutputCount());
    750     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
    751   }
    752 }
    753 
    754 
    755 TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
    756   const ODPI odpi = GetParam();
    757   TRACED_FOREACH(Shift, shift, kShifts) {
    758     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    759       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    760                       MachineType::Int32());
    761       m.Return(m.Projection(
    762           0, (m.*odpi.constructor)(m.Parameter(0),
    763                                    (m.*shift.constructor)(
    764                                        m.Parameter(1), m.Int32Constant(imm)))));
    765       Stream s = m.Build();
    766       ASSERT_EQ(1U, s.size());
    767       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    768       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    769       ASSERT_EQ(3U, s[0]->InputCount());
    770       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    771       EXPECT_LE(1U, s[0]->OutputCount());
    772       EXPECT_EQ(kFlags_none, s[0]->flags_mode());
    773     }
    774   }
    775   TRACED_FOREACH(Shift, shift, kShifts) {
    776     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    777       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    778                       MachineType::Int32());
    779       m.Return(m.Projection(
    780           0, (m.*odpi.constructor)(
    781                  (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
    782                  m.Parameter(0))));
    783       Stream s = m.Build();
    784       ASSERT_EQ(1U, s.size());
    785       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    786       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    787       ASSERT_EQ(3U, s[0]->InputCount());
    788       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    789       EXPECT_LE(1U, s[0]->OutputCount());
    790       EXPECT_EQ(kFlags_none, s[0]->flags_mode());
    791     }
    792   }
    793 }
    794 
    795 
    796 TEST_P(InstructionSelectorODPITest, BothWithParameters) {
    797   const ODPI odpi = GetParam();
    798   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    799                   MachineType::Int32());
    800   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
    801   m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
    802   Stream s = m.Build();
    803   ASSERT_LE(1U, s.size());
    804   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    805   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    806   EXPECT_EQ(2U, s[0]->InputCount());
    807   EXPECT_EQ(2U, s[0]->OutputCount());
    808   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    809   EXPECT_EQ(kOverflow, s[0]->flags_condition());
    810 }
    811 
    812 
    813 TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
    814   const ODPI odpi = GetParam();
    815   TRACED_FOREACH(int32_t, imm, kImmediates) {
    816     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    817     Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
    818     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
    819     Stream s = m.Build();
    820     ASSERT_LE(1U, s.size());
    821     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    822     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    823     ASSERT_EQ(2U, s[0]->InputCount());
    824     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    825     EXPECT_EQ(2U, s[0]->OutputCount());
    826     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    827     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    828   }
    829   TRACED_FOREACH(int32_t, imm, kImmediates) {
    830     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    831     Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
    832     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
    833     Stream s = m.Build();
    834     ASSERT_LE(1U, s.size());
    835     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    836     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    837     ASSERT_EQ(2U, s[0]->InputCount());
    838     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    839     EXPECT_EQ(2U, s[0]->OutputCount());
    840     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    841     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    842   }
    843 }
    844 
    845 
    846 TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
    847   const ODPI odpi = GetParam();
    848   TRACED_FOREACH(Shift, shift, kShifts) {
    849     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    850                     MachineType::Int32(), MachineType::Int32());
    851     Node* n = (m.*odpi.constructor)(
    852         m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
    853     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
    854     Stream s = m.Build();
    855     ASSERT_LE(1U, s.size());
    856     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    857     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    858     EXPECT_EQ(3U, s[0]->InputCount());
    859     EXPECT_EQ(2U, s[0]->OutputCount());
    860     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    861     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    862   }
    863   TRACED_FOREACH(Shift, shift, kShifts) {
    864     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    865                     MachineType::Int32(), MachineType::Int32());
    866     Node* n = (m.*odpi.constructor)(
    867         (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
    868     m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
    869     Stream s = m.Build();
    870     ASSERT_LE(1U, s.size());
    871     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    872     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
    873     EXPECT_EQ(3U, s[0]->InputCount());
    874     EXPECT_EQ(2U, s[0]->OutputCount());
    875     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    876     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    877   }
    878 }
    879 
    880 
    881 TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
    882   const ODPI odpi = GetParam();
    883   TRACED_FOREACH(Shift, shift, kShifts) {
    884     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    885       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    886                       MachineType::Int32());
    887       Node* n = (m.*odpi.constructor)(
    888           m.Parameter(0),
    889           (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
    890       m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
    891       Stream s = m.Build();
    892       ASSERT_LE(1U, s.size());
    893       EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    894       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    895       ASSERT_EQ(3U, s[0]->InputCount());
    896       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    897       EXPECT_EQ(2U, s[0]->OutputCount());
    898       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    899       EXPECT_EQ(kOverflow, s[0]->flags_condition());
    900     }
    901   }
    902   TRACED_FOREACH(Shift, shift, kShifts) {
    903     TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
    904       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    905                       MachineType::Int32());
    906       Node* n = (m.*odpi.constructor)(
    907           (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
    908           m.Parameter(1));
    909       m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
    910       Stream s = m.Build();
    911       ASSERT_LE(1U, s.size());
    912       EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    913       EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
    914       ASSERT_EQ(3U, s[0]->InputCount());
    915       EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
    916       EXPECT_EQ(2U, s[0]->OutputCount());
    917       EXPECT_EQ(kFlags_set, s[0]->flags_mode());
    918       EXPECT_EQ(kOverflow, s[0]->flags_condition());
    919     }
    920   }
    921 }
    922 
    923 
    924 TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
    925   const ODPI odpi = GetParam();
    926   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    927                   MachineType::Int32());
    928   RawMachineLabel a, b;
    929   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
    930   m.Branch(m.Projection(1, n), &a, &b);
    931   m.Bind(&a);
    932   m.Return(m.Int32Constant(0));
    933   m.Bind(&b);
    934   m.Return(m.Projection(0, n));
    935   Stream s = m.Build();
    936   ASSERT_EQ(1U, s.size());
    937   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    938   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
    939   EXPECT_EQ(4U, s[0]->InputCount());
    940   EXPECT_EQ(1U, s[0]->OutputCount());
    941   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    942   EXPECT_EQ(kOverflow, s[0]->flags_condition());
    943 }
    944 
    945 
    946 TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
    947   const ODPI odpi = GetParam();
    948   TRACED_FOREACH(int32_t, imm, kImmediates) {
    949     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    950     RawMachineLabel a, b;
    951     Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
    952     m.Branch(m.Projection(1, n), &a, &b);
    953     m.Bind(&a);
    954     m.Return(m.Int32Constant(0));
    955     m.Bind(&b);
    956     m.Return(m.Projection(0, n));
    957     Stream s = m.Build();
    958     ASSERT_EQ(1U, s.size());
    959     EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
    960     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    961     ASSERT_EQ(4U, s[0]->InputCount());
    962     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    963     EXPECT_EQ(1U, s[0]->OutputCount());
    964     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    965     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    966   }
    967   TRACED_FOREACH(int32_t, imm, kImmediates) {
    968     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    969     RawMachineLabel a, b;
    970     Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
    971     m.Branch(m.Projection(1, n), &a, &b);
    972     m.Bind(&a);
    973     m.Return(m.Int32Constant(0));
    974     m.Bind(&b);
    975     m.Return(m.Projection(0, n));
    976     Stream s = m.Build();
    977     ASSERT_EQ(1U, s.size());
    978     EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
    979     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
    980     ASSERT_EQ(4U, s[0]->InputCount());
    981     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
    982     EXPECT_EQ(1U, s[0]->OutputCount());
    983     EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
    984     EXPECT_EQ(kOverflow, s[0]->flags_condition());
    985   }
    986 }
    987 
    988 
    989 TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
    990   const ODPI odpi = GetParam();
    991   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    992                   MachineType::Int32());
    993   RawMachineLabel a, b;
    994   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
    995   m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
    996   m.Bind(&a);
    997   m.Return(m.Projection(0, n));
    998   m.Bind(&b);
    999   m.Return(m.Int32Constant(0));
   1000   Stream s = m.Build();
   1001   ASSERT_EQ(1U, s.size());
   1002   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
   1003   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   1004   EXPECT_EQ(4U, s[0]->InputCount());
   1005   EXPECT_EQ(1U, s[0]->OutputCount());
   1006   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
   1007   EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
   1008 }
   1009 
   1010 
   1011 TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
   1012   const ODPI odpi = GetParam();
   1013   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1014                   MachineType::Int32());
   1015   RawMachineLabel a, b;
   1016   Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
   1017   m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
   1018   m.Bind(&a);
   1019   m.Return(m.Projection(0, n));
   1020   m.Bind(&b);
   1021   m.Return(m.Int32Constant(0));
   1022   Stream s = m.Build();
   1023   ASSERT_EQ(1U, s.size());
   1024   EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
   1025   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   1026   EXPECT_EQ(4U, s[0]->InputCount());
   1027   EXPECT_EQ(1U, s[0]->OutputCount());
   1028   EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
   1029   EXPECT_EQ(kOverflow, s[0]->flags_condition());
   1030 }
   1031 
   1032 
   1033 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
   1034                         ::testing::ValuesIn(kODPIs));
   1035 
   1036 
   1037 // -----------------------------------------------------------------------------
   1038 // Shifts.
   1039 
   1040 
   1041 typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
   1042 
   1043 
   1044 TEST_P(InstructionSelectorShiftTest, Parameters) {
   1045   const Shift shift = GetParam();
   1046   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1047                   MachineType::Int32());
   1048   m.Return((m.*shift.constructor)(m.Parameter(0), m.Parameter(1)));
   1049   Stream s = m.Build();
   1050   ASSERT_EQ(1U, s.size());
   1051   EXPECT_EQ(kArmMov, s[0]->arch_opcode());
   1052   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
   1053   EXPECT_EQ(2U, s[0]->InputCount());
   1054   EXPECT_EQ(1U, s[0]->OutputCount());
   1055 }
   1056 
   1057 
   1058 TEST_P(InstructionSelectorShiftTest, Immediate) {
   1059   const Shift shift = GetParam();
   1060   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
   1061     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   1062     m.Return((m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)));
   1063     Stream s = m.Build();
   1064     ASSERT_EQ(1U, s.size());
   1065     EXPECT_EQ(kArmMov, s[0]->arch_opcode());
   1066     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
   1067     ASSERT_EQ(2U, s[0]->InputCount());
   1068     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
   1069     EXPECT_EQ(1U, s[0]->OutputCount());
   1070   }
   1071 }
   1072 
   1073 
   1074 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameter) {
   1075   const Shift shift = GetParam();
   1076   {
   1077     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1078                     MachineType::Int32(), MachineType::Int32());
   1079     m.Return(
   1080         m.Word32Equal(m.Parameter(0),
   1081                       (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
   1082     Stream s = m.Build();
   1083     ASSERT_EQ(1U, s.size());
   1084     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   1085     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
   1086     EXPECT_EQ(3U, s[0]->InputCount());
   1087     EXPECT_EQ(1U, s[0]->OutputCount());
   1088     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1089     EXPECT_EQ(kEqual, s[0]->flags_condition());
   1090   }
   1091   {
   1092     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1093                     MachineType::Int32(), MachineType::Int32());
   1094     m.Return(
   1095         m.Word32Equal((m.*shift.constructor)(m.Parameter(1), m.Parameter(2)),
   1096                       m.Parameter(0)));
   1097     Stream s = m.Build();
   1098     ASSERT_EQ(1U, s.size());
   1099     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   1100     EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
   1101     EXPECT_EQ(3U, s[0]->InputCount());
   1102     EXPECT_EQ(1U, s[0]->OutputCount());
   1103     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1104     EXPECT_EQ(kEqual, s[0]->flags_condition());
   1105   }
   1106 }
   1107 
   1108 
   1109 TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameterAndImmediate) {
   1110   const Shift shift = GetParam();
   1111   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
   1112     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1113                     MachineType::Int32());
   1114     m.Return(m.Word32Equal(
   1115         (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
   1116         m.Parameter(0)));
   1117     Stream s = m.Build();
   1118     ASSERT_EQ(1U, s.size());
   1119     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   1120     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
   1121     ASSERT_EQ(3U, s[0]->InputCount());
   1122     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
   1123     EXPECT_EQ(1U, s[0]->OutputCount());
   1124     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1125     EXPECT_EQ(kEqual, s[0]->flags_condition());
   1126   }
   1127   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
   1128     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1129                     MachineType::Int32());
   1130     m.Return(m.Word32Equal(
   1131         m.Parameter(0),
   1132         (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
   1133     Stream s = m.Build();
   1134     ASSERT_EQ(1U, s.size());
   1135     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   1136     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
   1137     ASSERT_EQ(3U, s[0]->InputCount());
   1138     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
   1139     EXPECT_EQ(1U, s[0]->OutputCount());
   1140     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1141     EXPECT_EQ(kEqual, s[0]->flags_condition());
   1142   }
   1143 }
   1144 
   1145 
   1146 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithParameters) {
   1147   const Shift shift = GetParam();
   1148   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1149                   MachineType::Int32());
   1150   m.Return(
   1151       m.Word32Equal(m.Int32Constant(0),
   1152                     (m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
   1153   Stream s = m.Build();
   1154   ASSERT_EQ(1U, s.size());
   1155   EXPECT_EQ(kArmMov, s[0]->arch_opcode());
   1156   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
   1157   EXPECT_EQ(2U, s[0]->InputCount());
   1158   EXPECT_EQ(2U, s[0]->OutputCount());
   1159   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1160   EXPECT_EQ(kEqual, s[0]->flags_condition());
   1161 }
   1162 
   1163 
   1164 TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithImmediate) {
   1165   const Shift shift = GetParam();
   1166   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
   1167     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1168                     MachineType::Int32());
   1169     m.Return(m.Word32Equal(
   1170         m.Int32Constant(0),
   1171         (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
   1172     Stream s = m.Build();
   1173     ASSERT_EQ(1U, s.size());
   1174     EXPECT_EQ(kArmMov, s[0]->arch_opcode());
   1175     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
   1176     ASSERT_EQ(2U, s[0]->InputCount());
   1177     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
   1178     EXPECT_EQ(2U, s[0]->OutputCount());
   1179     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1180     EXPECT_EQ(kEqual, s[0]->flags_condition());
   1181   }
   1182 }
   1183 
   1184 
   1185 TEST_P(InstructionSelectorShiftTest, Word32NotWithParameters) {
   1186   const Shift shift = GetParam();
   1187   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1188                   MachineType::Int32());
   1189   m.Return(m.Word32Not((m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
   1190   Stream s = m.Build();
   1191   ASSERT_EQ(1U, s.size());
   1192   EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
   1193   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
   1194   EXPECT_EQ(2U, s[0]->InputCount());
   1195   EXPECT_EQ(1U, s[0]->OutputCount());
   1196 }
   1197 
   1198 
   1199 TEST_P(InstructionSelectorShiftTest, Word32NotWithImmediate) {
   1200   const Shift shift = GetParam();
   1201   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
   1202     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   1203     m.Return(m.Word32Not(
   1204         (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
   1205     Stream s = m.Build();
   1206     ASSERT_EQ(1U, s.size());
   1207     EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
   1208     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
   1209     ASSERT_EQ(2U, s[0]->InputCount());
   1210     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
   1211     EXPECT_EQ(1U, s[0]->OutputCount());
   1212   }
   1213 }
   1214 
   1215 
   1216 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithParameters) {
   1217   const Shift shift = GetParam();
   1218   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1219                   MachineType::Int32(), MachineType::Int32());
   1220   m.Return(m.Word32And(m.Parameter(0), m.Word32Not((m.*shift.constructor)(
   1221                                            m.Parameter(1), m.Parameter(2)))));
   1222   Stream s = m.Build();
   1223   ASSERT_EQ(1U, s.size());
   1224   EXPECT_EQ(kArmBic, s[0]->arch_opcode());
   1225   EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
   1226   EXPECT_EQ(3U, s[0]->InputCount());
   1227   EXPECT_EQ(1U, s[0]->OutputCount());
   1228 }
   1229 
   1230 
   1231 TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithImmediate) {
   1232   const Shift shift = GetParam();
   1233   TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
   1234     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1235                     MachineType::Int32());
   1236     m.Return(m.Word32And(m.Parameter(0),
   1237                          m.Word32Not((m.*shift.constructor)(
   1238                              m.Parameter(1), m.Int32Constant(imm)))));
   1239     Stream s = m.Build();
   1240     ASSERT_EQ(1U, s.size());
   1241     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
   1242     EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
   1243     ASSERT_EQ(3U, s[0]->InputCount());
   1244     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
   1245     EXPECT_EQ(1U, s[0]->OutputCount());
   1246   }
   1247 }
   1248 
   1249 
   1250 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
   1251                         ::testing::ValuesIn(kShifts));
   1252 
   1253 
   1254 // -----------------------------------------------------------------------------
   1255 // Memory access instructions.
   1256 
   1257 
   1258 namespace {
   1259 
   1260 struct MemoryAccess {
   1261   MachineType type;
   1262   ArchOpcode ldr_opcode;
   1263   ArchOpcode str_opcode;
   1264   bool (InstructionSelectorTest::Stream::*val_predicate)(
   1265       const InstructionOperand*) const;
   1266   const int32_t immediates[40];
   1267 };
   1268 
   1269 
   1270 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
   1271   return os << memacc.type;
   1272 }
   1273 
   1274 
   1275 const MemoryAccess kMemoryAccesses[] = {
   1276     {MachineType::Int8(),
   1277      kArmLdrsb,
   1278      kArmStrb,
   1279      &InstructionSelectorTest::Stream::IsInteger,
   1280      {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
   1281       -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
   1282       115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
   1283     {MachineType::Uint8(),
   1284      kArmLdrb,
   1285      kArmStrb,
   1286      &InstructionSelectorTest::Stream::IsInteger,
   1287      {-4095, -3914, -3536, -3234, -3185, -3169, -1073, -990, -859, -720, -434,
   1288       -127, -124, -122, -105, -91, -86, -64, -55, -53, -30, -10, -3, 0, 20, 28,
   1289       39, 58, 64, 73, 75, 100, 108, 121, 686, 963, 1363, 2759, 3449, 4095}},
   1290     {MachineType::Int16(),
   1291      kArmLdrsh,
   1292      kArmStrh,
   1293      &InstructionSelectorTest::Stream::IsInteger,
   1294      {-255, -251, -232, -220, -144, -138, -130, -126, -116, -115, -102, -101,
   1295       -98, -69, -59, -56, -39, -35, -23, -19, -7, 0, 22, 26, 37, 68, 83, 87, 98,
   1296       102, 108, 111, 117, 171, 195, 203, 204, 245, 246, 255}},
   1297     {MachineType::Uint16(),
   1298      kArmLdrh,
   1299      kArmStrh,
   1300      &InstructionSelectorTest::Stream::IsInteger,
   1301      {-255, -230, -201, -172, -125, -119, -118, -105, -98, -79, -54, -42, -41,
   1302       -32, -12, -11, -5, -4, 0, 5, 9, 25, 28, 51, 58, 60, 89, 104, 108, 109,
   1303       114, 116, 120, 138, 150, 161, 166, 172, 228, 255}},
   1304     {MachineType::Int32(),
   1305      kArmLdr,
   1306      kArmStr,
   1307      &InstructionSelectorTest::Stream::IsInteger,
   1308      {-4095, -1898, -1685, -1562, -1408, -1313, -344, -128, -116, -100, -92,
   1309       -80, -72, -71, -56, -25, -21, -11, -9, 0, 3, 5, 27, 28, 42, 52, 63, 88,
   1310       93, 97, 125, 846, 1037, 2102, 2403, 2597, 2632, 2997, 3935, 4095}},
   1311     {MachineType::Float32(),
   1312      kArmVldrF32,
   1313      kArmVstrF32,
   1314      &InstructionSelectorTest::Stream::IsDouble,
   1315      {-1020, -928, -896, -772, -728, -680, -660, -488, -372, -112, -100, -92,
   1316       -84, -80, -72, -64, -60, -56, -52, -48, -36, -32, -20, -8, -4, 0, 8, 20,
   1317       24, 40, 64, 112, 204, 388, 516, 852, 856, 976, 988, 1020}},
   1318     {MachineType::Float64(),
   1319      kArmVldrF64,
   1320      kArmVstrF64,
   1321      &InstructionSelectorTest::Stream::IsDouble,
   1322      {-1020, -948, -796, -696, -612, -364, -320, -308, -128, -112, -108, -104,
   1323       -96, -84, -80, -56, -48, -40, -20, 0, 24, 28, 36, 48, 64, 84, 96, 100,
   1324       108, 116, 120, 140, 156, 408, 432, 444, 772, 832, 940, 1020}}};
   1325 
   1326 }  // namespace
   1327 
   1328 
   1329 typedef InstructionSelectorTestWithParam<MemoryAccess>
   1330     InstructionSelectorMemoryAccessTest;
   1331 
   1332 
   1333 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
   1334   const MemoryAccess memacc = GetParam();
   1335   StreamBuilder m(this, memacc.type, MachineType::Pointer(),
   1336                   MachineType::Int32());
   1337   m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
   1338   Stream s = m.Build();
   1339   ASSERT_EQ(1U, s.size());
   1340   EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
   1341   EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
   1342   EXPECT_EQ(2U, s[0]->InputCount());
   1343   ASSERT_EQ(1U, s[0]->OutputCount());
   1344   EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
   1345 }
   1346 
   1347 
   1348 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
   1349   const MemoryAccess memacc = GetParam();
   1350   TRACED_FOREACH(int32_t, index, memacc.immediates) {
   1351     StreamBuilder m(this, memacc.type, MachineType::Pointer());
   1352     m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
   1353     Stream s = m.Build();
   1354     ASSERT_EQ(1U, s.size());
   1355     EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
   1356     EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
   1357     ASSERT_EQ(2U, s[0]->InputCount());
   1358     ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
   1359     EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
   1360     ASSERT_EQ(1U, s[0]->OutputCount());
   1361     EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
   1362   }
   1363 }
   1364 
   1365 
   1366 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
   1367   const MemoryAccess memacc = GetParam();
   1368   StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
   1369                   MachineType::Int32(), memacc.type);
   1370   m.Store(memacc.type.representation(), m.Parameter(0), m.Parameter(1),
   1371           m.Parameter(2), kNoWriteBarrier);
   1372   m.Return(m.Int32Constant(0));
   1373   Stream s = m.Build();
   1374   ASSERT_EQ(1U, s.size());
   1375   EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
   1376   EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
   1377   EXPECT_EQ(3U, s[0]->InputCount());
   1378   EXPECT_EQ(0U, s[0]->OutputCount());
   1379 }
   1380 
   1381 
   1382 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
   1383   const MemoryAccess memacc = GetParam();
   1384   TRACED_FOREACH(int32_t, index, memacc.immediates) {
   1385     StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
   1386                     memacc.type);
   1387     m.Store(memacc.type.representation(), m.Parameter(0),
   1388             m.Int32Constant(index), m.Parameter(1), kNoWriteBarrier);
   1389     m.Return(m.Int32Constant(0));
   1390     Stream s = m.Build();
   1391     ASSERT_EQ(1U, s.size());
   1392     EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
   1393     EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
   1394     ASSERT_EQ(3U, s[0]->InputCount());
   1395     ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(2)->kind());
   1396     EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(2)));
   1397     EXPECT_EQ(0U, s[0]->OutputCount());
   1398   }
   1399 }
   1400 
   1401 
   1402 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
   1403                         InstructionSelectorMemoryAccessTest,
   1404                         ::testing::ValuesIn(kMemoryAccesses));
   1405 
   1406 TEST_F(InstructionSelectorMemoryAccessTest, LoadWithShiftedIndex) {
   1407   TRACED_FORRANGE(int, immediate_shift, 1, 31) {
   1408     StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
   1409                     MachineType::Int32());
   1410     Node* const index =
   1411         m.Word32Shl(m.Parameter(1), m.Int32Constant(immediate_shift));
   1412     m.Return(m.Load(MachineType::Int32(), m.Parameter(0), index));
   1413     Stream s = m.Build();
   1414     ASSERT_EQ(1U, s.size());
   1415     EXPECT_EQ(kArmLdr, s[0]->arch_opcode());
   1416     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
   1417     EXPECT_EQ(3U, s[0]->InputCount());
   1418     EXPECT_EQ(1U, s[0]->OutputCount());
   1419   }
   1420 }
   1421 
   1422 TEST_F(InstructionSelectorMemoryAccessTest, StoreWithShiftedIndex) {
   1423   TRACED_FORRANGE(int, immediate_shift, 1, 31) {
   1424     StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
   1425                     MachineType::Int32(), MachineType::Int32());
   1426     Node* const index =
   1427         m.Word32Shl(m.Parameter(1), m.Int32Constant(immediate_shift));
   1428     m.Store(MachineRepresentation::kWord32, m.Parameter(0), index,
   1429             m.Parameter(2), kNoWriteBarrier);
   1430     m.Return(m.Int32Constant(0));
   1431     Stream s = m.Build();
   1432     ASSERT_EQ(1U, s.size());
   1433     EXPECT_EQ(kArmStr, s[0]->arch_opcode());
   1434     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
   1435     EXPECT_EQ(4U, s[0]->InputCount());
   1436     EXPECT_EQ(0U, s[0]->OutputCount());
   1437   }
   1438 }
   1439 
   1440 // -----------------------------------------------------------------------------
   1441 // Conversions.
   1442 
   1443 
   1444 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
   1445   StreamBuilder m(this, MachineType::Float64(), MachineType::Float32());
   1446   m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
   1447   Stream s = m.Build();
   1448   ASSERT_EQ(1U, s.size());
   1449   EXPECT_EQ(kArmVcvtF64F32, s[0]->arch_opcode());
   1450   EXPECT_EQ(1U, s[0]->InputCount());
   1451   EXPECT_EQ(1U, s[0]->OutputCount());
   1452 }
   1453 
   1454 
   1455 TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) {
   1456   StreamBuilder m(this, MachineType::Float32(), MachineType::Float64());
   1457   m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
   1458   Stream s = m.Build();
   1459   ASSERT_EQ(1U, s.size());
   1460   EXPECT_EQ(kArmVcvtF32F64, s[0]->arch_opcode());
   1461   EXPECT_EQ(1U, s[0]->InputCount());
   1462   EXPECT_EQ(1U, s[0]->OutputCount());
   1463 }
   1464 
   1465 
   1466 // -----------------------------------------------------------------------------
   1467 // Comparisons.
   1468 
   1469 
   1470 namespace {
   1471 
   1472 struct Comparison {
   1473   Constructor constructor;
   1474   const char* constructor_name;
   1475   FlagsCondition flags_condition;
   1476   FlagsCondition negated_flags_condition;
   1477   FlagsCondition commuted_flags_condition;
   1478 };
   1479 
   1480 
   1481 std::ostream& operator<<(std::ostream& os, const Comparison& cmp) {
   1482   return os << cmp.constructor_name;
   1483 }
   1484 
   1485 
   1486 const Comparison kComparisons[] = {
   1487     {&RawMachineAssembler::Word32Equal, "Word32Equal", kEqual, kNotEqual,
   1488      kEqual},
   1489     {&RawMachineAssembler::Int32LessThan, "Int32LessThan", kSignedLessThan,
   1490      kSignedGreaterThanOrEqual, kSignedGreaterThan},
   1491     {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
   1492      kSignedLessThanOrEqual, kSignedGreaterThan, kSignedGreaterThanOrEqual},
   1493     {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kUnsignedLessThan,
   1494      kUnsignedGreaterThanOrEqual, kUnsignedGreaterThan},
   1495     {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
   1496      kUnsignedLessThanOrEqual, kUnsignedGreaterThan,
   1497      kUnsignedGreaterThanOrEqual}};
   1498 
   1499 }  // namespace
   1500 
   1501 
   1502 typedef InstructionSelectorTestWithParam<Comparison>
   1503     InstructionSelectorComparisonTest;
   1504 
   1505 
   1506 TEST_P(InstructionSelectorComparisonTest, Parameters) {
   1507   const Comparison& cmp = GetParam();
   1508   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1509                   MachineType::Int32());
   1510   Node* const p0 = m.Parameter(0);
   1511   Node* const p1 = m.Parameter(1);
   1512   Node* const r = (m.*cmp.constructor)(p0, p1);
   1513   m.Return(r);
   1514   Stream const s = m.Build();
   1515   ASSERT_EQ(1U, s.size());
   1516   EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   1517   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   1518   ASSERT_EQ(2U, s[0]->InputCount());
   1519   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1520   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1521   ASSERT_EQ(1U, s[0]->OutputCount());
   1522   EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
   1523   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1524   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
   1525 }
   1526 
   1527 
   1528 TEST_P(InstructionSelectorComparisonTest, Word32EqualWithZero) {
   1529   {
   1530     const Comparison& cmp = GetParam();
   1531     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1532                     MachineType::Int32());
   1533     Node* const p0 = m.Parameter(0);
   1534     Node* const p1 = m.Parameter(1);
   1535     Node* const r =
   1536         m.Word32Equal((m.*cmp.constructor)(p0, p1), m.Int32Constant(0));
   1537     m.Return(r);
   1538     Stream const s = m.Build();
   1539     ASSERT_EQ(1U, s.size());
   1540     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   1541     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   1542     ASSERT_EQ(2U, s[0]->InputCount());
   1543     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1544     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1545     ASSERT_EQ(1U, s[0]->OutputCount());
   1546     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
   1547     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1548     EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
   1549   }
   1550   {
   1551     const Comparison& cmp = GetParam();
   1552     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   1553                     MachineType::Int32());
   1554     Node* const p0 = m.Parameter(0);
   1555     Node* const p1 = m.Parameter(1);
   1556     Node* const r =
   1557         m.Word32Equal(m.Int32Constant(0), (m.*cmp.constructor)(p0, p1));
   1558     m.Return(r);
   1559     Stream const s = m.Build();
   1560     ASSERT_EQ(1U, s.size());
   1561     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   1562     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   1563     ASSERT_EQ(2U, s[0]->InputCount());
   1564     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1565     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1566     ASSERT_EQ(1U, s[0]->OutputCount());
   1567     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
   1568     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1569     EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
   1570   }
   1571 }
   1572 
   1573 
   1574 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
   1575                         InstructionSelectorComparisonTest,
   1576                         ::testing::ValuesIn(kComparisons));
   1577 
   1578 
   1579 // -----------------------------------------------------------------------------
   1580 // Floating point comparisons.
   1581 
   1582 
   1583 namespace {
   1584 
   1585 const Comparison kF32Comparisons[] = {
   1586     {&RawMachineAssembler::Float32Equal, "Float32Equal", kEqual, kNotEqual,
   1587      kEqual},
   1588     {&RawMachineAssembler::Float32LessThan, "Float32LessThan",
   1589      kFloatLessThan, kFloatGreaterThanOrEqualOrUnordered, kFloatGreaterThan},
   1590     {&RawMachineAssembler::Float32LessThanOrEqual, "Float32LessThanOrEqual",
   1591      kFloatLessThanOrEqual, kFloatGreaterThanOrUnordered,
   1592      kFloatGreaterThanOrEqual}};
   1593 
   1594 }  // namespace
   1595 
   1596 typedef InstructionSelectorTestWithParam<Comparison>
   1597     InstructionSelectorF32ComparisonTest;
   1598 
   1599 
   1600 TEST_P(InstructionSelectorF32ComparisonTest, WithParameters) {
   1601   const Comparison& cmp = GetParam();
   1602   StreamBuilder m(this, MachineType::Int32(), MachineType::Float32(),
   1603                   MachineType::Float32());
   1604   m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
   1605   Stream const s = m.Build();
   1606   ASSERT_EQ(1U, s.size());
   1607   EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
   1608   ASSERT_EQ(2U, s[0]->InputCount());
   1609   ASSERT_EQ(1U, s[0]->OutputCount());
   1610   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1611   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
   1612 }
   1613 
   1614 
   1615 TEST_P(InstructionSelectorF32ComparisonTest, NegatedWithParameters) {
   1616   const Comparison& cmp = GetParam();
   1617   StreamBuilder m(this, MachineType::Int32(), MachineType::Float32(),
   1618                   MachineType::Float32());
   1619   m.Return(
   1620       m.Word32BinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))));
   1621   Stream const s = m.Build();
   1622   ASSERT_EQ(1U, s.size());
   1623   EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
   1624   ASSERT_EQ(2U, s[0]->InputCount());
   1625   ASSERT_EQ(1U, s[0]->OutputCount());
   1626   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1627   EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
   1628 }
   1629 
   1630 
   1631 TEST_P(InstructionSelectorF32ComparisonTest, WithImmediateZeroOnRight) {
   1632   const Comparison& cmp = GetParam();
   1633   StreamBuilder m(this, MachineType::Int32(), MachineType::Float32());
   1634   m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float32Constant(0.0)));
   1635   Stream const s = m.Build();
   1636   ASSERT_EQ(1U, s.size());
   1637   EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
   1638   ASSERT_EQ(2U, s[0]->InputCount());
   1639   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
   1640   ASSERT_EQ(1U, s[0]->OutputCount());
   1641   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1642   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
   1643 }
   1644 
   1645 
   1646 TEST_P(InstructionSelectorF32ComparisonTest, WithImmediateZeroOnLeft) {
   1647   const Comparison& cmp = GetParam();
   1648   StreamBuilder m(this, MachineType::Int32(), MachineType::Float32());
   1649   m.Return((m.*cmp.constructor)(m.Float32Constant(0.0f), m.Parameter(0)));
   1650   Stream const s = m.Build();
   1651   ASSERT_EQ(1U, s.size());
   1652   EXPECT_EQ(kArmVcmpF32, s[0]->arch_opcode());
   1653   ASSERT_EQ(2U, s[0]->InputCount());
   1654   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
   1655   ASSERT_EQ(1U, s[0]->OutputCount());
   1656   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1657   EXPECT_EQ(cmp.commuted_flags_condition, s[0]->flags_condition());
   1658 }
   1659 
   1660 
   1661 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
   1662                         InstructionSelectorF32ComparisonTest,
   1663                         ::testing::ValuesIn(kF32Comparisons));
   1664 
   1665 
   1666 namespace {
   1667 
   1668 const Comparison kF64Comparisons[] = {
   1669     {&RawMachineAssembler::Float64Equal, "Float64Equal", kEqual, kNotEqual,
   1670      kEqual},
   1671     {&RawMachineAssembler::Float64LessThan, "Float64LessThan",
   1672      kFloatLessThan, kFloatGreaterThanOrEqualOrUnordered, kFloatGreaterThan},
   1673     {&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
   1674      kFloatLessThanOrEqual, kFloatGreaterThanOrUnordered,
   1675      kFloatGreaterThanOrEqual}};
   1676 
   1677 }  // namespace
   1678 
   1679 typedef InstructionSelectorTestWithParam<Comparison>
   1680     InstructionSelectorF64ComparisonTest;
   1681 
   1682 
   1683 TEST_P(InstructionSelectorF64ComparisonTest, WithParameters) {
   1684   const Comparison& cmp = GetParam();
   1685   StreamBuilder m(this, MachineType::Int32(), MachineType::Float64(),
   1686                   MachineType::Float64());
   1687   m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
   1688   Stream const s = m.Build();
   1689   ASSERT_EQ(1U, s.size());
   1690   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
   1691   ASSERT_EQ(2U, s[0]->InputCount());
   1692   ASSERT_EQ(1U, s[0]->OutputCount());
   1693   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1694   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
   1695 }
   1696 
   1697 
   1698 TEST_P(InstructionSelectorF64ComparisonTest, NegatedWithParameters) {
   1699   const Comparison& cmp = GetParam();
   1700   StreamBuilder m(this, MachineType::Int32(), MachineType::Float64(),
   1701                   MachineType::Float64());
   1702   m.Return(
   1703       m.Word32BinaryNot((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1))));
   1704   Stream const s = m.Build();
   1705   ASSERT_EQ(1U, s.size());
   1706   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
   1707   ASSERT_EQ(2U, s[0]->InputCount());
   1708   ASSERT_EQ(1U, s[0]->OutputCount());
   1709   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1710   EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
   1711 }
   1712 
   1713 
   1714 TEST_P(InstructionSelectorF64ComparisonTest, WithImmediateZeroOnRight) {
   1715   const Comparison& cmp = GetParam();
   1716   StreamBuilder m(this, MachineType::Int32(), MachineType::Float64());
   1717   m.Return((m.*cmp.constructor)(m.Parameter(0), m.Float64Constant(0.0)));
   1718   Stream const s = m.Build();
   1719   ASSERT_EQ(1U, s.size());
   1720   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
   1721   ASSERT_EQ(2U, s[0]->InputCount());
   1722   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
   1723   ASSERT_EQ(1U, s[0]->OutputCount());
   1724   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1725   EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
   1726 }
   1727 
   1728 
   1729 TEST_P(InstructionSelectorF64ComparisonTest, WithImmediateZeroOnLeft) {
   1730   const Comparison& cmp = GetParam();
   1731   StreamBuilder m(this, MachineType::Int32(), MachineType::Float64());
   1732   m.Return((m.*cmp.constructor)(m.Float64Constant(0.0), m.Parameter(0)));
   1733   Stream const s = m.Build();
   1734   ASSERT_EQ(1U, s.size());
   1735   EXPECT_EQ(kArmVcmpF64, s[0]->arch_opcode());
   1736   ASSERT_EQ(2U, s[0]->InputCount());
   1737   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
   1738   ASSERT_EQ(1U, s[0]->OutputCount());
   1739   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1740   EXPECT_EQ(cmp.commuted_flags_condition, s[0]->flags_condition());
   1741 }
   1742 
   1743 
   1744 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
   1745                         InstructionSelectorF64ComparisonTest,
   1746                         ::testing::ValuesIn(kF64Comparisons));
   1747 
   1748 
   1749 // -----------------------------------------------------------------------------
   1750 // Floating point arithmetic.
   1751 
   1752 
   1753 typedef InstructionSelectorTestWithParam<FAI> InstructionSelectorFAITest;
   1754 
   1755 
   1756 TEST_P(InstructionSelectorFAITest, Parameters) {
   1757   const FAI& fai = GetParam();
   1758   StreamBuilder m(this, fai.machine_type, fai.machine_type, fai.machine_type);
   1759   Node* const p0 = m.Parameter(0);
   1760   Node* const p1 = m.Parameter(1);
   1761   Node* const r = (m.*fai.constructor)(p0, p1);
   1762   m.Return(r);
   1763   Stream const s = m.Build();
   1764   ASSERT_EQ(1U, s.size());
   1765   EXPECT_EQ(fai.arch_opcode, s[0]->arch_opcode());
   1766   EXPECT_EQ(kMode_None, s[0]->addressing_mode());
   1767   ASSERT_EQ(2U, s[0]->InputCount());
   1768   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1769   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1770   ASSERT_EQ(1U, s[0]->OutputCount());
   1771   EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
   1772   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1773 }
   1774 
   1775 
   1776 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFAITest,
   1777                         ::testing::ValuesIn(kFAIs));
   1778 
   1779 
   1780 TEST_F(InstructionSelectorTest, Float32Abs) {
   1781   StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   1782   Node* const p0 = m.Parameter(0);
   1783   Node* const n = m.Float32Abs(p0);
   1784   m.Return(n);
   1785   Stream s = m.Build();
   1786   ASSERT_EQ(1U, s.size());
   1787   EXPECT_EQ(kArmVabsF32, s[0]->arch_opcode());
   1788   ASSERT_EQ(1U, s[0]->InputCount());
   1789   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1790   ASSERT_EQ(1U, s[0]->OutputCount());
   1791   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1792 }
   1793 
   1794 
   1795 TEST_F(InstructionSelectorTest, Float64Abs) {
   1796   StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   1797   Node* const p0 = m.Parameter(0);
   1798   Node* const n = m.Float64Abs(p0);
   1799   m.Return(n);
   1800   Stream s = m.Build();
   1801   ASSERT_EQ(1U, s.size());
   1802   EXPECT_EQ(kArmVabsF64, s[0]->arch_opcode());
   1803   ASSERT_EQ(1U, s[0]->InputCount());
   1804   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1805   ASSERT_EQ(1U, s[0]->OutputCount());
   1806   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1807 }
   1808 
   1809 
   1810 TEST_F(InstructionSelectorTest, Float32AddWithFloat32Mul) {
   1811   {
   1812     StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(),
   1813                     MachineType::Float32(), MachineType::Float32());
   1814     Node* const p0 = m.Parameter(0);
   1815     Node* const p1 = m.Parameter(1);
   1816     Node* const p2 = m.Parameter(2);
   1817     Node* const n = m.Float32Add(m.Float32Mul(p0, p1), p2);
   1818     m.Return(n);
   1819     Stream s = m.Build();
   1820     ASSERT_EQ(1U, s.size());
   1821     EXPECT_EQ(kArmVmlaF32, s[0]->arch_opcode());
   1822     ASSERT_EQ(3U, s[0]->InputCount());
   1823     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0)));
   1824     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   1825     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(2)));
   1826     ASSERT_EQ(1U, s[0]->OutputCount());
   1827     EXPECT_TRUE(
   1828         UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   1829     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1830     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1831   }
   1832   {
   1833     StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(),
   1834                     MachineType::Float32(), MachineType::Float32());
   1835     Node* const p0 = m.Parameter(0);
   1836     Node* const p1 = m.Parameter(1);
   1837     Node* const p2 = m.Parameter(2);
   1838     Node* const n = m.Float32Add(p0, m.Float32Mul(p1, p2));
   1839     m.Return(n);
   1840     Stream s = m.Build();
   1841     ASSERT_EQ(1U, s.size());
   1842     EXPECT_EQ(kArmVmlaF32, s[0]->arch_opcode());
   1843     ASSERT_EQ(3U, s[0]->InputCount());
   1844     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1845     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1846     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
   1847     ASSERT_EQ(1U, s[0]->OutputCount());
   1848     EXPECT_TRUE(
   1849         UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   1850     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1851     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1852   }
   1853 }
   1854 
   1855 
   1856 TEST_F(InstructionSelectorTest, Float64AddWithFloat64Mul) {
   1857   {
   1858     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
   1859                     MachineType::Float64(), MachineType::Float64());
   1860     Node* const p0 = m.Parameter(0);
   1861     Node* const p1 = m.Parameter(1);
   1862     Node* const p2 = m.Parameter(2);
   1863     Node* const n = m.Float64Add(m.Float64Mul(p0, p1), p2);
   1864     m.Return(n);
   1865     Stream s = m.Build();
   1866     ASSERT_EQ(1U, s.size());
   1867     EXPECT_EQ(kArmVmlaF64, s[0]->arch_opcode());
   1868     ASSERT_EQ(3U, s[0]->InputCount());
   1869     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0)));
   1870     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   1871     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(2)));
   1872     ASSERT_EQ(1U, s[0]->OutputCount());
   1873     EXPECT_TRUE(
   1874         UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   1875     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1876     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1877   }
   1878   {
   1879     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
   1880                     MachineType::Float64(), MachineType::Float64());
   1881     Node* const p0 = m.Parameter(0);
   1882     Node* const p1 = m.Parameter(1);
   1883     Node* const p2 = m.Parameter(2);
   1884     Node* const n = m.Float64Add(p0, m.Float64Mul(p1, p2));
   1885     m.Return(n);
   1886     Stream s = m.Build();
   1887     ASSERT_EQ(1U, s.size());
   1888     EXPECT_EQ(kArmVmlaF64, s[0]->arch_opcode());
   1889     ASSERT_EQ(3U, s[0]->InputCount());
   1890     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1891     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1892     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
   1893     ASSERT_EQ(1U, s[0]->OutputCount());
   1894     EXPECT_TRUE(
   1895         UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   1896     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1897     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1898   }
   1899 }
   1900 
   1901 
   1902 TEST_F(InstructionSelectorTest, Float32SubWithMinusZero) {
   1903   StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   1904   Node* const p0 = m.Parameter(0);
   1905   Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
   1906   m.Return(n);
   1907   Stream s = m.Build();
   1908   ASSERT_EQ(1U, s.size());
   1909   EXPECT_EQ(kArmVnegF32, s[0]->arch_opcode());
   1910   ASSERT_EQ(1U, s[0]->InputCount());
   1911   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1912   ASSERT_EQ(1U, s[0]->OutputCount());
   1913   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1914 }
   1915 
   1916 
   1917 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
   1918   StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   1919   Node* const p0 = m.Parameter(0);
   1920   Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
   1921   m.Return(n);
   1922   Stream s = m.Build();
   1923   ASSERT_EQ(1U, s.size());
   1924   EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode());
   1925   ASSERT_EQ(1U, s[0]->InputCount());
   1926   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1927   ASSERT_EQ(1U, s[0]->OutputCount());
   1928   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1929 }
   1930 
   1931 
   1932 TEST_F(InstructionSelectorTest, Float32SubWithFloat32Mul) {
   1933   StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(),
   1934                   MachineType::Float32(), MachineType::Float32());
   1935   Node* const p0 = m.Parameter(0);
   1936   Node* const p1 = m.Parameter(1);
   1937   Node* const p2 = m.Parameter(2);
   1938   Node* const n = m.Float32Sub(p0, m.Float32Mul(p1, p2));
   1939   m.Return(n);
   1940   Stream s = m.Build();
   1941   ASSERT_EQ(1U, s.size());
   1942   EXPECT_EQ(kArmVmlsF32, s[0]->arch_opcode());
   1943   ASSERT_EQ(3U, s[0]->InputCount());
   1944   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1945   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1946   EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
   1947   ASSERT_EQ(1U, s[0]->OutputCount());
   1948   EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   1949   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1950   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1951 }
   1952 
   1953 
   1954 TEST_F(InstructionSelectorTest, Float64SubWithFloat64Mul) {
   1955   StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
   1956                   MachineType::Float64(), MachineType::Float64());
   1957   Node* const p0 = m.Parameter(0);
   1958   Node* const p1 = m.Parameter(1);
   1959   Node* const p2 = m.Parameter(2);
   1960   Node* const n = m.Float64Sub(p0, m.Float64Mul(p1, p2));
   1961   m.Return(n);
   1962   Stream s = m.Build();
   1963   ASSERT_EQ(1U, s.size());
   1964   EXPECT_EQ(kArmVmlsF64, s[0]->arch_opcode());
   1965   ASSERT_EQ(3U, s[0]->InputCount());
   1966   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1967   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   1968   EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(2)));
   1969   ASSERT_EQ(1U, s[0]->OutputCount());
   1970   EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   1971   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1972   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1973 }
   1974 
   1975 
   1976 TEST_F(InstructionSelectorTest, Float32Sqrt) {
   1977   StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   1978   Node* const p0 = m.Parameter(0);
   1979   Node* const n = m.Float32Sqrt(p0);
   1980   m.Return(n);
   1981   Stream s = m.Build();
   1982   ASSERT_EQ(1U, s.size());
   1983   EXPECT_EQ(kArmVsqrtF32, s[0]->arch_opcode());
   1984   ASSERT_EQ(1U, s[0]->InputCount());
   1985   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1986   ASSERT_EQ(1U, s[0]->OutputCount());
   1987   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1988   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1989 }
   1990 
   1991 
   1992 TEST_F(InstructionSelectorTest, Float64Sqrt) {
   1993   StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   1994   Node* const p0 = m.Parameter(0);
   1995   Node* const n = m.Float64Sqrt(p0);
   1996   m.Return(n);
   1997   Stream s = m.Build();
   1998   ASSERT_EQ(1U, s.size());
   1999   EXPECT_EQ(kArmVsqrtF64, s[0]->arch_opcode());
   2000   ASSERT_EQ(1U, s[0]->InputCount());
   2001   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2002   ASSERT_EQ(1U, s[0]->OutputCount());
   2003   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   2004   EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   2005 }
   2006 
   2007 
   2008 // -----------------------------------------------------------------------------
   2009 // Miscellaneous.
   2010 
   2011 
   2012 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
   2013   {
   2014     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2015                     MachineType::Int32(), MachineType::Int32());
   2016     Node* const p0 = m.Parameter(0);
   2017     Node* const p1 = m.Parameter(1);
   2018     Node* const p2 = m.Parameter(2);
   2019     Node* const n = m.Int32Add(p0, m.Int32Mul(p1, p2));
   2020     m.Return(n);
   2021     Stream s = m.Build();
   2022     ASSERT_EQ(1U, s.size());
   2023     EXPECT_EQ(kArmMla, s[0]->arch_opcode());
   2024     ASSERT_EQ(3U, s[0]->InputCount());
   2025     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2026     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
   2027     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
   2028     ASSERT_EQ(1U, s[0]->OutputCount());
   2029     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   2030   }
   2031   {
   2032     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2033                     MachineType::Int32(), MachineType::Int32());
   2034     Node* const p0 = m.Parameter(0);
   2035     Node* const p1 = m.Parameter(1);
   2036     Node* const p2 = m.Parameter(2);
   2037     Node* const n = m.Int32Add(m.Int32Mul(p1, p2), p0);
   2038     m.Return(n);
   2039     Stream s = m.Build();
   2040     ASSERT_EQ(1U, s.size());
   2041     EXPECT_EQ(kArmMla, s[0]->arch_opcode());
   2042     ASSERT_EQ(3U, s[0]->InputCount());
   2043     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2044     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
   2045     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
   2046     ASSERT_EQ(1U, s[0]->OutputCount());
   2047     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   2048   }
   2049 }
   2050 
   2051 
   2052 TEST_F(InstructionSelectorTest, Int32AddWithInt32MulHigh) {
   2053   {
   2054     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2055                     MachineType::Int32(), MachineType::Int32());
   2056     Node* const p0 = m.Parameter(0);
   2057     Node* const p1 = m.Parameter(1);
   2058     Node* const p2 = m.Parameter(2);
   2059     Node* const n = m.Int32Add(p0, m.Int32MulHigh(p1, p2));
   2060     m.Return(n);
   2061     Stream s = m.Build();
   2062     ASSERT_EQ(1U, s.size());
   2063     EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
   2064     ASSERT_EQ(3U, s[0]->InputCount());
   2065     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2066     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
   2067     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
   2068     ASSERT_EQ(1U, s[0]->OutputCount());
   2069     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   2070   }
   2071   {
   2072     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2073                     MachineType::Int32(), MachineType::Int32());
   2074     Node* const p0 = m.Parameter(0);
   2075     Node* const p1 = m.Parameter(1);
   2076     Node* const p2 = m.Parameter(2);
   2077     Node* const n = m.Int32Add(m.Int32MulHigh(p1, p2), p0);
   2078     m.Return(n);
   2079     Stream s = m.Build();
   2080     ASSERT_EQ(1U, s.size());
   2081     EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
   2082     ASSERT_EQ(3U, s[0]->InputCount());
   2083     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2084     EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
   2085     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
   2086     ASSERT_EQ(1U, s[0]->OutputCount());
   2087     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   2088   }
   2089 }
   2090 
   2091 
   2092 TEST_F(InstructionSelectorTest, Int32AddWithWord32And) {
   2093   {
   2094     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2095                     MachineType::Int32());
   2096     Node* const p0 = m.Parameter(0);
   2097     Node* const p1 = m.Parameter(1);
   2098     Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xff)), p1);
   2099     m.Return(r);
   2100     Stream s = m.Build();
   2101     ASSERT_EQ(1U, s.size());
   2102     EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
   2103     ASSERT_EQ(3U, s[0]->InputCount());
   2104     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2105     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2106     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2107     ASSERT_EQ(1U, s[0]->OutputCount());
   2108     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2109   }
   2110   {
   2111     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2112                     MachineType::Int32());
   2113     Node* const p0 = m.Parameter(0);
   2114     Node* const p1 = m.Parameter(1);
   2115     Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xff)));
   2116     m.Return(r);
   2117     Stream s = m.Build();
   2118     ASSERT_EQ(1U, s.size());
   2119     EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
   2120     ASSERT_EQ(3U, s[0]->InputCount());
   2121     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2122     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2123     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2124     ASSERT_EQ(1U, s[0]->OutputCount());
   2125     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2126   }
   2127   {
   2128     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2129                     MachineType::Int32());
   2130     Node* const p0 = m.Parameter(0);
   2131     Node* const p1 = m.Parameter(1);
   2132     Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xffff)), p1);
   2133     m.Return(r);
   2134     Stream s = m.Build();
   2135     ASSERT_EQ(1U, s.size());
   2136     EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
   2137     ASSERT_EQ(3U, s[0]->InputCount());
   2138     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2139     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2140     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2141     ASSERT_EQ(1U, s[0]->OutputCount());
   2142     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2143   }
   2144   {
   2145     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2146                     MachineType::Int32());
   2147     Node* const p0 = m.Parameter(0);
   2148     Node* const p1 = m.Parameter(1);
   2149     Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xffff)));
   2150     m.Return(r);
   2151     Stream s = m.Build();
   2152     ASSERT_EQ(1U, s.size());
   2153     EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
   2154     ASSERT_EQ(3U, s[0]->InputCount());
   2155     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2156     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2157     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2158     ASSERT_EQ(1U, s[0]->OutputCount());
   2159     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2160   }
   2161 }
   2162 
   2163 
   2164 TEST_F(InstructionSelectorTest, Int32AddWithWord32SarWithWord32Shl) {
   2165   {
   2166     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2167                     MachineType::Int32());
   2168     Node* const p0 = m.Parameter(0);
   2169     Node* const p1 = m.Parameter(1);
   2170     Node* const r = m.Int32Add(
   2171         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)),
   2172         p1);
   2173     m.Return(r);
   2174     Stream s = m.Build();
   2175     ASSERT_EQ(1U, s.size());
   2176     EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
   2177     ASSERT_EQ(3U, s[0]->InputCount());
   2178     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2179     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2180     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2181     ASSERT_EQ(1U, s[0]->OutputCount());
   2182     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2183   }
   2184   {
   2185     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2186                     MachineType::Int32());
   2187     Node* const p0 = m.Parameter(0);
   2188     Node* const p1 = m.Parameter(1);
   2189     Node* const r = m.Int32Add(
   2190         p1,
   2191         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)));
   2192     m.Return(r);
   2193     Stream s = m.Build();
   2194     ASSERT_EQ(1U, s.size());
   2195     EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
   2196     ASSERT_EQ(3U, s[0]->InputCount());
   2197     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2198     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2199     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2200     ASSERT_EQ(1U, s[0]->OutputCount());
   2201     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2202   }
   2203   {
   2204     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2205                     MachineType::Int32());
   2206     Node* const p0 = m.Parameter(0);
   2207     Node* const p1 = m.Parameter(1);
   2208     Node* const r = m.Int32Add(
   2209         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)),
   2210         p1);
   2211     m.Return(r);
   2212     Stream s = m.Build();
   2213     ASSERT_EQ(1U, s.size());
   2214     EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
   2215     ASSERT_EQ(3U, s[0]->InputCount());
   2216     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2217     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2218     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2219     ASSERT_EQ(1U, s[0]->OutputCount());
   2220     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2221   }
   2222   {
   2223     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2224                     MachineType::Int32());
   2225     Node* const p0 = m.Parameter(0);
   2226     Node* const p1 = m.Parameter(1);
   2227     Node* const r = m.Int32Add(
   2228         p1,
   2229         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)));
   2230     m.Return(r);
   2231     Stream s = m.Build();
   2232     ASSERT_EQ(1U, s.size());
   2233     EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
   2234     ASSERT_EQ(3U, s[0]->InputCount());
   2235     EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
   2236     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
   2237     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
   2238     ASSERT_EQ(1U, s[0]->OutputCount());
   2239     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2240   }
   2241 }
   2242 
   2243 
   2244 TEST_F(InstructionSelectorTest, Int32SubWithInt32Mul) {
   2245   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2246                   MachineType::Int32(), MachineType::Int32());
   2247   m.Return(
   2248       m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
   2249   Stream s = m.Build();
   2250   ASSERT_EQ(2U, s.size());
   2251   EXPECT_EQ(kArmMul, s[0]->arch_opcode());
   2252   ASSERT_EQ(1U, s[0]->OutputCount());
   2253   EXPECT_EQ(kArmSub, s[1]->arch_opcode());
   2254   ASSERT_EQ(2U, s[1]->InputCount());
   2255   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
   2256 }
   2257 
   2258 
   2259 TEST_F(InstructionSelectorTest, Int32SubWithInt32MulForMLS) {
   2260   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2261                   MachineType::Int32(), MachineType::Int32());
   2262   m.Return(
   2263       m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
   2264   Stream s = m.Build(ARMv7);
   2265   ASSERT_EQ(1U, s.size());
   2266   EXPECT_EQ(kArmMls, s[0]->arch_opcode());
   2267   EXPECT_EQ(1U, s[0]->OutputCount());
   2268   EXPECT_EQ(3U, s[0]->InputCount());
   2269 }
   2270 
   2271 
   2272 TEST_F(InstructionSelectorTest, Int32DivWithParameters) {
   2273   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2274                   MachineType::Int32());
   2275   m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
   2276   Stream s = m.Build();
   2277   ASSERT_EQ(4U, s.size());
   2278   EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
   2279   ASSERT_EQ(1U, s[0]->OutputCount());
   2280   EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
   2281   ASSERT_EQ(1U, s[1]->OutputCount());
   2282   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
   2283   ASSERT_EQ(2U, s[2]->InputCount());
   2284   ASSERT_EQ(1U, s[2]->OutputCount());
   2285   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
   2286   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
   2287   EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
   2288   ASSERT_EQ(1U, s[3]->InputCount());
   2289   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
   2290 }
   2291 
   2292 
   2293 TEST_F(InstructionSelectorTest, Int32DivWithParametersForSUDIV) {
   2294   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2295                   MachineType::Int32());
   2296   m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
   2297   Stream s = m.Build(SUDIV);
   2298   ASSERT_EQ(1U, s.size());
   2299   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
   2300 }
   2301 
   2302 
   2303 TEST_F(InstructionSelectorTest, Int32ModWithParameters) {
   2304   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2305                   MachineType::Int32());
   2306   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
   2307   Stream s = m.Build();
   2308   ASSERT_EQ(6U, s.size());
   2309   EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
   2310   ASSERT_EQ(1U, s[0]->OutputCount());
   2311   EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
   2312   ASSERT_EQ(1U, s[1]->OutputCount());
   2313   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
   2314   ASSERT_EQ(2U, s[2]->InputCount());
   2315   ASSERT_EQ(1U, s[2]->OutputCount());
   2316   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
   2317   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
   2318   EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
   2319   ASSERT_EQ(1U, s[3]->InputCount());
   2320   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
   2321   EXPECT_EQ(kArmMul, s[4]->arch_opcode());
   2322   ASSERT_EQ(1U, s[4]->OutputCount());
   2323   ASSERT_EQ(2U, s[4]->InputCount());
   2324   EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
   2325   EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
   2326   EXPECT_EQ(kArmSub, s[5]->arch_opcode());
   2327   ASSERT_EQ(1U, s[5]->OutputCount());
   2328   ASSERT_EQ(2U, s[5]->InputCount());
   2329   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
   2330   EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
   2331 }
   2332 
   2333 
   2334 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIV) {
   2335   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2336                   MachineType::Int32());
   2337   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
   2338   Stream s = m.Build(SUDIV);
   2339   ASSERT_EQ(3U, s.size());
   2340   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
   2341   ASSERT_EQ(1U, s[0]->OutputCount());
   2342   ASSERT_EQ(2U, s[0]->InputCount());
   2343   EXPECT_EQ(kArmMul, s[1]->arch_opcode());
   2344   ASSERT_EQ(1U, s[1]->OutputCount());
   2345   ASSERT_EQ(2U, s[1]->InputCount());
   2346   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
   2347   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
   2348   EXPECT_EQ(kArmSub, s[2]->arch_opcode());
   2349   ASSERT_EQ(1U, s[2]->OutputCount());
   2350   ASSERT_EQ(2U, s[2]->InputCount());
   2351   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
   2352   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
   2353 }
   2354 
   2355 
   2356 TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIVAndMLS) {
   2357   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2358                   MachineType::Int32());
   2359   m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
   2360   Stream s = m.Build(ARMv7, SUDIV);
   2361   ASSERT_EQ(2U, s.size());
   2362   EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
   2363   ASSERT_EQ(1U, s[0]->OutputCount());
   2364   ASSERT_EQ(2U, s[0]->InputCount());
   2365   EXPECT_EQ(kArmMls, s[1]->arch_opcode());
   2366   ASSERT_EQ(1U, s[1]->OutputCount());
   2367   ASSERT_EQ(3U, s[1]->InputCount());
   2368   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
   2369   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
   2370   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
   2371 }
   2372 
   2373 
   2374 TEST_F(InstructionSelectorTest, Int32MulWithParameters) {
   2375   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2376                   MachineType::Int32());
   2377   m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
   2378   Stream s = m.Build();
   2379   ASSERT_EQ(1U, s.size());
   2380   EXPECT_EQ(kArmMul, s[0]->arch_opcode());
   2381   EXPECT_EQ(2U, s[0]->InputCount());
   2382   EXPECT_EQ(1U, s[0]->OutputCount());
   2383 }
   2384 
   2385 
   2386 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
   2387   // x * (2^k + 1) -> x + (x >> k)
   2388   TRACED_FORRANGE(int32_t, k, 1, 30) {
   2389     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2390     m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
   2391     Stream s = m.Build();
   2392     ASSERT_EQ(1U, s.size());
   2393     EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
   2394     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
   2395     ASSERT_EQ(3U, s[0]->InputCount());
   2396     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
   2397     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
   2398     EXPECT_EQ(1U, s[0]->OutputCount());
   2399   }
   2400   // x * (2^k - 1) -> -x + (x >> k)
   2401   TRACED_FORRANGE(int32_t, k, 3, 30) {
   2402     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2403     m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
   2404     Stream s = m.Build();
   2405     ASSERT_EQ(1U, s.size());
   2406     EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
   2407     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
   2408     ASSERT_EQ(3U, s[0]->InputCount());
   2409     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
   2410     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
   2411     EXPECT_EQ(1U, s[0]->OutputCount());
   2412   }
   2413   // (2^k + 1) * x -> x + (x >> k)
   2414   TRACED_FORRANGE(int32_t, k, 1, 30) {
   2415     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2416     m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
   2417     Stream s = m.Build();
   2418     ASSERT_EQ(1U, s.size());
   2419     EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
   2420     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
   2421     ASSERT_EQ(3U, s[0]->InputCount());
   2422     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
   2423     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
   2424     EXPECT_EQ(1U, s[0]->OutputCount());
   2425   }
   2426   // x * (2^k - 1) -> -x + (x >> k)
   2427   TRACED_FORRANGE(int32_t, k, 3, 30) {
   2428     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2429     m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
   2430     Stream s = m.Build();
   2431     ASSERT_EQ(1U, s.size());
   2432     EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
   2433     EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
   2434     ASSERT_EQ(3U, s[0]->InputCount());
   2435     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
   2436     EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
   2437     EXPECT_EQ(1U, s[0]->OutputCount());
   2438   }
   2439 }
   2440 
   2441 
   2442 TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
   2443   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2444                   MachineType::Int32());
   2445   Node* const p0 = m.Parameter(0);
   2446   Node* const p1 = m.Parameter(1);
   2447   Node* const n = m.Int32MulHigh(p0, p1);
   2448   m.Return(n);
   2449   Stream s = m.Build();
   2450   ASSERT_EQ(1U, s.size());
   2451   EXPECT_EQ(kArmSmmul, s[0]->arch_opcode());
   2452   ASSERT_EQ(2U, s[0]->InputCount());
   2453   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2454   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   2455   ASSERT_EQ(1U, s[0]->OutputCount());
   2456   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   2457 }
   2458 
   2459 
   2460 TEST_F(InstructionSelectorTest, Uint32MulHighWithParameters) {
   2461   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
   2462                   MachineType::Uint32());
   2463   Node* const p0 = m.Parameter(0);
   2464   Node* const p1 = m.Parameter(1);
   2465   Node* const n = m.Uint32MulHigh(p0, p1);
   2466   m.Return(n);
   2467   Stream s = m.Build();
   2468   ASSERT_EQ(1U, s.size());
   2469   EXPECT_EQ(kArmUmull, s[0]->arch_opcode());
   2470   ASSERT_EQ(2U, s[0]->InputCount());
   2471   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2472   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   2473   ASSERT_EQ(2U, s[0]->OutputCount());
   2474   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->OutputAt(1)));
   2475 }
   2476 
   2477 
   2478 TEST_F(InstructionSelectorTest, Uint32DivWithParameters) {
   2479   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2480                   MachineType::Int32());
   2481   m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
   2482   Stream s = m.Build();
   2483   ASSERT_EQ(4U, s.size());
   2484   EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
   2485   ASSERT_EQ(1U, s[0]->OutputCount());
   2486   EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
   2487   ASSERT_EQ(1U, s[1]->OutputCount());
   2488   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
   2489   ASSERT_EQ(2U, s[2]->InputCount());
   2490   ASSERT_EQ(1U, s[2]->OutputCount());
   2491   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
   2492   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
   2493   EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
   2494   ASSERT_EQ(1U, s[3]->InputCount());
   2495   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
   2496 }
   2497 
   2498 
   2499 TEST_F(InstructionSelectorTest, Uint32DivWithParametersForSUDIV) {
   2500   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2501                   MachineType::Int32());
   2502   m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
   2503   Stream s = m.Build(SUDIV);
   2504   ASSERT_EQ(1U, s.size());
   2505   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
   2506 }
   2507 
   2508 
   2509 TEST_F(InstructionSelectorTest, Uint32ModWithParameters) {
   2510   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2511                   MachineType::Int32());
   2512   m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
   2513   Stream s = m.Build();
   2514   ASSERT_EQ(6U, s.size());
   2515   EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
   2516   ASSERT_EQ(1U, s[0]->OutputCount());
   2517   EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
   2518   ASSERT_EQ(1U, s[1]->OutputCount());
   2519   EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
   2520   ASSERT_EQ(2U, s[2]->InputCount());
   2521   ASSERT_EQ(1U, s[2]->OutputCount());
   2522   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
   2523   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
   2524   EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
   2525   ASSERT_EQ(1U, s[3]->InputCount());
   2526   EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
   2527   EXPECT_EQ(kArmMul, s[4]->arch_opcode());
   2528   ASSERT_EQ(1U, s[4]->OutputCount());
   2529   ASSERT_EQ(2U, s[4]->InputCount());
   2530   EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
   2531   EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
   2532   EXPECT_EQ(kArmSub, s[5]->arch_opcode());
   2533   ASSERT_EQ(1U, s[5]->OutputCount());
   2534   ASSERT_EQ(2U, s[5]->InputCount());
   2535   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
   2536   EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
   2537 }
   2538 
   2539 
   2540 TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIV) {
   2541   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2542                   MachineType::Int32());
   2543   m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
   2544   Stream s = m.Build(SUDIV);
   2545   ASSERT_EQ(3U, s.size());
   2546   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
   2547   ASSERT_EQ(1U, s[0]->OutputCount());
   2548   ASSERT_EQ(2U, s[0]->InputCount());
   2549   EXPECT_EQ(kArmMul, s[1]->arch_opcode());
   2550   ASSERT_EQ(1U, s[1]->OutputCount());
   2551   ASSERT_EQ(2U, s[1]->InputCount());
   2552   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
   2553   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
   2554   EXPECT_EQ(kArmSub, s[2]->arch_opcode());
   2555   ASSERT_EQ(1U, s[2]->OutputCount());
   2556   ASSERT_EQ(2U, s[2]->InputCount());
   2557   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
   2558   EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
   2559 }
   2560 
   2561 
   2562 TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIVAndMLS) {
   2563   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2564                   MachineType::Int32());
   2565   m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
   2566   Stream s = m.Build(ARMv7, SUDIV);
   2567   ASSERT_EQ(2U, s.size());
   2568   EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
   2569   ASSERT_EQ(1U, s[0]->OutputCount());
   2570   ASSERT_EQ(2U, s[0]->InputCount());
   2571   EXPECT_EQ(kArmMls, s[1]->arch_opcode());
   2572   ASSERT_EQ(1U, s[1]->OutputCount());
   2573   ASSERT_EQ(3U, s[1]->InputCount());
   2574   EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
   2575   EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
   2576   EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
   2577 }
   2578 
   2579 
   2580 TEST_F(InstructionSelectorTest, Word32ShlWord32SarForSbfx) {
   2581   TRACED_FORRANGE(int32_t, shl, 1, 31) {
   2582     TRACED_FORRANGE(int32_t, sar, shl, 31) {
   2583       if ((shl == sar) && (sar == 16)) continue;  // Sxth.
   2584       if ((shl == sar) && (sar == 24)) continue;  // Sxtb.
   2585       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2586       m.Return(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(shl)),
   2587                            m.Int32Constant(sar)));
   2588       Stream s = m.Build(ARMv7);
   2589       ASSERT_EQ(1U, s.size());
   2590       EXPECT_EQ(kArmSbfx, s[0]->arch_opcode());
   2591       ASSERT_EQ(3U, s[0]->InputCount());
   2592       EXPECT_EQ(sar - shl, s.ToInt32(s[0]->InputAt(1)));
   2593       EXPECT_EQ(32 - sar, s.ToInt32(s[0]->InputAt(2)));
   2594     }
   2595   }
   2596 }
   2597 
   2598 
   2599 TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
   2600   TRACED_FORRANGE(int32_t, width, 9, 23) {
   2601     if (width == 16) continue;  // Uxth.
   2602     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2603     m.Return(m.Word32And(m.Parameter(0),
   2604                          m.Int32Constant(0xffffffffu >> (32 - width))));
   2605     Stream s = m.Build(ARMv7);
   2606     ASSERT_EQ(1U, s.size());
   2607     EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
   2608     ASSERT_EQ(3U, s[0]->InputCount());
   2609     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
   2610     EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2611   }
   2612   TRACED_FORRANGE(int32_t, width, 9, 23) {
   2613     if (width == 16) continue;  // Uxth.
   2614     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2615     m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
   2616                          m.Parameter(0)));
   2617     Stream s = m.Build(ARMv7);
   2618     ASSERT_EQ(1U, s.size());
   2619     EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
   2620     ASSERT_EQ(3U, s[0]->InputCount());
   2621     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
   2622     EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2623   }
   2624 }
   2625 
   2626 
   2627 TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
   2628   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
   2629     TRACED_FORRANGE(int32_t, width, 9, (24 - lsb) - 1) {
   2630       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2631       m.Return(m.Word32And(
   2632           m.Parameter(0),
   2633           m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb))));
   2634       Stream s = m.Build(ARMv7);
   2635       ASSERT_EQ(1U, s.size());
   2636       EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
   2637       ASSERT_EQ(1U, s[0]->OutputCount());
   2638       EXPECT_TRUE(
   2639           UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   2640       ASSERT_EQ(3U, s[0]->InputCount());
   2641       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
   2642       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2643     }
   2644   }
   2645   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
   2646     TRACED_FORRANGE(int32_t, width, 9, (24 - lsb) - 1) {
   2647       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2648       m.Return(
   2649           m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),
   2650                       m.Parameter(0)));
   2651       Stream s = m.Build(ARMv7);
   2652       ASSERT_EQ(1U, s.size());
   2653       EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
   2654       ASSERT_EQ(1U, s[0]->OutputCount());
   2655       EXPECT_TRUE(
   2656           UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
   2657       ASSERT_EQ(3U, s[0]->InputCount());
   2658       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
   2659       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2660     }
   2661   }
   2662 }
   2663 
   2664 
   2665 TEST_F(InstructionSelectorTest, Word32AndWith0xffff) {
   2666   {
   2667     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2668     Node* const p0 = m.Parameter(0);
   2669     Node* const r = m.Word32And(p0, m.Int32Constant(0xffff));
   2670     m.Return(r);
   2671     Stream s = m.Build();
   2672     ASSERT_EQ(1U, s.size());
   2673     EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
   2674     ASSERT_EQ(2U, s[0]->InputCount());
   2675     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2676     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
   2677     ASSERT_EQ(1U, s[0]->OutputCount());
   2678     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2679   }
   2680   {
   2681     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2682     Node* const p0 = m.Parameter(0);
   2683     Node* const r = m.Word32And(m.Int32Constant(0xffff), p0);
   2684     m.Return(r);
   2685     Stream s = m.Build();
   2686     ASSERT_EQ(1U, s.size());
   2687     EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
   2688     ASSERT_EQ(2U, s[0]->InputCount());
   2689     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2690     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
   2691     ASSERT_EQ(1U, s[0]->OutputCount());
   2692     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2693   }
   2694 }
   2695 
   2696 
   2697 TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
   2698   {
   2699     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2700     Node* const p0 = m.Parameter(0);
   2701     Node* const r =
   2702         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24));
   2703     m.Return(r);
   2704     Stream s = m.Build();
   2705     ASSERT_EQ(1U, s.size());
   2706     EXPECT_EQ(kArmSxtb, s[0]->arch_opcode());
   2707     ASSERT_EQ(2U, s[0]->InputCount());
   2708     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2709     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
   2710     ASSERT_EQ(1U, s[0]->OutputCount());
   2711     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2712   }
   2713   {
   2714     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2715     Node* const p0 = m.Parameter(0);
   2716     Node* const r =
   2717         m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16));
   2718     m.Return(r);
   2719     Stream s = m.Build();
   2720     ASSERT_EQ(1U, s.size());
   2721     EXPECT_EQ(kArmSxth, s[0]->arch_opcode());
   2722     ASSERT_EQ(2U, s[0]->InputCount());
   2723     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2724     EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
   2725     ASSERT_EQ(1U, s[0]->OutputCount());
   2726     EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
   2727   }
   2728 }
   2729 
   2730 
   2731 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediateForARMv7) {
   2732   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
   2733     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
   2734       uint32_t max = 1 << lsb;
   2735       if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
   2736       uint32_t jnk = rng()->NextInt(max);
   2737       uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
   2738       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2739       m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
   2740                            m.Int32Constant(lsb)));
   2741       Stream s = m.Build(ARMv7);
   2742       ASSERT_EQ(1U, s.size());
   2743       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
   2744       ASSERT_EQ(3U, s[0]->InputCount());
   2745       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
   2746       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2747     }
   2748   }
   2749   TRACED_FORRANGE(int32_t, lsb, 0, 31) {
   2750     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
   2751       uint32_t max = 1 << lsb;
   2752       if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
   2753       uint32_t jnk = rng()->NextInt(max);
   2754       uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
   2755       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2756       m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
   2757                            m.Int32Constant(lsb)));
   2758       Stream s = m.Build(ARMv7);
   2759       ASSERT_EQ(1U, s.size());
   2760       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
   2761       ASSERT_EQ(3U, s[0]->InputCount());
   2762       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
   2763       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2764     }
   2765   }
   2766 }
   2767 
   2768 
   2769 TEST_F(InstructionSelectorTest, Word32AndWithWord32Not) {
   2770   {
   2771     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2772                     MachineType::Int32());
   2773     m.Return(m.Word32And(m.Parameter(0), m.Word32Not(m.Parameter(1))));
   2774     Stream s = m.Build();
   2775     ASSERT_EQ(1U, s.size());
   2776     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
   2777     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   2778     EXPECT_EQ(2U, s[0]->InputCount());
   2779     EXPECT_EQ(1U, s[0]->OutputCount());
   2780   }
   2781   {
   2782     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2783                     MachineType::Int32());
   2784     m.Return(m.Word32And(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
   2785     Stream s = m.Build();
   2786     ASSERT_EQ(1U, s.size());
   2787     EXPECT_EQ(kArmBic, s[0]->arch_opcode());
   2788     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   2789     EXPECT_EQ(2U, s[0]->InputCount());
   2790     EXPECT_EQ(1U, s[0]->OutputCount());
   2791   }
   2792 }
   2793 
   2794 
   2795 TEST_F(InstructionSelectorTest, Word32EqualWithParameters) {
   2796   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
   2797                   MachineType::Int32());
   2798   m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
   2799   Stream s = m.Build();
   2800   ASSERT_EQ(1U, s.size());
   2801   EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   2802   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   2803   EXPECT_EQ(2U, s[0]->InputCount());
   2804   EXPECT_EQ(1U, s[0]->OutputCount());
   2805   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   2806   EXPECT_EQ(kEqual, s[0]->flags_condition());
   2807 }
   2808 
   2809 
   2810 TEST_F(InstructionSelectorTest, Word32EqualWithImmediate) {
   2811   TRACED_FOREACH(int32_t, imm, kImmediates) {
   2812     if (imm == 0) continue;
   2813     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2814     m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
   2815     Stream s = m.Build();
   2816     ASSERT_EQ(1U, s.size());
   2817     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   2818     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
   2819     ASSERT_EQ(2U, s[0]->InputCount());
   2820     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
   2821     EXPECT_EQ(1U, s[0]->OutputCount());
   2822     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   2823     EXPECT_EQ(kEqual, s[0]->flags_condition());
   2824   }
   2825   TRACED_FOREACH(int32_t, imm, kImmediates) {
   2826     if (imm == 0) continue;
   2827     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2828     m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
   2829     Stream s = m.Build();
   2830     ASSERT_EQ(1U, s.size());
   2831     EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
   2832     EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
   2833     ASSERT_EQ(2U, s[0]->InputCount());
   2834     EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
   2835     EXPECT_EQ(1U, s[0]->OutputCount());
   2836     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   2837     EXPECT_EQ(kEqual, s[0]->flags_condition());
   2838   }
   2839 }
   2840 
   2841 
   2842 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
   2843   {
   2844     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2845     m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
   2846     Stream s = m.Build();
   2847     ASSERT_EQ(1U, s.size());
   2848     EXPECT_EQ(kArmTst, s[0]->arch_opcode());
   2849     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   2850     ASSERT_EQ(2U, s[0]->InputCount());
   2851     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
   2852     EXPECT_EQ(1U, s[0]->OutputCount());
   2853     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   2854     EXPECT_EQ(kEqual, s[0]->flags_condition());
   2855   }
   2856   {
   2857     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2858     m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
   2859     Stream s = m.Build();
   2860     ASSERT_EQ(1U, s.size());
   2861     EXPECT_EQ(kArmTst, s[0]->arch_opcode());
   2862     EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   2863     ASSERT_EQ(2U, s[0]->InputCount());
   2864     EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
   2865     EXPECT_EQ(1U, s[0]->OutputCount());
   2866     EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   2867     EXPECT_EQ(kEqual, s[0]->flags_condition());
   2868   }
   2869 }
   2870 
   2871 
   2872 TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
   2873   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2874   m.Return(m.Word32Not(m.Parameter(0)));
   2875   Stream s = m.Build();
   2876   ASSERT_EQ(1U, s.size());
   2877   EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
   2878   EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
   2879   EXPECT_EQ(1U, s[0]->InputCount());
   2880   EXPECT_EQ(1U, s[0]->OutputCount());
   2881 }
   2882 
   2883 
   2884 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) {
   2885   TRACED_FORRANGE(int32_t, lsb, 1, 31) {
   2886     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
   2887       if (((width == 8) || (width == 16)) &&
   2888           ((lsb == 8) || (lsb == 16) || (lsb == 24)))
   2889         continue;  // Uxtb/h ror.
   2890       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2891       m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
   2892                            m.Int32Constant(0xffffffffu >> (32 - width))));
   2893       Stream s = m.Build(ARMv7);
   2894       ASSERT_EQ(1U, s.size());
   2895       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
   2896       ASSERT_EQ(3U, s[0]->InputCount());
   2897       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
   2898       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2899     }
   2900   }
   2901   TRACED_FORRANGE(int32_t, lsb, 1, 31) {
   2902     TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
   2903       if (((width == 8) || (width == 16)) &&
   2904           ((lsb == 8) || (lsb == 16) || (lsb == 24)))
   2905         continue;  // Uxtb/h ror.
   2906       StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2907       m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
   2908                            m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
   2909       Stream s = m.Build(ARMv7);
   2910       ASSERT_EQ(1U, s.size());
   2911       EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
   2912       ASSERT_EQ(3U, s[0]->InputCount());
   2913       EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
   2914       EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
   2915     }
   2916   }
   2917 }
   2918 
   2919 
   2920 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrAnd0xff) {
   2921   TRACED_FORRANGE(int32_t, shr, 1, 3) {
   2922     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2923     Node* const p0 = m.Parameter(0);
   2924     Node* const r = m.Word32And(m.Word32Shr(p0, m.Int32Constant(shr * 8)),
   2925                                 m.Int32Constant(0xff));
   2926     m.Return(r);
   2927     Stream s = m.Build();
   2928     ASSERT_EQ(1U, s.size());
   2929     EXPECT_EQ(kArmUxtb, s[0]->arch_opcode());
   2930     ASSERT_EQ(2U, s[0]->InputCount());
   2931     EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1)));
   2932   }
   2933   TRACED_FORRANGE(int32_t, shr, 1, 3) {
   2934     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2935     Node* const p0 = m.Parameter(0);
   2936     Node* const r = m.Word32And(m.Int32Constant(0xff),
   2937                                 m.Word32Shr(p0, m.Int32Constant(shr * 8)));
   2938     m.Return(r);
   2939     Stream s = m.Build();
   2940     ASSERT_EQ(1U, s.size());
   2941     EXPECT_EQ(kArmUxtb, s[0]->arch_opcode());
   2942     ASSERT_EQ(2U, s[0]->InputCount());
   2943     EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1)));
   2944   }
   2945 }
   2946 
   2947 
   2948 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrAnd0xffff) {
   2949   TRACED_FORRANGE(int32_t, shr, 1, 3) {
   2950     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2951     Node* const p0 = m.Parameter(0);
   2952     Node* const r = m.Word32And(m.Word32Shr(p0, m.Int32Constant(shr * 8)),
   2953                                 m.Int32Constant(0xffff));
   2954     m.Return(r);
   2955     Stream s = m.Build();
   2956     ASSERT_EQ(1U, s.size());
   2957     EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
   2958     ASSERT_EQ(2U, s[0]->InputCount());
   2959     EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1)));
   2960   }
   2961   TRACED_FORRANGE(int32_t, shr, 1, 3) {
   2962     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   2963     Node* const p0 = m.Parameter(0);
   2964     Node* const r = m.Word32And(m.Int32Constant(0xffff),
   2965                                 m.Word32Shr(p0, m.Int32Constant(shr * 8)));
   2966     m.Return(r);
   2967     Stream s = m.Build();
   2968     ASSERT_EQ(1U, s.size());
   2969     EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
   2970     ASSERT_EQ(2U, s[0]->InputCount());
   2971     EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1)));
   2972   }
   2973 }
   2974 
   2975 
   2976 TEST_F(InstructionSelectorTest, Word32Clz) {
   2977   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32());
   2978   Node* const p0 = m.Parameter(0);
   2979   Node* const n = m.Word32Clz(p0);
   2980   m.Return(n);
   2981   Stream s = m.Build();
   2982   ASSERT_EQ(1U, s.size());
   2983   EXPECT_EQ(kArmClz, s[0]->arch_opcode());
   2984   ASSERT_EQ(1U, s[0]->InputCount());
   2985   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   2986   ASSERT_EQ(1U, s[0]->OutputCount());
   2987   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   2988 }
   2989 
   2990 TEST_F(InstructionSelectorTest, Float32Max) {
   2991   StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(),
   2992                   MachineType::Float32());
   2993   Node* const p0 = m.Parameter(0);
   2994   Node* const p1 = m.Parameter(1);
   2995   Node* const n = m.Float32Max(p0, p1);
   2996   m.Return(n);
   2997   Stream s = m.Build(ARMv8);
   2998   // Float32Max is `(b < a) ? a : b`.
   2999   ASSERT_EQ(1U, s.size());
   3000   EXPECT_EQ(kArmFloat32Max, s[0]->arch_opcode());
   3001   ASSERT_EQ(2U, s[0]->InputCount());
   3002   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   3003   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   3004   ASSERT_EQ(1U, s[0]->OutputCount());
   3005   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   3006 }
   3007 
   3008 TEST_F(InstructionSelectorTest, Float32Min) {
   3009   StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(),
   3010                   MachineType::Float32());
   3011   Node* const p0 = m.Parameter(0);
   3012   Node* const p1 = m.Parameter(1);
   3013   Node* const n = m.Float32Min(p0, p1);
   3014   m.Return(n);
   3015   Stream s = m.Build(ARMv8);
   3016   // Float32Min is `(a < b) ? a : b`.
   3017   ASSERT_EQ(1U, s.size());
   3018   EXPECT_EQ(kArmFloat32Min, s[0]->arch_opcode());
   3019   ASSERT_EQ(2U, s[0]->InputCount());
   3020   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   3021   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   3022   ASSERT_EQ(1U, s[0]->OutputCount());
   3023   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   3024 }
   3025 
   3026 TEST_F(InstructionSelectorTest, Float64Max) {
   3027   StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
   3028                   MachineType::Float64());
   3029   Node* const p0 = m.Parameter(0);
   3030   Node* const p1 = m.Parameter(1);
   3031   Node* const n = m.Float64Max(p0, p1);
   3032   m.Return(n);
   3033   Stream s = m.Build(ARMv8);
   3034   // Float64Max is `(b < a) ? a : b`.
   3035   ASSERT_EQ(1U, s.size());
   3036   EXPECT_EQ(kArmFloat64Max, s[0]->arch_opcode());
   3037   ASSERT_EQ(2U, s[0]->InputCount());
   3038   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   3039   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   3040   ASSERT_EQ(1U, s[0]->OutputCount());
   3041   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   3042 }
   3043 
   3044 TEST_F(InstructionSelectorTest, Float64Min) {
   3045   StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
   3046                   MachineType::Float64());
   3047   Node* const p0 = m.Parameter(0);
   3048   Node* const p1 = m.Parameter(1);
   3049   Node* const n = m.Float64Min(p0, p1);
   3050   m.Return(n);
   3051   Stream s = m.Build(ARMv8);
   3052   // Float64Min is `(a < b) ? a : b`.
   3053   ASSERT_EQ(1U, s.size());
   3054   EXPECT_EQ(kArmFloat64Min, s[0]->arch_opcode());
   3055   ASSERT_EQ(2U, s[0]->InputCount());
   3056   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   3057   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
   3058   ASSERT_EQ(1U, s[0]->OutputCount());
   3059   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   3060 }
   3061 
   3062 TEST_F(InstructionSelectorTest, Float32Neg) {
   3063   StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   3064   Node* const p0 = m.Parameter(0);
   3065   // Don't use m.Float32Neg() as that generates an explicit sub.
   3066   Node* const n = m.AddNode(m.machine()->Float32Neg().op(), m.Parameter(0));
   3067   m.Return(n);
   3068   Stream s = m.Build();
   3069   ASSERT_EQ(1U, s.size());
   3070   EXPECT_EQ(kArmVnegF32, s[0]->arch_opcode());
   3071   ASSERT_EQ(1U, s[0]->InputCount());
   3072   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   3073   ASSERT_EQ(1U, s[0]->OutputCount());
   3074   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   3075 }
   3076 
   3077 TEST_F(InstructionSelectorTest, Float64Neg) {
   3078   StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   3079   Node* const p0 = m.Parameter(0);
   3080   // Don't use m.Float64Neg() as that generates an explicit sub.
   3081   Node* const n = m.AddNode(m.machine()->Float64Neg().op(), m.Parameter(0));
   3082   m.Return(n);
   3083   Stream s = m.Build();
   3084   ASSERT_EQ(1U, s.size());
   3085   EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode());
   3086   ASSERT_EQ(1U, s[0]->InputCount());
   3087   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   3088   ASSERT_EQ(1U, s[0]->OutputCount());
   3089   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   3090 }
   3091 
   3092 }  // namespace compiler
   3093 }  // namespace internal
   3094 }  // namespace v8
   3095