123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- #include "gc.h"
- void
- noretval(int n)
- {
- if(n & 1) {
- gins(ANOP, Z, Z);
- p->to.type = D_REG;
- p->to.reg = REGRET;
- }
- if(n & 2) {
- gins(ANOP, Z, Z);
- p->to.type = D_FREG;
- p->to.reg = FREGRET;
- }
- }
- /*
- * calculate addressability as follows
- * CONST ==> 20 $value
- * NAME ==> 10 name
- * REGISTER ==> 11 register
- * INDREG ==> 12 *[(reg)+offset]
- * &10 ==> 2 $name
- * ADD(2, 20) ==> 2 $name+offset
- * ADD(3, 20) ==> 3 $(reg)+offset
- * &12 ==> 3 $(reg)+offset
- * *11 ==> 11 ??
- * *2 ==> 10 name
- * *3 ==> 12 *(reg)+offset
- * calculate complexity (number of registers)
- */
- void
- xcom(Node *n)
- {
- Node *l, *r;
- int t;
- if(n == Z)
- return;
- l = n->left;
- r = n->right;
- n->addable = 0;
- n->complex = 0;
- switch(n->op) {
- case OCONST:
- n->addable = 20;
- return;
- case OREGISTER:
- n->addable = 11;
- return;
- case OINDREG:
- n->addable = 12;
- return;
- case ONAME:
- n->addable = 10;
- return;
- case OADDR:
- xcom(l);
- if(l->addable == 10)
- n->addable = 2;
- if(l->addable == 12)
- n->addable = 3;
- break;
- case OIND:
- xcom(l);
- if(l->addable == 11)
- n->addable = 12;
- if(l->addable == 3)
- n->addable = 12;
- if(l->addable == 2)
- n->addable = 10;
- break;
- case OADD:
- xcom(l);
- xcom(r);
- if(l->addable == 20) {
- if(r->addable == 2)
- n->addable = 2;
- if(r->addable == 3)
- n->addable = 3;
- }
- if(r->addable == 20) {
- if(l->addable == 2)
- n->addable = 2;
- if(l->addable == 3)
- n->addable = 3;
- }
- break;
- case OASLMUL:
- case OASMUL:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASASHL;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
- case OMUL:
- case OLMUL:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASHL;
- r->vconst = t;
- r->type = types[TINT];
- }
- t = vlog(l);
- if(t >= 0) {
- n->op = OASHL;
- n->left = r;
- n->right = l;
- r = l;
- l = n->left;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
- case OASLDIV:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASLSHR;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
- case OLDIV:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OLSHR;
- r->vconst = t;
- r->type = types[TINT];
- }
- break;
- case OASLMOD:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OASAND;
- r->vconst--;
- }
- break;
- case OLMOD:
- xcom(l);
- xcom(r);
- t = vlog(r);
- if(t >= 0) {
- n->op = OAND;
- r->vconst--;
- }
- break;
- default:
- if(l != Z)
- xcom(l);
- if(r != Z)
- xcom(r);
- break;
- }
- if(n->addable >= 10)
- return;
- if(l != Z)
- n->complex = l->complex;
- if(r != Z) {
- if(r->complex == n->complex)
- n->complex = r->complex+1;
- else
- if(r->complex > n->complex)
- n->complex = r->complex;
- }
- if(n->complex == 0)
- n->complex++;
- switch(n->op) {
- case OFUNC:
- n->complex = FNX;
- break;
- case OEQ:
- case ONE:
- case OLE:
- case OLT:
- case OGE:
- case OGT:
- case OHI:
- case OHS:
- case OLO:
- case OLS:
- /*
- * immediate operators, make const on right
- */
- if(l->op == OCONST) {
- n->left = r;
- n->right = l;
- n->op = invrel[relindex(n->op)];
- }
- break;
- case OADD:
- case OXOR:
- case OAND:
- case OOR:
- /*
- * immediate operators, make const on right
- */
- if(l->op == OCONST) {
- n->left = r;
- n->right = l;
- }
- break;
- }
- }
|