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

Side by Side Diff: src/mips64/macro-assembler-mips64.cc

Issue 1170923004: Reland "MIPS64: Fix lithium arithmetic operations for integers to sign-extend result." (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Include fix of removed EmitLoadRegister unsafe usage. 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 | « src/mips64/macro-assembler-mips64.h ('k') | no next file » | 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 // 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
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
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
OLDNEW
« no previous file with comments | « src/mips64/macro-assembler-mips64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698