gc/order.c rewrites OASOP nodes into ordinary assignments.
The back ends never see them anymore.
Change-Id: I268ac8bdc92dccd7123110a21f99ada3ceeb2baa
Reviewed-on: https://go-review.googlesource.com/3882
Reviewed-by: Austin Clements <austin@google.com>
arch.betypeinit = betypeinit;
arch.bgen = bgen;
arch.cgen = cgen;
- arch.cgen_asop = cgen_asop;
arch.cgen_call = cgen_call;
arch.cgen_callinter = cgen_callinter;
arch.cgen_ret = cgen_ret;
void betypeinit(void);
void bgen(Node*, int, int, Prog*);
void cgen(Node*, Node*);
-void cgen_asop(Node*);
void cgen_call(Node*, int);
void cgen_callinter(Node*, Node*, int);
void cgen_ret(Node*);
}
}
-/*
- * generate += *= etc.
- */
-void
-cgen_asop(Node *n)
-{
- Node n1, n2, n3, n4;
- Node *nl, *nr;
- Prog *p1;
- Addr addr;
- int a, w;
-
- nl = n->left;
- nr = n->right;
-
- if(nr->ullman >= UINF && nl->ullman >= UINF) {
- tempname(&n1, nr->type);
- cgen(nr, &n1);
- n2 = *n;
- n2.right = &n1;
- cgen_asop(&n2);
- goto ret;
- }
-
- if(!isint[nl->type->etype])
- goto hard;
- if(!isint[nr->type->etype])
- goto hard;
- if(is64(nl->type) || is64(nr->type))
- goto hard64;
-
- switch(n->etype) {
- case OADD:
- case OSUB:
- case OXOR:
- case OAND:
- case OOR:
- a = optoas(n->etype, nl->type);
- if(nl->addable) {
- if(smallintconst(nr))
- n3 = *nr;
- else {
- regalloc(&n3, nr->type, N);
- cgen(nr, &n3);
- }
- regalloc(&n2, nl->type, N);
- cgen(nl, &n2);
- gins(a, &n3, &n2);
- cgen(&n2, nl);
- regfree(&n2);
- if(n3.op != OLITERAL)
- regfree(&n3);
- goto ret;
- }
- if(nr->ullman < UINF)
- if(sudoaddable(a, nl, &addr, &w)) {
- w = optoas(OAS, nl->type);
- regalloc(&n2, nl->type, N);
- p1 = gins(w, N, &n2);
- p1->from = addr;
- regalloc(&n3, nr->type, N);
- cgen(nr, &n3);
- gins(a, &n3, &n2);
- p1 = gins(w, &n2, N);
- p1->to = addr;
- regfree(&n2);
- regfree(&n3);
- sudoclean();
- goto ret;
- }
- }
-
-hard:
- n2.op = 0;
- n1.op = 0;
- if(nr->op == OLITERAL) {
- // don't allocate a register for literals.
- } else if(nr->ullman >= nl->ullman || nl->addable) {
- regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
- nr = &n2;
- } else {
- tempname(&n2, nr->type);
- cgen(nr, &n2);
- nr = &n2;
- }
- if(!nl->addable) {
- igen(nl, &n1, N);
- nl = &n1;
- }
-
- n3 = *n;
- n3.left = nl;
- n3.right = nr;
- n3.op = n->etype;
-
- regalloc(&n4, nl->type, N);
- cgen(&n3, &n4);
- gmove(&n4, nl);
-
- if(n1.op)
- regfree(&n1);
- if(n2.op == OREGISTER)
- regfree(&n2);
- regfree(&n4);
- goto ret;
-
-hard64:
- if(nr->ullman > nl->ullman) {
- tempname(&n2, nr->type);
- cgen(nr, &n2);
- igen(nl, &n1, N);
- } else {
- igen(nl, &n1, N);
- tempname(&n2, nr->type);
- cgen(nr, &n2);
- }
-
- n3 = *n;
- n3.left = &n1;
- n3.right = &n2;
- n3.op = n->etype;
-
- cgen(&n3, &n1);
-
-ret:
- ;
-}
-
/*
* generate high multiply
* res = (nl * nr) >> wordsize
arch.betypeinit = betypeinit;
arch.bgen = bgen;
arch.cgen = cgen;
- arch.cgen_asop = cgen_asop;
arch.cgen_call = cgen_call;
arch.cgen_callinter = cgen_callinter;
arch.cgen_ret = cgen_ret;
void betypeinit(void);
void bgen(Node*, int, int, Prog*);
void cgen(Node*, Node*);
-void cgen_asop(Node*);
void cgen_call(Node*, int);
void cgen_callinter(Node*, Node*, int);
void cgen_ret(Node*);
}
}
-/*
- * generate += *= etc.
- */
-void
-cgen_asop(Node *n)
-{
- Node n1, n2, n3, n4;
- Node *nl, *nr;
- Prog *p1;
- Addr addr;
- int a;
-
- nl = n->left;
- nr = n->right;
-
- if(nr->ullman >= UINF && nl->ullman >= UINF) {
- tempname(&n1, nr->type);
- cgen(nr, &n1);
- n2 = *n;
- n2.right = &n1;
- cgen_asop(&n2);
- goto ret;
- }
-
- if(!isint[nl->type->etype])
- goto hard;
- if(!isint[nr->type->etype])
- goto hard;
-
- switch(n->etype) {
- case OADD:
- if(smallintconst(nr))
- if(mpgetfix(nr->val.u.xval) == 1) {
- a = optoas(OINC, nl->type);
- if(nl->addable) {
- gins(a, N, nl);
- goto ret;
- }
- if(sudoaddable(a, nl, &addr)) {
- p1 = gins(a, N, N);
- p1->to = addr;
- sudoclean();
- goto ret;
- }
- }
- break;
-
- case OSUB:
- if(smallintconst(nr))
- if(mpgetfix(nr->val.u.xval) == 1) {
- a = optoas(ODEC, nl->type);
- if(nl->addable) {
- gins(a, N, nl);
- goto ret;
- }
- if(sudoaddable(a, nl, &addr)) {
- p1 = gins(a, N, N);
- p1->to = addr;
- sudoclean();
- goto ret;
- }
- }
- break;
- }
-
- switch(n->etype) {
- case OADD:
- case OSUB:
- case OXOR:
- case OAND:
- case OOR:
- a = optoas(n->etype, nl->type);
- if(nl->addable) {
- if(smallintconst(nr)) {
- gins(a, nr, nl);
- goto ret;
- }
- regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
- gins(a, &n2, nl);
- regfree(&n2);
- goto ret;
- }
- if(nr->ullman < UINF)
- if(sudoaddable(a, nl, &addr)) {
- if(smallintconst(nr)) {
- p1 = gins(a, nr, N);
- p1->to = addr;
- sudoclean();
- goto ret;
- }
- regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
- p1 = gins(a, &n2, N);
- p1->to = addr;
- regfree(&n2);
- sudoclean();
- goto ret;
- }
- }
-
-hard:
- n2.op = 0;
- n1.op = 0;
- if(nr->op == OLITERAL) {
- // don't allocate a register for literals.
- } else if(nr->ullman >= nl->ullman || nl->addable) {
- regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
- nr = &n2;
- } else {
- tempname(&n2, nr->type);
- cgen(nr, &n2);
- nr = &n2;
- }
- if(!nl->addable) {
- igen(nl, &n1, N);
- nl = &n1;
- }
-
- n3 = *n;
- n3.left = nl;
- n3.right = nr;
- n3.op = n->etype;
-
- regalloc(&n4, nl->type, N);
- cgen(&n3, &n4);
- gmove(&n4, nl);
-
- if(n1.op)
- regfree(&n1);
- if(n2.op == OREGISTER)
- regfree(&n2);
- regfree(&n4);
-
-ret:
- ;
-}
-
/*
* generate division.
* generates one of:
arch.betypeinit = betypeinit;
arch.bgen = bgen;
arch.cgen = cgen;
- arch.cgen_asop = cgen_asop;
arch.cgen_call = cgen_call;
arch.cgen_callinter = cgen_callinter;
arch.cgen_ret = cgen_ret;
void betypeinit(void);
void bgen(Node*, int, int, Prog*);
void cgen(Node*, Node*);
-void cgen_asop(Node*);
void cgen_call(Node*, int);
void cgen_callinter(Node*, Node*, int);
void cgen_ret(Node*);
}
}
-/*
- * generate += *= etc.
- */
-void
-cgen_asop(Node *n)
-{
- Node n1, n2, n3, n4;
- Node *nl, *nr;
- Prog *p1;
- Addr addr;
- int a;
-
- nl = n->left;
- nr = n->right;
-
- if(nr->ullman >= UINF && nl->ullman >= UINF) {
- tempname(&n1, nr->type);
- cgen(nr, &n1);
- n2 = *n;
- n2.right = &n1;
- cgen_asop(&n2);
- goto ret;
- }
-
- if(!isint[nl->type->etype])
- goto hard;
- if(!isint[nr->type->etype])
- goto hard;
- if(is64(nl->type) || is64(nr->type))
- goto hard;
-
- switch(n->etype) {
- case OADD:
- if(smallintconst(nr))
- if(mpgetfix(nr->val.u.xval) == 1) {
- a = optoas(OINC, nl->type);
- if(nl->addable) {
- gins(a, N, nl);
- goto ret;
- }
- if(sudoaddable(a, nl, &addr)) {
- p1 = gins(a, N, N);
- p1->to = addr;
- sudoclean();
- goto ret;
- }
- }
- break;
-
- case OSUB:
- if(smallintconst(nr))
- if(mpgetfix(nr->val.u.xval) == 1) {
- a = optoas(ODEC, nl->type);
- if(nl->addable) {
- gins(a, N, nl);
- goto ret;
- }
- if(sudoaddable(a, nl, &addr)) {
- p1 = gins(a, N, N);
- p1->to = addr;
- sudoclean();
- goto ret;
- }
- }
- break;
- }
-
- switch(n->etype) {
- case OADD:
- case OSUB:
- case OXOR:
- case OAND:
- case OOR:
- a = optoas(n->etype, nl->type);
- if(nl->addable) {
- if(smallintconst(nr)) {
- gins(a, nr, nl);
- goto ret;
- }
- regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
- gins(a, &n2, nl);
- regfree(&n2);
- goto ret;
- }
- if(nr->ullman < UINF)
- if(sudoaddable(a, nl, &addr)) {
- if(smallintconst(nr)) {
- p1 = gins(a, nr, N);
- p1->to = addr;
- sudoclean();
- goto ret;
- }
- regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
- p1 = gins(a, &n2, N);
- p1->to = addr;
- regfree(&n2);
- sudoclean();
- goto ret;
- }
- }
-
-hard:
- n2.op = 0;
- n1.op = 0;
- if(nr->ullman >= nl->ullman || nl->addable) {
- mgen(nr, &n2, N);
- nr = &n2;
- } else {
- tempname(&n2, nr->type);
- cgen(nr, &n2);
- nr = &n2;
- }
- if(!nl->addable) {
- igen(nl, &n1, N);
- nl = &n1;
- }
-
- n3 = *n;
- n3.left = nl;
- n3.right = nr;
- n3.op = n->etype;
-
- mgen(&n3, &n4, N);
- gmove(&n4, nl);
-
- if(n1.op)
- regfree(&n1);
- mfree(&n2);
- mfree(&n4);
-
-ret:
- ;
-}
-
/*
* generate division.
* caller must set:
arch.betypeinit = betypeinit;
arch.bgen = bgen;
arch.cgen = cgen;
- arch.cgen_asop = cgen_asop;
arch.cgen_call = cgen_call;
arch.cgen_callinter = cgen_callinter;
arch.cgen_ret = cgen_ret;
void betypeinit(void);
void bgen(Node*, int, int, Prog*);
void cgen(Node*, Node*);
-void cgen_asop(Node*);
void cgen_call(Node*, int);
void cgen_callinter(Node*, Node*, int);
void cgen_ret(Node*);
}
}
-void
-cgen_asop(Node *n)
-{
- USED(n);
- fatal("cgen_asop"); // no longer used
-}
-
/*
* generate division.
* generates one of:
lab->breakpc = P;
break;
- case OASOP:
- arch.cgen_asop(n);
- break;
-
case ODCL:
cgen_dcl(n->left);
break;
void (*betypeinit)(void);
void (*bgen)(Node*, int, int, Prog*);
void (*cgen)(Node*, Node*);
- void (*cgen_asop)(Node*);
void (*cgen_call)(Node*, int);
void (*cgen_callinter)(Node*, Node*, int);
void (*cgen_ret)(Node*);