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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [eco32.md.SAVE-1] - Blame information for rev 49

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

powered by: WebSVN 2.1.0

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