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

Subversion Repositories eco32

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

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

Line No. Rev Author Line
1 4 hellwig
%{
2
enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 };
3
#include "c.h"
4
#define NODEPTR_TYPE Node
5
#define OP_LABEL(p) ((p)->op)
6
#define LEFT_CHILD(p) ((p)->kids[0])
7
#define RIGHT_CHILD(p) ((p)->kids[1])
8
#define STATE_LABEL(p) ((p)->x.state)
9
static void address(Symbol, Symbol, long);
10
static void blkfetch(int, int, int, int);
11
static void blkloop(int, int, int, int, int, int[]);
12
static void blkstore(int, int, int, int);
13
static void defaddress(Symbol);
14
static void defconst(int, int, Value);
15
static void defstring(int, char *);
16
static void defsymbol(Symbol);
17
static void doarg(Node);
18
static void emit2(Node);
19
static void export(Symbol);
20
static void clobber(Node);
21
static void function(Symbol, Symbol [], Symbol [], int);
22
static void global(Symbol);
23
static void import(Symbol);
24
static void local(Symbol);
25
static void progbeg(int, char **);
26
static void progend(void);
27
static void segment(int);
28
static void space(int);
29
static void target(Node);
30
extern int ckstack(Node, int);
31
extern int memop(Node);
32
extern int sametree(Node, Node);
33
static Symbol charreg[32], shortreg[32], intreg[32];
34
static Symbol fltreg[32];
35
 
36
static Symbol charregw, shortregw, intregw, fltregw;
37
 
38
static int cseg;
39
 
40
static Symbol quo, rem;
41
 
42
%}
43
%start stmt
44
%term CNSTF4=4113
45
%term CNSTF8=8209
46
%term CNSTF16=16401
47
%term CNSTI1=1045
48
%term CNSTI2=2069
49
%term CNSTI4=4117
50
%term CNSTI8=8213
51
%term CNSTP4=4119
52
%term CNSTP8=8215
53
%term CNSTU1=1046
54
%term CNSTU2=2070
55
%term CNSTU4=4118
56
%term CNSTU8=8214
57
 
58
%term ARGB=41
59
%term ARGF4=4129
60
%term ARGF8=8225
61
%term ARGF16=16417
62
%term ARGI4=4133
63
%term ARGI8=8229
64
%term ARGP4=4135
65
%term ARGP8=8231
66
%term ARGU4=4134
67
%term ARGU8=8230
68
 
69
%term ASGNB=57
70
%term ASGNF4=4145
71
%term ASGNF8=8241
72
%term ASGNF16=16433
73
%term ASGNI1=1077
74
%term ASGNI2=2101
75
%term ASGNI4=4149
76
%term ASGNI8=8245
77
%term ASGNP4=4151
78
%term ASGNP8=8247
79
%term ASGNU1=1078
80
%term ASGNU2=2102
81
%term ASGNU4=4150
82
%term ASGNU8=8246
83
 
84
%term INDIRB=73
85
%term INDIRF4=4161
86
%term INDIRF8=8257
87
%term INDIRF16=16449
88
%term INDIRI1=1093
89
%term INDIRI2=2117
90
%term INDIRI4=4165
91
%term INDIRI8=8261
92
%term INDIRP4=4167
93
%term INDIRP8=8263
94
%term INDIRU1=1094
95
%term INDIRU2=2118
96
%term INDIRU4=4166
97
%term INDIRU8=8262
98
 
99
%term CVFF4=4209
100
%term CVFF8=8305
101
%term CVFF16=16497
102
%term CVFI4=4213
103
%term CVFI8=8309
104
 
105
%term CVIF4=4225
106
%term CVIF8=8321
107
%term CVIF16=16513
108
%term CVII1=1157
109
%term CVII2=2181
110
%term CVII4=4229
111
%term CVII8=8325
112
%term CVIU1=1158
113
%term CVIU2=2182
114
%term CVIU4=4230
115
%term CVIU8=8326
116
 
117
%term CVPP4=4247
118
%term CVPP8=8343
119
%term CVPP16=16535
120
%term CVPU4=4246
121
%term CVPU8=8342
122
 
123
%term CVUI1=1205
124
%term CVUI2=2229
125
%term CVUI4=4277
126
%term CVUI8=8373
127
%term CVUP4=4279
128
%term CVUP8=8375
129
%term CVUP16=16567
130
%term CVUU1=1206
131
%term CVUU2=2230
132
%term CVUU4=4278
133
%term CVUU8=8374
134
 
135
%term NEGF4=4289
136
%term NEGF8=8385
137
%term NEGF16=16577
138
%term NEGI4=4293
139
%term NEGI8=8389
140
 
141
%term CALLB=217
142
%term CALLF4=4305
143
%term CALLF8=8401
144
%term CALLF16=16593
145
%term CALLI4=4309
146
%term CALLI8=8405
147
%term CALLP4=4311
148
%term CALLP8=8407
149
%term CALLU4=4310
150
%term CALLU8=8406
151
%term CALLV=216
152
 
153
%term RETF4=4337
154
%term RETF8=8433
155
%term RETF16=16625
156
%term RETI4=4341
157
%term RETI8=8437
158
%term RETP4=4343
159
%term RETP8=8439
160
%term RETU4=4342
161
%term RETU8=8438
162
%term RETV=248
163
 
164
%term ADDRGP4=4359
165
%term ADDRGP8=8455
166
 
167
%term ADDRFP4=4375
168
%term ADDRFP8=8471
169
 
170
%term ADDRLP4=4391
171
%term ADDRLP8=8487
172
 
173
%term ADDF4=4401
174
%term ADDF8=8497
175
%term ADDF16=16689
176
%term ADDI4=4405
177
%term ADDI8=8501
178
%term ADDP4=4407
179
%term ADDP8=8503
180
%term ADDU4=4406
181
%term ADDU8=8502
182
 
183
%term SUBF4=4417
184
%term SUBF8=8513
185
%term SUBF16=16705
186
%term SUBI4=4421
187
%term SUBI8=8517
188
%term SUBP4=4423
189
%term SUBP8=8519
190
%term SUBU4=4422
191
%term SUBU8=8518
192
 
193
%term LSHI4=4437
194
%term LSHI8=8533
195
%term LSHU4=4438
196
%term LSHU8=8534
197
 
198
%term MODI4=4453
199
%term MODI8=8549
200
%term MODU4=4454
201
%term MODU8=8550
202
 
203
%term RSHI4=4469
204
%term RSHI8=8565
205
%term RSHU4=4470
206
%term RSHU8=8566
207
 
208
%term BANDI4=4485
209
%term BANDI8=8581
210
%term BANDU4=4486
211
%term BANDU8=8582
212
 
213
%term BCOMI4=4501
214
%term BCOMI8=8597
215
%term BCOMU4=4502
216
%term BCOMU8=8598
217
 
218
%term BORI4=4517
219
%term BORI8=8613
220
%term BORU4=4518
221
%term BORU8=8614
222
 
223
%term BXORI4=4533
224
%term BXORI8=8629
225
%term BXORU4=4534
226
%term BXORU8=8630
227
 
228
%term DIVF4=4545
229
%term DIVF8=8641
230
%term DIVF16=16833
231
%term DIVI4=4549
232
%term DIVI8=8645
233
%term DIVU4=4550
234
%term DIVU8=8646
235
 
236
%term MULF4=4561
237
%term MULF8=8657
238
%term MULF16=16849
239
%term MULI4=4565
240
%term MULI8=8661
241
%term MULU4=4566
242
%term MULU8=8662
243
 
244
%term EQF4=4577
245
%term EQF8=8673
246
%term EQF16=16865
247
%term EQI4=4581
248
%term EQI8=8677
249
%term EQU4=4582
250
%term EQU8=8678
251
 
252
%term GEF4=4593
253
%term GEF8=8689
254
%term GEI4=4597
255
%term GEI8=8693
256
%term GEI16=16885
257
%term GEU4=4598
258
%term GEU8=8694
259
 
260
%term GTF4=4609
261
%term GTF8=8705
262
%term GTF16=16897
263
%term GTI4=4613
264
%term GTI8=8709
265
%term GTU4=4614
266
%term GTU8=8710
267
 
268
%term LEF4=4625
269
%term LEF8=8721
270
%term LEF16=16913
271
%term LEI4=4629
272
%term LEI8=8725
273
%term LEU4=4630
274
%term LEU8=8726
275
 
276
%term LTF4=4641
277
%term LTF8=8737
278
%term LTF16=16929
279
%term LTI4=4645
280
%term LTI8=8741
281
%term LTU4=4646
282
%term LTU8=8742
283
 
284
%term NEF4=4657
285
%term NEF8=8753
286
%term NEF16=16945
287
%term NEI4=4661
288
%term NEI8=8757
289
%term NEU4=4662
290
%term NEU8=8758
291
 
292
%term JUMPV=584
293
 
294
%term LABELV=600
295
 
296
%term LOADB=233
297
%term LOADF4=4321
298
%term LOADF8=8417
299
%term LOADF16=16609
300
%term LOADI1=1253
301
%term LOADI2=2277
302
%term LOADI4=4325
303
%term LOADI8=8421
304
%term LOADP4=4327
305
%term LOADP8=8423
306
%term LOADU1=1254
307
%term LOADU2=2278
308
%term LOADU4=4326
309
%term LOADU8=8422
310
 
311
%term VREGP=711
312
%%
313
reg:  INDIRI1(VREGP)     "# read register\n"
314
reg:  INDIRU1(VREGP)     "# read register\n"
315
 
316
reg:  INDIRI2(VREGP)     "# read register\n"
317
reg:  INDIRU2(VREGP)     "# read register\n"
318
 
319
reg:  INDIRF4(VREGP)     "# read register\n"
320
reg:  INDIRI4(VREGP)     "# read register\n"
321
reg:  INDIRP4(VREGP)     "# read register\n"
322
reg:  INDIRU4(VREGP)     "# read register\n"
323
 
324
reg:  INDIRF8(VREGP)     "# read register\n"
325
reg:  INDIRI8(VREGP)     "# read register\n"
326
reg:  INDIRP8(VREGP)     "# read register\n"
327
reg:  INDIRU8(VREGP)     "# read register\n"
328
 
329
stmt: ASGNI1(VREGP,reg)  "# write register\n"
330
stmt: ASGNU1(VREGP,reg)  "# write register\n"
331
 
332
stmt: ASGNI2(VREGP,reg)  "# write register\n"
333
stmt: ASGNU2(VREGP,reg)  "# write register\n"
334
 
335
stmt: ASGNF4(VREGP,reg)  "# write register\n"
336
stmt: ASGNI4(VREGP,reg)  "# write register\n"
337
stmt: ASGNP4(VREGP,reg)  "# write register\n"
338
stmt: ASGNU4(VREGP,reg)  "# write register\n"
339
 
340
stmt: ASGNF8(VREGP,reg)  "# write register\n"
341
stmt: ASGNI8(VREGP,reg)  "# write register\n"
342
stmt: ASGNP8(VREGP,reg)  "# write register\n"
343
stmt: ASGNU8(VREGP,reg)  "# write register\n"
344
con: CNSTI1  "%a"
345
con: CNSTU1  "%a"
346
 
347
con: CNSTI2  "%a"
348
con: CNSTU2  "%a"
349
 
350
con: CNSTI4  "%a"
351
con: CNSTU4  "%a"
352
con: CNSTP4  "%a"
353
 
354
con: CNSTI8  "%a"
355
con: CNSTU8  "%a"
356
con: CNSTP8  "%a"
357
stmt: reg  ""
358
acon: ADDRGP4  "(%a)"
359
acon: con     "(%0)"
360
base: ADDRGP4          "(%a)"
361
base: reg              "[%0]"
362
base: ADDI4(reg,acon)  "%1[%0]"
363
base: ADDP4(reg,acon)  "%1[%0]"
364
base: ADDU4(reg,acon)  "%1[%0]"
365
base: ADDRFP4  "(%a)[ebp]"
366
base: ADDRLP4  "(%a)[ebp]"
367
index: reg "%0"
368
index: LSHI4(reg,con1)  "%0*2"
369
index: LSHI4(reg,con2)  "%0*4"
370
index: LSHI4(reg,con3)  "%0*8"
371
 
372
con1:  CNSTI4  "1"  range(a, 1, 1)
373
con1:  CNSTU4  "1"  range(a, 1, 1)
374
con2:  CNSTI4  "2"  range(a, 2, 2)
375
con2:  CNSTU4  "2"  range(a, 2, 2)
376
con3:  CNSTI4  "3"  range(a, 3, 3)
377
con3:  CNSTU4  "3"  range(a, 3, 3)
378
index: LSHU4(reg,con1)  "%0*2"
379
index: LSHU4(reg,con2)  "%0*4"
380
index: LSHU4(reg,con3)  "%0*8"
381
addr: base              "%0"
382
addr: ADDI4(index,base)  "%1[%0]"
383
addr: ADDP4(index,base)  "%1[%0]"
384
addr: ADDU4(index,base)  "%1[%0]"
385
addr: index  "[%0]"
386
mem: INDIRI1(addr)  "byte ptr %0"
387
mem: INDIRI2(addr)  "word ptr %0"
388
mem: INDIRI4(addr)  "dword ptr %0"
389
mem: INDIRU1(addr)  "byte ptr %0"
390
mem: INDIRU2(addr)  "word ptr %0"
391
mem: INDIRU4(addr)  "dword ptr %0"
392
mem: INDIRP4(addr)  "dword ptr %0"
393
rc:   reg  "%0"
394
rc:   con  "%0"
395
 
396
mr:   reg  "%0"
397
mr:   mem  "%0"
398
 
399
mrc0: mem  "%0"
400
mrc0: rc   "%0"
401
mrc1: mem  "%0"  1
402
mrc1: rc   "%0"
403
 
404
mrc3: mem  "%0"  3
405
mrc3: rc   "%0"
406
reg: addr         "lea %c,%0\n"  1
407
reg: mrc0         "mov %c,%0\n"  1
408
reg: LOADI1(reg)  "# move\n"  1
409
reg: LOADI2(reg)  "# move\n"  1
410
reg: LOADI4(reg)  "# move\n"  move(a)
411
reg: LOADU1(reg)  "# move\n"  1
412
reg: LOADU2(reg)  "# move\n"  1
413
reg: LOADU4(reg)  "# move\n"  move(a)
414
reg: LOADP4(reg)  "# move\n"  move(a)
415
reg: ADDI4(reg,mrc1)  "?mov %c,%0\nadd %c,%1\n"  1
416
reg: ADDP4(reg,mrc1)  "?mov %c,%0\nadd %c,%1\n"  1
417
reg: ADDU4(reg,mrc1)  "?mov %c,%0\nadd %c,%1\n"  1
418
reg: SUBI4(reg,mrc1)  "?mov %c,%0\nsub %c,%1\n"  1
419
reg: SUBP4(reg,mrc1)  "?mov %c,%0\nsub %c,%1\n"  1
420
reg: SUBU4(reg,mrc1)  "?mov %c,%0\nsub %c,%1\n"  1
421
reg: BANDI4(reg,mrc1)  "?mov %c,%0\nand %c,%1\n"  1
422
reg: BORI4(reg,mrc1)   "?mov %c,%0\nor %c,%1\n"   1
423
reg: BXORI4(reg,mrc1)  "?mov %c,%0\nxor %c,%1\n"  1
424
reg: BANDU4(reg,mrc1)  "?mov %c,%0\nand %c,%1\n"  1
425
reg: BORU4(reg,mrc1)   "?mov %c,%0\nor %c,%1\n"   1
426
reg: BXORU4(reg,mrc1)  "?mov %c,%0\nxor %c,%1\n"  1
427
stmt: ASGNI4(addr,ADDI4(mem,con1))  "inc %1\n"  memop(a)
428
stmt: ASGNI4(addr,ADDU4(mem,con1))  "inc %1\n"  memop(a)
429
stmt: ASGNP4(addr,ADDP4(mem,con1))  "inc %1\n"  memop(a)
430
stmt: ASGNI4(addr,SUBI4(mem,con1))  "dec %1\n"  memop(a)
431
stmt: ASGNI4(addr,SUBU4(mem,con1))  "dec %1\n"  memop(a)
432
stmt: ASGNP4(addr,SUBP4(mem,con1))  "dec %1\n"  memop(a)
433
stmt: ASGNI4(addr,ADDI4(mem,rc))   "add %1,%2\n"  memop(a)
434
stmt: ASGNI4(addr,SUBI4(mem,rc))   "sub %1,%2\n"  memop(a)
435
stmt: ASGNU4(addr,ADDU4(mem,rc))   "add %1,%2\n"  memop(a)
436
stmt: ASGNU4(addr,SUBU4(mem,rc))   "sub %1,%2\n"  memop(a)
437
 
