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

📄 ldst.cpp

📁 RISC processor ARM-7 emulator
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

#if 0
void impl_st1_reg(IMPL_FORMALS)
{
	UInt32 offset = shifter_operand(IMPL_ARGS);
	UInt32 address;

	if (PFLD) /*preindex*/
		address = UFLD?RN+offset:RN-offset;
	else
		address = RN;

	if (BFLD)
		MEM_WRITE_BYTE(address, RD);
	else 
		MEM_WRITE_WORD(address, RD);

	if (!PFLD) 
		WRITE_REG(RNFLD, UFLD?RN+offset:RN-offset);
	else if (WFLD) 
		WRITE_REG(RNFLD, address);
}
#endif

/*p==0, b==0*/
void impl_st1_reg(IMPL_FORMALS)
{
	UInt32 offset = shifter_operand(IMPL_ARGS);
	UInt32 address;

	address = RN;
	MEM_WRITE_WORD(address, RD);
	WRITE_REG(RNFLD, UFLD?RN+offset:RN-offset);

	EMULATOR_STUB(st1_reg,inst);
}

/*p==1, b==0*/
void impl_st1_reg_p(IMPL_FORMALS)
{
	UInt32 offset = shifter_operand(IMPL_ARGS);
	UInt32 address;

	address = UFLD?RN+offset:RN-offset;
	MEM_WRITE_WORD(address, RD);
	if (WFLD) 
		WRITE_REG(RNFLD, address);

	EMULATOR_STUB(st1_reg_p,inst);
}

/*p==0, b==1*/
void impl_st1_reg_b(IMPL_FORMALS)
{
	UInt32 offset = shifter_operand(IMPL_ARGS);
	UInt32 address;

	address = RN;
	MEM_WRITE_BYTE(address, RD);
	WRITE_REG(RNFLD, UFLD?RN+offset:RN-offset);

	EMULATOR_STUB(st1_reg_b,inst);
}

/*p==1, b==1*/
void impl_st1_reg_pb(IMPL_FORMALS)
{
	UInt32 offset = shifter_operand(IMPL_ARGS);
	UInt32 address;

	address = UFLD?RN+offset:RN-offset;
	MEM_WRITE_BYTE(address, RD);
	if (WFLD) 
		WRITE_REG(RNFLD, address);

	EMULATOR_STUB(st1_reg_pb,inst);
}

void impl_st2_imm(IMPL_FORMALS)
{
	UInt32 offset = ((inst>>4) & 0xF0) | (inst & 0xF);
	UInt32 address, towrite;

	if (PFLD) /*preindex*/
		address = UFLD?RN+offset:RN-offset;
	else
		address = RN;

	if (address&0x1)
		towrite = 0xCCCCCCCC;	/*unpredictable*/
	else
		towrite = RD;

	MEM_WRITE_HALF_WORD(address, towrite);

	if (!PFLD) /*post index always updates*/
		WRITE_REG(RNFLD, UFLD?RN+offset:RN-offset);
	else if (WFLD) /*preindex and update*/
		WRITE_REG(RNFLD, address);

	EMULATOR_STUB(st2_imm,inst);
}

void impl_st2_reg(IMPL_FORMALS)
{
	UInt32 offset = RM;
	UInt32 address, towrite;

	if (PFLD) /*preindex*/
		address = UFLD?RN+offset:RN-offset;
	else
		address = RN;

	if (address&0x1)
		towrite = 0xCCCCCCCC;	/*unpredictable*/
	else
		towrite = RD;

	MEM_WRITE_HALF_WORD(address, towrite);

	if (!PFLD) 
		WRITE_REG(RNFLD, UFLD?RN+offset:RN-offset);
	else if (WFLD) 
		WRITE_REG(RNFLD, address);

	EMULATOR_STUB(st2_reg,inst);
}

void impl_swap(IMPL_FORMALS)
{
	UInt32 address = RN;
	UInt32 val = MEM_READ_WORD(address), towrite=RM;

	WRITE_REG(RDFLD, rotate_right(val, (address&0x3)<<3));
	MEM_WRITE_WORD(address, towrite);

	EMULATOR_STUB(swap,inst);
}

void impl_swap_byte(IMPL_FORMALS)
{
	UInt32 address = RN;
	UInt32 val = MEM_READ_BYTE(address);
	UInt8 towrite = RM;
	WRITE_REG(RDFLD, val);
	MEM_WRITE_BYTE(address, towrite);

	EMULATOR_STUB(swap_byte,inst);
}

