github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/8a/a.y (about)

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