Commit 000baddf authored by alan.li's avatar alan.li Committed by Commit bot

MIPS: Improve Cvt_d_uw on mips32.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#32418}
parent cfd9beec
......@@ -4507,9 +4507,7 @@ void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
LOperand* input = instr->value();
LOperand* output = instr->result();
FPURegister dbl_scratch = double_scratch0();
__ mtc1(ToRegister(input), dbl_scratch);
__ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22);
__ Cvt_d_uw(ToDoubleRegister(output), ToRegister(input), f22);
}
......@@ -4594,8 +4592,7 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
__ mtc1(src, dbl_scratch);
__ 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, src, f22);
}
if (FLAG_inline_new) {
......
......@@ -1265,50 +1265,39 @@ void MacroAssembler::Ins(Register rt,
}
void MacroAssembler::Cvt_d_uw(FPURegister fd,
FPURegister fs,
void MacroAssembler::Cvt_d_uw(FPURegister fd, Register rs,
FPURegister scratch) {
// Move the data from fs to t8.
mfc1(t8, fs);
Cvt_d_uw(fd, t8, scratch);
}
// In FP64Mode we do convertion from long.
if (IsFp64Mode()) {
mtc1(rs, scratch);
cvt_d_l(fd, scratch);
} else {
// Convert rs to a FP value in fd.
DCHECK(!fd.is(scratch));
DCHECK(!rs.is(at));
Label msb_clear, conversion_done;
// For a value which is < 2^31, regard it as a signed positve word.
Branch(&msb_clear, ge, rs, Operand(zero_reg), USE_DELAY_SLOT);
mtc1(rs, fd);
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).
li(at, 0x41F00000); // FP value: 2^32.
DCHECK(!fd.is(scratch));
DCHECK(!rs.is(t9));
DCHECK(!rs.is(at));
// For unsigned inputs > 2^31, we convert to double as a signed int32,
// then add 2^32 to move it back to unsigned value in range 2^31..2^31-1.
mtc1(zero_reg, scratch);
Mthc1(at, scratch);
// 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);
cvt_d_w(fd, fd);
// Convert fd to a real FP value.
cvt_d_w(fd, fd);
Branch(USE_DELAY_SLOT, &conversion_done);
add_d(fd, fd, scratch);
Label conversion_done;
bind(&msb_clear);
cvt_d_w(fd, fd);
// 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);
bind(&conversion_done);
}
}
......
......@@ -775,7 +775,6 @@ 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);
// Convert double to unsigned word.
......
......@@ -1812,6 +1812,53 @@ TEST(rint_s) {
}
TEST(Cvt_d_uw) {
if (IsMipsArchVariant(kMips32r2)) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0,
v8::internal::CodeObjectRequired::kYes);
typedef struct test_struct {
unsigned input;
uint64_t output;
} TestStruct;
unsigned inputs[] = {
0x0, 0xffffffff, 0x80000000, 0x7fffffff
};
uint64_t outputs[] = {
0x0, 0x41efffffffe00000,
0x41e0000000000000, 0x41dfffffffc00000
};
int kTableLength = sizeof(inputs)/sizeof(inputs[0]);
TestStruct test;
__ lw(t1, MemOperand(a0, offsetof(TestStruct, input)));
__ Cvt_d_uw(f4, t1, f6);
__ sdc1(f4, MemOperand(a0, offsetof(TestStruct, output)));
__ jr(ra);
__ nop();
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
for (int i = 0; i < kTableLength; i++) {
test.input = inputs[i];
(CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0));
// Check outputs
CHECK_EQ(test.output, outputs[i]);
}
}
}
TEST(mina_maxa) {
if (IsMipsArchVariant(kMips32r6)) {
const int kTableLength = 15;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment