| Index: src/compiler/mips64/code-generator-mips64.cc
|
| diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc
|
| index 8e94ceed2126841ab08b5e5897ccb4621b2be0c9..b46e6e98be6cc8c072a26c4d618bb36fe4ed1686 100644
|
| --- a/src/compiler/mips64/code-generator-mips64.cc
|
| +++ b/src/compiler/mips64/code-generator-mips64.cc
|
| @@ -163,6 +163,46 @@ class OutOfLineLoadInteger FINAL : public OutOfLineCode {
|
| Register const result_;
|
| };
|
|
|
| +
|
| +class OutOfLineRound : public OutOfLineCode {
|
| + public:
|
| + OutOfLineRound(CodeGenerator* gen, DoubleRegister result)
|
| + : OutOfLineCode(gen), result_(result) {}
|
| +
|
| + void Generate() FINAL {
|
| + // Handle rounding to zero case where sign has to be preserved.
|
| + // High bits of double input already in kScratchReg.
|
| + __ dsrl(at, kScratchReg, 31);
|
| + __ dsll(at, at, 31);
|
| + __ mthc1(at, result_);
|
| + }
|
| +
|
| + private:
|
| + DoubleRegister const result_;
|
| +};
|
| +
|
| +
|
| +class OutOfLineTruncate FINAL : public OutOfLineRound {
|
| + public:
|
| + OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result)
|
| + : OutOfLineRound(gen, result) {}
|
| +};
|
| +
|
| +
|
| +class OutOfLineFloor FINAL : public OutOfLineRound {
|
| + public:
|
| + OutOfLineFloor(CodeGenerator* gen, DoubleRegister result)
|
| + : OutOfLineRound(gen, result) {}
|
| +};
|
| +
|
| +
|
| +class OutOfLineCeil FINAL : public OutOfLineRound {
|
| + public:
|
| + OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
|
| + : OutOfLineRound(gen, result) {}
|
| +};
|
| +
|
| +
|
| } // namespace
|
|
|
|
|
| @@ -240,6 +280,24 @@ class OutOfLineLoadInteger FINAL : public OutOfLineCode {
|
| } while (0)
|
|
|
|
|
| +#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation) \
|
| + do { \
|
| + auto ool = \
|
| + new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister()); \
|
| + Label done; \
|
| + __ mfhc1(kScratchReg, i.InputDoubleRegister(0)); \
|
| + __ Ext(at, kScratchReg, 20, 11); \
|
| + __ Branch(USE_DELAY_SLOT, &done, hs, at, Operand(1075)); \
|
| + __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
|
| + __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
|
| + __ dmfc1(at, i.OutputDoubleRegister()); \
|
| + __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \
|
| + __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \
|
| + __ bind(ool->exit()); \
|
| + __ bind(&done); \
|
| + } while (0)
|
| +
|
| +
|
| // Assembles an instruction after register allocation, producing machine code.
|
| void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| MipsOperandConverter i(this, instr);
|
| @@ -472,19 +530,16 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| __ MovFromFloatResult(i.OutputDoubleRegister());
|
| break;
|
| }
|
| - case kMips64FloorD: {
|
| - __ floor_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| - __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());
|
| + case kMips64Float64Floor: {
|
| + ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor);
|
| break;
|
| }
|
| - case kMips64CeilD: {
|
| - __ ceil_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| - __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());
|
| + case kMips64Float64Ceil: {
|
| + ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil);
|
| break;
|
| }
|
| - case kMips64RoundTruncateD: {
|
| - __ trunc_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| - __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());
|
| + case kMips64Float64RoundTruncate: {
|
| + ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate);
|
| break;
|
| }
|
| case kMips64SqrtD: {
|
|
|