diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-10-06 06:55:05 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-10-06 06:55:05 +0200 |
commit | 4a916ba86e700d5e99311b45a81dc7be8a50b843 (patch) | |
tree | 94253321c7c34b3e4983229efae87b4fdbcfeda8 /sys/src/cmd | |
parent | fe3430ea998a3a494fa22ed574f97834cff38f7f (diff) |
kc: import various changes from charles forsyth
Diffstat (limited to 'sys/src/cmd')
-rw-r--r-- | sys/src/cmd/kc/cgen.c | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/sys/src/cmd/kc/cgen.c b/sys/src/cmd/kc/cgen.c index a6b5771cb..aa3c2ebff 100644 --- a/sys/src/cmd/kc/cgen.c +++ b/sys/src/cmd/kc/cgen.c @@ -1,5 +1,7 @@ #include "gc.h" +static void genasop(int, Node*, Node*, Node*); + void cgen(Node *n, Node *nn) { @@ -217,6 +219,8 @@ cgen(Node *n, Node *nn) regfree(&nod2); break; } + genasop(o, l, r, nn); + break; case OASLMUL: case OASLDIV: @@ -226,29 +230,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(&nod, n, nn); - cgen(r, &nod); - } else { - regalloc(&nod, n, nn); - cgen(r, &nod); - if(l->addable < INDEXED) - reglcgen(&nod2, l, Z); - else - nod2 = *l; - } - regalloc(&nod1, n, Z); - gopcode(OAS, &nod2, Z, &nod1); - gopcode(o, &nod, &nod1, &nod); - gopcode(OAS, &nod, Z, &nod2); - regfree(&nod); - regfree(&nod1); - if(l->addable < INDEXED) - regfree(&nod2); + genasop(o, l, r, nn); break; asbitop: @@ -517,6 +499,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(&nod2, nn); + regfree(&nod); + regfree(&nod1); + if(hardleft) + regfree(&nod2); +} + void reglcgen(Node *t, Node *n, Node *nn) { @@ -835,12 +854,12 @@ sugen(Node *n, Node *nn, long w) case OSTRUCT: /* - * rewrite so lhs has no fn call + * rewrite so lhs has no side effects */ - if(nn != Z && nn->complex >= FNX) { + if(nn != Z && side(nn)) { nod1 = *n; nod1.type = typ(TIND, n->type); - regret(&nod2, &nod1); + regalloc(&nod2, &nod1, Z); lcgen(nn, &nod2); regsalloc(&nod0, &nod1); gopcode(OAS, &nod2, Z, &nod0); |