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

     1  // cmd/9a/lex.c from Vita Nuova.
     2  //
     3  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     4  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     5  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     6  //	Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
     7  //	Portions Copyright © 2004,2006 Bruce Ellis
     8  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
     9  //	Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
    10  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    11  //
    12  // Permission is hereby granted, free of charge, to any person obtaining a copy
    13  // of this software and associated documentation files (the "Software"), to deal
    14  // in the Software without restriction, including without limitation the rights
    15  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    16  // copies of the Software, and to permit persons to whom the Software is
    17  // furnished to do so, subject to the following conditions:
    18  //
    19  // The above copyright notice and this permission notice shall be included in
    20  // all copies or substantial portions of the Software.
    21  //
    22  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    23  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    24  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    25  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    26  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    27  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    28  // THE SOFTWARE.
    29  
    30  #define	EXTERN
    31  #include <u.h>
    32  #include <libc.h>
    33  #include "a.h"
    34  #include "y.tab.h"
    35  
    36  enum
    37  {
    38  	Plan9	= 1<<0,
    39  	Unix	= 1<<1,
    40  	Windows	= 1<<2,
    41  };
    42  
    43  int
    44  systemtype(int sys)
    45  {
    46  #ifdef _WIN32
    47  	return sys&Windows;
    48  #else
    49  	return sys&Plan9;
    50  #endif
    51  }
    52  
    53  int
    54  pathchar(void)
    55  {
    56  	return '/';
    57  }
    58  
    59  int
    60  Lconv(Fmt *fp)
    61  {
    62  	return linklinefmt(ctxt, fp);
    63  }
    64  
    65  void
    66  dodef(char *p)
    67  {
    68  	if(nDlist%8 == 0)
    69  		Dlist = allocn(Dlist, nDlist*sizeof(char *),
    70  			8*sizeof(char *));
    71  	Dlist[nDlist++] = p;
    72  }
    73  
    74  LinkArch*       thelinkarch = &linkppc64;
    75  
    76  void
    77  usage(void)
    78  {
    79  	print("usage: %ca [options] file.c...\n", thechar);
    80  	flagprint(1);
    81  	errorexit();
    82  }
    83  
    84  void
    85  main(int argc, char *argv[])
    86  {
    87  	char *p;
    88  
    89  	thechar = '9';
    90  	thestring = "ppc64";
    91  
    92  	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
    93  	// but not other values.	
    94  	p = getgoarch();
    95  	if(strncmp(p, thestring, strlen(thestring)) != 0)
    96  		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
    97  	if(strcmp(p, "ppc64le") == 0)
    98  		thelinkarch = &linkppc64le;
    99  
   100  	ctxt = linknew(thelinkarch);
   101  	ctxt->diag = yyerror;
   102  	ctxt->bso = &bstdout;
   103  	ctxt->enforce_data_order = 1;
   104  	Binit(&bstdout, 1, OWRITE);
   105  	listinit9();
   106  	fmtinstall('L', Lconv);
   107  
   108  	ensuresymb(NSYMB);
   109  	memset(debug, 0, sizeof(debug));
   110  	cinit();
   111  	outfile = 0;
   112  	setinclude(".");
   113  
   114  	flagfn1("D", "name[=value]: add #define", dodef);
   115  	flagfn1("I", "dir: add dir to include path", setinclude);
   116  	flagcount("S", "print assembly and machine code", &debug['S']);
   117  	flagcount("m", "debug preprocessor macros", &debug['m']);
   118  	flagstr("o", "file: set output file", &outfile);
   119  	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
   120  
   121  	flagparse(&argc, &argv, usage);
   122  	ctxt->debugasm = debug['S'];
   123  
   124  	if(argc < 1)
   125  		usage();
   126  	if(argc > 1){
   127  		print("can't assemble multiple files\n");
   128  		errorexit();
   129  	}
   130  
   131  	if(assemble(argv[0]))
   132  		errorexit();
   133  	Bflush(&bstdout);
   134  	exits(0);
   135  }
   136  
   137  int
   138  assemble(char *file)
   139  {
   140  	char *ofile, *p;
   141  	int i, of;
   142  
   143  	ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
   144  	strcpy(ofile, file);
   145  	p = utfrrune(ofile, pathchar());
   146  	if(p) {
   147  		include[0] = ofile;
   148  		*p++ = 0;
   149  	} else
   150  		p = ofile;
   151  	if(outfile == 0) {
   152  		outfile = p;
   153  		if(outfile){
   154  			p = utfrrune(outfile, '.');
   155  			if(p)
   156  				if(p[1] == 's' && p[2] == 0)
   157  					p[0] = 0;
   158  			p = utfrune(outfile, 0);
   159  			p[0] = '.';
   160  			p[1] = thechar;
   161  			p[2] = 0;
   162  		} else
   163  			outfile = "/dev/null";
   164  	}
   165  
   166  	of = create(outfile, OWRITE, 0664);
   167  	if(of < 0) {
   168  		yyerror("%ca: cannot create %s", thechar, outfile);
   169  		errorexit();
   170  	}
   171  	Binit(&obuf, of, OWRITE);
   172  	Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
   173  	Bprint(&obuf, "!\n");
   174  
   175  	for(pass = 1; pass <= 2; pass++) {
   176  		nosched = 0;
   177  		pinit(file);
   178  		for(i=0; i<nDlist; i++)
   179  			dodefine(Dlist[i]);
   180  		yyparse();
   181  		cclean();
   182  		if(nerrors)
   183  			return nerrors;
   184  	}
   185  
   186  	writeobj(ctxt, &obuf);
   187  	Bflush(&obuf);
   188  	return 0;
   189  }
   190  
   191  struct
   192  {
   193  	char	*name;
   194  	ushort	type;
   195  	ushort	value;
   196  } itab[] =
   197  {
   198  	"SP",		LSP,	D_AUTO,
   199  	"SB",		LSB,	D_EXTERN,
   200  	"FP",		LFP,	D_PARAM,
   201  	"PC",		LPC,	D_BRANCH,
   202  
   203  	"LR",		LLR,	D_LR,
   204  	"CTR",		LCTR,	D_CTR,
   205  
   206  	"XER",		LSPREG,	D_XER,
   207  	"MSR",		LMSR,	D_MSR,
   208  	"FPSCR",	LFPSCR,	D_FPSCR,
   209  	"SPR",		LSPR,	D_SPR,
   210  	"DCR",		LSPR,	D_DCR,
   211  
   212  	"CR",		LCR,	0,
   213  	"CR0",		LCREG,	0,
   214  	"CR1",		LCREG,	1,
   215  	"CR2",		LCREG,	2,
   216  	"CR3",		LCREG,	3,
   217  	"CR4",		LCREG,	4,
   218  	"CR5",		LCREG,	5,
   219  	"CR6",		LCREG,	6,
   220  	"CR7",		LCREG,	7,
   221  
   222  	"R",		LR,	0,
   223  	"R0",		LREG,	0,
   224  	"R1",		LREG,	1,
   225  	"R2",		LREG,	2,
   226  	"R3",		LREG,	3,
   227  	"R4",		LREG,	4,
   228  	"R5",		LREG,	5,
   229  	"R6",		LREG,	6,
   230  	"R7",		LREG,	7,
   231  	"R8",		LREG,	8,
   232  	"R9",		LREG,	9,
   233  	"R10",		LREG,	10,
   234  	"R11",		LREG,	11,
   235  	"R12",		LREG,	12,
   236  	"R13",		LREG,	13,
   237  	"R14",		LREG,	14,
   238  	"R15",		LREG,	15,
   239  	"R16",		LREG,	16,
   240  	"R17",		LREG,	17,
   241  	"R18",		LREG,	18,
   242  	"R19",		LREG,	19,
   243  	"R20",		LREG,	20,
   244  	"R21",		LREG,	21,
   245  	"R22",		LREG,	22,
   246  	"R23",		LREG,	23,
   247  	"R24",		LREG,	24,
   248  	"R25",		LREG,	25,
   249  	"R26",		LREG,	26,
   250  	"R27",		LREG,	27,
   251  	"R28",		LREG,	28,
   252  	"R29",		LREG,	29,
   253  	"g",		LREG,	30, // avoid unintentionally clobbering g using R30
   254  	"R31",		LREG,	31,
   255  
   256  	"F",		LF,	0,
   257  	"F0",		LFREG,	0,
   258  	"F1",		LFREG,	1,
   259  	"F2",		LFREG,	2,
   260  	"F3",		LFREG,	3,
   261  	"F4",		LFREG,	4,
   262  	"F5",		LFREG,	5,
   263  	"F6",		LFREG,	6,
   264  	"F7",		LFREG,	7,
   265  	"F8",		LFREG,	8,
   266  	"F9",		LFREG,	9,
   267  	"F10",		LFREG,	10,
   268  	"F11",		LFREG,	11,
   269  	"F12",		LFREG,	12,
   270  	"F13",		LFREG,	13,
   271  	"F14",		LFREG,	14,
   272  	"F15",		LFREG,	15,
   273  	"F16",		LFREG,	16,
   274  	"F17",		LFREG,	17,
   275  	"F18",		LFREG,	18,
   276  	"F19",		LFREG,	19,
   277  	"F20",		LFREG,	20,
   278  	"F21",		LFREG,	21,
   279  	"F22",		LFREG,	22,
   280  	"F23",		LFREG,	23,
   281  	"F24",		LFREG,	24,
   282  	"F25",		LFREG,	25,
   283  	"F26",		LFREG,	26,
   284  	"F27",		LFREG,	27,
   285  	"F28",		LFREG,	28,
   286  	"F29",		LFREG,	29,
   287  	"F30",		LFREG,	30,
   288  	"F31",		LFREG,	31,
   289  
   290  	"CREQV",	LCROP, ACREQV,
   291  	"CRXOR",	LCROP, ACRXOR,
   292  	"CRAND",	LCROP, ACRAND,
   293  	"CROR",		LCROP, ACROR,
   294  	"CRANDN",	LCROP, ACRANDN,
   295  	"CRORN",	LCROP, ACRORN,
   296  	"CRNAND",	LCROP, ACRNAND,
   297  	"CRNOR",	LCROP, ACRNOR,
   298  
   299  	"ADD",		LADDW, AADD,
   300  	"ADDV",		LADDW, AADDV,
   301  	"ADDCC",	LADDW, AADDCC,
   302  	"ADDVCC",	LADDW, AADDVCC,
   303  	"ADDC",		LADDW, AADDC,
   304  	"ADDCV",	LADDW, AADDCV,
   305  	"ADDCCC",	LADDW, AADDCCC,
   306  	"ADDCVCC",	LADDW, AADDCVCC,
   307  	"ADDE",		LLOGW, AADDE,
   308  	"ADDEV",	LLOGW, AADDEV,
   309  	"ADDECC",	LLOGW, AADDECC,
   310  	"ADDEVCC",	LLOGW, AADDEVCC,
   311  
   312  	"ADDME",	LABS, AADDME,
   313  	"ADDMEV",	LABS, AADDMEV,
   314  	"ADDMECC",	LABS, AADDMECC,
   315  	"ADDMEVCC",	LABS, AADDMEVCC,
   316  	"ADDZE",	LABS, AADDZE,
   317  	"ADDZEV",	LABS, AADDZEV,
   318  	"ADDZECC",	LABS, AADDZECC,
   319  	"ADDZEVCC",	LABS, AADDZEVCC,
   320  
   321  	"SUB",		LADDW, ASUB,
   322  	"SUBV",		LADDW, ASUBV,
   323  	"SUBCC",	LADDW, ASUBCC,
   324  	"SUBVCC",	LADDW, ASUBVCC,
   325  	"SUBE",		LLOGW, ASUBE,
   326  	"SUBECC",	LLOGW, ASUBECC,
   327  	"SUBEV",	LLOGW, ASUBEV,
   328  	"SUBEVCC",	LLOGW, ASUBEVCC,
   329  	"SUBC",		LADDW, ASUBC,
   330  	"SUBCCC",	LADDW, ASUBCCC,
   331  	"SUBCV",	LADDW, ASUBCV,
   332  	"SUBCVCC",	LADDW, ASUBCVCC,
   333  
   334  	"SUBME",	LABS, ASUBME,
   335  	"SUBMEV",	LABS, ASUBMEV,
   336  	"SUBMECC",	LABS, ASUBMECC,
   337  	"SUBMEVCC",	LABS, ASUBMEVCC,
   338  	"SUBZE",	LABS, ASUBZE,
   339  	"SUBZEV",	LABS, ASUBZEV,
   340  	"SUBZECC",	LABS, ASUBZECC,
   341  	"SUBZEVCC",	LABS, ASUBZEVCC,
   342  
   343  	"AND",		LADDW, AAND,
   344  	"ANDCC",	LADDW, AANDCC,	/* includes andil & andiu */
   345  	"ANDN",		LLOGW, AANDN,
   346  	"ANDNCC",	LLOGW, AANDNCC,
   347  	"EQV",		LLOGW, AEQV,
   348  	"EQVCC",	LLOGW, AEQVCC,
   349  	"NAND",		LLOGW, ANAND,
   350  	"NANDCC",	LLOGW, ANANDCC,
   351  	"NOR",		LLOGW, ANOR,
   352  	"NORCC",	LLOGW, ANORCC,
   353  	"OR",		LADDW, AOR,	/* includes oril & oriu */
   354  	"ORCC",		LADDW, AORCC,
   355  	"ORN",		LLOGW, AORN,
   356  	"ORNCC",	LLOGW, AORNCC,
   357  	"XOR",		LADDW, AXOR,	/* includes xoril & xoriu */
   358  	"XORCC",	LLOGW, AXORCC,
   359  
   360  	"EXTSB",	LABS,	AEXTSB,
   361  	"EXTSBCC",	LABS,	AEXTSBCC,
   362  	"EXTSH",	LABS, AEXTSH,
   363  	"EXTSHCC",	LABS, AEXTSHCC,
   364  
   365  	"CNTLZW",	LABS, ACNTLZW,
   366  	"CNTLZWCC",	LABS, ACNTLZWCC,
   367  
   368  	"RLWMI",	LRLWM, ARLWMI,
   369  	"RLWMICC",	LRLWM, ARLWMICC,
   370  	"RLWNM",	LRLWM, ARLWNM,
   371  	"RLWNMCC", LRLWM, ARLWNMCC,
   372  
   373  	"SLW",		LSHW, ASLW,
   374  	"SLWCC",	LSHW, ASLWCC,
   375  	"SRW",		LSHW, ASRW,
   376  	"SRWCC",	LSHW, ASRWCC,
   377  	"SRAW",		LSHW, ASRAW,
   378  	"SRAWCC",	LSHW, ASRAWCC,
   379  
   380  	"BR",		LBRA, ABR,
   381  	"BC",		LBRA, ABC,
   382  	"BCL",		LBRA, ABC,
   383  	"BL",		LBRA, ABL,
   384  	"BEQ",		LBRA, ABEQ,
   385  	"BNE",		LBRA, ABNE,
   386  	"BGT",		LBRA, ABGT,
   387  	"BGE",		LBRA, ABGE,
   388  	"BLT",		LBRA, ABLT,
   389  	"BLE",		LBRA, ABLE,
   390  	"BVC",		LBRA, ABVC,
   391  	"BVS",		LBRA, ABVS,
   392  
   393  	"CMP",		LCMP, ACMP,
   394  	"CMPU",		LCMP, ACMPU,
   395  	"CMPW",		LCMP, ACMPW,
   396  	"CMPWU",	LCMP, ACMPWU,
   397  
   398  	"DIVW",		LLOGW, ADIVW,
   399  	"DIVWV",	LLOGW, ADIVWV,
   400  	"DIVWCC",	LLOGW, ADIVWCC,
   401  	"DIVWVCC",	LLOGW, ADIVWVCC,
   402  	"DIVWU",	LLOGW, ADIVWU,
   403  	"DIVWUV",	LLOGW, ADIVWUV,
   404  	"DIVWUCC",	LLOGW, ADIVWUCC,
   405  	"DIVWUVCC",	LLOGW, ADIVWUVCC,
   406  
   407  	"FABS",		LFCONV,	AFABS,
   408  	"FABSCC",	LFCONV,	AFABSCC,
   409  	"FNEG",		LFCONV,	AFNEG,
   410  	"FNEGCC",	LFCONV,	AFNEGCC,
   411  	"FNABS",	LFCONV,	AFNABS,
   412  	"FNABSCC",	LFCONV,	AFNABSCC,
   413  
   414  	"FADD",		LFADD,	AFADD,
   415  	"FADDCC",	LFADD,	AFADDCC,
   416  	"FSUB",		LFADD,  AFSUB,
   417  	"FSUBCC",	LFADD,	AFSUBCC,
   418  	"FMUL",		LFADD,	AFMUL,
   419  	"FMULCC",	LFADD,	AFMULCC,
   420  	"FDIV",		LFADD,	AFDIV,
   421  	"FDIVCC",	LFADD,	AFDIVCC,
   422  	"FRSP",		LFCONV,	AFRSP,
   423  	"FRSPCC",	LFCONV,	AFRSPCC,
   424  	"FCTIW",	LFCONV,	AFCTIW,
   425  	"FCTIWCC",	LFCONV,	AFCTIWCC,
   426  	"FCTIWZ",	LFCONV,	AFCTIWZ,
   427  	"FCTIWZCC",	LFCONV,	AFCTIWZCC,
   428  
   429  	"FMADD",	LFMA, AFMADD,
   430  	"FMADDCC",	LFMA, AFMADDCC,
   431  	"FMSUB",	LFMA, AFMSUB,
   432  	"FMSUBCC",	LFMA, AFMSUBCC,
   433  	"FNMADD",	LFMA, AFNMADD,
   434  	"FNMADDCC",	LFMA, AFNMADDCC,
   435  	"FNMSUB",	LFMA, AFNMSUB,
   436  	"FNMSUBCC",	LFMA, AFNMSUBCC,
   437  	"FMADDS",	LFMA, AFMADDS,
   438  	"FMADDSCC",	LFMA, AFMADDSCC,
   439  	"FMSUBS",	LFMA, AFMSUBS,
   440  	"FMSUBSCC",	LFMA, AFMSUBSCC,
   441  	"FNMADDS",	LFMA, AFNMADDS,
   442  	"FNMADDSCC",	LFMA, AFNMADDSCC,
   443  	"FNMSUBS",	LFMA, AFNMSUBS,
   444  	"FNMSUBSCC",	LFMA, AFNMSUBSCC,
   445  
   446  	"FCMPU",	LFCMP, AFCMPU,
   447  	"FCMPO",	LFCMP, AFCMPO,
   448  	"MTFSB0",	LMTFSB, AMTFSB0,
   449  	"MTFSB1",	LMTFSB,	AMTFSB1,
   450  
   451  	"FMOVD",	LFMOV, AFMOVD,
   452  	"FMOVS",	LFMOV, AFMOVS,
   453  	"FMOVDCC",	LFCONV,	AFMOVDCC,	/* fmr. */
   454  
   455  	"GLOBL",	LTEXT, AGLOBL,
   456  
   457  	"MOVB",		LMOVB, AMOVB,
   458  	"MOVBZ",	LMOVB, AMOVBZ,
   459  	"MOVBU",	LMOVB, AMOVBU,
   460  	"MOVBZU", LMOVB, AMOVBZU,
   461  	"MOVH",		LMOVB, AMOVH,
   462  	"MOVHZ",	LMOVB, AMOVHZ,
   463  	"MOVHU",	LMOVB, AMOVHU,
   464  	"MOVHZU", LMOVB, AMOVHZU,
   465  	"MOVHBR", 	LXMV, AMOVHBR,
   466  	"MOVWBR",	LXMV, AMOVWBR,
   467  	"MOVW",		LMOVW, AMOVW,
   468  	"MOVWU",	LMOVW, AMOVWU,
   469  	"MOVMW",	LMOVMW, AMOVMW,
   470  	"MOVFL",	LMOVW,	AMOVFL,
   471  
   472  	"MULLW",	LADDW, AMULLW,		/* includes multiply immediate 10-139 */
   473  	"MULLWV",	LLOGW, AMULLWV,
   474  	"MULLWCC",	LLOGW, AMULLWCC,
   475  	"MULLWVCC",	LLOGW, AMULLWVCC,
   476  
   477  	"MULHW",	LLOGW, AMULHW,
   478  	"MULHWCC",	LLOGW, AMULHWCC,
   479  	"MULHWU",	LLOGW, AMULHWU,
   480  	"MULHWUCC",	LLOGW, AMULHWUCC,
   481  
   482  	"NEG",		LABS, ANEG,
   483  	"NEGV",		LABS, ANEGV,
   484  	"NEGCC",	LABS, ANEGCC,
   485  	"NEGVCC",	LABS, ANEGVCC,
   486  
   487  	"NOP",		LNOP, ANOP,	/* ori 0,0,0 */
   488  	"SYSCALL",	LNOP, ASYSCALL,
   489  	"UNDEF",	LNOP, AUNDEF,
   490  
   491  	"RET",		LRETRN, ARETURN,
   492  	"RETURN",	LRETRN, ARETURN,
   493  	"RFI",		LRETRN,	ARFI,
   494  	"RFCI",		LRETRN,	ARFCI,
   495  
   496  	"DATA",		LDATA, ADATA,
   497  	"END",		LEND, AEND,
   498  	"TEXT",		LTEXT, ATEXT,
   499  
   500  	/* 64-bit instructions */
   501  	"CNTLZD",	LABS,	ACNTLZD,
   502  	"CNTLZDCC",	LABS,	ACNTLZDCC,
   503  	"DIVD",	LLOGW,	ADIVD,
   504  	"DIVDCC",	LLOGW,	ADIVDCC,
   505  	"DIVDVCC",	LLOGW,	ADIVDVCC,
   506  	"DIVDV",	LLOGW,	ADIVDV,
   507  	"DIVDU",	LLOGW,	ADIVDU,
   508  	"DIVDUCC",	LLOGW,	ADIVDUCC,
   509  	"DIVDUVCC",	LLOGW,	ADIVDUVCC,
   510  	"DIVDUV",	LLOGW,	ADIVDUV,
   511  	"EXTSW",	LABS, AEXTSW,
   512  	"EXTSWCC",	LABS, AEXTSWCC,
   513  	"FCTID",	LFCONV,	AFCTID,
   514  	"FCTIDCC",	LFCONV,	AFCTIDCC,
   515  	"FCTIDZ",	LFCONV,	AFCTIDZ,
   516  	"FCTIDZCC",	LFCONV,	AFCTIDZCC,
   517  	"FCFID",	LFCONV,	AFCFID,
   518  	"FCFIDCC",	LFCONV,	AFCFIDCC,
   519  	"LDAR", LXLD, ALDAR,
   520  	"MOVD",	LMOVW,	AMOVD,
   521  	"MOVDU",	LMOVW,	AMOVDU,
   522  	"MOVWZ",	LMOVW,	AMOVWZ,
   523  	"MOVWZU",	LMOVW,	AMOVWZU,
   524  	"MULHD",	LLOGW,	AMULHD,
   525  	"MULHDCC",	LLOGW,	AMULHDCC,
   526  	"MULHDU",	LLOGW,	AMULHDU,
   527  	"MULHDUCC",	LLOGW,	AMULHDUCC,
   528  	"MULLD",	LADDW,	AMULLD,	/* includes multiply immediate? */
   529  	"MULLDCC",	LLOGW,	AMULLDCC,
   530  	"MULLDVCC",	LLOGW,	AMULLDVCC,
   531  	"MULLDV",	LLOGW,	AMULLDV,
   532  	"RFID",	LRETRN,	ARFID,
   533  	"HRFID", LRETRN, AHRFID,
   534  	"RLDMI",	LRLWM,	ARLDMI,
   535  	"RLDMICC",	LRLWM,	ARLDMICC,
   536  	"RLDC",	LRLWM,	ARLDC,
   537  	"RLDCCC",	LRLWM,	ARLDCCC,
   538  	"RLDCR",	LRLWM,	ARLDCR,
   539  	"RLDCRCC",	LRLWM,	ARLDCRCC,
   540  	"RLDCL",	LRLWM,	ARLDCL,
   541  	"RLDCLCC",	LRLWM,	ARLDCLCC,
   542  	"SLBIA",	LNOP,	ASLBIA,
   543  	"SLBIE",	LNOP,	ASLBIE,
   544  	"SLBMFEE",	LABS,	ASLBMFEE,
   545  	"SLBMFEV",	LABS,	ASLBMFEV,
   546  	"SLBMTE",	LABS,	ASLBMTE,
   547  	"SLD",	LSHW,	ASLD,
   548  	"SLDCC",	LSHW,	ASLDCC,
   549  	"SRD",	LSHW,	ASRD,
   550  	"SRAD",	LSHW,	ASRAD,
   551  	"SRADCC",	LSHW,	ASRADCC,
   552  	"SRDCC",	LSHW,	ASRDCC,
   553  	"STDCCC",	LXST,	ASTDCCC,
   554  	"TD",	LADDW,	ATD,
   555  
   556  	/* pseudo instructions */
   557  	"REM",	LLOGW,	AREM,
   558  	"REMCC",	LLOGW,	AREMCC,
   559  	"REMV",	LLOGW,	AREMV,
   560  	"REMVCC",	LLOGW,	AREMVCC,
   561  	"REMU",	LLOGW,	AREMU,
   562  	"REMUCC",	LLOGW,	AREMUCC,
   563  	"REMUV",	LLOGW,	AREMUV,
   564  	"REMUVCC",	LLOGW,	AREMUVCC,
   565  	"REMD",	LLOGW,	AREMD,
   566  	"REMDCC",	LLOGW,	AREMDCC,
   567  	"REMDV",	LLOGW,	AREMDV,
   568  	"REMDVCC",	LLOGW,	AREMDVCC,
   569  	"REMDU",	LLOGW,	AREMDU,
   570  	"REMDUCC",	LLOGW,	AREMDUCC,
   571  	"REMDUV",	LLOGW,	AREMDUV,
   572  	"REMDUVCC",	LLOGW,	AREMDUVCC,
   573  
   574  /* special instructions */
   575  	"DCBF",		LXOP,	ADCBF,
   576  	"DCBI",		LXOP,	ADCBI,
   577  	"DCBST",	LXOP,	ADCBST,
   578  	"DCBT",		LXOP,	ADCBT,
   579  	"DCBTST",	LXOP,	ADCBTST,
   580  	"DCBZ",		LXOP,	ADCBZ,
   581  	"ICBI",		LXOP,	AICBI,
   582  
   583  	"ECIWX",	LXLD,	AECIWX,
   584  	"ECOWX",	LXST,	AECOWX,
   585  	"LWAR", LXLD, ALWAR,
   586  	"LWAR", LXLD, ALWAR,
   587  	"STWCCC", LXST, ASTWCCC,
   588  	"EIEIO",	LRETRN,	AEIEIO,
   589  	"TLBIE",	LNOP,	ATLBIE,
   590  	"TLBIEL",	LNOP,	ATLBIEL,
   591  	"LSW",	LXLD, ALSW,
   592  	"STSW",	LXST, ASTSW,
   593  	
   594  	"ISYNC",	LRETRN, AISYNC,
   595  	"SYNC",		LRETRN, ASYNC,
   596  	"TLBSYNC",	LRETRN,	ATLBSYNC,
   597  	"PTESYNC",	LRETRN,	APTESYNC,
   598  /*	"TW",		LADDW,	ATW,*/
   599  
   600  	"WORD",		LWORD, AWORD,
   601  	"DWORD",	LWORD, ADWORD,
   602  	"SCHED",	LSCHED, 0,
   603  	"NOSCHED",	LSCHED,	0x80,
   604  
   605  	"PCDATA",	LPCDAT,	APCDATA,
   606  	"FUNCDATA",	LFUNCDAT,	AFUNCDATA,
   607  
   608  	0
   609  };
   610  
   611  void
   612  cinit(void)
   613  {
   614  	Sym *s;
   615  	int i;
   616  
   617  	nullgen.type = D_NONE;
   618  	nullgen.name = D_NONE;
   619  	nullgen.reg = NREG;
   620  	nullgen.scale = NREG; // replaced Gen.xreg with Prog.scale
   621  
   622  	nerrors = 0;
   623  	iostack = I;
   624  	iofree = I;
   625  	peekc = IGN;
   626  	nhunk = 0;
   627  	for(i=0; i<NHASH; i++)
   628  		hash[i] = S;
   629  	for(i=0; itab[i].name; i++) {
   630  		s = slookup(itab[i].name);
   631  		s->type = itab[i].type;
   632  		s->value = itab[i].value;
   633  	}
   634  }
   635  
   636  void
   637  syminit(Sym *s)
   638  {
   639  
   640  	s->type = LNAME;
   641  	s->value = 0;
   642  }
   643  
   644  void
   645  cclean(void)
   646  {
   647  
   648  	outcode(AEND, &nullgen, NREG, &nullgen);
   649  }
   650  
   651  static Prog *lastpc;
   652  
   653  void
   654  outcode(int a, Addr *g1, int reg, Addr *g2)
   655  {
   656  	Prog *p;
   657  	Plist *pl;
   658  
   659  	if(pass == 1)
   660  		goto out;
   661  
   662  	if(g1->scale != NREG) {
   663  		if(reg != NREG || g2->scale != NREG)
   664  			yyerror("bad addressing modes");
   665  		reg = g1->scale;
   666  	} else
   667  	if(g2->scale != NREG) {
   668  		if(reg != NREG)
   669  			yyerror("bad addressing modes");
   670  		reg = g2->scale;
   671  	}
   672  
   673  	p = ctxt->arch->prg();
   674  	p->as = a;
   675  	p->lineno = lineno;
   676  	if(nosched)
   677  		p->mark |= NOSCHED;
   678  	p->from = *g1;
   679  	p->reg = reg;
   680  	p->to = *g2;
   681  	p->pc = pc;
   682  
   683  	if(lastpc == nil) {
   684  		pl = linknewplist(ctxt);
   685  		pl->firstpc = p;
   686  	} else
   687  		lastpc->link = p;
   688  	lastpc = p;
   689  out:
   690  	if(a != AGLOBL && a != ADATA)
   691  		pc++;
   692  }
   693  
   694  void
   695  outgcode(int a, Addr *g1, int reg, Addr *g2, Addr *g3)
   696  {
   697  	Prog *p;
   698  	Plist *pl;
   699  
   700  	if(pass == 1)
   701  		goto out;
   702  
   703  	p = ctxt->arch->prg();
   704  	p->as = a;
   705  	p->lineno = lineno;
   706  	if(nosched)
   707  		p->mark |= NOSCHED;
   708  	p->from = *g1;
   709  	p->reg = reg;
   710  	p->from3 = *g2;
   711  	p->to = *g3;
   712  	p->pc = pc;
   713  
   714  	if(lastpc == nil) {
   715  		pl = linknewplist(ctxt);
   716  		pl->firstpc = p;
   717  	} else
   718  		lastpc->link = p;
   719  	lastpc = p;
   720  out:
   721  	if(a != AGLOBL && a != ADATA)
   722  		pc++;
   723  }
   724  
   725  #include "../cc/lexbody"
   726  #include "../cc/macbody"