📄 tb.c
字号:
fprintf(stderr, "SKYEYE: mem_reset: Error allocating mem for bank number %d.\n", bank_num);
exit(-1);
}
}
state->mem.tbt[bank_num] = malloc(state->mem.rom_size[bank_num] / TB_LEN * sizeof(tb_t));
if (!state->mem.tbt[bank_num]) {
fprintf(stderr, "SKYEYE: mem_reset: Error allocating mem for bank number %d.\n", bank_num);
exit(-1);
}
memset(state->mem.tbt[bank_num], 0, state->mem.rom_size[bank_num] / TB_LEN * sizeof(tb_t));
}
tbt = &(state->mem.tbt[bank_num][(align_addr - mbp->addr)/TB_LEN]);
//get tbt->tbp
if (!tbt->tbp) {
if (tbp_dynamic) {
//dynamic tbp
tb_get_tbp(tbt);
}
else {
tbt->tbp = &(state->mem.tbp[bank_num][(align_addr - mbp->addr) / sizeof(ARMword) * TB_INSN_LEN_MAX + (align_addr - mbp->addr) / TB_LEN * op_return.len]);
}
}
else {
if (tbp_dynamic) {
list_del_init(&tbt->list);
}
}
}
//get tbp
tbp = tbt->tbp;
//set tb_now to check the current running block is written.
state->tb_now = (void *)tbt;
//set save_align_addr
save_align_addr = align_addr;
//add tbt to tbp_dynamic_list's tail to be the newest one
if (tbp_dynamic) {
list_add_tail(&tbt->list, &tbp_dynamic_list);
}
//find ret from tb
get_ret:
if (tbt->ted) {
//tbt has been translated
//addr is align
if (addr == align_addr) {
ret = tbp;
goto out;
}
if (addr >= tbt->tran_addr) {
//block need continue translate
if (bank_num == -1) {
mbp = tb_get_mbp(align_addr, &bank_num);
if(!mbp) {
goto out;
}
}
real_begin_addr = &(state->mem.rom[bank_num][(align_addr - mbp->addr) / sizeof(ARMword)]) + (tbt->tran_addr - align_addr) / sizeof(ARMword);
real_addr = real_begin_addr + (addr - tbt->tran_addr) / sizeof(ARMword);
ret = tb_translate(state, real_addr, real_begin_addr, tbt->tbp_now, &tbt->tran_addr, &tbt->tbp_now);
}
else {
//find in cache
ret = tb_find_cache(tbt, addr);
if (ret) {
goto out;
}
if (bank_num == -1) {
mbp = tb_get_mbp(align_addr, &bank_num);
if(!mbp) {
goto out;
}
}
real_begin_addr = &(state->mem.rom[bank_num][(align_addr - mbp->addr) / sizeof(ARMword)]);
real_addr = real_begin_addr + (addr - align_addr) / sizeof(ARMword);
ret = tb_translate_find(state, real_addr, real_begin_addr, tbp);
}
}
else {
//tbt has not been translated
if (bank_num == -1) {
mbp = tb_get_mbp(align_addr, &bank_num);
if(!mbp) {
goto out;
}
}
real_begin_addr = &(state->mem.rom[bank_num][(align_addr - mbp->addr) / sizeof(ARMword)]);
real_addr = real_begin_addr + (addr - align_addr) / sizeof(ARMword);
tbt->tran_addr = align_addr;
ret = tb_translate(state, real_addr, real_begin_addr, tbp, &tbt->tran_addr, &tbt->tbp_now);
if (ret) {
tbt->ted = 1;
}
}
if (ret) {
tb_insert_cache(tbt, addr, ret);
}
out:
return(ret);
}
int
tb_setdirty(ARMul_State * state, ARMword addr, mem_bank_t *mbp)
{
ARMword align_addr = TB_ALIGN(addr);
static ARMword save_align_addr = 0x1;
static tb_t *tbt = NULL;
if (save_align_addr == align_addr) {
goto setdirty;
}
save_align_addr = 0x1;
//get tbt
if (tbt_table_size) {
tbt = &(tbt_table[align_addr & (uint32_t)(tbt_table_size - 1)]);
if (tbt->addr != align_addr) {
return(0);
}
}
else {
int bank_num;
if (!mbp) {
mbp = tb_get_mbp(align_addr, &bank_num);
if(!mbp) {
return(0);
}
}
else {
bank_num = mbp - skyeye_config.mem.mem_banks;
}
if (!state->mem.tbt[bank_num]) {
return(0);
}
tbt = &(state->mem.tbt[bank_num][(align_addr - mbp->addr)/TB_LEN]);
}
save_align_addr = align_addr;
setdirty:
if (tbt->ted) {
tb_clear_cache(tbt);
tbt->ted = 0;
switch(skyeye_config.cpu->cpu_val & skyeye_config.cpu->cpu_mask){
case SA1100:
case SA1110:
mmu_wb_drain_all(state, (&state->mmu.u.sa_mmu.wb_t));
break;
case 0x41009200:
mmu_wb_drain_all(state, (&state->mmu.u.arm920t_mmu.wb_t));
break;
};
}
return(0);
}
int tb_insn_len_max = 0;
int
tb_insn_len_max_init(ARMul_State * state)
{
int dp_len = 0, other_len = 0;
//return if debug || irq || fiq || condition
if (op_begin.len > op_movl_Tx_im[0].len + sizeof(ARMword) + op_begin_test_T0.len) {
tb_insn_len_max += op_begin.len;
}
else {
tb_insn_len_max += op_movl_Tx_im[0].len + sizeof(ARMword) + op_begin_test_T0.len;
}
//end
tb_insn_len_max += op_return.len;
tb_insn_len_max += op_addpc.len;
//TEA_OUT(tb_insn_len_max += op_return.len);
//dp_len
{
int dp_head_len = 0;
int op_setcpsr_nzc_len = 0, op_setcpsr_nzc_setr15_len = 0, op_setcpsr_nzc_notsetr15_len = 0, op_setcpsr_nzc_setreg_len = 0;
int op_setcpsr_nzcv_len = 0, op_setcpsr_nzcv_setr15_len = 0, op_setcpsr_nzcv_notsetr15_len = 0, op_setcpsr_nzcv_setreg_len = 0;
int dp_tmp1;
//dp_head_len
{
int dp_head_imm_len = 0, dp_head_reg_len = 0;
//dp_head_imm_len
dp_head_imm_len += op_movl_Tx_im[1].len;
dp_head_imm_len += sizeof(ARMword);
if (op_logic_1_sc.len > op_logic_0_sc.len) {
dp_head_imm_len += op_logic_1_sc.len;
}
else {
dp_head_imm_len += op_logic_0_sc.len;
}
//dp_head_reg_len
{
int dp_head_reg_imm_len = 0, dp_head_reg_reg_len = 0;
dp_head_reg_len += op_movl_Tx_reg_array_maxlen[1];
//dp_head_reg_imm_len
//shift != 0
dp_head_reg_imm_len += op_shift_T1_im_sc_maxlen;
dp_head_reg_imm_len += op_set_cf.len;
dp_head_reg_imm_len += op_shift_T1_im_maxlen;
dp_head_reg_imm_len += sizeof(uint8_t);
//shift == 0
dp_tmp1 = op_movl_T2_T1.len;
dp_tmp1 += op_shift_T1_0_maxlen;
dp_tmp1 += op_shift_T2_0_sc_maxlen;
dp_tmp1 += op_set_cf.len;
//compare
if (dp_tmp1 > dp_head_reg_imm_len)
dp_head_reg_imm_len = dp_tmp1;
//dp_head_reg_reg_len
if (op_shift_T1_T0_sc_maxlen + op_set_cf.len > op_shift_T1_T0_maxlen) {
dp_head_reg_reg_len += op_shift_T1_T0_sc_maxlen + op_set_cf.len;
}
else {
dp_head_reg_reg_len += op_shift_T1_T0_maxlen;
}
dp_head_reg_reg_len += op_movl_Tx_reg_array_maxlen[0];
if (dp_head_reg_imm_len > dp_head_reg_reg_len) {
dp_head_reg_len += dp_head_reg_imm_len;
}
else {
dp_head_reg_len += dp_head_reg_reg_len;
}
}
if (dp_head_imm_len > dp_head_reg_len) {
dp_head_len = dp_head_imm_len;
}
else {
dp_head_len = dp_head_reg_len;
}
}
//op_setcpsr_nzc_len
op_setcpsr_nzc_len += op_logic_T0_sn.len;
//op_setcpsr_nzc_len += op_set_nf.len;
op_setcpsr_nzc_len += op_logic_T0_sz.len;
//op_setcpsr_nzc_len += op_set_zf.len;
//op_setcpsr_nzc_len += op_set_cf.len;
op_setcpsr_nzc_len += op_set_nzcf.len;
//op_setcpsr_nzcv_len
op_setcpsr_nzcv_len += op_logic_T0_sn.len;
//op_setcpsr_nzcv_len += op_set_nf.len;
op_setcpsr_nzcv_len += op_logic_T0_sz.len;
//op_setcpsr_nzcv_len += op_set_zf.len;
//op_setcpsr_nzcv_len += op_set_cf.len;
//op_setcpsr_nzcv_len += op_set_vf.len;
op_setcpsr_nzcv_len += op_set_nzcvf.len;
//op_setcpsr_nzc_setreg
op_setcpsr_nzc_notsetr15_len += op_setcpsr_nzc_len;
op_setcpsr_nzc_notsetr15_len += op_movl_reg_Tx_array_maxlen[0];
op_setcpsr_nzc_setr15_len += op_movl_reg_Tx_array_maxlen[0];
op_setcpsr_nzc_setr15_len += op_movl_Tx_im[2].len + sizeof(ARMword) + op_movl_trap_T2.len;
if (op_setcpsr_nzc_notsetr15_len > op_setcpsr_nzc_setr15_len) {
op_setcpsr_nzc_setreg_len += op_setcpsr_nzc_notsetr15_len;
}
else {
op_setcpsr_nzc_setreg_len += op_setcpsr_nzc_setr15_len;
}
//op_setcpsr_nzcv_setreg
op_setcpsr_nzcv_notsetr15_len += op_setcpsr_nzcv_len;
op_setcpsr_nzcv_notsetr15_len += op_movl_reg_Tx_array_maxlen[0];
op_setcpsr_nzcv_setr15_len += op_movl_reg_Tx_array_maxlen[0];
op_setcpsr_nzcv_setr15_len += op_movl_Tx_im[2].len + sizeof(ARMword) + op_movl_trap_T2.len;
if (op_setcpsr_nzcv_notsetr15_len > op_setcpsr_nzcv_setr15_len) {
op_setcpsr_nzcv_setreg_len += op_setcpsr_nzcv_notsetr15_len;
}
else {
op_setcpsr_nzcv_setreg_len += op_setcpsr_nzcv_setr15_len;
}
//mrs
if (op_mrs_T0_spsr.len > op_mrs_T0_cpsr.len) {
dp_len += op_mrs_T0_spsr.len;
}
else {
dp_len += op_mrs_T0_cpsr.len;
}
dp_len += op_movl_reg_Tx_array_maxlen[0];
TEA_OUT(printf("mrs insn's max len is %d\n", dp_len + tb_insn_len_max));
//msr
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_im[0].len + sizeof(ARMword);
if (op_msr_spsr_T0_T1.len > op_msr_cpsr_T0_T1.len) {
dp_tmp1 += op_msr_spsr_T0_T1.len;
}
else {
dp_tmp1 += op_msr_spsr_T0_T1.len;
}
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("msr insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//and
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
dp_tmp1 += op_andl_T0_T1.len;
dp_tmp1 += op_setcpsr_nzc_setreg_len;
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("and insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//eor
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
dp_tmp1 += op_eorl_T0_T1.len;
dp_tmp1 += op_setcpsr_nzc_setreg_len;
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("eor insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//sub
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
if (op_subl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len > op_subl_T0_T1.len + op_setcpsr_nzcv_setr15_len) {
dp_tmp1 += op_subl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len;
}
else {
dp_tmp1 += op_subl_T0_T1.len + op_setcpsr_nzcv_setr15_len;
}
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("sub insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//rsb
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
if (op_rsbl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len > op_rsbl_T0_T1.len + op_setcpsr_nzcv_setr15_len) {
dp_tmp1 += op_rsbl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len;
}
else {
dp_tmp1 += op_rsbl_T0_T1.len + op_setcpsr_nzcv_setr15_len;
}
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("rsb insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//add
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
if (op_addl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len > op_addl_T0_T1.len + op_setcpsr_nzcv_setr15_len) {
dp_tmp1 += op_addl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len;
}
else {
dp_tmp1 += op_addl_T0_T1.len + op_setcpsr_nzcv_setr15_len;
}
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("add insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//adc
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
if (op_adcl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len > op_adcl_T0_T1.len + op_setcpsr_nzcv_setr15_len) {
dp_tmp1 += op_adcl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len;
}
else {
dp_tmp1 += op_adcl_T0_T1.len + op_setcpsr_nzcv_setr15_len;
}
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("adc insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//sbc
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
if (op_sbcl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len > op_sbcl_T0_T1.len + op_setcpsr_nzcv_setr15_len) {
dp_tmp1 += op_sbcl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len;
}
else {
dp_tmp1 += op_sbcl_T0_T1.len + op_setcpsr_nzcv_setr15_len;
}
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("sbc insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//rsc
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
if (op_rscl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len > op_rscl_T0_T1.len + op_setcpsr_nzcv_setr15_len) {
dp_tmp1 += op_rscl_T0_T1_scv.len + op_setcpsr_nzcv_notsetr15_len;
}
else {
dp_tmp1 += op_rscl_T0_T1.len + op_setcpsr_nzcv_setr15_len;
}
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("rsc insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//tst
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
dp_tmp1 += op_andl_T0_T1.len;
dp_tmp1 += op_setcpsr_nzc_len;
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("tst insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
//teq
dp_tmp1 = 0;
dp_tmp1 += dp_head_len;
dp_tmp1 += op_movl_Tx_reg_array_maxlen[0];
dp_tmp1 += op_eorl_T0_T1.len;
dp_tmp1 += op_setcpsr_nzc_len;
if (dp_tmp1 > dp_len) {
dp_len = dp_tmp1;
}
TEA_OUT(printf("teq insn's max len is %d\n", dp_tmp1 + tb_insn_len_max));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -