📄 arm2x86_other.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"#include "arm2x86_self.h"uint8_t *get_op_addq_T0_T1_eax_T2 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_addq_T0_T1_eax_T2"); __asm__ __volatile__ ("addl %eax, %" AREG_T0); __asm__ __volatile__ ("adcl %" AREG_T2 ", %" AREG_T1); OP_END ("get_op_addq_T0_T1_eax_T2"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_b_offset (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_b_offset"); st->Reg[15] += INT32_MAX; OP_END ("get_op_b_offset"); *len = end - begin; if (*len <= sizeof (INT32_MAX)) { return (NULL); } else { *len -= sizeof (ULONG_MAX); } return ((uint8_t *) begin);}uint8_t *get_op_bl_offset (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_bl_offset"); //st->Reg[14] = st->Reg[15] + 4; st->Reg[14] = st->Reg[15]; wmb (); st->Reg[15] += INT32_MAX; OP_END ("get_op_bl_offset"); *len = end - begin; if (*len <= sizeof (INT32_MAX)) { return (NULL); } else { *len -= sizeof (ULONG_MAX); } return ((uint8_t *) begin);}//teawater add check thumb 2005.07.21-------------------------------------------uint8_t *get_op_bx_T1 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_bx_T1"); if (T1 & 1) { //thumb XXX st->TFlag = 1; st->Reg[15] = (T1 & 0xfffffffe) + 2; st->trap = TRAP_UNPREDICTABLE; } else { //arm st->TFlag = 0; st->Reg[15] = (T1 & 0xfffffffc) + 4; } OP_END ("get_op_bx_T1"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_blx_T1 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_blx_T1"); if (T1 & 1) { //thumb XXX st->TFlag = 1; st->Reg[14] = st->Reg[15]; st->Reg[15] = (T1 & 0xfffffffe) + 2; st->trap = TRAP_UNPREDICTABLE; } else { //arm st->TFlag = 0; st->Reg[14] = st->Reg[15]; st->Reg[15] = (T1 & 0xfffffffc) + 4; } OP_END ("get_op_blx_T1"); *len = end - begin; return ((uint8_t *) begin);}//AJ2D--------------------------------------------------------------------------//teawater add for xscale(arm v5) 2005.09.12------------------------------------uint8_t *get_op_hi_T0 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_hi_T0"); //T0 = (uint32_t)((int32_t)((int16_t)(T0 >> 16))); T0 = T0 >> 16; OP_END ("get_op_hi_T0"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_hi_T1 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_hi_T1"); //T1 = (uint32_t)((int32_t)((int16_t)(T1 >> 16))); T1 = T1 >> 16; OP_END ("get_op_hi_T1"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_lo_T0 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_lo_T0"); //T0 = (uint32_t)((int32_t)((int16_t)(T0 & 0xffff))); T0 = T0 & 0xffff; OP_END ("get_op_lo_T0"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_lo_T1 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_lo_T1"); //T1 = (uint32_t)((int32_t)((int16_t)(T1 & 0xffff))); T1 = T1 & 0xffff; OP_END ("get_op_lo_T1"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_smlalxy_T2_T1_T0 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_smlalxy_T2_T1_T0"); arm2x86_tmp64 = (uint64_t) T1; arm2x86_tmp64 = ((uint64_t) T2) << 32; arm2x86_tmp64 += (uint64_t) T0; T1 = (uint32_t) (arm2x86_tmp64 & 0xffffffff); T2 = (uint32_t) (arm2x86_tmp64 >> 32); OP_END ("get_op_smlalxy_T2_T1_T0"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_smlawy_T2_T1_T0 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_smlawy_T2_T1_T0"); arm2x86_tmp64 = (uint64_t) T0 *(uint64_t) T1; T0 = (uint32_t) ((arm2x86_tmp64 >> 16) & 0xffffffff); T1 = T0 + T2; QFLAG_reg = ~(T0 ^ T2); QFLAG_reg &= (T1 ^ T2); QFLAG_reg >>= 31; T0 = T1; OP_END ("get_op_smlawy_T2_T1_T0"); *len = end - begin; return ((uint8_t *) begin);}uint8_t *get_op_smulwy_T0_T1 (int *len){ unsigned int begin = 0, end = 0; OP_BEGIN ("get_op_smulwy_T0_T1"); arm2x86_tmp64 = (uint64_t) T0 *(uint64_t) T1; T0 = (uint32_t) ((arm2x86_tmp64 >> 16) & 0xffffffff); OP_END ("get_op_smulwy_T0_T1"); *len = end - begin; return ((uint8_t *) begin);}//AJ2D--------------------------------------------------------------------------//teawater change for local tb branch directly jump 2005.10.17------------------uint8_t *get_op_local_b_offset(int *len){ unsigned int begin=0,end=0; OP_BEGIN("get_op_local_b_offset"); __asm__ __volatile__ ("jmp 0xffffffff"); OP_END("get_op_local_b_offset"); *len = end - begin; if (*len <= sizeof(INT32_MAX)) { return(NULL); } return((uint8_t *)begin);}op_table_t op_local_b_offset;//AJ2D--------------------------------------------------------------------------op_table_t op_addq_T0_T1_eax_T2;op_table_t op_b_offset;op_table_t op_bl_offset;//teawater add check thumb 2005.07.21-------------------------------------------op_table_t op_bx_T1;op_table_t op_blx_T1;//AJ2D--------------------------------------------------------------------------//teawater add for xscale(arm v5) 2005.09.12------------------------------------op_table_t op_hi_T0;op_table_t op_hi_T1;op_table_t op_lo_T0;op_table_t op_lo_T1;op_table_t op_smlalxy_T2_T1_T0;op_table_t op_smlawy_T2_T1_T0;op_table_t op_smulwy_T0_T1;//AJ2D--------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------voidarm2x86_get_op_mul (ARMul_State * state, ARMword insn, uint8_t ** tbpp, int *plen){ ARMword rd, rn, rs, rm; rd = (insn >> 16) & 0xf; rn = (insn >> 12) & 0xf; rs = (insn >> 8) & 0xf; rm = (insn) & 0xf; if (!(insn & (1 << 23))) { //32 bit //mul gen_op_movl_Tx_reg (state, tbpp, plen, 0, rs); gen_op_movl_Tx_reg (state, tbpp, plen, 1, rm); GEN_OP (*tbpp, *plen, op_mul_T0_T1); if (insn & (1 << 21)) { //mla gen_op_movl_Tx_reg (state, tbpp, plen, 1, rn); GEN_OP (*tbpp, *plen, op_addl_T0_T1); } if (insn & (1 << 20)) { //set cpsr nf GEN_OP (*tbpp, *plen, op_logic_T0_sn); GEN_OP (*tbpp, *plen, op_set_nf); //set cpsr zf GEN_OP (*tbpp, *plen, op_logic_T0_sz); GEN_OP (*tbpp, *plen, op_set_zf); } gen_op_movl_reg_Tx (state, tbpp, plen, rd, 0); if (rd == 15) { state->trap = 1; } } else { //64 bit gen_op_movl_Tx_reg (state, tbpp, plen, 0, rs); gen_op_movl_Tx_reg (state, tbpp, plen, 1, rm); if (insn & (1 << 22)) { //smull GEN_OP (*tbpp, *plen, op_smull_T0_T1); } else { //umull GEN_OP (*tbpp, *plen, op_umull_T0_T1); } if (insn & (1 << 21)) { //smlal if smull //umlal if umull gen_op_movl_Tx_reg (state, tbpp, plen, 2, rn); GEN_OP (*tbpp, *plen, op_movl_eax_T2); gen_op_movl_Tx_reg (state, tbpp, plen, 2, rd); GEN_OP (*tbpp, *plen, op_addq_T0_T1_eax_T2); } if (insn & (1 << 20)) { //set cpsr nf GEN_OP (*tbpp, *plen, op_logic_T0_sn); GEN_OP (*tbpp, *plen, op_set_nf); //set cpsr zf GEN_OP (*tbpp, *plen, op_logic_T0_sz); GEN_OP (*tbpp, *plen, op_set_zf); } gen_op_movl_reg_Tx (state, tbpp, plen, rn, 0); gen_op_movl_reg_Tx (state, tbpp, plen, rd, 1); if (rn == 15 || rd == 15) { state->trap = 1; } }}voidarm2x86_get_op_swp (ARMul_State * state, ARMword insn, uint8_t ** tbpp, int *plen){ ARMword rd, rn, rm; rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; rm = (insn) & 0xf; gen_op_movl_Tx_reg (state, tbpp, plen, 0, rm); gen_op_movl_Tx_reg (state, tbpp, plen, 1, rn); if (insn & (1 << 22)) { //swpb //ldrb T2 from T1 GEN_OP (*tbpp, *plen, op_ldrb_T2_T1); //strb T0 to T1 GEN_OP (*tbpp, *plen, op_strb_T0_T1); } else { //swp //ldr T2 from T1 GEN_OP (*tbpp, *plen, op_ldr_T2_T1); //str T0 to T1 GEN_OP (*tbpp, *plen, op_str_T0_T1); } gen_op_movl_reg_Tx (state, tbpp, plen, rd, 2);}voidarm2x86_get_op_insn_undef (ARMul_State * state, ARMword insn, uint8_t ** tbpp, int *plen){ gen_op_movl_trap_im_use_T2 (state, tbpp, plen, TRAP_INSN_UNDEF); state->trap = 1;}voidarm2x86_get_op_ldrstr (ARMul_State * state, ARMword insn, uint8_t ** tbpp, int *plen){ ARMword rn = (insn >> 16) & 0xf; ARMword rd = (insn >> 12) & 0xf; gen_op_movl_Tx_reg (state, tbpp, plen, 1, rn); if (insn & (1 << 24)) { //P gen_op_add_data_offset (state, tbpp, plen, insn); } if (insn & (1 << 20)) { //L if (insn & (1 << 22)) { //B //ldrb GEN_OP (*tbpp, *plen, op_ldrb_T0_T1); } else { //ldr GEN_OP (*tbpp, *plen, op_ldr_T0_T1); } //if (!state->is_XScale) { if (state->abort_model > 1) { gen_op_test_dataabort_im (state, tbpp, plen, op_movl_reg_Tx[0][rd].len); } gen_op_movl_reg_Tx (state, tbpp, plen, rd, 0); } else { gen_op_movl_Tx_reg (state, tbpp, plen, 0, rd); if (insn & (1 << 22)) { //B //strb GEN_OP (*tbpp, *plen, op_strb_T0_T1); } else { //str
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -