Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/cmd/qa/a.y – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | 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>	LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
19
%token	<lval>	LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
20
%token	<lval>	LNOP LEND LRETT LWORD LTEXT LDATA LRETRN
21
%token	<lval>	LCONST LSP LSB LFP LPC LCREG LFLUSH
22
%token	<lval>	LREG LFREG LR LCR LF LFPSCR
23
%token	<lval>	LLR LCTR LSPR LSPREG LSEG LMSR LDCR
24
%token	<lval>	LSCHED LXLD LXST LXOP LXMV
25
%token	<lval>	LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA LFMOVX
26
%token	<dval>	LFCONST
27
%token	<sval>	LSCONST
28
%token	<sym>	LNAME LLAB LVAR
29
%type	<lval>	con expr pointer offset sreg
30
%type	<gen>	addr rreg regaddr name creg freg xlreg lr ctr
31
%type	<gen>	imm ximm fimm rel psr lcr cbit fpscr fpscrf seg msr mask
32
%%
33
prog:
34
|	prog line
35
 
36
line:
37
	LLAB ':'
38
	{
39
		if($1->value != pc)
40
			yyerror("redeclaration of %s", $1->name);
41
		$1->value = pc;
42
	}
43
	line
44
|	LNAME ':'
45
	{
46
		$1->type = LLAB;
47
		$1->value = pc;
48
	}
49
	line
50
|	LNAME '=' expr ';'
51
	{
52
		$1->type = LVAR;
53
		$1->value = $3;
54
	}
55
|	LVAR '=' expr ';'
56
	{
57
		if($1->value != $3)
58
			yyerror("redeclaration of %s", $1->name);
59
		$1->value = $3;
60
	}
61
|	LSCHED ';'
62
	{
63
		nosched = $1;
64
	}
65
|	';'
66
|	inst ';'
67
|	error ';'
68
 
69
inst:
70
/*
71
 * load ints and bytes
72
 */
73
	LMOVW rreg ',' rreg
74
	{
75
		outcode($1, &$2, NREG, &$4);
76
	}
77
|	LMOVW addr ',' rreg
78
	{
79
		outcode($1, &$2, NREG, &$4);
80
	}
81
|	LMOVW regaddr ',' rreg
82
	{
83
		outcode($1, &$2, NREG, &$4);
84
	}
85
|	LMOVB rreg ',' rreg
86
	{
87
		outcode($1, &$2, NREG, &$4);
88
	}
89
|	LMOVB addr ',' rreg
90
	{
91
		outcode($1, &$2, NREG, &$4);
92
	}
93
|	LMOVB regaddr ',' rreg
94
	{
95
		outcode($1, &$2, NREG, &$4);
96
	}
97
/*
98
 * load and store floats
99
 */
100
|	LFMOV addr ',' freg
101
	{
102
		outcode($1, &$2, NREG, &$4);
103
	}
104
|	LFMOV regaddr ',' freg
105
	{
106
		outcode($1, &$2, NREG, &$4);
107
	}
108
|	LFMOV fimm ',' freg
109
	{
110
		outcode($1, &$2, NREG, &$4);
111
	}
112
|	LFMOV freg ',' freg
113
	{
114
		outcode($1, &$2, NREG, &$4);
115
	}
116
|	LFMOV freg ',' addr
117
	{
118
		outcode($1, &$2, NREG, &$4);
119
	}
120
|	LFMOV freg ',' regaddr
121
	{
122
		outcode($1, &$2, NREG, &$4);
123
	}
124
/*
125
 * load and store floats, indexed only
126
 */
127
|	LFMOVX regaddr ',' freg
128
	{
129
		outcode($1, &$2, NREG, &$4);
130
	}
131
|	LFMOVX freg ',' regaddr
132
	{
133
		outcode($1, &$2, NREG, &$4);
134
	}
135
/*
136
 * store ints and bytes
137
 */
138
|	LMOVW rreg ',' addr
139
	{
140
		outcode($1, &$2, NREG, &$4);
141
	}
142
|	LMOVW rreg ',' regaddr
143
	{
144
		outcode($1, &$2, NREG, &$4);
145
	}
146
|	LMOVB rreg ',' addr
147
	{
148
		outcode($1, &$2, NREG, &$4);
149
	}
150
|	LMOVB rreg ',' regaddr
151
	{
152
		outcode($1, &$2, NREG, &$4);
153
	}
154
/*
155
 * store floats
156
 */
157
|	LMOVW freg ',' addr
158
	{
159
		outcode($1, &$2, NREG, &$4);
160
	}
161
|	LMOVW freg ',' regaddr
162
	{
163
		outcode($1, &$2, NREG, &$4);
164
	}
165
/*
166
 * floating point status
167
 */
168
|	LMOVW fpscr ',' freg
169
	{
170
		outcode($1, &$2, NREG, &$4);
171
	}
172
|	LMOVW freg ','  fpscr
173
	{
174
		outcode($1, &$2, NREG, &$4);
175
	}
176
|	LMOVW freg ',' imm ',' fpscr
177
	{
178
		outgcode($1, &$2, NREG, &$4, &$6);
179
	}
180
|	LMOVW fpscr ',' creg
181
	{
182
		outcode($1, &$2, NREG, &$4);
183
	}
184
|	LMOVW imm ',' fpscrf
185
	{
186
		outcode($1, &$2, NREG, &$4);
187
	}
188
|	LMTFSB imm ',' con
189
	{
190
		outcode($1, &$2, $4, &nullgen);
191
	}
192
/*
193
 * field moves (mtcrf)
194
 */
195
|	LMOVW rreg ',' imm ',' lcr
196
	{
197
		outgcode($1, &$2, NREG, &$4, &$6);
198
	}
199
|	LMOVW rreg ',' creg
200
	{
201
		outcode($1, &$2, NREG, &$4);
202
	}
203
|	LMOVW rreg ',' lcr
204
	{
205
		outcode($1, &$2, NREG, &$4);
206
	}
207
/*
208
 * integer operations
209
 * logical instructions
210
 * shift instructions
211
 * unary instructions
212
 */
213
|	LADDW rreg ',' sreg ',' rreg
214
	{
215
		outcode($1, &$2, $4, &$6);
216
	}
217
|	LADDW imm ',' sreg ',' rreg
218
	{
219
		outcode($1, &$2, $4, &$6);
220
	}
221
|	LADDW rreg ',' imm ',' rreg
222
	{
223
		outgcode($1, &$2, NREG, &$4, &$6);
224
	}
225
|	LADDW rreg ',' rreg
226
	{
227
		outcode($1, &$2, NREG, &$4);
228
	}
229
|	LADDW imm ',' rreg
230
	{
231
		outcode($1, &$2, NREG, &$4);
232
	}
233
|	LLOGW rreg ',' sreg ',' rreg
234
	{
235
		outcode($1, &$2, $4, &$6);
236
	}
237
|	LLOGW rreg ',' rreg
238
	{
239
		outcode($1, &$2, NREG, &$4);
240
	}
241
|	LSHW rreg ',' sreg ',' rreg
242
	{
243
		outcode($1, &$2, $4, &$6);
244
	}
245
|	LSHW rreg ',' rreg
246
	{
247
		outcode($1, &$2, NREG, &$4);
248
	}
249
|	LSHW imm ',' sreg ',' rreg
250
	{
251
		outcode($1, &$2, $4, &$6);
252
	}
253
|	LSHW imm ',' rreg
254
	{
255
		outcode($1, &$2, NREG, &$4);
256
	}
257
|	LABS rreg ',' rreg
258
	{
259
		outcode($1, &$2, NREG, &$4);
260
	}
261
|	LABS rreg
262
	{
263
		outcode($1, &$2, NREG, &$2);
264
	}
265
/*
266
 * multiply-accumulate
267
 */
268
|	LMA rreg ',' sreg ',' rreg
269
	{
270
		outcode($1, &$2, $4, &$6);
271
	}
