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

Side by Side Diff: test/cctest/test-assembler-mips.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
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 4244 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 __
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698