]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/new8a/a.y
[dev.cc] cmd/new5a etc, cmd/internal/asm: edit to produce working Go code
[gostls13.git] / src / cmd / new8a / a.y
1 // Inferno utils/8a/a.y
2 // http://code.google.com/p/inferno-os/source/browse/utils/8a/a.y
3 //
4 //      Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5 //      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6 //      Portions Copyright © 1997-1999 Vita Nuova Limited
7 //      Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8 //      Portions Copyright © 2004,2006 Bruce Ellis
9 //      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10 //      Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11 //      Portions Copyright © 2009 The Go Authors.  All rights reserved.
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a copy
14 // of this software and associated documentation files (the "Software"), to deal
15 // in the Software without restriction, including without limitation the rights
16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 // copies of the Software, and to permit persons to whom the Software is
18 // furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included in
21 // all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 // THE SOFTWARE.
30
31 %{
32 package main
33
34 import (
35         "cmd/internal/asm"
36         "cmd/internal/obj"
37         . "cmd/internal/obj/i386"
38 )
39 %}
40
41 %union {
42         sym *asm.Sym
43         lval int64
44         con2 struct {
45                 v1 int32
46                 v2 int32
47         }
48         dval float64
49         sval string
50         addr obj.Addr
51         addr2 Addr2
52 }
53
54 %left   '|'
55 %left   '^'
56 %left   '&'
57 %left   '<' '>'
58 %left   '+' '-'
59 %left   '*' '/' '%'
60 %token  <lval>  LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
61 %token  <lval>  LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG LTYPEXC
62 %token  <lval>  LTYPEX LTYPEPC LTYPEF LCONST LFP LPC LSB
63 %token  <lval>  LBREG LLREG LSREG LFREG LXREG
64 %token  <dval>  LFCONST
65 %token  <sval>  LSCONST LSP
66 %token  <sym>   LNAME LLAB LVAR
67 %type   <lval>  con expr pointer offset
68 %type   <con2>  con2
69 %type   <addr>  mem imm imm2 reg nam rel rem rim rom omem nmem
70 %type   <addr2> nonnon nonrel nonrem rimnon rimrem remrim
71 %type   <addr2> spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9 spec10 spec11 spec12
72 %%
73 prog:
74 |       prog
75         {
76                 stmtline = asm.Lineno;
77         }
78         line
79
80 line:
81         LNAME ':'
82         {
83                 $1 = asm.LabelLookup($1);
84                 if $1.Type == LLAB && $1.Value != int64(asm.PC) {
85                         yyerror("redeclaration of %s", $1.Labelname)
86                 }
87                 $1.Type = LLAB;
88                 $1.Value = int64(asm.PC)
89         }
90         line
91 |       ';'
92 |       inst ';'
93 |       error ';'
94
95 inst:
96         LNAME '=' expr
97         {
98                 $1.Type = LVAR;
99                 $1.Value = $3;
100         }
101 |       LVAR '=' expr
102         {
103                 if $1.Value != int64($3) {
104                         yyerror("redeclaration of %s", $1.Name);
105                 }
106                 $1.Value = $3;
107         }
108 |       LTYPE0 nonnon   { outcode(int($1), &$2); }
109 |       LTYPE1 nonrem   { outcode(int($1), &$2); }
110 |       LTYPE2 rimnon   { outcode(int($1), &$2); }
111 |       LTYPE3 rimrem   { outcode(int($1), &$2); }
112 |       LTYPE4 remrim   { outcode(int($1), &$2); }
113 |       LTYPER nonrel   { outcode(int($1), &$2); }
114 |       LTYPED spec1    { outcode(int($1), &$2); }
115 |       LTYPET spec2    { outcode(int($1), &$2); }
116 |       LTYPEC spec3    { outcode(int($1), &$2); }
117 |       LTYPEN spec4    { outcode(int($1), &$2); }
118 |       LTYPES spec5    { outcode(int($1), &$2); }
119 |       LTYPEM spec6    { outcode(int($1), &$2); }
120 |       LTYPEI spec7    { outcode(int($1), &$2); }
121 |       LTYPEG spec8    { outcode(int($1), &$2); }
122 |       LTYPEXC spec9   { outcode(int($1), &$2); }
123 |       LTYPEX spec10   { outcode(int($1), &$2); }
124 |       LTYPEPC spec11  { outcode(int($1), &$2); }
125 |       LTYPEF spec12   { outcode(int($1), &$2); }
126
127 nonnon:
128         {
129                 $$.from = nullgen;
130                 $$.to = nullgen;
131         }
132 |       ','
133         {
134                 $$.from = nullgen;
135                 $$.to = nullgen;
136         }
137
138 rimrem:
139         rim ',' rem
140         {
141                 $$.from = $1;
142                 $$.to = $3;
143         }
144
145 remrim:
146         rem ',' rim
147         {
148                 $$.from = $1;
149                 $$.to = $3;
150         }
151
152 rimnon:
153         rim ','
154         {
155                 $$.from = $1;
156                 $$.to = nullgen;
157         }
158 |       rim
159         {
160                 $$.from = $1;
161                 $$.to = nullgen;
162         }
163
164 nonrem:
165         ',' rem
166         {
167                 $$.from = nullgen;
168                 $$.to = $2;
169         }
170 |       rem
171         {
172                 $$.from = nullgen;
173                 $$.to = $1;
174         }
175
176 nonrel:
177         ',' rel
178         {
179                 $$.from = nullgen;
180                 $$.to = $2;
181         }
182 |       rel
183         {
184                 $$.from = nullgen;
185                 $$.to = $1;
186         }
187 |       imm ',' rel
188         {
189                 $$.from = $1;
190                 $$.to = $3;
191         }
192
193 spec1:  /* DATA */
194         nam '/' con ',' imm
195         {
196                 $$.from = $1;
197                 $$.from.Scale = int8($3);
198                 $$.to = $5;
199         }
200
201 spec2:  /* TEXT */
202         mem ',' imm2
203         {
204                 asm.Settext($1.Sym);
205                 $$.from = $1;
206                 $$.to = $3;
207         }
208 |       mem ',' con ',' imm2
209         {
210                 asm.Settext($1.Sym);
211                 $$.from = $1;
212                 $$.from.Scale = int8($3);
213                 $$.to = $5;
214         }
215
216 spec3:  /* JMP/CALL */
217         ',' rom
218         {
219                 $$.from = nullgen;
220                 $$.to = $2;
221         }
222 |       rom
223         {
224                 $$.from = nullgen;
225                 $$.to = $1;
226         }
227 |       '*' nam
228         {
229                 $$.from = nullgen;
230                 $$.to = $2;
231                 $$.to.Index = uint8($2.Type_)
232                 $$.to.Type_ = D_INDIR+D_ADDR;
233         }
234
235 spec4:  /* NOP */
236         nonnon
237 |       nonrem
238
239 spec5:  /* SHL/SHR */
240         rim ',' rem
241         {
242                 $$.from = $1;
243                 $$.to = $3;
244         }
245 |       rim ',' rem ':' LLREG
246         {
247                 $$.from = $1;
248                 $$.to = $3;
249                 if $$.from.Index != D_NONE {
250                         yyerror("dp shift with lhs index");
251                 }
252                 $$.from.Index = uint8($5);
253         }
254
255 spec6:  /* MOVW/MOVL */
256         rim ',' rem
257         {
258                 $$.from = $1;
259                 $$.to = $3;
260         }
261 |       rim ',' rem ':' LSREG
262         {
263                 $$.from = $1;
264                 $$.to = $3;
265                 if $$.to.Index != D_NONE {
266                         yyerror("dp move with lhs index");
267                 }
268                 $$.to.Index = uint8($5);
269         }
270
271 spec7:
272         rim ','
273         {
274                 $$.from = $1;
275                 $$.to = nullgen;
276         }
277 |       rim
278         {
279                 $$.from = $1;
280                 $$.to = nullgen;
281         }
282 |       rim ',' rem
283         {
284                 $$.from = $1;
285                 $$.to = $3;
286         }
287
288 spec8:  /* GLOBL */
289         mem ',' imm
290         {
291                 $$.from = $1;
292                 $$.to = $3;
293         }
294 |       mem ',' con ',' imm
295         {
296                 $$.from = $1;
297                 $$.from.Scale = int8($3);
298                 $$.to = $5;
299         }
300
301 spec9:  /* CMPPS/CMPPD */
302         reg ',' rem ',' con
303         {
304                 $$.from = $1;
305                 $$.to = $3;
306                 $$.to.Offset = $5;
307         }
308
309 spec10: /* PINSRD */
310         imm ',' rem ',' reg
311         {
312                 $$.from = $3;
313                 $$.to = $5;
314                 if $1.Type_ != D_CONST {
315                         yyerror("illegal constant")
316                 }
317                 $$.to.Offset = $1.Offset;
318         }
319
320 spec11: /* PCDATA */
321         rim ',' rim
322         {
323                 if $1.Type_ != D_CONST || $3.Type_ != D_CONST {
324                         yyerror("arguments to PCDATA must be integer constants");
325                 }
326                 $$.from = $1;
327                 $$.to = $3;
328         }
329
330 spec12: /* FUNCDATA */
331         rim ',' rim
332         {
333                 if $1.Type_ != D_CONST {
334                         yyerror("index for FUNCDATA must be integer constant");
335                 }
336                 if $3.Type_ != D_EXTERN && $3.Type_ != D_STATIC {
337                         yyerror("value for FUNCDATA must be symbol reference");
338                 }
339                 $$.from = $1;
340                 $$.to = $3;
341         }
342
343 rem:
344         reg
345 |       mem
346
347 rom:
348         rel
349 |       nmem
350 |       '*' reg
351         {
352                 $$ = $2;
353         }
354 |       '*' omem
355         {
356                 $$ = $2;
357         }
358 |       reg
359 |       omem
360 |       imm
361
362 rim:
363         rem
364 |       imm
365
366 rel:
367         con '(' LPC ')'
368         {
369                 $$ = nullgen;
370                 $$.Type_ = D_BRANCH;
371                 $$.Offset = $1 + int64(asm.PC);
372         }
373 |       LNAME offset
374         {
375                 $1 = asm.LabelLookup($1);
376                 $$ = nullgen;
377                 if asm.Pass == 2 && $1.Type != LLAB {
378                         yyerror("undefined label: %s", $1.Labelname);
379                 }
380                 $$.Type_ = D_BRANCH;
381                 $$.Offset = $1.Value + $2;
382         }
383
384 reg:
385         LBREG
386         {
387                 $$ = nullgen;
388                 $$.Type_ = int16($1);
389         }
390 |       LFREG
391         {
392                 $$ = nullgen;
393                 $$.Type_ = int16($1);
394         }
395 |       LLREG
396         {
397                 $$ = nullgen;
398                 $$.Type_ = int16($1);
399         }
400 |       LXREG
401         {
402                 $$ = nullgen;
403                 $$.Type_ = int16($1);
404         }
405 |       LSP
406         {
407                 $$ = nullgen;
408                 $$.Type_ = D_SP;
409         }
410 |       LSREG
411         {
412                 $$ = nullgen;
413                 $$.Type_ = int16($1);
414         }
415
416 imm:
417         '$' con
418         {
419                 $$ = nullgen;
420                 $$.Type_ = D_CONST;
421                 $$.Offset = $2;
422         }
423 |       '$' nam
424         {
425                 $$ = $2;
426                 $$.Index = uint8($2.Type_);
427                 $$.Type_ = D_ADDR;
428                 /*
429                 if($2.Type_ == D_AUTO || $2.Type_ == D_PARAM)
430                         yyerror("constant cannot be automatic: %s",
431                                 $2.Sym.name);
432                  */
433         }
434 |       '$' LSCONST
435         {
436                 $$ = nullgen;
437                 $$.Type_ = D_SCONST;
438                 $$.U.Sval = $2
439         }
440 |       '$' LFCONST
441         {
442                 $$ = nullgen;
443                 $$.Type_ = D_FCONST;
444                 $$.U.Dval = $2;
445         }
446 |       '$' '(' LFCONST ')'
447         {
448                 $$ = nullgen;
449                 $$.Type_ = D_FCONST;
450                 $$.U.Dval = $3;
451         }
452 |       '$' '(' '-' LFCONST ')'
453         {
454                 $$ = nullgen;
455                 $$.Type_ = D_FCONST;
456                 $$.U.Dval = -$4;
457         }
458 |       '$' '-' LFCONST
459         {
460                 $$ = nullgen;
461                 $$.Type_ = D_FCONST;
462                 $$.U.Dval = -$3;
463         }
464
465 imm2:
466         '$' con2
467         {
468                 $$ = nullgen;
469                 $$.Type_ = D_CONST2;
470                 $$.Offset = int64($2.v1);
471                 $$.Offset2 = int32($2.v2);
472         }
473
474 con2:
475         LCONST
476         {
477                 $$.v1 = int32($1);
478                 $$.v2 = -obj.ArgsSizeUnknown
479         }
480 |       '-' LCONST
481         {
482                 $$.v1 = int32(-$2);
483                 $$.v2 = -obj.ArgsSizeUnknown;
484         }
485 |       LCONST '-' LCONST
486         {
487                 $$.v1 = int32($1);
488                 $$.v2 = int32($3);
489         }
490 |       '-' LCONST '-' LCONST
491         {
492                 $$.v1 = int32(-$2);
493                 $$.v2 = int32($4);
494         }
495
496 mem:
497         omem
498 |       nmem
499
500 omem:
501         con
502         {
503                 $$ = nullgen;
504                 $$.Type_ = D_INDIR+D_NONE;
505                 $$.Offset = $1;
506         }
507 |       con '(' LLREG ')'
508         {
509                 $$ = nullgen;
510                 $$.Type_ = int16(D_INDIR+$3);
511                 $$.Offset = $1;
512         }
513 |       con '(' LSP ')'
514         {
515                 $$ = nullgen;
516                 $$.Type_ = D_INDIR+D_SP;
517                 $$.Offset = $1;
518         }
519 |       con '(' LLREG '*' con ')'
520         {
521                 $$ = nullgen;
522                 $$.Type_ = D_INDIR+D_NONE;
523                 $$.Offset = $1;
524                 $$.Index = uint8($3);
525                 $$.Scale = int8($5);
526                 checkscale($$.Scale);
527         }
528 |       con '(' LLREG ')' '(' LLREG '*' con ')'
529         {
530                 $$ = nullgen;
531                 $$.Type_ = int16(D_INDIR+$3);
532                 $$.Offset = $1;
533                 $$.Index = uint8($6);
534                 $$.Scale = int8($8);
535                 checkscale($$.Scale);
536         }
537 |       con '(' LLREG ')' '(' LSREG '*' con ')'
538         {
539                 $$ = nullgen;
540                 $$.Type_ = int16(D_INDIR+$3);
541                 $$.Offset = $1;
542                 $$.Index = uint8($6);
543                 $$.Scale = int8($8);
544                 checkscale($$.Scale);
545         }
546 |       '(' LLREG ')'
547         {
548                 $$ = nullgen;
549                 $$.Type_ = int16(D_INDIR+$2);
550         }
551 |       '(' LSP ')'
552         {
553                 $$ = nullgen;
554                 $$.Type_ = D_INDIR+D_SP;
555         }
556 |       con '(' LSREG ')'
557         {
558                 $$ = nullgen;
559                 $$.Type_ = int16(D_INDIR+$3);
560                 $$.Offset = $1;
561         }
562 |       '(' LLREG '*' con ')'
563         {
564                 $$ = nullgen;
565                 $$.Type_ = D_INDIR+D_NONE;
566                 $$.Index = uint8($2);
567                 $$.Scale = int8($4);
568                 checkscale($$.Scale);
569         }
570 |       '(' LLREG ')' '(' LLREG '*' con ')'
571         {
572                 $$ = nullgen;
573                 $$.Type_ = int16(D_INDIR+$2);
574                 $$.Index = uint8($5);
575                 $$.Scale = int8($7);
576                 checkscale($$.Scale);
577         }
578
579 nmem:
580         nam
581         {
582                 $$ = $1;
583         }
584 |       nam '(' LLREG '*' con ')'
585         {
586                 $$ = $1;
587                 $$.Index = uint8($3);
588                 $$.Scale = int8($5);
589                 checkscale($$.Scale);
590         }
591
592 nam:
593         LNAME offset '(' pointer ')'
594         {
595                 $$ = nullgen;
596                 $$.Type_ = int16($4);
597                 $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
598                 $$.Offset = $2;
599         }
600 |       LNAME '<' '>' offset '(' LSB ')'
601         {
602                 $$ = nullgen;
603                 $$.Type_ = D_STATIC;
604                 $$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
605                 $$.Offset = $4;
606         }
607
608 offset:
609         {
610                 $$ = 0;
611         }
612 |       '+' con
613         {
614                 $$ = $2;
615         }
616 |       '-' con
617         {
618                 $$ = -$2;
619         }
620
621 pointer:
622         LSB
623 |       LSP
624         {
625                 $$ = D_AUTO;
626         }
627 |       LFP
628
629 con:
630         LCONST
631 |       LVAR
632         {
633                 $$ = $1.Value;
634         }
635 |       '-' con
636         {
637                 $$ = -$2;
638         }
639 |       '+' con
640         {
641                 $$ = $2;
642         }
643 |       '~' con
644         {
645                 $$ = ^$2;
646         }
647 |       '(' expr ')'
648         {
649                 $$ = $2;
650         }
651
652 expr:
653         con
654 |       expr '+' expr
655         {
656                 $$ = $1 + $3;
657         }
658 |       expr '-' expr
659         {
660                 $$ = $1 - $3;
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         }
674 |       expr '<' '<' expr
675         {
676                 $$ = $1 << uint($4);
677         }
678 |       expr '>' '>' expr
679         {
680                 $$ = $1 >> uint($4);
681         }
682 |       expr '&' expr
683         {
684                 $$ = $1 & $3;
685         }
686 |       expr '^' expr
687         {
688                 $$ = $1 ^ $3;
689         }
690 |       expr '|' expr
691         {
692                 $$ = $1 | $3;
693         }