272
/*
273
 * move immediate: macro for cau+or, addi, addis, and other combinations
274
 */
275
|	LMOVW imm ',' rreg
276
	{
277
		outcode($1, &$2, NREG, &$4);
278
	}
279
|	LMOVW ximm ',' rreg
280
	{
281
		outcode($1, &$2, NREG, &$4);
282
	}
283
/*
284
 * condition register operations
285
 */
286
|	LCROP cbit ',' cbit
287
	{
288
		outcode($1, &$2, $4.reg, &$4);
289
	}
290
|	LCROP cbit ',' con ',' cbit
291
	{
292
		outcode($1, &$2, $4, &$6);
293
	}
294
/*
295
 * condition register moves
296
 * move from machine state register
297
 */
298
|	LMOVW creg ',' creg
299
	{
300
		outcode($1, &$2, NREG, &$4);
301
	}
302
|	LMOVW psr ',' creg
303
	{
304
		outcode($1, &$2, NREG, &$4);
305
	}
306
|	LMOVW lcr ',' rreg
307
	{
308
		outcode($1, &$2, NREG, &$4);
309
	}
310
|	LMOVW psr ',' rreg
311
	{
312
		outcode($1, &$2, NREG, &$4);
313
	}
314
|	LMOVW seg ',' rreg
315
	{
316
		int r;
317
		r = $2.offset;
318
		$2.offset = 0;
319
		outcode($1, &$2, r, &$4);
320
	}
321
|	LMOVW rreg ',' seg
322
	{
323
		int r;
324
		r = $4.offset;
325
		$4.offset = 0;
326
		outcode($1, &$2, r, &$4);
327
	}
328
|	LMOVW xlreg ',' rreg
329
	{
330
		outcode($1, &$2, NREG, &$4);
331
	}
332
|	LMOVW rreg ',' xlreg
333
	{
334
		outcode($1, &$2, NREG, &$4);
335
	}
336
|	LMOVW creg ',' psr
337
	{
338
		outcode($1, &$2, NREG, &$4);
339
	}
340
|	LMOVW rreg ',' psr
341
	{
342
		outcode($1, &$2, NREG, &$4);
343
	}
344
/*
345
 * branch, branch conditional
346
 * branch conditional register
347
 * branch conditional to count register
348
 */
349
|	LBRA rel
350
	{
351
		outcode($1, &nullgen, NREG, &$2);
352
	}
353
|	LBRA addr
354
	{
355
		outcode($1, &nullgen, NREG, &$2);
356
	}
357
|	LBRA '(' xlreg ')'
358
	{
359
		outcode($1, &nullgen, NREG, &$3);
360
	}
361
|	LBRA ',' rel
362
	{
363
		outcode($1, &nullgen, NREG, &$3);
364
	}
365
|	LBRA ',' addr
366
	{
367
		outcode($1, &nullgen, NREG, &$3);
368
	}
369
|	LBRA ',' '(' xlreg ')'
370
	{
371
		outcode($1, &nullgen, NREG, &$4);
372
	}
373
|	LBRA creg ',' rel
374
	{
375
		outcode($1, &$2, NREG, &$4);
376
	}
377
|	LBRA creg ',' addr
378
	{
379
		outcode($1, &$2, NREG, &$4);
380
	}
381
|	LBRA creg ',' '(' xlreg ')'
382
	{
383
		outcode($1, &$2, NREG, &$5);
384
	}
385
|	LBRA con ',' rel
386
	{
387
		outcode($1, &nullgen, $2, &$4);
388
	}
389
|	LBRA con ',' addr
390
	{
391
		outcode($1, &nullgen, $2, &$4);
392
	}
393
|	LBRA con ',' '(' xlreg ')'
394
	{
395
		outcode($1, &nullgen, $2, &$5);
396
	}
397
|	LBRA con ',' con ',' rel
398
	{
399
		Gen g;
400
		g = nullgen;
401
		g.type = D_CONST;
402
		g.offset = $2;
403
		outcode($1, &g, $4, &$6);
404
	}
405
|	LBRA con ',' con ',' addr
406
	{
407
		Gen g;
408
		g = nullgen;
409
		g.type = D_CONST;
410
		g.offset = $2;
411
		outcode($1, &g, $4, &$6);
412
	}
413
|	LBRA con ',' con ',' '(' xlreg ')'
414
	{
415
		Gen g;
416
		g = nullgen;
417
		g.type = D_CONST;
418
		g.offset = $2;
419
		outcode($1, &g, $4, &$7);
420
	}
421
/*
422
 * conditional trap
423
 */
424
|	LTRAP rreg ',' sreg
425
	{
426
		outcode($1, &$2, $4, &nullgen);
427
	}
428
|	LTRAP imm ',' sreg
429
	{
430
		outcode($1, &$2, $4, &nullgen);
431
	}
432
|	LTRAP rreg comma
433
	{
434
		outcode($1, &$2, NREG, &nullgen);
435
	}
436
|	LTRAP comma
437
	{
438
		outcode($1, &nullgen, NREG, &nullgen);
439
	}
440
/*
441
 * floating point operate
442
 */
443
|	LFCONV freg ',' freg
444
	{
445
		outcode($1, &$2, NREG, &$4);
446
	}
447
|	LFADD freg ',' freg
448
	{
449
		outcode($1, &$2, NREG, &$4);
450
	}
451
|	LFADD freg ',' freg ',' freg
452
	{
453
		outcode($1, &$2, $4.reg, &$6);
454
	}
455
|	LFMA freg ',' freg ',' freg ',' freg
456
	{
457
		outgcode($1, &$2, $4.reg, &$6, &$8);
458
	}
459
|	LFCMP freg ',' freg
460
	{
461
		outcode($1, &$2, NREG, &$4);
462
	}
463
|	LFCMP freg ',' freg ',' creg
464
	{
465
		outcode($1, &$2, $6.reg, &$4);
466
	}
467
/*
468
 * CMP
469
 */
470
|	LCMP rreg ',' rreg
471
	{
472
		outcode($1, &$2, NREG, &$4);
473
	}
474
|	LCMP rreg ',' imm
475
	{
476
		outcode($1, &$2, NREG, &$4);
477
	}
478
|	LCMP rreg ',' rreg ',' creg
479
	{
480
		outcode($1, &$2, $6.reg, &$4);
481
	}
482
|	LCMP rreg ',' imm ',' creg
483
	{
484
		outcode($1, &$2, $6.reg, &$4);
485
	}
486
/*
487
 * rotate and mask
488
 */
489
|	LRLWM  imm ',' rreg ',' imm ',' rreg
490
	{
491
		outgcode($1, &$2, $4.reg, &$6, &$8);
492
	}
493
|	LRLWM  imm ',' rreg ',' mask ',' rreg
494
	{
495
		outgcode($1, &$2, $4.reg, &$6, &$8);
496
	}
497
|	LRLWM  rreg ',' rreg ',' imm ',' rreg
498
	{
499
		outgcode($1, &$2, $4.reg, &$6, &$8);
500
	}
501
|	LRLWM  rreg ',' rreg ',' mask ',' rreg
502
	{
503
		outgcode($1, &$2, $4.reg, &$6, &$8);
504
	}
505
/*
506
 * load/store multiple
507
 */
508
|	LMOVMW addr ',' rreg
509
	{
510
		outcode($1, &$2, NREG, &$4);
511
	}
512
|	LMOVMW rreg ',' addr
513
	{
514
		outcode($1, &$2, NREG, &$4);
515
	}
516
/*
517
 * various indexed load/store
518
 * indexed unary (eg, cache clear)
519
 */
520
|	LXLD regaddr ',' rreg
521
	{
522
		outcode($1, &$2, NREG, &$4);
523
	}
524
|	LXLD regaddr ',' imm ',' rreg
525
	{
526
		outgcode($1, &$2, NREG, &$4, &$6);
527
	}
528
|	LXST rreg ',' regaddr
529
	{
530
		outcode($1, &$2, NREG, &$4);
531
	}
532
|	LXST rreg ',' imm ',' regaddr
533
	{
534
		outgcode($1, &$2, NREG, &$4, &$6);
535
	}
536
|	LXMV regaddr ',' rreg
537
	{
538
		outcode($1, &$2, NREG, &$4);
539
	}
540
|	LXMV rreg ',' regaddr
541
	{
542
		outcode($1, &$2, NREG, &$4);
543
	}
544
|	LXOP regaddr
545
	{
546
		outcode($1, &$2, NREG, &nullgen);
547
	}
548
/*
549
 * NOP
550
 */
551
|	LNOP comma
552
	{
553
		outcode($1, &nullgen, NREG, &nullgen);
554
	}
555
|	LNOP rreg comma
556
	{
557
		outcode($1, &$2, NREG, &nullgen);
558
	}
559
|	LNOP freg comma
560
	{
561
		outcode($1, &$2, NREG, &nullgen);
562
	}
563
|	LNOP ',' rreg
564
	{
565
		outcode($1, &nullgen, NREG, &$3);
566
	}
567
|	LNOP ',' freg
568
	{
569
		outcode($1, &nullgen, NREG, &$3);
570
	}
571
/*
572
 * word
573
 */
574
|	LWORD imm comma
575
	{
576
		outcode($1, &$2, NREG, &nullgen);
577
	}
578
|	LWORD ximm comma
579
	{
580
		outcode($1, &$2, NREG, &nullgen);
581
	}
582
/*
583
 * END
584
 */
585
|	LEND comma
586
	{
587
		outcode($1, &nullgen, NREG, &nullgen);
588
	}
589
/*
590
 * TEXT/GLOBL
591
 */
592
|	LTEXT name ',' imm
593
	{
594
		outcode($1, &$2, NREG, &$4);
595
	}
596
|	LTEXT name ',' con ',' imm
597
	{
598
		outcode($1, &$2, $4, &$6);
599
	}
600
|	LTEXT name ',' imm ':' imm
601
	{
602
		outgcode($1, &$2, NREG, &$6, &$4);
603
	}
604
|	LTEXT name ',' con ',' imm ':' imm
605
	{
606
		outgcode($1, &$2, $4, &$8, &$6);
607
	}
608
/*
609
 * DATA
610
 */
611
|	LDATA name '/' con ',' imm
612
	{
613
		outcode($1, &$2, $4, &$6);
614
	}
615
|	LDATA name '/' con ',' ximm
616
	{
617
		outcode($1, &$2, $4, &$6);
618
	}
619
|	LDATA name '/' con ',' fimm
620
	{
621
		outcode($1, &$2, $4, &$6);
622
	}
623
/*
624
 * RETURN
625
 */
626
|	LRETRN	comma
627
	{
628
		outcode($1, &nullgen, NREG, &nullgen);
629
	}
630
 
631
rel:
632
	con '(' LPC ')'
633
	{
634
		$$ = nullgen;
635
		$$.type = D_BRANCH;
636
		$$.offset = $1 + pc;
637
	}
638
|	LNAME offset
639
	{
640
		$$ = nullgen;
641
		if(pass == 2)
642
			yyerror("undefined label: %s", $1->name);
643
		$$.type = D_BRANCH;
644
		$$.sym = $1;
645
		$$.offset = $2;
646
	}
647
|	LLAB offset
648
	{
649
		$$ = nullgen;
650
		$$.type = D_BRANCH;
651
		$$.sym = $1;
652
		$$.offset = $1->value + $2;
653
	}
654
 
655
rreg:
656
	sreg
657
	{
658
		$$ = nullgen;
659
		$$.type = D_REG;
660
		$$.reg = $1;
661
	}
662
 
663
xlreg:
664
	lr
665
|	ctr
666
 
667
lr:
668
	LLR
669
	{
670
		$$ = nullgen;
671
		$$.type = D_SPR;
672
		$$.offset = $1;
673
	}
