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