summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/arm/softfloat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/arm/softfloat.c')
-rw-r--r--src/pkg/runtime/arm/softfloat.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/pkg/runtime/arm/softfloat.c b/src/pkg/runtime/arm/softfloat.c
index f60fab14f..f91a6fc09 100644
--- a/src/pkg/runtime/arm/softfloat.c
+++ b/src/pkg/runtime/arm/softfloat.c
@@ -91,6 +91,7 @@ static uint32
stepflt(uint32 *pc, uint32 *regs)
{
uint32 i, regd, regm, regn;
+ int32 delta;
uint32 *addr;
uint64 uval;
int64 sval;
@@ -117,7 +118,7 @@ stepflt(uint32 *pc, uint32 *regs)
return 1;
}
if(i == 0xe08bb00d) {
- // add sp to 11.
+ // add sp to r11.
// might be part of a large stack offset address
// (or might not, but again no harm done).
regs[11] += regs[13];
@@ -134,6 +135,19 @@ stepflt(uint32 *pc, uint32 *regs)
runtime·printf("*** fpsr R[CPSR] = F[CPSR] %x\n", regs[CPSR]);
return 1;
}
+ if((i&0xff000000) == 0xea000000) {
+ // unconditional branch
+ // can happen in the middle of floating point
+ // if the linker decides it is time to lay down
+ // a sequence of instruction stream constants.
+ delta = i&0xffffff;
+ delta = (delta<<8) >> 8; // sign extend
+
+ if(trace)
+ runtime·printf("*** cpu PC += %x\n", (delta+2)*4);
+ return delta+2;
+ }
+
goto stage1;
stage1: // load/store regn is cpureg, regm is 8bit offset
@@ -489,8 +503,10 @@ runtime·_sfloat2(uint32 *lr, uint32 r0)
uint32 skip;
skip = stepflt(lr, &r0);
- if(skip == 0)
+ if(skip == 0) {
+ runtime·printf("sfloat2 %p %x\n", lr, *lr);
fabort(); // not ok to fail first instruction
+ }
lr += skip;
while(skip = stepflt(lr, &r0))