| Index: src/compiler/mips/code-generator-mips.cc
|
| diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc
|
| index b808856dc011e6654514067036386be82d137e2c..dd92837bbde21bbc62857455cdd77702b76c3c28 100644
|
| --- a/src/compiler/mips/code-generator-mips.cc
|
| +++ b/src/compiler/mips/code-generator-mips.cc
|
| @@ -20,6 +20,7 @@ namespace compiler {
|
| // TODO(plind): Possibly avoid using these lithium names.
|
| #define kScratchReg kLithiumScratchReg
|
| #define kCompareReg kLithiumScratchReg2
|
| +#define kScratchReg2 kLithiumScratchReg2
|
| #define kScratchDoubleReg kLithiumScratchDouble
|
|
|
|
|
| @@ -162,6 +163,45 @@ 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.
|
| + __ srl(at, kScratchReg, 31);
|
| + __ sll(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
|
|
|
|
|
| @@ -239,6 +279,27 @@ 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, HeapNumber::kExponentShift, \
|
| + HeapNumber::kExponentBits); \
|
| + __ Branch(USE_DELAY_SLOT, &done, hs, at, \
|
| + Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \
|
| + __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
|
| + __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
|
| + __ Move(at, kScratchReg2, i.OutputDoubleRegister()); \
|
| + __ or_(at, at, kScratchReg2); \
|
| + __ 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);
|
| @@ -407,6 +468,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| __ MovFromFloatResult(i.OutputDoubleRegister());
|
| break;
|
| }
|
| + case kMipsFloat64Floor: {
|
| + ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor);
|
| + break;
|
| + }
|
| + case kMipsFloat64Ceil: {
|
| + ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil);
|
| + break;
|
| + }
|
| + case kMipsFloat64RoundTruncate: {
|
| + ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate);
|
| + break;
|
| + }
|
| case kMipsSqrtD: {
|
| __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
|
| break;
|
|
|