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

📄 m68k.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
 opP->mode==IMMED || opP->mode==REGLST)					losing++;				break;			case '~':		/* For now! (JF FOO is this right?) */				if(opP->mode==MSCR || opP->mode==DREG || opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)					losing++;				break;			case 'A':				if(opP->mode!=AREG)					losing++;				break;			case 'B':	/* FOO */				if(opP->mode!=ABSL)					losing++;				break;			case 'C':				if(opP->mode!=MSCR || opP->reg!=CCR)					losing++;				break;			case 'd':	/* FOO This mode is a KLUDGE!! */				if(opP->mode!=AOFF && (opP->mode!=ABSL || opP->con1->e_beg[0]!='(' || opP->con1->e_end[0]!=')'))					losing++;				break;			case 'D':				if(opP->mode!=DREG)					losing++;				break;			case 'F':				if(opP->mode!=MSCR || opP->reg<(FPREG+0) || opP->reg>(FPREG+7))					losing++;				break;			case 'I':				if(opP->mode!=MSCR || opP->reg<COPNUM || opP->reg>=COPNUM+7)					losing++;				break;			case 'J':				if(opP->mode!=MSCR || opP->reg<USP || opP->reg>MSP)					losing++;				break;			case 'k':				if(opP->mode!=IMMED)					losing++;				break;			case 'l':			case 'L':				if(opP->mode==DREG || opP->mode==AREG || opP->mode==FPREG) {					if(s[1]=='8')						losing++;					else {						opP->mode=REGLST;						opP->reg=1<<(opP->reg-DATA);					}				} else if(opP->mode!=REGLST) {					losing++;				} else if(s[1]=='8' && opP->reg&0x0FFffFF)					losing++;				else if(s[1]=='3' && opP->reg&0x7000000)					losing++;				break;			case 'M':				if(opP->mode!=IMMED)					losing++;				else {					long t;					t=get_num(opP->con1,80);					if(!issbyte(t) || isvar(opP->con1))						losing++;				}				break;			case 'O':				if(opP->mode!=DREG && opP->mode!=IMMED)					losing++;				break;			case 'Q':				if(opP->mode!=IMMED)					losing++;				else {					long t;					t=get_num(opP->con1,80);					if(t<1 || t>8 || isvar(opP->con1))						losing++;				}				break;			case 'R':				if(opP->mode!=DREG && opP->mode!=AREG)					losing++;				break;			case 's':				if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC))					losing++;				break;			case 'S':				if(opP->mode!=MSCR || opP->reg!=SR)					losing++;				break;			case 'U':				if(opP->mode!=MSCR || opP->reg!=USP)					losing++;				break;			/* JF these are out of order.  We could put them			   in order if we were willing to put up with			   bunches of #ifdef m68851s in the code */#ifdef m68851			/* Memory addressing mode used by pflushr */			case '|':				if(opP->mode==MSCR || opP->mode==DREG || opP->mode==AREG || opP->mode==REGLST)					losing++;				break;			case 'f':				if (opP->mode != MSCR || (opP->reg != SFC && opP->reg != DFC))					losing++;				break;			case 'P':				if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL &&				    opP->reg != VAL && opP->reg != SCC && opP->reg != AC))					losing++;				break;			case 'V':				if (opP->reg != VAL)					losing++;				break;			case 'W':				if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP &&				    opP->reg != CRP))					losing++;				break;			case 'X':				if (opP->mode != MSCR ||				    (!(opP->reg >= BAD && opP->reg <= BAD+7) &&				     !(opP->reg >= BAC && opP->reg <= BAC+7)))					losing++;				break;			case 'Y':				if (opP->reg != PSR)					losing++;				break;			case 'Z':				if (opP->reg != PCSR)					losing++;				break;#endif			default:				as_fatal("Internal error:  Operand mode %c unknown",*s);			}		}		if(!losing)			break;		opcode=opcode->m_next;		if(!opcode) {		/* Fell off the end */			the_ins.error="instruction/operands mismatch";			return;		}		losing=0;	}	the_ins.args=opcode->m_operands;	the_ins.numargs=opcode->m_opnum;	the_ins.numo=opcode->m_codenum;	the_ins.opcode[0]=getone(opcode);	the_ins.opcode[1]=gettwo(opcode);	for(s=the_ins.args,opP= &the_ins.operands[0];*s;s+=2,opP++) {			/* This switch is a doozy.			   What the first step; its a big one! */		switch(s[0]) {		case '*':		case '~':		case '%':		case ';':		case '@':		case '!':		case '&':		case '$':		case '?':		case '/':#ifdef m68851		case '|':#endif			switch(opP->mode) {			case IMMED:				tmpreg=0x3c;	/* 7.4 */				if(index("bwl",s[1])) nextword=get_num(opP->con1,80);				else nextword=nextword=get_num(opP->con1,0);				if(isvar(opP->con1))					add_fix(s[1],opP->con1,0);				switch(s[1]) {				case 'b':					if(!isbyte(nextword))						opP->error="operand out of range";					addword(nextword);					baseo=0;					break;				case 'w':					if(!isword(nextword))						opP->error="operand out of range";					addword(nextword);					baseo=0;					break;				case 'l':					addword(nextword>>16);					addword(nextword);					baseo=0;					break;				case 'f':					baseo=2;					outro=8;					break;				case 'F':					baseo=4;					outro=11;					break;				case 'x':					baseo=6;					outro=15;					break;				case 'p':					baseo=6;					outro= -1;					break;				default:					as_fatal("Internal error:  Can't decode %c%c",*s,s[1]);				}				if(!baseo)					break;				/* We gotta put out some float */				if(seg(opP->con1)!=SEG_BIG) {					int_to_gen(nextword);					gen_to_words(words,baseo,(long int)outro);					for(wordp=words;baseo--;wordp++)						addword(*wordp);					break;				}		/* Its BIG */				if(offs(opP->con1)>0) {					as_warn("Bignum assumed to be binary bit-pattern");					if(offs(opP->con1)>baseo) {						as_warn("Bignum too big for %c format; truncated",s[1]);						offs(opP->con1)=baseo;					}					baseo-=offs(opP->con1);					for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp)						addword(*wordp);					while(baseo--)						addword(0);					break;				}				gen_to_words(words,baseo,(long int)outro);				for(wordp=words;baseo--;wordp++)					addword(*wordp);				break;			case DREG:				tmpreg=opP->reg-DATA; /* 0.dreg */				break;			case AREG:				tmpreg=0x08+opP->reg-ADDR; /* 1.areg */				break;			case AINDR:				tmpreg=0x10+opP->reg-ADDR; /* 2.areg */				break;			case ADEC:				tmpreg=0x20+opP->reg-ADDR; /* 4.areg */				break;			case AINC:				tmpreg=0x18+opP->reg-ADDR; /* 3.areg */				break;			case AOFF:				nextword=get_num(opP->con1,80);				/* Force into index mode.  Hope this works */				/* We do the first bit for 32-bit displacements,				   and the second bit for 16 bit ones.  It is				   possible that we should make the default be				   WORD instead of LONG, but I think that'd				   break GCC, so we put up with a little				   inefficiency for the sake of working output.				 */				if(   !issword(nextword)				   || (   isvar(opP->con1)				       && (  (   opP->con1->e_siz==0					      && flagseen['l']==0)					   || opP->con1->e_siz==3))) {					if(opP->reg==PC)						tmpreg=0x3B;	/* 7.3 */					else						tmpreg=0x30+opP->reg-ADDR;	/* 6.areg */					if(isvar(opP->con1)) {						if(opP->reg==PC) {						       add_frag(adds(opP->con1),							 offs(opP->con1),							 TAB(PCLEA,SZ_UNDEF));							break;						} else {							addword(0x0170);							add_fix('l',opP->con1,1);						}					} else						addword(0x0170);					addword(nextword>>16);				} else {					if(opP->reg==PC)						tmpreg=0x3A; /* 7.2 */					else						tmpreg=0x28+opP->reg-ADDR; /* 5.areg */					if(isvar(opP->con1)) {						if(opP->reg==PC) {							add_fix('w',opP->con1,1);						} else							add_fix('w',opP->con1,0);						}				}				addword(nextword);				break;			case AINDX:			case APODX:			case AMIND:			case APRDX:				nextword=0;				baseo=get_num(opP->con1,80);				outro=get_num(opP->con2,80);					/* Figure out the 'addressing mode' */					/* Also turn on the BASE_DISABLE bit, if needed */				if(opP->reg==PC || opP->reg==ZPC) {					tmpreg=0x3b; /* 7.3 */					if(opP->reg==ZPC)						nextword|=0x80;				} else if(opP->reg==FAIL) {					nextword|=0x80;					tmpreg=0x30;	/* 6.garbage */				} else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */				siz1= (opP->con1) ? opP->con1->e_siz : 0;				siz2= (opP->con2) ? opP->con2->e_siz : 0;					/* Index register stuff */				if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) {					nextword|=(opP->ireg-DATA)<<12;					if(opP->isiz==0 || opP->isiz==3)						nextword|=0x800;					switch(opP->imul) {					case 1: break;					case 2: nextword|=0x200; break;					case 4: nextword|=0x400; break;					case 8: nextword|=0x600; break;					default: abort();					}						/* IF its simple,						   GET US OUT OF HERE! */						/* Must be INDEX, with an index						   register.  Address register						   cannot be ZERO-PC, and either						   :b was forced, or we know						   it will fit */					if(   opP->mode==AINDX					   && opP->reg!=FAIL					   && opP->reg!=ZPC					   && (   siz1==1					       || (   issbyte(baseo)						   && !isvar(opP->con1)))) {						nextword +=baseo&0xff;						addword(nextword);						if(isvar(opP->con1))							add_fix('B',opP->con1,0);						break;					}				} else					nextword|=0x40;	/* No index reg */					/* It aint simple */				nextword|=0x100;					/* If the guy specified a width, we assume that					   it is wide enough.  Maybe it isn't.  Ifso, we lose					 */				switch(siz1) {				case 0:					if(isvar(opP->con1) || !issword(baseo)) {						siz1=3;						nextword|=0x30;					} else if(baseo==0)						nextword|=0x10;					else {							nextword|=0x20;						siz1=2;					}					break;				case 1:					as_warn("Byte dispacement won't work.  Defaulting to :w");				case 2:					nextword|=0x20;					break;				case 3:					nextword|=0x30;					break;				}					/* Figure out innner displacement stuff */				if(opP->mode!=AINDX) {					switch(siz2) {					case 0:						if(isvar(opP->con2) || !issword(outro)) {							siz2=3;							nextword|=0x3;						} else if(outro==0)							nextword|=0x1;						else {								nextword|=0x2;							siz2=2;						}						break;					case 1:						as_warn("Byte dispacement won't work.  Defaulting to :w");					case 2:						nextword|=0x2;						break;					case 3:						nextword|=0x3;						break;					}					if(opP->mode==APODX) nextword|=0x04;					else if(opP->mode==AMIND) nextword|=0x40;				}				addword(nextword);				if(isvar(opP->con1)) {					if(opP->reg==PC || opP->reg==ZPC) {						add_fix(siz1==3 ? 'l' : 'w',opP->con1,1);						opP->con1->e_exp.X_add_number+=6;					} else						add_fix(siz1==3 ? 'l' : 'w',opP->con1,0);				}				if(siz1==3)					addword(baseo>>16);				if(siz1)					addword(baseo);				if(isvar(opP->con2)) {					if(opP->reg==PC || opP->reg==ZPC) {						add_fix(siz2==3 ? 'l' : 'w',opP->con2,1);						opP->con1->e_exp.X_add_number+=6;					} else						add_fix(siz2==3 ? 'l' : 'w',opP->con2,0);				}				if(siz2==3)					addword(outro>>16);				if(siz2)					addword(outro);				break;			case ABSL:				nextword=get_num(opP->con1,80);				switch(opP->con1->e_siz) {				default:					as_warn("Unknown size for absolute reference");				case 0:					if(!isvar(opP->con1) && issword(offs(opP->con1))) {						tmpreg=0x38; /* 7.0 */						addword(nextword);						break;					}					/* Don't generate pc relative code					   on 68010 and 68000 */					if(isvar(opP->con1) &&					   !subs(opP->con1) &&					   seg(opP->con1)==SEG_TEXT &&					   now_seg==SEG_TEXT &&					   flagseen['m']==0 &&					    !index("~%&$?", s[0])) {						tmpreg=0x3A; /* 7.2 */						add_frag(adds(opP->con1),							 offs(opP->con1),							 TAB(PCREL,SZ_UNDEF));						break;					}				case 3:		/* Fall through into long */					if(isvar(opP->con1))						add_fix('l',opP->con1,0);					tmpreg=0x39;	/* 7.1 mode */					addword(nextword>>16);					addword(nextword);					break;				case 2:		/* Word */					if(isvar(opP->con1))						add_fix('w',opP->con1,0);					tmpreg=0x38;	/* 7.0 mode */					addword(nextword);					break;				}				break;			case MSCR:			default:				as_bad("unknown/incorrect operand");				/* abort(); */			}			install_gen_operand(s[1],tmpreg);			break;		case '#':		case '^':			switch(s[1]) {	/* JF: I hate floating point! */			case 'j':				tmpreg=70;				break;			case '8':				tmpreg=20;				break;			case 'C':				tmpreg=50;				break;			case '3':			default:				tmpreg=80;				break;			}			tmpreg=get_num(opP->con1,tmpreg);			if(isvar(opP->con1))				add_fix(s[1],opP->con1,0);			switch(s[1]) {			case 'b':	/* Danger:  These do no check for					   certain types of overflow.					   user beware! */				if(!isbyte(tmpreg))					opP->error="out of range";				insop(tmpreg);				if(isvar(opP->con1))					the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;				break;			case 'w':				if(!isword(tmpreg))					opP->error="out of range";				insop(tmpreg);				if(isvar(opP->con1))					the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;				break;			case 'l':				insop(tmpreg);		/* Because of the way insop works, we put these two out backwards */				insop(tmpreg>>16);				if(isvar(opP->con1))					the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;				break;

⌨️ 快捷键说明

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