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

📄 tb.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
📖 第 1 页 / 共 4 页
字号:
/* This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public License alongwith this program; if not, write to the Free Software Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* * author teawater <c7code-uc@yahoo.com.cn> <teawater@gmail.com> */#include "armdefs.h"//teawater 2005-09-12  for gcc-3.3.x compiling, comment below line//#include "arm2x86_self.h"extern mem_bank_t *bank_ptr (ARMword addr);/*ywc 2005-04-22, in armmem.c*/extern mem_bank_t *insn_bank_ptr (ARMword addr);extern ARMul_State *state;//teawater add for new tb manage function 2005.07.10----------------------------//static uint32_t       tb_tbt_size = 0;//static uint32_t       tb_tbp_size = (1024 * 1024 * 32);#define TB_TBT_SIZE	skyeye_config.tb_tbt_size#define TB_TBP_SIZE	skyeye_config.tb_tbp_sizestatic tb_t *tbt_table = NULL;static int tbt_table_size = 0;static uint8_t *tbp_begin = NULL;static uint8_t *tbp_now = NULL;static uint32_t tbp_now_size = 0;static int tbp_dynamic = 0;static LIST_HEAD (tbp_dynamic_list);//AJ2D--------------------------------------------------------------------------#if defined(__FreeBSD__) || defined(__APPLE__)#define MAP_ANONYMOUS MAP_ANON#endifstatic __inline__ inttranslate_word (ARMul_State * state, ARMword insn, uint8_t * tbp){	int toplen = 0, len = 0;//teawater add for xscale(arm v5) 2005.09.26------------------------------------	ARMword cond, val, op1, shift, rm, rs, rn, rd, sh, y, x;//AJ2D--------------------------------------------------------------------------	uint8_t *begin = tbp;	//init	begin = tbp;	state->trap = 0;//teawater change for debug function 2005.07.09---------------------------------	//breakpoint	if (insn == 0xe7ffdefe) {		GEN_OP (tbp, len, op_begin);		gen_op_movl_trap_im_use_T2 (state, &tbp, &len,					    TRAP_BREAKPOINT);		GEN_OP (tbp, len, op_return);		goto out;	}//AJ2D--------------------------------------------------------------------------//teawater add for xscale(arm v5) 2005.09.01------------------------------------	if ((insn & 0xfff000f0) == 0xe1200070) {		//BKPT		//GEN_OP(tbp, len, op_begin);		gen_op_movl_trap_im_use_T2 (state, &tbp, &len,					    TRAP_INSN_ABORT);		GEN_OP (tbp, len, op_return);		goto out;	}//AJ2D--------------------------------------------------------------------------	//return if debug || irq || fiq || condition	cond = (insn >> 28) & 0xff;	if (cond == AL || cond == NV) {		GEN_OP (tbp, len, op_begin);		//some insn need it		//if (cond == NV)		//      goto translate_word_out;	}	else {		gen_op_movl_Tx_im (state, &tbp, &len, 0, cond);		GEN_OP (tbp, len, op_begin_test_T0);		toplen = len;	}	if (((insn & 0x0e000000) == 0 && (insn & 0x00000090) != 0x90)	    || ((insn & 0x0e000000) == (1 << 25))) {		ARMword set_cc, logic_cc, shiftop;		if (cond == NV)			goto translate_word_out;		op1 = (insn >> 21) & 0xf;		set_cc = (insn >> 20) & 1;//teawater add for xscale(arm v5) 2005.09.01------------------------------------		if (!set_cc & (op1 >= 0x8 && op1 <= 0xb)) {			if (state->is_v5) {				sh = ((insn >> 4) & 0xf);				if (sh == 0x5) {					rm = (insn >> 0) & 0xf;					rd = (insn >> 12) & 0xf;					rn = (insn >> 16) & 0xf;					switch (op1) {					case 0x8:						//qadd						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 0,								    rm);						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 1,								    rd);						GEN_OP (tbp, len,							op_qaddl_T0_T1_sq);						break;					case 0x9:						//qsub						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 0,								    rm);						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 1,								    rd);						GEN_OP (tbp, len,							op_qsubl_T0_T1_sq);						break;					case 0xa:						//qdadd						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 0,								    rn);						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 1,								    rn);						GEN_OP (tbp, len,							op_qaddl_T0_T1_sq);						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 1,								    rm);						GEN_OP (tbp, len,							op_qaddl_T0_T1_sq);						break;					case 0xb:						//qdsub						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 0,								    rn);						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 1,								    rn);						GEN_OP (tbp, len,							op_qaddl_T0_T1_sq);						GEN_OP (tbp, len,							op_movl_T1_T0);						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 0,								    rm);						GEN_OP (tbp, len,							op_qsubl_T0_T1_sq);						break;					}					gen_op_movl_reg_Tx (state, &tbp, &len,							    rd, 0);					GEN_OP (tbp, len, op_set_q);					goto translate_word_end;				}				else if ((sh & 0x9) == 0x8) {					rm = (insn >> 0) & 0xf;					rs = (insn >> 8) & 0xf;					rn = (insn >> 12) & 0xf;	//rdlo					rd = (insn >> 16) & 0xf;	//rdhi					y = (insn >> 6) & 0x1;					x = (insn >> 5) & 0x1;					gen_op_movl_Tx_reg (state, &tbp, &len,							    0, rm);					gen_op_movl_Tx_reg (state, &tbp, &len,							    1, rs);					if (op1 != 0x9) {						if (x) {							//t							GEN_OP (tbp, len,								op_hi_T0);						}						else {							//b							GEN_OP (tbp, len,								op_lo_T0);						}						GEN_OP (tbp, len,							op_signextend_halfword_T0);					}					if (y) {						//t						GEN_OP (tbp, len, op_hi_T1);					}					else {						//b						GEN_OP (tbp, len, op_lo_T1);					}					GEN_OP (tbp, len,						op_signextend_halfword_T1);					switch (op1) {					case 0x8:						//smlaxy						GEN_OP (tbp, len,							op_mul_T0_T1);						gen_op_movl_Tx_reg (state,								    &tbp,								    &len, 1,								    rn);						GEN_OP (tbp, len,							op_addl_T0_T1_sq);						gen_op_movl_reg_Tx (state,								    &tbp,								    &len, rd,								    0);						GEN_OP (tbp, len, op_set_q);						break;					case 0x9:						if (x) {							//smulwy							GEN_OP (tbp, len,								op_smulwy_T0_T1);							gen_op_movl_reg_Tx								(state, &tbp,								 &len, rd, 0);						}						else {							//smlawy							//gen_op_movl_Tx_reg(state, &tbp, &len, 2, rn);							//GEN_OP(tbp, len, op_smlawy_T2_T1_T0);							GEN_OP (tbp, len,								op_smulwy_T0_T1);							gen_op_movl_Tx_reg								(state, &tbp,								 &len, 1, rn);							GEN_OP (tbp, len,								op_addl_T0_T1_sq);							gen_op_movl_reg_Tx								(state, &tbp,								 &len, rd, 0);							GEN_OP (tbp, len,								op_set_q);						}						break;					case 0xa:						//smlalxy						GEN_OP (tbp, len,							op_mul_T0_T1);						gen_op_movl_Tx_reg (state, &tbp, &len, 1, rn);	//rdlo						gen_op_movl_Tx_reg (state, &tbp, &len, 2, rd);	//rdhi						GEN_OP (tbp, len,							op_smlalxy_T2_T1_T0);						gen_op_movl_reg_Tx (state,								    &tbp,								    &len, 1,								    rn);						gen_op_movl_reg_Tx (state,								    &tbp,								    &len, 2,								    rd);						break;					case 0xb:						//smulxy						GEN_OP (tbp, len,							op_mul_T0_T1);						gen_op_movl_reg_Tx (state,								    &tbp,								    &len, rd,								    0);						break;					}					goto translate_word_end;				}				else if (sh == 0x1 && op1 == 0xb) {					//clz					rm = insn & 0xf;					gen_op_movl_Tx_reg (state, &tbp, &len,							    1, rm);					GEN_OP (tbp, len, op_clzl_T0_T1);					rd = (insn >> 12) & 0xf;					gen_op_movl_reg_Tx (state, &tbp, &len,							    rd, 0);					goto translate_word_end;				}			}			if (op1 == 0x8 || op1 == 0xa) {				//mrs				gen_op_mrs (state, &tbp, &len, insn);				goto translate_word_end;			}		}//AJ2D--------------------------------------------------------------------------		logic_cc = table_logic_cc[op1] & set_cc;		//in arm_arm A 5.1		if (insn & (1 << 25)) {			//immediate operand arm_arm A 5.1.3			val = insn & 0xff;			shift = (uint8_t) ((insn >> 8) & 0xf) * 2;			//ror			if (shift)				val = (val >> shift) | (val << (32 - shift));			//op=set val to t1			gen_op_movl_Tx_im (state, &tbp, &len, 1, val);			if (logic_cc && shift) {				//val = ((insn & 0xff) >> (shift - 1)) & 1;				//op=set val[31] to C				if (val >> 31) {					GEN_OP (tbp, len, op_logic_1_sc);				}				else {					GEN_OP (tbp, len, op_logic_0_sc);				}			}		}		else {			//register			rm = (insn) & 0xf;			//op=set rm(0-15) to t1			gen_op_movl_Tx_reg (state, &tbp, &len, 1, rm);//teawater add check thumb 2005.07.21-------------------------------------------			if (op1 == 0x9 && !set_cc			    && ((insn >> 8) & 0xf) == 0xf) {				//bx or blx(2)				uint32_t tmp = (insn >> 4) & 0xf;				if (tmp == 0x1) {					//bx					GEN_OP (tbp, len, op_bx_T1);				}				else if (tmp == 0x2) {					//blx(2)					GEN_OP (tbp, len, op_blx_T1);				}				if (tmp == 0x1 || tmp == 0x2) {					state->trap = 1;					goto translate_word_end;				}			}//AJ2D--------------------------------------------------------------------------			shiftop = (insn >> 5) & 3;			if (!(insn & (1 << 4))) {				//imm				shift = (uint8_t) (insn >> 7) & 0x1f;				if (shift != 0) {					//op=shift, & set CF if logic_cc					if (logic_cc) {						gen_op_shift_T1_im_sc (state,								       &tbp,								       &len,								       shiftop,								       shift);					}					gen_op_shift_T1_im (state, &tbp, &len,							    shiftop, shift);				}				else {					GEN_OP (tbp, len, op_movl_T2_T1);					GEN_OP (tbp, len,						op_shift_T1_0[shiftop]);					if (logic_cc) {						GEN_OP (tbp, len,							op_shift_T2_0_sc							[shiftop]);						GEN_OP (tbp, len, op_set_cf);					}				}			}			else {				//reg				rs = (insn >> 8) & 0xf;				//op=set rs(0-15) to t0				gen_op_movl_Tx_reg (state, &tbp, &len, 0, rs);				//op=shift, & set CF if logic_cc				if (logic_cc) {					//op=shift & set CF					gen_op_shift_T1_T0_sc (state, &tbp,							       &len, shiftop);				}				else {					//op=shift					gen_op_shift_T1_T0 (state, &tbp, &len,							    shiftop);				}			}		}		if ((op1 == 0x9 || op1 == 0xb) && !set_cc) {			//msr   T1, psr			gen_op_msr (state, &tbp, &len, insn);			goto translate_word_end;		}		//data processing instruction		if (op1 != 0x0f && op1 != 0x0d) {	//!mov && !mvn			rn = (insn >> 16) & 0xf;			//op=set rn(0-15) to t0			gen_op_movl_Tx_reg (state, &tbp, &len, 0, rn);		}		rd = (insn >> 12) & 0xf;		arm2x86_get_dp_op[op1] (state, &tbp, &len, set_cc, rd);		arm2x86_get_dp_op_setcpsr[op1] (state, &tbp, &len, set_cc,						rd);	}	else {		//other instructions		op1 = (insn >> 24) & 0xf;		sh = (insn >> 5) & 3;		if (cond == NV) {//teawater add for xscale(arm v5) 2005.09.15------------------------------------			if (state->is_v5) {				switch (op1) {				case 0x5:				case 0x7:					if (((insn >> 12) & 0xf) == 0xf) {						//pld Ignored					}					goto translate_word_out;					break;//teawater add check thumb 2005.07.21-------------------------------------------				case 0xa:				case 0xb:					//blx(1)					gen_op_movl_trap_im_use_T2 (state,								    &tbp,								    &len,								    TRAP_UNPREDICTABLE);					GEN_OP (tbp, len, op_return);					goto out;					break;//AJ2D--------------------------------------------------------------------------				case 0xc:				case 0xd:					//ldc2 stc2					if (state->is_XScale					    && ((insn >> 8) & 0xf) == 0) {						//mar mra						goto translate_word_out;					}					break;				case 0xe:					//cdp2 mrc2 mcr2					if (state->is_XScale					    && (insn & (1 << 4))					    && (!(insn & (1 << 20)))					    && ((insn >> 8) & 0xf) == 0) {						//mia miaph miabb miabt miatb miatt						goto translate_word_out;					}					break;				default:					goto translate_word_out;					break;				}			}//AJ2D--------------------------------------------------------------------------			else {				goto translate_word_out;			}		}		if (sh != 0 && (op1 == 0 || op1 == 1)) {			//ldrh strh ldrsh ldrsb			gen_op_ldrhstrh (state, &tbp, &len, insn, sh);		}		else {			arm2x86_get_other_op[op1] (state, insn, &tbp, &len);		}	}      translate_word_end:	if (state->trap) {		GEN_OP (tbp, len, op_return);	}	if (toplen && begin) {		//set jmp length of condition code		//begin[toplen-1] = (uint8_t)(len - toplen);		int *p_tmp = (int *) (begin + (toplen - sizeof (int)));		*p_tmp = len - toplen;	}      translate_word_out:	//r15 += 4	if (!state->trap || toplen) {		GEN_OP (tbp, len, op_addpc);		state->trap = 0;	}	//TEA_OUT(GEN_OP(tbp, len, op_return));      out:	if (len > TB_INSN_LEN_MAX) {		fprintf (stderr,			 "SKYEYE: TB_INSN_LEN_MAX: insn %x len %d > TB_INSN_LEN_MAX %d.\n",			 insn, len, TB_INSN_LEN_MAX);		skyeye_exit (-1);	}/*#ifdef TEA_DEBUG	{		static int	insn_max = 0;		if (len > insn_max) {			insn_max = len;			fprintf(stderr, "\nSKYEYE: insn_max = %d.\n", insn_max);		}	}#endif	//TEA_DEBUG*/	return (len);}//teawater add tb_insn_addr 2005.10.08------------------------------------------/*static uint8_t *tb_translate(ARMul_State * state, ARMword *addr, ARMword *tb_begin_addr, uint8_t *tbp, ARMword *tran_addr, uint8_t **tbp_now)*/static uint8_t *tb_translate(ARMul_State * state, ARMword *addr, ARMword *tb_begin_addr, tb_t *tbt){	int		len;	uint8_t		*ret = NULL;//	ARMword		*tb_end_addr = tb_begin_addr + (TB_LEN - (*tran_addr - TB_ALIGN(*tran_addr)))  / sizeof(ARMword);	ARMword		*tb_end_addr = tb_begin_addr + (TB_LEN - (tbt->tran_addr - TB_ALIGN(tbt->tran_addr)))  / sizeof(ARMword);//teawater change for local tb branch directly jump 2005.10.10------------------	tb_branch_save_t	*e;	struct list_head	*list,*n;//AJ2D--------------------------------------------------------------------------//teawater change for local tb branch directly jump 2005.10.10------------------	INIT_LIST_HEAD(&tb_branch_save_list);	now_tbt = tbt;	tbt->ret_addr = 0;//AJ2D--------------------------------------------------------------------------	for( ; tb_begin_addr < tb_end_addr; tb_begin_addr++) {

⌨️ 快捷键说明

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