OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [eco32.md.SAVE-0] - Blame information for rev 58

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
%{
2
 
3
/*
4
 * eco32.md -- ECO32 back-end specification
5
 *
6
 * register usage:
7
 *   $0   always zero
8
 *   $1   reserved for assembler
9
 *   $2   func return value
10
 *   $3   func return value
11
 *   $4   proc/func argument
12
 *   $5   proc/func argument
13
 *   $6   proc/func argument
14
 *   $7   proc/func argument
15
 *   $8   temporary register (caller-save)
16
 *   $9   temporary register (caller-save)
17
 *   $10  temporary register (caller-save)
18
 *   $11  temporary register (caller-save)
19
 *   $12  temporary register (caller-save)
20
 *   $13  temporary register (caller-save)
21
 *   $14  temporary register (caller-save)
22
 *   $15  temporary register (caller-save)
23
 *   $16  register variable  (callee-save)
24
 *   $17  register variable  (callee-save)
25
 *   $18  register variable  (callee-save)
26
 *   $19  register variable  (callee-save)
27
 *   $20  register variable  (callee-save)
28
 *   $21  register variable  (callee-save)
29
 *   $22  register variable  (callee-save)
30
 *   $23  register variable  (callee-save)
31
 *   $24  temporary register (caller-save)
32
 *   $25  temporary register (caller-save)
33
 *   $26  reserved for OS kernel
34
 *   $27  reserved for OS kernel
35
 *   $28  reserved for OS kernel
36
 *   $29  stack pointer
37
 *   $30  interrupt return address
38
 *   $31  proc/func return address
39
 * caller-save registers are not preserved across procedure calls
40
 * callee-save registers are preserved across procedure calls
41
 *
42
 * tree grammar terminals produced by:
43
 *   ops c=1 s=2 i=4 l=4 h=4 f=4 d=8 x=8 p=4
44
 */
45
 
46
#include "c.h"
47
 
48
#define NODEPTR_TYPE    Node
49
#define OP_LABEL(p)     ((p)->op)
50
#define LEFT_CHILD(p)   ((p)->kids[0])
51
#define RIGHT_CHILD(p)  ((p)->kids[1])
52
#define STATE_LABEL(p)  ((p)->x.state)
53
 
54
static void address(Symbol, Symbol, long);
55
static void defaddress(Symbol);
56
static void defconst(int, int, Value);
57
static void defstring(int, char *);
58
static void defsymbol(Symbol);
59
static void export(Symbol);
60
static void function(Symbol, Symbol [], Symbol [], int);
61
static void global(Symbol);
62
static void import(Symbol);
63
static void local(Symbol);
64
static void progbeg(int, char * []);
65
static void progend(void);
66
static void segment(int);
67
static void space(int);
68
static Symbol rmap(int);
69
static void blkfetch(int, int, int, int);
70
static void blkstore(int, int, int, int);
71
static void blkloop(int, int, int, int, int, int []);
72
static void emit2(Node);
73
static void doarg(Node);
74
static void target(Node);
75
static void clobber(Node);
76
 
77
#define INTTMP  0x0100FF00
78
#define INTVAR  0x00FF0000
79
#define INTRET  0x00000004
80
#define FLTTMP  0x000F0FF0
81
#define FLTVAR  0xFFF00000
82
#define FLTRET  0x00000003
83
 
84
static Symbol ireg[32];
85
static Symbol iregw;
86
static Symbol freg2[32];
87
static Symbol freg2w;
88
 
89
%}
90
 
91
%start stmt
92
 
93
%term CNSTF4=4113 CNSTF8=8209
94
%term CNSTI1=1045 CNSTI2=2069 CNSTI4=4117
95
%term CNSTP4=4119
96
%term CNSTU1=1046 CNSTU2=2070 CNSTU4=4118
97
 
98
%term ARGB=41
99
%term ARGF4=4129 ARGF8=8225
100
%term ARGI4=4133
101
%term ARGP4=4135
102
%term ARGU4=4134
103
 
104
%term ASGNB=57
105
%term ASGNF4=4145 ASGNF8=8241
106
%term ASGNI1=1077 ASGNI2=2101 ASGNI4=4149
107
%term ASGNP4=4151
108
%term ASGNU1=1078 ASGNU2=2102 ASGNU4=4150
109
 
110
%term INDIRB=73
111
%term INDIRF4=4161 INDIRF8=8257
112
%term INDIRI1=1093 INDIRI2=2117 INDIRI4=4165
113
%term INDIRP4=4167
114
%term INDIRU1=1094 INDIRU2=2118 INDIRU4=4166
115
 
116
%term CVFF4=4209 CVFF8=8305
117
%term CVFI4=4213
118
 
119
%term CVIF4=4225 CVIF8=8321
120
%term CVII1=1157 CVII2=2181 CVII4=4229
121
%term CVIU1=1158 CVIU2=2182 CVIU4=4230
122
 
123
%term CVPU4=4246
124
 
125
%term CVUI1=1205 CVUI2=2229 CVUI4=4277
126
%term CVUP4=4279
127
%term CVUU1=1206 CVUU2=2230 CVUU4=4278
128
 
129
%term NEGF4=4289 NEGF8=8385
130
%term NEGI4=4293
131
 
132
%term CALLB=217
133
%term CALLF4=4305 CALLF8=8401
134
%term CALLI4=4309
135
%term CALLP4=4311
136
%term CALLU4=4310
137
%term CALLV=216
138
 
139
%term RETF4=4337 RETF8=8433
140
%term RETI4=4341
141
%term RETP4=4343
142
%term RETU4=4342
143
%term RETV=248
144
 
145
%term ADDRGP4=4359
146
 
147
%term ADDRFP4=4375
148
 
149
%term ADDRLP4=4391
150
 
151
%term ADDF4=4401 ADDF8=8497
152
%term ADDI4=4405
153
%term ADDP4=4407
154
%term ADDU4=4406
155
 
156
%term SUBF4=4417 SUBF8=8513
157
%term SUBI4=4421
158
%term SUBP4=4423
159
%term SUBU4=4422
160
 
161
%term LSHI4=4437
162
%term LSHU4=4438
163
 
164
%term MODI4=4453
165
%term MODU4=4454
166
 
167
%term RSHI4=4469
168
%term RSHU4=4470
169
 
170
%term BANDI4=4485
171
%term BANDU4=4486
172
 
173
%term BCOMI4=4501
174
%term BCOMU4=4502
175
 
176
%term BORI4=4517
177
%term BORU4=4518
178
 
179
%term BXORI4=4533
180
%term BXORU4=4534
181
 
182
%term DIVF4=4545 DIVF8=8641
183
%term DIVI4=4549
184
%term DIVU4=4550
185
 
186
%term MULF4=4561 MULF8=8657
187
%term MULI4=4565
188
%term MULU4=4566
189
 
190
%term EQF4=4577 EQF8=8673
191
%term EQI4=4581
192
%term EQU4=4582
193
 
194
%term GEF4=4593 GEF8=8689
195
%term GEI4=4597
196
%term GEU4=4598
197
 
198
%term GTF4=4609 GTF8=8705
199
%term GTI4=4613
200
%term GTU4=4614
201
 
202
%term LEF4=4625 LEF8=8721
203
%term LEI4=4629
204
%term LEU4=4630
205
 
206
%term LTF4=4641 LTF8=8737
207
%term LTI4=4645
208
%term LTU4=4646
209
 
210
%term NEF4=4657 NEF8=8753
211
%term NEI4=4661
212
%term NEU4=4662
213
 
214
%term JUMPV=584
215
 
216
%term LABELV=600
217
 
218
%term LOADB=233
219
%term LOADF4=4321 LOADF8=8417
220
%term LOADI1=1253 LOADI2=2277 LOADI4=4325
221
%term LOADP4=4327
222
%term LOADU1=1254 LOADU2=2278 LOADU4=4326
223
 
224
%term VREGP=711
225
 
226
 
227
%%
228
 
229
 
230
reg:    INDIRI1(VREGP)          "# read register\n"
231
reg:    INDIRI2(VREGP)          "# read register\n"
232
reg:    INDIRI4(VREGP)          "# read register\n"
233
reg:    INDIRP4(VREGP)          "# read register\n"
234
reg:    INDIRU1(VREGP)          "# read register\n"
235
reg:    INDIRU2(VREGP)          "# read register\n"
236
reg:    INDIRU4(VREGP)          "# read register\n"
237
 
238
stmt:   ASGNI1(VREGP,reg)       "# write register\n"
239
stmt:   ASGNI2(VREGP,reg)       "# write register\n"
240
stmt:   ASGNI4(VREGP,reg)       "# write register\n"
241
stmt:   ASGNP4(VREGP,reg)       "# write register\n"
242
stmt:   ASGNU1(VREGP,reg)       "# write register\n"
243
stmt:   ASGNU2(VREGP,reg)       "# write register\n"
244
stmt:   ASGNU4(VREGP,reg)       "# write register\n"
245
 
246
con:    CNSTI1                  "%a"
247
con:    CNSTI2                  "%a"
248
con:    CNSTI4                  "%a"
249
con:    CNSTP4                  "%a"
250
con:    CNSTU1                  "%a"
251
con:    CNSTU2                  "%a"
252
con:    CNSTU4                  "%a"
253
 
254
stmt:   reg                     ""
255
 
256
acon:   con                     "%0"
257
acon:   ADDRGP4                 "%a"
258
 
259
addr:   ADDI4(reg,acon)         "$%0,%1"
260
addr:   ADDP4(reg,acon)         "$%0,%1"
261
addr:   ADDU4(reg,acon)         "$%0,%1"
262
 
263
addr:   acon                    "$0,%0"
264
addr:   reg                     "$%0,0"
265
addr:   ADDRFP4                 "$29,%a+%F"
266
addr:   ADDRLP4                 "$29,%a+%F"
267
 
268
reg:    addr                    "\tadd\t$%c,%0\n"       1
269
 
270
reg:    CNSTI1                  "# reg\n"               range(a, 0, 0)
271
reg:    CNSTI2                  "# reg\n"               range(a, 0, 0)
272
reg:    CNSTI4                  "# reg\n"               range(a, 0, 0)
273
reg:    CNSTP4                  "# reg\n"               range(a, 0, 0)
274
reg:    CNSTU1                  "# reg\n"               range(a, 0, 0)
275
reg:    CNSTU2                  "# reg\n"               range(a, 0, 0)
276
reg:    CNSTU4                  "# reg\n"               range(a, 0, 0)
277
 
278
stmt:   ASGNI1(addr,reg)        "\tstb\t$%1,%0\n"       1
279
stmt:   ASGNI2(addr,reg)        "\tsth\t$%1,%0\n"       1
280
stmt:   ASGNI4(addr,reg)        "\tstw\t$%1,%0\n"       1
281
stmt:   ASGNP4(addr,reg)        "\tstw\t$%1,%0\n"       1
282
stmt:   ASGNU1(addr,reg)        "\tstb\t$%1,%0\n"       1
283
stmt:   ASGNU2(addr,reg)        "\tsth\t$%1,%0\n"       1
284
stmt:   ASGNU4(addr,reg)        "\tstw\t$%1,%0\n"       1
285
 
286
reg:    INDIRI1(addr)           "\tldb\t$%c,%0\n"       1
287
reg:    INDIRI2(addr)           "\tldh\t$%c,%0\n"       1
288
reg:    INDIRI4(addr)           "\tldw\t$%c,%0\n"       1
289
reg:    INDIRP4(addr)           "\tldw\t$%c,%0\n"       1
290
reg:    INDIRU1(addr)           "\tldbu\t$%c,%0\n"      1
291
reg:    INDIRU2(addr)           "\tldhu\t$%c,%0\n"      1
292
reg:    INDIRU4(addr)           "\tldw\t$%c,%0\n"       1
293
 
294
reg:    CVII4(INDIRI1(addr))    "\tldb\t$%c,%0\n"       1
295
reg:    CVII4(INDIRI2(addr))    "\tldh\t$%c,%0\n"       1
296
reg:    CVUU4(INDIRU1(addr))    "\tldbu\t$%c,%0\n"      1
297
reg:    CVUU4(INDIRU2(addr))    "\tldhu\t$%c,%0\n"      1
298
reg:    CVUI4(INDIRU1(addr))    "\tldbu\t$%c,%0\n"      1
299
reg:    CVUI4(INDIRU2(addr))    "\tldhu\t$%c,%0\n"      1
300
 
301
rc:     con                     "%0"
302
rc:     reg                     "$%0"
303
 
304
reg:    ADDI4(reg,rc)           "\tadd\t$%c,$%0,%1\n"   1
305
reg:    ADDP4(reg,rc)           "\tadd\t$%c,$%0,%1\n"   1
306
reg:    ADDU4(reg,rc)           "\tadd\t$%c,$%0,%1\n"   1
307
reg:    SUBI4(reg,rc)           "\tsub\t$%c,$%0,%1\n"   1
308
reg:    SUBP4(reg,rc)           "\tsub\t$%c,$%0,%1\n"   1
309
reg:    SUBU4(reg,rc)           "\tsub\t$%c,$%0,%1\n"   1
310
reg:    NEGI4(reg)              "\tsub\t$%c,$0,$%0\n"   1
311
 
312
reg:    MULI4(reg,rc)           "\tmul\t$%c,$%0,%1\n"   1
313
reg:    MULU4(reg,rc)           "\tmulu\t$%c,$%0,%1\n"  1
314
reg:    DIVI4(reg,rc)           "\tdiv\t$%c,$%0,%1\n"   1
315
reg:    DIVU4(reg,rc)           "\tdivu\t$%c,$%0,%1\n"  1
316
reg:    MODI4(reg,rc)           "\trem\t$%c,$%0,%1\n"   1
317
reg:    MODU4(reg,rc)           "\tremu\t$%c,$%0,%1\n"  1
318
 
319
reg:    BANDI4(reg,rc)          "\tand\t$%c,$%0,%1\n"   1
320
reg:    BANDU4(reg,rc)          "\tand\t$%c,$%0,%1\n"   1
321
reg:    BORI4(reg,rc)           "\tor\t$%c,$%0,%1\n"    1
322
reg:    BORU4(reg,rc)           "\tor\t$%c,$%0,%1\n"    1
323
reg:    BXORI4(reg,rc)          "\txor\t$%c,$%0,%1\n"   1
324
reg:    BXORU4(reg,rc)          "\txor\t$%c,$%0,%1\n"   1
325
reg:    BCOMI4(reg)             "\txnor\t$%c,$0,$%0\n"  1
326
reg:    BCOMU4(reg)             "\txnor\t$%c,$0,$%0\n"  1
327
 
328
rc5:    CNSTI4                  "%a"                    range(a, 0, 31)
329
rc5:    reg                     "$%0"
330
 
331
reg:    LSHI4(reg,rc5)          "\tsll\t$%c,$%0,%1\n"   1
332
reg:    LSHU4(reg,rc5)          "\tsll\t$%c,$%0,%1\n"   1
333
reg:    RSHI4(reg,rc5)          "\tsar\t$%c,$%0,%1\n"   1
334
reg:    RSHU4(reg,rc5)          "\tslr\t$%c,$%0,%1\n"   1
335
 
336
reg:    LOADI1(reg)             "\tadd\t$%c,$0,$%0\n"   move(a)
337
reg:    LOADI2(reg)             "\tadd\t$%c,$0,$%0\n"   move(a)
338
reg:    LOADI4(reg)             "\tadd\t$%c,$0,$%0\n"   move(a)
339
reg:    LOADP4(reg)             "\tadd\t$%c,$0,$%0\n"   move(a)
340
reg:    LOADU1(reg)             "\tadd\t$%c,$0,$%0\n"   move(a)
341
reg:    LOADU2(reg)             "\tadd\t$%c,$0,$%0\n"   move(a)
342
reg:    LOADU4(reg)             "\tadd\t$%c,$0,$%0\n"   move(a)
343
 
344
reg:    CVII4(reg)  "\tsll\t$%c,$%0,8*(4-%a)\n\tsar\t$%c,$%c,8*(4-%a)\n"  2
345
reg:    CVUI4(reg)  "\tand\t$%c,$%0,(1<<(8*%a))-1\n"    1
346
reg:    CVUU4(reg)  "\tand\t$%c,$%0,(1<<(8*%a))-1\n"    1
347
 
348
stmt:   LABELV                  "%a:\n"
349
stmt:   JUMPV(acon)             "\tj\t%0\n"             1
350
stmt:   JUMPV(reg)              "\tjr\t$%0\n"           1
351
 
352
stmt:   EQI4(reg,reg)           "\tbeq\t$%0,$%1,%a\n"   1
353
stmt:   EQU4(reg,reg)           "\tbeq\t$%0,$%1,%a\n"   1
354
stmt:   NEI4(reg,reg)           "\tbne\t$%0,$%1,%a\n"   1
355
stmt:   NEU4(reg,reg)           "\tbne\t$%0,$%1,%a\n"   1
356
stmt:   LEI4(reg,reg)           "\tble\t$%0,$%1,%a\n"   1
357
stmt:   LEU4(reg,reg)           "\tbleu\t$%0,$%1,%a\n"  1
358
stmt:   LTI4(reg,reg)           "\tblt\t$%0,$%1,%a\n"   1
359
stmt:   LTU4(reg,reg)           "\tbltu\t$%0,$%1,%a\n"  1
360
stmt:   GEI4(reg,reg)           "\tbge\t$%0,$%1,%a\n"   1
361
stmt:   GEU4(reg,reg)           "\tbgeu\t$%0,$%1,%a\n"  1
362
stmt:   GTI4(reg,reg)           "\tbgt\t$%0,$%1,%a\n"   1
363
stmt:   GTU4(reg,reg)           "\tbgtu\t$%0,$%1,%a\n"  1
364
 
365
reg:    CALLI4(ar)              "\tjal\t%0\n"           1
366
reg:    CALLP4(ar)              "\tjal\t%0\n"           1
367
reg:    CALLU4(ar)              "\tjal\t%0\n"           1
368
stmt:   CALLV(ar)               "\tjal\t%0\n"           1
369
 
370
ar:     ADDRGP4                 "%a"
371
ar:     reg                     "$%0"
372
ar:     CNSTP4                  "%a"            range(a, 0, 0x03FFFFFF)
373
 
374
stmt:   RETI4(reg)              "# ret\n"               1
375
stmt:   RETP4(reg)              "# ret\n"               1
376
stmt:   RETU4(reg)              "# ret\n"               1
377
stmt:   RETV(reg)               "# ret\n"               1
378
 
379
stmt:   ARGI4(reg)              "# arg\n"               1
380
stmt:   ARGP4(reg)              "# arg\n"               1
381
stmt:   ARGU4(reg)              "# arg\n"               1
382
 
383
 
384
%%
385
 
386
 
387
static void address(Symbol s1, Symbol s2, long n) {
388
  if (s2->scope == GLOBAL ||
389
      s2->sclass == STATIC ||
390
      s2->sclass == EXTERN) {
391
    s1->x.name = stringf("%s%s%D", s2->x.name, n >= 0 ? "+" : "", n);
392
  } else {
393
    assert(n >= INT_MIN && n <= INT_MAX);
394
    s1->x.offset = s2->x.offset + n;
395
    s1->x.name = stringd(s1->x.offset);
396
  }
397
}
398
 
399
 
400
static void defaddress(Symbol s) {
401
  print("\t.word\t%s\n", s->x.name);
402
}
403
 
404
 
405
static void defconst(int suffix, int size, Value v) {
406
  float f;
407
  double d;
408
 
409
  if (suffix == F && size == 4) {
410
    f = v.d;
411
    /* float not supported */
412
  } else
413
  if (suffix == F && size == 8) {
414
    d = v.d;
415
    /* double not supported */
416
  } else
417
  if (suffix == P) {
418
    print("\t.word\t0x%x\n", (unsigned) v.p);
419
  } else
420
  if (size == 1) {
421
    print("\t.byte\t0x%x\n",
422
          (unsigned) ((unsigned char) (suffix == I ? v.i : v.u)));
423
  } else
424
  if (size == 2) {
425
    print("\t.half\t0x%x\n",
426
          (unsigned) ((unsigned short) (suffix == I ? v.i : v.u)));
427
  } else
428
  if (size == 4) {
429
    print("\t.word\t0x%x\n", (unsigned) (suffix == I ? v.i : v.u));
430
  }
431
}
432
 
433
 
434
static void defstring(int n, char *str) {
435
  char *s;
436
 
437
  for (s = str; s < str + n; s++) {
438
    print("\t.byte\t0x%x\n", (*s) & 0xFF);
439
  }
440
}
441
 
442
 
443
static void defsymbol(Symbol s) {
444
  if (s->scope >= LOCAL && s->sclass == STATIC) {
445
    s->x.name = stringf("L.%d", genlabel(1));
446
  } else
447
  if (s->generated) {
448
    s->x.name = stringf("L.%s", s->name);
449
  } else {
450
    assert(s->scope != CONSTANTS || isint(s->type) || isptr(s->type));
451
    s->x.name = s->name;
452
  }
453
}
454
 
455
 
456
static void export(Symbol s) {
457
  print("\t.export\t%s\n", s->name);
458
}
459
 
460
 
