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

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

Powered by Google App Engine
This is Rietveld 408576698