rsc.io/go@v0.0.0-20150416155037-e040fd465409/src/cmd/old6a/a.y (about)

     1  // Inferno utils/6a/a.y
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6a/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/x86"
    38  )
    39  %}
    40  
    41  %union {
    42  	sym *asm.Sym
    43  	lval int64
    44  	dval float64
    45  	sval string
    46  	addr obj.Addr
    47  	addr2 Addr2
    48  }
    49  
    50  %left	'|'
    51  %left	'^'
    52  %left	'&'
    53  %left	'<' '>'
    54  %left	'+' '-'
    55  %left	'*' '/' '%'
    56  %token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
    57  %token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG LTYPEPC
    58  %token	<lval>	LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT LTYPEF
    59  %token	<lval>	LCONST LFP LPC LSB
    60  %token	<lval>	LBREG LLREG LSREG LFREG LMREG LXREG
    61  %token	<dval>	LFCONST
    62  %token	<sval>	LSCONST LSP
    63  %token	<sym>	LNAME LLAB LVAR
    64  %type	<lval>	con expr pointer offset
    65  %type	<addr>	mem imm textsize reg nam rel rem rim rom omem nmem
    66  %type	<addr2>	nonnon nonrel nonrem rimnon rimrem remrim
    67  %type	<addr2>	spec3 spec4 spec5 spec6 spec7 spec8 spec9
    68  %type	<addr2>	spec10 spec12 spec13
    69  %%
    70  prog:
    71  |	prog 
    72  	{
    73  		stmtline = asm.Lineno;
    74  	}
    75  	line
    76  
    77  line:
    78  	LNAME ':'
    79  	{
    80  		$1 = asm.LabelLookup($1);
    81  		if $1.Type == LLAB && $1.Value != int64(asm.PC) {
    82  			yyerror("redeclaration of %s (%s)", $1.Labelname, $1.Name);
    83  		}
    84  		$1.Type = LLAB;
    85  		$1.Value = int64(asm.PC)
    86  	}
    87  	line
    88  |	';'
    89  |	inst ';'
    90  |	error ';'
    91  
    92  inst:
    93  	LNAME '=' expr
    94  	{
    95  		$1.Type = LVAR;
    96  		$1.Value = $3;
    97  	}
    98  |	LVAR '=' expr
    99  	{
   100  		if $1.Value != $3 {
   101  			yyerror("redeclaration of %s", $1.Name);
   102  		}
   103  		$1.Value = $3;
   104  	}
   105  |	LTYPE0 nonnon	{ outcode(int($1), &$2); }
   106  |	LTYPE1 nonrem	{ outcode(int($1), &$2); }
   107  |	LTYPE2 rimnon	{ outcode(int($1), &$2); }
   108  |	LTYPE3 rimrem	{ outcode(int($1), &$2); }
   109  |	LTYPE4 remrim	{ outcode(int($1), &$2); }
   110  |	LTYPER nonrel	{ outcode(int($1), &$2); }
   111  |	spec1
   112  |	spec2
   113  |	LTYPEC spec3	{ outcode(int($1), &$2); }
   114  |	LTYPEN spec4	{ outcode(int($1), &$2); }
   115  |	LTYPES spec5	{ outcode(int($1), &$2); }
   116  |	LTYPEM spec6	{ outcode(int($1), &$2); }
   117  |	LTYPEI spec7	{ outcode(int($1), &$2); }
   118  |	LTYPEXC spec8	{ outcode(int($1), &$2); }
   119  |	LTYPEX spec9	{ outcode(int($1), &$2); }
   120  |	LTYPERT spec10	{ outcode(int($1), &$2); }
   121  |	spec11
   122  |	LTYPEPC spec12	{ outcode(int($1), &$2); }
   123  |	LTYPEF spec13	{ outcode(int($1), &$2); }
   124  
   125  nonnon:
   126  	{
   127  		$$.from = nullgen;
   128  		$$.to = nullgen;
   129  	}
   130  |	','
   131  	{
   132  		$$.from = nullgen;
   133  		$$.to = nullgen;
   134  	}
   135  
   136  rimrem:
   137  	rim ',' rem
   138  	{
   139  		$$.from = $1;
   140  		$$.to = $3;
   141  	}
   142  
   143  remrim:
   144  	rem ',' rim
   145  	{
   146  		$$.from = $1;
   147  		$$.to = $3;
   148  	}
   149  
   150  rimnon:
   151  	rim ','
   152  	{
   153  		$$.from = $1;
   154  		$$.to = nullgen;
   155  	}
   156  |	rim
   157  	{
   158  		$$.from = $1;
   159  		$$.to = nullgen;
   160  	}
   161  
   162  nonrem:
   163  	',' rem
   164  	{
   165  		$$.from = nullgen;
   166  		$$.to = $2;
   167  	}
   168  |	rem
   169  	{
   170  		$$.from = nullgen;
   171  		$$.to = $1;
   172  	}
   173  
   174  nonrel:
   175  	',' rel
   176  	{
   177  		$$.from = nullgen;
   178  		$$.to = $2;
   179  	}
   180  |	rel
   181  	{
   182  		$$.from = nullgen;
   183  		$$.to = $1;
   184  	}
   185  |	imm ',' rel
   186  	{
   187  		$$.from = $1;
   188  		$$.to = $3;
   189  	}
   190  
   191  spec1:	/* DATA */
   192  	LTYPED nam '/' con ',' imm
   193  	{
   194  		var a Addr2
   195  		a.from = $2
   196  		a.to = $6
   197  		outcode(obj.ADATA, &a)
   198  		if asm.Pass > 1 {
   199  			lastpc.From3.Type = obj.TYPE_CONST
   200  			lastpc.From3.Offset = $4
   201  		}
   202  	}
   203  
   204  spec2:	/* TEXT */
   205  	LTYPET mem ',' '$' textsize
   206  	{
   207  		asm.Settext($2.Sym);
   208  		outcode(obj.ATEXT, &Addr2{from: $2, to: $5})
   209  	}
   210  |	LTYPET mem ',' con ',' '$' textsize
   211  	{
   212  		asm.Settext($2.Sym);
   213  		outcode(obj.ATEXT, &Addr2{from: $2, to: $7})
   214  		if asm.Pass > 1 {
   215  			lastpc.From3.Type = obj.TYPE_CONST
   216  			lastpc.From3.Offset = $4
   217  		}
   218  	}
   219  
   220  spec11:	/* GLOBL */
   221  	LTYPEG mem ',' imm
   222  	{
   223  		asm.Settext($2.Sym)
   224  		outcode(obj.AGLOBL, &Addr2{from: $2, to: $4})
   225  	}
   226  |	LTYPEG mem ',' con ',' imm
   227  	{
   228  		asm.Settext($2.Sym)
   229  		outcode(obj.AGLOBL, &Addr2{from: $2, to: $6})
   230  		if asm.Pass > 1 {
   231  			lastpc.From3.Type = obj.TYPE_CONST
   232  			lastpc.From3.Offset = $4
   233  		}
   234  	}
   235  
   236  spec3:	/* JMP/CALL */
   237  	',' rom
   238  	{
   239  		$$.from = nullgen;
   240  		$$.to = $2;
   241  	}
   242  |	rom
   243  	{
   244  		$$.from = nullgen;
   245  		$$.to = $1;
   246  	}
   247  
   248  spec4:	/* NOP */
   249  	nonnon
   250  |	nonrem
   251  
   252  spec5:	/* SHL/SHR */
   253  	rim ',' rem
   254  	{
   255  		$$.from = $1;
   256  		$$.to = $3;
   257  	}
   258  |	rim ',' rem ':' LLREG
   259  	{
   260  		$$.from = $1;
   261  		$$.to = $3;
   262  		if $$.from.Index != obj.TYPE_NONE {
   263  			yyerror("dp shift with lhs index");
   264  		}
   265  		$$.from.Index = int16($5);
   266  	}
   267  
   268  spec6:	/* MOVW/MOVL */
   269  	rim ',' rem
   270  	{
   271  		$$.from = $1;
   272  		$$.to = $3;
   273  	}
   274  |	rim ',' rem ':' LSREG
   275  	{
   276  		$$.from = $1;
   277  		$$.to = $3;
   278  		if $$.to.Index != obj.TYPE_NONE {
   279  			yyerror("dp move with lhs index");
   280  		}
   281  		$$.to.Index = int16($5);
   282  	}
   283  
   284  spec7:
   285  	rim ','
   286  	{
   287  		$$.from = $1;
   288  		$$.to = nullgen;
   289  	}
   290  |	rim
   291  	{
   292  		$$.from = $1;
   293  		$$.to = nullgen;
   294  	}
   295  |	rim ',' rem
   296  	{
   297  		$$.from = $1;
   298  		$$.to = $3;
   299  	}
   300  
   301  spec8:	/* CMPPS/CMPPD */
   302  	rem ',' reg ',' con
   303  	{
   304  		$$.from = $1;
   305  		$$.from3 = $3;
   306  		$$.to.Type = obj.TYPE_MEM; // to give library something to do
   307  		$$.to.Offset = $5;
   308  	}
   309  
   310  spec9:	/* shufl */
   311  	imm ',' rem ',' reg
   312  	{
   313  		$$.from = $1;
   314  		$$.from3 = $3;
   315  		$$.to = $5;
   316  	}
   317  
   318  spec10:	/* RET/RETF */
   319  	{
   320  		$$.from = nullgen;
   321  		$$.to = nullgen;
   322  	}
   323  |	imm
   324  	{
   325  		$$.from = $1;
   326  		$$.to = nullgen;
   327  	}
   328  
   329  spec12:	/* asm.PCDATA */
   330  	rim ',' rim
   331  	{
   332  		if $1.Type != obj.TYPE_CONST || $3.Type != obj.TYPE_CONST {
   333  			yyerror("arguments to asm.PCDATA must be integer constants");
   334  		}
   335  		$$.from = $1;
   336  		$$.to = $3;
   337  	}
   338  
   339  spec13:	/* FUNCDATA */
   340  	rim ',' rim
   341  	{
   342  		if $1.Type != obj.TYPE_CONST {
   343  			yyerror("index for FUNCDATA must be integer constant");
   344  		}
   345  		if $3.Type != obj.TYPE_MEM || ($3.Name != obj.NAME_EXTERN && $3.Name != obj.NAME_STATIC) {
   346  			yyerror("value for FUNCDATA must be symbol reference");
   347  		}
   348  		$$.from = $1;
   349  		$$.to = $3;
   350  	}
   351  
   352  rem:
   353  	reg
   354  |	mem
   355  
   356  rom:
   357  	rel
   358  |	nmem
   359  |	'*' reg
   360  	{
   361  		$$ = $2;
   362  	}
   363  |	'*' omem
   364  	{
   365  		$$ = $2;
   366  	}
   367  |	reg
   368  |	omem
   369  
   370  rim:
   371  	rem
   372  |	imm
   373  
   374  rel:
   375  	con '(' LPC ')'
   376  	{
   377  		$$ = nullgen;
   378  		$$.Type = obj.TYPE_BRANCH;
   379  		$$.Offset = $1 + int64(asm.PC);
   380  	}
   381  |	LNAME offset
   382  	{
   383  		$1 = asm.LabelLookup($1);
   384  		$$ = nullgen;
   385  		if asm.Pass == 2 && $1.Type != LLAB {
   386  			yyerror("undefined label: %s", $1.Labelname);
   387  		}
   388  		$$.Type = obj.TYPE_BRANCH;
   389  		$$.Offset = $1.Value + $2;
   390  	}
   391  
   392  reg:
   393  	LBREG
   394  	{
   395  		$$ = nullgen;
   396  		$$.Type = obj.TYPE_REG
   397  		$$.Reg = int16($1);
   398  	}
   399  |	LFREG
   400  	{
   401  		$$ = nullgen;
   402  		$$.Type = obj.TYPE_REG
   403  		$$.Reg = int16($1);
   404  	}
   405  |	LLREG
   406  	{
   407  		$$ = nullgen;
   408  		$$.Type = obj.TYPE_REG
   409  		$$.Reg = int16($1);
   410  	}
   411  |	LMREG
   412  	{
   413  		$$ = nullgen;
   414  		$$.Type = obj.TYPE_REG
   415  		$$.Reg = int16($1);
   416  	}
   417  |	LSP
   418  	{
   419  		$$ = nullgen;
   420  		$$.Type = obj.TYPE_REG
   421  		$$.Reg = x86.REG_SP;
   422  	}
   423  |	LSREG
   424  	{
   425  		$$ = nullgen;
   426  		$$.Type = obj.TYPE_REG
   427  		$$.Reg = int16($1);
   428  	}
   429  |	LXREG
   430  	{
   431  		$$ = nullgen;
   432  		$$.Type = obj.TYPE_REG
   433  		$$.Reg = int16($1);
   434  	}
   435  
   436  imm:
   437  	'$' con
   438  	{
   439  		$$ = nullgen;
   440  		$$.Type = obj.TYPE_CONST;
   441  		$$.Offset = $2;
   442  	}
   443  |	'$' nam
   444  	{
   445  		$$ = $2;
   446  		$$.Type = obj.TYPE_ADDR;
   447  		/*
   448  		if($2.Type == x86.D_AUTO || $2.Type == x86.D_PARAM)
   449  			yyerror("constant cannot be automatic: %s",
   450  				$2.sym.Name);
   451  		 */
   452  	}
   453  |	'$' LSCONST
   454  	{
   455  		$$ = nullgen;
   456  		$$.Type = obj.TYPE_SCONST;
   457  		$$.Val = ($2+"\x00\x00\x00\x00\x00\x00\x00\x00")[:8]
   458  	}
   459  |	'$' LFCONST
   460  	{
   461  		$$ = nullgen;
   462  		$$.Type = obj.TYPE_FCONST;
   463  		$$.Val = $2;
   464  	}
   465  |	'$' '(' LFCONST ')'
   466  	{
   467  		$$ = nullgen;
   468  		$$.Type = obj.TYPE_FCONST;
   469  		$$.Val = $3;
   470  	}
   471  |	'$' '(' '-' LFCONST ')'
   472  	{
   473  		$$ = nullgen;
   474  		$$.Type = obj.TYPE_FCONST;
   475  		$$.Val = -$4;
   476  	}
   477  |	'$' '-' LFCONST
   478  	{
   479  		$$ = nullgen;
   480  		$$.Type = obj.TYPE_FCONST;
   481  		$$.Val = -$3;
   482  	}
   483  
   484  mem:
   485  	omem
   486  |	nmem
   487  
   488  omem:
   489  	con
   490  	{
   491  		$$ = nullgen;
   492  		$$.Type = obj.TYPE_MEM
   493  		$$.Offset = $1;
   494  	}
   495  |	con '(' LLREG ')'
   496  	{
   497  		$$ = nullgen;
   498  		$$.Type = obj.TYPE_MEM
   499  		$$.Reg = int16($3)
   500  		$$.Offset = $1;
   501  	}
   502  |	con '(' LSP ')'
   503  	{
   504  		$$ = nullgen;
   505  		$$.Type = obj.TYPE_MEM
   506  		$$.Reg = x86.REG_SP
   507  		$$.Offset = $1;
   508  	}
   509  |	con '(' LSREG ')'
   510  	{
   511  		$$ = nullgen;
   512  		$$.Type = obj.TYPE_MEM
   513  		$$.Reg = int16($3)
   514  		$$.Offset = $1;
   515  	}
   516  |	con '(' LLREG '*' con ')'
   517  	{
   518  		$$ = nullgen;
   519  		$$.Type = obj.TYPE_MEM
   520  		$$.Offset = $1;
   521  		$$.Index = int16($3);
   522  		$$.Scale = int16($5);
   523  		checkscale($$.Scale);
   524  	}
   525  |	con '(' LLREG ')' '(' LLREG '*' con ')'
   526  	{
   527  		$$ = nullgen;
   528  		$$.Type = obj.TYPE_MEM
   529  		$$.Reg = int16($3)
   530  		$$.Offset = $1;
   531  		$$.Index = int16($6);
   532  		$$.Scale = int16($8);
   533  		checkscale($$.Scale);
   534  	}
   535  |	con '(' LLREG ')' '(' LSREG '*' con ')'
   536  	{
   537  		$$ = nullgen;
   538  		$$.Type = obj.TYPE_MEM
   539  		$$.Reg = int16($3)
   540  		$$.Offset = $1;
   541  		$$.Index = int16($6);
   542  		$$.Scale = int16($8);
   543  		checkscale($$.Scale);
   544  	}
   545  |	'(' LLREG ')'
   546  	{
   547  		$$ = nullgen;
   548  		$$.Type = obj.TYPE_MEM
   549  		$$.Reg = int16($2)
   550  	}
   551  |	'(' LSP ')'
   552  	{
   553  		$$ = nullgen;
   554  		$$.Type = obj.TYPE_MEM
   555  		$$.Reg = x86.REG_SP
   556  	}
   557  |	'(' LLREG '*' con ')'
   558  	{
   559  		$$ = nullgen;
   560  		$$.Type = obj.TYPE_MEM
   561  		$$.Index = int16($2);
   562  		$$.Scale = int16($4);
   563  		checkscale($$.Scale);
   564  	}
   565  |	'(' LLREG ')' '(' LLREG '*' con ')'
   566  	{
   567  		$$ = nullgen;
   568  		$$.Type = obj.TYPE_MEM
   569  		$$.Reg = int16($2)
   570  		$$.Index = int16($5);
   571  		$$.Scale = int16($7);
   572  		checkscale($$.Scale);
   573  	}
   574  
   575  nmem:
   576  	nam
   577  	{
   578  		$$ = $1;
   579  	}
   580  |	nam '(' LLREG '*' con ')'
   581  	{
   582  		$$ = $1;
   583  		$$.Index = int16($3);
   584  		$$.Scale = int16($5);
   585  		checkscale($$.Scale);
   586  	}
   587  
   588  nam:
   589  	LNAME offset '(' pointer ')'
   590  	{
   591  		$$ = nullgen;
   592  		$$.Type = obj.TYPE_MEM
   593  		$$.Name = int8($4)
   594  		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
   595  		$$.Offset = $2;
   596  	}
   597  |	LNAME '<' '>' offset '(' LSB ')'
   598  	{
   599  		$$ = nullgen;
   600  		$$.Type = obj.TYPE_MEM
   601  		$$.Name = obj.NAME_STATIC
   602  		$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
   603  		$$.Offset = $4;
   604  	}
   605  
   606  offset:
   607  	{
   608  		$$ = 0;
   609  	}
   610  |	'+' con
   611  	{
   612  		$$ = $2;
   613  	}
   614  |	'-' con
   615  	{
   616  		$$ = -$2;
   617  	}
   618  
   619  pointer:
   620  	LSB
   621  |	LSP
   622  	{
   623  		$$ = obj.NAME_AUTO;
   624  	}
   625  |	LFP
   626  
   627  con:
   628  	LCONST
   629  |	LVAR
   630  	{
   631  		$$ = $1.Value;
   632  	}
   633  |	'-' con
   634  	{
   635  		$$ = -$2;
   636  	}
   637  |	'+' con
   638  	{
   639  		$$ = $2;
   640  	}
   641  |	'~' con
   642  	{
   643  		$$ = ^$2;
   644  	}
   645  |	'(' expr ')'
   646  	{
   647  		$$ = $2;
   648  	}
   649  
   650  textsize:
   651  	LCONST
   652  	{
   653  		$$ = nullgen;
   654  		$$.Type = obj.TYPE_TEXTSIZE;
   655  		$$.Offset = $1;
   656  		$$.Val = int32(obj.ArgsSizeUnknown);
   657  	}
   658  |	'-' LCONST
   659  	{
   660  		$$ = nullgen;
   661  		$$.Type = obj.TYPE_TEXTSIZE;
   662  		$$.Offset = -$2;
   663  		$$.Val = int32(obj.ArgsSizeUnknown);
   664  	}
   665  |	LCONST '-' LCONST
   666  	{
   667  		$$ = nullgen;
   668  		$$.Type = obj.TYPE_TEXTSIZE;
   669  		$$.Offset = $1;
   670  		$$.Val = int32($3);
   671  	}
   672  |	'-' LCONST '-' LCONST
   673  	{
   674  		$$ = nullgen;
   675  		$$.Type = obj.TYPE_TEXTSIZE;
   676  		$$.Offset = -$2;
   677  		$$.Val = int32($4);
   678  	}
   679  
   680  expr:
   681  	con
   682  |	expr '+' expr
   683  	{
   684  		$$ = $1 + $3;
   685  	}
   686  |	expr '-' expr
   687  	{
   688  		$$ = $1 - $3;
   689  	}
   690  |	expr '*' expr
   691  	{
   692  		$$ = $1 * $3;
   693  	}
   694  |	expr '/' expr
   695  	{
   696  		$$ = $1 / $3;
   697  	}
   698  |	expr '%' expr
   699  	{
   700  		$$ = $1 % $3;
   701  	}
   702  |	expr '<' '<' expr
   703  	{
   704  		$$ = $1 << uint($4);
   705  	}
   706  |	expr '>' '>' expr
   707  	{
   708  		$$ = $1 >> uint($4);
   709  	}
   710  |	expr '&' expr
   711  	{
   712  		$$ = $1 & $3;
   713  	}
   714  |	expr '^' expr
   715  	{
   716  		$$ = $1 ^ $3;
   717  	}
   718  |	expr '|' expr
   719  	{
   720  		$$ = $1 | $3;
   721  	}