From bfafdbfec33e0dc1d1bda0d0cfe2fd0555c45acc Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Wed, 11 Sep 2013 20:17:50 +0000 Subject: [PATCH] rewrite the ARM port of GNU lightning to a form compatible with the versions for the other CPUs --- src/runtime/c/pgf/lightning/arm/asm.h | 889 ++-- src/runtime/c/pgf/lightning/arm/core.h | 4599 +++++++++------------ src/runtime/c/pgf/lightning/arm/fp-swf.h | 3 +- src/runtime/c/pgf/lightning/arm/fp-vfp.h | 3 + src/runtime/c/pgf/lightning/arm/fp.h | 7 +- src/runtime/c/pgf/lightning/arm/funcs.h | 278 +- src/runtime/c/pgf/lightning/asm-common.h | 2 + src/runtime/c/pgf/lightning/core-common.h | 8 + 8 files changed, 2525 insertions(+), 3264 deletions(-) diff --git a/src/runtime/c/pgf/lightning/arm/asm.h b/src/runtime/c/pgf/lightning/arm/asm.h index 6d5351d1c..c60ae2224 100644 --- a/src/runtime/c/pgf/lightning/arm/asm.h +++ b/src/runtime/c/pgf/lightning/arm/asm.h @@ -102,7 +102,6 @@ typedef enum { /* match vfpv3 result */ #define NAN_TO_INT_IS_ZERO 1 -#define jit_thumb_p() jit_cpu.thumb #define jit_armv6_p() (jit_cpu.version >= 6) typedef union _jit_thumb_t { int i; @@ -110,13 +109,13 @@ typedef union _jit_thumb_t { } jit_thumb_t; #if __BYTE_ORDER == __LITTLE_ENDIAN -# define _jit_WW(i, j) do { _jit_W(j); _jit_W(i); } while (0) -# define code2thumb(t0, t1, c0, c1) do { t1 = c0; t0 = c1; } while (0) -# define thumb2code(t0, t1, c0, c1) do { c0 = t1; c1 = t0; } while (0) +# define _jit_WW(i, j) (_jit_W(j), _jit_W(i)) +# define code2thumb(t0, t1, c0, c1) (t1 = c0, t0 = c1) +# define thumb2code(t0, t1, c0, c1) (c0 = t1, c1 = t0) #else -# define _jit_WW(i, j) do { _jit_W(i); _jit_W(j); } while (0) -# define code2thumb(t0, t1, c0, c1) do { t0 = c0; t1 = c1; } while (0) -# define thumb2code(t0, t1, c0, c1) do { c0 = t0; c1 = t1; } while (0) +# define _jit_WW(i, j) (_jit_W(i), _jit_W(j)) +# define code2thumb(t0, t1, c0, c1) (t0 = c0, t1 = c1) +# define thumb2code(t0, t1, c0, c1) (c0 = t0, c1 = t1) #endif #define ARM_CC_EQ 0x00000000 /* Z=1 */ @@ -625,318 +624,111 @@ success: } imm = ((imm & 0x80) << 17) | ((imm & 0x70) << 12) | (imm & 0x0f); code |= mode | imm; - if (jit_thumb_p()) { +#ifdef USE_THUMB_CODE if (code & 0x1000000) code |= 0xff000000; else code |= 0xef000000; - } - else +#else code |= ARM_CC_NV; +#endif return (code); } -#define arm_vodi(oi,r0) _arm_vodi(_jit,oi,r0) -__jit_inline void -_arm_vodi(jit_state_t _jit, int oi, int r0) -{ - jit_thumb_t thumb; - assert(!(oi & 0x0000f000)); - assert(!(r0 & 1)); r0 >>= 1; - thumb.i = oi|(_u4(r0)<<12); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#ifdef USE_THUMB_CODE +#define _jit_TI(I) (_jitl.thumb.i = (I), _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) +#else +#define _jit_TI(I) _jit_I(I) +#endif -#define arm_voqi(oi,r0) _arm_voqi(_jit,oi,r0) -__jit_inline void -_arm_voqi(jit_state_t _jit, int oi, int r0) -{ - jit_thumb_t thumb; - assert(!(oi & 0x0000f000)); - assert(!(r0 & 3)); r0 >>= 1; - thumb.i = oi|(_u4(r0)<<12); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vodi(oi,r0) \ + (assert(!((oi) & 0x0000f000) && !((r0) & 1)), \ + _jit_TI((oi)|(_u4((r0) >> 1)<<12))) -#define arm_vo_ss(o,r0,r1) _arm_cc_vo_ss(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vo_ss(cc,o,r0,r1) _arm_cc_vo_ss(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vo_ss(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - if (r0 & 1) o |= ARM_V_D; r0 >>= 1; - if (r1 & 1) o |= ARM_V_M; r1 >>= 1; - thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_voqi(oi,r0) \ + (assert(!((oi) & 0x0000f000) && !((r0) & 3)), \ + _jit_TI((oi)|(_u4((r0) >> 1)<<12))) -#define arm_vo_dd(o,r0,r1) _arm_cc_vo_dd(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vo_dd(cc,o,r0,r1) _arm_cc_vo_dd(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vo_dd(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - assert(!(r0 & 1) && !(r1 & 1)); - r0 >>= 1; r1 >>= 1; - thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vo_ss(o,r0,r1) _arm_cc_vo_ss(ARM_CC_NV,o,r0,r1) +#define arm_cc_vo_ss(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f)), \ + _jit_TI((cc)|(o) | (((r0) & 1) ? ARM_V_D : 0) | (((r1) & 1) ? ARM_V_M : 0)|(_u4((r0) >> 1)<<12)|_u4((r1) >> 1))) -#define arm_vo_qd(o,r0,r1) _arm_cc_vo_qd(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vo_qd(cc,o,r0,r1) _arm_cc_vo_qd(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vo_qd(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - assert(!(r0 & 3) && !(r1 & 1)); - r0 >>= 1; r1 >>= 1; - thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vo_dd(o,r0,r1) _arm_cc_vo_dd(ARM_CC_NV,o,r0,r1) +#define arm_cc_vo_dd(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f) && !((r0) & 1) && !((r1) & 1)), \ + _jit_TI((cc)|(o)|(_u4((r0) >> 1)<<12)|_u4((r1) >> 1))) -#define arm_vo_qq(o,r0,r1) _arm_cc_vo_qq(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vo_qq(cc,o,r0,r1) _arm_cc_vo_qq(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vo_qq(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - assert(!(r0 & 3) && !(r1 & 3)); - r0 >>= 1; r1 >>= 1; - thumb.i = cc|o|(_u4(r0)<<12)|_u4(r1); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vo_qd(o,r0,r1) arm_cc_vo_qd(ARM_CC_NV,o,r0,r1) +#define arm_cc_vo_qd(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f) && !((r0) & 3) && !((r1) & 1)), \ + _jit_TI((cc)|(o)|(_u4((r0) >> 1)<<12)|_u4((r1) >> 1))) -#define arm_vorr_(o,r0,r1) _arm_cc_vorr_(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vorr_(cc,o,r0,r1) _arm_cc_vorr_(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vorr_(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vo_qq(o,r0,r1) arm_cc_vo_qq(ARM_CC_NV,o,r0,r1) +#define arm_cc_vo_qq(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f) && !((r0) & 3) && !((r1) & 3)), \ + _jit_TI((cc)|(o)|(_u4((r0) >> 1)<<12)|_u4((r1) >> 1))) -#define arm_vors_(o,r0,r1) _arm_cc_vors_(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vors_(cc,o,r0,r1) _arm_cc_vors_(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vors_(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - if (r1 & 1) o |= ARM_V_N; r1 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vorr_(o,r0,r1) arm_cc_vorr_(ARM_CC_NV,o,r0,r1) +#define arm_cc_vorr_(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f)), \ + _jit_TI((cc)|(o)|(_u4(r1)<<16)|(_u4(r0)<<12))) -#define arm_vorv_(o,r0,r1) _arm_cc_vorv_(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vorv_(cc,o,r0,r1) _arm_cc_vorv_(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vorv_(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - if (r1 & 1) cc |= ARM_V_M; r1 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vors_(o,r0,r1) arm_cc_vors_(ARM_CC_NV,o,r0,r1) +#define arm_cc_vors_(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f)), \ + _jit_TI((cc)|(o)|(((r1) & 1) ? ARM_V_N : 0)|(_u4(r1 >> 1)<<16)|(_u4(r0)<<12))) -#define arm_vori_(o,r0,r1) _arm_cc_vori_(_jit,ARM_CC_NV,o,r0,r1) -#define arm_cc_vori_(cc,o,r0,r1) _arm_cc_vori_(_jit,cc,o,r0,r1) -__jit_inline void -_arm_cc_vori_(jit_state_t _jit, int cc, int o, int r0, int r1) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - /* use same bit pattern, to set opc1... */ - if (r1 & 1) o |= ARM_V_I32; r1 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vorv_(o,r0,r1) arm_cc_vorv_(ARM_CC_NV,o,r0,r1) +#define arm_cc_vorv_(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && ((o) & 0xf000f00f)), \ + _jit_TI((cc)|(o)|(((r1) & 1) ? ARM_V_M : 0)|(_u4((r1) >> 1)<<16)|(_u4(r0)<<12))) -#define arm_vorrd(o,r0,r1,r2) _arm_cc_vorrd(_jit,ARM_CC_NV,o,r0,r1,r2) -#define arm_cc_vorrd(cc,o,r0,r1,r2) _arm_cc_vorrd(_jit,cc,o,r0,r1,r2) -__jit_inline void -_arm_cc_vorrd(jit_state_t _jit, int cc, int o, int r0, int r1, int r2) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff00f)); - assert(!(r2 & 1)); - r2 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vori_(o,r0,r1) arm_cc_vori_(ARM_CC_NV,o,r0,r1) +#define arm_cc_vori_(cc,o,r0,r1) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f)), \ + /* use same bit pattern, to set opc1... */ \ + _jit_TI((cc)|(o)|((r1 & 1) ? ARM_V_I32 : 0)|(_u4((r1) >> 1)<<16)|(_u4(r0)<<12))) -#define arm_vosss(o,r0,r1,r2) _arm_cc_vosss(_jit,ARM_CC_NV,o,r0,r1,r2) -#define arm_cc_vosss(cc,o,r0,r1,r2) _arm_cc_vosss(_jit,cc,o,r0,r1,r2) -__jit_inline void -_arm_cc_vosss(jit_state_t _jit, int cc, int o, int r0, int r1, int r2) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff00f)); - if (r0 & 1) o |= ARM_V_D; r0 >>= 1; - if (r1 & 1) o |= ARM_V_N; r1 >>= 1; - if (r2 & 1) o |= ARM_V_M; r2 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vorrd(o,r0,r1,r2) arm_cc_vorrd(ARM_CC_NV,o,r0,r1,r2) +#define arm_cc_vorrd(cc,o,r0,r1,r2) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff00f) && !((r2) & 1)), \ + _jit_TI((cc)|(o)|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4((r2) >> 1))) -#define arm_voddd(o,r0,r1,r2) _arm_cc_voddd(_jit,ARM_CC_NV,o,r0,r1,r2) -#define arm_cc_voddd(cc,o,r0,r1,r2) _arm_cc_voddd(_jit,cc,o,r0,r1,r2) -__jit_inline void -_arm_cc_voddd(jit_state_t _jit, int cc, int o, int r0, int r1, int r2) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff00f)); - assert(!(r0 & 1) && !(r1 & 1) && !(r2 & 1)); - r0 >>= 1; r1 >>= 1; r2 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_vosss(o,r0,r1,r2) arm_cc_vosss(ARM_CC_NV,o,r0,r1,r2) +#define arm_cc_vosss(cc,o,r0,r1,r2) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff00f)), \ + _jit_TI((cc)|(o)|(((r0) & 1) ? ARM_V_D : 0)|(((r1) & 1) ? ARM_V_N : 0)|(((r2) & 1) ? ARM_V_M : 0)|(_u4((r1) >> 1)<<16)|(_u4((r0) >> 1)<<12)|_u4((r2) >> 1))) -#define arm_voqdd(o,r0,r1,r2) _arm_cc_voqdd(_jit,ARM_CC_NV,o,r0,r1,r2) -#define arm_cc_voqdd(cc,o,r0,r1,r2) _arm_cc_voqdd(_jit,cc,o,r0,r1,r2) -__jit_inline void -_arm_cc_voqdd(jit_state_t _jit, int cc, int o, int r0, int r1, int r2) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff00f)); - assert(!(r0 & 3) && !(r1 & 1) && !(r2 & 1)); - r0 >>= 1; r1 >>= 1; r2 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_voddd(o,r0,r1,r2) arm_cc_voddd(ARM_CC_NV,o,r0,r1,r2) +#define arm_cc_voddd(cc,o,r0,r1,r2) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff00f) && !((r0) & 1) && !((r1) & 1) && !((r2) & 1)), \ + _jit_TI((cc)|(o)|(_u4((r1) >> 1)<<16)|(_u4((r0) >> 1)<<12)|_u4((r2) >> 1))) -#define arm_voqqd(o,r0,r1,r2) _arm_cc_voqqd(_jit,ARM_CC_NV,o,r0,r1,r2) -#define arm_cc_voqqd(cc,o,r0,r1,r2) _arm_cc_voqqd(_jit,cc,o,r0,r1,r2) -__jit_inline void -_arm_cc_voqqd(jit_state_t _jit, int cc, int o, int r0, int r1, int r2) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff00f)); - assert(!(r0 & 3) && !(r1 & 3) && !(r2 & 1)); - r0 >>= 1; r1 >>= 1; r2 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_voqdd(o,r0,r1,r2) arm_cc_voqdd(ARM_CC_NV,o,r0,r1,r2) +#define arm_cc_voqdd(cc,o,r0,r1,r2) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff00f) && !((r0) & 3) && !((r1) & 1) && !((r2) & 1)), \ + _jit_TI((cc)|(o)|(_u4((r1) >> 1)<<16)|(_u4((r0) >> 1)<<12)|_u4((r2) >> 1))) -#define arm_voqqq(o,r0,r1,r2) _arm_cc_voqqq(_jit,ARM_CC_NV,o,r0,r1,r2) -#define arm_cc_voqqq(cc,o,r0,r1,r2) _arm_cc_voqqq(_jit,cc,o,r0,r1,r2) -__jit_inline void -_arm_cc_voqqq(jit_state_t _jit, int cc, int o, int r0, int r1, int r2) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff00f)); - assert(!(r0 & 3) && !(r1 & 3) && !(r2 & 3)); - r0 >>= 1; r1 >>= 1; r2 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u4(r2); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_voqqd(o,r0,r1,r2) arm_cc_voqqd(ARM_CC_NV,o,r0,r1,r2) +#define arm_cc_voqqd(cc,o,r0,r1,r2) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff00f) && !((r0) & 3) && !((r1) & 3) && !((r2) & 1)), \ + _jit_TI((cc)|(o)|(_u4((r1) >> 1)<<16)|(_u4((r0) >> 1)<<12)|_u4((r2) >> 1))) -#define arm_cc_vldst(cc,o,r0,r1,i0) _arm_cc_vldst(_jit,cc,o,r0,r1,i0) -__jit_inline void -_arm_cc_vldst(jit_state_t _jit, int cc, int o, int r0, int r1, int i0) -{ - jit_thumb_t thumb; - /* i0 << 2 is byte offset */ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff0ff)); - if (r0 & 1) { - assert(!(o & ARM_V_F64)); - o |= ARM_V_D; - } - r0 >>= 1; - thumb.i = cc|o|(_u4(r1)<<16)|(_u4(r0)<<12)|_u8(i0); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_voqqq(o,r0,r1,r2) arm_cc_voqqq(ARM_CC_NV,o,r0,r1,r2) +#define arm_cc_voqqq(cc,o,r0,r1,r2) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff00f) && !((r0) & 3) && !((r1) & 3) && !((r2) & 3)), \ + _jit_TI((cc)|(o)|(_u4((r1) >> 1)<<16)|(_u4((r0) >> 1)<<12)|_u4((r2) >> 1))) -#define arm_cc_vorsl(cc,o,r0,r1,i0) _arm_cc_vorsl(_jit,cc,o,r0,r1,i0) -__jit_inline void -_arm_cc_vorsl(jit_state_t _jit, int cc, int o, int r0, int r1, int i0) -{ - jit_thumb_t thumb; - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff0ff)); - /* save i0 double precision registers */ - if (o & ARM_V_F64) i0 <<= 1; - assert(i0 && !(i0 & 1) && r1 + i0 <= 32); - /* if (r1 & 1) cc & ARM_V_F64 must be false */ - if (r1 & 1) o |= ARM_V_D; r1 >>= 1; - thumb.i = cc|o|(_u4(r0)<<16)|(_u4(r1)<<12)|_u8(i0); - if (jit_thumb_p()) - _jit_WW(thumb.s[0], thumb.s[1]); - else - _jit_I(thumb.i); -} +#define arm_cc_vldst(cc,o,r0,r1,i0) \ + /* i0 << 2 is byte offset */ \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff0ff) && (!((r0) & 1) | !((o) & ARM_V_F64))), \ + _jit_TI((cc)|(o)|(((r0) & 1) ? ARM_V_D : 0)|(_u4(r1)<<16)|(_u4((r0) >> 1)<<12)|_u8(i0))) + +#define arm_cc_vorsl(cc,o,r0,r1,i0) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff0ff)), \ + /* save i0 double precision registers */ \ + _jit_TI((cc)|((o) | ((r1) & 1) ? ARM_V_D : 0)|(_u4(r0)<<16)|(_u4((r1) >> 1)<<12)|_u8(((o) & ARM_V_F64) ? ((i0) << 1) : (i0)))) /*********************************************************************** * VFPv2 and VFPv3 (encoding T2/A2) instructions @@ -1247,117 +1039,53 @@ encode_arm_immediate(unsigned int v) return (-1); } -#define corrr(cc,o,rn,rd,rm) _corrr(_jit,cc,o,rn,rd,rm) -__jit_inline void -_corrr(jit_state_t _jit, int cc, int o, int rn, int rd, int rm) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00fff0f)); - _jit_I(cc|o|(_u4(rn)<<16)|(_u4(rd)<<12)|_u4(rm)); -} +#define corrr(cc,o,rn,rd,rm) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00fff0f)), \ + _jit_I((cc)|(o)|(_u4(rn)<<16)|(_u4(rd)<<12)|_u4(rm))) -#define corri(cc,o,rn,rd,im) _corri(_jit,cc,o,rn,rd,im) -__jit_inline void -_corri(jit_state_t _jit, int cc, int o, int rn, int rd, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00fffff)); - assert(!(im & 0xfffff000)); - _jit_I(cc|o|(_u4(rn)<<16)|(_u4(rd)<<12)|_u12(im)); -} +#define corri(cc,o,rn,rd,im) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00fffff) && !((im) & 0xfffff000)), \ + _jit_I((cc)|(o)|(_u4(rn)<<16)|(_u4(rd)<<12)|_u12(im))) -#define coriw(cc,o,rd,im) _coriw(_jit,cc,o,rd,im) -__jit_inline void -_coriw(jit_state_t _jit, int cc, int o, int rd, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00fffff)); - assert(!(im & 0xffff0000)); - _jit_I(cc|o|((im&0xf000)<<4)|(_u4(rd)<<12)|(im&0xfff)); -} +#define coriw(cc,o,rd,im) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00fffff) && !(im & 0xffff0000)), \ + _jit_I((cc)|(o)|((im&0xf000)<<4)|(_u4(rd)<<12)|(im&0xfff))) -#define corri8(cc,o,rn,rt,im) _corri8(_jit,cc,o,rn,rt,im) -__jit_inline void -_corri8(jit_state_t _jit, int cc, int o, int rn, int rt, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00fff0f)); - assert(!(im & 0xffffff00)); - _jit_I(cc|o|(_u4(rn)<<16)|(_u4(rt)<<12)|((im&0xf0)<<4)|(im&0x0f)); -} +#define corri8(cc,o,rn,rt,im) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00fff0f) && !(im & 0xffffff00)), \ + _jit_I((cc)|(o)|(_u4(rn)<<16)|(_u4(rt)<<12)|((im&0xf0)<<4)|(im&0x0f))) -#define corrrr(cc,o,rh,rl,rm,rn) _corrrr(_jit,cc,o,rh,rl,rm,rn) -__jit_inline void -_corrrr(jit_state_t _jit, int cc, int o, int rh, int rl, int rm, int rn) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00fff0f)); - _jit_I(cc|o|(_u4(rh)<<16)|(_u4(rl)<<12)|(_u4(rm)<<8)|_u4(rn)); -} +#define corrrr(cc,o,rh,rl,rm,rn) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00fff0f)), \ + _jit_I((cc)|(o)|(_u4(rh)<<16)|(_u4(rl)<<12)|(_u4(rm)<<8)|_u4(rn))) -#define corrrs(cc,o,rn,rd,rm,im) _corrrs(_jit,cc,o,rn,rd,rm,im) -__jit_inline void -_corrrs(jit_state_t _jit, int cc, int o, int rn, int rd, int rm, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000ff8f)); - _jit_I(cc|o|(_u4(rd)<<12)|(_u4(rn)<<16)|(im<<7)|_u4(rm)); -} +#define corrrs(cc,o,rn,rd,rm,im) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000ff8f)), \ + _jit_I((cc)|(o)|(_u4(rd)<<12)|(_u4(rn)<<16)|(im<<7)|_u4(rm))) -#define cshift(cc,o,rd,rm,rn,im) _cshift(_jit,cc,o,rd,rm,rn,im) -__jit_inline void -_cshift(jit_state_t _jit, int cc, int o, int rd, int rm, int rn, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xffe0ff8f)); - assert(((_u4(rm)<<8)&(im<<7)) == 0); - _jit_I(cc|ARM_SHIFT|o|(_u4(rd)<<12)|(_u4(rm)<<8)|(im<<7)|_u4(rn)); -} +#define cshift(cc,o,rd,rm,rn,im) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xffe0ff8f) && ((_u4(rm)<<8)&(im<<7)) == 0), \ + _jit_I((cc)|ARM_SHIFT|(o)|(_u4(rd)<<12)|(_u4(rm)<<8)|(im<<7)|_u4(rn))) -#define cb(cc,o,im) _cb(_jit,cc,o,im) -__jit_inline void -_cb(jit_state_t _jit, int cc, int o, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf0ffffff)); - _jit_I(cc|o|_u24(im)); -} +#define cb(cc,o,im) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf0ffffff)), \ + _jit_I((cc)|(o)|_u24(im))) -#define cbx(cc,o,rm) _cbx(_jit,cc,o,rm) -__jit_inline void -_cbx(jit_state_t _jit, int cc, int o, int rm) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000000f)); - _jit_I(cc|o|_u4(rm)); -} +#define cbx(cc,o,rm) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000000f)), \ + _jit_I((cc)|(o)|_u4(rm))) -#define corl(cc,o,r0,i0) _corl(_jit,cc,o,r0,i0) -__jit_inline void -_corl(jit_state_t _jit, int cc, int o, int r0, int i0) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00fffff)); - _jit_I(cc|o|(_u4(r0)<<16)|_u16(i0)); -} +#define corl(cc,o,r0,i0) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00fffff)), \ + _jit_I((cc)|(o)|(_u4(r0)<<16)|_u16(i0))) -#define c6orr(cc,o,rd,rm) _c6orr(_jit,cc,o,rd,rm) -__jit_inline void -_c6orr(jit_state_t _jit, int cc, int o, int rd, int rm) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf000f00f)); - _jit_I(cc|o|(_u4(rd)<<12)|_u4(rm)); -} +#define c6orr(cc,o,rd,rm) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf000f00f)), \ + _jit_I((cc)|(o)|(_u4(rd)<<12)|_u4(rm))) -#define arm_cc_pkh(cc,o,rn,rd,rm,im) _arm_cc_pkh(_jit,cc,o,rn,rd,rm,im) -__jit_inline void -_arm_cc_pkh(jit_state_t _jit, int cc, int o, int rn, int rd, int rm, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(!(o & 0xf00ff00f)); - _jit_I(cc|o|(_u4(rn)<<16)|(_u4(rd)<<12)|(_u5(im)<<7)|_u4(rm)); -} +#define arm_cc_pkh(cc,o,rn,rd,rm,im) \ + (assert(!((cc) & 0x0fffffff) && !((o) & 0xf00ff00f)), \ + _jit_I((cc)|(o)|(_u4(rn)<<16)|(_u4(rd)<<12)|(_u5(im)<<7)|_u4(rm))) #define _CC_MOV(cc,rd,rm) corrr(cc,ARM_MOV,0,rd,rm) @@ -1887,223 +1615,106 @@ encode_thumb_shift(int v, int type) } #endif -#define thumb2_orri(o,rn,rd,im) _torri(_jit,o,rn,rd,im) -#define torri(o,rn,rt,im) _torri(_jit,o,rn,rt,im) -__jit_inline void -_torri(jit_state_t _jit, int o, int rn, int rd, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x0c0f7fff)); - assert(!(im & 0xfbff8f00)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rd)<<8)|im; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define thumb2_orri(o,rn,rd,im) torri(o,rn,rd,im) +#define torri(o,rn,rd,im) \ + (assert(!((o) & 0x0c0f7fff) && !((im) & 0xfbff8f00)), \ + _jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rd)<<8)|(im)), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define torri8(o,rn,rt,im) _torri8(_jit,o,rn,rt,im) -__jit_inline void -_torri8(jit_state_t _jit, int o, int rn, int rt, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x000ff0ff)); - assert(!(im & 0xffffff00)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|im; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torri8(o,rn,rt,im) \ + (assert(!((o) & 0x000ff0ff) && !((im) & 0xffffff00)), \ + _jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rt)<<12)|im), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define torri12(o,rn,rt,im) _torri12(_jit,o,rn,rt,im) -__jit_inline void -_torri12(jit_state_t _jit, int o, int rn, int rt, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x000fffff)); - assert(!(im & 0xfffff000)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|im; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torri12(o,rn,rt,im) \ + (assert(!((o) & 0x000fffff) && !((im) & 0xfffff000)), \ + _jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rt)<<12)|(im)), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define toriw(o,rd,im) _toriw(_jit,o,rd,im) -__jit_inline void -_toriw(jit_state_t _jit, int o, int rd, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x40f7fff)); - assert(!(im & 0xffff0000)); - thumb.i = o|((im&0xf000)<<4)|((im&0x800)<<15)|((im&0x700)<<4)|(_u4(rd)<<8)|(im&0xff); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define toriw(o,rd,im) \ + (assert(!((o) & 0x40f7fff) && !((im) & 0xffff0000)), \ + _jitl.thumb.i = ((o)|(((im)&0xf000)<<4)|(((im)&0x800)<<15)|(((im)&0x700)<<4)|(_u4(rd)<<8)|((im)&0xff)), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define torrr(o,rn,rd,rm) _torrr(_jit,o,rn,rd,rm) -__jit_inline void -_torrr(jit_state_t _jit, int o, int rn, int rd, int rm) -{ - jit_thumb_t thumb; - assert(!(o & 0xf0f0f)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rd)<<8)|_u4(rm); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torrr(o,rn,rd,rm) \ + (assert(!((o) & 0xf0f0f)), \ + _jit.jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rd)<<8)|_u4(rm)), \ + _jit_WW(_jit.jitl.thumb.s[0], _jit.jitl.thumb.s[1])) -#define torrrs(o,rn,rd,rm,im) _torrrs(_jit,o,rn,rd,rm,im) -__jit_inline void -_torrrs(jit_state_t _jit, int o, int rn, int rd, int rm, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x000f0f0f)); - assert(!(im & 0xffff8f0f)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rd)<<8)|im|_u4(rm); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torrrs(o,rn,rd,rm,im) \ + (assert(!((o) & 0x000f0f0f) && !((im) & 0xffff8f0f)), \ + _jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rd)<<8)|(im)|_u4(rm)), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define torxr(o,rn,rt,rm) _torxr(_jit,o,rn,rt,rm) -__jit_inline void -_torxr(jit_state_t _jit, int o, int rn, int rt, int rm) -{ - jit_thumb_t thumb; - assert(!(o & 0xf0f0f)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|_u4(rm); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torxr(o,rn,rt,rm) \ + (assert(!((o) & 0xf0f0f)), \ + _jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rt)<<12)|_u4(rm)) \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define torrrr(o,rn,rl,rh,rm) _torrrr(_jit,o,rn,rl,rh,rm) -__jit_inline void -_torrrr(jit_state_t _jit, int o, int rn, int rl, int rh, int rm) -{ - jit_thumb_t thumb; - assert(!(o & 0x000fff0f)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rl)<<12)|(_u4(rh)<<8)|_u4(rm); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torrrr(o,rn,rl,rh,rm) \ + (assert(!((o) & 0x000fff0f)), \ + _jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rl)<<12)|(_u4(rh)<<8)|_u4(rm)), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define torrri8(o,rn,rt,rt2,im) _torrri8(_jit,o,rn,rt,rt2,im) -__jit_inline void -_torrri8(jit_state_t _jit, int o, int rn, int rt, int rt2, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x000fffff)); - assert(!(im & 0xffffff00)); - thumb.i = o|(_u4(rn)<<16)|(_u4(rt)<<12)|(_u4(rt2)<<8)|im; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torrri8(o,rn,rt,rt2,im) \ + (assert(!((o) & 0x000fffff) && !((im) & 0xffffff00)), \ + _jitl.thumb.i = ((o)|(_u4(rn)<<16)|(_u4(rt)<<12)|(_u4(rt2)<<8)|(im)), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define tc8(cc,im) _tc8(_jit,cc,im) -__jit_inline void -_tc8(jit_state_t _jit, int cc, int im) -{ - assert(!(cc & 0x0fffffff)); - assert(cc != ARM_CC_AL && cc != ARM_CC_NV); - assert(_s8P(im)); - _jit_W(THUMB_CC_B|(cc>>20)|(im&0xff)); -} +#define tc8(cc,im) \ + (assert(!((cc) & 0x0fffffff) && ((cc) != ARM_CC_AL) && ((cc) != ARM_CC_NV) && _s8P(im)), \ + _jit_W(THUMB_CC_B|((cc)>>20)|((im)&0xff))) -#define t11(im) _t11(_jit,im) -__jit_inline void -_t11(jit_state_t _jit, int im) -{ - assert(!(im & 0xfffff800)); - _jit_W(THUMB_B|im); -} +#define t11(im) \ + (assert(!((im) & 0xfffff800)), \ + _jit_W(THUMB_B|(im))) -#define tcb(cc,im) _tcb(_jit,cc,im) -__jit_inline void -_tcb(jit_state_t _jit, int cc, int im) -{ - jit_thumb_t thumb; - assert(!(cc & 0xfffffff)); - assert(cc != ARM_CC_AL && cc != ARM_CC_NV); - cc = ((unsigned)cc) >> 6; - assert(!(im & (THUMB2_CC_B|cc))); - thumb.i = THUMB2_CC_B|cc|im; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define tcb(cc,im) \ + (assert(!((cc) & 0xfffffff) && ((cc) != ARM_CC_AL) && ((cc) != ARM_CC_NV) && !((im) & (THUMB2_CC_B|(((unsigned)cc) >> 6)))), \ + _jitl.thumb.i = THUMB2_CC_B|(((unsigned)(cc)) >> 6)|(im), \ + _jit_WW(_jitl.thumb.s[0], _jitl.thumb.s[1])) -#define blxi(im) _blxi(_jit,im) -__jit_inline void -_blxi(jit_state_t _jit, int im) -{ - assert(!(im & 0xfe000000)); - _jit_I(ARM_BLXI|im); -} +#define blxi(im) \ + (assert(!((im) & 0xfe000000)), \ + _jit_I(ARM_BLXI|(im))) -#define tb(o,im) _tb(_jit,o,im) -__jit_inline void -_tb(jit_state_t _jit, int o, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x07ff2fff)); - assert(!(o & im)); - thumb.i = o|im; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define tb(o,im) \ + (assert(!((o) & 0x07ff2fff) && !((o) & (im))), \ + jitl.thumb.i = (o)|(im), \ + _jit_WW(thumb.s[0], thumb.s[1])) -#define tshift(o,rd,rm,im) _tshift(_jit,o,rd,rm,im) -__jit_inline void -_tshift(jit_state_t _jit, int o, int rd, int rm, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x7fcf)); - assert(im >= 0 && im < 32); - thumb.i = o|((im&0x1c)<<10)|(_u4(rd)<<8)|((im&3)<<6)|_u4(rm); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define tshift(o,rd,rm,im) \ + (assert(!((o) & 0x7fcf) && ((im) >= 0) && ((im) < 32)), \ + thumb.i = (o|(((im)&0x1c)<<10)|(_u4(rd)<<8)|(((im)&3)<<6)|_u4(rm)), \ + _jit_WW(thumb.s[0], thumb.s[1])) -#define thumb2_orrr(o,rn,rd,rm) _thumb2_orrr(_jit,o,rn,rd,rm) -__jit_inline void -_thumb2_orrr(jit_state_t _jit, int o, int rn, int rd, int rm) -{ - jit_thumb_t thumb; - assert(!(o & 0x000f0f0f)); - thumb.i = o | (_u4(rn)<<16) | (_u4(rd)<<8) | _u4(rm); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define thumb2_orrr(o,rn,rd,rm) \ + (assert(!((o) & 0x000f0f0f)), \ + thumb.i = (o) | (_u4(rn)<<16) | (_u4(rd)<<8) | _u4(rm), \ + _jit_WW(thumb.s[0], thumb.s[1])) -#define thumb2_bfx(o,rn,rd,lsb,width) _thumb2_bfx(_jit,o,rn,rd,lsb,width) -__jit_inline void -_thumb2_bfx(jit_state_t _jit, int o, int rn, int rd, int lsb, int width) -{ - int msb; - jit_thumb_t thumb; - assert(!(o & 0x7fdf)); - assert(lsb >= 0 && lsb < 32 && width >= 0 && width <= 32); - msb = lsb + width; - if (msb > 31) - msb = 31; - thumb.i = o | (_u4(rn) << 16) | (_u4(rd) << 8) | - ((msb & 7) << 10) | ((msb & 3) << 5) | msb; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define thumb2_bfx(o,rn,rd,lsb,width) \ + (assert(!((o) & 0x7fdf) && ((lsb) >= 0) && ((lsb) < 32) && ((width) >= 0) && ((width) <= 32)), \ + thumb.i = (o) | (_u4(rn) << 16) | (_u4(rd) << 8) | \ + (((((lsb) + (width) > 31) ? 31 : (lsb) + (width)) & 7) << 10) | \ + (((((lsb) + (width) > 31) ? 31 : (lsb) + (width)) & 3) << 5) | \ + (((lsb) + (width) > 31) ? 31 : (lsb) + (width)), \ + _jit_WW(thumb.s[0], thumb.s[1])) -#define thumb2_cbxz(o,rn,im) _thumb2_cbxz(_jit,o,rn,im) -__jit_inline void -_thumb2_cbxz(jit_state_t _jit, int o, int rn, int im) -{ - assert(!(o & 0x2ff)); - /* branch forward only */ - assert(im >= 0 && im < 128 && !(im & 1)); - im >>= 1; - _jit_W(o|((im&0x80)<<5)|((im&0x1f)<<3)|_u3(rn)); -} +#define thumb2_cbxz(o,rn,im) \ + (assert(!((o) & 0x2ff) && (im) >= 0 && (im) < 128 && !((im) & 1)), \ + _jit_W((o)|((((im) >> 1)&0x80)<<5)|((((im) >> 1)&0x1f)<<3)|_u3(rn))) -#define thumb2_dbg(h,l,im) _thumb2_dbg(_jit,h,l,im) -__jit_inline void -_thumb2_dbg(jit_state_t _jit, int h, int l, int im) -{ - assert(!(h & ~0xffff)); - assert(!(l & 0xffff000f)); - _jit_WW(h, l | _u4(im)); -} +#define thumb2_dbg(h,l,im) \ + (assert(!((h) & ~0xffff) && !((l) & 0xffff000f)), \ + _jit_WW((h), (l) | _u4(im))) -#define tpp(o,im) _tpp(_jit,o,im) -__jit_inline void -_tpp(jit_state_t _jit, int o, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x0000ffff)); - assert(!(im & 0xffff2000)); - if (o == THUMB2_PUSH) - assert(!(im & 0x8000)); - assert(__builtin_popcount(im & 0x1fff) > 1); - thumb.i = o|im; - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define tpp(o,im) \ + (assert(!((o) & 0x0000ffff) && !((im) & 0xffff2000) && \ + (!((o) == THUMB2_PUSH) || !((im) & 0x8000)) && \ + (__builtin_popcount((im) & 0x1fff) > 1)), \ + _jit.jitl.thumb.i = (o)|(im), \ + _jit_WW(_jit.jitl.thumb.s[0], _jit.jitl.thumb.s[1])) #define THUMB2_IT 0 #define THUMB2_ITT 1 @@ -2120,35 +1731,26 @@ _tpp(jit_state_t _jit, int o, int im) #define THUMB2_ITETE 12 #define THUMB2_ITTEE 13 #define THUMB2_ITEEE 14 -#define tcit(tc,it) _tcit(_jit,tc,it) -__jit_inline void -_tcit(jit_state_t _jit, unsigned int tc, int it) -{ - int c; - int m; - c = (tc >> 28) & 1; - assert(!(tc & 0xfffffff) && tc != ARM_CC_NV); - switch (it) { - case THUMB2_IT: m = 1<<3; break; - case THUMB2_ITT: m = (c<<3)| (1<<2); break; - case THUMB2_ITE: m = (!c<<3)| (1<<2); break; - case THUMB2_ITTT: m = (c<<3)| (c<<2)| (1<<1); break; - case THUMB2_ITET: m = (!c<<3)| (c<<2)| (1<<1); break; - case THUMB2_ITTE: m = (c<<3)|(!c<<2)| (1<<1); break; - case THUMB2_ITEE: m = (!c<<3)|(!c<<2)| (1<<1); break; - case THUMB2_ITTTT: m = (c<<3)| (c<<2)| (c<<1)|1; break; - case THUMB2_ITETT: m = (!c<<3)| (c<<2)| (c<<1)|1; break; - case THUMB2_ITTET: m = (c<<3)|(!c<<2)| (c<<1)|1; break; - case THUMB2_ITEET: m = (!c<<3)|(!c<<2)| (c<<1)|1; break; - case THUMB2_ITTTE: m = (c<<3)| (c<<2)|(!c<<1)|1; break; - case THUMB2_ITETE: m = (!c<<3)| (c<<2)|(!c<<1)|1; break; - case THUMB2_ITTEE: m = (c<<3)|(!c<<2)|(!c<<1)|1; break; - case THUMB2_ITEEE: m = (!c<<3)|(!c<<2)|(!c<<1)|1; break; - default: assert(!"valid it code!"); - } - assert(m && (tc != ARM_CC_AL || !(m & (m - 1)))); - _jit_W(0xbf00 | (tc >> 24) | m); -} +#define tcit(tc,it) \ + (assert(!(tc & 0xfffffff) && tc != ARM_CC_NV), \ + _jit_W(0xbf00 | (tc >> 24) | \ + ((it == THUMB2_IT) ? 1<<3 : \ + (it == THUMB2_ITT) ? ((((tc) >> 28) & 1)<<3)| (1<<2) : \ + (it == THUMB2_ITE) ? (!(((tc) >> 28) & 1)<<3)| (1<<2) : \ + (it == THUMB2_ITTT) ? ((((tc) >> 28) & 1)<<3)| ((((tc) >> 28) & 1)<<2)| (1<<1) : \ + (it == THUMB2_ITET) ? (!(((tc) >> 28) & 1)<<3)| ((((tc) >> 28) & 1)<<2)| (1<<1) : \ + (it == THUMB2_ITTE) ? ((((tc) >> 28) & 1)<<3)|(!(((tc) >> 28) & 1)<<2)| (1<<1) : \ + (it == THUMB2_ITEE) ? (!(((tc) >> 28) & 1)<<3)|(!(((tc) >> 28) & 1)<<2)| (1<<1) : \ + (it == THUMB2_ITTTT) ? ((((tc) >> 28) & 1)<<3)| ((((tc) >> 28) & 1)<<2)| ((((tc) >> 28) & 1)<<1)|1 : \ + (it == THUMB2_ITETT) ? (!(((tc) >> 28) & 1)<<3)| ((((tc) >> 28) & 1)<<2)| ((((tc) >> 28) & 1)<<1)|1 : \ + (it == THUMB2_ITTET) ? ((((tc) >> 28) & 1)<<3)|(!(((tc) >> 28) & 1)<<2)| ((((tc) >> 28) & 1)<<1)|1 : \ + (it == THUMB2_ITEET) ? (!(((tc) >> 28) & 1)<<3)|(!(((tc) >> 28) & 1)<<2)| ((((tc) >> 28) & 1)<<1)|1 : \ + (it == THUMB2_ITTTE) ? ((((tc) >> 28) & 1)<<3)| ((((tc) >> 28) & 1)<<2)|(!(((tc) >> 28) & 1)<<1)|1 : \ + (it == THUMB2_ITETE) ? (!(((tc) >> 28) & 1)<<3)| ((((tc) >> 28) & 1)<<2)|(!(((tc) >> 28) & 1)<<1)|1 : \ + (it == THUMB2_ITTEE) ? ((((tc) >> 28) & 1)<<3)|(!(((tc) >> 28) & 1)<<2)|(!(((tc) >> 28) & 1)<<1)|1 : \ + (it == THUMB2_ITEEE) ? (!(((tc) >> 28) & 1)<<3)|(!(((tc) >> 28) & 1)<<2)|(!(((tc) >> 28) & 1)<<1)|1 : \ + assert(!"valid it code")))) + #define _IT(cc) tcit(cc,THUMB2_IT) #define _ITT(cc) tcit(cc,THUMB2_ITT) #define _ITE(cc) tcit(cc,THUMB2_ITE) @@ -2165,38 +1767,23 @@ _tcit(jit_state_t _jit, unsigned int tc, int it) #define _ITTEE(cc) tcit(cc,THUMB2_ITTEE) #define _ITEEE(cc) tcit(cc,THUMB2_ITEEE) -#define torl(o,rn,im) _torl(_jit,o,rn,im) -__jit_inline void -_torl(jit_state_t _jit, int o, int rn, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0xf1fff)); - assert(rn != _R15 || !im || ((o & 0xc000) == 0xc000)); - assert(!(o & THUMB2_LDM_W) || !(im & (1 << rn))); - thumb.i = o | (_u4(rn)<<16) | _u13(im); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define torl(o,rn,im) \ + (assert(!((o) & 0xf1fff) && \ + ((rn) != _R15 || !(im) || (((o) & 0xc000) == 0xc000)) && \ + !((o) & THUMB2_LDM_W) || !((im) & (1 << (rn)))), \ + thumb.i = ((o) | (_u4(rn)<<16) | _u13(im)), \ + _jit_WW(thumb.s[0], thumb.s[1])) -#define thumb2_mrrc(o,t2,t,cc,o1,m) _thumb2_mrrc(_jit,o,t2,t,cc,o1,m) -__jit_inline void -_thumb2_mrrc(jit_state_t _jit, int o, int t2, int t, int cc, int o1, int m) -{ - jit_thumb_t thumb; - assert(!(o & 0x03afffff)); - thumb.i = o|(_u4(t2)<<16)|(_u4(t)<<12)|(_u4(cc)<<8)|(_u4(o1)<<4)|_u4(m); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define thumb2_mrrc(o,t2,t,cc,o1,m) \ + (assert(!((o) & 0x03afffff)), \ + thumb.i = ((o)|(_u4(t2)<<16)|(_u4(t)<<12)|(_u4(cc)<<8)|(_u4(o1)<<4)|_u4(m)), \ + _jit_WW(thumb.s[0], thumb.s[1])) -#define thumb2_pkh(o,rn,rd,rm,im) _thumb2_pkh(_jit,o,rn,rd,rm,im) -__jit_inline void -_thumb2_pkh(jit_state_t _jit, int o, int rn, int rd, int rm, int im) -{ - jit_thumb_t thumb; - assert(!(o & 0x7ffcf)); - thumb.i = o|(_u4(rn)<<16)|((_u5(im)&0x1c)<<10)| - (_u4(rd)<<12)|((im&3)<<6)|_u4(rm); - _jit_WW(thumb.s[0], thumb.s[1]); -} +#define thumb2_pkh(o,rn,rd,rm,im) \ + (assert(!((o) & 0x7ffcf)), \ + thumb.i = ((o)|(_u4(rn)<<16)|((_u5(im)&0x1c)<<10)| \ + (_u4(rd)<<12)|(((im)&3)<<6)|_u4(rm)), \ + _jit_WW(thumb.s[0], thumb.s[1])) /* v6T2, v7 */ #define THUMB2_BFX 0xf3600000 diff --git a/src/runtime/c/pgf/lightning/arm/core.h b/src/runtime/c/pgf/lightning/arm/core.h index b01d07735..e199bcc87 100644 --- a/src/runtime/c/pgf/lightning/arm/core.h +++ b/src/runtime/c/pgf/lightning/arm/core.h @@ -32,6 +32,47 @@ #ifndef __lightning_core_arm_h #define __lightning_core_arm_h +typedef unsigned char _uc, jit_insn; + +struct { + _ui version : 4; + _ui extend : 1; + /* only generate thumb instructions for thumb2 */ + _ui thumb : 1; + _ui vfp : 3; + _ui neon : 1; + _ui abi : 2; +} jit_cpu; +struct { + /* prevent using thumb instructions that set flags? */ + _ui no_set_flags : 1; +} jit_flags; + +struct jit_local_state { + int reglist; + int framesize; + int nextarg_get; + int nextarg_put; + int nextarg_getf; + int alloca_offset; + int stack_length; + int stack_offset; + void *stack; + jit_thumb_t thumb; + jit_insn* thumb_pc; + jit_insn* thumb_tmp; + /* hackish mostly to make test cases work; use arm instruction + * set in jmpi if did not yet see a prolog */ + int after_prolog; + void *arguments[256]; + int types[8]; +#ifdef JIT_NEED_PUSH_POP + /* minor support for unsupported code but that exists in test cases... */ + int push[32]; + int pop; +#endif +}; + #define JIT_R_NUM 4 static const jit_gpr_t jit_r_order[JIT_R_NUM] = { @@ -49,1193 +90,1031 @@ jit_v_order[JIT_V_NUM] = { #define JIT_FRAMESIZE 48 #define jit_no_set_flags() jit_flags.no_set_flags +#define jit_thumb_p() jit_cpu.thumb #define jit_armv5_p() (jit_cpu.version >= 5) #define jit_armv5e_p() (jit_cpu.version >= 5 && jit_cpu.extend) #define jit_armv7r_p() 0 #define jit_swf_p() (jit_cpu.vfp == 0) #define jit_hardfp_p() jit_cpu.abi -extern int __aeabi_idivmod(int, int); -extern unsigned __aeabi_uidivmod(unsigned, unsigned); +#define __jit_inline static -#define jit_nop(n) arm_nop(_jit, n) -__jit_inline void -arm_nop(jit_state_t _jit, int n) -{ - assert(n >= 0); - if (jit_thumb_p()) { - for (; n > 0; n -= 2) - T1_NOP(); - } - else { - for (; n > 0; n -= 4) - _NOP(); - } +#ifdef USE_THUMB_CODE +#define jit_nop(n) \ +{ \ + assert(n >= 0); \ + for (; n > 0; n -= 2) \ + T1_NOP(); \ } - -#define jit_movr_i(r0, r1) arm_movr_i(_jit, r0, r1) -__jit_inline void -arm_movr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (r0 != r1) { - if (jit_thumb_p()) - T1_MOV(r0, r1); - else - _MOV(r0, r1); - } +#else +#define jit_nop(n) \ +{ \ + assert(n >= 0); \ + for (; n > 0; n -= 4) \ + _NOP(); \ } - -#define jit_movi_i(r0, i0) arm_movi_i(_jit, r0, i0) -__jit_inline void -arm_movi_i(jit_state_t _jit, jit_gpr_t r0, int i0) -{ - int i; - if (jit_thumb_p()) { - if (!jit_no_set_flags() && r0 < 8 && !(i0 & 0xffffff80)) - T1_MOVI(r0, i0); - else if ((i = encode_thumb_immediate(i0)) != -1) - T2_MOVI(r0, i); - else if ((i = encode_thumb_immediate(~i0)) != -1) - T2_MVNI(r0, i); - else { - T2_MOVWI(r0, _jit_US(i0)); - if (i0 & 0xffff0000) - T2_MOVTI(r0, _jit_US((unsigned)i0 >> 16)); - } - } - else { - if (jit_armv6_p() && !(i0 & 0xffff0000)) - _MOVWI(r0, i0); - else if ((i = encode_arm_immediate(i0)) != -1) - _MOVI(r0, i); - else if ((i = encode_arm_immediate(~i0)) != -1) - _MVNI(r0, i); - else if (jit_armv6_p()) { - _MOVWI(r0, _jit_US(i0)); - if ((i0 & 0xffff0000)) - _MOVTI(r0, _jit_US((unsigned)i0 >> 16)); - } - else { - int p0, p1, p2, p3, q0, q1, q2, q3; - p0 = i0 & 0x000000ff; p1 = i0 & 0x0000ff00; - p2 = i0 & 0x00ff0000; p3 = i0 & 0xff000000; - i0 = ~i0; - q0 = i0 & 0x000000ff; q1 = i0 & 0x0000ff00; - q2 = i0 & 0x00ff0000; q3 = i0 & 0xff000000; - if (!!p0 + !!p1 + !!p2 + !!p3 <= !!q0 + !!q1 + !!q2 + !!q3) { - /* prefer no inversion on tie */ - if (p3) { - _MOVI(r0, encode_arm_immediate(p3)); - if (p2) _ORRI(r0, r0, encode_arm_immediate(p2)); - if (p1) _ORRI(r0, r0, encode_arm_immediate(p1)); - if (p0) _ORRI(r0, r0, p0); - } - else if (p2) { - _MOVI(r0, encode_arm_immediate(p2)); - if (p1) _ORRI(r0, r0, encode_arm_immediate(p1)); - if (p0) _ORRI(r0, r0, p0); - } - else { - _MOVI(r0, encode_arm_immediate(p1)); - _ORRI(r0, r0, p0); - } - } - else { - if (q3) { - _MVNI(r0, encode_arm_immediate(q3)); - if (q2) _EORI(r0, r0, encode_arm_immediate(q2)); - if (q1) _EORI(r0, r0, encode_arm_immediate(q1)); - if (q0) _EORI(r0, r0, q0); - } - else if (q2) { - _MVNI(r0, encode_arm_immediate(q2)); - if (q1) _EORI(r0, r0, encode_arm_immediate(q1)); - if (q0) _EORI(r0, r0, q0); - } - else { - _MVNI(r0, encode_arm_immediate(q1)); - _EORI(r0, r0, q0); - } - } - } - } -} - -#define jit_movi_p(r0, i0) arm_movi_p(_jit, r0, i0) -__jit_inline jit_insn * -arm_movi_p(jit_state_t _jit, jit_gpr_t r0, void *i0) -{ - jit_insn *l; - int im, q0, q1, q2, q3; - im = (int)i0; l = _jit->x.pc; - if (jit_thumb_p()) { - T2_MOVWI(r0, _jit_US((int)i0)); - T2_MOVTI(r0, _jit_US((int)i0 >> 16)); - } - else { - if (jit_armv6_p()) { - _MOVWI(r0, _jit_US((unsigned)i0)); - _MOVTI(r0, _jit_US((unsigned)i0 >> 16)); - } - else { - q0 = im & 0x000000ff; q1 = im & 0x0000ff00; - q2 = im & 0x00ff0000; q3 = im & 0xff000000; - _MOVI(r0, encode_arm_immediate(q3)); - _ORRI(r0, r0, encode_arm_immediate(q2)); - _ORRI(r0, r0, encode_arm_immediate(q1)); - _ORRI(r0, r0, q0); - } - } - return (l); -} - -#define jit_patch_movi(i0, i1) arm_patch_movi(_jit, i0, i1) -__jit_inline void -arm_patch_movi(jit_state_t _jit, jit_insn *i0, void *i1) -{ - union { - short *s; - int *i; - void *v; - } u; - jit_thumb_t thumb; - unsigned int im; - int q0, q1, q2, q3; - im = (unsigned int)i1; u.v = i0; - if (jit_thumb_p()) { - q0 = (im & 0xf000) << 4; - q1 = (im & 0x0800) << 15; - q2 = (im & 0x0700) << 4; - q3 = im & 0x00ff; - code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - assert( (thumb.i & 0xfbf00000) == THUMB2_MOVWI); - thumb.i = (thumb.i & 0xfbf00f00) | q0 | q1 | q2 | q3; - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - im >>= 16; - q0 = (im & 0xf000) << 4; - q1 = (im & 0x0800) << 15; - q2 = (im & 0x0700) << 4; - q3 = im & 0x00ff; - code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); - assert( (thumb.i & 0xfbf00000) == THUMB2_MOVTI); - thumb.i = (thumb.i & 0xfbf00f00) | q0 | q1 | q2 | q3; - thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); - } - else { - if (jit_armv6_p()) { - q0 = im & 0xfff; - q1 = (im & 0xf000) << 4; - q2 = (im & 0xfff0000) >> 16; - q3 = (im & 0xf0000000) >> 12; - assert( (u.i[0] & 0x0ff00000) == (ARM_MOVWI)); - assert( (u.i[1] & 0x0ff00000) == (ARM_MOVTI)); - u.i[0] = (u.i[0] & 0xfff0f000) | q1 | q0; - u.i[1] = (u.i[1] & 0xfff0f000) | q3 | q2; - } - else { - q0 = im & 0x000000ff; q1 = im & 0x0000ff00; - q2 = im & 0x00ff0000; q3 = im & 0xff000000; - assert( (u.i[0] & 0x0ff00000) == (ARM_MOV|ARM_I)); - u.i[0] = (u.i[0] & 0xfffff000) | encode_arm_immediate(q3); - assert( (u.i[1] & 0x0ff00000) == (ARM_ORR|ARM_I)); - u.i[1] = (u.i[1] & 0xfffff000) | encode_arm_immediate(q2); - assert( (u.i[2] & 0x0ff00000) == (ARM_ORR|ARM_I)); - u.i[2] = (u.i[2] & 0xfffff000) | encode_arm_immediate(q1); - assert( (u.i[3] & 0x0ff00000) == (ARM_ORR|ARM_I)); - u.i[3] = (u.i[3] & 0xfffff000) | encode_arm_immediate(q0); - } - } -} - -#define jit_patch_calli(i0, i1) arm_patch_at(_jit, i0, i1) -#define jit_patch_at(jump, label) arm_patch_at(_jit, jump, label) -__jit_inline void -arm_patch_at(jit_state_t _jit, jit_insn *jump, jit_insn *label) -{ - long d; - union { - short *s; - int *i; - void *v; - } u; - jit_thumb_t thumb; - u.v = jump; - if (jit_thumb_p() && jump >= _jitl.thumb) { -#if 0 - /* this actually matches other patterns, so cannot patch - * automatically short jumps */ - if ((u.s[0] & THUMB_CC_B) == THUMB_CC_B) { - assert(_s8P(d)); - u.s[0] = (u.s[0] & 0xff00) | (d & 0xff); - } - else if ((u.s[0] & THUMB_B) == THUMB_B) { - assert(_s11P(d)); - u.s[0] = (u.s[0] & 0xf800) | (d & 0x7ff); - } - else #endif - { - code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - if ((thumb.i & THUMB2_B) == THUMB2_B) { - d = (((long)label - (long)jump) >> 1) - 2; - assert(_s24P(d)); - thumb.i = THUMB2_B | encode_thumb_jump(d); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - } - else if ((thumb.i & THUMB2_B) == THUMB2_CC_B) { - d = (((long)label - (long)jump) >> 1) - 2; - assert(_s20P(d)); - thumb.i = THUMB2_CC_B | (thumb.i & 0x3c00000) | - encode_thumb_cc_jump(d); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - } - else if ((thumb.i & 0xfbf08000) == THUMB2_MOVWI) - jit_patch_movi(jump, label); - else - assert(!"handled branch opcode"); - } - } - else { - /* 0x0e000000 because 0x01000000 is (branch&) link modifier */ - if ((u.i[0] & 0x0e000000) == ARM_B) { - d = (((long)label - (long)jump) >> 2) - 2; - assert(_s24P(d)); - u.i[0] = (u.i[0] & 0xff000000) | (d & 0x00ffffff); - } - else if (( jit_armv6_p() && (u.i[0] & 0x0ff00000) == ARM_MOVWI) || - (!jit_armv6_p() && (u.i[0] & 0x0ff00000) == (ARM_MOV|ARM_I))) - jit_patch_movi(jump, label); - else - assert(!"handled branch opcode"); - } + +#ifdef USE_THUMB_CODE +#define jit_movr_i(r0, r1) \ +{ \ + if (r0 != r1) { \ + T1_MOV(r0, r1); \ + } \ +} +#else +#define jit_movr_i(r0, r1) \ +{ \ + if (r0 != r1) { \ + _MOV(r0, r1); \ + } \ +} +#endif + +#define jit_movi_i(r0, i0) \ +{ \ + int i; \ + if (!jit_no_set_flags() && r0 < 8 && !(i0 & 0xffffff80)) \ + T1_MOVI(r0, i0); \ + else if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_MOVI(r0, i); \ + else if ((i = encode_thumb_immediate(~i0)) != -1) \ + T2_MVNI(r0, i); \ + else { \ + T2_MOVWI(r0, _jit_US(i0)); \ + if (i0 & 0xffff0000) \ + T2_MOVTI(r0, _jit_US((unsigned)i0 >> 16)); \ + } \ } -#define jit_notr_i(r0, r1) arm_notr_i(_jit, r0, r1) -__jit_inline void -arm_notr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1) < 8) - T1_NOT(r0, r1); - else - T2_NOT(r0, r1); - } - else - _NOT(r0, r1); -} +#ifdef USE_THUMB_CODE +#define jit_movi_p(r0, i0) \ + (T2_MOVWI(r0, _jit_US((int)i0)), T2_MOVTI(r0, _jit_US((int)i0 >> 16)), _jit.x.pc-8) +#else +#define jit_movi_p(r0, i0) \ + ((jit_armv6_p()) ? \ + (_MOVWI(r0, _jit_US((unsigned int)i0)), \ + _MOVTI(r0, _jit_US(((unsigned int)i0) >> 16)), \ + _jit.x.pc - 8) : \ + (_MOVI(r0, encode_arm_immediate(((int) i0) & 0xff000000)), \ + _ORRI(r0, r0, encode_arm_immediate(((int) i0) & 0x00ff0000)), \ + _ORRI(r0, r0, encode_arm_immediate(((int) i0) & 0x0000ff00)), \ + _ORRI(r0, r0, ((int) i0) & 0x000000ff), \ + _jit.x.pc - 16)) +#endif -#define jit_negr_i(r0, r1) arm_negr_i(_jit, r0, r1) -__jit_inline void -arm_negr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1) < 8) - T1_RSBI(r0, r1); - else - T2_RSBI(r0, r1, 0); - } - else - _RSBI(r0, r1, 0); -} +#ifdef USE_THUMB_CODE +#define jit_patch_movi(i0, i1) \ +{ \ + union { \ + short *s; \ + int *i; \ + void *v; \ + } u; \ + jit_thumb_t thumb; \ + unsigned int im; \ + int q0, q1, q2, q3; \ + im = (unsigned int)i1; u.v = i0; \ +\ + q0 = (im & 0xf000) << 4; \ + q1 = (im & 0x0800) << 15; \ + q2 = (im & 0x0700) << 4; \ + q3 = im & 0x00ff; \ + code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); \ + assert( (thumb.i & 0xfbf00000) == THUMB2_MOVWI); \ + thumb.i = (thumb.i & 0xfbf00f00) | q0 | q1 | q2 | q3; \ + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); \ + im >>= 16; \ + q0 = (im & 0xf000) << 4; \ + q1 = (im & 0x0800) << 15; \ + q2 = (im & 0x0700) << 4; \ + q3 = im & 0x00ff; \ + code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); \ + assert( (thumb.i & 0xfbf00000) == THUMB2_MOVTI); \ + thumb.i = (thumb.i & 0xfbf00f00) | q0 | q1 | q2 | q3; \ + thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); \ +} +#else +#define jit_patch_movi(i0, i1) \ +{ \ + union { \ + short *s; \ + int *i; \ + void *v; \ + } u; \ + jit_thumb_t thumb; \ + unsigned int im; \ + int q0, q1, q2, q3; \ + im = (unsigned int)i1; u.v = i0; \ +\ + if (jit_armv6_p()) { \ + q0 = im & 0xfff; \ + q1 = (im & 0xf000) << 4; \ + q2 = (im & 0xfff0000) >> 16; \ + q3 = (im & 0xf0000000) >> 12; \ + assert( (u.i[0] & 0x0ff00000) == (ARM_MOVWI)); \ + assert( (u.i[1] & 0x0ff00000) == (ARM_MOVTI)); \ + u.i[0] = (u.i[0] & 0xfff0f000) | q1 | q0; \ + u.i[1] = (u.i[1] & 0xfff0f000) | q3 | q2; \ + } \ + else { \ + q0 = im & 0x000000ff; q1 = im & 0x0000ff00; \ + q2 = im & 0x00ff0000; q3 = im & 0xff000000; \ + assert( (u.i[0] & 0x0ff00000) == (ARM_MOV|ARM_I)); \ + u.i[0] = (u.i[0] & 0xfffff000) | encode_arm_immediate(q3); \ + assert( (u.i[1] & 0x0ff00000) == (ARM_ORR|ARM_I)); \ + u.i[1] = (u.i[1] & 0xfffff000) | encode_arm_immediate(q2); \ + assert( (u.i[2] & 0x0ff00000) == (ARM_ORR|ARM_I)); \ + u.i[2] = (u.i[2] & 0xfffff000) | encode_arm_immediate(q1); \ + assert( (u.i[3] & 0x0ff00000) == (ARM_ORR|ARM_I)); \ + u.i[3] = (u.i[3] & 0xfffff000) | encode_arm_immediate(q0); \ + } \ +} +#endif -#define jit_addr_i(r0, r1, r2) arm_addr_i(_jit, r0, r1, r2) -__jit_inline void -arm_addr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8) - T1_ADD(r0, r1, r2); - else if (r0 == r1 || r0 == r2) - T1_ADDX(r0, r0 == r1 ? r2 : r1); - else - T2_ADD(r0, r1, r2); - } - else - _ADD(r0, r1, r2); -} +#define jit_patch_calli(i0, i1) jit_patch_at(i0, i1) -#define jit_addi_i(r0, r1, i0) arm_addi_i(_jit, r0, r1, i0) -__jit_inline void -arm_addi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7)) - T1_ADDI3(r0, r1, i0); - else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7)) - T1_SUBI3(r0, r1, -i0); - else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff)) - T1_ADDI8(r0, i0); - else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) - T1_SUBI8(r0, -i0); - else if ((i = encode_thumb_immediate(i0)) != -1) - T2_ADDI(r0, r1, i); - else if ((i = encode_thumb_immediate(-i0)) != -1) - T2_SUBI(r0, r1, i); - else if ((i = encode_thumb_word_immediate(i0)) != -1) - T2_ADDWI(r0, r1, i); - else if ((i = encode_thumb_word_immediate(-i0)) != -1) - T2_SUBWI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - T2_ADD(r0, r1, reg); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _ADDI(r0, r1, i); - else if ((i = encode_arm_immediate(-i0)) != -1) - _SUBI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _ADD(r0, r1, reg); - } - } +#ifdef USE_THUMB_CODE +#define jit_patch_at(jump, label) \ +{ \ + long d; \ + union { \ + short *s; \ + int *i; \ + void *v; \ + } u; \ + jit_thumb_t thumb; \ + u.v = jump; \ + if (jump >= _jitl.thumb_pc) \ + { \ + code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); \ + if ((thumb.i & THUMB2_B) == THUMB2_B) { \ + d = (((long)label - (long)jump) >> 1) - 2; \ + assert(_s24P(d)); \ + thumb.i = THUMB2_B | encode_thumb_jump(d); \ + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); \ + } \ + else if ((thumb.i & THUMB2_B) == THUMB2_CC_B) { \ + d = (((long)label - (long)jump) >> 1) - 2; \ + assert(_s20P(d)); \ + thumb.i = THUMB2_CC_B | (thumb.i & 0x3c00000) | \ + encode_thumb_cc_jump(d); \ + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); \ + } \ + else if ((thumb.i & 0xfbf08000) == THUMB2_MOVWI) { \ + jit_patch_movi(jump, label); \ + } else \ + assert(!"handled branch opcode"); \ + } else { \ + /* 0x0e000000 because 0x01000000 is (branch&) link modifier */ \ + if ((u.i[0] & 0x0e000000) == ARM_B) { \ + d = (((long)label - (long)jump) >> 2) - 2; \ + assert(_s24P(d)); \ + u.i[0] = (u.i[0] & 0xff000000) | (d & 0x00ffffff); \ + } else if ((jit_armv6_p() && (u.i[0] & 0x0ff00000) == ARM_MOVWI) || \ + (!jit_armv6_p() && (u.i[0] & 0x0ff00000) == (ARM_MOV|ARM_I))) { \ + jit_patch_movi(jump, label); \ + } else { \ + assert(!"handled branch opcode"); \ + } \ + } \ } - -#define jit_addcr_ui(r0, r1, r2) arm_addcr_ui(_jit, r0, r1, r2) -__jit_inline void -arm_addcr_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - /* thumb auto set carry if not inside IT block */ - if ((r0|r1|r2) < 8) - T1_ADD(r0, r1, r2); - else - T2_ADDS(r0, r1, r2); - } - else - _ADDS(r0, r1, r2); +#else +#define jit_patch_at(jump, label) \ +{ \ + union { \ + short *s; \ + int *i; \ + void *v; \ + } u; \ + u.v = jump; \ + /* 0x0e000000 because 0x01000000 is (branch&) link modifier */ \ + if ((u.i[0] & 0x0e000000) == ARM_B) { \ + long d = (((long)label - (long)jump) >> 2) - 2; \ + assert(_s24P(d)); \ + u.i[0] = (u.i[0] & 0xff000000) | (d & 0x00ffffff); \ + } else if ((jit_armv6_p() && (u.i[0] & 0x0ff00000) == ARM_MOVWI) || \ + (!jit_armv6_p() && (u.i[0] & 0x0ff00000) == (ARM_MOV|ARM_I))) { \ + jit_patch_movi(jump, label); \ + } else { \ + assert(!"handled branch opcode"); \ + } \ } +#endif -#define jit_addci_ui(r0, r1, i0) arm_addci_ui(_jit, r0, r1, i0) -__jit_inline void -arm_addci_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((r0|r1) < 8 && !(i0 & ~7)) - T1_ADDI3(r0, r1, i0); - else if ((r0|r1) < 8 && !(-i0 & ~7)) - T1_SUBI3(r0, r1, -i0); - else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff)) - T1_ADDI8(r0, i0); - else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) - T1_SUBI8(r0, -i0); - else if ((i = encode_thumb_immediate(i0)) != -1) - T2_ADDSI(r0, r1, i); - else if ((i = encode_thumb_immediate(-i0)) != -1) - T2_SUBSI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - T2_ADDS(r0, r1, reg); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _ADDSI(r0, r1, i); - else if ((i = encode_arm_immediate(-i0)) != -1) - _SUBSI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _ADDS(r0, r1, reg); - } - } +#ifdef USE_THUMB_CODE +#define jit_notr_i(r0, r1) \ + ((!jit_no_set_flags() && (r0|r1) < 8) ? T1_NOT(r0, r1) : T2_NOT(r0, r1)) +#else +#define jit_notr_i(r0, r1) \ + _NOT(r0, r1) +#endif + +#ifdef USE_THUMB_CODE +#define jit_negr_i(r0, r1) \ + ((!jit_no_set_flags() && (r0|r1) < 8) ? T1_RSBI(r0, r1), T2_RSBI(r0, r1, 0)) +#else +#define jit_negr_i(r0, r1) \ + _RSBI(r0, r1, 0) +#endif + +#ifdef USE_THUMB_CODE +#define jit_addr_i(r0, r1, r2) \ +{ \ + if (!jit_no_set_flags() && (r0|r1|r2) < 8) \ + T1_ADD(r0, r1, r2); \ + else if (r0 == r1 || r0 == r2) \ + T1_ADDX(r0, r0 == r1 ? r2 : r1); \ + else \ + T2_ADD(r0, r1, r2); \ } +#else +#define jit_addr_i(r0, r1, r2) \ + _ADD(r0, r1, r2) +#endif -#define jit_addxr_ui(r0, r1, r2) arm_addxr_ui(_jit, r0, r1, r2) -__jit_inline void -arm_addxr_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - /* keep setting carry because don't know last ADC */ - if (jit_thumb_p()) { - /* thumb auto set carry if not inside IT block */ - if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) - T1_ADC(r0, r0 == r1 ? r2 : r1); - else - T2_ADCS(r0, r1, r2); - } - else - _ADCS(r0, r1, r2); +#ifdef USE_THUMB_CODE +#define jit_addi_i(r0, r1, i0) \ +{ \ + int i; \ + jit_gpr_t reg; \ + if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7)) \ + T1_ADDI3(r0, r1, i0); \ + else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7)) \ + T1_SUBI3(r0, r1, -i0); \ + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff)) \ + T1_ADDI8(r0, i0); \ + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) \ + T1_SUBI8(r0, -i0); \ + else if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_ADDI(r0, r1, i); \ + else if ((i = encode_thumb_immediate(-i0)) != -1) \ + T2_SUBI(r0, r1, i); \ + else if ((i = encode_thumb_word_immediate(i0)) != -1) \ + T2_ADDWI(r0, r1, i); \ + else if ((i = encode_thumb_word_immediate(-i0)) != -1) \ + T2_SUBWI(r0, r1, i); \ + else { \ + reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_ADD(r0, r1, reg); \ + } \ } - -#define jit_addxi_ui(r0, r1, i0) arm_addxi_ui(_jit, r0, r1, i0) -__jit_inline void -arm_addxi_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((i = encode_thumb_immediate(i0)) != -1) - T2_ADCSI(r0, r1, i); - else if ((i = encode_thumb_immediate(-i0)) != -1) - T2_SBCSI(r0, r1, i); - else { - int no_set_flags = jit_no_set_flags(); - reg = r0 != r1 ? r0 : JIT_TMP; - jit_no_set_flags() = 1; - jit_movi_i(reg, i0); - jit_no_set_flags() = no_set_flags; - T2_ADCS(r0, r1, reg); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _ADCSI(r0, r1, i); - else if ((i = encode_arm_immediate(-i0)) != -1) - _SBCSI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _ADCS(r0, r1, reg); - } - } +#else +#define jit_addi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _ADDI(r0, r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _SUBI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _ADD(r0, r1, reg); \ + } \ } +#endif -#define jit_subr_i(r0, r1, r2) arm_subr_i(_jit, r0, r1, r2) -__jit_inline void -arm_subr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8) - T1_SUB(r0, r1, r2); - else - T2_SUB(r0, r1, r2); - } - else +#ifdef USE_THUMB_CODE +#define jit_addcr_i(r0, r1, r2) \ + /* thumb auto set carry if not inside IT block */ \ + ((r0|r1|r2) < 8) ? T1_ADD(r0, r1, r2) : T2_ADDS(r0, r1, r2) +#else +#define jit_addcr_i(r0, r1, r2) \ + _ADDS(r0, r1, r2) +#endif + +#ifdef USE_THUMB_CODE +#define jit_addci_i(r0, r1, i0) \ +{ \ + int i; \ + if ((r0|r1) < 8 && !(i0 & ~7)) \ + T1_ADDI3(r0, r1, i0); \ + else if ((r0|r1) < 8 && !(-i0 & ~7)) \ + T1_SUBI3(r0, r1, -i0); \ + else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff)) \ + T1_ADDI8(r0, i0); \ + else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) \ + T1_SUBI8(r0, -i0); \ + else if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_ADDSI(r0, r1, i); \ + else if ((i = encode_thumb_immediate(-i0)) != -1) \ + T2_SUBSI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_ADDS(r0, r1, reg); \ + } \ +} +#else +#define jit_addci_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _ADDSI(r0, r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _SUBSI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _ADDS(r0, r1, reg); \ + } \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_addxr_i(r0, r1, r2) \ +{ /* keep setting carry because don't know last ADC */ \ + /* thumb auto set carry if not inside IT block */ \ + if ((r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) \ + T1_ADC(r0, r0 == r1 ? r2 : r1); \ + else \ + T2_ADCS(r0, r1, r2); \ +} +#else +#define jit_addxr_i(r0, r1, r2) \ + /* keep setting carry because don't know last ADC */ \ + _ADCS(r0, r1, r2) +#endif + +#ifdef USE_THUMB_CODE +#define jit_addxi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_ADCSI(r0, r1, i); \ + else if ((i = encode_thumb_immediate(-i0)) != -1) \ + T2_SBCSI(r0, r1, i); \ + else { \ + int no_set_flags = jit_no_set_flags(); \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_no_set_flags() = 1; \ + jit_movi_i(reg, i0); \ + jit_no_set_flags() = no_set_flags; \ + T2_ADCS(r0, r1, reg); \ + } \ +} +#else +#define jit_addxi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _ADCSI(r0, r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _SBCSI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _ADCS(r0, r1, reg); \ + } \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_subr_i(r0, r1, r2) \ +{ \ + if (!jit_no_set_flags() && (r0|r1|r2) < 8) \ + T1_SUB(r0, r1, r2); \ + else \ + T2_SUB(r0, r1, r2); \ +} +#else +#define jit_subr_i(r0, r1, r2) \ _SUB(r0, r1, r2); +#endif + +#ifdef USE_THUMB_CODE +#define jit_subi_i(r0, r1, i0) \ +{ \ + int i; \ + if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7)) \ + T1_SUBI3(r0, r1, i0); \ + else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7)) \ + T1_ADDI3(r0, r1, -i0); \ + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff)) \ + T1_SUBI8(r0, i0); \ + else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) \ + T1_ADDI8(r0, -i0); \ + else if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_SUBI(r0, r1, i); \ + else if ((i = encode_thumb_immediate(-i0)) != -1) \ + T2_ADDI(r0, r1, i); \ + else if ((i = encode_thumb_word_immediate(i0)) != -1) \ + T2_SUBWI(r0, r1, i); \ + else if ((i = encode_thumb_word_immediate(-i0)) != -1) \ + T2_ADDWI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_SUB(r0, r1, reg); \ + } \ +} +#else +#define jit_subi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _SUBI(r0, r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _ADDI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _SUB(r0, r1, reg); \ + } \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_subcr_i(r0, r1, r2) \ + /* thumb auto set carry if not inside IT block */ \ + ((r0|r1|r2) < 8) ? T1_SUB(r0, r1, r2) : T2_SUBS(r0, r1, r2) +#else +#define jit_subcr_i(r0, r1, r2) \ + _SUBS(r0, r1, r2) +#endif + +#ifdef USE_THUMB_CODE +#define jit_subci_i(r0, r1, i0) \ +{ \ + int i; \ + if ((r0|r1) < 8 && !(i0 & ~7)) \ + T1_SUBI3(r0, r1, i0); \ + else if ((r0|r1) < 8 && !(-i0 & ~7)) \ + T1_ADDI3(r0, r1, -i0); \ + else if (r0 < 8 && r0 == r1 && !(i0 & ~0xff)) \ + T1_SUBI8(r0, i0); \ + else if (r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) \ + T1_ADDI8(r0, -i0); \ + else if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_SUBSI(r0, r1, i); \ + else if ((i = encode_thumb_immediate(-i0)) != -1) \ + T2_ADDSI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_SUBS(r0, r1, reg); \ + } \ +} +#else +#define jit_subci_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _SUBSI(r0, r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _ADDSI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _SUBS(r0, r1, reg); \ + } \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_subxr_i(r0, r1, r2) \ + /* keep setting carry because don't know last ADC */ \ + /* thumb auto set carry if not inside IT block */ \ + ((r0|r1|r2) < 8 && r0 == r1) ? T1_SBC(r0, r2) : T2_SBCS(r0, r1, r2) +#else +#define jit_subxr_i(r0, r1, r2) \ + /* keep setting carry because don't know last ADC */ \ + _SBCS(r0, r1, r2) +#endif + +#ifdef USE_THUMB_CODE +#define jit_subxi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_SBCSI(r0, r1, i); \ + else if ((i = encode_thumb_immediate(-i0)) != -1) \ + T2_ADCSI(r0, r1, i); \ + else { \ + int no_set_flags = jit_no_set_flags(); \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_no_set_flags() = 1; \ + jit_movi_i(reg, i0); \ + jit_no_set_flags() = no_set_flags; \ + T2_SBCS(r0, r1, reg); \ + } \ +} +#else +#define jit_subxi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _SBCSI(r0, r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _ADCSI(r0, r1, i); \ + else { \ + reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _SBCS(r0, r1, reg); \ + } \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_rsbr_i(r0, r1, r2) \ + T2_RSB(r0, r1, r2) +#else +#define jit_rsbr_i(r0, r1, r2) \ + _RSB(r0, r1, r2) +#endif + +#ifdef USE_THUMB_CODE +#define jit_rsbi_i(r0, r1, i0) \ +{ \ + int i; \ + if (i0 == 0) \ + jit_negr_i(r0, r1); \ + else if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_RSBI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_RSB(r0, r1, reg); \ + } \ +} +#else +#define jit_rsbi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _RSBI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _RSB(r0, r1, reg); \ + } \ +} +#endif + +#define jit_mulr_i(r0, r1, r2) jit_mulr_ui(_jit, r0, r1, r2) +#ifdef USE_THUMB_CODE +#define jit_mulr_ui(r0, r1, r2) \ +{ \ + if (!jit_no_set_flags() && r0 == r2 && (r0|r1) < 8) \ + T1_MUL(r0, r1); \ + else if (!jit_no_set_flags() && r0 == r1 && (r0|r2) < 8) \ + T1_MUL(r0, r2); \ + else \ + T2_MUL(r0, r1, r2); \ +} +#else +#define jit_mulr_ui(r0, r1, r2) \ +{ \ + if (r0 == r1 && !jit_armv6_p()) { \ + if (r0 != r2) \ + _MUL(r0, r2, r1); \ + else { \ + _MOV(JIT_TMP, r1); \ + _MUL(r0, JIT_TMP, r2); \ + } \ + } \ + else \ + _MUL(r0, r1, r2); \ +} +#endif + +#define jit_muli_i(r0, r1, i0) jit_muli_ui(r0, r1, i0) +#define jit_muli_ui(r0, r1, i0) \ +{ \ + jit_gpr_t reg; \ + reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + jit_mulr_i(r0, r1, reg); \ } -#define jit_subi_i(r0, r1, i0) arm_subi_i(_jit, r0, r1, i0) -__jit_inline void -arm_subi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1) < 8 && !(i0 & ~7)) - T1_SUBI3(r0, r1, i0); - else if (!jit_no_set_flags() && (r0|r1) < 8 && !(-i0 & ~7)) - T1_ADDI3(r0, r1, -i0); - else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(i0 & ~0xff)) - T1_SUBI8(r0, i0); - else if (!jit_no_set_flags() && r0 < 8 && r0 == r1 && !(-i0 & ~0xff)) - T1_ADDI8(r0, -i0); - else if ((i = encode_thumb_immediate(i0)) != -1) - T2_SUBI(r0, r1, i); - else if ((i = encode_thumb_immediate(-i0)) != -1) - T2_ADDI(r0, r1, i); - else if ((i = encode_thumb_word_immediate(i0)) != -1) - T2_SUBWI(r0, r1, i); - else if ((i = encode_thumb_word_immediate(-i0)) != -1) - T2_ADDWI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - T2_SUB(r0, r1, reg); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _SUBI(r0, r1, i); - else if ((i = encode_arm_immediate(-i0)) != -1) - _ADDI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _SUB(r0, r1, reg); - } - } +#ifdef USE_THUMB_CODE +#define jit_hmulr_i(r0, r1, r2) \ + T2_SMULL(JIT_TMP, r0, r1, r2) +#else +#define jit_hmulr_i(r0, r1, r2) \ +{ \ + if (r0 == r1 && !jit_armv6_p()) { \ + assert(r2 != JIT_TMP); \ + _SMULL(JIT_TMP, r0, r2, r1); \ + } \ + else \ + _SMULL(JIT_TMP, r0, r1, r2); \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_hmuli_i(r0, r1, i0) \ +{ \ + assert(r0 != JIT_TMP); \ + jit_movi_i(JIT_TMP, i0); \ + T2_SMULL(JIT_TMP, r0, r1, JIT_TMP); \ +} +#else +#define jit_hmuli_i(r0, r1, i0) \ +{ \ + jit_gpr_t reg; \ + if (r0 != r1 || jit_armv6_p()) { \ + jit_movi_i(JIT_TMP, i0); \ + _SMULL(JIT_TMP, r0, r1, JIT_TMP); \ + } \ + else { \ + if (r0 != _R0) reg = _R0; \ + else if (r0 != _R1) reg = _R1; \ + else if (r0 != _R2) reg = _R2; \ + else reg = _R3; \ + _PUSH(1<x.pc) >> 1) - 2; - else - d = (((int)p - (int)_jit->x.pc) >> 2) - 2; - if (_s24P(d)) { - if (jit_thumb_p()) - T2_BLI(encode_thumb_jump(d)); - else - _BLI(d & 0x00ffffff); - } - else - goto fallback; - } - else { - fallback: - jit_movi_i(JIT_FTMP, (int)p); - if (jit_thumb_p()) - T1_BLX(JIT_FTMP); - else - _BLX(JIT_FTMP); - } - if (div) - jit_movr_i(r0, _R0); - else - jit_movr_i(r0, _R1); - if (jit_thumb_p()) - T1_POP(l); - else - _POP(l); -} - -#define jit_divr_i(r0, r1, r2) arm_divr_i(_jit, r0, r1, r2) -__jit_inline void -arm_divr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_armv7r_p() && jit_thumb_p()) - T2_SDIV(r0, r1, r2); - else - arm_divmod(_jit, 1, 1, r0, r1, r2); -} - -#define jit_divi_i(r0, r1, i0) arm_divi_i(_jit, r0, r1, i0) -__jit_inline void -arm_divi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_movi_i(JIT_TMP, i0); - arm_divr_i(_jit, r0, r1, JIT_TMP); -} - -#define jit_divr_ui(r0, r1, r2) arm_divr_ui(_jit, r0, r1, r2) -__jit_inline void -arm_divr_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_armv7r_p() && jit_thumb_p()) - T2_UDIV(r0, r1, r2); - else - arm_divmod(_jit, 1, 0, r0, r1, r2); -} - -#define jit_divi_ui(r0, r1, i0) arm_divi_ui(_jit, r0, r1, i0) -__jit_inline void -arm_divi_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, unsigned int i0) -{ - jit_movi_i(JIT_TMP, i0); - arm_divr_ui(_jit, r0, r1, JIT_TMP); -} - -#define jit_modr_i(r0, r1, r2) arm_modr_i(_jit, r0, r1, r2) -__jit_inline void -arm_modr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - arm_divmod(_jit, 0, 1, r0, r1, r2); -} - -#define jit_modi_i(r0, r1, i0) arm_modi_i(_jit, r0, r1, i0) -__jit_inline void -arm_modi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_movi_i(JIT_TMP, i0); - arm_modr_i(_jit, r0, r1, JIT_TMP); -} - -#define jit_modr_ui(r0, r1, r2) arm_modr_ui(_jit, r0, r1, r2) -__jit_inline void -arm_modr_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - arm_divmod(_jit, 0, 0, r0, r1, r2); -} - -#define jit_modi_ui(r0, r1, i0) arm_modi_ui(_jit, r0, r1, i0) -__jit_inline void -arm_modi_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_movi_i(JIT_TMP, i0); - arm_modr_ui(_jit, r0, r1, JIT_TMP); -} - -#define jit_andr_i(r0, r1, r2) arm_andr_i(_jit, r0, r1, r2) -__jit_inline void -arm_andr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) - T1_AND(r0, r0 == r1 ? r2 : r1); - else - T2_AND(r0, r1, r2); - } - else +#ifdef USE_THUMB_CODE +#define jit_andr_i(r0, r1, r2) \ + (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) ? T1_AND(r0, r0 == r1 ? r2 : r1) : T2_AND(r0, r1, r2) +#else +#define jit_andr_i(r0, r1, r2) \ _AND(r0, r1, r2); -} +#endif -#define jit_andi_i(r0, r1, i0) arm_andi_i(_jit, r0, r1, i0) -__jit_inline void -arm_andi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((i = encode_thumb_immediate(i0)) != -1) - T2_ANDI(r0, r1, i); - else if ((i = encode_thumb_immediate(~i0)) != -1) - T2_BICI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - T2_AND(r0, r1, reg); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _ANDI(r0, r1, i); - else if ((i = encode_arm_immediate(~i0)) != -1) - _BICI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _AND(r0, r1, reg); - } - } +#ifdef USE_THUMB_CODE +#define jit_andi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_ANDI(r0, r1, i); \ + else if ((i = encode_thumb_immediate(~i0)) != -1) \ + T2_BICI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_AND(r0, r1, reg); \ + } \ } +#else +#define jit_andi_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _ANDI(r0, r1, i); \ + else if ((i = encode_arm_immediate(~i0)) != -1) \ + _BICI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _AND(r0, r1, reg); \ + } \ +} +#endif -#define jit_orr_i(r0, r1, r2) arm_orr_i(_jit, r0, r1, r2) -__jit_inline void -arm_orr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) - T1_ORR(r0, r0 == r1 ? r2 : r1); - else - T2_ORR(r0, r1, r2); - } - else +#ifdef USE_THUMB_CODE +#define jit_orr_i(r0, r1, r2) \ +{ \ + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) \ + T1_ORR(r0, r0 == r1 ? r2 : r1); \ + else \ + T2_ORR(r0, r1, r2); \ +} +#else +#define jit_orr_i(r0, r1, r2) \ _ORR(r0, r1, r2); -} +#endif -#define jit_ori_i(r0, r1, i0) arm_ori_i(_jit, r0, r1, i0) -__jit_inline void -arm_ori_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((i = encode_thumb_immediate(i0)) != -1) - T2_ORRI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - T2_ORR(r0, r1, reg); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _ORRI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _ORR(r0, r1, reg); - } - } +#ifdef USE_THUMB_CODE +#define jit_ori_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_ORRI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_ORR(r0, r1, reg); \ + } \ } - -#define jit_xorr_i(r0, r1, r2) arm_xorr_i(_jit, r0, r1, r2) -__jit_inline void -arm_xorr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) - T1_EOR(r0, r0 == r1 ? r2 : r1); - else - T2_EOR(r0, r1, r2); - } - else - _EOR(r0, r1, r2); +#else +#define jit_ori_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _ORRI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _ORR(r0, r1, reg); \ + } \ } +#endif -#define jit_xori_i(r0, r1, i0) arm_xori_i(_jit, r0, r1, i0) -__jit_inline void -arm_xori_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((i = encode_thumb_immediate(i0)) != -1) - T2_EORI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - T2_EOR(r0, r1, reg); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _EORI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _EOR(r0, r1, reg); - } - } +#ifdef USE_THUMB_CODE +#define jit_xorr_i(r0, r1, r2) \ +{ \ + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && (r0 == r1 || r0 == r2)) \ + T1_EOR(r0, r0 == r1 ? r2 : r1); \ + else \ + T2_EOR(r0, r1, r2); \ } +#else +#define jit_xorr_i(r0, r1, r2) \ + _EOR(r0, r1, r2) +#endif -#define jit_lshr_i(r0, r1, r2) arm_lshr_i(_jit, r0, r1, r2) -__jit_inline void -arm_lshr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) - T1_LSL(r0, r2); - else +#ifdef USE_THUMB_CODE +#define jit_xori_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_EORI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + T2_EOR(r0, r1, reg); \ + } \ +} +#else +#define jit_xori_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _EORI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _EOR(r0, r1, reg); \ + } \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_lshr_i(r0, r1, r2) \ + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) \ + T1_LSL(r0, r2); \ + else \ T2_LSL(r0, r1, r2); - } - else - _LSL(r0, r1, r2); -} +#else +#define jit_lshr_i(r0, r1, r2) \ + _LSL(r0, r1, r2) +#endif -#define jit_lshi_i(r0, r1, i0) arm_lshi_i(_jit, r0, r1, i0) -__jit_inline void -arm_lshi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - assert(i0 >= 0 && i0 <= 31); - if (i0 == 0) - jit_movr_i(r0, r1); - else if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1) < 8) - T1_LSLI(r0, r1, i0); - else - T2_LSLI(r0, r1, i0); - } - else - _LSLI(r0, r1, i0); +#ifdef USE_THUMB_CODE +#define jit_lshi_i(r0, r1, i0) \ +{ \ + assert(i0 >= 0 && i0 <= 31); \ + if (i0 == 0) \ + jit_movr_i(r0, r1); \ + else \ + if (!jit_no_set_flags() && (r0|r1) < 8) \ + T1_LSLI(r0, r1, i0); \ + else \ + T2_LSLI(r0, r1, i0); \ } +#else +#define jit_lshi_i(r0, r1, i0) \ +{ \ + assert(i0 >= 0 && i0 <= 31); \ + if (i0 == 0) \ + jit_movr_i(r0, r1); \ + else \ + _LSLI(r0, r1, i0); \ +} +#endif -#define jit_rshr_i(r0, r1, r2) arm_rshr_i(_jit, r0, r1, r2) -__jit_inline void -arm_rshr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) - T1_ASR(r0, r2); - else - T2_ASR(r0, r1, r2); - } - else - _ASR(r0, r1, r2); +#ifdef USE_THUMB_CODE +#define jit_rshr_i(r0, r1, r2) \ +{ \ + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) \ + T1_ASR(r0, r2); \ + else \ + T2_ASR(r0, r1, r2); \ } +#else +#define jit_rshr_i(r0, r1, r2) \ + _ASR(r0, r1, r2) +#endif -#define jit_rshi_i(r0, r1, i0) arm_rshi_i(_jit, r0, r1, i0) -__jit_inline void -arm_rshi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - assert(i0 >= 0 && i0 <= 31); - if (i0 == 0) - jit_movr_i(r0, r1); - else if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1) < 8) - T1_ASRI(r0, r1, i0); - else - T2_ASRI(r0, r1, i0); - } - else - _ASRI(r0, r1, i0); +#ifdef USE_THUMB_CODE +#define jit_rshi_i(r0, r1, i0) \ +{ \ + assert(i0 >= 0 && i0 <= 31); \ + if (i0 == 0) \ + jit_movr_i(r0, r1); \ + else if (!jit_no_set_flags() && (r0|r1) < 8) \ + T1_ASRI(r0, r1, i0); \ + else \ + T2_ASRI(r0, r1, i0); \ } +#else +#define jit_rshi_i(r0, r1, i0) \ +{ \ + assert(i0 >= 0 && i0 <= 31); \ + if (i0 == 0) \ + jit_movr_i(r0, r1); \ + else \ + _ASRI(r0, r1, i0); \ +} +#endif -#define jit_rshr_ui(r0, r1, r2) arm_rshr_ui(_jit, r0, r1, r2) -__jit_inline void -arm_rshr_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) - T1_LSR(r0, r2); - else - T2_LSR(r0, r1, r2); - } - else - _LSR(r0, r1, r2); +#ifdef USE_THUMB_CODE +#define jit_rshr_ui(r0, r1, r2) \ +{ \ + if (!jit_no_set_flags() && (r0|r1|r2) < 8 && r0 == r1) \ + T1_LSR(r0, r2); \ + else \ + T2_LSR(r0, r1, r2); \ } +#else +#define jit_rshr_ui(r0, r1, r2) \ + _LSR(r0, r1, r2) +#endif -#define jit_rshi_ui(r0, r1, i0) arm_rshi_ui(_jit, r0, r1, i0) -__jit_inline void -arm_rshi_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - assert(i0 >= 0 && i0 <= 31); - if (i0 == 0) - jit_movr_i(r0, r1); - else if (jit_thumb_p()) { - if (!jit_no_set_flags() && (r0|r1) < 8) - T1_LSRI(r0, r1, i0); - else - T2_LSRI(r0, r1, i0); - } - else - _LSRI(r0, r1, i0); +#ifdef USE_THUMB_CODE +#define jit_rshi_ui(r0, r1, i0) \ +{ \ + assert(i0 >= 0 && i0 <= 31); \ + if (i0 == 0) \ + jit_movr_i(r0, r1); \ + else if (!jit_no_set_flags() && (r0|r1) < 8) \ + T1_LSRI(r0, r1, i0); \ + else \ + T2_LSRI(r0, r1, i0); \ } +#else +#define jit_rshi_ui(r0, r1, i0) \ +{ \ + assert(i0 >= 0 && i0 <= 31); \ + if (i0 == 0) \ + jit_movr_i(r0, r1); \ + else \ + _LSRI(r0, r1, i0); \ +} +#endif -__jit_inline void -arm_ccr(jit_state_t _jit, int ct, int cf, - jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - assert((ct ^ cf) >> 28 == 1); - if ((r1|r2) < 8) - T1_CMP(r1, r2); - else if ((r1&r2) & 8) - T1_CMPX(r1, r2); - else - T2_CMP(r1, r2); - _ITE(ct); - if (r0 < 8) { - T1_MOVI(r0, 1); - T1_MOVI(r0, 0); - } - else { - T2_MOVI(r0, 1); - T2_MOVI(r0, 0); - } - } - else { - _CMP(r1, r2); - _CC_MOVI(ct, r0, 1); - _CC_MOVI(cf, r0, 0); - } +#ifdef USE_THUMB_CODE +#define arm_ccr(ct, cf, r0, r1, r2) \ +{ \ + assert((ct ^ cf) >> 28 == 1); \ + if ((r1|r2) < 8) \ + T1_CMP(r1, r2); \ + else if ((r1&r2) & 8) \ + T1_CMPX(r1, r2); \ + else \ + T2_CMP(r1, r2); \ + _ITE(ct); \ + if (r0 < 8) { \ + T1_MOVI(r0, 1); \ + T1_MOVI(r0, 0); \ + } else { \ + T2_MOVI(r0, 1); \ + T2_MOVI(r0, 0); \ + } \ } -__jit_inline void -arm_cci(jit_state_t _jit, int ct, int cf, - jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) { - if (r1 < 7 && !(i0 & 0xffffff00)) - T1_CMPI(r1, i0); - else if ((i = encode_thumb_immediate(i0)) != -1) - T2_CMPI(r1, i); - else if ((i = encode_thumb_immediate(-i0)) != -1) - T2_CMNI(r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - arm_ccr(_jit, ct, cf, r0, r1, reg); - return; - } - _ITE(ct); - if (r0 < 8) { - T1_MOVI(r0, 1); - T1_MOVI(r0, 0); - } - else { - T2_MOVI(r0, 1); - T2_MOVI(r0, 0); - } - } - else { - if ((i = encode_arm_immediate(i0)) != -1) - _CMPI(r1, i); - else if ((i = encode_arm_immediate(-i0)) != -1) - _CMNI(r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _CMP(r1, reg); - } - _CC_MOVI(ct, r0, 1); - _CC_MOVI(cf, r0, 0); - } +#else +#define arm_ccr(ct, cf, r0, r1, r2) \ +{ \ + _CMP(r1, r2); \ + _CC_MOVI(ct, r0, 1); \ + _CC_MOVI(cf, r0, 0); \ } +#endif + +#ifdef USE_THUMB_CODE +#define arm_cci(ct, cf, r0, r1, i0) \ +{ \ + int i; \ + if (r1 < 7 && !(i0 & 0xffffff00)) \ + T1_CMPI(r1, i0); \ + else if ((i = encode_thumb_immediate(i0)) != -1) \ + T2_CMPI(r1, i); \ + else if ((i = encode_thumb_immediate(-i0)) != -1) \ + T2_CMNI(r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + arm_ccr(_jit, ct, cf, r0, r1, reg); \ + goto next; \ + } \ + _ITE(ct); \ + if (r0 < 8) { \ + T1_MOVI(r0, 1); \ + T1_MOVI(r0, 0); \ + } \ + else { \ + T2_MOVI(r0, 1); \ + T2_MOVI(r0, 0); \ + } \ +next: \ +} +#else +#define arm_cci(ct, cf, r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _CMPI(r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _CMNI(r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _CMP(r1, reg); \ + } \ + _CC_MOVI(ct, r0, 1); \ + _CC_MOVI(cf, r0, 0); \ +} +#endif + #define jit_ltr_i(r0, r1, r2) arm_ccr(_jit,ARM_CC_LT,ARM_CC_GE,r0,r1,r2) #define jit_lti_i(r0, r1, i0) arm_cci(_jit,ARM_CC_LT,ARM_CC_GE,r0,r1,i0) #define jit_ltr_ui(r0, r1, r2) arm_ccr(_jit,ARM_CC_LO,ARM_CC_HS,r0,r1,r2) @@ -1255,1566 +1134,1072 @@ arm_cci(jit_state_t _jit, int ct, int cf, #define jit_gtr_ui(r0, r1, r2) arm_ccr(_jit,ARM_CC_HI,ARM_CC_LS,r0,r1,r2) #define jit_gti_ui(r0, r1, i0) arm_cci(_jit,ARM_CC_HI,ARM_CC_LS,r0,r1,i0) -#define jit_ner_i(r0, r1, r2) arm_ner_i(_jit, r0, r1, r2) -__jit_inline void -arm_ner_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) - arm_ccr(_jit, ARM_CC_NE, ARM_CC_EQ, r0, r1, r2); - else { - _SUBS(r0, r1, r2); - _CC_MOVI(ARM_CC_NE, r0, 1); - } -} +#ifdef USE_THUMB_CODE +#define jit_ner_i(r0, r1, r2) \ + arm_ccr(_jit, ARM_CC_NE, ARM_CC_EQ, r0, r1, r2) +#else +#define jit_ner_i(r0, r1, r2) \ + (_SUBS(r0, r1, r2), _CC_MOVI(ARM_CC_NE, r0, 1)) +#endif -#define jit_nei_i(r0, r1, i0) arm_nei_i(_jit, r0, r1, i0) -__jit_inline void -arm_nei_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - int i; - jit_gpr_t reg; - if (jit_thumb_p()) - arm_cci(_jit, ARM_CC_NE, ARM_CC_EQ, r0, r1, i0); - else { - if ((i = encode_arm_immediate(i0)) != -1) - _SUBSI(r0, r1, i); - else if ((i = encode_arm_immediate(-i0)) != -1) - _ADDSI(r0, r1, i); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _SUBS(r0, r1, reg); - } - _CC_MOVI(ARM_CC_NE, r0, 1); - } +#ifdef USE_THUMB_CODE +#define jit_nei_i(r0, r1, i0) \ + arm_cci(_jit, ARM_CC_NE, ARM_CC_EQ, r0, r1, i0) +#else +#define jit_nei_i(r0, r1, i0) \ +{ \ + int i; \ + if ((i = encode_arm_immediate(i0)) != -1) \ + _SUBSI(r0, r1, i); \ + else if ((i = encode_arm_immediate(-i0)) != -1) \ + _ADDSI(r0, r1, i); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _SUBS(r0, r1, reg); \ + } \ + _CC_MOVI(ARM_CC_NE, r0, 1); \ } +#endif -#define jit_jmpr(r0) arm_jmpr(_jit, r0) -__jit_inline void -arm_jmpr(jit_state_t _jit, jit_gpr_t r0) -{ - if (jit_thumb_p()) - T1_MOV(_R15, r0); - else - _MOV(_R15, r0); -} +#ifdef USE_THUMB_CODE +#define jit_jmpr(r0) T1_MOV(_R15, r0) +#else +#define jit_jmpr(r0) _MOV(_R15, r0) +#endif -#define jit_jmpi(i0) arm_jmpi(_jit, i0) -__jit_inline jit_insn * -arm_jmpi(jit_state_t _jit, void *i0) -{ - jit_insn *l; - long d; - l = _jit->x.pc; - if (jit_thumb_p() && _jitl.after_prolog) { - d = (((long)i0 - (long)l) >> 1) - 2; - if (_s20P(d)) - T2_B(encode_thumb_jump(d)); - else { - jit_movi_p(JIT_TMP, i0); - jit_jmpr(JIT_TMP); - } - } - else { - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(ARM_CC_AL, d & 0x00ffffff); - } - return (l); -} +#ifdef USE_THUMB_CODE +#define jit_jmpi(i0) \ + (_jitl.thumb_tmp = _jit.x.pc, \ + (_jitl.after_prolog) ? \ + ((_s20P((((long)i0 - (long)l) >> 1) - 2)) ? \ + T2_B(encode_thumb_jump((((long)i0 - (long)l) >> 1) - 2)) : \ + (jit_movi_p(JIT_TMP, i0), jit_jmpr(JIT_TMP))) : \ + (assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(ARM_CC_AL, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff)) \ + _jitl.thumb_tmp) +#else +#define jit_jmpi(i0) \ + (_jit.thumb_tmp = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(ARM_CC_AL, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff), \ + _jit.thumb_tmp) +#endif -__jit_inline jit_insn * -arm_bccr(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1) -{ - jit_insn *l; - long d; - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_CMP(r0, r1); - else if ((r0&r1) & 8) - T1_CMPX(r0, r1); - else - T2_CMP(r0, r1); - /* use only thumb2 conditional as does not know if will be patched */ - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - _CMP(r0, r1); - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} -__jit_inline jit_insn * -arm_bcci(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, int i1) -{ - jit_insn *l; - long d; - int i; - if (jit_thumb_p()) { - if (r0 < 7 && !(i1 & 0xffffff00)) - T1_CMPI(r0, i1); - else if ((i = encode_thumb_immediate(i1)) != -1) - T2_CMPI(r0, i); - else if ((i = encode_thumb_immediate(-i1)) != -1) - T2_CMNI(r0, i); - else { - jit_movi_i(JIT_TMP, i1); - T2_CMP(r0, JIT_TMP); - } - /* use only thumb2 conditional as does not know if will be patched */ - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - if ((i = encode_arm_immediate(i1)) != -1) - _CMPI(r0, i); - else if ((i = encode_arm_immediate(-i1)) != -1) - _CMNI(r0, i); - else { - jit_movi_i(JIT_TMP, i1); - _CMP(r0, JIT_TMP); - } - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} -#define jit_bltr_i(i0, r0, r1) arm_bccr(_jit, ARM_CC_LT, i0, r0, r1) -#define jit_blti_i(i0, r0, i1) arm_bcci(_jit, ARM_CC_LT, i0, r0, i1) -#define jit_bltr_ui(i0, r0, r1) arm_bccr(_jit, ARM_CC_LO, i0, r0, r1) -#define jit_blti_ui(i0, r0, i1) arm_bcci(_jit, ARM_CC_LO, i0, r0, i1) -#define jit_bler_i(i0, r0, r1) arm_bccr(_jit, ARM_CC_LE, i0, r0, r1) -#define jit_blei_i(i0, r0, i1) arm_bcci(_jit, ARM_CC_LE, i0, r0, i1) -#define jit_bler_ui(i0, r0, r1) arm_bccr(_jit, ARM_CC_LS, i0, r0, r1) -#define jit_blei_ui(i0, r0, i1) arm_bcci(_jit, ARM_CC_LS, i0, r0, i1) -#define jit_beqr_i(i0, r0, r1) arm_bccr(_jit, ARM_CC_EQ, i0, r0, r1) -#define jit_beqi_i(i0, r0, i1) arm_bcci(_jit, ARM_CC_EQ, i0, r0, i1) -#define jit_bger_i(i0, r0, r1) arm_bccr(_jit, ARM_CC_GE, i0, r0, r1) -#define jit_bgei_i(i0, r0, i1) arm_bcci(_jit, ARM_CC_GE, i0, r0, i1) -#define jit_bger_ui(i0, r0, r1) arm_bccr(_jit, ARM_CC_HS, i0, r0, r1) -#define jit_bgei_ui(i0, r0, i1) arm_bcci(_jit, ARM_CC_HS, i0, r0, i1) -#define jit_bgtr_i(i0, r0, r1) arm_bccr(_jit, ARM_CC_GT, i0, r0, r1) -#define jit_bgti_i(i0, r0, i1) arm_bcci(_jit, ARM_CC_GT, i0, r0, i1) -#define jit_bgtr_ui(i0, r0, r1) arm_bccr(_jit, ARM_CC_HI, i0, r0, r1) -#define jit_bgti_ui(i0, r0, i1) arm_bcci(_jit, ARM_CC_HI, i0, r0, i1) -#define jit_bner_i(i0, r0, r1) arm_bccr(_jit, ARM_CC_NE, i0, r0, r1) -#define jit_bnei_i(i0, r0, i1) arm_bcci(_jit, ARM_CC_NE, i0, r0, i1) +#ifdef USE_THUMB_CODE +#define arm_bccr(cc, i0, r0, r1) \ + (((r0|r1) < 8) ? T1_CMP(r0, r1) : (((r0&r1) & 8) ? T1_CMPX(r0, r1) : T2_CMP(r0, r1)), \ + /* use only thumb2 conditional as does not know if will be patched */ \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s20P((((long)i0 - (long)l) >> 1) - 2)), \ + T2_CC_B(cc, encode_thumb_cc_jump((((long)i0 - (long)l) >> 1) - 2)), \ + _jitl.thumb_tmp) +#else +#define arm_bccr(cc, i0, r0, r1) \ + (_CMP(r0, r1), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s24P((((long)(i0) - (long)_jit.x.pc) >> 2) - 2)), \ + _CC_B(cc, ((((long)(i0) - (long)_jit.x.pc) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_tmp) +#endif -__jit_inline jit_insn * -arm_baddr(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1) -{ - jit_insn *l; - long d; - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_ADD(r0, r0, r1); - else - T2_ADDS(r0, r0, r1); - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - _ADDS(r0, r0, r1); - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} -__jit_inline jit_insn * -arm_baddi(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, int i1) -{ - jit_insn *l; - long d; - int i; - if (jit_thumb_p()) { - if (r0 < 8 && !(i1 & ~7)) - T1_ADDI3(r0, r0, i1); - else if (r0 < 8 && !(-i1 & ~7)) - T1_SUBI3(r0, r0, -i1); - else if (r0 < 8 && !(i1 & ~0xff)) - T1_ADDI8(r0, i1); - else if (r0 < 8 && !(-i1 & ~0xff)) - T1_SUBI8(r0, -i1); - else if ((i = encode_thumb_immediate(i1)) != -1) - T2_ADDSI(r0, r0, i); - else if ((i = encode_thumb_immediate(-i1)) != -1) - T2_SUBSI(r0, r0, i); - else { - jit_movi_i(JIT_TMP, i1); - T2_ADDS(r0, r0, JIT_TMP); - } - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - if ((i = encode_arm_immediate(i1)) != -1) - _ADDSI(r0, r0, i); - else if ((i = encode_arm_immediate(-i1)) != -1) - _SUBSI(r0, r0, i); - else { - jit_movi_i(JIT_TMP, i1); - _ADDS(r0, r0, JIT_TMP); - } - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} -#define jit_boaddr_i(i0, r0, r1) arm_baddr(_jit, ARM_CC_VS, i0, r0, r1) -#define jit_boaddi_i(i0, r0, i1) arm_baddi(_jit, ARM_CC_VS, i0, r0, i1) -#define jit_boaddr_ui(i0, r0, r1) arm_baddr(_jit, ARM_CC_HS, i0, r0, r1) -#define jit_boaddi_ui(i0, r0, i1) arm_baddi(_jit, ARM_CC_HS, i0, r0, i1) +#ifdef USE_THUMB_CODE +#define arm_bcci(cc, i0, r0, i1) \ + (((r0 < 7 && !(i1 & 0xffffff00)) ? \ + T1_CMPI(r0, i1) : \ + ((encode_thumb_immediate(i1) != -1) ? \ + T2_CMPI(r0, encode_thumb_immediate(i1)) : \ + ((encode_thumb_immediate(-i1) != -1) ? \ + T2_CMNI(r0, encode_thumb_immediate(-i1)) : \ + (jit_movi_i(JIT_TMP, i1), T2_CMP(r0, JIT_TMP))))), \ + /* use only thumb2 conditional as does not know if will be patched */ \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s20P((((long)i0 - (long)l) >> 1) - 2)), \ + T2_CC_B(cc, encode_thumb_cc_jump((((long)i0 - (long)l) >> 1) - 2)), \ + _jitl.thumb_tmp) +#else +#define arm_bcci(cc, i0, r0, i1) \ + (((encode_arm_immediate(i1) != -1) ? \ + _CMPI(r0, encode_arm_immediate(i1)) : \ + ((encode_arm_immediate(-i1) != -1) ? \ + _CMNI(r0, encode_arm_immediate(-i1)) : \ + (jit_movi_i(JIT_TMP, i1), _CMP(r0, JIT_TMP)))), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(cc, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_tmp) +#endif -__jit_inline jit_insn * -arm_bsubr(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1) -{ - jit_insn *l; - long d; - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_SUB(r0, r0, r1); - else - T2_SUBS(r0, r0, r1); - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - _SUBS(r0, r0, r1); - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} +#define jit_bltr_i(i0, r0, r1) arm_bccr(ARM_CC_LT, i0, r0, r1) +#define jit_blti_i(i0, r0, i1) arm_bcci(ARM_CC_LT, i0, r0, i1) +#define jit_bltr_ui(i0, r0, r1) arm_bccr(ARM_CC_LO, i0, r0, r1) +#define jit_blti_ui(i0, r0, i1) arm_bcci(ARM_CC_LO, i0, r0, i1) +#define jit_bler_i(i0, r0, r1) arm_bccr(ARM_CC_LE, i0, r0, r1) +#define jit_blei_i(i0, r0, i1) arm_bcci(ARM_CC_LE, i0, r0, i1) +#define jit_bler_ui(i0, r0, r1) arm_bccr(ARM_CC_LS, i0, r0, r1) +#define jit_blei_ui(i0, r0, i1) arm_bcci(ARM_CC_LS, i0, r0, i1) +#define jit_beqr_i(i0, r0, r1) arm_bccr(ARM_CC_EQ, i0, r0, r1) +#define jit_beqi_i(i0, r0, i1) arm_bcci(ARM_CC_EQ, i0, r0, i1) +#define jit_bger_i(i0, r0, r1) arm_bccr(ARM_CC_GE, i0, r0, r1) +#define jit_bgei_i(i0, r0, i1) arm_bcci(ARM_CC_GE, i0, r0, i1) +#define jit_bger_ui(i0, r0, r1) arm_bccr(ARM_CC_HS, i0, r0, r1) +#define jit_bgei_ui(i0, r0, i1) arm_bcci(ARM_CC_HS, i0, r0, i1) +#define jit_bgtr_i(i0, r0, r1) arm_bccr(ARM_CC_GT, i0, r0, r1) +#define jit_bgti_i(i0, r0, i1) arm_bcci(ARM_CC_GT, i0, r0, i1) +#define jit_bgtr_ui(i0, r0, r1) arm_bccr(ARM_CC_HI, i0, r0, r1) +#define jit_bgti_ui(i0, r0, i1) arm_bcci(ARM_CC_HI, i0, r0, i1) +#define jit_bner_i(i0, r0, r1) arm_bccr(ARM_CC_NE, i0, r0, r1) +#define jit_bnei_i(i0, r0, i1) arm_bcci(ARM_CC_NE, i0, r0, i1) -__jit_inline jit_insn * -arm_bsubi(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, int i1) -{ - jit_insn *l; - long d; - int i; - if (jit_thumb_p()) { - if (r0 < 8 && !(i1 & ~7)) - T1_SUBI3(r0, r0, i1); - else if (r0 < 8 && !(-i1 & ~7)) - T1_ADDI3(r0, r0, -i1); - else if (r0 < 8 && !(i1 & ~0xff)) - T1_SUBI8(r0, i1); - else if (r0 < 8 && !(-i1 & ~0xff)) - T1_ADDI8(r0, -i1); - else if ((i = encode_thumb_immediate(i1)) != -1) - T2_SUBSI(r0, r0, i); - else if ((i = encode_thumb_immediate(-i1)) != -1) - T2_ADDSI(r0, r0, i); - else { - jit_movi_i(JIT_TMP, i1); - T2_SUBS(r0, r0, JIT_TMP); - } - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - if ((i = encode_arm_immediate(i1)) != -1) - _SUBSI(r0, r0, i); - else if ((i = encode_arm_immediate(-i1)) != -1) - _ADDSI(r0, r0, i); - else { - jit_movi_i(JIT_TMP, i1); - _SUBS(r0, r0, JIT_TMP); - } - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} -#define jit_bosubr_i(i0, r0, r1) arm_bsubr(_jit, ARM_CC_VS, i0, r0, r1) -#define jit_bosubi_i(i0, r0, i1) arm_bsubi(_jit, ARM_CC_VS, i0, r0, i1) -#define jit_bosubr_ui(i0, r0, r1) arm_bsubr(_jit, ARM_CC_LO, i0, r0, r1) -#define jit_bosubi_ui(i0, r0, i1) arm_bsubi(_jit, ARM_CC_LO, i0, r0, i1) +#ifdef USE_THUMB_CODE +#define arm_baddr(cc, i0, r0, r1) \ + (((r0|r1) < 8) ? T1_ADD(r0, r0, r1) : T2_ADDS(r0, r0, r1), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s20P((((long)i0 - (long)l) >> 1) - 2)), \ + T2_CC_B(cc, encode_thumb_cc_jump((((long)i0 - (long)l) >> 1) - 2)), \ + _jitl.thumb_tmp) +#else +#define arm_baddr(cc, i0, r0, r1) \ + (_ADDS(r0, r0, r1), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(cc, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_tmp) +#endif -__jit_inline jit_insn * -arm_bmxr(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, jit_gpr_t r1) -{ - jit_insn *l; - long d; - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_TST(r0, r1); - else - T2_TST(r0, r1); - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - if (jit_armv5_p()) - _TST(r0, r1); - else - _ANDS(JIT_TMP, r0, r1); - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} -__jit_inline jit_insn * -arm_bmxi(jit_state_t _jit, int cc, jit_insn *i0, jit_gpr_t r0, int i1) -{ - jit_insn *l; - long d; - int i; - if (jit_thumb_p()) { - if ((i = encode_thumb_immediate(i1)) != -1) - T2_TSTI(r0, i); - else { - jit_movi_i(JIT_TMP, i1); - T2_TST(r0, JIT_TMP); - } - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 1) - 2; - assert(_s20P(d)); - T2_CC_B(cc, encode_thumb_cc_jump(d)); - } - else { - if (jit_armv5_p()) { - if ((i = encode_arm_immediate(i1)) != -1) - _TSTI(r0, i); - else { - jit_movi_i(JIT_TMP, i1); - _TST(r0, JIT_TMP); - } - } - else { - if ((i = encode_arm_immediate(i1)) != -1) - _ANDSI(JIT_TMP, r0, i); - else if ((i = encode_arm_immediate(~i1)) != -1) - _BICSI(JIT_TMP, r0, i); - else { - jit_movi_i(JIT_TMP, i1); - _ANDS(JIT_TMP, r0, JIT_TMP); - } - } - l = _jit->x.pc; - d = (((long)i0 - (long)l) >> 2) - 2; - assert(_s24P(d)); - _CC_B(cc, d & 0x00ffffff); - } - return (l); -} -#define jit_bmsr_i(i0, r0, r1) arm_bmxr(_jit, ARM_CC_NE, i0, r0, r1) -#define jit_bmsi_i(i0, r0, i1) arm_bmxi(_jit, ARM_CC_NE, i0, r0, i1) -#define jit_bmcr_i(i0, r0, r1) arm_bmxr(_jit, ARM_CC_EQ, i0, r0, r1) -#define jit_bmci_i(i0, r0, i1) arm_bmxi(_jit, ARM_CC_EQ, i0, r0, i1) +#ifdef USE_THUMB_CODE +#define arm_baddi(cc, i0, r0, i1) \ + (((r0 < 8 && !(i1 & ~7)) ? \ + T1_ADDI3(r0, r0, i1) : \ + ((r0 < 8 && !(-i1 & ~7)) ? \ + T1_SUBI3(r0, r0, -i1) : \ + ((r0 < 8 && !(i1 & ~0xff)) ? \ + T1_ADDI8(r0, i1) : \ + ((r0 < 8 && !(-i1 & ~0xff)) ? \ + T1_SUBI8(r0, -i1) : \ + ((encode_thumb_immediate(i1) != -1) ? \ + T2_ADDSI(r0, r0, encode_thumb_immediate(i1)) : \ + ((encode_thumb_immediate(-i1) != -1) ? \ + T2_SUBSI(r0, r0, encode_thumb_immediate(-i1)) : \ + (jit_movi_i(JIT_TMP, i1), T2_ADDS(r0, r0, JIT_TMP)))))))), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s20P((((long)i0 - (long)l) >> 1) - 2)), \ + T2_CC_B(cc, encode_thumb_cc_jump((((long)i0 - (long)l) >> 1) - 2)), \ + _jitl.thumb_tmp) +#else +#define arm_baddi(cc, i0, r0, i1) \ + (((encode_arm_immediate(i1) != -1) ? \ + _ADDSI(r0, r0, encode_arm_immediate(i1)) : \ + ((encode_arm_immediate(-i1) != -1) ? \ + _SUBSI(r0, r0, encode_arm_immediate(-i1)) : \ + (jit_movi_i(JIT_TMP, i1), _ADDS(r0, r0, JIT_TMP)))), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(cc, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_tmp) +#endif -#define jit_ldr_c(r0, r1) arm_ldr_c(_jit, r0, r1) -__jit_inline void -arm_ldr_c(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_LDRSBI(r0, r1, 0); - else - _LDRSBI(r0, r1, 0); -} +#define jit_boaddr_i(i0, r0, r1) arm_baddr(ARM_CC_VS, i0, r0, r1) +#define jit_boaddi_i(i0, r0, i1) arm_baddi(ARM_CC_VS, i0, r0, i1) +#define jit_boaddr_ui(i0, r0, r1) arm_baddr(ARM_CC_HS, i0, r0, r1) +#define jit_boaddi_ui(i0, r0, i1) arm_baddi(ARM_CC_HS, i0, r0, i1) -#define jit_ldi_c(r0, i0) arm_ldi_c(_jit, r0, i0) -__jit_inline void -arm_ldi_c(jit_state_t _jit, jit_gpr_t r0, void *i0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_LDRSBI(r0, JIT_TMP, 0); - else - _LDRSBI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define arm_bsubr(cc, i0, r0, r1) \ + (((r0|r1) < 8) ? T1_SUB(r0, r0, r1) : T2_SUBS(r0, r0, r1), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s20P((((long)i0 - (long)l) >> 1) - 2)), \ + T2_CC_B(cc, encode_thumb_cc_jump((((long)i0 - (long)l) >> 1) - 2)), \ + _jitl.thumb_tmp) +#else +#define arm_bsubr(cc, i0, r0, r1) \ + (_SUBS(r0, r0, r1), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(cc, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_tmp) +#endif -#define jit_ldxr_c(r0, r1, r2) arm_ldxr_c(_jit, r0, r1, r2) -__jit_inline void -arm_ldxr_c(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_LDRSB(r0, r1, r2); - else - T2_LDRSB(r0, r1, r2); - } - else - _LDRSB(r0, r1, r2); -} +#ifdef USE_THUMB_CODE +#define arm_bsubi(cc, i0, r0, i1) \ + (((r0 < 8 && !((i1) & ~7)) ? \ + T1_SUBI3(r0, r0, i1) : \ + ((r0 < 8 && !(-(i1) & ~7)) ? \ + T1_ADDI3(r0, r0, -i1) : \ + ((r0 < 8 && !((i1) & ~0xff)) ? \ + T1_SUBI8(r0, i1) : \ + ((r0 < 8 && !(-(i1) & ~0xff)) ? \ + T1_ADDI8(r0, -(i1)) : \ + ((encode_thumb_immediate(i1) != -1) ? \ + T2_SUBSI(r0, r0, encode_thumb_immediate(i1)) : \ + ((encode_thumb_immediate(-i1) != -1) ? \ + T2_ADDSI(r0, r0, encode_thumb_immediate(-i1)) : \ + (jit_movi_i(JIT_TMP, i1), T2_SUBS(r0, r0, JIT_TMP)))))))), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s20P((((long)i0 - (long)_jitl.thumb_tmp) >> 1) - 2)), \ + T2_CC_B(cc, encode_thumb_cc_jump((((long)(i0) - (long)_jitl.thumb_tmp) >> 1) - 2)), \ + _jitl.thumb_tmp) +#else +#define arm_bsubi(cc, i0, r0, i1) \ + (((encode_arm_immediate(i1) != -1) ? \ + _SUBSI(r0, r0, encode_arm_immediate(i1)) : \ + ((encode_arm_immediate(-i1) != -1) ? \ + _ADDSI(r0, r0, encode_arm_immediate(-i1)) : \ + (jit_movi_i(JIT_TMP, i1), _SUBS(r0, r0, JIT_TMP)))), \ + _jitl.thumb_tmp = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(cc, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_tmp) +#endif -#define jit_ldxi_c(r0, r1, i0) arm_ldxi_c(_jit, r0, r1, i0) -__jit_inline void -arm_ldxi_c(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_gpr_t reg; - if (jit_thumb_p()) { - if (i0 >= 0 && i0 <= 255) - T2_LDRSBI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - T2_LDRSBIN(r0, r1, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_LDRSBWI(r0, r1, i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - if ((r0|r1|reg) < 8) - T1_LDRSB(r0, r1, reg); - else - T2_LDRSB(r0, r1, reg); - } - } - else { - if (i0 >= 0 && i0 <= 255) - _LDRSBI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - _LDRSBIN(r0, r1, -i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _LDRSB(r0, r1, reg); - } - } -} +#define jit_bosubr_i(i0, r0, r1) arm_bsubr(ARM_CC_VS, i0, r0, r1) +#define jit_bosubi_i(i0, r0, i1) arm_bsubi(ARM_CC_VS, i0, r0, i1) +#define jit_bosubr_ui(i0, r0, r1) arm_bsubr(ARM_CC_LO, i0, r0, r1) +#define jit_bosubi_ui(i0, r0, i1) arm_bsubi(ARM_CC_LO, i0, r0, i1) -#define jit_ldr_uc(r0, r1) arm_ldr_uc(_jit, r0, r1) -__jit_inline void -arm_ldr_uc(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_LDRBI(r0, r1, 0); - else - _LDRBI(r0, r1, 0); -} +#ifdef USE_THUMB_CODE +#define arm_bmxr(cc, i0, r0, r1) \ + (((r0|r1) < 8) ? T1_TST(r0, r1) : T2_TST(r0, r1), \ + _jitl.thumb_pc = _jit.x.pc, \ + assert(_s20P((((long)i0 - (long)l) >> 1) - 2)), \ + T2_CC_B(cc, encode_thumb_cc_jump((((long)i0 - (long)l) >> 1) - 2)), \ + _jitl.thumb_pc) +#else +#define arm_bmxr(cc, i0, r0, r1) \ + (((jit_armv5_p()) ? _TST(r0, r1) : _ANDS(JIT_TMP, r0, r1)), \ + _jitl.thumb_pc = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)l) >> 2) - 2)), \ + _CC_B(cc, ((((long)i0 - (long)l) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_pc) +#endif -#define jit_ldi_uc(r0, i0) arm_ldi_uc(_jit, r0, i0) -__jit_inline void -arm_ldi_uc(jit_state_t _jit, jit_gpr_t r0, void *i0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_LDRBI(r0, JIT_TMP, 0); - else - _LDRBI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define arm_bmxi(cc, i0, r0, i1) \ + ((jit_armv5_p()) ? \ + ((encode_arm_immediate(i1) != -1) ? \ + _TSTI(r0, encode_arm_immediate(i1)) : \ + (jit_movi_i(JIT_TMP, i1), _TST(r0, JIT_TMP))) \ + (((i = encode_arm_immediate(i1)) != -1) ? \ + _ANDSI(JIT_TMP, r0, i) : \ + (((encode_arm_immediate(~i1)) != -1) ? \ + _BICSI(JIT_TMP, r0, encode_arm_immediate(~i1)) : \ + (jit_movi_i(JIT_TMP, i1), _ANDS(JIT_TMP, r0, JIT_TMP)))), \ + _jitl.thumb_pc = _jit.x.pc, \ + assert(_s24P((((long)i0 - (long)_jitl.thumb_pc) >> 2) - 2)), \ + _CC_B(cc, ((((long)i0 - (long)_jitl.thumb_pc) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_pc) +#else +#define arm_bmxi(cc, i0, r0, i1) \ + ((jit_armv5_p()) ? \ + ((encode_arm_immediate(i1) != -1) ? \ + _TSTI(r0, encode_arm_immediate(i1)) : \ + (jit_movi_i(JIT_TMP, i1), _TST(r0, JIT_TMP))) : \ + ((encode_arm_immediate(i1) != -1) ? \ + _ANDSI(JIT_TMP, r0, encode_arm_immediate(i1)) : \ + ((encode_arm_immediate(~(i1)) != -1) ? \ + _BICSI(JIT_TMP, r0, encode_arm_immediate(~i1)) : \ + (jit_movi_i(JIT_TMP, i1), _ANDS(JIT_TMP, r0, JIT_TMP)))), \ + _jitl.thumb_pc = _jit.x.pc, \ + assert(_s24P((((long)(i0) - (long)_jitl.thumb_pc) >> 2) - 2)), \ + _CC_B(cc, ((((long)(i0) - (long)_jitl.thumb_pc) >> 2) - 2) & 0x00ffffff), \ + _jitl.thumb_pc) +#endif -#define jit_ldxr_uc(r0, r1, r2) arm_ldxr_uc(_jit, r0, r1, r2) -__jit_inline void -arm_ldxr_uc(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_LDRB(r0, r1, r2); - else - T2_LDRB(r0, r1, r2); - } - else - _LDRB(r0, r1, r2); -} +#define jit_bmsr_i(i0, r0, r1) arm_bmxr(ARM_CC_NE, i0, r0, r1) +#define jit_bmsi_i(i0, r0, i1) arm_bmxi(ARM_CC_NE, i0, r0, i1) +#define jit_bmcr_i(i0, r0, r1) arm_bmxr(ARM_CC_EQ, i0, r0, r1) +#define jit_bmci_i(i0, r0, i1) arm_bmxi(ARM_CC_EQ, i0, r0, i1) -#define jit_ldxi_uc(r0, r1, i0) arm_ldxi_uc(_jit, r0, r1, i0) -__jit_inline void -arm_ldxi_uc(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20) - T1_LDRBI(r0, r1, i0); - else if (i0 >= 0 && i0 <= 255) - T2_LDRBI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - T2_LDRBIN(r0, r1, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_LDRBWI(r0, r1, i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - if ((r0|r1|reg) < 8) - T1_LDRB(r0, r1, reg); - else - T2_LDRB(r0, r1, reg); - } - } - else { - if (i0 >= 0 && i0 <= 4095) - _LDRBI(r0, r1, i0); - else if (i0 < 0 && i0 >= -4095) - _LDRBIN(r0, r1, -i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _LDRB(r0, r1, reg); - } - } -} +#ifdef USE_THUMB_CODE +#define jit_ldr_c(r0, r1) T2_LDRSBI(r0, r1, 0) +#else +#define jit_ldr_c(r0, r1) _LDRSBI(r0, r1, 0) +#endif -#define jit_ldr_s(r0, r1) arm_ldr_s(_jit, r0, r1) -__jit_inline void -arm_ldr_s(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_LDRSHI(r0, r1, 0); - else - _LDRSHI(r0, r1, 0); +#ifdef USE_THUMB_CODE +#define jit_ldi_c(r0, i0) \ +{ \ + jit_movi_i(JIT_TMP, (int)i0); \ + T2_LDRSBI(r0, JIT_TMP, 0); \ } +#else +#define jit_ldi_c(r0, i0) \ +{ \ + jit_movi_i(JIT_TMP, (int)i0); \ + _LDRSBI(r0, JIT_TMP, 0); \ +} +#endif -#define jit_ldi_s(r0, i0) arm_ldi_s(_jit, r0, i0) -__jit_inline void -arm_ldi_s(jit_state_t _jit, jit_gpr_t r0, void *i0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_LDRSHI(r0, JIT_TMP, 0); - else - _LDRSHI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldxr_c(r0, r1, r2) \ + ((r0|r1|r2) < 8) ? T1_LDRSB(r0, r1, r2) : T2_LDRSB(r0, r1, r2) +#else +#define jit_ldxr_c(r0, r1, r2) _LDRSB(r0, r1, r2) +#endif -#define jit_ldxr_s(r0, r1, r2) arm_ldxr_s(_jit, r0, r1, r2) -__jit_inline void -arm_ldxr_s(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_LDRSH(r0, r1, r2); - else - T2_LDRSH(r0, r1, r2); - } - else - _LDRSH(r0, r1, r2); +#ifdef USE_THUMB_CODE +#define jit_ldxi_c(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 255) \ + T2_LDRSBI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -255) \ + T2_LDRSBIN(r0, r1, -i0); \ + else if (i0 >= 0 && i0 <= 4095) \ + T2_LDRSBWI(r0, r1, i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + if ((r0|r1|reg) < 8) \ + T1_LDRSB(r0, r1, reg); \ + else \ + T2_LDRSB(r0, r1, reg); \ + } \ } +#else +#define jit_ldxi_c(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 255) \ + _LDRSBI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -255) \ + _LDRSBIN(r0, r1, -i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _LDRSB(r0, r1, reg); \ + } \ +} +#endif -#define jit_ldxi_s(r0, r1, i0) arm_ldxi_s(_jit, r0, r1, i0) -__jit_inline void -arm_ldxi_s(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_gpr_t reg; - if (jit_thumb_p()) { - if (i0 >= 0 && i0 <= 255) - T2_LDRSHI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - T2_LDRSHIN(r0, r1, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_LDRSHWI(r0, r1, i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - if ((r0|r1|reg) < 8) - T1_LDRSH(r0, r1, reg); - else - T2_LDRSH(r0, r1, reg); - } - } - else { - if (i0 >= 0 && i0 <= 255) - _LDRSHI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - _LDRSHIN(r0, r1, -i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _LDRSH(r0, r1, reg); - } - } +#ifdef USE_THUMB_CODE +#define jit_ldr_uc(r0, r1) T2_LDRBI(r0, r1, 0) +#else +#define jit_ldr_uc(r0, r1) _LDRBI(r0, r1, 0) +#endif -} -#define jit_ldr_us(r0, r1) arm_ldr_us(_jit, r0, r1) -__jit_inline void -arm_ldr_us(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_LDRHI(r0, r1, 0); - else - _LDRHI(r0, r1, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldi_uc(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), T2_LDRBI(r0, JIT_TMP, 0)) +#else +#define jit_ldi_uc(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), _LDRBI(r0, JIT_TMP, 0)) +#endif -#define jit_ldi_us(r0, i0) arm_ldi_us(_jit, r0, i0) -__jit_inline void -arm_ldi_us(jit_state_t _jit, jit_gpr_t r0, void *i0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_LDRHI(r0, JIT_TMP, 0); - else - _LDRHI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldxr_uc(r0, r1, r2) \ + ((r0|r1|r2) < 8) ? T1_LDRB(r0, r1, r2) : T2_LDRB(r0, r1, r2) +#else +#define jit_ldxr_uc(r0, r1, r2) _LDRB(r0, r1, r2) +#endif -#define jit_ldxr_us(r0, r1, r2) arm_ldxr_us(_jit, r0, r1, r2) -__jit_inline void -arm_ldxr_us(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_LDRH(r0, r1, r2); - else - T2_LDRH(r0, r1, r2); - } - else - _LDRH(r0, r1, r2); +#ifdef USE_THUMB_CODE +#define jit_ldxi_uc(r0, r1, i0) \ +{ \ + if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20) \ + T1_LDRBI(r0, r1, i0); \ + else if (i0 >= 0 && i0 <= 255) \ + T2_LDRBI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -255) \ + T2_LDRBIN(r0, r1, -i0); \ + else if (i0 >= 0 && i0 <= 4095) \ + T2_LDRBWI(r0, r1, i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + if ((r0|r1|reg) < 8) \ + T1_LDRB(r0, r1, reg); \ + else \ + T2_LDRB(r0, r1, reg); \ + } \ } +#else +#define jit_ldxi_uc(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 4095) \ + _LDRBI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -4095) \ + _LDRBIN(r0, r1, -i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _LDRB(r0, r1, reg); \ + } \ +} +#endif -#define jit_ldxi_us(r0, r1, i0) arm_ldxi_us(_jit, r0, r1, i0) -__jit_inline void -arm_ldxi_us(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20) - T1_LDRHI(r0, r1, i0 >> 1); - else if (i0 >= 0 && i0 <= 255) - T2_LDRHI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - T2_LDRHIN(r0, r1, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_LDRHWI(r0, r1, i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - if ((r0|r1|reg) < 8) - T1_LDRH(r0, r1, reg); - else - T2_LDRH(r0, r1, reg); - } - } - else { - if (i0 >= 0 && i0 <= 255) - _LDRHI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - _LDRHIN(r0, r1, -i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _LDRH(r0, r1, reg); - } - } -} +#ifdef USE_THUMB_CODE +#define jit_ldr_s(r0, r1) T2_LDRSHI(r0, r1, 0) +#else +#define jit_ldr_s(r0, r1) _LDRSHI(r0, r1, 0) +#endif -#define jit_ldr_i(r0, r1) arm_ldr_i(_jit, r0, r1) -__jit_inline void -arm_ldr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_LDRI(r0, r1, 0); - else - _LDRI(r0, r1, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldi_s(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), T2_LDRSHI(r0, JIT_TMP, 0)) +#else +#define jit_ldi_s(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), _LDRSHI(r0, JIT_TMP, 0)) +#endif -#define jit_ldi_i(r0, i0) arm_ldi_i(_jit, r0, i0) -__jit_inline void -arm_ldi_i(jit_state_t _jit, jit_gpr_t r0, void *i0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_LDRI(r0, JIT_TMP, 0); - else - _LDRI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldxr_s(r0, r1, r2) \ + ((r0|r1|r2) < 8) ? T1_LDRSH(r0, r1, r2) : T2_LDRSH(r0, r1, r2) +#else +#define jit_ldxr_s(r0, r1, r2) _LDRSH(r0, r1, r2) +#endif -#define jit_ldxr_i(r0, r1, r2) arm_ldxr_i(_jit, r0, r1, r2) -__jit_inline void -arm_ldxr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_LDR(r0, r1, r2); - else - T2_LDR(r0, r1, r2); - } - else - _LDR(r0, r1, r2); +#ifdef USE_THUMB_CODE +#define jit_ldxi_s(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 255) \ + T2_LDRSHI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -255) \ + T2_LDRSHIN(r0, r1, -i0); \ + else if (i0 >= 0 && i0 <= 4095) \ + T2_LDRSHWI(r0, r1, i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + if ((r0|r1|reg) < 8) \ + T1_LDRSH(r0, r1, reg); \ + else \ + T2_LDRSH(r0, r1, reg); \ + } \ } +#else +#define jit_ldxi_s(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 255) \ + _LDRSHI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -255) \ + _LDRSHIN(r0, r1, -i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _LDRSH(r0, r1, reg); \ + } \ +} +#endif -#define jit_ldxi_i(r0, r1, i0) arm_ldxi_i(_jit, r0, r1, i0) -__jit_inline void -arm_ldxi_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, int i0) -{ - jit_gpr_t reg; - if (jit_thumb_p()) { - if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20) - T1_LDRI(r0, r1, i0 >> 2); - else if (r1 == _R13 && r0 < 8 && - i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255) - T1_LDRISP(r0, i0 >> 2); - else if (i0 >= 0 && i0 <= 255) - T2_LDRI(r0, r1, i0); - else if (i0 < 0 && i0 >= -255) - T2_LDRIN(r0, r1, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_LDRWI(r0, r1, i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - if ((r0|r1|reg) < 8) - T1_LDR(r0, r1, reg); - else - T2_LDR(r0, r1, reg); - } - } - else { - if (i0 >= 0 && i0 <= 4095) - _LDRI(r0, r1, i0); - else if (i0 < 0 && i0 >= -4095) - _LDRIN(r0, r1, -i0); - else { - reg = r0 != r1 ? r0 : JIT_TMP; - jit_movi_i(reg, i0); - _LDR(r0, r1, reg); - } - } -} +#ifdef USE_THUMB_CODE +#define jit_ldr_us(r0, r1) T2_LDRHI(r0, r1, 0) +#else +#define jit_ldr_us(r0, r1) _LDRHI(r0, r1, 0) +#endif -#define jit_str_c(r0, r1) arm_str_c(_jit, r0, r1) -__jit_inline void -arm_str_c(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_STRBI(r1, r0, 0); - else - _STRBI(r1, r0, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldi_us(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), T2_LDRHI(r0, JIT_TMP, 0)) +#else +#define jit_ldi_us(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), _LDRHI(r0, JIT_TMP, 0)) +#endif -#define jit_sti_c(r0, i0) arm_sti_c(_jit, r0, i0) -__jit_inline void -arm_sti_c(jit_state_t _jit, void *i0, jit_gpr_t r0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_STRBI(r0, JIT_TMP, 0); - else - _STRBI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldxr_us(r0, r1, r2) \ + ((r0|r1|r2) < 8) ? T1_LDRH(r0, r1, r2) : T2_LDRH(r0, r1, r2) +#else +#define jit_ldxr_us(r0, r1, r2) _LDRH(r0, r1, r2) +#endif -#define jit_stxr_c(r0, r1, r2) arm_stxr_c(_jit, r0, r1, r2) -__jit_inline void -arm_stxr_c(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_STRB(r2, r1, r0); - else - T2_STRB(r2, r1, r0); - } - else - _STRB(r2, r1, r0); +#ifdef USE_THUMB_CODE +#define jit_ldxi_us(r0, r1, i0) \ +{ \ + if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20) \ + T1_LDRHI(r0, r1, i0 >> 1); \ + else if (i0 >= 0 && i0 <= 255) \ + T2_LDRHI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -255) \ + T2_LDRHIN(r0, r1, -i0); \ + else if (i0 >= 0 && i0 <= 4095) \ + T2_LDRHWI(r0, r1, i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + if ((r0|r1|reg) < 8) \ + T1_LDRH(r0, r1, reg); \ + else \ + T2_LDRH(r0, r1, reg); \ + } \ } +#else +#define jit_ldxi_us(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 255) \ + _LDRHI(r0, r1, i0); \ + else if (i0 < 0 && i0 >= -255) \ + _LDRHIN(r0, r1, -i0); \ + else { \ + jit_gpr_t reg = r0 != r1 ? r0 : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _LDRH(r0, r1, reg); \ + } \ +} +#endif -#define jit_stxi_c(r0, r1, i0) arm_stxi_c(_jit, r0, r1, i0) -__jit_inline void -arm_stxi_c(jit_state_t _jit, int i0, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20) - T1_STRBI(r1, r0, i0); - else if (i0 >= 0 && i0 <= 255) - T2_STRBI(r1, r0, i0); - else if (i0 < 0 && i0 >= -255) - T2_STRBIN(r1, r0, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_STRBWI(r1, r0, i0); - else { - jit_movi_i(JIT_TMP, (int)i0); - if ((r0|r1|JIT_TMP) < 8) - T1_STRB(r1, r0, JIT_TMP); - else - T2_STRB(r1, r0, JIT_TMP); - } - } - else { - if (i0 >= 0 && i0 <= 4095) - _STRBI(r1, r0, i0); - else if (i0 < 0 && i0 >= -4095) - _STRBIN(r1, r0, -i0); - else { - jit_movi_i(JIT_TMP, i0); - _STRB(r1, r0, JIT_TMP); - } - } -} +#ifdef USE_THUMB_CODE +#define jit_ldr_i(r0, r1) T2_LDRI(r0, r1, 0) +#else +#define jit_ldr_i(r0, r1) _LDRI(r0, r1, 0) +#endif -#define jit_str_s(r0, r1) arm_str_s(_jit, r0, r1) -__jit_inline void -arm_str_s(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_STRHI(r1, r0, 0); - else - _STRHI(r1, r0, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldi_i(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), T2_LDRI(r0, JIT_TMP, 0)) +#else +#define jit_ldi_i(r0, i0) \ + (jit_movi_i(JIT_TMP, (int)i0), _LDRI(r0, JIT_TMP, 0)) +#endif -#define jit_sti_s(r0, i0) arm_sti_s(_jit, r0, i0) -__jit_inline void -arm_sti_s(jit_state_t _jit, void *i0, jit_gpr_t r0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_STRHI(r0, JIT_TMP, 0); - else - _STRHI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define jit_ldxr_i(r0, r1, r2) \ + (((r0|r1|r2) < 8) ? T1_LDR(r0, r1, r2) : T2_LDR(r0, r1, r2)) +#else +#define jit_ldxr_i(r0, r1, r2) _LDR(r0, r1, r2) +#endif -#define jit_stxr_s(r0, r1, r2) arm_stxr_s(_jit, r0, r1, r2) -__jit_inline void -arm_stxr_s(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_STRH(r2, r1, r0); - else - T2_STRH(r2, r1, r0); - } - else - _STRH(r2, r1, r0); +#ifdef USE_THUMB_CODE +#define jit_ldxi_i(r0, r1, i0) \ +{ \ + if (((r0)|(r1)) < 8 && (i0) >= 0 && !((i0) & 3) && ((i0) >> 2) < 0x20) \ + T1_LDRI(r0, r1, (i0) >> 2); \ + else if ((r1) == _R13 && (r0) < 8 && \ + (i0) >= 0 && !((i0) & 3) && ((i0) >> 2) <= 255) \ + T1_LDRISP(r0, (i0) >> 2); \ + else if ((i0) >= 0 && (i0) <= 255) \ + T2_LDRI(r0, r1, i0); \ + else if ((i0) < 0 && (i0) >= -255) \ + T2_LDRIN((r0), (r1), -(i0)); \ + else if ((i0) >= 0 && (i0) <= 4095) \ + T2_LDRWI(r0, r1, i0); \ + else { \ + jit_gpr_t reg = (r0) != (r1) ? (r0) : JIT_TMP; \ + jit_movi_i(reg, i0); \ + if (((r0)|(r1)|reg) < 8) \ + T1_LDR(r0, r1, reg); \ + else \ + T2_LDR(r0, r1, reg); \ + } \ } +#else +#define jit_ldxi_i(r0, r1, i0) \ +{ \ + if ((i0) >= 0 && (i0) <= 4095) \ + _LDRI(r0, r1, i0); \ + else if ((i0) < 0 && (i0) >= -4095) \ + _LDRIN(r0, r1, -i0); \ + else { \ + jit_gpr_t reg = (r0) != (r1) ? (r0) : JIT_TMP; \ + jit_movi_i(reg, i0); \ + _LDR(r0, r1, reg); \ + } \ +} +#endif -#define jit_stxi_s(r0, r1, i0) arm_stxi_s(_jit, r0, r1, i0) -__jit_inline void -arm_stxi_s(jit_state_t _jit, int i0, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20) - T1_STRHI(r1, r0, i0 >> 1); - else if (i0 >= 0 && i0 <= 255) - T2_STRHI(r1, r0, i0); - else if (i0 < 0 && i0 >= -255) - T2_STRHIN(r1, r0, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_STRHWI(r1, r0, i0); - else { - jit_movi_i(JIT_TMP, (int)i0); - if ((r0|r1|JIT_TMP) < 8) - T1_STRH(r1, r0, JIT_TMP); - else - T2_STRH(r1, r0, JIT_TMP); - } - } - else { - if (i0 >= 0 && i0 <= 255) - _STRHI(r1, r0, i0); - else if (i0 < 0 && i0 >= -255) - _STRHIN(r1, r0, -i0); - else { - jit_movi_i(JIT_TMP, i0); - _STRH(r1, r0, JIT_TMP); - } - } -} +#ifdef USE_THUMB_CODE +#define jit_str_c(r0, r1) T2_STRBI(r1, r0, 0); +#else +#define jit_str_c(r0, r1) _STRBI(r1, r0, 0); +#endif -#define jit_str_i(r0, r1) arm_str_i(_jit, r0, r1) -__jit_inline void -arm_str_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) - T2_STRI(r1, r0, 0); - else - _STRI(r1, r0, 0); -} +#ifdef USE_THUMB_CODE +#define jit_sti_c(r0, i0) (jit_movi_i(JIT_TMP, (int)i0), T2_STRBI(r0, JIT_TMP, 0)) +#else +#define jit_sti_c(r0, i0) (jit_movi_i(JIT_TMP, (int)i0), _STRBI(r0, JIT_TMP, 0)) +#endif -#define jit_sti_i(r0, i0) arm_sti_i(_jit, r0, i0) -__jit_inline void -arm_sti_i(jit_state_t _jit, void *i0, jit_gpr_t r0) -{ - jit_movi_i(JIT_TMP, (int)i0); - if (jit_thumb_p()) - T2_STRI(r0, JIT_TMP, 0); - else - _STRI(r0, JIT_TMP, 0); -} +#ifdef USE_THUMB_CODE +#define jit_stxr_c(r0, r1, r2) \ + (((r0)|(r1)|(r2)) < 8) ? T1_STRB(r2, r1, r0) : T2_STRB(r2, r1, r0) +#else +#define jit_stxr_c(r0, r1, r2) _STRB(r2, r1, r0) +#endif -#define jit_stxr_i(r0, r1, r2) arm_stxr_i(_jit, r0, r1, r2) -__jit_inline void -arm_stxr_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) -{ - if (jit_thumb_p()) { - if ((r0|r1|r2) < 8) - T1_STR(r2, r1, r0); - else - T2_STR(r2, r1, r0); - } - else - _STR(r2, r1, r0); +#ifdef USE_THUMB_CODE +#define jit_stxi_c(r0, r1, i0) \ +{ \ + if ((r0|r1) < 8 && i0 >= 0 && i0 < 0x20) \ + T1_STRBI(r1, r0, i0); \ + else if (i0 >= 0 && i0 <= 255) \ + T2_STRBI(r1, r0, i0); \ + else if (i0 < 0 && i0 >= -255) \ + T2_STRBIN(r1, r0, -i0); \ + else if (i0 >= 0 && i0 <= 4095) \ + T2_STRBWI(r1, r0, i0); \ + else { \ + jit_movi_i(JIT_TMP, (int)i0); \ + if ((r0|r1|JIT_TMP) < 8) \ + T1_STRB(r1, r0, JIT_TMP); \ + else \ + T2_STRB(r1, r0, JIT_TMP); \ + } \ } +#else +#define jit_stxi_c(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 4095) \ + _STRBI(r1, r0, i0); \ + else if (i0 < 0 && i0 >= -4095) \ + _STRBIN(r1, r0, -i0); \ + else { \ + jit_movi_i(JIT_TMP, i0); \ + _STRB(r1, r0, JIT_TMP); \ + } \ +} +#endif -#define jit_stxi_i(r0, r1, i0) arm_stxi_i(_jit, r0, r1, i0) -__jit_inline void -arm_stxi_i(jit_state_t _jit, int i0, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20) - T1_STRI(r1, r0, i0 >> 2); - else if (r0 == _R13 && r1 < 8 && - i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255) - T1_STRISP(r1, i0 >> 2); - else if (i0 >= 0 && i0 <= 255) - T2_STRI(r1, r0, i0); - else if (i0 < 0 && i0 >= -255) - T2_STRIN(r1, r0, -i0); - else if (i0 >= 0 && i0 <= 4095) - T2_STRWI(r1, r0, i0); - else { - jit_movi_i(JIT_TMP, (int)i0); - if ((r0|r1|JIT_TMP) < 8) - T1_STR(r1, r0, JIT_TMP); - else - T2_STR(r1, r0, JIT_TMP); - } - } - else { - if (i0 >= 0 && i0 <= 4095) - _STRI(r1, r0, i0); - else if (i0 < 0 && i0 >= -4095) - _STRIN(r1, r0, -i0); - else { - jit_movi_i(JIT_TMP, i0); - _STR(r1, r0, JIT_TMP); - } - } +#ifdef USE_THUMB_CODE +#define jit_str_s(r0, r1) T2_STRHI(r1, r0, 0) +#else +#define jit_str_s(r0, r1) _STRHI(r1, r0, 0) +#endif + +#ifdef USE_THUMB_CODE +#define jit_sti_s(r0, i0) (jit_movi_i(JIT_TMP, (int)i0), T2_STRHI(r0, JIT_TMP, 0)) +#else +#define jit_sti_s(r0, i0) (jit_movi_i(JIT_TMP, (int)i0), _STRHI(r0, JIT_TMP, 0)) +#endif + +#ifdef USE_THUMB_CODE +#define jit_stxr_s(r0, r1, r2) \ + ((((r0)|(r1)|(r2)) < 8) ? T1_STRH(r2, r1, r0) : T2_STRH(r2, r1, r0)) +#else +#define jit_stxr_s(r0, r1, r2) _STRH(r2, r1, r0) +#endif + +#ifdef USE_THUMB_CODE +#define jit_stxi_s(r0, r1, i0) \ +{ \ + if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 1) && (i0 >> 1) < 0x20) \ + T1_STRHI(r1, r0, i0 >> 1); \ + else if (i0 >= 0 && i0 <= 255) \ + T2_STRHI(r1, r0, i0); \ + else if (i0 < 0 && i0 >= -255) \ + T2_STRHIN(r1, r0, -i0); \ + else if (i0 >= 0 && i0 <= 4095) \ + T2_STRHWI(r1, r0, i0); \ + else { \ + jit_movi_i(JIT_TMP, (int)i0); \ + if ((r0|r1|JIT_TMP) < 8) \ + T1_STRH(r1, r0, JIT_TMP); \ + else \ + T2_STRH(r1, r0, JIT_TMP); \ + } \ } +#else +#define jit_stxi_s(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 255) \ + _STRHI(r1, r0, i0); \ + else if (i0 < 0 && i0 >= -255) \ + _STRHIN(r1, r0, -i0); \ + else { \ + jit_movi_i(JIT_TMP, i0); \ + _STRH(r1, r0, JIT_TMP); \ + } \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_str_i(r0, r1) T2_STRI(r1, r0, 0) +#else +#define jit_str_i(r0, r1) _STRI(r1, r0, 0) +#endif + +#ifdef USE_THUMB_CODE +#define jit_sti_i(r0, i0) (jit_movi_i(JIT_TMP, (int)i0), T2_STRI(r0, JIT_TMP, 0)) +#else +#define jit_sti_i(r0, i0) (jit_movi_i(JIT_TMP, (int)i0), _STRI(r0, JIT_TMP, 0)) +#endif + +#ifdef USE_THUMB_CODE +#define jit_stxr_i(r0, r1, r2) ((((r0)|(r1)|(r2)) < 8) ? T1_STR(r2, r1, r0) : T2_STR(r2, r1, r0)) +#else +#define jit_stxr_i(r0, r1, r2) _STR(r2, r1, r0) +#endif + +#ifdef USE_THUMB_CODE +#define jit_stxi_i(r0, r1, i0) \ +{ \ + if ((r0|r1) < 8 && i0 >= 0 && !(i0 & 3) && (i0 >> 2) < 0x20) \ + T1_STRI(r1, r0, i0 >> 2); \ + else if (r0 == _R13 && r1 < 8 && \ + i0 >= 0 && !(i0 & 3) && (i0 >> 2) <= 255) \ + T1_STRISP(r1, i0 >> 2); \ + else if (i0 >= 0 && i0 <= 255) \ + T2_STRI(r1, r0, i0); \ + else if (i0 < 0 && i0 >= -255) \ + T2_STRIN(r1, r0, -i0); \ + else if (i0 >= 0 && i0 <= 4095) \ + T2_STRWI(r1, r0, i0); \ + else { \ + jit_movi_i(JIT_TMP, (int)i0); \ + if ((r0|r1|JIT_TMP) < 8) \ + T1_STR(r1, r0, JIT_TMP); \ + else \ + T2_STR(r1, r0, JIT_TMP); \ + } \ +} +#else +#define jit_stxi_i(r0, r1, i0) \ +{ \ + if (i0 >= 0 && i0 <= 4095) \ + _STRI(r1, r0, i0); \ + else if (i0 < 0 && i0 >= -4095) \ + _STRIN(r1, r0, -i0); \ + else { \ + jit_movi_i(JIT_TMP, i0); \ + _STR(r1, r0, JIT_TMP); \ + } \ +} +#endif #if __BYTE_ORDER == __LITTLE_ENDIAN /* inline glibc htons (without register clobber) */ -#define jit_ntoh_us(r0, r1) arm_ntoh_us(_jit, r0, r1) -__jit_inline void -arm_ntoh_us(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_REV16(r0, r1); - else - T2_REV16(r0, r1); - } - else { - if (jit_armv6_p()) - _REV16(r0, r1); - else { - _LSLI(JIT_TMP, r1, 24); - _LSRI(r0, r1, 8); - _ORR_SI(r0, r0, JIT_TMP, ARM_LSR, 16); - } - } -} - -/* inline glibc htonl (without register clobber) */ -#define jit_ntoh_ui(r0, r1) arm_ntoh_ui(_jit, r0, r1) -__jit_inline void -arm_ntoh_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_REV(r0, r1); - else - T2_REV(r0, r1); - } - else { - if (jit_armv6_p()) - _REV(r0, r1); - else { - _EOR_SI(JIT_TMP, r1, r1, ARM_ROR, 16); - _LSRI(JIT_TMP, JIT_TMP, 8); - _BICI(JIT_TMP, JIT_TMP, encode_arm_immediate(0xff00)); - _EOR_SI(r0, JIT_TMP, r1, ARM_ROR, 8); - } - } +#ifdef USE_THUMB_CODE +#define jit_ntoh_us(r0, r1) \ + ((r0|r1) < 8) ? T1_REV16(r0, r1) : T2_REV16(r0, r1) +#else +#define jit_ntoh_us(r0, r1) \ +{ \ + if (jit_armv6_p()) \ + _REV16(r0, r1); \ + else { \ + _LSLI(JIT_TMP, r1, 24); \ + _LSRI(r0, r1, 8); \ + _ORR_SI(r0, r0, JIT_TMP, ARM_LSR, 16); \ + } \ } #endif -#define jit_extr_c_i(r0, r1) arm_extr_c_i(_jit, r0, r1) -__jit_inline void -arm_extr_c_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_SXTB(r0, r1); - else - T2_SXTB(r0, r1); - } - else { - if (jit_armv6_p()) - _SXTB(r0, r1); - else { - _LSLI(r0, r1, 24); - _ASRI(r0, r0, 24); - } - } +/* inline glibc htonl (without register clobber) */ +#ifdef USE_THUMB_CODE +#define jit_ntoh_ui(r0, r1) \ + ((r0|r1) < 8) ? T1_REV(r0, r1) : T2_REV(r0, r1) +#else +#define jit_ntoh_ui(r0, r1) \ +{ \ + if (jit_armv6_p()) \ + _REV(r0, r1); \ + else { \ + _EOR_SI(JIT_TMP, r1, r1, ARM_ROR, 16); \ + _LSRI(JIT_TMP, JIT_TMP, 8); \ + _BICI(JIT_TMP, JIT_TMP, encode_arm_immediate(0xff00)); \ + _EOR_SI(r0, JIT_TMP, r1, ARM_ROR, 8); \ + } \ } +#endif +#endif -#define jit_extr_c_ui(r0, r1) arm_extr_c_ui(_jit, r0, r1) -__jit_inline void -arm_extr_c_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_UXTB(r0, r1); - else - T2_UXTB(r0, r1); - } - else { - if (jit_armv6_p()) - _UXTB(r0, r1); - else - _ANDI(r0, r1, 0xff); - } +#ifdef USE_THUMB_CODE +#define jit_extr_c_i(r0, r1) \ + ((r0|r1) < 8) ? T1_SXTB(r0, r1) : T2_SXTB(r0, r1) +#else +#define jit_extr_c_i(r0, r1) \ +{ \ + if (jit_armv6_p()) \ + _SXTB(r0, r1); \ + else { \ + _LSLI(r0, r1, 24); \ + _ASRI(r0, r0, 24); \ + } \ } +#endif -#define jit_extr_s_i(r0, r1) arm_extr_s_i(_jit, r0, r1) -__jit_inline void -arm_extr_s_i(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_SXTH(r0, r1); - else - T2_SXTH(r0, r1); - } - else { - if (jit_armv6_p()) - _SXTH(r0, r1); - else { - _LSLI(r0, r1, 16); - _ASRI(r0, r0, 16); - } - } -} +#ifdef USE_THUMB_CODE +#define jit_extr_c_ui(r0, r1) \ + ((r0|r1) < 8) ? T1_UXTB(r0, r1) : T2_UXTB(r0, r1) +#else +#define jit_extr_c_ui(r0, r1) \ + jit_armv6_p() ? _UXTB(r0, r1) : _ANDI(r0, r1, 0xff) +#endif -#define jit_extr_s_ui(r0, r1) arm_extr_s_ui(_jit, r0, r1) -__jit_inline void -arm_extr_s_ui(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1) -{ - if (jit_thumb_p()) { - if ((r0|r1) < 8) - T1_UXTH(r0, r1); - else - T2_UXTH(r0, r1); - } - else { - if (jit_armv6_p()) - _UXTH(r0, r1); - else { - /* _ANDI(r0, r1, 0xffff) needs more instructions */ - _LSLI(r0, r1, 16); - _LSRI(r0, r0, 16); - } - } -} +#ifdef USE_THUMB_CODE +#define jit_extr_s_i(r0, r1) \ + ((r0|r1) < 8) ? T1_SXTH(r0, r1) : T2_SXTH(r0, r1) +#else +#define jit_extr_s_i(r0, r1) \ + (jit_armv6_p()) ? _SXTH(r0, r1) : (_LSLI(r0, r1, 16), _ASRI(r0, r0, 16)) +#endif -#define jit_allocai(i0) arm_allocai(_jit, i0) -__jit_inline int -arm_allocai(jit_state_t _jit, int i0) -{ - assert(i0 >= 0); - _jitl.alloca_offset += i0; - jit_patch_movi(_jitl.stack, (void *) - ((_jitl.alloca_offset + _jitl.stack_length + 7) & -8)); - return (-_jitl.alloca_offset); -} +#ifdef USE_THUMB_CODE +#define jit_extr_s_ui(r0, r1) \ + ((r0|r1) < 8) ? T1_UXTH(r0, r1) : T2_UXTH(r0, r1) +#else +#define jit_extr_s_ui(r0, r1) \ + /* _ANDI(r0, r1, 0xffff) needs more instructions */ \ + (jit_armv6_p()) ? _UXTH(r0, r1) : (_LSLI(r0, r1, 16), _LSRI(r0, r0, 16)) +#endif -#define jit_prolog(n) arm_prolog(_jit, n) -__jit_inline void -arm_prolog(jit_state_t _jit, int i0) -{ - if (jit_thumb_p()) { +#define jit_allocai(i0) \ + (assert((i0) >= 0), \ + _jitl.alloca_offset += i0, \ + jit_patch_movi(_jitl.stack, (void *) \ + ((_jitl.alloca_offset + _jitl.stack_length + 7) & -8)), \ + (-_jitl.alloca_offset)) + +#ifdef USE_THUMB_CODE +#define jit_prolog(n) \ +{ \ /* switch to thumb mode (better approach would be to * or 1 address being called, but no clear distinction * of what is a pointer to a jit function, or if patching - * a pointer to a jit function) */ - _ADDI(_R12, _R15, 1); - _BX(_R12); - if (!_jitl.after_prolog) { - _jitl.after_prolog = 1; - _jitl.thumb = _jit->x.pc; - } - if (jit_hardfp_p()) { - T2_PUSH((1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|(1<<_R8)|(1<<_R9)| - /* previous fp and return address */ - (1<x.pc; - - if (jit_swf_p()) - /* 6 soft double precision float registers */ - _jitl.alloca_offset = 48; - else - _jitl.alloca_offset = 0; - - jit_movi_p(JIT_TMP, (void *)_jitl.alloca_offset); - jit_subr_i(JIT_SP, JIT_SP, JIT_TMP); - _jitl.stack_length = _jitl.stack_offset = 0; + * a pointer to a jit function) */ \ + _ADDI(_R12, _R15, 1); \ + _BX(_R12); \ + if (!_jitl.after_prolog) { \ + _jitl.after_prolog = 1; \ + _jitl.thumb_pc = _jit.x.pc; \ + } \ + if (jit_hardfp_p()) { \ + T2_PUSH((1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|(1<<_R8)|(1<<_R9)| \ + /* previous fp and return address */ \ + (1<x.pc; - jit_movi_p(JIT_TMP, i0); - if (jit_thumb_p()) - T1_BLX(JIT_TMP); - else - _BLX(JIT_TMP); - return (l); -} - -#define jit_prepare_i(i0) arm_prepare_i(_jit, i0) -__jit_inline void -arm_prepare_i(jit_state_t _jit, int i0) -{ - assert(i0 >= 0 && !_jitl.stack_offset && !_jitl.nextarg_put); - _jitl.stack_offset = i0 << 2; -} - -#define jit_arg_c() arm_arg_i(_jit) -#define jit_arg_uc() arm_arg_i(_jit) -#define jit_arg_s() arm_arg_i(_jit) -#define jit_arg_us() arm_arg_i(_jit) -#define jit_arg_i() arm_arg_i(_jit) -#define jit_arg_ui() arm_arg_i(_jit) -#define jit_arg_l() arm_arg_i(_jit) -#define jit_arg_ul() arm_arg_i(_jit) -#define jit_arg_p() arm_arg_i(_jit) -__jit_inline int -arm_arg_i(jit_state_t _jit) -{ - int ofs = _jitl.nextarg_get++; - if (ofs > 3) { - ofs = _jitl.framesize; - _jitl.framesize += sizeof(int); - } - return (ofs); -} - -#define jit_getarg_c(r0, i0) arm_getarg_c(_jit, r0, i0) -__jit_inline void -arm_getarg_c(jit_state_t _jit, jit_gpr_t r0, int i0) -{ - if (i0 < 4) - i0 <<= 2; -#if __BYTE_ORDER == __BIG_ENDIAN - i0 += sizeof(int) - sizeof(char); #endif - jit_ldxi_c(r0, JIT_FP, i0); -} -#define jit_getarg_uc(r0, i0) arm_getarg_uc(_jit, r0, i0) -__jit_inline void -arm_getarg_uc(jit_state_t _jit, jit_gpr_t r0, int i0) -{ - if (i0 < 4) - i0 <<= 2; -#if __BYTE_ORDER == __BIG_ENDIAN - i0 += sizeof(int) - sizeof(char); +#ifdef USE_THUMB_CODE +#define jit_callr(r0) T1_BLX(r0) +#else +#define jit_callr(r0) _BLX(r0) #endif - jit_ldxi_uc(r0, JIT_FP, i0); -} -#define jit_getarg_s(r0, i0) arm_getarg_s(_jit, r0, i0) -__jit_inline void -arm_getarg_s(jit_state_t _jit, jit_gpr_t r0, int i0) -{ - if (i0 < 4) - i0 <<= 2; -#if __BYTE_ORDER == __BIG_ENDIAN - i0 += sizeof(int) - sizeof(short); +#ifdef USE_THUMB_CODE +#define jit_calli(i0) \ + (_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \ + T1_BLX(JIT_TMP), \ + _jitl.thumb_tmp) +#else +#define jit_calli(i0) \ + (_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \ + _BLX(JIT_TMP), \ + _jitl.thumb_tmp) #endif - jit_ldxi_s(r0, JIT_FP, i0); -} -#define jit_getarg_us(r0, i0) arm_getarg_us(_jit, r0, i0) -__jit_inline void -arm_getarg_us(jit_state_t _jit, jit_gpr_t r0, int i0) -{ - if (i0 < 4) - i0 <<= 2; -#if __BYTE_ORDER == __BIG_ENDIAN - i0 += sizeof(int) - sizeof(short); -#endif - jit_ldxi_us(r0, JIT_FP, i0); -} +#define jit_prepare_i(i0) \ + (assert((i0) >= 0 && !_jitl.stack_offset && !_jitl.nextarg_put), \ + _jitl.stack_offset = i0 << 2) + +#define jit_arg_c() jit_arg_p() +#define jit_arg_uc() jit_arg_p() +#define jit_arg_s() jit_arg_p() +#define jit_arg_us() jit_arg_p() +#define jit_arg_i() jit_arg_p() +#define jit_arg_ui() jit_arg_p() +#define jit_arg_l() jit_arg_p() +#define jit_arg_ul() jit_arg_p() +#define jit_arg_p() \ + ((_jitl.nextarg_get > 2) ? \ + ((_jitl.framesize += sizeof(int)) - sizeof(int)) : \ + (_jitl.nextarg_get++)) + +#define jit_getarg_c(r0, i0) \ + jit_ldxi_c(r0, JIT_FP, (((i0) < 4) ? (i0) << 2 : (i0)) + ((__BYTE_ORDER == __BIG_ENDIAN) ? (sizeof(int) - sizeof(char)) : 0)) + +#define jit_getarg_uc(r0, i0) \ + jit_ldxi_uc(r0, JIT_FP, (((i0) < 4) ? (i0) << 2 : (i0)) + ((__BYTE_ORDER == __BIG_ENDIAN) ? (sizeof(int) - sizeof(char)) : 0)) + +#define jit_getarg_s(r0, i0) \ + jit_ldxi_s(r0, JIT_FP, (((i0) < 4) ? (i0) << 2 : (i0)) + ((__BYTE_ORDER == __BIG_ENDIAN) ? (sizeof(int) - sizeof(short)) : 0)) + +#define jit_getarg_us(r0, i0) \ + jit_ldxi_us(r0, JIT_FP, (((i0) < 4) ? (i0) << 2 : (i0)) + ((__BYTE_ORDER == __BIG_ENDIAN) ? (sizeof(int) - sizeof(short)) : 0)) #define jit_getarg_i(r0, i0) arm_getarg_i(_jit, r0, i0) #define jit_getarg_ui(r0, i0) arm_getarg_i(_jit, r0, i0) #define jit_getarg_l(r0, i0) arm_getarg_i(_jit, r0, i0) #define jit_getarg_ul(r0, i0) arm_getarg_i(_jit, r0, i0) -#define jit_getarg_p(r0, i0) arm_getarg_i(_jit, r0, i0) -__jit_inline void -arm_getarg_i(jit_state_t _jit, jit_gpr_t r0, int i0) -{ - /* arguments are saved in prolog */ - if (i0 < 4) - i0 <<= 2; - jit_ldxi_i(r0, JIT_FP, i0); +#define jit_getarg_p(r0, i0) \ + jit_ldxi_i(r0, JIT_FP, (((i0) < 4) ? (i0) << 2 : (i0))); /* arguments are saved in prolog */ + +#ifdef USE_THUMB_CODE +#define jit_pusharg_i(r0) \ +{ \ + int ofs = _jitl.nextarg_put++; \ + assert(ofs < 256); \ + _jitl.stack_offset -= sizeof(int); \ + _jitl.arguments[ofs] = (int *)_jit.x.pc; \ + _jitl.types[ofs >> 5] &= ~(1 << (ofs & 31)); \ + /* force 32 bit instruction due to possibly needing to trasform it */ \ + T2_STRWI(r0, JIT_SP, 0); \ } - -#define jit_pusharg_i(r0) arm_pusharg_i(_jit, r0) -__jit_inline void -arm_pusharg_i(jit_state_t _jit, jit_gpr_t r0) -{ - int ofs = _jitl.nextarg_put++; - assert(ofs < 256); - _jitl.stack_offset -= sizeof(int); - _jitl.arguments[ofs] = (int *)_jit->x.pc; - _jitl.types[ofs >> 5] &= ~(1 << (ofs & 31)); - /* force 32 bit instruction due to possibly needing to trasform it */ - if (jit_thumb_p()) - T2_STRWI(r0, JIT_SP, 0); - else - _STRI(r0, JIT_SP, 0); -} - -static void -arm_patch_arguments(jit_state_t _jit) -{ - int reg; - int ioff; - int foff; - int size; - int index; - jit_thumb_t thumb; - int offset; - union { - _ui *i; - _us *s; - } u; - - ioff = foff = 0; - for (index = _jitl.nextarg_put - 1, offset = 0; index >= 0; index--) { - if (_jitl.types[index >> 5] & (1 << (index & 31))) - size = sizeof(double); - else - size = sizeof(int); - u.i = _jitl.arguments[index]; - if (jit_thumb_p()) { - code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - switch (thumb.i & 0xfff00f00) { - case ARM_CC_AL|ARM_VSTR|ARM_P: - if (jit_hardfp_p()) { - if (foff < 16) { - reg = (thumb.i >> 12) & 0xf; - thumb.i = (ARM_CC_AL|ARM_VMOV_F | - ((foff >> 1) << 12) | reg); - if (foff & 1) - thumb.i |= ARM_V_D; - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - ++foff; - continue; - } - } - else { - if (ioff < 4) { - thumb.i = ((thumb.i & 0xfff0ff00) | - (JIT_FP << 16) | ioff); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - ++ioff; - continue; - } - } - thumb.i = (thumb.i & 0xffffff00) | (offset >> 2); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - break; - case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P: - if (jit_hardfp_p()) { - if (foff & 1) - ++foff; - if (foff < 16) { - reg = (thumb.i >> 12) & 0xf; - thumb.i = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 | - ((foff >> 1) << 12) | reg); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - foff += 2; - continue; - } - } - else { - if (ioff & 1) - ++ioff; - if (ioff < 4) { - thumb.i = ((thumb.i & 0xfff0ff00) | - (JIT_FP << 16) | ioff); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - ioff += 2; - continue; - } - } - if (offset & 7) - offset += sizeof(int); - thumb.i = (thumb.i & 0xffffff00) | (offset >> 2); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - break; - case THUMB2_STRWI: - thumb_stri: - if (size == 8 && (ioff & 1)) - ++ioff; - if (ioff < 4) { - thumb.i = ((thumb.i & 0xfff0f000) | - (JIT_FP << 16) | (ioff << 2)); - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - ++ioff; - if (size == 8) { - code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); - thumb.i = ((thumb.i & 0xfff0f000) | - (JIT_FP << 16) | (ioff << 2)); - thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); - ++ioff; - } - continue; - } - if (size == 8 && (offset & 7)) - offset += sizeof(int); - thumb.i = (thumb.i & 0xfffff000) | offset; - thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); - if (size == 8) { - code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); - thumb.i = (thumb.i & 0xfffff000) | (offset + 4); - thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); - } - break; - default: - /* offset too large */ - if ((thumb.i & 0xfff00000) == THUMB2_STRWI) - goto thumb_stri; - abort(); - } - } - else { - switch (u.i[0] & 0xfff00f00) { - case ARM_CC_AL|ARM_VSTR|ARM_P: - if (jit_hardfp_p()) { - if (foff < 16) { - reg = (u.i[0] >> 12) & 0xf; - u.i[0] = (ARM_CC_AL|ARM_VMOV_F | - ((foff >> 1) << 12) | reg); - if (foff & 1) - u.i[0] |= ARM_V_D; - ++foff; - continue; - } - } - else { - if (ioff < 4) { - u.i[0] = ((u.i[0] & 0xfff0ff00) | - (JIT_FP << 16) | ioff); - ++ioff; - continue; - } - } - u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2); - break; - case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P: - if (jit_hardfp_p()) { - if (foff & 1) - ++foff; - if (foff < 16) { - reg = (u.i[0] >> 12) & 0xf; - u.i[0] = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 | - ((foff >> 1) << 12) | reg); - foff += 2; - continue; - } - } - else { - if (ioff & 1) - ++ioff; - if (ioff < 4) { - u.i[0] = ((u.i[0] & 0xfff0ff00) | - (JIT_FP << 16) | ioff); - ioff += 2; - continue; - } - } - if (offset & 7) - offset += sizeof(int); - u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2); - break; - case ARM_CC_AL|ARM_STRI|ARM_P: - arm_stri: - if (size == 8 && (ioff & 1)) - ++ioff; - if (ioff < 4) { - u.i[0] = ((u.i[0] & 0xfff0f000) | - (JIT_FP << 16) | (ioff << 2)); - ++ioff; - if (size == 8) { - u.i[1] = ((u.i[1] & 0xfff0f000) | - (JIT_FP << 16) | (ioff << 2)); - ++ioff; - } - continue; - } - if (size == 8 && (offset & 7)) - offset += sizeof(int); - u.i[0] = (u.i[0] & 0xfffff000) | offset; - if (size == 8) - u.i[1] = (u.i[1] & 0xfffff000) | (offset + 4); - break; - default: - /* offset too large */ - if ((u.i[0] & 0xfff00000) == (ARM_CC_AL|ARM_STRI|ARM_P)) - goto arm_stri; - abort(); - } - } - offset += size; - } - _jitl.reglist = ((1 << ioff) - 1) & 0xf; - if (_jitl.stack_length < offset) { - _jitl.stack_length = offset; - jit_patch_movi(_jitl.stack, (void *) - ((_jitl.alloca_offset + - _jitl.stack_length + 7) & -8)); - } -} - -#define jit_finishr(rs) arm_finishr(_jit, rs) -__jit_inline void -arm_finishr(jit_state_t _jit, jit_gpr_t r0) -{ - assert(!_jitl.stack_offset); - if (r0 < 4) { - jit_movr_i(JIT_TMP, r0); - r0 = JIT_TMP; - } - arm_patch_arguments(_jit); - _jitl.nextarg_put = 0; - if (_jitl.reglist) { - if (jit_thumb_p()) - T2_LDMIA(JIT_FP, _jitl.reglist); - else - _LDMIA(JIT_FP, _jitl.reglist); - _jitl.reglist = 0; - } - jit_callr(r0); -} - -#define jit_finish(i0) arm_finishi(_jit, i0) -__jit_inline jit_insn * -arm_finishi(jit_state_t _jit, void *i0) -{ - assert(!_jitl.stack_offset); - arm_patch_arguments(_jit); - _jitl.nextarg_put = 0; - if (_jitl.reglist) { - if (jit_thumb_p()) - T2_LDMIA(JIT_FP, _jitl.reglist); - else - _LDMIA(JIT_FP, _jitl.reglist); - _jitl.reglist = 0; - } - return (jit_calli(i0)); -} - -#define jit_retval_i(r0) jit_movr_i(r0, JIT_RET) -#define jit_ret() arm_ret(_jit) -__jit_inline void -arm_ret(jit_state_t _jit) -{ - /* do not restore arguments */ - jit_addi_i(JIT_SP, JIT_FP, 16); - if (jit_hardfp_p()) - _VPOP_F64(_D8, 8); - if (jit_thumb_p()) - T2_POP(/* callee save */ - (1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|(1<<_R8)|(1<<_R9)| - /* previous fp and return address */ - (1<x.pc & 2)) - T1_NOP(); -} - -/* just to pass make check... */ -#ifdef JIT_NEED_PUSH_POP -# define jit_pushr_i(r0) arm_pushr_i(_jit, r0) -__jit_inline int -arm_pushr_i(jit_state_t _jit, jit_gpr_t r0) -{ - int offset; - assert(_jitl.pop < sizeof(_jitl.push) / sizeof(_jitl.push[0])); - offset = jit_allocai(4); - _jitl.push[_jitl.pop++] = offset; - jit_stxi_i(offset, JIT_FP, r0); -} - -# define jit_popr_i(r0) arm_popr_i(_jit, r0) -__jit_inline int -arm_popr_i(jit_state_t _jit, jit_gpr_t r0) -{ - int offset; - assert(_jitl.pop > 0); - offset = _jitl.push[--_jitl.pop]; - jit_ldxi_i(r0, JIT_FP, offset); +#else +#define jit_pusharg_i(r0) \ +{ \ + int ofs = _jitl.nextarg_put++; \ + assert(ofs < 256); \ + _jitl.stack_offset -= sizeof(int); \ + _jitl.arguments[ofs] = (int *)_jit.x.pc; \ + _jitl.types[ofs >> 5] &= ~(1 << (ofs & 31)); \ + _STRI(r0, JIT_SP, 0); \ } #endif +#ifdef USE_THUMB_CODE +#define jit_finishr(rs) \ +{ \ + assert(!_jitl.stack_offset); \ + if (r0 < 4) { \ + jit_movr_i(JIT_TMP, r0); \ + r0 = JIT_TMP; \ + } \ + arm_patch_arguments(&_jitl); \ + _jitl.nextarg_put = 0; \ + if (_jitl.reglist) { \ + T2_LDMIA(JIT_FP, _jitl.reglist); \ + _jitl.reglist = 0; \ + } \ + jit_callr(r0); \ +} +#else +#define jit_finishr(rs) \ +{ \ + assert(!_jitl.stack_offset); \ + if (r0 < 4) { \ + jit_movr_i(JIT_TMP, r0); \ + r0 = JIT_TMP; \ + } \ + arm_patch_arguments(&_jitl); \ + _jitl.nextarg_put = 0; \ + if (_jitl.reglist) { \ + _LDMIA(JIT_FP, _jitl.reglist); \ + _jitl.reglist = 0; \ + } \ + jit_callr(r0); \ +} +#endif + +#ifdef USE_THUMB_CODE +#define jit_finish(i0) \ + (assert(!_jitl.stack_offset), \ + arm_patch_arguments(&_jitl), \ + _jitl.nextarg_put = 0, \ + (_jitl.reglist) ? \ + (T2_LDMIA(JIT_FP, _jitl.reglist), \ + _jitl.reglist = 0) : 0, \ + jit_calli(i0)) +#else +#define jit_finish(i0) \ + (assert(!_jitl.stack_offset), \ + arm_patch_arguments(&_jitl), \ + _jitl.nextarg_put = 0, \ + (_jitl.reglist) ? \ + (_LDMIA(JIT_FP, _jitl.reglist), \ + _jitl.reglist = 0) : 0, \ + jit_calli(i0)) +#endif + +#define jit_retval_i(r0) jit_movr_i(r0, JIT_RET) + +#ifdef USE_THUMB_CODE +#define jit_ret() \ +{ \ + /* do not restore arguments */ \ + jit_addi_i(JIT_SP, JIT_FP, 16); \ + if (jit_hardfp_p()) \ + _VPOP_F64(_D8, 8); \ + T2_POP(/* callee save */ \ + (1<<_R4)|(1<<_R5)|(1<<_R6)|(1<<_R7)|(1<<_R8)|(1<<_R9)| \ + /* previous fp and return address */ \ + (1< 0), \ + _jitl.pop--, \ + jit_ldxi_i(r0, JIT_FP, _jitl.push[_jitl.pop])) +#endif #endif /* __lightning_core_arm_h */ diff --git a/src/runtime/c/pgf/lightning/arm/fp-swf.h b/src/runtime/c/pgf/lightning/arm/fp-swf.h index 4440482d1..e9ac82148 100644 --- a/src/runtime/c/pgf/lightning/arm/fp-swf.h +++ b/src/runtime/c/pgf/lightning/arm/fp-swf.h @@ -34,6 +34,7 @@ #ifndef __lightning_fp_swf_h #define __lightning_fp_swf_h +#if 0 #include #define swf_off(rn) ((rn) << 2) @@ -1249,5 +1250,5 @@ swf_retval_d(jit_state_t _jit, jit_fpr_t r0) swf_strin(_R1, JIT_FP, swf_off(r0) + 4); } } - +#endif #endif /* __lightning_fp_swf_h */ diff --git a/src/runtime/c/pgf/lightning/arm/fp-vfp.h b/src/runtime/c/pgf/lightning/arm/fp-vfp.h index c903df625..29c63371e 100644 --- a/src/runtime/c/pgf/lightning/arm/fp-vfp.h +++ b/src/runtime/c/pgf/lightning/arm/fp-vfp.h @@ -34,6 +34,8 @@ #ifndef __lightning_fp_vfp_h #define __lightning_fp_vfp_h +#if 0 + __jit_inline void vfp_movr_f(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { @@ -1084,5 +1086,6 @@ vfp_retval_d(jit_state_t _jit, jit_fpr_t r0) #undef vfp_unget_tmp #undef vfp_get_tmp +#endif #endif /* __lightning_fp_vfp_h */ diff --git a/src/runtime/c/pgf/lightning/arm/fp.h b/src/runtime/c/pgf/lightning/arm/fp.h index 58ed13b52..78fa7577e 100644 --- a/src/runtime/c/pgf/lightning/arm/fp.h +++ b/src/runtime/c/pgf/lightning/arm/fp.h @@ -45,9 +45,10 @@ jit_hard_order[6] = { #define JIT_FPR(n) \ (jit_hardfp_p() ? jit_hard_order[n] : jit_soft_order[n]) -#include "fp-swf.h" -#include "fp-vfp.h" +#include "arm/fp-swf.h" +#include "arm/fp-vfp.h" +#if 0 #define jit_movr_f(r0, r1) arm_movr_f(_jit, r0, r1) __jit_inline void arm_movr_f(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) @@ -1103,5 +1104,5 @@ arm_retval_d(jit_state_t _jit, jit_fpr_t r0) } /* else assume chaining call to jit_retval_d as done in tests/funcfp.c */ } - +#endif #endif /* __lightning_fp_arm_h */ diff --git a/src/runtime/c/pgf/lightning/arm/funcs.h b/src/runtime/c/pgf/lightning/arm/funcs.h index ec19e52a3..79d63df40 100644 --- a/src/runtime/c/pgf/lightning/arm/funcs.h +++ b/src/runtime/c/pgf/lightning/arm/funcs.h @@ -51,8 +51,7 @@ jit_flush_code(void *start, void *end) __clear_cache(start, end); } -#define jit_get_cpu jit_get_cpu -__jit_constructor static void +__attribute__((constructor)) static void jit_get_cpu(void) { #if defined(__linux__) @@ -106,4 +105,279 @@ jit_get_cpu(void) jit_cpu.thumb = 0; } +static void +arm_patch_arguments(struct jit_local_state* jitl) +{ + int reg; + int ioff; + int foff; + int size; + int index; + jit_thumb_t thumb; + int offset; + union { + _ui *i; + _us *s; + } u; + + ioff = foff = 0; + for (index = jitl->nextarg_put - 1, offset = 0; index >= 0; index--) { + if (jitl->types[index >> 5] & (1 << (index & 31))) + size = sizeof(double); + else + size = sizeof(int); + u.i = jitl->arguments[index]; + if (jit_thumb_p()) { + code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + switch (thumb.i & 0xfff00f00) { + case ARM_CC_AL|ARM_VSTR|ARM_P: + if (jit_hardfp_p()) { + if (foff < 16) { + reg = (thumb.i >> 12) & 0xf; + thumb.i = (ARM_CC_AL|ARM_VMOV_F | + ((foff >> 1) << 12) | reg); + if (foff & 1) + thumb.i |= ARM_V_D; + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + ++foff; + continue; + } + } + else { + if (ioff < 4) { + thumb.i = ((thumb.i & 0xfff0ff00) | + (JIT_FP << 16) | ioff); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + ++ioff; + continue; + } + } + thumb.i = (thumb.i & 0xffffff00) | (offset >> 2); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + break; + case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P: + if (jit_hardfp_p()) { + if (foff & 1) + ++foff; + if (foff < 16) { + reg = (thumb.i >> 12) & 0xf; + thumb.i = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 | + ((foff >> 1) << 12) | reg); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + foff += 2; + continue; + } + } + else { + if (ioff & 1) + ++ioff; + if (ioff < 4) { + thumb.i = ((thumb.i & 0xfff0ff00) | + (JIT_FP << 16) | ioff); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + ioff += 2; + continue; + } + } + if (offset & 7) + offset += sizeof(int); + thumb.i = (thumb.i & 0xffffff00) | (offset >> 2); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + break; + case THUMB2_STRWI: + thumb_stri: + if (size == 8 && (ioff & 1)) + ++ioff; + if (ioff < 4) { + thumb.i = ((thumb.i & 0xfff0f000) | + (JIT_FP << 16) | (ioff << 2)); + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + ++ioff; + if (size == 8) { + code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); + thumb.i = ((thumb.i & 0xfff0f000) | + (JIT_FP << 16) | (ioff << 2)); + thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); + ++ioff; + } + continue; + } + if (size == 8 && (offset & 7)) + offset += sizeof(int); + thumb.i = (thumb.i & 0xfffff000) | offset; + thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); + if (size == 8) { + code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); + thumb.i = (thumb.i & 0xfffff000) | (offset + 4); + thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); + } + break; + default: + /* offset too large */ + if ((thumb.i & 0xfff00000) == THUMB2_STRWI) + goto thumb_stri; + abort(); + } + } + else { + switch (u.i[0] & 0xfff00f00) { + case ARM_CC_AL|ARM_VSTR|ARM_P: + if (jit_hardfp_p()) { + if (foff < 16) { + reg = (u.i[0] >> 12) & 0xf; + u.i[0] = (ARM_CC_AL|ARM_VMOV_F | + ((foff >> 1) << 12) | reg); + if (foff & 1) + u.i[0] |= ARM_V_D; + ++foff; + continue; + } + } + else { + if (ioff < 4) { + u.i[0] = ((u.i[0] & 0xfff0ff00) | + (JIT_FP << 16) | ioff); + ++ioff; + continue; + } + } + u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2); + break; + case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P: + if (jit_hardfp_p()) { + if (foff & 1) + ++foff; + if (foff < 16) { + reg = (u.i[0] >> 12) & 0xf; + u.i[0] = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 | + ((foff >> 1) << 12) | reg); + foff += 2; + continue; + } + } + else { + if (ioff & 1) + ++ioff; + if (ioff < 4) { + u.i[0] = ((u.i[0] & 0xfff0ff00) | + (JIT_FP << 16) | ioff); + ioff += 2; + continue; + } + } + if (offset & 7) + offset += sizeof(int); + u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2); + break; + case ARM_CC_AL|ARM_STRI|ARM_P: + arm_stri: + if (size == 8 && (ioff & 1)) + ++ioff; + if (ioff < 4) { + u.i[0] = ((u.i[0] & 0xfff0f000) | + (JIT_FP << 16) | (ioff << 2)); + ++ioff; + if (size == 8) { + u.i[1] = ((u.i[1] & 0xfff0f000) | + (JIT_FP << 16) | (ioff << 2)); + ++ioff; + } + continue; + } + if (size == 8 && (offset & 7)) + offset += sizeof(int); + u.i[0] = (u.i[0] & 0xfffff000) | offset; + if (size == 8) + u.i[1] = (u.i[1] & 0xfffff000) | (offset + 4); + break; + default: + /* offset too large */ + if ((u.i[0] & 0xfff00000) == (ARM_CC_AL|ARM_STRI|ARM_P)) + goto arm_stri; + abort(); + } + } + offset += size; + } + jitl->reglist = ((1 << ioff) - 1) & 0xf; + if (jitl->stack_length < offset) { + jitl->stack_length = offset; + jit_patch_movi(jitl->stack, (void *) + ((jitl->alloca_offset + jitl->stack_length + 7) & -8)); + } +} + +extern int __aeabi_idivmod(int, int); +extern unsigned __aeabi_uidivmod(unsigned, unsigned); + +#pragma push_macro("_jit") +#ifdef _jit +#undef _jit +#endif +#define _jit (*jit) +static void +arm_divmod(jit_state* jit, int div, int sign, + jit_gpr_t r0, jit_gpr_t r1, jit_gpr_t r2) +{ + int d; + int l; + void *p; + l = 0xf; + if ((int)r0 < 4) + /* bogus extra push to align at 8 bytes */ + l = (l & ~(1 << r0)) | 0x10; +#ifdef USE_THUMB_CODE + T1_PUSH(l); +#else + _PUSH(l); +#endif + if (r1 == _R1 && r2 == _R0) { + jit_movr_i(JIT_FTMP, _R0); + jit_movr_i(_R0, _R1); + jit_movr_i(_R1, JIT_FTMP); + } else if (r2 == _R0) { + jit_movr_i(_R1, r2); + jit_movr_i(_R0, r1); + } else { + jit_movr_i(_R0, r1); + jit_movr_i(_R1, r2); + } + p = (sign) ? (void*) __aeabi_idivmod : (void*) __aeabi_uidivmod; + if (!jit_exchange_p()) { +#ifdef USE_THUMB_CODE + d = (((int)p - (int)_jit.x.pc) >> 1) - 2; +#else + d = (((int)p - (int)_jit.x.pc) >> 2) - 2; +#endif + if (_s24P(d)) { +#ifdef USE_THUMB_CODE + T2_BLI(encode_thumb_jump(d)); +#else + _BLI(d & 0x00ffffff); +#endif + } + else + goto fallback; + } else { +fallback: + jit_movi_i(JIT_FTMP, (int)p); +#ifdef USE_THUMB_CODE + T1_BLX(JIT_FTMP); +#else + _BLX(JIT_FTMP); +#endif + } + if (div) { + jit_movr_i(r0, _R0); + } else { + jit_movr_i(r0, _R1); + } +#ifdef USE_THUMB_CODE + T1_POP(l); +#else + _POP(l); +#endif +} +#pragma pop_macro("_jit") + #endif /* __lightning_funcs_h */ diff --git a/src/runtime/c/pgf/lightning/asm-common.h b/src/runtime/c/pgf/lightning/asm-common.h index bdaa6c2ea..3cc96649f 100644 --- a/src/runtime/c/pgf/lightning/asm-common.h +++ b/src/runtime/c/pgf/lightning/asm-common.h @@ -131,6 +131,8 @@ typedef unsigned long _ul; #define _s0P(I) ((I)==0) #define _s8P(I) _siP(8,I) #define _s16P(I) _siP(16,I) +#define _s20P(I) _siP(20,I) +#define _s24P(I) _siP(24,I) #define _s32P(I) _siP(32,I) #define _u8P(I) _uiP(8,I) #define _u16P(I) _uiP(16,I) diff --git a/src/runtime/c/pgf/lightning/core-common.h b/src/runtime/c/pgf/lightning/core-common.h index 9e29250e1..b60f0bf31 100644 --- a/src/runtime/c/pgf/lightning/core-common.h +++ b/src/runtime/c/pgf/lightning/core-common.h @@ -198,13 +198,19 @@ typedef union jit_code { #endif /* Common 'shortcut' implementations */ +#ifndef jit_subi_i #define jit_subi_i(d, rs, is) jit_addi_i((d), (rs), -(is)) +#endif #define jit_subi_l(d, rs, is) jit_addi_l((d), (rs), -(is)) +#ifndef jit_subci_i #define jit_subci_i(d, rs, is) jit_addci_i((d), (rs), -(is)) +#endif #define jit_subci_l(d, rs, is) jit_addci_l((d), (rs), -(is)) #define jit_rsbr_f(d, s1, s2) jit_subr_f((d), (s2), (s1)) #define jit_rsbr_d(d, s1, s2) jit_subr_d((d), (s2), (s1)) +#ifndef jit_rsbr_i #define jit_rsbr_i(d, s1, s2) jit_subr_i((d), (s2), (s1)) +#endif #define jit_rsbr_l(d, s1, s2) jit_subr_l((d), (s2), (s1)) #define jit_rsbr_p(d, s1, s2) jit_subr_p((d), (s2), (s1)) @@ -213,7 +219,9 @@ typedef union jit_code { #define jit_notr_uc(d, rs) jit_xori_c((d), (rs), 255) #define jit_notr_s(d, rs) jit_xori_s((d), (rs), 65535) #define jit_notr_us(d, rs) jit_xori_s((d), (rs), 65535) +#ifndef jit_notr_i #define jit_notr_i(d, rs) jit_xori_i((d), (rs), ~0) +#endif #define jit_notr_ui(d, rs) jit_xori_i((d), (rs), ~0) #define jit_notr_l(d, rs) jit_xori_l((d), (rs), ~0L) #define jit_notr_ul(d, rs) jit_xori_l((d), (rs), ~0L)