Commit d85bb818 authored by Kai Backman's avatar Kai Backman

first stub for softfloats, intercepts float instructions and skips

        them in the stream.

R=rsc
https://golang.org/cl/174052
parent 4ddcb0ea
......@@ -17,6 +17,7 @@ OFILES=\
optab.$O\
pass.$O\
thumb.$O\
softfloat.$O\
span.$O\
go.$O\
......
......@@ -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);
......
......@@ -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();
......
// 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;
}
}
......@@ -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)
......
......@@ -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);
......
......@@ -34,6 +34,7 @@ GOARM?=6
OFILES_arm=\
cas$(GOARM).$O\
memset.$O\
softfloat.$O\
vlop.$O\
vlrt.$O\
......
......@@ -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)
......
// 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;
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment