Land two MIPS changes contributed by Paul Lind.
1. Issue 7744014: MIPS: Fixed and optimized MacroAssembler::Trunc_uw_d, Cvt_d_uw, Ext, Ins. (http://codereview.chromium.org/7744014/) 2. Issue 7740019: MIPS: Fix for function argument access in non-strict mode. (http://codereview.chromium.org/7740019/) Review URL: http://codereview.chromium.org/7741016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9014 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
a546e4a8dd
commit
2b024e3d5d
@ -2506,7 +2506,7 @@ void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm,
|
||||
CpuFeatures::Scope scope(FPU);
|
||||
__ mtc1(a2, f0);
|
||||
if (op_ == Token::SHR) {
|
||||
__ Cvt_d_uw(f0, f0);
|
||||
__ Cvt_d_uw(f0, f0, f22);
|
||||
} else {
|
||||
__ cvt_d_w(f0, f0);
|
||||
}
|
||||
@ -2920,7 +2920,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
|
||||
} else {
|
||||
// The result must be interpreted as an unsigned 32-bit integer.
|
||||
__ mtc1(a2, double_scratch);
|
||||
__ Cvt_d_uw(double_scratch, double_scratch);
|
||||
__ Cvt_d_uw(double_scratch, double_scratch, single_scratch);
|
||||
}
|
||||
|
||||
// Store the result.
|
||||
|
@ -885,8 +885,8 @@ void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
|
||||
MemOperand unmapped_location =
|
||||
GenerateUnmappedArgumentsLookup(masm, a0, a2, a3, &slow);
|
||||
__ lw(a2, unmapped_location);
|
||||
__ Branch(&slow, eq, a2, Operand(a3));
|
||||
__ LoadRoot(a3, Heap::kTheHoleValueRootIndex);
|
||||
__ Branch(&slow, eq, a2, Operand(a3));
|
||||
__ mov(v0, a2);
|
||||
__ Ret();
|
||||
__ bind(&slow);
|
||||
|
@ -757,15 +757,22 @@ void MacroAssembler::Ext(Register rt,
|
||||
uint16_t pos,
|
||||
uint16_t size) {
|
||||
ASSERT(pos < 32);
|
||||
ASSERT(pos + size < 32);
|
||||
ASSERT(pos + size < 33);
|
||||
|
||||
if (mips32r2) {
|
||||
ext_(rt, rs, pos, size);
|
||||
} else {
|
||||
// Move rs to rt and shift it left then right to get the
|
||||
// desired bitfield on the right side and zeroes on the left.
|
||||
sll(rt, rs, 32 - (pos + size));
|
||||
srl(rt, rt, 32 - size);
|
||||
int shift_left = 32 - (pos + size);
|
||||
if (shift_left > 0) {
|
||||
sll(rt, rs, shift_left);
|
||||
}
|
||||
|
||||
int shift_right = 32 - size;
|
||||
if (shift_right > 0) {
|
||||
srl(rt, rt, shift_right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -807,28 +814,32 @@ void MacroAssembler::Ins(Register rt,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Cvt_d_uw(FPURegister fd, FPURegister fs) {
|
||||
// Move the data from fs to t4.
|
||||
mfc1(t4, fs);
|
||||
return Cvt_d_uw(fd, t4);
|
||||
void MacroAssembler::Cvt_d_uw(FPURegister fd,
|
||||
FPURegister fs,
|
||||
FPURegister scratch) {
|
||||
// Move the data from fs to t8.
|
||||
mfc1(t8, fs);
|
||||
Cvt_d_uw(fd, t8, scratch);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Cvt_d_uw(FPURegister fd, Register rs) {
|
||||
void MacroAssembler::Cvt_d_uw(FPURegister fd,
|
||||
Register rs,
|
||||
FPURegister scratch) {
|
||||
// Convert rs to a FP value in fd (and fd + 1).
|
||||
// We do this by converting rs minus the MSB to avoid sign conversion,
|
||||
// then adding 2^31-1 and 1 to the result.
|
||||
// then adding 2^31 to the result (if needed).
|
||||
|
||||
ASSERT(!fd.is(f20));
|
||||
ASSERT(!fd.is(scratch));
|
||||
ASSERT(!rs.is(t9));
|
||||
ASSERT(!rs.is(t8));
|
||||
ASSERT(!rs.is(at));
|
||||
|
||||
// Save rs's MSB to t8.
|
||||
And(t8, rs, 0x80000000);
|
||||
// Save rs's MSB to t9.
|
||||
Ext(t9, rs, 31, 1);
|
||||
// Remove rs's MSB.
|
||||
And(t9, rs, 0x7FFFFFFF);
|
||||
// Move t9 to fd.
|
||||
mtc1(t9, fd);
|
||||
Ext(at, rs, 0, 31);
|
||||
// Move the result to fd.
|
||||
mtc1(at, fd);
|
||||
|
||||
// Convert fd to a real FP value.
|
||||
cvt_d_w(fd, fd);
|
||||
@ -837,41 +848,39 @@ void MacroAssembler::Cvt_d_uw(FPURegister fd, Register rs) {
|
||||
|
||||
// If rs's MSB was 0, it's done.
|
||||
// Otherwise we need to add that to the FP register.
|
||||
Branch(&conversion_done, eq, t8, Operand(zero_reg));
|
||||
Branch(&conversion_done, eq, t9, Operand(zero_reg));
|
||||
|
||||
// First load 2^31 - 1 into f20.
|
||||
Or(t9, zero_reg, 0x7FFFFFFF);
|
||||
mtc1(t9, f20);
|
||||
// Load 2^31 into f20 as its float representation.
|
||||
li(at, 0x41E00000);
|
||||
mtc1(at, FPURegister::from_code(scratch.code() + 1));
|
||||
mtc1(zero_reg, scratch);
|
||||
// Add it to fd.
|
||||
add_d(fd, fd, scratch);
|
||||
|
||||
// Convert it to FP and add it to fd.
|
||||
cvt_d_w(f20, f20);
|
||||
add_d(fd, fd, f20);
|
||||
// Now add 1.
|
||||
Or(t9, zero_reg, 1);
|
||||
mtc1(t9, f20);
|
||||
|
||||
cvt_d_w(f20, f20);
|
||||
add_d(fd, fd, f20);
|
||||
bind(&conversion_done);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Trunc_uw_d(FPURegister fd, FPURegister fs) {
|
||||
Trunc_uw_d(fs, t4);
|
||||
mtc1(t4, fd);
|
||||
void MacroAssembler::Trunc_uw_d(FPURegister fd,
|
||||
FPURegister fs,
|
||||
FPURegister scratch) {
|
||||
Trunc_uw_d(fs, t8, scratch);
|
||||
mtc1(t8, fd);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::Trunc_uw_d(FPURegister fd, Register rs) {
|
||||
ASSERT(!fd.is(f22));
|
||||
ASSERT(!rs.is(t8));
|
||||
void MacroAssembler::Trunc_uw_d(FPURegister fd,
|
||||
Register rs,
|
||||
FPURegister scratch) {
|
||||
ASSERT(!fd.is(scratch));
|
||||
ASSERT(!rs.is(at));
|
||||
|
||||
// Load 2^31 into f22.
|
||||
Or(t8, zero_reg, 0x80000000);
|
||||
Cvt_d_uw(f22, t8);
|
||||
|
||||
// Test if f22 > fd.
|
||||
c(OLT, D, fd, f22);
|
||||
// Load 2^31 into scratch as its float representation.
|
||||
li(at, 0x41E00000);
|
||||
mtc1(at, FPURegister::from_code(scratch.code() + 1));
|
||||
mtc1(zero_reg, scratch);
|
||||
// Test if scratch > fd.
|
||||
c(OLT, D, fd, scratch);
|
||||
|
||||
Label simple_convert;
|
||||
// If fd < 2^31 we can convert it normally.
|
||||
@ -879,18 +888,17 @@ void MacroAssembler::Trunc_uw_d(FPURegister fd, Register rs) {
|
||||
|
||||
// First we subtract 2^31 from fd, then trunc it to rs
|
||||
// and add 2^31 to rs.
|
||||
|
||||
sub_d(f22, fd, f22);
|
||||
trunc_w_d(f22, f22);
|
||||
mfc1(rs, f22);
|
||||
or_(rs, rs, t8);
|
||||
sub_d(scratch, fd, scratch);
|
||||
trunc_w_d(scratch, scratch);
|
||||
mfc1(rs, scratch);
|
||||
Or(rs, rs, 1 << 31);
|
||||
|
||||
Label done;
|
||||
Branch(&done);
|
||||
// Simple conversion.
|
||||
bind(&simple_convert);
|
||||
trunc_w_d(f22, fd);
|
||||
mfc1(rs, f22);
|
||||
trunc_w_d(scratch, fd);
|
||||
mfc1(rs, scratch);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
@ -524,12 +524,12 @@ class MacroAssembler: public Assembler {
|
||||
void Ext(Register rt, Register rs, uint16_t pos, uint16_t size);
|
||||
|
||||
// Convert unsigned word to double.
|
||||
void Cvt_d_uw(FPURegister fd, FPURegister fs);
|
||||
void Cvt_d_uw(FPURegister fd, Register rs);
|
||||
void Cvt_d_uw(FPURegister fd, FPURegister fs, FPURegister scratch);
|
||||
void Cvt_d_uw(FPURegister fd, Register rs, FPURegister scratch);
|
||||
|
||||
// Convert double to unsigned word.
|
||||
void Trunc_uw_d(FPURegister fd, FPURegister fs);
|
||||
void Trunc_uw_d(FPURegister fd, Register rs);
|
||||
void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch);
|
||||
void Trunc_uw_d(FPURegister fd, Register rs, FPURegister scratch);
|
||||
|
||||
// Convert the HeapNumber pointed to by source to a 32bits signed integer
|
||||
// dest. If the HeapNumber does not fit into a 32bits signed integer branch
|
||||
|
@ -3638,7 +3638,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
||||
// __ mtc1(zero_reg, f1); // MS 32-bits are all zero.
|
||||
// __ cvt_d_l(f0, f0); // Use 64 bit conv to get correct unsigned 32-bit.
|
||||
|
||||
__ Cvt_d_uw(f0, value);
|
||||
__ Cvt_d_uw(f0, value, f22);
|
||||
|
||||
__ sdc1(f0, MemOperand(v0, HeapNumber::kValueOffset - kHeapObjectTag));
|
||||
|
||||
|
@ -1083,17 +1083,17 @@ TEST(MIPS13) {
|
||||
CpuFeatures::Scope scope(FPU);
|
||||
|
||||
__ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
|
||||
__ Cvt_d_uw(f10, t0);
|
||||
__ Cvt_d_uw(f10, t0, f22);
|
||||
__ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
|
||||
|
||||
__ Trunc_uw_d(f10, f10);
|
||||
__ Trunc_uw_d(f10, f10, f22);
|
||||
__ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
|
||||
|
||||
__ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
|
||||
__ Cvt_d_uw(f8, t0);
|
||||
__ Cvt_d_uw(f8, t0, f22);
|
||||
__ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
|
||||
|
||||
__ Trunc_uw_d(f8, f8);
|
||||
__ Trunc_uw_d(f8, f8, f22);
|
||||
__ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
|
||||
|
||||
__ jr(ra);
|
||||
|
Loading…
Reference in New Issue
Block a user