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