461
static int bitcount(unsigned mask) {
462
  unsigned i, n;
463
 
464
  n = 0;
465
  for (i = 1; i != 0; i <<= 1) {
466
    if (mask & i) {
467
      n++;
468
    }
469
  }
470
  return n;
471
}
472
 
473
 
474
static Symbol argreg(int argno, int offset, int ty, int sz, int ty0) {
475
  assert((offset & 3) == 0);
476
  if (offset > 12) {
477
    return NULL;
478
  }
479
  return ireg[(offset / 4) + 4];
480
}
481
 
482
 
483
static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
484
  int i;
485
  Symbol p, q;
486
  Symbol r;
487
  int sizeisave;
488
  int saved;
489
  Symbol argregs[4];
490
 
491
  usedmask[0] = usedmask[1] = 0;
492
  freemask[0] = freemask[1] = ~((unsigned) 0);
493
  offset = 0;
494
  maxoffset = 0;
495
  maxargoffset = 0;
496
  for (i = 0; callee[i] != NULL; i++) {
497
    p = callee[i];
498
    q = caller[i];
499
    assert(q != NULL);
500
    offset = roundup(offset, q->type->align);
501
    p->x.offset = q->x.offset = offset;
502
    p->x.name = q->x.name = stringd(offset);
503
    r = argreg(i, offset, optype(ttob(q->type)),
504
               q->type->size, optype(ttob(caller[0]->type)));
505
    if (i < 4) {
506
      argregs[i] = r;
507
    }
508
    offset = roundup(offset + q->type->size, 4);
509
    if (variadic(f->type)) {
510
      p->sclass = AUTO;
511
    } else
512
    if (r != NULL && ncalls == 0 && !isstruct(q->type) &&
513
        !p->addressed && !(isfloat(q->type) && r->x.regnode->set == IREG)) {
514
      p->sclass = q->sclass = REGISTER;
515
      askregvar(p, r);
516
      assert(p->x.regnode && p->x.regnode->vbl == p);
517
      q->x = p->x;
518
      q->type = p->type;
519
    } else
520
    if (askregvar(p, rmap(ttob(p->type))) &&
521
        r != NULL && (isint(p->type) || p->type == q->type)) {
522
      assert(q->sclass != REGISTER);
523
      p->sclass = q->sclass = REGISTER;
524
      q->type = p->type;
525
    }
526
  }
527
  assert(caller[i] == NULL);
528
  offset = 0;
529
  gencode(caller, callee);
530
  if (ncalls != 0) {
531
    usedmask[IREG] |= ((unsigned) 1) << 31;
532
  }
533
  usedmask[IREG] &= 0x80FF0000;
534
  usedmask[FREG] &= 0xFFF00000;
535
  maxargoffset = roundup(maxargoffset, 4);
536
  if (ncalls != 0 && maxargoffset < 16) {
537
    maxargoffset = 16;
538
  }
539
  sizeisave = 4 * bitcount(usedmask[IREG]);
540
  framesize = roundup(maxargoffset + sizeisave + maxoffset, 16);
541
  segment(CODE);
542
  print("\t.align\t4\n");
543
  print("%s:\n", f->x.name);
544
  if (framesize > 0) {
545
    print("\tsub\t$29,$29,%d\n", framesize);
546
  }
547
  saved = maxargoffset;
548
  for (i = 16; i < 32; i++) {
549
    if (usedmask[IREG] & (1 << i)) {
550
      print("\tstw\t$%d,$29,%d\n", i, saved);
551
      saved += 4;
552
    }
553
  }
554
  for (i = 0; i < 4 && callee[i] != NULL; i++) {
555
    r = argregs[i];
556
    if (r && r->x.regnode != callee[i]->x.regnode) {
557
      Symbol out = callee[i];
558
      Symbol in = caller[i];
559
      int rn = r->x.regnode->number;
560
      int rs = r->x.regnode->set;
561
      int tyin = ttob(in->type);
562
      assert(out && in && r && r->x.regnode);
563
      assert(out->sclass != REGISTER || out->x.regnode);
564
      if (out->sclass == REGISTER &&
565
          (isint(out->type) || out->type == in->type)) {
566
        int outn = out->x.regnode->number;
567
        print("\tadd\t$%d,$0,$%d\n", outn, rn);
568
      } else {
569
        int off = in->x.offset + framesize;
570
        int n = (in->type->size + 3) / 4;
571
        int i;
572
        for (i = rn; i < rn + n && i <= 7; i++) {
573
          print("\tstw\t$%d,$29,%d\n", i, off + (i - rn) * 4);
574
        }
575
      }
576
    }
577
  }
