Home | History | Annotate | Download | only in x64
      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 "test/unittests/compiler/instruction-selector-unittest.h"
      6 
      7 #include "src/compiler/node-matchers.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 namespace compiler {
     12 
     13 // -----------------------------------------------------------------------------
     14 // Conversions.
     15 
     16 
     17 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
     18   StreamBuilder m(this, MachineType::Float32(), MachineType::Float64());
     19   m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
     20   Stream s = m.Build();
     21   ASSERT_EQ(1U, s.size());
     22   EXPECT_EQ(kSSEFloat32ToFloat64, s[0]->arch_opcode());
     23   EXPECT_EQ(1U, s[0]->InputCount());
     24   EXPECT_EQ(1U, s[0]->OutputCount());
     25 }
     26 
     27 
     28 TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithParameter) {
     29   StreamBuilder m(this, MachineType::Int64(), MachineType::Int32());
     30   m.Return(m.ChangeInt32ToInt64(m.Parameter(0)));
     31   Stream s = m.Build();
     32   ASSERT_EQ(1U, s.size());
     33   EXPECT_EQ(kX64Movsxlq, s[0]->arch_opcode());
     34 }
     35 
     36 
     37 TEST_F(InstructionSelectorTest, ChangeUint32ToFloat64WithParameter) {
     38   StreamBuilder m(this, MachineType::Float64(), MachineType::Uint32());
     39   m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
     40   Stream s = m.Build();
     41   ASSERT_EQ(1U, s.size());
     42   EXPECT_EQ(kSSEUint32ToFloat64, s[0]->arch_opcode());
     43 }
     44 
     45 
     46 TEST_F(InstructionSelectorTest, ChangeUint32ToUint64WithParameter) {
     47   StreamBuilder m(this, MachineType::Uint64(), MachineType::Uint32());
     48   m.Return(m.ChangeUint32ToUint64(m.Parameter(0)));
     49   Stream s = m.Build();
     50   ASSERT_EQ(1U, s.size());
     51   EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
     52 }
     53 
     54 
     55 TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) {
     56   StreamBuilder m(this, MachineType::Float64(), MachineType::Float32());
     57   m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
     58   Stream s = m.Build();
     59   ASSERT_EQ(1U, s.size());
     60   EXPECT_EQ(kSSEFloat64ToFloat32, s[0]->arch_opcode());
     61   EXPECT_EQ(1U, s[0]->InputCount());
     62   EXPECT_EQ(1U, s[0]->OutputCount());
     63 }
     64 
     65 
     66 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) {
     67   StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
     68   m.Return(m.TruncateInt64ToInt32(m.Parameter(0)));
     69   Stream s = m.Build();
     70   ASSERT_EQ(1U, s.size());
     71   EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
     72 }
     73 
     74 
     75 // -----------------------------------------------------------------------------
     76 // Loads and stores
     77 
     78 
     79 namespace {
     80 
     81 struct MemoryAccess {
     82   MachineType type;
     83   ArchOpcode load_opcode;
     84   ArchOpcode store_opcode;
     85 };
     86 
     87 
     88 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
     89   return os << memacc.type;
     90 }
     91 
     92 
     93 static const MemoryAccess kMemoryAccesses[] = {
     94     {MachineType::Int8(), kX64Movsxbl, kX64Movb},
     95     {MachineType::Uint8(), kX64Movzxbl, kX64Movb},
     96     {MachineType::Int16(), kX64Movsxwl, kX64Movw},
     97     {MachineType::Uint16(), kX64Movzxwl, kX64Movw},
     98     {MachineType::Int32(), kX64Movl, kX64Movl},
     99     {MachineType::Uint32(), kX64Movl, kX64Movl},
    100     {MachineType::Int64(), kX64Movq, kX64Movq},
    101     {MachineType::Uint64(), kX64Movq, kX64Movq},
    102     {MachineType::Float32(), kX64Movss, kX64Movss},
    103     {MachineType::Float64(), kX64Movsd, kX64Movsd}};
    104 
    105 }  // namespace
    106 
    107 
    108 typedef InstructionSelectorTestWithParam<MemoryAccess>
    109     InstructionSelectorMemoryAccessTest;
    110 
    111 
    112 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
    113   const MemoryAccess memacc = GetParam();
    114   StreamBuilder m(this, memacc.type, MachineType::Pointer(),
    115                   MachineType::Int32());
    116   m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
    117   Stream s = m.Build();
    118   ASSERT_EQ(1U, s.size());
    119   EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
    120   EXPECT_EQ(2U, s[0]->InputCount());
    121   EXPECT_EQ(1U, s[0]->OutputCount());
    122 }
    123 
    124 
    125 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
    126   const MemoryAccess memacc = GetParam();
    127   StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
    128                   MachineType::Int32(), memacc.type);
    129   m.Store(memacc.type.representation(), m.Parameter(0), m.Parameter(1),
    130           m.Parameter(2), kNoWriteBarrier);
    131   m.Return(m.Int32Constant(0));
    132   Stream s = m.Build();
    133   ASSERT_EQ(1U, s.size());
    134   EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
    135   EXPECT_EQ(3U, s[0]->InputCount());
    136   EXPECT_EQ(0U, s[0]->OutputCount());
    137 }
    138 
    139 
    140 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
    141                         InstructionSelectorMemoryAccessTest,
    142                         ::testing::ValuesIn(kMemoryAccesses));
    143 
    144 
    145 // -----------------------------------------------------------------------------
    146 // ChangeUint32ToUint64.
    147 
    148 
    149 namespace {
    150 
    151 typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
    152 
    153 
    154 struct BinaryOperation {
    155   Constructor constructor;
    156   const char* constructor_name;
    157 };
    158 
    159 
    160 std::ostream& operator<<(std::ostream& os, const BinaryOperation& bop) {
    161   return os << bop.constructor_name;
    162 }
    163 
    164 
    165 const BinaryOperation kWord32BinaryOperations[] = {
    166     {&RawMachineAssembler::Word32And, "Word32And"},
    167     {&RawMachineAssembler::Word32Or, "Word32Or"},
    168     {&RawMachineAssembler::Word32Xor, "Word32Xor"},
    169     {&RawMachineAssembler::Word32Shl, "Word32Shl"},
    170     {&RawMachineAssembler::Word32Shr, "Word32Shr"},
    171     {&RawMachineAssembler::Word32Sar, "Word32Sar"},
    172     {&RawMachineAssembler::Word32Ror, "Word32Ror"},
    173     {&RawMachineAssembler::Word32Equal, "Word32Equal"},
    174     {&RawMachineAssembler::Int32Add, "Int32Add"},
    175     {&RawMachineAssembler::Int32Sub, "Int32Sub"},
    176     {&RawMachineAssembler::Int32Mul, "Int32Mul"},
    177     {&RawMachineAssembler::Int32MulHigh, "Int32MulHigh"},
    178     {&RawMachineAssembler::Int32Div, "Int32Div"},
    179     {&RawMachineAssembler::Int32LessThan, "Int32LessThan"},
    180     {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual"},
    181     {&RawMachineAssembler::Int32Mod, "Int32Mod"},
    182     {&RawMachineAssembler::Uint32Div, "Uint32Div"},
    183     {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan"},
    184     {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual"},
    185     {&RawMachineAssembler::Uint32Mod, "Uint32Mod"}};
    186 
    187 }  // namespace
    188 
    189 
    190 typedef InstructionSelectorTestWithParam<BinaryOperation>
    191     InstructionSelectorChangeUint32ToUint64Test;
    192 
    193 
    194 TEST_P(InstructionSelectorChangeUint32ToUint64Test, ChangeUint32ToUint64) {
    195   const BinaryOperation& bop = GetParam();
    196   StreamBuilder m(this, MachineType::Uint64(), MachineType::Int32(),
    197                   MachineType::Int32());
    198   Node* const p0 = m.Parameter(0);
    199   Node* const p1 = m.Parameter(1);
    200   m.Return(m.ChangeUint32ToUint64((m.*bop.constructor)(p0, p1)));
    201   Stream s = m.Build();
    202   ASSERT_EQ(1U, s.size());
    203 }
    204 
    205 
    206 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
    207                         InstructionSelectorChangeUint32ToUint64Test,
    208                         ::testing::ValuesIn(kWord32BinaryOperations));
    209 
    210 
    211 // -----------------------------------------------------------------------------
    212 // TruncateInt64ToInt32.
    213 
    214 
    215 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) {
    216   StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
    217   Node* const p = m.Parameter(0);
    218   Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32)));
    219   m.Return(t);
    220   Stream s = m.Build();
    221   ASSERT_EQ(1U, s.size());
    222   EXPECT_EQ(kX64Shr, s[0]->arch_opcode());
    223   ASSERT_EQ(2U, s[0]->InputCount());
    224   EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
    225   EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(1)));
    226   ASSERT_EQ(1U, s[0]->OutputCount());
    227   EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0)));
    228   EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
    229 }
    230 
    231 
    232 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) {
    233   StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
    234   Node* const p = m.Parameter(0);
    235   Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(32)));
    236   m.Return(t);
    237   Stream s = m.Build();
    238   ASSERT_EQ(1U, s.size());
    239   EXPECT_EQ(kX64Shr, s[0]->arch_opcode());
    240   ASSERT_EQ(2U, s[0]->InputCount());
    241   EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
    242   EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(1)));
    243   ASSERT_EQ(1U, s[0]->OutputCount());
    244   EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0)));
    245   EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
    246 }
    247 
    248 
    249 // -----------------------------------------------------------------------------
    250 // Addition.
    251 
    252 
    253 TEST_F(InstructionSelectorTest, Int32AddWithInt32ParametersLea) {
    254   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    255                   MachineType::Int32());
    256   Node* const p0 = m.Parameter(0);
    257   Node* const p1 = m.Parameter(1);
    258   Node* const a0 = m.Int32Add(p0, p1);
    259   // Additional uses of input to add chooses lea
    260   Node* const a1 = m.Int32Div(p0, p1);
    261   m.Return(m.Int32Div(a0, a1));
    262   Stream s = m.Build();
    263   ASSERT_EQ(3U, s.size());
    264   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    265   ASSERT_EQ(2U, s[0]->InputCount());
    266   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    267   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    268 }
    269 
    270 
    271 TEST_F(InstructionSelectorTest, Int32AddConstantAsLeaSingle) {
    272   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    273   Node* const p0 = m.Parameter(0);
    274   Node* const c0 = m.Int32Constant(15);
    275   // If one of the add's operands is only used once, use an "leal", even though
    276   // an "addl" could be used. The "leal" has proven faster--out best guess is
    277   // that it gives the register allocation more freedom and it doesn't set
    278   // flags, reducing pressure in the CPU's pipeline. If we're lucky with
    279   // register allocation, then code generation will select an "addl" later for
    280   // the cases that have been measured to be faster.
    281   Node* const v0 = m.Int32Add(p0, c0);
    282   m.Return(v0);
    283   Stream s = m.Build();
    284   ASSERT_EQ(1U, s.size());
    285   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    286   EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
    287   ASSERT_EQ(2U, s[0]->InputCount());
    288   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    289   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
    290 }
    291 
    292 
    293 TEST_F(InstructionSelectorTest, Int32AddConstantAsAdd) {
    294   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    295   Node* const p0 = m.Parameter(0);
    296   Node* const c0 = m.Int32Constant(1);
    297   // If there is only a single use of an add's input and the immediate constant
    298   // for the add is 1, don't use an inc. It is much slower on modern Intel
    299   // architectures.
    300   m.Return(m.Int32Add(p0, c0));
    301   Stream s = m.Build();
    302   ASSERT_EQ(1U, s.size());
    303   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    304   EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
    305   ASSERT_EQ(2U, s[0]->InputCount());
    306   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    307   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
    308 }
    309 
    310 
    311 TEST_F(InstructionSelectorTest, Int32AddConstantAsLeaDouble) {
    312   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    313   Node* const p0 = m.Parameter(0);
    314   Node* const c0 = m.Int32Constant(15);
    315   // A second use of an add's input uses lea
    316   Node* const a0 = m.Int32Add(p0, c0);
    317   m.Return(m.Int32Div(a0, p0));
    318   Stream s = m.Build();
    319   ASSERT_EQ(2U, s.size());
    320   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    321   EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
    322   ASSERT_EQ(2U, s[0]->InputCount());
    323   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    324   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
    325 }
    326 
    327 
    328 TEST_F(InstructionSelectorTest, Int32AddCommutedConstantAsLeaSingle) {
    329   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    330   Node* const p0 = m.Parameter(0);
    331   Node* const c0 = m.Int32Constant(15);
    332   // If one of the add's operands is only used once, use an "leal", even though
    333   // an "addl" could be used. The "leal" has proven faster--out best guess is
    334   // that it gives the register allocation more freedom and it doesn't set
    335   // flags, reducing pressure in the CPU's pipeline. If we're lucky with
    336   // register allocation, then code generation will select an "addl" later for
    337   // the cases that have been measured to be faster.
    338   m.Return(m.Int32Add(c0, p0));
    339   Stream s = m.Build();
    340   ASSERT_EQ(1U, s.size());
    341   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    342   EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
    343   ASSERT_EQ(2U, s[0]->InputCount());
    344   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    345   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
    346 }
    347 
    348 
    349 TEST_F(InstructionSelectorTest, Int32AddCommutedConstantAsLeaDouble) {
    350   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    351   Node* const p0 = m.Parameter(0);
    352   Node* const c0 = m.Int32Constant(15);
    353   // A second use of an add's input uses lea
    354   Node* const a0 = m.Int32Add(c0, p0);
    355   USE(a0);
    356   m.Return(m.Int32Div(a0, p0));
    357   Stream s = m.Build();
    358   ASSERT_EQ(2U, s.size());
    359   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    360   EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
    361   ASSERT_EQ(2U, s[0]->InputCount());
    362   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    363   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
    364 }
    365 
    366 
    367 TEST_F(InstructionSelectorTest, Int32AddSimpleAsAdd) {
    368   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    369                   MachineType::Int32());
    370   Node* const p0 = m.Parameter(0);
    371   Node* const p1 = m.Parameter(1);
    372   // If one of the add's operands is only used once, use an "leal", even though
    373   // an "addl" could be used. The "leal" has proven faster--out best guess is
    374   // that it gives the register allocation more freedom and it doesn't set
    375   // flags, reducing pressure in the CPU's pipeline. If we're lucky with
    376   // register allocation, then code generation will select an "addl" later for
    377   // the cases that have been measured to be faster.
    378   m.Return(m.Int32Add(p0, p1));
    379   Stream s = m.Build();
    380   ASSERT_EQ(1U, s.size());
    381   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    382   EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
    383   ASSERT_EQ(2U, s[0]->InputCount());
    384   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    385   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    386 }
    387 
    388 
    389 TEST_F(InstructionSelectorTest, Int32AddSimpleAsLea) {
    390   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    391                   MachineType::Int32());
    392   Node* const p0 = m.Parameter(0);
    393   Node* const p1 = m.Parameter(1);
    394   // If all of of the add's operands are used multiple times, use an "leal".
    395   Node* const v1 = m.Int32Add(p0, p1);
    396   m.Return(m.Int32Add(m.Int32Add(v1, p1), p0));
    397   Stream s = m.Build();
    398   ASSERT_EQ(3U, s.size());
    399   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    400   EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
    401   ASSERT_EQ(2U, s[0]->InputCount());
    402   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    403   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    404 }
    405 
    406 
    407 TEST_F(InstructionSelectorTest, Int32AddScaled2Mul) {
    408   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    409                   MachineType::Int32());
    410   Node* const p0 = m.Parameter(0);
    411   Node* const p1 = m.Parameter(1);
    412   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    413   m.Return(m.Int32Add(p0, s0));
    414   Stream s = m.Build();
    415   ASSERT_EQ(1U, s.size());
    416   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    417   EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
    418   ASSERT_EQ(2U, s[0]->InputCount());
    419   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    420   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    421 }
    422 
    423 
    424 TEST_F(InstructionSelectorTest, Int32AddCommutedScaled2Mul) {
    425   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    426                   MachineType::Int32());
    427   Node* const p0 = m.Parameter(0);
    428   Node* const p1 = m.Parameter(1);
    429   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    430   m.Return(m.Int32Add(s0, p0));
    431   Stream s = m.Build();
    432   ASSERT_EQ(1U, s.size());
    433   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    434   EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
    435   ASSERT_EQ(2U, s[0]->InputCount());
    436   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    437   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    438 }
    439 
    440 
    441 TEST_F(InstructionSelectorTest, Int32AddScaled2Shl) {
    442   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    443                   MachineType::Int32());
    444   Node* const p0 = m.Parameter(0);
    445   Node* const p1 = m.Parameter(1);
    446   Node* const s0 = m.Word32Shl(p1, m.Int32Constant(1));
    447   m.Return(m.Int32Add(p0, s0));
    448   Stream s = m.Build();
    449   ASSERT_EQ(1U, s.size());
    450   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    451   EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
    452   ASSERT_EQ(2U, s[0]->InputCount());
    453   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    454   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    455 }
    456 
    457 
    458 TEST_F(InstructionSelectorTest, Int32AddCommutedScaled2Shl) {
    459   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    460                   MachineType::Int32());
    461   Node* const p0 = m.Parameter(0);
    462   Node* const p1 = m.Parameter(1);
    463   Node* const s0 = m.Word32Shl(p1, m.Int32Constant(1));
    464   m.Return(m.Int32Add(s0, p0));
    465   Stream s = m.Build();
    466   ASSERT_EQ(1U, s.size());
    467   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    468   EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
    469   ASSERT_EQ(2U, s[0]->InputCount());
    470   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    471   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    472 }
    473 
    474 
    475 TEST_F(InstructionSelectorTest, Int32AddScaled4Mul) {
    476   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    477                   MachineType::Int32());
    478   Node* const p0 = m.Parameter(0);
    479   Node* const p1 = m.Parameter(1);
    480   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(4));
    481   m.Return(m.Int32Add(p0, s0));
    482   Stream s = m.Build();
    483   ASSERT_EQ(1U, s.size());
    484   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    485   EXPECT_EQ(kMode_MR4, s[0]->addressing_mode());
    486   ASSERT_EQ(2U, s[0]->InputCount());
    487   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    488   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    489 }
    490 
    491 
    492 TEST_F(InstructionSelectorTest, Int32AddScaled4Shl) {
    493   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    494                   MachineType::Int32());
    495   Node* const p0 = m.Parameter(0);
    496   Node* const p1 = m.Parameter(1);
    497   Node* const s0 = m.Word32Shl(p1, m.Int32Constant(2));
    498   m.Return(m.Int32Add(p0, s0));
    499   Stream s = m.Build();
    500   ASSERT_EQ(1U, s.size());
    501   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    502   EXPECT_EQ(kMode_MR4, s[0]->addressing_mode());
    503   ASSERT_EQ(2U, s[0]->InputCount());
    504   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    505   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    506 }
    507 
    508 
    509 TEST_F(InstructionSelectorTest, Int32AddScaled8Mul) {
    510   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    511                   MachineType::Int32());
    512   Node* const p0 = m.Parameter(0);
    513   Node* const p1 = m.Parameter(1);
    514   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(8));
    515   m.Return(m.Int32Add(p0, s0));
    516   Stream s = m.Build();
    517   ASSERT_EQ(1U, s.size());
    518   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    519   EXPECT_EQ(kMode_MR8, s[0]->addressing_mode());
    520   ASSERT_EQ(2U, s[0]->InputCount());
    521   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    522   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    523 }
    524 
    525 
    526 TEST_F(InstructionSelectorTest, Int32AddScaled8Shl) {
    527   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    528                   MachineType::Int32());
    529   Node* const p0 = m.Parameter(0);
    530   Node* const p1 = m.Parameter(1);
    531   Node* const s0 = m.Word32Shl(p1, m.Int32Constant(3));
    532   m.Return(m.Int32Add(p0, s0));
    533   Stream s = m.Build();
    534   ASSERT_EQ(1U, s.size());
    535   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    536   EXPECT_EQ(kMode_MR8, s[0]->addressing_mode());
    537   ASSERT_EQ(2U, s[0]->InputCount());
    538   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    539   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    540 }
    541 
    542 
    543 TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstant) {
    544   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    545                   MachineType::Int32());
    546   Node* const p0 = m.Parameter(0);
    547   Node* const p1 = m.Parameter(1);
    548   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    549   Node* const c0 = m.Int32Constant(15);
    550   m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
    551   Stream s = m.Build();
    552   ASSERT_EQ(1U, s.size());
    553   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    554   EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
    555   ASSERT_EQ(3U, s[0]->InputCount());
    556   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    557   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    558   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    559 }
    560 
    561 
    562 TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle1) {
    563   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    564                   MachineType::Int32());
    565   Node* const p0 = m.Parameter(0);
    566   Node* const p1 = m.Parameter(1);
    567   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    568   Node* const c0 = m.Int32Constant(15);
    569   m.Return(m.Int32Add(p0, m.Int32Add(s0, c0)));
    570   Stream s = m.Build();
    571   ASSERT_EQ(1U, s.size());
    572   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    573   EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
    574   ASSERT_EQ(3U, s[0]->InputCount());
    575   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    576   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    577   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    578 }
    579 
    580 
    581 TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle2) {
    582   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    583                   MachineType::Int32());
    584   Node* const p0 = m.Parameter(0);
    585   Node* const p1 = m.Parameter(1);
    586   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    587   Node* const c0 = m.Int32Constant(15);
    588   m.Return(m.Int32Add(s0, m.Int32Add(c0, p0)));
    589   Stream s = m.Build();
    590   ASSERT_EQ(1U, s.size());
    591   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    592   EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
    593   ASSERT_EQ(3U, s[0]->InputCount());
    594   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    595   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    596   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    597 }
    598 
    599 
    600 TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle3) {
    601   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    602                   MachineType::Int32());
    603   Node* const p0 = m.Parameter(0);
    604   Node* const p1 = m.Parameter(1);
    605   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    606   Node* const c0 = m.Int32Constant(15);
    607   m.Return(m.Int32Add(m.Int32Add(s0, c0), p0));
    608   Stream s = m.Build();
    609   ASSERT_EQ(1U, s.size());
    610   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    611   EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
    612   ASSERT_EQ(3U, s[0]->InputCount());
    613   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    614   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    615   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    616 }
    617 
    618 
    619 TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle4) {
    620   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    621                   MachineType::Int32());
    622   Node* const p0 = m.Parameter(0);
    623   Node* const p1 = m.Parameter(1);
    624   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    625   Node* const c0 = m.Int32Constant(15);
    626   m.Return(m.Int32Add(m.Int32Add(c0, p0), s0));
    627   Stream s = m.Build();
    628   ASSERT_EQ(1U, s.size());
    629   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    630   EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
    631   ASSERT_EQ(3U, s[0]->InputCount());
    632   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    633   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    634   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    635 }
    636 
    637 
    638 TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle5) {
    639   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    640                   MachineType::Int32());
    641   Node* const p0 = m.Parameter(0);
    642   Node* const p1 = m.Parameter(1);
    643   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    644   Node* const c0 = m.Int32Constant(15);
    645   m.Return(m.Int32Add(m.Int32Add(p0, s0), c0));
    646   Stream s = m.Build();
    647   ASSERT_EQ(1U, s.size());
    648   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    649   EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
    650   ASSERT_EQ(3U, s[0]->InputCount());
    651   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    652   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    653   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    654 }
    655 
    656 
    657 TEST_F(InstructionSelectorTest, Int32AddScaled2ShlWithConstant) {
    658   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    659                   MachineType::Int32());
    660   Node* const p0 = m.Parameter(0);
    661   Node* const p1 = m.Parameter(1);
    662   Node* const s0 = m.Word32Shl(p1, m.Int32Constant(1));
    663   Node* const c0 = m.Int32Constant(15);
    664   m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
    665   Stream s = m.Build();
    666   ASSERT_EQ(1U, s.size());
    667   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    668   EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
    669   ASSERT_EQ(3U, s[0]->InputCount());
    670   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    671   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    672   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    673 }
    674 
    675 
    676 TEST_F(InstructionSelectorTest, Int32AddScaled4MulWithConstant) {
    677   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    678                   MachineType::Int32());
    679   Node* const p0 = m.Parameter(0);
    680   Node* const p1 = m.Parameter(1);
    681   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(4));
    682   Node* const c0 = m.Int32Constant(15);
    683   m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
    684   Stream s = m.Build();
    685   ASSERT_EQ(1U, s.size());
    686   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    687   EXPECT_EQ(kMode_MR4I, s[0]->addressing_mode());
    688   ASSERT_EQ(3U, s[0]->InputCount());
    689   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    690   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    691   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    692 }
    693 
    694 
    695 TEST_F(InstructionSelectorTest, Int32AddScaled4ShlWithConstant) {
    696   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    697                   MachineType::Int32());
    698   Node* const p0 = m.Parameter(0);
    699   Node* const p1 = m.Parameter(1);
    700   Node* const s0 = m.Word32Shl(p1, m.Int32Constant(2));
    701   Node* const c0 = m.Int32Constant(15);
    702   m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
    703   Stream s = m.Build();
    704   ASSERT_EQ(1U, s.size());
    705   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    706   EXPECT_EQ(kMode_MR4I, s[0]->addressing_mode());
    707   ASSERT_EQ(3U, s[0]->InputCount());
    708   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    709   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    710   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    711 }
    712 
    713 
    714 TEST_F(InstructionSelectorTest, Int32AddScaled8MulWithConstant) {
    715   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    716                   MachineType::Int32());
    717   Node* const p0 = m.Parameter(0);
    718   Node* const p1 = m.Parameter(1);
    719   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(8));
    720   Node* const c0 = m.Int32Constant(15);
    721   m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
    722   Stream s = m.Build();
    723   ASSERT_EQ(1U, s.size());
    724   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    725   EXPECT_EQ(kMode_MR8I, s[0]->addressing_mode());
    726   ASSERT_EQ(3U, s[0]->InputCount());
    727   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    728   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    729   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    730 }
    731 
    732 
    733 TEST_F(InstructionSelectorTest, Int32AddScaled8ShlWithConstant) {
    734   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    735                   MachineType::Int32());
    736   Node* const p0 = m.Parameter(0);
    737   Node* const p1 = m.Parameter(1);
    738   Node* const s0 = m.Word32Shl(p1, m.Int32Constant(3));
    739   Node* const c0 = m.Int32Constant(15);
    740   m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
    741   Stream s = m.Build();
    742   ASSERT_EQ(1U, s.size());
    743   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    744   EXPECT_EQ(kMode_MR8I, s[0]->addressing_mode());
    745   ASSERT_EQ(3U, s[0]->InputCount());
    746   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    747   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    748   EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
    749 }
    750 
    751 
    752 TEST_F(InstructionSelectorTest, Int32SubConstantAsSub) {
    753   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    754   Node* const p0 = m.Parameter(0);
    755   Node* const c0 = m.Int32Constant(-1);
    756   // If there is only a single use of on of the sub's non-constant input, use a
    757   // "subl" instruction.
    758   m.Return(m.Int32Sub(p0, c0));
    759   Stream s = m.Build();
    760   ASSERT_EQ(1U, s.size());
    761   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    762   EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
    763   ASSERT_EQ(2U, s[0]->InputCount());
    764   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    765   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
    766 }
    767 
    768 
    769 TEST_F(InstructionSelectorTest, Int32SubConstantAsLea) {
    770   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
    771   Node* const p0 = m.Parameter(0);
    772   Node* const c0 = m.Int32Constant(-1);
    773   // If there are multiple uses of on of the sub's non-constant input, use a
    774   // "leal" instruction.
    775   Node* const v0 = m.Int32Sub(p0, c0);
    776   m.Return(m.Int32Div(p0, v0));
    777   Stream s = m.Build();
    778   ASSERT_EQ(2U, s.size());
    779   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    780   EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
    781   ASSERT_EQ(2U, s[0]->InputCount());
    782   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    783   EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
    784 }
    785 
    786 
    787 TEST_F(InstructionSelectorTest, Int32AddScaled2Other) {
    788   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    789                   MachineType::Int32(), MachineType::Int32());
    790   Node* const p0 = m.Parameter(0);
    791   Node* const p1 = m.Parameter(1);
    792   Node* const p2 = m.Parameter(2);
    793   Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
    794   Node* const a0 = m.Int32Add(s0, p2);
    795   Node* const a1 = m.Int32Add(p0, a0);
    796   m.Return(a1);
    797   Stream s = m.Build();
    798   ASSERT_EQ(2U, s.size());
    799   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    800   EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
    801   ASSERT_EQ(2U, s[0]->InputCount());
    802   EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0)));
    803   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    804   EXPECT_EQ(s.ToVreg(a0), s.ToVreg(s[0]->OutputAt(0)));
    805   ASSERT_EQ(2U, s[1]->InputCount());
    806   EXPECT_EQ(kX64Lea32, s[1]->arch_opcode());
    807   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[1]->InputAt(0)));
    808   EXPECT_EQ(s.ToVreg(a0), s.ToVreg(s[1]->InputAt(1)));
    809   EXPECT_EQ(s.ToVreg(a1), s.ToVreg(s[1]->OutputAt(0)));
    810 }
    811 
    812 
    813 // -----------------------------------------------------------------------------
    814 // Multiplication.
    815 
    816 
    817 TEST_F(InstructionSelectorTest, Int32MulWithInt32MulWithParameters) {
    818   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    819                   MachineType::Int32());
    820   Node* const p0 = m.Parameter(0);
    821   Node* const p1 = m.Parameter(1);
    822   Node* const m0 = m.Int32Mul(p0, p1);
    823   m.Return(m.Int32Mul(m0, p0));
    824   Stream s = m.Build();
    825   ASSERT_EQ(2U, s.size());
    826   EXPECT_EQ(kX64Imul32, s[0]->arch_opcode());
    827   ASSERT_EQ(2U, s[0]->InputCount());
    828   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
    829   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
    830   ASSERT_EQ(1U, s[0]->OutputCount());
    831   EXPECT_EQ(s.ToVreg(m0), s.ToVreg(s[0]->OutputAt(0)));
    832   EXPECT_EQ(kX64Imul32, s[1]->arch_opcode());
    833   ASSERT_EQ(2U, s[1]->InputCount());
    834   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[1]->InputAt(0)));
    835   EXPECT_EQ(s.ToVreg(m0), s.ToVreg(s[1]->InputAt(1)));
    836 }
    837 
    838 
    839 TEST_F(InstructionSelectorTest, Int32MulHigh) {
    840   StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
    841                   MachineType::Int32());
    842   Node* const p0 = m.Parameter(0);
    843   Node* const p1 = m.Parameter(1);
    844   Node* const n = m.Int32MulHigh(p0, p1);
    845   m.Return(n);
    846   Stream s = m.Build();
    847   ASSERT_EQ(1U, s.size());
    848   EXPECT_EQ(kX64ImulHigh32, s[0]->arch_opcode());
    849   ASSERT_EQ(2U, s[0]->InputCount());
    850   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    851   EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax));
    852   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    853   EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
    854   ASSERT_LE(1U, s[0]->OutputCount());
    855   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
    856   EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx));
    857 }
    858 
    859 
    860 TEST_F(InstructionSelectorTest, Uint32MulHigh) {
    861   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    862                   MachineType::Uint32());
    863   Node* const p0 = m.Parameter(0);
    864   Node* const p1 = m.Parameter(1);
    865   Node* const n = m.Uint32MulHigh(p0, p1);
    866   m.Return(n);
    867   Stream s = m.Build();
    868   ASSERT_EQ(1U, s.size());
    869   EXPECT_EQ(kX64UmulHigh32, s[0]->arch_opcode());
    870   ASSERT_EQ(2U, s[0]->InputCount());
    871   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    872   EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax));
    873   EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
    874   EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
    875   ASSERT_LE(1U, s[0]->OutputCount());
    876   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
    877   EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx));
    878 }
    879 
    880 
    881 TEST_F(InstructionSelectorTest, Int32Mul2BecomesLea) {
    882   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    883                   MachineType::Uint32());
    884   Node* const p0 = m.Parameter(0);
    885   Node* const c1 = m.Int32Constant(2);
    886   Node* const n = m.Int32Mul(p0, c1);
    887   m.Return(n);
    888   Stream s = m.Build();
    889   ASSERT_EQ(1U, s.size());
    890   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    891   EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
    892   ASSERT_EQ(2U, s[0]->InputCount());
    893   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    894   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
    895 }
    896 
    897 
    898 TEST_F(InstructionSelectorTest, Int32Mul3BecomesLea) {
    899   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    900                   MachineType::Uint32());
    901   Node* const p0 = m.Parameter(0);
    902   Node* const c1 = m.Int32Constant(3);
    903   Node* const n = m.Int32Mul(p0, c1);
    904   m.Return(n);
    905   Stream s = m.Build();
    906   ASSERT_EQ(1U, s.size());
    907   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    908   EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
    909   ASSERT_EQ(2U, s[0]->InputCount());
    910   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    911   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
    912 }
    913 
    914 
    915 TEST_F(InstructionSelectorTest, Int32Mul4BecomesLea) {
    916   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    917                   MachineType::Uint32());
    918   Node* const p0 = m.Parameter(0);
    919   Node* const c1 = m.Int32Constant(4);
    920   Node* const n = m.Int32Mul(p0, c1);
    921   m.Return(n);
    922   Stream s = m.Build();
    923   ASSERT_EQ(1U, s.size());
    924   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    925   EXPECT_EQ(kMode_M4, s[0]->addressing_mode());
    926   ASSERT_EQ(1U, s[0]->InputCount());
    927   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    928 }
    929 
    930 
    931 TEST_F(InstructionSelectorTest, Int32Mul5BecomesLea) {
    932   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    933                   MachineType::Uint32());
    934   Node* const p0 = m.Parameter(0);
    935   Node* const c1 = m.Int32Constant(5);
    936   Node* const n = m.Int32Mul(p0, c1);
    937   m.Return(n);
    938   Stream s = m.Build();
    939   ASSERT_EQ(1U, s.size());
    940   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    941   EXPECT_EQ(kMode_MR4, s[0]->addressing_mode());
    942   ASSERT_EQ(2U, s[0]->InputCount());
    943   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    944   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
    945 }
    946 
    947 
    948 TEST_F(InstructionSelectorTest, Int32Mul8BecomesLea) {
    949   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    950                   MachineType::Uint32());
    951   Node* const p0 = m.Parameter(0);
    952   Node* const c1 = m.Int32Constant(8);
    953   Node* const n = m.Int32Mul(p0, c1);
    954   m.Return(n);
    955   Stream s = m.Build();
    956   ASSERT_EQ(1U, s.size());
    957   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    958   EXPECT_EQ(kMode_M8, s[0]->addressing_mode());
    959   ASSERT_EQ(1U, s[0]->InputCount());
    960   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    961 }
    962 
    963 
    964 TEST_F(InstructionSelectorTest, Int32Mul9BecomesLea) {
    965   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    966                   MachineType::Uint32());
    967   Node* const p0 = m.Parameter(0);
    968   Node* const c1 = m.Int32Constant(9);
    969   Node* const n = m.Int32Mul(p0, c1);
    970   m.Return(n);
    971   Stream s = m.Build();
    972   ASSERT_EQ(1U, s.size());
    973   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    974   EXPECT_EQ(kMode_MR8, s[0]->addressing_mode());
    975   ASSERT_EQ(2U, s[0]->InputCount());
    976   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    977   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
    978 }
    979 
    980 
    981 // -----------------------------------------------------------------------------
    982 // Word32Shl.
    983 
    984 
    985 TEST_F(InstructionSelectorTest, Int32Shl1BecomesLea) {
    986   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
    987                   MachineType::Uint32());
    988   Node* const p0 = m.Parameter(0);
    989   Node* const c1 = m.Int32Constant(1);
    990   Node* const n = m.Word32Shl(p0, c1);
    991   m.Return(n);
    992   Stream s = m.Build();
    993   ASSERT_EQ(1U, s.size());
    994   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
    995   EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
    996   ASSERT_EQ(2U, s[0]->InputCount());
    997   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
    998   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
    999 }
   1000 
   1001 
   1002 TEST_F(InstructionSelectorTest, Int32Shl2BecomesLea) {
   1003   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
   1004                   MachineType::Uint32());
   1005   Node* const p0 = m.Parameter(0);
   1006   Node* const c1 = m.Int32Constant(2);
   1007   Node* const n = m.Word32Shl(p0, c1);
   1008   m.Return(n);
   1009   Stream s = m.Build();
   1010   ASSERT_EQ(1U, s.size());
   1011   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
   1012   EXPECT_EQ(kMode_M4, s[0]->addressing_mode());
   1013   ASSERT_EQ(1U, s[0]->InputCount());
   1014   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1015 }
   1016 
   1017 
   1018 TEST_F(InstructionSelectorTest, Int32Shl4BecomesLea) {
   1019   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32(),
   1020                   MachineType::Uint32());
   1021   Node* const p0 = m.Parameter(0);
   1022   Node* const c1 = m.Int32Constant(3);
   1023   Node* const n = m.Word32Shl(p0, c1);
   1024   m.Return(n);
   1025   Stream s = m.Build();
   1026   ASSERT_EQ(1U, s.size());
   1027   EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
   1028   EXPECT_EQ(kMode_M8, s[0]->addressing_mode());
   1029   ASSERT_EQ(1U, s[0]->InputCount());
   1030   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1031 }
   1032 
   1033 
   1034 // -----------------------------------------------------------------------------
   1035 // Floating point operations.
   1036 
   1037 
   1038 TEST_F(InstructionSelectorTest, Float32Abs) {
   1039   {
   1040     StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   1041     Node* const p0 = m.Parameter(0);
   1042     Node* const n = m.Float32Abs(p0);
   1043     m.Return(n);
   1044     Stream s = m.Build();
   1045     ASSERT_EQ(1U, s.size());
   1046     EXPECT_EQ(kSSEFloat32Abs, s[0]->arch_opcode());
   1047     ASSERT_EQ(1U, s[0]->InputCount());
   1048     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1049     ASSERT_EQ(1U, s[0]->OutputCount());
   1050     EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
   1051     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1052     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1053   }
   1054   {
   1055     StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   1056     Node* const p0 = m.Parameter(0);
   1057     Node* const n = m.Float32Abs(p0);
   1058     m.Return(n);
   1059     Stream s = m.Build(AVX);
   1060     ASSERT_EQ(1U, s.size());
   1061     EXPECT_EQ(kAVXFloat32Abs, s[0]->arch_opcode());
   1062     ASSERT_EQ(1U, s[0]->InputCount());
   1063     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1064     ASSERT_EQ(1U, s[0]->OutputCount());
   1065     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1066     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1067   }
   1068 }
   1069 
   1070 
   1071 TEST_F(InstructionSelectorTest, Float64Abs) {
   1072   {
   1073     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   1074     Node* const p0 = m.Parameter(0);
   1075     Node* const n = m.Float64Abs(p0);
   1076     m.Return(n);
   1077     Stream s = m.Build();
   1078     ASSERT_EQ(1U, s.size());
   1079     EXPECT_EQ(kSSEFloat64Abs, s[0]->arch_opcode());
   1080     ASSERT_EQ(1U, s[0]->InputCount());
   1081     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1082     ASSERT_EQ(1U, s[0]->OutputCount());
   1083     EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
   1084     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1085     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1086   }
   1087   {
   1088     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   1089     Node* const p0 = m.Parameter(0);
   1090     Node* const n = m.Float64Abs(p0);
   1091     m.Return(n);
   1092     Stream s = m.Build(AVX);
   1093     ASSERT_EQ(1U, s.size());
   1094     EXPECT_EQ(kAVXFloat64Abs, s[0]->arch_opcode());
   1095     ASSERT_EQ(1U, s[0]->InputCount());
   1096     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1097     ASSERT_EQ(1U, s[0]->OutputCount());
   1098     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1099     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1100   }
   1101 }
   1102 
   1103 
   1104 TEST_F(InstructionSelectorTest, Float64BinopArithmetic) {
   1105   {
   1106     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
   1107                     MachineType::Float64());
   1108     Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1));
   1109     Node* mul = m.Float64Mul(add, m.Parameter(1));
   1110     Node* sub = m.Float64Sub(mul, add);
   1111     Node* ret = m.Float64Div(mul, sub);
   1112     m.Return(ret);
   1113     Stream s = m.Build(AVX);
   1114     ASSERT_EQ(4U, s.size());
   1115     EXPECT_EQ(kAVXFloat64Add, s[0]->arch_opcode());
   1116     EXPECT_EQ(kAVXFloat64Mul, s[1]->arch_opcode());
   1117     EXPECT_EQ(kAVXFloat64Sub, s[2]->arch_opcode());
   1118     EXPECT_EQ(kAVXFloat64Div, s[3]->arch_opcode());
   1119   }
   1120   {
   1121     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
   1122                     MachineType::Float64());
   1123     Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1));
   1124     Node* mul = m.Float64Mul(add, m.Parameter(1));
   1125     Node* sub = m.Float64Sub(mul, add);
   1126     Node* ret = m.Float64Div(mul, sub);
   1127     m.Return(ret);
   1128     Stream s = m.Build();
   1129     ASSERT_EQ(4U, s.size());
   1130     EXPECT_EQ(kSSEFloat64Add, s[0]->arch_opcode());
   1131     EXPECT_EQ(kSSEFloat64Mul, s[1]->arch_opcode());
   1132     EXPECT_EQ(kSSEFloat64Sub, s[2]->arch_opcode());
   1133     EXPECT_EQ(kSSEFloat64Div, s[3]->arch_opcode());
   1134   }
   1135 }
   1136 
   1137 
   1138 TEST_F(InstructionSelectorTest, Float32SubWithMinusZeroAndParameter) {
   1139   {
   1140     StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   1141     Node* const p0 = m.Parameter(0);
   1142     Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
   1143     m.Return(n);
   1144     Stream s = m.Build();
   1145     ASSERT_EQ(1U, s.size());
   1146     EXPECT_EQ(kSSEFloat32Neg, s[0]->arch_opcode());
   1147     ASSERT_EQ(1U, s[0]->InputCount());
   1148     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1149     ASSERT_EQ(1U, s[0]->OutputCount());
   1150     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1151     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1152   }
   1153   {
   1154     StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
   1155     Node* const p0 = m.Parameter(0);
   1156     Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0);
   1157     m.Return(n);
   1158     Stream s = m.Build(AVX);
   1159     ASSERT_EQ(1U, s.size());
   1160     EXPECT_EQ(kAVXFloat32Neg, s[0]->arch_opcode());
   1161     ASSERT_EQ(1U, s[0]->InputCount());
   1162     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1163     ASSERT_EQ(1U, s[0]->OutputCount());
   1164     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1165     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1166   }
   1167 }
   1168 
   1169 
   1170 TEST_F(InstructionSelectorTest, Float64SubWithMinusZeroAndParameter) {
   1171   {
   1172     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   1173     Node* const p0 = m.Parameter(0);
   1174     Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
   1175     m.Return(n);
   1176     Stream s = m.Build();
   1177     ASSERT_EQ(1U, s.size());
   1178     EXPECT_EQ(kSSEFloat64Neg, s[0]->arch_opcode());
   1179     ASSERT_EQ(1U, s[0]->InputCount());
   1180     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1181     ASSERT_EQ(1U, s[0]->OutputCount());
   1182     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1183     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1184   }
   1185   {
   1186     StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
   1187     Node* const p0 = m.Parameter(0);
   1188     Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
   1189     m.Return(n);
   1190     Stream s = m.Build(AVX);
   1191     ASSERT_EQ(1U, s.size());
   1192     EXPECT_EQ(kAVXFloat64Neg, s[0]->arch_opcode());
   1193     ASSERT_EQ(1U, s[0]->InputCount());
   1194     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1195     ASSERT_EQ(1U, s[0]->OutputCount());
   1196     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1197     EXPECT_EQ(kFlags_none, s[0]->flags_mode());
   1198   }
   1199 }
   1200 
   1201 
   1202 // -----------------------------------------------------------------------------
   1203 // Miscellaneous.
   1204 
   1205 
   1206 TEST_F(InstructionSelectorTest, Uint64LessThanWithLoadAndLoadStackPointer) {
   1207   StreamBuilder m(this, MachineType::Bool());
   1208   Node* const sl = m.Load(
   1209       MachineType::Pointer(),
   1210       m.ExternalConstant(ExternalReference::address_of_stack_limit(isolate())));
   1211   Node* const sp = m.LoadStackPointer();
   1212   Node* const n = m.Uint64LessThan(sl, sp);
   1213   m.Return(n);
   1214   Stream s = m.Build();
   1215   ASSERT_EQ(1U, s.size());
   1216   EXPECT_EQ(kX64StackCheck, s[0]->arch_opcode());
   1217   ASSERT_EQ(0U, s[0]->InputCount());
   1218   ASSERT_EQ(1U, s[0]->OutputCount());
   1219   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1220   EXPECT_EQ(kFlags_set, s[0]->flags_mode());
   1221   EXPECT_EQ(kUnsignedGreaterThan, s[0]->flags_condition());
   1222 }
   1223 
   1224 
   1225 TEST_F(InstructionSelectorTest, Word64ShlWithChangeInt32ToInt64) {
   1226   TRACED_FORRANGE(int64_t, x, 32, 63) {
   1227     StreamBuilder m(this, MachineType::Int64(), MachineType::Int32());
   1228     Node* const p0 = m.Parameter(0);
   1229     Node* const n = m.Word64Shl(m.ChangeInt32ToInt64(p0), m.Int64Constant(x));
   1230     m.Return(n);
   1231     Stream s = m.Build();
   1232     ASSERT_EQ(1U, s.size());
   1233     EXPECT_EQ(kX64Shl, s[0]->arch_opcode());
   1234     ASSERT_EQ(2U, s[0]->InputCount());
   1235     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1236     EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1)));
   1237     ASSERT_EQ(1U, s[0]->OutputCount());
   1238     EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
   1239     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1240   }
   1241 }
   1242 
   1243 
   1244 TEST_F(InstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) {
   1245   TRACED_FORRANGE(int64_t, x, 32, 63) {
   1246     StreamBuilder m(this, MachineType::Int64(), MachineType::Uint32());
   1247     Node* const p0 = m.Parameter(0);
   1248     Node* const n = m.Word64Shl(m.ChangeUint32ToUint64(p0), m.Int64Constant(x));
   1249     m.Return(n);
   1250     Stream s = m.Build();
   1251     ASSERT_EQ(1U, s.size());
   1252     EXPECT_EQ(kX64Shl, s[0]->arch_opcode());
   1253     ASSERT_EQ(2U, s[0]->InputCount());
   1254     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1255     EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1)));
   1256     ASSERT_EQ(1U, s[0]->OutputCount());
   1257     EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
   1258     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1259   }
   1260 }
   1261 
   1262 
   1263 TEST_F(InstructionSelectorTest, Word32AndWith0xff) {
   1264   {
   1265     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   1266     Node* const p0 = m.Parameter(0);
   1267     Node* const n = m.Word32And(p0, m.Int32Constant(0xff));
   1268     m.Return(n);
   1269     Stream s = m.Build();
   1270     ASSERT_EQ(1U, s.size());
   1271     EXPECT_EQ(kX64Movzxbl, s[0]->arch_opcode());
   1272     ASSERT_EQ(1U, s[0]->InputCount());
   1273     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1274     ASSERT_EQ(1U, s[0]->OutputCount());
   1275     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1276   }
   1277   {
   1278     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   1279     Node* const p0 = m.Parameter(0);
   1280     Node* const n = m.Word32And(m.Int32Constant(0xff), p0);
   1281     m.Return(n);
   1282     Stream s = m.Build();
   1283     ASSERT_EQ(1U, s.size());
   1284     EXPECT_EQ(kX64Movzxbl, s[0]->arch_opcode());
   1285     ASSERT_EQ(1U, s[0]->InputCount());
   1286     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1287     ASSERT_EQ(1U, s[0]->OutputCount());
   1288     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1289   }
   1290 }
   1291 
   1292 
   1293 TEST_F(InstructionSelectorTest, Word32AndWith0xffff) {
   1294   {
   1295     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   1296     Node* const p0 = m.Parameter(0);
   1297     Node* const n = m.Word32And(p0, m.Int32Constant(0xffff));
   1298     m.Return(n);
   1299     Stream s = m.Build();
   1300     ASSERT_EQ(1U, s.size());
   1301     EXPECT_EQ(kX64Movzxwl, s[0]->arch_opcode());
   1302     ASSERT_EQ(1U, s[0]->InputCount());
   1303     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1304     ASSERT_EQ(1U, s[0]->OutputCount());
   1305     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1306   }
   1307   {
   1308     StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
   1309     Node* const p0 = m.Parameter(0);
   1310     Node* const n = m.Word32And(m.Int32Constant(0xffff), p0);
   1311     m.Return(n);
   1312     Stream s = m.Build();
   1313     ASSERT_EQ(1U, s.size());
   1314     EXPECT_EQ(kX64Movzxwl, s[0]->arch_opcode());
   1315     ASSERT_EQ(1U, s[0]->InputCount());
   1316     EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1317     ASSERT_EQ(1U, s[0]->OutputCount());
   1318     EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1319   }
   1320 }
   1321 
   1322 
   1323 TEST_F(InstructionSelectorTest, Word32Clz) {
   1324   StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32());
   1325   Node* const p0 = m.Parameter(0);
   1326   Node* const n = m.Word32Clz(p0);
   1327   m.Return(n);
   1328   Stream s = m.Build();
   1329   ASSERT_EQ(1U, s.size());
   1330   EXPECT_EQ(kX64Lzcnt32, s[0]->arch_opcode());
   1331   ASSERT_EQ(1U, s[0]->InputCount());
   1332   EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
   1333   ASSERT_EQ(1U, s[0]->OutputCount());
   1334   EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
   1335 }
   1336 
   1337 }  // namespace compiler
   1338 }  // namespace internal
   1339 }  // namespace v8
   1340