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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [eco32.md] - Blame information for rev 252

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
reg:    INDIRF4(VREGP)          "# read register\n"
389
stmt:   ASGNF4(VREGP,reg)       "# write register\n"
390
reg:    INDIRF4(addr)           ";FP: l.s $f%c,%0\n"            1
391
stmt:   ASGNF4(addr,reg)        ";FP: s.s $f%1,%0\n"            1
392
reg:    ADDF4(reg,reg)          ";FP: add.s $f%c,$f%0,$f%1\n"   1
393
reg:    SUBF4(reg,reg)          ";FP: sub.s $f%c,$f%0,$f%1\n"   1
394
reg:    MULF4(reg,reg)          ";FP: mul.s $f%c,$f%0,$f%1\n"   1
395
reg:    DIVF4(reg,reg)          ";FP: div.s $f%c,$f%0,$f%1\n"   1
396
reg:    LOADF4(reg)             ";FP: mov.s $f%c,$f%0\n"        1
397
reg:    NEGF4(reg)              ";FP: neg.s $f%c,$f%0\n"        1
398
reg:    CVFF4(reg)              ";FP: cvt.s.d $f%c,$f%0\n"      1
399
reg:    CVIF4(reg)              ";FP: mtc1 $%0,$f%c; cvt.s.w $f%c,$f%c\n"      1
400
reg:    CVFI4(reg)              ";FP: trunc.w.s $f2,$f%0,$%c; mfc1 $%c,$f2\n"  (a->syms[0]->u.c.v.i == 4 ? 1 : LBURG_MAX)
401
stmt:   EQF4(reg,reg)           ";FP: c.eq.s $f%0,$f%1; bc1t %a\n"      1
402
stmt:   LEF4(reg,reg)           ";FP: c.ule.s $f%0,$f%1; bc1t %a\n"     1
403
stmt:   LTF4(reg,reg)           ";FP: c.ult.s $f%0,$f%1; bc1t %a\n"     1
404
stmt:   GEF4(reg,reg)           ";FP: c.lt.s $f%0,$f%1; bc1f %a\n"      1
405
stmt:   GTF4(reg,reg)           ";FP: c.le.s $f%0,$f%1; bc1f %a\n"      1
406
stmt:   NEF4(reg,reg)           ";FP: c.eq.s $f%0,$f%1; bc1f %a\n"      1
407
reg:    CALLF4(ar)              "\tjal\t%0\n"                   1
408
stmt:   RETF4(reg)              "# ret\n"                       1
409
stmt:   ARGF4(reg)              "# arg\n"                       1
410
 
411
reg:    INDIRF8(VREGP)          "# read register\n"
412
stmt:   ASGNF8(VREGP,reg)       "# write register\n"
413
reg:    INDIRF8(addr)           ";FP: l.d $f%c,%0\n"            1
414
stmt:   ASGNF8(addr,reg)        ";FP: s.d $f%1,%0\n"            1
415
reg:    ADDF8(reg,reg)          ";FP: add.d $f%c,$f%0,$f%1\n"   1
416
reg:    SUBF8(reg,reg)          ";FP: sub.d $f%c,$f%0,$f%1\n"   1
417
reg:    MULF8(reg,reg)          ";FP: mul.d $f%c,$f%0,$f%1\n"   1
418
reg:    DIVF8(reg,reg)          ";FP: div.d $f%c,$f%0,$f%1\n"   1
419
reg:    LOADF8(reg)             ";FP: mov.d $f%c,$f%0\n"        1
420
reg:    NEGF8(reg)              ";FP: neg.d $f%c,$f%0\n"        1
421
reg:    CVFF8(reg)              ";FP: cvt.d.s $f%c,$f%0\n"      1
422
reg:    CVIF8(reg)              ";FP: mtc1 $%0,$f%c; cvt.d.w $f%c,$f%c\n"      1
423
reg:    CVFI4(reg)              ";FP: trunc.w.d $f2,$f%0,$%c; mfc1 $%c,$f2\n"  (a->syms[0]->u.c.v.i == 8 ? 1 : LBURG_MAX)
424
stmt:   EQF8(reg,reg)           ";FP: c.eq.d $f%0,$f%1; bc1t %a\n"      1
425
stmt:   LEF8(reg,reg)           ";FP: c.ule.d $f%0,$f%1; bc1t %a\n"     1
426
stmt:   LTF8(reg,reg)           ";FP: c.ult.d $f%0,$f%1; bc1t %a\n"     1
427
stmt:   GEF8(reg,reg)           ";FP: c.lt.d $f%0,$f%1; bc1f %a\n"      1
428
stmt:   GTF8(reg,reg)           ";FP: c.le.d $f%0,$f%1; bc1f %a\n"      1
429
stmt:   NEF8(reg,reg)           ";FP: c.eq.d $f%0,$f%1; bc1f %a\n"      1
430
reg:    CALLF8(ar)              "\tjal\t%0\n"                   1
431
stmt:   RETF8(reg)              "# ret\n"                       1
432
stmt:   ARGF8(reg)              "# arg\n"                       1
433
 
