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

📄 arm.isa

📁 arm的模拟器
💻 ISA
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************    Copyright (C) 2002 - 2007 Wei Qin    See file COPYING for more information.    This program is free software; you can redistribute it and/or modify        it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, 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 of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.*************************************************************************//************************************************************************** Note: when specifying an instruction, the statement that may modify the program counter must be at the end. Failing to follow the rule causes unpredictable outcome for compiled simulation. ARM Reference Manual states that the base register Rn of memory instructions should not be R15. Otherwise the result is unpredictable. Therefore an update to the base register can be an exception to the rule. Check page A2-17 for details. A second issue related to compiled simulation is the handling of self-modifying code (SMC). If a memory write by a compiled instruction modifies a compiled address, it should abort immediately (before modifying memory) to the main loop, which will then unload the DLL containing the modified address. The instruction will then restart. Aborting immediately is necessary since the modified address may be in the same DLL as the instruction, or may even be the instruction itself. However, aborting immediately is not easy. Some instructions have side-effects that need to roll back before they can abort, such as ldt, sdt, ldm2, etc. To solve the problem, the interpretation code should defer the SMC abort to the same point where regular data abort is handled. A convenient way is to generate a special artificial SMC fault in MMU_WRITE_* macros. The fault will be caught by ABORT and will not cause raise_exception(v) to be called.**************************************************************************/field {	cond:4;	rn:4;	rd:4;	rs:4;	rm:4;	rotate:4;	shift_imm:5;	field_mask:4;		imm4_1:4;	imm4_2:4;	imm8:8;	imm12:12;	imm24:24;	ufld:1;	wfld:1;	abit:1;	reg_mask:16;	reg_mask2:15;	cp_num:4;	x_bit:1;	y_bit:1;}var {	op1:uint32_t;	op2:uint32_t;	val32:uint32_t;	tmp32:uint32_t;	rslt8:uint8_t;	rslt16:uint16_t;	rslt32:uint32_t;	rslt64:uint64_t;	address:uint32_t;	offset:uint32_t;	start_addr:uint32_t;	base_addr:uint32_t;	pcount:uint32_t;	iterator:uint32_t;	carry:uint32_t;	overflow:uint32_t;	current_mode:cpu_mode_t;	fault:mmu_fault_t;	cpab:uint32_t;}group rotate_imm32{op imm_mode1(0000:imm8) {execute="$imm8$"}op rot_mode1(rotate:imm8) {execute="(($imm8$>>($rotate$<<1))|($imm8$<<(32-($rotate$<<1))))"}}group rotate_imm32_s{op imm_mode1_s(0000:imm8) {	execute="(carry=C_FLAG,$imm8$)"}op rot_mode1_s(rotate:imm8) {	execute="(rslt32=($imm8$>>($rotate$<<1))|($imm8$<<(32-($rotate$<<1))), carry=BIT31(rslt32), rslt32)"}}group shifts {group imm_shifts{op lsl_mode2(shift_imm:00:0:rm) {	execute="(READ_REG($rm$)<<$shift_imm$)"}op zero_mode2(00000:01:0:----) {	execute="0"}op lsr_mode2(shift_imm:01:0:rm) {	execute="(READ_REG($rm$)>>$shift_imm$)"}op sign_mode2(00000:10:0:rm) {	execute="(BIT31(READ_REG($rm$))?~0:0)"}op asr_mode2(shift_imm:10:0:rm) {	execute="((int32_t)(READ_REG($rm$))>>$shift_imm$)"}op rrx_mode2(00000:11:0:rm) {	execute="((READ_REG($rm$)>>1)|(C_FLAG<<31))"}op ror_mode2(shift_imm:11:0:rm) {	execute="(val32=READ_REG($rm$), (val32>>$shift_imm$)|(val32<<(32-$shift_imm$)))"}}group reg_shifts{op lsl_mode3(rs:0:00:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), (tmp32<32)?(val32<<tmp32):0)"}op lsr_mode3(rs:0:01:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), (tmp32<32)?(val32>>tmp32):0)"}op asr_mode3(rs:0:10:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), (int32_t)val32>>(tmp32<32?tmp32:31))"}op ror_mode3(rs:0:11:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), (val32>>(tmp32&0x1f))|(val32<<(32-(tmp32&0x1f))))"}} /* reg_shifts */} /* shifts */group shifts_s{group imm_shifts_s{op lsz_mode2_s(00000:00:0:rm) {	execute="(carry=C_FLAG, READ_REG($rm$))"}op lsl_mode2_s(shift_imm:00:0:rm) {	execute="(val32=READ_REG($rm$), carry=BITn(val32, 32-$shift_imm$), val32<<$shift_imm$)"}op zero_mode2_s(00000:01:0:rm) {	execute="(carry=BIT31(READ_REG($rm$)), 0)"}op lsr_mode2_s(shift_imm:01:0:rm) {	execute="(val32=READ_REG($rm$), carry=BITn(val32, $shift_imm$-1), val32>>$shift_imm$)"}op sign_mode2_s(00000:10:0:rm) {	execute="(val32=READ_REG($rm$), carry=BIT31(val32), BIT31(val32)?~0:0)"}op asr_mode2_s(shift_imm:10:0:rm) {	execute="(val32=READ_REG($rm$), carry=BITn(val32, $shift_imm$-1), (int32_t)val32>>$shift_imm$)"}op rrx_mode2_s(00000:11:0:rm) {	execute="(val32=READ_REG($rm$), carry=BIT0(val32), (val32>>1)|(C_FLAG<<31))"}op ror_mode2_s(shift_imm:11:0:rm) {	execute="(val32=READ_REG($rm$), carry=BITn(val32, $shift_imm$-1), (val32>>$shift_imm$)|(val32<<(32-$shift_imm$)))"}}group reg_shifts_s{op lsl_mode3_s(rs:0:00:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), carry=(tmp32==0)?C_FLAG:((tmp32>32)?0:BITn(val32,32-val32)), (tmp32<32)?(val32<<tmp32):0)"}op lsr_mode3_s(rs:0:01:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), carry=(tmp32==0)?C_FLAG:((tmp32>32)?0:BITn(val32,tmp32-1)), (tmp32<32)?(val32>>tmp32):0)"}op asr_mode3_s(rs:0:10:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), carry=(tmp32==0)?C_FLAG:((tmp32>31)?BIT31(val32):BITn(val32,tmp32-1)), (int32_t)val32>>(tmp32<32?tmp32:31))"}op ror_mode3_s(rs:0:11:1:rm) {	execute="(tmp32=READ_REG($rs$)&0xFF, val32=READ_REG($rm$), carry=(tmp32==0)?C_FLAG:((tmp32&0x1f==0)?BIT31(val32):BITn(val32,(tmp32&0x1f)-1)), (val32>>(tmp32&0x1f))|(val32<<(32-(tmp32&0x1f))))"}}} /*shifts_s */group ldm_mode1 {op ldm1_000(000:01:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount + 4;"}op ldm1_001(000:11:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount + 4;	WRITE_REG($rn$, base_addr - pcount);"}op ldm1_010(010:01:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr;"}op ldm1_011(010:11:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr;	WRITE_REG($rn$, base_addr + pcount);"}op ldm1_100(100:01:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount;"}op ldm1_101(100:11:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount;	WRITE_REG($rn$, base_addr - pcount);"}op ldm1_110(110:01:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr + 4;"}op ldm1_111(110:11:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr + 4;	WRITE_REG($rn$, base_addr + pcount);"}} /* ldm_mode1 */group ldm_mode2 {op ldm2_000(001:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr - pcount + 4;"}op ldm2_010(011:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr;"}op ldm2_100(101:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr - pcount;"}op ldm2_110(111:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr + 4;"}} /* ldm_mode2 */group ldm_mode3 {op ldm3_000(001:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr - pcount + 4;"}op ldm3_001(001:11:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr - pcount + 4;	WRITE_REG($rn$, base_addr - pcount);"}op ldm3_010(011:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr;"}op ldm3_011(011:11:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr;	WRITE_REG($rn$, base_addr + pcount);"}op ldm3_100(101:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr - pcount;"}op ldm3_101(101:11:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr - pcount;	WRITE_REG($rn$, base_addr - pcount);"}op ldm3_110(111:01:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr + 4;"}op ldm3_111(111:11:rn) {execute = "	base_addr = READ_REG($rn$);		start_addr = base_addr + 4;	WRITE_REG($rn$, base_addr + pcount);"}} /* ldm_mode3 */group stm_mode1 {op stm1_000(000:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount + 4;"}op stm1_001(000:10:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount + 4;	WRITE_REG($rn$, base_addr - pcount);"}op stm1_010(010:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr;"}op stm1_011(010:10:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr;	WRITE_REG($rn$, base_addr + pcount);"}op stm1_100(100:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount;"}op stm1_101(100:10:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount;	WRITE_REG($rn$, base_addr - pcount);"}op stm1_110(110:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr + 4;"}op stm1_111(110:10:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr + 4;	WRITE_REG($rn$, base_addr + pcount);"}} /* stm_mode1 */group stm_mode2 {op stm2_000(001:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount + 4;"}op stm2_010(011:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr;"}op stm2_100(101:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr - pcount;"}op stm2_110(111:00:rn) {execute = "	base_addr = READ_REG($rn$);	start_addr = base_addr + 4;"}} /* stm_mode2 */group ldc_mode1 {op ldc1_01(01-01:rn){execute = "	address = READ_REG($rn$);"}op ldc1_10(10-01:rn){execute = "	address = READ_REG($rn$) - (offset << 2);"}op ldc1_11(11-01:rn){execute = "	address = READ_REG($rn$) + (offset << 2);"}} /* ldc_mode1 */group ldc_mode2 {op ldc2_00(00-11){execute = "	start_addr = base_addr;	address = base_addr - (offset << 2);"}op ldc2_01(01-11){execute = "	start_addr = base_addr;	address = base_addr + (offset << 2);"}op ldc2_10(10-11){execute = "	start_addr = address = base_addr - (offset << 2);"}op ldc2_11(11-11){execute = "	start_addr = address = base_addr + (offset << 2);"}} /* ldc_mode2 */group stc_mode1 {op stc1_01(01-00:rn){execute = "	address = READ_REG($rn$);"}op stc1_10(10-00:rn){execute = "	address = READ_REG($rn$) - (offset << 2);"}op stc1_11(11-00:rn){execute = "	address = READ_REG($rn$) + (offset << 2);"}} /* stc_mode1 */group stc_mode2 {op stc2_00(00-10){execute = "	start_addr = base_addr;	address = base_addr - (offset << 2);"}op stc2_01(01-10){execute = "	start_addr = base_addr;	address = base_addr + (offset << 2);"}op stc2_10(10-10){execute = "	start_addr = address = base_addr - (offset << 2);"}op stc2_11(11-10){execute = "	start_addr = address = base_addr + (offset << 2);"}} /* stc_mode2 */group root{op movi(----00111010----:rd:rotate_imm32){execute="	WRITE_REG($rd$, $rotate_imm32$);"}op movis(----00111011----:rd:rotate_imm32_s){execute="	rslt32 = $rotate_imm32_s$;	if ($rd$==15)		WRITE_CPSR(SPSR);	else		ASGN_NZC(rslt32, carry);	WRITE_REG($rd$, rslt32);"}op mov(----00011010----:rd:shifts){execute="	WRITE_REG($rd$, $shifts$);"}op movs(----00011011----:rd:shifts_s){execute="	rslt32 = $shifts_s$;	if ($rd$==15)    	WRITE_CPSR(SPSR);	else		ASGN_NZC(rslt32, carry);	WRITE_REG($rd$, rslt32);"}op mvni(----00111110----:rd:rotate_imm32){execute="	WRITE_REG($rd$, ~$rotate_imm32$);"}op mvnis(----00111111----:rd:rotate_imm32_s){execute="	rslt32 = ~$rotate_imm32_s$;	if ($rd$==15)		WRITE_CPSR(SPSR);	else		ASGN_NZC(rslt32, carry);	WRITE_REG($rd$, rslt32);"}op mvn(----00011110----:rd:shifts){execute="	WRITE_REG($rd$, ~$shifts$);"}op mvns(----00011111----:rd:shifts_s){execute="	rslt32 = ~$shifts_s$;    if ($rd$==15)        WRITE_CPSR(SPSR);    else		ASGN_NZC(rslt32, carry);	WRITE_REG($rd$, rslt32);"}op addi(----00101000:rn:rd:rotate_imm32) {execute="	WRITE_REG($rd$, READ_REG($rn$) + $rotate_imm32$);"}op addis(----00101001:rn:rd:rotate_imm32) {execute="	tmp32 = $rotate_imm32$;	val32  = READ_REG($rn$);	rslt32 = val32 + tmp32;    if ($rd$==15)        WRITE_CPSR(SPSR);    else		ASGN_NZCV(rslt32, rslt32<val32, (val32^tmp32^-1) & (val32^rslt32));	WRITE_REG($rd$, rslt32);"}op add(----00001000:rn:rd:shifts) {execute="	WRITE_REG($rd$, READ_REG($rn$) + $shifts$);"}op adds(----00001001:rn:rd:shifts) {execute="	tmp32 = $shifts$;	val32  = READ_REG($rn$);	rslt32 = val32 + tmp32;    if ($rd$==15)        WRITE_CPSR(SPSR);    else		ASGN_NZCV(rslt32, rslt32<val32, (val32^tmp32^-1) & (val32^rslt32));	WRITE_REG($rd$, rslt32);"}op adci(----00101010:rn:rd:rotate_imm32) {execute="	WRITE_REG($rd$, READ_REG($rn$) + $rotate_imm32$ + C_FLAG);"}op adcis(----00101011:rn:rd:rotate_imm32) {execute="	tmp32  = $rotate_imm32$;	val32  = READ_REG($rn$);	if (C_FLAG) {		rslt32 = tmp32+val32+1;		carry = rslt32 <= val32;	}	else {		rslt32 = tmp32+val32;		carry = rslt32 < val32;	}

⌨️ 快捷键说明

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