| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <list> | 5 #include <list> |
| 6 | 6 |
| 7 #include "test/cctest/compiler/instruction-selector-tester.h" | 7 #include "test/cctest/compiler/instruction-selector-tester.h" |
| 8 #include "test/cctest/compiler/value-helper.h" | 8 #include "test/cctest/compiler/value-helper.h" |
| 9 | 9 |
| 10 using namespace v8::internal; | 10 using namespace v8::internal; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq}; | 34 DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq}; |
| 35 push_back(xor_); | 35 push_back(xor_); |
| 36 DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn}; | 36 DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn}; |
| 37 push_back(add); | 37 push_back(add); |
| 38 DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp}; | 38 DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp}; |
| 39 push_back(sub); | 39 push_back(sub); |
| 40 } | 40 } |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 | 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 |
| 44 // ARM immediates. | 64 // ARM immediates. |
| 45 class Immediates V8_FINAL : public std::list<int32_t> { | 65 class Immediates V8_FINAL : public std::list<int32_t> { |
| 46 public: | 66 public: |
| 47 Immediates() { | 67 Immediates() { |
| 48 for (uint32_t imm8 = 0; imm8 < 256; ++imm8) { | 68 for (uint32_t imm8 = 0; imm8 < 256; ++imm8) { |
| 49 for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) { | 69 for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) { |
| 50 int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4)); | 70 int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4)); |
| 51 CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm)); | 71 CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm)); |
| 52 push_back(imm); | 72 push_back(imm); |
| 53 } | 73 } |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 CHECK_EQ(1, m.code.size()); | 238 CHECK_EQ(1, m.code.size()); |
| 219 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | 239 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 220 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 240 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 221 } | 241 } |
| 222 } | 242 } |
| 223 } | 243 } |
| 224 } | 244 } |
| 225 } | 245 } |
| 226 | 246 |
| 227 | 247 |
| 228 TEST(InstructionSelectorInt32AddWithOverflowP) { | 248 TEST(InstructionSelectorODPIP) { |
| 229 { | 249 ODPIs odpis; |
| 230 InstructionSelectorTester m; | 250 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
| 231 Node* ovf; | 251 ODPI odpi = *i; |
| 232 m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), NULL, &ovf); | |
| 233 m.Return(ovf); | |
| 234 m.SelectInstructions(); | |
| 235 CHECK_EQ(1, m.code.size()); | |
| 236 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 237 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
| 238 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
| 239 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
| 240 CHECK_EQ(2, m.code[0]->InputCount()); | |
| 241 CHECK_EQ(1, m.code[0]->OutputCount()); | |
| 242 } | |
| 243 { | |
| 244 InstructionSelectorTester m; | |
| 245 Node* val; | |
| 246 m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), &val, NULL); | |
| 247 m.Return(val); | |
| 248 m.SelectInstructions(); | |
| 249 CHECK_EQ(1, m.code.size()); | |
| 250 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 251 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
| 252 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
| 253 CHECK_EQ(2, m.code[0]->InputCount()); | |
| 254 CHECK_EQ(1, m.code[0]->OutputCount()); | |
| 255 } | |
| 256 { | |
| 257 InstructionSelectorTester m; | |
| 258 Node* val, *ovf; | |
| 259 m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), &val, &ovf); | |
| 260 m.Return(m.Word32Equal(val, ovf)); | |
| 261 m.SelectInstructions(); | |
| 262 CHECK_LE(1, m.code.size()); | |
| 263 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 264 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
| 265 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
| 266 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
| 267 CHECK_EQ(2, m.code[0]->InputCount()); | |
| 268 CHECK_EQ(2, m.code[0]->OutputCount()); | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 | |
| 273 TEST(InstructionSelectorInt32AddWithOverflowImm) { | |
| 274 Immediates immediates; | |
| 275 for (Immediates::const_iterator i = immediates.begin(); i != immediates.end(); | |
| 276 ++i) { | |
| 277 int32_t imm = *i; | |
| 278 { | 252 { |
| 279 InstructionSelectorTester m; | 253 InstructionSelectorTester m; |
| 280 Node* ovf; | 254 m.Return( |
| 281 m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), NULL, &ovf); | 255 m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)))); |
| 282 m.Return(ovf); | |
| 283 m.SelectInstructions(); | 256 m.SelectInstructions(); |
| 284 CHECK_EQ(1, m.code.size()); | 257 CHECK_EQ(1, m.code.size()); |
| 285 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 258 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 286 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | 259 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
| 287 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 260 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 288 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 261 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 289 CHECK_EQ(2, m.code[0]->InputCount()); | 262 CHECK_EQ(2, m.code[0]->InputCount()); |
| 290 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
| 291 CHECK_EQ(1, m.code[0]->OutputCount()); | 263 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 292 } | 264 } |
| 293 { | 265 { |
| 294 InstructionSelectorTester m; | 266 InstructionSelectorTester m; |
| 295 Node* ovf; | 267 m.Return( |
| 296 m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), NULL, &ovf); | 268 m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)))); |
| 297 m.Return(ovf); | |
| 298 m.SelectInstructions(); | 269 m.SelectInstructions(); |
| 299 CHECK_EQ(1, m.code.size()); | 270 CHECK_EQ(1, m.code.size()); |
| 300 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 271 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 301 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | 272 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
| 273 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 274 CHECK_EQ(2, m.code[0]->InputCount()); |
| 275 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 276 } |
| 277 { |
| 278 InstructionSelectorTester m; |
| 279 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)); |
| 280 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 281 m.SelectInstructions(); |
| 282 CHECK_LE(1, m.code.size()); |
| 283 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 284 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
| 302 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 285 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 303 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 286 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 304 CHECK_EQ(2, m.code[0]->InputCount()); | 287 CHECK_EQ(2, m.code[0]->InputCount()); |
| 305 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
| 306 CHECK_EQ(1, m.code[0]->OutputCount()); | |
| 307 } | |
| 308 { | |
| 309 InstructionSelectorTester m; | |
| 310 Node* val; | |
| 311 m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), &val, NULL); | |
| 312 m.Return(val); | |
| 313 m.SelectInstructions(); | |
| 314 CHECK_EQ(1, m.code.size()); | |
| 315 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 316 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
| 317 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
| 318 CHECK_EQ(2, m.code[0]->InputCount()); | |
| 319 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
| 320 CHECK_EQ(1, m.code[0]->OutputCount()); | |
| 321 } | |
| 322 { | |
| 323 InstructionSelectorTester m; | |
| 324 Node* val; | |
| 325 m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), &val, NULL); | |
| 326 m.Return(val); | |
| 327 m.SelectInstructions(); | |
| 328 CHECK_EQ(1, m.code.size()); | |
| 329 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 330 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
| 331 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
| 332 CHECK_EQ(2, m.code[0]->InputCount()); | |
| 333 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
| 334 CHECK_EQ(1, m.code[0]->OutputCount()); | |
| 335 } | |
| 336 { | |
| 337 InstructionSelectorTester m; | |
| 338 Node* val, *ovf; | |
| 339 m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), &val, &ovf); | |
| 340 m.Return(m.Word32Equal(val, ovf)); | |
| 341 m.SelectInstructions(); | |
| 342 CHECK_LE(1, m.code.size()); | |
| 343 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 344 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
| 345 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
| 346 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
| 347 CHECK_EQ(2, m.code[0]->InputCount()); | |
| 348 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
| 349 CHECK_EQ(2, m.code[0]->OutputCount()); | |
| 350 } | |
| 351 { | |
| 352 InstructionSelectorTester m; | |
| 353 Node* val, *ovf; | |
| 354 m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), &val, &ovf); | |
| 355 m.Return(m.Word32Equal(val, ovf)); | |
| 356 m.SelectInstructions(); | |
| 357 CHECK_LE(1, m.code.size()); | |
| 358 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 359 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
| 360 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
| 361 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
| 362 CHECK_EQ(2, m.code[0]->InputCount()); | |
| 363 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
| 364 CHECK_EQ(2, m.code[0]->OutputCount()); | 288 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 365 } | 289 } |
| 366 } | 290 } |
| 367 } | 291 } |
| 368 | 292 |
| 369 | 293 |
| 370 TEST(InstructionSelectorInt32AddWithOverflowAndShiftP) { | 294 TEST(InstructionSelectorODPIImm) { |
| 371 Shifts shifts; | 295 ODPIs odpis; |
| 372 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | 296 Immediates immediates; |
| 373 Shift shift = *i; | 297 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
| 374 { | 298 ODPI odpi = *i; |
| 375 InstructionSelectorTester m; | 299 for (Immediates::const_iterator j = immediates.begin(); |
| 376 Node* ovf; | 300 j != immediates.end(); ++j) { |
| 377 m.Int32AddWithOverflow( | 301 int32_t imm = *j; |
| 378 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | 302 { |
| 379 NULL, &ovf); | 303 InstructionSelectorTester m; |
| 380 m.Return(ovf); | 304 m.Return(m.Projection( |
| 381 m.SelectInstructions(); | 305 1, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)))); |
| 382 CHECK_EQ(1, m.code.size()); | 306 m.SelectInstructions(); |
| 383 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 307 CHECK_EQ(1, m.code.size()); |
| 384 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 308 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 385 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 309 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
| 386 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 310 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 387 CHECK_EQ(3, m.code[0]->InputCount()); | 311 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 388 CHECK_EQ(1, m.code[0]->OutputCount()); | 312 CHECK_EQ(2, m.code[0]->InputCount()); |
| 389 } | 313 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
| 390 { | 314 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 391 InstructionSelectorTester m; | 315 } |
| 392 Node* ovf; | 316 { |
| 393 m.Int32AddWithOverflow( | 317 InstructionSelectorTester m; |
| 394 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), | 318 m.Return(m.Projection( |
| 395 NULL, &ovf); | 319 1, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)))); |
| 396 m.Return(ovf); | 320 m.SelectInstructions(); |
| 397 m.SelectInstructions(); | 321 CHECK_EQ(1, m.code.size()); |
| 398 CHECK_EQ(1, m.code.size()); | 322 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 399 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 323 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
| 400 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 324 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 401 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 325 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 402 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 326 CHECK_EQ(2, m.code[0]->InputCount()); |
| 403 CHECK_EQ(3, m.code[0]->InputCount()); | 327 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
| 404 CHECK_EQ(1, m.code[0]->OutputCount()); | 328 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 405 } | 329 } |
| 406 { | 330 { |
| 407 InstructionSelectorTester m; | 331 InstructionSelectorTester m; |
| 408 Node* val; | 332 m.Return(m.Projection( |
| 409 m.Int32AddWithOverflow( | 333 0, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)))); |
| 410 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | 334 m.SelectInstructions(); |
| 411 &val, NULL); | 335 CHECK_EQ(1, m.code.size()); |
| 412 m.Return(val); | 336 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 413 m.SelectInstructions(); | 337 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
| 414 CHECK_EQ(1, m.code.size()); | 338 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 415 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 339 CHECK_EQ(2, m.code[0]->InputCount()); |
| 416 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 340 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
| 417 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 341 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 418 CHECK_EQ(3, m.code[0]->InputCount()); | 342 } |
| 419 CHECK_EQ(1, m.code[0]->OutputCount()); | 343 { |
| 420 } | 344 InstructionSelectorTester m; |
| 421 { | 345 m.Return(m.Projection( |
| 422 InstructionSelectorTester m; | 346 0, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)))); |
| 423 Node* val; | 347 m.SelectInstructions(); |
| 424 m.Int32AddWithOverflow( | 348 CHECK_EQ(1, m.code.size()); |
| 425 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), | 349 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 426 &val, NULL); | 350 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
| 427 m.Return(val); | 351 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 428 m.SelectInstructions(); | 352 CHECK_EQ(2, m.code[0]->InputCount()); |
| 429 CHECK_EQ(1, m.code.size()); | 353 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
| 430 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 354 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 431 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 355 } |
| 432 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 356 { |
| 433 CHECK_EQ(3, m.code[0]->InputCount()); | 357 InstructionSelectorTester m; |
| 434 CHECK_EQ(1, m.code[0]->OutputCount()); | 358 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)); |
| 435 } | 359 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 436 { | 360 m.SelectInstructions(); |
| 437 InstructionSelectorTester m; | 361 CHECK_LE(1, m.code.size()); |
| 438 Node* val, *ovf; | 362 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 439 m.Int32AddWithOverflow( | 363 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
| 440 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | 364 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 441 &val, &ovf); | 365 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 442 m.Return(m.Word32Equal(val, ovf)); | 366 CHECK_EQ(2, m.code[0]->InputCount()); |
| 443 m.SelectInstructions(); | 367 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
| 444 CHECK_LE(1, m.code.size()); | 368 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 445 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 369 } |
| 446 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 370 { |
| 447 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 371 InstructionSelectorTester m; |
| 448 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 372 Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)); |
| 449 CHECK_EQ(3, m.code[0]->InputCount()); | 373 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 450 CHECK_EQ(2, m.code[0]->OutputCount()); | 374 m.SelectInstructions(); |
| 451 } | 375 CHECK_LE(1, m.code.size()); |
| 452 { | 376 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 453 InstructionSelectorTester m; | 377 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
| 454 Node* val, *ovf; | 378 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 455 m.Int32AddWithOverflow( | 379 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 456 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), | 380 CHECK_EQ(2, m.code[0]->InputCount()); |
| 457 &val, &ovf); | 381 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
| 458 m.Return(m.Word32Equal(val, ovf)); | 382 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 459 m.SelectInstructions(); | 383 } |
| 460 CHECK_LE(1, m.code.size()); | |
| 461 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 462 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
| 463 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
| 464 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
| 465 CHECK_EQ(3, m.code[0]->InputCount()); | |
| 466 CHECK_EQ(2, m.code[0]->OutputCount()); | |
| 467 } | 384 } |
| 468 } | 385 } |
| 469 } | 386 } |
| 470 | 387 |
| 471 | 388 |
| 472 TEST(InstructionSelectorInt32AddWithOverflowAndShiftImm) { | 389 TEST(InstructionSelectorODPIAndShiftP) { |
| 390 ODPIs odpis; |
| 473 Shifts shifts; | 391 Shifts shifts; |
| 474 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | 392 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
| 475 Shift shift = *i; | 393 ODPI odpi = *i; |
| 476 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { | 394 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { |
| 477 { | 395 Shift shift = *j; |
| 478 InstructionSelectorTester m; | 396 { |
| 479 Node* ovf; | 397 InstructionSelectorTester m; |
| 480 m.Int32AddWithOverflow( | 398 m.Return(m.Projection( |
| 481 m.Parameter(0), | 399 1, m.NewNode(odpi.op, m.Parameter(0), |
| 482 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), NULL, | 400 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))))); |
| 483 &ovf); | 401 m.SelectInstructions(); |
| 484 m.Return(ovf); | 402 CHECK_EQ(1, m.code.size()); |
| 485 m.SelectInstructions(); | 403 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 486 CHECK_EQ(1, m.code.size()); | 404 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
| 487 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 405 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 488 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 406 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 489 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 407 CHECK_EQ(3, m.code[0]->InputCount()); |
| 490 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 408 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 491 CHECK_EQ(3, m.code[0]->InputCount()); | 409 } |
| 492 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 410 { |
| 493 CHECK_EQ(1, m.code[0]->OutputCount()); | 411 InstructionSelectorTester m; |
| 494 } | 412 m.Return(m.Projection( |
| 495 { | 413 1, m.NewNode(odpi.op, |
| 496 InstructionSelectorTester m; | 414 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), |
| 497 Node* ovf; | 415 m.Parameter(2)))); |
| 498 m.Int32AddWithOverflow( | 416 m.SelectInstructions(); |
| 499 m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), | 417 CHECK_EQ(1, m.code.size()); |
| 500 m.Parameter(1), NULL, &ovf); | 418 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 501 m.Return(ovf); | 419 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
| 502 m.SelectInstructions(); | 420 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 503 CHECK_EQ(1, m.code.size()); | 421 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 504 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 422 CHECK_EQ(3, m.code[0]->InputCount()); |
| 505 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 423 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 506 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 424 } |
| 507 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 425 { |
| 508 CHECK_EQ(3, m.code[0]->InputCount()); | 426 InstructionSelectorTester m; |
| 509 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 427 m.Return(m.Projection( |
| 510 CHECK_EQ(1, m.code[0]->OutputCount()); | 428 0, m.NewNode(odpi.op, m.Parameter(0), |
| 511 } | 429 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))))); |
| 512 { | 430 m.SelectInstructions(); |
| 513 InstructionSelectorTester m; | 431 CHECK_EQ(1, m.code.size()); |
| 514 Node* val; | 432 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 515 m.Int32AddWithOverflow( | 433 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
| 516 m.Parameter(0), | 434 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 517 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), &val, | 435 CHECK_EQ(3, m.code[0]->InputCount()); |
| 518 NULL); | 436 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 519 m.Return(val); | 437 } |
| 520 m.SelectInstructions(); | 438 { |
| 521 CHECK_EQ(1, m.code.size()); | 439 InstructionSelectorTester m; |
| 522 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 440 m.Return(m.Projection( |
| 523 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 441 0, m.NewNode(odpi.op, |
| 524 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 442 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), |
| 525 CHECK_EQ(3, m.code[0]->InputCount()); | 443 m.Parameter(2)))); |
| 526 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 444 m.SelectInstructions(); |
| 527 CHECK_EQ(1, m.code[0]->OutputCount()); | 445 CHECK_EQ(1, m.code.size()); |
| 528 } | 446 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 529 { | 447 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
| 530 InstructionSelectorTester m; | 448 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 531 Node* val; | 449 CHECK_EQ(3, m.code[0]->InputCount()); |
| 532 m.Int32AddWithOverflow( | 450 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 533 m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), | 451 } |
| 534 m.Parameter(1), &val, NULL); | 452 { |
| 535 m.Return(val); | 453 InstructionSelectorTester m; |
| 536 m.SelectInstructions(); | 454 Node* node = |
| 537 CHECK_EQ(1, m.code.size()); | 455 m.NewNode(odpi.op, m.Parameter(0), |
| 538 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 456 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))); |
| 539 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 457 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 540 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 458 m.SelectInstructions(); |
| 541 CHECK_EQ(3, m.code[0]->InputCount()); | 459 CHECK_LE(1, m.code.size()); |
| 542 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 460 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 543 CHECK_EQ(1, m.code[0]->OutputCount()); | 461 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
| 544 } | 462 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 545 { | 463 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 546 InstructionSelectorTester m; | 464 CHECK_EQ(3, m.code[0]->InputCount()); |
| 547 Node* val, *ovf; | 465 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 548 m.Int32AddWithOverflow( | 466 } |
| 549 m.Parameter(0), | 467 { |
| 550 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), &val, | 468 InstructionSelectorTester m; |
| 551 &ovf); | 469 Node* node = m.NewNode( |
| 552 m.Return(m.Word32Equal(val, ovf)); | 470 odpi.op, m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), |
| 553 m.SelectInstructions(); | 471 m.Parameter(2)); |
| 554 CHECK_LE(1, m.code.size()); | 472 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 555 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 473 m.SelectInstructions(); |
| 556 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 474 CHECK_LE(1, m.code.size()); |
| 557 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 475 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 558 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 476 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
| 559 CHECK_EQ(3, m.code[0]->InputCount()); | 477 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 560 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 478 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 561 CHECK_EQ(2, m.code[0]->OutputCount()); | 479 CHECK_EQ(3, m.code[0]->InputCount()); |
| 562 } | 480 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 563 { | 481 } |
| 564 InstructionSelectorTester m; | 482 } |
| 565 Node* val, *ovf; | |
| 566 m.Int32AddWithOverflow( | |
| 567 m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), | |
| 568 m.Parameter(1), &val, &ovf); | |
| 569 m.Return(m.Word32Equal(val, ovf)); | |
| 570 m.SelectInstructions(); | |
| 571 CHECK_LE(1, m.code.size()); | |
| 572 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
| 573 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
| 574 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
| 575 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
| 576 CHECK_EQ(3, m.code[0]->InputCount()); | |
| 577 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
| 578 CHECK_EQ(2, m.code[0]->OutputCount()); | |
| 579 } | |
| 580 } | |
| 581 } | 483 } |
| 582 } | 484 } |
| 583 | 485 |
| 584 | 486 |
| 487 TEST(InstructionSelectorODPIAndShiftImm) { |
| 488 ODPIs odpis; |
| 489 Shifts shifts; |
| 490 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
| 491 ODPI odpi = *i; |
| 492 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { |
| 493 Shift shift = *j; |
| 494 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { |
| 495 { |
| 496 InstructionSelectorTester m; |
| 497 m.Return(m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), |
| 498 m.NewNode(shift.op, m.Parameter(1), |
| 499 m.Int32Constant(imm))))); |
| 500 m.SelectInstructions(); |
| 501 CHECK_EQ(1, m.code.size()); |
| 502 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 503 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 504 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 505 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 506 CHECK_EQ(3, m.code[0]->InputCount()); |
| 507 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 508 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 509 } |
| 510 { |
| 511 InstructionSelectorTester m; |
| 512 m.Return(m.Projection( |
| 513 1, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), |
| 514 m.Int32Constant(imm)), |
| 515 m.Parameter(1)))); |
| 516 m.SelectInstructions(); |
| 517 CHECK_EQ(1, m.code.size()); |
| 518 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 519 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 520 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 521 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 522 CHECK_EQ(3, m.code[0]->InputCount()); |
| 523 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 524 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 525 } |
| 526 { |
| 527 InstructionSelectorTester m; |
| 528 m.Return(m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), |
| 529 m.NewNode(shift.op, m.Parameter(1), |
| 530 m.Int32Constant(imm))))); |
| 531 m.SelectInstructions(); |
| 532 CHECK_EQ(1, m.code.size()); |
| 533 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 534 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 535 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 536 CHECK_EQ(3, m.code[0]->InputCount()); |
| 537 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 538 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 539 } |
| 540 { |
| 541 InstructionSelectorTester m; |
| 542 m.Return(m.Projection( |
| 543 0, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), |
| 544 m.Int32Constant(imm)), |
| 545 m.Parameter(1)))); |
| 546 m.SelectInstructions(); |
| 547 CHECK_EQ(1, m.code.size()); |
| 548 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 549 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 550 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 551 CHECK_EQ(3, m.code[0]->InputCount()); |
| 552 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 553 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 554 } |
| 555 { |
| 556 InstructionSelectorTester m; |
| 557 Node* node = m.NewNode( |
| 558 odpi.op, m.Parameter(0), |
| 559 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm))); |
| 560 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 561 m.SelectInstructions(); |
| 562 CHECK_LE(1, m.code.size()); |
| 563 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 564 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 565 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 566 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 567 CHECK_EQ(3, m.code[0]->InputCount()); |
| 568 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 569 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 570 } |
| 571 { |
| 572 InstructionSelectorTester m; |
| 573 Node* node = m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), |
| 574 m.Int32Constant(imm)), |
| 575 m.Parameter(1)); |
| 576 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 577 m.SelectInstructions(); |
| 578 CHECK_LE(1, m.code.size()); |
| 579 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 580 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 581 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 582 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 583 CHECK_EQ(3, m.code[0]->InputCount()); |
| 584 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 585 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 586 } |
| 587 } |
| 588 } |
| 589 } |
| 590 } |
| 591 |
| 592 |
| 585 TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) { | 593 TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) { |
| 586 { | 594 { |
| 587 InstructionSelectorTester m; | 595 InstructionSelectorTester m; |
| 588 m.Return(m.Word32And(m.Parameter(0), | 596 m.Return(m.Word32And(m.Parameter(0), |
| 589 m.Word32Xor(m.Int32Constant(-1), m.Parameter(1)))); | 597 m.Word32Xor(m.Int32Constant(-1), m.Parameter(1)))); |
| 590 m.SelectInstructions(); | 598 m.SelectInstructions(); |
| 591 CHECK_EQ(1, m.code.size()); | 599 CHECK_EQ(1, m.code.size()); |
| 592 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | 600 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); |
| 593 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | 601 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
| 594 } | 602 } |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1738 m.Return(m.Int32Constant(0)); | 1746 m.Return(m.Int32Constant(0)); |
| 1739 m.SelectInstructions(); | 1747 m.SelectInstructions(); |
| 1740 CHECK_EQ(1, m.code.size()); | 1748 CHECK_EQ(1, m.code.size()); |
| 1741 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | 1749 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); |
| 1742 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | 1750 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
| 1743 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | 1751 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); |
| 1744 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | 1752 CHECK_EQ(kEqual, m.code[0]->flags_condition()); |
| 1745 } | 1753 } |
| 1746 } | 1754 } |
| 1747 } | 1755 } |
| OLD | NEW |