434
 
435
%%
436
 
437
 
438
static void address(Symbol s1, Symbol s2, long n) {
439
  if (s2->scope == GLOBAL ||
440
      s2->sclass == STATIC ||
441
      s2->sclass == EXTERN) {
442
    s1->x.name = stringf("%s%s%D", s2->x.name, n >= 0 ? "+" : "", n);
443
  } else {
444
    assert(n >= INT_MIN && n <= INT_MAX);
445
    s1->x.offset = s2->x.offset + n;
446
    s1->x.name = stringd(s1->x.offset);
447
  }
448
}
449
 
450
 
451
static void defaddress(Symbol s) {
452
  print("\t.word\t%s\n", s->x.name);
453
}
454
 
455
 
456
static void defconst(int suffix, int size, Value v) {
457
  float f;
458
  double d;
459
  unsigned *p;
460
 
461
  if (suffix == F && size == 4) {
462
    f = v.d;
463
    print("\t.word\t0x%x\n", * (unsigned *) &f);
464
  } else
465
  if (suffix == F && size == 8) {
466
    d = v.d;
467
    p = (unsigned *) &d;
468
    print("\t.word\t0x%x\n", p[swap]);
469
    print("\t.word\t0x%x\n", p[1 - swap]);
470
  } else
471
  if (suffix == P) {
472 252 hellwig
    print("\t.word\t0x%lx\n", (unsigned long) v.p);
473 4 hellwig
  } else
474
  if (size == 1) {
475
    print("\t.byte\t0x%x\n",
476
          (unsigned) ((unsigned char) (suffix == I ? v.i : v.u)));
477
  } else
478
  if (size == 2) {
479
    print("\t.half\t0x%x\n",
480
          (unsigned) ((unsigned short) (suffix == I ? v.i : v.u)));
481
  } else
482
  if (size == 4) {
483
    print("\t.word\t0x%x\n", (unsigned) (suffix == I ? v.i : v.u));
484
  }
485
}
486
 
487
 
488
static void defstring(int n, char *str) {
489
  char *s;
490
 
491
  for (s = str; s < str + n; s++) {
492
    print("\t.byte\t0x%x\n", (*s) & 0xFF);
493
  }
494
}
495
 
496
 
497
static void defsymbol(Symbol s) {
498
  if (s->scope >= LOCAL && s->sclass == STATIC) {
499
    s->x.name = stringf("L.%d", genlabel(1));
500
  } else
501
  if (s->generated) {
502
    s->x.name = stringf("L.%s", s->name);
503
  } else {
504
    assert(s->scope != CONSTANTS || isint(s->type) || isptr(s->type));
505
    s->x.name = s->name;
506
  }
507
}
508
 
509
 
510
static void export(Symbol s) {
511
  print("\t.export\t%s\n", s->name);
512
}
513
 
514
 
515
static int bitcount(unsigned mask) {
516
  unsigned i, n;
517
 
518
  n = 0;
519
  for (i = 1; i != 0; i <<= 1) {
520
    if (mask & i) {
521
      n++;
522
    }
523
  }
524
  return n;
525
}
526
 
527
 
528
static Symbol argreg(int argno, int offset, int ty, int sz, int ty0) {
529
  assert((offset & 3) == 0);
530
  if (offset > 12) {
531
    return NULL;
532
  }
533
  return ireg[(offset / 4) + 4];
534
}
535
 
536
 
537
static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
538
  int i;
539
  Symbol p, q;
540
  Symbol r;
541
  int sizeisave;
542
  int saved;
543
  Symbol argregs[4];
544
 
545
  usedmask[0] = usedmask[1] = 0;
546
  freemask[0] = freemask[1] = ~((unsigned) 0);
547
  offset = 0;
548
  maxoffset = 0;
549
  maxargoffset = 0;
550
  for (i = 0; callee[i] != NULL; i++) {
551
    p = callee[i];
552
    q = caller[i];
553
    assert(q != NULL);
554
    offset = roundup(offset, q->type->align);
555
    p->x.offset = q->x.offset = offset;
556
    p->x.name = q->x.name = stringd(offset);
557
    r = argreg(i, offset, optype(ttob(q->type)),
558
               q->type->size, optype(ttob(caller[0]->type)));
559
    if (i < 4) {
560
      argregs[i] = r;
561
    }
562
    offset = roundup(offset + q->type->size, 4);
563
    if (variadic(f->type)) {
564
      p->sclass = AUTO;
565
    } else
566
    if (r != NULL && ncalls == 0 && !isstruct(q->type) &&
567
        !p->addressed && !(isfloat(q->type) && r->x.regnode->set == IREG)) {
568
      p->sclass = q->sclass = REGISTER;
569
      askregvar(p, r);
570
      assert(p->x.regnode && p->x.regnode->vbl == p);
571
      q->x = p->x;
572
      q->type = p->type;
573
    } else
574
    if (askregvar(p, rmap(ttob(p->type))) &&
575
        r != NULL && (isint(p->type) || p->type == q->type)) {
576
      assert(q->sclass != REGISTER);
577
      p->sclass = q->sclass = REGISTER;
578
      q->type = p->type;
579
    }
580
  }
581
  assert(caller[i] == NULL);
582
  offset = 0;
583
  gencode(caller, callee);
584
  if (ncalls != 0) {
585
    usedmask[IREG] |= ((unsigned) 1) << 31;
586
  }
587
  usedmask[IREG] &= 0x80FF0000;
588
  usedmask[FREG] &= 0xFFF00000;
589
  maxargoffset = roundup(maxargoffset, 4);
590
  if (ncalls != 0 && maxargoffset < 16) {
591
    maxargoffset = 16;
592
  }
593
  sizeisave = 4 * bitcount(usedmask[IREG]);
594
  framesize = roundup(maxargoffset + sizeisave + maxoffset, 16);
595
  segment(CODE);
596
  print("\t.align\t4\n");
597
  print("%s:\n", f->x.name);
598
  if (framesize > 0) {
599
    print("\tsub\t$29,$29,%d\n", framesize);
600
  }
601
  saved = maxargoffset;
602
  for (i = 16; i < 32; i++) {
603
    if (usedmask[IREG] & (1 << i)) {
604
      print("\tstw\t$%d,$29,%d\n", i, saved);
605
      saved += 4;
606
    }
607
  }
608
  for (i = 0; i < 4 && callee[i] != NULL; i++) {
609
    r = argregs[i];
610
    if (r && r->x.regnode != callee[i]->x.regnode) {
611
      Symbol out = callee[i];
612
      Symbol in = caller[i];
613
      int rn = r->x.regnode->number;
614
      int rs = r->x.regnode->set;
615
      int tyin = ttob(in->type);
616
      assert(out && in && r && r->x.regnode);
617
      assert(out->sclass != REGISTER || out->x.regnode);
618
      if (out->sclass == REGISTER &&
619
          (isint(out->type) || out->type == in->type)) {
620
        int outn = out->x.regnode->number;
621
        print("\tadd\t$%d,$0,$%d\n", outn, rn);
622
      } else {
623
        int off = in->x.offset + framesize;
624
        int n = (in->type->size + 3) / 4;
625
        int i;
626
        for (i = rn; i < rn + n && i <= 7; i++) {
627
          print("\tstw\t$%d,$29,%d\n", i, off + (i - rn) * 4);
628
        }
629
      }
630
    }
631
  }
