Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
%{
2
#include "a.h"
3
%}
4
%union	{
5
	Sym	*sym;
6
	vlong	lval;
7
	double	dval;
8
	char	sval[8];
9
	Gen	gen;
10
	Gen2	gen2;
11
}
12
%left	'|'
13
%left	'^'
14
%left	'&'
15
%left	'<' '>'
16
%left	'+' '-'
17
%left	'*' '/' '%'
18
%token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
19
%token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT
20
%token	<lval>	LCONST LFP LPC LSB
21
%token	<lval>	LBREG LLREG LSREG LFREG LMREG LXREG
22
%token	<dval>	LFCONST
23
%token	<sval>	LSCONST LSP
24
%token	<sym>	LNAME LLAB LVAR
25
%type	<lval>	con expr pointer offset
26
%type	<gen>	mem imm reg nam rel rem rim rom omem nmem
27
%type	<gen2>	nonnon nonrel nonrem rimnon rimrem remrim spec10
28
%type	<gen2>	spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
29
%%
30
prog:
31
|	prog line
32
 
33
line:
34
	LLAB ':'
35
	{
36
		if($1->value != pc)
37
			yyerror("redeclaration of %s", $1->name);
38
		$1->value = pc;
39
	}
40
	line
41
|	LNAME ':'
42
	{
43
		$1->type = LLAB;
44
		$1->value = pc;
45
	}
46
	line
47
|	';'
48
|	inst ';'
49
|	error ';'
50
 
51
inst:
52
	LNAME '=' expr
53
	{
54
		$1->type = LVAR;
55
		$1->value = $3;
56
	}
57
|	LVAR '=' expr
58
	{
59
		if($1->value != $3)
60
			yyerror("redeclaration of %s", $1->name);
61
		$1->value = $3;
62
	}
63
|	LTYPE0 nonnon	{ outcode($1, &$2); }
64
|	LTYPE1 nonrem	{ outcode($1, &$2); }
65
|	LTYPE2 rimnon	{ outcode($1, &$2); }
66
|	LTYPE3 rimrem	{ outcode($1, &$2); }
67
|	LTYPE4 remrim	{ outcode($1, &$2); }
68
|	LTYPER nonrel	{ outcode($1, &$2); }
69
|	LTYPED spec1	{ outcode($1, &$2); }
70
|	LTYPET spec2	{ outcode($1, &$2); }
71
|	LTYPEC spec3	{ outcode($1, &$2); }
72
|	LTYPEN spec4	{ outcode($1, &$2); }
73
|	LTYPES spec5	{ outcode($1, &$2); }
74
|	LTYPEM spec6	{ outcode($1, &$2); }
75
|	LTYPEI spec7	{ outcode($1, &$2); }
76
|	LTYPEXC spec8	{ outcode($1, &$2); }
77
|	LTYPEX spec9	{ outcode($1, &$2); }
78
|	LTYPERT spec10	{ outcode($1, &$2); }
79
 
80
nonnon:
81
	{
82
		$$.from = nullgen;
83
		$$.to = nullgen;
84
	}
85
|	','
86
	{
87
		$$.from = nullgen;
88
		$$.to = nullgen;
89
	}
90
 
91
rimrem:
92
	rim ',' rem
93
	{
94
		$$.from = $1;
95
		$$.to = $3;
96
	}
97
 
98
remrim:
99
	rem ',' rim
100
	{
101
		$$.from = $1;
102
		$$.to = $3;
103
	}
104
 
105
rimnon:
106
	rim ','
107
	{
108
		$$.from = $1;
109
		$$.to = nullgen;
110
	}
111
|	rim
112
	{
113
		$$.from = $1;
114
		$$.to = nullgen;
115
	}
116
 
117
nonrem:
118
	',' rem
119
	{
120
		$$.from = nullgen;
121
		$$.to = $2;
122
	}
123
|	rem
124
	{
125
		$$.from = nullgen;
126
		$$.to = $1;
127
	}
128
 
129
nonrel:
130
	',' rel
131
	{
132
		$$.from = nullgen;
133
		$$.to = $2;
134
	}
135
|	rel
136
	{
137
		$$.from = nullgen;
138
		$$.to = $1;
139
	}
140
 
141
spec1:	/* DATA */
142
	nam '/' con ',' imm
143
	{
144
		$$.from = $1;
145
		$$.from.scale = $3;
146
		$$.to = $5;
147
	}
148
 
149
spec2:	/* TEXT */
150
	mem ',' imm
151
	{
152
		$$.from = $1;
153
		$$.to = $3;
154
	}
155
|	mem ',' con ',' imm
156
	{
157
		$$.from = $1;
158
		$$.from.scale = $3;
159
		$$.to = $5;
160
	}
161
 
162
spec3:	/* JMP/CALL */
163
	',' rom
164
	{
165
		$$.from = nullgen;
166
		$$.to = $2;
167
	}
168
|	rom
169
	{
170
		$$.from = nullgen;
171
		$$.to = $1;
172
	}
173
 
174
spec4:	/* NOP */
175
	nonnon
176
|	nonrem
177
 
178
spec5:	/* SHL/SHR */
179
	rim ',' rem
180
	{
181
		$$.from = $1;
182
		$$.to = $3;
183
	}
184
|	rim ',' rem ':' LLREG
185
	{
186
		$$.from = $1;
187
		$$.to = $3;
188
		if($$.from.index != D_NONE)
189
			yyerror("dp shift with lhs index");
190
		$$.from.index = $5;
191
	}
192
 
193
spec6:	/* MOVW/MOVL */
194
	rim ',' rem
195
	{
196
		$$.from = $1;
197
		$$.to = $3;
198
	}
199
|	rim ',' rem ':' LSREG
200
	{
201
		$$.from = $1;
202
		$$.to = $3;
203
		if($$.to.index != D_NONE)
204
			yyerror("dp move with lhs index");
205
		$$.to.index = $5;
206
	}
207
 
208
spec7:
209
	rim ','
210
	{
211
		$$.from = $1;
212
		$$.to = nullgen;
213
	}
214
|	rim
215
	{
216
		$$.from = $1;
217
		$$.to = nullgen;
218
	}
219
|	rim ',' rem
220
	{
221
		$$.from = $1;
222
		$$.to = $3;
223
	}
224
 
225
spec8:	/* CMPPS/CMPPD */
226
	reg ',' rem ',' con
227
	{
228
		$$.from = $1;
229
		$$.to = $3;
230
		$$.from.offset = $5;
231
	}
232
 
233
spec9:	/* shufl */
234
	imm ',' rem ',' reg
235
	{
236
		$$.from = $3;
237
		$$.to = $5;
238
		if($1.type != D_CONST)
239
			yyerror("illegal constant");
240
		$$.to.offset = $1.offset;
241
	}
242
 
243
spec10:	/* RET/RETF */
244
	{
245
		$$.from = nullgen;
246
		$$.to = nullgen;
247
	}
248
|	imm
249
	{
250
		$$.from = $1;
251
		$$.to = nullgen;
252
	}
253
 
254
rem:
255
	reg
256
|	mem
257
 
258
rom:
259
	rel
260
|	nmem
261
|	'*' reg
262
	{
263
		$$ = $2;
264
	}
265
|	'*' omem
266
	{
267
		$$ = $2;
268
	}
269
|	reg
270
|	omem
271
 
272
rim:
273
	rem
274
|	imm
275
 
276
rel:
277
	con '(' LPC ')'
278
	{
279
		$$ = nullgen;
280
		$$.type = D_BRANCH;
281
		$$.offset = $1 + pc;
282
	}
283
|	LNAME offset
284
	{
285
		$$ = nullgen;
286
		if(pass == 2)
287
			yyerror("undefined label: %s", $1->name);
288
		$$.type = D_BRANCH;
289
		$$.sym = $1;
290
		$$.offset = $2;
291
	}
292
|	LLAB offset
293
	{
294
		$$ = nullgen;
295
		$$.type = D_BRANCH;
296
		$$.sym = $1;
297
		$$.offset = $1->value + $2;
298
	}
299
 
300
reg:
301
	LBREG
302
	{
303
		$$ = nullgen;
304
		$$.type = $1;
305
	}
306
|	LFREG
307
	{
308
		$$ = nullgen;
309
		$$.type = $1;
310
	}
311
|	LLREG
312
	{
313
		$$ = nullgen;
314
		$$.type = $1;
315
	}
316
|	LMREG
317
	{
318
		$$ = nullgen;
319
		$$.type = $1;
320
	}
321
|	LSP
322
	{
323
		$$ = nullgen;
324
		$$.type = D_SP;
325
	}
326
|	LSREG
327
	{
328
		$$ = nullgen;
329
		$$.type = $1;
330
	}
331
|	LXREG
332
	{
333
		$$ = nullgen;
334
		$$.type = $1;
335
	}
336
 
337
imm:
338
	'$' con
339
	{
340
		$$ = nullgen;
341
		$$.type = D_CONST;
342
		$$.offset = $2;
343
	}
344
|	'$' nam
345
	{
346
		$$ = $2;
347
		$$.index = $2.type;
348
		$$.type = D_ADDR;
349
		/*
350
		if($2.type == D_AUTO || $2.type == D_PARAM)
351
			yyerror("constant cannot be automatic: %s",
352
				$2.sym->name);
353
		 */
354
	}
355
|	'$' LSCONST
356
	{
357
		$$ = nullgen;
358
		$$.type = D_SCONST;
359
		memcpy($$.sval, $2, sizeof($$.sval));
360
	}
361
|	'$' LFCONST
362
	{
363
		$$ = nullgen;
364
		$$.type = D_FCONST;
365
		$$.dval = $2;
366
	}
367
|	'$' '(' LFCONST ')'
368
	{
369
		$$ = nullgen;
370
		$$.type = D_FCONST;
371
		$$.dval = $3;
372
	}
373
|	'$' '-' LFCONST
374
	{
375
		$$ = nullgen;
376
		$$.type = D_FCONST;
377
		$$.dval = -$3;
378
	}
379
 
380
mem:
381
	omem
382
|	nmem
383
 
384
omem:
385
	con
386
	{
387
		$$ = nullgen;
388
		$$.type = D_INDIR+D_NONE;
389
		$$.offset = $1;
390
	}
391
|	con '(' LLREG ')'
392
	{
393
		$$ = nullgen;
394
		$$.type = D_INDIR+$3;
395
		$$.offset = $1;
396
	}
397
|	con '(' LSP ')'
398
	{
399
		$$ = nullgen;
400
		$$.type = D_INDIR+D_SP;
401
		$$.offset = $1;
402
	}
403
|	con '(' LLREG '*' con ')'
404
	{
405
		$$ = nullgen;
406
		$$.type = D_INDIR+D_NONE;
407
		$$.offset = $1;
408
		$$.index = $3;
409
		$$.scale = $5;
410
		checkscale($$.scale);
411
	}
412
|	con '(' LLREG ')' '(' LLREG '*' con ')'
413
	{
414
		$$ = nullgen;
415
		$$.type = D_INDIR+$3;
416
		$$.offset = $1;
417
		$$.index = $6;
418
		$$.scale = $8;
419
		checkscale($$.scale);
420
	}
421
|	'(' LLREG ')'
422
	{
423
		$$ = nullgen;
424
		$$.type = D_INDIR+$2;
425
	}
426
|	'(' LSP ')'
427
	{
428
		$$ = nullgen;
429
		$$.type = D_INDIR+D_SP;
430
	}
431
|	'(' LLREG '*' con ')'
432
	{
433
		$$ = nullgen;
434
		$$.type = D_INDIR+D_NONE;
435
		$$.index = $2;
436
		$$.scale = $4;
437
		checkscale($$.scale);
438
	}
439
|	'(' LLREG ')' '(' LLREG '*' con ')'
440
	{
441
		$$ = nullgen;
442
		$$.type = D_INDIR+$2;
443
		$$.index = $5;
444
		$$.scale = $7;
445
		checkscale($$.scale);
446
	}
447
 
448
nmem:
449
	nam
450
	{
451
		$$ = $1;
452
	}
453
|	nam '(' LLREG '*' con ')'
454
	{
455
		$$ = $1;
456
		$$.index = $3;
457
		$$.scale = $5;
458
		checkscale($$.scale);
459
	}
460
 
461
nam:
462
	LNAME offset '(' pointer ')'
463
	{
464
		$$ = nullgen;
465
		$$.type = $4;
466
		$$.sym = $1;
467
		$$.offset = $2;
468
	}
469
|	LNAME '<' '>' offset '(' LSB ')'
470
	{
471
		$$ = nullgen;
472
		$$.type = D_STATIC;
473
		$$.sym = $1;
474
		$$.offset = $4;
475
	}
476
 
477
offset:
478
	{
479
		$$ = 0;
480
	}
481
|	'+' con
482
	{
483
		$$ = $2;
484
	}
485
|	'-' con
486
	{
487
		$$ = -$2;
488
	}
489
 
490
pointer:
491
	LSB
492
|	LSP
493
	{
494
		$$ = D_AUTO;
495
	}
496
|	LFP
497
 
498
con:
499
	LCONST
500
|	LVAR
501
	{
502
		$$ = $1->value;
503
	}
504
|	'-' con
505
	{
506
		$$ = -$2;
507
	}
508
|	'+' con
509
	{
510
		$$ = $2;
511
	}
512
|	'~' con
513
	{
514
		$$ = ~$2;
515
	}
516
|	'(' expr ')'
517
	{
518
		$$ = $2;
519
	}
520
 
521
expr:
522
	con
523
|	expr '+' expr
524
	{
525
		$$ = $1 + $3;
526
	}
527
|	expr '-' expr
528
	{
529
		$$ = $1 - $3;
530
	}
531
|	expr '*' expr
532
	{
533
		$$ = $1 * $3;
534
	}
535
|	expr '/' expr
536
	{
537
		$$ = $1 / $3;
538
	}
539
|	expr '%' expr
540
	{
541
		$$ = $1 % $3;
542
	}
543
|	expr '<' '<' expr
544
	{
545
		$$ = $1 << $4;
546
	}
547
|	expr '>' '>' expr
548
	{
549
		$$ = $1 >> $4;
550
	}
551
|	expr '&' expr
552
	{
553
		$$ = $1 & $3;
554
	}
555
|	expr '^' expr
556
	{
557
		$$ = $1 ^ $3;
558
	}
559
|	expr '|' expr
560
	{
561
		$$ = $1 | $3;
562
	}