OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
10 | 10 |
(...skipping 4429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4440 Branch(not_number, eq, exponent, Operand(mask_reg)); | 4440 Branch(not_number, eq, exponent, Operand(mask_reg)); |
4441 } | 4441 } |
4442 ldc1(result, FieldMemOperand(object, HeapNumber::kValueOffset)); | 4442 ldc1(result, FieldMemOperand(object, HeapNumber::kValueOffset)); |
4443 bind(&done); | 4443 bind(&done); |
4444 } | 4444 } |
4445 | 4445 |
4446 | 4446 |
4447 void MacroAssembler::SmiToDoubleFPURegister(Register smi, | 4447 void MacroAssembler::SmiToDoubleFPURegister(Register smi, |
4448 FPURegister value, | 4448 FPURegister value, |
4449 Register scratch1) { | 4449 Register scratch1) { |
4450 // dsra(scratch1, smi, kSmiTagSize); | |
4451 dsra32(scratch1, smi, 0); | 4450 dsra32(scratch1, smi, 0); |
4452 mtc1(scratch1, value); | 4451 mtc1(scratch1, value); |
4453 cvt_d_w(value, value); | 4452 cvt_d_w(value, value); |
4454 } | 4453 } |
4455 | 4454 |
4456 | 4455 |
4457 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, | 4456 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, |
4458 const Operand& right, | 4457 const Operand& right, |
4459 Register overflow_dst, | 4458 Register overflow_dst, |
4460 Register scratch) { | 4459 Register scratch) { |
4461 if (right.is_reg()) { | 4460 if (right.is_reg()) { |
4462 AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | 4461 AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); |
4463 } else { | 4462 } else { |
4464 if (dst.is(left)) { | 4463 if (dst.is(left)) { |
| 4464 li(t9, right); // Load right. |
4465 mov(scratch, left); // Preserve left. | 4465 mov(scratch, left); // Preserve left. |
4466 daddiu(dst, left, | 4466 addu(dst, left, t9); // Left is overwritten. |
4467 static_cast<int32_t>(right.immediate())); // Left is overwritten. | |
4468 xor_(scratch, dst, scratch); // Original left. | 4467 xor_(scratch, dst, scratch); // Original left. |
4469 // Load right since xori takes uint16 as immediate. | |
4470 daddiu(t9, zero_reg, static_cast<int32_t>(right.immediate())); | |
4471 xor_(overflow_dst, dst, t9); | 4468 xor_(overflow_dst, dst, t9); |
4472 and_(overflow_dst, overflow_dst, scratch); | 4469 and_(overflow_dst, overflow_dst, scratch); |
4473 } else { | 4470 } else { |
4474 daddiu(dst, left, static_cast<int32_t>(right.immediate())); | 4471 li(t9, right); |
| 4472 addu(dst, left, t9); |
4475 xor_(overflow_dst, dst, left); | 4473 xor_(overflow_dst, dst, left); |
4476 // Load right since xori takes uint16 as immediate. | |
4477 daddiu(t9, zero_reg, static_cast<int32_t>(right.immediate())); | |
4478 xor_(scratch, dst, t9); | 4474 xor_(scratch, dst, t9); |
4479 and_(overflow_dst, scratch, overflow_dst); | 4475 and_(overflow_dst, scratch, overflow_dst); |
4480 } | 4476 } |
4481 } | 4477 } |
4482 } | 4478 } |
4483 | 4479 |
4484 | 4480 |
4485 void MacroAssembler::AdduAndCheckForOverflow(Register dst, | 4481 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, |
4486 Register left, | |
4487 Register right, | 4482 Register right, |
4488 Register overflow_dst, | 4483 Register overflow_dst, |
4489 Register scratch) { | 4484 Register scratch) { |
4490 DCHECK(!dst.is(overflow_dst)); | 4485 DCHECK(!dst.is(overflow_dst)); |
4491 DCHECK(!dst.is(scratch)); | 4486 DCHECK(!dst.is(scratch)); |
4492 DCHECK(!overflow_dst.is(scratch)); | 4487 DCHECK(!overflow_dst.is(scratch)); |
4493 DCHECK(!overflow_dst.is(left)); | 4488 DCHECK(!overflow_dst.is(left)); |
4494 DCHECK(!overflow_dst.is(right)); | 4489 DCHECK(!overflow_dst.is(right)); |
4495 | 4490 |
4496 if (left.is(right) && dst.is(left)) { | 4491 if (left.is(right) && dst.is(left)) { |
4497 DCHECK(!dst.is(t9)); | 4492 DCHECK(!dst.is(t9)); |
4498 DCHECK(!scratch.is(t9)); | 4493 DCHECK(!scratch.is(t9)); |
4499 DCHECK(!left.is(t9)); | 4494 DCHECK(!left.is(t9)); |
4500 DCHECK(!right.is(t9)); | 4495 DCHECK(!right.is(t9)); |
4501 DCHECK(!overflow_dst.is(t9)); | 4496 DCHECK(!overflow_dst.is(t9)); |
4502 mov(t9, right); | 4497 mov(t9, right); |
4503 right = t9; | 4498 right = t9; |
4504 } | 4499 } |
4505 | 4500 |
4506 if (dst.is(left)) { | 4501 if (dst.is(left)) { |
| 4502 mov(scratch, left); // Preserve left. |
| 4503 addu(dst, left, right); // Left is overwritten. |
| 4504 xor_(scratch, dst, scratch); // Original left. |
| 4505 xor_(overflow_dst, dst, right); |
| 4506 and_(overflow_dst, overflow_dst, scratch); |
| 4507 } else if (dst.is(right)) { |
| 4508 mov(scratch, right); // Preserve right. |
| 4509 addu(dst, left, right); // Right is overwritten. |
| 4510 xor_(scratch, dst, scratch); // Original right. |
| 4511 xor_(overflow_dst, dst, left); |
| 4512 and_(overflow_dst, overflow_dst, scratch); |
| 4513 } else { |
| 4514 addu(dst, left, right); |
| 4515 xor_(overflow_dst, dst, left); |
| 4516 xor_(scratch, dst, right); |
| 4517 and_(overflow_dst, scratch, overflow_dst); |
| 4518 } |
| 4519 } |
| 4520 |
| 4521 |
| 4522 void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left, |
| 4523 const Operand& right, |
| 4524 Register overflow_dst, |
| 4525 Register scratch) { |
| 4526 if (right.is_reg()) { |
| 4527 DadduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); |
| 4528 } else { |
| 4529 if (dst.is(left)) { |
| 4530 li(t9, right); // Load right. |
| 4531 mov(scratch, left); // Preserve left. |
| 4532 daddu(dst, left, t9); // Left is overwritten. |
| 4533 xor_(scratch, dst, scratch); // Original left. |
| 4534 xor_(overflow_dst, dst, t9); |
| 4535 and_(overflow_dst, overflow_dst, scratch); |
| 4536 } else { |
| 4537 li(t9, right); // Load right. |
| 4538 Daddu(dst, left, t9); |
| 4539 xor_(overflow_dst, dst, left); |
| 4540 xor_(scratch, dst, t9); |
| 4541 and_(overflow_dst, scratch, overflow_dst); |
| 4542 } |
| 4543 } |
| 4544 } |
| 4545 |
| 4546 |
| 4547 void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left, |
| 4548 Register right, |
| 4549 Register overflow_dst, |
| 4550 Register scratch) { |
| 4551 DCHECK(!dst.is(overflow_dst)); |
| 4552 DCHECK(!dst.is(scratch)); |
| 4553 DCHECK(!overflow_dst.is(scratch)); |
| 4554 DCHECK(!overflow_dst.is(left)); |
| 4555 DCHECK(!overflow_dst.is(right)); |
| 4556 |
| 4557 if (left.is(right) && dst.is(left)) { |
| 4558 DCHECK(!dst.is(t9)); |
| 4559 DCHECK(!scratch.is(t9)); |
| 4560 DCHECK(!left.is(t9)); |
| 4561 DCHECK(!right.is(t9)); |
| 4562 DCHECK(!overflow_dst.is(t9)); |
| 4563 mov(t9, right); |
| 4564 right = t9; |
| 4565 } |
| 4566 |
| 4567 if (dst.is(left)) { |
4507 mov(scratch, left); // Preserve left. | 4568 mov(scratch, left); // Preserve left. |
4508 daddu(dst, left, right); // Left is overwritten. | 4569 daddu(dst, left, right); // Left is overwritten. |
4509 xor_(scratch, dst, scratch); // Original left. | 4570 xor_(scratch, dst, scratch); // Original left. |
4510 xor_(overflow_dst, dst, right); | 4571 xor_(overflow_dst, dst, right); |
4511 and_(overflow_dst, overflow_dst, scratch); | 4572 and_(overflow_dst, overflow_dst, scratch); |
4512 } else if (dst.is(right)) { | 4573 } else if (dst.is(right)) { |
4513 mov(scratch, right); // Preserve right. | 4574 mov(scratch, right); // Preserve right. |
4514 daddu(dst, left, right); // Right is overwritten. | 4575 daddu(dst, left, right); // Right is overwritten. |
4515 xor_(scratch, dst, scratch); // Original right. | 4576 xor_(scratch, dst, scratch); // Original right. |
4516 xor_(overflow_dst, dst, left); | 4577 xor_(overflow_dst, dst, left); |
4517 and_(overflow_dst, overflow_dst, scratch); | 4578 and_(overflow_dst, overflow_dst, scratch); |
4518 } else { | 4579 } else { |
4519 daddu(dst, left, right); | 4580 daddu(dst, left, right); |
4520 xor_(overflow_dst, dst, left); | 4581 xor_(overflow_dst, dst, left); |
4521 xor_(scratch, dst, right); | 4582 xor_(scratch, dst, right); |
4522 and_(overflow_dst, scratch, overflow_dst); | 4583 and_(overflow_dst, scratch, overflow_dst); |
4523 } | 4584 } |
4524 } | 4585 } |
4525 | 4586 |
4526 | 4587 |
4527 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, | 4588 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, |
4528 const Operand& right, | 4589 const Operand& right, |
4529 Register overflow_dst, | 4590 Register overflow_dst, |
4530 Register scratch) { | 4591 Register scratch) { |
4531 if (right.is_reg()) { | 4592 if (right.is_reg()) { |
4532 SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | 4593 SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); |
4533 } else { | 4594 } else { |
4534 if (dst.is(left)) { | 4595 if (dst.is(left)) { |
| 4596 li(t9, right); // Load right. |
4535 mov(scratch, left); // Preserve left. | 4597 mov(scratch, left); // Preserve left. |
4536 daddiu(dst, left, | 4598 Subu(dst, left, t9); // Left is overwritten. |
4537 static_cast<int32_t>(-right.immediate())); // Left is overwritten. | |
4538 xor_(overflow_dst, dst, scratch); // scratch is original left. | 4599 xor_(overflow_dst, dst, scratch); // scratch is original left. |
4539 // Load right since xori takes uint16 as immediate. | |
4540 daddiu(t9, zero_reg, static_cast<int32_t>(right.immediate())); | |
4541 xor_(scratch, scratch, t9); // scratch is original left. | 4600 xor_(scratch, scratch, t9); // scratch is original left. |
4542 and_(overflow_dst, scratch, overflow_dst); | 4601 and_(overflow_dst, scratch, overflow_dst); |
4543 } else { | 4602 } else { |
4544 daddiu(dst, left, static_cast<int32_t>(-right.immediate())); | 4603 li(t9, right); |
| 4604 subu(dst, left, t9); |
4545 xor_(overflow_dst, dst, left); | 4605 xor_(overflow_dst, dst, left); |
4546 // Load right since xori takes uint16 as immediate. | |
4547 daddiu(t9, zero_reg, static_cast<int32_t>(right.immediate())); | |
4548 xor_(scratch, left, t9); | 4606 xor_(scratch, left, t9); |
4549 and_(overflow_dst, scratch, overflow_dst); | 4607 and_(overflow_dst, scratch, overflow_dst); |
4550 } | 4608 } |
4551 } | 4609 } |
4552 } | 4610 } |
4553 | 4611 |
4554 | 4612 |
4555 void MacroAssembler::SubuAndCheckForOverflow(Register dst, | 4613 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, |
4556 Register left, | |
4557 Register right, | 4614 Register right, |
4558 Register overflow_dst, | 4615 Register overflow_dst, |
4559 Register scratch) { | 4616 Register scratch) { |
4560 DCHECK(!dst.is(overflow_dst)); | 4617 DCHECK(!dst.is(overflow_dst)); |
4561 DCHECK(!dst.is(scratch)); | 4618 DCHECK(!dst.is(scratch)); |
4562 DCHECK(!overflow_dst.is(scratch)); | 4619 DCHECK(!overflow_dst.is(scratch)); |
4563 DCHECK(!overflow_dst.is(left)); | 4620 DCHECK(!overflow_dst.is(left)); |
4564 DCHECK(!overflow_dst.is(right)); | 4621 DCHECK(!overflow_dst.is(right)); |
4565 DCHECK(!scratch.is(left)); | 4622 DCHECK(!scratch.is(left)); |
4566 DCHECK(!scratch.is(right)); | 4623 DCHECK(!scratch.is(right)); |
4567 | 4624 |
4568 // This happens with some crankshaft code. Since Subu works fine if | 4625 // This happens with some crankshaft code. Since Subu works fine if |
4569 // left == right, let's not make that restriction here. | 4626 // left == right, let's not make that restriction here. |
4570 if (left.is(right)) { | 4627 if (left.is(right)) { |
4571 mov(dst, zero_reg); | 4628 mov(dst, zero_reg); |
4572 mov(overflow_dst, zero_reg); | 4629 mov(overflow_dst, zero_reg); |
4573 return; | 4630 return; |
4574 } | 4631 } |
4575 | 4632 |
4576 if (dst.is(left)) { | 4633 if (dst.is(left)) { |
| 4634 mov(scratch, left); // Preserve left. |
| 4635 subu(dst, left, right); // Left is overwritten. |
| 4636 xor_(overflow_dst, dst, scratch); // scratch is original left. |
| 4637 xor_(scratch, scratch, right); // scratch is original left. |
| 4638 and_(overflow_dst, scratch, overflow_dst); |
| 4639 } else if (dst.is(right)) { |
| 4640 mov(scratch, right); // Preserve right. |
| 4641 subu(dst, left, right); // Right is overwritten. |
| 4642 xor_(overflow_dst, dst, left); |
| 4643 xor_(scratch, left, scratch); // Original right. |
| 4644 and_(overflow_dst, scratch, overflow_dst); |
| 4645 } else { |
| 4646 subu(dst, left, right); |
| 4647 xor_(overflow_dst, dst, left); |
| 4648 xor_(scratch, left, right); |
| 4649 and_(overflow_dst, scratch, overflow_dst); |
| 4650 } |
| 4651 } |
| 4652 |
| 4653 |
| 4654 void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left, |
| 4655 const Operand& right, |
| 4656 Register overflow_dst, |
| 4657 Register scratch) { |
| 4658 if (right.is_reg()) { |
| 4659 DsubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); |
| 4660 } else { |
| 4661 if (dst.is(left)) { |
| 4662 li(t9, right); // Load right. |
| 4663 mov(scratch, left); // Preserve left. |
| 4664 dsubu(dst, left, t9); // Left is overwritten. |
| 4665 xor_(overflow_dst, dst, scratch); // scratch is original left. |
| 4666 xor_(scratch, scratch, t9); // scratch is original left. |
| 4667 and_(overflow_dst, scratch, overflow_dst); |
| 4668 } else { |
| 4669 li(t9, right); |
| 4670 dsubu(dst, left, t9); |
| 4671 xor_(overflow_dst, dst, left); |
| 4672 xor_(scratch, left, t9); |
| 4673 and_(overflow_dst, scratch, overflow_dst); |
| 4674 } |
| 4675 } |
| 4676 } |
| 4677 |
| 4678 |
| 4679 void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left, |
| 4680 Register right, |
| 4681 Register overflow_dst, |
| 4682 Register scratch) { |
| 4683 DCHECK(!dst.is(overflow_dst)); |
| 4684 DCHECK(!dst.is(scratch)); |
| 4685 DCHECK(!overflow_dst.is(scratch)); |
| 4686 DCHECK(!overflow_dst.is(left)); |
| 4687 DCHECK(!overflow_dst.is(right)); |
| 4688 DCHECK(!scratch.is(left)); |
| 4689 DCHECK(!scratch.is(right)); |
| 4690 |
| 4691 // This happens with some crankshaft code. Since Subu works fine if |
| 4692 // left == right, let's not make that restriction here. |
| 4693 if (left.is(right)) { |
| 4694 mov(dst, zero_reg); |
| 4695 mov(overflow_dst, zero_reg); |
| 4696 return; |
| 4697 } |
| 4698 |
| 4699 if (dst.is(left)) { |
4577 mov(scratch, left); // Preserve left. | 4700 mov(scratch, left); // Preserve left. |
4578 dsubu(dst, left, right); // Left is overwritten. | 4701 dsubu(dst, left, right); // Left is overwritten. |
4579 xor_(overflow_dst, dst, scratch); // scratch is original left. | 4702 xor_(overflow_dst, dst, scratch); // scratch is original left. |
4580 xor_(scratch, scratch, right); // scratch is original left. | 4703 xor_(scratch, scratch, right); // scratch is original left. |
4581 and_(overflow_dst, scratch, overflow_dst); | 4704 and_(overflow_dst, scratch, overflow_dst); |
4582 } else if (dst.is(right)) { | 4705 } else if (dst.is(right)) { |
4583 mov(scratch, right); // Preserve right. | 4706 mov(scratch, right); // Preserve right. |
4584 dsubu(dst, left, right); // Right is overwritten. | 4707 dsubu(dst, left, right); // Right is overwritten. |
4585 xor_(overflow_dst, dst, left); | 4708 xor_(overflow_dst, dst, left); |
4586 xor_(scratch, left, scratch); // Original right. | 4709 xor_(scratch, left, scratch); // Original right. |
4587 and_(overflow_dst, scratch, overflow_dst); | 4710 and_(overflow_dst, scratch, overflow_dst); |
4588 } else { | 4711 } else { |
4589 dsubu(dst, left, right); | 4712 dsubu(dst, left, right); |
4590 xor_(overflow_dst, dst, left); | 4713 xor_(overflow_dst, dst, left); |
4591 xor_(scratch, left, right); | 4714 xor_(scratch, left, right); |
4592 and_(overflow_dst, scratch, overflow_dst); | 4715 and_(overflow_dst, scratch, overflow_dst); |
4593 } | 4716 } |
4594 } | 4717 } |
4595 | 4718 |
4596 | |
4597 void MacroAssembler::CallRuntime(const Runtime::Function* f, | 4719 void MacroAssembler::CallRuntime(const Runtime::Function* f, |
4598 int num_arguments, | 4720 int num_arguments, |
4599 SaveFPRegsMode save_doubles) { | 4721 SaveFPRegsMode save_doubles) { |
4600 // All parameters are on the stack. v0 has the return value after call. | 4722 // All parameters are on the stack. v0 has the return value after call. |
4601 | 4723 |
4602 // If the expected number of arguments of the runtime function is | 4724 // If the expected number of arguments of the runtime function is |
4603 // constant, we check that the actual number of arguments match the | 4725 // constant, we check that the actual number of arguments match the |
4604 // expectation. | 4726 // expectation. |
4605 CHECK(f->nargs < 0 || f->nargs == num_arguments); | 4727 CHECK(f->nargs < 0 || f->nargs == num_arguments); |
4606 | 4728 |
(...skipping 1627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6234 if (mag.shift > 0) sra(result, result, mag.shift); | 6356 if (mag.shift > 0) sra(result, result, mag.shift); |
6235 srl(at, dividend, 31); | 6357 srl(at, dividend, 31); |
6236 Addu(result, result, Operand(at)); | 6358 Addu(result, result, Operand(at)); |
6237 } | 6359 } |
6238 | 6360 |
6239 | 6361 |
6240 } // namespace internal | 6362 } // namespace internal |
6241 } // namespace v8 | 6363 } // namespace v8 |
6242 | 6364 |
6243 #endif // V8_TARGET_ARCH_MIPS64 | 6365 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |