]> Cypherpunks repositories - gostls13.git/commitdiff
first stub for softfloats, intercepts float instructions and skips
authorKai Backman <kaib@golang.org>
Fri, 18 Dec 2009 00:08:42 +0000 (16:08 -0800)
committerKai Backman <kaib@golang.org>
Fri, 18 Dec 2009 00:08:42 +0000 (16:08 -0800)
        them in the stream.

R=rsc
https://golang.org/cl/174052

src/cmd/5l/Makefile
src/cmd/5l/l.h
src/cmd/5l/obj.c
src/cmd/5l/softfloat.c [new file with mode: 0644]
src/cmd/ld/go.c
src/cmd/ld/lib.h
src/pkg/runtime/Makefile
src/pkg/runtime/arm/asm.s
src/pkg/runtime/arm/softfloat.c [new file with mode: 0644]
src/pkg/runtime/arm/vlop.s

index be866b87a4e5590c4f5ae1a4cf6d18627a54d672..aa175d14c6cc11bed97d07756ec81b55c6bc376d 100644 (file)
@@ -17,6 +17,7 @@ OFILES=\
        optab.$O\
        pass.$O\
        thumb.$O\
+       softfloat.$O\
        span.$O\
        go.$O\
 
index 05a20bad367c4c29f4ce18ea9c138d623179dc35..ba2de0a0f2f0fd3cfd02123151f3ca75e4eeb54d 100644 (file)
@@ -451,6 +451,7 @@ void        putsymb(char*, int, int32, int);
 int32  regoff(Adr*);
 int    relinv(int);
 int32  rnd(int32, int32);
+void   softfloat(void);
 void   span(void);
 void   strnput(char*, int);
 void   undef(void);
index 805d39544eee06b6424858637eae48109e551424..8fd39c29193139976aefead3902cd5f7fbaddf39 100644 (file)
@@ -71,6 +71,12 @@ isobjfile(char *f)
        return v;
 }
 
+static char*
+linkername[] =
+{
+       "runtime·softfloat",
+};
+
 void
 usage(void)
 {
@@ -81,7 +87,7 @@ usage(void)
 void
 main(int argc, char *argv[])
 {
-       int c;
+       int c, i;
 
        Binit(&bso, 1, OWRITE);
        cout = -1;
@@ -257,6 +263,10 @@ main(int argc, char *argv[])
        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;
@@ -294,6 +304,7 @@ main(int argc, char *argv[])
        follow();
        if(firstp == P)
                goto out;
+       softfloat();
        noops();
        span();
        asmb();
diff --git a/src/cmd/5l/softfloat.c b/src/cmd/5l/softfloat.c
new file mode 100644 (file)
index 0000000..f5a146f
--- /dev/null
@@ -0,0 +1,70 @@
+// 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;
+       }
+}
index 8f0e66d3306bff189ba2b8b514277879da4f7947..9a9346c1f272c3f6841501e9268e9d32879c032b 100644 (file)
@@ -364,7 +364,6 @@ err:
        nerrors++;
 }
 
-static void mark(Sym*);
 static int markdepth;
 
 static void
@@ -408,7 +407,7 @@ marktext(Prog *p)
        markdepth--;
 }
 
-static void
+void
 mark(Sym *s)
 {
        if(s == S || s->reachable)
index 0ae4106b8a9fd3690f9022b7e6117b6dfc82b412..4a300ac4e9022a4e2e91baa06837c9e910afb31a 100644 (file)
@@ -77,6 +77,8 @@ void  usage(void);
 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);
index bd6cd908bd63245440965ed36d721e9b163adb02..a85c4419049d52fff1f053827107596d202a81bc 100644 (file)
@@ -34,6 +34,7 @@ GOARM?=6
 OFILES_arm=\
        cas$(GOARM).$O\
        memset.$O\
+       softfloat.$O\
        vlop.$O\
        vlrt.$O\
 
index d65a1190215c0739b2e44f4db8b656d5d56df9ad..8c18fc85eb6afb0f2ef2016376cc88145b199d6a 100644 (file)
@@ -73,7 +73,7 @@ TEXT mainstart(SB),7,$4
        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)
@@ -81,6 +81,7 @@ TEXT _dep_dummy(SB),7,$0
        BL      _mod(SB)
        BL      _modu(SB)
        BL      _modu(SB)
+       BL      _sfloat(SB)
 
 TEXT   breakpoint(SB),7,$0
        BL      abort(SB)
diff --git a/src/pkg/runtime/arm/softfloat.c b/src/pkg/runtime/arm/softfloat.c
new file mode 100644 (file)
index 0000000..a71b251
--- /dev/null
@@ -0,0 +1,53 @@
+// 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;
+}
+
+
index 2c1d583fdb5f879089edf5821eb499e35d1f2086..b32204b176218387c83e1400c32700a0cc739ef0 100644 (file)
@@ -165,3 +165,20 @@ TEXT       _modu(SB), 7, $16
 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
+                       
+