674
 
675
lcr:
676
	LCR
677
	{
678
		$$ = nullgen;
679
		$$.type = D_CREG;
680
		$$.reg = NREG;	/* whole register */
681
	}
682
 
683
ctr:
684
	LCTR
685
	{
686
		$$ = nullgen;
687
		$$.type = D_SPR;
688
		$$.offset = $1;
689
	}
690
 
691
msr:
692
	LMSR
693
	{
694
		$$ = nullgen;
695
		$$.type = D_MSR;
696
	}
697
 
698
psr:
699
	LSPREG
700
	{
701
		$$ = nullgen;
702
		$$.type = D_SPR;
703
		$$.offset = $1;
704
	}
705
|	LSPR '(' con ')'
706
	{
707
		$$ = nullgen;
708
		$$.type = $1;
709
		$$.offset = $3;
710
	}
711
|	LDCR '(' con ')'
712
	{
713
		$$ = nullgen;
714
		$$.type = $1;
715
		$$.offset = $3;
716
	}
717
|	LDCR '(' sreg ')'
718
	{
719
		$$ = nullgen;
720
		$$.type = $1;
721
		$$.reg = $3;
722
		$$.offset = 0;
723
	}
724
|	msr
725
 
726
seg:
727
	LSEG '(' con ')'
728
	{
729
		if($3 < 0 || $3 > 15)
730
			yyerror("segment register number out of range");
731
		$$ = nullgen;
732
		$$.type = D_SREG;
733
		$$.reg = $3;
734
		$$.offset = NREG;
735
	}
736
|	LSEG '(' sreg ')'
737
	{
738
		$$ = nullgen;
739
		$$.type = D_SREG;
740
		$$.reg = NREG;
741
		$$.offset = $3;
742
	}
743
 
744
fpscr:
745
	LFPSCR
746
	{
747
		$$ = nullgen;
748
		$$.type = D_FPSCR;
749
		$$.reg = NREG;
750
	}
751
 
752
fpscrf:
753
	LFPSCR '(' con ')'
754
	{
755
		$$ = nullgen;
756
		$$.type = D_FPSCR;
757
		$$.reg = $3;
758
	}
759
 
760
freg:
761
	LFREG
762
	{
763
		$$ = nullgen;
764
		$$.type = D_FREG;
765
		$$.reg = $1;
766
	}
767
|	LF '(' con ')'
768
	{
769
		$$ = nullgen;
770
		$$.type = D_FREG;
771
		$$.reg = $3;
772
	}
773
 
774
creg:
775
	LCREG
776
	{
777
		$$ = nullgen;
778
		$$.type = D_CREG;
779
		$$.reg = $1;
780
	}
781
|	LCR '(' con ')'
782
	{
783
		$$ = nullgen;
784
		$$.type = D_CREG;
785
		$$.reg = $3;
786
	}
787
 
788
 
789
cbit:	con
790
	{
791
		$$ = nullgen;
792
		$$.type = D_REG;
793
		$$.reg = $1;
794
	}
795
 
796
mask:
797
	con ',' con
798
	{
799
		int mb, me;
800
		ulong v;
801
 
802
		$$ = nullgen;
803
		$$.type = D_CONST;
804
		mb = $1;
805
		me = $3;
806
		if(mb < 0 || mb > 31 || me < 0 || me > 31){
807
			yyerror("illegal mask start/end value(s)");
808
			mb = me = 0;
809
		}
810
		if(mb <= me)
811
			v = ((ulong)~0L>>mb) & (~0L<<(31-me));
812
		else
813
			v = ~(((ulong)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
814
		$$.offset = v;
815
	}
816
 
817
ximm:
818
	'$' addr
819
	{
820
		$$ = $2;
821
		$$.type = D_CONST;
822
	}
823
|	'$' LSCONST
824
	{
825
		$$ = nullgen;
826
		$$.type = D_SCONST;
827
		memcpy($$.sval, $2, sizeof($$.sval));
828
	}
829
 
830
fimm:
831
	'$' LFCONST
832
	{
833
		$$ = nullgen;
834
		$$.type = D_FCONST;
835
		$$.dval = $2;
836
	}
837
|	'$' '-' LFCONST
838
	{
839
		$$ = nullgen;
840
		$$.type = D_FCONST;
841
		$$.dval = -$3;
842
	}
843
 
844
imm:	'$' con
845
	{
846
		$$ = nullgen;
847
		$$.type = D_CONST;
848
		$$.offset = $2;
849
	}
850
 
851
sreg:
852
	LREG
853
|	LR '(' con ')'
854
	{
855
		if($$ < 0 || $$ >= NREG)
856
			print("register value out of range\n");
857
		$$ = $3;
858
	}
859
 
860
regaddr:
861
	'(' sreg ')'
862
	{
863
		$$ = nullgen;
864
		$$.type = D_OREG;
865
		$$.reg = $2;
866
		$$.offset = 0;
867
	}
868
|	'(' sreg '+' sreg ')'
869
	{
870
		$$ = nullgen;
871
		$$.type = D_OREG;
872
		$$.reg = $2;
873
		$$.xreg = $4;
874
		$$.offset = 0;
875
	}
876
 
877
addr:
878
	name
879
|	con '(' sreg ')'
880
	{
881
		$$ = nullgen;
882
		$$.type = D_OREG;
883
		$$.reg = $3;
884
		$$.offset = $1;
885
	}
886
 
887
name:
888
	con '(' pointer ')'
889
	{
890
		$$ = nullgen;
891
		$$.type = D_OREG;
892
		$$.name = $3;
893
		$$.sym = S;
894
		$$.offset = $1;
895
	}
896
|	LNAME offset '(' pointer ')'
897
	{
898
		$$ = nullgen;
899
		$$.type = D_OREG;
900
		$$.name = $4;
901
		$$.sym = $1;
902
		$$.offset = $2;
903
	}
904
|	LNAME '<' '>' offset '(' LSB ')'
905
	{
906
		$$ = nullgen;
907
		$$.type = D_OREG;
908
		$$.name = D_STATIC;
909
		$$.sym = $1;
910
		$$.offset = $4;
911
	}
912
 
913
comma:
914
|	','
915
 
916
offset:
917
	{
918
		$$ = 0;
919
	}
920
|	'+' con
921
	{
922
		$$ = $2;
923
	}
924
|	'-' con
925
	{
926
		$$ = -$2;
927
	}
928
 
929
pointer:
930
	LSB
931
|	LSP
932
|	LFP
933
 
934
con:
935
	LCONST
936
|	LVAR
937
	{
938
		$$ = $1->value;
939
	}
940
|	'-' con
941
	{
942
		$$ = -$2;
943
	}
944
|	'+' con
945
	{
946
		$$ = $2;
947
	}
948
|	'~' con
949
	{
950
		$$ = ~$2;
951
	}
952
|	'(' expr ')'
953
	{
954
		$$ = $2;
955
	}
956
 
957
expr:
958
	con
959
|	expr '+' expr
960
	{
961
		$$ = $1 + $3;
962
	}
963
|	expr '-' expr
964
	{
965
		$$ = $1 - $3;
966
	}
967
|	expr '*' expr
968
	{
969
		$$ = $1 * $3;
970
	}
971
|	expr '/' expr
972
	{
973
		$$ = $1 / $3;
974
	}
975
|	expr '%' expr
976
	{
977
		$$ = $1 % $3;
978
	}
979
|	expr '<' '<' expr
980
	{
981
		$$ = $1 << $4;
982
	}
983
|	expr '>' '>' expr
984
	{
985
		$$ = $1 >> $4;
986
	}
987
|	expr '&' expr
988
	{
989
		$$ = $1 & $3;
990
	}
991
|	expr '^' expr
992
	{
993
		$$ = $1 ^ $3;
994
	}
995
|	expr '|' expr
996
	{
997
		$$ = $1 | $3;
998
	}