Skip to content

Commit

Permalink
Bug 1518957 - Implement ARM64 truncation and remove unused emitRoundD…
Browse files Browse the repository at this point in the history
…ouble(). r=nbp

--HG--
extra : amend_source : 6d7336b98d91c2f252431d38823731b394e30dd7
  • Loading branch information
sstangl committed Jan 10, 2019
1 parent d983955 commit 56c0daa
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 24 deletions.
12 changes: 0 additions & 12 deletions js/src/jit/arm/CodeGenerator-arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1285,18 +1285,6 @@ void CodeGenerator::visitTruncF(LTruncF* lir) {
bailoutFrom(&bail, lir->snapshot());
}

void CodeGeneratorARM::emitRoundDouble(FloatRegister src, Register dest,
Label* fail) {
ScratchDoubleScope scratch(masm);
ScratchRegisterScope scratchReg(masm);

masm.ma_vcvt_F64_I32(src, scratch);
masm.ma_vxfer(scratch, dest);
masm.ma_cmp(dest, Imm32(0x7fffffff), scratchReg);
masm.ma_cmp(dest, Imm32(0x80000000), scratchReg, Assembler::NotEqual);
masm.ma_b(fail, Assembler::Equal);
}

void CodeGenerator::visitTruncateDToInt32(LTruncateDToInt32* ins) {
emitTruncateDouble(ToFloatRegister(ins->input()), ToRegister(ins->output()),
ins->mir());
Expand Down
2 changes: 0 additions & 2 deletions js/src/jit/arm/CodeGenerator-arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ class CodeGeneratorARM : public CodeGeneratorShared {

bool generateOutOfLineCode();

void emitRoundDouble(FloatRegister src, Register dest, Label* fail);

// Emits a branch that directs control flow to the true block if |cond| is
// true, and the false block if |cond| is false.
void emitBranch(Assembler::Condition cond, MBasicBlock* ifTrue,
Expand Down
85 changes: 77 additions & 8 deletions js/src/jit/arm64/CodeGenerator-arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ void CodeGenerator::visitRoundF(LRoundF* lir) {
masm.Fcmp(input32, 0.0f);
bailoutIf(Assembler::Overflow, lir->snapshot());

// Move all 64 bits of the input into a scratch register to check for -0.
// Move all 32 bits of the input into a scratch register to check for -0.
vixl::UseScratchRegisterScope temps(&masm.asVIXL());
const ARMRegister scratchGPR32 = temps.AcquireW();
masm.Fmov(scratchGPR32, input32);
Expand Down Expand Up @@ -1098,9 +1098,83 @@ void CodeGenerator::visitRoundF(LRoundF* lir) {
masm.bind(&done);
}

void CodeGenerator::visitTrunc(LTrunc* lir) { MOZ_CRASH("visitTrunc"); }
void CodeGenerator::visitTrunc(LTrunc* lir) {
const FloatRegister input = ToFloatRegister(lir->input());
const ARMFPRegister input64(input, 64);
const Register output = ToRegister(lir->output());
const ARMRegister output32(output, 32);

Label done, zeroCase;

void CodeGenerator::visitTruncF(LTruncF* lir) { MOZ_CRASH("visitTruncF"); }
// Convert scalar to signed 32-bit fixed-point, rounding toward zero.
// In the case of overflow, the output is saturated.
// In the case of NaN and -0, the output is zero.
masm.Fcvtzs(output32, input64);

// If the output was zero, worry about special cases.
masm.branch32(Assembler::Equal, output, Imm32(0), &zeroCase);

// Bail on overflow cases.
bailoutCmp32(Assembler::Equal, output, Imm32(INT_MAX), lir->snapshot());
bailoutCmp32(Assembler::Equal, output, Imm32(INT_MIN), lir->snapshot());

// If the output was non-zero and wasn't saturated, just return it.
masm.jump(&done);

// Handle the case of a zero output:
// 1. The input may have been NaN, requiring a bail.
// 2. The input may have been in (-1,-0], requiring a bail.
{
masm.bind(&zeroCase);

// If input is a negative number that truncated to zero, the real
// output should be the non-integer -0.
// The use of "lt" instead of "lo" also catches unordered NaN input.
masm.Fcmp(input64, 0.0);
bailoutIf(vixl::lt, lir->snapshot());
}

masm.bind(&done);
}

void CodeGenerator::visitTruncF(LTruncF* lir) {
const FloatRegister input = ToFloatRegister(lir->input());
const ARMFPRegister input32(input, 32);
const Register output = ToRegister(lir->output());
const ARMRegister output32(output, 32);

Label done, zeroCase;

// Convert scalar to signed 32-bit fixed-point, rounding toward zero.
// In the case of overflow, the output is saturated.
// In the case of NaN and -0, the output is zero.
masm.Fcvtzs(output32, input32);

// If the output was zero, worry about special cases.
masm.branch32(Assembler::Equal, output, Imm32(0), &zeroCase);

// Bail on overflow cases.
bailoutCmp32(Assembler::Equal, output, Imm32(INT_MAX), lir->snapshot());
bailoutCmp32(Assembler::Equal, output, Imm32(INT_MIN), lir->snapshot());

// If the output was non-zero and wasn't saturated, just return it.
masm.jump(&done);

// Handle the case of a zero output:
// 1. The input may have been NaN, requiring a bail.
// 2. The input may have been in (-1,-0], requiring a bail.
{
masm.bind(&zeroCase);

// If input is a negative number that truncated to zero, the real
// output should be the non-integer -0.
// The use of "lt" instead of "lo" also catches unordered NaN input.
masm.Fcmp(input32, 0.0f);
bailoutIf(vixl::lt, lir->snapshot());
}

masm.bind(&done);
}

void CodeGenerator::visitClzI(LClzI* lir) {
ARMRegister input = toWRegister(lir->input());
Expand All @@ -1114,11 +1188,6 @@ void CodeGenerator::visitCtzI(LCtzI* lir) {
masm.ctz32(input, output, /* knownNotZero = */ false);
}

void CodeGeneratorARM64::emitRoundDouble(FloatRegister src, Register dest,
Label* fail) {
MOZ_CRASH("CodeGeneratorARM64::emitRoundDouble");
}

void CodeGenerator::visitTruncateDToInt32(LTruncateDToInt32* ins) {
emitTruncateDouble(ToFloatRegister(ins->input()), ToRegister(ins->output()),
ins->mir());
Expand Down
2 changes: 0 additions & 2 deletions js/src/jit/arm64/CodeGenerator-arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ class CodeGeneratorARM64 : public CodeGeneratorShared {

bool generateOutOfLineCode();

void emitRoundDouble(FloatRegister src, Register dest, Label* fail);

// Emits a branch that directs control flow to the true block if |cond| is
// true, and the false block if |cond| is false.
void emitBranch(Assembler::Condition cond, MBasicBlock* ifTrue,
Expand Down

0 comments on commit 56c0daa

Please sign in to comment.