summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/softfloat_arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/softfloat_arm.c')
-rw-r--r--src/pkg/runtime/softfloat_arm.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/src/pkg/runtime/softfloat_arm.c b/src/pkg/runtime/softfloat_arm.c
index 9a5440630..f5801dde4 100644
--- a/src/pkg/runtime/softfloat_arm.c
+++ b/src/pkg/runtime/softfloat_arm.c
@@ -7,6 +7,7 @@
// It uses true little-endian doubles, while the 7500 used mixed-endian.
#include "runtime.h"
+#include "../../cmd/ld/textflag.h"
#define CPSR 14
#define FLAGS_N (1U << 31)
@@ -576,20 +577,44 @@ done:
return 0;
}
-#pragma textflag 7
+typedef struct Sfregs Sfregs;
+
+// NOTE: These are all recorded as pointers because they are possibly live registers,
+// and we don't know what they contain. Recording them as pointers should be
+// safer than not.
+struct Sfregs
+{
+ uint32 *r0;
+ uint32 *r1;
+ uint32 *r2;
+ uint32 *r3;
+ uint32 *r4;
+ uint32 *r5;
+ uint32 *r6;
+ uint32 *r7;
+ uint32 *r8;
+ uint32 *r9;
+ uint32 *r10;
+ uint32 *r11;
+ uint32 *r12;
+ uint32 *r13;
+ uint32 cspr;
+};
+
+#pragma textflag NOSPLIT
uint32*
-runtime·_sfloat2(uint32 *lr, uint32 r0)
+runtime·_sfloat2(uint32 *lr, Sfregs regs)
{
uint32 skip;
- skip = stepflt(lr, &r0);
+ skip = stepflt(lr, (uint32*)&regs.r0);
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))
+ while(skip = stepflt(lr, (uint32*)&regs.r0))
lr += skip;
return lr;
}