github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/6a/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  #include <u.h>
    33  #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
    34  #include <libc.h>
    35  #include "a.h"
    36  %}
    37  %union	{
    38  	Sym	*sym;
    39  	vlong	lval;
    40  	double	dval;
    41  	char	sval[8];
    42  	Gen	gen;
    43  	Gen2	gen2;
    44  }
    45  %left	'|'
    46  %left	'^'
    47  %left	'&'
    48  %left	'<' '>'
    49  %left	'+' '-'
    50  %left	'*' '/' '%'
    51  %token	<lval>	LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
    52  %token	<lval>	LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPEG
    53  %token	<lval>	LTYPES LTYPEM LTYPEI LTYPEXC LTYPEX LTYPERT
    54  %token	<lval>	LCONST LFP LPC LSB
    55  %token	<lval>	LBREG LLREG LSREG LFREG LMREG LXREG
    56  %token	<dval>	LFCONST
    57  %token	<sval>	LSCONST LSP
    58  %token	<sym>	LNAME LLAB LVAR
    59  %type	<lval>	con con2 expr pointer offset
    60  %type	<gen>	mem imm imm2 reg nam rel rem rim rom omem nmem
    61  %type	<gen2>	nonnon nonrel nonrem rimnon rimrem remrim spec10 spec11
    62  %type	<gen2>	spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8 spec9
    63  %%
    64  prog:
    65  |	prog 
    66  	{
    67  		stmtline = lineno;
    68  	}
    69  	line
    70  
    71  line:
    72  	LLAB ':'
    73  	{
    74  		if($1->value != pc)
    75  			yyerror("redeclaration of %s", $1->name);
    76  		$1->value = pc;
    77  	}
    78  	line
    79  |	LNAME ':'
    80  	{
    81  		$1->type = LLAB;
    82  		$1->value = pc;
    83  	}
    84  	line
    85  |	';'
    86  |	inst ';'
    87  |	error ';'
    88  
    89  inst:
    90  	LNAME '=' expr
    91  	{
    92  		$1->type = LVAR;
    93  		$1->value = $3;
    94  	}
    95  |	LVAR '=' expr
    96  	{
    97  		if($1->value != $3)
    98  			yyerror("redeclaration of %s", $1->name);
    99  		$1->value = $3;
   100  	}
   101  |	LTYPE0 nonnon	{ outcode($1, &$2); }
   102  |	LTYPE1 nonrem	{ outcode($1, &$2); }
   103  |	LTYPE2 rimnon	{ outcode($1, &$2); }
   104  |	LTYPE3 rimrem	{ outcode($1, &$2); }
   105  |	LTYPE4 remrim	{ outcode($1, &$2); }
   106  |	LTYPER nonrel	{ outcode($1, &$2); }
   107  |	LTYPED spec1	{ outcode($1, &$2); }
   108  |	LTYPET spec2	{ outcode($1, &$2); }
   109  |	LTYPEC spec3	{ outcode($1, &$2); }
   110  |	LTYPEN spec4	{ outcode($1, &$2); }
   111  |	LTYPES spec5	{ outcode($1, &$2); }
   112  |	LTYPEM spec6	{ outcode($1, &$2); }
   113  |	LTYPEI spec7	{ outcode($1, &$2); }
   114  |	LTYPEXC spec8	{ outcode($1, &$2); }
   115  |	LTYPEX spec9	{ outcode($1, &$2); }
   116  |	LTYPERT spec10	{ outcode($1, &$2); }
   117  |	LTYPEG spec11	{ outcode($1, &$2); }
   118  
   119  nonnon:
   120  	{
   121  		$$.from = nullgen;
   122  		$$.to = nullgen;
   123  	}
   124  |	','
   125  	{
   126  		$$.from = nullgen;
   127  		$$.to = nullgen;
   128  	}
   129  
   130  rimrem:
   131  	rim ',' rem
   132  	{
   133  		$$.from = $1;
   134  		$$.to = $3;
   135  	}
   136  
   137  remrim:
   138  	rem ',' rim
   139  	{
   140  		$$.from = $1;
   141  		$$.to = $3;
   142  	}
   143  
   144  rimnon:
   145  	rim ','
   146  	{
   147  		$$.from = $1;
   148  		$$.to = nullgen;
   149  	}
   150  |	rim
   151  	{
   152  		$$.from = $1;
   153  		$$.to = nullgen;
   154  	}
   155  
   156  nonrem:
   157  	',' rem
   158  	{
   159  		$$.from = nullgen;
   160  		$$.to = $2;
   161  	}
   162  |	rem
   163  	{
   164  		$$.from = nullgen;
   165  		$$.to = $1;
   166  	}
   167  
   168  nonrel:
   169  	',' rel
   170  	{
   171  		$$.from = nullgen;
   172  		$$.to = $2;
   173  	}
   174  |	rel
   175  	{
   176  		$$.from = nullgen;
   177  		$$.to = $1;
   178  	}
   179  |	imm ',' rel
   180  	{
   181  		$$.from = $1;
   182  		$$.to = $3;
   183  	}
   184  
   185  spec1:	/* DATA */
   186  	nam '/' con ',' imm
   187  	{
   188  		$$.from = $1;
   189  		$$.from.scale = $3;
   190  		$$.to = $5;
   191  	}
   192  
   193  spec2:	/* TEXT */
   194  	mem ',' imm2
   195  	{
   196  		$$.from = $1;
   197  		$$.to = $3;
   198  	}
   199  |	mem ',' con ',' imm2
   200  	{
   201  		$$.from = $1;
   202  		$$.from.scale = $3;
   203  		$$.to = $5;
   204  	}
   205  
   206  spec3:	/* JMP/CALL */
   207  	',' rom
   208  	{
   209  		$$.from = nullgen;
   210  		$$.to = $2;
   211  	}
   212  |	rom
   213  	{
   214  		$$.from = nullgen;
   215  		$$.to = $1;
   216  	}
   217  
   218  spec4:	/* NOP */
   219  	nonnon
   220  |	nonrem
   221  
   222  spec5:	/* SHL/SHR */
   223  	rim ',' rem
   224  	{
   225  		$$.from = $1;
   226  		$$.to = $3;
   227  	}
   228  |	rim ',' rem ':' LLREG
   229  	{
   230  		$$.from = $1;
   231  		$$.to = $3;
   232  		if($$.from.index != D_NONE)
   233  			yyerror("dp shift with lhs index");
   234  		$$.from.index = $5;
   235  	}
   236  
   237  spec6:	/* MOVW/MOVL */
   238  	rim ',' rem
   239  	{
   240  		$$.from = $1;
   241  		$$.to = $3;
   242  	}
   243  |	rim ',' rem ':' LSREG
   244  	{
   245  		$$.from = $1;
   246  		$$.to = $3;
   247  		if($$.to.index != D_NONE)
   248  			yyerror("dp move with lhs index");
   249  		$$.to.index = $5;
   250  	}
   251  
   252  spec7:
   253  	rim ','
   254  	{
   255  		$$.from = $1;
   256  		$$.to = nullgen;
   257  	}
   258  |	rim
   259  	{
   260  		$$.from = $1;
   261  		$$.to = nullgen;
   262  	}
   263  |	rim ',' rem
   264  	{
   265  		$$.from = $1;
   266  		$$.to = $3;
   267  	}
   268  
   269  spec8:	/* CMPPS/CMPPD */
   270  	reg ',' rem ',' con
   271  	{
   272  		$$.from = $1;
   273  		$$.to = $3;
   274  		$$.to.offset = $5;
   275  	}
   276  
   277  spec9:	/* shufl */
   278  	imm ',' rem ',' reg
   279  	{
   280  		$$.from = $3;
   281  		$$.to = $5;
   282  		if($1.type != D_CONST)
   283  			yyerror("illegal constant");
   284  		$$.to.offset = $1.offset;
   285  	}
   286  
   287  spec10:	/* RET/RETF */
   288  	{
   289  		$$.from = nullgen;
   290  		$$.to = nullgen;
   291  	}
   292  |	imm
   293  	{
   294  		$$.from = $1;
   295  		$$.to = nullgen;
   296  	}
   297  
   298  spec11:	/* GLOBL */
   299  	mem ',' imm
   300  	{
   301  		$$.from = $1;
   302  		$$.to = $3;
   303  	}
   304  |	mem ',' con ',' imm
   305  	{
   306  		$$.from = $1;
   307  		$$.from.scale = $3;
   308  		$$.to = $5;
   309  	}
   310  
   311  rem:
   312  	reg
   313  |	mem
   314  
   315  rom:
   316  	rel
   317  |	nmem
   318  |	'*' reg
   319  	{
   320  		$$ = $2;
   321  	}
   322  |	'*' omem
   323  	{
   324  		$$ = $2;
   325  	}
   326  |	reg
   327  |	omem
   328  
   329  rim:
   330  	rem
   331  |	imm
   332  
   333  rel:
   334  	con '(' LPC ')'
   335  	{
   336  		$$ = nullgen;
   337  		$$.type = D_BRANCH;
   338  		$$.offset = $1 + pc;
   339  	}
   340  |	LNAME offset
   341  	{
   342  		$$ = nullgen;
   343  		if(pass == 2)
   344  			yyerror("undefined label: %s", $1->name);
   345  		$$.type = D_BRANCH;
   346  		$$.sym = $1;
   347  		$$.offset = $2;
   348  	}
   349  |	LLAB offset
   350  	{
   351  		$$ = nullgen;
   352  		$$.type = D_BRANCH;
   353  		$$.sym = $1;
   354  		$$.offset = $1->value + $2;
   355  	}
   356  
   357  reg:
   358  	LBREG
   359  	{
   360  		$$ = nullgen;
   361  		$$.type = $1;
   362  	}
   363  |	LFREG
   364  	{
   365  		$$ = nullgen;
   366  		$$.type = $1;
   367  	}
   368  |	LLREG
   369  	{
   370  		$$ = nullgen;
   371  		$$.type = $1;
   372  	}
   373  |	LMREG
   374  	{
   375  		$$ = nullgen;
   376  		$$.type = $1;
   377  	}
   378  |	LSP
   379  	{
   380  		$$ = nullgen;
   381  		$$.type = D_SP;
   382  	}
   383  |	LSREG
   384  	{
   385  		$$ = nullgen;
   386  		$$.type = $1;
   387  	}
   388  |	LXREG
   389  	{
   390  		$$ = nullgen;
   391  		$$.type = $1;
   392  	}
   393  imm2:
   394  	'$' con2
   395  	{
   396  		$$ = nullgen;
   397  		$$.type = D_CONST;
   398  		$$.offset = $2;
   399  	}
   400  
   401  imm:
   402  	'$' con
   403  	{
   404  		$$ = nullgen;
   405  		$$.type = D_CONST;
   406  		$$.offset = $2;
   407  	}
   408  |	'$' nam
   409  	{
   410  		$$ = $2;
   411  		$$.index = $2.type;
   412  		$$.type = D_ADDR;
   413  		/*
   414  		if($2.type == D_AUTO || $2.type == D_PARAM)
   415  			yyerror("constant cannot be automatic: %s",
   416  				$2.sym->name);
   417  		 */
   418  	}
   419  |	'$' LSCONST
   420  	{
   421  		$$ = nullgen;
   422  		$$.type = D_SCONST;
   423  		memcpy($$.sval, $2, sizeof($$.sval));
   424  	}
   425  |	'$' LFCONST
   426  	{
   427  		$$ = nullgen;
   428  		$$.type = D_FCONST;
   429  		$$.dval = $2;
   430  	}
   431  |	'$' '(' LFCONST ')'
   432  	{
   433  		$$ = nullgen;
   434  		$$.type = D_FCONST;
   435  		$$.dval = $3;
   436  	}
   437  |	'$' '(' '-' LFCONST ')'
   438  	{
   439  		$$ = nullgen;
   440  		$$.type = D_FCONST;
   441  		$$.dval = -$4;
   442  	}
   443  |	'$' '-' LFCONST
   444  	{
   445  		$$ = nullgen;
   446  		$$.type = D_FCONST;
   447  		$$.dval = -$3;
   448  	}
   449  
   450  mem:
   451  	omem
   452  |	nmem
   453  
   454  omem:
   455  	con
   456  	{
   457  		$$ = nullgen;
   458  		$$.type = D_INDIR+D_NONE;
   459  		$$.offset = $1;
   460  	}
   461  |	con '(' LLREG ')'
   462  	{
   463  		$$ = nullgen;
   464  		$$.type = D_INDIR+$3;
   465  		$$.offset = $1;
   466  	}
   467  |	con '(' LSP ')'
   468  	{
   469  		$$ = nullgen;
   470  		$$.type = D_INDIR+D_SP;
   471  		$$.offset = $1;
   472  	}
   473  |	con '(' LSREG ')'
   474  	{
   475  		$$ = nullgen;
   476  		$$.type = D_INDIR+$3;
   477  		$$.offset = $1;
   478  	}
   479  |	con '(' LLREG '*' con ')'
   480  	{
   481  		$$ = nullgen;
   482  		$$.type = D_INDIR+D_NONE;
   483  		$$.offset = $1;
   484  		$$.index = $3;
   485  		$$.scale = $5;
   486  		checkscale($$.scale);
   487  	}
   488  |	con '(' LLREG ')' '(' LLREG '*' con ')'
   489  	{
   490  		$$ = nullgen;
   491  		$$.type = D_INDIR+$3;
   492  		$$.offset = $1;
   493  		$$.index = $6;
   494  		$$.scale = $8;
   495  		checkscale($$.scale);
   496  	}
   497  |	'(' LLREG ')'
   498  	{
   499  		$$ = nullgen;
   500  		$$.type = D_INDIR+$2;
   501  	}
   502  |	'(' LSP ')'
   503  	{
   504  		$$ = nullgen;
   505  		$$.type = D_INDIR+D_SP;
   506  	}
   507  |	'(' LLREG '*' con ')'
   508  	{
   509  		$$ = nullgen;
   510  		$$.type = D_INDIR+D_NONE;
   511  		$$.index = $2;
   512  		$$.scale = $4;
   513  		checkscale($$.scale);
   514  	}
   515  |	'(' LLREG ')' '(' LLREG '*' con ')'
   516  	{
   517  		$$ = nullgen;
   518  		$$.type = D_INDIR+$2;
   519  		$$.index = $5;
   520  		$$.scale = $7;
   521  		checkscale($$.scale);
   522  	}
   523  
   524  nmem:
   525  	nam
   526  	{
   527  		$$ = $1;
   528  	}
   529  |	nam '(' LLREG '*' con ')'
   530  	{
   531  		$$ = $1;
   532  		$$.index = $3;
   533  		$$.scale = $5;
   534  		checkscale($$.scale);
   535  	}
   536  
   537  nam:
   538  	LNAME offset '(' pointer ')'
   539  	{
   540  		$$ = nullgen;
   541  		$$.type = $4;
   542  		$$.sym = $1;
   543  		$$.offset = $2;
   544  	}
   545  |	LNAME '<' '>' offset '(' LSB ')'
   546  	{
   547  		$$ = nullgen;
   548  		$$.type = D_STATIC;
   549  		$$.sym = $1;
   550  		$$.offset = $4;
   551  	}
   552  
   553  offset:
   554  	{
   555  		$$ = 0;
   556  	}
   557  |	'+' con
   558  	{
   559  		$$ = $2;
   560  	}
   561  |	'-' con
   562  	{
   563  		$$ = -$2;
   564  	}
   565  
   566  pointer:
   567  	LSB
   568  |	LSP
   569  	{
   570  		$$ = D_AUTO;
   571  	}
   572  |	LFP
   573  
   574  con:
   575  	LCONST
   576  |	LVAR
   577  	{
   578  		$$ = $1->value;
   579  	}
   580  |	'-' con
   581  	{
   582  		$$ = -$2;
   583  	}
   584  |	'+' con
   585  	{
   586  		$$ = $2;
   587  	}
   588  |	'~' con
   589  	{
   590  		$$ = ~$2;
   591  	}
   592  |	'(' expr ')'
   593  	{
   594  		$$ = $2;
   595  	}
   596  
   597  con2:
   598  	LCONST
   599  	{
   600  		$$ = $1 & 0xffffffffLL;
   601  	}
   602  |	'-' LCONST
   603  	{
   604  		$$ = -$2 & 0xffffffffLL;
   605  	}
   606  |	LCONST '-' LCONST
   607  	{
   608  		$$ = ($1 & 0xffffffffLL) +
   609  			(($3 & 0xffffLL) << 32);
   610  	}
   611  |	'-' LCONST '-' LCONST
   612  	{
   613  		$$ = (-$2 & 0xffffffffLL) +
   614  			(($4 & 0xffffLL) << 32);
   615  	}
   616  
   617  expr:
   618  	con
   619  |	expr '+' expr
   620  	{
   621  		$$ = $1 + $3;
   622  	}
   623  |	expr '-' expr
   624  	{
   625  		$$ = $1 - $3;
   626  	}
   627  |	expr '*' expr
   628  	{
   629  		$$ = $1 * $3;
   630  	}
   631  |	expr '/' expr
   632  	{
   633  		$$ = $1 / $3;
   634  	}
   635  |	expr '%' expr
   636  	{
   637  		$$ = $1 % $3;
   638  	}
   639  |	expr '<' '<' expr
   640  	{
   641  		$$ = $1 << $4;
   642  	}
   643  |	expr '>' '>' expr
   644  	{
   645  		$$ = $1 >> $4;
   646  	}
   647  |	expr '&' expr
   648  	{
   649  		$$ = $1 & $3;
   650  	}
   651  |	expr '^' expr
   652  	{
   653  		$$ = $1 ^ $3;
   654  	}
   655  |	expr '|' expr
   656  	{
   657  		$$ = $1 | $3;
   658  	}