--- /n/sources/plan9/sys/src/cmd/cc/com64.c Fri Jul 29 19:49:19 2011 +++ /sys/src/cmd/cc/com64.c Thu Feb 18 00:00:00 2016 @@ -63,6 +63,11 @@ Node* nodvmm; Node* nodmmv; +Node* nodaddd; +Node* nodsubd; +Node* nodmuld; +Node* noddivd; + Node* nodvasop; char etconv[NTYPE]; /* for _vasop */ @@ -160,6 +165,11 @@ nodvmm = fvn("_vmm", TVLONG); nodmmv = fvn("_mmv", TVLONG); + nodaddd = fvn("_vasaddd", TVLONG); + nodsubd = fvn("_vassubd", TVLONG); + nodmuld = fvn("_vasmuld", TVLONG); + noddivd = fvn("_vasdivd", TVLONG); + nodvasop = fvn("_vasop", TVLONG); for(p = initetconv; p->code >= 0; p++) @@ -524,30 +534,54 @@ return 1; setasop: - if(l->op == OFUNC) { + while(l->op == OFUNC) l = l->right; - goto setasop; - } - t = new(OCONST, 0, 0); - t->vconst = etconv[l->type->etype]; - t->type = types[TLONG]; - t->addable = 20; - r = new(OLIST, t, r); - - t = new(OADDR, a, 0); - t->type = typ(TIND, a->type); - r = new(OLIST, t, r); - - t = new(OADDR, l, 0); - t->type = typ(TIND, l->type); - t->complex = l->complex; - r = new(OLIST, t, r); + if(mixedasop(n->left->type, n->right->type)) { + if(n->right->type->etype != TDOUBLE) { + r = new(OCAST, r, 0); + r->type = types[TDOUBLE]; + } - n->left = nodvasop; - n->right = r; - n->complex = FNX; - n->op = OFUNC; + t = new(OADDR, l, 0); + t->type = typ(TIND, l->type); + t->complex = l->complex; + r = new(OLIST, t, r); + + switch(n->op) { + case OASADD: a = nodaddd; break; + case OASSUB: a = nodsubd; break; + case OASMUL: a = nodmuld; break; + case OASDIV: a = noddivd; break; + default: diag(n, "bad vasop %O", n->op); a = nodaddd; break; + } + + n->left = a; + n->right = r; + n->complex = FNX; + n->op = OFUNC; + + } else { + t = new(OCONST, 0, 0); + t->vconst = etconv[l->type->etype]; + t->type = types[TLONG]; + t->addable = 20; + r = new(OLIST, t, r); + + t = new(OADDR, a, 0); + t->type = typ(TIND, a->type); + r = new(OLIST, t, r); + + t = new(OADDR, l, 0); + t->type = typ(TIND, l->type); + t->complex = l->complex; + r = new(OLIST, t, r); + + n->left = nodvasop; + n->right = r; + n->complex = FNX; + n->op = OFUNC; + } return 1; }