Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: test/cctest/test-assembler-mips64.cc

Issue 1144373003: MIPS: Implemented PC-relative instructions for R6. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Implementation BC and BALC. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 if (kArchVariant == kMips64r6) {
4528 CcTest::InitializeVM();
4529
4530 struct TestCaseDalign {
4531 uint64_t rd_expected;
4532 uint64_t rs;
4533 uint64_t rt;
4534 uint8_t bp;
4535 };
4536
4537 struct TestCaseDalign tc[] = {
4538 // rd_expected, rs, rt, bp
4539 { 0xaabbccddeeff8899, 0x1122334455667700, 0xaabbccddeeff8899, 0 },
4540 { 0xbbccddeeff889911, 0x1122334455667700, 0xaabbccddeeff8899, 1 },
4541 { 0xccddeeff88991122, 0x1122334455667700, 0xaabbccddeeff8899, 2 },
4542 { 0xddeeff8899112233, 0x1122334455667700, 0xaabbccddeeff8899, 3 },
4543 { 0xeeff889911223344, 0x1122334455667700, 0xaabbccddeeff8899, 4 },
4544 { 0xff88991122334455, 0x1122334455667700, 0xaabbccddeeff8899, 5 },
4545 { 0x8899112233445566, 0x1122334455667700, 0xaabbccddeeff8899, 6 },
4546 { 0x9911223344556677, 0x1122334455667700, 0xaabbccddeeff8899, 7 }
4547 };
4548
4549 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDalign);
4550 for (size_t i = 0; i < nr_test_cases; ++i) {
4551 CHECK_EQ(tc[i].rd_expected, run_dalign(tc[i].rs, tc[i].rt, tc[i].bp));
4552 }
4553 }
4554 }
4555
4556
4557 uint64_t PC; // Program Counter
4558
4559 uint64_t run_aluipc(int16_t imm16) {
4560 Isolate* isolate = CcTest::i_isolate();
4561 HandleScope scope(isolate);
4562
4563 MacroAssembler assm(isolate, NULL, 0);
4564
4565 // ALUIPC rs, imm16
4566 __ aluipc(v0, imm16);
4567 __ jr(ra);
4568 __ nop();
4569
4570 CodeDesc desc;
4571 assm.GetCode(&desc);
4572 Handle<Code> code = isolate->factory()->NewCode(
4573 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
4574
4575 F2 f = FUNCTION_CAST<F2>(code->entry());
4576 PC = (uint64_t) f; // set program counter
4577
4578 uint64_t rs =
4579 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, imm16, 0, 0, 0, 0));
4580
4581 return rs;
4582 }
4583
4584
4585 TEST(r6_aluipc) {
4586 if (kArchVariant == kMips64r6) {
4587 CcTest::InitializeVM();
4588
4589 struct TestCaseAluipc {
4590 uint64_t rs_expected;
4591 int16_t imm16;
4592 };
4593
4594 struct TestCaseAluipc tc[] = {
4595 // rs_expected has formal arguments
4596 // rs_expected, imm16
4597 { 0x0, -32768 }, // 0x8000
4598 { 0x0, -1 }, // 0xFFFF
4599 { 0x0, 0 },
4600 { 0x0, 1 },
4601 { 0x0, 32767 }, // 0x7FFF
4602 };
4603
4604 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc);
4605 for (size_t i = 0; i < nr_test_cases; ++i) {
4606 PC = 0;
4607 uint64_t rs = run_aluipc(tc[i].imm16);
4608 // Now, the program_counter (PC) is set
4609 uint64_t rs_expected = ~0x0FFFF & (PC + (tc[i].imm16 << 16));
4610 CHECK_EQ(rs_expected, rs);
4611 }
4612 }
4613 }
4614
4615
4616 uint64_t run_auipc(int16_t imm16) {
4617 Isolate* isolate = CcTest::i_isolate();
4618 HandleScope scope(isolate);
4619
4620 MacroAssembler assm(isolate, NULL, 0);
4621
4622 // AUIPC rs, imm16
4623 __ auipc(v0, imm16);
4624 __ jr(ra);
4625 __ nop();
4626
4627 CodeDesc desc;
4628 assm.GetCode(&desc);
4629 Handle<Code> code = isolate->factory()->NewCode(
4630 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
4631
4632 F2 f = FUNCTION_CAST<F2>(code->entry());
4633 PC = (uint64_t) f; // set program counter
4634
4635 uint64_t rs =
4636 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, imm16, 0, 0, 0, 0));
4637
4638 return rs;
4639 }
4640
4641
4642 TEST(r6_auipc) {
4643 if (kArchVariant == kMips64r6) {
4644 CcTest::InitializeVM();
4645
4646 struct TestCaseAuipc {
4647 uint64_t rs_expected;
4648 int16_t imm16;
4649 };
4650
4651 struct TestCaseAuipc tc[] = {
4652 // rs_expected has formal arguments
4653 // rs_expected, imm16
4654 { 0x0, -32768 }, // 0x8000
4655 { 0x0, -1 }, // 0xFFFF
4656 { 0x0, 0 },
4657 { 0x0, 1 },
4658 { 0x0, 32767 }, // 0x7FFF
4659 };
4660
4661 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc);
4662 for (size_t i = 0; i < nr_test_cases; ++i) {
4663 PC = 0;
4664 uint64_t rs = run_auipc(tc[i].imm16);
4665 // Now, the program_counter (PC) is set
4666 uint64_t rs_expected = PC + (tc[i].imm16 << 16);
4667 CHECK_EQ(rs_expected, rs);
4668 }
4669 }
4670 }
4671
4672
4673 uint64_t run_lwpc(int rs, int offset) {
4674 Isolate* isolate = CcTest::i_isolate();
4675 HandleScope scope(isolate);
4676
4677 MacroAssembler assm(isolate, NULL, 0);
4678
4679 // 256k instructions; 2^8k
4680 // addiu t3, a4, 0xffff; (0x250fffff)
4681 // ...
4682 // addiu t0, a4, 0x0000; (0x250c0000)
4683 uint32_t addiu_start_1 = 0x25000000;
4684 for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
4685 uint32_t addiu_new = addiu_start_1 + i;
4686 __ dd(addiu_new);
4687 }
4688
4689 __ lwpc(t8, offset); // offset 0; 0xef080000 (t8 register)
4690 __ mov(v0, t8);
4691
4692 // 256k instructions; 2^8k
4693 // addiu a4, a4, 0x0000; (0x25080000)
4694 // ...
4695 // addiu a7, a4, 0xffff; (0x250bffff)
4696 uint32_t addiu_start_2 = 0x25000000;
4697 for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
4698 uint32_t addiu_new = addiu_start_2 + i;
4699 __ dd(addiu_new);
4700 }
4701
4702 __ jr(ra);
4703 __ nop();
4704
4705 CodeDesc desc;
4706 assm.GetCode(&desc);
4707 Handle<Code> code = isolate->factory()->NewCode(
4708 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
4709
4710 F2 f = FUNCTION_CAST<F2>(code->entry());
4711
4712 uint64_t res =
4713 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0));
4714
4715 return res;
4716 }
4717
4718
4719 TEST(r6_lwpc) {
4720 if (kArchVariant == kMips64r6) {
4721 CcTest::InitializeVM();
4722
4723 struct TestCaseLwpc {
4724 int rs;
4725 int offset;
4726 uint64_t expected_rs;
4727 };
4728
4729 struct TestCaseLwpc tc[] = {
4730 // rs, offset, expected_rs_value
4731 { t8.code(), -262144, 0x250fffff }, // offset 0x40000
4732 { t8.code(), -4, 0x250c0003 },
4733 { t8.code(), -1, 0x250c0000 },
4734 { t8.code(), 0, 0xffffffffef080000 },
4735 { t8.code(), 1, 0x03001025 }, // mov(v0, t8)
4736 { t8.code(), 2, 0x25080000 },
4737 { t8.code(), 4, 0x25080002 },
4738 { t8.code(), 262143, 0x250bfffd }, // offset 0x3ffff
4739 };
4740
4741 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc);
4742 for (size_t i = 0; i < nr_test_cases; ++i) {
4743 uint64_t res = run_lwpc(tc[i].rs, tc[i].offset);
4744 CHECK_EQ(tc[i].expected_rs, res);
4745 }
4746 }
4747 }
4748
4749
4750 uint64_t run_lwupc(int rs, int offset) {
4751 Isolate* isolate = CcTest::i_isolate();
4752 HandleScope scope(isolate);
4753
4754 MacroAssembler assm(isolate, NULL, 0);
4755
4756 // 256k instructions; 2^8k
4757 // addiu t3, a4, 0xffff; (0x250fffff)
4758 // ...
4759 // addiu t0, a4, 0x0000; (0x250c0000)
4760 uint32_t addiu_start_1 = 0x25000000;
4761 for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
4762 uint32_t addiu_new = addiu_start_1 + i;
4763 __ dd(addiu_new);
4764 }
4765
4766 __ lwupc(t8, offset); // offset 0; 0xef080000 (t8 register)
4767 __ mov(v0, t8);
4768
4769 // 256k instructions; 2^8k
4770 // addiu a4, a4, 0x0000; (0x25080000)
4771 // ...
4772 // addiu a7, a4, 0xffff; (0x250bffff)
4773 uint32_t addiu_start_2 = 0x25000000;
4774 for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
4775 uint32_t addiu_new = addiu_start_2 + i;
4776 __ dd(addiu_new);
4777 }
4778
4779 __ jr(ra);
4780 __ nop();
4781
4782 CodeDesc desc;
4783 assm.GetCode(&desc);
4784 Handle<Code> code = isolate->factory()->NewCode(
4785 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
4786
4787 F2 f = FUNCTION_CAST<F2>(code->entry());
4788
4789 uint64_t res =
4790 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0));
4791
4792 return res;
4793 }
4794
4795
4796 TEST(r6_lwupc) {
4797 if (kArchVariant == kMips64r6) {
4798 CcTest::InitializeVM();
4799
4800 struct TestCaseLwupc {
4801 int rs;
4802 int offset;
4803 uint64_t expected_rs;
4804 };
4805
4806 struct TestCaseLwupc tc[] = {
4807 // rs, offset, expected_rs_value
4808 { t8.code(), -262144, 0x250fffff }, // offset 0x40000
4809 { t8.code(), -4, 0x250c0003 },
4810 { t8.code(), -1, 0x250c0000 },
4811 { t8.code(), 0, 0xef100000 },
4812 { t8.code(), 1, 0x03001025 }, // mov(v0, t8)
4813 { t8.code(), 2, 0x25080000 },
4814 { t8.code(), 4, 0x25080002 },
4815 { t8.code(), 262143, 0x250bfffd }, // offset 0x3ffff
4816 };
4817
4818 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwupc);
4819 for (size_t i = 0; i < nr_test_cases; ++i) {
4820 uint64_t res = run_lwupc(tc[i].rs, tc[i].offset);
4821 CHECK_EQ(tc[i].expected_rs, res);
4822 }
4823 }
4824 }
4825
4826
4827 uint64_t run_jic(int rt, int16_t offset) {
4828 Isolate* isolate = CcTest::i_isolate();
4829 HandleScope scope(isolate);
4830
4831 MacroAssembler assm(isolate, NULL, 0);
4832
4833 Label get_program_counter, stop_execution;
4834 __ push(ra);
4835 __ li(v0, 0);
4836 __ li(t1, 0x66);
4837
4838 __ addiu(v0, v0, 0x1); // <-- offset = -32
4839 __ addiu(v0, v0, 0x2);
4840 __ addiu(v0, v0, 0x10);
4841 __ addiu(v0, v0, 0x20);
4842 __ beq(v0, t1, &stop_execution);
4843 __ nop();
4844
4845 __ bal(&get_program_counter); // t0 <- program counter
4846 __ nop();
4847 __ jic(t0, offset); // JIC rt, offset
4848
4849 __ addiu(v0, v0, 0x100);
4850 __ addiu(v0, v0, 0x200);
4851 __ addiu(v0, v0, 0x1000);
4852 __ addiu(v0, v0, 0x2000); // <--- offset = 16
4853 __ pop(ra);
4854 __ jr(ra);
4855 __ nop();
4856
4857 __ bind(&get_program_counter);
4858 __ mov(t0, ra);
4859 __ jr(ra);
4860 __ nop();
4861
4862 __ bind(&stop_execution);
4863 __ pop(ra);
4864 __ jr(ra);
4865 __ nop();
4866
4867 CodeDesc desc;
4868 assm.GetCode(&desc);
4869 Handle<Code> code = isolate->factory()->NewCode(
4870 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
4871
4872 F2 f = FUNCTION_CAST<F2>(code->entry());
4873
4874 uint64_t res =
4875 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rt, offset, 0, 0, 0));
4876
4877 return res;
4878 }
4879
4880
4881 TEST(r6_jic) {
4882 if (kArchVariant == kMips64r6) {
4883 CcTest::InitializeVM();
4884
4885 struct TestCaseJic {
4886 uint32_t rt;
4887 int16_t offset;
4888 uint32_t expected_res;
4889 };
4890
4891 struct TestCaseJic tc[] = {
4892 // rt - formal argument; will contain value of the program counter
4893 // rt offset, expected_result
4894 { 0, 16, 0x2033 },
4895 //{ 0, 0, 0x0 }, // JIC in loop
4896 { 0, 4, 0x3333 },
4897 { 0, -32, 0x66 },
4898 };
4899
4900 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic);
4901 for (size_t i = 0; i < nr_test_cases; ++i) {
4902 uint32_t res = run_jic(tc[i].rt, tc[i].offset);
4903 CHECK_EQ(tc[i].expected_res, res);
4904 }
4905 }
4906 }
4907
4908
4909 uint64_t run_beqzc(int32_t rs, int32_t offset) {
4910 Isolate* isolate = CcTest::i_isolate();
4911 HandleScope scope(isolate);
4912
4913 MacroAssembler assm(isolate, NULL, 0);
4914
4915 Label stop_execution;
4916 __ li(v0, 0);
4917 __ li(t1, 0x66);
4918
4919 __ addiu(v0, v0, 0x1); // <-- offset = -8
4920 __ addiu(v0, v0, 0x2);
4921 __ addiu(v0, v0, 0x10);
4922 __ addiu(v0, v0, 0x20);
4923 __ beq(v0, t1, &stop_execution);
4924 __ nop();
4925
4926 __ beqzc(a0, offset); // BEQZC rs, offset
4927
4928 __ addiu(v0, v0, 0x1);
4929 __ addiu(v0, v0, 0x100);
4930 __ addiu(v0, v0, 0x200);
4931 __ addiu(v0, v0, 0x1000);
4932 __ addiu(v0, v0, 0x2000); // <--- offset = 4
4933 __ jr(ra);
4934 __ nop();
4935
4936 __ bind(&stop_execution);
4937 __ jr(ra);
4938 __ nop();
4939
4940 CodeDesc desc;
4941 assm.GetCode(&desc);
4942 Handle<Code> code = isolate->factory()->NewCode(
4943 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
4944
4945 F2 f = FUNCTION_CAST<F2>(code->entry());
4946
4947 uint64_t res =
4948 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0));
4949
4950 return res;
4951 }
4952
4953
4954 TEST(r6_beqzc) {
4955 if (kArchVariant == kMips64r6) {
4956 CcTest::InitializeVM();
4957
4958 struct TestCaseBeqzc {
4959 uint32_t rs;
4960 int32_t offset;
4961 uint32_t expected_res;
4962 };
4963
4964 struct TestCaseBeqzc tc[] = {
4965 // rs, offset, expected_result
4966 { 0x0, -8, 0x66 },
4967 { 0x0, 0, 0x3334 },
4968 { 0x0, 1, 0x3333 },
4969 { 0xabc, 1, 0x3334 },
4970 { 0x0, 4, 0x2033 },
4971 };
4972
4973 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc);
4974 for (size_t i = 0; i < nr_test_cases; ++i) {
4975 uint32_t res = run_beqzc(tc[i].rs, tc[i].offset);
4976 CHECK_EQ(tc[i].expected_res, res);
4977 }
4978 }
4979 }
4980
4981
4982 uint64_t run_jialc(int rt, int16_t offset) {
4983 Isolate* isolate = CcTest::i_isolate();
4984 HandleScope scope(isolate);
4985
4986 MacroAssembler assm(isolate, NULL, 0);
4987
4988 Label main_block, get_program_counter;
4989 __ push(ra);
4990 __ li(v0, 0);
4991 __ beq(v0, v0, &main_block);
4992 __ nop();
4993
4994 // Block 1
4995 __ addiu(v0, v0, 0x1); // <-- offset = -40
4996 __ addiu(v0, v0, 0x2);
4997 __ jr(ra);
4998 __ nop();
4999
5000 // Block 2
5001 __ addiu(v0, v0, 0x10); // <-- offset = -24
5002 __ addiu(v0, v0, 0x20);
5003 __ jr(ra);
5004 __ nop();
5005
5006 // Block 3 (Main)
5007 __ bind(&main_block);
5008 __ bal(&get_program_counter); // t0 <- program counter
5009 __ nop();
5010 __ jialc(t0, offset); // JIALC rt, offset
5011 __ addiu(v0, v0, 0x4);
5012 __ pop(ra);
5013 __ jr(ra);
5014 __ nop();
5015
5016 // Block 4
5017 __ addiu(v0, v0, 0x100); // <-- offset = 20
5018 __ addiu(v0, v0, 0x200);
5019 __ jr(ra);
5020 __ nop();
5021
5022 // Block 5
5023 __ addiu(v0, v0, 0x1000); // <--- offset = 36
5024 __ addiu(v0, v0, 0x2000);
5025 __ jr(ra);
5026 __ nop();
5027
5028 __ bind(&get_program_counter);
5029 __ mov(t0, ra);
5030 __ jr(ra);
5031 __ nop();
5032
5033
5034 CodeDesc desc;
5035 assm.GetCode(&desc);
5036 Handle<Code> code = isolate->factory()->NewCode(
5037 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
5038
5039 F2 f = FUNCTION_CAST<F2>(code->entry());
5040
5041 uint64_t res =
5042 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rt, offset, 0, 0, 0));
5043
5044 return res;
5045 }
5046
5047
5048 TEST(r6_jialc) {
5049 if (kArchVariant == kMips64r6) {
5050 CcTest::InitializeVM();
5051
5052 struct TestCaseJialc {
5053 uint32_t rt;
5054 int16_t offset;
5055 uint32_t expected_res;
5056 };
5057
5058 struct TestCaseJialc tc[] = {
5059 // rt - formal argument; will contain value of the program counter
5060 // rt, offset, expected_result
5061 { 0, -40, 0x7 },
5062 { 0, -24, 0x34 },
5063 { 0, 20, 0x304 },
5064 { 0, 36, 0x3004 }
5065 };
5066
5067 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc);
5068 for (size_t i = 0; i < nr_test_cases; ++i) {
5069 uint32_t res = run_jialc(tc[i].rt, tc[i].offset);
5070 CHECK_EQ(tc[i].expected_res, res);
5071 }
5072 }
5073 }
5074
5075
5076 uint64_t run_addiupc(int32_t imm19) {
5077 Isolate* isolate = CcTest::i_isolate();
5078 HandleScope scope(isolate);
5079
5080 MacroAssembler assm(isolate, NULL, 0);
5081
5082 // ADDIUPC rs, imm19
5083 __ addiupc(v0, imm19);
5084 __ jr(ra);
5085 __ nop();
5086
5087 CodeDesc desc;
5088 assm.GetCode(&desc);
5089 Handle<Code> code = isolate->factory()->NewCode(
5090 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
5091
5092 F2 f = FUNCTION_CAST<F2>(code->entry());
5093 PC = (uint64_t) f; // set program counter
5094
5095 uint64_t rs =
5096 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, imm19, 0, 0, 0, 0));
5097
5098 return rs;
5099 }
5100
5101
5102 TEST(r6_addiupc) {
5103 if (kArchVariant == kMips64r6) {
5104 CcTest::InitializeVM();
5105
5106 struct TestCaseAddiupc {
5107 uint64_t rs_expected;
5108 int32_t imm19;
5109 };
5110
5111 struct TestCaseAddiupc tc[] = {
5112 // rs_expected - formal argument; will be calculated later
5113 // rs_expected, imm19
5114 { 0x0, -262144 }, // 0x40000
5115 { 0x0, -1 }, // 0x7FFFF
5116 { 0x0, 0 },
5117 { 0x0, 1 }, // 0x00001
5118 { 0x0, 262143 } // 0x3FFFF
5119 };
5120
5121 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc);
5122 for (size_t i = 0; i < nr_test_cases; ++i) {
5123 PC = 0;
5124 uint64_t rs = run_addiupc(tc[i].imm19);
5125 // Now, the program_counter (PC) is set
5126 uint64_t rs_expected = PC + (tc[i].imm19 << 2);
5127 CHECK_EQ(rs_expected, rs);
5128 }
5129 }
5130 }
5131
5132
5133 uint64_t run_ldpc(int rs, int offset) {
5134 Isolate* isolate = CcTest::i_isolate();
5135 HandleScope scope(isolate);
5136
5137 MacroAssembler assm(isolate, NULL, 0);
5138
5139 // 256k instructions; 2 * 2^7k = 2^8k
5140 // addiu t3, a4, 0xffff; (0x250fffff)
5141 // ...
5142 // addiu t0, a4, 0x0000; (0x250c0000)
5143 uint32_t addiu_start_1 = 0x25000000;
5144 for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
5145 uint32_t addiu_new = addiu_start_1 + i;
5146 __ dd(addiu_new);
5147 }
5148
5149 __ ldpc(t8, offset); // offset 0; 0xef080000 (t8 register)
5150 __ mov(v0, t8);
5151
5152 // 256k instructions; 2 * 2^7k = 2^8k
5153 // addiu a4, a4, 0x0000; (0x25080000)
5154 // ...
5155 // addiu a7, a4, 0xffff; (0x250bffff)
5156 uint32_t addiu_start_2 = 0x25000000;
5157 for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
5158 uint32_t addiu_new = addiu_start_2 + i;
5159 __ dd(addiu_new);
5160 }
5161
5162 __ jr(ra);
5163 __ nop();
5164
5165 CodeDesc desc;
5166 assm.GetCode(&desc);
5167 Handle<Code> code = isolate->factory()->NewCode(
5168 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
5169
5170 F2 f = FUNCTION_CAST<F2>(code->entry());
5171
5172 uint64_t res =
5173 reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs, offset, 0, 0, 0));
5174
5175 return res;
5176 }
5177
5178
5179 TEST(r6_ldpc) {
5180 if (kArchVariant == kMips64r6) {
5181 CcTest::InitializeVM();
5182
5183 struct TestCaseLdpc {
5184 int rs;
5185 int offset;
5186 uint64_t expected_rs;
5187 };
5188
5189 struct TestCaseLdpc tc[] = {
5190 // rs, offset, expected_rs_value
5191 { t8.code(), -131072, 0x250ffffe250fffff },
5192 { t8.code(), -4, 0x250c0006250c0007 },
5193 { t8.code(), -1, 0x250c0000250c0001 },
5194 { t8.code(), 0, 0x03001025ef180000 },
5195 { t8.code(), 1, 0x2508000125080000 },
5196 { t8.code(), 4, 0x2508000725080006 },
5197 { t8.code(), 131071, 0x250bfffd250bfffc },
5198 };
5199
5200 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLdpc);
5201 for (size_t i = 0; i < nr_test_cases; ++i) {
5202 uint64_t res = run_ldpc(tc[i].rs, tc[i].offset);
5203 CHECK_EQ(tc[i].expected_rs, res);
5204 }
5205 }
5206 }
5207
5208
5209 int64_t run_bc(int32_t offset) {
5210 Isolate* isolate = CcTest::i_isolate();
5211 HandleScope scope(isolate);
5212
5213 MacroAssembler assm(isolate, NULL, 0);
5214
5215 Label continue_1, stop_execution;
5216 __ push(ra);
5217 __ li(v0, 0);
5218 __ li(t8, 0);
5219 __ li(t9, 2); // condition for the stopping execution
5220
5221 uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
5222 for (int32_t i = -100; i <= -11; ++i) {
5223 __ dd(instruction_addiu);
5224 }
5225
5226 __ addiu(t8, t8, 1); // -10
5227
5228 __ beq(t8, t9, &stop_execution); // -9
5229 __ nop(); // -8
5230 __ beq(t8, t8, &continue_1); // -7
5231 __ nop(); // -6
5232
5233 __ bind(&stop_execution);
5234 __ pop(ra); // -5, -4
5235 __ jr(ra); // -3
5236 __ nop(); // -2
5237
5238 __ bind(&continue_1);
5239 __ bc(offset); // -1
5240
5241 for (int32_t i = 0; i <= 99; ++i) {
5242 __ dd(instruction_addiu);
5243 }
5244
5245 __ pop(ra);
5246 __ jr(ra);
5247 __ nop();
5248
5249 CodeDesc desc;
5250 assm.GetCode(&desc);
5251 Handle<Code> code = isolate->factory()->NewCode(
5252 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
5253
5254 F2 f = FUNCTION_CAST<F2>(code->entry());
5255
5256 int64_t res =
5257 reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, offset, 0, 0, 0, 0));
5258
5259 return res;
5260 }
5261
5262
5263 TEST(r6_bc) {
5264 if (kArchVariant == kMips64r6) {
5265 CcTest::InitializeVM();
5266
5267 struct TestCaseBc {
5268 int32_t offset;
5269 int64_t expected_res;
5270 };
5271
5272 struct TestCaseBc tc[] = {
5273 // offset, expected_result
5274 { -100, (abs(-100) - 10) * 2 },
5275 { -11, (abs(-100) - 10 + 1) },
5276 { 0, (abs(-100) - 10 + 1 + 99) },
5277 { 1, (abs(-100) - 10 + 99) },
5278 { 99, (abs(-100) - 10 + 1) },
5279 };
5280
5281 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc);
5282 for (size_t i = 0; i < nr_test_cases; ++i) {
5283 int64_t res = run_bc(tc[i].offset);
5284 CHECK_EQ(tc[i].expected_res, res);
5285 }
5286 }
5287 }
5288
5289
5290 int64_t run_balc(int32_t offset) {
5291 Isolate* isolate = CcTest::i_isolate();
5292 HandleScope scope(isolate);
5293
5294 MacroAssembler assm(isolate, NULL, 0);
5295
5296 Label continue_1, stop_execution;
5297 __ push(ra);
5298 __ li(v0, 0);
5299 __ li(t8, 0);
5300 __ li(t9, 2); // condition for stopping execution
5301
5302 __ beq(t8, t8, &continue_1);
5303 __ nop();
5304
5305 uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
5306 for (int32_t i = -117; i <= -57; ++i) {
5307 __ dd(instruction_addiu);
5308 }
5309 __ jr(ra); // -56
5310 __ nop(); // -55
5311
5312 for (int32_t i = -54; i <= -4; ++i) {
5313 __ dd(instruction_addiu);
5314 }
5315 __ jr(ra); // -3
5316 __ nop(); // -2
5317
5318 __ bind(&continue_1);
5319 __ balc(offset); // -1
5320
5321 __ pop(ra); // 0, 1
5322 __ jr(ra); // 2
5323 __ nop(); // 3
5324
5325 for (int32_t i = 4; i <= 44; ++i) {
5326 __ dd(instruction_addiu);
5327 }
5328 __ jr(ra);
5329 __ nop();
5330
5331 CodeDesc desc;
5332 assm.GetCode(&desc);
5333 Handle<Code> code = isolate->factory()->NewCode(
5334 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
5335
5336 F2 f = FUNCTION_CAST<F2>(code->entry());
5337
5338 int64_t res =
5339 reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, offset, 0, 0, 0, 0));
5340
5341 return res;
5342 }
5343
5344
5345 TEST(r6_balc) {
5346 if (kArchVariant == kMips64r6) {
5347 CcTest::InitializeVM();
5348
5349 struct TestCaseBalc {
5350 int32_t offset;
5351 int64_t expected_res;
5352 };
5353
5354 struct TestCaseBalc tc[] = {
5355 // offset, expected_result
5356 { -117, 61 },
5357 { -54, 51 },
5358 { 0, 0 },
5359 { 4, 41 },
5360 };
5361
5362 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc);
5363 for (size_t i = 0; i < nr_test_cases; ++i) {
5364 int64_t res = run_balc(tc[i].offset);
5365 CHECK_EQ(tc[i].expected_res, res);
5366 }
5367 }
5368 }
5369
5370
4449 #undef __ 5371 #undef __
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698