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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-04-20 17:36:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110420173648-ifergoxyrm832trd
Tags: upstream-2011.03.07.1
Import upstream version 2011.03.07.1

Show diffs side-by-side

added added

removed removed

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