| 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 "src/base/utils/random-number-generator.h" | 5 #include "src/base/utils/random-number-generator.h" |
| 6 #include "src/compiler/pipeline.h" | 6 #include "src/compiler/pipeline.h" |
| 7 #include "test/unittests/compiler/instruction-sequence-unittest.h" | 7 #include "test/unittests/compiler/instruction-sequence-unittest.h" |
| 8 #include "test/unittests/test-utils.h" | 8 #include "test/unittests/test-utils.h" |
| 9 #include "testing/gmock/include/gmock/gmock.h" | 9 #include "testing/gmock/include/gmock/gmock.h" |
| 10 | 10 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 loc += base::OS::SNPrintF(loc, 100, "gp_%d", i); | 34 loc += base::OS::SNPrintF(loc, 100, "gp_%d", i); |
| 35 *loc++ = 0; | 35 *loc++ = 0; |
| 36 } | 36 } |
| 37 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) { | 37 for (int i = 0; i < RegisterConfiguration::kMaxFPRegisters; ++i) { |
| 38 double_register_names_[i] = loc; | 38 double_register_names_[i] = loc; |
| 39 loc += base::OS::SNPrintF(loc, 100, "fp_%d", i) + 1; | 39 loc += base::OS::SNPrintF(loc, 100, "fp_%d", i) + 1; |
| 40 *loc++ = 0; | 40 *loc++ = 0; |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 | 43 |
| 44 | |
| 45 InstructionSequenceTest::InstructionSequenceTest() | 44 InstructionSequenceTest::InstructionSequenceTest() |
| 46 : sequence_(nullptr), | 45 : sequence_(nullptr), |
| 47 num_general_registers_(kDefaultNRegs), | 46 num_general_registers_(kDefaultNRegs), |
| 48 num_double_registers_(kDefaultNRegs), | 47 num_double_registers_(kDefaultNRegs), |
| 49 instruction_blocks_(zone()), | 48 instruction_blocks_(zone()), |
| 50 current_block_(nullptr), | 49 current_block_(nullptr), |
| 51 block_returns_(false) { | 50 block_returns_(false) { |
| 52 InitializeRegisterNames(); | 51 InitializeRegisterNames(); |
| 53 } | 52 } |
| 54 | 53 |
| 55 | 54 |
| 56 void InstructionSequenceTest::SetNumRegs(int num_general_registers, | 55 void InstructionSequenceTest::SetNumRegs(int num_general_registers, |
| 57 int num_double_registers) { | 56 int num_double_registers) { |
| 58 CHECK(!config_); | 57 CHECK(!config_); |
| 59 CHECK(instructions_.empty()); | 58 CHECK(instructions_.empty()); |
| 60 CHECK(instruction_blocks_.empty()); | 59 CHECK(instruction_blocks_.empty()); |
| 61 num_general_registers_ = num_general_registers; | 60 num_general_registers_ = num_general_registers; |
| 62 num_double_registers_ = num_double_registers; | 61 num_double_registers_ = num_double_registers; |
| 63 } | 62 } |
| 64 | 63 |
| 64 int InstructionSequenceTest::GetNumRegs(MachineRepresentation rep) { |
| 65 switch (rep) { |
| 66 case MachineRepresentation::kFloat32: |
| 67 return config()->num_float_registers(); |
| 68 case MachineRepresentation::kFloat64: |
| 69 return config()->num_double_registers(); |
| 70 case MachineRepresentation::kSimd128: |
| 71 return config()->num_simd128_registers(); |
| 72 default: |
| 73 return config()->num_general_registers(); |
| 74 } |
| 75 } |
| 65 | 76 |
| 66 RegisterConfiguration* InstructionSequenceTest::config() { | 77 RegisterConfiguration* InstructionSequenceTest::config() { |
| 67 if (!config_) { | 78 if (!config_) { |
| 68 config_.reset(new RegisterConfiguration( | 79 config_.reset(new RegisterConfiguration( |
| 69 num_general_registers_, num_double_registers_, num_general_registers_, | 80 num_general_registers_, num_double_registers_, num_general_registers_, |
| 70 num_double_registers_, num_double_registers_, allocatable_codes, | 81 num_double_registers_, num_double_registers_, allocatable_codes, |
| 71 allocatable_double_codes, | 82 allocatable_double_codes, |
| 72 kSimpleFPAliasing ? RegisterConfiguration::OVERLAP | 83 kSimpleFPAliasing ? RegisterConfiguration::OVERLAP |
| 73 : RegisterConfiguration::COMBINE, | 84 : RegisterConfiguration::COMBINE, |
| 74 general_register_names_, | 85 general_register_names_, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 153 } |
| 143 | 154 |
| 144 | 155 |
| 145 InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) { | 156 InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) { |
| 146 return TestOperand(kImmediate, imm); | 157 return TestOperand(kImmediate, imm); |
| 147 } | 158 } |
| 148 | 159 |
| 149 | 160 |
| 150 InstructionSequenceTest::VReg InstructionSequenceTest::Define( | 161 InstructionSequenceTest::VReg InstructionSequenceTest::Define( |
| 151 TestOperand output_op) { | 162 TestOperand output_op) { |
| 152 VReg vreg = NewReg(); | 163 VReg vreg = NewReg(output_op); |
| 153 InstructionOperand outputs[1]{ConvertOutputOp(vreg, output_op)}; | 164 InstructionOperand outputs[1]{ConvertOutputOp(vreg, output_op)}; |
| 154 Emit(kArchNop, 1, outputs); | 165 Emit(kArchNop, 1, outputs); |
| 155 return vreg; | 166 return vreg; |
| 156 } | 167 } |
| 157 | 168 |
| 158 | |
| 159 Instruction* InstructionSequenceTest::Return(TestOperand input_op_0) { | 169 Instruction* InstructionSequenceTest::Return(TestOperand input_op_0) { |
| 160 block_returns_ = true; | 170 block_returns_ = true; |
| 161 InstructionOperand inputs[1]{ConvertInputOp(input_op_0)}; | 171 InstructionOperand inputs[1]{ConvertInputOp(input_op_0)}; |
| 162 return Emit(kArchRet, 0, nullptr, 1, inputs); | 172 return Emit(kArchRet, 0, nullptr, 1, inputs); |
| 163 } | 173 } |
| 164 | 174 |
| 165 | 175 |
| 166 PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0, | 176 PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0, |
| 167 VReg incoming_vreg_1, | 177 VReg incoming_vreg_1, |
| 168 VReg incoming_vreg_2, | 178 VReg incoming_vreg_2, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 TestOperand input_op_1, | 243 TestOperand input_op_1, |
| 234 TestOperand input_op_2, | 244 TestOperand input_op_2, |
| 235 TestOperand input_op_3) { | 245 TestOperand input_op_3) { |
| 236 TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3}; | 246 TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3}; |
| 237 return EmitI(CountInputs(arraysize(inputs), inputs), inputs); | 247 return EmitI(CountInputs(arraysize(inputs), inputs), inputs); |
| 238 } | 248 } |
| 239 | 249 |
| 240 | 250 |
| 241 InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( | 251 InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( |
| 242 TestOperand output_op, size_t input_size, TestOperand* inputs) { | 252 TestOperand output_op, size_t input_size, TestOperand* inputs) { |
| 243 VReg output_vreg = NewReg(); | 253 VReg output_vreg = NewReg(output_op); |
| 244 InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)}; | 254 InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)}; |
| 245 InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); | 255 InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); |
| 246 Emit(kArchNop, 1, outputs, input_size, mapped_inputs); | 256 Emit(kArchNop, 1, outputs, input_size, mapped_inputs); |
| 247 return output_vreg; | 257 return output_vreg; |
| 248 } | 258 } |
| 249 | 259 |
| 250 | 260 |
| 251 InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( | 261 InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( |
| 252 TestOperand output_op, TestOperand input_op_0, TestOperand input_op_1, | 262 TestOperand output_op, TestOperand input_op_0, TestOperand input_op_1, |
| 253 TestOperand input_op_2, TestOperand input_op_3) { | 263 TestOperand input_op_2, TestOperand input_op_3) { |
| 254 TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3}; | 264 TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3}; |
| 255 return EmitOI(output_op, CountInputs(arraysize(inputs), inputs), inputs); | 265 return EmitOI(output_op, CountInputs(arraysize(inputs), inputs), inputs); |
| 256 } | 266 } |
| 257 | 267 |
| 258 | 268 |
| 259 InstructionSequenceTest::VRegPair InstructionSequenceTest::EmitOOI( | 269 InstructionSequenceTest::VRegPair InstructionSequenceTest::EmitOOI( |
| 260 TestOperand output_op_0, TestOperand output_op_1, size_t input_size, | 270 TestOperand output_op_0, TestOperand output_op_1, size_t input_size, |
| 261 TestOperand* inputs) { | 271 TestOperand* inputs) { |
| 262 VRegPair output_vregs = std::make_pair(NewReg(), NewReg()); | 272 VRegPair output_vregs = |
| 273 std::make_pair(NewReg(output_op_0), NewReg(output_op_1)); |
| 263 InstructionOperand outputs[2]{ | 274 InstructionOperand outputs[2]{ |
| 264 ConvertOutputOp(output_vregs.first, output_op_0), | 275 ConvertOutputOp(output_vregs.first, output_op_0), |
| 265 ConvertOutputOp(output_vregs.second, output_op_1)}; | 276 ConvertOutputOp(output_vregs.second, output_op_1)}; |
| 266 InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); | 277 InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); |
| 267 Emit(kArchNop, 2, outputs, input_size, mapped_inputs); | 278 Emit(kArchNop, 2, outputs, input_size, mapped_inputs); |
| 268 return output_vregs; | 279 return output_vregs; |
| 269 } | 280 } |
| 270 | 281 |
| 271 | 282 |
| 272 InstructionSequenceTest::VRegPair InstructionSequenceTest::EmitOOI( | 283 InstructionSequenceTest::VRegPair InstructionSequenceTest::EmitOOI( |
| 273 TestOperand output_op_0, TestOperand output_op_1, TestOperand input_op_0, | 284 TestOperand output_op_0, TestOperand output_op_1, TestOperand input_op_0, |
| 274 TestOperand input_op_1, TestOperand input_op_2, TestOperand input_op_3) { | 285 TestOperand input_op_1, TestOperand input_op_2, TestOperand input_op_3) { |
| 275 TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3}; | 286 TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3}; |
| 276 return EmitOOI(output_op_0, output_op_1, | 287 return EmitOOI(output_op_0, output_op_1, |
| 277 CountInputs(arraysize(inputs), inputs), inputs); | 288 CountInputs(arraysize(inputs), inputs), inputs); |
| 278 } | 289 } |
| 279 | 290 |
| 280 | 291 |
| 281 InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall( | 292 InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall( |
| 282 TestOperand output_op, size_t input_size, TestOperand* inputs) { | 293 TestOperand output_op, size_t input_size, TestOperand* inputs) { |
| 283 VReg output_vreg = NewReg(); | 294 VReg output_vreg = NewReg(output_op); |
| 284 InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)}; | 295 InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)}; |
| 285 CHECK(UnallocatedOperand::cast(outputs[0]).HasFixedPolicy()); | 296 CHECK(UnallocatedOperand::cast(outputs[0]).HasFixedPolicy()); |
| 286 InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); | 297 InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); |
| 287 Emit(kArchCallCodeObject, 1, outputs, input_size, mapped_inputs, 0, nullptr, | 298 Emit(kArchCallCodeObject, 1, outputs, input_size, mapped_inputs, 0, nullptr, |
| 288 true); | 299 true); |
| 289 return output_vreg; | 300 return output_vreg; |
| 290 } | 301 } |
| 291 | 302 |
| 292 | 303 |
| 293 InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall( | 304 InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall( |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 case kUnique: | 391 case kUnique: |
| 381 return Unallocated(op, UnallocatedOperand::NONE); | 392 return Unallocated(op, UnallocatedOperand::NONE); |
| 382 case kUniqueRegister: | 393 case kUniqueRegister: |
| 383 return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER); | 394 return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER); |
| 384 case kRegister: | 395 case kRegister: |
| 385 return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER, | 396 return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER, |
| 386 UnallocatedOperand::USED_AT_START); | 397 UnallocatedOperand::USED_AT_START); |
| 387 case kSlot: | 398 case kSlot: |
| 388 return Unallocated(op, UnallocatedOperand::MUST_HAVE_SLOT, | 399 return Unallocated(op, UnallocatedOperand::MUST_HAVE_SLOT, |
| 389 UnallocatedOperand::USED_AT_START); | 400 UnallocatedOperand::USED_AT_START); |
| 390 case kFixedRegister: | 401 case kFixedRegister: { |
| 391 CHECK(0 <= op.value_ && op.value_ < num_general_registers_); | 402 MachineRepresentation rep = GetCanonicalRep(op); |
| 392 return Unallocated(op, UnallocatedOperand::FIXED_REGISTER, op.value_); | 403 CHECK(0 <= op.value_ && op.value_ < GetNumRegs(rep)); |
| 404 if (DoesRegisterAllocation()) { |
| 405 auto extended_policy = IsFloatingPoint(rep) |
| 406 ? UnallocatedOperand::FIXED_FP_REGISTER |
| 407 : UnallocatedOperand::FIXED_REGISTER; |
| 408 return Unallocated(op, extended_policy, op.value_); |
| 409 } else { |
| 410 return AllocatedOperand(LocationOperand::REGISTER, rep, op.value_); |
| 411 } |
| 412 } |
| 393 case kFixedSlot: | 413 case kFixedSlot: |
| 394 return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_); | 414 if (DoesRegisterAllocation()) { |
| 415 return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_); |
| 416 } else { |
| 417 return AllocatedOperand(LocationOperand::STACK_SLOT, |
| 418 GetCanonicalRep(op), op.value_); |
| 419 } |
| 395 default: | 420 default: |
| 396 break; | 421 break; |
| 397 } | 422 } |
| 398 CHECK(false); | 423 CHECK(false); |
| 399 return InstructionOperand(); | 424 return InstructionOperand(); |
| 400 } | 425 } |
| 401 | 426 |
| 402 | 427 |
| 403 InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg, | 428 InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg, |
| 404 TestOperand op) { | 429 TestOperand op) { |
| 405 CHECK_EQ(op.vreg_.value_, kNoValue); | 430 CHECK_EQ(op.vreg_.value_, kNoValue); |
| 406 op.vreg_ = vreg; | 431 op.vreg_ = vreg; |
| 407 switch (op.type_) { | 432 switch (op.type_) { |
| 408 case kSameAsFirst: | 433 case kSameAsFirst: |
| 409 return Unallocated(op, UnallocatedOperand::SAME_AS_FIRST_INPUT); | 434 return Unallocated(op, UnallocatedOperand::SAME_AS_FIRST_INPUT); |
| 410 case kRegister: | 435 case kRegister: |
| 411 return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER); | 436 return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER); |
| 412 case kFixedSlot: | 437 case kFixedSlot: |
| 413 return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_); | 438 if (DoesRegisterAllocation()) { |
| 414 case kFixedRegister: | 439 return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_); |
| 415 CHECK(0 <= op.value_ && op.value_ < num_general_registers_); | 440 } else { |
| 416 return Unallocated(op, UnallocatedOperand::FIXED_REGISTER, op.value_); | 441 return AllocatedOperand(LocationOperand::STACK_SLOT, |
| 442 GetCanonicalRep(op), op.value_); |
| 443 } |
| 444 case kFixedRegister: { |
| 445 MachineRepresentation rep = GetCanonicalRep(op); |
| 446 CHECK(0 <= op.value_ && op.value_ < GetNumRegs(rep)); |
| 447 if (DoesRegisterAllocation()) { |
| 448 auto extended_policy = IsFloatingPoint(rep) |
| 449 ? UnallocatedOperand::FIXED_FP_REGISTER |
| 450 : UnallocatedOperand::FIXED_REGISTER; |
| 451 return Unallocated(op, extended_policy, op.value_); |
| 452 } else { |
| 453 return AllocatedOperand(LocationOperand::REGISTER, rep, op.value_); |
| 454 } |
| 455 } |
| 417 default: | 456 default: |
| 418 break; | 457 break; |
| 419 } | 458 } |
| 420 CHECK(false); | 459 CHECK(false); |
| 421 return InstructionOperand(); | 460 return InstructionOperand(); |
| 422 } | 461 } |
| 423 | 462 |
| 424 | 463 |
| 425 InstructionBlock* InstructionSequenceTest::NewBlock(bool deferred) { | 464 InstructionBlock* InstructionSequenceTest::NewBlock(bool deferred) { |
| 426 CHECK(current_block_ == nullptr); | 465 CHECK(current_block_ == nullptr); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 | 545 |
| 507 | 546 |
| 508 Instruction* InstructionSequenceTest::AddInstruction(Instruction* instruction) { | 547 Instruction* InstructionSequenceTest::AddInstruction(Instruction* instruction) { |
| 509 sequence()->AddInstruction(instruction); | 548 sequence()->AddInstruction(instruction); |
| 510 return instruction; | 549 return instruction; |
| 511 } | 550 } |
| 512 | 551 |
| 513 } // namespace compiler | 552 } // namespace compiler |
| 514 } // namespace internal | 553 } // namespace internal |
| 515 } // namespace v8 | 554 } // namespace v8 |
| OLD | NEW |