📄 thumb-opcodes.cpp
字号:
/*************************************************************************** DSemu - The Next Generation ** Portable ARM cores: Thumb opcode implementations [thumb-opcodes.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// Various helper values we'll be using throughout#define _ROR(val, shft) ((((val)&(~((1<<(shft))-1)))>>(shft)) | (((val)&((1<<(shft))-1))<<(32-(shft))))#define _RM reg.r[(reg.curop&TMSK_RM)>>TSHFT_RM]#define _RN reg.r[(reg.curop&TMSK_RN)>>TSHFT_RN]#define _RD reg.r[(reg.curop&TMSK_RD)>>TSHFT_RD]#define _RDH reg.r[((reg.curop&TMSK_RD)>>TSHFT_RD)|((reg.curop&0x0080)>>4)]#define _RNH reg.r[((reg.curop&TMSK_RN)>>TSHFT_RN)|((reg.curop&0x0040)>>3)]// Called if an undefined opcode is encountered. Exactly the same as the// ARM equivalent, so why not just call that?OPC topUND() { return opUND(); }//---Data processing-------------------------------------------------------#define flagDPnz \ reg.flags[FLAG_N] = _RD>>31; \ reg.flags[FLAG_Z] = (_RD)?0:1; \ return 1#define flagDPnzTST \ reg.flags[FLAG_N] = reg.tmp3>>31; \ reg.flags[FLAG_Z] = (reg.tmp3)?0:1; \ return 1#define flagDPnzt(x) \ reg.flags[FLAG_N] = reg.r[(x)]>>31; \ reg.flags[FLAG_Z] = (reg.r[(x)])?0:1; \ return 1#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#define flagDPcADDt(x) reg.flags[FLAG_C]=(((reg.r[(x)]<reg.tmp2)||(reg.r[(x)]<reg.tmp1))?1:0)#define flagDPcSUBt(x) reg.flags[FLAG_C]=(((reg.tmp2&(~reg.tmp1))|(reg.tmp2&(~reg.r[(x)]))|((~reg.tmp1)&(~reg.r[(x)])))&0x80000000)?1:0//#define flagDPcSUBt(x) flagDPcSUB#define flagDPvADDt(x) reg.flags[FLAG_V]=( (reg.tmp2^reg.r[(x)]) & (~(reg.tmp1^reg.tmp2)) & 0x80000000)?1:0#define flagDPvSUBt(x) reg.flags[FLAG_V]=( (~(reg.tmp1^reg.r[(x)])) & (reg.tmp1^reg.tmp2) & 0x80000000)?1:0#define LSror _RD=_ROR(_RD, ((reg.tmp1&3)*8))OPC topLSLimm(){ reg.tmp1=(reg.curop&TMSK_IMM5)>>TSHFT_IMM5; reg.flags[FLAG_C]=(_RN&(1<<(32-reg.tmp1)))?1:0; _RD = _RN << reg.tmp1; flagDPnz;}OPC topLSRimm(){ reg.tmp1=(reg.curop&TMSK_IMM5)>>TSHFT_IMM5; if(!reg.tmp1) { reg.flags[FLAG_C]=_RN>>31; _RD=0; } else { reg.flags[FLAG_C]=(_RN&(1<<(reg.tmp1-1)))?1:0; _RD=_RN >> reg.tmp1; } flagDPnz;}OPC topASRimm(){ reg.tmp1=(reg.curop&TMSK_IMM5)>>TSHFT_IMM5; if(!reg.tmp1) { _RD=(_RN&0x80000000)?~0:0; reg.flags[FLAG_C]=_RD&1; } else { reg.flags[FLAG_C]=(_RN&(1<<(reg.tmp1-1)))?1:0; _RD = (signed)_RN >> (signed)reg.tmp1; } flagDPnz;}OPC topADDreg() { reg.tmp1=_RM; reg.tmp2=_RN; _RD=_RN+reg.tmp1; flagDPcADD; flagDPvADD; flagDPnz; }OPC topSUBreg() { reg.tmp1=_RM; reg.tmp2=_RN; _RD=_RN-reg.tmp1; flagDPcSUB; flagDPvSUB; flagDPnz; }OPC topADDimm3() { reg.tmp1=(reg.curop&TMSK_RM)>>TSHFT_RM; reg.tmp2=_RN; _RD=_RN+reg.tmp1; flagDPcADD; flagDPvADD; flagDPnz; }OPC topSUBimm3() { reg.tmp1=(reg.curop&TMSK_RM)>>TSHFT_RM; reg.tmp2=_RN; _RD=_RN-reg.tmp1; flagDPcSUB; flagDPvSUB; flagDPnz; }OPC topMOVimm8r0() { reg.r[0]=reg.curop&TMSK_IMM8; flagDPnzt(0); }OPC topMOVimm8r1() { reg.r[1]=reg.curop&TMSK_IMM8; flagDPnzt(1); }OPC topMOVimm8r2() { reg.r[2]=reg.curop&TMSK_IMM8; flagDPnzt(2); }OPC topMOVimm8r3() { reg.r[3]=reg.curop&TMSK_IMM8; flagDPnzt(3); }OPC topMOVimm8r4() { reg.r[4]=reg.curop&TMSK_IMM8; flagDPnzt(4); }OPC topMOVimm8r5() { reg.r[5]=reg.curop&TMSK_IMM8; flagDPnzt(5); }OPC topMOVimm8r6() { reg.r[6]=reg.curop&TMSK_IMM8; flagDPnzt(6); }OPC topMOVimm8r7() { reg.r[7]=reg.curop&TMSK_IMM8; flagDPnzt(7); }OPC topCMPimm8r0() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[0]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topCMPimm8r1() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[1]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topCMPimm8r2() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[2]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topCMPimm8r3() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[3]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topCMPimm8r4() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[4]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topCMPimm8r5() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[5]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topCMPimm8r6() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[6]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topCMPimm8r7() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[7]; reg.tmp3=reg.tmp2-reg.tmp1;flagDPcCMP;flagDPvCMP;flagDPnzTST;}OPC topADDimm8r0() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[0]; reg.r[0]+=reg.tmp1;flagDPcADDt(0);flagDPvADDt(0);flagDPnzt(0);}OPC topADDimm8r1() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[1]; reg.r[1]+=reg.tmp1;flagDPcADDt(1);flagDPvADDt(1);flagDPnzt(1);}OPC topADDimm8r2() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[2]; reg.r[2]+=reg.tmp1;flagDPcADDt(2);flagDPvADDt(2);flagDPnzt(2);}OPC topADDimm8r3() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[3]; reg.r[3]+=reg.tmp1;flagDPcADDt(3);flagDPvADDt(3);flagDPnzt(3);}OPC topADDimm8r4() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[4]; reg.r[4]+=reg.tmp1;flagDPcADDt(4);flagDPvADDt(4);flagDPnzt(4);}OPC topADDimm8r5() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[5]; reg.r[5]+=reg.tmp1;flagDPcADDt(5);flagDPvADDt(5);flagDPnzt(5);}OPC topADDimm8r6() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[6]; reg.r[6]+=reg.tmp1;flagDPcADDt(6);flagDPvADDt(6);flagDPnzt(6);}OPC topADDimm8r7() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[7]; reg.r[7]+=reg.tmp1;flagDPcADDt(7);flagDPvADDt(7);flagDPnzt(7);}OPC topSUBimm8r0() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[0]; reg.r[0]-=reg.tmp1;flagDPcSUBt(0);flagDPvSUBt(0);flagDPnzt(0);}OPC topSUBimm8r1() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[1]; reg.r[1]-=reg.tmp1;flagDPcSUBt(1);flagDPvSUBt(1);flagDPnzt(1);}OPC topSUBimm8r2() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[2]; reg.r[2]-=reg.tmp1;flagDPcSUBt(2);flagDPvSUBt(2);flagDPnzt(2);}OPC topSUBimm8r3() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[3]; reg.r[3]-=reg.tmp1;flagDPcSUBt(3);flagDPvSUBt(3);flagDPnzt(3);}OPC topSUBimm8r4() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[4]; reg.r[4]-=reg.tmp1;flagDPcSUBt(4);flagDPvSUBt(4);flagDPnzt(4);}OPC topSUBimm8r5() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[5]; reg.r[5]-=reg.tmp1;flagDPcSUBt(5);flagDPvSUBt(5);flagDPnzt(5);}OPC topSUBimm8r6() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[6]; reg.r[6]-=reg.tmp1;flagDPcSUBt(6);flagDPvSUBt(6);flagDPnzt(6);}OPC topSUBimm8r7() {reg.tmp1=reg.curop&TMSK_IMM8; reg.tmp2=reg.r[7]; reg.r[7]-=reg.tmp1;flagDPcSUBt(7);flagDPvSUBt(7);flagDPnzt(7);}OPC topDPg1(){ switch(reg.curop&0x00C0) { case 0x00: _RD&=_RN; break; case 0x40: _RD^=_RN; break; case 0x80: if(_RN&255) { if((_RN&255) < 32) { reg.flags[FLAG_C]=(_RD&(1<<(32-(_RN&255))))?1:0; _RD <<= (_RN&255); } else if((_RN&255) == 32) { reg.flags[FLAG_C] = _RD&1; _RD=0; } else { _RD=0; reg.flags[FLAG_C]=0; } } break; case 0xC0: if(_RN&255) { if((_RN&255) < 32) { reg.flags[FLAG_C]=(_RD&(1<<((_RN&255)-1)))?1:0; _RD >>= (_RN&255); } else if((_RN&255) == 32) { reg.flags[FLAG_C]=(_RD&0x80000000)?1:0; _RD=0; } else { _RD=0; reg.flags[FLAG_C]=0; } } break; } flagDPnz;}OPC topDPg2(){ switch(reg.curop&0x00C0) { case 0x00: if(_RN&255) { if((_RN&255) < 32) { reg.flags[FLAG_C]=(_RD&(1<<((_RN&255)-1)))?1:0; _RD >>= (signed)(_RN&255); } else if((_RN&255) == 32) { _RD=(_RN&0x80000000)?~0:0; reg.flags[FLAG_C]=_RD&1; } else { _RD=0; reg.flags[FLAG_C]=0; } } break; case 0x40: reg.tmp1=_RN+reg.flags[FLAG_C]; reg.tmp2=_RD; _RD+=reg.tmp1; flagDPcADD; flagDPvADD; break; case 0x80: reg.tmp1=_RN-(1-reg.flags[FLAG_C]); reg.tmp2=_RD; _RD-=reg.tmp1; flagDPcSUB; flagDPvSUB; break; case 0xC0:// if(_RN&255)// { if(_RN&31) { reg.flags[FLAG_C]=(_RD&(1<<((_RN&31)-1)))?1:0; _RD=_ROR(_RD, _RN&31); } else reg.flags[FLAG_C]=_RD>>31;// } break; } flagDPnz;}OPC topDPg3(){ switch(reg.curop&0x00C0) { case 0x00: reg.tmp2=_RD&_RN; flagDPnzTST; break; case 0x40: reg.tmp1=0; reg.tmp2=_RN; _RD=0-_RN; flagDPcSUB; flagDPvSUB; flagDPnz; break; case 0x80: reg.tmp1=_RD; reg.tmp2=_RN; reg.tmp3=_RD-_RN; flagDPcCMP; flagDPvCMP; flagDPnzTST; break; case 0xC0: reg.tmp1=_RD; reg.tmp2=_RN; reg.tmp3=_RD+_RN; flagDPcCMN; flagDPvCMN; flagDPnzTST; break; } return 1;}OPC topDPg4(){ switch(reg.curop&0x00C0) { case 0x00: _RD|=_RN; break; case 0x40: if((reg.curop&TMSK_RD)==((reg.curop&TMSK_RN)>>TSHFT_RN)) opUNP(); _RD*=_RN; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -