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

📄 tb.c

📁 这是Skyeye 0.9 版本的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
					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 + -