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

📄 arm9es-opcodes.cpp

📁 一个任天堂掌上游戏机NDS的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** DSemu - The Next Generation                                             ** Portable ARM9ES core: ARM9-specific opcodes [arm9es-opcodes.cpp]        ** Copyright Imran Nazar, 2005; released under the BSD public licence.     ***************************************************************************/#include "arm9es.h"#include "plgmmu32.h"#include "armmasks.h"#include "armhelp.h"#include "datadefs.h"#include "log.h"#include "err.h"//---Conditional execution-------------------------------------------------// Each of these functions returns 1 or 0, dependent on flag state.// Called by the dispatcher, by lookup in the condition LUT.int ARM9ES::condEQ(){return  reg.flags[FLAG_Z];}int ARM9ES::condNE(){return !reg.flags[FLAG_Z];}int ARM9ES::condCS(){return  reg.flags[FLAG_C];}int ARM9ES::condCC(){return !reg.flags[FLAG_C];}int ARM9ES::condMI(){return  reg.flags[FLAG_N];}int ARM9ES::condPL(){return !reg.flags[FLAG_N];}int ARM9ES::condVS(){return  reg.flags[FLAG_V];}int ARM9ES::condVC(){return !reg.flags[FLAG_V];}int ARM9ES::condHI(){return (!reg.flags[FLAG_Z])&reg.flags[FLAG_C];}int ARM9ES::condLS(){return reg.flags[FLAG_Z]|(!reg.flags[FLAG_C]);}int ARM9ES::condGE(){return !(reg.flags[FLAG_N]^reg.flags[FLAG_V]);}int ARM9ES::condLT(){return  (reg.flags[FLAG_N]^reg.flags[FLAG_V]);}int ARM9ES::condGT(){return (!reg.flags[FLAG_Z])&(!(reg.flags[FLAG_N]^reg.flags[FLAG_V]));}int ARM9ES::condLE(){return reg.flags[FLAG_Z]|(reg.flags[FLAG_N]^reg.flags[FLAG_V]);}int ARM9ES::condAL(){return 1;}int ARM9ES::condNV(){return 0;}//---Branching-------------------------------------------------------------OPC opB(){    s32 i = (reg.curop & 0x00FFFFFF) << 2;     // Extract address    i = (i & 0x02000000)?(0xFC000000 | i):i;   // Sign extend    reg.r[15] += i+4;                          // And branch    return 3;}OPC opBL(){    reg.r[14] = reg.r[15];                     // Save link addr    s32 i = (reg.curop & 0x00FFFFFF) << 2;     // Extract address    i = (i & 0x02000000)?(0xFC000000 | i):i;   // Sign extend    reg.r[15] += i+4;                          // And branch    return 3;}OPC opBX(){/*  if((_RM&3)==2) opUNP();*/    reg.r[15]=(_RM&~1)+Rm15hack; reg.flags[FLAG_T]=_RM&1;    return 1;}OPC opBLXr(){/*  if((_RM&3)==2) opUNP();*//*  if(_OP_RM==15) opUNP();*/    reg.r[14] = reg.r[15];    reg.r[15]=(_RM&~1)+Rm15hack; reg.flags[FLAG_T]=_RM&1;    return 1;}// TODO: BLXimm is pending a method to call unconditional opcodesOPC opBLX(){    return 1;}//---Coprocessor execution-------------------------------------------------OPC opMCR(){/*  if(_OP_RD==15) opUNP();*/    copro[_OP_RS]->set((reg.curop&MSK_OPLO)>>21, (reg.curop&MSK_FUNC)>>5, _OP_RN, _OP_RM, _RD);    return 1;}OPC opMRC(){    reg.tmp1 = copro[_OP_RS]->get((reg.curop&MSK_OPLO)>>21, (reg.curop&MSK_FUNC)>>5, _OP_RN, _OP_RM);    if(_OP_RD==15)    {	reg.flags[FLAG_N]=(reg.tmp1&0x80000000)?1:0;	reg.flags[FLAG_Z]=(reg.tmp1&0x40000000)?1:0;	reg.flags[FLAG_C]=(reg.tmp1&0x20000000)?1:0;	reg.flags[FLAG_V]=(reg.tmp1&0x10000000)?1:0;    }    else _RD=reg.tmp1;    return 1;}OPC opCDP(){    copro[_OP_RS]->op((reg.curop&MSK_OPLO)>>21, (reg.curop&MSK_FUNC)>>5, _OP_RN, _OP_RM, _OP_RD);    return 1;}#define LCi ((reg.curop&MSK_IMM8)<<2)#define LCofm reg.tmp1 = _RN + Rn15hack - LCi#define LCofp reg.tmp1 = _RN + Rn15hack + LCi#define LCwb _RN = reg.tmp1#define LCun reg.tmp1 = _RN + Rn15hack#define LCptm _RN -= LCi#define LCptp _RN += LCiOPC opLDCofm() { LCofm; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opLDCofp() { LCofp; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opLDCprm() { LCofm; LCwb; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opLDCprp() { LCofp; LCwb; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opLDCunm() { LCun; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, reg.curop&255); return 1; }OPC opLDCunp() { LCun; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, reg.curop&255); return 1; }OPC opLDCptm() { LCun; LCptm; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opLDCptp() { LCun; LCptp; copro[_OP_RS]->read(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opSTCofm() { LCofm; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opSTCofp() { LCofp; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opSTCprm() { LCofm; LCwb; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opSTCprp() { LCofp; LCwb; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opSTCunm() { LCun; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, reg.curop&255); return 1; }OPC opSTCunp() { LCun; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, reg.curop&255); return 1; }OPC opSTCptm() { LCun; LCptm; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }OPC opSTCptp() { LCun; LCptp; copro[_OP_RS]->write(_OP_RD, reg.tmp1, (reg.curop&0x00400000)?1:0, 0); return 1; }//---Enhanced DSP extension------------------------------------------------// LDRD/STRD are very similar to the standard halfword-style load/stores,// hence the defines from there are duplicated here.#define Rn15hack ((_OP_RN==15)?4:0)#define Rm15hack ((_OP_RM==15)?4:0)#define LSofm /*if(_OP_RM==15) opUNP();*/ reg.tmp1 = _RN + Rn15hack -#define LSofp /*if(_OP_RM==15) opUNP();*/ reg.tmp1 = _RN + Rn15hack +#define LSwb _RN = reg.tmp1#define LSptm /*if(_OP_RM==15 || _OP_RN==15) opUNP();*/ reg.tmp1 = _RN; _RN -=#define LSptp /*if(_OP_RM==15 || _OP_RN==15) opUNP();*/ reg.tmp1 = _RN; _RN +=#define LHi ((reg.curop&MSK_RM)|((reg.curop&MSK_RS)>>4))#define LHr _RM + Rm15hack#define LDRD { reg.r[_OP_RD]=MMU->rdW(reg.tmp1); reg.r[_OP_RD+1]=MMU->rdW(reg.tmp1+4); }#define STRD { MMU->wrW(reg.tmp1,reg.r[_OP_RD]); MMU->wrW(reg.tmp1+4,reg.r[_OP_RD+1]); }								 OPC opLDRDptim(){ LSptm(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDptip(){ LSptp(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDptrm(){ LSptm(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDptrp(){ LSptp(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDofim(){ LSofm(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDofip(){ LSofp(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDofrm(){ LSofm(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDofrp(){ LSofp(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDprim(){ LSofm(LHi); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDprip(){ LSofp(LHi); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDprrm(){ LSofm(LHr); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opLDRDprrp(){ LSofp(LHr); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) LDRD; return 3; }OPC opSTRDptim(){ LSptm(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDptip(){ LSptp(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDptrm(){ LSptm(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDptrp(){ LSptp(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDofim(){ LSofm(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDofip(){ LSofp(LHi); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDofrm(){ LSofm(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDofrp(){ LSofp(LHr); if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDprim(){ LSofm(LHi); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDprip(){ LSofp(LHi); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDprrm(){ LSofm(LHr); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }OPC opSTRDprrp(){ LSofp(LHr); LSwb; if(_OP_RD&1) return opUND(); reg.tmp1&=~3; if(_OP_RD<14) STRD; return 3; }#define flagDPqADD sat=( (reg.tmp2^_RD) & (~(reg.tmp1^reg.tmp2)) & 0x80000000); if(sat) reg.flags[FLAG_Q]=1#define flagDPqSUB sat=( (~(reg.tmp1^_RD)) & (reg.tmp1^reg.tmp2) & 0x80000000); if(sat) reg.flags[FLAG_Q]=1#define flagDPqSMLA sat=( (reg.tmp2^_RN) & (~(reg.tmp1^reg.tmp2)) & 0x80000000); if(sat) reg.flags[FLAG_Q]=1#define flagDPcSMLAL carry=(((_RD<reg.tmp2)||(_RD<reg.tmp1))?1:0)OPC opQADD(){    int sat;    reg.tmp1=_RM;    reg.tmp2=_RN;    _RD=_RM+_RN; flagDPqADD;    if(sat) _RD=(_RD&0x80000000)?0x7FFFFFFF:0x80000000;    return 1;}OPC opQSUB(){    int sat;    reg.tmp1=_RM;    reg.tmp2=_RN;    _RD=_RM-_RN; flagDPqSUB;    if(sat) _RD=(_RD&0x80000000)?0x7FFFFFFF:0x80000000;    return 1;}OPC opQDADD(){    int sat;    reg.tmp1=_RN; reg.tmp2=_RN;    _RD=reg.tmp1+reg.tmp2; flagDPqADD;    if(sat) _RD=(_RD&0x80000000)?0x7FFFFFFF:0x80000000;    reg.tmp1=_RM; reg.tmp2=_RD;    _RD=reg.tmp1+reg.tmp2; flagDPqADD;    if(sat) _RD=(_RD&0x80000000)?0x7FFFFFFF:0x80000000;    return 1;}OPC opQDSUB(){    int sat;    reg.tmp1=_RN; reg.tmp2=_RN;    _RD=reg.tmp1+reg.tmp2; flagDPqADD;    if(sat) _RD=(_RD&0x80000000)?0x7FFFFFFF:0x80000000;    reg.tmp1=_RM; reg.tmp2=_RD;    _RD=reg.tmp1-reg.tmp2; flagDPqSUB;    if(sat) _RD=(_RD&0x80000000)?0x7FFFFFFF:0x80000000;    return 1;}OPC opSMULBB(){/*  if((_OP_RM==15)|       (_OP_RS==15)|       (_OP_RD==15)|       (_OP_RN==15)) opUNP();*/    u32 r=(_RM&65535), d=(_RS&65535);    r=(r&0x8000)?(0xFFFF0000|r):r;    d=(d&0x8000)?(0xFFFF0000|d):d;    _RN = r*d;    return 1; }OPC opSMULBT(){/*  if((_OP_RM==15)|       (_OP_RS==15)|       (_OP_RD==15)|       (_OP_RN==15)) opUNP();*/    u32 r=(_RM&65535), d=(_RS>>16);    r=(r&0x8000)?(0xFFFF0000|r):r;    d=(d&0x8000)?(0xFFFF0000|d):d;    _RN = r*d;    return 1;}OPC opSMULTB(){/*  if((_OP_RM==15)|       (_OP_RS==15)|       (_OP_RD==15)|       (_OP_RN==15)) opUNP();*/    u32 r=(_RM>>16), d=(_RS&65535);    r=(r&0x8000)?(0xFFFF0000|r):r;    d=(d&0x8000)?(0xFFFF0000|d):d;    _RN = r*d;    return 1;

⌨️ 快捷键说明

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