Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
%{
2
#include "a.h"
3
%}
4
%union
5
{
6
	Sym	*sym;
7
	long	lval;
8
	double	dval;
9
	char	sval[8];
10
	Gen	gen;
11
}
12
%left	'|'
13
%left	'^'
14
%left	'&'
15
%left	'<' '>'
16
%left	'+' '-'
17
%left	'*' '/' '%'
18
%token	<lval>	LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
19
%token	<lval>	LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
20
%token	<lval>	LTYPEB LTYPEC LTYPED LTYPEE LTYPEF
21
%token	<lval>	LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
22
%token	<lval>	LTYPEL LTYPEM LTYPEN LTYPEBX
23
%token	<lval>	LCONST LSP LSB LFP LPC
24
%token	<lval>	LTYPEX LR LREG LF LFREG LC LCREG LPSR LFCR
25
%token	<lval>	LCOND LS LAT
26
%token	<dval>	LFCONST
27
%token	<sval>	LSCONST
28
%token	<sym>	LNAME LLAB LVAR
29
%type	<lval>	con expr oexpr pointer offset sreg spreg creg
30
%type	<lval>	rcon cond reglist
31
%type	<gen>	gen rel reg regreg freg shift fcon frcon
32
%type	<gen>	imm ximm name oreg ireg nireg ioreg imsr
33
%%
34
prog:
35
|	prog line
36
 
37
line:
38
	LLAB ':'
39
	{
40
		if($1->value != pc)
41
			yyerror("redeclaration of %s", $1->name);
42
		$1->value = pc;
43
	}
44
	line
45
|	LNAME ':'
46
	{
47
		$1->type = LLAB;
48
		$1->value = pc;
49
	}
50
	line
51
|	LNAME '=' expr ';'
52
	{
53
		$1->type = LVAR;
54
		$1->value = $3;
55
	}
56
|	LVAR '=' expr ';'
57
	{
58
		if($1->value != $3)
59
			yyerror("redeclaration of %s", $1->name);
60
		$1->value = $3;
61
	}
62
|	';'
63
|	inst ';'
64
|	error ';'
65
 
66
inst:
67
/*
68
 * ADD
69
 */
70
	LTYPE1 cond imsr ',' spreg ',' reg
71
	{
72
		outcode($1, $2, &$3, $5, &$7);
73
	}
74
|	LTYPE1 cond imsr ',' spreg ','
75
	{
76
		outcode($1, $2, &$3, $5, &nullgen);
77
	}
78
|	LTYPE1 cond imsr ',' reg
79
	{
80
		outcode($1, $2, &$3, NREG, &$5);
81
	}
82
/*
83
 * MVN
84
 */
85
|	LTYPE2 cond imsr ',' reg
86
	{
87
		outcode($1, $2, &$3, NREG, &$5);
88
	}
89
/*
90
 * MOVW
91
 */
92
|	LTYPE3 cond gen ',' gen
93
	{
94
		outcode($1, $2, &$3, NREG, &$5);
95
	}
96
/*
97
 * B/BL
98
 */
99
|	LTYPE4 cond comma rel
100
	{
101
		outcode($1, $2, &nullgen, NREG, &$4);
102
	}
103
|	LTYPE4 cond comma nireg
104
	{
105
		outcode($1, $2, &nullgen, NREG, &$4);
106
	}
107
/*
108
 * BX
109
 */
110
|	LTYPEBX comma ireg
111
	{
112
		outcode($1, Always, &nullgen, NREG, &$3);
113
	}
114
/*
115
 * BEQ
116
 */
117
|	LTYPE5 comma rel
118
	{
119
		outcode($1, Always, &nullgen, NREG, &$3);
120
	}
121
/*
122
 * SWI
123
 */
124
|	LTYPE6 cond comma gen
125
	{
126
		outcode($1, $2, &nullgen, NREG, &$4);
127
	}
128
/*
129
 * CMP
130
 */
131
|	LTYPE7 cond imsr ',' spreg comma
132
	{
133
		outcode($1, $2, &$3, $5, &nullgen);
134
	}
135
/*
136
 * MOVM
137
 */
138
|	LTYPE8 cond ioreg ',' '[' reglist ']'
139
	{
140
		Gen g;
141
 
142
		g = nullgen;
143
		g.type = D_CONST;
144
		g.offset = $6;
145
		outcode($1, $2, &$3, NREG, &g);
146
	}
147
|	LTYPE8 cond '[' reglist ']' ',' ioreg
148
	{
149
		Gen g;
150
 
151
		g = nullgen;
152
		g.type = D_CONST;
153
		g.offset = $4;
154
		outcode($1, $2, &g, NREG, &$7);
155
	}
156
/*
157
 * SWAP
158
 */
159
|	LTYPE9 cond reg ',' ireg ',' reg
160
	{
161
		outcode($1, $2, &$5, $3.reg, &$7);
162
	}
163
|	LTYPE9 cond reg ',' ireg comma
164
	{
165
		outcode($1, $2, &$5, $3.reg, &$3);
166
	}
167
|	LTYPE9 cond comma ireg ',' reg
168
	{
169
		outcode($1, $2, &$4, $6.reg, &$6);
170
	}
171
/*
172
 * RET
173
 */
174
|	LTYPEA cond comma
175
	{
176
		outcode($1, $2, &nullgen, NREG, &nullgen);
177
	}
178
/*
179
 * TEXT/GLOBL
180
 */
181
|	LTYPEB name ',' imm
182
	{
183
		outcode($1, Always, &$2, NREG, &$4);
184
	}
185
|	LTYPEB name ',' con ',' imm
186
	{
187
		outcode($1, Always, &$2, $4, &$6);
188
	}
189
/*
190
 * DATA
191
 */
192
|	LTYPEC name '/' con ',' ximm
193
	{
194
		outcode($1, Always, &$2, $4, &$6);
195
	}
196
/*
197
 * CASE
198
 */
199
|	LTYPED cond reg comma
200
	{
201
		outcode($1, $2, &$3, NREG, &nullgen);
202
	}
203
/*
204
 * word
205
 */
206
|	LTYPEH comma ximm
207
	{
208
		outcode($1, Always, &nullgen, NREG, &$3);
209
	}
210
/*
211
 * floating-point coprocessor
212
 */
213
|	LTYPEI cond freg ',' freg
214
	{
215
		outcode($1, $2, &$3, NREG, &$5);
216
	}
217
|	LTYPEK cond frcon ',' freg
218
	{
219
		outcode($1, $2, &$3, NREG, &$5);
220
	}
221
|	LTYPEK cond frcon ',' LFREG ',' freg
222
	{
223
		outcode($1, $2, &$3, $5, &$7);
224
	}
225
|	LTYPEL cond freg ',' freg comma
226
	{
227
		outcode($1, $2, &$3, $5.reg, &nullgen);
228
	}
229
/*
230
 * MCR MRC
231
 */
232
|	LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
233
	{
234
		Gen g;
235
 
236
		g = nullgen;
237
		g.type = D_CONST;
238
		g.offset =
239
			(0xe << 24) |		/* opcode */
240
			($1 << 20) |		/* MCR/MRC */
241
			($2 << 28) |		/* scond */
242
			(($3 & 15) << 8) |	/* coprocessor number */
243
			(($5 & 7) << 21) |	/* coprocessor operation */
244
			(($7 & 15) << 12) |	/* arm register */
245
			(($9 & 15) << 16) |	/* Crn */
246
			(($11 & 15) << 0) |	/* Crm */
247
			(($12 & 7) << 5) |	/* coprocessor information */
248
			(1<<4);			/* must be set */
249
		outcode(AWORD, Always, &nullgen, NREG, &g);
250
	}
251
/*
252
 * MULL hi,lo,r1,r2
253
 */
254
|	LTYPEM cond reg ',' reg ',' regreg
255
	{
256
		outcode($1, $2, &$3, $5.reg, &$7);
257
	}
258
/*
259
 * MULA hi,lo,r1,r2
260
 */
261
|	LTYPEN cond reg ',' reg ',' reg ',' spreg 
262
	{
263
		$7.type = D_REGREG;
264
		$7.offset = $9;
265
		outcode($1, $2, &$3, $5.reg, &$7);
266
	}
267
/*
268
 * END
269
 */
270
|	LTYPEE comma
271
	{
272
		outcode($1, Always, &nullgen, NREG, &nullgen);
273
	}
274
 
275
cond:
276
	{
277
		$$ = Always;
278
	}
279
|	cond LCOND
280
	{
281
		$$ = ($1 & ~C_SCOND) | $2;
282
	}
283
|	cond LS
284
	{
285
		$$ = $1 | $2;
286
	}
287
 
288
comma:
289
|	',' comma
290
 
291
rel:
292
	con '(' LPC ')'
293
	{
294
		$$ = nullgen;
295
		$$.type = D_BRANCH;
296
		$$.offset = $1 + pc;
297
	}
298
|	LNAME offset
299
	{
300
		$$ = nullgen;
301
		if(pass == 2)
302
			yyerror("undefined label: %s", $1->name);
303
		$$.type = D_BRANCH;
304
		$$.sym = $1;
305
		$$.offset = $2;
306
	}
307
|	LLAB offset
308
	{
309
		$$ = nullgen;
310
		$$.type = D_BRANCH;
311
		$$.sym = $1;
312
		$$.offset = $1->value + $2;
313
	}
314
 
315
ximm:	'$' con
316
	{
317
		$$ = nullgen;
318
		$$.type = D_CONST;
319
		$$.offset = $2;
320
	}
321
|	'$' oreg
322
	{
323
		$$ = $2;
324
		$$.type = D_CONST;
325
	}
326
|	'$' '*' '$' oreg
327
	{
328
		$$ = $4;
329
		$$.type = D_OCONST;
330
	}
331
|	'$' LSCONST
332
	{
333
		$$ = nullgen;
334
		$$.type = D_SCONST;
335
		memcpy($$.sval, $2, sizeof($$.sval));
336
	}
337
|	fcon
338
 
339
fcon:
340
	'$' LFCONST
341
	{
342
		$$ = nullgen;
343
		$$.type = D_FCONST;
344
		$$.dval = $2;
345
	}
346
|	'$' '-' LFCONST
347
	{
348
		$$ = nullgen;
349
		$$.type = D_FCONST;
350
		$$.dval = -$3;
351
	}
352
 
353
reglist:
354
	spreg
355
	{
356
		$$ = 1 << $1;
357
	}
358
|	spreg '-' spreg
359
	{
360
		int i;
361
		$$=0;
362
		for(i=$1; i<=$3; i++)
363
			$$ |= 1<<i;
364
		for(i=$3; i<=$1; i++)
365
			$$ |= 1<<i;
366
	}
367
|	spreg comma reglist
368
	{
369
		$$ = (1<<$1) | $3;
370
	}
371
 
372
gen:
373
	reg
374
|	ximm
375
|	shift
376
|	shift '(' spreg ')'
377
	{
378
		$$ = $1;
379
		$$.reg = $3;
380
	}
381
|	LPSR
382
	{
383
		$$ = nullgen;
384
		$$.type = D_PSR;
385
		$$.reg = $1;
386
	}
387
|	LFCR
388
	{
389
		$$ = nullgen;
390
		$$.type = D_FPCR;
391
		$$.reg = $1;
392
	}
393
|	con
394
	{
395
		$$ = nullgen;
396
		$$.type = D_OREG;
397
		$$.offset = $1;
398
	}
399
|	oreg
400
|	freg
401
 
402
nireg:
403
	ireg
404
|	name
405
	{
406
		$$ = $1;
407
		if($1.name != D_EXTERN && $1.name != D_STATIC) {
408
		}
409
	}
410
 
411
ireg:
412
	'(' spreg ')'
413
	{
414
		$$ = nullgen;
415
		$$.type = D_OREG;
416
		$$.reg = $2;
417
		$$.offset = 0;
418
	}
419
 
420
ioreg:
421
	ireg
422
|	con '(' sreg ')'
423
	{
424
		$$ = nullgen;
425
		$$.type = D_OREG;
426
		$$.reg = $3;
427
		$$.offset = $1;
428
	}
429
 
430
oreg:
431
	name
432
|	name '(' sreg ')'
433
	{
434
		$$ = $1;
435
		$$.type = D_OREG;
436
		$$.reg = $3;
437
	}
438
|	ioreg
439
 
440
imsr:
441
	reg
442
|	imm
443
|	shift
444
 
445
imm:	'$' con
446
	{
447
		$$ = nullgen;
448
		$$.type = D_CONST;
449
		$$.offset = $2;
450
	}
451
 
452
reg:
453
	spreg
454
	{
455
		$$ = nullgen;
456
		$$.type = D_REG;
457
		$$.reg = $1;
458
	}
459
 
460
regreg:
461
	'(' spreg ',' spreg ')'
462
	{
463
		$$ = nullgen;
464
		$$.type = D_REGREG;
465
		$$.reg = $2;
466
		$$.offset = $4;
467
	}
468
 
469
shift:
470
	spreg '<' '<' rcon
471
	{
472
		$$ = nullgen;
473
		$$.type = D_SHIFT;
474
		$$.offset = $1 | $4 | (0 << 5);
475
	}
476
|	spreg '>' '>' rcon
477
	{
478
		$$ = nullgen;
479
		$$.type = D_SHIFT;
480
		$$.offset = $1 | $4 | (1 << 5);
481
	}
482
|	spreg '-' '>' rcon
483
	{
484
		$$ = nullgen;
485
		$$.type = D_SHIFT;
486
		$$.offset = $1 | $4 | (2 << 5);
487
	}
488
|	spreg LAT '>' rcon
489
	{
490
		$$ = nullgen;
491
		$$.type = D_SHIFT;
492
		$$.offset = $1 | $4 | (3 << 5);
493
	}
494
 
495
rcon:
496
	spreg
497
	{
498
		if($$ < 0 || $$ >= 16)
499
			print("register value out of range\n");
500
		$$ = (($1&15) << 8) | (1 << 4);
501
	}
502
|	con
503
	{
504
		if($$ < 0 || $$ >= 32)
505
			print("shift value out of range\n");
506
		$$ = ($1&31) << 7;
507
	}
508
 
509
sreg:
510
	LREG
511
|	LPC
512
	{
513
		$$ = REGPC;
514
	}
515
|	LR '(' expr ')'
516
	{
517
		if($3 < 0 || $3 >= NREG)
518
			print("register value out of range\n");
519
		$$ = $3;
520
	}
521
 
522
spreg:
523
	sreg
524
|	LSP
525
	{
526
		$$ = REGSP;
527
	}
528
 
529
creg:
530
	LCREG
531
|	LC '(' expr ')'
532
	{
533
		if($3 < 0 || $3 >= NREG)
534
			print("register value out of range\n");
535
		$$ = $3;
536
	}
537
 
538
frcon:
539
	freg
540
|	fcon
541
 
542
freg:
543
	LFREG
544
	{
545
		$$ = nullgen;
546
		$$.type = D_FREG;
547
		$$.reg = $1;
548
	}
549
|	LF '(' con ')'
550
	{
551
		$$ = nullgen;
552
		$$.type = D_FREG;
553
		$$.reg = $3;
554
	}
555
 
556
name:
557
	con '(' pointer ')'
558
	{
559
		$$ = nullgen;
560
		$$.type = D_OREG;
561
		$$.name = $3;
562
		$$.sym = S;
563
		$$.offset = $1;
564
	}
565
|	LNAME offset '(' pointer ')'
566
	{
567
		$$ = nullgen;
568
		$$.type = D_OREG;
569
		$$.name = $4;
570
		$$.sym = $1;
571
		$$.offset = $2;
572
	}
573
|	LNAME '<' '>' offset '(' LSB ')'
574
	{
575
		$$ = nullgen;
576
		$$.type = D_OREG;
577
		$$.name = D_STATIC;
578
		$$.sym = $1;
579
		$$.offset = $4;
580
	}
581
 
582
offset:
583
	{
584
		$$ = 0;
585
	}
586
|	'+' con
587
	{
588
		$$ = $2;
589
	}
590
|	'-' con
591
	{
592
		$$ = -$2;
593
	}
594
 
595
pointer:
596
	LSB
597
|	LSP
598
|	LFP
599
 
600
con:
601
	LCONST
602
|	LVAR
603
	{
604
		$$ = $1->value;
605
	}
606
|	'-' con
607
	{
608
		$$ = -$2;
609
	}
610
|	'+' con
611
	{
612
		$$ = $2;
613
	}
614
|	'~' con
615
	{
616
		$$ = ~$2;
617
	}
618
|	'(' expr ')'
619
	{
620
		$$ = $2;
621
	}
622
 
623
oexpr:
624
	{
625
		$$ = 0;
626
	}
627
|	',' expr
628
	{
629
		$$ = $2;
630
	}
631
 
632
expr:
633
	con
634
|	expr '+' expr
635
	{
636
		$$ = $1 + $3;
637
	}
638
|	expr '-' expr
639
	{
640
		$$ = $1 - $3;
641
	}
642
|	expr '*' expr
643
	{
644
		$$ = $1 * $3;
645
	}
646
|	expr '/' expr
647
	{
648
		$$ = $1 / $3;
649
	}
650
|	expr '%' expr
651
	{
652
		$$ = $1 % $3;
653
	}
654
|	expr '<' '<' expr
655
	{
656
		$$ = $1 << $4;
657
	}
658
|	expr '>' '>' expr
659
	{
660
		$$ = $1 >> $4;
661
	}
662
|	expr '&' expr
663
	{
664
		$$ = $1 & $3;
665
	}
666
|	expr '^' expr
667
	{
668
		$$ = $1 ^ $3;
669
	}
670
|	expr '|' expr
671
	{
672
		$$ = $1 | $3;
673
	}