summaryrefslogtreecommitdiff
path: root/sys/src/cmd/vc
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-10-04 20:08:10 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-10-04 20:08:10 +0200
commitb556e87e08dd27f127e82963c5b2dc39f10dd389 (patch)
treed26990859f82cad02b009f4c371111810f818d50 /sys/src/cmd/vc
parent8e41723741b8d011ff0412efed33a20dec37dc98 (diff)
vc: handle 64 bit mixedmode asop
Diffstat (limited to 'sys/src/cmd/vc')
-rw-r--r--sys/src/cmd/vc/cgen.c70
-rw-r--r--sys/src/cmd/vc/txt.c3
2 files changed, 46 insertions, 27 deletions
diff --git a/sys/src/cmd/vc/cgen.c b/sys/src/cmd/vc/cgen.c
index faaa0ade8..c13228e08 100644
--- a/sys/src/cmd/vc/cgen.c
+++ b/sys/src/cmd/vc/cgen.c
@@ -1,5 +1,7 @@
#include "gc.h"
+static void genasop(int, Node*, Node*, Node*);
+
void
cgen(Node *n, Node *nn)
{
@@ -208,7 +210,7 @@ cgen(Node *n, Node *nn)
nod2 = *l;
regalloc(&nod, r, nn);
gopcode(OAS, &nod2, Z, &nod);
- gopcode(o, r, Z, &nod);
+ gopcode(o, l, Z, &nod);
gopcode(OAS, &nod, Z, &nod2);
regfree(&nod);
@@ -216,6 +218,8 @@ cgen(Node *n, Node *nn)
regfree(&nod2);
break;
}
+ genasop(o, l, r, nn);
+ break;
case OASLMUL:
case OASLDIV:
@@ -225,32 +229,7 @@ cgen(Node *n, Node *nn)
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:
@@ -521,6 +500,43 @@ cgen(Node *n, Node *nn)
cursafe = curs;
}
+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/vc/txt.c b/sys/src/cmd/vc/txt.c
index 3ff08b93a..d86a69697 100644
--- a/sys/src/cmd/vc/txt.c
+++ b/sys/src/cmd/vc/txt.c
@@ -557,6 +557,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) {
d = f->fconst;