OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
6 | 6 |
7 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |