~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to .pc/010-fix_arm_ftbfs.patch/src/cmd/5g/reg.c

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-08-03 17:04:59 UTC
  • mfrom: (14.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20110803170459-wzd99m3567y80ila
Tags: 1:59-1
* Imported Upstream version 59
* Refresh patches to a new release
* Fix FTBFS on ARM (Closes: #634270)
* Update version.bash to work with Debian packaging and not hg
  repository

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Inferno utils/5c/reg.c
2
 
// http://code.google.com/p/inferno-os/source/browse/utils/5g/reg.c
3
 
//
4
 
//      Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
5
 
//      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6
 
//      Portions Copyright © 1997-1999 Vita Nuova Limited
7
 
//      Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8
 
//      Portions Copyright © 2004,2006 Bruce Ellis
9
 
//      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10
 
//      Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11
 
//      Portions Copyright © 2009 The Go Authors.  All rights reserved.
12
 
//
13
 
// Permission is hereby granted, free of charge, to any person obtaining a copy
14
 
// of this software and associated documentation files (the "Software"), to deal
15
 
// in the Software without restriction, including without limitation the rights
16
 
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 
// copies of the Software, and to permit persons to whom the Software is
18
 
// furnished to do so, subject to the following conditions:
19
 
//
20
 
// The above copyright notice and this permission notice shall be included in
21
 
// all copies or substantial portions of the Software.
22
 
//
23
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
26
 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
 
// THE SOFTWARE.
30
 
 
31
 
 
32
 
#include "gg.h"
33
 
#include "opt.h"
34
 
 
35
 
#define NREGVAR 24
36
 
#define REGBITS ((uint32)0xffffff)
37
 
#define P2R(p)  (Reg*)(p->reg)
38
 
 
39
 
        void    addsplits(void);
40
 
        int     noreturn(Prog *p);
41
 
static  int     first   = 0;
42
 
 
43
 
Reg*
44
 
rega(void)
45
 
{
46
 
        Reg *r;
47
 
 
48
 
        r = freer;
49
 
        if(r == R) {
50
 
                r = mal(sizeof(*r));
51
 
        } else
52
 
                freer = r->link;
53
 
 
54
 
        *r = zreg;
55
 
        return r;
56
 
}
57
 
 
58
 
int
59
 
rcmp(const void *a1, const void *a2)
60
 
{
61
 
        Rgn *p1, *p2;
62
 
        int c1, c2;
63
 
 
64
 
        p1 = (Rgn*)a1;
65
 
        p2 = (Rgn*)a2;
66
 
        c1 = p2->cost;
67
 
        c2 = p1->cost;
68
 
        if(c1 -= c2)
69
 
                return c1;
70
 
        return p2->varno - p1->varno;
71
 
}
72
 
 
73
 
static void
74
 
setoutvar(void)
75
 
{
76
 
        Type *t;
77
 
        Node *n;
78
 
        Addr a;
79
 
        Iter save;
80
 
        Bits bit;
81
 
        int z;
82
 
 
83
 
        t = structfirst(&save, getoutarg(curfn->type));
84
 
        while(t != T) {
85
 
                n = nodarg(t, 1);
86
 
                a = zprog.from;
87
 
                naddr(n, &a, 0);
88
 
                bit = mkvar(R, &a);
89
 
                for(z=0; z<BITS; z++)
90
 
                        ovar.b[z] |= bit.b[z];
91
 
                t = structnext(&save);
92
 
        }
93
 
//if(bany(b))
94
 
//print("ovars = %Q\n", &ovar);
95
 
}
96
 
 
97
 
void
98
 
excise(Reg *r)
99
 
{
100
 
        Prog *p;
101
 
 
102
 
        p = r->prog;
103
 
        p->as = ANOP;
104
 
        p->scond = zprog.scond;
105
 
        p->from = zprog.from;
106
 
        p->to = zprog.to;
107
 
        p->reg = zprog.reg;
108
 
}
109
 
 
110
 
static void
111
 
setaddrs(Bits bit)
112
 
{
113
 
        int i, n;
114
 
        Var *v;
115
 
        Sym *s;
116
 
 
117
 
        while(bany(&bit)) {
118
 
                // convert each bit to a variable
119
 
                i = bnum(bit);
120
 
                s = var[i].sym;
121
 
                n = var[i].name;
122
 
                bit.b[i/32] &= ~(1L<<(i%32));
123
 
 
124
 
                // disable all pieces of that variable
125
 
                for(i=0; i<nvar; i++) {
126
 
                        v = var+i;
127
 
                        if(v->sym == s && v->name == n)
128
 
                                v->addr = 2;
129
 
                }
130
 
        }
131
 
}
132
 
 
133
 
static char* regname[] = {
134
 
        ".R0",
135
 
        ".R1",
136
 
        ".R2",
137
 
        ".R3",
138
 
        ".R4",
139
 
        ".R5",
140
 
        ".R6",
141
 
        ".R7",
142
 
        ".R8",
143
 
        ".R9",
144
 
        ".R10",
145
 
        ".R11",
146
 
        ".R12",
147
 
        ".R13",
148
 
        ".R14",
149
 
        ".R15",
150
 
        ".F0",
151
 
        ".F1",
152
 
        ".F2",
153
 
        ".F3",
154
 
        ".F4",
155
 
        ".F5",
156
 
        ".F6",
157
 
        ".F7",
158
 
};
159
 
 
160
 
void
161
 
regopt(Prog *firstp)
162
 
{
163
 
        Reg *r, *r1;
164
 
        Prog *p;
165
 
        int i, z, nr;
166
 
        uint32 vreg;
167
 
        Bits bit;
168
 
        
169
 
        if(first == 0) {
170
 
                fmtinstall('Q', Qconv);
171
 
        }
172
 
 
173
 
        first++;
174
 
        if(debug['K']) {
175
 
                if(first != 13)
176
 
                        return;
177
 
//              debug['R'] = 2;
178
 
//              debug['P'] = 2;
179
 
                print("optimizing %S\n", curfn->nname->sym);
180
 
        }
181
 
 
182
 
        // count instructions
183
 
        nr = 0;
184
 
        for(p=firstp; p!=P; p=p->link)
185
 
                nr++;
186
 
 
187
 
        // if too big dont bother
188
 
        if(nr >= 10000) {
189
 
//              print("********** %S is too big (%d)\n", curfn->nname->sym, nr);
190
 
                return;
191
 
        }
192
 
 
193
 
        r1 = R;
194
 
        firstr = R;
195
 
        lastr = R;
196
 
 
197
 
        /*
198
 
         * control flow is more complicated in generated go code
199
 
         * than in generated c code.  define pseudo-variables for
200
 
         * registers, so we have complete register usage information.
201
 
         */
202
 
        nvar = NREGVAR;
203
 
        memset(var, 0, NREGVAR*sizeof var[0]);
204
 
        for(i=0; i<NREGVAR; i++)
205
 
                var[i].sym = lookup(regname[i]);
206
 
 
207
 
        regbits = RtoB(REGSP)|RtoB(REGLINK)|RtoB(REGPC);
208
 
        for(z=0; z<BITS; z++) {
209
 
                externs.b[z] = 0;
210
 
                params.b[z] = 0;
211
 
                consts.b[z] = 0;
212
 
                addrs.b[z] = 0;
213
 
                ovar.b[z] = 0;
214
 
        }
215
 
 
216
 
        // build list of return variables
217
 
        setoutvar();
218
 
 
219
 
        /*
220
 
         * pass 1
221
 
         * build aux data structure
222
 
         * allocate pcs
223
 
         * find use and set of variables
224
 
         */
225
 
        nr = 0;
226
 
        for(p=firstp; p != P; p = p->link) {
227
 
                switch(p->as) {
228
 
                case ADATA:
229
 
                case AGLOBL:
230
 
                case ANAME:
231
 
                case ASIGNAME:
232
 
                        continue;
233
 
                }
234
 
                r = rega();
235
 
                nr++;
236
 
                if(firstr == R) {
237
 
                        firstr = r;
238
 
                        lastr = r;
239
 
                } else {
240
 
                        lastr->link = r;
241
 
                        r->p1 = lastr;
242
 
                        lastr->s1 = r;
243
 
                        lastr = r;
244
 
                }
245
 
                r->prog = p;
246
 
                p->regp = r;
247
 
 
248
 
                r1 = r->p1;
249
 
                if(r1 != R) {
250
 
                        switch(r1->prog->as) {
251
 
                        case ARET:
252
 
                        case AB:
253
 
                        case ARFE:
254
 
                                r->p1 = R;
255
 
                                r1->s1 = R;
256
 
                        }
257
 
                }
258
 
 
259
 
                /*
260
 
                 * left side always read
261
 
                 */
262
 
                bit = mkvar(r, &p->from);
263
 
                for(z=0; z<BITS; z++)
264
 
                        r->use1.b[z] |= bit.b[z];
265
 
                
266
 
                /*
267
 
                 * middle always read when present
268
 
                 */
269
 
                if(p->reg != NREG) {
270
 
                        if(p->from.type != D_FREG)
271
 
                                r->use1.b[0] |= RtoB(p->reg);
272
 
                        else
273
 
                                r->use1.b[0] |= FtoB(p->reg);
274
 
                }
275
 
 
276
 
                /*
277
 
                 * right side depends on opcode
278
 
                 */
279
 
                bit = mkvar(r, &p->to);
280
 
                if(bany(&bit))
281
 
                switch(p->as) {
282
 
                default:
283
 
                        yyerror("reg: unknown op: %A", p->as);
284
 
                        break;
285
 
                
286
 
                /*
287
 
                 * right side read
288
 
                 */
289
 
                case ATST:
290
 
                case ATEQ:
291
 
                case ACMP:
292
 
                case ACMN:
293
 
                case ACMPD:
294
 
                case ACMPF:
295
 
                rightread:
296
 
                        for(z=0; z<BITS; z++)
297
 
                                r->use2.b[z] |= bit.b[z];
298
 
                        break;
299
 
                        
300
 
                /*
301
 
                 * right side read or read+write, depending on middle
302
 
                 *      ADD x, z => z += x
303
 
                 *      ADD x, y, z  => z = x + y
304
 
                 */
305
 
                case AADD:
306
 
                case AAND:
307
 
                case AEOR:
308
 
                case ASUB:
309
 
                case ARSB:
310
 
                case AADC:
311
 
                case ASBC:
312
 
                case ARSC:
313
 
                case AORR:
314
 
                case ABIC:
315
 
                case ASLL:
316
 
                case ASRL:
317
 
                case ASRA:
318
 
                case AMUL:
319
 
                case AMULU:
320
 
                case ADIV:
321
 
                case AMOD:
322
 
                case AMODU:
323
 
                case ADIVU:
324
 
                        if(p->reg != NREG)
325
 
                                goto rightread;
326
 
                        // fall through
327
 
 
328
 
                /*
329
 
                 * right side read+write
330
 
                 */
331
 
                case AADDF:
332
 
                case AADDD:
333
 
                case ASUBF:
334
 
                case ASUBD:
335
 
                case AMULF:
336
 
                case AMULD:
337
 
                case ADIVF:
338
 
                case ADIVD:
339
 
                case AMULAL:
340
 
                case AMULALU:
341
 
                        for(z=0; z<BITS; z++) {
342
 
                                r->use2.b[z] |= bit.b[z];
343
 
                                r->set.b[z] |= bit.b[z];
344
 
                        }
345
 
                        break;
346
 
 
347
 
                /*
348
 
                 * right side write
349
 
                 */
350
 
                case ANOP:
351
 
                case AMOVB:
352
 
                case AMOVBU:
353
 
                case AMOVD:
354
 
                case AMOVDF:
355
 
                case AMOVDW:
356
 
                case AMOVF:
357
 
                case AMOVFW:
358
 
                case AMOVH:
359
 
                case AMOVHU:
360
 
                case AMOVW:
361
 
                case AMOVWD:
362
 
                case AMOVWF:
363
 
                case AMVN:
364
 
                case AMULL:
365
 
                case AMULLU:
366
 
                        if((p->scond & C_SCOND) != C_SCOND_NONE)
367
 
                                for(z=0; z<BITS; z++)
368
 
                                        r->use2.b[z] |= bit.b[z];
369
 
                        for(z=0; z<BITS; z++)
370
 
                                r->set.b[z] |= bit.b[z];
371
 
                        break;
372
 
 
373
 
                /*
374
 
                 * funny
375
 
                 */
376
 
                case ABL:
377
 
                        setaddrs(bit);
378
 
                        break;
379
 
                }
380
 
 
381
 
                if(p->as == AMOVM) {
382
 
                        z = p->to.offset;
383
 
                        if(p->from.type == D_CONST)
384
 
                                z = p->from.offset;
385
 
                        for(i=0; z; i++) {
386
 
                                if(z&1)
387
 
                                        regbits |= RtoB(i);
388
 
                                z >>= 1;
389
 
                        }
390
 
                }
391
 
        }
392
 
        if(firstr == R)
393
 
                return;
394
 
 
395
 
        for(i=0; i<nvar; i++) {
396
 
                Var *v = var+i;
397
 
                if(v->addr) {
398
 
                        bit = blsh(i);
399
 
                        for(z=0; z<BITS; z++)
400
 
                                addrs.b[z] |= bit.b[z];
401
 
                }
402
 
 
403
 
//              print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n",
404
 
//                      i, v->addr, v->etype, v->width, v->sym, v->offset);
405
 
        }
406
 
 
407
 
        /*
408
 
         * pass 2
409
 
         * turn branch references to pointers
410
 
         * build back pointers
411
 
         */
412
 
        for(r=firstr; r!=R; r=r->link) {
413
 
                p = r->prog;
414
 
                if(p->to.type == D_BRANCH) {
415
 
                        if(p->to.branch == P)
416
 
                                fatal("pnil %P", p);
417
 
                        r1 = p->to.branch->regp;
418
 
                        if(r1 == R)
419
 
                                fatal("rnil %P", p);
420
 
                        if(r1 == r) {
421
 
                                //fatal("ref to self %P", p);
422
 
                                continue;
423
 
                        }
424
 
                        r->s2 = r1;
425
 
                        r->p2link = r1->p2;
426
 
                        r1->p2 = r;
427
 
                }
428
 
        }
429
 
        if(debug['R']) {
430
 
                p = firstr->prog;
431
 
                print("\n%L %D\n", p->lineno, &p->from);
432
 
                print(" addr = %Q\n", addrs);
433
 
        }
434
 
 
435
 
        /*
436
 
         * pass 2.5
437
 
         * find looping structure
438
 
         */
439
 
        for(r = firstr; r != R; r = r->link)
440
 
                r->active = 0;
441
 
        change = 0;
442
 
        loopit(firstr, nr);
443
 
 
444
 
        /*
445
 
         * pass 3
446
 
         * iterate propagating usage
447
 
         *      back until flow graph is complete
448
 
         */
449
 
loop1:
450
 
        change = 0;
451
 
        for(r = firstr; r != R; r = r->link)
452
 
                r->active = 0;
453
 
        for(r = firstr; r != R; r = r->link)
454
 
                if(r->prog->as == ARET)
455
 
                        prop(r, zbits, zbits);
456
 
loop11:
457
 
        /* pick up unreachable code */
458
 
        i = 0;
459
 
        for(r = firstr; r != R; r = r1) {
460
 
                r1 = r->link;
461
 
                if(r1 && r1->active && !r->active) {
462
 
                        prop(r, zbits, zbits);
463
 
                        i = 1;
464
 
                }
465
 
        }
466
 
        if(i)
467
 
                goto loop11;
468
 
        if(change)
469
 
                goto loop1;
470
 
 
471
 
 
472
 
        /*
473
 
         * pass 4
474
 
         * iterate propagating register/variable synchrony
475
 
         *      forward until graph is complete
476
 
         */
477
 
loop2:
478
 
        change = 0;
479
 
        for(r = firstr; r != R; r = r->link)
480
 
                r->active = 0;
481
 
        synch(firstr, zbits);
482
 
        if(change)
483
 
                goto loop2;
484
 
 
485
 
        addsplits();
486
 
 
487
 
        if(debug['R'] > 1) {
488
 
                print("\nprop structure:\n");
489
 
                for(r = firstr; r != R; r = r->link) {
490
 
                        print("%d:%P", r->loop, r->prog);
491
 
                        for(z=0; z<BITS; z++) {
492
 
                                bit.b[z] = r->set.b[z] |
493
 
                                        r->refahead.b[z] | r->calahead.b[z] |
494
 
                                        r->refbehind.b[z] | r->calbehind.b[z] |
495
 
                                        r->use1.b[z] | r->use2.b[z];
496
 
                                bit.b[z] &= ~addrs.b[z];
497
 
                        }
498
 
 
499
 
                        if(bany(&bit)) {
500
 
                                print("\t");
501
 
                                if(bany(&r->use1))
502
 
                                        print(" u1=%Q", r->use1);
503
 
                                if(bany(&r->use2))
504
 
                                        print(" u2=%Q", r->use2);
505
 
                                if(bany(&r->set))
506
 
                                        print(" st=%Q", r->set);
507
 
                                if(bany(&r->refahead))
508
 
                                        print(" ra=%Q", r->refahead);
509
 
                                if(bany(&r->calahead))
510
 
                                        print(" ca=%Q", r->calahead);
511
 
                                if(bany(&r->refbehind))
512
 
                                        print(" rb=%Q", r->refbehind);
513
 
                                if(bany(&r->calbehind))
514
 
                                        print(" cb=%Q", r->calbehind);
515
 
                        }
516
 
                        print("\n");
517
 
                }
518
 
        }
519
 
 
520
 
        /*
521
 
         * pass 4.5
522
 
         * move register pseudo-variables into regu.
523
 
         */
524
 
        for(r = firstr; r != R; r = r->link) {
525
 
                r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS;
526
 
 
527
 
                r->set.b[0] &= ~REGBITS;
528
 
                r->use1.b[0] &= ~REGBITS;
529
 
                r->use2.b[0] &= ~REGBITS;
530
 
                r->refbehind.b[0] &= ~REGBITS;
531
 
                r->refahead.b[0] &= ~REGBITS;
532
 
                r->calbehind.b[0] &= ~REGBITS;
533
 
                r->calahead.b[0] &= ~REGBITS;
534
 
                r->regdiff.b[0] &= ~REGBITS;
535
 
                r->act.b[0] &= ~REGBITS;
536
 
        }
537
 
 
538
 
        /*
539
 
         * pass 5
540
 
         * isolate regions
541
 
         * calculate costs (paint1)
542
 
         */
543
 
        r = firstr;
544
 
        if(r) {
545
 
                for(z=0; z<BITS; z++)
546
 
                        bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
547
 
                          ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
548
 
                if(bany(&bit) & !r->refset) {
549
 
                        // should never happen - all variables are preset
550
 
                        if(debug['w'])
551
 
                                print("%L: used and not set: %Q\n", r->prog->lineno, bit);
552
 
                        r->refset = 1;
553
 
                }
554
 
        }
555
 
 
556
 
        for(r = firstr; r != R; r = r->link)
557
 
                r->act = zbits;
558
 
        rgp = region;
559
 
        nregion = 0;
560
 
        for(r = firstr; r != R; r = r->link) {
561
 
                for(z=0; z<BITS; z++)
562
 
                        bit.b[z] = r->set.b[z] &
563
 
                          ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
564
 
                if(bany(&bit) && !r->refset) {
565
 
                        if(debug['w'])
566
 
                                print("%L: set and not used: %Q\n", r->prog->lineno, bit);
567
 
                        r->refset = 1;
568
 
                        excise(r);
569
 
                }
570
 
                for(z=0; z<BITS; z++)
571
 
                        bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
572
 
                while(bany(&bit)) {
573
 
                        i = bnum(bit);
574
 
                        rgp->enter = r;
575
 
                        rgp->varno = i;
576
 
                        change = 0;
577
 
                        if(debug['R'] > 1)
578
 
                                print("\n");
579
 
                        paint1(r, i);
580
 
                        bit.b[i/32] &= ~(1L<<(i%32));
581
 
                        if(change <= 0) {
582
 
                                if(debug['R'])
583
 
                                        print("%L $%d: %Q\n",
584
 
                                                r->prog->lineno, change, blsh(i));
585
 
                                continue;
586
 
                        }
587
 
                        rgp->cost = change;
588
 
                        nregion++;
589
 
                        if(nregion >= NRGN) {
590
 
                                if(debug['R'] > 1)
591
 
                                        print("too many regions\n");
592
 
                                goto brk;
593
 
                        }
594
 
                        rgp++;
595
 
                }
596
 
        }
597
 
brk:
598
 
        qsort(region, nregion, sizeof(region[0]), rcmp);
599
 
 
600
 
        /*
601
 
         * pass 6
602
 
         * determine used registers (paint2)
603
 
         * replace code (paint3)
604
 
         */
605
 
        rgp = region;
606
 
        for(i=0; i<nregion; i++) {
607
 
                bit = blsh(rgp->varno);
608
 
                vreg = paint2(rgp->enter, rgp->varno);
609
 
                vreg = allreg(vreg, rgp);
610
 
                if(debug['R']) {
611
 
                        if(rgp->regno >= NREG)
612
 
                                print("%L $%d F%d: %Q\n",
613
 
                                        rgp->enter->prog->lineno,
614
 
                                        rgp->cost,
615
 
                                        rgp->regno-NREG,
616
 
                                        bit);
617
 
                        else
618
 
                                print("%L $%d R%d: %Q\n",
619
 
                                        rgp->enter->prog->lineno,
620
 
                                        rgp->cost,
621
 
                                        rgp->regno,
622
 
                                        bit);
623
 
                }
624
 
                if(rgp->regno != 0)
625
 
                        paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
626
 
                rgp++;
627
 
        }
628
 
        /*
629
 
         * pass 7
630
 
         * peep-hole on basic block
631
 
         */
632
 
        if(!debug['R'] || debug['P']) {
633
 
                peep();
634
 
        }
635
 
 
636
 
        /*
637
 
         * last pass
638
 
         * eliminate nops
639
 
         * free aux structures
640
 
         * adjust the stack pointer
641
 
         *      MOVW.W  R1,-12(R13)                     <<- start
642
 
         *      MOVW    R0,R1
643
 
         *      MOVW    R1,8(R13)
644
 
         *      MOVW    $0,R1
645
 
         *      MOVW    R1,4(R13)
646
 
         *      BL      ,runtime.newproc+0(SB)
647
 
         *      MOVW    &ft+-32(SP),R7                  <<- adjust
648
 
         *      MOVW    &j+-40(SP),R6                   <<- adjust
649
 
         *      MOVW    autotmp_0003+-24(SP),R5         <<- adjust
650
 
         *      MOVW    $12(R13),R13                    <<- finish
651
 
         */
652
 
        vreg = 0;
653
 
        for(p = firstp; p != P; p = p->link) {
654
 
                while(p->link != P && p->link->as == ANOP)
655
 
                        p->link = p->link->link;
656
 
                if(p->to.type == D_BRANCH)
657
 
                        while(p->to.branch != P && p->to.branch->as == ANOP)
658
 
                                p->to.branch = p->to.branch->link;
659
 
                if(p->as == AMOVW && p->to.reg == 13) {
660
 
                        if(p->scond & C_WBIT) {
661
 
                                vreg = -p->to.offset;           // in adjust region
662
 
//                              print("%P adjusting %d\n", p, vreg);
663
 
                                continue;
664
 
                        }
665
 
                        if(p->from.type == D_CONST && p->to.type == D_REG) {
666
 
                                if(p->from.offset != vreg)
667
 
                                        print("in and out different\n");
668
 
//                              print("%P finish %d\n", p, vreg);
669
 
                                vreg = 0;       // done adjust region
670
 
                                continue;
671
 
                        }
672
 
 
673
 
//                      print("%P %d %d from type\n", p, p->from.type, D_CONST);
674
 
//                      print("%P %d %d to type\n\n", p, p->to.type, D_REG);
675
 
                }
676
 
 
677
 
                if(p->as == AMOVW && vreg != 0) {
678
 
                        if(p->from.sym != S)
679
 
                        if(p->from.name == D_AUTO || p->from.name == D_PARAM) {
680
 
                                p->from.offset += vreg;
681
 
//                              print("%P adjusting from %d %d\n", p, vreg, p->from.type);
682
 
                        }
683
 
                        if(p->to.sym != S)
684
 
                        if(p->to.name == D_AUTO || p->to.name == D_PARAM) {
685
 
                                p->to.offset += vreg;
686
 
//                              print("%P adjusting to %d %d\n", p, vreg, p->from.type);
687
 
                        }
688
 
                }
689
 
        }
690
 
        if(r1 != R) {
691
 
                r1->link = freer;
692
 
                freer = firstr;
693
 
        }
694
 
 
695
 
}
696
 
 
697
 
void
698
 
addsplits(void)
699
 
{
700
 
        Reg *r, *r1;
701
 
        int z, i;
702
 
        Bits bit;
703
 
 
704
 
        for(r = firstr; r != R; r = r->link) {
705
 
                if(r->loop > 1)
706
 
                        continue;
707
 
                if(r->prog->as == ABL)
708
 
                        continue;
709
 
                for(r1 = r->p2; r1 != R; r1 = r1->p2link) {
710
 
                        if(r1->loop <= 1)
711
 
                                continue;
712
 
                        for(z=0; z<BITS; z++)
713
 
                                bit.b[z] = r1->calbehind.b[z] &
714
 
                                        (r->refahead.b[z] | r->use1.b[z] | r->use2.b[z]) &
715
 
                                        ~(r->calahead.b[z] & addrs.b[z]);
716
 
                        while(bany(&bit)) {
717
 
                                i = bnum(bit);
718
 
                                bit.b[i/32] &= ~(1L << (i%32));
719
 
                        }
720
 
                }
721
 
        }
722
 
}
723
 
 
724
 
/*
725
 
 * add mov b,rn
726
 
 * just after r
727
 
 */
728
 
void
729
 
addmove(Reg *r, int bn, int rn, int f)
730
 
{
731
 
        Prog *p, *p1;
732
 
        Adr *a;
733
 
        Var *v;
734
 
 
735
 
        p1 = mal(sizeof(*p1));
736
 
        *p1 = zprog;
737
 
        p = r->prog;
738
 
 
739
 
        p1->link = p->link;
740
 
        p->link = p1;
741
 
        p1->lineno = p->lineno;
742
 
 
743
 
        v = var + bn;
744
 
 
745
 
        a = &p1->to;
746
 
        a->sym = v->sym;
747
 
        a->name = v->name;
748
 
        a->node = v->node;
749
 
        a->offset = v->offset;
750
 
        a->etype = v->etype;
751
 
        a->type = D_OREG;
752
 
        if(a->etype == TARRAY || a->sym == S)
753
 
                a->type = D_CONST;
754
 
 
755
 
        if(v->addr)
756
 
                fatal("addmove: shouldnt be doing this %A\n", a);
757
 
 
758
 
        switch(v->etype) {
759
 
        default:
760
 
                print("What is this %E\n", v->etype);
761
 
 
762
 
        case TINT8:
763
 
                p1->as = AMOVB;
764
 
                break;
765
 
        case TBOOL:
766
 
        case TUINT8:
767
 
                p1->as = AMOVBU;
768
 
                break;
769
 
        case TINT16:
770
 
                p1->as = AMOVH;
771
 
                break;
772
 
        case TUINT16:
773
 
                p1->as = AMOVHU;
774
 
                break;
775
 
        case TINT32:
776
 
        case TUINT32:
777
 
        case TPTR32:
778
 
                p1->as = AMOVW;
779
 
                break;
780
 
        case TFLOAT32:
781
 
                p1->as = AMOVF;
782
 
                break;
783
 
        case TFLOAT64:
784
 
                p1->as = AMOVD;
785
 
                break;
786
 
        }
787
 
 
788
 
        p1->from.type = D_REG;
789
 
        p1->from.reg = rn;
790
 
        if(rn >= NREG) {
791
 
                p1->from.type = D_FREG;
792
 
                p1->from.reg = rn-NREG;
793
 
        }
794
 
        if(!f) {
795
 
                p1->from = *a;
796
 
                *a = zprog.from;
797
 
                a->type = D_REG;
798
 
                a->reg = rn;
799
 
                if(rn >= NREG) {
800
 
                        a->type = D_FREG;
801
 
                        a->reg = rn-NREG;
802
 
                }
803
 
                if(v->etype == TUINT8 || v->etype == TBOOL)
804
 
                        p1->as = AMOVBU;
805
 
                if(v->etype == TUINT16)
806
 
                        p1->as = AMOVHU;
807
 
        }
808
 
        if(debug['R'])
809
 
                print("%P\t.a%P\n", p, p1);
810
 
}
811
 
 
812
 
static int
813
 
overlap(int32 o1, int w1, int32 o2, int w2)
814
 
{
815
 
        int32 t1, t2;
816
 
 
817
 
        t1 = o1+w1;
818
 
        t2 = o2+w2;
819
 
 
820
 
        if(!(t1 > o2 && t2 > o1))
821
 
                return 0;
822
 
 
823
 
        return 1;
824
 
}
825
 
 
826
 
Bits
827
 
mkvar(Reg *r, Adr *a)
828
 
{
829
 
        Var *v;
830
 
        int i, t, n, et, z, w, flag;
831
 
        int32 o;
832
 
        Bits bit;
833
 
        Sym *s;
834
 
 
835
 
        // mark registers used
836
 
        t = a->type;
837
 
        n = D_NONE;
838
 
 
839
 
        flag = 0;
840
 
        if(a->pun)
841
 
                flag = 1;
842
 
 
843
 
        switch(t) {
844
 
        default:
845
 
                print("type %d %d %D\n", t, a->name, a);
846
 
                goto none;
847
 
 
848
 
        case D_NONE:
849
 
        case D_FCONST:
850
 
        case D_BRANCH:
851
 
                break;
852
 
 
853
 
        case D_CONST:
854
 
                flag = 1;
855
 
                goto onereg;
856
 
 
857
 
        case D_REGREG:
858
 
                bit = zbits;
859
 
                if(a->offset != NREG)
860
 
                        bit.b[0] |= RtoB(a->offset);
861
 
                if(a->reg != NREG)
862
 
                        bit.b[0] |= RtoB(a->reg);
863
 
                return bit;
864
 
 
865
 
        case D_REG:
866
 
        case D_SHIFT:
867
 
        onereg:
868
 
                if(a->reg != NREG) {
869
 
                        bit = zbits;
870
 
                        bit.b[0] = RtoB(a->reg);
871
 
                        return bit;
872
 
                }
873
 
                break;
874
 
 
875
 
        case D_OREG:
876
 
                if(a->reg != NREG) {
877
 
                        if(a == &r->prog->from)
878
 
                                r->use1.b[0] |= RtoB(a->reg);
879
 
                        else
880
 
                                r->use2.b[0] |= RtoB(a->reg);
881
 
                        if(r->prog->scond & (C_PBIT|C_WBIT))
882
 
                                r->set.b[0] |= RtoB(a->reg);
883
 
                }
884
 
                break;
885
 
 
886
 
        case D_FREG:
887
 
                if(a->reg != NREG) {
888
 
                        bit = zbits;
889
 
                        bit.b[0] = FtoB(a->reg);
890
 
                        return bit;
891
 
                }
892
 
                break;
893
 
        }
894
 
 
895
 
        switch(a->name) {
896
 
        default:
897
 
                goto none;
898
 
 
899
 
        case D_EXTERN:
900
 
        case D_STATIC:
901
 
        case D_AUTO:
902
 
        case D_PARAM:
903
 
                n = a->name;
904
 
                break;
905
 
        }
906
 
 
907
 
        s = a->sym;
908
 
        if(s == S)
909
 
                goto none;
910
 
        if(s->name[0] == '.')
911
 
                goto none;
912
 
        et = a->etype;
913
 
        o = a->offset;
914
 
        w = a->width;
915
 
 
916
 
        for(i=0; i<nvar; i++) {
917
 
                v = var+i;
918
 
                if(v->sym == s && v->name == n) {
919
 
                        if(v->offset == o)
920
 
                        if(v->etype == et)
921
 
                        if(v->width == w)
922
 
                                if(!flag)
923
 
                                        return blsh(i);
924
 
 
925
 
                        // if they overlaps, disable both
926
 
                        if(overlap(v->offset, v->width, o, w)) {
927
 
                                v->addr = 1;
928
 
                                flag = 1;
929
 
                        }
930
 
                }
931
 
        }
932
 
 
933
 
        switch(et) {
934
 
        case 0:
935
 
        case TFUNC:
936
 
        case TARRAY:
937
 
        case TSTRING:
938
 
                goto none;
939
 
        }
940
 
 
941
 
        if(nvar >= NVAR) {
942
 
                if(debug['w'] > 1 && s)
943
 
                        fatal("variable not optimized: %D", a);
944
 
                goto none;
945
 
        }
946
 
 
947
 
        i = nvar;
948
 
        nvar++;
949
 
        v = var+i;
950
 
        v->sym = s;
951
 
        v->offset = o;
952
 
        v->name = n;
953
 
//      v->gotype = a->gotype;
954
 
        v->etype = et;
955
 
        v->width = w;
956
 
        v->addr = flag;         // funny punning
957
 
        v->node = a->node;
958
 
        
959
 
        if(debug['R'])
960
 
                print("bit=%2d et=%E pun=%d %D\n", i, et, flag, a);
961
 
 
962
 
        bit = blsh(i);
963
 
        if(n == D_EXTERN || n == D_STATIC)
964
 
                for(z=0; z<BITS; z++)
965
 
                        externs.b[z] |= bit.b[z];
966
 
        if(n == D_PARAM)
967
 
                for(z=0; z<BITS; z++)
968
 
                        params.b[z] |= bit.b[z];
969
 
 
970
 
        return bit;
971
 
 
972
 
none:
973
 
        return zbits;
974
 
}
975
 
 
976
 
void
977
 
prop(Reg *r, Bits ref, Bits cal)
978
 
{
979
 
        Reg *r1, *r2;
980
 
        int z;
981
 
 
982
 
        for(r1 = r; r1 != R; r1 = r1->p1) {
983
 
                for(z=0; z<BITS; z++) {
984
 
                        ref.b[z] |= r1->refahead.b[z];
985
 
                        if(ref.b[z] != r1->refahead.b[z]) {
986
 
                                r1->refahead.b[z] = ref.b[z];
987
 
                                change++;
988
 
                        }
989
 
                        cal.b[z] |= r1->calahead.b[z];
990
 
                        if(cal.b[z] != r1->calahead.b[z]) {
991
 
                                r1->calahead.b[z] = cal.b[z];
992
 
                                change++;
993
 
                        }
994
 
                }
995
 
                switch(r1->prog->as) {
996
 
                case ABL:
997
 
                        if(noreturn(r1->prog))
998
 
                                break;
999
 
                        for(z=0; z<BITS; z++) {
1000
 
                                cal.b[z] |= ref.b[z] | externs.b[z];
1001
 
                                ref.b[z] = 0;
1002
 
                        }
1003
 
                        break;
1004
 
 
1005
 
                case ATEXT:
1006
 
                        for(z=0; z<BITS; z++) {
1007
 
                                cal.b[z] = 0;
1008
 
                                ref.b[z] = 0;
1009
 
                        }
1010
 
                        break;
1011
 
 
1012
 
                case ARET:
1013
 
                        for(z=0; z<BITS; z++) {
1014
 
                                cal.b[z] = externs.b[z] | ovar.b[z];
1015
 
                                ref.b[z] = 0;
1016
 
                        }
1017
 
                        break;
1018
 
                }
1019
 
                for(z=0; z<BITS; z++) {
1020
 
                        ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
1021
 
                                r1->use1.b[z] | r1->use2.b[z];
1022
 
                        cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
1023
 
                        r1->refbehind.b[z] = ref.b[z];
1024
 
                        r1->calbehind.b[z] = cal.b[z];
1025
 
                }
1026
 
                if(r1->active)
1027
 
                        break;
1028
 
                r1->active = 1;
1029
 
        }
1030
 
        for(; r != r1; r = r->p1)
1031
 
                for(r2 = r->p2; r2 != R; r2 = r2->p2link)
1032
 
                        prop(r2, r->refbehind, r->calbehind);
1033
 
}
1034
 
 
1035
 
/*
1036
 
 * find looping structure
1037
 
 *
1038
 
 * 1) find reverse postordering
1039
 
 * 2) find approximate dominators,
1040
 
 *      the actual dominators if the flow graph is reducible
1041
 
 *      otherwise, dominators plus some other non-dominators.
1042
 
 *      See Matthew S. Hecht and Jeffrey D. Ullman,
1043
 
 *      "Analysis of a Simple Algorithm for Global Data Flow Problems",
1044
 
 *      Conf.  Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
1045
 
 *      Oct. 1-3, 1973, pp.  207-217.
1046
 
 * 3) find all nodes with a predecessor dominated by the current node.
1047
 
 *      such a node is a loop head.
1048
 
 *      recursively, all preds with a greater rpo number are in the loop
1049
 
 */
1050
 
int32
1051
 
postorder(Reg *r, Reg **rpo2r, int32 n)
1052
 
{
1053
 
        Reg *r1;
1054
 
 
1055
 
        r->rpo = 1;
1056
 
        r1 = r->s1;
1057
 
        if(r1 && !r1->rpo)
1058
 
                n = postorder(r1, rpo2r, n);
1059
 
        r1 = r->s2;
1060
 
        if(r1 && !r1->rpo)
1061
 
                n = postorder(r1, rpo2r, n);
1062
 
        rpo2r[n] = r;
1063
 
        n++;
1064
 
        return n;
1065
 
}
1066
 
 
1067
 
int32
1068
 
rpolca(int32 *idom, int32 rpo1, int32 rpo2)
1069
 
{
1070
 
        int32 t;
1071
 
 
1072
 
        if(rpo1 == -1)
1073
 
                return rpo2;
1074
 
        while(rpo1 != rpo2){
1075
 
                if(rpo1 > rpo2){
1076
 
                        t = rpo2;
1077
 
                        rpo2 = rpo1;
1078
 
                        rpo1 = t;
1079
 
                }
1080
 
                while(rpo1 < rpo2){
1081
 
                        t = idom[rpo2];
1082
 
                        if(t >= rpo2)
1083
 
                                fatal("bad idom");
1084
 
                        rpo2 = t;
1085
 
                }
1086
 
        }
1087
 
        return rpo1;
1088
 
}
1089
 
 
1090
 
int
1091
 
doms(int32 *idom, int32 r, int32 s)
1092
 
{
1093
 
        while(s > r)
1094
 
                s = idom[s];
1095
 
        return s == r;
1096
 
}
1097
 
 
1098
 
int
1099
 
loophead(int32 *idom, Reg *r)
1100
 
{
1101
 
        int32 src;
1102
 
 
1103
 
        src = r->rpo;
1104
 
        if(r->p1 != R && doms(idom, src, r->p1->rpo))
1105
 
                return 1;
1106
 
        for(r = r->p2; r != R; r = r->p2link)
1107
 
                if(doms(idom, src, r->rpo))
1108
 
                        return 1;
1109
 
        return 0;
1110
 
}
1111
 
 
1112
 
void
1113
 
loopmark(Reg **rpo2r, int32 head, Reg *r)
1114
 
{
1115
 
        if(r->rpo < head || r->active == head)
1116
 
                return;
1117
 
        r->active = head;
1118
 
        r->loop += LOOP;
1119
 
        if(r->p1 != R)
1120
 
                loopmark(rpo2r, head, r->p1);
1121
 
        for(r = r->p2; r != R; r = r->p2link)
1122
 
                loopmark(rpo2r, head, r);
1123
 
}
1124
 
 
1125
 
void
1126
 
loopit(Reg *r, int32 nr)
1127
 
{
1128
 
        Reg *r1;
1129
 
        int32 i, d, me;
1130
 
 
1131
 
        if(nr > maxnr) {
1132
 
                rpo2r = mal(nr * sizeof(Reg*));
1133
 
                idom = mal(nr * sizeof(int32));
1134
 
                maxnr = nr;
1135
 
        }
1136
 
        d = postorder(r, rpo2r, 0);
1137
 
        if(d > nr)
1138
 
                fatal("too many reg nodes");
1139
 
        nr = d;
1140
 
        for(i = 0; i < nr / 2; i++){
1141
 
                r1 = rpo2r[i];
1142
 
                rpo2r[i] = rpo2r[nr - 1 - i];
1143
 
                rpo2r[nr - 1 - i] = r1;
1144
 
        }
1145
 
        for(i = 0; i < nr; i++)
1146
 
                rpo2r[i]->rpo = i;
1147
 
 
1148
 
        idom[0] = 0;
1149
 
        for(i = 0; i < nr; i++){
1150
 
                r1 = rpo2r[i];
1151
 
                me = r1->rpo;
1152
 
                d = -1;
1153
 
                if(r1->p1 != R && r1->p1->rpo < me)
1154
 
                        d = r1->p1->rpo;
1155
 
                for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
1156
 
                        if(r1->rpo < me)
1157
 
                                d = rpolca(idom, d, r1->rpo);
1158
 
                idom[i] = d;
1159
 
        }
1160
 
 
1161
 
        for(i = 0; i < nr; i++){
1162
 
                r1 = rpo2r[i];
1163
 
                r1->loop++;
1164
 
                if(r1->p2 != R && loophead(idom, r1))
1165
 
                        loopmark(rpo2r, i, r1);
1166
 
        }
1167
 
}
1168
 
 
1169
 
void
1170
 
synch(Reg *r, Bits dif)
1171
 
{
1172
 
        Reg *r1;
1173
 
        int z;
1174
 
 
1175
 
        for(r1 = r; r1 != R; r1 = r1->s1) {
1176
 
                for(z=0; z<BITS; z++) {
1177
 
                        dif.b[z] = (dif.b[z] &
1178
 
                                ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
1179
 
                                        r1->set.b[z] | r1->regdiff.b[z];
1180
 
                        if(dif.b[z] != r1->regdiff.b[z]) {
1181
 
                                r1->regdiff.b[z] = dif.b[z];
1182
 
                                change++;
1183
 
                        }
1184
 
                }
1185
 
                if(r1->active)
1186
 
                        break;
1187
 
                r1->active = 1;
1188
 
                for(z=0; z<BITS; z++)
1189
 
                        dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
1190
 
                if(r1->s2 != R)
1191
 
                        synch(r1->s2, dif);
1192
 
        }
1193
 
}
1194
 
 
1195
 
uint32
1196
 
allreg(uint32 b, Rgn *r)
1197
 
{
1198
 
        Var *v;
1199
 
        int i;
1200
 
 
1201
 
        v = var + r->varno;
1202
 
        r->regno = 0;
1203
 
        switch(v->etype) {
1204
 
 
1205
 
        default:
1206
 
                fatal("unknown etype %d/%E", bitno(b), v->etype);
1207
 
                break;
1208
 
 
1209
 
        case TINT8:
1210
 
        case TUINT8:
1211
 
        case TINT16:
1212
 
        case TUINT16:
1213
 
        case TINT32:
1214
 
        case TUINT32:
1215
 
        case TINT:
1216
 
        case TUINT:
1217
 
        case TUINTPTR:
1218
 
        case TBOOL:
1219
 
        case TPTR32:
1220
 
                i = BtoR(~b);
1221
 
                if(i && r->cost >= 0) {
1222
 
                        r->regno = i;
1223
 
                        return RtoB(i);
1224
 
                }
1225
 
                break;
1226
 
 
1227
 
        case TFLOAT32:
1228
 
        case TFLOAT64:
1229
 
                i = BtoF(~b);
1230
 
                if(i && r->cost >= 0) {
1231
 
                        r->regno = i+NREG;
1232
 
                        return FtoB(i);
1233
 
                }
1234
 
                break;
1235
 
 
1236
 
        case TINT64:
1237
 
        case TUINT64:
1238
 
        case TPTR64:
1239
 
        case TINTER:
1240
 
        case TSTRUCT:
1241
 
        case TARRAY:
1242
 
                break;
1243
 
        }
1244
 
        return 0;
1245
 
}
1246
 
 
1247
 
void
1248
 
paint1(Reg *r, int bn)
1249
 
{
1250
 
        Reg *r1;
1251
 
        Prog *p;
1252
 
        int z;
1253
 
        uint32 bb;
1254
 
 
1255
 
        z = bn/32;
1256
 
        bb = 1L<<(bn%32);
1257
 
        if(r->act.b[z] & bb)
1258
 
                return;
1259
 
        for(;;) {
1260
 
                if(!(r->refbehind.b[z] & bb))
1261
 
                        break;
1262
 
                r1 = r->p1;
1263
 
                if(r1 == R)
1264
 
                        break;
1265
 
                if(!(r1->refahead.b[z] & bb))
1266
 
                        break;
1267
 
                if(r1->act.b[z] & bb)
1268
 
                        break;
1269
 
                r = r1;
1270
 
        }
1271
 
 
1272
 
        if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) {
1273
 
                change -= CLOAD * r->loop;
1274
 
                if(debug['R'] > 1)
1275
 
                        print("%d%P\td %Q $%d\n", r->loop,
1276
 
                                r->prog, blsh(bn), change);
1277
 
        }
1278
 
        for(;;) {
1279
 
                r->act.b[z] |= bb;
1280
 
                p = r->prog;
1281
 
 
1282
 
                if(r->use1.b[z] & bb) {
1283
 
                        change += CREF * r->loop;
1284
 
                        if(debug['R'] > 1)
1285
 
                                print("%d%P\tu1 %Q $%d\n", r->loop,
1286
 
                                        p, blsh(bn), change);
1287
 
                }
1288
 
 
1289
 
                if((r->use2.b[z]|r->set.b[z]) & bb) {
1290
 
                        change += CREF * r->loop;
1291
 
                        if(debug['R'] > 1)
1292
 
                                print("%d%P\tu2 %Q $%d\n", r->loop,
1293
 
                                        p, blsh(bn), change);
1294
 
                }
1295
 
 
1296
 
                if(STORE(r) & r->regdiff.b[z] & bb) {
1297
 
                        change -= CLOAD * r->loop;
1298
 
                        if(debug['R'] > 1)
1299
 
                                print("%d%P\tst %Q $%d\n", r->loop,
1300
 
                                        p, blsh(bn), change);
1301
 
                }
1302
 
 
1303
 
                if(r->refbehind.b[z] & bb)
1304
 
                        for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1305
 
                                if(r1->refahead.b[z] & bb)
1306
 
                                        paint1(r1, bn);
1307
 
 
1308
 
                if(!(r->refahead.b[z] & bb))
1309
 
                        break;
1310
 
                r1 = r->s2;
1311
 
                if(r1 != R)
1312
 
                        if(r1->refbehind.b[z] & bb)
1313
 
                                paint1(r1, bn);
1314
 
                r = r->s1;
1315
 
                if(r == R)
1316
 
                        break;
1317
 
                if(r->act.b[z] & bb)
1318
 
                        break;
1319
 
                if(!(r->refbehind.b[z] & bb))
1320
 
                        break;
1321
 
        }
1322
 
}
1323
 
 
1324
 
uint32
1325
 
paint2(Reg *r, int bn)
1326
 
{
1327
 
        Reg *r1;
1328
 
        int z;
1329
 
        uint32 bb, vreg;
1330
 
 
1331
 
        z = bn/32;
1332
 
        bb = 1L << (bn%32);
1333
 
        vreg = regbits;
1334
 
        if(!(r->act.b[z] & bb))
1335
 
                return vreg;
1336
 
        for(;;) {
1337
 
                if(!(r->refbehind.b[z] & bb))
1338
 
                        break;
1339
 
                r1 = r->p1;
1340
 
                if(r1 == R)
1341
 
                        break;
1342
 
                if(!(r1->refahead.b[z] & bb))
1343
 
                        break;
1344
 
                if(!(r1->act.b[z] & bb))
1345
 
                        break;
1346
 
                r = r1;
1347
 
        }
1348
 
        for(;;) {
1349
 
                r->act.b[z] &= ~bb;
1350
 
 
1351
 
                vreg |= r->regu;
1352
 
 
1353
 
                if(r->refbehind.b[z] & bb)
1354
 
                        for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1355
 
                                if(r1->refahead.b[z] & bb)
1356
 
                                        vreg |= paint2(r1, bn);
1357
 
 
1358
 
                if(!(r->refahead.b[z] & bb))
1359
 
                        break;
1360
 
                r1 = r->s2;
1361
 
                if(r1 != R)
1362
 
                        if(r1->refbehind.b[z] & bb)
1363
 
                                vreg |= paint2(r1, bn);
1364
 
                r = r->s1;
1365
 
                if(r == R)
1366
 
                        break;
1367
 
                if(!(r->act.b[z] & bb))
1368
 
                        break;
1369
 
                if(!(r->refbehind.b[z] & bb))
1370
 
                        break;
1371
 
        }
1372
 
        return vreg;
1373
 
}
1374
 
 
1375
 
void
1376
 
paint3(Reg *r, int bn, int32 rb, int rn)
1377
 
{
1378
 
        Reg *r1;
1379
 
        Prog *p;
1380
 
        int z;
1381
 
        uint32 bb;
1382
 
 
1383
 
        z = bn/32;
1384
 
        bb = 1L << (bn%32);
1385
 
        if(r->act.b[z] & bb)
1386
 
                return;
1387
 
        for(;;) {
1388
 
                if(!(r->refbehind.b[z] & bb))
1389
 
                        break;
1390
 
                r1 = r->p1;
1391
 
                if(r1 == R)
1392
 
                        break;
1393
 
                if(!(r1->refahead.b[z] & bb))
1394
 
                        break;
1395
 
                if(r1->act.b[z] & bb)
1396
 
                        break;
1397
 
                r = r1;
1398
 
        }
1399
 
 
1400
 
        if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
1401
 
                addmove(r, bn, rn, 0);
1402
 
 
1403
 
        for(;;) {
1404
 
                r->act.b[z] |= bb;
1405
 
                p = r->prog;
1406
 
 
1407
 
                if(r->use1.b[z] & bb) {
1408
 
                        if(debug['R'])
1409
 
                                print("%P", p);
1410
 
                        addreg(&p->from, rn);
1411
 
                        if(debug['R'])
1412
 
                                print("\t.c%P\n", p);
1413
 
                }
1414
 
                if((r->use2.b[z]|r->set.b[z]) & bb) {
1415
 
                        if(debug['R'])
1416
 
                                print("%P", p);
1417
 
                        addreg(&p->to, rn);
1418
 
                        if(debug['R'])
1419
 
                                print("\t.c%P\n", p);
1420
 
                }
1421
 
 
1422
 
                if(STORE(r) & r->regdiff.b[z] & bb)
1423
 
                        addmove(r, bn, rn, 1);
1424
 
                r->regu |= rb;
1425
 
 
1426
 
                if(r->refbehind.b[z] & bb)
1427
 
                        for(r1 = r->p2; r1 != R; r1 = r1->p2link)
1428
 
                                if(r1->refahead.b[z] & bb)
1429
 
                                        paint3(r1, bn, rb, rn);
1430
 
 
1431
 
                if(!(r->refahead.b[z] & bb))
1432
 
                        break;
1433
 
                r1 = r->s2;
1434
 
                if(r1 != R)
1435
 
                        if(r1->refbehind.b[z] & bb)
1436
 
                                paint3(r1, bn, rb, rn);
1437
 
                r = r->s1;
1438
 
                if(r == R)
1439
 
                        break;
1440
 
                if(r->act.b[z] & bb)
1441
 
                        break;
1442
 
                if(!(r->refbehind.b[z] & bb))
1443
 
                        break;
1444
 
        }
1445
 
}
1446
 
 
1447
 
void
1448
 
addreg(Adr *a, int rn)
1449
 
{
1450
 
 
1451
 
        if(a->type == D_CONST)
1452
 
                fatal("addreg: cant do this %D %d\n", a, rn);
1453
 
 
1454
 
        a->sym = 0;
1455
 
        a->name = D_NONE;
1456
 
        a->type = D_REG;
1457
 
        a->reg = rn;
1458
 
        if(rn >= NREG) {
1459
 
                a->type = D_FREG;
1460
 
                a->reg = rn-NREG;
1461
 
        }
1462
 
}
1463
 
 
1464
 
/*
1465
 
 *      bit     reg
1466
 
 *      0       R0
1467
 
 *      1       R1
1468
 
 *      ...     ...
1469
 
 *      10      R10
1470
 
 */
1471
 
int32
1472
 
RtoB(int r)
1473
 
{
1474
 
 
1475
 
        if(r < 2 || r >= REGTMP-2)      // excluded R9 and R10 for m and g
1476
 
                return 0;
1477
 
        return 1L << r;
1478
 
}
1479
 
 
1480
 
int
1481
 
BtoR(int32 b)
1482
 
{
1483
 
        b &= 0x01fcL;   // excluded R9 and R10 for m and g
1484
 
        if(b == 0)
1485
 
                return 0;
1486
 
        return bitno(b);
1487
 
}
1488
 
 
1489
 
/*
1490
 
 *      bit     reg
1491
 
 *      18      F2
1492
 
 *      19      F3
1493
 
 *      ...     ...
1494
 
 *      23      F7
1495
 
 */
1496
 
int32
1497
 
FtoB(int f)
1498
 
{
1499
 
 
1500
 
        if(f < 2 || f > NFREG-1)
1501
 
                return 0;
1502
 
        return 1L << (f + 16);
1503
 
}
1504
 
 
1505
 
int
1506
 
BtoF(int32 b)
1507
 
{
1508
 
 
1509
 
        b &= 0xfc0000L;
1510
 
        if(b == 0)
1511
 
                return 0;
1512
 
        return bitno(b) - 16;
1513
 
}
1514
 
 
1515
 
static Sym*     symlist[10];
1516
 
 
1517
 
int
1518
 
noreturn(Prog *p)
1519
 
{
1520
 
        Sym *s;
1521
 
        int i;
1522
 
 
1523
 
        if(symlist[0] == S) {
1524
 
                symlist[0] = pkglookup("panicindex", runtimepkg);
1525
 
                symlist[1] = pkglookup("panicslice", runtimepkg);
1526
 
                symlist[2] = pkglookup("throwinit", runtimepkg);
1527
 
                symlist[3] = pkglookup("panic", runtimepkg);
1528
 
        }
1529
 
 
1530
 
        s = p->to.sym;
1531
 
        if(s == S)
1532
 
                return 0;
1533
 
        for(i=0; symlist[i]!=S; i++)
1534
 
                if(s == symlist[i])
1535
 
                        return 1;
1536
 
        return 0;
1537
 
}
1538
 
 
1539
 
void
1540
 
dumpone(Reg *r)
1541
 
{
1542
 
        int z;
1543
 
        Bits bit;
1544
 
 
1545
 
        print("%d:%P", r->loop, r->prog);
1546
 
        for(z=0; z<BITS; z++)
1547
 
                bit.b[z] =
1548
 
                        r->set.b[z] |
1549
 
                        r->use1.b[z] |
1550
 
                        r->use2.b[z] |
1551
 
                        r->refbehind.b[z] |
1552
 
                        r->refahead.b[z] |
1553
 
                        r->calbehind.b[z] |
1554
 
                        r->calahead.b[z] |
1555
 
                        r->regdiff.b[z] |
1556
 
                        r->act.b[z] |
1557
 
                                0;
1558
 
//      if(bany(&bit)) {
1559
 
//              print("\t");
1560
 
//              if(bany(&r->set))
1561
 
//                      print(" s:%Q", r->set);
1562
 
//              if(bany(&r->use1))
1563
 
//                      print(" u1:%Q", r->use1);
1564
 
//              if(bany(&r->use2))
1565
 
//                      print(" u2:%Q", r->use2);
1566
 
//              if(bany(&r->refbehind))
1567
 
//                      print(" rb:%Q ", r->refbehind);
1568
 
//              if(bany(&r->refahead))
1569
 
//                      print(" ra:%Q ", r->refahead);
1570
 
//              if(bany(&r->calbehind))
1571
 
//                      print("cb:%Q ", r->calbehind);
1572
 
//              if(bany(&r->calahead))
1573
 
//                      print(" ca:%Q ", r->calahead);
1574
 
//              if(bany(&r->regdiff))
1575
 
//                      print(" d:%Q ", r->regdiff);
1576
 
//              if(bany(&r->act))
1577
 
//                      print(" a:%Q ", r->act);
1578
 
//      }
1579
 
        print("\n");
1580
 
}
1581
 
 
1582
 
void
1583
 
dumpit(char *str, Reg *r0)
1584
 
{
1585
 
        Reg *r, *r1;
1586
 
 
1587
 
        print("\n%s\n", str);
1588
 
        for(r = r0; r != R; r = r->link) {
1589
 
                dumpone(r);
1590
 
                r1 = r->p2;
1591
 
                if(r1 != R) {
1592
 
                        print(" pred:");
1593
 
                        for(; r1 != R; r1 = r1->p2link)
1594
 
                                print(" %.4ud", r1->prog->loc);
1595
 
                        print("\n");
1596
 
                }
1597
 
//              r1 = r->s1;
1598
 
//              if(r1 != R) {
1599
 
//                      print(" succ:");
1600
 
//                      for(; r1 != R; r1 = r1->s1)
1601
 
//                              print(" %.4ud", r1->prog->loc);
1602
 
//                      print("\n");
1603
 
//              }
1604
 
        }
1605
 
}