1
0
mirror of https://github.com/golang/go synced 2024-11-25 09:07:58 -07:00

first stub for softfloats, intercepts float instructions and skips

them in the stream.

R=rsc
https://golang.org/cl/174052
This commit is contained in:
Kai Backman 2009-12-17 16:08:42 -08:00
parent 4ddcb0ea73
commit d85bb81878
10 changed files with 160 additions and 4 deletions

View File

@ -17,6 +17,7 @@ OFILES=\
optab.$O\ optab.$O\
pass.$O\ pass.$O\
thumb.$O\ thumb.$O\
softfloat.$O\
span.$O\ span.$O\
go.$O\ go.$O\

View File

@ -451,6 +451,7 @@ void putsymb(char*, int, int32, int);
int32 regoff(Adr*); int32 regoff(Adr*);
int relinv(int); int relinv(int);
int32 rnd(int32, int32); int32 rnd(int32, int32);
void softfloat(void);
void span(void); void span(void);
void strnput(char*, int); void strnput(char*, int);
void undef(void); void undef(void);

View File

@ -71,6 +71,12 @@ isobjfile(char *f)
return v; return v;
} }
static char*
linkername[] =
{
"runtime·softfloat",
};
void void
usage(void) usage(void)
{ {
@ -81,7 +87,7 @@ usage(void)
void void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int c; int c, i;
Binit(&bso, 1, OWRITE); Binit(&bso, 1, OWRITE);
cout = -1; cout = -1;
@ -257,6 +263,10 @@ main(int argc, char *argv[])
if(!debug['l']) if(!debug['l'])
loadlib(); 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(); deadcode();
firstp = firstp->link; firstp = firstp->link;
@ -294,6 +304,7 @@ main(int argc, char *argv[])
follow(); follow();
if(firstp == P) if(firstp == P)
goto out; goto out;
softfloat();
noops(); noops();
span(); span();
asmb(); asmb();

70
src/cmd/5l/softfloat.c Normal file
View File

@ -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;
}
}

View File

@ -364,7 +364,6 @@ err:
nerrors++; nerrors++;
} }
static void mark(Sym*);
static int markdepth; static int markdepth;
static void static void
@ -408,7 +407,7 @@ marktext(Prog *p)
markdepth--; markdepth--;
} }
static void void
mark(Sym *s) mark(Sym *s)
{ {
if(s == S || s->reachable) if(s == S || s->reachable)

View File

@ -77,6 +77,8 @@ void usage(void);
void ldobj1(Biobuf *f, int64 len, char *pn); void ldobj1(Biobuf *f, int64 len, char *pn);
void ldobj(Biobuf*, int64, char*); void ldobj(Biobuf*, int64, char*);
void ldpkg(Biobuf*, int64, char*); void ldpkg(Biobuf*, int64, char*);
void mark(Sym *s);
int pathchar(void); int pathchar(void);
void* mal(uint32); void* mal(uint32);

View File

@ -34,6 +34,7 @@ GOARM?=6
OFILES_arm=\ OFILES_arm=\
cas$(GOARM).$O\ cas$(GOARM).$O\
memset.$O\ memset.$O\
softfloat.$O\
vlop.$O\ vlop.$O\
vlrt.$O\ vlrt.$O\

View File

@ -73,7 +73,7 @@ TEXT mainstart(SB),7,$4
MOVW R0, (R1) // fail hard MOVW R0, (R1) // fail hard
RET 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 // pull in dummy dependencies
TEXT _dep_dummy(SB),7,$0 TEXT _dep_dummy(SB),7,$0
BL _div(SB) BL _div(SB)
@ -81,6 +81,7 @@ TEXT _dep_dummy(SB),7,$0
BL _mod(SB) BL _mod(SB)
BL _modu(SB) BL _modu(SB)
BL _modu(SB) BL _modu(SB)
BL _sfloat(SB)
TEXT breakpoint(SB),7,$0 TEXT breakpoint(SB),7,$0
BL abort(SB) BL abort(SB)

View File

@ -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;
}

View File

@ -165,3 +165,20 @@ TEXT _modu(SB), 7, $16
out: out:
BL rest<>(SB) BL rest<>(SB)
B out 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