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 v, nr; 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 OASMUL: 99 case OASLMUL: 100 xcom(l); 101 xcom(r); 102 v = vlog(r); 103 if(v >= 0) { 104 n->op = OASASHL; 105 r->vconst = v; 106 r->type = types[TINT]; 107 } 108 break; 109 110 case OMUL: 111 case OLMUL: 112 xcom(l); 113 xcom(r); 114 v = vlog(r); 115 if(v >= 0) { 116 n->op = OASHL; 117 r->vconst = v; 118 r->type = types[TINT]; 119 } 120 v = vlog(l); 121 if(v >= 0) { 122 n->op = OASHL; 123 n->left = r; 124 n->right = l; 125 r = l; 126 l = n->left; 127 r->vconst = v; 128 r->type = types[TINT]; 129 simplifyshift(n); 130 } 131 break; 132 133 case OASLDIV: 134 xcom(l); 135 xcom(r); 136 v = vlog(r); 137 if(v >= 0) { 138 n->op = OASLSHR; 139 r->vconst = v; 140 r->type = types[TINT]; 141 } 142 break; 143 144 case OLDIV: 145 xcom(l); 146 xcom(r); 147 v = vlog(r); 148 if(v >= 0) { 149 n->op = OLSHR; 150 r->vconst = v; 151 r->type = types[TINT]; 152 simplifyshift(n); 153 } 154 break; 155 156 case OASLMOD: 157 xcom(l); 158 xcom(r); 159 v = vlog(r); 160 if(v >= 0) { 161 n->op = OASAND; 162 r->vconst--; 163 } 164 break; 165 166 case OLMOD: 167 xcom(l); 168 xcom(r); 169 v = vlog(r); 170 if(v >= 0) { 171 n->op = OAND; 172 r->vconst--; 173 } 174 break; 175 176 case OLSHR: 177 case OASHL: 178 case OASHR: 179 xcom(l); 180 xcom(r); 181 simplifyshift(n); 182 break; 183 184 default: 185 if(l != Z) 186 xcom(l); 187 if(r != Z) 188 xcom(r); 189 break; 190 } 191 if(n->addable >= 10) 192 return; 193 if(l != Z) 194 n->complex = l->complex; 195 if(r != Z) { 196 nr = 1; 197 if(r->type != T && typev[r->type->etype] || n->type != T && typev[n->type->etype]) { 198 nr = 2; 199 if(n->op == OMUL || n->op == OLMUL) 200 nr += 3; 201 } 202 if(r->complex == n->complex) 203 n->complex = r->complex+nr; 204 else 205 if(r->complex > n->complex) 206 n->complex = r->complex; 207 } 208 if(n->complex == 0){ 209 n->complex++; 210 if(n->type != T && typev[n->type->etype]) 211 n->complex++; 212 } 213 214 if(com64(n)) 215 return; 216 217 switch(n->op) { 218 219 case OFUNC: 220 n->complex = FNX; 221 break; 222 223 case OEQ: 224 case ONE: 225 case OLE: 226 case OLT: 227 case OGE: 228 case OGT: 229 case OHI: 230 case OHS: 231 case OLO: 232 case OLS: 233 /* 234 * immediate operators, make const on right 235 */ 236 if(l->op == OCONST) { 237 n->left = r; 238 n->right = l; 239 n->op = invrel[relindex(n->op)]; 240 } 241 break; 242 243 case OADD: 244 case OXOR: 245 case OAND: 246 case OOR: 247 /* 248 * immediate operators, make const on right 249 */ 250 if(l->op == OCONST) { 251 n->left = r; 252 n->right = l; 253 } 254 break; 255 } 256 } 257 258