1
0
forked from GitHub/gf-core

bugfix in GNU lightning for ARM

This commit is contained in:
kr.angelov
2013-10-08 13:33:18 +00:00
parent dfb5a78a8d
commit 527ea8fc5c

View File

@@ -107,7 +107,7 @@ jit_get_cpu(void)
static void static void
arm_patch_arguments(struct jit_local_state* jitl) arm_patch_arguments(struct jit_local_state* jitl)
{ {
int reg; int reg;
int ioff; int ioff;
int foff; int foff;
@@ -122,183 +122,183 @@ arm_patch_arguments(struct jit_local_state* jitl)
ioff = foff = 0; ioff = foff = 0;
for (index = jitl->nextarg_put - 1, offset = 0; index >= 0; index--) { for (index = jitl->nextarg_put - 1, offset = 0; index >= 0; index--) {
if (jitl->types[index >> 5] & (1 << (index & 31))) if (jitl->types[index >> 5] & (1 << (index & 31)))
size = sizeof(double); size = sizeof(double);
else else
size = sizeof(int); size = sizeof(int);
u.i = jitl->arguments[index]; u.i = jitl->arguments[index];
if (jit_thumb_p()) { #ifdef USE_THUMB_CODE
code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
switch (thumb.i & 0xfff00f00) { switch (thumb.i & 0xfff00f00) {
case ARM_CC_AL|ARM_VSTR|ARM_P: case ARM_CC_AL|ARM_VSTR|ARM_P:
if (jit_hardfp_p()) { if (jit_hardfp_p()) {
if (foff < 16) { if (foff < 16) {
reg = (thumb.i >> 12) & 0xf; reg = (thumb.i >> 12) & 0xf;
thumb.i = (ARM_CC_AL|ARM_VMOV_F | thumb.i = (ARM_CC_AL|ARM_VMOV_F |
((foff >> 1) << 12) | reg); ((foff >> 1) << 12) | reg);
if (foff & 1) if (foff & 1)
thumb.i |= ARM_V_D; thumb.i |= ARM_V_D;
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
++foff; ++foff;
continue; continue;
} }
} }
else { else {
if (ioff < 4) { if (ioff < 4) {
thumb.i = ((thumb.i & 0xfff0ff00) | thumb.i = ((thumb.i & 0xfff0ff00) |
(JIT_FP << 16) | ioff); (JIT_FP << 16) | ioff);
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
++ioff; ++ioff;
continue; continue;
} }
} }
thumb.i = (thumb.i & 0xffffff00) | (offset >> 2); thumb.i = (thumb.i & 0xffffff00) | (offset >> 2);
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
break; break;
case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P: case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P:
if (jit_hardfp_p()) { if (jit_hardfp_p()) {
if (foff & 1) if (foff & 1)
++foff; ++foff;
if (foff < 16) { if (foff < 16) {
reg = (thumb.i >> 12) & 0xf; reg = (thumb.i >> 12) & 0xf;
thumb.i = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 | thumb.i = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 |
((foff >> 1) << 12) | reg); ((foff >> 1) << 12) | reg);
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
foff += 2; foff += 2;
continue; continue;
} }
} }
else { else {
if (ioff & 1) if (ioff & 1)
++ioff; ++ioff;
if (ioff < 4) { if (ioff < 4) {
thumb.i = ((thumb.i & 0xfff0ff00) | thumb.i = ((thumb.i & 0xfff0ff00) |
(JIT_FP << 16) | ioff); (JIT_FP << 16) | ioff);
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
ioff += 2; ioff += 2;
continue; continue;
} }
} }
if (offset & 7) if (offset & 7)
offset += sizeof(int); offset += sizeof(int);
thumb.i = (thumb.i & 0xffffff00) | (offset >> 2); thumb.i = (thumb.i & 0xffffff00) | (offset >> 2);
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
break; break;
case THUMB2_STRWI: case THUMB2_STRWI:
thumb_stri: thumb_stri:
if (size == 8 && (ioff & 1)) if (size == 8 && (ioff & 1))
++ioff; ++ioff;
if (ioff < 4) { if (ioff < 4) {
thumb.i = ((thumb.i & 0xfff0f000) | thumb.i = ((thumb.i & 0xfff0f000) |
(JIT_FP << 16) | (ioff << 2)); (JIT_FP << 16) | (ioff << 2));
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
++ioff; ++ioff;
if (size == 8) { if (size == 8) {
code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]);
thumb.i = ((thumb.i & 0xfff0f000) | thumb.i = ((thumb.i & 0xfff0f000) |
(JIT_FP << 16) | (ioff << 2)); (JIT_FP << 16) | (ioff << 2));
thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]);
++ioff; ++ioff;
} }
continue; continue;
} }
if (size == 8 && (offset & 7)) if (size == 8 && (offset & 7))
offset += sizeof(int); offset += sizeof(int);
thumb.i = (thumb.i & 0xfffff000) | offset; thumb.i = (thumb.i & 0xfffff000) | offset;
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]); thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
if (size == 8) { if (size == 8) {
code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); code2thumb(thumb.s[0], thumb.s[1], u.s[2], u.s[3]);
thumb.i = (thumb.i & 0xfffff000) | (offset + 4); thumb.i = (thumb.i & 0xfffff000) | (offset + 4);
thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]); thumb2code(thumb.s[0], thumb.s[1], u.s[2], u.s[3]);
} }
break; break;
default: default:
/* offset too large */ /* offset too large */
if ((thumb.i & 0xfff00000) == THUMB2_STRWI) if ((thumb.i & 0xfff00000) == THUMB2_STRWI)
goto thumb_stri; goto thumb_stri;
abort(); abort();
} }
} #else
else { switch (u.i[0] & 0xfff00f00) {
switch (u.i[0] & 0xfff00f00) {
case ARM_CC_AL|ARM_VSTR|ARM_P: case ARM_CC_AL|ARM_VSTR|ARM_P:
if (jit_hardfp_p()) { if (jit_hardfp_p()) {
if (foff < 16) { if (foff < 16) {
reg = (u.i[0] >> 12) & 0xf; reg = (u.i[0] >> 12) & 0xf;
u.i[0] = (ARM_CC_AL|ARM_VMOV_F | u.i[0] = (ARM_CC_AL|ARM_VMOV_F |
((foff >> 1) << 12) | reg); ((foff >> 1) << 12) | reg);
if (foff & 1) if (foff & 1)
u.i[0] |= ARM_V_D; u.i[0] |= ARM_V_D;
++foff; ++foff;
continue; continue;
} }
} }
else { else {
if (ioff < 4) { if (ioff < 4) {
u.i[0] = ((u.i[0] & 0xfff0ff00) | u.i[0] = ((u.i[0] & 0xfff0ff00) |
(JIT_FP << 16) | ioff); (JIT_FP << 16) | ioff);
++ioff; ++ioff;
continue; continue;
} }
} }
u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2); u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2);
break; break;
case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P: case ARM_CC_AL|ARM_VSTR|ARM_V_F64|ARM_P:
if (jit_hardfp_p()) { if (jit_hardfp_p()) {
if (foff & 1) if (foff & 1)
++foff; ++foff;
if (foff < 16) { if (foff < 16) {
reg = (u.i[0] >> 12) & 0xf; reg = (u.i[0] >> 12) & 0xf;
u.i[0] = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 | u.i[0] = (ARM_CC_AL|ARM_VMOV_F|ARM_V_F64 |
((foff >> 1) << 12) | reg); ((foff >> 1) << 12) | reg);
foff += 2; foff += 2;
continue; continue;
} }
} }
else { else {
if (ioff & 1) if (ioff & 1)
++ioff; ++ioff;
if (ioff < 4) { if (ioff < 4) {
u.i[0] = ((u.i[0] & 0xfff0ff00) | u.i[0] = ((u.i[0] & 0xfff0ff00) |
(JIT_FP << 16) | ioff); (JIT_FP << 16) | ioff);
ioff += 2; ioff += 2;
continue; continue;
} }
} }
if (offset & 7) if (offset & 7)
offset += sizeof(int); offset += sizeof(int);
u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2); u.i[0] = (u.i[0] & 0xffffff00) | (offset >> 2);
break; break;
case ARM_CC_AL|ARM_STRI|ARM_P: case ARM_CC_AL|ARM_STRI|ARM_P:
arm_stri: arm_stri:
if (size == 8 && (ioff & 1)) if (size == 8 && (ioff & 1))
++ioff; ++ioff;
if (ioff < 4) { if (ioff < 4) {
u.i[0] = ((u.i[0] & 0xfff0f000) | u.i[0] = ((u.i[0] & 0xfff0f000) |
(JIT_FP << 16) | (ioff << 2)); (JIT_FP << 16) | (ioff << 2));
++ioff; ++ioff;
if (size == 8) { if (size == 8) {
u.i[1] = ((u.i[1] & 0xfff0f000) | u.i[1] = ((u.i[1] & 0xfff0f000) |
(JIT_FP << 16) | (ioff << 2)); (JIT_FP << 16) | (ioff << 2));
++ioff; ++ioff;
} }
continue; continue;
} }
if (size == 8 && (offset & 7)) if (size == 8 && (offset & 7))
offset += sizeof(int); offset += sizeof(int);
u.i[0] = (u.i[0] & 0xfffff000) | offset; u.i[0] = (u.i[0] & 0xfffff000) | offset;
if (size == 8) if (size == 8)
u.i[1] = (u.i[1] & 0xfffff000) | (offset + 4); u.i[1] = (u.i[1] & 0xfffff000) | (offset + 4);
break; break;
default: default:
/* offset too large */ /* offset too large */
if ((u.i[0] & 0xfff00000) == (ARM_CC_AL|ARM_STRI|ARM_P)) if ((u.i[0] & 0xfff00000) == (ARM_CC_AL|ARM_STRI|ARM_P))
goto arm_stri; goto arm_stri;
abort(); abort();
} }
} #endif
offset += size; offset += size;
} }
jitl->reglist = ((1 << ioff) - 1) & 0xf; jitl->reglist = ((1 << ioff) - 1) & 0xf;
if (jitl->stack_length < offset) { if (jitl->stack_length < offset) {
jitl->stack_length = offset; jitl->stack_length = offset;