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 |