Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(948)

Side by Side Diff: test/unittests/compiler/x64/instruction-selector-x64-unittest.cc

Issue 1513543003: [turbofan] Make MachineType a pair of enums. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moar rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/unittests/compiler/tail-call-optimization-unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
OLDNEW
« no previous file with comments | « test/unittests/compiler/tail-call-optimization-unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698