OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include <list> | |
6 | |
7 #include "test/cctest/compiler/instruction-selector-tester.h" | |
8 #include "test/cctest/compiler/value-helper.h" | |
9 | |
10 using namespace v8::internal; | |
11 using namespace v8::internal::compiler; | |
12 | |
13 namespace { | |
14 | |
15 typedef RawMachineAssembler::Label MLabel; | |
16 | |
17 struct DPI { | |
18 Operator* op; | |
19 ArchOpcode arch_opcode; | |
20 ArchOpcode reverse_arch_opcode; | |
21 ArchOpcode test_arch_opcode; | |
22 }; | |
23 | |
24 | |
25 // ARM data processing instructions. | |
26 class DPIs V8_FINAL : public std::list<DPI>, private HandleAndZoneScope { | |
27 public: | |
28 DPIs() { | |
29 MachineOperatorBuilder machine(main_zone()); | |
30 DPI and_ = {machine.Word32And(), kArmAnd, kArmAnd, kArmTst}; | |
31 push_back(and_); | |
32 DPI or_ = {machine.Word32Or(), kArmOrr, kArmOrr, kArmOrr}; | |
33 push_back(or_); | |
34 DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq}; | |
35 push_back(xor_); | |
36 DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn}; | |
37 push_back(add); | |
38 DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp}; | |
39 push_back(sub); | |
40 } | |
41 }; | |
42 | |
43 | |
44 struct ODPI { | |
45 Operator* op; | |
46 ArchOpcode arch_opcode; | |
47 ArchOpcode reverse_arch_opcode; | |
48 }; | |
49 | |
50 | |
51 // ARM data processing instructions with overflow. | |
52 class ODPIs V8_FINAL : public std::list<ODPI>, private HandleAndZoneScope { | |
53 public: | |
54 ODPIs() { | |
55 MachineOperatorBuilder machine(main_zone()); | |
56 ODPI add = {machine.Int32AddWithOverflow(), kArmAdd, kArmAdd}; | |
57 push_back(add); | |
58 ODPI sub = {machine.Int32SubWithOverflow(), kArmSub, kArmRsb}; | |
59 push_back(sub); | |
60 } | |
61 }; | |
62 | |
63 | |
64 // ARM immediates. | |
65 class Immediates V8_FINAL : public std::list<int32_t> { | |
66 public: | |
67 Immediates() { | |
68 for (uint32_t imm8 = 0; imm8 < 256; ++imm8) { | |
69 for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) { | |
70 int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4)); | |
71 CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm)); | |
72 push_back(imm); | |
73 } | |
74 } | |
75 } | |
76 }; | |
77 | |
78 | |
79 struct Shift { | |
80 Operator* op; | |
81 int32_t i_low; // lowest possible immediate | |
82 int32_t i_high; // highest possible immediate | |
83 AddressingMode i_mode; // Operand2_R_<shift>_I | |
84 AddressingMode r_mode; // Operand2_R_<shift>_R | |
85 }; | |
86 | |
87 | |
88 // ARM shifts. | |
89 class Shifts V8_FINAL : public std::list<Shift>, private HandleAndZoneScope { | |
90 public: | |
91 Shifts() { | |
92 MachineOperatorBuilder machine(main_zone()); | |
93 Shift sar = {machine.Word32Sar(), 1, 32, kMode_Operand2_R_ASR_I, | |
94 kMode_Operand2_R_ASR_R}; | |
95 Shift shl = {machine.Word32Shl(), 0, 31, kMode_Operand2_R_LSL_I, | |
96 kMode_Operand2_R_LSL_R}; | |
97 Shift shr = {machine.Word32Shr(), 1, 32, kMode_Operand2_R_LSR_I, | |
98 kMode_Operand2_R_LSR_R}; | |
99 push_back(sar); | |
100 push_back(shl); | |
101 push_back(shr); | |
102 } | |
103 }; | |
104 | |
105 } // namespace | |
106 | |
107 | |
108 TEST(InstructionSelectorDPIP) { | |
109 DPIs dpis; | |
110 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
111 DPI dpi = *i; | |
112 InstructionSelectorTester m; | |
113 m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1))); | |
114 m.SelectInstructions(); | |
115 CHECK_EQ(1, m.code.size()); | |
116 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode()); | |
117 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
118 } | |
119 } | |
120 | |
121 | |
122 TEST(InstructionSelectorDPIImm) { | |
123 DPIs dpis; | |
124 Immediates immediates; | |
125 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
126 DPI dpi = *i; | |
127 for (Immediates::const_iterator j = immediates.begin(); | |
128 j != immediates.end(); ++j) { | |
129 int32_t imm = *j; | |
130 { | |
131 InstructionSelectorTester m; | |
132 m.Return(m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm))); | |
133 m.SelectInstructions(); | |
134 CHECK_EQ(1, m.code.size()); | |
135 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode()); | |
136 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
137 } | |
138 { | |
139 InstructionSelectorTester m; | |
140 m.Return(m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0))); | |
141 m.SelectInstructions(); | |
142 CHECK_EQ(1, m.code.size()); | |
143 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
144 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
145 } | |
146 } | |
147 } | |
148 } | |
149 | |
150 | |
151 TEST(InstructionSelectorDPIAndShiftP) { | |
152 DPIs dpis; | |
153 Shifts shifts; | |
154 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
155 DPI dpi = *i; | |
156 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { | |
157 Shift shift = *j; | |
158 { | |
159 InstructionSelectorTester m; | |
160 m.Return( | |
161 m.NewNode(dpi.op, m.Parameter(0), | |
162 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))); | |
163 m.SelectInstructions(); | |
164 CHECK_EQ(1, m.code.size()); | |
165 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode()); | |
166 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
167 } | |
168 { | |
169 InstructionSelectorTester m; | |
170 m.Return(m.NewNode(dpi.op, | |
171 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), | |
172 m.Parameter(2))); | |
173 m.SelectInstructions(); | |
174 CHECK_EQ(1, m.code.size()); | |
175 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
176 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
177 } | |
178 } | |
179 } | |
180 } | |
181 | |
182 | |
183 TEST(InstructionSelectorDPIAndRotateRightP) { | |
184 DPIs dpis; | |
185 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
186 DPI dpi = *i; | |
187 { | |
188 InstructionSelectorTester m; | |
189 Node* value = m.Parameter(1); | |
190 Node* shift = m.Parameter(2); | |
191 Node* ror = m.Word32Or( | |
192 m.Word32Shr(value, shift), | |
193 m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift))); | |
194 m.Return(m.NewNode(dpi.op, m.Parameter(0), ror)); | |
195 m.SelectInstructions(); | |
196 CHECK_EQ(1, m.code.size()); | |
197 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode()); | |
198 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
199 } | |
200 { | |
201 InstructionSelectorTester m; | |
202 Node* value = m.Parameter(1); | |
203 Node* shift = m.Parameter(2); | |
204 Node* ror = | |
205 m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)), | |
206 m.Word32Shr(value, shift)); | |
207 m.Return(m.NewNode(dpi.op, m.Parameter(0), ror)); | |
208 m.SelectInstructions(); | |
209 CHECK_EQ(1, m.code.size()); | |
210 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode()); | |
211 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
212 } | |
213 { | |
214 InstructionSelectorTester m; | |
215 Node* value = m.Parameter(1); | |
216 Node* shift = m.Parameter(2); | |
217 Node* ror = m.Word32Or( | |
218 m.Word32Shr(value, shift), | |
219 m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift))); | |
220 m.Return(m.NewNode(dpi.op, ror, m.Parameter(0))); | |
221 m.SelectInstructions(); | |
222 CHECK_EQ(1, m.code.size()); | |
223 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
224 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
225 } | |
226 { | |
227 InstructionSelectorTester m; | |
228 Node* value = m.Parameter(1); | |
229 Node* shift = m.Parameter(2); | |
230 Node* ror = | |
231 m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)), | |
232 m.Word32Shr(value, shift)); | |
233 m.Return(m.NewNode(dpi.op, ror, m.Parameter(0))); | |
234 m.SelectInstructions(); | |
235 CHECK_EQ(1, m.code.size()); | |
236 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
237 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
238 } | |
239 } | |
240 } | |
241 | |
242 | |
243 TEST(InstructionSelectorDPIAndShiftImm) { | |
244 DPIs dpis; | |
245 Shifts shifts; | |
246 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
247 DPI dpi = *i; | |
248 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { | |
249 Shift shift = *j; | |
250 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { | |
251 { | |
252 InstructionSelectorTester m; | |
253 m.Return(m.NewNode( | |
254 dpi.op, m.Parameter(0), | |
255 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)))); | |
256 m.SelectInstructions(); | |
257 CHECK_EQ(1, m.code.size()); | |
258 CHECK_EQ(dpi.arch_opcode, m.code[0]->arch_opcode()); | |
259 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
260 } | |
261 { | |
262 InstructionSelectorTester m; | |
263 m.Return(m.NewNode( | |
264 dpi.op, m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), | |
265 m.Parameter(1))); | |
266 m.SelectInstructions(); | |
267 CHECK_EQ(1, m.code.size()); | |
268 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
269 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
270 } | |
271 } | |
272 } | |
273 } | |
274 } | |
275 | |
276 | |
277 TEST(InstructionSelectorODPIP) { | |
278 ODPIs odpis; | |
279 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { | |
280 ODPI odpi = *i; | |
281 { | |
282 InstructionSelectorTester m; | |
283 m.Return( | |
284 m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)))); | |
285 m.SelectInstructions(); | |
286 CHECK_EQ(1, m.code.size()); | |
287 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
288 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
289 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
290 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
291 CHECK_EQ(2, m.code[0]->InputCount()); | |
292 CHECK_LE(1, m.code[0]->OutputCount()); | |
293 } | |
294 { | |
295 InstructionSelectorTester m; | |
296 m.Return( | |
297 m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)))); | |
298 m.SelectInstructions(); | |
299 CHECK_EQ(1, m.code.size()); | |
300 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
301 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
302 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
303 CHECK_EQ(2, m.code[0]->InputCount()); | |
304 CHECK_LE(1, m.code[0]->OutputCount()); | |
305 } | |
306 { | |
307 InstructionSelectorTester m; | |
308 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)); | |
309 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); | |
310 m.SelectInstructions(); | |
311 CHECK_LE(1, m.code.size()); | |
312 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
313 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
314 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
315 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
316 CHECK_EQ(2, m.code[0]->InputCount()); | |
317 CHECK_EQ(2, m.code[0]->OutputCount()); | |
318 } | |
319 } | |
320 } | |
321 | |
322 | |
323 TEST(InstructionSelectorODPIImm) { | |
324 ODPIs odpis; | |
325 Immediates immediates; | |
326 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { | |
327 ODPI odpi = *i; | |
328 for (Immediates::const_iterator j = immediates.begin(); | |
329 j != immediates.end(); ++j) { | |
330 int32_t imm = *j; | |
331 { | |
332 InstructionSelectorTester m; | |
333 m.Return(m.Projection( | |
334 1, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)))); | |
335 m.SelectInstructions(); | |
336 CHECK_EQ(1, m.code.size()); | |
337 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
338 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
339 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
340 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
341 CHECK_EQ(2, m.code[0]->InputCount()); | |
342 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
343 CHECK_LE(1, m.code[0]->OutputCount()); | |
344 } | |
345 { | |
346 InstructionSelectorTester m; | |
347 m.Return(m.Projection( | |
348 1, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)))); | |
349 m.SelectInstructions(); | |
350 CHECK_EQ(1, m.code.size()); | |
351 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
352 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
353 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
354 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
355 CHECK_EQ(2, m.code[0]->InputCount()); | |
356 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
357 CHECK_LE(1, m.code[0]->OutputCount()); | |
358 } | |
359 { | |
360 InstructionSelectorTester m; | |
361 m.Return(m.Projection( | |
362 0, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)))); | |
363 m.SelectInstructions(); | |
364 CHECK_EQ(1, m.code.size()); | |
365 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
366 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
367 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
368 CHECK_EQ(2, m.code[0]->InputCount()); | |
369 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
370 CHECK_LE(1, m.code[0]->OutputCount()); | |
371 } | |
372 { | |
373 InstructionSelectorTester m; | |
374 m.Return(m.Projection( | |
375 0, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)))); | |
376 m.SelectInstructions(); | |
377 CHECK_EQ(1, m.code.size()); | |
378 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
379 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
380 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
381 CHECK_EQ(2, m.code[0]->InputCount()); | |
382 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
383 CHECK_LE(1, m.code[0]->OutputCount()); | |
384 } | |
385 { | |
386 InstructionSelectorTester m; | |
387 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)); | |
388 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); | |
389 m.SelectInstructions(); | |
390 CHECK_LE(1, m.code.size()); | |
391 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
392 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
393 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
394 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
395 CHECK_EQ(2, m.code[0]->InputCount()); | |
396 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
397 CHECK_EQ(2, m.code[0]->OutputCount()); | |
398 } | |
399 { | |
400 InstructionSelectorTester m; | |
401 Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)); | |
402 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); | |
403 m.SelectInstructions(); | |
404 CHECK_LE(1, m.code.size()); | |
405 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
406 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
407 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
408 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
409 CHECK_EQ(2, m.code[0]->InputCount()); | |
410 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
411 CHECK_EQ(2, m.code[0]->OutputCount()); | |
412 } | |
413 } | |
414 } | |
415 } | |
416 | |
417 | |
418 TEST(InstructionSelectorODPIAndShiftP) { | |
419 ODPIs odpis; | |
420 Shifts shifts; | |
421 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { | |
422 ODPI odpi = *i; | |
423 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { | |
424 Shift shift = *j; | |
425 { | |
426 InstructionSelectorTester m; | |
427 m.Return(m.Projection( | |
428 1, m.NewNode(odpi.op, m.Parameter(0), | |
429 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))))); | |
430 m.SelectInstructions(); | |
431 CHECK_EQ(1, m.code.size()); | |
432 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
433 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
434 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
435 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
436 CHECK_EQ(3, m.code[0]->InputCount()); | |
437 CHECK_LE(1, m.code[0]->OutputCount()); | |
438 } | |
439 { | |
440 InstructionSelectorTester m; | |
441 m.Return(m.Projection( | |
442 1, m.NewNode(odpi.op, | |
443 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), | |
444 m.Parameter(2)))); | |
445 m.SelectInstructions(); | |
446 CHECK_EQ(1, m.code.size()); | |
447 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
448 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
449 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
450 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
451 CHECK_EQ(3, m.code[0]->InputCount()); | |
452 CHECK_LE(1, m.code[0]->OutputCount()); | |
453 } | |
454 { | |
455 InstructionSelectorTester m; | |
456 m.Return(m.Projection( | |
457 0, m.NewNode(odpi.op, m.Parameter(0), | |
458 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))))); | |
459 m.SelectInstructions(); | |
460 CHECK_EQ(1, m.code.size()); | |
461 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
462 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
463 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
464 CHECK_EQ(3, m.code[0]->InputCount()); | |
465 CHECK_LE(1, m.code[0]->OutputCount()); | |
466 } | |
467 { | |
468 InstructionSelectorTester m; | |
469 m.Return(m.Projection( | |
470 0, m.NewNode(odpi.op, | |
471 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), | |
472 m.Parameter(2)))); | |
473 m.SelectInstructions(); | |
474 CHECK_EQ(1, m.code.size()); | |
475 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
476 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
477 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
478 CHECK_EQ(3, m.code[0]->InputCount()); | |
479 CHECK_LE(1, m.code[0]->OutputCount()); | |
480 } | |
481 { | |
482 InstructionSelectorTester m; | |
483 Node* node = | |
484 m.NewNode(odpi.op, m.Parameter(0), | |
485 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))); | |
486 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); | |
487 m.SelectInstructions(); | |
488 CHECK_LE(1, m.code.size()); | |
489 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
490 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
491 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
492 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
493 CHECK_EQ(3, m.code[0]->InputCount()); | |
494 CHECK_EQ(2, m.code[0]->OutputCount()); | |
495 } | |
496 { | |
497 InstructionSelectorTester m; | |
498 Node* node = m.NewNode( | |
499 odpi.op, m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), | |
500 m.Parameter(2)); | |
501 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); | |
502 m.SelectInstructions(); | |
503 CHECK_LE(1, m.code.size()); | |
504 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
505 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
506 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
507 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
508 CHECK_EQ(3, m.code[0]->InputCount()); | |
509 CHECK_EQ(2, m.code[0]->OutputCount()); | |
510 } | |
511 } | |
512 } | |
513 } | |
514 | |
515 | |
516 TEST(InstructionSelectorODPIAndShiftImm) { | |
517 ODPIs odpis; | |
518 Shifts shifts; | |
519 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { | |
520 ODPI odpi = *i; | |
521 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { | |
522 Shift shift = *j; | |
523 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { | |
524 { | |
525 InstructionSelectorTester m; | |
526 m.Return(m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), | |
527 m.NewNode(shift.op, m.Parameter(1), | |
528 m.Int32Constant(imm))))); | |
529 m.SelectInstructions(); | |
530 CHECK_EQ(1, m.code.size()); | |
531 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
532 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
533 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
534 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
535 CHECK_EQ(3, m.code[0]->InputCount()); | |
536 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
537 CHECK_LE(1, m.code[0]->OutputCount()); | |
538 } | |
539 { | |
540 InstructionSelectorTester m; | |
541 m.Return(m.Projection( | |
542 1, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), | |
543 m.Int32Constant(imm)), | |
544 m.Parameter(1)))); | |
545 m.SelectInstructions(); | |
546 CHECK_EQ(1, m.code.size()); | |
547 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
548 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
549 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
550 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
551 CHECK_EQ(3, m.code[0]->InputCount()); | |
552 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
553 CHECK_LE(1, m.code[0]->OutputCount()); | |
554 } | |
555 { | |
556 InstructionSelectorTester m; | |
557 m.Return(m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), | |
558 m.NewNode(shift.op, m.Parameter(1), | |
559 m.Int32Constant(imm))))); | |
560 m.SelectInstructions(); | |
561 CHECK_EQ(1, m.code.size()); | |
562 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
563 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
564 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
565 CHECK_EQ(3, m.code[0]->InputCount()); | |
566 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
567 CHECK_LE(1, m.code[0]->OutputCount()); | |
568 } | |
569 { | |
570 InstructionSelectorTester m; | |
571 m.Return(m.Projection( | |
572 0, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), | |
573 m.Int32Constant(imm)), | |
574 m.Parameter(1)))); | |
575 m.SelectInstructions(); | |
576 CHECK_EQ(1, m.code.size()); | |
577 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
578 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
579 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
580 CHECK_EQ(3, m.code[0]->InputCount()); | |
581 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
582 CHECK_LE(1, m.code[0]->OutputCount()); | |
583 } | |
584 { | |
585 InstructionSelectorTester m; | |
586 Node* node = m.NewNode( | |
587 odpi.op, m.Parameter(0), | |
588 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm))); | |
589 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); | |
590 m.SelectInstructions(); | |
591 CHECK_LE(1, m.code.size()); | |
592 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
593 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
594 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
595 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
596 CHECK_EQ(3, m.code[0]->InputCount()); | |
597 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
598 CHECK_EQ(2, m.code[0]->OutputCount()); | |
599 } | |
600 { | |
601 InstructionSelectorTester m; | |
602 Node* node = m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), | |
603 m.Int32Constant(imm)), | |
604 m.Parameter(1)); | |
605 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); | |
606 m.SelectInstructions(); | |
607 CHECK_LE(1, m.code.size()); | |
608 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
609 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
610 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
611 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
612 CHECK_EQ(3, m.code[0]->InputCount()); | |
613 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
614 CHECK_EQ(2, m.code[0]->OutputCount()); | |
615 } | |
616 } | |
617 } | |
618 } | |
619 } | |
620 | |
621 | |
622 TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) { | |
623 { | |
624 InstructionSelectorTester m; | |
625 m.Return(m.Word32And(m.Parameter(0), | |
626 m.Word32Xor(m.Int32Constant(-1), m.Parameter(1)))); | |
627 m.SelectInstructions(); | |
628 CHECK_EQ(1, m.code.size()); | |
629 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
630 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
631 } | |
632 { | |
633 InstructionSelectorTester m; | |
634 m.Return(m.Word32And(m.Parameter(0), | |
635 m.Word32Xor(m.Parameter(1), m.Int32Constant(-1)))); | |
636 m.SelectInstructions(); | |
637 CHECK_EQ(1, m.code.size()); | |
638 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
639 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
640 } | |
641 { | |
642 InstructionSelectorTester m; | |
643 m.Return(m.Word32And(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)), | |
644 m.Parameter(1))); | |
645 m.SelectInstructions(); | |
646 CHECK_EQ(1, m.code.size()); | |
647 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
648 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
649 } | |
650 { | |
651 InstructionSelectorTester m; | |
652 m.Return(m.Word32And(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)), | |
653 m.Parameter(1))); | |
654 m.SelectInstructions(); | |
655 CHECK_EQ(1, m.code.size()); | |
656 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
657 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
658 } | |
659 } | |
660 | |
661 | |
662 TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1AndShiftP) { | |
663 Shifts shifts; | |
664 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | |
665 Shift shift = *i; | |
666 { | |
667 InstructionSelectorTester m; | |
668 m.Return(m.Word32And( | |
669 m.Parameter(0), | |
670 m.Word32Xor(m.Int32Constant(-1), | |
671 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))))); | |
672 m.SelectInstructions(); | |
673 CHECK_EQ(1, m.code.size()); | |
674 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
675 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
676 } | |
677 { | |
678 InstructionSelectorTester m; | |
679 m.Return(m.Word32And( | |
680 m.Parameter(0), | |
681 m.Word32Xor(m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | |
682 m.Int32Constant(-1)))); | |
683 m.SelectInstructions(); | |
684 CHECK_EQ(1, m.code.size()); | |
685 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
686 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
687 } | |
688 { | |
689 InstructionSelectorTester m; | |
690 m.Return(m.Word32And( | |
691 m.Word32Xor(m.Int32Constant(-1), | |
692 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1))), | |
693 m.Parameter(2))); | |
694 m.SelectInstructions(); | |
695 CHECK_EQ(1, m.code.size()); | |
696 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
697 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
698 } | |
699 { | |
700 InstructionSelectorTester m; | |
701 m.Return(m.Word32And( | |
702 m.Word32Xor(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), | |
703 m.Int32Constant(-1)), | |
704 m.Parameter(2))); | |
705 m.SelectInstructions(); | |
706 CHECK_EQ(1, m.code.size()); | |
707 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | |
708 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
709 } | |
710 } | |
711 } | |
712 | |
713 | |
714 TEST(InstructionSelectorWord32XorWithMinus1P) { | |
715 { | |
716 InstructionSelectorTester m; | |
717 m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0))); | |
718 m.SelectInstructions(); | |
719 CHECK_EQ(1, m.code.size()); | |
720 CHECK_EQ(kArmMvn, m.code[0]->arch_opcode()); | |
721 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
722 } | |
723 { | |
724 InstructionSelectorTester m; | |
725 m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1))); | |
726 m.SelectInstructions(); | |
727 CHECK_EQ(1, m.code.size()); | |
728 CHECK_EQ(kArmMvn, m.code[0]->arch_opcode()); | |
729 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
730 } | |
731 } | |
732 | |
733 | |
734 TEST(InstructionSelectorWord32XorWithMinus1AndShiftP) { | |
735 Shifts shifts; | |
736 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | |
737 Shift shift = *i; | |
738 { | |
739 InstructionSelectorTester m; | |
740 m.Return( | |
741 m.Word32Xor(m.Int32Constant(-1), | |
742 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)))); | |
743 m.SelectInstructions(); | |
744 CHECK_EQ(1, m.code.size()); | |
745 CHECK_EQ(kArmMvn, m.code[0]->arch_opcode()); | |
746 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
747 } | |
748 { | |
749 InstructionSelectorTester m; | |
750 m.Return(m.Word32Xor(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), | |
751 m.Int32Constant(-1))); | |
752 m.SelectInstructions(); | |
753 CHECK_EQ(1, m.code.size()); | |
754 CHECK_EQ(kArmMvn, m.code[0]->arch_opcode()); | |
755 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
756 } | |
757 } | |
758 } | |
759 | |
760 | |
761 TEST(InstructionSelectorShiftP) { | |
762 Shifts shifts; | |
763 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | |
764 Shift shift = *i; | |
765 InstructionSelectorTester m; | |
766 m.Return(m.NewNode(shift.op, m.Parameter(0), m.Parameter(1))); | |
767 m.SelectInstructions(); | |
768 CHECK_EQ(1, m.code.size()); | |
769 CHECK_EQ(kArmMov, m.code[0]->arch_opcode()); | |
770 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
771 CHECK_EQ(2, m.code[0]->InputCount()); | |
772 } | |
773 } | |
774 | |
775 | |
776 TEST(InstructionSelectorShiftImm) { | |
777 Shifts shifts; | |
778 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | |
779 Shift shift = *i; | |
780 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { | |
781 InstructionSelectorTester m; | |
782 m.Return(m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm))); | |
783 m.SelectInstructions(); | |
784 CHECK_EQ(1, m.code.size()); | |
785 CHECK_EQ(kArmMov, m.code[0]->arch_opcode()); | |
786 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
787 CHECK_EQ(2, m.code[0]->InputCount()); | |
788 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
789 } | |
790 } | |
791 } | |
792 | |
793 | |
794 TEST(InstructionSelectorRotateRightP) { | |
795 { | |
796 InstructionSelectorTester m; | |
797 Node* value = m.Parameter(0); | |
798 Node* shift = m.Parameter(1); | |
799 m.Return( | |
800 m.Word32Or(m.Word32Shr(value, shift), | |
801 m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)))); | |
802 m.SelectInstructions(); | |
803 CHECK_EQ(1, m.code.size()); | |
804 CHECK_EQ(kArmMov, m.code[0]->arch_opcode()); | |
805 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
806 CHECK_EQ(2, m.code[0]->InputCount()); | |
807 } | |
808 { | |
809 InstructionSelectorTester m; | |
810 Node* value = m.Parameter(0); | |
811 Node* shift = m.Parameter(1); | |
812 m.Return( | |
813 m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)), | |
814 m.Word32Shr(value, shift))); | |
815 m.SelectInstructions(); | |
816 CHECK_EQ(1, m.code.size()); | |
817 CHECK_EQ(kArmMov, m.code[0]->arch_opcode()); | |
818 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
819 CHECK_EQ(2, m.code[0]->InputCount()); | |
820 } | |
821 } | |
822 | |
823 | |
824 TEST(InstructionSelectorRotateRightImm) { | |
825 FOR_INPUTS(uint32_t, ror, i) { | |
826 uint32_t shift = *i; | |
827 { | |
828 InstructionSelectorTester m; | |
829 Node* value = m.Parameter(0); | |
830 m.Return(m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)), | |
831 m.Word32Shl(value, m.Int32Constant(32 - shift)))); | |
832 m.SelectInstructions(); | |
833 CHECK_EQ(1, m.code.size()); | |
834 CHECK_EQ(kArmMov, m.code[0]->arch_opcode()); | |
835 CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode()); | |
836 CHECK_EQ(2, m.code[0]->InputCount()); | |
837 CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1))); | |
838 } | |
839 { | |
840 InstructionSelectorTester m; | |
841 Node* value = m.Parameter(0); | |
842 m.Return(m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)), | |
843 m.Word32Shr(value, m.Int32Constant(shift)))); | |
844 m.SelectInstructions(); | |
845 CHECK_EQ(1, m.code.size()); | |
846 CHECK_EQ(kArmMov, m.code[0]->arch_opcode()); | |
847 CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode()); | |
848 CHECK_EQ(2, m.code[0]->InputCount()); | |
849 CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(1))); | |
850 } | |
851 } | |
852 } | |
853 | |
854 | |
855 TEST(InstructionSelectorInt32MulP) { | |
856 InstructionSelectorTester m; | |
857 m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1))); | |
858 m.SelectInstructions(); | |
859 CHECK_EQ(1, m.code.size()); | |
860 CHECK_EQ(kArmMul, m.code[0]->arch_opcode()); | |
861 } | |
862 | |
863 | |
864 TEST(InstructionSelectorInt32MulImm) { | |
865 // x * (2^k + 1) -> (x >> k) + x | |
866 for (int k = 1; k < 31; ++k) { | |
867 InstructionSelectorTester m; | |
868 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1))); | |
869 m.SelectInstructions(); | |
870 CHECK_EQ(1, m.code.size()); | |
871 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
872 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode()); | |
873 } | |
874 // (2^k + 1) * x -> (x >> k) + x | |
875 for (int k = 1; k < 31; ++k) { | |
876 InstructionSelectorTester m; | |
877 m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0))); | |
878 m.SelectInstructions(); | |
879 CHECK_EQ(1, m.code.size()); | |
880 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
881 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode()); | |
882 } | |
883 // x * (2^k - 1) -> (x >> k) - x | |
884 for (int k = 3; k < 31; ++k) { | |
885 InstructionSelectorTester m; | |
886 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1))); | |
887 m.SelectInstructions(); | |
888 CHECK_EQ(1, m.code.size()); | |
889 CHECK_EQ(kArmRsb, m.code[0]->arch_opcode()); | |
890 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode()); | |
891 } | |
892 // (2^k - 1) * x -> (x >> k) - x | |
893 for (int k = 3; k < 31; ++k) { | |
894 InstructionSelectorTester m; | |
895 m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0))); | |
896 m.SelectInstructions(); | |
897 CHECK_EQ(1, m.code.size()); | |
898 CHECK_EQ(kArmRsb, m.code[0]->arch_opcode()); | |
899 CHECK_EQ(kMode_Operand2_R_LSL_I, m.code[0]->addressing_mode()); | |
900 } | |
901 } | |
902 | |
903 | |
904 TEST(InstructionSelectorWord32AndImm_ARMv7) { | |
905 for (uint32_t width = 1; width <= 32; ++width) { | |
906 InstructionSelectorTester m; | |
907 m.Return(m.Word32And(m.Parameter(0), | |
908 m.Int32Constant(0xffffffffu >> (32 - width)))); | |
909 m.SelectInstructions(ARMv7); | |
910 CHECK_EQ(1, m.code.size()); | |
911 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode()); | |
912 CHECK_EQ(3, m.code[0]->InputCount()); | |
913 CHECK_EQ(0, m.ToInt32(m.code[0]->InputAt(1))); | |
914 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2))); | |
915 } | |
916 for (uint32_t lsb = 0; lsb <= 31; ++lsb) { | |
917 for (uint32_t width = 1; width < 32 - lsb; ++width) { | |
918 uint32_t msk = ~((0xffffffffu >> (32 - width)) << lsb); | |
919 InstructionSelectorTester m; | |
920 m.Return(m.Word32And(m.Parameter(0), m.Int32Constant(msk))); | |
921 m.SelectInstructions(ARMv7); | |
922 CHECK_EQ(1, m.code.size()); | |
923 CHECK_EQ(kArmBfc, m.code[0]->arch_opcode()); | |
924 CHECK_EQ(1, m.code[0]->OutputCount()); | |
925 CHECK(UnallocatedOperand::cast(m.code[0]->Output()) | |
926 ->HasSameAsInputPolicy()); | |
927 CHECK_EQ(3, m.code[0]->InputCount()); | |
928 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1))); | |
929 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2))); | |
930 } | |
931 } | |
932 } | |
933 | |
934 | |
935 TEST(InstructionSelectorWord32AndAndWord32ShrImm_ARMv7) { | |
936 for (uint32_t lsb = 0; lsb <= 31; ++lsb) { | |
937 for (uint32_t width = 1; width <= 32 - lsb; ++width) { | |
938 { | |
939 InstructionSelectorTester m; | |
940 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)), | |
941 m.Int32Constant(0xffffffffu >> (32 - width)))); | |
942 m.SelectInstructions(ARMv7); | |
943 CHECK_EQ(1, m.code.size()); | |
944 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode()); | |
945 CHECK_EQ(3, m.code[0]->InputCount()); | |
946 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1))); | |
947 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2))); | |
948 } | |
949 { | |
950 InstructionSelectorTester m; | |
951 m.Return( | |
952 m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)), | |
953 m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)))); | |
954 m.SelectInstructions(ARMv7); | |
955 CHECK_EQ(1, m.code.size()); | |
956 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode()); | |
957 CHECK_EQ(3, m.code[0]->InputCount()); | |
958 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1))); | |
959 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2))); | |
960 } | |
961 } | |
962 } | |
963 } | |
964 | |
965 | |
966 TEST(InstructionSelectorWord32ShrAndWord32AndImm_ARMv7) { | |
967 for (uint32_t lsb = 0; lsb <= 31; ++lsb) { | |
968 for (uint32_t width = 1; width <= 32 - lsb; ++width) { | |
969 uint32_t max = 1 << lsb; | |
970 if (max > static_cast<uint32_t>(kMaxInt)) max -= 1; | |
971 uint32_t jnk = CcTest::random_number_generator()->NextInt(max); | |
972 uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk; | |
973 { | |
974 InstructionSelectorTester m; | |
975 m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)), | |
976 m.Int32Constant(lsb))); | |
977 m.SelectInstructions(ARMv7); | |
978 CHECK_EQ(1, m.code.size()); | |
979 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode()); | |
980 CHECK_EQ(3, m.code[0]->InputCount()); | |
981 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1))); | |
982 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2))); | |
983 } | |
984 { | |
985 InstructionSelectorTester m; | |
986 m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)), | |
987 m.Int32Constant(lsb))); | |
988 m.SelectInstructions(ARMv7); | |
989 CHECK_EQ(1, m.code.size()); | |
990 CHECK_EQ(kArmUbfx, m.code[0]->arch_opcode()); | |
991 CHECK_EQ(3, m.code[0]->InputCount()); | |
992 CHECK_EQ(lsb, m.ToInt32(m.code[0]->InputAt(1))); | |
993 CHECK_EQ(width, m.ToInt32(m.code[0]->InputAt(2))); | |
994 } | |
995 } | |
996 } | |
997 } | |
998 | |
999 | |
1000 TEST(InstructionSelectorInt32SubAndInt32MulP) { | |
1001 InstructionSelectorTester m; | |
1002 m.Return( | |
1003 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); | |
1004 m.SelectInstructions(); | |
1005 CHECK_EQ(2, m.code.size()); | |
1006 CHECK_EQ(kArmMul, m.code[0]->arch_opcode()); | |
1007 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1008 CHECK_EQ(kArmSub, m.code[1]->arch_opcode()); | |
1009 CHECK_EQ(2, m.code[1]->InputCount()); | |
1010 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(1)); | |
1011 } | |
1012 | |
1013 | |
1014 TEST(InstructionSelectorInt32SubAndInt32MulP_MLS) { | |
1015 InstructionSelectorTester m; | |
1016 m.Return( | |
1017 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); | |
1018 m.SelectInstructions(MLS); | |
1019 CHECK_EQ(1, m.code.size()); | |
1020 CHECK_EQ(kArmMls, m.code[0]->arch_opcode()); | |
1021 } | |
1022 | |
1023 | |
1024 TEST(InstructionSelectorInt32DivP) { | |
1025 InstructionSelectorTester m; | |
1026 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1))); | |
1027 m.SelectInstructions(); | |
1028 CHECK_EQ(4, m.code.size()); | |
1029 CHECK_EQ(kArmVcvtF64S32, m.code[0]->arch_opcode()); | |
1030 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1031 CHECK_EQ(kArmVcvtF64S32, m.code[1]->arch_opcode()); | |
1032 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1033 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode()); | |
1034 CHECK_EQ(2, m.code[2]->InputCount()); | |
1035 CHECK_EQ(1, m.code[2]->OutputCount()); | |
1036 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0)); | |
1037 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1)); | |
1038 CHECK_EQ(kArmVcvtS32F64, m.code[3]->arch_opcode()); | |
1039 CHECK_EQ(1, m.code[3]->InputCount()); | |
1040 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0)); | |
1041 } | |
1042 | |
1043 | |
1044 TEST(InstructionSelectorInt32DivP_SUDIV) { | |
1045 InstructionSelectorTester m; | |
1046 m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1))); | |
1047 m.SelectInstructions(SUDIV); | |
1048 CHECK_EQ(1, m.code.size()); | |
1049 CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode()); | |
1050 } | |
1051 | |
1052 | |
1053 TEST(InstructionSelectorInt32UDivP) { | |
1054 InstructionSelectorTester m; | |
1055 m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1))); | |
1056 m.SelectInstructions(); | |
1057 CHECK_EQ(4, m.code.size()); | |
1058 CHECK_EQ(kArmVcvtF64U32, m.code[0]->arch_opcode()); | |
1059 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1060 CHECK_EQ(kArmVcvtF64U32, m.code[1]->arch_opcode()); | |
1061 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1062 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode()); | |
1063 CHECK_EQ(2, m.code[2]->InputCount()); | |
1064 CHECK_EQ(1, m.code[2]->OutputCount()); | |
1065 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0)); | |
1066 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1)); | |
1067 CHECK_EQ(kArmVcvtU32F64, m.code[3]->arch_opcode()); | |
1068 CHECK_EQ(1, m.code[3]->InputCount()); | |
1069 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0)); | |
1070 } | |
1071 | |
1072 | |
1073 TEST(InstructionSelectorInt32UDivP_SUDIV) { | |
1074 InstructionSelectorTester m; | |
1075 m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1))); | |
1076 m.SelectInstructions(SUDIV); | |
1077 CHECK_EQ(1, m.code.size()); | |
1078 CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode()); | |
1079 } | |
1080 | |
1081 | |
1082 TEST(InstructionSelectorInt32ModP) { | |
1083 InstructionSelectorTester m; | |
1084 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1))); | |
1085 m.SelectInstructions(); | |
1086 CHECK_EQ(6, m.code.size()); | |
1087 CHECK_EQ(kArmVcvtF64S32, m.code[0]->arch_opcode()); | |
1088 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1089 CHECK_EQ(kArmVcvtF64S32, m.code[1]->arch_opcode()); | |
1090 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1091 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode()); | |
1092 CHECK_EQ(2, m.code[2]->InputCount()); | |
1093 CHECK_EQ(1, m.code[2]->OutputCount()); | |
1094 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0)); | |
1095 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1)); | |
1096 CHECK_EQ(kArmVcvtS32F64, m.code[3]->arch_opcode()); | |
1097 CHECK_EQ(1, m.code[3]->InputCount()); | |
1098 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0)); | |
1099 CHECK_EQ(kArmMul, m.code[4]->arch_opcode()); | |
1100 CHECK_EQ(1, m.code[4]->OutputCount()); | |
1101 CHECK_EQ(2, m.code[4]->InputCount()); | |
1102 CheckSameVreg(m.code[3]->Output(), m.code[4]->InputAt(0)); | |
1103 CheckSameVreg(m.code[1]->InputAt(0), m.code[4]->InputAt(1)); | |
1104 CHECK_EQ(kArmSub, m.code[5]->arch_opcode()); | |
1105 CHECK_EQ(1, m.code[5]->OutputCount()); | |
1106 CHECK_EQ(2, m.code[5]->InputCount()); | |
1107 CheckSameVreg(m.code[0]->InputAt(0), m.code[5]->InputAt(0)); | |
1108 CheckSameVreg(m.code[4]->Output(), m.code[5]->InputAt(1)); | |
1109 } | |
1110 | |
1111 | |
1112 TEST(InstructionSelectorInt32ModP_SUDIV) { | |
1113 InstructionSelectorTester m; | |
1114 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1))); | |
1115 m.SelectInstructions(SUDIV); | |
1116 CHECK_EQ(3, m.code.size()); | |
1117 CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode()); | |
1118 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1119 CHECK_EQ(2, m.code[0]->InputCount()); | |
1120 CHECK_EQ(kArmMul, m.code[1]->arch_opcode()); | |
1121 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1122 CHECK_EQ(2, m.code[1]->InputCount()); | |
1123 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0)); | |
1124 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1)); | |
1125 CHECK_EQ(kArmSub, m.code[2]->arch_opcode()); | |
1126 CHECK_EQ(1, m.code[2]->OutputCount()); | |
1127 CHECK_EQ(2, m.code[2]->InputCount()); | |
1128 CheckSameVreg(m.code[0]->InputAt(0), m.code[2]->InputAt(0)); | |
1129 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1)); | |
1130 } | |
1131 | |
1132 | |
1133 TEST(InstructionSelectorInt32ModP_MLS_SUDIV) { | |
1134 InstructionSelectorTester m; | |
1135 m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1))); | |
1136 m.SelectInstructions(MLS, SUDIV); | |
1137 CHECK_EQ(2, m.code.size()); | |
1138 CHECK_EQ(kArmSdiv, m.code[0]->arch_opcode()); | |
1139 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1140 CHECK_EQ(2, m.code[0]->InputCount()); | |
1141 CHECK_EQ(kArmMls, m.code[1]->arch_opcode()); | |
1142 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1143 CHECK_EQ(3, m.code[1]->InputCount()); | |
1144 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0)); | |
1145 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1)); | |
1146 CheckSameVreg(m.code[0]->InputAt(0), m.code[1]->InputAt(2)); | |
1147 } | |
1148 | |
1149 | |
1150 TEST(InstructionSelectorInt32UModP) { | |
1151 InstructionSelectorTester m; | |
1152 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1))); | |
1153 m.SelectInstructions(); | |
1154 CHECK_EQ(6, m.code.size()); | |
1155 CHECK_EQ(kArmVcvtF64U32, m.code[0]->arch_opcode()); | |
1156 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1157 CHECK_EQ(kArmVcvtF64U32, m.code[1]->arch_opcode()); | |
1158 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1159 CHECK_EQ(kArmVdivF64, m.code[2]->arch_opcode()); | |
1160 CHECK_EQ(2, m.code[2]->InputCount()); | |
1161 CHECK_EQ(1, m.code[2]->OutputCount()); | |
1162 CheckSameVreg(m.code[0]->Output(), m.code[2]->InputAt(0)); | |
1163 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1)); | |
1164 CHECK_EQ(kArmVcvtU32F64, m.code[3]->arch_opcode()); | |
1165 CHECK_EQ(1, m.code[3]->InputCount()); | |
1166 CheckSameVreg(m.code[2]->Output(), m.code[3]->InputAt(0)); | |
1167 CHECK_EQ(kArmMul, m.code[4]->arch_opcode()); | |
1168 CHECK_EQ(1, m.code[4]->OutputCount()); | |
1169 CHECK_EQ(2, m.code[4]->InputCount()); | |
1170 CheckSameVreg(m.code[3]->Output(), m.code[4]->InputAt(0)); | |
1171 CheckSameVreg(m.code[1]->InputAt(0), m.code[4]->InputAt(1)); | |
1172 CHECK_EQ(kArmSub, m.code[5]->arch_opcode()); | |
1173 CHECK_EQ(1, m.code[5]->OutputCount()); | |
1174 CHECK_EQ(2, m.code[5]->InputCount()); | |
1175 CheckSameVreg(m.code[0]->InputAt(0), m.code[5]->InputAt(0)); | |
1176 CheckSameVreg(m.code[4]->Output(), m.code[5]->InputAt(1)); | |
1177 } | |
1178 | |
1179 | |
1180 TEST(InstructionSelectorInt32UModP_SUDIV) { | |
1181 InstructionSelectorTester m; | |
1182 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1))); | |
1183 m.SelectInstructions(SUDIV); | |
1184 CHECK_EQ(3, m.code.size()); | |
1185 CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode()); | |
1186 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1187 CHECK_EQ(2, m.code[0]->InputCount()); | |
1188 CHECK_EQ(kArmMul, m.code[1]->arch_opcode()); | |
1189 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1190 CHECK_EQ(2, m.code[1]->InputCount()); | |
1191 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0)); | |
1192 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1)); | |
1193 CHECK_EQ(kArmSub, m.code[2]->arch_opcode()); | |
1194 CHECK_EQ(1, m.code[2]->OutputCount()); | |
1195 CHECK_EQ(2, m.code[2]->InputCount()); | |
1196 CheckSameVreg(m.code[0]->InputAt(0), m.code[2]->InputAt(0)); | |
1197 CheckSameVreg(m.code[1]->Output(), m.code[2]->InputAt(1)); | |
1198 } | |
1199 | |
1200 | |
1201 TEST(InstructionSelectorInt32UModP_MLS_SUDIV) { | |
1202 InstructionSelectorTester m; | |
1203 m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1))); | |
1204 m.SelectInstructions(MLS, SUDIV); | |
1205 CHECK_EQ(2, m.code.size()); | |
1206 CHECK_EQ(kArmUdiv, m.code[0]->arch_opcode()); | |
1207 CHECK_EQ(1, m.code[0]->OutputCount()); | |
1208 CHECK_EQ(2, m.code[0]->InputCount()); | |
1209 CHECK_EQ(kArmMls, m.code[1]->arch_opcode()); | |
1210 CHECK_EQ(1, m.code[1]->OutputCount()); | |
1211 CHECK_EQ(3, m.code[1]->InputCount()); | |
1212 CheckSameVreg(m.code[0]->Output(), m.code[1]->InputAt(0)); | |
1213 CheckSameVreg(m.code[0]->InputAt(1), m.code[1]->InputAt(1)); | |
1214 CheckSameVreg(m.code[0]->InputAt(0), m.code[1]->InputAt(2)); | |
1215 } | |
1216 | |
1217 | |
1218 TEST(InstructionSelectorWord32EqualP) { | |
1219 InstructionSelectorTester m; | |
1220 m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1))); | |
1221 m.SelectInstructions(); | |
1222 CHECK_EQ(1, m.code.size()); | |
1223 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1224 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1225 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1226 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1227 } | |
1228 | |
1229 | |
1230 TEST(InstructionSelectorWord32EqualImm) { | |
1231 Immediates immediates; | |
1232 for (Immediates::const_iterator i = immediates.begin(); i != immediates.end(); | |
1233 ++i) { | |
1234 int32_t imm = *i; | |
1235 { | |
1236 InstructionSelectorTester m; | |
1237 m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm))); | |
1238 m.SelectInstructions(); | |
1239 CHECK_EQ(1, m.code.size()); | |
1240 if (imm == 0) { | |
1241 CHECK_EQ(kArmTst, m.code[0]->arch_opcode()); | |
1242 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1243 CHECK_EQ(2, m.code[0]->InputCount()); | |
1244 CheckSameVreg(m.code[0]->InputAt(0), m.code[0]->InputAt(1)); | |
1245 } else { | |
1246 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1247 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1248 } | |
1249 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1250 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1251 } | |
1252 { | |
1253 InstructionSelectorTester m; | |
1254 m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0))); | |
1255 m.SelectInstructions(); | |
1256 CHECK_EQ(1, m.code.size()); | |
1257 if (imm == 0) { | |
1258 CHECK_EQ(kArmTst, m.code[0]->arch_opcode()); | |
1259 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1260 CHECK_EQ(2, m.code[0]->InputCount()); | |
1261 CheckSameVreg(m.code[0]->InputAt(0), m.code[0]->InputAt(1)); | |
1262 } else { | |
1263 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1264 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1265 } | |
1266 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1267 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1268 } | |
1269 } | |
1270 } | |
1271 | |
1272 | |
1273 TEST(InstructionSelectorWord32EqualAndDPIP) { | |
1274 DPIs dpis; | |
1275 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
1276 DPI dpi = *i; | |
1277 { | |
1278 InstructionSelectorTester m; | |
1279 m.Return(m.Word32Equal(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)), | |
1280 m.Int32Constant(0))); | |
1281 m.SelectInstructions(); | |
1282 CHECK_EQ(1, m.code.size()); | |
1283 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1284 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1285 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1286 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1287 } | |
1288 { | |
1289 InstructionSelectorTester m; | |
1290 m.Return( | |
1291 m.Word32Equal(m.Int32Constant(0), | |
1292 m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)))); | |
1293 m.SelectInstructions(); | |
1294 CHECK_EQ(1, m.code.size()); | |
1295 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1296 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1297 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1298 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1299 } | |
1300 } | |
1301 } | |
1302 | |
1303 | |
1304 TEST(InstructionSelectorWord32EqualAndDPIImm) { | |
1305 DPIs dpis; | |
1306 Immediates immediates; | |
1307 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
1308 DPI dpi = *i; | |
1309 for (Immediates::const_iterator j = immediates.begin(); | |
1310 j != immediates.end(); ++j) { | |
1311 int32_t imm = *j; | |
1312 { | |
1313 InstructionSelectorTester m; | |
1314 m.Return(m.Word32Equal( | |
1315 m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)), | |
1316 m.Int32Constant(0))); | |
1317 m.SelectInstructions(); | |
1318 CHECK_EQ(1, m.code.size()); | |
1319 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1320 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1321 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1322 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1323 } | |
1324 { | |
1325 InstructionSelectorTester m; | |
1326 m.Return(m.Word32Equal( | |
1327 m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0)), | |
1328 m.Int32Constant(0))); | |
1329 m.SelectInstructions(); | |
1330 CHECK_EQ(1, m.code.size()); | |
1331 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1332 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1333 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1334 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1335 } | |
1336 { | |
1337 InstructionSelectorTester m; | |
1338 m.Return(m.Word32Equal( | |
1339 m.Int32Constant(0), | |
1340 m.NewNode(dpi.op, m.Parameter(0), m.Int32Constant(imm)))); | |
1341 m.SelectInstructions(); | |
1342 CHECK_EQ(1, m.code.size()); | |
1343 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1344 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1345 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1346 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1347 } | |
1348 { | |
1349 InstructionSelectorTester m; | |
1350 m.Return(m.Word32Equal( | |
1351 m.Int32Constant(0), | |
1352 m.NewNode(dpi.op, m.Int32Constant(imm), m.Parameter(0)))); | |
1353 m.SelectInstructions(); | |
1354 CHECK_EQ(1, m.code.size()); | |
1355 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1356 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1357 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1358 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1359 } | |
1360 } | |
1361 } | |
1362 } | |
1363 | |
1364 | |
1365 TEST(InstructionSelectorWord32EqualAndShiftP) { | |
1366 Shifts shifts; | |
1367 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | |
1368 Shift shift = *i; | |
1369 { | |
1370 InstructionSelectorTester m; | |
1371 m.Return(m.Word32Equal( | |
1372 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)))); | |
1373 m.SelectInstructions(); | |
1374 CHECK_EQ(1, m.code.size()); | |
1375 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1376 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
1377 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1378 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1379 } | |
1380 { | |
1381 InstructionSelectorTester m; | |
1382 m.Return(m.Word32Equal( | |
1383 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2))); | |
1384 m.SelectInstructions(); | |
1385 CHECK_EQ(1, m.code.size()); | |
1386 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1387 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
1388 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
1389 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1390 } | |
1391 } | |
1392 } | |
1393 | |
1394 | |
1395 TEST(InstructionSelectorBranchWithWord32EqualAndShiftP) { | |
1396 Shifts shifts; | |
1397 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | |
1398 Shift shift = *i; | |
1399 { | |
1400 InstructionSelectorTester m; | |
1401 MLabel blocka, blockb; | |
1402 m.Branch(m.Word32Equal(m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), | |
1403 m.Parameter(2))), | |
1404 &blocka, &blockb); | |
1405 m.Bind(&blocka); | |
1406 m.Return(m.Int32Constant(1)); | |
1407 m.Bind(&blockb); | |
1408 m.Return(m.Int32Constant(0)); | |
1409 m.SelectInstructions(); | |
1410 CHECK_EQ(1, m.code.size()); | |
1411 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1412 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
1413 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1414 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1415 } | |
1416 { | |
1417 InstructionSelectorTester m; | |
1418 MLabel blocka, blockb; | |
1419 m.Branch( | |
1420 m.Word32Equal(m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | |
1421 m.Parameter(0)), | |
1422 &blocka, &blockb); | |
1423 m.Bind(&blocka); | |
1424 m.Return(m.Int32Constant(1)); | |
1425 m.Bind(&blockb); | |
1426 m.Return(m.Int32Constant(0)); | |
1427 m.SelectInstructions(); | |
1428 CHECK_EQ(1, m.code.size()); | |
1429 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1430 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
1431 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1432 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1433 } | |
1434 } | |
1435 } | |
1436 | |
1437 | |
1438 TEST(InstructionSelectorBranchWithWord32EqualAndShiftImm) { | |
1439 Shifts shifts; | |
1440 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | |
1441 Shift shift = *i; | |
1442 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { | |
1443 { | |
1444 InstructionSelectorTester m; | |
1445 MLabel blocka, blockb; | |
1446 m.Branch( | |
1447 m.Word32Equal(m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), | |
1448 m.Int32Constant(imm))), | |
1449 &blocka, &blockb); | |
1450 m.Bind(&blocka); | |
1451 m.Return(m.Int32Constant(1)); | |
1452 m.Bind(&blockb); | |
1453 m.Return(m.Int32Constant(0)); | |
1454 m.SelectInstructions(); | |
1455 CHECK_EQ(1, m.code.size()); | |
1456 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1457 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
1458 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1459 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1460 } | |
1461 { | |
1462 InstructionSelectorTester m; | |
1463 MLabel blocka, blockb; | |
1464 m.Branch(m.Word32Equal( | |
1465 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), | |
1466 m.Parameter(0)), | |
1467 &blocka, &blockb); | |
1468 m.Bind(&blocka); | |
1469 m.Return(m.Int32Constant(1)); | |
1470 m.Bind(&blockb); | |
1471 m.Return(m.Int32Constant(0)); | |
1472 m.SelectInstructions(); | |
1473 CHECK_EQ(1, m.code.size()); | |
1474 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1475 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
1476 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1477 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1478 } | |
1479 } | |
1480 } | |
1481 } | |
1482 | |
1483 | |
1484 TEST(InstructionSelectorBranchWithWord32EqualAndRotateRightP) { | |
1485 { | |
1486 InstructionSelectorTester m; | |
1487 MLabel blocka, blockb; | |
1488 Node* input = m.Parameter(0); | |
1489 Node* value = m.Parameter(1); | |
1490 Node* shift = m.Parameter(2); | |
1491 Node* ror = | |
1492 m.Word32Or(m.Word32Shr(value, shift), | |
1493 m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift))); | |
1494 m.Branch(m.Word32Equal(input, ror), &blocka, &blockb); | |
1495 m.Bind(&blocka); | |
1496 m.Return(m.Int32Constant(1)); | |
1497 m.Bind(&blockb); | |
1498 m.Return(m.Int32Constant(0)); | |
1499 m.SelectInstructions(); | |
1500 CHECK_EQ(1, m.code.size()); | |
1501 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1502 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
1503 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1504 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1505 } | |
1506 { | |
1507 InstructionSelectorTester m; | |
1508 MLabel blocka, blockb; | |
1509 Node* input = m.Parameter(0); | |
1510 Node* value = m.Parameter(1); | |
1511 Node* shift = m.Parameter(2); | |
1512 Node* ror = | |
1513 m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)), | |
1514 m.Word32Shr(value, shift)); | |
1515 m.Branch(m.Word32Equal(input, ror), &blocka, &blockb); | |
1516 m.Bind(&blocka); | |
1517 m.Return(m.Int32Constant(1)); | |
1518 m.Bind(&blockb); | |
1519 m.Return(m.Int32Constant(0)); | |
1520 m.SelectInstructions(); | |
1521 CHECK_EQ(1, m.code.size()); | |
1522 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1523 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
1524 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1525 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1526 } | |
1527 { | |
1528 InstructionSelectorTester m; | |
1529 MLabel blocka, blockb; | |
1530 Node* input = m.Parameter(0); | |
1531 Node* value = m.Parameter(1); | |
1532 Node* shift = m.Parameter(2); | |
1533 Node* ror = | |
1534 m.Word32Or(m.Word32Shr(value, shift), | |
1535 m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift))); | |
1536 m.Branch(m.Word32Equal(ror, input), &blocka, &blockb); | |
1537 m.Bind(&blocka); | |
1538 m.Return(m.Int32Constant(1)); | |
1539 m.Bind(&blockb); | |
1540 m.Return(m.Int32Constant(0)); | |
1541 m.SelectInstructions(); | |
1542 CHECK_EQ(1, m.code.size()); | |
1543 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1544 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
1545 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1546 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1547 } | |
1548 { | |
1549 InstructionSelectorTester m; | |
1550 MLabel blocka, blockb; | |
1551 Node* input = m.Parameter(0); | |
1552 Node* value = m.Parameter(1); | |
1553 Node* shift = m.Parameter(2); | |
1554 Node* ror = | |
1555 m.Word32Or(m.Word32Shl(value, m.Int32Sub(m.Int32Constant(32), shift)), | |
1556 m.Word32Shr(value, shift)); | |
1557 m.Branch(m.Word32Equal(ror, input), &blocka, &blockb); | |
1558 m.Bind(&blocka); | |
1559 m.Return(m.Int32Constant(1)); | |
1560 m.Bind(&blockb); | |
1561 m.Return(m.Int32Constant(0)); | |
1562 m.SelectInstructions(); | |
1563 CHECK_EQ(1, m.code.size()); | |
1564 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1565 CHECK_EQ(kMode_Operand2_R_ROR_R, m.code[0]->addressing_mode()); | |
1566 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1567 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1568 } | |
1569 } | |
1570 | |
1571 | |
1572 TEST(InstructionSelectorBranchWithWord32EqualAndRotateRightImm) { | |
1573 FOR_INPUTS(uint32_t, ror, i) { | |
1574 uint32_t shift = *i; | |
1575 { | |
1576 InstructionSelectorTester m; | |
1577 MLabel blocka, blockb; | |
1578 Node* input = m.Parameter(0); | |
1579 Node* value = m.Parameter(1); | |
1580 Node* ror = m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)), | |
1581 m.Word32Shl(value, m.Int32Constant(32 - shift))); | |
1582 m.Branch(m.Word32Equal(input, ror), &blocka, &blockb); | |
1583 m.Bind(&blocka); | |
1584 m.Return(m.Int32Constant(1)); | |
1585 m.Bind(&blockb); | |
1586 m.Return(m.Int32Constant(0)); | |
1587 m.SelectInstructions(); | |
1588 CHECK_EQ(1, m.code.size()); | |
1589 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1590 CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode()); | |
1591 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1592 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1593 CHECK_LE(3, m.code[0]->InputCount()); | |
1594 CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2))); | |
1595 } | |
1596 { | |
1597 InstructionSelectorTester m; | |
1598 MLabel blocka, blockb; | |
1599 Node* input = m.Parameter(0); | |
1600 Node* value = m.Parameter(1); | |
1601 Node* ror = m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)), | |
1602 m.Word32Shr(value, m.Int32Constant(shift))); | |
1603 m.Branch(m.Word32Equal(input, ror), &blocka, &blockb); | |
1604 m.Bind(&blocka); | |
1605 m.Return(m.Int32Constant(1)); | |
1606 m.Bind(&blockb); | |
1607 m.Return(m.Int32Constant(0)); | |
1608 m.SelectInstructions(); | |
1609 CHECK_EQ(1, m.code.size()); | |
1610 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1611 CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode()); | |
1612 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1613 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1614 CHECK_LE(3, m.code[0]->InputCount()); | |
1615 CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2))); | |
1616 } | |
1617 { | |
1618 InstructionSelectorTester m; | |
1619 MLabel blocka, blockb; | |
1620 Node* input = m.Parameter(0); | |
1621 Node* value = m.Parameter(1); | |
1622 Node* ror = m.Word32Or(m.Word32Shr(value, m.Int32Constant(shift)), | |
1623 m.Word32Shl(value, m.Int32Constant(32 - shift))); | |
1624 m.Branch(m.Word32Equal(ror, input), &blocka, &blockb); | |
1625 m.Bind(&blocka); | |
1626 m.Return(m.Int32Constant(1)); | |
1627 m.Bind(&blockb); | |
1628 m.Return(m.Int32Constant(0)); | |
1629 m.SelectInstructions(); | |
1630 CHECK_EQ(1, m.code.size()); | |
1631 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1632 CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode()); | |
1633 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1634 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1635 CHECK_LE(3, m.code[0]->InputCount()); | |
1636 CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2))); | |
1637 } | |
1638 { | |
1639 InstructionSelectorTester m; | |
1640 MLabel blocka, blockb; | |
1641 Node* input = m.Parameter(0); | |
1642 Node* value = m.Parameter(1); | |
1643 Node* ror = m.Word32Or(m.Word32Shl(value, m.Int32Constant(32 - shift)), | |
1644 m.Word32Shr(value, m.Int32Constant(shift))); | |
1645 m.Branch(m.Word32Equal(ror, input), &blocka, &blockb); | |
1646 m.Bind(&blocka); | |
1647 m.Return(m.Int32Constant(1)); | |
1648 m.Bind(&blockb); | |
1649 m.Return(m.Int32Constant(0)); | |
1650 m.SelectInstructions(); | |
1651 CHECK_EQ(1, m.code.size()); | |
1652 CHECK_EQ(kArmCmp, m.code[0]->arch_opcode()); | |
1653 CHECK_EQ(kMode_Operand2_R_ROR_I, m.code[0]->addressing_mode()); | |
1654 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1655 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1656 CHECK_LE(3, m.code[0]->InputCount()); | |
1657 CHECK_EQ(shift, m.ToInt32(m.code[0]->InputAt(2))); | |
1658 } | |
1659 } | |
1660 } | |
1661 | |
1662 | |
1663 TEST(InstructionSelectorBranchWithDPIP) { | |
1664 DPIs dpis; | |
1665 for (DPIs::const_iterator i = dpis.begin(); i != dpis.end(); ++i) { | |
1666 DPI dpi = *i; | |
1667 { | |
1668 InstructionSelectorTester m; | |
1669 MLabel blocka, blockb; | |
1670 m.Branch(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)), &blocka, | |
1671 &blockb); | |
1672 m.Bind(&blocka); | |
1673 m.Return(m.Int32Constant(1)); | |
1674 m.Bind(&blockb); | |
1675 m.Return(m.Int32Constant(0)); | |
1676 m.SelectInstructions(); | |
1677 CHECK_EQ(1, m.code.size()); | |
1678 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1679 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1680 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1681 CHECK_EQ(kNotEqual, m.code[0]->flags_condition()); | |
1682 } | |
1683 { | |
1684 InstructionSelectorTester m; | |
1685 MLabel blocka, blockb; | |
1686 m.Branch(m.Word32Equal(m.Int32Constant(0), | |
1687 m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1))), | |
1688 &blocka, &blockb); | |
1689 m.Bind(&blocka); | |
1690 m.Return(m.Int32Constant(1)); | |
1691 m.Bind(&blockb); | |
1692 m.Return(m.Int32Constant(0)); | |
1693 m.SelectInstructions(); | |
1694 CHECK_EQ(1, m.code.size()); | |
1695 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1696 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1697 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1698 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1699 } | |
1700 { | |
1701 InstructionSelectorTester m; | |
1702 MLabel blocka, blockb; | |
1703 m.Branch(m.Word32Equal(m.NewNode(dpi.op, m.Parameter(0), m.Parameter(1)), | |
1704 m.Int32Constant(0)), | |
1705 &blocka, &blockb); | |
1706 m.Bind(&blocka); | |
1707 m.Return(m.Int32Constant(1)); | |
1708 m.Bind(&blockb); | |
1709 m.Return(m.Int32Constant(0)); | |
1710 m.SelectInstructions(); | |
1711 CHECK_EQ(1, m.code.size()); | |
1712 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | |
1713 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1714 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1715 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | |
1716 } | |
1717 } | |
1718 } | |
1719 | |
1720 | |
1721 TEST(InstructionSelectorBranchWithODPIP) { | |
1722 ODPIs odpis; | |
1723 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { | |
1724 ODPI odpi = *i; | |
1725 { | |
1726 InstructionSelectorTester m; | |
1727 MLabel blocka, blockb; | |
1728 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)); | |
1729 m.Branch(m.Projection(1, node), &blocka, &blockb); | |
1730 m.Bind(&blocka); | |
1731 m.Return(m.Int32Constant(0)); | |
1732 m.Bind(&blockb); | |
1733 m.Return(m.Projection(0, node)); | |
1734 m.SelectInstructions(); | |
1735 CHECK_EQ(1, m.code.size()); | |
1736 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
1737 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1738 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1739 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
1740 } | |
1741 { | |
1742 InstructionSelectorTester m; | |
1743 MLabel blocka, blockb; | |
1744 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)); | |
1745 m.Branch(m.Word32Equal(m.Projection(1, node), m.Int32Constant(0)), | |
1746 &blocka, &blockb); | |
1747 m.Bind(&blocka); | |
1748 m.Return(m.Int32Constant(0)); | |
1749 m.Bind(&blockb); | |
1750 m.Return(m.Projection(0, node)); | |
1751 m.SelectInstructions(); | |
1752 CHECK_EQ(1, m.code.size()); | |
1753 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
1754 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1755 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1756 CHECK_EQ(kNotOverflow, m.code[0]->flags_condition()); | |
1757 } | |
1758 { | |
1759 InstructionSelectorTester m; | |
1760 MLabel blocka, blockb; | |
1761 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)); | |
1762 m.Branch(m.Word32Equal(m.Int32Constant(0), m.Projection(1, node)), | |
1763 &blocka, &blockb); | |
1764 m.Bind(&blocka); | |
1765 m.Return(m.Int32Constant(0)); | |
1766 m.Bind(&blockb); | |
1767 m.Return(m.Projection(0, node)); | |
1768 m.SelectInstructions(); | |
1769 CHECK_EQ(1, m.code.size()); | |
1770 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
1771 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
1772 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1773 CHECK_EQ(kNotOverflow, m.code[0]->flags_condition()); | |
1774 } | |
1775 } | |
1776 } | |
1777 | |
1778 | |
1779 TEST(InstructionSelectorBranchWithODPIImm) { | |
1780 ODPIs odpis; | |
1781 Immediates immediates; | |
1782 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { | |
1783 ODPI odpi = *i; | |
1784 for (Immediates::const_iterator j = immediates.begin(); | |
1785 j != immediates.end(); ++j) { | |
1786 int32_t imm = *j; | |
1787 { | |
1788 InstructionSelectorTester m; | |
1789 MLabel blocka, blockb; | |
1790 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)); | |
1791 m.Branch(m.Projection(1, node), &blocka, &blockb); | |
1792 m.Bind(&blocka); | |
1793 m.Return(m.Int32Constant(0)); | |
1794 m.Bind(&blockb); | |
1795 m.Return(m.Projection(0, node)); | |
1796 m.SelectInstructions(); | |
1797 CHECK_EQ(1, m.code.size()); | |
1798 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
1799 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1800 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1801 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
1802 CHECK_LE(2, m.code[0]->InputCount()); | |
1803 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
1804 } | |
1805 { | |
1806 InstructionSelectorTester m; | |
1807 MLabel blocka, blockb; | |
1808 Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)); | |
1809 m.Branch(m.Projection(1, node), &blocka, &blockb); | |
1810 m.Bind(&blocka); | |
1811 m.Return(m.Int32Constant(0)); | |
1812 m.Bind(&blockb); | |
1813 m.Return(m.Projection(0, node)); | |
1814 m.SelectInstructions(); | |
1815 CHECK_EQ(1, m.code.size()); | |
1816 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
1817 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1818 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1819 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
1820 CHECK_LE(2, m.code[0]->InputCount()); | |
1821 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
1822 } | |
1823 { | |
1824 InstructionSelectorTester m; | |
1825 MLabel blocka, blockb; | |
1826 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)); | |
1827 m.Branch(m.Word32Equal(m.Projection(1, node), m.Int32Constant(0)), | |
1828 &blocka, &blockb); | |
1829 m.Bind(&blocka); | |
1830 m.Return(m.Int32Constant(0)); | |
1831 m.Bind(&blockb); | |
1832 m.Return(m.Projection(0, node)); | |
1833 m.SelectInstructions(); | |
1834 CHECK_EQ(1, m.code.size()); | |
1835 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); | |
1836 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1837 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1838 CHECK_EQ(kNotOverflow, m.code[0]->flags_condition()); | |
1839 CHECK_LE(2, m.code[0]->InputCount()); | |
1840 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
1841 } | |
1842 { | |
1843 InstructionSelectorTester m; | |
1844 MLabel blocka, blockb; | |
1845 Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)); | |
1846 m.Branch(m.Word32Equal(m.Projection(1, node), m.Int32Constant(0)), | |
1847 &blocka, &blockb); | |
1848 m.Bind(&blocka); | |
1849 m.Return(m.Int32Constant(0)); | |
1850 m.Bind(&blockb); | |
1851 m.Return(m.Projection(0, node)); | |
1852 m.SelectInstructions(); | |
1853 CHECK_EQ(1, m.code.size()); | |
1854 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | |
1855 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
1856 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | |
1857 CHECK_EQ(kNotOverflow, m.code[0]->flags_condition()); | |
1858 CHECK_LE(2, m.code[0]->InputCount()); | |
1859 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
1860 } | |
1861 } | |
1862 } | |
1863 } | |
OLD | NEW |