/* Since ldm/stm were used almost only on the stack,
 * it is possible to shortcut page table lookup
 * by applying the similar method used in fetch.
 * However, the instruction frequency of ldm/stm is low and
 * the gain is only <=1%. To keep code clean, nothing is done.
 */
void impl_ldm(IMPL_FORMALS)
{
	UInt32 start_addr, end_addr, address, i;
	SInt32 j, pcount = popcount16(inst)*4;

	if (!PFLD && UFLD) {
		start_addr = RN;
		end_addr = RN + pcount - 4;
		if (WFLD) WRITE_REG(RNFLD, RN + pcount);
	}
	else if (PFLD && UFLD) {
		start_addr = RN+4;
		end_addr = RN + pcount;
		if (WFLD) WRITE_REG(RNFLD, RN + pcount);
	}
	else if (!PFLD && !UFLD) {
		start_addr = RN - pcount + 4;
		end_addr = RN;
		if (WFLD) WRITE_REG(RNFLD, RN - pcount);
	}
	else {
		start_addr = RN - pcount;
		end_addr = RN - 4;
		if (WFLD) WRITE_REG(RNFLD, RN - pcount);
	}

	/*ignore the last two bits of the address*/
	address = end_addr - (end_addr & 0x3);
	j = inst<<16; i=15;
	while (j) {
		if (j<0) {
			word_t val;

			/*WRITE_REG(i, MEM_READ_WORD(address));*/
		    val = MEM_READ_WORD(address);
			WRITE_REG(i, val);
			address -= 4;
		}
		j = j<<1; i--;
	}

	assert(start_addr-(start_addr&0x3) == address+4);
	if (BITn(inst, 15) & BITn(inst, 22))
		WRITE_CPSR(SPSR);

	EMULATOR_STUB(ldm,inst);
}

void impl_stm(IMPL_FORMALS)
{
	UInt32 start_addr, end_addr, address, i;
	SInt32 j, pcount = popcount16(inst)*4;

	if (!PFLD && UFLD) {
		start_addr = RN;
		end_addr = RN + pcount - 4;
		if (WFLD) WRITE_REG(RNFLD, RN + pcount);
	}
	else if (PFLD && UFLD) {
		start_addr = RN+4;
		end_addr = RN + pcount;
		if (WFLD) WRITE_REG(RNFLD, RN + pcount);
	}
	else if (!PFLD && !UFLD) {
		start_addr = RN - pcount + 4;;
		end_addr = RN;
		if (WFLD) WRITE_REG(RNFLD, RN - pcount);
	}
	else {
		start_addr = RN - pcount;
		end_addr = RN - 4;
		if (WFLD) WRITE_REG(RNFLD, RN - pcount);
	}

	/*ignore the last two bits of the address*/
	address = end_addr - (end_addr & 0x3);
	j = inst<<16; i=15;
	while (j) {
		if (j<0) {
			word_t val=READ_REG(i);
			MEM_WRITE_WORD(address, val);
			/*MEM_WRITE_WORD(address, READ_REG(i));*/
			address -= 4;
		}
		j = j<<1; i--;
	}
	assert(start_addr - (start_addr&0x3) == address+4);

	EMULATOR_STUB(stm,inst);
}


char *disasm_ldst1_imm(arm_inst_t inst, arm_addr_t addr, char *buf)
{
	buf += sprintf(buf, "%s%s%s%s %s, ",
		LFLD?"ldr":"str", arm_conditional[COND], BFLD?"b":"",
		(!PFLD&&WFLD)?"t":"", arm_regnames[RDFLD]);

	/*immediate offset*/
	if (PFLD) {
		buf += sprintf(buf, "[%s, #%s%d]",
			arm_regnames[RNFLD], UFLD?"":"-", inst&0xFFF);
		if (WFLD)
			buf += sprintf(buf, "!");
	}
	else {
		buf += sprintf(buf, "[%s], #%s%d",
			arm_regnames[RNFLD], UFLD?"":"-", inst&0xFFF);
	}
	buf += sprintf(buf, ";\n");
	return buf;
}

