github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/src/cmd/5a/a.y (about)

     1  // Inferno utils/5a/a.y
     2  // http://code.google.com/p/inferno-os/source/browse/utils/5a/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  {
    40  	Sym	*sym;
    41  	int32	lval;
    42  	double	dval;
    43  	char	sval[8];
    44  	Addr	addr;
    45  }
    46  %left	'|'
    47  %left	'^'
    48  %left	'&'
    49  %left	'<' '>'
    50  %left	'+' '-'
    51  %left	'*' '/' '%'
    52  %token	<lval>	LTYPE1 LTYPE2 LTYPE3 LTYPE4 LTYPE5
    53  %token	<lval>	LTYPE6 LTYPE7 LTYPE8 LTYPE9 LTYPEA
    54  %token	<lval>	LTYPEB LTYPEC LTYPED LTYPEE
    55  %token	<lval>	LTYPEG LTYPEH LTYPEI LTYPEJ LTYPEK
    56  %token	<lval>	LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
    57  %token	<lval>	LCONST LSP LSB LFP LPC
    58  %token	<lval>	LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
    59  %token	<lval>	LCOND LS LAT
    60  %token	<dval>	LFCONST
    61  %token	<sval>	LSCONST
    62  %token	<sym>	LNAME LLAB LVAR
    63  %type	<lval>	con expr oexpr pointer offset sreg spreg creg
    64  %type	<lval>	rcon cond reglist
    65  %type	<addr>	gen rel reg regreg freg shift fcon frcon
    66  %type	<addr>	imm ximm name oreg ireg nireg ioreg imsr
    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  |	LNAME '=' expr ';'
    90  	{
    91  		$1->type = LVAR;
    92  		$1->value = $3;
    93  	}
    94  |	LVAR '=' expr ';'
    95  	{
    96  		if($1->value != $3)
    97  			yyerror("redeclaration of %s", $1->name);
    98  		$1->value = $3;
    99  	}
   100  |	';'
   101  |	inst ';'
   102  |	error ';'
   103  
   104  inst:
   105  /*
   106   * ADD
   107   */
   108  	LTYPE1 cond imsr ',' spreg ',' reg
   109  	{
   110  		outcode($1, $2, &$3, $5, &$7);
   111  	}
   112  |	LTYPE1 cond imsr ',' spreg ','
   113  	{
   114  		outcode($1, $2, &$3, $5, &nullgen);
   115  	}
   116  |	LTYPE1 cond imsr ',' reg
   117  	{
   118  		outcode($1, $2, &$3, NREG, &$5);
   119  	}
   120  /*
   121   * MVN
   122   */
   123  |	LTYPE2 cond imsr ',' reg
   124  	{
   125  		outcode($1, $2, &$3, NREG, &$5);
   126  	}
   127  /*
   128   * MOVW
   129   */
   130  |	LTYPE3 cond gen ',' gen
   131  	{
   132  		outcode($1, $2, &$3, NREG, &$5);
   133  	}
   134  /*
   135   * B/BL
   136   */
   137  |	LTYPE4 cond comma rel
   138  	{
   139  		outcode($1, $2, &nullgen, NREG, &$4);
   140  	}
   141  |	LTYPE4 cond comma nireg
   142  	{
   143  		outcode($1, $2, &nullgen, NREG, &$4);
   144  	}
   145  /*
   146   * BX
   147   */
   148  |	LTYPEBX comma ireg
   149  	{
   150  		outcode($1, Always, &nullgen, NREG, &$3);
   151  	}
   152  /*
   153   * BEQ
   154   */
   155  |	LTYPE5 comma rel
   156  	{
   157  		outcode($1, Always, &nullgen, NREG, &$3);
   158  	}
   159  /*
   160   * SWI
   161   */
   162  |	LTYPE6 cond comma gen
   163  	{
   164  		outcode($1, $2, &nullgen, NREG, &$4);
   165  	}
   166  /*
   167   * CMP
   168   */
   169  |	LTYPE7 cond imsr ',' spreg comma
   170  	{
   171  		outcode($1, $2, &$3, $5, &nullgen);
   172  	}
   173  /*
   174   * MOVM
   175   */
   176  |	LTYPE8 cond ioreg ',' '[' reglist ']'
   177  	{
   178  		Addr g;
   179  
   180  		g = nullgen;
   181  		g.type = D_CONST;
   182  		g.offset = $6;
   183  		outcode($1, $2, &$3, NREG, &g);
   184  	}
   185  |	LTYPE8 cond '[' reglist ']' ',' ioreg
   186  	{
   187  		Addr g;
   188  
   189  		g = nullgen;
   190  		g.type = D_CONST;
   191  		g.offset = $4;
   192  		outcode($1, $2, &g, NREG, &$7);
   193  	}
   194  /*
   195   * SWAP
   196   */
   197  |	LTYPE9 cond reg ',' ireg ',' reg
   198  	{
   199  		outcode($1, $2, &$5, $3.reg, &$7);
   200  	}
   201  |	LTYPE9 cond reg ',' ireg comma
   202  	{
   203  		outcode($1, $2, &$5, $3.reg, &$3);
   204  	}
   205  |	LTYPE9 cond comma ireg ',' reg
   206  	{
   207  		outcode($1, $2, &$4, $6.reg, &$6);
   208  	}
   209  /*
   210   * RET
   211   */
   212  |	LTYPEA cond comma
   213  	{
   214  		outcode($1, $2, &nullgen, NREG, &nullgen);
   215  	}
   216  /*
   217   * TEXT/GLOBL
   218   */
   219  |	LTYPEB name ',' imm
   220  	{
   221  		$4.type = D_CONST2;
   222  		$4.offset2 = ArgsSizeUnknown;
   223  		outcode($1, Always, &$2, 0, &$4);
   224  	}
   225  |	LTYPEB name ',' con ',' imm
   226  	{
   227  		$6.type = D_CONST2;
   228  		$6.offset2 = ArgsSizeUnknown;
   229  		outcode($1, Always, &$2, $4, &$6);
   230  	}
   231  |	LTYPEB name ',' con ',' imm '-' con
   232  	{
   233  		$6.type = D_CONST2;
   234  		$6.offset2 = $8;
   235  		outcode($1, Always, &$2, $4, &$6);
   236  	}
   237  /*
   238   * DATA
   239   */
   240  |	LTYPEC name '/' con ',' ximm
   241  	{
   242  		outcode($1, Always, &$2, $4, &$6);
   243  	}
   244  /*
   245   * CASE
   246   */
   247  |	LTYPED cond reg comma
   248  	{
   249  		outcode($1, $2, &$3, NREG, &nullgen);
   250  	}
   251  /*
   252   * word
   253   */
   254  |	LTYPEH comma ximm
   255  	{
   256  		outcode($1, Always, &nullgen, NREG, &$3);
   257  	}
   258  /*
   259   * floating-point coprocessor
   260   */
   261  |	LTYPEI cond freg ',' freg
   262  	{
   263  		outcode($1, $2, &$3, NREG, &$5);
   264  	}
   265  |	LTYPEK cond frcon ',' freg
   266  	{
   267  		outcode($1, $2, &$3, NREG, &$5);
   268  	}
   269  |	LTYPEK cond frcon ',' LFREG ',' freg
   270  	{
   271  		outcode($1, $2, &$3, $5, &$7);
   272  	}
   273  |	LTYPEL cond freg ',' freg comma
   274  	{
   275  		outcode($1, $2, &$3, $5.reg, &nullgen);
   276  	}
   277  /*
   278   * MCR MRC
   279   */
   280  |	LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
   281  	{
   282  		Addr g;
   283  
   284  		g = nullgen;
   285  		g.type = D_CONST;
   286  		g.offset =
   287  			(0xe << 24) |		/* opcode */
   288  			($1 << 20) |		/* MCR/MRC */
   289  			($2 << 28) |		/* scond */
   290  			(($3 & 15) << 8) |	/* coprocessor number */
   291  			(($5 & 7) << 21) |	/* coprocessor operation */
   292  			(($7 & 15) << 12) |	/* arm register */
   293  			(($9 & 15) << 16) |	/* Crn */
   294  			(($11 & 15) << 0) |	/* Crm */
   295  			(($12 & 7) << 5) |	/* coprocessor information */
   296  			(1<<4);			/* must be set */
   297  		outcode(AMRC, Always, &nullgen, NREG, &g);
   298  	}
   299  /*
   300   * MULL r1,r2,(hi,lo)
   301   */
   302  |	LTYPEM cond reg ',' reg ',' regreg
   303  	{
   304  		outcode($1, $2, &$3, $5.reg, &$7);
   305  	}
   306  /*
   307   * MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
   308   * MULAW{T,B} r1,r2,r3,r4
   309   */
   310  |	LTYPEN cond reg ',' reg ',' reg ',' spreg
   311  	{
   312  		$7.type = D_REGREG2;
   313  		$7.offset = $9;
   314  		outcode($1, $2, &$3, $5.reg, &$7);
   315  	}
   316  /*
   317   * PLD
   318   */
   319  |	LTYPEPLD oreg
   320  	{
   321  		outcode($1, Always, &$2, NREG, &nullgen);
   322  	}
   323  /*
   324   * PCDATA
   325   */
   326  |	LTYPEPC gen ',' gen
   327  	{
   328  		if($2.type != D_CONST || $4.type != D_CONST)
   329  			yyerror("arguments to PCDATA must be integer constants");
   330  		outcode($1, Always, &$2, NREG, &$4);
   331  	}
   332  /*
   333   * FUNCDATA
   334   */
   335  |	LTYPEF gen ',' gen
   336  	{
   337  		if($2.type != D_CONST)
   338  			yyerror("index for FUNCDATA must be integer constant");
   339  		if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
   340  			yyerror("value for FUNCDATA must be symbol reference");
   341   		outcode($1, Always, &$2, NREG, &$4);
   342  	}
   343  /*
   344   * END
   345   */
   346  |	LTYPEE comma
   347  	{
   348  		outcode($1, Always, &nullgen, NREG, &nullgen);
   349  	}
   350  
   351  cond:
   352  	{
   353  		$$ = Always;
   354  	}
   355  |	cond LCOND
   356  	{
   357  		$$ = ($1 & ~C_SCOND) | $2;
   358  	}
   359  |	cond LS
   360  	{
   361  		$$ = $1 | $2;
   362  	}
   363  
   364  comma:
   365  |	',' comma
   366  
   367  rel:
   368  	con '(' LPC ')'
   369  	{
   370  		$$ = nullgen;
   371  		$$.type = D_BRANCH;
   372  		$$.offset = $1 + pc;
   373  	}
   374  |	LNAME offset
   375  	{
   376  		$$ = nullgen;
   377  		if(pass == 2)
   378  			yyerror("undefined label: %s", $1->name);
   379  		$$.type = D_BRANCH;
   380  		$$.offset = $2;
   381  	}
   382  |	LLAB offset
   383  	{
   384  		$$ = nullgen;
   385  		$$.type = D_BRANCH;
   386  		$$.offset = $1->value + $2;
   387  	}
   388  
   389  ximm:	'$' con
   390  	{
   391  		$$ = nullgen;
   392  		$$.type = D_CONST;
   393  		$$.offset = $2;
   394  	}
   395  |	'$' oreg
   396  	{
   397  		$$ = $2;
   398  		$$.type = D_CONST;
   399  	}
   400  |	'$' '*' '$' oreg
   401  	{
   402  		$$ = $4;
   403  		$$.type = D_OCONST;
   404  	}
   405  |	'$' LSCONST
   406  	{
   407  		$$ = nullgen;
   408  		$$.type = D_SCONST;
   409  		memcpy($$.u.sval, $2, sizeof($$.u.sval));
   410  	}
   411  |	fcon
   412  
   413  fcon:
   414  	'$' LFCONST
   415  	{
   416  		$$ = nullgen;
   417  		$$.type = D_FCONST;
   418  		$$.u.dval = $2;
   419  	}
   420  |	'$' '-' LFCONST
   421  	{
   422  		$$ = nullgen;
   423  		$$.type = D_FCONST;
   424  		$$.u.dval = -$3;
   425  	}
   426  
   427  reglist:
   428  	spreg
   429  	{
   430  		$$ = 1 << $1;
   431  	}
   432  |	spreg '-' spreg
   433  	{
   434  		int i;
   435  		$$=0;
   436  		for(i=$1; i<=$3; i++)
   437  			$$ |= 1<<i;
   438  		for(i=$3; i<=$1; i++)
   439  			$$ |= 1<<i;
   440  	}
   441  |	spreg comma reglist
   442  	{
   443  		$$ = (1<<$1) | $3;
   444  	}
   445  
   446  gen:
   447  	reg
   448  |	ximm
   449  |	shift
   450  |	shift '(' spreg ')'
   451  	{
   452  		$$ = $1;
   453  		$$.reg = $3;
   454  	}
   455  |	LPSR
   456  	{
   457  		$$ = nullgen;
   458  		$$.type = D_PSR;
   459  		$$.reg = $1;
   460  	}
   461  |	LFCR
   462  	{
   463  		$$ = nullgen;
   464  		$$.type = D_FPCR;
   465  		$$.reg = $1;
   466  	}
   467  |	con
   468  	{
   469  		$$ = nullgen;
   470  		$$.type = D_OREG;
   471  		$$.offset = $1;
   472  	}
   473  |	oreg
   474  |	freg
   475  
   476  nireg:
   477  	ireg
   478  |	name
   479  	{
   480  		$$ = $1;
   481  		if($1.name != D_EXTERN && $1.name != D_STATIC) {
   482  		}
   483  	}
   484  
   485  ireg:
   486  	'(' spreg ')'
   487  	{
   488  		$$ = nullgen;
   489  		$$.type = D_OREG;
   490  		$$.reg = $2;
   491  		$$.offset = 0;
   492  	}
   493  
   494  ioreg:
   495  	ireg
   496  |	con '(' sreg ')'
   497  	{
   498  		$$ = nullgen;
   499  		$$.type = D_OREG;
   500  		$$.reg = $3;
   501  		$$.offset = $1;
   502  	}
   503  
   504  oreg:
   505  	name
   506  |	name '(' sreg ')'
   507  	{
   508  		$$ = $1;
   509  		$$.type = D_OREG;
   510  		$$.reg = $3;
   511  	}
   512  |	ioreg
   513  
   514  imsr:
   515  	reg
   516  |	imm
   517  |	shift
   518  
   519  imm:	'$' con
   520  	{
   521  		$$ = nullgen;
   522  		$$.type = D_CONST;
   523  		$$.offset = $2;
   524  	}
   525  
   526  reg:
   527  	spreg
   528  	{
   529  		$$ = nullgen;
   530  		$$.type = D_REG;
   531  		$$.reg = $1;
   532  	}
   533  
   534  regreg:
   535  	'(' spreg ',' spreg ')'
   536  	{
   537  		$$ = nullgen;
   538  		$$.type = D_REGREG;
   539  		$$.reg = $2;
   540  		$$.offset = $4;
   541  	}
   542  
   543  shift:
   544  	spreg '<' '<' rcon
   545  	{
   546  		$$ = nullgen;
   547  		$$.type = D_SHIFT;
   548  		$$.offset = $1 | $4 | (0 << 5);
   549  	}
   550  |	spreg '>' '>' rcon
   551  	{
   552  		$$ = nullgen;
   553  		$$.type = D_SHIFT;
   554  		$$.offset = $1 | $4 | (1 << 5);
   555  	}
   556  |	spreg '-' '>' rcon
   557  	{
   558  		$$ = nullgen;
   559  		$$.type = D_SHIFT;
   560  		$$.offset = $1 | $4 | (2 << 5);
   561  	}
   562  |	spreg LAT '>' rcon
   563  	{
   564  		$$ = nullgen;
   565  		$$.type = D_SHIFT;
   566  		$$.offset = $1 | $4 | (3 << 5);
   567  	}
   568  
   569  rcon:
   570  	spreg
   571  	{
   572  		if($$ < 0 || $$ >= 16)
   573  			print("register value out of range\n");
   574  		$$ = (($1&15) << 8) | (1 << 4);
   575  	}
   576  |	con
   577  	{
   578  		if($$ < 0 || $$ >= 32)
   579  			print("shift value out of range\n");
   580  		$$ = ($1&31) << 7;
   581  	}
   582  
   583  sreg:
   584  	LREG
   585  |	LPC
   586  	{
   587  		$$ = REGPC;
   588  	}
   589  |	LR '(' expr ')'
   590  	{
   591  		if($3 < 0 || $3 >= NREG)
   592  			print("register value out of range\n");
   593  		$$ = $3;
   594  	}
   595  
   596  spreg:
   597  	sreg
   598  |	LSP
   599  	{
   600  		$$ = REGSP;
   601  	}
   602  
   603  creg:
   604  	LCREG
   605  |	LC '(' expr ')'
   606  	{
   607  		if($3 < 0 || $3 >= NREG)
   608  			print("register value out of range\n");
   609  		$$ = $3;
   610  	}
   611  
   612  frcon:
   613  	freg
   614  |	fcon
   615  
   616  freg:
   617  	LFREG
   618  	{
   619  		$$ = nullgen;
   620  		$$.type = D_FREG;
   621  		$$.reg = $1;
   622  	}
   623  |	LF '(' con ')'
   624  	{
   625  		$$ = nullgen;
   626  		$$.type = D_FREG;
   627  		$$.reg = $3;
   628  	}
   629  
   630  name:
   631  	con '(' pointer ')'
   632  	{
   633  		$$ = nullgen;
   634  		$$.type = D_OREG;
   635  		$$.name = $3;
   636  		$$.sym = nil;
   637  		$$.offset = $1;
   638  	}
   639  |	LNAME offset '(' pointer ')'
   640  	{
   641  		$$ = nullgen;
   642  		$$.type = D_OREG;
   643  		$$.name = $4;
   644  		$$.sym = linklookup(ctxt, $1->name, 0);
   645  		$$.offset = $2;
   646  	}
   647  |	LNAME '<' '>' offset '(' LSB ')'
   648  	{
   649  		$$ = nullgen;
   650  		$$.type = D_OREG;
   651  		$$.name = D_STATIC;
   652  		$$.sym = linklookup(ctxt, $1->name, 1);
   653  		$$.offset = $4;
   654  	}
   655  
   656  offset:
   657  	{
   658  		$$ = 0;
   659  	}
   660  |	'+' con
   661  	{
   662  		$$ = $2;
   663  	}
   664  |	'-' con
   665  	{
   666  		$$ = -$2;
   667  	}
   668  
   669  pointer:
   670  	LSB
   671  |	LSP
   672  |	LFP
   673  
   674  con:
   675  	LCONST
   676  |	LVAR
   677  	{
   678  		$$ = $1->value;
   679  	}
   680  |	'-' con
   681  	{
   682  		$$ = -$2;
   683  	}
   684  |	'+' con
   685  	{
   686  		$$ = $2;
   687  	}
   688  |	'~' con
   689  	{
   690  		$$ = ~$2;
   691  	}
   692  |	'(' expr ')'
   693  	{
   694  		$$ = $2;
   695  	}
   696  
   697  oexpr:
   698  	{
   699  		$$ = 0;
   700  	}
   701  |	',' expr
   702  	{
   703  		$$ = $2;
   704  	}
   705  
   706  expr:
   707  	con
   708  |	expr '+' expr
   709  	{
   710  		$$ = $1 + $3;
   711  	}
   712  |	expr '-' expr
   713  	{
   714  		$$ = $1 - $3;
   715  	}
   716  |	expr '*' expr
   717  	{
   718  		$$ = $1 * $3;
   719  	}
   720  |	expr '/' expr
   721  	{
   722  		$$ = $1 / $3;
   723  	}
   724  |	expr '%' expr
   725  	{
   726  		$$ = $1 % $3;
   727  	}
   728  |	expr '<' '<' expr
   729  	{
   730  		$$ = $1 << $4;
   731  	}
   732  |	expr '>' '>' expr
   733  	{
   734  		$$ = $1 >> $4;
   735  	}
   736  |	expr '&' expr
   737  	{
   738  		$$ = $1 & $3;
   739  	}
   740  |	expr '^' expr
   741  	{
   742  		$$ = $1 ^ $3;
   743  	}
   744  |	expr '|' expr
   745  	{
   746  		$$ = $1 | $3;
   747  	}