summaryrefslogtreecommitdiff
path: root/src/cmd/5l/softfloat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5l/softfloat.c')
-rw-r--r--src/cmd/5l/softfloat.c113
1 files changed, 64 insertions, 49 deletions
diff --git a/src/cmd/5l/softfloat.c b/src/cmd/5l/softfloat.c
index 82874ee1c..fd66b0969 100644
--- a/src/cmd/5l/softfloat.c
+++ b/src/cmd/5l/softfloat.c
@@ -5,67 +5,82 @@
#define EXTERN
#include "l.h"
+// Software floating point.
+
void
-softfloat()
+softfloat(void)
{
Prog *p, *next, *psfloat;
Sym *symsfloat;
int wasfloat;
-
+
+ if(!debug['F'])
+ return;
+
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;
- }
- }
- }
+ psfloat = symsfloat->text;
+
+ for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ wasfloat = 0;
+ for(p = cursym->text; p != P; p = p->link)
+ if(p->cond != P)
+ p->cond->mark |= LABEL;
+ for(p = cursym->text; p != P; p = p->link) {
+ switch(p->as) {
+ case AMOVW:
+ if(p->to.type == D_FREG || p->from.type == D_FREG)
+ goto soft;
+ goto notsoft;
+
+ 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:
+ goto soft;
- wasfloat = 0;
- p = firstp;
- 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) {
- next = prg();
- *next = *p;
+ default:
+ goto notsoft;
- // BL _sfloat(SB)
- *p = zprg;
- p->link = next;
- p->as = ABL;
- p->to.type = D_BRANCH;
- p->to.sym = symsfloat;
- p->cond = psfloat;
+ soft:
+ if (psfloat == P)
+ diag("floats used with _sfloat not defined");
+ if (!wasfloat || (p->mark&LABEL)) {
+ next = prg();
+ *next = *p;
+
+ // BL _sfloat(SB)
+ *p = zprg;
+ p->link = next;
+ p->as = ABL;
+ p->to.type = D_BRANCH;
+ p->to.sym = symsfloat;
+ p->cond = psfloat;
+
+ p = next;
+ wasfloat = 1;
+ }
+ break;
- p = next;
- wasfloat = 1;
+ notsoft:
+ wasfloat = 0;
}
- break;
- default:
- wasfloat = 0;
}
}
}