1 #include "gc.h" 2 3 void 4 noretval(int n) 5 { 6 7 if(n & 1) { 8 gins(ANOP, Z, Z); 9 p->to.type = D_REG; 10 p->to.reg = REGRET; 11 } 12 if(n & 2) { 13 gins(ANOP, Z, Z); 14 p->to.type = D_FREG; 15 p->to.reg = FREGRET; 16 } 17 } 18 19 /* 20 * calculate addressability as follows 21 * CONST ==> 20 $value 22 * NAME ==> 10 name 23 * REGISTER ==> 11 register 24 * INDREG ==> 12 *[(reg)+offset] 25 * &10 ==> 2 $name 26 * ADD(2, 20) ==> 2 $name+offset 27 * ADD(3, 20) ==> 3 $(reg)+offset 28 * &12 ==> 3 $(reg)+offset 29 * *11 ==> 11 ?? 30 * *2 ==> 10 name 31 * *3 ==> 12 *(reg)+offset 32 * calculate complexity (number of registers) 33 */ 34 void 35 xcom(Node *n) 36 { 37 Node *l, *r; 38 int t; 39 40 if(n == Z) 41 return; 42 l = n->left; 43 r = n->right; 44 n->addable = 0; 45 n->complex = 0; 46 switch(n->op) { 47 case OCONST: 48 n->addable = 20; 49 return; 50 51 case OREGISTER: 52 n->addable = 11; 53 return; 54 55 case OINDREG: 56 n->addable = 12; 57 return; 58 59 case ONAME: 60 n->addable = 10; 61 return; 62 63 case OADDR: 64 xcom(l); 65 if(l->addable == 10) 66 n->addable = 2; 67 if(l->addable == 12) 68 n->addable = 3; 69 break; 70 71 case OIND: 72 xcom(l); 73 if(l->addable == 11) 74 n->addable = 12; 75 if(l->addable == 3) 76 n->addable = 12; 77 if(l->addable == 2) 78 n->addable = 10; 79 break; 80 81 case OADD: 82 xcom(l); 83 xcom(r); 84 if(l->addable == 20) { 85 if(r->addable == 2) 86 n->addable = 2; 87 if(r->addable == 3) 88 n->addable = 3; 89 } 90 if(r->addable == 20) { 91 if(l->addable == 2) 92 n->addable = 2; 93 if(l->addable == 3) 94 n->addable = 3; 95 } 96 break; 97 98 case OASLMUL: 99 case OASMUL: 100 xcom(l); 101 xcom(r); 102 t = vlog(r); 103 if(t >= 0) { 104 n->op = OASASHL; 105 r->vconst = t; 106 r->type = types[TINT]; 107 } 108 break; 109 110 case OMUL: 111 case OLMUL: 112 xcom(l); 113 xcom(r); 114 t = vlog(l); 115 if(t >= 0) { 116 n->left = r; 117 n->right = l; 118 l = r; 119 r = n->right; 120 } 121 t = vlog(r); 122 if(t >= 0) { 123 n->op = OASHL; 124 r->vconst = t; 125 r->type = types[TINT]; 126 simplifyshift(n); 127 } 128 break; 129 130 case OASLDIV: 131 xcom(l); 132 xcom(r); 133 t = vlog(r); 134 if(t >= 0) { 135 n->op = OASLSHR; 136 r->vconst = t; 137 r->type = types[TINT]; 138 } 139 break; 140 141 case OLDIV: 142 xcom(l); 143 xcom(r); 144 t = vlog(r); 145 if(t >= 0) { 146 n->op = OLSHR; 147 r->vconst = t; 148 r->type = types[TINT]; 149 simplifyshift(n); 150 } 151 break; 152 153 case OASLMOD: 154 xcom(l); 155 xcom(r); 156 t = vlog(r); 157 if(t >= 0) { 158 n->op = OASAND; 159 r->vconst--; 160 } 161 break; 162 163 case OLMOD: 164 xcom(l); 165 xcom(r); 166 t = vlog(r); 167 if(t >= 0) { 168 n->op = OAND; 169 r->vconst--; 170 } 171 break; 172 173 case OLSHR: 174 case OASHL: 175 case OASHR: 176 xcom(l); 177 xcom(r); 178 simplifyshift(n); 179 break; 180 181 default: 182 if(l != Z) 183 xcom(l); 184 if(r != Z) 185 xcom(r); 186 break; 187 } 188 if(n->addable >= 10) 189 return; 190 191 if(l != Z) 192 n->complex = l->complex; 193 if(r != Z) { 194 if(r->complex == n->complex) 195 n->complex = r->complex+1; 196 else 197 if(r->complex > n->complex) 198 n->complex = r->complex; 199 } 200 if(n->complex == 0) 201 n->complex++; 202 203 if(com64(n)) 204 return; 205 206 switch(n->op) { 207 case OFUNC: 208 n->complex = FNX; 209 break; 210 211 case OADD: 212 case OXOR: 213 case OAND: 214 case OOR: 215 case OEQ: 216 case ONE: 217 /* 218 * immediate operators, make const on right 219 */ 220 if(l->op == OCONST) { 221 n->left = r; 222 n->right = l; 223 } 224 break; 225 } 226 } 227 228