char *disasm_ldst1_reg(arm_inst_t inst, arm_addr_t addr, char *buf)
{
	UInt32 shift_imm = (inst>>7) & 0x01f;
	UInt8 type = (inst>>5) & 0x03;

	buf += sprintf(buf, "%s%s%s%s %s, ",
		LFLD?"ldr":"str", arm_conditional[COND], BFLD?"b":"",
		(!PFLD&&WFLD)?"t":"", arm_regnames[RDFLD]);

	/*register offset*/
	if (PFLD) {
		buf += sprintf(buf, "[%s, %s%s",
			arm_regnames[RNFLD], UFLD?"":"-", arm_regnames[RMFLD]);

		if (shift_imm==0 && type==0) 
			buf += sprintf(buf, "]");
		else if (shift_imm==0 && type==3)
			buf += sprintf(buf, ", rrx]");
		else
			buf += sprintf(buf, ", %s #%d]", arm_shift[type], shift_imm); 

		if (WFLD)
			buf += sprintf(buf, "!");
	}
	else {
		buf += sprintf(buf, "[%s], %s%s",
			arm_regnames[RNFLD], UFLD?"":"-", arm_regnames[RMFLD]);

		if (shift_imm==0 && type==3)
			buf += sprintf(buf, ", rrx");
		else if (shift_imm || type) 
			buf += sprintf(buf, ", %s #%d", arm_shift[type], shift_imm); 
	}

	buf += sprintf(buf, ";\n");
	return buf;
}

char *disasm_ldst2_imm(arm_inst_t inst, arm_addr_t addr, char *buf)
{
	UInt32 offset = ((inst>>4) & 0xF0) | (inst & 0xF);

	buf += sprintf(buf, "%s%s%s%s %s, ",
		LFLD?"ldr":"str", arm_conditional[COND], SIGN?"s":"", HFLD?"h":"b",
		arm_regnames[RDFLD]);

	/*immediate offset*/
	if (PFLD) {
		buf += sprintf(buf, "[%s, #%s%d]",
			arm_regnames[RNFLD], UFLD?"":"-", offset);
		if (WFLD)
			buf += sprintf(buf, "!");
	}
	else {
		buf += sprintf(buf, "[%s], #%s%d",
			arm_regnames[RNFLD], UFLD?"":"-", offset);
	}
	buf += sprintf(buf, ";\n");
	return buf;
}

char *disasm_ldst2_reg(arm_inst_t inst, arm_addr_t addr, char *buf)
{
	buf += sprintf(buf, "%s%s%s%s %s, ",
		LFLD?"ldr":"str", arm_conditional[COND], SIGN?"s":"", HFLD?"h":"b",
		arm_regnames[RDFLD]);

	/*immediate offset*/
	if (PFLD) {
		buf += sprintf(buf, "[%s, %s%s]",
			arm_regnames[RNFLD], UFLD?"":"-", arm_regnames[RMFLD]);
		if (WFLD)
			buf += sprintf(buf, "!");
	}
	else {
		buf += sprintf(buf, "[%s], %s%s",
			arm_regnames[RNFLD], UFLD?"":"-", arm_regnames[RMFLD]);
	}
	buf += sprintf(buf, ";\n");
	return buf;
}
	
char *disasm_swap(arm_inst_t inst, arm_addr_t addr, char *buf)
{
    buf += sprintf(buf, "swp%s %s, %s, [%s];\n",
		arm_conditional[COND],
		arm_regnames[RDFLD], arm_regnames[RMFLD], arm_regnames[RNFLD]);
    return buf;
}

char *disasm_swap_byte(arm_inst_t inst, arm_addr_t addr, char *buf)
{
    buf += sprintf(buf, "swp%sb %s, %s, [%s];\n",
		arm_conditional[COND],
		arm_regnames[RDFLD], arm_regnames[RMFLD], arm_regnames[RNFLD]);
    return buf;
}

char *disasm_ldstm(arm_inst_t inst, arm_addr_t addr, char *buf)
{
	UInt32 i, first = 1;
	buf += sprintf(buf, "%s%s%s%s %s%s, {",
		LFLD?"ldm":"stm", arm_conditional[COND], UFLD?"i":"d", PFLD?"b":"a",
		arm_regnames[RNFLD], WFLD?"!":"");

	for (i = 0; i<16; i++) {
		if ((1<<i) & inst) {
			buf += sprintf(buf, "%s%s", first?"":", ", arm_regnames[i]);
			first = 0;
		}
	}
	buf += sprintf(buf, "}");

	if (BITn(inst,22))
		buf += sprintf(buf, "^");

	buf += sprintf(buf, ";\n");
	return buf;
}

⌨️ 快捷键说明

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