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 = REGRET; 10 } 11 if(n & 2) { 12 gins(ANOP, Z, Z); 13 p->to.type = FREGRET; 14 } 15 } 16 17 /* welcome to commute */ 18 static void 19 commute(Node *n) 20 { 21 Node *l, *r; 22 23 l = n->left; 24 r = n->right; 25 if(r->complex > l->complex) { 26 n->left = r; 27 n->right = l; 28 } 29 } 30 31 void 32 indexshift(Node *n) 33 { 34 int g; 35 36 if(!typechlpv[n->type->etype]) 37 return; 38 simplifyshift(n); 39 if(n->op == OASHL && n->right->op == OCONST){ 40 g = vconst(n->right); 41 if(g >= 0 && g <= 3) 42 n->addable = 7; 43 } 44 } 45 46 /* 47 * calculate addressability as follows 48 * NAME ==> 10/11 name+value(SB/SP) 49 * REGISTER ==> 12 register 50 * CONST ==> 20 $value 51 * *(20) ==> 21 value 52 * &(10) ==> 13 $name+value(SB) 53 * &(11) ==> 1 $name+value(SP) 54 * (13) + (20) ==> 13 fold constants 55 * (1) + (20) ==> 1 fold constants 56 * *(13) ==> 10 back to name 57 * *(1) ==> 11 back to name 58 * 59 * (20) * (X) ==> 7 multiplier in indexing 60 * (X,7) + (13,1) ==> 8 adder in indexing (addresses) 61 * (8) ==> &9(OINDEX) index, almost addressable 62 * 63 * calculate complexity (number of registers) 64 */ 65 void 66 xcom(Node *n) 67 { 68 Node *l, *r; 69 int g; 70 71 if(n == Z) 72 return; 73 l = n->left; 74 r = n->right; 75 n->complex = 0; 76 n->addable = 0; 77 switch(n->op) { 78 case OCONST: 79 n->addable = 20; 80 break; 81 82 case ONAME: 83 n->addable = 10; 84 if(n->class == CPARAM || n->class == CAUTO) 85 n->addable = 11; 86 break; 87 88 case OREGISTER: 89 n->addable = 12; 90 break; 91 92 case OINDREG: 93 n->addable = 12; 94 break; 95 96 case OADDR: 97 xcom(l); 98 if(l->addable == 10) 99 n->addable = 13; 100 else 101 if(l->addable == 11) 102 n->addable = 1; 103 break; 104 105 case OADD: 106 xcom(l); 107 xcom(r); 108 if(n->type->etype != TIND) 109 break; 110 111 switch(r->addable) { 112 case 20: 113 switch(l->addable) { 114 case 1: 115 case 13: 116 commadd: 117 l->type = n->type; 118 *n = *l; 119 l = new(0, Z, Z); 120 *l = *(n->left); 121 l->xoffset += r->vconst; 122 n->left = l; 123 r = n->right; 124 goto brk; 125 } 126 break; 127 128 case 1: 129 case 13: 130 case 10: 131 case 11: 132 /* l is the base, r is the index */ 133 if(l->addable != 20) 134 n->addable = 8; 135 break; 136 } 137 switch(l->addable) { 138 case 20: 139 switch(r->addable) { 140 case 13: 141 case 1: 142 r = n->left; 143 l = n->right; 144 n->left = l; 145 n->right = r; 146 goto commadd; 147 } 148 break; 149 150 case 13: 151 case 1: 152 case 10: 153 case 11: 154 /* r is the base, l is the index */ 155 if(r->addable != 20) 156 n->addable = 8; 157 break; 158 } 159 if(n->addable == 8 && !side(n)) { 160 indx(n); 161 l = new1(OINDEX, idx.basetree, idx.regtree); 162 l->scale = idx.scale; 163 l->addable = 9; 164 l->complex = l->right->complex; 165 l->type = l->left->type; 166 n->op = OADDR; 167 n->left = l; 168 n->right = Z; 169 n->addable = 8; 170 break; 171 } 172 break; 173 174 case OINDEX: 175 xcom(l); 176 xcom(r); 177 n->addable = 9; 178 break; 179 180 case OIND: 181 xcom(l); 182 if(l->op == OADDR) { 183 l = l->left; 184 l->type = n->type; 185 *n = *l; 186 return; 187 } 188 switch(l->addable) { 189 case 20: 190 n->addable = 21; 191 break; 192 case 1: 193 n->addable = 11; 194 break; 195 case 13: 196 n->addable = 10; 197 break; 198 } 199 break; 200 201 case OASHL: 202 xcom(l); 203 xcom(r); 204 indexshift(n); 205 break; 206 207 case OMUL: 208 case OLMUL: 209 xcom(l); 210 xcom(r); 211 g = vlog(l); 212 if(g >= 0) { 213 n->left = r; 214 n->right = l; 215 l = r; 216 r = n->right; 217 } 218 g = vlog(r); 219 if(g >= 0) { 220 n->op = OASHL; 221 r->vconst = g; 222 r->type = types[TINT]; 223 indexshift(n); 224 break; 225 } 226 commute(n); 227 break; 228 229 case OASLDIV: 230 xcom(l); 231 xcom(r); 232 g = vlog(r); 233 if(g >= 0) { 234 n->op = OASLSHR; 235 r->vconst = g; 236 r->type = types[TINT]; 237 } 238 break; 239 240 case OLDIV: 241 xcom(l); 242 xcom(r); 243 g = vlog(r); 244 if(g >= 0) { 245 n->op = OLSHR; 246 r->vconst = g; 247 r->type = types[TINT]; 248 indexshift(n); 249 break; 250 } 251 break; 252 253 case OASLMOD: 254 xcom(l); 255 xcom(r); 256 g = vlog(r); 257 if(g >= 0) { 258 n->op = OASAND; 259 r->vconst--; 260 } 261 break; 262 263 case OLMOD: 264 xcom(l); 265 xcom(r); 266 g = vlog(r); 267 if(g >= 0) { 268 n->op = OAND; 269 r->vconst--; 270 } 271 break; 272 273 case OASMUL: 274 case OASLMUL: 275 xcom(l); 276 xcom(r); 277 g = vlog(r); 278 if(g >= 0) { 279 n->op = OASASHL; 280 r->vconst = g; 281 } 282 break; 283 284 case OLSHR: 285 case OASHR: 286 xcom(l); 287 xcom(r); 288 indexshift(n); 289 break; 290 291 default: 292 if(l != Z) 293 xcom(l); 294 if(r != Z) 295 xcom(r); 296 break; 297 } 298 brk: 299 if(n->addable >= 10) 300 return; 301 if(l != Z) 302 n->complex = l->complex; 303 if(r != Z) { 304 if(r->complex == n->complex) 305 n->complex = r->complex+1; 306 else 307 if(r->complex > n->complex) 308 n->complex = r->complex; 309 } 310 if(n->complex == 0) 311 n->complex++; 312 313 switch(n->op) { 314 315 case OFUNC: 316 n->complex = FNX; 317 break; 318 319 case OCAST: 320 if(l->type->etype == TUVLONG && typefd[n->type->etype]) 321 n->complex += 2; 322 break; 323 324 case OLMOD: 325 case OMOD: 326 case OLMUL: 327 case OLDIV: 328 case OMUL: 329 case ODIV: 330 case OASLMUL: 331 case OASLDIV: 332 case OASLMOD: 333 case OASMUL: 334 case OASDIV: 335 case OASMOD: 336 if(r->complex >= l->complex) { 337 n->complex = l->complex + 3; 338 if(r->complex > n->complex) 339 n->complex = r->complex; 340 } else { 341 n->complex = r->complex + 3; 342 if(l->complex > n->complex) 343 n->complex = l->complex; 344 } 345 break; 346 347 case OLSHR: 348 case OASHL: 349 case OASHR: 350 case OASLSHR: 351 case OASASHL: 352 case OASASHR: 353 if(r->complex >= l->complex) { 354 n->complex = l->complex + 2; 355 if(r->complex > n->complex) 356 n->complex = r->complex; 357 } else { 358 n->complex = r->complex + 2; 359 if(l->complex > n->complex) 360 n->complex = l->complex; 361 } 362 break; 363 364 case OADD: 365 case OXOR: 366 case OAND: 367 case OOR: 368 /* 369 * immediate operators, make const on right 370 */ 371 if(l->op == OCONST) { 372 n->left = r; 373 n->right = l; 374 } 375 break; 376 377 case OEQ: 378 case ONE: 379 case OLE: 380 case OLT: 381 case OGE: 382 case OGT: 383 case OHI: 384 case OHS: 385 case OLO: 386 case OLS: 387 /* 388 * compare operators, make const on left 389 */ 390 if(r->op == OCONST) { 391 n->left = r; 392 n->right = l; 393 n->op = invrel[relindex(n->op)]; 394 } 395 break; 396 } 397 } 398 399 void 400 indx(Node *n) 401 { 402 Node *l, *r; 403 404 if(debug['x']) 405 prtree(n, "indx"); 406 407 l = n->left; 408 r = n->right; 409 if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) { 410 n->right = l; 411 n->left = r; 412 l = r; 413 r = n->right; 414 } 415 if(l->addable != 7) { 416 idx.regtree = l; 417 idx.scale = 1; 418 } else 419 if(l->right->addable == 20) { 420 idx.regtree = l->left; 421 idx.scale = 1 << l->right->vconst; 422 } else 423 if(l->left->addable == 20) { 424 idx.regtree = l->right; 425 idx.scale = 1 << l->left->vconst; 426 } else 427 diag(n, "bad index"); 428 429 idx.basetree = r; 430 if(debug['x']) { 431 print("scale = %d\n", idx.scale); 432 prtree(idx.regtree, "index"); 433 prtree(idx.basetree, "base"); 434 } 435 } 436