summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/assembler
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/assembler')
-rw-r--r--JavaScriptCore/assembler/ARMAssembler.h12
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerARM.h16
2 files changed, 22 insertions, 6 deletions
diff --git a/JavaScriptCore/assembler/ARMAssembler.h b/JavaScriptCore/assembler/ARMAssembler.h
index da128e7..dfa726a 100644
--- a/JavaScriptCore/assembler/ARMAssembler.h
+++ b/JavaScriptCore/assembler/ARMAssembler.h
@@ -161,6 +161,7 @@ namespace JSC {
VMOV_ARM = 0x0e100a10,
VCVT_F64_S32 = 0x0eb80bc0,
VCVT_S32_F64 = 0x0ebd0b40,
+ VCVTR_S32_F64 = 0x0ebd0bc0,
VMRS_APSR = 0x0ef1fa10,
#if WTF_ARM_ARCH_AT_LEAST(5)
CLZ = 0x016f0f10,
@@ -371,6 +372,11 @@ namespace JSC {
emitInst(static_cast<ARMWord>(cc) | CMP | SET_CC, 0, rn, op2);
}
+ void cmn_r(int rn, ARMWord op2, Condition cc = AL)
+ {
+ emitInst(static_cast<ARMWord>(cc) | CMN | SET_CC, 0, rn, op2);
+ }
+
void orr_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
emitInst(static_cast<ARMWord>(cc) | ORR, rd, rn, op2);
@@ -578,6 +584,12 @@ namespace JSC {
emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_S32_F64, (sd >> 1), 0, dm);
}
+ void vcvtr_s32_f64_r(int sd, int dm, Condition cc = AL)
+ {
+ ASSERT(!(sd & 0x1)); // sd must be divisible by 2
+ emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVTR_S32_F64, (sd >> 1), 0, dm);
+ }
+
void vmrs_apsr(Condition cc = AL)
{
m_buffer.putInt(static_cast<ARMWord>(cc) | VMRS_APSR);
diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h
index 48ddf24..5de8b34 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -769,7 +769,7 @@ public:
bool supportsFloatingPointTruncate() const
{
- return false;
+ return s_isVFPPresent;
}
bool supportsFloatingPointSqrt() const
@@ -878,13 +878,17 @@ public:
// Truncates 'src' to an integer, and places the resulting 'dest'.
// If the result is not representable as a 32 bit value, branch.
// 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)
{
- UNUSED_PARAM(src);
- UNUSED_PARAM(dest);
- ASSERT_NOT_REACHED();
- return jump();
+ m_assembler.vcvtr_s32_f64_r(ARMRegisters::SD0 << 1, src);
+ // If VCVTR.S32.F64 can't fit the result into a 32-bit
+ // integer, it saturates at INT_MAX or INT_MIN. Testing this is
+ // probably quicker than testing FPSCR for exception.
+ m_assembler.vmov_arm_r(dest, ARMRegisters::SD0 << 1);
+ m_assembler.sub_r(ARMRegisters::S0, dest, ARMAssembler::getOp2(0x80000000));
+ m_assembler.cmn_r(ARMRegisters::S0, ARMAssembler::getOp2(1), ARMCondition(NotEqual));
+ return Jump(m_assembler.jmp(ARMCondition(Equal)));
}
// Convert 'src' to an integer, and places the resulting 'dest'.