| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 4244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4255 __ lwc1(f2, MemOperand(a0, OFFSET_OF(Test, fOp2)) ); | 4255 __ lwc1(f2, MemOperand(a0, OFFSET_OF(Test, fOp2)) ); |
| 4256 __ nop(); | 4256 __ nop(); |
| 4257 __ div_s(f6, f4, f2); | 4257 __ div_s(f6, f4, f2); |
| 4258 __ swc1(f6, MemOperand(a0, OFFSET_OF(Test, fRes)) ); | 4258 __ swc1(f6, MemOperand(a0, OFFSET_OF(Test, fRes)) ); |
| 4259 | 4259 |
| 4260 // Restore FCSR. | 4260 // Restore FCSR. |
| 4261 __ ctc1(a1, FCSR); | 4261 __ ctc1(a1, FCSR); |
| 4262 | 4262 |
| 4263 __ jr(ra); | 4263 __ jr(ra); |
| 4264 __ nop(); | 4264 __ nop(); |
| 4265 |
| 4265 CodeDesc desc; | 4266 CodeDesc desc; |
| 4266 assm.GetCode(&desc); | 4267 assm.GetCode(&desc); |
| 4267 Handle<Code> code = isolate->factory()->NewCode( | 4268 Handle<Code> code = isolate->factory()->NewCode( |
| 4268 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 4269 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4270 |
| 4269 F3 f = FUNCTION_CAST<F3>(code->entry()); | 4271 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 4270 | 4272 |
| 4271 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 4273 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4272 | 4274 |
| 4273 const int test_size = 3; | 4275 const int test_size = 3; |
| 4274 | 4276 |
| 4275 double dOp1[test_size] = { | 4277 double dOp1[test_size] = { |
| 4276 5.0, | 4278 5.0, |
| 4277 DBL_MAX, | 4279 DBL_MAX, |
| 4278 DBL_MAX, | 4280 DBL_MAX, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4336 test.dOp2 = -5.0; | 4338 test.dOp2 = -5.0; |
| 4337 test.fOp1 = std::numeric_limits<float>::quiet_NaN(); | 4339 test.fOp1 = std::numeric_limits<float>::quiet_NaN(); |
| 4338 test.fOp2 = -5.0; | 4340 test.fOp2 = -5.0; |
| 4339 | 4341 |
| 4340 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 4342 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4341 CHECK_EQ(true, std::isnan(test.dRes)); | 4343 CHECK_EQ(true, std::isnan(test.dRes)); |
| 4342 CHECK_EQ(true, std::isnan(test.fRes)); | 4344 CHECK_EQ(true, std::isnan(test.fRes)); |
| 4343 } | 4345 } |
| 4344 | 4346 |
| 4345 | 4347 |
| 4348 uint32_t run_align(uint32_t rs, uint32_t rt, uint8_t bp) { |
| 4349 Isolate* isolate = CcTest::i_isolate(); |
| 4350 HandleScope scope(isolate); |
| 4351 |
| 4352 MacroAssembler assm(isolate, NULL, 0); |
| 4353 |
| 4354 // ALIGN rd, rs, rt, bp |
| 4355 __ align(v0, a0, a1, bp); |
| 4356 __ jr(ra); |
| 4357 __ nop(); |
| 4358 |
| 4359 CodeDesc desc; |
| 4360 assm.GetCode(&desc); |
| 4361 Handle<Code> code = isolate->factory()->NewCode( |
| 4362 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4363 |
| 4364 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4365 |
| 4366 uint32_t rd = |
| 4367 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, rs, rt, bp, 0, 0)); |
| 4368 |
| 4369 return rd; |
| 4370 } |
| 4371 |
| 4372 |
| 4373 TEST(r6_align) { |
| 4374 if (IsMipsArchVariant(kMips32r6)) { |
| 4375 CcTest::InitializeVM(); |
| 4376 |
| 4377 struct TestCaseAlign { |
| 4378 uint32_t rd_expected; |
| 4379 uint32_t rs; |
| 4380 uint32_t rt; |
| 4381 uint8_t bp; |
| 4382 }; |
| 4383 |
| 4384 struct TestCaseAlign tc[] = { |
| 4385 // rd_expected, rs, rt, bp |
| 4386 { 0xaabbccdd, 0x11223344, 0xaabbccdd, 0 }, |
| 4387 { 0xbbccdd11, 0x11223344, 0xaabbccdd, 1 }, |
| 4388 { 0xccdd1122, 0x11223344, 0xaabbccdd, 2 }, |
| 4389 { 0xdd112233, 0x11223344, 0xaabbccdd, 3 }, |
| 4390 }; |
| 4391 |
| 4392 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign); |
| 4393 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4394 CHECK_EQ(tc[i].rd_expected, run_align(tc[i].rs, tc[i].rt, tc[i].bp)); |
| 4395 } |
| 4396 } |
| 4397 } |
| 4398 |
| 4399 uint32_t PC; // The program counter. |
| 4400 |
| 4401 uint32_t run_aluipc(int16_t imm16) { |
| 4402 Isolate* isolate = CcTest::i_isolate(); |
| 4403 HandleScope scope(isolate); |
| 4404 |
| 4405 MacroAssembler assm(isolate, NULL, 0); |
| 4406 |
| 4407 __ aluipc(v0, imm16); |
| 4408 __ jr(ra); |
| 4409 __ nop(); |
| 4410 |
| 4411 CodeDesc desc; |
| 4412 assm.GetCode(&desc); |
| 4413 Handle<Code> code = isolate->factory()->NewCode( |
| 4414 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4415 |
| 4416 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4417 PC = (uint32_t) f; // Set the program counter. |
| 4418 |
| 4419 uint32_t rs = |
| 4420 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, imm16, 0, 0, 0, 0)); |
| 4421 |
| 4422 return rs; |
| 4423 } |
| 4424 |
| 4425 |
| 4426 TEST(r6_aluipc) { |
| 4427 if (IsMipsArchVariant(kMips32r6)) { |
| 4428 CcTest::InitializeVM(); |
| 4429 |
| 4430 struct TestCaseAluipc { |
| 4431 int16_t imm16; |
| 4432 // Expected value of rs register will be calculated later. |
| 4433 // As rs register will be used v0 register. |
| 4434 }; |
| 4435 |
| 4436 struct TestCaseAluipc tc[] = { |
| 4437 // imm16 |
| 4438 { -32768 }, // 0x8000 |
| 4439 { -1 }, // 0xFFFF |
| 4440 { 0 }, |
| 4441 { 1 }, |
| 4442 { 32767 }, // 0x7FFF |
| 4443 }; |
| 4444 |
| 4445 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc); |
| 4446 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4447 PC = 0; |
| 4448 uint32_t rs = run_aluipc(tc[i].imm16); |
| 4449 // Now, the program_counter (PC) is set. |
| 4450 uint32_t rs_expected = ~0x0FFFF & (PC + (tc[i].imm16 << 16)); |
| 4451 CHECK_EQ(rs_expected, rs); |
| 4452 } |
| 4453 } |
| 4454 } |
| 4455 |
| 4456 |
| 4457 uint32_t run_auipc(int16_t imm16) { |
| 4458 Isolate* isolate = CcTest::i_isolate(); |
| 4459 HandleScope scope(isolate); |
| 4460 |
| 4461 MacroAssembler assm(isolate, NULL, 0); |
| 4462 |
| 4463 __ auipc(v0, imm16); |
| 4464 __ jr(ra); |
| 4465 __ nop(); |
| 4466 |
| 4467 CodeDesc desc; |
| 4468 assm.GetCode(&desc); |
| 4469 Handle<Code> code = isolate->factory()->NewCode( |
| 4470 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4471 |
| 4472 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4473 PC = (uint32_t) f; // Set program counter. |
| 4474 |
| 4475 uint32_t rs = |
| 4476 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, imm16, 0, 0, 0, 0)); |
| 4477 |
| 4478 return rs; |
| 4479 } |
| 4480 |
| 4481 |
| 4482 TEST(r6_auipc) { |
| 4483 if (IsMipsArchVariant(kMips32r6)) { |
| 4484 CcTest::InitializeVM(); |
| 4485 |
| 4486 struct TestCaseAuipc { |
| 4487 int16_t imm16; |
| 4488 // Expected value of rs register will be calculated later. |
| 4489 // As rs register will be used v0 register. |
| 4490 }; |
| 4491 |
| 4492 struct TestCaseAuipc tc[] = { |
| 4493 // imm16 |
| 4494 { -32768 }, // 0x8000 |
| 4495 { -1 }, // 0xFFFF |
| 4496 { 0 }, |
| 4497 { 1 }, |
| 4498 { 32767 }, // 0x7FFF |
| 4499 }; |
| 4500 |
| 4501 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc); |
| 4502 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4503 PC = 0; |
| 4504 uint32_t rs = run_auipc(tc[i].imm16); |
| 4505 // Now, the program_counter (PC) is set. |
| 4506 uint32_t rs_expected = PC + (tc[i].imm16 << 16); |
| 4507 CHECK_EQ(rs_expected, rs); |
| 4508 } |
| 4509 } |
| 4510 } |
| 4511 |
| 4512 |
| 4513 uint32_t run_lwpc(int offset) { |
| 4514 Isolate* isolate = CcTest::i_isolate(); |
| 4515 HandleScope scope(isolate); |
| 4516 |
| 4517 MacroAssembler assm(isolate, NULL, 0); |
| 4518 |
| 4519 // 256k instructions; 2^8k |
| 4520 // addiu t7, t0, 0xffff; (0x250fffff) |
| 4521 // ... |
| 4522 // addiu t4, t0, 0x0000; (0x250c0000) |
| 4523 uint32_t addiu_start_1 = 0x25000000; |
| 4524 for (int32_t i = 0xfffff; i >= 0xc0000; --i) { |
| 4525 uint32_t addiu_new = addiu_start_1 + i; |
| 4526 __ dd(addiu_new); |
| 4527 } |
| 4528 |
| 4529 __ lwpc(t8, offset); // offset 0; 0xef080000 (t8 register) |
| 4530 __ mov(v0, t8); |
| 4531 |
| 4532 // 256k instructions; 2^8k |
| 4533 // addiu t0, t0, 0x0000; (0x25080000) |
| 4534 // ... |
| 4535 // addiu t3, t0, 0xffff; (0x250bffff) |
| 4536 uint32_t addiu_start_2 = 0x25000000; |
| 4537 for (int32_t i = 0x80000; i <= 0xbffff; ++i) { |
| 4538 uint32_t addiu_new = addiu_start_2 + i; |
| 4539 __ dd(addiu_new); |
| 4540 } |
| 4541 |
| 4542 __ jr(ra); |
| 4543 __ nop(); |
| 4544 |
| 4545 CodeDesc desc; |
| 4546 assm.GetCode(&desc); |
| 4547 Handle<Code> code = isolate->factory()->NewCode( |
| 4548 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4549 |
| 4550 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4551 |
| 4552 uint32_t res = |
| 4553 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, offset, 0, 0, 0, 0)); |
| 4554 |
| 4555 return res; |
| 4556 } |
| 4557 |
| 4558 |
| 4559 TEST(r6_lwpc) { |
| 4560 if (IsMipsArchVariant(kMips32r6)) { |
| 4561 CcTest::InitializeVM(); |
| 4562 |
| 4563 struct TestCaseLwpc { |
| 4564 // rs - A word from memory will be stored in t8 register. |
| 4565 int offset; |
| 4566 uint32_t expected_rs; |
| 4567 }; |
| 4568 |
| 4569 struct TestCaseLwpc tc[] = { |
| 4570 // offset, expected_rs |
| 4571 { -262144, 0x250fffff }, // offset 0x40000 |
| 4572 { -4, 0x250c0003 }, |
| 4573 { -1, 0x250c0000 }, |
| 4574 { 0, 0xef080000 }, |
| 4575 { 1, 0x03001025 }, // mov(v0, t8) |
| 4576 { 2, 0x25080000 }, |
| 4577 { 4, 0x25080002 }, |
| 4578 { 262143, 0x250bfffd }, // offset 0x3ffff |
| 4579 }; |
| 4580 |
| 4581 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc); |
| 4582 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4583 uint32_t res = run_lwpc(tc[i].offset); |
| 4584 CHECK_EQ(tc[i].expected_rs, res); |
| 4585 } |
| 4586 } |
| 4587 } |
| 4588 |
| 4589 |
| 4590 uint32_t run_jic(int16_t offset) { |
| 4591 Isolate* isolate = CcTest::i_isolate(); |
| 4592 HandleScope scope(isolate); |
| 4593 |
| 4594 MacroAssembler assm(isolate, NULL, 0); |
| 4595 |
| 4596 Label get_program_counter, stop_execution; |
| 4597 __ push(ra); |
| 4598 __ li(v0, 0); |
| 4599 __ li(t1, 0x66); |
| 4600 |
| 4601 __ addiu(v0, v0, 0x1); // <-- offset = -32 |
| 4602 __ addiu(v0, v0, 0x2); |
| 4603 __ addiu(v0, v0, 0x10); |
| 4604 __ addiu(v0, v0, 0x20); |
| 4605 __ beq(v0, t1, &stop_execution); |
| 4606 __ nop(); |
| 4607 |
| 4608 __ bal(&get_program_counter); // t0 <- program counter |
| 4609 __ nop(); |
| 4610 __ jic(t0, offset); |
| 4611 |
| 4612 __ addiu(v0, v0, 0x100); |
| 4613 __ addiu(v0, v0, 0x200); |
| 4614 __ addiu(v0, v0, 0x1000); |
| 4615 __ addiu(v0, v0, 0x2000); // <--- offset = 16 |
| 4616 __ pop(ra); |
| 4617 __ jr(ra); |
| 4618 __ nop(); |
| 4619 |
| 4620 __ bind(&get_program_counter); |
| 4621 __ mov(t0, ra); |
| 4622 __ jr(ra); |
| 4623 __ nop(); |
| 4624 |
| 4625 __ bind(&stop_execution); |
| 4626 __ pop(ra); |
| 4627 __ jr(ra); |
| 4628 __ nop(); |
| 4629 |
| 4630 CodeDesc desc; |
| 4631 assm.GetCode(&desc); |
| 4632 Handle<Code> code = isolate->factory()->NewCode( |
| 4633 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4634 |
| 4635 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4636 |
| 4637 uint32_t res = |
| 4638 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, offset, 0, 0, 0, 0)); |
| 4639 |
| 4640 return res; |
| 4641 } |
| 4642 |
| 4643 |
| 4644 TEST(r6_jic) { |
| 4645 if (IsMipsArchVariant(kMips32r6)) { |
| 4646 CcTest::InitializeVM(); |
| 4647 |
| 4648 struct TestCaseJic { |
| 4649 // As rt will be used t0 register which will have value of |
| 4650 // the program counter for the jic instruction. |
| 4651 int16_t offset; |
| 4652 uint32_t expected_res; |
| 4653 }; |
| 4654 |
| 4655 struct TestCaseJic tc[] = { |
| 4656 // offset, expected_result |
| 4657 { 16, 0x2033 }, |
| 4658 { 4, 0x3333 }, |
| 4659 { -32, 0x66 }, |
| 4660 }; |
| 4661 |
| 4662 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic); |
| 4663 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4664 uint32_t res = run_jic(tc[i].offset); |
| 4665 CHECK_EQ(tc[i].expected_res, res); |
| 4666 } |
| 4667 } |
| 4668 } |
| 4669 |
| 4670 |
| 4671 uint64_t run_beqzc(int32_t rs, int32_t offset) { |
| 4672 Isolate* isolate = CcTest::i_isolate(); |
| 4673 HandleScope scope(isolate); |
| 4674 |
| 4675 MacroAssembler assm(isolate, NULL, 0); |
| 4676 |
| 4677 Label stop_execution; |
| 4678 __ li(v0, 0); |
| 4679 __ li(t1, 0x66); |
| 4680 __ push(ra); |
| 4681 |
| 4682 __ addiu(v0, v0, 0x1); // <-- offset = -32 |
| 4683 __ addiu(v0, v0, 0x2); |
| 4684 __ addiu(v0, v0, 0x10); |
| 4685 __ addiu(v0, v0, 0x20); |
| 4686 __ beq(v0, t1, &stop_execution); |
| 4687 __ nop(); |
| 4688 |
| 4689 __ beqzc(a0, offset); // BEQZC rs, offset |
| 4690 |
| 4691 __ addiu(v0, v0, 0x1); |
| 4692 __ addiu(v0, v0, 0x100); |
| 4693 __ addiu(v0, v0, 0x200); |
| 4694 __ addiu(v0, v0, 0x1000); |
| 4695 __ addiu(v0, v0, 0x2000); // <--- offset = 16 |
| 4696 __ jr(ra); |
| 4697 __ nop(); |
| 4698 |
| 4699 __ bind(&stop_execution); |
| 4700 __ pop(ra); |
| 4701 __ jr(ra); |
| 4702 __ nop(); |
| 4703 |
| 4704 CodeDesc desc; |
| 4705 assm.GetCode(&desc); |
| 4706 Handle<Code> code = isolate->factory()->NewCode( |
| 4707 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4708 |
| 4709 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4710 |
| 4711 uint32_t res = |
| 4712 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0)); |
| 4713 |
| 4714 return res; |
| 4715 } |
| 4716 |
| 4717 |
| 4718 TEST(r6_beqzc) { |
| 4719 if (IsMipsArchVariant(kMips32r6)) { |
| 4720 CcTest::InitializeVM(); |
| 4721 |
| 4722 struct TestCaseBeqzc { |
| 4723 uint32_t rs_value; |
| 4724 int32_t offset; |
| 4725 uint32_t expected_res; |
| 4726 }; |
| 4727 |
| 4728 struct TestCaseBeqzc tc[] = { |
| 4729 // rs_value, offset, expected_res |
| 4730 { 0x0, -8, 0x66 }, |
| 4731 { 0x0, 0, 0x3334 }, |
| 4732 { 0x0, 1, 0x3333 }, |
| 4733 { 0xabc, 1, 0x3334 }, |
| 4734 { 0x0, 4, 0x2033 }, |
| 4735 }; |
| 4736 |
| 4737 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc); |
| 4738 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4739 uint32_t res = run_beqzc(tc[i].rs_value, tc[i].offset); |
| 4740 CHECK_EQ(tc[i].expected_res, res); |
| 4741 } |
| 4742 } |
| 4743 } |
| 4744 |
| 4745 |
| 4746 uint32_t run_jialc(int16_t offset) { |
| 4747 Isolate* isolate = CcTest::i_isolate(); |
| 4748 HandleScope scope(isolate); |
| 4749 |
| 4750 MacroAssembler assm(isolate, NULL, 0); |
| 4751 |
| 4752 Label main_block, get_program_counter; |
| 4753 __ push(ra); |
| 4754 __ li(v0, 0); |
| 4755 __ beq(v0, v0, &main_block); |
| 4756 __ nop(); |
| 4757 |
| 4758 // Block 1 |
| 4759 __ addiu(v0, v0, 0x1); // <-- offset = -40 |
| 4760 __ addiu(v0, v0, 0x2); |
| 4761 __ jr(ra); |
| 4762 __ nop(); |
| 4763 |
| 4764 // Block 2 |
| 4765 __ addiu(v0, v0, 0x10); // <-- offset = -24 |
| 4766 __ addiu(v0, v0, 0x20); |
| 4767 __ jr(ra); |
| 4768 __ nop(); |
| 4769 |
| 4770 // Block 3 (Main) |
| 4771 __ bind(&main_block); |
| 4772 __ bal(&get_program_counter); // t0 <- program counter |
| 4773 __ nop(); |
| 4774 __ jialc(t0, offset); |
| 4775 __ addiu(v0, v0, 0x4); |
| 4776 __ pop(ra); |
| 4777 __ jr(ra); |
| 4778 __ nop(); |
| 4779 |
| 4780 // Block 4 |
| 4781 __ addiu(v0, v0, 0x100); // <-- offset = 20 |
| 4782 __ addiu(v0, v0, 0x200); |
| 4783 __ jr(ra); |
| 4784 __ nop(); |
| 4785 |
| 4786 // Block 5 |
| 4787 __ addiu(v0, v0, 0x1000); // <--- offset = 36 |
| 4788 __ addiu(v0, v0, 0x2000); |
| 4789 __ jr(ra); |
| 4790 __ nop(); |
| 4791 |
| 4792 __ bind(&get_program_counter); |
| 4793 __ mov(t0, ra); |
| 4794 __ jr(ra); |
| 4795 __ nop(); |
| 4796 |
| 4797 |
| 4798 CodeDesc desc; |
| 4799 assm.GetCode(&desc); |
| 4800 Handle<Code> code = isolate->factory()->NewCode( |
| 4801 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4802 |
| 4803 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4804 |
| 4805 uint32_t res = |
| 4806 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, offset, 0, 0, 0, 0)); |
| 4807 |
| 4808 return res; |
| 4809 } |
| 4810 |
| 4811 |
| 4812 TEST(r6_jialc) { |
| 4813 if (IsMipsArchVariant(kMips32r6)) { |
| 4814 CcTest::InitializeVM(); |
| 4815 |
| 4816 struct TestCaseJialc { |
| 4817 // As rt will be used t0 register which will have value of |
| 4818 // the program counter for the jialc instruction. |
| 4819 int16_t offset; |
| 4820 uint32_t expected_res; |
| 4821 }; |
| 4822 |
| 4823 struct TestCaseJialc tc[] = { |
| 4824 // offset, expected_res |
| 4825 { -40, 0x7 }, |
| 4826 { -24, 0x34 }, |
| 4827 { 20, 0x304 }, |
| 4828 { 36, 0x3004 } |
| 4829 }; |
| 4830 |
| 4831 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc); |
| 4832 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4833 uint32_t res = run_jialc(tc[i].offset); |
| 4834 CHECK_EQ(tc[i].expected_res, res); |
| 4835 } |
| 4836 } |
| 4837 } |
| 4838 |
| 4839 |
| 4840 uint64_t run_addiupc(int32_t imm19) { |
| 4841 Isolate* isolate = CcTest::i_isolate(); |
| 4842 HandleScope scope(isolate); |
| 4843 |
| 4844 MacroAssembler assm(isolate, NULL, 0); |
| 4845 |
| 4846 __ addiupc(v0, imm19); |
| 4847 __ jr(ra); |
| 4848 __ nop(); |
| 4849 |
| 4850 CodeDesc desc; |
| 4851 assm.GetCode(&desc); |
| 4852 Handle<Code> code = isolate->factory()->NewCode( |
| 4853 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4854 |
| 4855 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4856 PC = (uint32_t) f; // Set the program counter. |
| 4857 |
| 4858 uint32_t rs = |
| 4859 reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, imm19, 0, 0, 0, 0)); |
| 4860 |
| 4861 return rs; |
| 4862 } |
| 4863 |
| 4864 |
| 4865 TEST(r6_addiupc) { |
| 4866 if (IsMipsArchVariant(kMips32r6)) { |
| 4867 CcTest::InitializeVM(); |
| 4868 |
| 4869 struct TestCaseAddiupc { |
| 4870 int32_t imm19; |
| 4871 // Expected value of the rs register will be calculated later. |
| 4872 // As rs register will be used v0 register. |
| 4873 }; |
| 4874 |
| 4875 struct TestCaseAddiupc tc[] = { |
| 4876 // imm19 |
| 4877 { -262144 }, // 0x40000 |
| 4878 { -1 }, // 0x7FFFF |
| 4879 { 0 }, |
| 4880 { 1 }, // 0x00001 |
| 4881 { 262143 } // 0x3FFFF |
| 4882 }; |
| 4883 |
| 4884 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc); |
| 4885 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4886 PC = 0; |
| 4887 uint32_t rs = run_addiupc(tc[i].imm19); |
| 4888 // Now, the program_counter (PC) is set. |
| 4889 uint32_t rs_expected = PC + (tc[i].imm19 << 2); |
| 4890 CHECK_EQ(rs_expected, rs); |
| 4891 } |
| 4892 } |
| 4893 } |
| 4894 |
| 4895 |
| 4896 int32_t run_bc(int32_t offset) { |
| 4897 Isolate* isolate = CcTest::i_isolate(); |
| 4898 HandleScope scope(isolate); |
| 4899 |
| 4900 MacroAssembler assm(isolate, NULL, 0); |
| 4901 |
| 4902 Label continue_1, stop_execution; |
| 4903 __ push(ra); |
| 4904 __ li(v0, 0); |
| 4905 __ li(t8, 0); |
| 4906 __ li(t9, 2); // A condition for stopping execution. |
| 4907 |
| 4908 uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1 |
| 4909 for (int32_t i = -100; i <= -11; ++i) { |
| 4910 __ dd(instruction_addiu); |
| 4911 } |
| 4912 |
| 4913 __ addiu(t8, t8, 1); // -10 |
| 4914 |
| 4915 __ beq(t8, t9, &stop_execution); // -9 |
| 4916 __ nop(); // -8 |
| 4917 __ beq(t8, t8, &continue_1); // -7 |
| 4918 __ nop(); // -6 |
| 4919 |
| 4920 __ bind(&stop_execution); |
| 4921 __ pop(ra); // -5, -4 |
| 4922 __ jr(ra); // -3 |
| 4923 __ nop(); // -2 |
| 4924 |
| 4925 __ bind(&continue_1); |
| 4926 __ bc(offset); // -1 |
| 4927 |
| 4928 for (int32_t i = 0; i <= 99; ++i) { |
| 4929 __ dd(instruction_addiu); |
| 4930 } |
| 4931 |
| 4932 __ pop(ra); |
| 4933 __ jr(ra); |
| 4934 __ nop(); |
| 4935 |
| 4936 CodeDesc desc; |
| 4937 assm.GetCode(&desc); |
| 4938 Handle<Code> code = isolate->factory()->NewCode( |
| 4939 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4940 |
| 4941 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4942 |
| 4943 int32_t res = |
| 4944 reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, offset, 0, 0, 0, 0)); |
| 4945 |
| 4946 return res; |
| 4947 } |
| 4948 |
| 4949 |
| 4950 TEST(r6_bc) { |
| 4951 if (IsMipsArchVariant(kMips32r6)) { |
| 4952 CcTest::InitializeVM(); |
| 4953 |
| 4954 struct TestCaseBc { |
| 4955 int32_t offset; |
| 4956 int32_t expected_res; |
| 4957 }; |
| 4958 |
| 4959 struct TestCaseBc tc[] = { |
| 4960 // offset, expected_result |
| 4961 { -100, (abs(-100) - 10) * 2 }, |
| 4962 { -11, (abs(-100) - 10 + 1) }, |
| 4963 { 0, (abs(-100) - 10 + 1 + 99) }, |
| 4964 { 1, (abs(-100) - 10 + 99) }, |
| 4965 { 99, (abs(-100) - 10 + 1) }, |
| 4966 }; |
| 4967 |
| 4968 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc); |
| 4969 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4970 int32_t res = run_bc(tc[i].offset); |
| 4971 CHECK_EQ(tc[i].expected_res, res); |
| 4972 } |
| 4973 } |
| 4974 } |
| 4975 |
| 4976 |
| 4977 int32_t run_balc(int32_t offset) { |
| 4978 Isolate* isolate = CcTest::i_isolate(); |
| 4979 HandleScope scope(isolate); |
| 4980 |
| 4981 MacroAssembler assm(isolate, NULL, 0); |
| 4982 |
| 4983 Label continue_1, stop_execution; |
| 4984 __ push(ra); |
| 4985 __ li(v0, 0); |
| 4986 __ li(t8, 0); |
| 4987 __ li(t9, 2); // A condition for stopping execution. |
| 4988 |
| 4989 __ beq(t8, t8, &continue_1); |
| 4990 __ nop(); |
| 4991 |
| 4992 uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1 |
| 4993 for (int32_t i = -117; i <= -57; ++i) { |
| 4994 __ dd(instruction_addiu); |
| 4995 } |
| 4996 __ jr(ra); // -56 |
| 4997 __ nop(); // -55 |
| 4998 |
| 4999 for (int32_t i = -54; i <= -4; ++i) { |
| 5000 __ dd(instruction_addiu); |
| 5001 } |
| 5002 __ jr(ra); // -3 |
| 5003 __ nop(); // -2 |
| 5004 |
| 5005 __ bind(&continue_1); |
| 5006 __ balc(offset); // -1 |
| 5007 |
| 5008 __ pop(ra); // 0, 1 |
| 5009 __ jr(ra); // 2 |
| 5010 __ nop(); // 3 |
| 5011 |
| 5012 for (int32_t i = 4; i <= 44; ++i) { |
| 5013 __ dd(instruction_addiu); |
| 5014 } |
| 5015 __ jr(ra); |
| 5016 __ nop(); |
| 5017 |
| 5018 CodeDesc desc; |
| 5019 assm.GetCode(&desc); |
| 5020 Handle<Code> code = isolate->factory()->NewCode( |
| 5021 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 5022 |
| 5023 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 5024 |
| 5025 int32_t res = |
| 5026 reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, offset, 0, 0, 0, 0)); |
| 5027 |
| 5028 return res; |
| 5029 } |
| 5030 |
| 5031 |
| 5032 TEST(r6_balc) { |
| 5033 if (IsMipsArchVariant(kMips32r6)) { |
| 5034 CcTest::InitializeVM(); |
| 5035 |
| 5036 struct TestCaseBalc { |
| 5037 int32_t offset; |
| 5038 int32_t expected_res; |
| 5039 }; |
| 5040 |
| 5041 struct TestCaseBalc tc[] = { |
| 5042 // offset, expected_result |
| 5043 { -117, 61 }, |
| 5044 { -54, 51 }, |
| 5045 { 0, 0 }, |
| 5046 { 4, 41 }, |
| 5047 }; |
| 5048 |
| 5049 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc); |
| 5050 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 5051 int32_t res = run_balc(tc[i].offset); |
| 5052 CHECK_EQ(tc[i].expected_res, res); |
| 5053 } |
| 5054 } |
| 5055 } |
| 5056 |
| 5057 |
| 4346 #undef __ | 5058 #undef __ |
| OLD | NEW |