632
  if (variadic(f->type) && callee[i - 1] != NULL) {
633
    i = callee[i - 1]->x.offset + callee[i - 1]->type->size;
634
    for (i = roundup(i, 4)/4; i <= 3; i++) {
635
      print("\tstw\t$%d,$29,%d\n", i + 4, framesize + 4 * i);
636
    }
637
  }
638
  emitcode();
639
  saved = maxargoffset;
640
  for (i = 16; i < 32; i++) {
641
    if (usedmask[IREG] & (1 << i)) {
642
      print("\tldw\t$%d,$29,%d\n", i, saved);
643
      saved += 4;
644
    }
645
  }
646
  if (framesize > 0) {
647
    print("\tadd\t$29,$29,%d\n", framesize);
648
  }
649
  print("\tjr\t$31\n");
650
  print("\n");
651
}
652
 
653
 
654
static void global(Symbol s) {
655
  if (s->type->align != 0) {
656
    print("\t.align\t%d\n", s->type->align);
657
  } else {
658
    print("\t.align\t%d\n", 4);
659
  }
660
  print("%s:\n", s->x.name);
661
}
662
 
663
 
664
static void import(Symbol s) {
665
  print("\t.import\t%s\n", s->name);
666
}
667
 
668
 
669
static void local(Symbol s) {
670
  if (askregvar(s, rmap(ttob(s->type))) == 0) {
671
    mkauto(s);
672
  }
673
}
674
 
675
 
676
static void setSwap(void) {
677
  union {
678
    char c;
679
    int i;
680
  } u;
681
 
682
  u.i = 0;
683
  u.c = 1;
684
  swap = ((u.i == 1) != IR->little_endian);
685
}
686
 
687
 
688
static void progbeg(int argc, char *argv[]) {
689
  int i;
690
 
691
  setSwap();
692
  segment(CODE);
693
  parseflags(argc, argv);
694
  for (i = 0; i < 32; i++) {
695
    ireg[i] = mkreg("%d", i, 1, IREG);
696
  }
697
  iregw = mkwildcard(ireg);
698
  for (i = 0; i < 32; i += 2) {
699
    freg2[i] = mkreg("%d", i, 3, FREG);
700
  }
701
  freg2w = mkwildcard(freg2);
702
  tmask[IREG] = INTTMP;
703
  vmask[IREG] = INTVAR;
704
  tmask[FREG] = FLTTMP;
705
  vmask[FREG] = FLTVAR;
706
  blkreg = mkreg("8", 8, 7, IREG);
707
}
708
 
709
 
710
static void progend(void) {
711
}
712
 
713
 
714
static void segment(int n) {
715
  static int currSeg = -1;
716
  int newSeg;
717
 
718
  switch (n) {
719
    case CODE:
720
      newSeg = CODE;
721
      break;
722
    case BSS:
723
      newSeg = BSS;
724
      break;
725
    case DATA:
726
      newSeg = DATA;
727
      break;
728
    case LIT:
729
      newSeg = DATA;
730
      break;
731
  }
732
  if (currSeg == newSeg) {
733
    return;
734
  }
735
  switch (newSeg) {
736
    case CODE:
737
      print("\t.code\n");
738
      break;
739
    case BSS:
740
      print("\t.bss\n");
741
      break;
742
    case DATA:
743
      print("\t.data\n");
744
      break;
745
  }
746
  currSeg = newSeg;
747
}
748
 
749
 
750
static void space(int n) {
751
  print("\t.space\t%d\n", n);
752
}
753
 
754
 
755
static Symbol rmap(int opk) {
756
  switch (optype(opk)) {
757
    case I:
758
    case U:
759
    case P:
760
    case B:
761
      return iregw;
762
    case F:
763
      return freg2w;
764
    default:
765
      return 0;
766
  }
767
}
768
 
769
 