438
stmt: ASGNI4(addr,BANDI4(mem,rc))  "and %1,%2\n"  memop(a)
439
stmt: ASGNI4(addr,BORI4(mem,rc))   "or %1,%2\n"   memop(a)
440
stmt: ASGNI4(addr,BXORI4(mem,rc))  "xor %1,%2\n"  memop(a)
441
stmt: ASGNU4(addr,BANDU4(mem,rc))  "and %1,%2\n"  memop(a)
442
stmt: ASGNU4(addr,BORU4(mem,rc))   "or %1,%2\n"   memop(a)
443
stmt: ASGNU4(addr,BXORU4(mem,rc))  "xor %1,%2\n"  memop(a)
444
reg: BCOMI4(reg)  "?mov %c,%0\nnot %c\n"  2
445
reg: BCOMU4(reg)  "?mov %c,%0\nnot %c\n"  2
446
reg: NEGI4(reg)   "?mov %c,%0\nneg %c\n"  2
447
 
448
stmt: ASGNI4(addr,BCOMI4(mem))  "not %1\n"  memop(a)
449
stmt: ASGNU4(addr,BCOMU4(mem))  "not %1\n"  memop(a)
450
stmt: ASGNI4(addr,NEGI4(mem))   "neg %1\n"  memop(a)
451
reg: LSHI4(reg,con5)  "?mov %c,%0\nsal %c,%1\n"  2
452
reg: LSHU4(reg,con5)  "?mov %c,%0\nshl %c,%1\n"  2
453
reg: RSHI4(reg,con5)  "?mov %c,%0\nsar %c,%1\n"  2
454
reg: RSHU4(reg,con5)  "?mov %c,%0\nshr %c,%1\n"  2
455
 
456
stmt: ASGNI4(addr,LSHI4(mem,con5))  "sal %1,%2\n"  memop(a)
457
stmt: ASGNI4(addr,LSHU4(mem,con5))  "shl %1,%2\n"  memop(a)
458
stmt: ASGNI4(addr,RSHI4(mem,con5))  "sar %1,%2\n"  memop(a)
459
stmt: ASGNI4(addr,RSHU4(mem,con5))  "shr %1,%2\n"  memop(a)
460
 
461
con5: CNSTI4  "%a"  range(a, 0, 31)
462
 
463
reg: LSHI4(reg,reg)  "?mov %c,%0\nmov ecx,%1\nsal %c,cl\n"  3
464
reg: LSHU4(reg,reg)  "?mov %c,%0\nmov ecx,%1\nshl %c,cl\n"  2
465
reg: RSHI4(reg,reg)  "?mov %c,%0\nmov ecx,%1\nsar %c,cl\n"  2
466
reg: RSHU4(reg,reg)  "?mov %c,%0\nmov ecx,%1\nshr %c,cl\n"  2
467
reg: MULI4(reg,mrc3)  "?mov %c,%0\nimul %c,%1\n"  14
468
reg: MULI4(con,mr)    "imul %c,%1,%0\n"  13
469
reg: MULU4(reg,mr)  "mul %1\n"  13
470
reg: DIVU4(reg,reg)  "xor edx,edx\ndiv %1\n"
471
reg: MODU4(reg,reg)  "xor edx,edx\ndiv %1\n"
472
reg: DIVI4(reg,reg)  "cdq\nidiv %1\n"
473
reg: MODI4(reg,reg)  "cdq\nidiv %1\n"
474
reg: CVPU4(reg)  "mov %c,%0\n"  move(a)
475
reg: CVUP4(reg)  "mov %c,%0\n"  move(a)
476
reg: CVII4(INDIRI1(addr))  "movsx %c,byte ptr %0\n"  3
477
reg: CVII4(INDIRI2(addr))  "movsx %c,word ptr %0\n"  3
478
reg: CVUU4(INDIRU1(addr))  "movzx %c,byte ptr %0\n"  3
479
reg: CVUU4(INDIRU2(addr))  "movzx %c,word ptr %0\n"  3
480
reg: CVII4(reg)  "# extend\n"  3
481
reg: CVIU4(reg)  "# extend\n"  3
482
reg: CVUI4(reg)  "# extend\n"  3
483
reg: CVUU4(reg)  "# extend\n"  3
484
 
485
reg: CVII1(reg)  "# truncate\n"  1
486
reg: CVII2(reg)  "# truncate\n"  1
487
reg: CVUU1(reg)  "# truncate\n"  1
488
reg: CVUU2(reg)  "# truncate\n"  1
489
stmt: ASGNI1(addr,rc)  "mov byte ptr %0,%1\n"   1
490
stmt: ASGNI2(addr,rc)  "mov word ptr %0,%1\n"   1
491
stmt: ASGNI4(addr,rc)  "mov dword ptr %0,%1\n"  1
492
stmt: ASGNU1(addr,rc)  "mov byte ptr %0,%1\n"   1
493
stmt: ASGNU2(addr,rc)  "mov word ptr %0,%1\n"   1
494
stmt: ASGNU4(addr,rc)  "mov dword ptr %0,%1\n"  1
495
stmt: ASGNP4(addr,rc)  "mov dword ptr %0,%1\n"  1
496
stmt: ARGI4(mrc3)  "push %0\n"  1
497
stmt: ARGU4(mrc3)  "push %0\n"  1
498
stmt: ARGP4(mrc3)  "push %0\n"  1
499
stmt: ASGNB(reg,INDIRB(reg))  "mov ecx,%a\nrep movsb\n"
500
stmt: ARGB(INDIRB(reg))  "# ARGB\n"
501
memf: INDIRF8(addr)         "qword ptr %0"
502
memf: INDIRF4(addr)         "dword ptr %0"
503
memf: CVFF8(INDIRF4(addr))  "dword ptr %0"
504
reg: memf  "fld %0\n"  3
505
stmt: ASGNF8(addr,reg)         "fstp qword ptr %0\n"  7
506
stmt: ASGNF4(addr,reg)         "fstp dword ptr %0\n"  7
507
stmt: ASGNF4(addr,CVFF4(reg))  "fstp dword ptr %0\n"  7
508
stmt: ARGF8(reg)  "sub esp,8\nfstp qword ptr [esp]\n"
509
stmt: ARGF4(reg)  "sub esp,4\nfstp dword ptr [esp]\n"
510
reg: NEGF8(reg)  "fchs\n"
511
reg: NEGF4(reg)  "fchs\n"
512
flt: memf  " %0"
513
flt: reg   "p st(1),st"
514
reg: ADDF8(reg,flt)  "fadd%1\n"
515
reg: ADDF4(reg,flt)  "fadd%1\n"
516
reg: DIVF8(reg,flt)  "fdiv%1\n"
517
reg: DIVF4(reg,flt)  "fdiv%1\n"
518
reg: MULF8(reg,flt)  "fmul%1\n"
519
reg: MULF4(reg,flt)  "fmul%1\n"
520
reg: SUBF8(reg,flt)  "fsub%1\n"
521
reg: SUBF4(reg,flt)  "fsub%1\n"
522
reg: CVFF8(reg)  "# CVFF8\n"
523
reg: CVFF4(reg)  "sub esp,4\nfstp dword ptr 0[esp]\nfld dword ptr 0[esp]\nadd esp,4\n"  12
524
 
525
reg: CVFI4(reg)  "call __ftol\n" 31
526
reg: CVIF8(INDIRI4(addr))  "fild dword ptr %0\n"  10
527
reg: CVIF4(reg)  "push %0\nfild dword ptr 0[esp]\nadd esp,4\n"  12
528
 
529
reg: CVIF8(reg)  "push %0\nfild dword ptr 0[esp]\nadd esp,4\n"  12
530
 
531
addrj: ADDRGP4  "%a"
532
addrj: reg      "%0"  2
533
addrj: mem      "%0"  2
534
 
535
stmt:  JUMPV(addrj)  "jmp %0\n"  3
536
stmt:  LABELV        "%a:\n"
537
stmt: EQI4(mem,rc)  "cmp %0,%1\nje %a\n"   5
538
stmt: GEI4(mem,rc)  "cmp %0,%1\njge %a\n"  5
539
stmt: GTI4(mem,rc)  "cmp %0,%1\njg %a\n"   5
540
stmt: LEI4(mem,rc)  "cmp %0,%1\njle %a\n"  5
541
stmt: LTI4(mem,rc)  "cmp %0,%1\njl %a\n"   5
542
stmt: NEI4(mem,rc)  "cmp %0,%1\njne %a\n"  5
543
stmt: GEU4(mem,rc)  "cmp %0,%1\njae %a\n"  5
544
stmt: GTU4(mem,rc)  "cmp %0,%1\nja  %a\n"  5
545
stmt: LEU4(mem,rc)  "cmp %0,%1\njbe %a\n"  5
546
stmt: LTU4(mem,rc)  "cmp %0,%1\njb  %a\n"  5
547
stmt: EQI4(reg,mrc1)  "cmp %0,%1\nje %a\n"   4
548
stmt: GEI4(reg,mrc1)  "cmp %0,%1\njge %a\n"  4
549
stmt: GTI4(reg,mrc1)  "cmp %0,%1\njg %a\n"   4
550
stmt: LEI4(reg,mrc1)  "cmp %0,%1\njle %a\n"  4
551
stmt: LTI4(reg,mrc1)  "cmp %0,%1\njl %a\n"   4
552
stmt: NEI4(reg,mrc1)  "cmp %0,%1\njne %a\n"  4
553
 
554
stmt: EQU4(reg,mrc1)  "cmp %0,%1\nje %a\n"   4
555
stmt: GEU4(reg,mrc1)  "cmp %0,%1\njae %a\n"  4
556
stmt: GTU4(reg,mrc1)  "cmp %0,%1\nja %a\n"   4
557
stmt: LEU4(reg,mrc1)  "cmp %0,%1\njbe %a\n"  4
558
stmt: LTU4(reg,mrc1)  "cmp %0,%1\njb %a\n"   4
559
stmt: NEU4(reg,mrc1)  "cmp %0,%1\njne %a\n"  4
560
cmpf: memf  " %0"
561
cmpf: reg   "p"
562
stmt: EQF8(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %b\nje %a\n%b:\n"
563
stmt: GEF8(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njbe %a\n"
564
stmt: GTF8(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njb %a\n"
565
stmt: LEF8(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njae %a\n"
566
stmt: LTF8(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\nja %a\n"
567
stmt: NEF8(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njne %a\n"
568
 
569
stmt: EQF4(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %b\nje %a\n%b:\n"
570
stmt: GEF4(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njbe %a\n\n"
571
stmt: GTF4(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njb %a\n"
572
stmt: LEF4(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njae %a\n\n"
573
stmt: LTF4(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\nja %a\n"
574
stmt: NEF4(cmpf,reg)  "fcomp%0\nfstsw ax\nsahf\njp %a\njne %a\n"
575
reg:  CALLI4(addrj)  "call %0\nadd esp,%a\n"
576
reg:  CALLU4(addrj)  "call %0\nadd esp,%a\n"
577
reg:  CALLP4(addrj)  "call %0\nadd esp,%a\n"
578
stmt: CALLV(addrj)   "call %0\nadd esp,%a\n"
579
reg: CALLF4(addrj)  "call %0\nadd esp,%a\n"
580
reg: CALLF8(addrj)  "call %0\nadd esp,%a\n"
581
stmt: CALLF4(addrj)  "call %0\nadd esp,%a\nfstp\n"
582
stmt: CALLF8(addrj)  "call %0\nadd esp,%a\nfstp\n"
583
 
584
stmt: RETI4(reg)  "# ret\n"
585
stmt: RETU4(reg)  "# ret\n"
586
stmt: RETP4(reg)  "# ret\n"
587
stmt: RETF4(reg)  "# ret\n"
588
stmt: RETF8(reg)  "# ret\n"
589
%%
590
static void progbeg(int argc, char *argv[]) {
591
        int i;
592
 
593
        {
594
                union {
595
                        char c;
596
                        int i;
597
                } u;
598
                u.i = 0;
599
                u.c = 1;
600
                swap = ((int)(u.i == 1)) != IR->little_endian;
601
        }
602
        parseflags(argc, argv);
603
        intreg[EAX] = mkreg("eax", EAX, 1, IREG);
604
        intreg[EDX] = mkreg("edx", EDX, 1, IREG);
605
        intreg[ECX] = mkreg("ecx", ECX, 1, IREG);
606
        intreg[EBX] = mkreg("ebx", EBX, 1, IREG);
607
        intreg[ESI] = mkreg("esi", ESI, 1, IREG);
608
        intreg[EDI] = mkreg("edi", EDI, 1, IREG);
609
 
610
        shortreg[EAX] = mkreg("ax", EAX, 1, IREG);
611
        shortreg[ECX] = mkreg("cx", ECX, 1, IREG);
612
        shortreg[EDX] = mkreg("dx", EDX, 1, IREG);
613
        shortreg[EBX] = mkreg("bx", EBX, 1, IREG);
614
        shortreg[ESI] = mkreg("si", ESI, 1, IREG);
615
        shortreg[EDI] = mkreg("di", EDI, 1, IREG);
616
 
617
        charreg[EAX]  = mkreg("al", EAX, 1, IREG);
618
        charreg[ECX]  = mkreg("cl", ECX, 1, IREG);
619
        charreg[EDX]  = mkreg("dl", EDX, 1, IREG);
620
        charreg[EBX]  = mkreg("bl", EBX, 1, IREG);
621
        for (i = 0; i < 8; i++)
622
                fltreg[i] = mkreg("%d", i, 0, FREG);
623
        charregw = mkwildcard(charreg);
624
        shortregw = mkwildcard(shortreg);
625
        intregw = mkwildcard(intreg);
626
        fltregw = mkwildcard(fltreg);
627
 
628
        tmask[IREG] = (1<
629
                    | (1<
630
        vmask[IREG] = 0;
631
        tmask[FREG] = 0xff;
632
        vmask[FREG] = 0;
633
        print(".486\n");
634
        print(".model flat\n");
635
        print("extrn __fltused:near\n");
636
        print("extrn __ftol:near\n");
637
        cseg = 0;
638
        quo = mkreg("eax", EAX, 1, IREG);
639
        quo->x.regnode->mask |= 1<
640
        rem = mkreg("edx", EDX, 1, IREG);
641
        rem->x.regnode->mask |= 1<
642
}
643
static Symbol rmap(int opk) {
644
        switch (optype(opk)) {
645
        case B: case P:
646
                return intregw;
647
        case I: case U:
648
                if (opsize(opk) == 1)
649
                        return charregw;
650
                else if (opsize(opk) == 2)
651
                        return shortregw;
652
                else
653
                        return intregw;
654
        case F:
655
                return fltregw;
656
        default:
657
                return 0;
658
        }
659
}
660
static void segment(int n) {
661
        if (n == cseg)
662
                return;
663
        if (cseg == CODE || cseg == LIT)
664
                print("_TEXT ends\n");
665
        else if (cseg == DATA || cseg == BSS)
666
                print("_DATA ends\n");
667
        cseg = n;
668
        if (cseg == CODE || cseg == LIT)
669
                print("_TEXT segment\n");
670
        else if (cseg == DATA || cseg == BSS)
671
                print("_DATA segment\n");
672
}
673
static void progend(void) {
674
        segment(0);
675
        print("end\n");
676
}
677
static void target(Node p) {
678
        assert(p);
679
        switch (specific(p->op)) {
680
        case MUL+U:
681
                setreg(p, quo);
682
                rtarget(p, 0, intreg[EAX]);
683
                break;
684
        case DIV+I: case DIV+U:
685
                setreg(p, quo);
686
                rtarget(p, 0, quo);
687
                break;
688
        case MOD+I: case MOD+U:
689
                setreg(p, rem);
690
                rtarget(p, 0, quo);
691
                break;
692
        case ASGN+B:
693
                rtarget(p, 0, intreg[EDI]);
694
                rtarget(p->kids[1], 0, intreg[ESI]);
695
                break;
696
        case ARG+B:
697
                rtarget(p->kids[0], 0, intreg[ESI]);
698
                break;
699
        case CVF+I:
700
                setreg(p, intreg[EAX]);
701
                break;
702
        case CALL+I: case CALL+U: case CALL+P: case CALL+V:
703
                setreg(p, intreg[EAX]);
704
                break;
705
        case RET+I: case RET+U: case RET+P:
706
                rtarget(p, 0, intreg[EAX]);
707
                break;
708
        }
709
}
710
 
711
static void clobber(Node p) {
712
        static int nstack = 0;
713
 
714
        assert(p);
715
        nstack = ckstack(p, nstack);
716
        switch (specific(p->op)) {
717
        case RSH+I: case RSH+U: case LSH+I: case LSH+U:
718
                if (generic(p->kids[1]->op) != CNST
719
                && !(   generic(p->kids[1]->op) == INDIR
720
                     && specific(p->kids[1]->kids[0]->op) == VREG+P
721
                     && p->kids[1]->syms[RX]->u.t.cse
722
                     && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST
723
)) {
724
                        spill(1<
725
                }
726
                break;
727
        case ASGN+B: case ARG+B:
728
                spill(1<
729
                break;
730
        case EQ+F: case LE+F: case GE+F: case LT+F: case GT+F: case NE+F:
731
                spill(1<
732
                if (specific(p->op) == EQ+F)
733
                        p->syms[1] = findlabel(genlabel(1));
734
                break;
735
        case CALL+F:
736
                spill(1<
737
                break;
738
        case CALL+I: case CALL+U: case CALL+P: case CALL+V:
739
                spill(1<
740
                break;
741
        }
742
}
743
#define isfp(p) (optype((p)->op)==F)
744
 
745
int ckstack(Node p, int n) {
746
        int i;
747
 
748
        for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
749
                if (isfp(p->x.kids[i]))
750
                        n--;
751
        if (isfp(p) && p->count > 0)
752
                n++;
753
        if (n > 8)
754
                error("expression too complicated\n");
755
        debug(fprint(stderr, "(ckstack(%x)=%d)\n", p, n));
756
        assert(n >= 0);
757
        return n;
758
}
759
int memop(Node p) {
760
        assert(p);
761
        assert(generic(p->op) == ASGN);
762
        assert(p->kids[0]);
763
        assert(p->kids[1]);
764
        if (generic(p->kids[1]->kids[0]->op) == INDIR
765
        && sametree(p->kids[0], p->kids[1]->kids[0]->kids[0]))
766
                return 3;
767
        else
768
                return LBURG_MAX;
769
}
770
int sametree(Node p, Node q) {
771
        return p == NULL && q == NULL
772
        || p && q && p->op == q->op && p->syms[0] == q->syms[0]
773
                && sametree(p->kids[0], q->kids[0])
774
                && sametree(p->kids[1], q->kids[1]);
775
}
776
static void emit2(Node p) {
777
        int op = specific(p->op);
778
#define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name)
779
 
780
        if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
781
                print("movsx %s,%s\n", p->syms[RX]->x.name
782
, preg(charreg));
783
        else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
784
                print("movsx %s,%s\n", p->syms[RX]->x.name
785
, preg(charreg));
786
        else if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
787
                print("movsx %s,%s\n", p->syms[RX]->x.name
788
, preg(shortreg));
789
        else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
790
                print("movsx %s,%s\n", p->syms[RX]->x.name
791
, preg(shortreg));
792
 
793
        else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
794
                print("movzx %s,%s\n", p->syms[RX]->x.name
795
, preg(charreg));
796
        else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1)
797
                print("movzx %s,%s\n", p->syms[RX]->x.name
798
, preg(charreg));
799
        else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
800
                print("movzx %s,%s\n", p->syms[RX]->x.name
801
, preg(shortreg));
802
        else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2)
803
                print("movzx %s,%s\n", p->syms[RX]->x.name
804
, preg(shortreg));
805
        else if (generic(op) == CVI || generic(op) == CVU || generic(op) == LOAD) {
806
                char *dst = intreg[getregnum(p)]->x.name;
807
                char *src = preg(intreg);
808
                assert(opsize(p->op) <= opsize(p->x.kids[0]->op));
809
                if (dst != src)
810
                        print("mov %s,%s\n", dst, src);
811
        }
812
        else if (op == ARG+B)
813
                print("sub esp,%d\nmov edi,esp\nmov ecx,%d\nrep movsb\n",
814
                        roundup(p->syms[0]->u.c.v.i, 4), p->syms[0]->u.c.v.i);
815
}
816
 
817
static void doarg(Node p) {
818
        assert(p && p->syms[0]);
819
        mkactual(4, p->syms[0]->u.c.v.i);
820
}
821
static void blkfetch(int k, int off, int reg, int tmp) {}
822
static void blkstore(int k, int off, int reg, int tmp) {}
823
static void blkloop(int dreg, int doff, int sreg, int soff,
824
        int size, int tmps[]) {}
825
static void local(Symbol p) {
826
        if (isfloat(p->type))
827
                p->sclass = AUTO;
828
        if (askregvar(p, (*IR->x.rmap)(ttob(p->type))) == 0) {
829
                assert(p->sclass == AUTO);
830
                offset = roundup(offset + p->type->size,
831
                        p->type->align < 4 ? 4 : p->type->align);
832
                p->x.offset = -offset;
833
                p->x.name = stringd(-offset);
834
        }
835
}
836
static void function(Symbol f, Symbol caller[], Symbol callee[], int n) {
837
        int i;
838
 
839
        print("%s:\n", f->x.name);
840
        print("push ebx\n");
841
        print("push esi\n");
842
        print("push edi\n");
843
        print("push ebp\n");
844
        print("mov ebp,esp\n");
845
        usedmask[0] = usedmask[1] = 0;
846
        freemask[0] = freemask[1] = ~(unsigned)0;
847
        offset = 16 + 4;
848
        for (i = 0; callee[i]; i++) {
849
                Symbol p = callee[i];
850
                Symbol q = caller[i];
851
                assert(q);
852
                p->x.offset = q->x.offset = offset;
853
                p->x.name = q->x.name = stringf("%d", p->x.offset);
854
                p->sclass = q->sclass = AUTO;
855
                offset += roundup(q->type->size, 4);
856
        }
857
        assert(caller[i] == 0);
858
        offset = maxoffset = 0;
859
        gencode(caller, callee);
860
        framesize = roundup(maxoffset, 4);
861
        if (framesize >= 4096)
862
                print("mov eax,%d\ncall __chkstk\n", framesize);
863
        else if (framesize > 0)
864
                print("sub esp,%d\n", framesize);
865
        emitcode();
866
        print("mov esp,ebp\n");
867
        print("pop ebp\n");
868
        print("pop edi\n");
869
        print("pop esi\n");
870
        print("pop ebx\n");
871
        print("ret\n");
872
        if (framesize >= 4096) {
873
                int oldseg = cseg;
874
                segment(0);
875
                print("extrn __chkstk:near\n");
876
                segment(oldseg);
877
        }
878
}
879
static void defsymbol(Symbol p) {
880
        if (p->scope >= LOCAL && p->sclass == STATIC)
881
                p->x.name = stringf("L%d", genlabel(1));
882
        else if (p->generated)
883
                p->x.name = stringf("L%s", p->name);
884
        else if (p->scope == GLOBAL || p->sclass == EXTERN)
885
                p->x.name = stringf("_%s", p->name);
886
        else if (p->scope == CONSTANTS
887
        && (isint(p->type) || isptr(p->type))
888
        && p->name[0] == '0' && p->name[1] == 'x')
889
                p->x.name = stringf("0%sH", &p->name[2]);
890
        else
891
                p->x.name = p->name;
892
}
893
static void address(Symbol q, Symbol p, long n) {
894
        if (p->scope == GLOBAL
895
        || p->sclass == STATIC || p->sclass == EXTERN)
896
                q->x.name = stringf("%s%s%D",
897
                        p->x.name, n >= 0 ? "+" : "", n);
898
        else {
899
                assert(n <= INT_MAX && n >= INT_MIN);
900
                q->x.offset = p->x.offset + n;
901
                q->x.name = stringd(q->x.offset);
902
        }
903
}
904
static void defconst(int suffix, int size, Value v) {
905
        if (suffix == I && size == 1)
906
                print("db %d\n",   v.u);
907
        else if (suffix == I && size == 2)
908
                print("dw %d\n",   v.i);
909
        else if (suffix == I && size == 4)
910
                print("dd %d\n",   v.i);
911
        else if (suffix == U && size == 1)
912
                print("db 0%xH\n", (unsigned)((unsigned char)v.u));
913
        else if (suffix == U && size == 2)
914
                print("dw 0%xH\n", (unsigned)((unsigned short)v.u));
915
        else if (suffix == U && size == 4)
916
                print("dd 0%xH\n", (unsigned)v.u);
917
        else if (suffix == P && size == 4)
918
                print("dd 0%xH\n", (unsigned)v.p);
919
        else if (suffix == F && size == 4) {
920
                float f = v.d;
921
                print("dd 0%xH\n", *(unsigned *)&f);
922
        }
923
        else if (suffix == F && size == 8) {
924
                double d = v.d;
925
                unsigned *p = (unsigned *)&d;
926
                print("dd 0%xH\ndd 0%xH\n", p[swap], p[!swap]);
927
        }
928
        else assert(0);
929
}
930
static void defaddress(Symbol p) {
931
        print("dd %s\n", p->x.name);
932
}
933
static void defstring(int n, char *str) {
934
        char *s;
935
 
936
        for (s = str; s < str + n; s++)
937
                print("db %d\n", (*s)&0377);
938
}
939
static void export(Symbol p) {
940
        print("public %s\n", p->x.name);
941
}
942
static void import(Symbol p) {
943
        int oldseg = cseg;
944
 
945
        if (p->ref > 0) {
946
                segment(0);
947
                print("extrn %s:near\n", p->x.name);
948
                segment(oldseg);
949
        }
950
}
951
static void global(Symbol p) {
952
        print("align %d\n",
953
                p->type->align > 4 ? 4 : p->type->align);
954
        print("%s label byte\n", p->x.name);
955
}
956
static void space(int n) {
957
        print("db %d dup (0)\n", n);
958
}
959
Interface x86IR = {
960
        1, 1, 0,  /* char */
961
        2, 2, 0,  /* short */
962
        4, 4, 0,  /* int */
963
        4, 4, 0,  /* long */
964
        4, 4, 0,  /* long long */
965
        4, 4, 1,  /* float */
966
        8, 4, 1,  /* double */
967
        8, 4, 1,  /* long double */
968
        4, 4, 0,  /* T * */
969
        0, 1, 0,  /* struct */
970
        1,        /* little_endian */
971
        0,        /* mulops_calls */
972
        0,        /* wants_callb */
973
        1,        /* wants_argb */
974
        0,        /* left_to_right */
975
        0,        /* wants_dag */
976
        0,        /* unsigned_char */
977
        address,
978
        blockbeg,
979
        blockend,
980
        defaddress,
981
        defconst,
982
        defstring,
983
        defsymbol,
984
        emit,
985
        export,
986
        function,
987
        gen,
988
        global,
989
        import,
990
        local,
991
        progbeg,
992
        progend,
993
        segment,
994
        space,
995
        0, 0, 0, 0, 0, 0, 0,
996
        {1, rmap,
997
            blkfetch, blkstore, blkloop,
998
            _label,
999
            _rule,
1000
            _nts,
1001
            _kids,
1002
            _string,
1003
            _templates,
1004
            _isinstruction,
1005
            _ntname,
1006
            emit2,
1007
            doarg,
1008
            target,
1009
            clobber,
1010
}
1011
};
1012
static char rcsid[] = "$Id: x86.md,v 1.1 2002/08/28 23:12:48 drh Exp $";

powered by: WebSVN 2.1.0

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