Fixed 2 floating point bugs; improved debug output; armv7-a thumb2 inline sqrt
diff --git a/vm/compiler/codegen/arm/ArchUtility.c b/vm/compiler/codegen/arm/ArchUtility.c
index 6d1a261..abcb2eb 100644
--- a/vm/compiler/codegen/arm/ArchUtility.c
+++ b/vm/compiler/codegen/arm/ArchUtility.c
@@ -62,6 +62,12 @@
assert((unsigned)(nc-'0') < 3);
operand = lir->operands[nc-'0'];
switch(*fmt++) {
+ case 's':
+ sprintf(tbuf,"s%d",operand & FP_REG_MASK);
+ break;
+ case 'S':
+ sprintf(tbuf,"d%d",(operand & FP_REG_MASK) >> 1);
+ break;
case 'h':
sprintf(tbuf,"%04x", operand);
break;
diff --git a/vm/compiler/codegen/arm/ArmLIR.h b/vm/compiler/codegen/arm/ArmLIR.h
index ed02bae..b43dab0 100644
--- a/vm/compiler/codegen/arm/ArmLIR.h
+++ b/vm/compiler/codegen/arm/ArmLIR.h
@@ -254,6 +254,10 @@
[10101100] vm[3..0] */
THUMB2_VCVTDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
[10111100] vm[3..0] */
+ THUMB2_VSQRTS, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
+ [10101100] vm[3..0] */
+ THUMB2_VSQRTD, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
+ [10111100] vm[3..0] */
ARM_LAST,
} ArmOpCode;
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index 5a87014..fb85253 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -63,6 +63,8 @@
* u -> 1st half of bl[x] target
* v -> 2nd half ob bl[x] target
* R -> register list
+ * s -> single precision floating point register
+ * S -> double precision floating point register
*
* [!] escape. To insert "!", use "!!"
*/
@@ -364,75 +366,83 @@
ENCODING_MAP(THUMB2_VLDRS, 0xed900a00,
SFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
IS_TERTIARY_OP,
- "vldr", "s!0d, [r!1d, #!2E]", 2),
+ "vldr", "!0s, [r!1d, #!2E]", 2),
ENCODING_MAP(THUMB2_VLDRD, 0xed900b00,
DFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
IS_TERTIARY_OP,
- "vldr", "d!0d, [r!1d, #!2E]", 2),
+ "vldr", "!0S, [r!1d, #!2E]", 2),
ENCODING_MAP(THUMB2_VMULS, 0xee200a00,
SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
IS_TERTIARY_OP,
- "vmuls", "s!0d, s!1d, s!2d", 2),
+ "vmuls", "!0s, !1s, !2s", 2),
ENCODING_MAP(THUMB2_VMULD, 0xee200b00,
DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
IS_TERTIARY_OP,
- "vmuld", "d!0d, d!1d, d!2d", 2),
+ "vmuld", "!0S, !1S, !2S", 2),
ENCODING_MAP(THUMB2_VSTRS, 0xed800a00,
SFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
IS_TERTIARY_OP,
- "vstr", "s!0d, [r!1d, #!2E]", 2),
+ "vstr", "!0s, [r!1d, #!2E]", 2),
ENCODING_MAP(THUMB2_VSTRD, 0xed800b00,
DFP, 22, 12, BITBLT, 19, 16, BITBLT, 7, 0,
IS_TERTIARY_OP,
- "vstr", "d!0d, [r!1d, #!2E]", 2),
+ "vstr", "!0S, [r!1d, #!2E]", 2),
ENCODING_MAP(THUMB2_VSUBS, 0xee300a40,
SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
IS_TERTIARY_OP,
- "vsub", "s!0d, s!1d, s!2d", 2),
+ "vsub", "!0s, !1s, !2s", 2),
ENCODING_MAP(THUMB2_VSUBD, 0xee300b40,
DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
IS_TERTIARY_OP,
- "vsub", "d!0d, s!1d, s!2d", 2),
+ "vsub", "!0S, !1S, !2S", 2),
ENCODING_MAP(THUMB2_VADDS, 0xee300a00,
SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
IS_TERTIARY_OP,
- "vadd", "s!0d, s!1d, s!2d", 2),
+ "vadd", "!0s, !1s, !2s", 2),
ENCODING_MAP(THUMB2_VADDD, 0xee300b00,
DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
IS_TERTIARY_OP,
- "vadd", "d!0d, s!1d, s!2d", 2),
+ "vadd", "!0S, !1S, !2S", 2),
ENCODING_MAP(THUMB2_VDIVS, 0xee800a00,
SFP, 22, 12, SFP, 7, 16, SFP, 5, 0,
IS_TERTIARY_OP,
- "vdivs", "s!0d, s!1d, s!2d", 2),
+ "vdivs", "!0s, !1s, !2s", 2),
ENCODING_MAP(THUMB2_VDIVD, 0xee800b00,
DFP, 22, 12, DFP, 7, 16, DFP, 5, 0,
IS_TERTIARY_OP,
- "vdivs", "s!0d, s!1d, s!2d", 2),
+ "vdivs", "!0S, !1S, !2S", 2),
ENCODING_MAP(THUMB2_VCVTIF, 0xeeb80ac0,
SFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
IS_BINARY_OP,
- "vcvf.f32", "s!0d, s!1d", 2),
+ "vcvt.f32", "!0s, !1s", 2),
ENCODING_MAP(THUMB2_VCVTID, 0xeeb80bc0,
DFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
IS_BINARY_OP,
- "vcvf.f64", "s!0d, s!1d", 2),
+ "vcvt.f64", "!0S, !1s", 2),
ENCODING_MAP(THUMB2_VCVTFI, 0xeebd0ac0,
SFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
IS_BINARY_OP,
- "vcvf.s32.f32", "s!0d, s!1d", 2),
+ "vcvt.s32.f32 ", "!0s, !1s", 2),
ENCODING_MAP(THUMB2_VCVTDI, 0xeebd0bc0,
SFP, 22, 12, DFP, 5, 0, UNUSED, -1, -1,
IS_BINARY_OP,
- "vcvf.s32.f64", "s!0d, s!1d", 2),
+ "vcvt.s32.f64 ", "!0s, !1S", 2),
ENCODING_MAP(THUMB2_VCVTFD, 0xeeb70ac0,
DFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
IS_BINARY_OP,
- "vcvf.f64.f32", "s!0d, s!1d", 2),
+ "vcvt.f64.f32 ", "!0S, !1s", 2),
ENCODING_MAP(THUMB2_VCVTDF, 0xeeb70bc0,
SFP, 22, 12, DFP, 5, 0, UNUSED, -1, -1,
IS_BINARY_OP,
- "vcvf.f32.f64", "s!0d, s!1d", 2),
+ "vcvt.f32.f64 ", "!0s, !1S", 2),
+ ENCODING_MAP(THUMB2_VSQRTS, 0xeeb10ac0,
+ SFP, 22, 12, SFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vsqrt.f32 ", "!0s, !1s", 2),
+ ENCODING_MAP(THUMB2_VSQRTD, 0xeeb10bc0,
+ DFP, 22, 12, DFP, 5, 0, UNUSED, -1, -1,
+ IS_BINARY_OP,
+ "vsqrt.f64 ", "!0S, !1S", 2),
};
#define PADDING_MOV_R0_R0 0x1C00
diff --git a/vm/compiler/codegen/arm/Codegen.c b/vm/compiler/codegen/arm/Codegen.c
index 5b3f802..7d127f8 100644
--- a/vm/compiler/codegen/arm/Codegen.c
+++ b/vm/compiler/codegen/arm/Codegen.c
@@ -2817,17 +2817,17 @@
return genInlinedStringCharAt(cUnit, mir);
case INLINE_MATH_SQRT:
if (genInlineSqrt(cUnit, mir))
- return true;
+ return false;
else
break; /* Handle with C routine */
case INLINE_MATH_COS:
if (genInlineCos(cUnit, mir))
- return true;
+ return false;
else
break; /* Handle with C routine */
case INLINE_MATH_SIN:
if (genInlineSin(cUnit, mir))
- return true;
+ return false;
else
break; /* Handle with C routine */
case INLINE_MATH_ABS_FLOAT:
diff --git a/vm/compiler/codegen/arm/armv7-a/ArchVariant.c b/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
index 15ed078..794d754 100644
--- a/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
+++ b/vm/compiler/codegen/arm/armv7-a/ArchVariant.c
@@ -118,13 +118,13 @@
static bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir)
{
int offset = offsetof(InterpState, retval);
- OpCode opCode = mir->dalvikInsn.opCode;
int vSrc = mir->dalvikInsn.vA;
- loadValueAddress(cUnit, vSrc, r2);
- genDispatchToHandler(cUnit, TEMPLATE_SQRT_DOUBLE_VFP);
- newLIR3(cUnit, THUMB_STR_RRI5, r0, rGLUE, offset >> 2);
- newLIR3(cUnit, THUMB_STR_RRI5, r1, rGLUE, (offset >> 2) + 1);
- return false;
+ loadDouble(cUnit, vSrc, fr2);
+ newLIR2(cUnit, THUMB2_VSQRTD, fr0, fr2);
+ assert(offset & 0x3 == 0); /* Must be word aligned */
+ assert(offset < 1024);
+ newLIR3(cUnit, THUMB2_VSTRD, fr0, rGLUE, offset >> 2);
+ return true;
}
static bool genInlineCos(CompilationUnit *cUnit, MIR *mir)
@@ -272,7 +272,7 @@
else
loadFloat(cUnit, vSrc2, fr2);
newLIR2(cUnit, op, fr0, fr2);
- if (longSrc)
+ if (longDest)
storeDouble(cUnit, fr0, vSrc1Dest, 0);
else
storeFloat(cUnit, fr0, vSrc1Dest, 0);
diff --git a/vm/interp/Jit.c b/vm/interp/Jit.c
index ff17ef2..2bcb1f5 100644
--- a/vm/interp/Jit.c
+++ b/vm/interp/Jit.c
@@ -671,12 +671,12 @@
*/
s8 dvmJitd2l(double d)
{
- static const double kMaxLong = (double)0x7fffffffffffffffULL;
- static const double kMinLong = (double)0x8000000000000000ULL;
+ static const double kMaxLong = (double)(s8)0x7fffffffffffffffULL;
+ static const double kMinLong = (double)(s8)0x8000000000000000ULL;
if (d >= kMaxLong)
- return 0x7fffffffffffffffULL;
+ return (s8)0x7fffffffffffffffULL;
else if (d <= kMinLong)
- return 0x8000000000000000ULL;
+ return (s8)0x8000000000000000ULL;
else if (d != d) // NaN case
return 0;
else
@@ -685,12 +685,12 @@
s8 dvmJitf2l(float f)
{
- static const float kMaxLong = (float)0x7fffffffffffffffULL;
- static const float kMinLong = (float)0x8000000000000000ULL;
+ static const float kMaxLong = (float)(s8)0x7fffffffffffffffULL;
+ static const float kMinLong = (float)(s8)0x8000000000000000ULL;
if (f >= kMaxLong)
- return 0x7fffffffffffffffULL;
+ return (s8)0x7fffffffffffffffULL;
else if (f <= kMinLong)
- return 0x8000000000000000ULL;
+ return (s8)0x8000000000000000ULL;
else if (f != f) // NaN case
return 0;
else