770
static void blkfetch(int size, int off, int reg, int tmp) {
771
  assert(size == 1 || size == 2 || size == 4);
772
  if (size == 1) {
773
    print("\tldbu\t$%d,$%d,%d\n", tmp, reg, off);
774
  } else
775
  if (size == 2) {
776
    print("\tldhu\t$%d,$%d,%d\n", tmp, reg, off);
777
  } else
778
  if (size == 4) {
779
    print("\tldw\t$%d,$%d,%d\n", tmp, reg, off);
780
  }
781
}
782
 
783
 
784
static void blkstore(int size, int off, int reg, int tmp) {
785
  assert(size == 1 || size == 2 || size == 4);
786
  if (size == 1) {
787
    print("\tstb\t$%d,$%d,%d\n", tmp, reg, off);
788
  } else
789
  if (size == 2) {
790
    print("\tsth\t$%d,$%d,%d\n", tmp, reg, off);
791
  } else
792
  if (size == 4) {
793
    print("\tstw\t$%d,$%d,%d\n", tmp, reg, off);
794
  }
795
}
796
 
797
 
798
static void blkloop(int dreg, int doff,
799
                    int sreg, int soff,
800
                    int size, int tmps[]) {
801
  int label;
802
 
803
  label = genlabel(1);
804
  print("\tadd\t$%d,$%d,%d\n", sreg, sreg, size & ~7);
805
  print("\tadd\t$%d,$%d,%d\n", tmps[2], dreg, size & ~7);
806
  blkcopy(tmps[2], doff, sreg, soff, size & 7, tmps);
807
  print("L.%d:\n", label);
808
  print("\tsub\t$%d,$%d,%d\n", sreg, sreg, 8);
809
  print("\tsub\t$%d,$%d,%d\n", tmps[2], tmps[2], 8);
810
  blkcopy(tmps[2], doff, sreg, soff, 8, tmps);
811
  print("\tbltu\t$%d,$%d,L.%d\n", dreg, tmps[2], label);
812
}
813
 
814
 
815
static void emit2(Node p) {
816
  static int ty0;
817
  int ty, sz;
818
  Symbol q;
819
  int src;
820
  int dst, n;
821
 
822
  switch (specific(p->op)) {
823
    case ARG+I:
824
    case ARG+P:
825
    case ARG+U:
826
      ty = optype(p->op);
827
      sz = opsize(p->op);
828
      if (p->x.argno == 0) {
829
        ty0 = ty;
830
      }
831
      q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, sz, ty0);
832
      src = getregnum(p->x.kids[0]);
833
      if (q == NULL) {
834
        print("\tstw\t$%d,$29,%d\n", src, p->syms[2]->u.c.v.i);
835
      }
836
      break;
837
    case ASGN+B:
838
      dalign = p->syms[1]->u.c.v.i;
839
      salign = p->syms[1]->u.c.v.i;
840
      blkcopy(getregnum(p->x.kids[0]), 0,
841
              getregnum(p->x.kids[1]), 0,
842
              p->syms[0]->u.c.v.i, tmpregs);
843
      break;
844
    case ARG+B:
845
      dalign = 4;
846
      salign = p->syms[1]->u.c.v.i;
847
      blkcopy(29, p->syms[2]->u.c.v.i,
848
              getregnum(p->x.kids[0]), 0,
849
              p->syms[0]->u.c.v.i, tmpregs);
850
      n = p->syms[2]->u.c.v.i + p->syms[0]->u.c.v.i;
851
      dst = p->syms[2]->u.c.v.i;
852
      for (; dst <= 12 && dst < n; dst += 4) {
853
        print("\tldw\t$%d,$29,%d\n", (dst / 4) + 4, dst);
854
      }
855
      break;
856
  }
857
}
858
 
859
 
860
static void doarg(Node p) {
861
  static int argno;
862
  int align;
863
  int size;
864
  int offset;
865
 
866
  if (argoffset == 0) {
867
    argno = 0;
868
  }
869
  p->x.argno = argno++;
870
  align = p->syms[1]->u.c.v.i;
871
  if (align < 4) {
872
    align = 4;
873
  }
874
  size = p->syms[0]->u.c.v.i;
875
  offset = mkactual(align, size);
876
  p->syms[2] = intconst(offset);
877
}
878
 
