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