Chromium Code Reviews| 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..cee1b1d37e651add263ca4854ad8bd8386bb415e 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,25 @@ 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)); \ |
|
paul.l...
2014/12/18 18:07:41
Hmmm, would prefer we don't use so many magic numb
dusmil.imgtec
2014/12/22 14:34:49
Done.
|
| + __ 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 +466,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; |