diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc index 6591fbfc9b..8d010d896a 100644 --- a/src/compiler/mips64/code-generator-mips64.cc +++ b/src/compiler/mips64/code-generator-mips64.cc @@ -987,6 +987,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch); break; } + case kMips64TruncUlD: { + FPURegister scratch = kScratchDoubleReg; + // TODO(plind): Fix wrong param order of Trunc_ul_d() macro-asm function. + __ Trunc_ul_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch); + break; + } case kMips64BitcastDL: __ dmfc1(i.OutputRegister(), i.InputDoubleRegister(0)); break; diff --git a/src/compiler/mips64/instruction-codes-mips64.h b/src/compiler/mips64/instruction-codes-mips64.h index bc3ba14b00..8cb51b7d9f 100644 --- a/src/compiler/mips64/instruction-codes-mips64.h +++ b/src/compiler/mips64/instruction-codes-mips64.h @@ -76,6 +76,7 @@ namespace compiler { V(Mips64TruncWD) \ V(Mips64TruncLD) \ V(Mips64TruncUwD) \ + V(Mips64TruncUlD) \ V(Mips64CvtDW) \ V(Mips64CvtSL) \ V(Mips64CvtSUl) \ diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc index 779ebfdfc8..8bfc523bf3 100644 --- a/src/compiler/mips64/instruction-selector-mips64.cc +++ b/src/compiler/mips64/instruction-selector-mips64.cc @@ -713,7 +713,7 @@ void InstructionSelector::VisitTruncateFloat64ToInt64(Node* node) { void InstructionSelector::VisitTruncateFloat64ToUint64(Node* node) { - UNIMPLEMENTED(); + VisitRR(this, kMips64TruncUlD, node); } diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc index ac37df49a0..5fe691bc5c 100644 --- a/src/mips64/macro-assembler-mips64.cc +++ b/src/mips64/macro-assembler-mips64.cc @@ -1623,6 +1623,12 @@ void MacroAssembler::Trunc_uw_d(FPURegister fd, mtc1(t8, fd); } +void MacroAssembler::Trunc_ul_d(FPURegister fd, FPURegister fs, + FPURegister scratch) { + Trunc_ul_d(fs, t8, scratch); + dmtc1(t8, fd); +} + void MacroAssembler::Trunc_w_d(FPURegister fd, FPURegister fs) { trunc_w_d(fd, fs); @@ -1677,6 +1683,37 @@ void MacroAssembler::Trunc_uw_d(FPURegister fd, } +void MacroAssembler::Trunc_ul_d(FPURegister fd, Register rs, + FPURegister scratch) { + DCHECK(!fd.is(scratch)); + DCHECK(!rs.is(at)); + + // Load 2^63 into scratch as its float representation. + li(at, 0x43e0000000000000); + dmtc1(at, scratch); + + // Test if scratch > fd. + // If fd < 2^63 we can convert it normally. + Label simple_convert, done; + BranchF(&simple_convert, NULL, lt, fd, scratch); + + // First we subtract 2^63 from fd, then trunc it to rs + // and add 2^63 to rs. + sub_d(scratch, fd, scratch); + trunc_l_d(scratch, scratch); + dmfc1(rs, scratch); + Or(rs, rs, Operand(1UL << 63)); + Branch(&done); + + // Simple conversion. + bind(&simple_convert); + trunc_l_d(scratch, fd); + dmfc1(rs, scratch); + + bind(&done); +} + + void MacroAssembler::Madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft, FPURegister scratch) { if (0) { // TODO(plind): find reasonable arch-variant symbol names. diff --git a/src/mips64/macro-assembler-mips64.h b/src/mips64/macro-assembler-mips64.h index 888b1ff3ea..7fae8ddf02 100644 --- a/src/mips64/macro-assembler-mips64.h +++ b/src/mips64/macro-assembler-mips64.h @@ -838,6 +838,10 @@ class MacroAssembler: public Assembler { void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch); void Trunc_uw_d(FPURegister fd, Register rs, FPURegister scratch); + // Convert double to unsigned long. + void Trunc_ul_d(FPURegister fd, FPURegister fs, FPURegister scratch); + void Trunc_ul_d(FPURegister fd, Register rs, FPURegister scratch); + void Trunc_w_d(FPURegister fd, FPURegister fs); void Round_w_d(FPURegister fd, FPURegister fs); void Floor_w_d(FPURegister fd, FPURegister fs);