OLD | NEW |
1 | 1 |
2 // Copyright 2012 the V8 project authors. All rights reserved. | 2 // Copyright 2012 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 4288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4299 | 4299 |
4300 void MacroAssembler::SmiToDoubleFPURegister(Register smi, | 4300 void MacroAssembler::SmiToDoubleFPURegister(Register smi, |
4301 FPURegister value, | 4301 FPURegister value, |
4302 Register scratch1) { | 4302 Register scratch1) { |
4303 sra(scratch1, smi, kSmiTagSize); | 4303 sra(scratch1, smi, kSmiTagSize); |
4304 mtc1(scratch1, value); | 4304 mtc1(scratch1, value); |
4305 cvt_d_w(value, value); | 4305 cvt_d_w(value, value); |
4306 } | 4306 } |
4307 | 4307 |
4308 | 4308 |
4309 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, | 4309 static inline void BranchOvfHelper(MacroAssembler* masm, Register overflow_dst, |
4310 const Operand& right, | 4310 Label* overflow_label, |
4311 Register overflow_dst, | 4311 Label* no_overflow_label) { |
4312 Register scratch) { | 4312 DCHECK(overflow_label || no_overflow_label); |
| 4313 if (!overflow_label) { |
| 4314 DCHECK(no_overflow_label); |
| 4315 masm->Branch(no_overflow_label, ge, overflow_dst, Operand(zero_reg)); |
| 4316 } else { |
| 4317 masm->Branch(overflow_label, lt, overflow_dst, Operand(zero_reg)); |
| 4318 if (no_overflow_label) masm->Branch(no_overflow_label); |
| 4319 } |
| 4320 } |
| 4321 |
| 4322 |
| 4323 void MacroAssembler::AddBranchOvf(Register dst, Register left, |
| 4324 const Operand& right, Label* overflow_label, |
| 4325 Label* no_overflow_label, Register scratch) { |
4313 if (right.is_reg()) { | 4326 if (right.is_reg()) { |
4314 AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | 4327 AddBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 4328 scratch); |
4315 } else { | 4329 } else { |
4316 if (dst.is(left)) { | 4330 if (IsMipsArchVariant(kMips32r6)) { |
4317 mov(scratch, left); // Preserve left. | 4331 Register right_reg = t9; |
4318 Addu(dst, left, right.immediate()); // Left is overwritten. | 4332 DCHECK(!left.is(right_reg)); |
4319 xor_(scratch, dst, scratch); // Original left. | 4333 li(right_reg, Operand(right)); |
4320 // Load right since xori takes uint16 as immediate. | 4334 AddBranchOvf(dst, left, right_reg, overflow_label, no_overflow_label); |
4321 Addu(t9, zero_reg, right); | |
4322 xor_(overflow_dst, dst, t9); | |
4323 and_(overflow_dst, overflow_dst, scratch); | |
4324 } else { | 4335 } else { |
4325 Addu(dst, left, right.immediate()); | 4336 Register overflow_dst = t9; |
4326 xor_(overflow_dst, dst, left); | 4337 DCHECK(!dst.is(scratch)); |
4327 // Load right since xori takes uint16 as immediate. | 4338 DCHECK(!dst.is(overflow_dst)); |
4328 Addu(t9, zero_reg, right); | 4339 DCHECK(!scratch.is(overflow_dst)); |
4329 xor_(scratch, dst, t9); | 4340 DCHECK(!left.is(overflow_dst)); |
4330 and_(overflow_dst, scratch, overflow_dst); | 4341 if (dst.is(left)) { |
| 4342 mov(scratch, left); // Preserve left. |
| 4343 Addu(dst, left, right.immediate()); // Left is overwritten. |
| 4344 xor_(scratch, dst, scratch); // Original left. |
| 4345 // Load right since xori takes uint16 as immediate. |
| 4346 Addu(overflow_dst, zero_reg, right); |
| 4347 xor_(overflow_dst, dst, overflow_dst); |
| 4348 and_(overflow_dst, overflow_dst, scratch); |
| 4349 } else { |
| 4350 Addu(dst, left, right.immediate()); |
| 4351 xor_(overflow_dst, dst, left); |
| 4352 // Load right since xori takes uint16 as immediate. |
| 4353 Addu(scratch, zero_reg, right); |
| 4354 xor_(scratch, dst, scratch); |
| 4355 and_(overflow_dst, scratch, overflow_dst); |
| 4356 } |
| 4357 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
4331 } | 4358 } |
4332 } | 4359 } |
4333 } | 4360 } |
4334 | 4361 |
4335 | 4362 |
4336 void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left, | 4363 void MacroAssembler::AddBranchOvf(Register dst, Register left, Register right, |
4337 Register right, | 4364 Label* overflow_label, |
4338 Register overflow_dst, | 4365 Label* no_overflow_label, Register scratch) { |
4339 Register scratch) { | 4366 if (IsMipsArchVariant(kMips32r6)) { |
4340 DCHECK(!dst.is(overflow_dst)); | 4367 if (!overflow_label) { |
4341 DCHECK(!dst.is(scratch)); | 4368 DCHECK(no_overflow_label); |
4342 DCHECK(!overflow_dst.is(scratch)); | 4369 DCHECK(!dst.is(scratch)); |
4343 DCHECK(!overflow_dst.is(left)); | 4370 Register left_reg = left.is(dst) ? scratch : left; |
4344 DCHECK(!overflow_dst.is(right)); | 4371 Register right_reg = right.is(dst) ? t9 : right; |
| 4372 DCHECK(!dst.is(left_reg)); |
| 4373 DCHECK(!dst.is(right_reg)); |
| 4374 Move(left_reg, left); |
| 4375 Move(right_reg, right); |
| 4376 addu(dst, left, right); |
| 4377 bnvc(left_reg, right_reg, no_overflow_label); |
| 4378 } else { |
| 4379 bovc(left, right, overflow_label); |
| 4380 addu(dst, left, right); |
| 4381 if (no_overflow_label) bc(no_overflow_label); |
| 4382 } |
| 4383 } else { |
| 4384 Register overflow_dst = t9; |
| 4385 DCHECK(!dst.is(scratch)); |
| 4386 DCHECK(!dst.is(overflow_dst)); |
| 4387 DCHECK(!scratch.is(overflow_dst)); |
| 4388 DCHECK(!left.is(overflow_dst)); |
| 4389 DCHECK(!right.is(overflow_dst)); |
| 4390 DCHECK(!left.is(scratch)); |
| 4391 DCHECK(!right.is(scratch)); |
4345 | 4392 |
4346 if (left.is(right) && dst.is(left)) { | 4393 if (left.is(right) && dst.is(left)) { |
4347 DCHECK(!dst.is(t9)); | 4394 mov(overflow_dst, right); |
4348 DCHECK(!scratch.is(t9)); | 4395 right = overflow_dst; |
4349 DCHECK(!left.is(t9)); | 4396 } |
4350 DCHECK(!right.is(t9)); | |
4351 DCHECK(!overflow_dst.is(t9)); | |
4352 mov(t9, right); | |
4353 right = t9; | |
4354 } | |
4355 | 4397 |
4356 if (dst.is(left)) { | 4398 if (dst.is(left)) { |
4357 mov(scratch, left); // Preserve left. | 4399 mov(scratch, left); // Preserve left. |
4358 addu(dst, left, right); // Left is overwritten. | 4400 addu(dst, left, right); // Left is overwritten. |
4359 xor_(scratch, dst, scratch); // Original left. | 4401 xor_(scratch, dst, scratch); // Original left. |
4360 xor_(overflow_dst, dst, right); | 4402 xor_(overflow_dst, dst, right); |
4361 and_(overflow_dst, overflow_dst, scratch); | 4403 and_(overflow_dst, overflow_dst, scratch); |
4362 } else if (dst.is(right)) { | 4404 } else if (dst.is(right)) { |
4363 mov(scratch, right); // Preserve right. | 4405 mov(scratch, right); // Preserve right. |
4364 addu(dst, left, right); // Right is overwritten. | 4406 addu(dst, left, right); // Right is overwritten. |
4365 xor_(scratch, dst, scratch); // Original right. | 4407 xor_(scratch, dst, scratch); // Original right. |
4366 xor_(overflow_dst, dst, left); | 4408 xor_(overflow_dst, dst, left); |
4367 and_(overflow_dst, overflow_dst, scratch); | 4409 and_(overflow_dst, overflow_dst, scratch); |
4368 } else { | 4410 } else { |
4369 addu(dst, left, right); | 4411 addu(dst, left, right); |
4370 xor_(overflow_dst, dst, left); | 4412 xor_(overflow_dst, dst, left); |
4371 xor_(scratch, dst, right); | 4413 xor_(scratch, dst, right); |
4372 and_(overflow_dst, scratch, overflow_dst); | 4414 and_(overflow_dst, scratch, overflow_dst); |
| 4415 } |
| 4416 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
4373 } | 4417 } |
4374 } | 4418 } |
4375 | 4419 |
4376 | 4420 |
4377 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, | 4421 void MacroAssembler::SubBranchOvf(Register dst, Register left, |
4378 const Operand& right, | 4422 const Operand& right, Label* overflow_label, |
4379 Register overflow_dst, | 4423 Label* no_overflow_label, Register scratch) { |
4380 Register scratch) { | 4424 DCHECK(overflow_label || no_overflow_label); |
4381 if (right.is_reg()) { | 4425 if (right.is_reg()) { |
4382 SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch); | 4426 SubBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label, |
| 4427 scratch); |
4383 } else { | 4428 } else { |
| 4429 Register overflow_dst = t9; |
| 4430 DCHECK(!dst.is(scratch)); |
| 4431 DCHECK(!dst.is(overflow_dst)); |
| 4432 DCHECK(!scratch.is(overflow_dst)); |
| 4433 DCHECK(!left.is(overflow_dst)); |
| 4434 DCHECK(!left.is(scratch)); |
4384 if (dst.is(left)) { | 4435 if (dst.is(left)) { |
4385 mov(scratch, left); // Preserve left. | 4436 mov(scratch, left); // Preserve left. |
4386 Subu(dst, left, right); // Left is overwritten. | 4437 Subu(dst, left, right.immediate()); // Left is overwritten. |
4387 xor_(overflow_dst, dst, scratch); // scratch is original left. | |
4388 // Load right since xori takes uint16 as immediate. | 4438 // Load right since xori takes uint16 as immediate. |
4389 Addu(t9, zero_reg, right); | 4439 Addu(overflow_dst, zero_reg, right); |
4390 xor_(scratch, scratch, t9); // scratch is original left. | 4440 xor_(overflow_dst, scratch, overflow_dst); // scratch is original left. |
| 4441 xor_(scratch, dst, scratch); // scratch is original left. |
4391 and_(overflow_dst, scratch, overflow_dst); | 4442 and_(overflow_dst, scratch, overflow_dst); |
4392 } else { | 4443 } else { |
4393 Subu(dst, left, right); | 4444 Subu(dst, left, right); |
4394 xor_(overflow_dst, dst, left); | 4445 xor_(overflow_dst, dst, left); |
4395 // Load right since xori takes uint16 as immediate. | 4446 // Load right since xori takes uint16 as immediate. |
4396 Addu(t9, zero_reg, right); | 4447 Addu(scratch, zero_reg, right); |
4397 xor_(scratch, left, t9); | 4448 xor_(scratch, left, scratch); |
4398 and_(overflow_dst, scratch, overflow_dst); | 4449 and_(overflow_dst, scratch, overflow_dst); |
4399 } | 4450 } |
| 4451 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
4400 } | 4452 } |
4401 } | 4453 } |
4402 | 4454 |
4403 | 4455 |
4404 void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left, | 4456 void MacroAssembler::SubBranchOvf(Register dst, Register left, Register right, |
4405 Register right, | 4457 Label* overflow_label, |
4406 Register overflow_dst, | 4458 Label* no_overflow_label, Register scratch) { |
4407 Register scratch) { | 4459 DCHECK(overflow_label || no_overflow_label); |
| 4460 Register overflow_dst = t9; |
| 4461 DCHECK(!dst.is(scratch)); |
4408 DCHECK(!dst.is(overflow_dst)); | 4462 DCHECK(!dst.is(overflow_dst)); |
4409 DCHECK(!dst.is(scratch)); | 4463 DCHECK(!scratch.is(overflow_dst)); |
4410 DCHECK(!overflow_dst.is(scratch)); | |
4411 DCHECK(!overflow_dst.is(left)); | 4464 DCHECK(!overflow_dst.is(left)); |
4412 DCHECK(!overflow_dst.is(right)); | 4465 DCHECK(!overflow_dst.is(right)); |
4413 DCHECK(!scratch.is(left)); | 4466 DCHECK(!scratch.is(left)); |
4414 DCHECK(!scratch.is(right)); | 4467 DCHECK(!scratch.is(right)); |
4415 | 4468 |
4416 // This happens with some crankshaft code. Since Subu works fine if | 4469 // This happens with some crankshaft code. Since Subu works fine if |
4417 // left == right, let's not make that restriction here. | 4470 // left == right, let's not make that restriction here. |
4418 if (left.is(right)) { | 4471 if (left.is(right)) { |
4419 mov(dst, zero_reg); | 4472 mov(dst, zero_reg); |
4420 mov(overflow_dst, zero_reg); | 4473 if (no_overflow_label) { |
4421 return; | 4474 Branch(no_overflow_label); |
| 4475 } |
4422 } | 4476 } |
4423 | 4477 |
4424 if (dst.is(left)) { | 4478 if (dst.is(left)) { |
4425 mov(scratch, left); // Preserve left. | 4479 mov(scratch, left); // Preserve left. |
4426 subu(dst, left, right); // Left is overwritten. | 4480 subu(dst, left, right); // Left is overwritten. |
4427 xor_(overflow_dst, dst, scratch); // scratch is original left. | 4481 xor_(overflow_dst, dst, scratch); // scratch is original left. |
4428 xor_(scratch, scratch, right); // scratch is original left. | 4482 xor_(scratch, scratch, right); // scratch is original left. |
4429 and_(overflow_dst, scratch, overflow_dst); | 4483 and_(overflow_dst, scratch, overflow_dst); |
4430 } else if (dst.is(right)) { | 4484 } else if (dst.is(right)) { |
4431 mov(scratch, right); // Preserve right. | 4485 mov(scratch, right); // Preserve right. |
4432 subu(dst, left, right); // Right is overwritten. | 4486 subu(dst, left, right); // Right is overwritten. |
4433 xor_(overflow_dst, dst, left); | 4487 xor_(overflow_dst, dst, left); |
4434 xor_(scratch, left, scratch); // Original right. | 4488 xor_(scratch, left, scratch); // Original right. |
4435 and_(overflow_dst, scratch, overflow_dst); | 4489 and_(overflow_dst, scratch, overflow_dst); |
4436 } else { | 4490 } else { |
4437 subu(dst, left, right); | 4491 subu(dst, left, right); |
4438 xor_(overflow_dst, dst, left); | 4492 xor_(overflow_dst, dst, left); |
4439 xor_(scratch, left, right); | 4493 xor_(scratch, left, right); |
4440 and_(overflow_dst, scratch, overflow_dst); | 4494 and_(overflow_dst, scratch, overflow_dst); |
4441 } | 4495 } |
| 4496 BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label); |
4442 } | 4497 } |
4443 | 4498 |
4444 | 4499 |
4445 void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, | 4500 void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, |
4446 SaveFPRegsMode save_doubles, | 4501 SaveFPRegsMode save_doubles, |
4447 BranchDelaySlot bd) { | 4502 BranchDelaySlot bd) { |
4448 // All parameters are on the stack. v0 has the return value after call. | 4503 // All parameters are on the stack. v0 has the return value after call. |
4449 | 4504 |
4450 // If the expected number of arguments of the runtime function is | 4505 // If the expected number of arguments of the runtime function is |
4451 // constant, we check that the actual number of arguments match the | 4506 // constant, we check that the actual number of arguments match the |
(...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5825 if (mag.shift > 0) sra(result, result, mag.shift); | 5880 if (mag.shift > 0) sra(result, result, mag.shift); |
5826 srl(at, dividend, 31); | 5881 srl(at, dividend, 31); |
5827 Addu(result, result, Operand(at)); | 5882 Addu(result, result, Operand(at)); |
5828 } | 5883 } |
5829 | 5884 |
5830 | 5885 |
5831 } // namespace internal | 5886 } // namespace internal |
5832 } // namespace v8 | 5887 } // namespace v8 |
5833 | 5888 |
5834 #endif // V8_TARGET_ARCH_MIPS | 5889 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |