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

Subversion Repositories eco32

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
%{
2
#define INTTMP 0x0100ff00
3
#define INTVAR 0x40ff0000
4
#define FLTTMP 0x000f0ff0
5
#define FLTVAR 0xfff00000
6
 
7
#define INTRET 0x00000004
8
#define FLTRET 0x00000003
9
 
10
#define readsreg(p) \
11
        (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P)
12
#define setsrc(d) ((d) && (d)->x.regnode && \
13
        (d)->x.regnode->set == src->x.regnode->set && \
14
        (d)->x.regnode->mask&src->x.regnode->mask)
15
 
16
#define relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b))
17
 
18
#include "c.h"
19
#define NODEPTR_TYPE Node
20
#define OP_LABEL(p) ((p)->op)
21
#define LEFT_CHILD(p) ((p)->kids[0])
22
#define RIGHT_CHILD(p) ((p)->kids[1])
23
#define STATE_LABEL(p) ((p)->x.state)
24
static void address(Symbol, Symbol, long);
25
static void blkfetch(int, int, int, int);
26
static void blkloop(int, int, int, int, int, int[]);
27
static void blkstore(int, int, int, int);
28
static void defaddress(Symbol);
29
static void defconst(int, int, Value);
30
static void defstring(int, char *);
31
static void defsymbol(Symbol);
32
static void doarg(Node);
33
static void emit2(Node);
34
static void export(Symbol);
35
static void clobber(Node);
36
static void function(Symbol, Symbol [], Symbol [], int);
37
static void global(Symbol);
38
static void import(Symbol);
39
static void local(Symbol);
40
static void progbeg(int, char **);
41
static void progend(void);
42
static void segment(int);
43
static void space(int);
44
static void target(Node);
45
static int      bitcount       (unsigned);
46
static Symbol   argreg         (int, int, int, int, int);
47
 
48
static Symbol ireg[32], freg2[32], d6;
49
static Symbol iregw, freg2w;
50
static int tmpregs[] = {3, 9, 10};
51
static Symbol blkreg;
52
 
53
static int gnum = 8;
54
static int pic;
55
 
56
static int cseg;
57
%}
58
%start stmt
59
%term CNSTF4=4113
60
%term CNSTF8=8209
61
%term CNSTF16=16401
62
%term CNSTI1=1045
63
%term CNSTI2=2069
64
%term CNSTI4=4117
65
%term CNSTI8=8213
66
%term CNSTP4=4119
67
%term CNSTP8=8215
68
%term CNSTU1=1046
69
%term CNSTU2=2070
70
%term CNSTU4=4118
71
%term CNSTU8=8214
72
 
73
%term ARGB=41
74
%term ARGF4=4129
75
%term ARGF8=8225
76
%term ARGF16=16417
77
%term ARGI4=4133
78
%term ARGI8=8229
79
%term ARGP4=4135
80
%term ARGP8=8231
81
%term ARGU4=4134
82
%term ARGU8=8230
83
 
84
%term ASGNB=57
85
%term ASGNF4=4145
86
%term ASGNF8=8241
87
%term ASGNF16=16433
88
%term ASGNI1=1077
89
%term ASGNI2=2101
90
%term ASGNI4=4149
91
%term ASGNI8=8245
92
%term ASGNP4=4151
93
%term ASGNP8=8247
94
%term ASGNU1=1078
95
%term ASGNU2=2102
96
%term ASGNU4=4150
97
%term ASGNU8=8246
98
 
99
%term INDIRB=73
100
%term INDIRF4=4161
101
%term INDIRF8=8257
102
%term INDIRF16=16449
103
%term INDIRI1=1093
104
%term INDIRI2=2117
105
%term INDIRI4=4165
106
%term INDIRI8=8261
107
%term INDIRP4=4167
108
%term INDIRP8=8263
109
%term INDIRU1=1094
110
%term INDIRU2=2118
111
%term INDIRU4=4166
112
%term INDIRU8=8262
113
 
114
%term CVFF4=4209
115
%term CVFF8=8305
116
%term CVFF16=16497
117
%term CVFI4=4213
118
%term CVFI8=8309
119
 
120
%term CVIF4=4225
121
%term CVIF8=8321
122
%term CVIF16=16513
123
%term CVII1=1157
124
%term CVII2=2181
125
%term CVII4=4229
126
%term CVII8=8325
127
%term CVIU1=1158
128
%term CVIU2=2182
129
%term CVIU4=4230
130
%term CVIU8=8326
131
 
132
%term CVPP4=4247
133
%term CVPP8=8343
134
%term CVPP16=16535
135
%term CVPU4=4246
136
%term CVPU8=8342
137
 
138
%term CVUI1=1205
139
%term CVUI2=2229
140
%term CVUI4=4277
141
%term CVUI8=8373
142
%term CVUP4=4279
143
%term CVUP8=8375
144
%term CVUP16=16567
145
%term CVUU1=1206
146
%term CVUU2=2230
147
%term CVUU4=4278
148
%term CVUU8=8374
149
 
150
%term NEGF4=4289
151
%term NEGF8=8385
152
%term NEGF16=16577
153
%term NEGI4=4293
154
%term NEGI8=8389
155
 
156
%term CALLB=217
157
%term CALLF4=4305
158
%term CALLF8=8401
159
%term CALLF16=16593
160
%term CALLI4=4309
161
%term CALLI8=8405
162
%term CALLP4=4311
163
%term CALLP8=8407
164
%term CALLU4=4310
165
%term CALLU8=8406
166
%term CALLV=216
167
 
168
%term RETF4=4337
169
%term RETF8=8433
170
%term RETF16=16625
171
%term RETI4=4341
172
%term RETI8=8437
173
%term RETP4=4343
174
%term RETP8=8439
175
%term RETU4=4342
176
%term RETU8=8438
177
%term RETV=248
178
 
179
%term ADDRGP4=4359
180
%term ADDRGP8=8455
181
 
182
%term ADDRFP4=4375
183
%term ADDRFP8=8471
184
 
185
%term ADDRLP4=4391
186
%term ADDRLP8=8487
187
 
188
%term ADDF4=4401
189
%term ADDF8=8497
190
%term ADDF16=16689
191
%term ADDI4=4405
192
%term ADDI8=8501
193
%term ADDP4=4407
194
%term ADDP8=8503
195
%term ADDU4=4406
196
%term ADDU8=8502
197
 
198
%term SUBF4=4417
199
%term SUBF8=8513
200
%term SUBF16=16705
201
%term SUBI4=4421
202
%term SUBI8=8517
203
%term SUBP4=4423
204
%term SUBP8=8519
205
%term SUBU4=4422
206
%term SUBU8=8518
207
 
208
%term LSHI4=4437
209
%term LSHI8=8533
210
%term LSHU4=4438
211
%term LSHU8=8534
212
 
213
%term MODI4=4453
214
%term MODI8=8549
215
%term MODU4=4454
216
%term MODU8=8550
217
 
218
%term RSHI4=4469
219
%term RSHI8=8565
220
%term RSHU4=4470
221
%term RSHU8=8566
222
 
223
%term BANDI4=4485
224
%term BANDI8=8581
225
%term BANDU4=4486
226
%term BANDU8=8582
227
 
228
%term BCOMI4=4501
229
%term BCOMI8=8597
230
%term BCOMU4=4502
231
%term BCOMU8=8598
232
 
233
%term BORI4=4517
234
%term BORI8=8613
235
%term BORU4=4518
236
%term BORU8=8614
237
 
238
%term BXORI4=4533
239
%term BXORI8=8629
240
%term BXORU4=4534
241
%term BXORU8=8630
242
 
243
%term DIVF4=4545
244
%term DIVF8=8641
245
%term DIVF16=16833
246
%term DIVI4=4549
247
%term DIVI8=8645
248
%term DIVU4=4550
249
%term DIVU8=8646
250
 
251
%term MULF4=4561
252
%term MULF8=8657
253
%term MULF16=16849
254
%term MULI4=4565
255
%term MULI8=8661
256
%term MULU4=4566
257
%term MULU8=8662
258
 
259
%term EQF4=4577
260
%term EQF8=8673
261
%term EQF16=16865
262
%term EQI4=4581
263
%term EQI8=8677
264
%term EQU4=4582
265
%term EQU8=8678
266
 
267
%term GEF4=4593
268
%term GEF8=8689
269
%term GEI4=4597
270
%term GEI8=8693
271
%term GEI16=16885
272
%term GEU4=4598
273
%term GEU8=8694
274
 
275
%term GTF4=4609
276
%term GTF8=8705
277
%term GTF16=16897
278
%term GTI4=4613
279
%term GTI8=8709
280
%term GTU4=4614
281
%term GTU8=8710
282
 
283
%term LEF4=4625
284
%term LEF8=8721
285
%term LEF16=16913
286
%term LEI4=4629
287
%term LEI8=8725
288
%term LEU4=4630
289
%term LEU8=8726
290
 
291
%term LTF4=4641
292
%term LTF8=8737
293
%term LTF16=16929
294
%term LTI4=4645
295
%term LTI8=8741
296
%term LTU4=4646
297
%term LTU8=8742
298
 
299
%term NEF4=4657
300
%term NEF8=8753
301
%term NEF16=16945
302
%term NEI4=4661
303
%term NEI8=8757
304
%term NEU4=4662
305
%term NEU8=8758
306
 
307
%term JUMPV=584
308
 
309
%term LABELV=600
310
 
311
%term LOADB=233
312
%term LOADF4=4321
313
%term LOADF8=8417
314
%term LOADF16=16609
315
%term LOADI1=1253
316
%term LOADI2=2277
317
%term LOADI4=4325
318
%term LOADI8=8421
319
%term LOADP4=4327
320
%term LOADP8=8423
321
%term LOADU1=1254
322
%term LOADU2=2278
323
%term LOADU4=4326
324
%term LOADU8=8422
325
 
326
%term VREGP=711
327
%%
328
reg:  INDIRI1(VREGP)     "# read register\n"
329
reg:  INDIRU1(VREGP)     "# read register\n"
330
 
331
reg:  INDIRI2(VREGP)     "# read register\n"
332
reg:  INDIRU2(VREGP)     "# read register\n"
333
 
334
reg:  INDIRF4(VREGP)     "# read register\n"
335
reg:  INDIRI4(VREGP)     "# read register\n"
336
reg:  INDIRP4(VREGP)     "# read register\n"
337
reg:  INDIRU4(VREGP)     "# read register\n"
338
 
339
reg:  INDIRF8(VREGP)     "# read register\n"
340
reg:  INDIRI8(VREGP)     "# read register\n"
341
reg:  INDIRP8(VREGP)     "# read register\n"
342
reg:  INDIRU8(VREGP)     "# read register\n"
343
 
344
stmt: ASGNI1(VREGP,reg)  "# write register\n"
345
stmt: ASGNU1(VREGP,reg)  "# write register\n"
346
 
347
stmt: ASGNI2(VREGP,reg)  "# write register\n"
348
stmt: ASGNU2(VREGP,reg)  "# write register\n"
349
 
350
stmt: ASGNF4(VREGP,reg)  "# write register\n"
351
stmt: ASGNI4(VREGP,reg)  "# write register\n"
352
stmt: ASGNP4(VREGP,reg)  "# write register\n"
353
stmt: ASGNU4(VREGP,reg)  "# write register\n"
354
 
355
stmt: ASGNF8(VREGP,reg)  "# write register\n"
356
stmt: ASGNI8(VREGP,reg)  "# write register\n"
357
stmt: ASGNP8(VREGP,reg)  "# write register\n"
358
stmt: ASGNU8(VREGP,reg)  "# write register\n"
359
con: CNSTI1  "%a"
360
con: CNSTU1  "%a"
361
 
362
con: CNSTI2  "%a"
363
con: CNSTU2  "%a"
364
 
365
con: CNSTI4  "%a"
366
con: CNSTU4  "%a"
367
con: CNSTP4  "%a"
368
 
369
con: CNSTI8  "%a"
370
con: CNSTU8  "%a"
371
con: CNSTP8  "%a"
372
stmt: reg  ""
373
acon: con     "%0"
374
acon: ADDRGP4  "%a"
375
addr: ADDI4(reg,acon)  "%1($%0)"
376
addr: ADDU4(reg,acon)  "%1($%0)"
377
addr: ADDP4(reg,acon)  "%1($%0)"
378
addr: acon  "%0"
379
addr: reg   "($%0)"
380
addr: ADDRFP4  "%a+%F($sp)"
381
addr: ADDRLP4  "%a+%F($sp)"
382
reg: addr  "la $%c,%0\n"  1
383
reg: CNSTI1  "# reg\n"  range(a, 0, 0)
384
reg: CNSTI2  "# reg\n"  range(a, 0, 0)
385
reg: CNSTI4  "# reg\n"  range(a, 0, 0)
386
reg: CNSTU1  "# reg\n"  range(a, 0, 0)
387
reg: CNSTU2  "# reg\n"  range(a, 0, 0)
388
reg: CNSTU4  "# reg\n"  range(a, 0, 0)
389
reg: CNSTP4  "# reg\n"  range(a, 0, 0)
390
stmt: ASGNI1(addr,reg)  "sb $%1,%0\n"  1
391
stmt: ASGNU1(addr,reg)  "sb $%1,%0\n"  1
392
stmt: ASGNI2(addr,reg)  "sh $%1,%0\n"  1
393
stmt: ASGNU2(addr,reg)  "sh $%1,%0\n"  1
394
stmt: ASGNI4(addr,reg)  "sw $%1,%0\n"  1
395
stmt: ASGNU4(addr,reg)  "sw $%1,%0\n"  1
396
stmt: ASGNP4(addr,reg)  "sw $%1,%0\n"  1
397
reg:  INDIRI1(addr)     "lb $%c,%0\n"  1
398
reg:  INDIRU1(addr)     "lbu $%c,%0\n"  1
399
reg:  INDIRI2(addr)     "lh $%c,%0\n"  1
400
reg:  INDIRU2(addr)     "lhu $%c,%0\n"  1
401
reg:  INDIRI4(addr)     "lw $%c,%0\n"  1
402
reg:  INDIRU4(addr)     "lw $%c,%0\n"  1
403
reg:  INDIRP4(addr)     "lw $%c,%0\n"  1
404
 
405
reg:  CVII4(INDIRI1(addr))     "lb $%c,%0\n"  1
406
reg:  CVII4(INDIRI2(addr))     "lh $%c,%0\n"  1
407
reg:  CVUU4(INDIRU1(addr))     "lbu $%c,%0\n"  1
408
reg:  CVUU4(INDIRU2(addr))     "lhu $%c,%0\n"  1
409
reg:  CVUI4(INDIRU1(addr))     "lbu $%c,%0\n"  1
410
reg:  CVUI4(INDIRU2(addr))     "lhu $%c,%0\n"  1
411
reg:  INDIRF4(addr)     "l.s $f%c,%0\n"  1
412
reg:  INDIRF8(addr)     "l.d $f%c,%0\n"  1
413
stmt: ASGNF4(addr,reg)  "s.s $f%1,%0\n"  1
414
stmt: ASGNF8(addr,reg)  "s.d $f%1,%0\n"  1
415
reg: DIVI4(reg,reg)  "div $%c,$%0,$%1\n"   1
416
reg: DIVU4(reg,reg)  "divu $%c,$%0,$%1\n"  1
417
reg: MODI4(reg,reg)  "rem $%c,$%0,$%1\n"   1
418
reg: MODU4(reg,reg)  "remu $%c,$%0,$%1\n"  1
419
reg: MULI4(reg,reg)  "mul $%c,$%0,$%1\n"   1
420
reg: MULU4(reg,reg)  "mul $%c,$%0,$%1\n"   1
421
rc:  con            "%0"
422
rc:  reg            "$%0"
423
 
424
reg: ADDI4(reg,rc)   "addu $%c,$%0,%1\n"  1
425
reg: ADDP4(reg,rc)   "addu $%c,$%0,%1\n"  1
426
reg: ADDU4(reg,rc)   "addu $%c,$%0,%1\n"  1
427
reg: BANDI4(reg,rc)  "and $%c,$%0,%1\n"   1
428
reg: BORI4(reg,rc)   "or $%c,$%0,%1\n"    1
429
reg: BXORI4(reg,rc)  "xor $%c,$%0,%1\n"   1
430
reg: BANDU4(reg,rc)  "and $%c,$%0,%1\n"   1
431
reg: BORU4(reg,rc)   "or $%c,$%0,%1\n"    1
432
reg: BXORU4(reg,rc)  "xor $%c,$%0,%1\n"   1
433
reg: SUBI4(reg,rc)   "subu $%c,$%0,%1\n"  1
434
reg: SUBP4(reg,rc)   "subu $%c,$%0,%1\n"  1
435
reg: SUBU4(reg,rc)   "subu $%c,$%0,%1\n"  1
436
rc5: CNSTI4         "%a"                range(a,0,31)
437
rc5: reg            "$%0"
438
 
439
reg: LSHI4(reg,rc5)  "sll $%c,$%0,%1\n"  1
440
reg: LSHU4(reg,rc5)  "sll $%c,$%0,%1\n"  1
441
reg: RSHI4(reg,rc5)  "sra $%c,$%0,%1\n"  1
442
reg: RSHU4(reg,rc5)  "srl $%c,$%0,%1\n"  1
443
reg: BCOMI4(reg)  "not $%c,$%0\n"   1
444
reg: BCOMU4(reg)  "not $%c,$%0\n"   1
445
reg: NEGI4(reg)   "negu $%c,$%0\n"  1
446
reg: LOADI1(reg)  "move $%c,$%0\n"  move(a)
447
reg: LOADU1(reg)  "move $%c,$%0\n"  move(a)
448
reg: LOADI2(reg)  "move $%c,$%0\n"  move(a)
449
reg: LOADU2(reg)  "move $%c,$%0\n"  move(a)
450
reg: LOADI4(reg)  "move $%c,$%0\n"  move(a)
451
reg: LOADP4(reg)  "move $%c,$%0\n"  move(a)
452
reg: LOADU4(reg)  "move $%c,$%0\n"  move(a)
453
reg: ADDF4(reg,reg)  "add.s $f%c,$f%0,$f%1\n"  1
454
reg: ADDF8(reg,reg)  "add.d $f%c,$f%0,$f%1\n"  1
455
reg: DIVF4(reg,reg)  "div.s $f%c,$f%0,$f%1\n"  1
456
reg: DIVF8(reg,reg)  "div.d $f%c,$f%0,$f%1\n"  1
457
reg: MULF4(reg,reg)  "mul.s $f%c,$f%0,$f%1\n"  1
458
reg: MULF8(reg,reg)  "mul.d $f%c,$f%0,$f%1\n"  1
459
reg: SUBF4(reg,reg)  "sub.s $f%c,$f%0,$f%1\n"  1
460
reg: SUBF8(reg,reg)  "sub.d $f%c,$f%0,$f%1\n"  1
461
reg: LOADF4(reg)     "mov.s $f%c,$f%0\n"       move(a)
462
reg: LOADF8(reg)     "mov.d $f%c,$f%0\n"       move(a)
463
reg: NEGF4(reg)      "neg.s $f%c,$f%0\n"       1
464
reg: NEGF8(reg)      "neg.d $f%c,$f%0\n"       1
465
reg: CVII4(reg)  "sll $%c,$%0,8*(4-%a); sra $%c,$%c,8*(4-%a)\n"  2
466
reg: CVUI4(reg)  "and $%c,$%0,(1<<(8*%a))-1\n"  1
467
reg: CVUU4(reg)  "and $%c,$%0,(1<<(8*%a))-1\n"  1
468
reg: CVFF4(reg)  "cvt.s.d $f%c,$f%0\n"  1
469
reg: CVFF8(reg)  "cvt.d.s $f%c,$f%0\n"  1
470
reg: CVIF4(reg)  "mtc1 $%0,$f%c; cvt.s.w $f%c,$f%c\n"  2
471
reg: CVIF8(reg)  "mtc1 $%0,$f%c; cvt.d.w $f%c,$f%c\n"  2
472
reg: CVFI4(reg)  "trunc.w.s $f2,$f%0,$%c; mfc1 $%c,$f2\n"  (a->syms[0]->u.c.v.i==4?2:LBURG_MAX)
473
reg: CVFI4(reg)  "trunc.w.d $f2,$f%0,$%c; mfc1 $%c,$f2\n"  (a->syms[0]->u.c.v.i==8?2:LBURG_MAX)
474
stmt: LABELV  "%a:\n"
475
stmt: JUMPV(acon)  "b %0\n"   1
476
stmt: JUMPV(reg)   ".cpadd $%0\nj $%0\n"  !pic
477
stmt: JUMPV(reg)   "j $%0\n"  pic
478
stmt: EQI4(reg,reg)  "beq $%0,$%1,%a\n"   1
479
stmt: EQU4(reg,reg)  "beq $%0,$%1,%a\n"   1
480
stmt: GEI4(reg,reg)  "bge $%0,$%1,%a\n"   1
481
stmt: GEU4(reg,reg)  "bgeu $%0,$%1,%a\n"  1
482
stmt: GTI4(reg,reg)  "bgt $%0,$%1,%a\n"   1
483
stmt: GTU4(reg,reg)  "bgtu $%0,$%1,%a\n"  1
484
stmt: LEI4(reg,reg)  "ble $%0,$%1,%a\n"   1
485
stmt: LEU4(reg,reg)  "bleu $%0,$%1,%a\n"  1
486
stmt: LTI4(reg,reg)  "blt $%0,$%1,%a\n"   1
487
stmt: LTU4(reg,reg)  "bltu $%0,$%1,%a\n"  1
488
stmt: NEI4(reg,reg)  "bne $%0,$%1,%a\n"   1
489
stmt: NEU4(reg,reg)  "bne $%0,$%1,%a\n"   1
490
stmt: EQF4(reg,reg)  "c.eq.s $f%0,$f%1; bc1t %a\n"  2
491
stmt: EQF8(reg,reg)  "c.eq.d $f%0,$f%1; bc1t %a\n"  2
492
stmt: LEF4(reg,reg)  "c.ule.s $f%0,$f%1; bc1t %a\n"  2
493
stmt: LEF8(reg,reg)  "c.ule.d $f%0,$f%1; bc1t %a\n"  2
494
stmt: LTF4(reg,reg)  "c.ult.s $f%0,$f%1; bc1t %a\n"  2
495
stmt: LTF8(reg,reg)  "c.ult.d $f%0,$f%1; bc1t %a\n"  2
496
stmt: GEF4(reg,reg)  "c.lt.s $f%0,$f%1; bc1f %a\n"  2
497
stmt: GEF8(reg,reg)  "c.lt.d $f%0,$f%1; bc1f %a\n"  2
498
stmt: GTF4(reg,reg)  "c.le.s $f%0,$f%1; bc1f %a\n"  2
499
stmt: GTF8(reg,reg)  "c.le.d $f%0,$f%1; bc1f %a\n"  2
500
stmt: NEF4(reg,reg)  "c.eq.s $f%0,$f%1; bc1f %a\n"  2
501
stmt: NEF8(reg,reg)  "c.eq.d $f%0,$f%1; bc1f %a\n"  2
502
ar:   ADDRGP4     "%a"
503
 
504
reg:  CALLF4(ar)  "jal %0\n"  1
505
reg:  CALLF8(ar)  "jal %0\n"  1
506
reg:  CALLI4(ar)  "jal %0\n"  1
507
reg:  CALLP4(ar)  "jal %0\n"  1
508
reg:  CALLU4(ar)  "jal %0\n"  1
509
stmt: CALLV(ar)  "jal %0\n"  1
510
ar: reg    "$%0"
511
ar: CNSTP4  "%a"   range(a, 0, 0x0fffffff)
512
stmt: RETF4(reg)  "# ret\n"  1
513
stmt: RETF8(reg)  "# ret\n"  1
514
stmt: RETI4(reg)  "# ret\n"  1
515
stmt: RETU4(reg)  "# ret\n"  1
516
stmt: RETP4(reg)  "# ret\n"  1
517
stmt: RETV(reg)   "# ret\n"  1
518
stmt: ARGF4(reg)  "# arg\n"  1
519
stmt: ARGF8(reg)  "# arg\n"  1
520
stmt: ARGI4(reg)  "# arg\n"  1
521
stmt: ARGP4(reg)  "# arg\n"  1
522
stmt: ARGU4(reg)  "# arg\n"  1
523
 
524
stmt: ARGB(INDIRB(reg))       "# argb %0\n"      1
525
stmt: ASGNB(reg,INDIRB(reg))  "# asgnb %0 %1\n"  1
526
%%
527
static void progend(void){}
528
static void progbeg(int argc, char *argv[]) {
529
        int i;
530
 
531
        {
532
                union {
533
                        char c;
534
                        int i;
535
                } u;
536
                u.i = 0;
537
                u.c = 1;
538
                swap = ((int)(u.i == 1)) != IR->little_endian;
539
        }
540
        print(".set reorder\n");
541
        pic = !IR->little_endian;
542
        parseflags(argc, argv);
543
        for (i = 0; i < argc; i++)
544
                if (strncmp(argv[i], "-G", 2) == 0)
545
                        gnum = atoi(argv[i] + 2);
546
                else if (strcmp(argv[i], "-pic=1") == 0
547
                ||       strcmp(argv[i], "-pic=0") == 0)
548
                        pic = argv[i][5]-'0';
549
        for (i = 0; i < 31; i += 2)
550
                freg2[i] = mkreg("%d", i, 3, FREG);
551
        for (i = 0; i < 32; i++)
552
                ireg[i]  = mkreg("%d", i, 1, IREG);
553
        ireg[29]->x.name = "sp";
554
        d6 = mkreg("6", 6, 3, IREG);
555
        freg2w = mkwildcard(freg2);
556
        iregw = mkwildcard(ireg);
557
        tmask[IREG] = INTTMP; tmask[FREG] = FLTTMP;
558
        vmask[IREG] = INTVAR; vmask[FREG] = FLTVAR;
559
        blkreg = mkreg("8", 8, 7, IREG);
560
}
561
static Symbol rmap(int opk) {
562
        switch (optype(opk)) {
563
        case I: case U: case P: case B:
564
                return iregw;
565
        case F:
566
                return freg2w;
567
        default:
568
                return 0;
569
        }
570
}
571
static void target(Node p) {
572
        assert(p);
573
        switch (specific(p->op)) {
574
        case CNST+I: case CNST+U: case CNST+P:
575
                if (range(p, 0, 0) == 0) {
576
                        setreg(p, ireg[0]);
577
                        p->x.registered = 1;
578
                }
579
                break;
580
        case CALL+V:
581
                rtarget(p, 0, ireg[25]);
582
                break;
583
        case CALL+F:
584
                rtarget(p, 0, ireg[25]);
585
                setreg(p, freg2[0]);
586
                break;
587
        case CALL+I: case CALL+P: case CALL+U:
588
                rtarget(p, 0, ireg[25]);
589
                setreg(p, ireg[2]);
590
                break;
591
        case RET+F:
592
                rtarget(p, 0, freg2[0]);
593
                break;
594
        case RET+I: case RET+U: case RET+P:
595
                rtarget(p, 0, ireg[2]);
596
                break;
597
        case ARG+F: case ARG+I: case ARG+P: case ARG+U: {
598
                static int ty0;
599
                int ty = optype(p->op);
600
                Symbol q;
601
 
602
                q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, opsize(p->op), ty0);
603
                if (p->x.argno == 0)
604
                        ty0 = ty;
605
                if (q &&
606
                !(ty == F && q->x.regnode->set == IREG))
607
                        rtarget(p, 0, q);
608
                break;
609
                }
610
        case ASGN+B: rtarget(p->kids[1], 0, blkreg); break;
611
        case ARG+B:  rtarget(p->kids[0], 0, blkreg); break;
612
        }
613
}
614
static void clobber(Node p) {
615
        assert(p);
616
        switch (specific(p->op)) {
617
        case CALL+F:
618
                spill(INTTMP | INTRET, IREG, p);
619
                spill(FLTTMP,          FREG, p);
620
                break;
621
        case CALL+I: case CALL+P: case CALL+U:
622
                spill(INTTMP,          IREG, p);
623
                spill(FLTTMP | FLTRET, FREG, p);
624
                break;
625
        case CALL+V:
626
                spill(INTTMP | INTRET, IREG, p);
627
                spill(FLTTMP | FLTRET, FREG, p);
628
                break;
629
        }
630
}
631
static void emit2(Node p) {
632
        int dst, n, src, sz, ty;
633
        static int ty0;
634
        Symbol q;
635
 
636
        switch (specific(p->op)) {
637
        case ARG+F: case ARG+I: case ARG+P: case ARG+U:
638
                ty = optype(p->op);
639
                sz = opsize(p->op);
640
                if (p->x.argno == 0)
641
                        ty0 = ty;
642
                q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, sz, ty0);
643
                src = getregnum(p->x.kids[0]);
644
                if (q == NULL && ty == F && sz == 4)
645
                        print("s.s $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i);
646
                else if (q == NULL && ty == F)
647
                        print("s.d $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i);
648
                else if (q == NULL)
649
                        print("sw $%d,%d($sp)\n", src, p->syms[2]->u.c.v.i);
650
                else if (ty == F && sz == 4 && q->x.regnode->set == IREG)
651
                        print("mfc1 $%d,$f%d\n", q->x.regnode->number, src);
652
                else if (ty == F && q->x.regnode->set == IREG)
653
                        print("mfc1.d $%d,$f%d\n", q->x.regnode->number, src);
654
                break;
655
        case ASGN+B:
656
                dalign = salign = p->syms[1]->u.c.v.i;
657
                blkcopy(getregnum(p->x.kids[0]), 0,
658
                        getregnum(p->x.kids[1]), 0,
659
                        p->syms[0]->u.c.v.i, tmpregs);
660
                break;
661
        case ARG+B:
662
                dalign = 4;
663
                salign = p->syms[1]->u.c.v.i;
664
                blkcopy(29, p->syms[2]->u.c.v.i,
665
                        getregnum(p->x.kids[0]), 0,
666
                        p->syms[0]->u.c.v.i, tmpregs);
667
                n   = p->syms[2]->u.c.v.i + p->syms[0]->u.c.v.i;
668
                dst = p->syms[2]->u.c.v.i;
669
                for ( ; dst <= 12 && dst < n; dst += 4)
670
                        print("lw $%d,%d($sp)\n", (dst/4)+4, dst);
671
                break;
672
        }
673
}
674
static Symbol argreg(int argno, int offset, int ty, int sz, int ty0) {
675
        assert((offset&3) == 0);
676
        if (offset > 12)
677
                return NULL;
678
        else if (argno == 0 && ty == F)
679
                return freg2[12];
680
        else if (argno == 1 && ty == F && ty0 == F)
681
                return freg2[14];
682
        else if (argno == 1 && ty == F && sz == 8)
683
                return d6;  /* Pair! */
684
        else
685
                return ireg[(offset/4) + 4];
686
}
687
static void doarg(Node p) {
688
        static int argno;
689
        int align;
690
 
691
        if (argoffset == 0)
692
                argno = 0;
693
        p->x.argno = argno++;
694
        align = p->syms[1]->u.c.v.i < 4 ? 4 : p->syms[1]->u.c.v.i;
695
        p->syms[2] = intconst(mkactual(align,
696
                p->syms[0]->u.c.v.i));
697
}
698
static void local(Symbol p) {
699
        if (askregvar(p, rmap(ttob(p->type))) == 0)
700
                mkauto(p);
701
}
702
static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
703
        int i, saved, sizefsave, sizeisave, varargs;
704
        Symbol r, argregs[4];
705
 
706
        usedmask[0] = usedmask[1] = 0;
707
        freemask[0] = freemask[1] = ~(unsigned)0;
708
        offset = maxoffset = maxargoffset = 0;
709
        for (i = 0; callee[i]; i++)
710
                ;
711
        varargs = variadic(f->type)
712
                || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0;
713
        for (i = 0; callee[i]; i++) {
714
                Symbol p = callee[i];
715
                Symbol q = caller[i];
716
                assert(q);
717
                offset = roundup(offset, q->type->align);
718
                p->x.offset = q->x.offset = offset;
719
                p->x.name = q->x.name = stringd(offset);
720
                r = argreg(i, offset, optype(ttob(q->type)), q->type->size, optype(ttob(caller[0]->type)));
721
                if (i < 4)
722
                        argregs[i] = r;
723
                offset = roundup(offset + q->type->size, 4);
724
                if (varargs)
725
                        p->sclass = AUTO;
726
                else if (r && ncalls == 0 &&
727
                         !isstruct(q->type) && !p->addressed &&
728
                         !(isfloat(q->type) && r->x.regnode->set == IREG)
729
) {
730
                        p->sclass = q->sclass = REGISTER;
731
                        askregvar(p, r);
732
                        assert(p->x.regnode && p->x.regnode->vbl == p);
733
                        q->x = p->x;
734
                        q->type = p->type;
735
                }
736
                else if (askregvar(p, rmap(ttob(p->type)))
737
                         && r != NULL
738
                         && (isint(p->type) || p->type == q->type)) {
739
                        assert(q->sclass != REGISTER);
740
                        p->sclass = q->sclass = REGISTER;
741
                        q->type = p->type;
742
                }
743
        }
744
        assert(!caller[i]);
745
        offset = 0;
746
        gencode(caller, callee);
747
        if (ncalls)
748
                usedmask[IREG] |= ((unsigned)1)<<31;
749
        usedmask[IREG] &= 0xc0ff0000;
750
        usedmask[FREG] &= 0xfff00000;
751
        if (pic && ncalls)
752
                usedmask[IREG] |= 1<<25;
753
        maxargoffset = roundup(maxargoffset, usedmask[FREG] ? 8 : 4);
754
        if (ncalls && maxargoffset < 16)
755
                maxargoffset = 16;
756
        sizefsave = 4*bitcount(usedmask[FREG]);
757
        sizeisave = 4*bitcount(usedmask[IREG]);
758
        framesize = roundup(maxargoffset + sizefsave
759
                + sizeisave + maxoffset, 16);
760
        segment(CODE);
761
        print(".align 2\n");
762
        print(".ent %s\n", f->x.name);
763
        print("%s:\n", f->x.name);
764
        i = maxargoffset + sizefsave - framesize;
765
        print(".frame $sp,%d,$31\n", framesize);
766
        if (pic)
767
                print(".set noreorder\n.cpload $25\n.set reorder\n");
768
        if (framesize > 0)
769
                print("addu $sp,$sp,%d\n", -framesize);
770
        if (usedmask[FREG])
771
                print(".fmask 0x%x,%d\n", usedmask[FREG], i - 8);
772
        if (usedmask[IREG])
773
                print(".mask 0x%x,%d\n",  usedmask[IREG],
774
                        i + sizeisave - 4);
775
        saved = maxargoffset;
776
        for (i = 20; i <= 30; i += 2)
777
                if (usedmask[FREG]&(3<
778
                        print("s.d $f%d,%d($sp)\n", i, saved);
779
                        saved += 8;
780
                }
781
 
782
        for (i = 16; i <= 31; i++)
783
                if (usedmask[IREG]&(1<
784
                        if (i == 25)
785
                                print(".cprestore %d\n", saved);
786
                        else
787
                                print("sw $%d,%d($sp)\n", i, saved);
788
                        saved += 4;
789
                }
790
        for (i = 0; i < 4 && callee[i]; i++) {
791
                r = argregs[i];
792
                if (r && r->x.regnode != callee[i]->x.regnode) {
793
                        Symbol out = callee[i];
794
                        Symbol in  = caller[i];
795
                        int rn = r->x.regnode->number;
796
                        int rs = r->x.regnode->set;
797
                        int tyin = ttob(in->type);
798
 
799
                        assert(out && in && r && r->x.regnode);
800
                        assert(out->sclass != REGISTER || out->x.regnode);
801
                        if (out->sclass == REGISTER
802
                        && (isint(out->type) || out->type == in->type)) {
803
                                int outn = out->x.regnode->number;
804
                                if (rs == FREG && tyin == F+sizeop(8))
805
                                        print("mov.d $f%d,$f%d\n", outn, rn);
806
                                else if (rs == FREG && tyin == F+sizeop(4))
807
                                        print("mov.s $f%d,$f%d\n", outn, rn);
808
                                else if (rs == IREG && tyin == F+sizeop(8))
809
                                        print("mtc1.d $%d,$f%d\n", rn,   outn);
810
                                else if (rs == IREG && tyin == F+sizeop(4))
811
                                        print("mtc1 $%d,$f%d\n",   rn,   outn);
812
                                else
813
                                        print("move $%d,$%d\n",    outn, rn);
814
                        } else {
815
                                int off = in->x.offset + framesize;
816
                                if (rs == FREG && tyin == F+sizeop(8))
817
                                        print("s.d $f%d,%d($sp)\n", rn, off);
818
                                else if (rs == FREG && tyin == F+sizeop(4))
819
                                        print("s.s $f%d,%d($sp)\n", rn, off);
820
                                else {
821
                                        int i, n = (in->type->size + 3)/4;
822
                                        for (i = rn; i < rn+n && i <= 7; i++)
823
                                                print("sw $%d,%d($sp)\n", i, off + (i-rn)*4);
824
                                }
825
                        }
826
                }
827
        }
828
        if (varargs && callee[i-1]) {
829
                i = callee[i-1]->x.offset + callee[i-1]->type->size;
830
                for (i = roundup(i, 4)/4; i <= 3; i++)
831
                        print("sw $%d,%d($sp)\n", i + 4, framesize + 4*i);
832
                }
833
        emitcode();
834
        saved = maxargoffset;
835
        for (i = 20; i <= 30; i += 2)
836
                if (usedmask[FREG]&(3<
837
                        print("l.d $f%d,%d($sp)\n", i, saved);
838
                        saved += 8;
839
                }
840
        for (i = 16; i <= 31; i++)
841
                if (usedmask[IREG]&(1<
842
                        print("lw $%d,%d($sp)\n", i, saved);
843
                        saved += 4;
844
                }
845
        if (framesize > 0)
846
                print("addu $sp,$sp,%d\n", framesize);
847
        print("j $31\n");
848
        print(".end %s\n", f->x.name);
849
}
850
static void defconst(int suffix, int size, Value v) {
851
        if (suffix == F && size == 4) {
852
                float f = v.d;
853
                print(".word 0x%x\n", *(unsigned *)&f);
854
        }
855
        else if (suffix == F && size == 8) {
856
                double d = v.d;
857
                unsigned *p = (unsigned *)&d;
858
                print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]);
859
        }
860
        else if (suffix == P)
861 252 hellwig
                print(".word 0x%lx\n", (unsigned long)v.p);
862 4 hellwig
        else if (size == 1)
863
                print(".byte 0x%x\n", (unsigned)((unsigned char)(suffix == I ? v.i : v.u)));
864
        else if (size == 2)
865
                print(".half 0x%x\n", (unsigned)((unsigned short)(suffix == I ? v.i : v.u)));
866
        else if (size == 4)
867
                print(".word 0x%x\n", (unsigned)(suffix == I ? v.i : v.u));
868
}
869
static void defaddress(Symbol p) {
870
        if (pic && p->scope == LABELS)
871
                print(".gpword %s\n", p->x.name);
872
        else
873
                print(".word %s\n", p->x.name);
874
}
875
static void defstring(int n, char *str) {
876
        char *s;
877
 
878
        for (s = str; s < str + n; s++)
879
                print(".byte %d\n", (*s)&0377);
880
}
881
static void export(Symbol p) {
882
        print(".globl %s\n", p->x.name);
883
}
884
static void import(Symbol p) {
885
        if (!isfunc(p->type))
886
                print(".extern %s %d\n", p->name, p->type->size);
887
}
888
static void defsymbol(Symbol p) {
889
        if (p->scope >= LOCAL && p->sclass == STATIC)
890
                p->x.name = stringf("L.%d", genlabel(1));
891
        else if (p->generated)
892
                p->x.name = stringf("L.%s", p->name);
893
        else
894
                assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)),
895
                p->x.name = p->name;
896
}
897
static void address(Symbol q, Symbol p, long n) {
898
        if (p->scope == GLOBAL
899
        || p->sclass == STATIC || p->sclass == EXTERN)
900
                q->x.name = stringf("%s%s%D", p->x.name,
901
                        n >= 0 ? "+" : "", n);
902
        else {
903
                assert(n <= INT_MAX && n >= INT_MIN);
904
                q->x.offset = p->x.offset + n;
905
                q->x.name = stringd(q->x.offset);
906
        }
907
}
908
static void global(Symbol p) {
909
        if (p->u.seg == BSS) {
910
                if (p->sclass == STATIC || Aflag >= 2)
911
                        print(".lcomm %s,%d\n", p->x.name, p->type->size);
912
                else
913
                        print( ".comm %s,%d\n", p->x.name, p->type->size);
914
        } else {
915
                if (p->u.seg == DATA
916
                && (p->type->size == 0 || p->type->size > gnum))
917
                        print(".data\n");
918
                else if (p->u.seg == DATA)
919
                        print(".sdata\n");
920
                print(".align %c\n", ".01.2...3"[p->type->align]);
921
                print("%s:\n", p->x.name);
922
        }
923
}
924
static void segment(int n) {
925
        cseg = n;
926
        switch (n) {
927
        case CODE: print(".text\n");  break;
928
        case LIT:  print(".rdata\n"); break;
929
        }
930
}
931
static void space(int n) {
932
        if (cseg != BSS)
933
                print(".space %d\n", n);
934
}
935
static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) {
936
        int lab = genlabel(1);
937
 
938
        print("addu $%d,$%d,%d\n", sreg, sreg, size&~7);
939
        print("addu $%d,$%d,%d\n", tmps[2], dreg, size&~7);
940
        blkcopy(tmps[2], doff, sreg, soff, size&7, tmps);
941
        print("L.%d:\n", lab);
942
        print("addu $%d,$%d,%d\n", sreg, sreg, -8);
943
        print("addu $%d,$%d,%d\n", tmps[2], tmps[2], -8);
944
        blkcopy(tmps[2], doff, sreg, soff, 8, tmps);
945
        print("bltu $%d,$%d,L.%d\n", dreg, tmps[2], lab);
946
}
947
static void blkfetch(int size, int off, int reg, int tmp) {
948
        assert(size == 1 || size == 2 || size == 4);
949
        if (size == 1)
950
                print("lbu $%d,%d($%d)\n",  tmp, off, reg);
951
        else if (salign >= size && size == 2)
952
                print("lhu $%d,%d($%d)\n",  tmp, off, reg);
953
        else if (salign >= size)
954
                print("lw $%d,%d($%d)\n",   tmp, off, reg);
955
        else if (size == 2)
956
                print("ulhu $%d,%d($%d)\n", tmp, off, reg);
957
        else
958
                print("ulw $%d,%d($%d)\n",  tmp, off, reg);
959
}
960
static void blkstore(int size, int off, int reg, int tmp) {
961
        if (size == 1)
962
                print("sb $%d,%d($%d)\n",  tmp, off, reg);
963
        else if (dalign >= size && size == 2)
964
                print("sh $%d,%d($%d)\n",  tmp, off, reg);
965
        else if (dalign >= size)
966
                print("sw $%d,%d($%d)\n",  tmp, off, reg);
967
        else if (size == 2)
968
                print("ush $%d,%d($%d)\n", tmp, off, reg);
969
        else
970
                print("usw $%d,%d($%d)\n", tmp, off, reg);
971
}
972
static void stabinit(char *, int, char *[]);
973
static void stabline(Coordinate *);
974
static void stabsym(Symbol);
975
 
976
static char *currentfile;
977
 
978
static int bitcount(unsigned mask) {
979
        unsigned i, n = 0;
980
 
981
        for (i = 1; i; i <<= 1)
982
                if (mask&i)
983
                        n++;
984
        return n;
985
}
986
 
987
/* stabinit - initialize stab output */
988
static void stabinit(char *file, int argc, char *argv[]) {
989
        if (file) {
990
                print(".file 2,\"%s\"\n", file);
991
                currentfile = file;
992
        }
993
}
994
 
995
/* stabline - emit stab entry for source coordinate *cp */
996
static void stabline(Coordinate *cp) {
997
        if (cp->file && cp->file != currentfile) {
998
                print(".file 2,\"%s\"\n", cp->file);
999
                currentfile = cp->file;
1000
        }
1001
        print(".loc 2,%d\n", cp->y);
1002
}
1003
 
1004
/* stabsym - output a stab entry for symbol p */
1005
static void stabsym(Symbol p) {
1006
        if (p == cfunc && IR->stabline)
1007
                (*IR->stabline)(&p->src);
1008
}
1009
Interface mipsebIR = {
1010
        1, 1, 0,  /* char */
1011
        2, 2, 0,  /* short */
1012
        4, 4, 0,  /* int */
1013
        4, 4, 0,  /* long */
1014
        4, 4, 0,  /* long long */
1015
        4, 4, 1,  /* float */
1016
        8, 8, 1,  /* double */
1017
        8, 8, 1,  /* long double */
1018
        4, 4, 0,  /* T * */
1019
        0, 1, 0,  /* struct */
1020
        0,      /* little_endian */
1021
        0,  /* mulops_calls */
1022
        0,  /* wants_callb */
1023
        1,  /* wants_argb */
1024
        1,  /* left_to_right */
1025
        0,  /* wants_dag */
1026
        0,  /* unsigned_char */
1027
        address,
1028
        blockbeg,
1029
        blockend,
1030
        defaddress,
1031
        defconst,
1032
        defstring,
1033
        defsymbol,
1034
        emit,
1035
        export,
1036
        function,
1037
        gen,
1038
        global,
1039
        import,
1040
        local,
1041
        progbeg,
1042
        progend,
1043
        segment,
1044
        space,
1045
        0, 0, 0, stabinit, stabline, stabsym, 0,
1046
        {
1047
                4,      /* max_unaligned_load */
1048
                rmap,
1049
                blkfetch, blkstore, blkloop,
1050
                _label,
1051
                _rule,
1052
                _nts,
1053
                _kids,
1054
                _string,
1055
                _templates,
1056
                _isinstruction,
1057
                _ntname,
1058
                emit2,
1059
                doarg,
1060
                target,
1061
                clobber,
1062
 
1063
        }
1064
}, mipselIR = {
1065
        1, 1, 0,  /* char */
1066
        2, 2, 0,  /* short */
1067
        4, 4, 0,  /* int */
1068
        4, 4, 0,  /* long */
1069
        4, 4, 0,  /* long long */
1070
        4, 4, 1,  /* float */
1071
        8, 8, 1,  /* double */
1072
        8, 8, 1,  /* long double */
1073
        4, 4, 0,  /* T * */
1074
        0, 1, 0,  /* struct */
1075
        1,      /* little_endian */
1076
        0,  /* mulops_calls */
1077
        0,  /* wants_callb */
1078
        1,  /* wants_argb */
1079
        1,  /* left_to_right */
1080
        0,  /* wants_dag */
1081
        0,  /* unsigned_char */
1082
        address,
1083
        blockbeg,
1084
        blockend,
1085
        defaddress,
1086
        defconst,
1087
        defstring,
1088
        defsymbol,
1089
        emit,
1090
        export,
1091
        function,
1092
        gen,
1093
        global,
1094
        import,
1095
        local,
1096
        progbeg,
1097
        progend,
1098
        segment,
1099
        space,
1100
        0, 0, 0, stabinit, stabline, stabsym, 0,
1101
        {
1102
                4,      /* max_unaligned_load */
1103
                rmap,
1104
                blkfetch, blkstore, blkloop,
1105
                _label,
1106
                _rule,
1107
                _nts,
1108
                _kids,
1109
                _string,
1110
                _templates,
1111
                _isinstruction,
1112
                _ntname,
1113
                emit2,
1114
                doarg,
1115
                target,
1116
                clobber,
1117
 
1118
        }
1119
};
1120
static char rcsid[] = "$Id: mips.md,v 1.1 2002/08/28 23:12:44 drh Exp $";

powered by: WebSVN 2.1.0

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