LEFT | RIGHT |
1 // Inferno utils/5c/reg.c | 1 // Inferno utils/5c/reg.c |
2 // http://code.google.com/p/inferno-os/source/browse/utils/5g/reg.c | 2 // http://code.google.com/p/inferno-os/source/browse/utils/5g/reg.c |
3 // | 3 // |
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. | 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. |
5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) |
6 // Portions Copyright © 1997-1999 Vita Nuova Limited | 6 // Portions Copyright © 1997-1999 Vita Nuova Limited |
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) | 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) |
8 // Portions Copyright © 2004,2006 Bruce Ellis | 8 // Portions Copyright © 2004,2006 Bruce Ellis |
9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) |
10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others | 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 int i, z, nr; | 136 int i, z, nr; |
137 uint32 vreg; | 137 uint32 vreg; |
138 Bits bit; | 138 Bits bit; |
139 | 139 |
140 if(first == 0) { | 140 if(first == 0) { |
141 fmtinstall('Q', Qconv); | 141 fmtinstall('Q', Qconv); |
142 } | 142 } |
143 first++; | 143 first++; |
144 | 144 |
145 if(debug['K']) { | 145 if(debug['K']) { |
146 » » if(first != 4) | 146 » » if(first != 1) |
147 return; | 147 return; |
148 // debug['R'] = 2; | 148 // debug['R'] = 2; |
149 // debug['P'] = 2; | 149 // debug['P'] = 2; |
150 print("optimizing %S\n", curfn->nname->sym); | 150 print("optimizing %S\n", curfn->nname->sym); |
151 } | 151 } |
152 | 152 |
153 // count instructions | 153 // count instructions |
154 nr = 0; | 154 nr = 0; |
155 for(p=firstp; p!=P; p=p->link) | 155 for(p=firstp; p!=P; p=p->link) |
156 nr++; | 156 nr++; |
(...skipping 27 matching lines...) Expand all Loading... |
184 * find use and set of variables | 184 * find use and set of variables |
185 */ | 185 */ |
186 nr = 0; | 186 nr = 0; |
187 for(p=firstp; p != P; p = p->link) { | 187 for(p=firstp; p != P; p = p->link) { |
188 switch(p->as) { | 188 switch(p->as) { |
189 case ADATA: | 189 case ADATA: |
190 case AGLOBL: | 190 case AGLOBL: |
191 case ANAME: | 191 case ANAME: |
192 case ASIGNAME: | 192 case ASIGNAME: |
193 continue; | 193 continue; |
194 | |
195 case AMOVW: | |
196 // mark instructions that set SP | |
197 if(p->to.type == D_REG) { | |
198 switch(p->to.reg) { | |
199 case REGSP: | |
200 case REGLINK: | |
201 case REGPC: | |
202 r->nomove = 1; | |
203 break; | |
204 } | |
205 } | |
206 if(p->scond != C_SCOND_NONE) | |
207 r->nomove = 1; | |
208 break; | |
209 } | 194 } |
210 r = rega(); | 195 r = rega(); |
211 nr++; | 196 nr++; |
212 if(firstr == R) { | 197 if(firstr == R) { |
213 firstr = r; | 198 firstr = r; |
214 lastr = r; | 199 lastr = r; |
215 } else { | 200 } else { |
216 lastr->link = r; | 201 lastr->link = r; |
217 r->p1 = lastr; | 202 r->p1 = lastr; |
218 lastr->s1 = r; | 203 lastr->s1 = r; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 continue; | 301 continue; |
317 } | 302 } |
318 r->s2 = r1; | 303 r->s2 = r1; |
319 r->p2link = r1->p2; | 304 r->p2link = r1->p2; |
320 r1->p2 = r; | 305 r1->p2 = r; |
321 } | 306 } |
322 } | 307 } |
323 if(debug['R']) { | 308 if(debug['R']) { |
324 p = firstr->prog; | 309 p = firstr->prog; |
325 print("\n%L %D\n", p->lineno, &p->from); | 310 print("\n%L %D\n", p->lineno, &p->from); |
| 311 print(" addr = %Q\n", addrs); |
326 } | 312 } |
327 | 313 |
328 /* | 314 /* |
329 * pass 2.5 | 315 * pass 2.5 |
330 * find looping structure | 316 * find looping structure |
331 */ | 317 */ |
332 for(r = firstr; r != R; r = r->link) | 318 for(r = firstr; r != R; r = r->link) |
333 r->active = 0; | 319 r->active = 0; |
334 change = 0; | 320 change = 0; |
335 loopit(firstr, nr); | 321 loopit(firstr, nr); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 | 365 |
380 if(debug['R'] > 1) { | 366 if(debug['R'] > 1) { |
381 print("\nprop structure:\n"); | 367 print("\nprop structure:\n"); |
382 for(r = firstr; r != R; r = r->link) { | 368 for(r = firstr; r != R; r = r->link) { |
383 print("%d:%P", r->loop, r->prog); | 369 print("%d:%P", r->loop, r->prog); |
384 for(z=0; z<BITS; z++) { | 370 for(z=0; z<BITS; z++) { |
385 bit.b[z] = r->set.b[z] | | 371 bit.b[z] = r->set.b[z] | |
386 r->refahead.b[z] | r->calahead.b[z] | | 372 r->refahead.b[z] | r->calahead.b[z] | |
387 r->refbehind.b[z] | r->calbehind.b[z] | | 373 r->refbehind.b[z] | r->calbehind.b[z] | |
388 r->use1.b[z] | r->use2.b[z]; | 374 r->use1.b[z] | r->use2.b[z]; |
| 375 bit.b[z] &= ~addrs.b[z]; |
389 } | 376 } |
390 | 377 |
391 if(bany(&bit)) { | 378 if(bany(&bit)) { |
392 print("\t"); | 379 print("\t"); |
393 if(bany(&r->use1)) | 380 if(bany(&r->use1)) |
394 print(" u1=%Q", r->use1); | 381 print(" u1=%Q", r->use1); |
395 if(bany(&r->use2)) | 382 if(bany(&r->use2)) |
396 print(" u2=%Q", r->use2); | 383 print(" u2=%Q", r->use2); |
397 if(bany(&r->set)) | 384 if(bany(&r->set)) |
398 print(" st=%Q", r->set); | 385 print(" st=%Q", r->set); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 * peep-hole on basic block | 491 * peep-hole on basic block |
505 */ | 492 */ |
506 if(!debug['R'] || debug['P']) { | 493 if(!debug['R'] || debug['P']) { |
507 // peep(); | 494 // peep(); |
508 } | 495 } |
509 | 496 |
510 /* | 497 /* |
511 * last pass | 498 * last pass |
512 * eliminate nops | 499 * eliminate nops |
513 * free aux structures | 500 * free aux structures |
| 501 * adjust the stack pointer |
| 502 * MOVW.W R1,-12(R13) <<- start |
| 503 * MOVW R0,R1 |
| 504 * MOVW R1,8(R13) |
| 505 * MOVW $0,R1 |
| 506 * MOVW R1,4(R13) |
| 507 * BL ,runtime.newproc+0(SB) |
| 508 * MOVW &ft+-32(SP),R7 <<- adjust |
| 509 * MOVW &j+-40(SP),R6 <<- adjust |
| 510 * MOVW autotmp_0003+-24(SP),R5 <<- adjust |
| 511 * MOVW $12(R13),R13 <<- finish |
514 */ | 512 */ |
| 513 vreg = 0; |
515 for(p = firstp; p != P; p = p->link) { | 514 for(p = firstp; p != P; p = p->link) { |
516 while(p->link != P && p->link->as == ANOP) | 515 while(p->link != P && p->link->as == ANOP) |
517 p->link = p->link->link; | 516 p->link = p->link->link; |
518 if(p->to.type == D_BRANCH) | 517 if(p->to.type == D_BRANCH) |
519 while(p->to.branch != P && p->to.branch->as == ANOP) | 518 while(p->to.branch != P && p->to.branch->as == ANOP) |
520 p->to.branch = p->to.branch->link; | 519 p->to.branch = p->to.branch->link; |
| 520 if(p->as == AMOVW && p->to.reg == 13) { |
| 521 if(p->scond & C_WBIT) { |
| 522 vreg = -p->to.offset; // in adjust reg
ion |
| 523 // print("%P adjusting %d\n", p, vreg); |
| 524 continue; |
| 525 } |
| 526 if(p->from.type == D_CONST && p->to.type == D_REG) { |
| 527 if(p->from.offset != vreg) |
| 528 print("in and out different\n"); |
| 529 // print("%P finish %d\n", p, vreg); |
| 530 vreg = 0; // done adjust region |
| 531 continue; |
| 532 } |
| 533 |
| 534 // print("%P %d %d from type\n", p, p->from.type, D_CONST); |
| 535 // print("%P %d %d to type\n\n", p, p->to.type, D_REG); |
| 536 } |
| 537 |
| 538 if(p->as == AMOVW && vreg != 0) { |
| 539 if(p->from.sym != S) |
| 540 if(p->from.name == D_AUTO || p->from.name == D_PARAM) { |
| 541 p->from.offset += vreg; |
| 542 // print("%P adjusting from %d %d\n", p, vreg, p->f
rom.type); |
| 543 } |
| 544 if(p->to.sym != S) |
| 545 if(p->to.name == D_AUTO || p->to.name == D_PARAM) { |
| 546 p->to.offset += vreg; |
| 547 // print("%P adjusting to %d %d\n", p, vreg, p->fro
m.type); |
| 548 } |
| 549 } |
521 } | 550 } |
522 if(r1 != R) { | 551 if(r1 != R) { |
523 r1->link = freer; | 552 r1->link = freer; |
524 freer = firstr; | 553 freer = firstr; |
525 } | 554 } |
| 555 |
526 } | 556 } |
527 | 557 |
528 void | 558 void |
529 addsplits(void) | 559 addsplits(void) |
530 { | 560 { |
531 Reg *r, *r1; | 561 Reg *r, *r1; |
532 int z, i; | 562 int z, i; |
533 Bits bit; | 563 Bits bit; |
534 | 564 |
535 for(r = firstr; r != R; r = r->link) { | 565 for(r = firstr; r != R; r = r->link) { |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 r1 = r->p1; | 1230 r1 = r->p1; |
1201 if(r1 == R) | 1231 if(r1 == R) |
1202 break; | 1232 break; |
1203 if(!(r1->refahead.b[z] & bb)) | 1233 if(!(r1->refahead.b[z] & bb)) |
1204 break; | 1234 break; |
1205 if(r1->act.b[z] & bb) | 1235 if(r1->act.b[z] & bb) |
1206 break; | 1236 break; |
1207 r = r1; | 1237 r = r1; |
1208 } | 1238 } |
1209 | 1239 |
1210 // horrible hack to prevent loading a | |
1211 // variable after a call (to defer) but | |
1212 // before popping the SP. | |
1213 if(r->prog->as == ABL && r->nomove) | |
1214 r = r->p1; | |
1215 | |
1216 if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) | 1240 if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) |
1217 addmove(r, bn, rn, 0); | 1241 addmove(r, bn, rn, 0); |
1218 | 1242 |
1219 for(;;) { | 1243 for(;;) { |
1220 r->act.b[z] |= bb; | 1244 r->act.b[z] |= bb; |
1221 p = r->prog; | 1245 p = r->prog; |
1222 | 1246 |
1223 if(r->use1.b[z] & bb) { | 1247 if(r->use1.b[z] & bb) { |
1224 if(debug['R']) | 1248 if(debug['R']) |
1225 print("%P", p); | 1249 print("%P", p); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 } | 1368 } |
1345 | 1369 |
1346 s = p->to.sym; | 1370 s = p->to.sym; |
1347 if(s == S) | 1371 if(s == S) |
1348 return 0; | 1372 return 0; |
1349 for(i=0; symlist[i]!=S; i++) | 1373 for(i=0; symlist[i]!=S; i++) |
1350 if(s == symlist[i]) | 1374 if(s == symlist[i]) |
1351 return 1; | 1375 return 1; |
1352 return 0; | 1376 return 0; |
1353 } | 1377 } |
LEFT | RIGHT |