578
  if (variadic(f->type) && callee[i - 1] != NULL) {
579
    i = callee[i - 1]->x.offset + callee[i - 1]->type->size;
580
    for (i = roundup(i, 4)/4; i <= 3; i++) {
581
      print("\tstw\t$%d,$29,%d\n", i + 4, framesize + 4 * i);
582
    }
583
  }
584
  emitcode();
585
  saved = maxargoffset;
586
  for (i = 16; i < 32; i++) {
587
    if (usedmask[IREG] & (1 << i)) {
588
      print("\tldw\t$%d,$29,%d\n", i, saved);
589
      saved += 4;
590
    }
591
  }
592
  if (framesize > 0) {
593
    print("\tadd\t$29,$29,%d\n", framesize);
594
  }
595
  print("\tjr\t$31\n");
596
  print("\n");
597
}
598
 
599
 
600
static void global(Symbol s) {
601
  print("\t.align\t%d\n", s->type->align);
602
  print("%s:\n", s->x.name);
603
}
604
 
605
 
606
static void import(Symbol s) {
607
  print("\t.import\t%s\n", s->name);
608
}
609
 
610
 
611
static void local(Symbol s) {
612
  if (askregvar(s, rmap(ttob(s->type))) == 0) {
613
    mkauto(s);
614
  }
615
}
616
 
617
 
618
static void setSwap(void) {
619
  union {
620
    char c;
621
    int i;
622
  } u;
623
 
624
  u.i = 0;
625
  u.c = 1;
626
  swap = ((u.i == 1) != IR->little_endian);
627
}
628
 
629
 
630
static void progbeg(int argc, char *argv[]) {
631
  int i;
632
 
633
  setSwap();
634
  segment(CODE);
635
  parseflags(argc, argv);
636
  for (i = 0; i < 32; i++) {
637
    ireg[i] = mkreg("%d", i, 1, IREG);
638
  }
639
  iregw = mkwildcard(ireg);
640
  for (i = 0; i < 32; i += 2) {
641
    freg2[i] = mkreg("%d", i, 3, FREG);
642
  }
643
  freg2w = mkwildcard(freg2);
644
  tmask[IREG] = INTTMP;
645
  vmask[IREG] = INTVAR;
646
  tmask[FREG] = FLTTMP;
647
  vmask[FREG] = FLTVAR;
648
}
649
 
650
 
651
static void progend(void) {
652
}
653
 
654
 
655
static void segment(int n) {
656
  static int currSeg = -1;
657
  int newSeg;
658
 
659
  switch (n) {
660
    case CODE:
661
      newSeg = CODE;
662
      break;
663
    case BSS:
664
      newSeg = BSS;
665
      break;
666
    case DATA:
667
      newSeg = DATA;
668
      break;
669
    case LIT:
670
      newSeg = DATA;
671
      break;
672
  }
673
  if (currSeg == newSeg) {
674
    return;
675
  }
676
  switch (newSeg) {
677
    case CODE:
678
      print("\t.code\n");
679
      break;
680
    case BSS:
681
      print("\t.bss\n");
682
      break;
683
    case DATA:
684
      print("\t.data\n");
685
      break;
686
  }
687
  currSeg = newSeg;
688
}
689
 
690
 
691
static void space(int n) {
692
  print("\t.space\t%d\n", n);
693
}
694
 
695
 
696
static Symbol rmap(int opk) {
697
  switch (optype(opk)) {
698
    case I:
699
    case U:
700
    case P:
701
    case B:
702
      return iregw;
703
    case F:
704
      return freg2w;
705
    default:
706
      return 0;
707
  }
708
}
709
 
710
 
711
static void blkfetch(int n1, int n2, int n3, int n4) {
712
  /* not supported yet */
713
}
714
 
715
 
716
static void blkstore(int n1, int n2, int n3, int n4) {
717
  /* not supported yet */
718
}
719
 
720
 
721
static void blkloop(int n1, int n2, int n3, int n4, int n5, int n6[]) {
722
  /* not supported yet */
723
}
724
 
725
 
