diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-10-04 20:07:34 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-10-04 20:07:34 +0200 |
commit | 8e41723741b8d011ff0412efed33a20dec37dc98 (patch) | |
tree | 3e6f3dc50c5a8c6d8edea765be6485e4be4cf78f /sys/src/cmd/5c | |
parent | e6d64bab9dc7c71c80e82b7c41555a413f502399 (diff) |
5c: handle 64 bit mixedmode asop
Diffstat (limited to 'sys/src/cmd/5c')
-rw-r--r-- | sys/src/cmd/5c/cgen.c | 72 | ||||
-rw-r--r-- | sys/src/cmd/5c/txt.c | 3 |
2 files changed, 47 insertions, 28 deletions
diff --git a/sys/src/cmd/5c/cgen.c b/sys/src/cmd/5c/cgen.c index 18971103b..0c0fa4c9b 100644 --- a/sys/src/cmd/5c/cgen.c +++ b/sys/src/cmd/5c/cgen.c @@ -1,5 +1,7 @@ #include "gc.h" +static void genasop(int, Node*, Node*, Node*); + void cgen(Node *n, Node *nn) { @@ -54,7 +56,7 @@ cgenrel(Node *n, Node *nn, int inrel) cgen(r, &nod); regsalloc(&nod1, r); - gopcode(OAS, &nod, Z, &nod1); + gmove(&nod, &nod1); regfree(&nod); nod = *n; @@ -244,7 +246,7 @@ cgenrel(Node *n, Node *nn, int inrel) reglcgen(&nod2, l, Z); else nod2 = *l; - regalloc(&nod, r, nn); + regalloc(&nod, l, nn); gopcode(OAS, &nod2, Z, &nod); gopcode(o, r, Z, &nod); gopcode(OAS, &nod, Z, &nod2); @@ -254,6 +256,8 @@ cgenrel(Node *n, Node *nn, int inrel) regfree(&nod2); break; } + genasop(o, l, r, nn); + break; case OASLMUL: case OASLDIV: @@ -263,32 +267,7 @@ cgenrel(Node *n, Node *nn, int inrel) case OASMOD: if(l->op == OBIT) goto asbitop; - if(l->complex >= r->complex) { - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - regalloc(&nod1, r, Z); - cgen(r, &nod1); - } else { - regalloc(&nod1, r, Z); - cgen(r, &nod1); - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - } - - regalloc(&nod, n, nn); - gmove(&nod2, &nod); - gopcode(o, &nod1, Z, &nod); - gmove(&nod, &nod2); - if(nn != Z) - gopcode(OAS, &nod, Z, nn); - regfree(&nod); - regfree(&nod1); - if(l->addable < INDEXED) - regfree(&nod2); + genasop(o, l, r, nn); break; asbitop: @@ -564,6 +543,43 @@ cgenrel(Node *n, Node *nn, int inrel) return; } +static void +genasop(int o, Node *l, Node *r, Node *nn) +{ + Node nod, nod1, nod2; + int hardleft; + + hardleft = l->addable < INDEXED || l->complex >= FNX; + if(l->complex >= r->complex) { + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + regalloc(&nod1, r, Z); + cgen(r, &nod1); + } else { + regalloc(&nod1, r, Z); + cgen(r, &nod1); + if(hardleft) + reglcgen(&nod2, l, Z); + else + nod2 = *l; + } + if(nod1.type == nod2.type || !typefd[nod1.type->etype]) + regalloc(&nod, &nod2, nn); + else + regalloc(&nod, &nod1, Z); + gmove(&nod2, &nod); + gopcode(o, &nod1, Z, &nod); + gmove(&nod, &nod2); + if(nn != Z) + gmove(&nod, nn); + regfree(&nod); + regfree(&nod1); + if(hardleft) + regfree(&nod2); +} + void reglcgen(Node *t, Node *n, Node *nn) { diff --git a/sys/src/cmd/5c/txt.c b/sys/src/cmd/5c/txt.c index 574694cdd..52cf600f8 100644 --- a/sys/src/cmd/5c/txt.c +++ b/sys/src/cmd/5c/txt.c @@ -566,6 +566,9 @@ gmove(Node *f, Node *t) ft = f->type->etype; tt = t->type->etype; + if(debug['M']) + print("gop: %O %O[%s],%O[%s]\n", OAS, + f->op, tnames[ft], t->op, tnames[tt]); if(ft == TDOUBLE && f->op == OCONST) { } |