⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m68k.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
			n = 3;			ret = (PSR);		}#endif		break;	case 's':#ifdef m68851		if (c2 == 'c' && c3 == 'c') {			n = 3;			ret = (SCC);		} else if (c2 == 'r' && c3 == 'p') {			n = 3;			ret = (SRP);		} else#endif		if(c2=='r') {			n=2;			ret = SR;		} else if(c2=='p') {			n=2;			ret = ADDR+7;		} else if(c2=='f' && c3=='c') {			n=3;			ret = SFC;		}		break;#ifdef m68851	case 't':		if(c2 == 'c') {			n=2;			ret=TC;		}		break;#endif	case 'u':		if(c2=='s' && c3=='p') {			n=3;			ret = USP;		}		break;	case 'v':#ifdef m68851		if (c2 == 'a' && c3 == 'l') {			n = 3;			ret = (VAL);		} else#endif		if(c2=='b' && c3=='r') {			n=3;			ret = VBR;		}		break;	case 'z':		if(c2=='p' && c3=='c') {			n=3;			ret = ZPC;		}		break;	default:		break;	}	if(n) {#ifdef REGISTER_PREFIX		n++;#endif		if(isalnum(ccp[0][n]) || ccp[0][n]=='_')			ret=FAIL;		else			ccp[0]+=n;	} else		ret = FAIL;	return ret;}#define SKIP_WHITE()	{ str++; if(*str==' ') str++;}intm68k_ip_op(str,opP)char *str;register struct m68k_op *opP;{	char	*strend;	long	i;	char	*parse_index();	if(*str==' ')		str++;		/* Find the end of the string */	if(!*str) {		/* Out of gas */		opP->error="Missing operand";		return FAIL;	}	for(strend=str;*strend;strend++)		;	--strend;		/* Guess what:  A constant.  Shar and enjoy */	if(*str=='#') {		str++;		opP->con1=add_exp(str,strend);		opP->mode=IMMED;		return OK;	}	i=m68k_reg_parse(&str);	if((i==FAIL || *str!='\0') && *str!='@') {		char *stmp;		char *index();		if(i!=FAIL && (*str=='/' || *str=='-')) {			opP->mode=REGLST;			return get_regs(i,str,opP);		}		if(stmp=index(str,'@')) {			opP->con1=add_exp(str,stmp-1);			if(stmp==strend) {				opP->mode=AINDX;				return OK;			}			stmp++;			if(*stmp++!='(' || *strend--!=')') {				opP->error="Malformed operand";				return FAIL;			}			i=try_index(&stmp,opP);			opP->con2=add_exp(stmp,strend);			if(i==FAIL) opP->mode=AMIND;			else opP->mode=APODX;			return OK;		}		opP->mode=ABSL;		opP->con1=add_exp(str,strend);		return OK;	}	opP->reg=i;	if(*str=='\0') {		if(i>=DATA+0 && i<=DATA+7)			opP->mode=DREG;		else if(i>=ADDR+0 && i<=ADDR+7)			opP->mode=AREG;		else			opP->mode=MSCR;		return OK;	}	if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) {	/* Can't indirect off non address regs */		opP->error="Invalid indirect register";		return FAIL;	}	if(*str!='@')		abort();	str++;	switch(*str) {	case '\0':		opP->mode=AINDR;		return OK;	case '-':		opP->mode=ADEC;		return OK;	case '+':		opP->mode=AINC;		return OK;	case '(':		str++;		break;	default:		opP->error="Junk after indirect";		return FAIL;	}		/* Some kind of indexing involved.  Lets find out how bad it is */	i=try_index(&str,opP);		/* Didn't start with an index reg, maybe its offset or offset,reg */	if(i==FAIL) {		char *beg_str;		beg_str=str;		for(i=1;i;) {			switch(*str++) {			case '\0':				opP->error="Missing )";				return FAIL;			case ',': i=0; break;			case '(': i++; break;			case ')': --i; break;			}		}		/* if(str[-3]==':') {			int siz;			switch(str[-2]) {			case 'b':			case 'B':				siz=1;				break;			case 'w':			case 'W':				siz=2;				break;			case 'l':			case 'L':				siz=3;				break;			default:				opP->error="Specified size isn't :w or :l";				return FAIL;			}			opP->con1=add_exp(beg_str,str-4);			opP->con1->e_siz=siz;		} else */			opP->con1=add_exp(beg_str,str-2);			/* Should be offset,reg */		if(str[-1]==',') {			i=try_index(&str,opP);			if(i==FAIL) {				opP->error="Malformed index reg";				return FAIL;			}		}	}		/* We've now got offset)   offset,reg)   or    reg) */	if(*str=='\0') {		/* Th-the-thats all folks */		if(opP->reg==FAIL) opP->mode=AINDX;	/* Other form of indirect */		else if(opP->ireg==FAIL) opP->mode=AOFF;		else opP->mode=AINDX;		return OK;	}		/* Next thing had better be another @ */	if(*str!='@' || str[1]!='(') {		opP->error="junk after indirect";		return FAIL;	}	str+=2;	if(opP->ireg!=FAIL) {		opP->mode=APRDX;		i=try_index(&str,opP);		if(i!=FAIL) {			opP->error="Two index registers!  not allowed!";			return FAIL;		}	} else		i=try_index(&str,opP);	if(i==FAIL) {		char *beg_str;		beg_str=str;		for(i=1;i;) {			switch(*str++) {			case '\0':				opP->error="Missing )";				return FAIL;			case ',': i=0; break;			case '(': i++; break;			case ')': --i; break;			}		}		opP->con2=add_exp(beg_str,str-2);		if(str[-1]==',') {			if(opP->ireg!=FAIL) {				opP->error="Can't have two index regs";				return FAIL;			}			i=try_index(&str,opP);			if(i==FAIL) {				opP->error="malformed index reg";				return FAIL;			}			opP->mode=APODX;		} else if(opP->ireg!=FAIL)			opP->mode=APRDX;		else			opP->mode=AMIND;	} else		opP->mode=APODX;	if(*str!='\0') {		opP->error="Junk after indirect";		return FAIL;	}	return OK;}inttry_index(s,opP)char **s;struct m68k_op *opP;{	register int	i;	char	*ss;#define SKIP_W()	{ ss++; if(*ss==' ') ss++;}	ss= *s;	/* SKIP_W(); */	i=m68k_reg_parse(&ss);	if(!(i>=DATA+0 && i<=ADDR+7)) {	/* if i is not DATA or ADDR reg */		*s=ss;		return FAIL;	}	opP->ireg=i;	/* SKIP_W(); */	if(*ss==')') {		opP->isiz=0;		opP->imul=1;		SKIP_W();		*s=ss;		return OK;	}	if(*ss!=':') {		opP->error="Missing : in index register";		*s=ss;		return FAIL;	}	SKIP_W();	switch(*ss) {	case 'w':	case 'W':		opP->isiz=2;		break;	case 'l':	case 'L':		opP->isiz=3;		break;	default:		opP->error="Index register size spec not :w or :l";		*s=ss;		return FAIL;	}	SKIP_W();	if(*ss==':') {		SKIP_W();		switch(*ss) {		case '1':		case '2':		case '4':		case '8':			opP->imul= *ss-'0';			break;		default:			opP->error="index multiplier not 1, 2, 4 or 8";			*s=ss;			return FAIL;		}		SKIP_W();	} else opP->imul=1;	if(*ss!=')') {		opP->error="Missing )";		*s=ss;		return FAIL;	}	SKIP_W();	*s=ss;	return OK;}#ifdef TEST1	/* TEST1 tests m68k_ip_op(), which parses operands */main(){	char buf[128];	struct m68k_op thark;	for(;;) {		if(!gets(buf))			break;		bzero(&thark,sizeof(thark));		if(!m68k_ip_op(buf,&thark)) printf("FAIL:");		if(thark.error)			printf("op1 error %s in %s\n",thark.error,buf);		printf("mode %d, reg %d, ",thark.mode,thark.reg);		if(thark.b_const)			printf("Constant: '%.*s',",1+thark.e_const-thark.b_const,thark.b_const);		printf("ireg %d, isiz %d, imul %d ",thark.ireg,thark.isiz,thark.imul);		if(thark.b_iadd)			printf("Iadd: '%.*s'",1+thark.e_iadd-thark.b_iadd,thark.b_iadd);		printf("\n");	}	exit(0);}#endifstatic struct hash_control*   op_hash = NULL;	/* handle of the OPCODE hash table				   NULL means any use before m68_ip_begin()				   will crash *//* *		m 6 8 _ i p ( ) * * This converts a string into a 68k instruction. * The string must be a bare single instruction in sun format * with RMS-style 68020 indirects *  (example:  ) * * It provides some error messages: at most one fatal error message (which * stops the scan) and at most one warning message for each operand. * The 68k instruction is returned in exploded form, since we have no * knowledge of how you parse (or evaluate) your expressions. * We do however strip off and decode addressing modes and operation * mnemonic. * * This function's value is a string. If it is not "" then an internal * logic error was found: read this code to assign meaning to the string. * No argument string should generate such an error string: * it means a bug in our code, not in the user's text. * * You MUST have called m86_ip_begin() once and m86_ip_end() never before using * this function. *//* JF this function no longer returns a useful value.  Sorry */voidm68_ip (instring)char	*instring;{	register char *p;	register struct m68k_op *opP;	register struct m68_incant *opcode;	register char *s;	register int tmpreg,		baseo,		outro,		nextword;	int	siz1,		siz2;	char	c;	int	losing;	int	opsfound;	char	*crack_operand();	LITTLENUM_TYPE words[6];	LITTLENUM_TYPE *wordp;	if (*instring == ' ')		instring++;			/* skip leading whitespace */  /* Scan up to end of operation-code, which MUST end in end-of-string     or exactly 1 space. */	for (p = instring; *p != '\0'; p++)		if (*p == ' ')			break;	if (p == instring) {		the_ins.error = "No operator";		the_ins.opcode[0] = NULL;		/* the_ins.numo=1; */		return;	}  /* p now points to the end of the opcode name, probably whitespace.     make sure the name is null terminated by clobbering the whitespace,     look it up in the hash table, then fix it back. */   	c = *p;	*p = '\0';	opcode = (struct m68_incant *)hash_find (op_hash, instring);	*p = c;	if (opcode == NULL) {		the_ins.error = "Unknown operator";		the_ins.opcode[0] = NULL;		/* the_ins.numo=1; */		return;	}  /* found a legitimate opcode, start matching operands */	for(opP= &the_ins.operands[0];*p;opP++) {		p = crack_operand (p, opP);		if(opP->error) {			the_ins.error=opP->error;			return;		}	}	opsfound=opP- &the_ins.operands[0];	/* This ugly hack is to support the floating pt opcodes in their standard form */	/* Essentially, we fake a first enty of type COP#1 */	if(opcode->m_operands[0]=='I') {		int	n;		for(n=opsfound;n>0;--n)			the_ins.operands[n]=the_ins.operands[n-1];		/* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */		bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0]));		the_ins.operands[0].mode=MSCR;		the_ins.operands[0].reg=COPNUM;		/* COP #1 */		opsfound++;	}		/* We've got the operands.  Find an opcode that'll		   accept them */	for(losing=0;;) {		if(opsfound!=opcode->m_opnum)			losing++;		else for(s=opcode->m_operands,opP= &the_ins.operands[0];*s && !losing;s+=2,opP++) {				/* Warning: this switch is huge! */				/* I've tried to organize the cases into  this order:				   non-alpha first, then alpha by letter.  lower-case goes directly				   before uppercase counterpart. */				/* Code with multiple case ...: gets sorted by the lowest case ...				   it belongs to.  I hope this makes sense. */			switch(*s) {			case '!':				if(opP->mode==MSCR || opP->mode==IMMED || opP->mode==DREG || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)					losing++;				break;			case '#':				if(opP->mode!=IMMED)					losing++;				else {					long t;					t=get_num(opP->con1,80);					if(s[1]=='b' && !isbyte(t))						losing++;					else if(s[1]=='w' && !isword(t))						losing++;				}				break;			case '^':			case 'T':				if(opP->mode!=IMMED)					losing++;				break;			case '$':				if(opP->mode==MSCR || opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)					losing++;				break;			case '%':				if(opP->mode==MSCR || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)					losing++;				break;			case '&':				if(opP->mode==MSCR || opP->mode==DREG || opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)					losing++;				break;			case '*':				if(opP->mode==MSCR || opP->mode==REGLST)					losing++;				break;			case '+':				if(opP->mode!=AINC)					losing++;				break;			case '-':				if(opP->mode!=ADEC)					losing++;				break;			case '/':				if(opP->mode==MSCR || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->mode==REGLST)					losing++;				break;			case ';':				if(opP->mode==MSCR || opP->mode==AREG || opP->mode==REGLST)					losing++;				break;			case '?':				if(opP->mode==MSCR || opP->mode==AREG || opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)					losing++;				break;			case '@':				if(opP->mode==MSCR || opP->mode==AREG ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -