| 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 |