them in the stream.
R=rsc
https://golang.org/cl/174052
optab.$O\
pass.$O\
thumb.$O\
+ softfloat.$O\
span.$O\
go.$O\
int32 regoff(Adr*);
int relinv(int);
int32 rnd(int32, int32);
+void softfloat(void);
void span(void);
void strnput(char*, int);
void undef(void);
return v;
}
+static char*
+linkername[] =
+{
+ "runtime·softfloat",
+};
+
void
usage(void)
{
void
main(int argc, char *argv[])
{
- int c;
+ int c, i;
Binit(&bso, 1, OWRITE);
cout = -1;
if(!debug['l'])
loadlib();
+ // mark some functions that are only referenced after linker code editing
+ // TODO(kaib): this doesn't work, the prog can't be found in runtime
+ for(i=0; i<nelem(linkername); i++)
+ mark(lookup(linkername[i], 0));
deadcode();
firstp = firstp->link;
follow();
if(firstp == P)
goto out;
+ softfloat();
noops();
span();
asmb();
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define EXTERN
+#include "l.h"
+
+void
+softfloat()
+{
+ Prog *p, *prev, *psfloat;
+ Sym *symsfloat;
+ int wasfloat;
+
+ symsfloat = lookup("_sfloat", 0);
+ psfloat = P;
+ if(symsfloat->type == STEXT)
+ for(p = firstp; p != P; p = p->link) {
+ if(p->as == ATEXT) {
+ if(p->from.sym == symsfloat) {
+ psfloat = p;
+ break;
+ }
+ }
+ }
+
+ wasfloat = 0;
+ p = firstp;
+ prev = P;
+ for(p = firstp; p != P; p = p->link) {
+ switch(p->as) {
+ case AMOVWD:
+ case AMOVWF:
+ case AMOVDW:
+ case AMOVFW:
+ case AMOVFD:
+ case AMOVDF:
+ case AMOVF:
+ case AMOVD:
+ case ACMPF:
+ case ACMPD:
+ case AADDF:
+ case AADDD:
+ case ASUBF:
+ case ASUBD:
+ case AMULF:
+ case AMULD:
+ case ADIVF:
+ case ADIVD:
+ if (psfloat == P)
+ diag("floats used with _sfloat not defined");
+ if (!wasfloat) {
+ if (prev == P)
+ diag("float instruction without predecessor TEXT");
+ // BL _sfloat(SB)
+ prev = appendp(prev);
+ prev->as = ABL;
+ prev->to.type = D_BRANCH;
+ prev->to.sym = symsfloat;
+ prev->cond = psfloat;
+
+ wasfloat = 1;
+ }
+ break;
+ default:
+ wasfloat = 0;
+ }
+ prev = p;
+ }
+}
nerrors++;
}
-static void mark(Sym*);
static int markdepth;
static void
markdepth--;
}
-static void
+void
mark(Sym *s)
{
if(s == S || s->reachable)
void ldobj1(Biobuf *f, int64 len, char *pn);
void ldobj(Biobuf*, int64, char*);
void ldpkg(Biobuf*, int64, char*);
+void mark(Sym *s);
+
int pathchar(void);
void* mal(uint32);
OFILES_arm=\
cas$(GOARM).$O\
memset.$O\
+ softfloat.$O\
vlop.$O\
vlrt.$O\
MOVW R0, (R1) // fail hard
RET
-// TODO(kaib): remove these once linker works properly
+// TODO(kaib): remove these once i actually understand how the linker removes symbols
// pull in dummy dependencies
TEXT _dep_dummy(SB),7,$0
BL _div(SB)
BL _mod(SB)
BL _modu(SB)
BL _modu(SB)
+ BL _sfloat(SB)
TEXT breakpoint(SB),7,$0
BL abort(SB)
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+
+// returns number of bytes that the fp instruction is occupying
+static uint32
+isfltinstr(uint32 *pc)
+{
+ uint32 i;
+ uint32 c;
+
+ i = *pc;
+ c = i >> 25 & 7;
+
+ switch(c) {
+ case 6: // 110
+//printf(" %p coproc multi: %x\n", pc, i);
+ return 4;
+ case 7: // 111
+ if (i>>24 & 1) return 0; // ignore swi
+//printf(" %p coproc %x\n", pc, i);
+ return 4;
+ }
+
+ // lookahead for virtual instructions that span multiple arm instructions
+ c = ((*pc & 0x0f000000) >> 16) |
+ ((*(pc + 1) & 0x0f000000) >> 20) |
+ ((*(pc + 2) & 0x0f000000) >> 24);
+ if(c == 0x50d) {
+//printf(" %p coproc const %x\n", pc, i);
+ return 12;
+ }
+
+//printf(" %p %x\n", pc, i);
+ return 0;
+}
+
+#pragma textflag 7
+uint32*
+_sfloat2(uint32 *lr, uint32 r0)
+{
+ uint32 skip;
+
+//printf("softfloat: pre %p\n", lr);
+ while(skip = isfltinstr(lr))
+ lr += skip;
+//printf(" post: %p\n", lr);
+ return lr;
+}
+
+
out:
BL rest<>(SB)
B out
+
+// trampoline for _sfloat2. passes LR as arg0 and
+// saves registers R0-R11 on the stack for mutation
+// by _sfloat2
+TEXT _sfloat(SB), 7, $52 // 4 arg + 12*4 saved regs
+ MOVW R14, 4(R13)
+ MOVW R0, 8(R13)
+ MOVW $12(R13), R0
+ MOVM.IA.W [R1-R11], (R0)
+ BL _sfloat2(SB)
+ MOVW R0, 0(R13)
+ MOVW $12(R13), R0
+ MOVM.IA.W (R0), [R1-R11]
+ MOVW 8(R13), R0
+ RET
+
+