diff options
Diffstat (limited to 'src/cmd/8c')
-rw-r--r-- | src/cmd/8c/cgen.c | 35 | ||||
-rw-r--r-- | src/cmd/8c/gc.h | 3 | ||||
-rw-r--r-- | src/cmd/8c/swt.c | 24 |
3 files changed, 58 insertions, 4 deletions
diff --git a/src/cmd/8c/cgen.c b/src/cmd/8c/cgen.c index 7f02bd96e..869d31ace 100644 --- a/src/cmd/8c/cgen.c +++ b/src/cmd/8c/cgen.c @@ -1221,7 +1221,7 @@ void boolgen(Node *n, int true, Node *nn) { int o; - Prog *p1, *p2; + Prog *p1, *p2, *p3; Node *l, *r, nod, nod1; int32 curs; @@ -1346,6 +1346,15 @@ boolgen(Node *n, int true, Node *nn) cgen64(n, Z); goto com; } + if(true && typefd[l->type->etype] && (o == OEQ || o == ONE)) { + // Cannot rewrite !(l == r) into l != r with float64; it breaks NaNs. + // Jump around instead. + boolgen(n, 0, Z); + p1 = p; + gbranch(OGOTO); + patch(p1, pc); + goto com; + } if(true) o = comrel[relindex(o)]; if(l->complex >= FNX && r->complex >= FNX) { @@ -1378,6 +1387,30 @@ boolgen(Node *n, int true, Node *nn) } else fgopcode(o, l, &fregnode0, 0, 1); } + switch(o) { + case OEQ: + // Already emitted AJEQ; want AJEQ and AJPC. + p1 = p; + gbranch(OGOTO); + p2 = p; + patch(p1, pc); + gins(AJPC, Z, Z); + patch(p2, pc); + break; + + case ONE: + // Already emitted AJNE; want AJNE or AJPS. + p1 = p; + gins(AJPS, Z, Z); + p2 = p; + gbranch(OGOTO); + p3 = p; + patch(p1, pc); + patch(p2, pc); + gbranch(OGOTO); + patch(p3, pc); + break; + } goto com; } if(l->op == OCONST) { diff --git a/src/cmd/8c/gc.h b/src/cmd/8c/gc.h index 32b80e995..4a57f5d3c 100644 --- a/src/cmd/8c/gc.h +++ b/src/cmd/8c/gc.h @@ -304,7 +304,8 @@ void gpseudo(int, Sym*, Node*); int swcmp(const void*, const void*); void doswit(Node*); void swit1(C1*, int, int32, Node*); -void cas(void); +void swit2(C1*, int, int32, Node*); +void newcase(void); void bitload(Node*, Node*, Node*, Node*, Node*); void bitstore(Node*, Node*, Node*, Node*, Node*); int32 outstring(char*, int32); diff --git a/src/cmd/8c/swt.c b/src/cmd/8c/swt.c index 006bfdfe2..f1ca4c25f 100644 --- a/src/cmd/8c/swt.c +++ b/src/cmd/8c/swt.c @@ -33,6 +33,26 @@ void swit1(C1 *q, int nc, int32 def, Node *n) { + Node nreg; + + if(typev[n->type->etype]) { + regsalloc(&nreg, n); + nreg.type = types[TVLONG]; + cgen(n, &nreg); + swit2(q, nc, def, &nreg); + return; + } + + regalloc(&nreg, n, Z); + nreg.type = types[TLONG]; + cgen(n, &nreg); + swit2(q, nc, def, &nreg); + regfree(&nreg); +} + +void +swit2(C1 *q, int nc, int32 def, Node *n) +{ C1 *r; int i; Prog *sp; @@ -58,12 +78,12 @@ swit1(C1 *q, int nc, int32 def, Node *n) gbranch(OGOTO); p->as = AJEQ; patch(p, r->label); - swit1(q, i, def, n); + swit2(q, i, def, n); if(debug['W']) print("case < %.8ux\n", r->val); patch(sp, pc); - swit1(r+1, nc-i-1, def, n); + swit2(r+1, nc-i-1, def, n); } void |