Charles.Forsyth20060303644188019 years agoHistory
689 lines · 11.0 KB · C
RawDownload
#define	EXTERN#include "a.h"#include "y.tab.h"#include <ctype.h> voidmain(int argc, char *argv[]){	char *p;	int nout, nproc, status, i, c; 	thechar = '5';	thestring = "arm";	memset(debug, 0, sizeof(debug));	cinit();	outfile = 0;	include[ninclude++] = ".";	ARGBEGIN {	default:		c = ARGC();		if(c >= 0 || c < sizeof(debug))			debug[c] = 1;		break; 	case 'o':		outfile = ARGF();		break; 	case 'D':		p = ARGF();		if(p)			Dlist[nDlist++] = p;		break; 	case 'I':		p = ARGF();		setinclude(p);		break;	case 't':		thechar = 't';		thestring = "thumb";		break;	} ARGEND	if(*argv == 0) {		print("usage: %ca [-options] file.s\n", thechar);		errorexit();	}	if(argc > 1 && systemtype(Windows)){		print("can't assemble multiple files on windows\n");		errorexit();	}	if(argc > 1 && !systemtype(Windows)) {		nproc = 1;		if(p = getenv("NPROC"))			nproc = atol(p);	/* */		c = 0;		nout = 0;		for(;;) {			while(nout < nproc && argc > 0) {				i = myfork();				if(i < 0) {					i = mywait(&status);					if(i < 0)						errorexit();					if(status)						c++;					nout--;					continue;				}				if(i == 0) {					print("%s:\n", *argv);					if(assemble(*argv))						errorexit();					exits(0);				}				nout++;				argc--;				argv++;			}			i = mywait(&status);			if(i < 0) {				if(c)					errorexit();				exits(0);			}			if(status)				c++;			nout--;		}	}	if(assemble(argv[0]))		errorexit();	exits(0);} intassemble(char *file){	char ofile[100], incfile[20], *p;	int i, of; 	strcpy(ofile, file);	p = utfrrune(ofile, pathchar());	if(p) {		include[0] = ofile;		*p++ = 0;	} else		p = ofile;	if(outfile == 0) {		outfile = p;		if(outfile){			p = utfrrune(outfile, '.');			if(p)				if(p[1] == 's' && p[2] == 0)					p[0] = 0;			p = utfrune(outfile, 0);			p[0] = '.';			p[1] = thechar;			p[2] = 0;		} else			outfile = "/dev/null";	}	p = getenv("INCLUDE");	if(p) {		setinclude(p);	} else {		if(systemtype(Plan9)) {			sprint(incfile,"/%s/include", thestring);			setinclude(strdup(incfile));		}	} 	of = mycreat(outfile, 0664);	if(of < 0) {		yyerror("%ca: cannot create %s", thechar, outfile);		errorexit();	}	Binit(&obuf, of, OWRITE); 	pass = 1;	pinit(file);	for(i=0; i<nDlist; i++)		dodefine(Dlist[i]);	yyparse();	if(nerrors) {		cclean();		return nerrors;	} 	pass = 2;	outhist();	pinit(file);	for(i=0; i<nDlist; i++)		dodefine(Dlist[i]);	yyparse();	cclean();	return nerrors;} struct{	char	*name;	ushort	type;	ushort	value;} itab[] ={	"SP",		LSP,	D_AUTO,	"SB",		LSB,	D_EXTERN,	"FP",		LFP,	D_PARAM,	"PC",		LPC,	D_BRANCH, 	"R",		LR,	0,	"R0",		LREG,	0,	"R1",		LREG,	1,	"R2",		LREG,	2,	"R3",		LREG,	3,	"R4",		LREG,	4,	"R5",		LREG,	5,	"R6",		LREG,	6,	"R7",		LREG,	7,	"R8",		LREG,	8,	"R9",		LREG,	9,	"R10",		LREG,	10,	"R11",		LREG,	11,	"R12",		LREG,	12,	"R13",		LREG,	13,	"R14",		LREG,	14,	"R15",		LREG,	15, 	"F",		LF,	0, 	"F0",		LFREG,	0,	"F1",		LFREG,	1,	"F2",		LFREG,	2,	"F3",		LFREG,	3,	"F4",		LFREG,	4,	"F5",		LFREG,	5,	"F6",		LFREG,	6,	"F7",		LFREG,	7,	"F8",		LFREG,	8,	"F9",		LFREG,	9,	"F10",		LFREG,	10,	"F11",		LFREG,	11,	"F12",		LFREG,	12,	"F13",		LFREG,	13,	"F14",		LFREG,	14,	"F15",		LFREG,	15, 	"C",		LC,	0, 	"C0",		LCREG,	0,	"C1",		LCREG,	1,	"C2",		LCREG,	2,	"C3",		LCREG,	3,	"C4",		LCREG,	4,	"C5",		LCREG,	5,	"C6",		LCREG,	6,	"C7",		LCREG,	7,	"C8",		LCREG,	8,	"C9",		LCREG,	9,	"C10",		LCREG,	10,	"C11",		LCREG,	11,	"C12",		LCREG,	12,	"C13",		LCREG,	13,	"C14",		LCREG,	14,	"C15",		LCREG,	15, 	"CPSR",		LPSR,	0,	"SPSR",		LPSR,	1, 	"FPSR",		LFCR,	0,	"FPCR",		LFCR,	1, 	".EQ",		LCOND,	0,	".NE",		LCOND,	1,	".CS",		LCOND,	2,	".HS",		LCOND,	2,	".CC",		LCOND,	3,	".LO",		LCOND,	3,	".MI",		LCOND,	4,	".PL",		LCOND,	5,	".VS",		LCOND,	6,	".VC",		LCOND,	7,	".HI",		LCOND,	8,	".LS",		LCOND,	9,	".GE",		LCOND,	10,	".LT",		LCOND,	11,	".GT",		LCOND,	12,	".LE",		LCOND,	13,	".AL",		LCOND,	Always, 	".U",		LS,	C_UBIT,	".S",		LS,	C_SBIT,	".W",		LS,	C_WBIT,	".P",		LS,	C_PBIT,	".PW",		LS,	C_WBIT|C_PBIT,	".WP",		LS,	C_WBIT|C_PBIT, 	".F",		LS,	C_FBIT, 	".IBW",		LS,	C_WBIT|C_PBIT|C_UBIT,	".IAW",		LS,	C_WBIT|C_UBIT,	".DBW",		LS,	C_WBIT|C_PBIT,	".DAW",		LS,	C_WBIT,	".IB",		LS,	C_PBIT|C_UBIT,	".IA",		LS,	C_UBIT,	".DB",		LS,	C_PBIT,	".DA",		LS,	0, 	"@",		LAT,	0, 	"AND",		LTYPE1,	AAND,	"EOR",		LTYPE1,	AEOR,	"SUB",		LTYPE1,	ASUB,	"RSB",		LTYPE1,	ARSB,	"ADD",		LTYPE1,	AADD,	"ADC",		LTYPE1,	AADC,	"SBC",		LTYPE1,	ASBC,	"RSC",		LTYPE1,	ARSC,	"ORR",		LTYPE1,	AORR,	"BIC",		LTYPE1,	ABIC, 	"SLL",		LTYPE1,	ASLL,	"SRL",		LTYPE1,	ASRL,	"SRA",		LTYPE1,	ASRA, 	"MUL",		LTYPE1, AMUL,	"MULA",		LTYPEN, AMULA,	"DIV",		LTYPE1,	ADIV,	"MOD",		LTYPE1,	AMOD, 	"MULL",		LTYPEM, AMULL,	"MULAL",	LTYPEM, AMULAL,	"MULLU",	LTYPEM, AMULLU,	"MULALU",	LTYPEM, AMULALU, 	"MVN",		LTYPE2, AMVN,	/* op2 ignored */ 	"MOVB",		LTYPE3, AMOVB,	"MOVBU",	LTYPE3, AMOVBU,	"MOVH",		LTYPE3, AMOVH,	"MOVHU",	LTYPE3, AMOVHU,	"MOVW",		LTYPE3, AMOVW, 	"MOVD",		LTYPE3, AMOVD,	"MOVDF",		LTYPE3, AMOVDF,	"MOVDW",	LTYPE3, AMOVDW,	"MOVF",		LTYPE3, AMOVF,	"MOVFD",		LTYPE3, AMOVFD,	"MOVFW",		LTYPE3, AMOVFW,	"MOVWD",	LTYPE3, AMOVWD,	"MOVWF",		LTYPE3, AMOVWF, /*	"ABSF",		LTYPEI, AABSF,	"ABSD",		LTYPEI, AABSD,	"NEGF",		LTYPEI, ANEGF,	"NEGD",		LTYPEI, ANEGD,	"SQTF",		LTYPEI,	ASQTF,	"SQTD",		LTYPEI,	ASQTD,	"RNDF",		LTYPEI,	ARNDF,	"RNDD",		LTYPEI,	ARNDD,	"URDF",		LTYPEI,	AURDF,	"URDD",		LTYPEI,	AURDD,	"NRMF",		LTYPEI,	ANRMF,	"NRMD",		LTYPEI,	ANRMD,*/ 	"CMPF",		LTYPEL, ACMPF,	"CMPD",		LTYPEL, ACMPD,	"ADDF",		LTYPEK,	AADDF,	"ADDD",		LTYPEK,	AADDD,	"SUBF",		LTYPEK,	ASUBF,	"SUBD",		LTYPEK,	ASUBD,	"MULF",		LTYPEK,	AMULF,	"MULD",		LTYPEK,	AMULD,	"DIVF",		LTYPEK,	ADIVF,	"DIVD",		LTYPEK,	ADIVD, 	"B",		LTYPE4, AB,	"BL",		LTYPE4, ABL,	"BX",		LTYPEBX,	ABX, 	"BEQ",		LTYPE5,	ABEQ,	"BNE",		LTYPE5,	ABNE,	"BCS",		LTYPE5,	ABCS,	"BHS",		LTYPE5,	ABHS,	"BCC",		LTYPE5,	ABCC,	"BLO",		LTYPE5,	ABLO,	"BMI",		LTYPE5,	ABMI,	"BPL",		LTYPE5,	ABPL,	"BVS",		LTYPE5,	ABVS,	"BVC",		LTYPE5,	ABVC,	"BHI",		LTYPE5,	ABHI,	"BLS",		LTYPE5,	ABLS,	"BGE",		LTYPE5,	ABGE,	"BLT",		LTYPE5,	ABLT,	"BGT",		LTYPE5,	ABGT,	"BLE",		LTYPE5,	ABLE,	"BCASE",	LTYPE5,	ABCASE, 	"SWI",		LTYPE6, ASWI, 	"CMP",		LTYPE7,	ACMP,	"TST",		LTYPE7,	ATST,	"TEQ",		LTYPE7,	ATEQ,	"CMN",		LTYPE7,	ACMN, 	"MOVM",		LTYPE8, AMOVM, 	"SWPBU",	LTYPE9, ASWPBU,	"SWPW",		LTYPE9, ASWPW, 	"RET",		LTYPEA, ARET,	"RFE",		LTYPEA, ARFE, 	"TEXT",		LTYPEB, ATEXT,	"GLOBL",	LTYPEB, AGLOBL,	"DATA",		LTYPEC, ADATA,	"CASE",		LTYPED, ACASE,	"END",		LTYPEE, AEND,	"WORD",		LTYPEH, AWORD,	"NOP",		LTYPEI, ANOP, 	"MCR",		LTYPEJ, 0,	"MRC",		LTYPEJ, 1,	0}; voidcinit(void){	Sym *s;	int i; 	nullgen.sym = S;	nullgen.offset = 0;	nullgen.type = D_NONE;	nullgen.name = D_NONE;	nullgen.reg = NREG;	if(FPCHIP)		nullgen.dval = 0;	for(i=0; i<sizeof(nullgen.sval); i++)		nullgen.sval[i] = 0; 	nerrors = 0;	iostack = I;	iofree = I;	peekc = IGN;	nhunk = 0;	for(i=0; i<NHASH; i++)		hash[i] = S;	for(i=0; itab[i].name; i++) {		s = slookup(itab[i].name);		s->type = itab[i].type;		s->value = itab[i].value;	} 	pathname = allocn(pathname, 0, 100);	if(mygetwd(pathname, 99) == 0) {		pathname = allocn(pathname, 100, 900);		if(mygetwd(pathname, 999) == 0)			strcpy(pathname, "/???");	}} voidsyminit(Sym *s){ 	s->type = LNAME;	s->value = 0;} intisreg(Gen *g){ 	USED(g);	return 1;} voidcclean(void){ 	outcode(AEND, Always, &nullgen, NREG, &nullgen);	Bflush(&obuf);} voidzname(char *n, int t, int s){ 	Bputc(&obuf, ANAME);	Bputc(&obuf, t);	/* type */	Bputc(&obuf, s);	/* sym */	while(*n) {		Bputc(&obuf, *n);		n++;	}	Bputc(&obuf, 0);} voidzaddr(Gen *a, int s){	long l;	int i;	char *n;	Ieee e; 	Bputc(&obuf, a->type);	Bputc(&obuf, a->reg);	Bputc(&obuf, s);	Bputc(&obuf, a->name);	switch(a->type) {	default:		print("unknown type %d\n", a->type);		exits("arg"); 	case D_NONE:	case D_REG:	case D_FREG:	case D_PSR:	case D_FPCR:		break; 	case D_REGREG:		Bputc(&obuf, a->offset);		break; 	case D_OREG:	case D_CONST:	case D_BRANCH:	case D_SHIFT:		l = a->offset;		Bputc(&obuf, l);		Bputc(&obuf, l>>8);		Bputc(&obuf, l>>16);

Lines 1–500 of 689.