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
	vlong	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>	LCONST LSP LSB LFP LPC LHI LLO LMREG 
23
%token	<lval>	LTYPEX LREG LFREG LFCREG LR LM LF
24
%token	<lval>	LFCR LSCHED
25
%token	<dval>	LFCONST
26
%token	<sval>	LSCONST
27
%token	<sym>	LNAME LLAB LVAR
28
%type	<lval>	con expr pointer offset sreg
29
%type	<gen>	gen vgen lgen vlgen rel reg freg mreg fcreg
30
%type	<gen>	imm ximm ireg name oreg imr nireg fgen
31
%%
32
prog:
33
|	prog line
34
 
35
line:
36
	LLAB ':'
37
	{
38
		if($1->value != pc)
39
			yyerror("redeclaration of %s", $1->name);
40
		$1->value = pc;
41
	}
42
	line
43
|	LNAME ':'
44
	{
45
		$1->type = LLAB;
46
		$1->value = pc;
47
	}
48
	line
49
|	LNAME '=' expr ';'
50
	{
51
		$1->type = LVAR;
52
		$1->value = $3;
53
	}
54
|	LVAR '=' expr ';'
55
	{
56
		if($1->value != $3)
57
			yyerror("redeclaration of %s", $1->name);
58
		$1->value = $3;
59
	}
60
|	LSCHED ';'
61
	{
62
		nosched = $1;
63
	}
64
|	';'
65
|	inst ';'
66
|	error ';'
67
 
68
inst:
69
/*
70
 * Immed-type
71
 */
72
	LTYPE1 imr ',' sreg ',' reg
73
	{
74
		outcode($1, &$2, $4, &$6);
75
	}
76
|	LTYPE1 imr ',' reg
77
	{
78
		outcode($1, &$2, NREG, &$4);
79
	}
80
/*
81
 * NOR
82
 */
83
|	LTYPE2 imr ',' sreg ',' imr
84
	{
85
		outcode($1, &$2, $4, &$6);
86
	}
87
|	LTYPE2 imr ',' imr
88
	{
89
		outcode($1, &$2, NREG, &$4);
90
	}
91
/*
92
 * LOAD/STORE, but not MOVW
93
 */
94
|	LTYPE3 lgen ',' gen
95
	{
96
		if(!isreg(&$2) && !isreg(&$4))
97
			print("one side must be register\n");
98
		outcode($1, &$2, NREG, &$4);
99
	}
100
/*
101
 * SPECIAL
102
 */
103
|	LTYPE4 comma
104
	{
105
		outcode($1, &nullgen, NREG, &nullgen);
106
	}
107
/*
108
 * MOVW
109
 */
110
|	LTYPE5 vlgen ',' vgen
111
	{
112
		if(!isreg(&$2) && !isreg(&$4))
113
			print("one side must be register\n");
114
		outcode($1, &$2, NREG, &$4);
115
	}
116
/*
117
 * MUL/DIV
118
 */
119
|	LTYPE6 reg ',' sreg comma
120
	{
121
		outcode($1, &$2, $4, &nullgen);
122
	}
123
|	LTYPE6 reg ',' sreg ',' reg
124
	{
125
		outcode($1, &$2, $4, &$6);
126
	}
127
/*
128
 * JMP/JAL
129
 */
130
|	LTYPE7 comma rel
131
	{
132
		outcode($1, &nullgen, NREG, &$3);
133
	}
134
|	LTYPE7 comma nireg
135
	{
136
		outcode($1, &nullgen, NREG, &$3);
137
	}
138
|	LTYPE8 comma rel
139
	{
140
		outcode($1, &nullgen, NREG, &$3);
141
	}
142
|	LTYPE8 comma nireg
143
	{
144
		outcode($1, &nullgen, NREG, &$3);
145
	}
146
|	LTYPE8 sreg ',' nireg
147
	{
148
		outcode($1, &nullgen, $2, &$4);
149
	}
150
/*
151
 * BEQ/BNE
152
 */
153
|	LTYPE9 gen ',' rel
154
	{
155
		if(!isreg(&$2))
156
			print("left side must be register\n");
157
		outcode($1, &$2, NREG, &$4);
158
	}
159
|	LTYPE9 gen ',' sreg ',' rel
160
	{
161
		if(!isreg(&$2))
162
			print("left side must be register\n");
163
		outcode($1, &$2, $4, &$6);
164
	}
165
/*
166
 * B-other
167
 */
168
|	LTYPEA gen ',' rel
169
	{
170
		if(!isreg(&$2))
171
			print("left side must be register\n");
172
		outcode($1, &$2, NREG, &$4);
173
	}
174
/*
175
 * TEXT/GLOBL
176
 */
177
|	LTYPEB name ',' imm
178
	{
179
		outcode($1, &$2, NREG, &$4);
180
	}
181
|	LTYPEB name ',' con ',' imm
182
	{
183
		outcode($1, &$2, $4, &$6);
184
	}
185
/*
186
 * DATA
187
 */
188
|	LTYPEC name '/' con ',' ximm
189
	{
190
		outcode($1, &$2, $4, &$6);
191
	}
192
/*
193
 * floating-type
194
 */
195
|	LTYPED freg ',' freg
196
	{
197
		outcode($1, &$2, NREG, &$4);
198
	}
199
|	LTYPEE freg ',' freg
200
	{
201
		outcode($1, &$2, NREG, &$4);
202
	}
203
|	LTYPEE freg ',' LFREG ',' freg
204
	{
205
		outcode($1, &$2, $4, &$6);
206
	}
207
|	LTYPEF freg ',' LFREG comma
208
	{
209
		outcode($1, &$2, $4, &nullgen);
210
	}
211
/*
212
 * coprocessor branch
213
 */
214
|	LTYPEG comma rel
215
	{
216
		outcode($1, &nullgen, NREG, &$3);
217
	}
218
/*
219
 * word
220
 */
221
|	LTYPEH comma ximm
222
	{
223
		outcode($1, &nullgen, NREG, &$3);
224
	}
225
/*
226
 * NOP
227
 */
228
|	LTYPEI comma
229
	{
230
		outcode($1, &nullgen, NREG, &nullgen);
231
	}
232
|	LTYPEI ',' vgen
233
	{
234
		outcode($1, &nullgen, NREG, &$3);
235
	}
236
|	LTYPEI vgen comma
237
	{
238
		outcode($1, &$2, NREG, &nullgen);
239
	}
240
/*
241
 * BREAK -- overloaded with CACHE opcode
242
 */
243
|	LTYPEJ comma
244
	{
245
		outcode($1, &nullgen, NREG, &nullgen);
246
	}
247
|	LTYPEJ vgen ',' vgen
248
	{
249
		outcode($1, &$2, NREG, &$4);
250
	}
251
 
252
comma:
253
|	','
254
 
255
rel:
256
	con '(' LPC ')'
257
	{
258
		$$ = nullgen;
259
		$$.type = D_BRANCH;
260
		$$.offset = $1 + pc;
261
	}
262
|	LNAME offset
263
	{
264
		$$ = nullgen;
265
		if(pass == 2)
266
			yyerror("undefined label: %s", $1->name);
267
		$$.type = D_BRANCH;
268
		$$.sym = $1;
269
		$$.offset = $2;
270
	}
271
|	LLAB offset
272
	{
273
		$$ = nullgen;
274
		$$.type = D_BRANCH;
275
		$$.sym = $1;
276
		$$.offset = $1->value + $2;
277
	}
278
 
279
vlgen:
280
	lgen
281
|	fgen
282
|	mreg
283
|	fcreg
284
|	LHI
285
	{
286
		$$ = nullgen;
287
		$$.type = D_HI;
288
	}
289
|	LLO
290
	{
291
		$$ = nullgen;
292
		$$.type = D_LO;
293
	}
294
 
295
vgen:
296
	gen
297
|	fgen
298
|	mreg
299
|	fcreg
300
|	LHI
301
	{
302
		$$ = nullgen;
303
		$$.type = D_HI;
304
	}
305
|	LLO
306
	{
307
		$$ = nullgen;
308
		$$.type = D_LO;
309
	}
310
 
311
lgen:
312
	gen
313
|	ximm
314
 
315
fgen:
316
	freg
317
 
318
mreg:
319
	LMREG
320
	{
321
		$$ = nullgen;
322
		$$.type = D_MREG;
323
		$$.reg = $1;
324
	}
325
|	LM '(' con ')'
326
	{
327
		$$ = nullgen;
328
		$$.type = D_MREG;
329
		$$.reg = $3;
330
	}
331
 
332
fcreg:
333
	LFCREG
334
	{
335
		$$ = nullgen;
336
		$$.type = D_FCREG;
337
		$$.reg = $1;
338
	}
339
|	LFCR '(' con ')'
340
	{
341
		$$ = nullgen;
342
		$$.type = D_FCREG;
343
		$$.reg = $3;
344
	}
345
 
346
freg:
347
	LFREG
348
	{
349
		$$ = nullgen;
350
		$$.type = D_FREG;
351
		$$.reg = $1;
352
	}
353
|	LF '(' con ')'
354
	{
355
		$$ = nullgen;
356
		$$.type = D_FREG;
357
		$$.reg = $3;
358
	}
359
 
360
ximm:	'$' con
361
	{
362
		$$ = nullgen;
363
		$$.type = D_CONST;
364
		$$.offset = $2;
365
	}
366
|	'$' oreg
367
	{
368
		$$ = $2;
369
		$$.type = D_CONST;
370
	}
371
|	'$' '*' '$' oreg
372
	{
373
		$$ = $4;
374
		$$.type = D_OCONST;
375
	}
376
|	'$' LSCONST
377
	{
378
		$$ = nullgen;
379
		$$.type = D_SCONST;
380
		memcpy($$.sval, $2, sizeof($$.sval));
381
	}
382
|	'$' LFCONST
383
	{
384
		$$ = nullgen;
385
		$$.type = D_FCONST;
386
		$$.dval = $2;
387
	}
388
|	'$' '-' LFCONST
389
	{
390
		$$ = nullgen;
391
		$$.type = D_FCONST;
392
		$$.dval = -$3;
393
	}
394
 
395
nireg:
396
	ireg
397
|	con ireg
398
	{
399
		if($1 != 0)
400
			yyerror("offset must be zero");
401
		$$ = $2;
402
	}
403
|	name
404
	{
405
		$$ = $1;
406
		if($1.name != D_EXTERN && $1.name != D_STATIC) {
407
		}
408
	}
409
 
410
ireg:
411
	'(' sreg ')'
412
	{
413
		$$ = nullgen;
414
		$$.type = D_OREG;
415
		$$.reg = $2;
416
		$$.offset = 0;
417
	}
418
 
419
gen:
420
	reg
421
|	con
422
	{
423
		$$ = nullgen;
424
		$$.type = D_OREG;
425
		$$.offset = $1;
426
	}
427
|	oreg
428
 
429
oreg:
430
	name
431
|	name '(' sreg ')'
432
	{
433
		$$ = $1;
434
		$$.type = D_OREG;
435
		$$.reg = $3;
436
	}
437
|	'(' sreg ')'
438
	{
439
		$$ = nullgen;
440
		$$.type = D_OREG;
441
		$$.reg = $2;
442
		$$.offset = 0;
443
	}
444
|	con '(' sreg ')'
445
	{
446
		$$ = nullgen;
447
		$$.type = D_OREG;
448
		$$.reg = $3;
449
		$$.offset = $1;
450
	}
451
 
452
imr:
453
	reg
454
|	imm
455
 
456
imm:	'$' con
457
	{
458
		$$ = nullgen;
459
		$$.type = D_CONST;
460
		$$.offset = $2;
461
	}
462
 
463
reg:
464
	sreg
465
	{
466
		$$ = nullgen;
467
		$$.type = D_REG;
468
		$$.reg = $1;
469
	}
470
 
471
sreg:
472
	LREG
473
|	LR '(' con ')'
474
	{
475
		if($$ < 0 || $$ >= NREG)
476
			print("register value out of range\n");
477
		$$ = $3;
478
	}
479
 
480
name:
481
	con '(' pointer ')'
482
	{
483
		$$ = nullgen;
484
		$$.type = D_OREG;
485
		$$.name = $3;
486
		$$.sym = S;
487
		$$.offset = $1;
488
	}
489
|	LNAME offset '(' pointer ')'
490
	{
491
		$$ = nullgen;
492
		$$.type = D_OREG;
493
		$$.name = $4;
494
		$$.sym = $1;
495
		$$.offset = $2;
496
	}
497
|	LNAME '<' '>' offset '(' LSB ')'
498
	{
499
		$$ = nullgen;
500
		$$.type = D_OREG;
501
		$$.name = D_STATIC;
502
		$$.sym = $1;
503
		$$.offset = $4;
504
	}
505
 
506
offset:
507
	{
508
		$$ = 0;
509
	}
510
|	'+' con
511
	{
512
		$$ = $2;
513
	}
514
|	'-' con
515
	{
516
		$$ = -$2;
517
	}
518
 
519
pointer:
520
	LSB
521
|	LSP
522
|	LFP
523
 
524
con:
525
	LCONST
526
|	LVAR
527
	{
528
		$$ = $1->value;
529
	}
530
|	'-' con
531
	{
532
		$$ = -$2;
533
	}
534
|	'+' con
535
	{
536
		$$ = $2;
537
	}
538
|	'~' con
539
	{
540
		$$ = ~$2;
541
	}
542
|	'(' expr ')'
543
	{
544
		$$ = $2;
545
	}
546
 
547
expr:
548
	con
549
|	expr '+' expr
550
	{
551
		$$ = $1 + $3;
552
	}
553
|	expr '-' expr
554
	{
555
		$$ = $1 - $3;
556
	}
557
|	expr '*' expr
558
	{
559
		$$ = $1 * $3;
560
	}
561
|	expr '/' expr
562
	{
563
		$$ = $1 / $3;
564
	}
565
|	expr '%' expr
566
	{
567
		$$ = $1 % $3;
568
	}
569
|	expr '<' '<' expr
570
	{
571
		$$ = $1 << $4;
572
	}
573
|	expr '>' '>' expr
574
	{
575
		$$ = $1 >> $4;
576
	}
577
|	expr '&' expr
578
	{
579
		$$ = $1 & $3;
580
	}
581
|	expr '^' expr
582
	{
583
		$$ = $1 ^ $3;
584
	}
585
|	expr '|' expr
586
	{
587
		$$ = $1 | $3;
588
	}