?? tb.c
字號:
/* 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--------------------------------------------------------------------------#ifdef __FreeBSD__#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 + -