Commit e184dcae authored by Ivica Bogosavljevic's avatar Ivica Bogosavljevic Committed by Commit Bot

MIPS[64]: Implement Round, Ceil, Floor and Trunc in LiftOff

Change-Id: I13c58a462ec844b6df0e55bbbbf9134a476363c4
Reviewed-on: https://chromium-review.googlesource.com/1009908Reviewed-by: 's avatarSreten Kovacevic <sreten.kovacevic@mips.com>
Commit-Queue: Ivica Bogosavljevic <ivica.bogosavljevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#52575}
parent 5874911b
......@@ -143,41 +143,6 @@ static inline bool HasRegisterInput(Instruction* instr, size_t index) {
namespace {
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 OutOfLineRound32 : public OutOfLineCode {
public:
OutOfLineRound32(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 float input already in kScratchReg.
__ srl(at, kScratchReg, 31);
__ sll(at, at, 31);
__ mtc1(at, result_);
}
private:
DoubleRegister const result_;
};
class OutOfLineRecordWrite final : public OutOfLineCode {
public:
......@@ -367,57 +332,6 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} // namespace
#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \
if (IsMipsArchVariant(kMips32r6)) { \
__ cfc1(kScratchReg, FCSR); \
__ li(at, Operand(mode_##mode)); \
__ ctc1(at, FCSR); \
__ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ ctc1(kScratchReg, FCSR); \
} else { \
auto ool = new (zone()) OutOfLineRound(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)); \
__ mode##_l_d(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); \
}
#define ASSEMBLE_ROUND_FLOAT_TO_FLOAT(mode) \
if (IsMipsArchVariant(kMips32r6)) { \
__ cfc1(kScratchReg, FCSR); \
__ li(at, Operand(mode_##mode)); \
__ ctc1(at, FCSR); \
__ rint_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ ctc1(kScratchReg, FCSR); \
} else { \
int32_t kFloat32ExponentBias = 127; \
int32_t kFloat32MantissaBits = 23; \
int32_t kFloat32ExponentBits = 8; \
auto ool = new (zone()) OutOfLineRound32(this, i.OutputDoubleRegister()); \
Label done; \
__ mfc1(kScratchReg, i.InputDoubleRegister(0)); \
__ Ext(at, kScratchReg, kFloat32MantissaBits, kFloat32ExponentBits); \
__ Branch(USE_DELAY_SLOT, &done, hs, at, \
Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \
__ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ mfc1(at, i.OutputDoubleRegister()); \
__ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \
__ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \
__ bind(ool->exit()); \
__ bind(&done); \
}
#define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr) \
do { \
......@@ -1351,35 +1265,35 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputDoubleRegister(1));
break;
case kMipsFloat64RoundDown: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor);
__ Floor_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMipsFloat32RoundDown: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(floor);
__ Floor_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMipsFloat64RoundTruncate: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc);
__ Trunc_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMipsFloat32RoundTruncate: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(trunc);
__ Trunc_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMipsFloat64RoundUp: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil);
__ Ceil_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMipsFloat32RoundUp: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(ceil);
__ Ceil_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMipsFloat64RoundTiesEven: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round);
__ Round_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMipsFloat32RoundTiesEven: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(round);
__ Round_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMipsFloat32Max: {
......
......@@ -143,41 +143,6 @@ static inline bool HasRegisterInput(Instruction* instr, size_t index) {
namespace {
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 OutOfLineRound32 : public OutOfLineCode {
public:
OutOfLineRound32(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 float input already in kScratchReg.
__ srl(at, kScratchReg, 31);
__ sll(at, at, 31);
__ mtc1(at, result_);
}
private:
DoubleRegister const result_;
};
class OutOfLineRecordWrite final : public OutOfLineCode {
public:
......@@ -375,56 +340,6 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} // namespace
#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \
if (kArchVariant == kMips64r6) { \
__ cfc1(kScratchReg, FCSR); \
__ li(at, Operand(mode_##mode)); \
__ ctc1(at, FCSR); \
__ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ ctc1(kScratchReg, FCSR); \
} else { \
auto ool = new (zone()) OutOfLineRound(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)); \
__ mode##_l_d(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); \
}
#define ASSEMBLE_ROUND_FLOAT_TO_FLOAT(mode) \
if (kArchVariant == kMips64r6) { \
__ cfc1(kScratchReg, FCSR); \
__ li(at, Operand(mode_##mode)); \
__ ctc1(at, FCSR); \
__ rint_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ ctc1(kScratchReg, FCSR); \
} else { \
int32_t kFloat32ExponentBias = 127; \
int32_t kFloat32MantissaBits = 23; \
int32_t kFloat32ExponentBits = 8; \
auto ool = new (zone()) OutOfLineRound32(this, i.OutputDoubleRegister()); \
Label done; \
__ mfc1(kScratchReg, i.InputDoubleRegister(0)); \
__ Ext(at, kScratchReg, kFloat32MantissaBits, kFloat32ExponentBits); \
__ Branch(USE_DELAY_SLOT, &done, hs, at, \
Operand(kFloat32ExponentBias + kFloat32MantissaBits)); \
__ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
__ mfc1(at, i.OutputDoubleRegister()); \
__ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg)); \
__ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \
__ bind(ool->exit()); \
__ bind(&done); \
}
#define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr) \
do { \
__ asm_instr(i.OutputRegister(), i.MemoryOperand()); \
......@@ -1458,35 +1373,35 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.InputDoubleRegister(1));
break;
case kMips64Float64RoundDown: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor);
__ Floor_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMips64Float32RoundDown: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(floor);
__ Floor_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMips64Float64RoundTruncate: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc);
__ Trunc_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMips64Float32RoundTruncate: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(trunc);
__ Trunc_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMips64Float64RoundUp: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil);
__ Ceil_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMips64Float32RoundUp: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(ceil);
__ Ceil_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMips64Float64RoundTiesEven: {
ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round);
__ Round_d_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
case kMips64Float32RoundTiesEven: {
ASSEMBLE_ROUND_FLOAT_TO_FLOAT(round);
__ Round_s_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
break;
}
case kMips64Float32Max: {
......
......@@ -1905,6 +1905,125 @@ void TurboAssembler::Trunc_uw_s(FPURegister fd, Register rs,
bind(&done);
}
template <typename RoundFunc>
void TurboAssembler::RoundDouble(FPURegister dst, FPURegister src,
FPURoundingMode mode, RoundFunc round) {
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch = t8;
Register scratch2 = t9;
if (IsMipsArchVariant(kMips32r6)) {
cfc1(scratch, FCSR);
li(at, Operand(mode));
ctc1(at, FCSR);
rint_d(dst, src);
ctc1(scratch, FCSR);
} else {
Label done;
Mfhc1(scratch, src);
Ext(at, scratch, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
Branch(USE_DELAY_SLOT, &done, hs, at,
Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits));
mov_d(dst, src);
round(this, dst, src);
Move(at, scratch2, dst);
or_(at, at, scratch2);
Branch(USE_DELAY_SLOT, &done, ne, at, Operand(zero_reg));
cvt_d_l(dst, dst);
srl(at, scratch, 31);
sll(at, at, 31);
Mthc1(at, dst);
bind(&done);
}
}
void TurboAssembler::Floor_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_floor,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->floor_l_d(dst, src);
});
}
void TurboAssembler::Ceil_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_ceil,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->ceil_l_d(dst, src);
});
}
void TurboAssembler::Trunc_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_trunc,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->trunc_l_d(dst, src);
});
}
void TurboAssembler::Round_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_round,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->round_l_d(dst, src);
});
}
template <typename RoundFunc>
void TurboAssembler::RoundFloat(FPURegister dst, FPURegister src,
FPURoundingMode mode, RoundFunc round) {
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch = t8;
if (IsMipsArchVariant(kMips32r6)) {
cfc1(scratch, FCSR);
li(at, Operand(mode));
ctc1(at, FCSR);
rint_s(dst, src);
ctc1(scratch, FCSR);
} else {
int32_t kFloat32ExponentBias = 127;
int32_t kFloat32MantissaBits = 23;
int32_t kFloat32ExponentBits = 8;
Label done;
mfc1(scratch, src);
Ext(at, scratch, kFloat32MantissaBits, kFloat32ExponentBits);
Branch(USE_DELAY_SLOT, &done, hs, at,
Operand(kFloat32ExponentBias + kFloat32MantissaBits));
mov_s(dst, src);
round(this, dst, src);
mfc1(at, dst);
Branch(USE_DELAY_SLOT, &done, ne, at, Operand(zero_reg));
cvt_s_w(dst, dst);
srl(at, scratch, 31);
sll(at, at, 31);
mtc1(at, dst);
bind(&done);
}
}
void TurboAssembler::Floor_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_floor,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->floor_w_s(dst, src);
});
}
void TurboAssembler::Ceil_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_ceil,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->ceil_w_s(dst, src);
});
}
void TurboAssembler::Trunc_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_trunc,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->trunc_w_s(dst, src);
});
}
void TurboAssembler::Round_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_round,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->round_w_s(dst, src);
});
}
void TurboAssembler::Mthc1(Register rt, FPURegister fs) {
if (IsFp32Mode()) {
mtc1(rt, fs.high());
......
......@@ -626,6 +626,18 @@ class TurboAssembler : public Assembler {
void Floor_w_d(FPURegister fd, FPURegister fs);
void Ceil_w_d(FPURegister fd, FPURegister fs);
// Round double functions
void Trunc_d_d(FPURegister fd, FPURegister fs);
void Round_d_d(FPURegister fd, FPURegister fs);
void Floor_d_d(FPURegister fd, FPURegister fs);
void Ceil_d_d(FPURegister fd, FPURegister fs);
// Round float functions
void Trunc_s_s(FPURegister fd, FPURegister fs);
void Round_s_s(FPURegister fd, FPURegister fs);
void Floor_s_s(FPURegister fd, FPURegister fs);
void Ceil_s_s(FPURegister fd, FPURegister fs);
// FP32 mode: Move the general purpose register into
// the high part of the double-register pair.
// FP64 mode: Move the general-purpose register into
......@@ -867,6 +879,14 @@ class TurboAssembler : public Assembler {
BranchDelaySlot bdslot);
void BranchAndLinkLong(Label* L, BranchDelaySlot bdslot);
template <typename RoundFunc>
void RoundDouble(FPURegister dst, FPURegister src, FPURoundingMode mode,
RoundFunc round);
template <typename RoundFunc>
void RoundFloat(FPURegister dst, FPURegister src, FPURoundingMode mode,
RoundFunc round);
// Push a fixed frame, consisting of ra, fp.
void PushCommonFrame(Register marker_reg = no_reg);
};
......
......@@ -2474,6 +2474,123 @@ void TurboAssembler::Trunc_ul_s(FPURegister fd, Register rs,
bind(&fail);
}
template <typename RoundFunc>
void TurboAssembler::RoundDouble(FPURegister dst, FPURegister src,
FPURoundingMode mode, RoundFunc round) {
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch = t8;
if (kArchVariant == kMips64r6) {
cfc1(scratch, FCSR);
li(at, Operand(mode));
ctc1(at, FCSR);
rint_d(dst, src);
ctc1(scratch, FCSR);
} else {
Label done;
mfhc1(scratch, src);
Ext(at, scratch, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
Branch(USE_DELAY_SLOT, &done, hs, at,
Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits));
mov_d(dst, src);
round(this, dst, src);
dmfc1(at, dst);
Branch(USE_DELAY_SLOT, &done, ne, at, Operand(zero_reg));
cvt_d_l(dst, dst);
srl(at, scratch, 31);
sll(at, at, 31);
mthc1(at, dst);
bind(&done);
}
}
void TurboAssembler::Floor_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_floor,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->floor_l_d(dst, src);
});
}
void TurboAssembler::Ceil_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_ceil,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->ceil_l_d(dst, src);
});
}
void TurboAssembler::Trunc_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_trunc,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->trunc_l_d(dst, src);
});
}
void TurboAssembler::Round_d_d(FPURegister dst, FPURegister src) {
RoundDouble(dst, src, mode_round,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->round_l_d(dst, src);
});
}
template <typename RoundFunc>
void TurboAssembler::RoundFloat(FPURegister dst, FPURegister src,
FPURoundingMode mode, RoundFunc round) {
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch = t8;
if (kArchVariant == kMips64r6) {
cfc1(scratch, FCSR);
li(at, Operand(mode));
ctc1(at, FCSR);
rint_s(dst, src);
ctc1(scratch, FCSR);
} else {
int32_t kFloat32ExponentBias = 127;
int32_t kFloat32MantissaBits = 23;
int32_t kFloat32ExponentBits = 8;
Label done;
mfc1(scratch, src);
Ext(at, scratch, kFloat32MantissaBits, kFloat32ExponentBits);
Branch(USE_DELAY_SLOT, &done, hs, at,
Operand(kFloat32ExponentBias + kFloat32MantissaBits));
mov_s(dst, src);
round(this, dst, src);
mfc1(at, dst);
Branch(USE_DELAY_SLOT, &done, ne, at, Operand(zero_reg));
cvt_s_w(dst, dst);
srl(at, scratch, 31);
sll(at, at, 31);
mtc1(at, dst);
bind(&done);
}
}
void TurboAssembler::Floor_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_floor,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->floor_w_s(dst, src);
});
}
void TurboAssembler::Ceil_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_ceil,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->ceil_w_s(dst, src);
});
}
void TurboAssembler::Trunc_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_trunc,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->trunc_w_s(dst, src);
});
}
void TurboAssembler::Round_s_s(FPURegister dst, FPURegister src) {
RoundFloat(dst, src, mode_round,
[](TurboAssembler* tasm, FPURegister dst, FPURegister src) {
tasm->round_w_s(dst, src);
});
}
void MacroAssembler::Madd_s(FPURegister fd, FPURegister fr, FPURegister fs,
FPURegister ft, FPURegister scratch) {
DCHECK(fr != scratch && fs != scratch && ft != scratch);
......
......@@ -824,6 +824,18 @@ class TurboAssembler : public Assembler {
void Trunc_ul_s(FPURegister fd, Register rs, FPURegister scratch,
Register result = no_reg);
// Round double functions
void Trunc_d_d(FPURegister fd, FPURegister fs);
void Round_d_d(FPURegister fd, FPURegister fs);
void Floor_d_d(FPURegister fd, FPURegister fs);
void Ceil_d_d(FPURegister fd, FPURegister fs);
// Round float functions
void Trunc_s_s(FPURegister fd, FPURegister fs);
void Round_s_s(FPURegister fd, FPURegister fs);
void Floor_s_s(FPURegister fd, FPURegister fs);
void Ceil_s_s(FPURegister fd, FPURegister fs);
// Jump the register contains a smi.
void JumpIfSmi(Register value, Label* smi_label, Register scratch = at,
BranchDelaySlot bd = PROTECT);
......@@ -900,6 +912,14 @@ class TurboAssembler : public Assembler {
void BranchLong(Label* L, BranchDelaySlot bdslot);
void BranchAndLinkLong(Label* L, BranchDelaySlot bdslot);
template <typename RoundFunc>
void RoundDouble(FPURegister dst, FPURegister src, FPURoundingMode mode,
RoundFunc round);
template <typename RoundFunc>
void RoundFloat(FPURegister dst, FPURegister src, FPURoundingMode mode,
RoundFunc round);
// Push a fixed frame, consisting of ra, fp.
void PushCommonFrame(Register marker_reg = no_reg);
};
......
......@@ -674,10 +674,10 @@ FP_BINOP(f32_mul, mul_s)
FP_BINOP(f32_div, div_s)
FP_UNOP(f32_abs, abs_s)
FP_UNOP(f32_neg, neg_s)
FP_UNOP(f32_ceil, ceil_w_s)
FP_UNOP(f32_floor, floor_w_s)
FP_UNOP(f32_trunc, trunc_w_s)
FP_UNOP(f32_nearest_int, rint_s)
FP_UNOP(f32_ceil, Ceil_s_s)
FP_UNOP(f32_floor, Floor_s_s)
FP_UNOP(f32_trunc, Trunc_s_s)
FP_UNOP(f32_nearest_int, Round_s_s)
FP_UNOP(f32_sqrt, sqrt_s)
FP_BINOP(f64_add, add_d)
FP_BINOP(f64_sub, sub_d)
......@@ -685,15 +685,48 @@ FP_BINOP(f64_mul, mul_d)
FP_BINOP(f64_div, div_d)
FP_UNOP(f64_abs, abs_d)
FP_UNOP(f64_neg, neg_d)
FP_UNOP(f64_ceil, ceil_w_d)
FP_UNOP(f64_floor, floor_w_d)
FP_UNOP(f64_trunc, trunc_w_d)
FP_UNOP(f64_nearest_int, rint_d)
FP_UNOP(f64_sqrt, sqrt_d)
#undef FP_BINOP
#undef FP_UNOP
void LiftoffAssembler::emit_f64_ceil(DoubleRegister dst, DoubleRegister src) {
if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
IsFp64Mode()) {
Ceil_d_d(dst, src);
} else {
BAILOUT("emit_f64_ceil");
}
}
void LiftoffAssembler::emit_f64_floor(DoubleRegister dst, DoubleRegister src) {
if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
IsFp64Mode()) {
Floor_d_d(dst, src);
} else {
BAILOUT("emit_f64_floor");
}
}
void LiftoffAssembler::emit_f64_trunc(DoubleRegister dst, DoubleRegister src) {
if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
IsFp64Mode()) {
Trunc_d_d(dst, src);
} else {
BAILOUT("emit_f64_trunc");
}
}
void LiftoffAssembler::emit_f64_nearest_int(DoubleRegister dst,
DoubleRegister src) {
if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
IsFp64Mode()) {
Round_d_d(dst, src);
} else {
BAILOUT("emit_f64_nearest_int");
}
}
bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode,
LiftoffRegister dst,
LiftoffRegister src) {
......
......@@ -561,10 +561,10 @@ FP_BINOP(f32_mul, mul_s)
FP_BINOP(f32_div, div_s)
FP_UNOP(f32_abs, abs_s)
FP_UNOP(f32_neg, neg_s)
FP_UNOP(f32_ceil, ceil_w_s)
FP_UNOP(f32_floor, floor_w_s)
FP_UNOP(f32_trunc, trunc_w_s)
FP_UNOP(f32_nearest_int, rint_s)
FP_UNOP(f32_ceil, Ceil_s_s)
FP_UNOP(f32_floor, Floor_s_s)
FP_UNOP(f32_trunc, Trunc_s_s)
FP_UNOP(f32_nearest_int, Round_s_s)
FP_UNOP(f32_sqrt, sqrt_s)
FP_BINOP(f64_add, add_d)
FP_BINOP(f64_sub, sub_d)
......@@ -572,10 +572,10 @@ FP_BINOP(f64_mul, mul_d)
FP_BINOP(f64_div, div_d)
FP_UNOP(f64_abs, abs_d)
FP_UNOP(f64_neg, neg_d)
FP_UNOP(f64_ceil, ceil_w_d)
FP_UNOP(f64_floor, floor_w_d)
FP_UNOP(f64_trunc, trunc_w_d)
FP_UNOP(f64_nearest_int, rint_d)
FP_UNOP(f64_ceil, Ceil_d_d)
FP_UNOP(f64_floor, Floor_d_d)
FP_UNOP(f64_trunc, Trunc_d_d)
FP_UNOP(f64_nearest_int, Round_d_d)
FP_UNOP(f64_sqrt, sqrt_d)
#undef FP_BINOP
......
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