[JAEGER] Implement branchTruncateDoubleToInt32 for ARM. [Bug 585918] [r=dmandelin]

This commit is contained in:
Jacob Bramley 2010-08-11 15:23:22 +01:00
parent 6e99eea69c
commit fc7096bbbe
2 changed files with 28 additions and 8 deletions

View File

@ -205,6 +205,7 @@ namespace JSC {
FMRS = 0x0e100a10, FMRS = 0x0e100a10,
FSITOD = 0x0eb80bc0, FSITOD = 0x0eb80bc0,
FTOSID = 0x0ebd0b40, FTOSID = 0x0ebd0b40,
FTOSIZD = 0x0ebd0bc0,
FMSTAT = 0x0ef1fa10 FMSTAT = 0x0ef1fa10
#if WTF_ARM_ARCH_VERSION >= 5 #if WTF_ARM_ARCH_VERSION >= 5
,CLZ = 0x016f0f10, ,CLZ = 0x016f0f10,
@ -426,6 +427,12 @@ namespace JSC {
emitInst(static_cast<ARMWord>(cc) | CMP | SET_CC, 0, rn, op2); emitInst(static_cast<ARMWord>(cc) | CMP | SET_CC, 0, rn, op2);
} }
void cmn_r(int rn, ARMWord op2, Condition cc = AL)
{
spewInsWithOp2("cmn", cc, rn, op2);
emitInst(static_cast<ARMWord>(cc) | CMN | SET_CC, 0, rn, op2);
}
void orr_r(int rd, int rn, ARMWord op2, Condition cc = AL) void orr_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{ {
spewInsWithOp2("orr", cc, rd, rn, op2); spewInsWithOp2("orr", cc, rd, rn, op2);
@ -673,16 +680,18 @@ namespace JSC {
void fdtr_u(bool isLoad, int dd, int rn, ARMWord offset, Condition cc = AL) void fdtr_u(bool isLoad, int dd, int rn, ARMWord offset, Condition cc = AL)
{ {
char const * ins = isLoad ? "vldr.f64" : "vstr.f64";
js::JaegerSpew(js::JSpew_Insns, js::JaegerSpew(js::JSpew_Insns,
IPFX "%-15s %s, [%s, #+%u]\n", MAYBE_PAD, "vldr.f64", nameFpRegD(dd), nameGpReg(rn), offset); IPFX "%-15s %s, [%s, #+%u]\n", MAYBE_PAD, ins, nameFpRegD(dd), nameGpReg(rn), offset);
ASSERT(offset <= 0xff); ASSERT(offset <= 0xff);
emitInst(static_cast<ARMWord>(cc) | FDTR | DT_UP | (isLoad ? DT_LOAD : 0), dd, rn, offset); emitInst(static_cast<ARMWord>(cc) | FDTR | DT_UP | (isLoad ? DT_LOAD : 0), dd, rn, offset);
} }
void fdtr_d(bool isLoad, int dd, int rn, ARMWord offset, Condition cc = AL) void fdtr_d(bool isLoad, int dd, int rn, ARMWord offset, Condition cc = AL)
{ {
char const * ins = isLoad ? "vldr.f64" : "vstr.f64";
js::JaegerSpew(js::JSpew_Insns, js::JaegerSpew(js::JSpew_Insns,
IPFX "%-15s %s, [%s, #-%u]\n", MAYBE_PAD, "vldr.f64", nameFpRegD(dd), nameGpReg(rn), offset); IPFX "%-15s %s, [%s, #-%u]\n", MAYBE_PAD, ins, nameFpRegD(dd), nameGpReg(rn), offset);
ASSERT(offset <= 0xff); ASSERT(offset <= 0xff);
emitInst(static_cast<ARMWord>(cc) | FDTR | (isLoad ? DT_LOAD : 0), dd, rn, offset); emitInst(static_cast<ARMWord>(cc) | FDTR | (isLoad ? DT_LOAD : 0), dd, rn, offset);
} }
@ -741,6 +750,13 @@ namespace JSC {
emitInst(static_cast<ARMWord>(cc) | FTOSID, fd, 0, dm); emitInst(static_cast<ARMWord>(cc) | FTOSID, fd, 0, dm);
} }
void ftosizd_r(int fd, int dm, Condition cc = AL)
{
// TODO: emitInst doesn't work for VFP instructions, though it
// seems to work for current usage.
emitInst(static_cast<ARMWord>(cc) | FTOSIZD, fd, 0, dm);
}
void fmstat(Condition cc = AL) void fmstat(Condition cc = AL)
{ {
// TODO: emitInst doesn't work for VFP instructions, though it // TODO: emitInst doesn't work for VFP instructions, though it

View File

@ -853,7 +853,7 @@ public:
bool supportsFloatingPointTruncate() const bool supportsFloatingPointTruncate() const
{ {
return false; return true;
} }
bool supportsFloatingPointSqrt() const bool supportsFloatingPointSqrt() const
@ -972,13 +972,17 @@ public:
// Truncates 'src' to an integer, and places the resulting 'dest'. // Truncates 'src' to an integer, and places the resulting 'dest'.
// If the result is not representable as a 32 bit value, branch. // If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits // May also branch for some values that are representable in 32 bits
// (specifically, in this case, INT_MIN). // (specifically, in this case, INT_MIN and INT_MAX).
Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest) Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
{ {
(void)(src); m_assembler.ftosizd_r(ARMRegisters::SD0, src);
(void)(dest); // If FTOSIZD (VCVT.S32.F64) can't fit the result into a 32-bit
ASSERT_NOT_REACHED(); // integer, it saturates at INT_MAX or INT_MIN. Testing this is
return jump(); // probably quicker than testing FPSCR for exception.
m_assembler.fmrs_r(dest, ARMRegisters::SD0);
m_assembler.cmn_r(dest, ARMAssembler::getOp2(1));
m_assembler.cmp_r(dest, ARMAssembler::getOp2(0x80000000), ARMCondition(NonZero));
return Jump(m_assembler.jmp(ARMCondition(Zero)));
} }
// Convert 'src' to an integer, and places the resulting 'dest'. // Convert 'src' to an integer, and places the resulting 'dest'.