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