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

Side by Side Diff: test/unittests/compiler/arm64/instruction-selector-arm64-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
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 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace compiler { 9 namespace compiler {
10 10
(...skipping 25 matching lines...) Expand all
36 36
37 std::ostream& operator<<(std::ostream& os, const Shift& shift) { 37 std::ostream& operator<<(std::ostream& os, const Shift& shift) {
38 return os << shift.mi; 38 return os << shift.mi;
39 } 39 }
40 40
41 41
42 // Helper to build Int32Constant or Int64Constant depending on the given 42 // Helper to build Int32Constant or Int64Constant depending on the given
43 // machine type. 43 // machine type.
44 Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type, 44 Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type,
45 int64_t value) { 45 int64_t value) {
46 switch (type) { 46 switch (type.representation()) {
47 case kMachInt32: 47 case MachineRepresentation::kWord32:
48 return m.Int32Constant(static_cast<int32_t>(value)); 48 return m.Int32Constant(static_cast<int32_t>(value));
49 break; 49 break;
50 50
51 case kMachInt64: 51 case MachineRepresentation::kWord64:
52 return m.Int64Constant(value); 52 return m.Int64Constant(value);
53 break; 53 break;
54 54
55 default: 55 default:
56 UNIMPLEMENTED(); 56 UNIMPLEMENTED();
57 } 57 }
58 return NULL; 58 return NULL;
59 } 59 }
60 60
61 61
62 // ARM64 logical instructions. 62 // ARM64 logical instructions.
63 const MachInst2 kLogicalInstructions[] = { 63 const MachInst2 kLogicalInstructions[] = {
64 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32}, 64 {&RawMachineAssembler::Word32And, "Word32And", kArm64And32,
65 {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64}, 65 MachineType::Int32()},
66 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32}, 66 {&RawMachineAssembler::Word64And, "Word64And", kArm64And,
67 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64}, 67 MachineType::Int64()},
68 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eor32, kMachInt32}, 68 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32,
69 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eor, kMachInt64}}; 69 MachineType::Int32()},
70 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or,
71 MachineType::Int64()},
72 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eor32,
73 MachineType::Int32()},
74 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eor,
75 MachineType::Int64()}};
70 76
71 77
72 // ARM64 logical immediates: contiguous set bits, rotated about a power of two 78 // ARM64 logical immediates: contiguous set bits, rotated about a power of two
73 // sized block. The block is then duplicated across the word. Below is a random 79 // sized block. The block is then duplicated across the word. Below is a random
74 // subset of the 32-bit immediates. 80 // subset of the 32-bit immediates.
75 const uint32_t kLogical32Immediates[] = { 81 const uint32_t kLogical32Immediates[] = {
76 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0, 82 0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0,
77 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000, 83 0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000,
78 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000, 84 0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000,
79 0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000, 85 0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 ArchOpcode negate_arch_opcode; 129 ArchOpcode negate_arch_opcode;
124 }; 130 };
125 131
126 132
127 std::ostream& operator<<(std::ostream& os, const AddSub& op) { 133 std::ostream& operator<<(std::ostream& os, const AddSub& op) {
128 return os << op.mi; 134 return os << op.mi;
129 } 135 }
130 136
131 137
132 const AddSub kAddSubInstructions[] = { 138 const AddSub kAddSubInstructions[] = {
133 {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32}, 139 {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32,
140 MachineType::Int32()},
134 kArm64Sub32}, 141 kArm64Sub32},
135 {{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64}, 142 {{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add,
143 MachineType::Int64()},
136 kArm64Sub}, 144 kArm64Sub},
137 {{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32}, 145 {{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32,
146 MachineType::Int32()},
138 kArm64Add32}, 147 kArm64Add32},
139 {{&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}, 148 {{&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub,
149 MachineType::Int64()},
140 kArm64Add}}; 150 kArm64Add}};
141 151
142 152
143 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12. 153 // ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12.
144 // Below is a combination of a random subset and some edge values. 154 // Below is a combination of a random subset and some edge values.
145 const int32_t kAddSubImmediates[] = { 155 const int32_t kAddSubImmediates[] = {
146 0, 1, 69, 493, 599, 701, 719, 156 0, 1, 69, 493, 599, 701, 719,
147 768, 818, 842, 945, 1246, 1286, 1429, 157 768, 818, 842, 945, 1246, 1286, 1429,
148 1669, 2171, 2179, 2182, 2254, 2334, 2338, 158 1669, 2171, 2179, 2182, 2254, 2334, 2338,
149 2343, 2396, 2449, 2610, 2732, 2855, 2876, 159 2343, 2396, 2449, 2610, 2732, 2855, 2876,
150 2944, 3377, 3458, 3475, 3476, 3540, 3574, 160 2944, 3377, 3458, 3475, 3476, 3540, 3574,
151 3601, 3813, 3871, 3917, 4095, 4096, 16384, 161 3601, 3813, 3871, 3917, 4095, 4096, 16384,
152 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456, 162 364544, 462848, 970752, 1523712, 1863680, 2363392, 3219456,
153 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144, 163 3280896, 4247552, 4526080, 4575232, 4960256, 5505024, 5894144,
154 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224, 164 6004736, 6193152, 6385664, 6795264, 7114752, 7233536, 7348224,
155 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688, 165 7499776, 7573504, 7729152, 8634368, 8937472, 9465856, 10354688,
156 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224, 166 10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224,
157 15597568, 15892480, 16773120}; 167 15597568, 15892480, 16773120};
158 168
159 169
160 // ARM64 flag setting data processing instructions. 170 // ARM64 flag setting data processing instructions.
161 const MachInst2 kDPFlagSetInstructions[] = { 171 const MachInst2 kDPFlagSetInstructions[] = {
162 {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, kMachInt32}, 172 {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32,
163 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, kMachInt32}, 173 MachineType::Int32()},
164 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32}, 174 {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32,
165 {&RawMachineAssembler::Word64And, "Word64And", kArm64Tst, kMachInt64}}; 175 MachineType::Int32()},
176 {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32,
177 MachineType::Int32()},
178 {&RawMachineAssembler::Word64And, "Word64And", kArm64Tst,
179 MachineType::Int64()}};
166 180
167 181
168 // ARM64 arithmetic with overflow instructions. 182 // ARM64 arithmetic with overflow instructions.
169 const MachInst2 kOvfAddSubInstructions[] = { 183 const MachInst2 kOvfAddSubInstructions[] = {
170 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow", 184 {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
171 kArm64Add32, kMachInt32}, 185 kArm64Add32, MachineType::Int32()},
172 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow", 186 {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
173 kArm64Sub32, kMachInt32}}; 187 kArm64Sub32, MachineType::Int32()}};
174 188
175 189
176 // ARM64 shift instructions. 190 // ARM64 shift instructions.
177 const Shift kShiftInstructions[] = { 191 const Shift kShiftInstructions[] = {
178 {{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, kMachInt32}, 192 {{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32,
193 MachineType::Int32()},
179 kMode_Operand2_R_LSL_I}, 194 kMode_Operand2_R_LSL_I},
180 {{&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, kMachInt64}, 195 {{&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl,
196 MachineType::Int64()},
181 kMode_Operand2_R_LSL_I}, 197 kMode_Operand2_R_LSL_I},
182 {{&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32, kMachInt32}, 198 {{&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32,
199 MachineType::Int32()},
183 kMode_Operand2_R_LSR_I}, 200 kMode_Operand2_R_LSR_I},
184 {{&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr, kMachInt64}, 201 {{&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr,
202 MachineType::Int64()},
185 kMode_Operand2_R_LSR_I}, 203 kMode_Operand2_R_LSR_I},
186 {{&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32, kMachInt32}, 204 {{&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32,
205 MachineType::Int32()},
187 kMode_Operand2_R_ASR_I}, 206 kMode_Operand2_R_ASR_I},
188 {{&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr, kMachInt64}, 207 {{&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr,
208 MachineType::Int64()},
189 kMode_Operand2_R_ASR_I}, 209 kMode_Operand2_R_ASR_I},
190 {{&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32}, 210 {{&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32,
211 MachineType::Int32()},
191 kMode_Operand2_R_ROR_I}, 212 kMode_Operand2_R_ROR_I},
192 {{&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}, 213 {{&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror,
214 MachineType::Int64()},
193 kMode_Operand2_R_ROR_I}}; 215 kMode_Operand2_R_ROR_I}};
194 216
195 217
196 // ARM64 Mul/Div instructions. 218 // ARM64 Mul/Div instructions.
197 const MachInst2 kMulDivInstructions[] = { 219 const MachInst2 kMulDivInstructions[] = {
198 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32}, 220 {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32,
199 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64}, 221 MachineType::Int32()},
200 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32}, 222 {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul,
201 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64}, 223 MachineType::Int64()},
202 {&RawMachineAssembler::Uint32Div, "Uint32Div", kArm64Udiv32, kMachInt32}, 224 {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32,
203 {&RawMachineAssembler::Uint64Div, "Uint64Div", kArm64Udiv, kMachInt64}}; 225 MachineType::Int32()},
226 {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv,
227 MachineType::Int64()},
228 {&RawMachineAssembler::Uint32Div, "Uint32Div", kArm64Udiv32,
229 MachineType::Int32()},
230 {&RawMachineAssembler::Uint64Div, "Uint64Div", kArm64Udiv,
231 MachineType::Int64()}};
204 232
205 233
206 // ARM64 FP arithmetic instructions. 234 // ARM64 FP arithmetic instructions.
207 const MachInst2 kFPArithInstructions[] = { 235 const MachInst2 kFPArithInstructions[] = {
208 {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add, 236 {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add,
209 kMachFloat64}, 237 MachineType::Float64()},
210 {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub, 238 {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub,
211 kMachFloat64}, 239 MachineType::Float64()},
212 {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul, 240 {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul,
213 kMachFloat64}, 241 MachineType::Float64()},
214 {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div, 242 {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div,
215 kMachFloat64}}; 243 MachineType::Float64()}};
216 244
217 245
218 struct FPCmp { 246 struct FPCmp {
219 MachInst2 mi; 247 MachInst2 mi;
220 FlagsCondition cond; 248 FlagsCondition cond;
221 FlagsCondition commuted_cond; 249 FlagsCondition commuted_cond;
222 }; 250 };
223 251
224 252
225 std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) { 253 std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) {
226 return os << cmp.mi; 254 return os << cmp.mi;
227 } 255 }
228 256
229 257
230 // ARM64 FP comparison instructions. 258 // ARM64 FP comparison instructions.
231 const FPCmp kFPCmpInstructions[] = { 259 const FPCmp kFPCmpInstructions[] = {
232 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp, 260 {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp,
233 kMachFloat64}, 261 MachineType::Float64()},
234 kEqual, kEqual}, 262 kEqual,
263 kEqual},
235 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", 264 {{&RawMachineAssembler::Float64LessThan, "Float64LessThan",
236 kArm64Float64Cmp, kMachFloat64}, 265 kArm64Float64Cmp, MachineType::Float64()},
237 kFloatLessThan, kFloatGreaterThan}, 266 kFloatLessThan,
267 kFloatGreaterThan},
238 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual", 268 {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
239 kArm64Float64Cmp, kMachFloat64}, 269 kArm64Float64Cmp, MachineType::Float64()},
240 kFloatLessThanOrEqual, kFloatGreaterThanOrEqual}, 270 kFloatLessThanOrEqual,
271 kFloatGreaterThanOrEqual},
241 {{&RawMachineAssembler::Float32Equal, "Float32Equal", kArm64Float32Cmp, 272 {{&RawMachineAssembler::Float32Equal, "Float32Equal", kArm64Float32Cmp,
242 kMachFloat32}, 273 MachineType::Float32()},
243 kEqual, kEqual}, 274 kEqual,
275 kEqual},
244 {{&RawMachineAssembler::Float32LessThan, "Float32LessThan", 276 {{&RawMachineAssembler::Float32LessThan, "Float32LessThan",
245 kArm64Float32Cmp, kMachFloat32}, 277 kArm64Float32Cmp, MachineType::Float32()},
246 kFloatLessThan, kFloatGreaterThan}, 278 kFloatLessThan,
279 kFloatGreaterThan},
247 {{&RawMachineAssembler::Float32LessThanOrEqual, "Float32LessThanOrEqual", 280 {{&RawMachineAssembler::Float32LessThanOrEqual, "Float32LessThanOrEqual",
248 kArm64Float32Cmp, kMachFloat32}, 281 kArm64Float32Cmp, MachineType::Float32()},
249 kFloatLessThanOrEqual, kFloatGreaterThanOrEqual}}; 282 kFloatLessThanOrEqual,
283 kFloatGreaterThanOrEqual}};
250 284
251 285
252 struct Conversion { 286 struct Conversion {
253 // The machine_type field in MachInst1 represents the destination type. 287 // The machine_type field in MachInst1 represents the destination type.
254 MachInst1 mi; 288 MachInst1 mi;
255 MachineType src_machine_type; 289 MachineType src_machine_type;
256 }; 290 };
257 291
258 292
259 std::ostream& operator<<(std::ostream& os, const Conversion& conv) { 293 std::ostream& operator<<(std::ostream& os, const Conversion& conv) {
260 return os << conv.mi; 294 return os << conv.mi;
261 } 295 }
262 296
263 297
264 // ARM64 type conversion instructions. 298 // ARM64 type conversion instructions.
265 const Conversion kConversionInstructions[] = { 299 const Conversion kConversionInstructions[] = {
266 {{&RawMachineAssembler::ChangeFloat32ToFloat64, "ChangeFloat32ToFloat64", 300 {{&RawMachineAssembler::ChangeFloat32ToFloat64, "ChangeFloat32ToFloat64",
267 kArm64Float32ToFloat64, kMachFloat64}, 301 kArm64Float32ToFloat64, MachineType::Float64()},
268 kMachFloat32}, 302 MachineType::Float32()},
269 {{&RawMachineAssembler::TruncateFloat64ToFloat32, 303 {{&RawMachineAssembler::TruncateFloat64ToFloat32,
270 "TruncateFloat64ToFloat32", kArm64Float64ToFloat32, kMachFloat32}, 304 "TruncateFloat64ToFloat32", kArm64Float64ToFloat32,
271 kMachFloat64}, 305 MachineType::Float32()},
306 MachineType::Float64()},
272 {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64", 307 {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64",
273 kArm64Sxtw, kMachInt64}, 308 kArm64Sxtw, MachineType::Int64()},
274 kMachInt32}, 309 MachineType::Int32()},
275 {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64", 310 {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64",
276 kArm64Mov32, kMachUint64}, 311 kArm64Mov32, MachineType::Uint64()},
277 kMachUint32}, 312 MachineType::Uint32()},
278 {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32", 313 {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32",
279 kArm64Mov32, kMachInt32}, 314 kArm64Mov32, MachineType::Int32()},
280 kMachInt64}, 315 MachineType::Int64()},
281 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64", 316 {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
282 kArm64Int32ToFloat64, kMachFloat64}, 317 kArm64Int32ToFloat64, MachineType::Float64()},
283 kMachInt32}, 318 MachineType::Int32()},
284 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64", 319 {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
285 kArm64Uint32ToFloat64, kMachFloat64}, 320 kArm64Uint32ToFloat64, MachineType::Float64()},
286 kMachUint32}, 321 MachineType::Uint32()},
287 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32", 322 {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
288 kArm64Float64ToInt32, kMachInt32}, 323 kArm64Float64ToInt32, MachineType::Int32()},
289 kMachFloat64}, 324 MachineType::Float64()},
290 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32", 325 {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
291 kArm64Float64ToUint32, kMachUint32}, 326 kArm64Float64ToUint32, MachineType::Uint32()},
292 kMachFloat64}}; 327 MachineType::Float64()}};
293 328
294 } // namespace 329 } // namespace
295 330
296 331
297 // ----------------------------------------------------------------------------- 332 // -----------------------------------------------------------------------------
298 // Logical instructions. 333 // Logical instructions.
299 334
300 335
301 typedef InstructionSelectorTestWithParam<MachInst2> 336 typedef InstructionSelectorTestWithParam<MachInst2>
302 InstructionSelectorLogicalTest; 337 InstructionSelectorLogicalTest;
303 338
304 339
305 TEST_P(InstructionSelectorLogicalTest, Parameter) { 340 TEST_P(InstructionSelectorLogicalTest, Parameter) {
306 const MachInst2 dpi = GetParam(); 341 const MachInst2 dpi = GetParam();
307 const MachineType type = dpi.machine_type; 342 const MachineType type = dpi.machine_type;
308 StreamBuilder m(this, type, type, type); 343 StreamBuilder m(this, type, type, type);
309 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))); 344 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
310 Stream s = m.Build(); 345 Stream s = m.Build();
311 ASSERT_EQ(1U, s.size()); 346 ASSERT_EQ(1U, s.size());
312 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 347 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
313 EXPECT_EQ(2U, s[0]->InputCount()); 348 EXPECT_EQ(2U, s[0]->InputCount());
314 EXPECT_EQ(1U, s[0]->OutputCount()); 349 EXPECT_EQ(1U, s[0]->OutputCount());
315 } 350 }
316 351
317 352
318 TEST_P(InstructionSelectorLogicalTest, Immediate) { 353 TEST_P(InstructionSelectorLogicalTest, Immediate) {
319 const MachInst2 dpi = GetParam(); 354 const MachInst2 dpi = GetParam();
320 const MachineType type = dpi.machine_type; 355 const MachineType type = dpi.machine_type;
321 // TODO(all): Add support for testing 64-bit immediates. 356 // TODO(all): Add support for testing 64-bit immediates.
322 if (type == kMachInt32) { 357 if (type == MachineType::Int32()) {
323 // Immediate on the right. 358 // Immediate on the right.
324 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { 359 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
325 StreamBuilder m(this, type, type); 360 StreamBuilder m(this, type, type);
326 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))); 361 m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
327 Stream s = m.Build(); 362 Stream s = m.Build();
328 ASSERT_EQ(1U, s.size()); 363 ASSERT_EQ(1U, s.size());
329 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 364 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
330 ASSERT_EQ(2U, s[0]->InputCount()); 365 ASSERT_EQ(2U, s[0]->InputCount());
331 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 366 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
332 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 367 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
(...skipping 16 matching lines...) Expand all
349 } 384 }
350 385
351 386
352 TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) { 387 TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) {
353 const MachInst2 dpi = GetParam(); 388 const MachInst2 dpi = GetParam();
354 const MachineType type = dpi.machine_type; 389 const MachineType type = dpi.machine_type;
355 TRACED_FOREACH(Shift, shift, kShiftInstructions) { 390 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
356 // Only test 64-bit shifted operands with 64-bit instructions. 391 // Only test 64-bit shifted operands with 64-bit instructions.
357 if (shift.mi.machine_type != type) continue; 392 if (shift.mi.machine_type != type) continue;
358 393
359 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) { 394 TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) {
360 StreamBuilder m(this, type, type, type); 395 StreamBuilder m(this, type, type, type);
361 m.Return((m.*dpi.constructor)( 396 m.Return((m.*dpi.constructor)(
362 m.Parameter(0), 397 m.Parameter(0),
363 (m.*shift.mi.constructor)(m.Parameter(1), 398 (m.*shift.mi.constructor)(m.Parameter(1),
364 BuildConstant(m, type, imm)))); 399 BuildConstant(m, type, imm))));
365 Stream s = m.Build(); 400 Stream s = m.Build();
366 ASSERT_EQ(1U, s.size()); 401 ASSERT_EQ(1U, s.size());
367 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 402 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
368 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 403 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
369 EXPECT_EQ(3U, s[0]->InputCount()); 404 EXPECT_EQ(3U, s[0]->InputCount());
370 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); 405 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
371 EXPECT_EQ(1U, s[0]->OutputCount()); 406 EXPECT_EQ(1U, s[0]->OutputCount());
372 } 407 }
373 408
374 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) { 409 TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) {
375 StreamBuilder m(this, type, type, type); 410 StreamBuilder m(this, type, type, type);
376 m.Return((m.*dpi.constructor)( 411 m.Return((m.*dpi.constructor)(
377 (m.*shift.mi.constructor)(m.Parameter(1), 412 (m.*shift.mi.constructor)(m.Parameter(1),
378 BuildConstant(m, type, imm)), 413 BuildConstant(m, type, imm)),
379 m.Parameter(0))); 414 m.Parameter(0)));
380 Stream s = m.Build(); 415 Stream s = m.Build();
381 ASSERT_EQ(1U, s.size()); 416 ASSERT_EQ(1U, s.size());
382 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); 417 EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
383 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 418 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
384 EXPECT_EQ(3U, s[0]->InputCount()); 419 EXPECT_EQ(3U, s[0]->InputCount());
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 TRACED_FOREACH(Shift, shift, kShiftInstructions) { 490 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
456 // Only test 64-bit shifted operands with 64-bit instructions. 491 // Only test 64-bit shifted operands with 64-bit instructions.
457 if (shift.mi.machine_type != type) continue; 492 if (shift.mi.machine_type != type) continue;
458 493
459 if ((shift.mi.arch_opcode == kArm64Ror32) || 494 if ((shift.mi.arch_opcode == kArm64Ror32) ||
460 (shift.mi.arch_opcode == kArm64Ror)) { 495 (shift.mi.arch_opcode == kArm64Ror)) {
461 // Not supported by add/sub instructions. 496 // Not supported by add/sub instructions.
462 continue; 497 continue;
463 } 498 }
464 499
465 TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) { 500 TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) {
466 StreamBuilder m(this, type, type, type); 501 StreamBuilder m(this, type, type, type);
467 m.Return((m.*dpi.mi.constructor)( 502 m.Return((m.*dpi.mi.constructor)(
468 m.Parameter(0), 503 m.Parameter(0),
469 (m.*shift.mi.constructor)(m.Parameter(1), 504 (m.*shift.mi.constructor)(m.Parameter(1),
470 BuildConstant(m, type, imm)))); 505 BuildConstant(m, type, imm))));
471 Stream s = m.Build(); 506 Stream s = m.Build();
472 ASSERT_EQ(1U, s.size()); 507 ASSERT_EQ(1U, s.size());
473 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); 508 EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode());
474 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 509 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
475 EXPECT_EQ(3U, s[0]->InputCount()); 510 EXPECT_EQ(3U, s[0]->InputCount());
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 580
546 581
547 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest, 582 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
548 ::testing::ValuesIn(kAddSubInstructions)); 583 ::testing::ValuesIn(kAddSubInstructions));
549 584
550 585
551 TEST_F(InstructionSelectorTest, AddImmediateOnLeft) { 586 TEST_F(InstructionSelectorTest, AddImmediateOnLeft) {
552 { 587 {
553 // 32-bit add. 588 // 32-bit add.
554 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 589 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
555 StreamBuilder m(this, kMachInt32, kMachInt32); 590 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
556 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0))); 591 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
557 Stream s = m.Build(); 592 Stream s = m.Build();
558 ASSERT_EQ(1U, s.size()); 593 ASSERT_EQ(1U, s.size());
559 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 594 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
560 ASSERT_EQ(2U, s[0]->InputCount()); 595 ASSERT_EQ(2U, s[0]->InputCount());
561 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 596 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
562 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 597 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
563 EXPECT_EQ(1U, s[0]->OutputCount()); 598 EXPECT_EQ(1U, s[0]->OutputCount());
564 } 599 }
565 } 600 }
566 { 601 {
567 // 64-bit add. 602 // 64-bit add.
568 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 603 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
569 StreamBuilder m(this, kMachInt64, kMachInt64); 604 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
570 m.Return(m.Int64Add(m.Int64Constant(imm), m.Parameter(0))); 605 m.Return(m.Int64Add(m.Int64Constant(imm), m.Parameter(0)));
571 Stream s = m.Build(); 606 Stream s = m.Build();
572 ASSERT_EQ(1U, s.size()); 607 ASSERT_EQ(1U, s.size());
573 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 608 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
574 ASSERT_EQ(2U, s[0]->InputCount()); 609 ASSERT_EQ(2U, s[0]->InputCount());
575 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 610 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
576 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); 611 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
577 EXPECT_EQ(1U, s[0]->OutputCount()); 612 EXPECT_EQ(1U, s[0]->OutputCount());
578 } 613 }
579 } 614 }
580 } 615 }
581 616
582 617
583 TEST_F(InstructionSelectorTest, SubZeroOnLeft) { 618 TEST_F(InstructionSelectorTest, SubZeroOnLeft) {
584 { 619 {
585 // 32-bit subtract. 620 // 32-bit subtract.
586 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 621 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
622 MachineType::Int32());
587 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0))); 623 m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0)));
588 Stream s = m.Build(); 624 Stream s = m.Build();
589 625
590 ASSERT_EQ(1U, s.size()); 626 ASSERT_EQ(1U, s.size());
591 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); 627 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode());
592 ASSERT_EQ(2U, s[0]->InputCount()); 628 ASSERT_EQ(2U, s[0]->InputCount());
593 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); 629 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
594 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); 630 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
595 EXPECT_EQ(1U, s[0]->OutputCount()); 631 EXPECT_EQ(1U, s[0]->OutputCount());
596 } 632 }
597 { 633 {
598 // 64-bit subtract. 634 // 64-bit subtract.
599 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 635 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
636 MachineType::Int64());
600 m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0))); 637 m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0)));
601 Stream s = m.Build(); 638 Stream s = m.Build();
602 639
603 ASSERT_EQ(1U, s.size()); 640 ASSERT_EQ(1U, s.size());
604 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); 641 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
605 ASSERT_EQ(2U, s[0]->InputCount()); 642 ASSERT_EQ(2U, s[0]->InputCount());
606 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); 643 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
607 EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(0))); 644 EXPECT_EQ(0, s.ToInt64(s[0]->InputAt(0)));
608 EXPECT_EQ(1U, s[0]->OutputCount()); 645 EXPECT_EQ(1U, s[0]->OutputCount());
609 } 646 }
610 } 647 }
611 648
612 649
613 TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) { 650 TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) {
614 TRACED_FOREACH(Shift, shift, kShiftInstructions) { 651 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
615 { 652 {
616 // Test 32-bit operations. Ignore ROR shifts, as subtract does not 653 // Test 32-bit operations. Ignore ROR shifts, as subtract does not
617 // support them. 654 // support them.
618 if ((shift.mi.machine_type != kMachInt32) || 655 if ((shift.mi.machine_type != MachineType::Int32()) ||
619 (shift.mi.arch_opcode == kArm64Ror32) || 656 (shift.mi.arch_opcode == kArm64Ror32) ||
620 (shift.mi.arch_opcode == kArm64Ror)) 657 (shift.mi.arch_opcode == kArm64Ror))
621 continue; 658 continue;
622 659
623 TRACED_FORRANGE(int, imm, -32, 63) { 660 TRACED_FORRANGE(int, imm, -32, 63) {
624 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 661 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
662 MachineType::Int32());
625 m.Return(m.Int32Sub( 663 m.Return(m.Int32Sub(
626 m.Int32Constant(0), 664 m.Int32Constant(0),
627 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)))); 665 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm))));
628 Stream s = m.Build(); 666 Stream s = m.Build();
629 667
630 ASSERT_EQ(1U, s.size()); 668 ASSERT_EQ(1U, s.size());
631 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); 669 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode());
632 ASSERT_EQ(3U, s[0]->InputCount()); 670 ASSERT_EQ(3U, s[0]->InputCount());
633 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); 671 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
634 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); 672 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
635 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 673 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
636 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); 674 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
637 EXPECT_EQ(1U, s[0]->OutputCount()); 675 EXPECT_EQ(1U, s[0]->OutputCount());
638 } 676 }
639 } 677 }
640 { 678 {
641 // Test 64-bit operations. Ignore ROR shifts, as subtract does not 679 // Test 64-bit operations. Ignore ROR shifts, as subtract does not
642 // support them. 680 // support them.
643 if ((shift.mi.machine_type != kMachInt64) || 681 if ((shift.mi.machine_type != MachineType::Int64()) ||
644 (shift.mi.arch_opcode == kArm64Ror32) || 682 (shift.mi.arch_opcode == kArm64Ror32) ||
645 (shift.mi.arch_opcode == kArm64Ror)) 683 (shift.mi.arch_opcode == kArm64Ror))
646 continue; 684 continue;
647 685
648 TRACED_FORRANGE(int, imm, -32, 127) { 686 TRACED_FORRANGE(int, imm, -32, 127) {
649 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 687 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
688 MachineType::Int64());
650 m.Return(m.Int64Sub( 689 m.Return(m.Int64Sub(
651 m.Int64Constant(0), 690 m.Int64Constant(0),
652 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)))); 691 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm))));
653 Stream s = m.Build(); 692 Stream s = m.Build();
654 693
655 ASSERT_EQ(1U, s.size()); 694 ASSERT_EQ(1U, s.size());
656 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); 695 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
657 ASSERT_EQ(3U, s[0]->InputCount()); 696 ASSERT_EQ(3U, s[0]->InputCount());
658 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate()); 697 EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
659 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0))); 698 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
660 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 699 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
661 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); 700 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
662 EXPECT_EQ(1U, s[0]->OutputCount()); 701 EXPECT_EQ(1U, s[0]->OutputCount());
663 } 702 }
664 } 703 }
665 } 704 }
666 } 705 }
667 706
668 707
669 TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) { 708 TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) {
670 { 709 {
671 // 32-bit add. 710 // 32-bit add.
672 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 711 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
673 if (imm == 0) continue; 712 if (imm == 0) continue;
674 StreamBuilder m(this, kMachInt32, kMachInt32); 713 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
675 m.Return(m.Int32Add(m.Int32Constant(-imm), m.Parameter(0))); 714 m.Return(m.Int32Add(m.Int32Constant(-imm), m.Parameter(0)));
676 Stream s = m.Build(); 715 Stream s = m.Build();
677 716
678 ASSERT_EQ(1U, s.size()); 717 ASSERT_EQ(1U, s.size());
679 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode()); 718 EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode());
680 ASSERT_EQ(2U, s[0]->InputCount()); 719 ASSERT_EQ(2U, s[0]->InputCount());
681 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); 720 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
682 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 721 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
683 EXPECT_EQ(1U, s[0]->OutputCount()); 722 EXPECT_EQ(1U, s[0]->OutputCount());
684 } 723 }
685 } 724 }
686 { 725 {
687 // 64-bit add. 726 // 64-bit add.
688 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 727 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
689 if (imm == 0) continue; 728 if (imm == 0) continue;
690 StreamBuilder m(this, kMachInt64, kMachInt64); 729 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
691 m.Return(m.Int64Add(m.Int64Constant(-imm), m.Parameter(0))); 730 m.Return(m.Int64Add(m.Int64Constant(-imm), m.Parameter(0)));
692 Stream s = m.Build(); 731 Stream s = m.Build();
693 732
694 ASSERT_EQ(1U, s.size()); 733 ASSERT_EQ(1U, s.size());
695 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode()); 734 EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
696 ASSERT_EQ(2U, s[0]->InputCount()); 735 ASSERT_EQ(2U, s[0]->InputCount());
697 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate()); 736 ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
698 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1))); 737 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
699 EXPECT_EQ(1U, s[0]->OutputCount()); 738 EXPECT_EQ(1U, s[0]->OutputCount());
700 } 739 }
701 } 740 }
702 } 741 }
703 742
704 743
705 TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) { 744 TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) {
706 // 32-bit add. 745 // 32-bit add.
707 TRACED_FOREACH(Shift, shift, kShiftInstructions) { 746 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
708 // Only test relevant shifted operands. 747 // Only test relevant shifted operands.
709 if (shift.mi.machine_type != kMachInt32) continue; 748 if (shift.mi.machine_type != MachineType::Int32()) continue;
710 if (shift.mi.arch_opcode == kArm64Ror32) continue; 749 if (shift.mi.arch_opcode == kArm64Ror32) continue;
711 750
712 // The available shift operand range is `0 <= imm < 32`, but we also test 751 // The available shift operand range is `0 <= imm < 32`, but we also test
713 // that immediates outside this range are handled properly (modulo-32). 752 // that immediates outside this range are handled properly (modulo-32).
714 TRACED_FORRANGE(int, imm, -32, 63) { 753 TRACED_FORRANGE(int, imm, -32, 63) {
715 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 754 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
755 MachineType::Int32());
716 m.Return((m.Int32Add)( 756 m.Return((m.Int32Add)(
717 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)), 757 (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)),
718 m.Parameter(0))); 758 m.Parameter(0)));
719 Stream s = m.Build(); 759 Stream s = m.Build();
720 ASSERT_EQ(1U, s.size()); 760 ASSERT_EQ(1U, s.size());
721 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 761 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
722 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 762 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
723 EXPECT_EQ(3U, s[0]->InputCount()); 763 EXPECT_EQ(3U, s[0]->InputCount());
724 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); 764 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
725 EXPECT_EQ(1U, s[0]->OutputCount()); 765 EXPECT_EQ(1U, s[0]->OutputCount());
726 } 766 }
727 } 767 }
728 768
729 // 64-bit add. 769 // 64-bit add.
730 TRACED_FOREACH(Shift, shift, kShiftInstructions) { 770 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
731 // Only test relevant shifted operands. 771 // Only test relevant shifted operands.
732 if (shift.mi.machine_type != kMachInt64) continue; 772 if (shift.mi.machine_type != MachineType::Int64()) continue;
733 if (shift.mi.arch_opcode == kArm64Ror) continue; 773 if (shift.mi.arch_opcode == kArm64Ror) continue;
734 774
735 // The available shift operand range is `0 <= imm < 64`, but we also test 775 // The available shift operand range is `0 <= imm < 64`, but we also test
736 // that immediates outside this range are handled properly (modulo-64). 776 // that immediates outside this range are handled properly (modulo-64).
737 TRACED_FORRANGE(int, imm, -64, 127) { 777 TRACED_FORRANGE(int, imm, -64, 127) {
738 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 778 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
779 MachineType::Int64());
739 m.Return((m.Int64Add)( 780 m.Return((m.Int64Add)(
740 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)), 781 (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)),
741 m.Parameter(0))); 782 m.Parameter(0)));
742 Stream s = m.Build(); 783 Stream s = m.Build();
743 ASSERT_EQ(1U, s.size()); 784 ASSERT_EQ(1U, s.size());
744 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 785 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
745 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 786 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
746 EXPECT_EQ(3U, s[0]->InputCount()); 787 EXPECT_EQ(3U, s[0]->InputCount());
747 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2))); 788 EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
748 EXPECT_EQ(1U, s[0]->OutputCount()); 789 EXPECT_EQ(1U, s[0]->OutputCount());
749 } 790 }
750 } 791 }
751 } 792 }
752 793
753 794
754 TEST_F(InstructionSelectorTest, AddUnsignedExtendByteOnLeft) { 795 TEST_F(InstructionSelectorTest, AddUnsignedExtendByteOnLeft) {
755 { 796 {
756 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 797 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
798 MachineType::Int32());
757 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)), 799 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)),
758 m.Parameter(1))); 800 m.Parameter(1)));
759 Stream s = m.Build(); 801 Stream s = m.Build();
760 ASSERT_EQ(1U, s.size()); 802 ASSERT_EQ(1U, s.size());
761 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 803 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
762 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); 804 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode());
763 ASSERT_EQ(2U, s[0]->InputCount()); 805 ASSERT_EQ(2U, s[0]->InputCount());
764 ASSERT_EQ(1U, s[0]->OutputCount()); 806 ASSERT_EQ(1U, s[0]->OutputCount());
765 } 807 }
766 { 808 {
767 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); 809 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(),
810 MachineType::Int64());
768 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)), 811 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xff)),
769 m.Parameter(1))); 812 m.Parameter(1)));
770 Stream s = m.Build(); 813 Stream s = m.Build();
771 ASSERT_EQ(1U, s.size()); 814 ASSERT_EQ(1U, s.size());
772 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 815 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
773 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); 816 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode());
774 ASSERT_EQ(2U, s[0]->InputCount()); 817 ASSERT_EQ(2U, s[0]->InputCount());
775 ASSERT_EQ(1U, s[0]->OutputCount()); 818 ASSERT_EQ(1U, s[0]->OutputCount());
776 } 819 }
777 } 820 }
778 821
779 822
780 TEST_F(InstructionSelectorTest, AddUnsignedExtendHalfwordOnLeft) { 823 TEST_F(InstructionSelectorTest, AddUnsignedExtendHalfwordOnLeft) {
781 { 824 {
782 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 825 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
826 MachineType::Int32());
783 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)), 827 m.Return(m.Int32Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)),
784 m.Parameter(1))); 828 m.Parameter(1)));
785 Stream s = m.Build(); 829 Stream s = m.Build();
786 ASSERT_EQ(1U, s.size()); 830 ASSERT_EQ(1U, s.size());
787 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 831 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
788 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); 832 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode());
789 ASSERT_EQ(2U, s[0]->InputCount()); 833 ASSERT_EQ(2U, s[0]->InputCount());
790 ASSERT_EQ(1U, s[0]->OutputCount()); 834 ASSERT_EQ(1U, s[0]->OutputCount());
791 } 835 }
792 { 836 {
793 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); 837 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(),
838 MachineType::Int64());
794 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)), 839 m.Return(m.Int64Add(m.Word32And(m.Parameter(0), m.Int32Constant(0xffff)),
795 m.Parameter(1))); 840 m.Parameter(1)));
796 Stream s = m.Build(); 841 Stream s = m.Build();
797 ASSERT_EQ(1U, s.size()); 842 ASSERT_EQ(1U, s.size());
798 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 843 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
799 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); 844 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode());
800 ASSERT_EQ(2U, s[0]->InputCount()); 845 ASSERT_EQ(2U, s[0]->InputCount());
801 ASSERT_EQ(1U, s[0]->OutputCount()); 846 ASSERT_EQ(1U, s[0]->OutputCount());
802 } 847 }
803 } 848 }
804 849
805 850
806 TEST_F(InstructionSelectorTest, AddSignedExtendByteOnLeft) { 851 TEST_F(InstructionSelectorTest, AddSignedExtendByteOnLeft) {
807 { 852 {
808 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 853 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
854 MachineType::Int32());
809 m.Return( 855 m.Return(
810 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)), 856 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)),
811 m.Int32Constant(24)), 857 m.Int32Constant(24)),
812 m.Parameter(1))); 858 m.Parameter(1)));
813 Stream s = m.Build(); 859 Stream s = m.Build();
814 ASSERT_EQ(1U, s.size()); 860 ASSERT_EQ(1U, s.size());
815 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 861 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
816 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); 862 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
817 ASSERT_EQ(2U, s[0]->InputCount()); 863 ASSERT_EQ(2U, s[0]->InputCount());
818 ASSERT_EQ(1U, s[0]->OutputCount()); 864 ASSERT_EQ(1U, s[0]->OutputCount());
819 } 865 }
820 { 866 {
821 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); 867 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(),
868 MachineType::Int64());
822 m.Return( 869 m.Return(
823 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)), 870 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(24)),
824 m.Int32Constant(24)), 871 m.Int32Constant(24)),
825 m.Parameter(1))); 872 m.Parameter(1)));
826 Stream s = m.Build(); 873 Stream s = m.Build();
827 ASSERT_EQ(1U, s.size()); 874 ASSERT_EQ(1U, s.size());
828 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 875 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
829 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); 876 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
830 ASSERT_EQ(2U, s[0]->InputCount()); 877 ASSERT_EQ(2U, s[0]->InputCount());
831 ASSERT_EQ(1U, s[0]->OutputCount()); 878 ASSERT_EQ(1U, s[0]->OutputCount());
832 } 879 }
833 } 880 }
834 881
835 882
836 TEST_F(InstructionSelectorTest, AddSignedExtendHalfwordOnLeft) { 883 TEST_F(InstructionSelectorTest, AddSignedExtendHalfwordOnLeft) {
837 { 884 {
838 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 885 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
886 MachineType::Int32());
839 m.Return( 887 m.Return(
840 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)), 888 m.Int32Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)),
841 m.Int32Constant(16)), 889 m.Int32Constant(16)),
842 m.Parameter(1))); 890 m.Parameter(1)));
843 Stream s = m.Build(); 891 Stream s = m.Build();
844 ASSERT_EQ(1U, s.size()); 892 ASSERT_EQ(1U, s.size());
845 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 893 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
846 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); 894 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode());
847 ASSERT_EQ(2U, s[0]->InputCount()); 895 ASSERT_EQ(2U, s[0]->InputCount());
848 ASSERT_EQ(1U, s[0]->OutputCount()); 896 ASSERT_EQ(1U, s[0]->OutputCount());
849 } 897 }
850 { 898 {
851 StreamBuilder m(this, kMachInt64, kMachInt32, kMachInt64); 899 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32(),
900 MachineType::Int64());
852 m.Return( 901 m.Return(
853 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)), 902 m.Int64Add(m.Word32Sar(m.Word32Shl(m.Parameter(0), m.Int32Constant(16)),
854 m.Int32Constant(16)), 903 m.Int32Constant(16)),
855 m.Parameter(1))); 904 m.Parameter(1)));
856 Stream s = m.Build(); 905 Stream s = m.Build();
857 ASSERT_EQ(1U, s.size()); 906 ASSERT_EQ(1U, s.size());
858 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 907 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
859 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); 908 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode());
860 ASSERT_EQ(2U, s[0]->InputCount()); 909 ASSERT_EQ(2U, s[0]->InputCount());
861 ASSERT_EQ(1U, s[0]->OutputCount()); 910 ASSERT_EQ(1U, s[0]->OutputCount());
(...skipping 30 matching lines...) Expand all
892 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, 941 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
893 InstructionSelectorDPFlagSetTest, 942 InstructionSelectorDPFlagSetTest,
894 ::testing::ValuesIn(kDPFlagSetInstructions)); 943 ::testing::ValuesIn(kDPFlagSetInstructions));
895 944
896 945
897 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) { 946 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) {
898 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { 947 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
899 // Skip the cases where the instruction selector would use tbz/tbnz. 948 // Skip the cases where the instruction selector would use tbz/tbnz.
900 if (base::bits::CountPopulation32(imm) == 1) continue; 949 if (base::bits::CountPopulation32(imm) == 1) continue;
901 950
902 StreamBuilder m(this, kMachInt32, kMachInt32); 951 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
903 RawMachineLabel a, b; 952 RawMachineLabel a, b;
904 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b); 953 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
905 m.Bind(&a); 954 m.Bind(&a);
906 m.Return(m.Int32Constant(1)); 955 m.Return(m.Int32Constant(1));
907 m.Bind(&b); 956 m.Bind(&b);
908 m.Return(m.Int32Constant(0)); 957 m.Return(m.Int32Constant(0));
909 Stream s = m.Build(); 958 Stream s = m.Build();
910 ASSERT_EQ(1U, s.size()); 959 ASSERT_EQ(1U, s.size());
911 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); 960 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
912 EXPECT_EQ(4U, s[0]->InputCount()); 961 EXPECT_EQ(4U, s[0]->InputCount());
913 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 962 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
914 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 963 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
915 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 964 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
916 } 965 }
917 } 966 }
918 967
919 968
920 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) { 969 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) {
921 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { 970 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) {
922 // Skip the cases where the instruction selector would use tbz/tbnz. 971 // Skip the cases where the instruction selector would use tbz/tbnz.
923 if (base::bits::CountPopulation64(imm) == 1) continue; 972 if (base::bits::CountPopulation64(imm) == 1) continue;
924 973
925 StreamBuilder m(this, kMachInt64, kMachInt64); 974 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
926 RawMachineLabel a, b; 975 RawMachineLabel a, b;
927 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b); 976 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b);
928 m.Bind(&a); 977 m.Bind(&a);
929 m.Return(m.Int32Constant(1)); 978 m.Return(m.Int32Constant(1));
930 m.Bind(&b); 979 m.Bind(&b);
931 m.Return(m.Int32Constant(0)); 980 m.Return(m.Int32Constant(0));
932 Stream s = m.Build(); 981 Stream s = m.Build();
933 ASSERT_EQ(1U, s.size()); 982 ASSERT_EQ(1U, s.size());
934 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); 983 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
935 EXPECT_EQ(4U, s[0]->InputCount()); 984 EXPECT_EQ(4U, s[0]->InputCount());
936 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 985 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
937 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 986 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
938 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 987 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
939 } 988 }
940 } 989 }
941 990
942 991
943 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) { 992 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) {
944 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 993 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
945 StreamBuilder m(this, kMachInt32, kMachInt32); 994 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
946 RawMachineLabel a, b; 995 RawMachineLabel a, b;
947 m.Branch(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)), &a, &b); 996 m.Branch(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
948 m.Bind(&a); 997 m.Bind(&a);
949 m.Return(m.Int32Constant(1)); 998 m.Return(m.Int32Constant(1));
950 m.Bind(&b); 999 m.Bind(&b);
951 m.Return(m.Int32Constant(0)); 1000 m.Return(m.Int32Constant(0));
952 Stream s = m.Build(); 1001 Stream s = m.Build();
953 ASSERT_EQ(1U, s.size()); 1002 ASSERT_EQ(1U, s.size());
954 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); 1003 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
955 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 1004 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
956 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1005 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
957 } 1006 }
958 } 1007 }
959 1008
960 1009
961 TEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) { 1010 TEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) {
962 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 1011 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
963 StreamBuilder m(this, kMachInt32, kMachInt32); 1012 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
964 RawMachineLabel a, b; 1013 RawMachineLabel a, b;
965 m.Branch(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)), &a, &b); 1014 m.Branch(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
966 m.Bind(&a); 1015 m.Bind(&a);
967 m.Return(m.Int32Constant(1)); 1016 m.Return(m.Int32Constant(1));
968 m.Bind(&b); 1017 m.Bind(&b);
969 m.Return(m.Int32Constant(0)); 1018 m.Return(m.Int32Constant(0));
970 Stream s = m.Build(); 1019 Stream s = m.Build();
971 ASSERT_EQ(1U, s.size()); 1020 ASSERT_EQ(1U, s.size());
972 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 1021 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
973 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 1022 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
974 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1023 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
975 } 1024 }
976 } 1025 }
977 1026
978 1027
979 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) { 1028 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) {
980 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { 1029 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
981 // Skip the cases where the instruction selector would use tbz/tbnz. 1030 // Skip the cases where the instruction selector would use tbz/tbnz.
982 if (base::bits::CountPopulation32(imm) == 1) continue; 1031 if (base::bits::CountPopulation32(imm) == 1) continue;
983 1032
984 StreamBuilder m(this, kMachInt32, kMachInt32); 1033 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
985 RawMachineLabel a, b; 1034 RawMachineLabel a, b;
986 m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b); 1035 m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
987 m.Bind(&a); 1036 m.Bind(&a);
988 m.Return(m.Int32Constant(1)); 1037 m.Return(m.Int32Constant(1));
989 m.Bind(&b); 1038 m.Bind(&b);
990 m.Return(m.Int32Constant(0)); 1039 m.Return(m.Int32Constant(0));
991 Stream s = m.Build(); 1040 Stream s = m.Build();
992 ASSERT_EQ(1U, s.size()); 1041 ASSERT_EQ(1U, s.size());
993 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); 1042 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
994 EXPECT_EQ(4U, s[0]->InputCount()); 1043 EXPECT_EQ(4U, s[0]->InputCount());
995 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1044 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
996 ASSERT_LE(1U, s[0]->InputCount()); 1045 ASSERT_LE(1U, s[0]->InputCount());
997 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 1046 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
998 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1047 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
999 } 1048 }
1000 } 1049 }
1001 1050
1002 1051
1003 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) { 1052 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) {
1004 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { 1053 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) {
1005 // Skip the cases where the instruction selector would use tbz/tbnz. 1054 // Skip the cases where the instruction selector would use tbz/tbnz.
1006 if (base::bits::CountPopulation64(imm) == 1) continue; 1055 if (base::bits::CountPopulation64(imm) == 1) continue;
1007 1056
1008 StreamBuilder m(this, kMachInt64, kMachInt64); 1057 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
1009 RawMachineLabel a, b; 1058 RawMachineLabel a, b;
1010 m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b); 1059 m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b);
1011 m.Bind(&a); 1060 m.Bind(&a);
1012 m.Return(m.Int32Constant(1)); 1061 m.Return(m.Int32Constant(1));
1013 m.Bind(&b); 1062 m.Bind(&b);
1014 m.Return(m.Int32Constant(0)); 1063 m.Return(m.Int32Constant(0));
1015 Stream s = m.Build(); 1064 Stream s = m.Build();
1016 ASSERT_EQ(1U, s.size()); 1065 ASSERT_EQ(1U, s.size());
1017 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); 1066 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
1018 EXPECT_EQ(4U, s[0]->InputCount()); 1067 EXPECT_EQ(4U, s[0]->InputCount());
1019 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1068 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1020 ASSERT_LE(1U, s[0]->InputCount()); 1069 ASSERT_LE(1U, s[0]->InputCount());
1021 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 1070 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
1022 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1071 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
1023 } 1072 }
1024 } 1073 }
1025 1074
1026 1075
1027 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) { 1076 TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) {
1028 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 1077 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
1029 StreamBuilder m(this, kMachInt32, kMachInt32); 1078 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1030 RawMachineLabel a, b; 1079 RawMachineLabel a, b;
1031 m.Branch(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)), &a, &b); 1080 m.Branch(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
1032 m.Bind(&a); 1081 m.Bind(&a);
1033 m.Return(m.Int32Constant(1)); 1082 m.Return(m.Int32Constant(1));
1034 m.Bind(&b); 1083 m.Bind(&b);
1035 m.Return(m.Int32Constant(0)); 1084 m.Return(m.Int32Constant(0));
1036 Stream s = m.Build(); 1085 Stream s = m.Build();
1037 ASSERT_EQ(1U, s.size()); 1086 ASSERT_EQ(1U, s.size());
1038 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); 1087 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
1039 ASSERT_LE(1U, s[0]->InputCount()); 1088 ASSERT_LE(1U, s[0]->InputCount());
1040 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); 1089 EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
1041 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1090 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
1042 } 1091 }
1043 } 1092 }
1044 1093
1045 1094
1046 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnRight) { 1095 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnRight) {
1047 TRACED_FORRANGE(int, bit, 0, 31) { 1096 TRACED_FORRANGE(int, bit, 0, 31) {
1048 uint32_t mask = 1 << bit; 1097 uint32_t mask = 1 << bit;
1049 StreamBuilder m(this, kMachInt32, kMachInt32); 1098 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1050 RawMachineLabel a, b; 1099 RawMachineLabel a, b;
1051 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b); 1100 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b);
1052 m.Bind(&a); 1101 m.Bind(&a);
1053 m.Return(m.Int32Constant(1)); 1102 m.Return(m.Int32Constant(1));
1054 m.Bind(&b); 1103 m.Bind(&b);
1055 m.Return(m.Int32Constant(0)); 1104 m.Return(m.Int32Constant(0));
1056 Stream s = m.Build(); 1105 Stream s = m.Build();
1057 ASSERT_EQ(1U, s.size()); 1106 ASSERT_EQ(1U, s.size());
1058 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); 1107 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
1059 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1108 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
1060 EXPECT_EQ(4U, s[0]->InputCount()); 1109 EXPECT_EQ(4U, s[0]->InputCount());
1061 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1110 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1062 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); 1111 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
1063 } 1112 }
1064 1113
1065 TRACED_FORRANGE(int, bit, 0, 31) { 1114 TRACED_FORRANGE(int, bit, 0, 31) {
1066 uint32_t mask = 1 << bit; 1115 uint32_t mask = 1 << bit;
1067 StreamBuilder m(this, kMachInt32, kMachInt32); 1116 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1068 RawMachineLabel a, b; 1117 RawMachineLabel a, b;
1069 m.Branch( 1118 m.Branch(
1070 m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))), 1119 m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))),
1071 &a, &b); 1120 &a, &b);
1072 m.Bind(&a); 1121 m.Bind(&a);
1073 m.Return(m.Int32Constant(1)); 1122 m.Return(m.Int32Constant(1));
1074 m.Bind(&b); 1123 m.Bind(&b);
1075 m.Return(m.Int32Constant(0)); 1124 m.Return(m.Int32Constant(0));
1076 Stream s = m.Build(); 1125 Stream s = m.Build();
1077 ASSERT_EQ(1U, s.size()); 1126 ASSERT_EQ(1U, s.size());
1078 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); 1127 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
1079 EXPECT_EQ(kEqual, s[0]->flags_condition()); 1128 EXPECT_EQ(kEqual, s[0]->flags_condition());
1080 EXPECT_EQ(4U, s[0]->InputCount()); 1129 EXPECT_EQ(4U, s[0]->InputCount());
1081 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1130 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1082 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); 1131 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
1083 } 1132 }
1084 } 1133 }
1085 1134
1086 1135
1087 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) { 1136 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) {
1088 TRACED_FORRANGE(int, bit, 0, 31) { 1137 TRACED_FORRANGE(int, bit, 0, 31) {
1089 uint32_t mask = 1 << bit; 1138 uint32_t mask = 1 << bit;
1090 StreamBuilder m(this, kMachInt32, kMachInt32); 1139 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1091 RawMachineLabel a, b; 1140 RawMachineLabel a, b;
1092 m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b); 1141 m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b);
1093 m.Bind(&a); 1142 m.Bind(&a);
1094 m.Return(m.Int32Constant(1)); 1143 m.Return(m.Int32Constant(1));
1095 m.Bind(&b); 1144 m.Bind(&b);
1096 m.Return(m.Int32Constant(0)); 1145 m.Return(m.Int32Constant(0));
1097 Stream s = m.Build(); 1146 Stream s = m.Build();
1098 ASSERT_EQ(1U, s.size()); 1147 ASSERT_EQ(1U, s.size());
1099 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); 1148 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
1100 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1149 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
1101 EXPECT_EQ(4U, s[0]->InputCount()); 1150 EXPECT_EQ(4U, s[0]->InputCount());
1102 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1151 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1103 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); 1152 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
1104 } 1153 }
1105 1154
1106 TRACED_FORRANGE(int, bit, 0, 31) { 1155 TRACED_FORRANGE(int, bit, 0, 31) {
1107 uint32_t mask = 1 << bit; 1156 uint32_t mask = 1 << bit;
1108 StreamBuilder m(this, kMachInt32, kMachInt32); 1157 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1109 RawMachineLabel a, b; 1158 RawMachineLabel a, b;
1110 m.Branch( 1159 m.Branch(
1111 m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))), 1160 m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))),
1112 &a, &b); 1161 &a, &b);
1113 m.Bind(&a); 1162 m.Bind(&a);
1114 m.Return(m.Int32Constant(1)); 1163 m.Return(m.Int32Constant(1));
1115 m.Bind(&b); 1164 m.Bind(&b);
1116 m.Return(m.Int32Constant(0)); 1165 m.Return(m.Int32Constant(0));
1117 Stream s = m.Build(); 1166 Stream s = m.Build();
1118 ASSERT_EQ(1U, s.size()); 1167 ASSERT_EQ(1U, s.size());
1119 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); 1168 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
1120 EXPECT_EQ(kEqual, s[0]->flags_condition()); 1169 EXPECT_EQ(kEqual, s[0]->flags_condition());
1121 EXPECT_EQ(4U, s[0]->InputCount()); 1170 EXPECT_EQ(4U, s[0]->InputCount());
1122 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1171 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1123 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); 1172 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
1124 } 1173 }
1125 } 1174 }
1126 1175
1127 1176
1128 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) { 1177 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) {
1129 TRACED_FORRANGE(int, bit, 0, 63) { 1178 TRACED_FORRANGE(int, bit, 0, 63) {
1130 uint64_t mask = 1L << bit; 1179 uint64_t mask = 1L << bit;
1131 StreamBuilder m(this, kMachInt64, kMachInt64); 1180 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
1132 RawMachineLabel a, b; 1181 RawMachineLabel a, b;
1133 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b); 1182 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b);
1134 m.Bind(&a); 1183 m.Bind(&a);
1135 m.Return(m.Int32Constant(1)); 1184 m.Return(m.Int32Constant(1));
1136 m.Bind(&b); 1185 m.Bind(&b);
1137 m.Return(m.Int32Constant(0)); 1186 m.Return(m.Int32Constant(0));
1138 Stream s = m.Build(); 1187 Stream s = m.Build();
1139 ASSERT_EQ(1U, s.size()); 1188 ASSERT_EQ(1U, s.size());
1140 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); 1189 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
1141 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1190 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
1142 EXPECT_EQ(4U, s[0]->InputCount()); 1191 EXPECT_EQ(4U, s[0]->InputCount());
1143 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1192 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1144 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); 1193 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
1145 } 1194 }
1146 } 1195 }
1147 1196
1148 1197
1149 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) { 1198 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) {
1150 TRACED_FORRANGE(int, bit, 0, 63) { 1199 TRACED_FORRANGE(int, bit, 0, 63) {
1151 uint64_t mask = 1L << bit; 1200 uint64_t mask = 1L << bit;
1152 StreamBuilder m(this, kMachInt64, kMachInt64); 1201 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
1153 RawMachineLabel a, b; 1202 RawMachineLabel a, b;
1154 m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b); 1203 m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b);
1155 m.Bind(&a); 1204 m.Bind(&a);
1156 m.Return(m.Int32Constant(1)); 1205 m.Return(m.Int32Constant(1));
1157 m.Bind(&b); 1206 m.Bind(&b);
1158 m.Return(m.Int32Constant(0)); 1207 m.Return(m.Int32Constant(0));
1159 Stream s = m.Build(); 1208 Stream s = m.Build();
1160 ASSERT_EQ(1U, s.size()); 1209 ASSERT_EQ(1U, s.size());
1161 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); 1210 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
1162 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1211 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
1163 EXPECT_EQ(4U, s[0]->InputCount()); 1212 EXPECT_EQ(4U, s[0]->InputCount());
1164 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 1213 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
1165 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); 1214 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
1166 } 1215 }
1167 } 1216 }
1168 1217
1169 1218
1170 TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) { 1219 TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) {
1171 { 1220 {
1172 StreamBuilder m(this, kMachInt32, kMachInt32); 1221 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1173 RawMachineLabel a, b; 1222 RawMachineLabel a, b;
1174 Node* p0 = m.Parameter(0); 1223 Node* p0 = m.Parameter(0);
1175 m.Branch(p0, &a, &b); 1224 m.Branch(p0, &a, &b);
1176 m.Bind(&a); 1225 m.Bind(&a);
1177 m.Return(m.Int32Constant(1)); 1226 m.Return(m.Int32Constant(1));
1178 m.Bind(&b); 1227 m.Bind(&b);
1179 m.Return(m.Int32Constant(0)); 1228 m.Return(m.Int32Constant(0));
1180 Stream s = m.Build(); 1229 Stream s = m.Build();
1181 ASSERT_EQ(1U, s.size()); 1230 ASSERT_EQ(1U, s.size());
1182 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); 1231 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode());
1183 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 1232 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
1184 EXPECT_EQ(3U, s[0]->InputCount()); 1233 EXPECT_EQ(3U, s[0]->InputCount());
1185 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 1234 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1186 } 1235 }
1187 1236
1188 { 1237 {
1189 StreamBuilder m(this, kMachInt32, kMachInt32); 1238 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1190 RawMachineLabel a, b; 1239 RawMachineLabel a, b;
1191 Node* p0 = m.Parameter(0); 1240 Node* p0 = m.Parameter(0);
1192 m.Branch(m.Word32BinaryNot(p0), &a, &b); 1241 m.Branch(m.Word32BinaryNot(p0), &a, &b);
1193 m.Bind(&a); 1242 m.Bind(&a);
1194 m.Return(m.Int32Constant(1)); 1243 m.Return(m.Int32Constant(1));
1195 m.Bind(&b); 1244 m.Bind(&b);
1196 m.Return(m.Int32Constant(0)); 1245 m.Return(m.Int32Constant(0));
1197 Stream s = m.Build(); 1246 Stream s = m.Build();
1198 ASSERT_EQ(1U, s.size()); 1247 ASSERT_EQ(1U, s.size());
1199 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); 1248 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode());
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 } 1408 }
1360 1409
1361 1410
1362 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, 1411 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1363 InstructionSelectorOvfAddSubTest, 1412 InstructionSelectorOvfAddSubTest,
1364 ::testing::ValuesIn(kOvfAddSubInstructions)); 1413 ::testing::ValuesIn(kOvfAddSubInstructions));
1365 1414
1366 1415
1367 TEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) { 1416 TEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) {
1368 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 1417 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
1369 StreamBuilder m(this, kMachInt32, kMachInt32); 1418 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1370 m.Return(m.Projection( 1419 m.Return(m.Projection(
1371 1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); 1420 1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
1372 Stream s = m.Build(); 1421 Stream s = m.Build();
1373 1422
1374 ASSERT_EQ(1U, s.size()); 1423 ASSERT_EQ(1U, s.size());
1375 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1424 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1376 EXPECT_EQ(2U, s[0]->InputCount()); 1425 EXPECT_EQ(2U, s[0]->InputCount());
1377 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 1426 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1378 EXPECT_LE(1U, s[0]->OutputCount()); 1427 EXPECT_LE(1U, s[0]->OutputCount());
1379 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 1428 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1380 EXPECT_EQ(kOverflow, s[0]->flags_condition()); 1429 EXPECT_EQ(kOverflow, s[0]->flags_condition());
1381 } 1430 }
1382 } 1431 }
1383 1432
1384 1433
1385 TEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) { 1434 TEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) {
1386 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 1435 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
1387 StreamBuilder m(this, kMachInt32, kMachInt32); 1436 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1388 m.Return(m.Projection( 1437 m.Return(m.Projection(
1389 0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)))); 1438 0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
1390 Stream s = m.Build(); 1439 Stream s = m.Build();
1391 1440
1392 ASSERT_EQ(1U, s.size()); 1441 ASSERT_EQ(1U, s.size());
1393 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1442 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1394 ASSERT_EQ(2U, s[0]->InputCount()); 1443 ASSERT_EQ(2U, s[0]->InputCount());
1395 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 1444 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1396 EXPECT_LE(1U, s[0]->OutputCount()); 1445 EXPECT_LE(1U, s[0]->OutputCount());
1397 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); 1446 EXPECT_EQ(kFlags_none, s[0]->flags_mode());
1398 } 1447 }
1399 } 1448 }
1400 1449
1401 1450
1402 TEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) { 1451 TEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) {
1403 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 1452 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
1404 StreamBuilder m(this, kMachInt32, kMachInt32); 1453 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1405 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)); 1454 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
1406 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n))); 1455 m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
1407 Stream s = m.Build(); 1456 Stream s = m.Build();
1408 1457
1409 ASSERT_LE(1U, s.size()); 1458 ASSERT_LE(1U, s.size());
1410 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1459 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1411 ASSERT_EQ(2U, s[0]->InputCount()); 1460 ASSERT_EQ(2U, s[0]->InputCount());
1412 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 1461 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1413 EXPECT_EQ(2U, s[0]->OutputCount()); 1462 EXPECT_EQ(2U, s[0]->OutputCount());
1414 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 1463 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1415 EXPECT_EQ(kOverflow, s[0]->flags_condition()); 1464 EXPECT_EQ(kOverflow, s[0]->flags_condition());
1416 } 1465 }
1417 } 1466 }
1418 1467
1419 1468
1420 TEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) { 1469 TEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) {
1421 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { 1470 TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
1422 StreamBuilder m(this, kMachInt32, kMachInt32); 1471 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1423 RawMachineLabel a, b; 1472 RawMachineLabel a, b;
1424 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0)); 1473 Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
1425 m.Branch(m.Projection(1, n), &a, &b); 1474 m.Branch(m.Projection(1, n), &a, &b);
1426 m.Bind(&a); 1475 m.Bind(&a);
1427 m.Return(m.Int32Constant(0)); 1476 m.Return(m.Int32Constant(0));
1428 m.Bind(&b); 1477 m.Bind(&b);
1429 m.Return(m.Projection(0, n)); 1478 m.Return(m.Projection(0, n));
1430 Stream s = m.Build(); 1479 Stream s = m.Build();
1431 1480
1432 ASSERT_EQ(1U, s.size()); 1481 ASSERT_EQ(1U, s.size());
(...skipping 23 matching lines...) Expand all
1456 ASSERT_EQ(1U, s.size()); 1505 ASSERT_EQ(1U, s.size());
1457 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode()); 1506 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode());
1458 EXPECT_EQ(2U, s[0]->InputCount()); 1507 EXPECT_EQ(2U, s[0]->InputCount());
1459 EXPECT_EQ(1U, s[0]->OutputCount()); 1508 EXPECT_EQ(1U, s[0]->OutputCount());
1460 } 1509 }
1461 1510
1462 1511
1463 TEST_P(InstructionSelectorShiftTest, Immediate) { 1512 TEST_P(InstructionSelectorShiftTest, Immediate) {
1464 const Shift shift = GetParam(); 1513 const Shift shift = GetParam();
1465 const MachineType type = shift.mi.machine_type; 1514 const MachineType type = shift.mi.machine_type;
1466 TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) { 1515 TRACED_FORRANGE(int32_t, imm, 0,
1516 ((1 << ElementSizeLog2Of(type.representation())) * 8) - 1) {
1467 StreamBuilder m(this, type, type); 1517 StreamBuilder m(this, type, type);
1468 m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Int32Constant(imm))); 1518 m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
1469 Stream s = m.Build(); 1519 Stream s = m.Build();
1470 ASSERT_EQ(1U, s.size()); 1520 ASSERT_EQ(1U, s.size());
1471 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode()); 1521 EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode());
1472 EXPECT_EQ(2U, s[0]->InputCount()); 1522 EXPECT_EQ(2U, s[0]->InputCount());
1473 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 1523 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
1474 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); 1524 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
1475 EXPECT_EQ(1U, s[0]->OutputCount()); 1525 EXPECT_EQ(1U, s[0]->OutputCount());
1476 } 1526 }
1477 } 1527 }
1478 1528
1479 1529
1480 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest, 1530 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
1481 ::testing::ValuesIn(kShiftInstructions)); 1531 ::testing::ValuesIn(kShiftInstructions));
1482 1532
1483 1533
1484 TEST_F(InstructionSelectorTest, Word64ShlWithChangeInt32ToInt64) { 1534 TEST_F(InstructionSelectorTest, Word64ShlWithChangeInt32ToInt64) {
1485 TRACED_FORRANGE(int64_t, x, 32, 63) { 1535 TRACED_FORRANGE(int64_t, x, 32, 63) {
1486 StreamBuilder m(this, kMachInt64, kMachInt32); 1536 StreamBuilder m(this, MachineType::Int64(), MachineType::Int32());
1487 Node* const p0 = m.Parameter(0); 1537 Node* const p0 = m.Parameter(0);
1488 Node* const n = m.Word64Shl(m.ChangeInt32ToInt64(p0), m.Int64Constant(x)); 1538 Node* const n = m.Word64Shl(m.ChangeInt32ToInt64(p0), m.Int64Constant(x));
1489 m.Return(n); 1539 m.Return(n);
1490 Stream s = m.Build(); 1540 Stream s = m.Build();
1491 ASSERT_EQ(1U, s.size()); 1541 ASSERT_EQ(1U, s.size());
1492 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode()); 1542 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode());
1493 ASSERT_EQ(2U, s[0]->InputCount()); 1543 ASSERT_EQ(2U, s[0]->InputCount());
1494 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 1544 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1495 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); 1545 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1)));
1496 ASSERT_EQ(1U, s[0]->OutputCount()); 1546 ASSERT_EQ(1U, s[0]->OutputCount());
1497 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 1547 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1498 } 1548 }
1499 } 1549 }
1500 1550
1501 1551
1502 TEST_F(InstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) { 1552 TEST_F(InstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) {
1503 TRACED_FORRANGE(int64_t, x, 32, 63) { 1553 TRACED_FORRANGE(int64_t, x, 32, 63) {
1504 StreamBuilder m(this, kMachInt64, kMachUint32); 1554 StreamBuilder m(this, MachineType::Int64(), MachineType::Uint32());
1505 Node* const p0 = m.Parameter(0); 1555 Node* const p0 = m.Parameter(0);
1506 Node* const n = m.Word64Shl(m.ChangeUint32ToUint64(p0), m.Int64Constant(x)); 1556 Node* const n = m.Word64Shl(m.ChangeUint32ToUint64(p0), m.Int64Constant(x));
1507 m.Return(n); 1557 m.Return(n);
1508 Stream s = m.Build(); 1558 Stream s = m.Build();
1509 ASSERT_EQ(1U, s.size()); 1559 ASSERT_EQ(1U, s.size());
1510 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode()); 1560 EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode());
1511 ASSERT_EQ(2U, s[0]->InputCount()); 1561 ASSERT_EQ(2U, s[0]->InputCount());
1512 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 1562 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
1513 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); 1563 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1)));
1514 ASSERT_EQ(1U, s[0]->OutputCount()); 1564 ASSERT_EQ(1U, s[0]->OutputCount());
1515 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 1565 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
1516 } 1566 }
1517 } 1567 }
1518 1568
1519 1569
1520 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) { 1570 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) {
1521 StreamBuilder m(this, kMachInt32, kMachInt64); 1571 StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
1522 Node* const p = m.Parameter(0); 1572 Node* const p = m.Parameter(0);
1523 Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32))); 1573 Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32)));
1524 m.Return(t); 1574 m.Return(t);
1525 Stream s = m.Build(); 1575 Stream s = m.Build();
1526 ASSERT_EQ(1U, s.size()); 1576 ASSERT_EQ(1U, s.size());
1527 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode()); 1577 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode());
1528 ASSERT_EQ(2U, s[0]->InputCount()); 1578 ASSERT_EQ(2U, s[0]->InputCount());
1529 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0))); 1579 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
1530 EXPECT_EQ(32, s.ToInt64(s[0]->InputAt(1))); 1580 EXPECT_EQ(32, s.ToInt64(s[0]->InputAt(1)));
1531 ASSERT_EQ(1U, s[0]->OutputCount()); 1581 ASSERT_EQ(1U, s[0]->OutputCount());
1532 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0))); 1582 EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
1533 } 1583 }
1534 1584
1535 1585
1536 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) { 1586 TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) {
1537 TRACED_FORRANGE(int64_t, x, 32, 63) { 1587 TRACED_FORRANGE(int64_t, x, 32, 63) {
1538 StreamBuilder m(this, kMachInt32, kMachInt64); 1588 StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
1539 Node* const p = m.Parameter(0); 1589 Node* const p = m.Parameter(0);
1540 Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(x))); 1590 Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(x)));
1541 m.Return(t); 1591 m.Return(t);
1542 Stream s = m.Build(); 1592 Stream s = m.Build();
1543 ASSERT_EQ(1U, s.size()); 1593 ASSERT_EQ(1U, s.size());
1544 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode()); 1594 EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode());
1545 ASSERT_EQ(2U, s[0]->InputCount()); 1595 ASSERT_EQ(2U, s[0]->InputCount());
1546 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0))); 1596 EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
1547 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1))); 1597 EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1)));
1548 ASSERT_EQ(1U, s[0]->OutputCount()); 1598 ASSERT_EQ(1U, s[0]->OutputCount());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 std::ostream& operator<<(std::ostream& os, const MulDPInst& inst) { 1643 std::ostream& operator<<(std::ostream& os, const MulDPInst& inst) {
1594 return os << inst.mul_constructor_name; 1644 return os << inst.mul_constructor_name;
1595 } 1645 }
1596 1646
1597 } // namespace 1647 } // namespace
1598 1648
1599 1649
1600 static const MulDPInst kMulDPInstructions[] = { 1650 static const MulDPInst kMulDPInstructions[] = {
1601 {"Int32Mul", &RawMachineAssembler::Int32Mul, &RawMachineAssembler::Int32Add, 1651 {"Int32Mul", &RawMachineAssembler::Int32Mul, &RawMachineAssembler::Int32Add,
1602 &RawMachineAssembler::Int32Sub, kArm64Madd32, kArm64Msub32, kArm64Mneg32, 1652 &RawMachineAssembler::Int32Sub, kArm64Madd32, kArm64Msub32, kArm64Mneg32,
1603 kMachInt32}, 1653 MachineType::Int32()},
1604 {"Int64Mul", &RawMachineAssembler::Int64Mul, &RawMachineAssembler::Int64Add, 1654 {"Int64Mul", &RawMachineAssembler::Int64Mul, &RawMachineAssembler::Int64Add,
1605 &RawMachineAssembler::Int64Sub, kArm64Madd, kArm64Msub, kArm64Mneg, 1655 &RawMachineAssembler::Int64Sub, kArm64Madd, kArm64Msub, kArm64Mneg,
1606 kMachInt64}}; 1656 MachineType::Int64()}};
1607 1657
1608 1658
1609 typedef InstructionSelectorTestWithParam<MulDPInst> 1659 typedef InstructionSelectorTestWithParam<MulDPInst>
1610 InstructionSelectorIntDPWithIntMulTest; 1660 InstructionSelectorIntDPWithIntMulTest;
1611 1661
1612 1662
1613 TEST_P(InstructionSelectorIntDPWithIntMulTest, AddWithMul) { 1663 TEST_P(InstructionSelectorIntDPWithIntMulTest, AddWithMul) {
1614 const MulDPInst mdpi = GetParam(); 1664 const MulDPInst mdpi = GetParam();
1615 const MachineType type = mdpi.machine_type; 1665 const MachineType type = mdpi.machine_type;
1616 { 1666 {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 1731
1682 1732
1683 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, 1733 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
1684 InstructionSelectorIntDPWithIntMulTest, 1734 InstructionSelectorIntDPWithIntMulTest,
1685 ::testing::ValuesIn(kMulDPInstructions)); 1735 ::testing::ValuesIn(kMulDPInstructions));
1686 1736
1687 1737
1688 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) { 1738 TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
1689 // x * (2^k + 1) -> x + (x << k) 1739 // x * (2^k + 1) -> x + (x << k)
1690 TRACED_FORRANGE(int32_t, k, 1, 30) { 1740 TRACED_FORRANGE(int32_t, k, 1, 30) {
1691 StreamBuilder m(this, kMachInt32, kMachInt32); 1741 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1692 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1))); 1742 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
1693 Stream s = m.Build(); 1743 Stream s = m.Build();
1694 ASSERT_EQ(1U, s.size()); 1744 ASSERT_EQ(1U, s.size());
1695 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1745 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1696 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1746 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1697 ASSERT_EQ(3U, s[0]->InputCount()); 1747 ASSERT_EQ(3U, s[0]->InputCount());
1698 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1748 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1699 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1749 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1700 EXPECT_EQ(1U, s[0]->OutputCount()); 1750 EXPECT_EQ(1U, s[0]->OutputCount());
1701 } 1751 }
1702 // (2^k + 1) * x -> x + (x << k) 1752 // (2^k + 1) * x -> x + (x << k)
1703 TRACED_FORRANGE(int32_t, k, 1, 30) { 1753 TRACED_FORRANGE(int32_t, k, 1, 30) {
1704 StreamBuilder m(this, kMachInt32, kMachInt32); 1754 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
1705 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0))); 1755 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
1706 Stream s = m.Build(); 1756 Stream s = m.Build();
1707 ASSERT_EQ(1U, s.size()); 1757 ASSERT_EQ(1U, s.size());
1708 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1758 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1709 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1759 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1710 ASSERT_EQ(3U, s[0]->InputCount()); 1760 ASSERT_EQ(3U, s[0]->InputCount());
1711 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1761 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1712 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1762 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1713 EXPECT_EQ(1U, s[0]->OutputCount()); 1763 EXPECT_EQ(1U, s[0]->OutputCount());
1714 } 1764 }
1715 // x * (2^k + 1) + c -> x + (x << k) + c 1765 // x * (2^k + 1) + c -> x + (x << k) + c
1716 TRACED_FORRANGE(int32_t, k, 1, 30) { 1766 TRACED_FORRANGE(int32_t, k, 1, 30) {
1717 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 1767 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
1768 MachineType::Int32());
1718 m.Return( 1769 m.Return(
1719 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)), 1770 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)),
1720 m.Parameter(1))); 1771 m.Parameter(1)));
1721 Stream s = m.Build(); 1772 Stream s = m.Build();
1722 ASSERT_EQ(2U, s.size()); 1773 ASSERT_EQ(2U, s.size());
1723 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1774 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1724 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); 1775 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
1725 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1776 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1726 ASSERT_EQ(3U, s[0]->InputCount()); 1777 ASSERT_EQ(3U, s[0]->InputCount());
1727 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1778 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1728 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1779 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1729 EXPECT_EQ(1U, s[0]->OutputCount()); 1780 EXPECT_EQ(1U, s[0]->OutputCount());
1730 } 1781 }
1731 // (2^k + 1) * x + c -> x + (x << k) + c 1782 // (2^k + 1) * x + c -> x + (x << k) + c
1732 TRACED_FORRANGE(int32_t, k, 1, 30) { 1783 TRACED_FORRANGE(int32_t, k, 1, 30) {
1733 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 1784 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
1785 MachineType::Int32());
1734 m.Return( 1786 m.Return(
1735 m.Int32Add(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)), 1787 m.Int32Add(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)),
1736 m.Parameter(1))); 1788 m.Parameter(1)));
1737 Stream s = m.Build(); 1789 Stream s = m.Build();
1738 ASSERT_EQ(2U, s.size()); 1790 ASSERT_EQ(2U, s.size());
1739 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1791 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1740 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); 1792 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
1741 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1793 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1742 ASSERT_EQ(3U, s[0]->InputCount()); 1794 ASSERT_EQ(3U, s[0]->InputCount());
1743 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1795 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1744 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1796 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1745 EXPECT_EQ(1U, s[0]->OutputCount()); 1797 EXPECT_EQ(1U, s[0]->OutputCount());
1746 } 1798 }
1747 // c + x * (2^k + 1) -> c + x + (x << k) 1799 // c + x * (2^k + 1) -> c + x + (x << k)
1748 TRACED_FORRANGE(int32_t, k, 1, 30) { 1800 TRACED_FORRANGE(int32_t, k, 1, 30) {
1749 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 1801 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
1802 MachineType::Int32());
1750 m.Return( 1803 m.Return(
1751 m.Int32Add(m.Parameter(0), 1804 m.Int32Add(m.Parameter(0),
1752 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1)))); 1805 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1))));
1753 Stream s = m.Build(); 1806 Stream s = m.Build();
1754 ASSERT_EQ(2U, s.size()); 1807 ASSERT_EQ(2U, s.size());
1755 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1808 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1756 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); 1809 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
1757 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1810 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1758 ASSERT_EQ(3U, s[0]->InputCount()); 1811 ASSERT_EQ(3U, s[0]->InputCount());
1759 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); 1812 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
1760 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1813 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1761 EXPECT_EQ(1U, s[0]->OutputCount()); 1814 EXPECT_EQ(1U, s[0]->OutputCount());
1762 } 1815 }
1763 // c + (2^k + 1) * x -> c + x + (x << k) 1816 // c + (2^k + 1) * x -> c + x + (x << k)
1764 TRACED_FORRANGE(int32_t, k, 1, 30) { 1817 TRACED_FORRANGE(int32_t, k, 1, 30) {
1765 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 1818 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
1819 MachineType::Int32());
1766 m.Return( 1820 m.Return(
1767 m.Int32Add(m.Parameter(0), 1821 m.Int32Add(m.Parameter(0),
1768 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1)))); 1822 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1))));
1769 Stream s = m.Build(); 1823 Stream s = m.Build();
1770 ASSERT_EQ(2U, s.size()); 1824 ASSERT_EQ(2U, s.size());
1771 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1825 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1772 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode()); 1826 EXPECT_EQ(kArm64Add32, s[1]->arch_opcode());
1773 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1827 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1774 ASSERT_EQ(3U, s[0]->InputCount()); 1828 ASSERT_EQ(3U, s[0]->InputCount());
1775 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); 1829 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
1776 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1830 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1777 EXPECT_EQ(1U, s[0]->OutputCount()); 1831 EXPECT_EQ(1U, s[0]->OutputCount());
1778 } 1832 }
1779 // c - x * (2^k + 1) -> c - x + (x << k) 1833 // c - x * (2^k + 1) -> c - x + (x << k)
1780 TRACED_FORRANGE(int32_t, k, 1, 30) { 1834 TRACED_FORRANGE(int32_t, k, 1, 30) {
1781 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 1835 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
1836 MachineType::Int32());
1782 m.Return( 1837 m.Return(
1783 m.Int32Sub(m.Parameter(0), 1838 m.Int32Sub(m.Parameter(0),
1784 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1)))); 1839 m.Int32Mul(m.Parameter(1), m.Int32Constant((1 << k) + 1))));
1785 Stream s = m.Build(); 1840 Stream s = m.Build();
1786 ASSERT_EQ(2U, s.size()); 1841 ASSERT_EQ(2U, s.size());
1787 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1842 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1788 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode()); 1843 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode());
1789 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1844 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1790 ASSERT_EQ(3U, s[0]->InputCount()); 1845 ASSERT_EQ(3U, s[0]->InputCount());
1791 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); 1846 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
1792 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1847 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1793 EXPECT_EQ(1U, s[0]->OutputCount()); 1848 EXPECT_EQ(1U, s[0]->OutputCount());
1794 } 1849 }
1795 // c - (2^k + 1) * x -> c - x + (x << k) 1850 // c - (2^k + 1) * x -> c - x + (x << k)
1796 TRACED_FORRANGE(int32_t, k, 1, 30) { 1851 TRACED_FORRANGE(int32_t, k, 1, 30) {
1797 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 1852 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
1853 MachineType::Int32());
1798 m.Return( 1854 m.Return(
1799 m.Int32Sub(m.Parameter(0), 1855 m.Int32Sub(m.Parameter(0),
1800 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1)))); 1856 m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(1))));
1801 Stream s = m.Build(); 1857 Stream s = m.Build();
1802 ASSERT_EQ(2U, s.size()); 1858 ASSERT_EQ(2U, s.size());
1803 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode()); 1859 EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
1804 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode()); 1860 EXPECT_EQ(kArm64Sub32, s[1]->arch_opcode());
1805 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1861 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1806 ASSERT_EQ(3U, s[0]->InputCount()); 1862 ASSERT_EQ(3U, s[0]->InputCount());
1807 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1))); 1863 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[0]->InputAt(1)));
1808 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2))); 1864 EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
1809 EXPECT_EQ(1U, s[0]->OutputCount()); 1865 EXPECT_EQ(1U, s[0]->OutputCount());
1810 } 1866 }
1811 } 1867 }
1812 1868
1813 1869
1814 TEST_F(InstructionSelectorTest, Int64MulWithImmediate) { 1870 TEST_F(InstructionSelectorTest, Int64MulWithImmediate) {
1815 // x * (2^k + 1) -> x + (x << k) 1871 // x * (2^k + 1) -> x + (x << k)
1816 TRACED_FORRANGE(int64_t, k, 1, 62) { 1872 TRACED_FORRANGE(int64_t, k, 1, 62) {
1817 StreamBuilder m(this, kMachInt64, kMachInt64); 1873 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
1818 m.Return(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1))); 1874 m.Return(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1)));
1819 Stream s = m.Build(); 1875 Stream s = m.Build();
1820 ASSERT_EQ(1U, s.size()); 1876 ASSERT_EQ(1U, s.size());
1821 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1877 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1822 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1878 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1823 ASSERT_EQ(3U, s[0]->InputCount()); 1879 ASSERT_EQ(3U, s[0]->InputCount());
1824 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1880 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1825 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); 1881 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
1826 EXPECT_EQ(1U, s[0]->OutputCount()); 1882 EXPECT_EQ(1U, s[0]->OutputCount());
1827 } 1883 }
1828 // (2^k + 1) * x -> x + (x << k) 1884 // (2^k + 1) * x -> x + (x << k)
1829 TRACED_FORRANGE(int64_t, k, 1, 62) { 1885 TRACED_FORRANGE(int64_t, k, 1, 62) {
1830 StreamBuilder m(this, kMachInt64, kMachInt64); 1886 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
1831 m.Return(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0))); 1887 m.Return(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0)));
1832 Stream s = m.Build(); 1888 Stream s = m.Build();
1833 ASSERT_EQ(1U, s.size()); 1889 ASSERT_EQ(1U, s.size());
1834 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1890 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1835 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1891 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1836 ASSERT_EQ(3U, s[0]->InputCount()); 1892 ASSERT_EQ(3U, s[0]->InputCount());
1837 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1893 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1838 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); 1894 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
1839 EXPECT_EQ(1U, s[0]->OutputCount()); 1895 EXPECT_EQ(1U, s[0]->OutputCount());
1840 } 1896 }
1841 // x * (2^k + 1) + c -> x + (x << k) + c 1897 // x * (2^k + 1) + c -> x + (x << k) + c
1842 TRACED_FORRANGE(int64_t, k, 1, 62) { 1898 TRACED_FORRANGE(int64_t, k, 1, 62) {
1843 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 1899 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
1900 MachineType::Int64());
1844 m.Return( 1901 m.Return(
1845 m.Int64Add(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1)), 1902 m.Int64Add(m.Int64Mul(m.Parameter(0), m.Int64Constant((1L << k) + 1)),
1846 m.Parameter(1))); 1903 m.Parameter(1)));
1847 Stream s = m.Build(); 1904 Stream s = m.Build();
1848 ASSERT_EQ(2U, s.size()); 1905 ASSERT_EQ(2U, s.size());
1849 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1906 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1850 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); 1907 EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
1851 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1908 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1852 ASSERT_EQ(3U, s[0]->InputCount()); 1909 ASSERT_EQ(3U, s[0]->InputCount());
1853 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1910 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1854 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); 1911 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
1855 EXPECT_EQ(1U, s[0]->OutputCount()); 1912 EXPECT_EQ(1U, s[0]->OutputCount());
1856 } 1913 }
1857 // (2^k + 1) * x + c -> x + (x << k) + c 1914 // (2^k + 1) * x + c -> x + (x << k) + c
1858 TRACED_FORRANGE(int64_t, k, 1, 62) { 1915 TRACED_FORRANGE(int64_t, k, 1, 62) {
1859 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 1916 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
1917 MachineType::Int64());
1860 m.Return( 1918 m.Return(
1861 m.Int64Add(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0)), 1919 m.Int64Add(m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(0)),
1862 m.Parameter(1))); 1920 m.Parameter(1)));
1863 Stream s = m.Build(); 1921 Stream s = m.Build();
1864 ASSERT_EQ(2U, s.size()); 1922 ASSERT_EQ(2U, s.size());
1865 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1923 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1866 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); 1924 EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
1867 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1925 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1868 ASSERT_EQ(3U, s[0]->InputCount()); 1926 ASSERT_EQ(3U, s[0]->InputCount());
1869 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1927 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1870 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); 1928 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
1871 EXPECT_EQ(1U, s[0]->OutputCount()); 1929 EXPECT_EQ(1U, s[0]->OutputCount());
1872 } 1930 }
1873 // c + x * (2^k + 1) -> c + x + (x << k) 1931 // c + x * (2^k + 1) -> c + x + (x << k)
1874 TRACED_FORRANGE(int64_t, k, 1, 62) { 1932 TRACED_FORRANGE(int64_t, k, 1, 62) {
1875 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 1933 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
1934 MachineType::Int64());
1876 m.Return( 1935 m.Return(
1877 m.Int64Add(m.Parameter(0), 1936 m.Int64Add(m.Parameter(0),
1878 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1)))); 1937 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1))));
1879 Stream s = m.Build(); 1938 Stream s = m.Build();
1880 ASSERT_EQ(2U, s.size()); 1939 ASSERT_EQ(2U, s.size());
1881 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1940 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1882 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); 1941 EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
1883 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1942 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1884 ASSERT_EQ(3U, s[0]->InputCount()); 1943 ASSERT_EQ(3U, s[0]->InputCount());
1885 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1944 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1886 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); 1945 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
1887 EXPECT_EQ(1U, s[0]->OutputCount()); 1946 EXPECT_EQ(1U, s[0]->OutputCount());
1888 } 1947 }
1889 // c + (2^k + 1) * x -> c + x + (x << k) 1948 // c + (2^k + 1) * x -> c + x + (x << k)
1890 TRACED_FORRANGE(int64_t, k, 1, 62) { 1949 TRACED_FORRANGE(int64_t, k, 1, 62) {
1891 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 1950 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
1951 MachineType::Int64());
1892 m.Return( 1952 m.Return(
1893 m.Int64Add(m.Parameter(0), 1953 m.Int64Add(m.Parameter(0),
1894 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1)))); 1954 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1))));
1895 Stream s = m.Build(); 1955 Stream s = m.Build();
1896 ASSERT_EQ(2U, s.size()); 1956 ASSERT_EQ(2U, s.size());
1897 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1957 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1898 EXPECT_EQ(kArm64Add, s[1]->arch_opcode()); 1958 EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
1899 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1959 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1900 ASSERT_EQ(3U, s[0]->InputCount()); 1960 ASSERT_EQ(3U, s[0]->InputCount());
1901 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1961 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1902 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); 1962 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
1903 EXPECT_EQ(1U, s[0]->OutputCount()); 1963 EXPECT_EQ(1U, s[0]->OutputCount());
1904 } 1964 }
1905 // c - x * (2^k + 1) -> c - x + (x << k) 1965 // c - x * (2^k + 1) -> c - x + (x << k)
1906 TRACED_FORRANGE(int64_t, k, 1, 62) { 1966 TRACED_FORRANGE(int64_t, k, 1, 62) {
1907 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 1967 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
1968 MachineType::Int64());
1908 m.Return( 1969 m.Return(
1909 m.Int64Sub(m.Parameter(0), 1970 m.Int64Sub(m.Parameter(0),
1910 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1)))); 1971 m.Int64Mul(m.Parameter(1), m.Int64Constant((1L << k) + 1))));
1911 Stream s = m.Build(); 1972 Stream s = m.Build();
1912 ASSERT_EQ(2U, s.size()); 1973 ASSERT_EQ(2U, s.size());
1913 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1974 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1914 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode()); 1975 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode());
1915 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1976 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1916 ASSERT_EQ(3U, s[0]->InputCount()); 1977 ASSERT_EQ(3U, s[0]->InputCount());
1917 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1978 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
1918 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2))); 1979 EXPECT_EQ(k, s.ToInt64(s[0]->InputAt(2)));
1919 EXPECT_EQ(1U, s[0]->OutputCount()); 1980 EXPECT_EQ(1U, s[0]->OutputCount());
1920 } 1981 }
1921 // c - (2^k + 1) * x -> c - x + (x << k) 1982 // c - (2^k + 1) * x -> c - x + (x << k)
1922 TRACED_FORRANGE(int64_t, k, 1, 62) { 1983 TRACED_FORRANGE(int64_t, k, 1, 62) {
1923 StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64); 1984 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64(),
1985 MachineType::Int64());
1924 m.Return( 1986 m.Return(
1925 m.Int64Sub(m.Parameter(0), 1987 m.Int64Sub(m.Parameter(0),
1926 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1)))); 1988 m.Int64Mul(m.Int64Constant((1L << k) + 1), m.Parameter(1))));
1927 Stream s = m.Build(); 1989 Stream s = m.Build();
1928 ASSERT_EQ(2U, s.size()); 1990 ASSERT_EQ(2U, s.size());
1929 EXPECT_EQ(kArm64Add, s[0]->arch_opcode()); 1991 EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
1930 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode()); 1992 EXPECT_EQ(kArm64Sub, s[1]->arch_opcode());
1931 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode()); 1993 EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
1932 ASSERT_EQ(3U, s[0]->InputCount()); 1994 ASSERT_EQ(3U, s[0]->InputCount());
1933 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 1995 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
(...skipping 24 matching lines...) Expand all
1958 2020
1959 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest, 2021 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
1960 ::testing::ValuesIn(kFPArithInstructions)); 2022 ::testing::ValuesIn(kFPArithInstructions));
1961 2023
1962 2024
1963 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest; 2025 typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
1964 2026
1965 2027
1966 TEST_P(InstructionSelectorFPCmpTest, Parameter) { 2028 TEST_P(InstructionSelectorFPCmpTest, Parameter) {
1967 const FPCmp cmp = GetParam(); 2029 const FPCmp cmp = GetParam();
1968 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type); 2030 StreamBuilder m(this, MachineType::Int32(), cmp.mi.machine_type,
2031 cmp.mi.machine_type);
1969 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1))); 2032 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
1970 Stream s = m.Build(); 2033 Stream s = m.Build();
1971 ASSERT_EQ(1U, s.size()); 2034 ASSERT_EQ(1U, s.size());
1972 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); 2035 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
1973 EXPECT_EQ(2U, s[0]->InputCount()); 2036 EXPECT_EQ(2U, s[0]->InputCount());
1974 EXPECT_EQ(1U, s[0]->OutputCount()); 2037 EXPECT_EQ(1U, s[0]->OutputCount());
1975 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2038 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1976 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); 2039 EXPECT_EQ(cmp.cond, s[0]->flags_condition());
1977 } 2040 }
1978 2041
1979 2042
1980 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnRight) { 2043 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnRight) {
1981 const FPCmp cmp = GetParam(); 2044 const FPCmp cmp = GetParam();
1982 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type); 2045 StreamBuilder m(this, MachineType::Int32(), cmp.mi.machine_type);
1983 if (cmp.mi.machine_type == kMachFloat64) { 2046 if (cmp.mi.machine_type == MachineType::Float64()) {
1984 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float64Constant(0.0))); 2047 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float64Constant(0.0)));
1985 } else { 2048 } else {
1986 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float32Constant(0.0f))); 2049 m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Float32Constant(0.0f)));
1987 } 2050 }
1988 Stream s = m.Build(); 2051 Stream s = m.Build();
1989 ASSERT_EQ(1U, s.size()); 2052 ASSERT_EQ(1U, s.size());
1990 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); 2053 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
1991 EXPECT_EQ(2U, s[0]->InputCount()); 2054 EXPECT_EQ(2U, s[0]->InputCount());
1992 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 2055 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
1993 EXPECT_EQ(1U, s[0]->OutputCount()); 2056 EXPECT_EQ(1U, s[0]->OutputCount());
1994 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2057 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
1995 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); 2058 EXPECT_EQ(cmp.cond, s[0]->flags_condition());
1996 } 2059 }
1997 2060
1998 2061
1999 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnLeft) { 2062 TEST_P(InstructionSelectorFPCmpTest, WithImmediateZeroOnLeft) {
2000 const FPCmp cmp = GetParam(); 2063 const FPCmp cmp = GetParam();
2001 StreamBuilder m(this, kMachInt32, cmp.mi.machine_type); 2064 StreamBuilder m(this, MachineType::Int32(), cmp.mi.machine_type);
2002 if (cmp.mi.machine_type == kMachFloat64) { 2065 if (cmp.mi.machine_type == MachineType::Float64()) {
2003 m.Return((m.*cmp.mi.constructor)(m.Float64Constant(0.0), m.Parameter(0))); 2066 m.Return((m.*cmp.mi.constructor)(m.Float64Constant(0.0), m.Parameter(0)));
2004 } else { 2067 } else {
2005 m.Return((m.*cmp.mi.constructor)(m.Float32Constant(0.0f), m.Parameter(0))); 2068 m.Return((m.*cmp.mi.constructor)(m.Float32Constant(0.0f), m.Parameter(0)));
2006 } 2069 }
2007 Stream s = m.Build(); 2070 Stream s = m.Build();
2008 ASSERT_EQ(1U, s.size()); 2071 ASSERT_EQ(1U, s.size());
2009 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode()); 2072 EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
2010 EXPECT_EQ(2U, s[0]->InputCount()); 2073 EXPECT_EQ(2U, s[0]->InputCount());
2011 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate()); 2074 EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
2012 EXPECT_EQ(1U, s[0]->OutputCount()); 2075 EXPECT_EQ(1U, s[0]->OutputCount());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2058 2121
2059 2122
2060 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) { 2123 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
2061 return os << memacc.type; 2124 return os << memacc.type;
2062 } 2125 }
2063 2126
2064 } // namespace 2127 } // namespace
2065 2128
2066 2129
2067 static const MemoryAccess kMemoryAccesses[] = { 2130 static const MemoryAccess kMemoryAccesses[] = {
2068 {kMachInt8, 2131 {MachineType::Int8(),
2069 kArm64Ldrsb, 2132 kArm64Ldrsb,
2070 kArm64Strb, 2133 kArm64Strb,
2071 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121, 2134 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121,
2072 2442, 4093, 4094, 4095}}, 2135 2442, 4093, 4094, 4095}},
2073 {kMachUint8, 2136 {MachineType::Uint8(),
2074 kArm64Ldrb, 2137 kArm64Ldrb,
2075 kArm64Strb, 2138 kArm64Strb,
2076 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121, 2139 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121,
2077 2442, 4093, 4094, 4095}}, 2140 2442, 4093, 4094, 4095}},
2078 {kMachInt16, 2141 {MachineType::Int16(),
2079 kArm64Ldrsh, 2142 kArm64Ldrsh,
2080 kArm64Strh, 2143 kArm64Strh,
2081 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100, 2144 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100,
2082 4242, 6786, 8188, 8190}}, 2145 4242, 6786, 8188, 8190}},
2083 {kMachUint16, 2146 {MachineType::Uint16(),
2084 kArm64Ldrh, 2147 kArm64Ldrh,
2085 kArm64Strh, 2148 kArm64Strh,
2086 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100, 2149 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100,
2087 4242, 6786, 8188, 8190}}, 2150 4242, 6786, 8188, 8190}},
2088 {kMachInt32, 2151 {MachineType::Int32(),
2089 kArm64LdrW, 2152 kArm64LdrW,
2090 kArm64StrW, 2153 kArm64StrW,
2091 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, 2154 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196,
2092 3276, 3280, 16376, 16380}}, 2155 3276, 3280, 16376, 16380}},
2093 {kMachUint32, 2156 {MachineType::Uint32(),
2094 kArm64LdrW, 2157 kArm64LdrW,
2095 kArm64StrW, 2158 kArm64StrW,
2096 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, 2159 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196,
2097 3276, 3280, 16376, 16380}}, 2160 3276, 3280, 16376, 16380}},
2098 {kMachInt64, 2161 {MachineType::Int64(),
2099 kArm64Ldr, 2162 kArm64Ldr,
2100 kArm64Str, 2163 kArm64Str,
2101 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, 2164 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200,
2102 16384, 16392, 32752, 32760}}, 2165 16384, 16392, 32752, 32760}},
2103 {kMachUint64, 2166 {MachineType::Uint64(),
2104 kArm64Ldr, 2167 kArm64Ldr,
2105 kArm64Str, 2168 kArm64Str,
2106 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, 2169 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200,
2107 16384, 16392, 32752, 32760}}, 2170 16384, 16392, 32752, 32760}},
2108 {kMachFloat32, 2171 {MachineType::Float32(),
2109 kArm64LdrS, 2172 kArm64LdrS,
2110 kArm64StrS, 2173 kArm64StrS,
2111 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196, 2174 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196,
2112 3276, 3280, 16376, 16380}}, 2175 3276, 3280, 16376, 16380}},
2113 {kMachFloat64, 2176 {MachineType::Float64(),
2114 kArm64LdrD, 2177 kArm64LdrD,
2115 kArm64StrD, 2178 kArm64StrD,
2116 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200, 2179 {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200,
2117 16384, 16392, 32752, 32760}}}; 2180 16384, 16392, 32752, 32760}}};
2118 2181
2119 2182
2120 typedef InstructionSelectorTestWithParam<MemoryAccess> 2183 typedef InstructionSelectorTestWithParam<MemoryAccess>
2121 InstructionSelectorMemoryAccessTest; 2184 InstructionSelectorMemoryAccessTest;
2122 2185
2123 2186
2124 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { 2187 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
2125 const MemoryAccess memacc = GetParam(); 2188 const MemoryAccess memacc = GetParam();
2126 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32); 2189 StreamBuilder m(this, memacc.type, MachineType::Pointer(),
2190 MachineType::Int32());
2127 m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1))); 2191 m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
2128 Stream s = m.Build(); 2192 Stream s = m.Build();
2129 ASSERT_EQ(1U, s.size()); 2193 ASSERT_EQ(1U, s.size());
2130 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); 2194 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
2131 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode()); 2195 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
2132 EXPECT_EQ(2U, s[0]->InputCount()); 2196 EXPECT_EQ(2U, s[0]->InputCount());
2133 EXPECT_EQ(1U, s[0]->OutputCount()); 2197 EXPECT_EQ(1U, s[0]->OutputCount());
2134 } 2198 }
2135 2199
2136 2200
2137 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { 2201 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
2138 const MemoryAccess memacc = GetParam(); 2202 const MemoryAccess memacc = GetParam();
2139 TRACED_FOREACH(int32_t, index, memacc.immediates) { 2203 TRACED_FOREACH(int32_t, index, memacc.immediates) {
2140 StreamBuilder m(this, memacc.type, kMachPtr); 2204 StreamBuilder m(this, memacc.type, MachineType::Pointer());
2141 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); 2205 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
2142 Stream s = m.Build(); 2206 Stream s = m.Build();
2143 ASSERT_EQ(1U, s.size()); 2207 ASSERT_EQ(1U, s.size());
2144 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode()); 2208 EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
2145 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); 2209 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
2146 EXPECT_EQ(2U, s[0]->InputCount()); 2210 EXPECT_EQ(2U, s[0]->InputCount());
2147 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 2211 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
2148 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); 2212 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
2149 ASSERT_EQ(1U, s[0]->OutputCount()); 2213 ASSERT_EQ(1U, s[0]->OutputCount());
2150 } 2214 }
2151 } 2215 }
2152 2216
2153 2217
2154 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { 2218 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
2155 const MemoryAccess memacc = GetParam(); 2219 const MemoryAccess memacc = GetParam();
2156 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); 2220 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
2221 MachineType::Int32(), memacc.type);
2157 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), 2222 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2),
2158 kNoWriteBarrier); 2223 kNoWriteBarrier);
2159 m.Return(m.Int32Constant(0)); 2224 m.Return(m.Int32Constant(0));
2160 Stream s = m.Build(); 2225 Stream s = m.Build();
2161 ASSERT_EQ(1U, s.size()); 2226 ASSERT_EQ(1U, s.size());
2162 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); 2227 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
2163 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode()); 2228 EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
2164 EXPECT_EQ(3U, s[0]->InputCount()); 2229 EXPECT_EQ(3U, s[0]->InputCount());
2165 EXPECT_EQ(0U, s[0]->OutputCount()); 2230 EXPECT_EQ(0U, s[0]->OutputCount());
2166 } 2231 }
2167 2232
2168 2233
2169 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { 2234 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
2170 const MemoryAccess memacc = GetParam(); 2235 const MemoryAccess memacc = GetParam();
2171 TRACED_FOREACH(int32_t, index, memacc.immediates) { 2236 TRACED_FOREACH(int32_t, index, memacc.immediates) {
2172 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); 2237 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
2238 memacc.type);
2173 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), 2239 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1),
2174 kNoWriteBarrier); 2240 kNoWriteBarrier);
2175 m.Return(m.Int32Constant(0)); 2241 m.Return(m.Int32Constant(0));
2176 Stream s = m.Build(); 2242 Stream s = m.Build();
2177 ASSERT_EQ(1U, s.size()); 2243 ASSERT_EQ(1U, s.size());
2178 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode()); 2244 EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
2179 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode()); 2245 EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
2180 ASSERT_EQ(3U, s[0]->InputCount()); 2246 ASSERT_EQ(3U, s[0]->InputCount());
2181 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); 2247 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
2182 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); 2248 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
2183 EXPECT_EQ(0U, s[0]->OutputCount()); 2249 EXPECT_EQ(0U, s[0]->OutputCount());
2184 } 2250 }
2185 } 2251 }
2186 2252
2187 2253
2188 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, 2254 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
2189 InstructionSelectorMemoryAccessTest, 2255 InstructionSelectorMemoryAccessTest,
2190 ::testing::ValuesIn(kMemoryAccesses)); 2256 ::testing::ValuesIn(kMemoryAccesses));
2191 2257
2192 2258
2193 // ----------------------------------------------------------------------------- 2259 // -----------------------------------------------------------------------------
2194 // Comparison instructions. 2260 // Comparison instructions.
2195 2261
2196 static const MachInst2 kComparisonInstructions[] = { 2262 static const MachInst2 kComparisonInstructions[] = {
2197 {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, kMachInt32}, 2263 {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32,
2198 {&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp, kMachInt64}, 2264 MachineType::Int32()},
2265 {&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp,
2266 MachineType::Int64()},
2199 }; 2267 };
2200 2268
2201 2269
2202 typedef InstructionSelectorTestWithParam<MachInst2> 2270 typedef InstructionSelectorTestWithParam<MachInst2>
2203 InstructionSelectorComparisonTest; 2271 InstructionSelectorComparisonTest;
2204 2272
2205 2273
2206 TEST_P(InstructionSelectorComparisonTest, WithParameters) { 2274 TEST_P(InstructionSelectorComparisonTest, WithParameters) {
2207 const MachInst2 cmp = GetParam(); 2275 const MachInst2 cmp = GetParam();
2208 const MachineType type = cmp.machine_type; 2276 const MachineType type = cmp.machine_type;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 } 2321 }
2254 } 2322 }
2255 2323
2256 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, 2324 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
2257 InstructionSelectorComparisonTest, 2325 InstructionSelectorComparisonTest,
2258 ::testing::ValuesIn(kComparisonInstructions)); 2326 ::testing::ValuesIn(kComparisonInstructions));
2259 2327
2260 2328
2261 TEST_F(InstructionSelectorTest, Word32EqualWithZero) { 2329 TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
2262 { 2330 {
2263 StreamBuilder m(this, kMachInt32, kMachInt32); 2331 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2264 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); 2332 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
2265 Stream s = m.Build(); 2333 Stream s = m.Build();
2266 ASSERT_EQ(1U, s.size()); 2334 ASSERT_EQ(1U, s.size());
2267 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); 2335 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
2268 ASSERT_EQ(2U, s[0]->InputCount()); 2336 ASSERT_EQ(2U, s[0]->InputCount());
2269 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 2337 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2270 EXPECT_EQ(1U, s[0]->OutputCount()); 2338 EXPECT_EQ(1U, s[0]->OutputCount());
2271 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2339 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2272 EXPECT_EQ(kEqual, s[0]->flags_condition()); 2340 EXPECT_EQ(kEqual, s[0]->flags_condition());
2273 } 2341 }
2274 { 2342 {
2275 StreamBuilder m(this, kMachInt32, kMachInt32); 2343 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2276 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); 2344 m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
2277 Stream s = m.Build(); 2345 Stream s = m.Build();
2278 ASSERT_EQ(1U, s.size()); 2346 ASSERT_EQ(1U, s.size());
2279 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); 2347 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
2280 ASSERT_EQ(2U, s[0]->InputCount()); 2348 ASSERT_EQ(2U, s[0]->InputCount());
2281 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 2349 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2282 EXPECT_EQ(1U, s[0]->OutputCount()); 2350 EXPECT_EQ(1U, s[0]->OutputCount());
2283 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2351 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2284 EXPECT_EQ(kEqual, s[0]->flags_condition()); 2352 EXPECT_EQ(kEqual, s[0]->flags_condition());
2285 } 2353 }
2286 } 2354 }
2287 2355
2288 2356
2289 TEST_F(InstructionSelectorTest, Word64EqualWithZero) { 2357 TEST_F(InstructionSelectorTest, Word64EqualWithZero) {
2290 { 2358 {
2291 StreamBuilder m(this, kMachInt64, kMachInt64); 2359 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2292 m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0))); 2360 m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0)));
2293 Stream s = m.Build(); 2361 Stream s = m.Build();
2294 ASSERT_EQ(1U, s.size()); 2362 ASSERT_EQ(1U, s.size());
2295 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); 2363 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
2296 ASSERT_EQ(2U, s[0]->InputCount()); 2364 ASSERT_EQ(2U, s[0]->InputCount());
2297 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 2365 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2298 EXPECT_EQ(1U, s[0]->OutputCount()); 2366 EXPECT_EQ(1U, s[0]->OutputCount());
2299 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2367 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2300 EXPECT_EQ(kEqual, s[0]->flags_condition()); 2368 EXPECT_EQ(kEqual, s[0]->flags_condition());
2301 } 2369 }
2302 { 2370 {
2303 StreamBuilder m(this, kMachInt64, kMachInt64); 2371 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2304 m.Return(m.Word64Equal(m.Int64Constant(0), m.Parameter(0))); 2372 m.Return(m.Word64Equal(m.Int64Constant(0), m.Parameter(0)));
2305 Stream s = m.Build(); 2373 Stream s = m.Build();
2306 ASSERT_EQ(1U, s.size()); 2374 ASSERT_EQ(1U, s.size());
2307 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); 2375 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
2308 ASSERT_EQ(2U, s[0]->InputCount()); 2376 ASSERT_EQ(2U, s[0]->InputCount());
2309 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); 2377 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
2310 EXPECT_EQ(1U, s[0]->OutputCount()); 2378 EXPECT_EQ(1U, s[0]->OutputCount());
2311 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2379 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2312 EXPECT_EQ(kEqual, s[0]->flags_condition()); 2380 EXPECT_EQ(kEqual, s[0]->flags_condition());
2313 } 2381 }
2314 } 2382 }
2315 2383
2316 2384
2317 TEST_F(InstructionSelectorTest, Word32EqualWithWord32Shift) { 2385 TEST_F(InstructionSelectorTest, Word32EqualWithWord32Shift) {
2318 TRACED_FOREACH(Shift, shift, kShiftInstructions) { 2386 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
2319 // Skip non 32-bit shifts or ror operations. 2387 // Skip non 32-bit shifts or ror operations.
2320 if (shift.mi.machine_type != kMachInt32 || 2388 if (shift.mi.machine_type != MachineType::Int32() ||
2321 shift.mi.arch_opcode == kArm64Ror32) { 2389 shift.mi.arch_opcode == kArm64Ror32) {
2322 continue; 2390 continue;
2323 } 2391 }
2324 2392
2325 TRACED_FORRANGE(int32_t, imm, -32, 63) { 2393 TRACED_FORRANGE(int32_t, imm, -32, 63) {
2326 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2394 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2395 MachineType::Int32());
2327 Node* const p0 = m.Parameter(0); 2396 Node* const p0 = m.Parameter(0);
2328 Node* const p1 = m.Parameter(1); 2397 Node* const p1 = m.Parameter(1);
2329 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); 2398 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm));
2330 m.Return(m.Word32Equal(p0, r)); 2399 m.Return(m.Word32Equal(p0, r));
2331 Stream s = m.Build(); 2400 Stream s = m.Build();
2332 ASSERT_EQ(1U, s.size()); 2401 ASSERT_EQ(1U, s.size());
2333 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2402 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2334 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 2403 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
2335 ASSERT_EQ(3U, s[0]->InputCount()); 2404 ASSERT_EQ(3U, s[0]->InputCount());
2336 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2405 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2337 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2406 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2338 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); 2407 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
2339 ASSERT_EQ(1U, s[0]->OutputCount()); 2408 ASSERT_EQ(1U, s[0]->OutputCount());
2340 } 2409 }
2341 TRACED_FORRANGE(int32_t, imm, -32, 63) { 2410 TRACED_FORRANGE(int32_t, imm, -32, 63) {
2342 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2411 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2412 MachineType::Int32());
2343 Node* const p0 = m.Parameter(0); 2413 Node* const p0 = m.Parameter(0);
2344 Node* const p1 = m.Parameter(1); 2414 Node* const p1 = m.Parameter(1);
2345 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); 2415 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm));
2346 m.Return(m.Word32Equal(r, p0)); 2416 m.Return(m.Word32Equal(r, p0));
2347 Stream s = m.Build(); 2417 Stream s = m.Build();
2348 ASSERT_EQ(1U, s.size()); 2418 ASSERT_EQ(1U, s.size());
2349 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2419 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2350 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 2420 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
2351 ASSERT_EQ(3U, s[0]->InputCount()); 2421 ASSERT_EQ(3U, s[0]->InputCount());
2352 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2422 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2353 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2423 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2354 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); 2424 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
2355 ASSERT_EQ(1U, s[0]->OutputCount()); 2425 ASSERT_EQ(1U, s[0]->OutputCount());
2356 } 2426 }
2357 } 2427 }
2358 } 2428 }
2359 2429
2360 2430
2361 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendByte) { 2431 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendByte) {
2362 { 2432 {
2363 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2433 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2434 MachineType::Int32());
2364 Node* const p0 = m.Parameter(0); 2435 Node* const p0 = m.Parameter(0);
2365 Node* const p1 = m.Parameter(1); 2436 Node* const p1 = m.Parameter(1);
2366 Node* r = m.Word32And(p1, m.Int32Constant(0xff)); 2437 Node* r = m.Word32And(p1, m.Int32Constant(0xff));
2367 m.Return(m.Word32Equal(p0, r)); 2438 m.Return(m.Word32Equal(p0, r));
2368 Stream s = m.Build(); 2439 Stream s = m.Build();
2369 ASSERT_EQ(1U, s.size()); 2440 ASSERT_EQ(1U, s.size());
2370 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2441 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2371 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); 2442 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode());
2372 ASSERT_EQ(2U, s[0]->InputCount()); 2443 ASSERT_EQ(2U, s[0]->InputCount());
2373 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2444 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2374 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2445 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2375 ASSERT_EQ(1U, s[0]->OutputCount()); 2446 ASSERT_EQ(1U, s[0]->OutputCount());
2376 } 2447 }
2377 { 2448 {
2378 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2449 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2450 MachineType::Int32());
2379 Node* const p0 = m.Parameter(0); 2451 Node* const p0 = m.Parameter(0);
2380 Node* const p1 = m.Parameter(1); 2452 Node* const p1 = m.Parameter(1);
2381 Node* r = m.Word32And(p1, m.Int32Constant(0xff)); 2453 Node* r = m.Word32And(p1, m.Int32Constant(0xff));
2382 m.Return(m.Word32Equal(r, p0)); 2454 m.Return(m.Word32Equal(r, p0));
2383 Stream s = m.Build(); 2455 Stream s = m.Build();
2384 ASSERT_EQ(1U, s.size()); 2456 ASSERT_EQ(1U, s.size());
2385 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2457 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2386 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode()); 2458 EXPECT_EQ(kMode_Operand2_R_UXTB, s[0]->addressing_mode());
2387 ASSERT_EQ(2U, s[0]->InputCount()); 2459 ASSERT_EQ(2U, s[0]->InputCount());
2388 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2460 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2389 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2461 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2390 ASSERT_EQ(1U, s[0]->OutputCount()); 2462 ASSERT_EQ(1U, s[0]->OutputCount());
2391 } 2463 }
2392 } 2464 }
2393 2465
2394 2466
2395 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendHalfword) { 2467 TEST_F(InstructionSelectorTest, Word32EqualWithUnsignedExtendHalfword) {
2396 { 2468 {
2397 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2469 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2470 MachineType::Int32());
2398 Node* const p0 = m.Parameter(0); 2471 Node* const p0 = m.Parameter(0);
2399 Node* const p1 = m.Parameter(1); 2472 Node* const p1 = m.Parameter(1);
2400 Node* r = m.Word32And(p1, m.Int32Constant(0xffff)); 2473 Node* r = m.Word32And(p1, m.Int32Constant(0xffff));
2401 m.Return(m.Word32Equal(p0, r)); 2474 m.Return(m.Word32Equal(p0, r));
2402 Stream s = m.Build(); 2475 Stream s = m.Build();
2403 ASSERT_EQ(1U, s.size()); 2476 ASSERT_EQ(1U, s.size());
2404 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2477 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2405 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); 2478 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode());
2406 ASSERT_EQ(2U, s[0]->InputCount()); 2479 ASSERT_EQ(2U, s[0]->InputCount());
2407 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2480 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2408 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2481 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2409 ASSERT_EQ(1U, s[0]->OutputCount()); 2482 ASSERT_EQ(1U, s[0]->OutputCount());
2410 } 2483 }
2411 { 2484 {
2412 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2485 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2486 MachineType::Int32());
2413 Node* const p0 = m.Parameter(0); 2487 Node* const p0 = m.Parameter(0);
2414 Node* const p1 = m.Parameter(1); 2488 Node* const p1 = m.Parameter(1);
2415 Node* r = m.Word32And(p1, m.Int32Constant(0xffff)); 2489 Node* r = m.Word32And(p1, m.Int32Constant(0xffff));
2416 m.Return(m.Word32Equal(r, p0)); 2490 m.Return(m.Word32Equal(r, p0));
2417 Stream s = m.Build(); 2491 Stream s = m.Build();
2418 ASSERT_EQ(1U, s.size()); 2492 ASSERT_EQ(1U, s.size());
2419 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2493 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2420 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode()); 2494 EXPECT_EQ(kMode_Operand2_R_UXTH, s[0]->addressing_mode());
2421 ASSERT_EQ(2U, s[0]->InputCount()); 2495 ASSERT_EQ(2U, s[0]->InputCount());
2422 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2496 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2423 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2497 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2424 ASSERT_EQ(1U, s[0]->OutputCount()); 2498 ASSERT_EQ(1U, s[0]->OutputCount());
2425 } 2499 }
2426 } 2500 }
2427 2501
2428 2502
2429 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendByte) { 2503 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendByte) {
2430 { 2504 {
2431 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2505 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2506 MachineType::Int32());
2432 Node* const p0 = m.Parameter(0); 2507 Node* const p0 = m.Parameter(0);
2433 Node* const p1 = m.Parameter(1); 2508 Node* const p1 = m.Parameter(1);
2434 Node* r = 2509 Node* r =
2435 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24)); 2510 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24));
2436 m.Return(m.Word32Equal(p0, r)); 2511 m.Return(m.Word32Equal(p0, r));
2437 Stream s = m.Build(); 2512 Stream s = m.Build();
2438 ASSERT_EQ(1U, s.size()); 2513 ASSERT_EQ(1U, s.size());
2439 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2514 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2440 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); 2515 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
2441 ASSERT_EQ(2U, s[0]->InputCount()); 2516 ASSERT_EQ(2U, s[0]->InputCount());
2442 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2517 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2443 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2518 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2444 ASSERT_EQ(1U, s[0]->OutputCount()); 2519 ASSERT_EQ(1U, s[0]->OutputCount());
2445 } 2520 }
2446 { 2521 {
2447 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2522 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2523 MachineType::Int32());
2448 Node* const p0 = m.Parameter(0); 2524 Node* const p0 = m.Parameter(0);
2449 Node* const p1 = m.Parameter(1); 2525 Node* const p1 = m.Parameter(1);
2450 Node* r = 2526 Node* r =
2451 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24)); 2527 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(24)), m.Int32Constant(24));
2452 m.Return(m.Word32Equal(r, p0)); 2528 m.Return(m.Word32Equal(r, p0));
2453 Stream s = m.Build(); 2529 Stream s = m.Build();
2454 ASSERT_EQ(1U, s.size()); 2530 ASSERT_EQ(1U, s.size());
2455 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2531 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2456 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode()); 2532 EXPECT_EQ(kMode_Operand2_R_SXTB, s[0]->addressing_mode());
2457 ASSERT_EQ(2U, s[0]->InputCount()); 2533 ASSERT_EQ(2U, s[0]->InputCount());
2458 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2534 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2459 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2535 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2460 ASSERT_EQ(1U, s[0]->OutputCount()); 2536 ASSERT_EQ(1U, s[0]->OutputCount());
2461 } 2537 }
2462 } 2538 }
2463 2539
2464 2540
2465 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) { 2541 TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) {
2466 { 2542 {
2467 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2543 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2544 MachineType::Int32());
2468 Node* const p0 = m.Parameter(0); 2545 Node* const p0 = m.Parameter(0);
2469 Node* const p1 = m.Parameter(1); 2546 Node* const p1 = m.Parameter(1);
2470 Node* r = 2547 Node* r =
2471 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16)); 2548 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16));
2472 m.Return(m.Word32Equal(p0, r)); 2549 m.Return(m.Word32Equal(p0, r));
2473 Stream s = m.Build(); 2550 Stream s = m.Build();
2474 ASSERT_EQ(1U, s.size()); 2551 ASSERT_EQ(1U, s.size());
2475 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2552 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2476 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); 2553 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode());
2477 ASSERT_EQ(2U, s[0]->InputCount()); 2554 ASSERT_EQ(2U, s[0]->InputCount());
2478 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2555 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2479 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2556 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2480 ASSERT_EQ(1U, s[0]->OutputCount()); 2557 ASSERT_EQ(1U, s[0]->OutputCount());
2481 } 2558 }
2482 { 2559 {
2483 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2560 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2561 MachineType::Int32());
2484 Node* const p0 = m.Parameter(0); 2562 Node* const p0 = m.Parameter(0);
2485 Node* const p1 = m.Parameter(1); 2563 Node* const p1 = m.Parameter(1);
2486 Node* r = 2564 Node* r =
2487 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16)); 2565 m.Word32Sar(m.Word32Shl(p1, m.Int32Constant(16)), m.Int32Constant(16));
2488 m.Return(m.Word32Equal(r, p0)); 2566 m.Return(m.Word32Equal(r, p0));
2489 Stream s = m.Build(); 2567 Stream s = m.Build();
2490 ASSERT_EQ(1U, s.size()); 2568 ASSERT_EQ(1U, s.size());
2491 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2569 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2492 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode()); 2570 EXPECT_EQ(kMode_Operand2_R_SXTH, s[0]->addressing_mode());
2493 ASSERT_EQ(2U, s[0]->InputCount()); 2571 ASSERT_EQ(2U, s[0]->InputCount());
2494 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2572 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2495 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2573 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2496 ASSERT_EQ(1U, s[0]->OutputCount()); 2574 ASSERT_EQ(1U, s[0]->OutputCount());
2497 } 2575 }
2498 } 2576 }
2499 2577
2500 2578
2501 TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) { 2579 TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) {
2502 { 2580 {
2503 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2581 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2582 MachineType::Int32());
2504 Node* const p0 = m.Parameter(0); 2583 Node* const p0 = m.Parameter(0);
2505 Node* const p1 = m.Parameter(1); 2584 Node* const p1 = m.Parameter(1);
2506 m.Return(m.Word32Equal(m.Word32Equal(p0, p1), m.Int32Constant(0))); 2585 m.Return(m.Word32Equal(m.Word32Equal(p0, p1), m.Int32Constant(0)));
2507 Stream s = m.Build(); 2586 Stream s = m.Build();
2508 ASSERT_EQ(1U, s.size()); 2587 ASSERT_EQ(1U, s.size());
2509 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2588 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2510 ASSERT_EQ(2U, s[0]->InputCount()); 2589 ASSERT_EQ(2U, s[0]->InputCount());
2511 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2590 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2512 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2591 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2513 EXPECT_EQ(1U, s[0]->OutputCount()); 2592 EXPECT_EQ(1U, s[0]->OutputCount());
2514 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2593 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2515 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); 2594 EXPECT_EQ(kNotEqual, s[0]->flags_condition());
2516 } 2595 }
2517 { 2596 {
2518 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2597 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2598 MachineType::Int32());
2519 Node* const p0 = m.Parameter(0); 2599 Node* const p0 = m.Parameter(0);
2520 Node* const p1 = m.Parameter(1); 2600 Node* const p1 = m.Parameter(1);
2521 m.Return(m.Word32Equal(m.Int32Constant(0), m.Word32Equal(p0, p1))); 2601 m.Return(m.Word32Equal(m.Int32Constant(0), m.Word32Equal(p0, p1)));
2522 Stream s = m.Build(); 2602 Stream s = m.Build();
2523 ASSERT_EQ(1U, s.size()); 2603 ASSERT_EQ(1U, s.size());
2524 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); 2604 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
2525 ASSERT_EQ(2U, s[0]->InputCount()); 2605 ASSERT_EQ(2U, s[0]->InputCount());
2526 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 2606 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2527 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 2607 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2528 EXPECT_EQ(1U, s[0]->OutputCount()); 2608 EXPECT_EQ(1U, s[0]->OutputCount());
(...skipping 11 matching lines...) Expand all
2540 2620
2541 2621
2542 std::ostream& operator<<(std::ostream& os, const IntegerCmp& cmp) { 2622 std::ostream& operator<<(std::ostream& os, const IntegerCmp& cmp) {
2543 return os << cmp.mi; 2623 return os << cmp.mi;
2544 } 2624 }
2545 2625
2546 2626
2547 // ARM64 32-bit integer comparison instructions. 2627 // ARM64 32-bit integer comparison instructions.
2548 const IntegerCmp kIntegerCmpInstructions[] = { 2628 const IntegerCmp kIntegerCmpInstructions[] = {
2549 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, 2629 {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32,
2550 kMachInt32}, 2630 MachineType::Int32()},
2551 kEqual}, 2631 kEqual},
2552 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32, 2632 {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kArm64Cmp32,
2553 kMachInt32}, 2633 MachineType::Int32()},
2554 kSignedLessThan}, 2634 kSignedLessThan},
2555 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual", 2635 {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
2556 kArm64Cmp32, kMachInt32}, 2636 kArm64Cmp32, MachineType::Int32()},
2557 kSignedLessThanOrEqual}, 2637 kSignedLessThanOrEqual},
2558 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32, 2638 {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kArm64Cmp32,
2559 kMachUint32}, 2639 MachineType::Uint32()},
2560 kUnsignedLessThan}, 2640 kUnsignedLessThan},
2561 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual", 2641 {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
2562 kArm64Cmp32, kMachUint32}, 2642 kArm64Cmp32, MachineType::Uint32()},
2563 kUnsignedLessThanOrEqual}}; 2643 kUnsignedLessThanOrEqual}};
2564 2644
2565 } // namespace 2645 } // namespace
2566 2646
2567 2647
2568 TEST_F(InstructionSelectorTest, Word32CompareNegateWithWord32Shift) { 2648 TEST_F(InstructionSelectorTest, Word32CompareNegateWithWord32Shift) {
2569 TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) { 2649 TRACED_FOREACH(IntegerCmp, cmp, kIntegerCmpInstructions) {
2570 TRACED_FOREACH(Shift, shift, kShiftInstructions) { 2650 TRACED_FOREACH(Shift, shift, kShiftInstructions) {
2571 // Test 32-bit operations. Ignore ROR shifts, as compare-negate does not 2651 // Test 32-bit operations. Ignore ROR shifts, as compare-negate does not
2572 // support them. 2652 // support them.
2573 if (shift.mi.machine_type != kMachInt32 || 2653 if (shift.mi.machine_type != MachineType::Int32() ||
2574 shift.mi.arch_opcode == kArm64Ror32) { 2654 shift.mi.arch_opcode == kArm64Ror32) {
2575 continue; 2655 continue;
2576 } 2656 }
2577 2657
2578 TRACED_FORRANGE(int32_t, imm, -32, 63) { 2658 TRACED_FORRANGE(int32_t, imm, -32, 63) {
2579 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 2659 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
2660 MachineType::Int32());
2580 Node* const p0 = m.Parameter(0); 2661 Node* const p0 = m.Parameter(0);
2581 Node* const p1 = m.Parameter(1); 2662 Node* const p1 = m.Parameter(1);
2582 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm)); 2663 Node* r = (m.*shift.mi.constructor)(p1, m.Int32Constant(imm));
2583 m.Return( 2664 m.Return(
2584 (m.*cmp.mi.constructor)(p0, m.Int32Sub(m.Int32Constant(0), r))); 2665 (m.*cmp.mi.constructor)(p0, m.Int32Sub(m.Int32Constant(0), r)));
2585 Stream s = m.Build(); 2666 Stream s = m.Build();
2586 ASSERT_EQ(1U, s.size()); 2667 ASSERT_EQ(1U, s.size());
2587 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); 2668 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
2588 EXPECT_EQ(3U, s[0]->InputCount()); 2669 EXPECT_EQ(3U, s[0]->InputCount());
2589 EXPECT_EQ(shift.mode, s[0]->addressing_mode()); 2670 EXPECT_EQ(shift.mode, s[0]->addressing_mode());
2590 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2))); 2671 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
2591 EXPECT_EQ(1U, s[0]->OutputCount()); 2672 EXPECT_EQ(1U, s[0]->OutputCount());
2592 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); 2673 EXPECT_EQ(kFlags_set, s[0]->flags_mode());
2593 EXPECT_EQ(cmp.cond, s[0]->flags_condition()); 2674 EXPECT_EQ(cmp.cond, s[0]->flags_condition());
2594 } 2675 }
2595 } 2676 }
2596 } 2677 }
2597 } 2678 }
2598 2679
2599 2680
2600 // ----------------------------------------------------------------------------- 2681 // -----------------------------------------------------------------------------
2601 // Miscellaneous 2682 // Miscellaneous
2602 2683
2603 2684
2604 static const MachInst2 kLogicalWithNotRHSs[] = { 2685 static const MachInst2 kLogicalWithNotRHSs[] = {
2605 {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32, kMachInt32}, 2686 {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32,
2606 {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic, kMachInt64}, 2687 MachineType::Int32()},
2607 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Orn32, kMachInt32}, 2688 {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic,
2608 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Orn, kMachInt64}, 2689 MachineType::Int64()},
2609 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eon32, kMachInt32}, 2690 {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Orn32,
2610 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eon, kMachInt64}}; 2691 MachineType::Int32()},
2692 {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Orn,
2693 MachineType::Int64()},
2694 {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eon32,
2695 MachineType::Int32()},
2696 {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eon,
2697 MachineType::Int64()}};
2611 2698
2612 2699
2613 typedef InstructionSelectorTestWithParam<MachInst2> 2700 typedef InstructionSelectorTestWithParam<MachInst2>
2614 InstructionSelectorLogicalWithNotRHSTest; 2701 InstructionSelectorLogicalWithNotRHSTest;
2615 2702
2616 2703
2617 TEST_P(InstructionSelectorLogicalWithNotRHSTest, Parameter) { 2704 TEST_P(InstructionSelectorLogicalWithNotRHSTest, Parameter) {
2618 const MachInst2 inst = GetParam(); 2705 const MachInst2 inst = GetParam();
2619 const MachineType type = inst.machine_type; 2706 const MachineType type = inst.machine_type;
2620 // Test cases where RHS is Xor(x, -1). 2707 // Test cases where RHS is Xor(x, -1).
2621 { 2708 {
2622 StreamBuilder m(this, type, type, type); 2709 StreamBuilder m(this, type, type, type);
2623 if (type == kMachInt32) { 2710 if (type == MachineType::Int32()) {
2624 m.Return((m.*inst.constructor)( 2711 m.Return((m.*inst.constructor)(
2625 m.Parameter(0), m.Word32Xor(m.Parameter(1), m.Int32Constant(-1)))); 2712 m.Parameter(0), m.Word32Xor(m.Parameter(1), m.Int32Constant(-1))));
2626 } else { 2713 } else {
2627 ASSERT_EQ(kMachInt64, type); 2714 ASSERT_EQ(MachineType::Int64(), type);
2628 m.Return((m.*inst.constructor)( 2715 m.Return((m.*inst.constructor)(
2629 m.Parameter(0), m.Word64Xor(m.Parameter(1), m.Int64Constant(-1)))); 2716 m.Parameter(0), m.Word64Xor(m.Parameter(1), m.Int64Constant(-1))));
2630 } 2717 }
2631 Stream s = m.Build(); 2718 Stream s = m.Build();
2632 ASSERT_EQ(1U, s.size()); 2719 ASSERT_EQ(1U, s.size());
2633 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); 2720 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
2634 EXPECT_EQ(2U, s[0]->InputCount()); 2721 EXPECT_EQ(2U, s[0]->InputCount());
2635 EXPECT_EQ(1U, s[0]->OutputCount()); 2722 EXPECT_EQ(1U, s[0]->OutputCount());
2636 } 2723 }
2637 { 2724 {
2638 StreamBuilder m(this, type, type, type); 2725 StreamBuilder m(this, type, type, type);
2639 if (type == kMachInt32) { 2726 if (type == MachineType::Int32()) {
2640 m.Return((m.*inst.constructor)( 2727 m.Return((m.*inst.constructor)(
2641 m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)), m.Parameter(1))); 2728 m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)), m.Parameter(1)));
2642 } else { 2729 } else {
2643 ASSERT_EQ(kMachInt64, type); 2730 ASSERT_EQ(MachineType::Int64(), type);
2644 m.Return((m.*inst.constructor)( 2731 m.Return((m.*inst.constructor)(
2645 m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)), m.Parameter(1))); 2732 m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)), m.Parameter(1)));
2646 } 2733 }
2647 Stream s = m.Build(); 2734 Stream s = m.Build();
2648 ASSERT_EQ(1U, s.size()); 2735 ASSERT_EQ(1U, s.size());
2649 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); 2736 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
2650 EXPECT_EQ(2U, s[0]->InputCount()); 2737 EXPECT_EQ(2U, s[0]->InputCount());
2651 EXPECT_EQ(1U, s[0]->OutputCount()); 2738 EXPECT_EQ(1U, s[0]->OutputCount());
2652 } 2739 }
2653 // Test cases where RHS is Not(x). 2740 // Test cases where RHS is Not(x).
2654 { 2741 {
2655 StreamBuilder m(this, type, type, type); 2742 StreamBuilder m(this, type, type, type);
2656 if (type == kMachInt32) { 2743 if (type == MachineType::Int32()) {
2657 m.Return( 2744 m.Return(
2658 (m.*inst.constructor)(m.Parameter(0), m.Word32Not(m.Parameter(1)))); 2745 (m.*inst.constructor)(m.Parameter(0), m.Word32Not(m.Parameter(1))));
2659 } else { 2746 } else {
2660 ASSERT_EQ(kMachInt64, type); 2747 ASSERT_EQ(MachineType::Int64(), type);
2661 m.Return( 2748 m.Return(
2662 (m.*inst.constructor)(m.Parameter(0), m.Word64Not(m.Parameter(1)))); 2749 (m.*inst.constructor)(m.Parameter(0), m.Word64Not(m.Parameter(1))));
2663 } 2750 }
2664 Stream s = m.Build(); 2751 Stream s = m.Build();
2665 ASSERT_EQ(1U, s.size()); 2752 ASSERT_EQ(1U, s.size());
2666 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); 2753 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
2667 EXPECT_EQ(2U, s[0]->InputCount()); 2754 EXPECT_EQ(2U, s[0]->InputCount());
2668 EXPECT_EQ(1U, s[0]->OutputCount()); 2755 EXPECT_EQ(1U, s[0]->OutputCount());
2669 } 2756 }
2670 { 2757 {
2671 StreamBuilder m(this, type, type, type); 2758 StreamBuilder m(this, type, type, type);
2672 if (type == kMachInt32) { 2759 if (type == MachineType::Int32()) {
2673 m.Return( 2760 m.Return(
2674 (m.*inst.constructor)(m.Word32Not(m.Parameter(0)), m.Parameter(1))); 2761 (m.*inst.constructor)(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
2675 } else { 2762 } else {
2676 ASSERT_EQ(kMachInt64, type); 2763 ASSERT_EQ(MachineType::Int64(), type);
2677 m.Return( 2764 m.Return(
2678 (m.*inst.constructor)(m.Word64Not(m.Parameter(0)), m.Parameter(1))); 2765 (m.*inst.constructor)(m.Word64Not(m.Parameter(0)), m.Parameter(1)));
2679 } 2766 }
2680 Stream s = m.Build(); 2767 Stream s = m.Build();
2681 ASSERT_EQ(1U, s.size()); 2768 ASSERT_EQ(1U, s.size());
2682 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); 2769 EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
2683 EXPECT_EQ(2U, s[0]->InputCount()); 2770 EXPECT_EQ(2U, s[0]->InputCount());
2684 EXPECT_EQ(1U, s[0]->OutputCount()); 2771 EXPECT_EQ(1U, s[0]->OutputCount());
2685 } 2772 }
2686 } 2773 }
2687 2774
2688 2775
2689 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, 2776 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
2690 InstructionSelectorLogicalWithNotRHSTest, 2777 InstructionSelectorLogicalWithNotRHSTest,
2691 ::testing::ValuesIn(kLogicalWithNotRHSs)); 2778 ::testing::ValuesIn(kLogicalWithNotRHSs));
2692 2779
2693 2780
2694 TEST_F(InstructionSelectorTest, Word32NotWithParameter) { 2781 TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
2695 StreamBuilder m(this, kMachInt32, kMachInt32); 2782 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2696 m.Return(m.Word32Not(m.Parameter(0))); 2783 m.Return(m.Word32Not(m.Parameter(0)));
2697 Stream s = m.Build(); 2784 Stream s = m.Build();
2698 ASSERT_EQ(1U, s.size()); 2785 ASSERT_EQ(1U, s.size());
2699 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); 2786 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode());
2700 EXPECT_EQ(1U, s[0]->InputCount()); 2787 EXPECT_EQ(1U, s[0]->InputCount());
2701 EXPECT_EQ(1U, s[0]->OutputCount()); 2788 EXPECT_EQ(1U, s[0]->OutputCount());
2702 } 2789 }
2703 2790
2704 2791
2705 TEST_F(InstructionSelectorTest, Word64NotWithParameter) { 2792 TEST_F(InstructionSelectorTest, Word64NotWithParameter) {
2706 StreamBuilder m(this, kMachInt64, kMachInt64); 2793 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2707 m.Return(m.Word64Not(m.Parameter(0))); 2794 m.Return(m.Word64Not(m.Parameter(0)));
2708 Stream s = m.Build(); 2795 Stream s = m.Build();
2709 ASSERT_EQ(1U, s.size()); 2796 ASSERT_EQ(1U, s.size());
2710 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); 2797 EXPECT_EQ(kArm64Not, s[0]->arch_opcode());
2711 EXPECT_EQ(1U, s[0]->InputCount()); 2798 EXPECT_EQ(1U, s[0]->InputCount());
2712 EXPECT_EQ(1U, s[0]->OutputCount()); 2799 EXPECT_EQ(1U, s[0]->OutputCount());
2713 } 2800 }
2714 2801
2715 2802
2716 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) { 2803 TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) {
2717 { 2804 {
2718 StreamBuilder m(this, kMachInt32, kMachInt32); 2805 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2719 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1))); 2806 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)));
2720 Stream s = m.Build(); 2807 Stream s = m.Build();
2721 ASSERT_EQ(1U, s.size()); 2808 ASSERT_EQ(1U, s.size());
2722 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); 2809 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode());
2723 EXPECT_EQ(1U, s[0]->InputCount()); 2810 EXPECT_EQ(1U, s[0]->InputCount());
2724 EXPECT_EQ(1U, s[0]->OutputCount()); 2811 EXPECT_EQ(1U, s[0]->OutputCount());
2725 } 2812 }
2726 { 2813 {
2727 StreamBuilder m(this, kMachInt32, kMachInt32); 2814 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2728 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0))); 2815 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)));
2729 Stream s = m.Build(); 2816 Stream s = m.Build();
2730 ASSERT_EQ(1U, s.size()); 2817 ASSERT_EQ(1U, s.size());
2731 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode()); 2818 EXPECT_EQ(kArm64Not32, s[0]->arch_opcode());
2732 EXPECT_EQ(1U, s[0]->InputCount()); 2819 EXPECT_EQ(1U, s[0]->InputCount());
2733 EXPECT_EQ(1U, s[0]->OutputCount()); 2820 EXPECT_EQ(1U, s[0]->OutputCount());
2734 } 2821 }
2735 } 2822 }
2736 2823
2737 2824
2738 TEST_F(InstructionSelectorTest, Word64XorMinusOneWithParameter) { 2825 TEST_F(InstructionSelectorTest, Word64XorMinusOneWithParameter) {
2739 { 2826 {
2740 StreamBuilder m(this, kMachInt64, kMachInt64); 2827 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2741 m.Return(m.Word64Xor(m.Parameter(0), m.Int64Constant(-1))); 2828 m.Return(m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)));
2742 Stream s = m.Build(); 2829 Stream s = m.Build();
2743 ASSERT_EQ(1U, s.size()); 2830 ASSERT_EQ(1U, s.size());
2744 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); 2831 EXPECT_EQ(kArm64Not, s[0]->arch_opcode());
2745 EXPECT_EQ(1U, s[0]->InputCount()); 2832 EXPECT_EQ(1U, s[0]->InputCount());
2746 EXPECT_EQ(1U, s[0]->OutputCount()); 2833 EXPECT_EQ(1U, s[0]->OutputCount());
2747 } 2834 }
2748 { 2835 {
2749 StreamBuilder m(this, kMachInt64, kMachInt64); 2836 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2750 m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0))); 2837 m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0)));
2751 Stream s = m.Build(); 2838 Stream s = m.Build();
2752 ASSERT_EQ(1U, s.size()); 2839 ASSERT_EQ(1U, s.size());
2753 EXPECT_EQ(kArm64Not, s[0]->arch_opcode()); 2840 EXPECT_EQ(kArm64Not, s[0]->arch_opcode());
2754 EXPECT_EQ(1U, s[0]->InputCount()); 2841 EXPECT_EQ(1U, s[0]->InputCount());
2755 EXPECT_EQ(1U, s[0]->OutputCount()); 2842 EXPECT_EQ(1U, s[0]->OutputCount());
2756 } 2843 }
2757 } 2844 }
2758 2845
2759 2846
2760 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) { 2847 TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) {
2761 // The available shift operand range is `0 <= imm < 32`, but we also test 2848 // The available shift operand range is `0 <= imm < 32`, but we also test
2762 // that immediates outside this range are handled properly (modulo-32). 2849 // that immediates outside this range are handled properly (modulo-32).
2763 TRACED_FORRANGE(int32_t, shift, -32, 63) { 2850 TRACED_FORRANGE(int32_t, shift, -32, 63) {
2764 int32_t lsb = shift & 0x1f; 2851 int32_t lsb = shift & 0x1f;
2765 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { 2852 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2766 uint32_t jnk = rng()->NextInt(); 2853 uint32_t jnk = rng()->NextInt();
2767 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; 2854 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0;
2768 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; 2855 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
2769 StreamBuilder m(this, kMachInt32, kMachInt32); 2856 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2770 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), 2857 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
2771 m.Int32Constant(shift))); 2858 m.Int32Constant(shift)));
2772 Stream s = m.Build(); 2859 Stream s = m.Build();
2773 ASSERT_EQ(1U, s.size()); 2860 ASSERT_EQ(1U, s.size());
2774 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); 2861 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
2775 ASSERT_EQ(3U, s[0]->InputCount()); 2862 ASSERT_EQ(3U, s[0]->InputCount());
2776 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); 2863 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2777 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); 2864 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2778 } 2865 }
2779 } 2866 }
2780 TRACED_FORRANGE(int32_t, shift, -32, 63) { 2867 TRACED_FORRANGE(int32_t, shift, -32, 63) {
2781 int32_t lsb = shift & 0x1f; 2868 int32_t lsb = shift & 0x1f;
2782 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { 2869 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
2783 uint32_t jnk = rng()->NextInt(); 2870 uint32_t jnk = rng()->NextInt();
2784 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0; 2871 jnk = (lsb > 0) ? (jnk >> (32 - lsb)) : 0;
2785 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; 2872 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
2786 StreamBuilder m(this, kMachInt32, kMachInt32); 2873 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2787 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), 2874 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
2788 m.Int32Constant(shift))); 2875 m.Int32Constant(shift)));
2789 Stream s = m.Build(); 2876 Stream s = m.Build();
2790 ASSERT_EQ(1U, s.size()); 2877 ASSERT_EQ(1U, s.size());
2791 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); 2878 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
2792 ASSERT_EQ(3U, s[0]->InputCount()); 2879 ASSERT_EQ(3U, s[0]->InputCount());
2793 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); 2880 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2794 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); 2881 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
2795 } 2882 }
2796 } 2883 }
2797 } 2884 }
2798 2885
2799 2886
2800 TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) { 2887 TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) {
2801 // The available shift operand range is `0 <= imm < 64`, but we also test 2888 // The available shift operand range is `0 <= imm < 64`, but we also test
2802 // that immediates outside this range are handled properly (modulo-64). 2889 // that immediates outside this range are handled properly (modulo-64).
2803 TRACED_FORRANGE(int32_t, shift, -64, 127) { 2890 TRACED_FORRANGE(int32_t, shift, -64, 127) {
2804 int32_t lsb = shift & 0x3f; 2891 int32_t lsb = shift & 0x3f;
2805 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { 2892 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) {
2806 uint64_t jnk = rng()->NextInt64(); 2893 uint64_t jnk = rng()->NextInt64();
2807 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0; 2894 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0;
2808 uint64_t msk = 2895 uint64_t msk =
2809 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; 2896 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk;
2810 StreamBuilder m(this, kMachInt64, kMachInt64); 2897 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2811 m.Return(m.Word64Shr(m.Word64And(m.Parameter(0), m.Int64Constant(msk)), 2898 m.Return(m.Word64Shr(m.Word64And(m.Parameter(0), m.Int64Constant(msk)),
2812 m.Int64Constant(shift))); 2899 m.Int64Constant(shift)));
2813 Stream s = m.Build(); 2900 Stream s = m.Build();
2814 ASSERT_EQ(1U, s.size()); 2901 ASSERT_EQ(1U, s.size());
2815 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); 2902 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
2816 ASSERT_EQ(3U, s[0]->InputCount()); 2903 ASSERT_EQ(3U, s[0]->InputCount());
2817 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); 2904 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
2818 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); 2905 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
2819 } 2906 }
2820 } 2907 }
2821 TRACED_FORRANGE(int32_t, shift, -64, 127) { 2908 TRACED_FORRANGE(int32_t, shift, -64, 127) {
2822 int32_t lsb = shift & 0x3f; 2909 int32_t lsb = shift & 0x3f;
2823 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) { 2910 TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) {
2824 uint64_t jnk = rng()->NextInt64(); 2911 uint64_t jnk = rng()->NextInt64();
2825 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0; 2912 jnk = (lsb > 0) ? (jnk >> (64 - lsb)) : 0;
2826 uint64_t msk = 2913 uint64_t msk =
2827 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk; 2914 ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk;
2828 StreamBuilder m(this, kMachInt64, kMachInt64); 2915 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2829 m.Return(m.Word64Shr(m.Word64And(m.Int64Constant(msk), m.Parameter(0)), 2916 m.Return(m.Word64Shr(m.Word64And(m.Int64Constant(msk), m.Parameter(0)),
2830 m.Int64Constant(shift))); 2917 m.Int64Constant(shift)));
2831 Stream s = m.Build(); 2918 Stream s = m.Build();
2832 ASSERT_EQ(1U, s.size()); 2919 ASSERT_EQ(1U, s.size());
2833 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); 2920 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
2834 ASSERT_EQ(3U, s[0]->InputCount()); 2921 ASSERT_EQ(3U, s[0]->InputCount());
2835 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); 2922 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
2836 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2))); 2923 EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
2837 } 2924 }
2838 } 2925 }
2839 } 2926 }
2840 2927
2841 2928
2842 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { 2929 TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) {
2843 // The available shift operand range is `0 <= imm < 32`, but we also test 2930 // The available shift operand range is `0 <= imm < 32`, but we also test
2844 // that immediates outside this range are handled properly (modulo-32). 2931 // that immediates outside this range are handled properly (modulo-32).
2845 TRACED_FORRANGE(int32_t, shift, -32, 63) { 2932 TRACED_FORRANGE(int32_t, shift, -32, 63) {
2846 int32_t lsb = shift & 0x1f; 2933 int32_t lsb = shift & 0x1f;
2847 TRACED_FORRANGE(int32_t, width, 1, 31) { 2934 TRACED_FORRANGE(int32_t, width, 1, 31) {
2848 uint32_t msk = (1 << width) - 1; 2935 uint32_t msk = (1 << width) - 1;
2849 StreamBuilder m(this, kMachInt32, kMachInt32); 2936 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2850 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), 2937 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)),
2851 m.Int32Constant(msk))); 2938 m.Int32Constant(msk)));
2852 Stream s = m.Build(); 2939 Stream s = m.Build();
2853 ASSERT_EQ(1U, s.size()); 2940 ASSERT_EQ(1U, s.size());
2854 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); 2941 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
2855 ASSERT_EQ(3U, s[0]->InputCount()); 2942 ASSERT_EQ(3U, s[0]->InputCount());
2856 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); 2943 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2857 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; 2944 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
2858 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); 2945 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
2859 } 2946 }
2860 } 2947 }
2861 TRACED_FORRANGE(int32_t, shift, -32, 63) { 2948 TRACED_FORRANGE(int32_t, shift, -32, 63) {
2862 int32_t lsb = shift & 0x1f; 2949 int32_t lsb = shift & 0x1f;
2863 TRACED_FORRANGE(int32_t, width, 1, 31) { 2950 TRACED_FORRANGE(int32_t, width, 1, 31) {
2864 uint32_t msk = (1 << width) - 1; 2951 uint32_t msk = (1 << width) - 1;
2865 StreamBuilder m(this, kMachInt32, kMachInt32); 2952 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
2866 m.Return( 2953 m.Return(
2867 m.Word32And(m.Int32Constant(msk), 2954 m.Word32And(m.Int32Constant(msk),
2868 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); 2955 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))));
2869 Stream s = m.Build(); 2956 Stream s = m.Build();
2870 ASSERT_EQ(1U, s.size()); 2957 ASSERT_EQ(1U, s.size());
2871 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); 2958 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
2872 ASSERT_EQ(3U, s[0]->InputCount()); 2959 ASSERT_EQ(3U, s[0]->InputCount());
2873 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); 2960 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
2874 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width; 2961 int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
2875 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2))); 2962 EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
2876 } 2963 }
2877 } 2964 }
2878 } 2965 }
2879 2966
2880 2967
2881 TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) { 2968 TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
2882 // The available shift operand range is `0 <= imm < 64`, but we also test 2969 // The available shift operand range is `0 <= imm < 64`, but we also test
2883 // that immediates outside this range are handled properly (modulo-64). 2970 // that immediates outside this range are handled properly (modulo-64).
2884 TRACED_FORRANGE(int64_t, shift, -64, 127) { 2971 TRACED_FORRANGE(int64_t, shift, -64, 127) {
2885 int64_t lsb = shift & 0x3f; 2972 int64_t lsb = shift & 0x3f;
2886 TRACED_FORRANGE(int64_t, width, 1, 63) { 2973 TRACED_FORRANGE(int64_t, width, 1, 63) {
2887 uint64_t msk = (V8_UINT64_C(1) << width) - 1; 2974 uint64_t msk = (V8_UINT64_C(1) << width) - 1;
2888 StreamBuilder m(this, kMachInt64, kMachInt64); 2975 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2889 m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)), 2976 m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)),
2890 m.Int64Constant(msk))); 2977 m.Int64Constant(msk)));
2891 Stream s = m.Build(); 2978 Stream s = m.Build();
2892 ASSERT_EQ(1U, s.size()); 2979 ASSERT_EQ(1U, s.size());
2893 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); 2980 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
2894 ASSERT_EQ(3U, s[0]->InputCount()); 2981 ASSERT_EQ(3U, s[0]->InputCount());
2895 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); 2982 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
2896 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width; 2983 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
2897 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2))); 2984 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
2898 } 2985 }
2899 } 2986 }
2900 TRACED_FORRANGE(int64_t, shift, -64, 127) { 2987 TRACED_FORRANGE(int64_t, shift, -64, 127) {
2901 int64_t lsb = shift & 0x3f; 2988 int64_t lsb = shift & 0x3f;
2902 TRACED_FORRANGE(int64_t, width, 1, 63) { 2989 TRACED_FORRANGE(int64_t, width, 1, 63) {
2903 uint64_t msk = (V8_UINT64_C(1) << width) - 1; 2990 uint64_t msk = (V8_UINT64_C(1) << width) - 1;
2904 StreamBuilder m(this, kMachInt64, kMachInt64); 2991 StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
2905 m.Return( 2992 m.Return(
2906 m.Word64And(m.Int64Constant(msk), 2993 m.Word64And(m.Int64Constant(msk),
2907 m.Word64Shr(m.Parameter(0), m.Int64Constant(shift)))); 2994 m.Word64Shr(m.Parameter(0), m.Int64Constant(shift))));
2908 Stream s = m.Build(); 2995 Stream s = m.Build();
2909 ASSERT_EQ(1U, s.size()); 2996 ASSERT_EQ(1U, s.size());
2910 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode()); 2997 EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
2911 ASSERT_EQ(3U, s[0]->InputCount()); 2998 ASSERT_EQ(3U, s[0]->InputCount());
2912 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1))); 2999 EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
2913 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width; 3000 int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
2914 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2))); 3001 EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
2915 } 3002 }
2916 } 3003 }
2917 } 3004 }
2918 3005
2919 3006
2920 TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) { 3007 TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
2921 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 3008 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
3009 MachineType::Int32());
2922 Node* const p0 = m.Parameter(0); 3010 Node* const p0 = m.Parameter(0);
2923 Node* const p1 = m.Parameter(1); 3011 Node* const p1 = m.Parameter(1);
2924 Node* const n = m.Int32MulHigh(p0, p1); 3012 Node* const n = m.Int32MulHigh(p0, p1);
2925 m.Return(n); 3013 m.Return(n);
2926 Stream s = m.Build(); 3014 Stream s = m.Build();
2927 ASSERT_EQ(2U, s.size()); 3015 ASSERT_EQ(2U, s.size());
2928 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); 3016 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode());
2929 ASSERT_EQ(2U, s[0]->InputCount()); 3017 ASSERT_EQ(2U, s[0]->InputCount());
2930 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3018 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2931 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 3019 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2932 ASSERT_EQ(1U, s[0]->OutputCount()); 3020 ASSERT_EQ(1U, s[0]->OutputCount());
2933 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode()); 3021 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode());
2934 ASSERT_EQ(2U, s[1]->InputCount()); 3022 ASSERT_EQ(2U, s[1]->InputCount());
2935 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); 3023 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
2936 EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(1))); 3024 EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(1)));
2937 ASSERT_EQ(1U, s[1]->OutputCount()); 3025 ASSERT_EQ(1U, s[1]->OutputCount());
2938 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); 3026 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output()));
2939 } 3027 }
2940 3028
2941 3029
2942 TEST_F(InstructionSelectorTest, Int32MulHighWithSar) { 3030 TEST_F(InstructionSelectorTest, Int32MulHighWithSar) {
2943 TRACED_FORRANGE(int32_t, shift, -32, 63) { 3031 TRACED_FORRANGE(int32_t, shift, -32, 63) {
2944 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 3032 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
3033 MachineType::Int32());
2945 Node* const p0 = m.Parameter(0); 3034 Node* const p0 = m.Parameter(0);
2946 Node* const p1 = m.Parameter(1); 3035 Node* const p1 = m.Parameter(1);
2947 Node* const n = m.Word32Sar(m.Int32MulHigh(p0, p1), m.Int32Constant(shift)); 3036 Node* const n = m.Word32Sar(m.Int32MulHigh(p0, p1), m.Int32Constant(shift));
2948 m.Return(n); 3037 m.Return(n);
2949 Stream s = m.Build(); 3038 Stream s = m.Build();
2950 ASSERT_EQ(2U, s.size()); 3039 ASSERT_EQ(2U, s.size());
2951 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); 3040 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode());
2952 ASSERT_EQ(2U, s[0]->InputCount()); 3041 ASSERT_EQ(2U, s[0]->InputCount());
2953 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3042 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
2954 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 3043 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
2955 ASSERT_EQ(1U, s[0]->OutputCount()); 3044 ASSERT_EQ(1U, s[0]->OutputCount());
2956 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode()); 3045 EXPECT_EQ(kArm64Asr, s[1]->arch_opcode());
2957 ASSERT_EQ(2U, s[1]->InputCount()); 3046 ASSERT_EQ(2U, s[1]->InputCount());
2958 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); 3047 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
2959 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1))); 3048 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1)));
2960 ASSERT_EQ(1U, s[1]->OutputCount()); 3049 ASSERT_EQ(1U, s[1]->OutputCount());
2961 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); 3050 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output()));
2962 } 3051 }
2963 } 3052 }
2964 3053
2965 3054
2966 TEST_F(InstructionSelectorTest, Int32MulHighWithAdd) { 3055 TEST_F(InstructionSelectorTest, Int32MulHighWithAdd) {
2967 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 3056 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
3057 MachineType::Int32());
2968 Node* const p0 = m.Parameter(0); 3058 Node* const p0 = m.Parameter(0);
2969 Node* const p1 = m.Parameter(1); 3059 Node* const p1 = m.Parameter(1);
2970 Node* const a = m.Int32Add(m.Int32MulHigh(p0, p1), p0); 3060 Node* const a = m.Int32Add(m.Int32MulHigh(p0, p1), p0);
2971 // Test only one shift constant here, as we're only interested in it being a 3061 // Test only one shift constant here, as we're only interested in it being a
2972 // 32-bit operation; the shift amount is irrelevant. 3062 // 32-bit operation; the shift amount is irrelevant.
2973 Node* const n = m.Word32Sar(a, m.Int32Constant(1)); 3063 Node* const n = m.Word32Sar(a, m.Int32Constant(1));
2974 m.Return(n); 3064 m.Return(n);
2975 Stream s = m.Build(); 3065 Stream s = m.Build();
2976 ASSERT_EQ(3U, s.size()); 3066 ASSERT_EQ(3U, s.size());
2977 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode()); 3067 EXPECT_EQ(kArm64Smull, s[0]->arch_opcode());
(...skipping 12 matching lines...) Expand all
2990 ASSERT_EQ(2U, s[2]->InputCount()); 3080 ASSERT_EQ(2U, s[2]->InputCount());
2991 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(0))); 3081 EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(0)));
2992 EXPECT_EQ(1, s.ToInt64(s[2]->InputAt(1))); 3082 EXPECT_EQ(1, s.ToInt64(s[2]->InputAt(1)));
2993 ASSERT_EQ(1U, s[2]->OutputCount()); 3083 ASSERT_EQ(1U, s[2]->OutputCount());
2994 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[2]->Output())); 3084 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[2]->Output()));
2995 } 3085 }
2996 3086
2997 3087
2998 TEST_F(InstructionSelectorTest, Uint32MulHighWithShr) { 3088 TEST_F(InstructionSelectorTest, Uint32MulHighWithShr) {
2999 TRACED_FORRANGE(int32_t, shift, -32, 63) { 3089 TRACED_FORRANGE(int32_t, shift, -32, 63) {
3000 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); 3090 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
3091 MachineType::Int32());
3001 Node* const p0 = m.Parameter(0); 3092 Node* const p0 = m.Parameter(0);
3002 Node* const p1 = m.Parameter(1); 3093 Node* const p1 = m.Parameter(1);
3003 Node* const n = 3094 Node* const n =
3004 m.Word32Shr(m.Uint32MulHigh(p0, p1), m.Int32Constant(shift)); 3095 m.Word32Shr(m.Uint32MulHigh(p0, p1), m.Int32Constant(shift));
3005 m.Return(n); 3096 m.Return(n);
3006 Stream s = m.Build(); 3097 Stream s = m.Build();
3007 ASSERT_EQ(2U, s.size()); 3098 ASSERT_EQ(2U, s.size());
3008 EXPECT_EQ(kArm64Umull, s[0]->arch_opcode()); 3099 EXPECT_EQ(kArm64Umull, s[0]->arch_opcode());
3009 ASSERT_EQ(2U, s[0]->InputCount()); 3100 ASSERT_EQ(2U, s[0]->InputCount());
3010 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3101 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3011 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 3102 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
3012 ASSERT_EQ(1U, s[0]->OutputCount()); 3103 ASSERT_EQ(1U, s[0]->OutputCount());
3013 EXPECT_EQ(kArm64Lsr, s[1]->arch_opcode()); 3104 EXPECT_EQ(kArm64Lsr, s[1]->arch_opcode());
3014 ASSERT_EQ(2U, s[1]->InputCount()); 3105 ASSERT_EQ(2U, s[1]->InputCount());
3015 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); 3106 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
3016 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1))); 3107 EXPECT_EQ((shift & 0x1f) + 32, s.ToInt64(s[1]->InputAt(1)));
3017 ASSERT_EQ(1U, s[1]->OutputCount()); 3108 ASSERT_EQ(1U, s[1]->OutputCount());
3018 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); 3109 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output()));
3019 } 3110 }
3020 } 3111 }
3021 3112
3022 3113
3023 TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) { 3114 TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
3024 TRACED_FORRANGE(int32_t, shift, 1, 31) { 3115 TRACED_FORRANGE(int32_t, shift, 1, 31) {
3025 StreamBuilder m(this, kMachInt32, kMachInt32); 3116 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
3026 Node* const p0 = m.Parameter(0); 3117 Node* const p0 = m.Parameter(0);
3027 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift)), 3118 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift)),
3028 m.Int32Constant(shift)); 3119 m.Int32Constant(shift));
3029 m.Return(r); 3120 m.Return(r);
3030 Stream s = m.Build(); 3121 Stream s = m.Build();
3031 ASSERT_EQ(1U, s.size()); 3122 ASSERT_EQ(1U, s.size());
3032 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode()); 3123 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode());
3033 ASSERT_EQ(3U, s[0]->InputCount()); 3124 ASSERT_EQ(3U, s[0]->InputCount());
3034 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3125 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3035 ASSERT_EQ(1U, s[0]->OutputCount()); 3126 ASSERT_EQ(1U, s[0]->OutputCount());
3036 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); 3127 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
3037 } 3128 }
3038 TRACED_FORRANGE(int32_t, shift, 1, 31) { 3129 TRACED_FORRANGE(int32_t, shift, 1, 31) {
3039 StreamBuilder m(this, kMachInt32, kMachInt32); 3130 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
3040 Node* const p0 = m.Parameter(0); 3131 Node* const p0 = m.Parameter(0);
3041 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift + 32)), 3132 Node* const r = m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(shift + 32)),
3042 m.Int32Constant(shift + 64)); 3133 m.Int32Constant(shift + 64));
3043 m.Return(r); 3134 m.Return(r);
3044 Stream s = m.Build(); 3135 Stream s = m.Build();
3045 ASSERT_EQ(1U, s.size()); 3136 ASSERT_EQ(1U, s.size());
3046 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode()); 3137 EXPECT_EQ(kArm64Sbfx32, s[0]->arch_opcode());
3047 ASSERT_EQ(3U, s[0]->InputCount()); 3138 ASSERT_EQ(3U, s[0]->InputCount());
3048 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3139 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3049 ASSERT_EQ(1U, s[0]->OutputCount()); 3140 ASSERT_EQ(1U, s[0]->OutputCount());
3050 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); 3141 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
3051 } 3142 }
3052 } 3143 }
3053 3144
3054 3145
3055 TEST_F(InstructionSelectorTest, Word32ShrWithWord32Shl) { 3146 TEST_F(InstructionSelectorTest, Word32ShrWithWord32Shl) {
3056 TRACED_FORRANGE(int32_t, shift, 1, 31) { 3147 TRACED_FORRANGE(int32_t, shift, 1, 31) {
3057 StreamBuilder m(this, kMachInt32, kMachInt32); 3148 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
3058 Node* const p0 = m.Parameter(0); 3149 Node* const p0 = m.Parameter(0);
3059 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift)), 3150 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift)),
3060 m.Int32Constant(shift)); 3151 m.Int32Constant(shift));
3061 m.Return(r); 3152 m.Return(r);
3062 Stream s = m.Build(); 3153 Stream s = m.Build();
3063 ASSERT_EQ(1U, s.size()); 3154 ASSERT_EQ(1U, s.size());
3064 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); 3155 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
3065 ASSERT_EQ(3U, s[0]->InputCount()); 3156 ASSERT_EQ(3U, s[0]->InputCount());
3066 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3157 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3067 ASSERT_EQ(1U, s[0]->OutputCount()); 3158 ASSERT_EQ(1U, s[0]->OutputCount());
3068 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); 3159 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
3069 } 3160 }
3070 TRACED_FORRANGE(int32_t, shift, 1, 31) { 3161 TRACED_FORRANGE(int32_t, shift, 1, 31) {
3071 StreamBuilder m(this, kMachInt32, kMachInt32); 3162 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
3072 Node* const p0 = m.Parameter(0); 3163 Node* const p0 = m.Parameter(0);
3073 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift + 32)), 3164 Node* const r = m.Word32Shr(m.Word32Shl(p0, m.Int32Constant(shift + 32)),
3074 m.Int32Constant(shift + 64)); 3165 m.Int32Constant(shift + 64));
3075 m.Return(r); 3166 m.Return(r);
3076 Stream s = m.Build(); 3167 Stream s = m.Build();
3077 ASSERT_EQ(1U, s.size()); 3168 ASSERT_EQ(1U, s.size());
3078 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode()); 3169 EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
3079 ASSERT_EQ(3U, s[0]->InputCount()); 3170 ASSERT_EQ(3U, s[0]->InputCount());
3080 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3171 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3081 ASSERT_EQ(1U, s[0]->OutputCount()); 3172 ASSERT_EQ(1U, s[0]->OutputCount());
3082 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); 3173 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
3083 } 3174 }
3084 } 3175 }
3085 3176
3086 3177
3087 TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) { 3178 TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) {
3088 TRACED_FORRANGE(int32_t, shift, 1, 30) { 3179 TRACED_FORRANGE(int32_t, shift, 1, 30) {
3089 StreamBuilder m(this, kMachInt32, kMachInt32); 3180 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
3090 Node* const p0 = m.Parameter(0); 3181 Node* const p0 = m.Parameter(0);
3091 Node* const r = 3182 Node* const r =
3092 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), 3183 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)),
3093 m.Int32Constant(shift)); 3184 m.Int32Constant(shift));
3094 m.Return(r); 3185 m.Return(r);
3095 Stream s = m.Build(); 3186 Stream s = m.Build();
3096 ASSERT_EQ(1U, s.size()); 3187 ASSERT_EQ(1U, s.size());
3097 EXPECT_EQ(kArm64Ubfiz32, s[0]->arch_opcode()); 3188 EXPECT_EQ(kArm64Ubfiz32, s[0]->arch_opcode());
3098 ASSERT_EQ(3U, s[0]->InputCount()); 3189 ASSERT_EQ(3U, s[0]->InputCount());
3099 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3190 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3100 ASSERT_EQ(1U, s[0]->OutputCount()); 3191 ASSERT_EQ(1U, s[0]->OutputCount());
3101 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); 3192 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
3102 } 3193 }
3103 TRACED_FORRANGE(int32_t, shift, 0, 30) { 3194 TRACED_FORRANGE(int32_t, shift, 0, 30) {
3104 StreamBuilder m(this, kMachInt32, kMachInt32); 3195 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
3105 Node* const p0 = m.Parameter(0); 3196 Node* const p0 = m.Parameter(0);
3106 Node* const r = 3197 Node* const r =
3107 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), 3198 m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)),
3108 m.Int32Constant(shift + 1)); 3199 m.Int32Constant(shift + 1));
3109 m.Return(r); 3200 m.Return(r);
3110 Stream s = m.Build(); 3201 Stream s = m.Build();
3111 ASSERT_EQ(1U, s.size()); 3202 ASSERT_EQ(1U, s.size());
3112 EXPECT_EQ(kArm64Lsl32, s[0]->arch_opcode()); 3203 EXPECT_EQ(kArm64Lsl32, s[0]->arch_opcode());
3113 ASSERT_EQ(2U, s[0]->InputCount()); 3204 ASSERT_EQ(2U, s[0]->InputCount());
3114 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3205 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3115 ASSERT_EQ(1U, s[0]->OutputCount()); 3206 ASSERT_EQ(1U, s[0]->OutputCount());
3116 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); 3207 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
3117 } 3208 }
3118 } 3209 }
3119 3210
3120 3211
3121 TEST_F(InstructionSelectorTest, Word32Clz) { 3212 TEST_F(InstructionSelectorTest, Word32Clz) {
3122 StreamBuilder m(this, kMachUint32, kMachUint32); 3213 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32());
3123 Node* const p0 = m.Parameter(0); 3214 Node* const p0 = m.Parameter(0);
3124 Node* const n = m.Word32Clz(p0); 3215 Node* const n = m.Word32Clz(p0);
3125 m.Return(n); 3216 m.Return(n);
3126 Stream s = m.Build(); 3217 Stream s = m.Build();
3127 ASSERT_EQ(1U, s.size()); 3218 ASSERT_EQ(1U, s.size());
3128 EXPECT_EQ(kArm64Clz32, s[0]->arch_opcode()); 3219 EXPECT_EQ(kArm64Clz32, s[0]->arch_opcode());
3129 ASSERT_EQ(1U, s[0]->InputCount()); 3220 ASSERT_EQ(1U, s[0]->InputCount());
3130 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3221 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3131 ASSERT_EQ(1U, s[0]->OutputCount()); 3222 ASSERT_EQ(1U, s[0]->OutputCount());
3132 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3223 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3133 } 3224 }
3134 3225
3135 3226
3136 TEST_F(InstructionSelectorTest, Float32Abs) { 3227 TEST_F(InstructionSelectorTest, Float32Abs) {
3137 StreamBuilder m(this, kMachFloat32, kMachFloat32); 3228 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32());
3138 Node* const p0 = m.Parameter(0); 3229 Node* const p0 = m.Parameter(0);
3139 Node* const n = m.Float32Abs(p0); 3230 Node* const n = m.Float32Abs(p0);
3140 m.Return(n); 3231 m.Return(n);
3141 Stream s = m.Build(); 3232 Stream s = m.Build();
3142 ASSERT_EQ(1U, s.size()); 3233 ASSERT_EQ(1U, s.size());
3143 EXPECT_EQ(kArm64Float32Abs, s[0]->arch_opcode()); 3234 EXPECT_EQ(kArm64Float32Abs, s[0]->arch_opcode());
3144 ASSERT_EQ(1U, s[0]->InputCount()); 3235 ASSERT_EQ(1U, s[0]->InputCount());
3145 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3236 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3146 ASSERT_EQ(1U, s[0]->OutputCount()); 3237 ASSERT_EQ(1U, s[0]->OutputCount());
3147 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3238 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3148 } 3239 }
3149 3240
3150 3241
3151 TEST_F(InstructionSelectorTest, Float64Abs) { 3242 TEST_F(InstructionSelectorTest, Float64Abs) {
3152 StreamBuilder m(this, kMachFloat64, kMachFloat64); 3243 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
3153 Node* const p0 = m.Parameter(0); 3244 Node* const p0 = m.Parameter(0);
3154 Node* const n = m.Float64Abs(p0); 3245 Node* const n = m.Float64Abs(p0);
3155 m.Return(n); 3246 m.Return(n);
3156 Stream s = m.Build(); 3247 Stream s = m.Build();
3157 ASSERT_EQ(1U, s.size()); 3248 ASSERT_EQ(1U, s.size());
3158 EXPECT_EQ(kArm64Float64Abs, s[0]->arch_opcode()); 3249 EXPECT_EQ(kArm64Float64Abs, s[0]->arch_opcode());
3159 ASSERT_EQ(1U, s[0]->InputCount()); 3250 ASSERT_EQ(1U, s[0]->InputCount());
3160 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3251 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3161 ASSERT_EQ(1U, s[0]->OutputCount()); 3252 ASSERT_EQ(1U, s[0]->OutputCount());
3162 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3253 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3163 } 3254 }
3164 3255
3165 3256
3166 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) { 3257 TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
3167 StreamBuilder m(this, kMachFloat64, kMachFloat64); 3258 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64());
3168 Node* const p0 = m.Parameter(0); 3259 Node* const p0 = m.Parameter(0);
3169 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); 3260 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
3170 m.Return(n); 3261 m.Return(n);
3171 Stream s = m.Build(); 3262 Stream s = m.Build();
3172 ASSERT_EQ(1U, s.size()); 3263 ASSERT_EQ(1U, s.size());
3173 EXPECT_EQ(kArm64Float64Neg, s[0]->arch_opcode()); 3264 EXPECT_EQ(kArm64Float64Neg, s[0]->arch_opcode());
3174 ASSERT_EQ(1U, s[0]->InputCount()); 3265 ASSERT_EQ(1U, s[0]->InputCount());
3175 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3266 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3176 ASSERT_EQ(1U, s[0]->OutputCount()); 3267 ASSERT_EQ(1U, s[0]->OutputCount());
3177 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3268 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3178 } 3269 }
3179 3270
3180 3271
3181 TEST_F(InstructionSelectorTest, Float32Max) { 3272 TEST_F(InstructionSelectorTest, Float32Max) {
3182 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); 3273 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(),
3274 MachineType::Float32());
3183 Node* const p0 = m.Parameter(0); 3275 Node* const p0 = m.Parameter(0);
3184 Node* const p1 = m.Parameter(1); 3276 Node* const p1 = m.Parameter(1);
3185 Node* const n = m.Float32Max(p0, p1); 3277 Node* const n = m.Float32Max(p0, p1);
3186 m.Return(n); 3278 m.Return(n);
3187 Stream s = m.Build(); 3279 Stream s = m.Build();
3188 // Float32Max is `(b < a) ? a : b`. 3280 // Float32Max is `(b < a) ? a : b`.
3189 ASSERT_EQ(1U, s.size()); 3281 ASSERT_EQ(1U, s.size());
3190 EXPECT_EQ(kArm64Float32Max, s[0]->arch_opcode()); 3282 EXPECT_EQ(kArm64Float32Max, s[0]->arch_opcode());
3191 ASSERT_EQ(2U, s[0]->InputCount()); 3283 ASSERT_EQ(2U, s[0]->InputCount());
3192 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3284 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3193 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 3285 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
3194 ASSERT_EQ(1U, s[0]->OutputCount()); 3286 ASSERT_EQ(1U, s[0]->OutputCount());
3195 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3287 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3196 } 3288 }
3197 3289
3198 3290
3199 TEST_F(InstructionSelectorTest, Float32Min) { 3291 TEST_F(InstructionSelectorTest, Float32Min) {
3200 StreamBuilder m(this, kMachFloat32, kMachFloat32, kMachFloat32); 3292 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32(),
3293 MachineType::Float32());
3201 Node* const p0 = m.Parameter(0); 3294 Node* const p0 = m.Parameter(0);
3202 Node* const p1 = m.Parameter(1); 3295 Node* const p1 = m.Parameter(1);
3203 Node* const n = m.Float32Min(p0, p1); 3296 Node* const n = m.Float32Min(p0, p1);
3204 m.Return(n); 3297 m.Return(n);
3205 Stream s = m.Build(); 3298 Stream s = m.Build();
3206 // Float32Min is `(a < b) ? a : b`. 3299 // Float32Min is `(a < b) ? a : b`.
3207 ASSERT_EQ(1U, s.size()); 3300 ASSERT_EQ(1U, s.size());
3208 EXPECT_EQ(kArm64Float32Min, s[0]->arch_opcode()); 3301 EXPECT_EQ(kArm64Float32Min, s[0]->arch_opcode());
3209 ASSERT_EQ(2U, s[0]->InputCount()); 3302 ASSERT_EQ(2U, s[0]->InputCount());
3210 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3303 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3211 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 3304 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
3212 ASSERT_EQ(1U, s[0]->OutputCount()); 3305 ASSERT_EQ(1U, s[0]->OutputCount());
3213 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3306 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3214 } 3307 }
3215 3308
3216 3309
3217 TEST_F(InstructionSelectorTest, Float64Max) { 3310 TEST_F(InstructionSelectorTest, Float64Max) {
3218 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); 3311 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
3312 MachineType::Float64());
3219 Node* const p0 = m.Parameter(0); 3313 Node* const p0 = m.Parameter(0);
3220 Node* const p1 = m.Parameter(1); 3314 Node* const p1 = m.Parameter(1);
3221 Node* const n = m.Float64Max(p0, p1); 3315 Node* const n = m.Float64Max(p0, p1);
3222 m.Return(n); 3316 m.Return(n);
3223 Stream s = m.Build(); 3317 Stream s = m.Build();
3224 // Float64Max is `(b < a) ? a : b`. 3318 // Float64Max is `(b < a) ? a : b`.
3225 ASSERT_EQ(1U, s.size()); 3319 ASSERT_EQ(1U, s.size());
3226 EXPECT_EQ(kArm64Float64Max, s[0]->arch_opcode()); 3320 EXPECT_EQ(kArm64Float64Max, s[0]->arch_opcode());
3227 ASSERT_EQ(2U, s[0]->InputCount()); 3321 ASSERT_EQ(2U, s[0]->InputCount());
3228 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3322 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3229 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 3323 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
3230 ASSERT_EQ(1U, s[0]->OutputCount()); 3324 ASSERT_EQ(1U, s[0]->OutputCount());
3231 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3325 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3232 } 3326 }
3233 3327
3234 3328
3235 TEST_F(InstructionSelectorTest, Float64Min) { 3329 TEST_F(InstructionSelectorTest, Float64Min) {
3236 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); 3330 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(),
3331 MachineType::Float64());
3237 Node* const p0 = m.Parameter(0); 3332 Node* const p0 = m.Parameter(0);
3238 Node* const p1 = m.Parameter(1); 3333 Node* const p1 = m.Parameter(1);
3239 Node* const n = m.Float64Min(p0, p1); 3334 Node* const n = m.Float64Min(p0, p1);
3240 m.Return(n); 3335 m.Return(n);
3241 Stream s = m.Build(); 3336 Stream s = m.Build();
3242 // Float64Min is `(a < b) ? a : b`. 3337 // Float64Min is `(a < b) ? a : b`.
3243 ASSERT_EQ(1U, s.size()); 3338 ASSERT_EQ(1U, s.size());
3244 EXPECT_EQ(kArm64Float64Min, s[0]->arch_opcode()); 3339 EXPECT_EQ(kArm64Float64Min, s[0]->arch_opcode());
3245 ASSERT_EQ(2U, s[0]->InputCount()); 3340 ASSERT_EQ(2U, s[0]->InputCount());
3246 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); 3341 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
3247 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); 3342 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
3248 ASSERT_EQ(1U, s[0]->OutputCount()); 3343 ASSERT_EQ(1U, s[0]->OutputCount());
3249 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); 3344 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
3250 } 3345 }
3251 3346
3252 } // namespace compiler 3347 } // namespace compiler
3253 } // namespace internal 3348 } // namespace internal
3254 } // namespace v8 3349 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698