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

📄 risc_x86.h

📁 DOSBox emulates a full x86 pc with sound and dos. Its main use is to run old dosgames on platforms w
💻 H
📖 第 1 页 / 共 2 页
字号:
	case DOP_MOV:	cache_addb(0xb8+(gr1->index)); dr1->flags|=DYNFLG_CHANGED; goto finish;	default:		IllegalOption("gen_dop_word_imm");	}	dr1->flags|=DYNFLG_CHANGED;nochange:	cache_addw(tmp+(gr1->index<<8));finish:	if (dword) cache_addd(imm);	else cache_addw(imm);}static void gen_dop_word_imm_mem(DualOps op,bool dword,DynReg * dr1,void* data) {	GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV);	Bit16u tmp;	switch (op) {	case DOP_ADD:	tmp=0x0503; break; 	case DOP_ADC:	tmp=0x0513; break;	case DOP_SUB:	tmp=0x052b; break;	case DOP_SBB:	tmp=0x051b; break;	case DOP_CMP:	tmp=0x053b; goto nochange;	//Doesn't change	case DOP_XOR:	tmp=0x0533; break;	case DOP_AND:	tmp=0x0523; break;	case DOP_OR:	tmp=0x050b; break;	case DOP_TEST:	tmp=0x0585; goto nochange;	//Doesn't change	case DOP_MOV:		gen_mov_host(data,dr1,dword?4:2);		dr1->flags|=DYNFLG_CHANGED;		return;	default:		IllegalOption("gen_dop_word_imm_mem");	}	dr1->flags|=DYNFLG_CHANGED;nochange:	if (!dword) cache_addb(0x66);	cache_addw(tmp+(gr1->index<<11));	cache_addd((Bit32u)data);}static void gen_dop_word_var(DualOps op,bool dword,DynReg * dr1,void* drd) {	GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV);	Bit8u tmp;	switch (op) {	case DOP_ADD:	tmp=0x03; break;	case DOP_ADC:	tmp=0x13; break;	case DOP_SUB:	tmp=0x2b; break;	case DOP_SBB:	tmp=0x1b; break;	case DOP_CMP:	tmp=0x3b; break;	case DOP_XOR:	tmp=0x33; break;	case DOP_AND:	tmp=0x23; break;	case DOP_OR:	tmp=0x0b; break;	case DOP_TEST:	tmp=0x85; break;	case DOP_MOV:	tmp=0x8b; break;	case DOP_XCHG:	tmp=0x87; break;	default:		IllegalOption("gen_dop_word_var");	}	if (!dword) cache_addb(0x66);	cache_addw(tmp|(0x05+((gr1->index)<<3))<<8);	cache_addd((Bit32u)drd);}static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) {	GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2);	dr1->flags|=DYNFLG_CHANGED;	if (!dword) {		cache_addd(0xaf0f66|(0xc0+(gr1->index<<3)+gr2->index)<<24);	} else {		cache_addw(0xaf0f);		cache_addb(0xc0+(gr1->index<<3)+gr2->index);	}}static void gen_imul_word_imm(bool dword,DynReg * dr1,DynReg * dr2,Bits imm) {	GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2);	if (!dword) cache_addb(0x66);	if ((imm>=-128 && imm<=127)) {		cache_addb(0x6b);		cache_addb(0xc0+(gr1->index<<3)+gr2->index);		cache_addb(imm);	} else {		cache_addb(0x69);		cache_addb(0xc0+(gr1->index<<3)+gr2->index);		if (dword) cache_addd(imm);		else cache_addw(imm);	}	dr1->flags|=DYNFLG_CHANGED;}static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) {	GenReg * gr1=FindDynReg(dr1);	if (!dword) cache_addb(0x66);	switch (op) {	case SOP_INC:cache_addb(0x40+gr1->index);break;	case SOP_DEC:cache_addb(0x48+gr1->index);break;	case SOP_NOT:cache_addw(0xd0f7+(gr1->index<<8));break;	case SOP_NEG:cache_addw(0xd8f7+(gr1->index<<8));break;	default:		IllegalOption("gen_sop_word");	}	dr1->flags|=DYNFLG_CHANGED;}static void gen_shift_byte_cl(Bitu op,DynReg * dr1,Bit8u di1,DynReg * drecx) {	ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);	GenReg * gr1=FindDynReg(dr1);	cache_addw(0xc0d2+(((Bit16u)op) << 11)+ ((gr1->index+di1)<<8));	dr1->flags|=DYNFLG_CHANGED;}static void gen_shift_byte_imm(Bitu op,DynReg * dr1,Bit8u di1,Bit8u imm) {	GenReg * gr1=FindDynReg(dr1);	cache_addw(0xc0c0+(((Bit16u)op) << 11) + ((gr1->index+di1)<<8));	cache_addb(imm);	dr1->flags|=DYNFLG_CHANGED;}static void gen_shift_word_cl(Bitu op,bool dword,DynReg * dr1,DynReg * drecx) {	ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);	GenReg * gr1=FindDynReg(dr1);	if (!dword) cache_addb(0x66);	cache_addw(0xc0d3+(((Bit16u)op) << 11) + ((gr1->index)<<8));	dr1->flags|=DYNFLG_CHANGED;}static void gen_shift_word_imm(Bitu op,bool dword,DynReg * dr1,Bit8u imm) {	GenReg * gr1=FindDynReg(dr1);	dr1->flags|=DYNFLG_CHANGED;	if (!dword) {		cache_addd(0x66|((0xc0c1+((Bit16u)op << 11) + (gr1->index<<8))|imm<<16)<<8);	} else { 		cache_addw(0xc0c1+((Bit16u)op << 11) + (gr1->index<<8));		cache_addb(imm);	}}static void gen_cbw(bool dword,DynReg * dyn_ax) {	ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);	if (!dword) cache_addb(0x66);	cache_addb(0x98);	dyn_ax->flags|=DYNFLG_CHANGED;}static void gen_cwd(bool dword,DynReg * dyn_ax,DynReg * dyn_dx) {	ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);	ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx);	dyn_ax->flags|=DYNFLG_CHANGED;	dyn_dx->flags|=DYNFLG_CHANGED;	if (!dword) cache_addw(0x9966);	else cache_addb(0x99);}static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) {	ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);	GenReg * gr1=FindDynReg(dr1);	if (imul) cache_addw(0xe8f6+((gr1->index+di1)<<8));	else cache_addw(0xe0f6+((gr1->index+di1)<<8));	dyn_ax->flags|=DYNFLG_CHANGED;}static void gen_mul_word(bool imul,DynReg * dyn_ax,DynReg * dyn_dx,bool dword,DynReg * dr1) {	ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);	ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx);	GenReg * gr1=FindDynReg(dr1);	if (!dword) cache_addb(0x66);	if (imul) cache_addw(0xe8f7+(gr1->index<<8));	else cache_addw(0xe0f7+(gr1->index<<8));	dyn_ax->flags|=DYNFLG_CHANGED;	dyn_dx->flags|=DYNFLG_CHANGED;}static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) {	GenReg * gr1=FindDynReg(dr1);	GenReg * gr2=FindDynReg(dr2);	if (!dword) cache_addb(0x66);	if (left) cache_addw(0xa40f);		//SHLD IMM	else  cache_addw(0xac0f);			//SHRD IMM	cache_addb(0xc0+gr1->index+(gr2->index<<3));	cache_addb(imm);	dr1->flags|=DYNFLG_CHANGED;}static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg * drecx) {	ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);	GenReg * gr1=FindDynReg(dr1);	GenReg * gr2=FindDynReg(dr2);	if (!dword) cache_addb(0x66);	if (left) cache_addw(0xa50f);		//SHLD CL	else  cache_addw(0xad0f);			//SHRD CL	cache_addb(0xc0+gr1->index+(gr2->index<<3));	dr1->flags|=DYNFLG_CHANGED;}static void gen_call_function(void * func,char * ops,...) {	Bits paramcount=0;	bool release_flags=false;	struct ParamInfo {		char * line;		Bitu value;	} pinfo[32];	ParamInfo * retparam=0;	/* Clear the EAX Genreg for usage */	x86gen.regs[X86_REG_EAX]->Clear();	x86gen.regs[X86_REG_EAX]->notusable=true;	/* Save the flags */	if (GCC_UNLIKELY(!skip_flags)) gen_protectflags();	/* Scan for the amount of params */	if (ops) {		va_list params;		va_start(params,ops);		Bitu stack_used=0;		bool free_flags=false;		Bits pindex=0;		while (*ops) {			if (*ops=='%') {                pinfo[pindex].line=ops+1;				pinfo[pindex].value=va_arg(params,Bitu);#if defined (MACOSX)				char * scan=pinfo[pindex].line;				if ((*scan=='I') || (*scan=='D')) stack_used+=4;				else if (*scan=='F') free_flags=true;#endif				pindex++;			}			ops++;		}#if defined (MACOSX)		/* align stack */		stack_used+=4;			// saving esp on stack as well		cache_addw(0xc48b);		// mov eax,esp		cache_addb(0x2d);		// sub eax,stack_used		cache_addd(stack_used);		cache_addw(0xe083);		// and eax,0xfffffff0		cache_addb(0xf0);		cache_addb(0x05);		// sub eax,stack_used		cache_addd(stack_used);		cache_addb(0x94);		// xchg eax,esp		if (free_flags) {			cache_addw(0xc083);	// add eax,4			cache_addb(0x04);		}		cache_addb(0x50);		// push eax (==old esp)#endif		paramcount=0;		while (pindex) {			pindex--;			char * scan=pinfo[pindex].line;			switch (*scan++) {			case 'I':				/* immediate value */				paramcount++;				cache_addb(0x68);			//Push immediate				cache_addd(pinfo[pindex].value);	//Push value				break;			case 'D':				/* Dynamic register */				{					bool release=false;					paramcount++;					DynReg * dynreg=(DynReg *)pinfo[pindex].value;					GenReg * genreg=FindDynReg(dynreg);					scanagain:					switch (*scan++) {					case 'd':						cache_addb(0x50+genreg->index);		//Push reg						break;					case 'w':						cache_addw(0xb70f);					//MOVZX EAX,reg						cache_addb(0xc0+genreg->index);						cache_addb(0x50);					//Push EAX						break;					case 'l':						cache_addw(0xb60f);					//MOVZX EAX,reg[0]						cache_addb(0xc0+genreg->index);						cache_addb(0x50);					//Push EAX						break;					case 'h':						cache_addw(0xb60f);					//MOVZX EAX,reg[1]						cache_addb(0xc4+genreg->index);						cache_addb(0x50);					//Push EAX						break;					case 'r':								/* release the reg afterwards */						release=true;						goto scanagain;					default:						IllegalOption("gen_call_function param:DREG");					}					if (release) gen_releasereg(dynreg);				}				break;			case 'R':				/* Dynamic register to get the return value */				retparam =&pinfo[pindex];				pinfo[pindex].line=scan;				break;			case 'F':				/* Release flags from stack */				release_flags=true;				break;			default:				IllegalOption("gen_call_function unknown param");			}		}#if defined (MACOSX)		if (free_flags) release_flags=false;	} else {		/* align stack */		Bit32u stack_used=8;	// saving esp and return address on the stack		cache_addw(0xc48b);		// mov eax,esp		cache_addb(0x2d);		// sub eax,stack_used		cache_addd(stack_used);		cache_addw(0xe083);		// and eax,0xfffffff0		cache_addb(0xf0);		cache_addb(0x05);		// sub eax,stack_used		cache_addd(stack_used);		cache_addb(0x94);		// xchg eax,esp		cache_addb(0x50);		// push esp (==old esp)#endif	}	/* Clear some unprotected registers */	x86gen.regs[X86_REG_ECX]->Clear();	x86gen.regs[X86_REG_EDX]->Clear();	/* Do the actual call to the procedure */	cache_addb(0xe8);	cache_addd((Bit32u)func - (Bit32u)cache.pos-4);	/* Restore the params of the stack */	if (paramcount) {		cache_addw(0xc483);				//add ESP,imm byte		cache_addb(paramcount*4+(release_flags?4:0));	} else if (release_flags) {		cache_addw(0xc483);				//add ESP,imm byte		cache_addb(4);	}	/* Save the return value in correct register */	if (retparam) {		DynReg * dynreg=(DynReg *)retparam->value;		GenReg * genreg=FindDynReg(dynreg);		if (genreg->index)		// test for (e)ax/al		switch (*retparam->line) {		case 'd':			cache_addw(0xc08b+(genreg->index <<(8+3)));	//mov reg,eax			break;		case 'w':			cache_addb(0x66);										cache_addw(0xc08b+(genreg->index <<(8+3)));	//mov reg,eax			break;		case 'l':			cache_addw(0xc08a+(genreg->index <<(8+3)));	//mov reg,eax			break;		case 'h':			cache_addw(0xc08a+((genreg->index+4) <<(8+3)));	//mov reg,eax			break;		}		dynreg->flags|=DYNFLG_CHANGED;	}	/* Restore EAX registers to be used again */	x86gen.regs[X86_REG_EAX]->notusable=false;#if defined (MACOSX)	/* restore stack */	cache_addb(0x5c);	// pop esp#endif}static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) {	/* Clear the EAX Genreg for usage */	x86gen.regs[X86_REG_EAX]->Clear();	x86gen.regs[X86_REG_EAX]->notusable=true;	gen_protectflags();#if defined (MACOSX)	/* align stack */	Bitu stack_used=12;	cache_addw(0xc48b);		// mov eax,esp	cache_addb(0x2d);		// sub eax,stack_used	cache_addd(stack_used);	cache_addw(0xe083);		// and eax,0xfffffff0	cache_addb(0xf0);	cache_addb(0x05);		// sub eax,stack_used	cache_addd(stack_used);	cache_addb(0x94);		// xchg eax,esp	cache_addb(0x50);		// push eax (==old esp)#endif	cache_addb(0x68);	//PUSH val	cache_addd(val);	GenReg * genreg=FindDynReg(dr);	cache_addb(0x50+genreg->index);		//PUSH reg	/* Clear some unprotected registers */	x86gen.regs[X86_REG_ECX]->Clear();	x86gen.regs[X86_REG_EDX]->Clear();	/* Do the actual call to the procedure */	cache_addb(0xe8);	switch (write_size) {		case 1: cache_addd((Bit32u)mem_writeb_checked_x86 - (Bit32u)cache.pos-4); break;		case 2: cache_addd((Bit32u)mem_writew_checked_x86 - (Bit32u)cache.pos-4); break;		case 4: cache_addd((Bit32u)mem_writed_checked_x86 - (Bit32u)cache.pos-4); break;		default: IllegalOption("gen_call_write");	}	cache_addw(0xc483);		//ADD ESP,8	cache_addb(2*4);	x86gen.regs[X86_REG_EAX]->notusable=false;	gen_releasereg(dr);#if defined (MACOSX)	/* restore stack */	cache_addb(0x5c);	// pop esp#endif}static Bit8u * gen_create_branch(BranchTypes type) {	/* First free all registers */	cache_addw(0x70+type);	return (cache.pos-1);}static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) {#if C_DEBUG	Bits len=from-data;	if (len<0) len=-len;	if (len>126) LOG_MSG("Big jump %d",len);#endif	*data=(from-data-1);}static Bit8u * gen_create_branch_long(BranchTypes type) {	cache_addw(0x800f+(type<<8));	cache_addd(0);	return (cache.pos-4);}static void gen_fill_branch_long(Bit8u * data,Bit8u * from=cache.pos) {	*(Bit32u*)data=(from-data-4);}static Bit8u * gen_create_jump(Bit8u * to=0) {	/* First free all registers */	cache_addb(0xe9);	cache_addd(to-(cache.pos+4));	return (cache.pos-4);}static void gen_fill_jump(Bit8u * data,Bit8u * to=cache.pos) {	*(Bit32u*)data=(to-data-4);}static void gen_jmp_ptr(void * ptr,Bits imm=0) {	cache_addb(0xa1);	cache_addd((Bit32u)ptr);	cache_addb(0xff);		//JMP EA	if (!imm) {			//NO EBP		cache_addb(0x20);    } else if ((imm>=-128 && imm<=127)) {		cache_addb(0x60);		cache_addb(imm);	} else {		cache_addb(0xa0);		cache_addd(imm);	}}static void gen_save_flags(DynReg * dynreg) {	if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_save_flags");	GenReg * genreg=FindDynReg(dynreg);	cache_addb(0x8b);					//MOV REG,[esp]	cache_addw(0x2404+(genreg->index << 3));	dynreg->flags|=DYNFLG_CHANGED;}static void gen_load_flags(DynReg * dynreg) {	if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_load_flags");	cache_addw(0xc483);				//ADD ESP,4	cache_addb(0x4);	GenReg * genreg=FindDynReg(dynreg);	cache_addb(0x50+genreg->index);		//PUSH 32}static void gen_save_host_direct(void * data,Bits imm) {	cache_addw(0x05c7);		//MOV [],dword	cache_addd((Bit32u)data);	cache_addd(imm);}static void gen_return(BlockReturn retcode) {	gen_protectflags();	cache_addb(0x59);			//POP ECX, the flags	if (retcode==0) cache_addw(0xc033);		//MOV EAX, 0	else {		cache_addb(0xb8);		//MOV EAX, retcode		cache_addd(retcode);	}	cache_addb(0xc3);			//RET}static void gen_return_fast(BlockReturn retcode,bool ret_exception=false) {	if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast");	cache_addw(0x0d8b);			//MOV ECX, the flags	cache_addd((Bit32u)&cpu_regs.flags);	if (!ret_exception) {		cache_addw(0xc483);			//ADD ESP,4		cache_addb(0x4);		if (retcode==0) cache_addw(0xc033);		//MOV EAX, 0		else {			cache_addb(0xb8);		//MOV EAX, retcode			cache_addd(retcode);		}	}	cache_addb(0xc3);			//RET}static void gen_init(void) {	x86gen.regs[X86_REG_EAX]=new GenReg(0);	x86gen.regs[X86_REG_ECX]=new GenReg(1);	x86gen.regs[X86_REG_EDX]=new GenReg(2);	x86gen.regs[X86_REG_EBX]=new GenReg(3);	x86gen.regs[X86_REG_EBP]=new GenReg(5);	x86gen.regs[X86_REG_ESI]=new GenReg(6);	x86gen.regs[X86_REG_EDI]=new GenReg(7);}

⌨️ 快捷键说明

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