📄 arm-dp.cpp
字号:
/*************************************************************************** DSemu - The Next Generation ** Portable ARM cores: Common: Data processing opcodes [arm-dp.cpp] ** Copyright Imran Nazar, 2005; released under the BSD public licence. ***************************************************************************/// __ARMHDR is set by the Makefile to be either arm7tdmi.h or arm9es.h#include __ARMHDR#include "datadefs.h"#include "armmasks.h"#include "armhelp.h"//---Addressing modes------------------------------------------------------// BUGBUG: Doubling of Rm15hack in DP addressing is GBA-specific// ACK: Stephen Stair (DP addressing, _RN would be overwritten if Rn==Rd)#define addrDPrn reg.tmp2=_RN+Rn15hack#define addrDPimm \ reg.tmp1 = _ROR(reg.curop&MSK_IMM8, (reg.curop&MSK_RS)>>7); \ reg.tmpc = (reg.curop&MSK_RS)?(reg.tmp1>>31):reg.flags[FLAG_C]#define addrDPreg \ reg.tmp1 = _RM+Rm15hack; \ reg.tmpc = reg.flags[FLAG_C]#define addrDPlli \ reg.tmp1 = (_RM+Rm15hack) << helpDPshfti; \ reg.tmpc = (helpDPshfti)?(((_RM+Rm15hack)&(1<<(32-helpDPshfti)))?1:0):reg.flags[FLAG_C]#define addrDPllr \ reg.tmp1 = (_RM+Rm15hack+Rm15hack) << helpDPshftr; \ reg.tmpc = helpDPshftr \ ?((helpDPshftr>32)?0:(((_RM+Rm15hack+Rm15hack)&(1<<(32-helpDPshftr)))?1:0)) \ :reg.flags[FLAG_C]#define addrDPlri \ if(!helpDPshfti) reg.tmp1=0; else \ reg.tmp1 = (_RM+Rm15hack) >> helpDPshfti; \ reg.tmpc = helpDPshfti?(((_RM+Rm15hack)&(1<<(helpDPshfti-1)))?1:0):(_RM>>31)#define addrDPlrr \ reg.tmp1 = (helpDPshftr>=32)?0:((_RM+Rm15hack+Rm15hack) >> helpDPshftr); \ reg.tmpc = helpDPshftr \ ?((helpDPshftr>32)?0:(((_RM+Rm15hack+Rm15hack)&(1<<(helpDPshftr-1)))?1:0)) \ :reg.flags[FLAG_C]#define addrDPari \ if(!helpDPshfti) reg.tmp1=((_RM+Rm15hack)&0x80000000)?0xFFFFFFFF:0; \ else reg.tmp1 = (signed)(_RM+Rm15hack) >> helpDPshfti; \ reg.tmpc = helpDPshfti?(((_RM+Rm15hack)&(1<<(helpDPshfti-1)))?1:0):((_RM+Rm15hack)>>31)#define addrDParr \ if(helpDPshftr>=32) reg.tmp1=((_RM+Rm15hack+Rm15hack)&0x80000000)?~0:0; \ else reg.tmp1 = (signed)(_RM+Rm15hack+Rm15hack) >> helpDPshftr; \ reg.tmpc = helpDPshftr \ ?((helpDPshftr>=32)?((_RM+Rm15hack+Rm15hack)>>31):(((_RM+Rm15hack+Rm15hack)&(1<<(helpDPshftr-1)))?1:0)) \ :reg.flags[FLAG_C]#define addrDPrri \ reg.tmp1 = (helpDPshfti)?_ROR((_RM+Rm15hack), helpDPshfti):(((_RM+Rm15hack)>>1)|(reg.flags[FLAG_C]<<31)); \ reg.tmpc = helpDPshfti?(((_RM+Rm15hack)&(1<<(helpDPshfti-1)))?1:0):(_RM&1)#define addrDPrrr \ reg.tmp1 = _ROR(_RM+Rm15hack+Rm15hack, (helpDPshftr&31)); \ reg.tmpc = helpDPshftr \ ?((helpDPshftr&31)?(((_RM+Rm15hack+Rm15hack)&(1<<(((helpDPshftr&31)-1))))?1:0):((_RM+Rm15hack+Rm15hack)>>31)) \ :reg.flags[FLAG_C]//---Opcode actions-------------------------------------------------------- #define opAND _RD = reg.tmp2 & reg.tmp1#define opEOR _RD = reg.tmp2 ^ reg.tmp1#define opSUB _RD = reg.tmp2 - reg.tmp1#define opRSB _RD = reg.tmp1 - reg.tmp2#define opADD _RD = reg.tmp2 + reg.tmp1#define opADC reg.tmp1 += reg.flags[FLAG_C]; _RD = reg.tmp2 + reg.tmp1#define opSBC reg.tmp1 += (1-reg.flags[FLAG_C]); _RD = reg.tmp2 - reg.tmp1#define opRSC reg.tmp1 -= (1-reg.flags[FLAG_C]); _RD = reg.tmp1 - reg.tmp2#define opTST reg.tmp3 = reg.tmp2 & reg.tmp1#define opTEQ reg.tmp3 = reg.tmp2 ^ reg.tmp1#define opCMP reg.tmp3 = reg.tmp2 - reg.tmp1#define opCMN reg.tmp3 = reg.tmp2 + reg.tmp1#define opORR _RD = reg.tmp2 | reg.tmp1#define opMOV _RD = reg.tmp1#define opBIC _RD = reg.tmp2 & (~reg.tmp1)#define opMVN _RD = ~reg.tmp1//---Flag setting----------------------------------------------------------// ACK: Mike Murphy [emu7800.sf.net] (V flag setting inspired by M6502.cs) #define cpsrDP \ if(((reg.curop&MSK_RD)>>SHFT_RD)==15) { \ /*if((reg.curmode != MODE_USR) && (reg.curmode != MODE_SYS)) opUNP();*/ \ reg.cpsr=reg.spsr[reg.curmode]; \ cpsrSplit(); \ } #define flagDPnz \ reg.flags[FLAG_N] = _RD>>31; \ reg.flags[FLAG_Z] = (_RD)?0:1; \ reg.flags[FLAG_C] = reg.tmpc#define flagDPnzTST \ reg.flags[FLAG_N] = reg.tmp3>>31; \ reg.flags[FLAG_Z] = (reg.tmp3)?0:1#define flagDPcBIT \ reg.flags[FLAG_C] = reg.tmpc#define flagDPvADD reg.flags[FLAG_V]=( (reg.tmp2^_RD) & (~(reg.tmp1^reg.tmp2)) & 0x80000000)?1:0#define flagDPvCMN reg.flags[FLAG_V]=( (reg.tmp2^reg.tmp3) & (~(reg.tmp1^reg.tmp2)) & 0x80000000)?1:0#define flagDPvSUB reg.flags[FLAG_V]=( (~(reg.tmp1^_RD)) & (reg.tmp1^reg.tmp2) & 0x80000000)?1:0#define flagDPvRSB reg.flags[FLAG_V]=( (~(reg.tmp2^_RD)) & (reg.tmp1^reg.tmp2) & 0x80000000)?1:0#define flagDPvCMP reg.flags[FLAG_V]=( (~(reg.tmp1^reg.tmp3)) & (reg.tmp1^reg.tmp2) & 0x80000000)?1:0//#define flagDPvSUB reg.flags[FLAG_V]=(((reg.tmp2&(~reg.tmp1)&(~_RD))|((~reg.tmp2)®.tmp1&_RD))&0x80000000)?1:0//#define flagDPvRSB reg.flags[FLAG_V]=(((reg.tmp1&(~reg.tmp2)&(~_RD))|((~reg.tmp1)®.tmp2&_RD))&0x80000000)?1:0//#define flagDPvCMP reg.flags[FLAG_V]=(((reg.tmp1&(~reg.tmp2)&(~reg.tmp3))|((~reg.tmp1)®.tmp2®.tmp3))&0x80000000)?1:0 #define flagDPcADD reg.flags[FLAG_C]=(((_RD<reg.tmp2)||(_RD<reg.tmp1))?1:0)#define flagDPcCMN reg.flags[FLAG_C]=(((reg.tmp3<reg.tmp2)||(reg.tmp3<reg.tmp1))?1:0)//#define flagDPcSUB reg.flags[FLAG_C]=((reg.tmp1>reg.tmp2)?0:1)//#define flagDPcRSB reg.flags[FLAG_C]=((reg.tmp1<reg.tmp2)?0:1)//#define flagDPcCMP flagDPcSUB#define flagDPcSUB reg.flags[FLAG_C]=(((reg.tmp2&(~reg.tmp1))|(reg.tmp2&(~_RD))|((~reg.tmp1)&(~_RD)))&0x80000000)?1:0#define flagDPcRSB reg.flags[FLAG_C]=(((reg.tmp1&(~reg.tmp2))|(reg.tmp1&(~_RD))|((~reg.tmp2)&(~_RD)))&0x80000000)?1:0#define flagDPcCMP reg.flags[FLAG_C]=(((reg.tmp1&(~reg.tmp2))|(reg.tmp1&(~reg.tmp3))|((~reg.tmp2)&(~reg.tmp3)))&0x80000000)?1:0 // Once the defines are in place, it's a simple matter of tacking// addressing, opcode and flagset together. A few hundred times. OPC opANDlli() { addrDPrn; addrDPlli; opAND; return 2; }OPC opANDllr() { addrDPrn; addrDPllr; opAND; return 2; }OPC opANDlri() { addrDPrn; addrDPlri; opAND; return 2; }OPC opANDlrr() { addrDPrn; addrDPlrr; opAND; return 2; }OPC opANDari() { addrDPrn; addrDPari; opAND; return 2; }OPC opANDarr() { addrDPrn; addrDParr; opAND; return 2; }OPC opANDrri() { addrDPrn; addrDPrri; opAND; return 2; }OPC opANDrrr() { addrDPrn; addrDPrrr; opAND; return 2; }OPC opANDimm() { addrDPrn; addrDPimm; opAND; return 1; }OPC opEORlli() { addrDPrn; addrDPlli; opEOR; return 2; }OPC opEORllr() { addrDPrn; addrDPllr; opEOR; return 2; }OPC opEORlri() { addrDPrn; addrDPlri; opEOR; return 2; }OPC opEORlrr() { addrDPrn; addrDPlrr; opEOR; return 2; }OPC opEORari() { addrDPrn; addrDPari; opEOR; return 2; }OPC opEORarr() { addrDPrn; addrDParr; opEOR; return 2; }OPC opEORrri() { addrDPrn; addrDPrri; opEOR; return 2; }OPC opEORrrr() { addrDPrn; addrDPrrr; opEOR; return 2; }OPC opEORimm() { addrDPrn; addrDPimm; opEOR; return 1; }OPC opSUBlli() { addrDPrn; addrDPlli; opSUB; return 2; }OPC opSUBllr() { addrDPrn; addrDPllr; opSUB; return 2; }OPC opSUBlri() { addrDPrn; addrDPlri; opSUB; return 2; }OPC opSUBlrr() { addrDPrn; addrDPlrr; opSUB; return 2; }OPC opSUBari() { addrDPrn; addrDPari; opSUB; return 2; }OPC opSUBarr() { addrDPrn; addrDParr; opSUB; return 2; }OPC opSUBrri() { addrDPrn; addrDPrri; opSUB; return 2; }OPC opSUBrrr() { addrDPrn; addrDPrrr; opSUB; return 2; }OPC opSUBimm() { addrDPrn; addrDPimm; opSUB; return 1; }OPC opRSBlli() { addrDPrn; addrDPlli; opRSB; return 2; }OPC opRSBllr() { addrDPrn; addrDPllr; opRSB; return 2; }OPC opRSBlri() { addrDPrn; addrDPlri; opRSB; return 2; }OPC opRSBlrr() { addrDPrn; addrDPlrr; opRSB; return 2; }OPC opRSBari() { addrDPrn; addrDPari; opRSB; return 2; }OPC opRSBarr() { addrDPrn; addrDParr; opRSB; return 2; }OPC opRSBrri() { addrDPrn; addrDPrri; opRSB; return 2; }OPC opRSBrrr() { addrDPrn; addrDPrrr; opRSB; return 2; }OPC opRSBimm() { addrDPrn; addrDPimm; opRSB; return 1; }OPC opADDlli() { addrDPrn; addrDPlli; opADD; return 2; }OPC opADDllr() { addrDPrn; addrDPllr; opADD; return 2; }OPC opADDlri() { addrDPrn; addrDPlri; opADD; return 2; }OPC opADDlrr() { addrDPrn; addrDPlrr; opADD; return 2; }OPC opADDari() { addrDPrn; addrDPari; opADD; return 2; }OPC opADDarr() { addrDPrn; addrDParr; opADD; return 2; }OPC opADDrri() { addrDPrn; addrDPrri; opADD; return 2; }OPC opADDrrr() { addrDPrn; addrDPrrr; opADD; return 2; }OPC opADDimm() { addrDPrn; addrDPimm; opADD; return 1; }OPC opADClli() { addrDPrn; addrDPlli; opADC; return 2; }OPC opADCllr() { addrDPrn; addrDPllr; opADC; return 2; }OPC opADClri() { addrDPrn; addrDPlri; opADC; return 2; }OPC opADClrr() { addrDPrn; addrDPlrr; opADC; return 2; }OPC opADCari() { addrDPrn; addrDPari; opADC; return 2; }OPC opADCarr() { addrDPrn; addrDParr; opADC; return 2; }OPC opADCrri() { addrDPrn; addrDPrri; opADC; return 2; }OPC opADCrrr() { addrDPrn; addrDPrrr; opADC; return 2; }OPC opADCimm() { addrDPrn; addrDPimm; opADC; return 1; }OPC opSBClli() { addrDPrn; addrDPlli; opSBC; return 2; }OPC opSBCllr() { addrDPrn; addrDPllr; opSBC; return 2; }OPC opSBClri() { addrDPrn; addrDPlri; opSBC; return 2; }OPC opSBClrr() { addrDPrn; addrDPlrr; opSBC; return 2; }OPC opSBCari() { addrDPrn; addrDPari; opSBC; return 2; }OPC opSBCarr() { addrDPrn; addrDParr; opSBC; return 2; }OPC opSBCrri() { addrDPrn; addrDPrri; opSBC; return 2; }OPC opSBCrrr() { addrDPrn; addrDPrrr; opSBC; return 2; }OPC opSBCimm() { addrDPrn; addrDPimm; opSBC; return 1; }OPC opRSClli() { addrDPrn; addrDPlli; opRSC; return 2; }OPC opRSCllr() { addrDPrn; addrDPllr; opRSC; return 2; }OPC opRSClri() { addrDPrn; addrDPlri; opRSC; return 2; }OPC opRSClrr() { addrDPrn; addrDPlrr; opRSC; return 2; }OPC opRSCari() { addrDPrn; addrDPari; opRSC; return 2; }OPC opRSCarr() { addrDPrn; addrDParr; opRSC; return 2; }OPC opRSCrri() { addrDPrn; addrDPrri; opRSC; return 2; }OPC opRSCrrr() { addrDPrn; addrDPrrr; opRSC; return 2; }OPC opRSCimm() { addrDPrn; addrDPimm; opRSC; return 1; }OPC opORRlli() { addrDPrn; addrDPlli; opORR; return 2; }OPC opORRllr() { addrDPrn; addrDPllr; opORR; return 2; }OPC opORRlri() { addrDPrn; addrDPlri; opORR; return 2; }OPC opORRlrr() { addrDPrn; addrDPlrr; opORR; return 2; }OPC opORRari() { addrDPrn; addrDPari; opORR; return 2; }OPC opORRarr() { addrDPrn; addrDParr; opORR; return 2; }OPC opORRrri() { addrDPrn; addrDPrri; opORR; return 2; }OPC opORRrrr() { addrDPrn; addrDPrrr; opORR; return 2; }OPC opORRimm() { addrDPrn; addrDPimm; opORR; return 1; }OPC opMOVlli() { addrDPrn; addrDPlli; opMOV; return 2; }OPC opMOVllr() { addrDPrn; addrDPllr; opMOV; return 2; }OPC opMOVlri() { addrDPrn; addrDPlri; opMOV; return 2; }OPC opMOVlrr() { addrDPrn; addrDPlrr; opMOV; return 2; }OPC opMOVari() { addrDPrn; addrDPari; opMOV; return 2; }OPC opMOVarr() { addrDPrn; addrDParr; opMOV; return 2; }OPC opMOVrri() { addrDPrn; addrDPrri; opMOV; return 2; }OPC opMOVrrr() { addrDPrn; addrDPrrr; opMOV; return 2; }OPC opMOVimm() { addrDPrn; addrDPimm; opMOV; return 1; }OPC opBIClli() { addrDPrn; addrDPlli; opBIC; return 2; }OPC opBICllr() { addrDPrn; addrDPllr; opBIC; return 2; }OPC opBIClri() { addrDPrn; addrDPlri; opBIC; return 2; }OPC opBIClrr() { addrDPrn; addrDPlrr; opBIC; return 2; }OPC opBICari() { addrDPrn; addrDPari; opBIC; return 2; }OPC opBICarr() { addrDPrn; addrDParr; opBIC; return 2; }OPC opBICrri() { addrDPrn; addrDPrri; opBIC; return 2; }OPC opBICrrr() { addrDPrn; addrDPrrr; opBIC; return 2; }OPC opBICimm() { addrDPrn; addrDPimm; opBIC; return 1; }OPC opMVNlli() { addrDPrn; addrDPlli; opMVN; return 2; }OPC opMVNllr() { addrDPrn; addrDPllr; opMVN; return 2; }OPC opMVNlri() { addrDPrn; addrDPlri; opMVN; return 2; }OPC opMVNlrr() { addrDPrn; addrDPlrr; opMVN; return 2; }OPC opMVNari() { addrDPrn; addrDPari; opMVN; return 2; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -