Bug 1499536 - Implement CodeGeneratorARM64::visitShiftI and visitUrshD. r=mgaudet

Fixes ion/bug1000960.js.
This commit is contained in:
Sean Stangl 2018-10-22 14:00:00 -04:00
parent a1e70818c8
commit bc9aaf0cf8

View File

@ -568,13 +568,82 @@ CodeGenerator::visitBitOpI(LBitOpI* ins)
void void
CodeGenerator::visitShiftI(LShiftI* ins) CodeGenerator::visitShiftI(LShiftI* ins)
{ {
MOZ_CRASH("visitShiftI"); const ARMRegister lhs = toWRegister(ins->lhs());
const LAllocation* rhs = ins->rhs();
const ARMRegister dest = toWRegister(ins->output());
if (rhs->isConstant()) {
int32_t shift = ToInt32(rhs) & 0x1F;
switch (ins->bitop()) {
case JSOP_LSH:
masm.Lsl(dest, lhs, shift);
break;
case JSOP_RSH:
masm.Asr(dest, lhs, shift);
break;
case JSOP_URSH:
if (shift) {
masm.Lsr(dest, lhs, shift);
} else if (ins->mir()->toUrsh()->fallible()) {
// x >>> 0 can overflow.
masm.Ands(dest, lhs, Operand(0xFFFFFFFF));
bailoutIf(Assembler::Signed, ins->snapshot());
} else {
masm.Mov(dest, lhs);
}
break;
default:
MOZ_CRASH("Unexpected shift op");
}
} else {
const ARMRegister rhsreg = toWRegister(rhs);
switch (ins->bitop()) {
case JSOP_LSH:
masm.Lsl(dest, lhs, rhsreg);
break;
case JSOP_RSH:
masm.Asr(dest, lhs, rhsreg);
break;
case JSOP_URSH:
masm.Lsr(dest, lhs, rhsreg);
if (ins->mir()->toUrsh()->fallible()) {
/// x >>> 0 can overflow.
Label nonzero;
masm.Cbnz(rhsreg, &nonzero);
masm.Cmp(dest, Operand(0));
bailoutIf(Assembler::LessThan, ins->snapshot());
masm.bind(&nonzero);
}
break;
default:
MOZ_CRASH("Unexpected shift op");
}
}
} }
void void
CodeGenerator::visitUrshD(LUrshD* ins) CodeGenerator::visitUrshD(LUrshD* ins)
{ {
MOZ_CRASH("visitUrshD"); const ARMRegister lhs = toWRegister(ins->lhs());
const LAllocation* rhs = ins->rhs();
const FloatRegister out = ToFloatRegister(ins->output());
const Register temp = ToRegister(ins->temp());
const ARMRegister temp32 = toWRegister(ins->temp());
if (rhs->isConstant()) {
int32_t shift = ToInt32(rhs) & 0x1F;
if (shift) {
masm.Lsr(temp32, lhs, shift);
masm.convertUInt32ToDouble(temp, out);
} else {
masm.convertUInt32ToDouble(ToRegister(ins->lhs()), out);
}
} else {
masm.And(temp32, toWRegister(rhs), Operand(0x1F));
masm.Lsr(temp32, lhs, temp32);
masm.convertUInt32ToDouble(temp, out);
}
} }
void void