github.com/yanyiwu/go@v0.0.0-20150106053140-03d6637dbb7f/src/cmd/5a/lex.c (about)

     1  // Inferno utils/5a/lex.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c
     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  #define	EXTERN
    32  #include <u.h>
    33  #include <libc.h>
    34  #include "a.h"
    35  #include "y.tab.h"
    36  
    37  enum
    38  {
    39  	Plan9	= 1<<0,
    40  	Unix	= 1<<1,
    41  	Windows	= 1<<2,
    42  };
    43  
    44  int
    45  systemtype(int sys)
    46  {
    47  #ifdef _WIN32
    48  	return sys&Windows;
    49  #else
    50  	return sys&Plan9;
    51  #endif
    52  }
    53  
    54  int
    55  Lconv(Fmt *fp)
    56  {
    57  	return linklinefmt(ctxt, fp);
    58  }
    59  
    60  void
    61  dodef(char *p)
    62  {
    63  	if(nDlist%8 == 0)
    64  		Dlist = allocn(Dlist, nDlist*sizeof(char *),
    65  			8*sizeof(char *));
    66  	Dlist[nDlist++] = p;
    67  }
    68  
    69  void
    70  usage(void)
    71  {
    72  	print("usage: %ca [options] file.c...\n", thechar);
    73  	flagprint(1);
    74  	errorexit();
    75  }
    76  
    77  void
    78  main(int argc, char *argv[])
    79  {
    80  	char *p;
    81  
    82  	thechar = '5';
    83  	thestring = "arm";
    84  
    85  	ctxt = linknew(&linkarm);
    86  	ctxt->diag = yyerror;
    87  	ctxt->bso = &bstdout;
    88  	ctxt->enforce_data_order = 1;
    89  	Binit(&bstdout, 1, OWRITE);
    90  	listinit5();
    91  	fmtinstall('L', Lconv);
    92  
    93  	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
    94  	// but not other values.	
    95  	p = getgoarch();
    96  	if(strncmp(p, thestring, strlen(thestring)) != 0)
    97  		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
    98  
    99  	ensuresymb(NSYMB);
   100  	memset(debug, 0, sizeof(debug));
   101  	cinit();
   102  	outfile = 0;
   103  	setinclude(".");
   104  	
   105  	flagfn1("D", "name[=value]: add #define", dodef);
   106  	flagfn1("I", "dir: add dir to include path", setinclude);
   107  	flagcount("S", "print assembly and machine code", &debug['S']);
   108  	flagcount("m", "debug preprocessor macros", &debug['m']);
   109  	flagstr("o", "file: set output file", &outfile);
   110  	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
   111  
   112  	flagparse(&argc, &argv, usage);
   113  	ctxt->debugasm = debug['S'];
   114  
   115  	if(argc < 1)
   116  		usage();
   117  	if(argc > 1){
   118  		print("can't assemble multiple files\n");
   119  		errorexit();
   120  	}
   121  
   122  	if(assemble(argv[0]))
   123  		errorexit();
   124  	Bflush(&bstdout);
   125  	exits(0);
   126  }
   127  
   128  int
   129  assemble(char *file)
   130  {
   131  	char *ofile, *p;
   132  	int i, of;
   133  
   134  	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
   135  	strcpy(ofile, file);
   136  	p = utfrrune(ofile, '/');
   137  	if(p) {
   138  		include[0] = ofile;
   139  		*p++ = 0;
   140  	} else
   141  		p = ofile;
   142  	if(outfile == 0) {
   143  		outfile = p;
   144  		if(outfile){
   145  			p = utfrrune(outfile, '.');
   146  			if(p)
   147  				if(p[1] == 's' && p[2] == 0)
   148  					p[0] = 0;
   149  			p = utfrune(outfile, 0);
   150  			p[0] = '.';
   151  			p[1] = thechar;
   152  			p[2] = 0;
   153  		} else
   154  			outfile = "/dev/null";
   155  	}
   156  
   157  	of = create(outfile, OWRITE, 0664);
   158  	if(of < 0) {
   159  		yyerror("%ca: cannot create %s", thechar, outfile);
   160  		errorexit();
   161  	}
   162  	Binit(&obuf, of, OWRITE);
   163  	Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
   164  	Bprint(&obuf, "!\n");
   165  
   166  	for(pass = 1; pass <= 2; pass++) {
   167  		pinit(file);
   168  		for(i=0; i<nDlist; i++)
   169  			dodefine(Dlist[i]);
   170  		yyparse();
   171  		cclean();
   172  		if(nerrors)
   173  			return nerrors;
   174  	}
   175  
   176  	writeobj(ctxt, &obuf);
   177  	Bflush(&obuf);
   178  	return 0;
   179  }
   180  
   181  struct
   182  {
   183  	char	*name;
   184  	ushort	type;
   185  	ushort	value;
   186  } itab[] =
   187  {
   188  	"SP",		LSP,	D_AUTO,
   189  	"SB",		LSB,	D_EXTERN,
   190  	"FP",		LFP,	D_PARAM,
   191  	"PC",		LPC,	D_BRANCH,
   192  
   193  	"R",		LR,	0,
   194  	"R0",		LREG,	0,
   195  	"R1",		LREG,	1,
   196  	"R2",		LREG,	2,
   197  	"R3",		LREG,	3,
   198  	"R4",		LREG,	4,
   199  	"R5",		LREG,	5,
   200  	"R6",		LREG,	6,
   201  	"R7",		LREG,	7,
   202  	"R8",		LREG,	8,
   203  	"R9",		LREG,	9,
   204  	"g",		LREG,	10, // avoid unintentionally clobber g using R10
   205  	"R11",		LREG,	11,
   206  	"R12",		LREG,	12,
   207  	"R13",		LREG,	13,
   208  	"R14",		LREG,	14,
   209  	"R15",		LREG,	15,
   210  
   211  	"F",		LF,	0,
   212  
   213  	"F0",		LFREG,	0,
   214  	"F1",		LFREG,	1,
   215  	"F2",		LFREG,	2,
   216  	"F3",		LFREG,	3,
   217  	"F4",		LFREG,	4,
   218  	"F5",		LFREG,	5,
   219  	"F6",		LFREG,	6,
   220  	"F7",		LFREG,	7,
   221  	"F8",		LFREG,	8,
   222  	"F9",		LFREG,	9,
   223  	"F10",		LFREG,	10,
   224  	"F11",		LFREG,	11,
   225  	"F12",		LFREG,	12,
   226  	"F13",		LFREG,	13,
   227  	"F14",		LFREG,	14,
   228  	"F15",		LFREG,	15,
   229  
   230  	"C",		LC,	0,
   231  
   232  	"C0",		LCREG,	0,
   233  	"C1",		LCREG,	1,
   234  	"C2",		LCREG,	2,
   235  	"C3",		LCREG,	3,
   236  	"C4",		LCREG,	4,
   237  	"C5",		LCREG,	5,
   238  	"C6",		LCREG,	6,
   239  	"C7",		LCREG,	7,
   240  	"C8",		LCREG,	8,
   241  	"C9",		LCREG,	9,
   242  	"C10",		LCREG,	10,
   243  	"C11",		LCREG,	11,
   244  	"C12",		LCREG,	12,
   245  	"C13",		LCREG,	13,
   246  	"C14",		LCREG,	14,
   247  	"C15",		LCREG,	15,
   248  
   249  	"CPSR",		LPSR,	0,
   250  	"SPSR",		LPSR,	1,
   251  
   252  	"FPSR",		LFCR,	0,
   253  	"FPCR",		LFCR,	1,
   254  
   255  	".EQ",		LCOND,	0,
   256  	".NE",		LCOND,	1,
   257  	".CS",		LCOND,	2,
   258  	".HS",		LCOND,	2,
   259  	".CC",		LCOND,	3,
   260  	".LO",		LCOND,	3,
   261  	".MI",		LCOND,	4,
   262  	".PL",		LCOND,	5,
   263  	".VS",		LCOND,	6,
   264  	".VC",		LCOND,	7,
   265  	".HI",		LCOND,	8,
   266  	".LS",		LCOND,	9,
   267  	".GE",		LCOND,	10,
   268  	".LT",		LCOND,	11,
   269  	".GT",		LCOND,	12,
   270  	".LE",		LCOND,	13,
   271  	".AL",		LCOND,	Always,
   272  
   273  	".U",		LS,	C_UBIT,
   274  	".S",		LS,	C_SBIT,
   275  	".W",		LS,	C_WBIT,
   276  	".P",		LS,	C_PBIT,
   277  	".PW",		LS,	C_WBIT|C_PBIT,
   278  	".WP",		LS,	C_WBIT|C_PBIT,
   279  
   280  	".F",		LS,	C_FBIT,
   281  
   282  	".IBW",		LS,	C_WBIT|C_PBIT|C_UBIT,
   283  	".IAW",		LS,	C_WBIT|C_UBIT,
   284  	".DBW",		LS,	C_WBIT|C_PBIT,
   285  	".DAW",		LS,	C_WBIT,
   286  	".IB",		LS,	C_PBIT|C_UBIT,
   287  	".IA",		LS,	C_UBIT,
   288  	".DB",		LS,	C_PBIT,
   289  	".DA",		LS,	0,
   290  
   291  	"@",		LAT,	0,
   292  
   293  	"AND",		LTYPE1,	AAND,
   294  	"EOR",		LTYPE1,	AEOR,
   295  	"SUB",		LTYPE1,	ASUB,
   296  	"RSB",		LTYPE1,	ARSB,
   297  	"ADD",		LTYPE1,	AADD,
   298  	"ADC",		LTYPE1,	AADC,
   299  	"SBC",		LTYPE1,	ASBC,
   300  	"RSC",		LTYPE1,	ARSC,
   301  	"ORR",		LTYPE1,	AORR,
   302  	"BIC",		LTYPE1,	ABIC,
   303  
   304  	"SLL",		LTYPE1,	ASLL,
   305  	"SRL",		LTYPE1,	ASRL,
   306  	"SRA",		LTYPE1,	ASRA,
   307  
   308  	"MUL",		LTYPE1, AMUL,
   309  	"MULA",		LTYPEN, AMULA,
   310  	"DIV",		LTYPE1,	ADIV,
   311  	"MOD",		LTYPE1,	AMOD,
   312  
   313  	"MULL",		LTYPEM, AMULL,
   314  	"MULAL",	LTYPEM, AMULAL,
   315  	"MULLU",	LTYPEM, AMULLU,
   316  	"MULALU",	LTYPEM, AMULALU,
   317  
   318  	"MVN",		LTYPE2, AMVN,	/* op2 ignored */
   319  
   320  	"MOVB",		LTYPE3, AMOVB,
   321  	"MOVBU",	LTYPE3, AMOVBU,
   322  	"MOVH",		LTYPE3, AMOVH,
   323  	"MOVHU",	LTYPE3, AMOVHU,
   324  	"MOVW",		LTYPE3, AMOVW,
   325  
   326  	"MOVD",		LTYPE3, AMOVD,
   327  	"MOVDF",		LTYPE3, AMOVDF,
   328  	"MOVDW",	LTYPE3, AMOVDW,
   329  	"MOVF",		LTYPE3, AMOVF,
   330  	"MOVFD",		LTYPE3, AMOVFD,
   331  	"MOVFW",		LTYPE3, AMOVFW,
   332  	"MOVWD",	LTYPE3, AMOVWD,
   333  	"MOVWF",		LTYPE3, AMOVWF,
   334  
   335  	"LDREX",		LTYPE3, ALDREX,
   336  	"LDREXD",		LTYPE3, ALDREXD,
   337  	"STREX",		LTYPE9, ASTREX,
   338  	"STREXD",		LTYPE9, ASTREXD,
   339  
   340  /*
   341  	"NEGF",		LTYPEI, ANEGF,
   342  	"NEGD",		LTYPEI, ANEGD,
   343  	"SQTF",		LTYPEI,	ASQTF,
   344  	"SQTD",		LTYPEI,	ASQTD,
   345  	"RNDF",		LTYPEI,	ARNDF,
   346  	"RNDD",		LTYPEI,	ARNDD,
   347  	"URDF",		LTYPEI,	AURDF,
   348  	"URDD",		LTYPEI,	AURDD,
   349  	"NRMF",		LTYPEI,	ANRMF,
   350  	"NRMD",		LTYPEI,	ANRMD,
   351  */
   352  
   353  	"ABSF",		LTYPEI, AABSF,
   354  	"ABSD",		LTYPEI, AABSD,
   355  	"SQRTF",	LTYPEI, ASQRTF,
   356  	"SQRTD",	LTYPEI, ASQRTD,
   357  	"CMPF",		LTYPEL, ACMPF,
   358  	"CMPD",		LTYPEL, ACMPD,
   359  	"ADDF",		LTYPEK,	AADDF,
   360  	"ADDD",		LTYPEK,	AADDD,
   361  	"SUBF",		LTYPEK,	ASUBF,
   362  	"SUBD",		LTYPEK,	ASUBD,
   363  	"MULF",		LTYPEK,	AMULF,
   364  	"MULD",		LTYPEK,	AMULD,
   365  	"DIVF",		LTYPEK,	ADIVF,
   366  	"DIVD",		LTYPEK,	ADIVD,
   367  
   368  	"B",		LTYPE4, AB,
   369  	"BL",		LTYPE4, ABL,
   370  	"BX",		LTYPEBX,	ABX,
   371  
   372  	"BEQ",		LTYPE5,	ABEQ,
   373  	"BNE",		LTYPE5,	ABNE,
   374  	"BCS",		LTYPE5,	ABCS,
   375  	"BHS",		LTYPE5,	ABHS,
   376  	"BCC",		LTYPE5,	ABCC,
   377  	"BLO",		LTYPE5,	ABLO,
   378  	"BMI",		LTYPE5,	ABMI,
   379  	"BPL",		LTYPE5,	ABPL,
   380  	"BVS",		LTYPE5,	ABVS,
   381  	"BVC",		LTYPE5,	ABVC,
   382  	"BHI",		LTYPE5,	ABHI,
   383  	"BLS",		LTYPE5,	ABLS,
   384  	"BGE",		LTYPE5,	ABGE,
   385  	"BLT",		LTYPE5,	ABLT,
   386  	"BGT",		LTYPE5,	ABGT,
   387  	"BLE",		LTYPE5,	ABLE,
   388  	"BCASE",	LTYPE5,	ABCASE,
   389  
   390  	"SWI",		LTYPE6, ASWI,
   391  
   392  	"CMP",		LTYPE7,	ACMP,
   393  	"TST",		LTYPE7,	ATST,
   394  	"TEQ",		LTYPE7,	ATEQ,
   395  	"CMN",		LTYPE7,	ACMN,
   396  
   397  	"MOVM",		LTYPE8, AMOVM,
   398  
   399  	"SWPBU",	LTYPE9, ASWPBU,
   400  	"SWPW",		LTYPE9, ASWPW,
   401  
   402  	"RET",		LTYPEA, ARET,
   403  	"RFE",		LTYPEA, ARFE,
   404  
   405  	"TEXT",		LTYPEB, ATEXT,
   406  	"GLOBL",	LTYPEB, AGLOBL,
   407  	"DATA",		LTYPEC, ADATA,
   408  	"CASE",		LTYPED, ACASE,
   409  	"END",		LTYPEE, AEND,
   410  	"WORD",		LTYPEH, AWORD,
   411  	"NOP",		LTYPEI, ANOP,
   412  
   413  	"MCR",		LTYPEJ, 0,
   414  	"MRC",		LTYPEJ, 1,
   415  
   416  	"PLD",		LTYPEPLD, APLD,
   417  	"UNDEF",	LTYPEE,	AUNDEF,
   418  	"CLZ",		LTYPE2, ACLZ,
   419  
   420  	"MULWT",	LTYPE1, AMULWT,
   421  	"MULWB",	LTYPE1, AMULWB,
   422  	"MULAWT",	LTYPEN, AMULAWT,
   423  	"MULAWB",	LTYPEN, AMULAWB,
   424  
   425  	"USEFIELD",	LTYPEN, AUSEFIELD,
   426  	"PCDATA",	LTYPEPC,	APCDATA,
   427  	"FUNCDATA",	LTYPEF,	AFUNCDATA,
   428  
   429  	0
   430  };
   431  
   432  void
   433  cinit(void)
   434  {
   435  	Sym *s;
   436  	int i;
   437  
   438  	nullgen.type = D_NONE;
   439  	nullgen.name = D_NONE;
   440  	nullgen.reg = NREG;
   441  
   442  	nerrors = 0;
   443  	iostack = I;
   444  	iofree = I;
   445  	peekc = IGN;
   446  	nhunk = 0;
   447  	for(i=0; i<NHASH; i++)
   448  		hash[i] = S;
   449  	for(i=0; itab[i].name; i++) {
   450  		s = slookup(itab[i].name);
   451  		s->type = itab[i].type;
   452  		s->value = itab[i].value;
   453  	}
   454  }
   455  
   456  void
   457  syminit(Sym *s)
   458  {
   459  
   460  	s->type = LNAME;
   461  	s->value = 0;
   462  }
   463  
   464  int
   465  isreg(Addr *g)
   466  {
   467  
   468  	USED(g);
   469  	return 1;
   470  }
   471  
   472  void
   473  cclean(void)
   474  {
   475  	outcode(AEND, Always, &nullgen, NREG, &nullgen);
   476  }
   477  
   478  static int bcode[] =
   479  {
   480  	ABEQ,
   481  	ABNE,
   482  	ABCS,
   483  	ABCC,
   484  	ABMI,
   485  	ABPL,
   486  	ABVS,
   487  	ABVC,
   488  	ABHI,
   489  	ABLS,
   490  	ABGE,
   491  	ABLT,
   492  	ABGT,
   493  	ABLE,
   494  	AB,
   495  	ANOP,
   496  };
   497  
   498  static Prog *lastpc;
   499  
   500  void
   501  outcode(int a, int scond, Addr *g1, int reg, Addr *g2)
   502  {
   503  	Prog *p;
   504  	Plist *pl;
   505  
   506  	/* hack to make B.NE etc. work: turn it into the corresponding conditional */
   507  	if(a == AB){
   508  		a = bcode[scond&0xf];
   509  		scond = (scond & ~0xf) | Always;
   510  	}
   511  
   512  	if(pass == 1)
   513  		goto out;
   514  	
   515  	p = malloc(sizeof *p);
   516  	memset(p, 0, sizeof *p);
   517  	p->as = a;
   518  	p->lineno = stmtline;
   519  	p->scond = scond;
   520  	p->from = *g1;
   521  	p->reg = reg;
   522  	p->to = *g2;
   523  	p->pc = pc;
   524  
   525  	if(lastpc == nil) {
   526  		pl = linknewplist(ctxt);
   527  		pl->firstpc = p;
   528  	} else
   529  		lastpc->link = p;
   530  	lastpc = p;	
   531  
   532  out:
   533  	if(a != AGLOBL && a != ADATA)
   534  		pc++;
   535  }
   536  
   537  #include "../cc/lexbody"
   538  #include "../cc/macbody"