| 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 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 #include "test/cctest/cctest.h" | 39 #include "test/cctest/cctest.h" |
| 40 | 40 |
| 41 using namespace v8::internal; | 41 using namespace v8::internal; |
| 42 | 42 |
| 43 | 43 |
| 44 // Define these function prototypes to match JSEntryFunction in execution.cc. | 44 // Define these function prototypes to match JSEntryFunction in execution.cc. |
| 45 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); | 45 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); |
| 46 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); | 46 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); |
| 47 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); | 47 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); |
| 48 typedef Object* (*F4)(int64_t x, int64_t y, int64_t p2, int64_t p3, int64_t p4); |
| 48 | 49 |
| 49 // clang-format off | 50 // clang-format off |
| 50 | 51 |
| 51 | 52 |
| 52 #define __ assm. | 53 #define __ assm. |
| 53 | 54 |
| 54 TEST(MIPS0) { | 55 TEST(MIPS0) { |
| 55 CcTest::InitializeVM(); | 56 CcTest::InitializeVM(); |
| 56 Isolate* isolate = CcTest::i_isolate(); | 57 Isolate* isolate = CcTest::i_isolate(); |
| 57 HandleScope scope(isolate); | 58 HandleScope scope(isolate); |
| (...skipping 4381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4439 test.dOp2 = -5.0; | 4440 test.dOp2 = -5.0; |
| 4440 test.fOp1 = std::numeric_limits<float>::quiet_NaN(); | 4441 test.fOp1 = std::numeric_limits<float>::quiet_NaN(); |
| 4441 test.fOp2 = -5.0; | 4442 test.fOp2 = -5.0; |
| 4442 | 4443 |
| 4443 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); | 4444 (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); |
| 4444 CHECK_EQ(true, std::isnan(test.dRes)); | 4445 CHECK_EQ(true, std::isnan(test.dRes)); |
| 4445 CHECK_EQ(true, std::isnan(test.fRes)); | 4446 CHECK_EQ(true, std::isnan(test.fRes)); |
| 4446 } | 4447 } |
| 4447 | 4448 |
| 4448 | 4449 |
| 4450 uint64_t run_align(uint64_t rs, uint64_t rt, uint8_t bp) { |
| 4451 Isolate* isolate = CcTest::i_isolate(); |
| 4452 HandleScope scope(isolate); |
| 4453 |
| 4454 MacroAssembler assm(isolate, NULL, 0); |
| 4455 |
| 4456 // ALIGN rd, rs, rt, bp |
| 4457 __ align(v0, a0, a1, bp); |
| 4458 __ jr(ra); |
| 4459 __ nop(); |
| 4460 |
| 4461 CodeDesc desc; |
| 4462 assm.GetCode(&desc); |
| 4463 Handle<Code> code = isolate->factory()->NewCode( |
| 4464 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4465 |
| 4466 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4467 |
| 4468 uint64_t rd = |
| 4469 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, rt, bp, 0, 0)); |
| 4470 |
| 4471 return rd; |
| 4472 } |
| 4473 |
| 4474 |
| 4475 TEST(r6_align) { |
| 4476 if (kArchVariant == kMips64r6) { |
| 4477 CcTest::InitializeVM(); |
| 4478 |
| 4479 struct TestCaseAlign { |
| 4480 uint64_t rd_expected; |
| 4481 uint64_t rs; |
| 4482 uint64_t rt; |
| 4483 uint8_t bp; |
| 4484 }; |
| 4485 |
| 4486 struct TestCaseAlign tc[] = { |
| 4487 // rd_expected, rs, rt, bp |
| 4488 { 0xffffffffaabbccdd, 0x11223344, 0xaabbccdd, 0 }, |
| 4489 { 0xffffffffbbccdd11, 0x11223344, 0xaabbccdd, 1 }, |
| 4490 { 0xffffffffccdd1122, 0x11223344, 0xaabbccdd, 2 }, |
| 4491 { 0xffffffffdd112233, 0x11223344, 0xaabbccdd, 3 }, |
| 4492 }; |
| 4493 |
| 4494 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign); |
| 4495 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4496 CHECK_EQ(tc[i].rd_expected, run_align(tc[i].rs, tc[i].rt, tc[i].bp)); |
| 4497 } |
| 4498 } |
| 4499 } |
| 4500 |
| 4501 |
| 4502 uint64_t run_dalign(uint64_t rs, uint64_t rt, uint8_t bp) { |
| 4503 Isolate* isolate = CcTest::i_isolate(); |
| 4504 HandleScope scope(isolate); |
| 4505 |
| 4506 MacroAssembler assm(isolate, NULL, 0); |
| 4507 |
| 4508 // DALIGN rd, rs, rt, bp |
| 4509 __ dalign(v0, a0, a1, bp); |
| 4510 __ jr(ra); |
| 4511 __ nop(); |
| 4512 |
| 4513 CodeDesc desc; |
| 4514 assm.GetCode(&desc); |
| 4515 Handle<Code> code = isolate->factory()->NewCode( |
| 4516 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4517 |
| 4518 F4 f = FUNCTION_CAST<F4>(code->entry()); |
| 4519 uint64_t rd = |
| 4520 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, rt, bp, 0, 0)); |
| 4521 |
| 4522 return rd; |
| 4523 } |
| 4524 |
| 4525 |
| 4526 TEST(r6_dalign) { |
| 4527 CcTest::InitializeVM(); |
| 4528 |
| 4529 struct TestCaseDalign { |
| 4530 uint64_t rd_expected; |
| 4531 uint64_t rs; |
| 4532 uint64_t rt; |
| 4533 uint8_t bp; |
| 4534 }; |
| 4535 |
| 4536 struct TestCaseDalign tc[] = { |
| 4537 // rd_expected, rs, rt, bp |
| 4538 { 0xaabbccddeeff8899, 0x1122334455667700, 0xaabbccddeeff8899, 0 }, |
| 4539 { 0xbbccddeeff889911, 0x1122334455667700, 0xaabbccddeeff8899, 1 }, |
| 4540 { 0xccddeeff88991122, 0x1122334455667700, 0xaabbccddeeff8899, 2 }, |
| 4541 { 0xddeeff8899112233, 0x1122334455667700, 0xaabbccddeeff8899, 3 }, |
| 4542 { 0xeeff889911223344, 0x1122334455667700, 0xaabbccddeeff8899, 4 }, |
| 4543 { 0xff88991122334455, 0x1122334455667700, 0xaabbccddeeff8899, 5 }, |
| 4544 { 0x8899112233445566, 0x1122334455667700, 0xaabbccddeeff8899, 6 }, |
| 4545 { 0x9911223344556677, 0x1122334455667700, 0xaabbccddeeff8899, 7 } |
| 4546 }; |
| 4547 |
| 4548 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDalign); |
| 4549 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4550 CHECK_EQ(tc[i].rd_expected, run_dalign(tc[i].rs, tc[i].rt, tc[i].bp)); |
| 4551 } |
| 4552 } |
| 4553 |
| 4554 |
| 4555 uint64_t PC; // Program Counter |
| 4556 |
| 4557 uint64_t run_aluipc(int16_t imm16) { |
| 4558 Isolate* isolate = CcTest::i_isolate(); |
| 4559 HandleScope scope(isolate); |
| 4560 |
| 4561 MacroAssembler assm(isolate, NULL, 0); |
| 4562 |
| 4563 // ALUIPC rs, imm16 |
| 4564 __ aluipc(v0, imm16); |
| 4565 __ jr(ra); |
| 4566 __ nop(); |
| 4567 |
| 4568 CodeDesc desc; |
| 4569 assm.GetCode(&desc); |
| 4570 Handle<Code> code = isolate->factory()->NewCode( |
| 4571 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4572 |
| 4573 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4574 PC = (uint64_t) f; // set program counter |
| 4575 |
| 4576 uint64_t rs = |
| 4577 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, imm16, 0, 0, 0, 0)); |
| 4578 |
| 4579 return rs; |
| 4580 } |
| 4581 |
| 4582 |
| 4583 TEST(r6_aluipc) { |
| 4584 CcTest::InitializeVM(); |
| 4585 |
| 4586 struct TestCaseAluipc { |
| 4587 uint64_t rs_expected; |
| 4588 int16_t imm16; |
| 4589 }; |
| 4590 |
| 4591 struct TestCaseAluipc tc[] = { |
| 4592 // rs_expected has formal arguments |
| 4593 // rs_expected, imm16 |
| 4594 { 0x0, -32768 }, // 0x8000 |
| 4595 { 0x0, -1 }, // 0xFFFF |
| 4596 { 0x0, 0 }, |
| 4597 { 0x0, 1 }, |
| 4598 { 0x0, 32767 }, // 0x7FFF |
| 4599 }; |
| 4600 |
| 4601 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc); |
| 4602 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4603 PC = 0; |
| 4604 uint64_t rs = run_aluipc(tc[i].imm16); |
| 4605 // Now, the program_counter (PC) is set |
| 4606 uint64_t rs_expected = ~0x0FFFF & (PC + (tc[i].imm16 << 16)); |
| 4607 CHECK_EQ(rs_expected, rs); |
| 4608 } |
| 4609 } |
| 4610 |
| 4611 |
| 4612 uint64_t run_lwpc(int rs, int offset) { |
| 4613 Isolate* isolate = CcTest::i_isolate(); |
| 4614 HandleScope scope(isolate); |
| 4615 |
| 4616 MacroAssembler assm(isolate, NULL, 0); |
| 4617 |
| 4618 // 256k instructions; 2^8k |
| 4619 // addiu t3, a4, 0xffff; (0x250fffff) |
| 4620 // ... |
| 4621 // addiu t0, a4, 0x0000; (0x250c0000) |
| 4622 uint32_t addiu_start_1 = 0x25000000; |
| 4623 for (int32_t i = 0xfffff; i >= 0xc0000; --i) { |
| 4624 uint32_t addiu_new = addiu_start_1 + i; |
| 4625 __ dd(addiu_new); |
| 4626 } |
| 4627 |
| 4628 __ lwpc(t8, offset); // offset 0; 0xef080000 (t8 register) |
| 4629 __ mov(v0, t8); |
| 4630 |
| 4631 // 256k instructions; 2^8k |
| 4632 // addiu a4, a4, 0x0000; (0x25080000) |
| 4633 // ... |
| 4634 // addiu a7, a4, 0xffff; (0x250bffff) |
| 4635 uint32_t addiu_start_2 = 0x25000000; |
| 4636 for (int32_t i = 0x80000; i <= 0xbffff; ++i) { |
| 4637 uint32_t addiu_new = addiu_start_2 + i; |
| 4638 __ dd(addiu_new); |
| 4639 } |
| 4640 |
| 4641 __ jr(ra); |
| 4642 __ nop(); |
| 4643 |
| 4644 CodeDesc desc; |
| 4645 assm.GetCode(&desc); |
| 4646 Handle<Code> code = isolate->factory()->NewCode( |
| 4647 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4648 |
| 4649 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4650 |
| 4651 uint64_t res = |
| 4652 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0)); |
| 4653 |
| 4654 return res; |
| 4655 } |
| 4656 |
| 4657 |
| 4658 TEST(r6_lwpc) { |
| 4659 CcTest::InitializeVM(); |
| 4660 |
| 4661 struct TestCaseLwpc { |
| 4662 int rs; |
| 4663 int offset; |
| 4664 uint64_t expected_rs; |
| 4665 }; |
| 4666 |
| 4667 struct TestCaseLwpc tc[] = { |
| 4668 // rs, offset, expected_rs_value |
| 4669 { t8.code(), -262144, 0x250fffff }, // offset 0x40000 |
| 4670 { t8.code(), -4, 0x250c0003 }, |
| 4671 { t8.code(), -1, 0x250c0000 }, |
| 4672 { t8.code(), 0, 0xef080000 }, |
| 4673 { t8.code(), 1, 0x03001025 }, // mov(v0, t8) |
| 4674 { t8.code(), 2, 0x25080000 }, |
| 4675 { t8.code(), 4, 0x25080002 }, |
| 4676 { t8.code(), 262143, 0x250bfffd }, // offset 0x3ffff |
| 4677 }; |
| 4678 |
| 4679 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc); |
| 4680 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4681 uint64_t res = run_lwpc(tc[i].rs, tc[i].offset); |
| 4682 CHECK_EQ(tc[i].expected_rs, res); |
| 4683 } |
| 4684 } |
| 4685 |
| 4686 |
| 4687 uint64_t run_jic(int rt, int16_t offset) { |
| 4688 Isolate* isolate = CcTest::i_isolate(); |
| 4689 HandleScope scope(isolate); |
| 4690 |
| 4691 MacroAssembler assm(isolate, NULL, 0); |
| 4692 |
| 4693 Label get_program_counter, stop_execution; |
| 4694 __ push(ra); |
| 4695 __ li(v0, 0); |
| 4696 __ li(t1, 0x66); |
| 4697 |
| 4698 __ addiu(v0, v0, 0x1); // <-- offset = -32 |
| 4699 __ addiu(v0, v0, 0x2); |
| 4700 __ addiu(v0, v0, 0x10); |
| 4701 __ addiu(v0, v0, 0x20); |
| 4702 __ beq(v0, t1, &stop_execution); |
| 4703 __ nop(); |
| 4704 |
| 4705 __ bal(&get_program_counter); // t0 <- program counter |
| 4706 __ nop(); |
| 4707 __ jic(t0, offset); // JIC rt, offset |
| 4708 |
| 4709 __ addiu(v0, v0, 0x100); |
| 4710 __ addiu(v0, v0, 0x200); |
| 4711 __ addiu(v0, v0, 0x1000); |
| 4712 __ addiu(v0, v0, 0x2000); // <--- offset = 16 |
| 4713 __ pop(ra); |
| 4714 __ jr(ra); |
| 4715 __ nop(); |
| 4716 |
| 4717 __ bind(&get_program_counter); |
| 4718 __ mov(t0, ra); |
| 4719 __ jr(ra); |
| 4720 __ nop(); |
| 4721 |
| 4722 __ bind(&stop_execution); |
| 4723 __ pop(ra); |
| 4724 __ jr(ra); |
| 4725 __ nop(); |
| 4726 |
| 4727 CodeDesc desc; |
| 4728 assm.GetCode(&desc); |
| 4729 Handle<Code> code = isolate->factory()->NewCode( |
| 4730 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4731 |
| 4732 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4733 |
| 4734 uint64_t res = |
| 4735 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rt, offset, 0, 0, 0)); |
| 4736 |
| 4737 return res; |
| 4738 } |
| 4739 |
| 4740 |
| 4741 TEST(r6_jic) { |
| 4742 CcTest::InitializeVM(); |
| 4743 |
| 4744 struct TestCaseJic { |
| 4745 uint32_t rt; |
| 4746 int16_t offset; |
| 4747 uint32_t expected_res; |
| 4748 }; |
| 4749 |
| 4750 struct TestCaseJic tc[] = { |
| 4751 // rt - formal argument; will contain value of the program counter |
| 4752 // rt offset, expected_result |
| 4753 { 0, 16, 0x2033 }, |
| 4754 //{ 0, 0, 0x0 }, // JIC in loop |
| 4755 { 0, 4, 0x3333 }, |
| 4756 { 0, -32, 0x66 }, |
| 4757 }; |
| 4758 |
| 4759 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic); |
| 4760 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4761 uint32_t res = run_jic(tc[i].rt, tc[i].offset); |
| 4762 CHECK_EQ(tc[i].expected_res, res); |
| 4763 } |
| 4764 } |
| 4765 |
| 4766 |
| 4767 uint64_t run_beqzc(int32_t rs, int32_t offset) { |
| 4768 Isolate* isolate = CcTest::i_isolate(); |
| 4769 HandleScope scope(isolate); |
| 4770 |
| 4771 MacroAssembler assm(isolate, NULL, 0); |
| 4772 |
| 4773 Label stop_execution; |
| 4774 __ li(v0, 0); |
| 4775 __ li(t1, 0x66); |
| 4776 |
| 4777 __ addiu(v0, v0, 0x1); // <-- offset = -8 |
| 4778 __ addiu(v0, v0, 0x2); |
| 4779 __ addiu(v0, v0, 0x10); |
| 4780 __ addiu(v0, v0, 0x20); |
| 4781 __ beq(v0, t1, &stop_execution); |
| 4782 __ nop(); |
| 4783 |
| 4784 __ beqzc(a0, offset); // BEQZC rs, offset |
| 4785 |
| 4786 __ addiu(v0, v0, 0x1); |
| 4787 __ addiu(v0, v0, 0x100); |
| 4788 __ addiu(v0, v0, 0x200); |
| 4789 __ addiu(v0, v0, 0x1000); |
| 4790 __ addiu(v0, v0, 0x2000); // <--- offset = 4 |
| 4791 __ jr(ra); |
| 4792 __ nop(); |
| 4793 |
| 4794 __ bind(&stop_execution); |
| 4795 __ jr(ra); |
| 4796 __ nop(); |
| 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 uint64_t res = |
| 4806 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0)); |
| 4807 |
| 4808 return res; |
| 4809 } |
| 4810 |
| 4811 |
| 4812 TEST(r6_beqzc) { |
| 4813 CcTest::InitializeVM(); |
| 4814 |
| 4815 struct TestCaseBeqzc { |
| 4816 uint32_t rs; |
| 4817 int32_t offset; |
| 4818 uint32_t expected_res; |
| 4819 }; |
| 4820 |
| 4821 struct TestCaseBeqzc tc[] = { |
| 4822 // rs, offset, expected_result |
| 4823 { 0x0, -8, 0x66 }, |
| 4824 { 0x0, 0, 0x3334 }, |
| 4825 { 0x0, 1, 0x3333 }, |
| 4826 { 0xabc, 1, 0x3334 }, |
| 4827 { 0x0, 4, 0x2033 }, |
| 4828 }; |
| 4829 |
| 4830 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc); |
| 4831 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4832 uint32_t res = run_beqzc(tc[i].rs, tc[i].offset); |
| 4833 CHECK_EQ(tc[i].expected_res, res); |
| 4834 } |
| 4835 } |
| 4836 |
| 4837 |
| 4838 uint64_t run_jialc(int rt, int16_t offset) { |
| 4839 Isolate* isolate = CcTest::i_isolate(); |
| 4840 HandleScope scope(isolate); |
| 4841 |
| 4842 MacroAssembler assm(isolate, NULL, 0); |
| 4843 |
| 4844 Label main_block, get_program_counter; |
| 4845 __ push(ra); |
| 4846 __ li(v0, 0); |
| 4847 __ beq(v0, v0, &main_block); |
| 4848 __ nop(); |
| 4849 |
| 4850 // Block 1 |
| 4851 __ addiu(v0, v0, 0x1); // <-- offset = -40 |
| 4852 __ addiu(v0, v0, 0x2); |
| 4853 __ jr(ra); |
| 4854 __ nop(); |
| 4855 |
| 4856 // Block 2 |
| 4857 __ addiu(v0, v0, 0x10); // <-- offset = -24 |
| 4858 __ addiu(v0, v0, 0x20); |
| 4859 __ jr(ra); |
| 4860 __ nop(); |
| 4861 |
| 4862 // Block 3 (Main) |
| 4863 __ bind(&main_block); |
| 4864 __ bal(&get_program_counter); // t0 <- program counter |
| 4865 __ nop(); |
| 4866 __ jialc(t0, offset); // JIALC rt, offset |
| 4867 __ addiu(v0, v0, 0x4); |
| 4868 __ pop(ra); |
| 4869 __ jr(ra); |
| 4870 __ nop(); |
| 4871 |
| 4872 // Block 4 |
| 4873 __ addiu(v0, v0, 0x100); // <-- offset = 20 |
| 4874 __ addiu(v0, v0, 0x200); |
| 4875 __ jr(ra); |
| 4876 __ nop(); |
| 4877 |
| 4878 // Block 5 |
| 4879 __ addiu(v0, v0, 0x1000); // <--- offset = 36 |
| 4880 __ addiu(v0, v0, 0x2000); |
| 4881 __ jr(ra); |
| 4882 __ nop(); |
| 4883 |
| 4884 __ bind(&get_program_counter); |
| 4885 __ mov(t0, ra); |
| 4886 __ jr(ra); |
| 4887 __ nop(); |
| 4888 |
| 4889 |
| 4890 CodeDesc desc; |
| 4891 assm.GetCode(&desc); |
| 4892 Handle<Code> code = isolate->factory()->NewCode( |
| 4893 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4894 |
| 4895 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4896 |
| 4897 uint64_t res = |
| 4898 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rt, offset, 0, 0, 0)); |
| 4899 |
| 4900 return res; |
| 4901 } |
| 4902 |
| 4903 |
| 4904 TEST(r6_jialc) { |
| 4905 CcTest::InitializeVM(); |
| 4906 |
| 4907 struct TestCaseJialc { |
| 4908 uint32_t rt; |
| 4909 int16_t offset; |
| 4910 uint32_t expected_res; |
| 4911 }; |
| 4912 |
| 4913 struct TestCaseJialc tc[] = { |
| 4914 // rt - formal argument; will contain value of the program counter |
| 4915 // rt, offset, expected_result |
| 4916 { 0, -40, 0x7 }, |
| 4917 { 0, -24, 0x34 }, |
| 4918 { 0, 20, 0x304 }, |
| 4919 { 0, 36, 0x3004 } |
| 4920 }; |
| 4921 |
| 4922 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc); |
| 4923 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4924 uint32_t res = run_jialc(tc[i].rt, tc[i].offset); |
| 4925 CHECK_EQ(tc[i].expected_res, res); |
| 4926 } |
| 4927 } |
| 4928 |
| 4929 |
| 4930 uint64_t run_addiupc(int32_t imm19) { |
| 4931 Isolate* isolate = CcTest::i_isolate(); |
| 4932 HandleScope scope(isolate); |
| 4933 |
| 4934 MacroAssembler assm(isolate, NULL, 0); |
| 4935 |
| 4936 // ADDIUPC rs, imm19 |
| 4937 __ addiupc(v0, imm19); |
| 4938 __ jr(ra); |
| 4939 __ nop(); |
| 4940 |
| 4941 CodeDesc desc; |
| 4942 assm.GetCode(&desc); |
| 4943 Handle<Code> code = isolate->factory()->NewCode( |
| 4944 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 4945 |
| 4946 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 4947 PC = (uint64_t) f; // set program counter |
| 4948 |
| 4949 uint64_t rs = |
| 4950 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, imm19, 0, 0, 0, 0)); |
| 4951 |
| 4952 return rs; |
| 4953 } |
| 4954 |
| 4955 |
| 4956 TEST(r6_addiupc) { |
| 4957 CcTest::InitializeVM(); |
| 4958 |
| 4959 struct TestCaseAddiupc { |
| 4960 uint64_t rs_expected; |
| 4961 int32_t imm19; |
| 4962 }; |
| 4963 |
| 4964 struct TestCaseAddiupc tc[] = { |
| 4965 // rs_expected - formal argument; will be calculated later |
| 4966 // rs_expected, imm19 |
| 4967 { 0x0, -262144 }, // 0x40000 |
| 4968 { 0x0, -1 }, // 0x7FFFF |
| 4969 { 0x0, 0 }, |
| 4970 { 0x0, 1 }, // 0x00001 |
| 4971 { 0x0, 262143 } // 0x3FFFF |
| 4972 }; |
| 4973 |
| 4974 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc); |
| 4975 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 4976 PC = 0; |
| 4977 uint64_t rs = run_addiupc(tc[i].imm19); |
| 4978 // Now, the program_counter (PC) is set |
| 4979 uint64_t rs_expected = PC + (tc[i].imm19 << 2); |
| 4980 CHECK_EQ(rs_expected, rs); |
| 4981 } |
| 4982 } |
| 4983 |
| 4984 |
| 4985 uint64_t run_ldpc(int rs, int offset) { |
| 4986 Isolate* isolate = CcTest::i_isolate(); |
| 4987 HandleScope scope(isolate); |
| 4988 |
| 4989 MacroAssembler assm(isolate, NULL, 0); |
| 4990 |
| 4991 // 256k instructions; 2 * 2^7k = 2^8k |
| 4992 // addiu t3, a4, 0xffff; (0x250fffff) |
| 4993 // ... |
| 4994 // addiu t0, a4, 0x0000; (0x250c0000) |
| 4995 uint32_t addiu_start_1 = 0x25000000; |
| 4996 for (int32_t i = 0xfffff; i >= 0xc0000; --i) { |
| 4997 uint32_t addiu_new = addiu_start_1 + i; |
| 4998 __ dd(addiu_new); |
| 4999 } |
| 5000 |
| 5001 __ ldpc(t8, offset); // offset 0; 0xef080000 (t8 register) |
| 5002 __ mov(v0, t8); |
| 5003 |
| 5004 // 256k instructions; 2 * 2^7k = 2^8k |
| 5005 // addiu a4, a4, 0x0000; (0x25080000) |
| 5006 // ... |
| 5007 // addiu a7, a4, 0xffff; (0x250bffff) |
| 5008 uint32_t addiu_start_2 = 0x25000000; |
| 5009 for (int32_t i = 0x80000; i <= 0xbffff; ++i) { |
| 5010 uint32_t addiu_new = addiu_start_2 + i; |
| 5011 __ dd(addiu_new); |
| 5012 } |
| 5013 |
| 5014 __ jr(ra); |
| 5015 __ nop(); |
| 5016 |
| 5017 CodeDesc desc; |
| 5018 assm.GetCode(&desc); |
| 5019 Handle<Code> code = isolate->factory()->NewCode( |
| 5020 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 5021 |
| 5022 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 5023 |
| 5024 uint64_t res = |
| 5025 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0)); |
| 5026 |
| 5027 return res; |
| 5028 } |
| 5029 |
| 5030 |
| 5031 TEST(r6_ldpc) { |
| 5032 CcTest::InitializeVM(); |
| 5033 |
| 5034 struct TestCaseLdpc { |
| 5035 int rs; |
| 5036 int offset; |
| 5037 uint64_t expected_rs; |
| 5038 }; |
| 5039 |
| 5040 struct TestCaseLdpc tc[] = { |
| 5041 // rs, offset, expected_rs_value |
| 5042 { t8.code(), -131072, 0x250ffffe250fffff }, // offset 0x20000 |
| 5043 { t8.code(), -4, 0x250c0006250c0007 }, |
| 5044 { t8.code(), -1, 0x250c0000250c0001 }, |
| 5045 { t8.code(), 0, 0x03001025ef180000 }, |
| 5046 { t8.code(), 1, 0x2508000125080000 }, |
| 5047 { t8.code(), 4, 0x2508000725080006 }, |
| 5048 { t8.code(), 131071, 0x250bfffd250bfffc }, // offset 0x1ffff |
| 5049 }; |
| 5050 |
| 5051 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLdpc); |
| 5052 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 5053 uint64_t res = run_ldpc(tc[i].rs, tc[i].offset); |
| 5054 CHECK_EQ(tc[i].expected_rs, res); |
| 5055 } |
| 5056 } |
| 5057 |
| 5058 |
| 4449 #undef __ | 5059 #undef __ |
| OLD | NEW |