mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 03:32:51 -06:00
more fixes for GNU Lightning for ARM
This commit is contained in:
@@ -49,7 +49,6 @@ struct {
|
|||||||
} jit_flags;
|
} jit_flags;
|
||||||
|
|
||||||
struct jit_local_state {
|
struct jit_local_state {
|
||||||
int reglist;
|
|
||||||
int framesize;
|
int framesize;
|
||||||
int nextarg_get;
|
int nextarg_get;
|
||||||
int nextarg_put;
|
int nextarg_put;
|
||||||
@@ -356,7 +355,12 @@ jit_v_order[JIT_V_NUM] = {
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define jit_addi_i(r0, r1, i0) 0
|
#define jit_addi_i(r0, r1, i0) \
|
||||||
|
(encode_arm_immediate(i0) != -1) ? \
|
||||||
|
_ADDI(r0, r1, encode_arm_immediate(i0)) : \
|
||||||
|
((encode_arm_immediate(-i0) != -1) ? \
|
||||||
|
_SUBI(r0, r1, encode_arm_immediate(-i0)) : \
|
||||||
|
(jit_movi_i(JIT_TMP, i0), _ADD(r0, r1, JIT_TMP)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_THUMB_CODE
|
#ifdef USE_THUMB_CODE
|
||||||
@@ -1999,39 +2003,36 @@ next: \
|
|||||||
\
|
\
|
||||||
/* patch alloca and stack adjustment */ \
|
/* patch alloca and stack adjustment */ \
|
||||||
_jitl.stack = (int *)_jit.x.pc; \
|
_jitl.stack = (int *)_jit.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; \
|
_jitl.stack_length = _jitl.stack_offset = 0; \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_THUMB_CODE
|
#ifdef USE_THUMB_CODE
|
||||||
#define jit_callr(r0) T1_BLX(r0)
|
#define jit_callr(r0) \
|
||||||
|
(T1_ADDI3(JIT_LR, JIT_PC, 4), \
|
||||||
|
T2_PUSH((1<<JIT_LR)), \
|
||||||
|
T1_MOV(JIT_PC, r0))
|
||||||
#else
|
#else
|
||||||
#define jit_callr(r0) _BLX(r0)
|
#define jit_callr(r0) \
|
||||||
|
(_ADDI(JIT_LR, JIT_PC, 4), \
|
||||||
|
_PUSH((1<<JIT_LR)), \
|
||||||
|
_MOV(JIT_PC, r0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_THUMB_CODE
|
#ifdef USE_THUMB_CODE
|
||||||
#define jit_calli(i0) \
|
#define jit_calli(i0) \
|
||||||
(_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \
|
(_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \
|
||||||
T1_BLX(JIT_TMP), \
|
jit_callr(JIT_TMP), \
|
||||||
_jitl.thumb_tmp)
|
_jitl.thumb_tmp)
|
||||||
#else
|
#else
|
||||||
#define jit_calli(i0) \
|
#define jit_calli(i0) \
|
||||||
(_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \
|
(_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \
|
||||||
_BLX(JIT_TMP), \
|
jit_callr(JIT_TMP), \
|
||||||
_jitl.thumb_tmp)
|
_jitl.thumb_tmp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define jit_prepare_i(i0) \
|
#define jit_prepare_i(i0) \
|
||||||
(assert((i0) >= 0 && !_jitl.stack_offset && !_jitl.nextarg_put), \
|
(assert((i0) >= 0 && !_jitl.nextarg_put), \
|
||||||
_jitl.stack_offset = i0 << 2)
|
_jitl.stack_offset = i0 << 2)
|
||||||
|
|
||||||
#define jit_arg_c() jit_arg_p()
|
#define jit_arg_c() jit_arg_p()
|
||||||
@@ -2066,81 +2067,53 @@ next: \
|
|||||||
#define jit_getarg_p(r0, i0) \
|
#define jit_getarg_p(r0, i0) \
|
||||||
jit_ldxi_i(r0, JIT_FP, (((i0) < 4) ? (i0) << 2 : (i0))); /* arguments are saved in prolog */
|
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) \
|
#define jit_pusharg_i(r0) \
|
||||||
{ \
|
(jit_pushr_i(r0), _jitl.nextarg_put++)
|
||||||
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); \
|
|
||||||
}
|
|
||||||
#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
|
#ifdef USE_THUMB_CODE
|
||||||
#define jit_finishr(rs) \
|
#define jit_finishr(rs) \
|
||||||
{ \
|
{ \
|
||||||
assert(!_jitl.stack_offset); \
|
|
||||||
if (r0 < 4) { \
|
if (r0 < 4) { \
|
||||||
jit_movr_i(JIT_TMP, r0); \
|
jit_movr_i(JIT_TMP, r0); \
|
||||||
r0 = JIT_TMP; \
|
r0 = JIT_TMP; \
|
||||||
} \
|
} \
|
||||||
arm_patch_arguments(&_jitl); \
|
if (_jitl.nextarg_put) { \
|
||||||
_jitl.nextarg_put = 0; \
|
T2_POP(((1 << _jitl.nextarg_put) - 1) & 0xf); \
|
||||||
if (_jitl.reglist) { \
|
_jitl.nextarg_put = 0; \
|
||||||
T2_LDMIA(JIT_FP, _jitl.reglist); \
|
|
||||||
_jitl.reglist = 0; \
|
|
||||||
} \
|
} \
|
||||||
jit_callr(r0); \
|
T1_BLX(r0); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define jit_finishr(rs) \
|
#define jit_finishr(rs) \
|
||||||
{ \
|
{ \
|
||||||
assert(!_jitl.stack_offset); \
|
|
||||||
if (r0 < 4) { \
|
if (r0 < 4) { \
|
||||||
jit_movr_i(JIT_TMP, r0); \
|
jit_movr_i(JIT_TMP, r0); \
|
||||||
r0 = JIT_TMP; \
|
r0 = JIT_TMP; \
|
||||||
} \
|
} \
|
||||||
arm_patch_arguments(&_jitl); \
|
if (_jitl.nextarg_put) { \
|
||||||
_jitl.nextarg_put = 0; \
|
_POP(((1 << _jitl.nextarg_put) - 1) & 0xf); \
|
||||||
if (_jitl.reglist) { \
|
_jitl.nextarg_put = 0; \
|
||||||
_LDMIA(JIT_FP, _jitl.reglist); \
|
|
||||||
_jitl.reglist = 0; \
|
|
||||||
} \
|
} \
|
||||||
jit_callr(r0); \
|
_BLX(r0); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_THUMB_CODE
|
#ifdef USE_THUMB_CODE
|
||||||
#define jit_finish(i0) \
|
#define jit_finish(i0) \
|
||||||
(assert(!_jitl.stack_offset), \
|
((_jitl.nextarg_put) ? \
|
||||||
arm_patch_arguments(&_jitl), \
|
(T2_POP(((1 << _jitl.nextarg_put) - 1) & 0xf), \
|
||||||
_jitl.nextarg_put = 0, \
|
_jitl.nextarg_put = 0) : 0, \
|
||||||
(_jitl.reglist) ? \
|
_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \
|
||||||
(T2_LDMIA(JIT_FP, _jitl.reglist), \
|
T1_BLX(JIT_TMP), \
|
||||||
_jitl.reglist = 0) : 0, \
|
_jitl.thumb_tmp)
|
||||||
jit_calli(i0))
|
|
||||||
#else
|
#else
|
||||||
#define jit_finish(i0) \
|
#define jit_finish(i0) \
|
||||||
(assert(!_jitl.stack_offset), \
|
((_jitl.nextarg_put) ? \
|
||||||
arm_patch_arguments(&_jitl), \
|
(_POP(((1 << _jitl.nextarg_put) - 1) & 0xf), \
|
||||||
_jitl.nextarg_put = 0, \
|
_jitl.nextarg_put = 0) : 0, \
|
||||||
(_jitl.reglist) ? \
|
_jitl.thumb_tmp = jit_movi_p(JIT_TMP, i0), \
|
||||||
(_LDMIA(JIT_FP, _jitl.reglist), \
|
_BLX(JIT_TMP), \
|
||||||
_jitl.reglist = 0) : 0, \
|
_jitl.thumb_tmp)
|
||||||
jit_calli(i0))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define jit_retval_i(r0) jit_movr_i(r0, JIT_RET)
|
#define jit_retval_i(r0) jit_movr_i(r0, JIT_RET)
|
||||||
@@ -2179,19 +2152,12 @@ next: \
|
|||||||
#define jit_bare_ret() _POP(1<<JIT_PC)
|
#define jit_bare_ret() _POP(1<<JIT_PC)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* just to pass make check... */
|
#ifdef USE_THUMB_CODE
|
||||||
#ifdef JIT_NEED_PUSH_POP
|
# define jit_pushr_i(r0) T2_PUSH((1<<r0))
|
||||||
# define jit_pushr_i(r0) \
|
# define jit_popr_i(r0) T2_POP((1<<r0))
|
||||||
(assert(_jitl.pop < sizeof(_jitl.push) / sizeof(_jitl.push[0])), \
|
|
||||||
_jitl.push[_jitl.pop++] = jit_allocai(4), \
|
|
||||||
jit_stxi_i(_jitl.push[_jitl.pop], JIT_FP, r0))
|
|
||||||
|
|
||||||
# define jit_popr_i(r0) \
|
|
||||||
(assert(_jitl.pop > 0), \
|
|
||||||
_jitl.pop--, \
|
|
||||||
jit_ldxi_i(r0, JIT_FP, _jitl.push[_jitl.pop]))
|
|
||||||
#else
|
#else
|
||||||
# define jit_pushr_i(r0) 0
|
# define jit_pushr_i(r0) _PUSH((1<<r0))
|
||||||
# define jit_popr_i(r0) 0
|
# define jit_popr_i(r0) _POP((1<<r0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __lightning_core_arm_h */
|
#endif /* __lightning_core_arm_h */
|
||||||
|
|||||||
@@ -117,208 +117,6 @@ jit_get_cpu(void)
|
|||||||
jit_cpu.thumb = 0;
|
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];
|
|
||||||
#ifdef USE_THUMB_CODE
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
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 int __aeabi_idivmod(int, int);
|
||||||
extern unsigned __aeabi_uidivmod(unsigned, unsigned);
|
extern unsigned __aeabi_uidivmod(unsigned, unsigned);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user