726
static void emit2(Node p) {
727
  static int ty0;
728
  int ty, sz;
729
  Symbol q;
730
  int src;
731
 
732
  switch (specific(p->op)) {
733
    case ARG+I:
734
    case ARG+P:
735
    case ARG+U:
736
      ty = optype(p->op);
737
      sz = opsize(p->op);
738
      if (p->x.argno == 0) {
739
        ty0 = ty;
740
      }
741
      q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, sz, ty0);
742
      src = getregnum(p->x.kids[0]);
743
      if (q == NULL) {
744
        print("\tstw\t$%d,$29,%d\n", src, p->syms[2]->u.c.v.i);
745
      }
746
      break;
747
  }
748
}
749
 
750
 
751
static void doarg(Node p) {
752
  static int argno;
753
  int align;
754
 
755
  if (argoffset == 0) {
756
    argno = 0;
757
  }
758
  p->x.argno = argno++;
759
  align = p->syms[1]->u.c.v.i < 4 ? 4 : p->syms[1]->u.c.v.i;
760
  p->syms[2] = intconst(mkactual(align, p->syms[0]->u.c.v.i));
761
}
762
 
763
 
764
static void target(Node p) {
765
  static int ty0;
766
  int ty;
767
  Symbol q;
768
 
769
  assert(p);
770
  switch (specific(p->op)) {
771
    case CNST+I:
772
    case CNST+P:
773
    case CNST+U:
774
      if (range(p, 0, 0) == 0) {
775
        setreg(p, ireg[0]);
776
        p->x.registered = 1;
777
      }
778
      break;
779
    case CALL+I:
780
    case CALL+P:
781
    case CALL+U:
782
      rtarget(p, 0, ireg[25]);
783
      setreg(p, ireg[2]);
784
      break;
785
    case CALL+V:
786
      rtarget(p, 0, ireg[25]);
787
      break;
788
    case RET+I:
789
    case RET+P:
790
    case RET+U:
791
      rtarget(p, 0, ireg[2]);
792
      break;
793
    case ARG+I:
794
    case ARG+P:
795
    case ARG+U:
796
      ty = optype(p->op);
797
      q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, opsize(p->op), ty0);
798
      if (p->x.argno == 0) {
799
        ty0 = ty;
800
      }
801
      if (q && !(ty == F && q->x.regnode->set == IREG)) {
802
        rtarget(p, 0, q);
803
      }
804
      break;
805
  }
806
}
807
 
808
 
809
static void clobber(Node p) {
810
  assert(p);
811
  switch (specific(p->op)) {
812
    case CALL+F:
813
      spill(INTTMP | INTRET, IREG, p);
814
      spill(FLTTMP, FREG, p);
815
      break;
816
    case CALL+I:
817
    case CALL+P:
818
    case CALL+U:
819
      spill(INTTMP, IREG, p);
820
      spill(FLTTMP | FLTRET, FREG, p);
821
      break;
822
    case CALL+V:
823
      spill(INTTMP | INTRET, IREG, p);
824
      spill(FLTTMP | FLTRET, FREG, p);
825
      break;
826
  }
827
}
828
 
829
 
830
Interface eco32IR = {
831
  1, 1, 0,  /* char */
832
  2, 2, 0,  /* short */
833
  4, 4, 0,  /* int */
834
  4, 4, 0,  /* long */
835
  4, 4, 0,  /* long long */
836
  4, 4, 1,  /* float */
837
  8, 8, 1,  /* double */
838
  8, 8, 1,  /* long double */
839
  4, 4, 0,  /* T * */
840
  0, 1, 0,  /* struct */
841
  0,        /* little_endian */
842
  0,        /* mulops_calls */
843
  0,        /* wants_callb */
844
  1,        /* wants_argb */
845
  1,        /* left_to_right */
846
  0,        /* wants_dag */
847
  0,        /* unsigned_char */
848
  address,
849
  blockbeg,
850
  blockend,
851
  defaddress,
852
  defconst,
853
  defstring,
854
  defsymbol,
855
  emit,
856
  export,
857
  function,
858
  gen,
859
  global,
860
  import,
861
  local,
862
  progbeg,
863
  progend,
864
  segment,
865
  space,
866
  0, 0, 0, 0, 0, 0, 0,
867
  {
868
    1,      /* max_unaligned_load */
869
    rmap,
870
    blkfetch, blkstore, blkloop,
871
    _label,
872
    _rule,
873
    _nts,
874
    _kids,
875
    _string,
876
    _templates,
877
    _isinstruction,
878
    _ntname,
879
    emit2,
880
    doarg,
881
    target,
882
    clobber
883
  }
884
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.