MIPS64: Improve UInt32 to Double conversion.

TEST=
BUG=

Review URL: https://codereview.chromium.org/1446363002

Cr-Commit-Position: refs/heads/master@{#32018}
This commit is contained in:
dusan.m.milosavljevic 2015-11-16 15:23:46 -08:00 committed by Commit bot
parent bb332195d3
commit 9717fff12d
5 changed files with 20 additions and 49 deletions

View File

@ -953,8 +953,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
}
case kMips64CvtDUw: {
FPURegister scratch = kScratchDoubleReg;
__ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch);
__ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0));
break;
}
case kMips64CvtDUl: {

View File

@ -4736,7 +4736,7 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
FPURegister dbl_scratch = double_scratch0();
__ mtc1(ToRegister(input), dbl_scratch);
__ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); // TODO(plind): f22?
__ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch);
}
@ -4793,7 +4793,7 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
__ cvt_d_w(dbl_scratch, dbl_scratch);
} else {
__ mtc1(src, dbl_scratch);
__ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
__ Cvt_d_uw(dbl_scratch, dbl_scratch);
}
if (FLAG_inline_new) {

View File

@ -1494,51 +1494,23 @@ void MacroAssembler::Ins(Register rt,
}
void MacroAssembler::Cvt_d_uw(FPURegister fd,
FPURegister fs,
FPURegister scratch) {
void MacroAssembler::Cvt_d_uw(FPURegister fd, FPURegister fs) {
// Move the data from fs to t8.
mfc1(t8, fs);
Cvt_d_uw(fd, t8, scratch);
Cvt_d_uw(fd, t8);
}
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 to the result (if needed).
void MacroAssembler::Cvt_d_uw(FPURegister fd, Register rs) {
// Convert rs to a FP value in fd.
DCHECK(!fd.is(scratch));
DCHECK(!rs.is(t9));
DCHECK(!rs.is(at));
// Save rs's MSB to t9.
Ext(t9, rs, 31, 1);
// Remove rs's MSB.
Ext(at, rs, 0, 31);
// Move the result to fd.
mtc1(at, fd);
mthc1(zero_reg, fd);
// Convert fd to a real FP value.
cvt_d_w(fd, fd);
Label conversion_done;
// If rs's MSB was 0, it's done.
// Otherwise we need to add that to the FP register.
Branch(&conversion_done, eq, t9, Operand(zero_reg));
// Load 2^31 into f20 as its float representation.
li(at, 0x41E00000);
mtc1(zero_reg, scratch);
mthc1(at, scratch);
// Add it to fd.
add_d(fd, fd, scratch);
bind(&conversion_done);
// Zero extend int32 in rs.
Dext(t9, rs, 0, 32);
dmtc1(t9, fd);
cvt_d_l(fd, fd);
}
@ -1555,11 +1527,11 @@ void MacroAssembler::Cvt_d_ul(FPURegister fd, Register rs) {
DCHECK(!rs.is(t9));
DCHECK(!rs.is(at));
Label positive, conversion_done;
Label msb_clear, conversion_done;
Branch(&positive, ge, rs, Operand(zero_reg));
Branch(&msb_clear, ge, rs, Operand(zero_reg));
// Rs >= 2^31.
// Rs >= 2^63
andi(t9, rs, 1);
dsrl(rs, rs, 1);
or_(t9, t9, rs);
@ -1568,8 +1540,8 @@ void MacroAssembler::Cvt_d_ul(FPURegister fd, Register rs) {
Branch(USE_DELAY_SLOT, &conversion_done);
add_d(fd, fd, fd); // In delay slot.
bind(&positive);
// Rs < 2^31, we can do simple conversion.
bind(&msb_clear);
// Rs < 2^63, we can do simple conversion.
dmtc1(rs, fd);
cvt_d_l(fd, fd);

View File

@ -818,8 +818,8 @@ class MacroAssembler: public Assembler {
// FPU macros. These do not handle special cases like NaN or +- inf.
// Convert unsigned word to double.
void Cvt_d_uw(FPURegister fd, FPURegister fs, FPURegister scratch);
void Cvt_d_uw(FPURegister fd, Register rs, FPURegister scratch);
void Cvt_d_uw(FPURegister fd, FPURegister fs);
void Cvt_d_uw(FPURegister fd, Register rs);
// Convert unsigned long to double.
void Cvt_d_ul(FPURegister fd, FPURegister fs);

View File

@ -1186,14 +1186,14 @@ TEST(MIPS13) {
MacroAssembler assm(isolate, NULL, 0);
__ sw(a4, MemOperand(a0, offsetof(T, cvt_small_in)));
__ Cvt_d_uw(f10, a4, f4);
__ Cvt_d_uw(f10, a4);
__ sdc1(f10, MemOperand(a0, offsetof(T, cvt_small_out)));
__ Trunc_uw_d(f10, f10, f4);
__ swc1(f10, MemOperand(a0, offsetof(T, trunc_small_out)));
__ sw(a4, MemOperand(a0, offsetof(T, cvt_big_in)));
__ Cvt_d_uw(f8, a4, f4);
__ Cvt_d_uw(f8, a4);
__ sdc1(f8, MemOperand(a0, offsetof(T, cvt_big_out)));
__ Trunc_uw_d(f8, f8, f4);