/******************************** -*- C -*- **************************** * * Support macros for arm software floating-point math * ***********************************************************************/ /*********************************************************************** * * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU lightning. * * GNU lightning is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 3, or (at your option) * any later version. * * GNU lightning is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with GNU lightning; see the file COPYING.LESSER; if not, write to the * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * Authors: * Paulo Cesar Pereira de Andrade ***********************************************************************/ #ifndef __lightning_fp_swf_h #define __lightning_fp_swf_h #include #define swf_off(rn) ((rn) << 2) extern float __addsf3(float, float); extern double __adddf3(double, double); extern float __aeabi_fsub(float, float); extern double __aeabi_dsub(double, double); extern float __aeabi_fmul(float, float); extern double __aeabi_dmul(double, double); extern float __aeabi_fdiv(float, float); extern double __aeabi_ddiv(double, double); extern float __aeabi_i2f(int); extern double __aeabi_i2d(int); extern float __aeabi_d2f(double); extern double __aeabi_f2d(float); extern int __aeabi_f2iz(double); extern int __aeabi_d2iz(float); extern int __aeabi_fcmplt(float, float); extern int __aeabi_dcmplt(double, double); extern int __aeabi_fcmple(float, float); extern int __aeabi_dcmple(double, double); extern int __aeabi_fcmpeq(float, float); extern int __aeabi_dcmpeq(double, double); extern int __aeabi_fcmpge(float, float); extern int __aeabi_dcmpge(double, double); extern int __aeabi_fcmpgt(float, float); extern int __aeabi_dcmpgt(double, double); extern int __aeabi_fcmpun(float, float); extern int __aeabi_dcmpun(double, double); #define swf_call(function, label) \ do { \ int d; \ if (!jit_exchange_p()) { \ if (jit_thumb_p()) \ d = (((int)function - (int)_jit->x.pc) >> 1) - 2; \ else \ d = (((int)function - (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 label; \ } \ else { \ label: \ jit_movi_i(JIT_FTMP, (int)function); \ if (jit_thumb_p()) \ T1_BLX(JIT_FTMP); \ else \ _BLX(JIT_FTMP); \ } \ } while (0) #define swf_ldrin(rt, rn, im) \ do { \ if (jit_thumb_p()) T2_LDRIN(rt, rn, im); \ else _LDRIN(rt, rn, im); \ } while (0) #define swf_strin(rt, rn, im) \ do { \ if (jit_thumb_p()) T2_STRIN(rt, rn, im); \ else _STRIN(rt, rn, im); \ } while (0) #define swf_push(mask) \ do { \ if (jit_thumb_p()) T1_PUSH(mask); \ else _PUSH(mask); \ } while (0) #define swf_pop(mask) \ do { \ if (jit_thumb_p()) T1_POP(mask); \ else _POP(mask); \ } while (0) #define swf_bici(rt, rn, im) \ do { \ if (jit_thumb_p()) \ T2_BICI(rt, rn, encode_thumb_immediate(im)); \ else \ _BICI(rt, rn, encode_arm_immediate(im)); \ } while (0) #if 0 __jit_inline void swf_movr_f(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { if (r0 != r1) { if (r0 == JIT_FPRET) /* jit_ret() must follow! */ swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); else { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } } } __jit_inline void swf_movr_d(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { if (r0 != r1) { if (!jit_thumb_p() && jit_armv5e_p()) { if (r0 == JIT_FPRET) /* jit_ret() must follow! */ _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); else { _LDRDIN(JIT_TMP, JIT_FP, swf_off(r1) + 8); _STRDIN(JIT_TMP, JIT_FP, swf_off(r0) + 8); } } else { if (r0 == JIT_FPRET) { /* jit_ret() must follow! */ swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); } else { swf_ldrin(JIT_TMP, JIT_FP, swf_off(r1) + 8); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 4); swf_strin(JIT_TMP, JIT_FP, swf_off(r0) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } } } } __jit_inline void swf_movi_f(jit_state_t _jit, jit_fpr_t r0, float i0) { union { int i; float f; } u; u.f = i0; if (r0 == JIT_FPRET) /* jit_ret() must follow! */ jit_movi_i(_R0, u.i); else { jit_movi_i(JIT_FTMP, u.i); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } } __jit_inline void swf_movi_d(jit_state_t _jit, jit_fpr_t r0, double i0) { union { int i[2]; double d; } u; u.d = i0; if (r0 == JIT_FPRET) { /* jit_ret() must follow! */ jit_movi_i(_R0, u.i[0]); jit_movi_i(_R1, u.i[1]); } else { jit_movi_i(JIT_FTMP, u.i[0]); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); jit_movi_i(JIT_FTMP, u.i[1]); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } } __jit_inline void swf_extr_i_f(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1) { swf_push(0xf); if (r1 != _R0) jit_movr_i(_R0, r1); swf_call(__aeabi_i2f, i2f); swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_pop(0xf); } __jit_inline void swf_extr_i_d(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1) { swf_push(0xf); if (r1 != _R0) jit_movr_i(_R0, r1); swf_call(__aeabi_i2d, i2d); if (!jit_thumb_p() && jit_armv5e_p()) _STRDIN(_R0, JIT_FP, swf_off(r0) + 8); else { swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_strin(_R1, JIT_FP, swf_off(r0) + 4); } swf_pop(0xf); } static void swf_extr_d_f(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { swf_push(0xf); if (!jit_thumb_p() && jit_armv5e_p()) _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); } swf_call(__aeabi_d2f, d2f); swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_pop(0xf); } static void swf_extr_f_d(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { swf_push(0xf); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_call(__aeabi_f2d, f2d); if (!jit_thumb_p() && jit_armv5e_p()) _STRDIN(_R0, JIT_FP, swf_off(r0) + 8); else { swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_strin(_R1, JIT_FP, swf_off(r0) + 4); } swf_pop(0xf); } static void swf_if(jit_state_t _jit, float (*i0)(float), jit_gpr_t r0, jit_fpr_t r1) { int l; #if !NAN_TO_INT_IS_ZERO jit_insn *is_nan; jit_insn *fast_not_nan; jit_insn *slow_not_nan; #endif l = 0xf; if ((int)r0 < 4) /* bogus extra push to align at 8 bytes */ l = (l & ~(1 << r0)) | 0x10; swf_push(l); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); #if !NAN_TO_INT_IS_ZERO /* >> based on fragment of __aeabi_fcmpun */ jit_lshi_i(JIT_FTMP, _R0, 1); if (jit_thumb_p()) torrrs(THUMB2_MVN|ARM_S, _R0, JIT_TMP, JIT_FTMP, encode_thumb_shift(24, ARM_ASR)); else corrrs(ARM_CC_AL,ARM_MVN|ARM_S|ARM_ASR, _R0, JIT_TMP, JIT_FTMP, 24); fast_not_nan = _jit->x.pc; if (jit_thumb_p()) { T2_CC_B(ARM_CC_NE, 0); tshift(THUMB2_LSLI|ARM_S, _R0, JIT_TMP, 9); } else { _CC_B(ARM_CC_NE, 0); cshift(ARM_CC_AL, ARM_S|ARM_LSL, _R0, JIT_TMP, _R0, 9); } slow_not_nan = _jit->x.pc; if (jit_thumb_p()) T2_CC_B(ARM_CC_EQ, 0); else _CC_B(ARM_CC_EQ, 0); jit_movi_i(r0, 0x80000000); is_nan = _jit->x.pc; if (jit_thumb_p()) T2_B(0); else _B(ARM_CC_AL, 0); jit_patch(fast_not_nan); jit_patch(slow_not_nan); /* << based on fragment of __aeabi_fcmpun */ #endif if (i0) swf_call(i0, fallback); swf_call(__aeabi_f2iz, f2iz); jit_movr_i(r0, _R0); #if !NAN_TO_INT_IS_ZERO jit_patch(is_nan); #endif swf_pop(l); } static void swf_id(jit_state_t _jit, double (*i0)(double), jit_gpr_t r0, jit_fpr_t r1) { int l; #if !NAN_TO_INT_IS_ZERO jit_insn *is_nan; jit_insn *fast_not_nan; jit_insn *slow_not_nan; #endif l = 0xf; if ((int)r0 < 4) /* bogus extra push to align at 8 bytes */ l = (l & ~(1 << r0)) | 0x10; swf_push(l); if (!jit_thumb_p() && jit_armv5e_p()) _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); } #if !NAN_TO_INT_IS_ZERO /* >> based on fragment of __aeabi_dcmpun */ jit_lshi_i(JIT_TMP, _R1, 1); if (jit_thumb_p()) torrrs(THUMB2_MVN|ARM_S, _R0, JIT_TMP, JIT_TMP, encode_thumb_shift(21, ARM_ASR)); else corrrs(ARM_CC_AL,ARM_MVN|ARM_S|ARM_ASR, _R0, JIT_TMP, JIT_TMP, 21); fast_not_nan = _jit->x.pc; if (jit_thumb_p()) { T2_CC_B(ARM_CC_NE, 0); torrrs(THUMB2_ORR|ARM_S, _R0, JIT_TMP, _R1, encode_thumb_shift(12, ARM_LSL)); } else { _CC_B(ARM_CC_NE, 0); corrrs(ARM_CC_AL,ARM_ORR|ARM_S|ARM_LSL, _R0, JIT_TMP, _R1, 12); } slow_not_nan = _jit->x.pc; if (jit_thumb_p()) T2_CC_B(ARM_CC_EQ, 0); else _CC_B(ARM_CC_EQ, 0); jit_movi_i(r0, 0x80000000); is_nan = _jit->x.pc; if (jit_thumb_p()) T2_B(0); else _B(0); jit_patch(fast_not_nan); jit_patch(slow_not_nan); /* << based on fragment of __aeabi_dcmpun */ #endif if (i0) swf_call(i0, fallback); swf_call(__aeabi_d2iz, d2iz); jit_movr_i(r0, _R0); #if !NAN_TO_INT_IS_ZERO jit_patch(is_nan); #endif swf_pop(l); } #define swf_rintr_f_i(_jit, r0, r1) swf_if(_jit, rintf, r0, r1) #define swf_rintr_d_i(_jit, r0, r1) swf_id(_jit, rint, r0, r1) #define swf_roundr_f_i(_jit, r0, r1) swf_if(_jit, roundf, r0, r1) #define swf_roundr_d_i(_jit, r0, r1) swf_id(_jit, round, r0, r1) #define swf_truncr_f_i(_jit, r0, r1) swf_if(_jit, (void *)0, r0, r1) #define swf_truncr_d_i(_jit, r0, r1) swf_id(_jit, (void *)0, r0, r1) #define swf_ceilr_f_i(_jit, r0, r1) swf_if(_jit, ceilf, r0, r1) #define swf_ceilr_d_i(_jit, r0, r1) swf_id(_jit, ceil, r0, r1) #define swf_floorr_f_i(_jit, r0, r1) swf_if(_jit, floorf, r0, r1) #define swf_floorr_d_i(_jit, r0, r1) swf_id(_jit, floor, r0, r1) __jit_inline void swf_absr_f(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 8); swf_bici(JIT_FTMP, JIT_FTMP, 0x80000000); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } __jit_inline void swf_absr_d(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 4); swf_bici(JIT_FTMP, JIT_FTMP, 0x80000000); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); if (r0 != r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } } __jit_inline void swf_negr_f(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 8); jit_xori_i(JIT_FTMP, JIT_FTMP, 0x80000000); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } __jit_inline void swf_negr_d(jit_state_t _jit, jit_fpr_t r0, jit_fpr_t r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 4); jit_xori_i(JIT_FTMP, JIT_FTMP, 0x80000000); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); if (r0 != r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } } static void swf_ff(jit_state_t _jit, float (*i0)(float), jit_fpr_t r0, jit_fpr_t r1) { swf_push(0xf); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_call(i0, fallback); swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_pop(0xf); } static void swf_dd(jit_state_t _jit, double (*i0)(double), jit_fpr_t r0, jit_fpr_t r1) { swf_push(0xf); if (!jit_thumb_p() && jit_armv5e_p()) _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); } swf_call(i0, fallback); if (!jit_thumb_p() && jit_armv5e_p()) _STRDIN(_R0, JIT_FP, swf_off(r0) + 8); else { swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_strin(_R1, JIT_FP, swf_off(r0) + 4); } swf_pop(0xf); } #define swf_sqrtr_f(_jit, r0, r1) swf_ff(_jit, sqrtf, r0, r1) #define swf_sqrtr_d(_jit, r0, r1) swf_dd(_jit, sqrt, r0, r1) static void swf_fff(jit_state_t _jit, float (*i0)(float, float), jit_fpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_push(0xf); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r2) + 8); swf_call(i0, fallback); swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_pop(0xf); } static void swf_ddd(jit_state_t _jit, double (*i0)(double, double), jit_fpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_push(0xf); if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); _LDRDIN(_R2, JIT_FP, swf_off(r2) + 8); } else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); swf_ldrin(_R2, JIT_FP, swf_off(r2) + 8); swf_ldrin(_R3, JIT_FP, swf_off(r2) + 4); } swf_call(i0, fallback); if (!jit_thumb_p() && jit_armv5e_p()) _STRDIN(_R0, JIT_FP, swf_off(r0) + 8); else { swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_strin(_R1, JIT_FP, swf_off(r0) + 4); } swf_pop(0xf); } #define swf_addr_f(_jit, r0, r1, r2) swf_fff(_jit, __addsf3, r0, r1, r2) #define swf_addr_d(_jit, r0, r1, r2) swf_ddd(_jit, __adddf3, r0, r1, r2) #define swf_subr_f(_jit, r0, r1, r2) swf_fff(_jit, __aeabi_fsub, r0, r1, r2) #define swf_subr_d(_jit, r0, r1, r2) swf_ddd(_jit, __aeabi_dsub, r0, r1, r2) #define swf_mulr_f(_jit, r0, r1, r2) swf_fff(_jit, __aeabi_fmul, r0, r1, r2) #define swf_mulr_d(_jit, r0, r1, r2) swf_ddd(_jit, __aeabi_dmul, r0, r1, r2) #define swf_divr_f(_jit, r0, r1, r2) swf_fff(_jit, __aeabi_fdiv, r0, r1, r2) #define swf_divr_d(_jit, r0, r1, r2) swf_ddd(_jit, __aeabi_ddiv, r0, r1, r2) static void swf_iff(jit_state_t _jit, int (*i0)(float, float), jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { int l; l = 0xf; if ((int)r0 < 4) /* bogus extra push to align at 8 bytes */ l = (l & ~(1 << r0)) | 0x10; swf_push(l); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r2) + 8); swf_call(i0, fallback); jit_movr_i(r0, _R0); swf_pop(l); } static void swf_idd(jit_state_t _jit, int (*i0)(double, double), jit_fpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { int l; l = 0xf; if ((int)r0 < 4) /* bogus extra push to align at 8 bytes */ l = (l & ~(1 << r0)) | 0x10; swf_push(l); if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); _LDRDIN(_R2, JIT_FP, swf_off(r2) + 8); } else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); swf_ldrin(_R2, JIT_FP, swf_off(r2) + 8); swf_ldrin(_R3, JIT_FP, swf_off(r2) + 4); } swf_call(i0, fallback); jit_movr_i(r0, _R0); swf_pop(l); } #define swf_ltr_f(_jit, r0, r1, r2) swf_iff(_jit, __aeabi_fcmplt,r0,r1,r2) #define swf_ltr_d(_jit, r0, r1, r2) swf_idd(_jit, __aeabi_dcmplt,r0,r1,r2) #define swf_ler_f(_jit, r0, r1, r2) swf_iff(_jit, __aeabi_fcmple,r0,r1,r2) #define swf_ler_d(_jit, r0, r1, r2) swf_idd(_jit, __aeabi_dcmple,r0,r1,r2) #define swf_eqr_f(_jit, r0, r1, r2) swf_iff(_jit, __aeabi_fcmpeq,r0,r1,r2) #define swf_eqr_d(_jit, r0, r1, r2) swf_idd(_jit, __aeabi_dcmpeq,r0,r1,r2) #define swf_ger_f(_jit, r0, r1, r2) swf_iff(_jit, __aeabi_fcmpge,r0,r1,r2) #define swf_ger_d(_jit, r0, r1, r2) swf_idd(_jit, __aeabi_dcmpge,r0,r1,r2) #define swf_gtr_f(_jit, r0, r1, r2) swf_iff(_jit, __aeabi_fcmpgt,r0,r1,r2) #define swf_gtr_d(_jit, r0, r1, r2) swf_idd(_jit, __aeabi_dcmpgt,r0,r1,r2) __jit_inline void swf_ner_f(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_iff(_jit, __aeabi_fcmpeq, r0, r1, r2); jit_xori_i(r0, r0, 1); } __jit_inline void swf_ner_d(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_idd(_jit, __aeabi_dcmpeq, r0, r1, r2); jit_xori_i(r0, r0, 1); } static void swf_iunff(jit_state_t _jit, int (*i0)(float, float), jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { int l; jit_insn *i; l = 0xf; if ((int)r0 < 4) /* bogus extra push to align at 8 bytes */ l = (l & ~(1 << r0)) | 0x10; swf_push(l); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r2) + 8); swf_call(__aeabi_fcmpun, fcmpun); if (jit_thumb_p()) { T1_CMPI(_R0, 0); _IT(ARM_CC_NE); if (r0 < 8) T1_MOVI(r0, 1); else T2_MOVI(r0, 1); i = _jit->x.pc; T2_CC_B(ARM_CC_NE, 0); } else { _CMPI(_R0, 0); _CC_MOVI(ARM_CC_NE, r0, 1); i = _jit->x.pc; _CC_B(ARM_CC_NE, 0); } swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r2) + 8); swf_call(i0, fallback); jit_movr_i(r0, _R0); jit_patch(i); swf_pop(l); } static void swf_iundd(jit_state_t _jit, int (*i0)(double, double), jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { int l; jit_insn *i; l = 0xf; if ((int)r0 < 4) /* bogus extra push to align at 8 bytes */ l = (l & ~(1 << r0)) | 0x10; swf_push(l); if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); _LDRDIN(_R2, JIT_FP, swf_off(r2) + 8); } else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); swf_ldrin(_R2, JIT_FP, swf_off(r2) + 8); swf_ldrin(_R3, JIT_FP, swf_off(r2) + 4); } swf_call(__aeabi_dcmpun, dcmpun); if (jit_thumb_p()) { T1_CMPI(_R0, 0); _IT(ARM_CC_NE); if (r0 < 8) T1_MOVI(r0, 1); else T2_MOVI(r0, 1); i = _jit->x.pc; T2_CC_B(ARM_CC_NE, 0); } else { _CMPI(_R0, 0); _CC_MOVI(ARM_CC_NE, r0, 1); i = _jit->x.pc; _CC_B(ARM_CC_NE, 0); } if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); _LDRDIN(_R2, JIT_FP, swf_off(r2) + 8); } else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); swf_ldrin(_R2, JIT_FP, swf_off(r2) + 8); swf_ldrin(_R3, JIT_FP, swf_off(r2) + 4); } swf_call(i0, fallback); jit_movr_i(r0, _R0); jit_patch(i); swf_pop(l); } #define swf_unltr_f(_jit, r0, r1, r2) swf_iunff(_jit,__aeabi_fcmplt,r0,r1,r2) #define swf_unltr_d(_jit, r0, r1, r2) swf_iundd(_jit,__aeabi_dcmplt,r0,r1,r2) #define swf_unler_f(_jit, r0, r1, r2) swf_iunff(_jit,__aeabi_fcmple,r0,r1,r2) #define swf_unler_d(_jit, r0, r1, r2) swf_iundd(_jit,__aeabi_dcmple,r0,r1,r2) #define swf_uneqr_f(_jit, r0, r1, r2) swf_iunff(_jit,__aeabi_fcmpeq,r0,r1,r2) #define swf_uneqr_d(_jit, r0, r1, r2) swf_iundd(_jit,__aeabi_dcmpeq,r0,r1,r2) #define swf_unger_f(_jit, r0, r1, r2) swf_iunff(_jit,__aeabi_fcmpge,r0,r1,r2) #define swf_unger_d(_jit, r0, r1, r2) swf_iundd(_jit,__aeabi_dcmpge,r0,r1,r2) #define swf_ungtr_f(_jit, r0, r1, r2) swf_iunff(_jit,__aeabi_fcmpgt,r0,r1,r2) #define swf_ungtr_d(_jit, r0, r1, r2) swf_iundd(_jit,__aeabi_dcmpgt,r0,r1,r2) __jit_inline void swf_ltgtr_f(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_iunff(_jit, __aeabi_fcmpeq, r0, r1, r2); jit_xori_i(r0, r0, 1); } __jit_inline void swf_ltgtr_d(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_iundd(_jit, __aeabi_dcmpeq, r0, r1, r2); jit_xori_i(r0, r0, 1); } __jit_inline void swf_ordr_f(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_iff(_jit, __aeabi_fcmpun, r0, r1, r2); jit_xori_i(r0, r0, 1); } __jit_inline void swf_ordr_d(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1, jit_fpr_t r2) { swf_idd(_jit, __aeabi_dcmpun, r0, r1, r2); jit_xori_i(r0, r0, 1); } #define swf_unordr_f(_jit, r0, r1, r2) swf_iunff(_jit,__aeabi_fcmpun,r0,r1,r2) #define swf_unordr_d(_jit, r0, r1, r2) swf_iundd(_jit,__aeabi_dcmpun,r0,r1,r2) static jit_insn * swf_bff(jit_state_t _jit, int (*i0)(float, float), int cc, void *i1, jit_fpr_t r1, jit_fpr_t r2) { jit_insn *l; int d; assert(r1 != JIT_FPRET && r2 != JIT_FPRET); swf_push(0xf); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r2) + 8); swf_call(i0, fallback); if (jit_thumb_p()) { T1_CMPI(_R0, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 1) - 2; assert(_s20P(d)); T2_CC_B(cc, encode_thumb_cc_jump(d)); } else { _CMPI(_R0, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 2) - 2; assert(_s24P(d)); _CC_B(cc, d & 0x00ffffff); } return (l); } static jit_insn * swf_bdd(jit_state_t _jit, int (*i0)(double, double), int cc, void *i1, jit_fpr_t r1, jit_fpr_t r2) { jit_insn *l; int d; assert(r1 != JIT_FPRET && r2 != JIT_FPRET); swf_push(0xf); if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); _LDRDIN(_R2, JIT_FP, swf_off(r2) + 8); } else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); swf_ldrin(_R2, JIT_FP, swf_off(r2) + 8); swf_ldrin(_R3, JIT_FP, swf_off(r2) + 4); } swf_call(i0, fallback); if (jit_thumb_p()) { T1_CMPI(_R0, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 1) - 2; assert(_s20P(d)); T2_CC_B(cc, encode_thumb_cc_jump(d)); } else { _CMPI(_R0, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 2) - 2; assert(_s24P(d)); _CC_B(cc, d & 0x00ffffff); } return (l); } #define swf_bltr_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmplt,ARM_CC_NE,i0,r0,r1) #define swf_bltr_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmplt,ARM_CC_NE,i0,r0,r1) #define swf_bler_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmple,ARM_CC_NE,i0,r0,r1) #define swf_bler_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmple,ARM_CC_NE,i0,r0,r1) #define swf_beqr_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpeq,ARM_CC_NE,i0,r0,r1) #define swf_beqr_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpeq,ARM_CC_NE,i0,r0,r1) #define swf_bger_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpge,ARM_CC_NE,i0,r0,r1) #define swf_bger_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpge,ARM_CC_NE,i0,r0,r1) #define swf_bgtr_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpgt,ARM_CC_NE,i0,r0,r1) #define swf_bgtr_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpgt,ARM_CC_NE,i0,r0,r1) #define swf_bner_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpeq,ARM_CC_EQ,i0,r0,r1) #define swf_bner_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpeq,ARM_CC_EQ,i0,r0,r1) #define swf_bunltr_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpge,ARM_CC_EQ,i0,r0,r1) #define swf_bunltr_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpge,ARM_CC_EQ,i0,r0,r1) #define swf_bunler_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpgt,ARM_CC_EQ,i0,r0,r1) #define swf_bunler_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpgt,ARM_CC_EQ,i0,r0,r1) static jit_insn * swf_bunff(jit_state_t _jit, int eq, void *i1, jit_fpr_t r1, jit_fpr_t r2) { int d; jit_insn *l; jit_insn *j0; jit_insn *j1; assert(r1 != JIT_FPRET && r2 != JIT_FPRET); swf_push(0xf); swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r2) + 8); swf_call(__aeabi_fcmpun, fcmpun); /* if unordered */ if (jit_thumb_p()) { T1_CMPI(_R0, 0); j0 = _jit->x.pc; T2_CC_B(ARM_CC_NE, 0); } else { _CMPI(_R0, 0); j0 = _jit->x.pc; _CC_B(ARM_CC_NE, 0); } swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r2) + 8); swf_call(__aeabi_fcmpeq, fcmpeq); if (jit_thumb_p()) { T1_CMPI(_R0, 0); j1 = _jit->x.pc; if (eq) { T2_CC_B(ARM_CC_EQ, 0); jit_patch(j0); } else T2_CC_B(ARM_CC_NE, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 1) - 2; assert(_s24P(d)); T2_B(encode_thumb_jump(d)); } else { _CMPI(_R0, 0); j1 = _jit->x.pc; if (eq) { _CC_B(ARM_CC_EQ, 0); jit_patch(j0); } else _CC_B(ARM_CC_NE, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 2) - 2; assert(_s24P(d)); _B(d & 0x00ffffff); } if (!eq) jit_patch(j0); jit_patch(j1); swf_pop(0xf); return (l); } static jit_insn * swf_bundd(jit_state_t _jit, int eq, void *i1, jit_fpr_t r1, jit_fpr_t r2) { int d; jit_insn *l; jit_insn *j0; jit_insn *j1; assert(r1 != JIT_FPRET && r2 != JIT_FPRET); swf_push(0xf); if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); _LDRDIN(_R2, JIT_FP, swf_off(r2) + 8); } else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); swf_ldrin(_R2, JIT_FP, swf_off(r2) + 8); swf_ldrin(_R3, JIT_FP, swf_off(r2) + 4); } swf_call(__aeabi_dcmpun, dcmpun); /* if unordered */ if (jit_thumb_p()) { T1_CMPI(_R0, 0); j0 = _jit->x.pc; T2_CC_B(ARM_CC_NE, 0); } else { _CMPI(_R0, 0); j0 = _jit->x.pc; _CC_B(ARM_CC_NE, 0); } if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(_R0, JIT_FP, swf_off(r1) + 8); _LDRDIN(_R2, JIT_FP, swf_off(r2) + 8); } else { swf_ldrin(_R0, JIT_FP, swf_off(r1) + 8); swf_ldrin(_R1, JIT_FP, swf_off(r1) + 4); swf_ldrin(_R2, JIT_FP, swf_off(r2) + 8); swf_ldrin(_R3, JIT_FP, swf_off(r2) + 4); } swf_call(__aeabi_dcmpeq, dcmpeq); if (jit_thumb_p()) { T1_CMPI(_R0, 0); j1 = _jit->x.pc; if (eq) { T2_CC_B(ARM_CC_EQ, 0); jit_patch(j0); } else T2_CC_B(ARM_CC_NE, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 1) - 2; assert(_s24P(d)); T2_B(encode_thumb_jump(d)); } else { _CMPI(_R0, 0); j1 = _jit->x.pc; if (eq) { _CC_B(ARM_CC_EQ, 0); jit_patch(j0); } else _CC_B(ARM_CC_NE, 0); swf_pop(0xf); l = _jit->x.pc; d = (((int)i1 - (int)l) >> 2) - 2; assert(_s24P(d)); _B(d & 0x00ffffff); } if (!eq) jit_patch(j0); jit_patch(j1); swf_pop(0xf); return (l); } #define swf_buneqr_f(_jit,i0,r0,r1) swf_bunff(_jit,1,i0,r0,r1) #define swf_buneqr_d(_jit,i0,r0,r1) swf_bundd(_jit,1,i0,r0,r1) #define swf_bunger_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmplt,ARM_CC_EQ,i0,r0,r1) #define swf_bunger_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmplt,ARM_CC_EQ,i0,r0,r1) #define swf_bungtr_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmple,ARM_CC_EQ,i0,r0,r1) #define swf_bungtr_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmple,ARM_CC_EQ,i0,r0,r1) #define swf_bltgtr_f(_jit,i0,r0,r1) swf_bunff(_jit,0,i0,r0,r1) #define swf_bltgtr_d(_jit,i0,r0,r1) swf_bundd(_jit,0,i0,r0,r1) #define swf_bordr_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpun,ARM_CC_EQ,i0,r0,r1) #define swf_bordr_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpun,ARM_CC_EQ,i0,r0,r1) #define swf_bunordr_f(_jit,i0,r0,r1) swf_bff(_jit,__aeabi_fcmpun,ARM_CC_NE,i0,r0,r1) #define swf_bunordr_d(_jit,i0,r0,r1) swf_bdd(_jit,__aeabi_dcmpun,ARM_CC_NE,i0,r0,r1) __jit_inline void swf_ldr_f(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1) { jit_ldr_i(JIT_FTMP, r1); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } __jit_inline void swf_ldr_d(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1) { if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDI(JIT_TMP, r1, 0); _STRDIN(JIT_TMP, JIT_FP, swf_off(r0) + 8); } else { jit_ldxi_i(JIT_TMP, r1, 0); jit_ldxi_i(JIT_FTMP, r1, 4); swf_strin(JIT_TMP, JIT_FP, swf_off(r0) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } } __jit_inline void swf_ldi_f(jit_state_t _jit, jit_fpr_t r0, void *i0) { jit_ldi_i(JIT_FTMP, i0); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } __jit_inline void swf_ldi_d(jit_state_t _jit, jit_fpr_t r0, void *i0) { jit_movi_i(JIT_TMP, (int)i0); if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDI(JIT_TMP, JIT_TMP, 0); _STRDIN(JIT_TMP, JIT_FP, swf_off(r0) + 8); } else { jit_ldxi_i(JIT_FTMP, JIT_TMP, 4); jit_ldxi_i(JIT_TMP, JIT_TMP, 0); swf_strin(JIT_TMP, JIT_FP, swf_off(r0) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } } __jit_inline void swf_ldxr_f(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1, jit_gpr_t r2) { jit_ldxr_i(JIT_TMP, r1, r2); swf_strin(JIT_TMP, JIT_FP, swf_off(r0) + 8); } __jit_inline void swf_ldxr_d(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1, jit_gpr_t r2) { if (!jit_thumb_p() && jit_armv5e_p()) { _LDRD(JIT_TMP, r1, r2); _STRDIN(JIT_TMP, JIT_FP, swf_off(r0) + 8); } else { jit_addr_i(JIT_TMP, r1, r2); jit_ldxi_i(JIT_FTMP, JIT_TMP, 4); jit_ldxi_i(JIT_TMP, JIT_TMP, 0); swf_strin(JIT_TMP, JIT_FP, swf_off(r0) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } } __jit_inline void swf_ldxi_f(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1, int i0) { jit_ldxi_i(JIT_FTMP, r1, i0); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } __jit_inline void swf_ldxi_d(jit_state_t _jit, jit_fpr_t r0, jit_gpr_t r1, int i0) { if (!jit_thumb_p() && jit_armv5e_p()) { if (i0 >= 0 && i0 <= 255) _LDRDI(JIT_TMP, r1, i0); else if (i0 < 0 && i0 >= -255) _LDRDIN(JIT_TMP, r1, -i0); else { jit_addi_i(JIT_FTMP, r1, i0); _LDRDI(JIT_TMP, JIT_FTMP, 0); } _STRDIN(JIT_TMP, JIT_FP, swf_off(r0) + 8); } else { if (((jit_thumb_p() && i0 >= -255) || (!jit_thumb_p() && i0 >= -4095)) && i0 + 4 <= 4095) { if (i0 >= 0) jit_ldxi_i(JIT_TMP, r1, i0); else if (i0 < 0) swf_ldrin(JIT_TMP, r1, -i0); i0 += 4; if (i0 >= 0) jit_ldxi_i(JIT_FTMP, r1, i0); else if (i0 < 0) swf_ldrin(JIT_FTMP, r1, -i0); } else { jit_addi_i(JIT_FTMP, r1, i0); jit_ldxi_i(JIT_TMP, JIT_FTMP, 0); jit_ldxi_i(JIT_FTMP, JIT_FTMP, 4); } swf_strin(JIT_TMP, JIT_FP, swf_off(r0) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } } __jit_inline void swf_str_f(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 8); jit_stxi_i(0, r0, JIT_FTMP); } __jit_inline void swf_str_d(jit_state_t _jit, jit_gpr_t r0, jit_fpr_t r1) { if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(JIT_TMP, JIT_FP, swf_off(r1) + 8); _STRDI(JIT_TMP, r0, 0); } else { swf_ldrin(JIT_TMP, JIT_FP, swf_off(r1) + 8); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 4); jit_stxi_i(0, r0, JIT_TMP); jit_stxi_i(4, r0, JIT_FTMP); } } __jit_inline void swf_sti_f(jit_state_t _jit, void *i0, jit_fpr_t r0) { jit_movi_i(JIT_TMP, (int)i0); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); jit_stxi_i(0, JIT_TMP, JIT_FTMP); } __jit_inline void swf_sti_d(jit_state_t _jit, void *i0, jit_fpr_t r0) { jit_movi_i(JIT_TMP, (int)i0); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); jit_stxi_i(0, JIT_TMP, JIT_FTMP); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); jit_stxi_i(4, JIT_TMP, JIT_FTMP); } __jit_inline void swf_stxr_f(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_fpr_t r2) { swf_ldrin(JIT_TMP, JIT_FP, swf_off(r2) + 8); jit_stxr_i(r1, r0, JIT_TMP); } __jit_inline void swf_stxr_d(jit_state_t _jit, jit_gpr_t r0, jit_gpr_t r1, jit_fpr_t r2) { if (!jit_thumb_p() && jit_armv5e_p()) { _LDRDIN(JIT_TMP, JIT_FP, swf_off(r2) + 8); _STRD(JIT_TMP, r0, r1); } else { jit_addr_i(JIT_TMP, r0, r1); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r2) + 8); jit_stxi_i(0, JIT_TMP, JIT_FTMP); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r2) + 4); jit_stxi_i(4, JIT_TMP, JIT_FTMP); } } __jit_inline void swf_stxi_f(jit_state_t _jit, int i0, jit_gpr_t r0, jit_fpr_t r1) { swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r1) + 8); jit_stxi_i(i0, r0, JIT_FTMP); } __jit_inline void swf_stxi_d(jit_state_t _jit, int i0, jit_gpr_t r0, jit_fpr_t r1) { if (!jit_thumb_p() && jit_armv5e_p()) { if (i0 >= 0 && i0 <= 255) { _LDRDIN(JIT_TMP, JIT_FP, swf_off(r1) + 8); _STRDI(JIT_TMP, r0, i0); } else if (i0 < 0 && i0 >= -255) { _LDRDIN(JIT_TMP, JIT_FP, swf_off(r1) + 8); _STRDIN(JIT_TMP, r0, -i0); } else { jit_addi_i(JIT_FTMP, r0, i0); swf_ldrin(JIT_TMP, JIT_FP, swf_off(r1) + 8); jit_stxi_i(0, JIT_TMP, JIT_FTMP); swf_ldrin(JIT_TMP, JIT_FP, swf_off(r1) + 4); jit_stxi_i(4, JIT_TMP, JIT_FTMP); } } else { jit_addi_i(JIT_FTMP, r0, i0); swf_ldrin(JIT_TMP, JIT_FP, swf_off(r1) + 8); jit_stxi_i(0, JIT_FTMP, JIT_TMP); swf_ldrin(JIT_TMP, JIT_FP, swf_off(r1) + 4); jit_stxi_i(4, JIT_FTMP, JIT_TMP); } } __jit_inline void swf_getarg_f(jit_state_t _jit, jit_fpr_t r0, int i0) { if (i0 < 4) i0 <<= 2; jit_ldxi_i(JIT_FTMP, JIT_FP, i0); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); } __jit_inline void swf_getarg_d(jit_state_t _jit, jit_fpr_t r0, int i0) { if (i0 < 4) i0 <<= 2; if (!jit_thumb_p() && jit_armv5e_p()) { if (i0 < 255) _LDRDI(JIT_TMP, JIT_FP, i0); else { jit_addi_i(JIT_FTMP, JIT_FP, i0); jit_ldxi_i(JIT_TMP, JIT_FTMP, 0); jit_ldxi_i(JIT_FTMP, JIT_FTMP, 4); } _STRDIN(JIT_TMP, JIT_FP, swf_off(r0) + 8); } else { if (i0 + 4 < 4095) { jit_ldxi_i(JIT_TMP, JIT_FP, i0); jit_ldxi_i(JIT_FTMP, JIT_FP, i0 + 4); } else { jit_addi_i(JIT_FTMP, JIT_FP, i0); jit_ldxi_i(JIT_TMP, JIT_FTMP, 0); jit_ldxi_i(JIT_FTMP, JIT_FTMP, 4); } swf_strin(JIT_TMP, JIT_FP, swf_off(r0) + 8); swf_strin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } } __jit_inline void swf_pusharg_f(jit_state_t _jit, jit_fpr_t r0) { int ofs = _jitl.nextarg_put++; assert(ofs < 256); _jitl.stack_offset -= sizeof(float); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r0) + 8); _jitl.arguments[ofs] = (int *)_jit->x.pc; _jitl.types[ofs >> 5] &= ~(1 << (ofs & 31)); if (jit_thumb_p()) T2_STRWI(JIT_FTMP, JIT_SP, 0); else _STRI(JIT_FTMP, JIT_SP, 0); } #endif __jit_inline void swf_pusharg_d(jit_state _jit, jit_fpr_t r0) { int ofs = _jitl.nextarg_put++; assert(ofs < 256); _jitl.stack_offset -= sizeof(double); if (!jit_thumb_p() && jit_armv5e_p()) _LDRDIN(JIT_TMP, JIT_FP, swf_off(r0) + 8); else { swf_ldrin(JIT_TMP, JIT_FP, swf_off(r0) + 8); swf_ldrin(JIT_FTMP, JIT_FP, swf_off(r0) + 4); } _jitl.arguments[ofs] = (int *)_jit.x.pc; _jitl.types[ofs >> 5] |= 1 << (ofs & 31); /* large offsets (handled by patch_arguments) cannot be encoded in STRDI */ if (jit_thumb_p()) { T2_STRWI(JIT_TMP, JIT_SP, 0); T2_STRWI(JIT_FTMP, JIT_SP, 0); } else { _STRI(JIT_TMP, JIT_SP, 0); _STRI(JIT_FTMP, JIT_SP, 0); } } #if 0 #define swf_retval_f(_jit, r0) swf_strin(_R0, JIT_FP, swf_off(r0) + 8) __jit_inline void swf_retval_d(jit_state_t _jit, jit_fpr_t r0) { if (!jit_thumb_p() && jit_armv5e_p()) _STRDIN(_R0, JIT_FP, swf_off(r0) + 8); else { swf_strin(_R0, JIT_FP, swf_off(r0) + 8); swf_strin(_R1, JIT_FP, swf_off(r0) + 4); } } #endif #endif /* __lightning_fp_swf_h */