~ubuntu-branches/ubuntu/saucy/golang/saucy

« back to all changes in this revision

Viewing changes to src/cmd/8c/reg.c

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-07-08 05:52:37 UTC
  • mfrom: (29.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20130708055237-at01839e0hp8z3ni
Tags: 2:1.1-1ubuntu1
016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 
31
31
#include "gc.h"
32
32
 
 
33
static  void    fixjmp(Reg*);
 
34
 
33
35
Reg*
34
36
rega(void)
35
37
{
148
150
                        r->p1 = R;
149
151
                        r1->s1 = R;
150
152
                }
151
 
 
152
153
                bit = mkvar(r, &p->from);
153
154
                if(bany(&bit))
154
155
                switch(p->as) {
182
183
                case ACMPB:
183
184
                case ACMPL:
184
185
                case ACMPW:
 
186
                case APREFETCHT0:
 
187
                case APREFETCHT1:
 
188
                case APREFETCHT2:
 
189
                case APREFETCHNTA:
185
190
                        for(z=0; z<BITS; z++)
186
191
                                r->use2.b[z] |= bit.b[z];
187
192
                        break;
372
377
        }
373
378
 
374
379
        /*
 
380
         * pass 2.1
 
381
         * fix jumps
 
382
         */
 
383
        fixjmp(firstr);
 
384
 
 
385
        /*
375
386
         * pass 2.5
376
387
         * find looping structure
377
388
         */
543
554
        if(!debug['R'] || debug['P'])
544
555
                peep();
545
556
 
 
557
        if(debug['R'] && debug['v']) {
 
558
                print("after pass 7 (peep)\n");
 
559
                for(r=firstr; r; r=r->link)
 
560
                        print("%04d %P\n", r->pc, r->prog);
 
561
                print("\n");
 
562
        }
 
563
 
546
564
        /*
547
565
         * pass 8
548
566
         * recalculate pc
596
614
                while(p->link && p->link->as == ANOP)
597
615
                        p->link = p->link->link;
598
616
        }
 
617
 
 
618
        if(debug['R'] && debug['v']) {
 
619
                print("after pass 8 (fixup pc)\n");
 
620
                for(p1=firstr->prog; p1!=P; p1=p1->link)
 
621
                        print("%P\n", p1);
 
622
                print("\n");
 
623
        }
 
624
 
599
625
        if(r1 != R) {
600
626
                r1->link = freer;
601
627
                freer = firstr;
1285
1311
                return 0;
1286
1312
        return bitno(b) + D_AX;
1287
1313
}
 
1314
 
 
1315
/* what instruction does a JMP to p eventually land on? */
 
1316
static Reg*
 
1317
chasejmp(Reg *r, int *jmploop)
 
1318
{
 
1319
        int n;
 
1320
 
 
1321
        n = 0;
 
1322
        for(; r; r=r->s2) {
 
1323
                if(r->prog->as != AJMP || r->prog->to.type != D_BRANCH)
 
1324
                        break;
 
1325
                if(++n > 10) {
 
1326
                        *jmploop = 1;
 
1327
                        break;
 
1328
                }
 
1329
        }
 
1330
        return r;
 
1331
}
 
1332
 
 
1333
/* mark all code reachable from firstp as alive */
 
1334
static void
 
1335
mark(Reg *firstr)
 
1336
{
 
1337
        Reg *r;
 
1338
        Prog *p;
 
1339
 
 
1340
        for(r=firstr; r; r=r->link) {
 
1341
                if(r->active)
 
1342
                        break;
 
1343
                r->active = 1;
 
1344
                p = r->prog;
 
1345
                if(p->as != ACALL && p->to.type == D_BRANCH)
 
1346
                        mark(r->s2);
 
1347
                if(p->as == AJMP || p->as == ARET || p->as == AUNDEF)
 
1348
                        break;
 
1349
        }
 
1350
}
 
1351
 
 
1352
/*
 
1353
 * the code generator depends on being able to write out JMP
 
1354
 * instructions that it can jump to now but fill in later.
 
1355
 * the linker will resolve them nicely, but they make the code
 
1356
 * longer and more difficult to follow during debugging.
 
1357
 * remove them.
 
1358
 */
 
1359
static void
 
1360
fixjmp(Reg *firstr)
 
1361
{
 
1362
        int jmploop;
 
1363
        Reg *r;
 
1364
        Prog *p;
 
1365
 
 
1366
        if(debug['R'] && debug['v'])
 
1367
                print("\nfixjmp\n");
 
1368
 
 
1369
        // pass 1: resolve jump to AJMP, mark all code as dead.
 
1370
        jmploop = 0;
 
1371
        for(r=firstr; r; r=r->link) {
 
1372
                p = r->prog;
 
1373
                if(debug['R'] && debug['v'])
 
1374
                        print("%04d %P\n", r->pc, p);
 
1375
                if(p->as != ACALL && p->to.type == D_BRANCH && r->s2 && r->s2->prog->as == AJMP) {
 
1376
                        r->s2 = chasejmp(r->s2, &jmploop);
 
1377
                        p->to.offset = r->s2->pc;
 
1378
                        if(debug['R'] && debug['v'])
 
1379
                                print("->%P\n", p);
 
1380
                }
 
1381
                r->active = 0;
 
1382
        }
 
1383
        if(debug['R'] && debug['v'])
 
1384
                print("\n");
 
1385
 
 
1386
        // pass 2: mark all reachable code alive
 
1387
        mark(firstr);
 
1388
 
 
1389
        // pass 3: delete dead code (mostly JMPs).
 
1390
        for(r=firstr; r; r=r->link) {
 
1391
                if(!r->active) {
 
1392
                        p = r->prog;
 
1393
                        if(p->link == P && p->as == ARET && r->p1 && r->p1->prog->as != ARET) {
 
1394
                                // This is the final ARET, and the code so far doesn't have one.
 
1395
                                // Let it stay.
 
1396
                        } else {
 
1397
                                if(debug['R'] && debug['v'])
 
1398
                                        print("del %04d %P\n", r->pc, p);
 
1399
                                p->as = ANOP;
 
1400
                        }
 
1401
                }
 
1402
        }
 
1403
 
 
1404
        // pass 4: elide JMP to next instruction.
 
1405
        // only safe if there are no jumps to JMPs anymore.
 
1406
        if(!jmploop) {
 
1407
                for(r=firstr; r; r=r->link) {
 
1408
                        p = r->prog;
 
1409
                        if(p->as == AJMP && p->to.type == D_BRANCH && r->s2 == r->link) {
 
1410
                                if(debug['R'] && debug['v'])
 
1411
                                        print("del %04d %P\n", r->pc, p);
 
1412
                                p->as = ANOP;
 
1413
                        }
 
1414
                }
 
1415
        }
 
1416
 
 
1417
        // fix back pointers.
 
1418
        for(r=firstr; r; r=r->link) {
 
1419
                r->p2 = R;
 
1420
                r->p2link = R;
 
1421
        }
 
1422
        for(r=firstr; r; r=r->link) {
 
1423
                if(r->s2) {
 
1424
                        r->p2link = r->s2->p2;
 
1425
                        r->s2->p2 = r;
 
1426
                }
 
1427
        }
 
1428
 
 
1429
        if(debug['R'] && debug['v']) {
 
1430
                print("\n");
 
1431
                for(r=firstr; r; r=r->link)
 
1432
                        print("%04d %P\n", r->pc, r->prog);
 
1433
                print("\n");
 
1434
        }
 
1435
}
 
1436