879
 
880
static void target(Node p) {
881
  static int ty0;
882
  int ty;
883
  Symbol q;
884
 
885
  assert(p);
886
  switch (specific(p->op)) {
887
    case CNST+I:
888
    case CNST+P:
889
    case CNST+U:
890
      if (range(p, 0, 0) == 0) {
891
        setreg(p, ireg[0]);
892
        p->x.registered = 1;
893
      }
894
      break;
895
    case CALL+I:
896
    case CALL+P:
897
    case CALL+U:
898
      rtarget(p, 0, ireg[25]);
899
      setreg(p, ireg[2]);
900
      break;
901
    case CALL+F:
902
      rtarget(p, 0, ireg[25]);
903
      setreg(p, freg2[0]);
904
      break;
905
    case CALL+V:
906
      rtarget(p, 0, ireg[25]);
907
      break;
908
    case RET+I:
909
    case RET+P:
910
    case RET+U:
911
      rtarget(p, 0, ireg[2]);
912
      break;
913
    case RET+F:
914
      rtarget(p, 0, freg2[0]);
915
      break;
916
    case ARG+I:
917
    case ARG+P:
918
    case ARG+U:
919
    case ARG+F:
920
      ty = optype(p->op);
921
      q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, opsize(p->op), ty0);
922
      if (p->x.argno == 0) {
923
        ty0 = ty;
924
      }
925
      if (q && !(ty == F && q->x.regnode->set == IREG)) {
926
        rtarget(p, 0, q);
927
      }
928
      break;
929
    case ASGN+B:
930
      rtarget(p->kids[1], 0, blkreg);
931
      break;
932
    case ARG+B:
933
      rtarget(p->kids[0], 0, blkreg);
934
      break;
935
  }
936
}
937
 
938
 
939
static void clobber(Node p) {
940
  assert(p);
941
  switch (specific(p->op)) {
942
    case CALL+F:
943
      spill(INTTMP | INTRET, IREG, p);
944
      spill(FLTTMP, FREG, p);
945
      break;
946
    case CALL+I:
947
    case CALL+P:
948
    case CALL+U:
949
      spill(INTTMP, IREG, p);
950
      spill(FLTTMP | FLTRET, FREG, p);
951
      break;
952
    case CALL+V:
953
      spill(INTTMP | INTRET, IREG, p);
954
      spill(FLTTMP | FLTRET, FREG, p);
955
      break;
956
  }
957
}
958
 
959
 
960
Interface eco32IR = {
961
  1, 1, 0,  /* char */
962
  2, 2, 0,  /* short */
963
  4, 4, 0,  /* int */
964
  4, 4, 0,  /* long */
965
  4, 4, 0,  /* long long */
966
  4, 4, 1,  /* float */
967
  8, 4, 1,  /* double */
968
  8, 4, 1,  /* long double */
969
  4, 4, 0,  /* T * */
970
  0, 1, 0,  /* struct */
971
  0,        /* little_endian */
972
  0,        /* mulops_calls */
973
  0,        /* wants_callb */
974
  1,        /* wants_argb */
975
  1,        /* left_to_right */
976
  0,        /* wants_dag */
977
  0,        /* unsigned_char */
978
  address,
979
  blockbeg,
980
  blockend,
981
  defaddress,
982
  defconst,
983
  defstring,
984
  defsymbol,
985
  emit,
986
  export,
987
  function,
988
  gen,
989
  global,
990
  import,
991
  local,
992
  progbeg,
993
  progend,
994
  segment,
995
  space,
996
  0, 0, 0, 0, 0, 0, 0,
997
  {
998
    1,      /* max_unaligned_load */
999
    rmap,
1000
    blkfetch, blkstore, blkloop,
1001
    _label,
1002
    _rule,
1003
    _nts,
1004
    _kids,
1005
    _string,
1006
    _templates,
1007
    _isinstruction,
1008
    _ntname,
1009
    emit2,
1010
    doarg,
1011
    target,
1012
    clobber
1013
  }
1014
};

powered by: WebSVN 2.1.0

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