ARMv7: more opcodes + STR

This commit is contained in:
Nekotekina 2014-11-01 01:00:36 +03:00
parent 3895c083cb
commit 536c5a900a
5 changed files with 213 additions and 25 deletions

View file

@ -11,6 +11,11 @@ void ARMv7DisAsm::NULL_OP(const u32 data, const ARMv7_encoding type)
Write("Illegal opcode (null)"); Write("Illegal opcode (null)");
} }
void ARMv7DisAsm::HACK(const u32 data, const ARMv7_encoding type)
{
Write(__FUNCTION__);
}
void ARMv7DisAsm::ADC_IMM(const u32 data, const ARMv7_encoding type) void ARMv7DisAsm::ADC_IMM(const u32 data, const ARMv7_encoding type)
{ {
Write(__FUNCTION__); Write(__FUNCTION__);
@ -881,12 +886,6 @@ void ARMv7DisAsm::SVC(const u32 data, const ARMv7_encoding type)
} }
void ARMv7DisAsm::SWP_(const u32 data, const ARMv7_encoding type)
{
Write(__FUNCTION__);
}
void ARMv7DisAsm::SXTAB(const u32 data, const ARMv7_encoding type) void ARMv7DisAsm::SXTAB(const u32 data, const ARMv7_encoding type)
{ {
Write(__FUNCTION__); Write(__FUNCTION__);

View file

@ -49,6 +49,8 @@ protected:
virtual void NULL_OP(const u32 data, const ARMv7_encoding type); virtual void NULL_OP(const u32 data, const ARMv7_encoding type);
virtual void HACK(const u32 data, const ARMv7_encoding type);
virtual void ADC_IMM(const u32 data, const ARMv7_encoding type); virtual void ADC_IMM(const u32 data, const ARMv7_encoding type);
virtual void ADC_REG(const u32 data, const ARMv7_encoding type); virtual void ADC_REG(const u32 data, const ARMv7_encoding type);
virtual void ADC_RSR(const u32 data, const ARMv7_encoding type); virtual void ADC_RSR(const u32 data, const ARMv7_encoding type);
@ -265,8 +267,6 @@ protected:
virtual void SVC(const u32 data, const ARMv7_encoding type); virtual void SVC(const u32 data, const ARMv7_encoding type);
virtual void SWP_(const u32 data, const ARMv7_encoding type);
virtual void SXTAB(const u32 data, const ARMv7_encoding type); virtual void SXTAB(const u32 data, const ARMv7_encoding type);
virtual void SXTAB16(const u32 data, const ARMv7_encoding type); virtual void SXTAB16(const u32 data, const ARMv7_encoding type);
virtual void SXTAH(const u32 data, const ARMv7_encoding type); virtual void SXTAH(const u32 data, const ARMv7_encoding type);

View file

@ -17,6 +17,33 @@ void ARMv7Interpreter::NULL_OP(const u32 data, const ARMv7_encoding type)
Emu.Pause(); Emu.Pause();
} }
void ARMv7Interpreter::HACK(const u32 data, const ARMv7_encoding type)
{
u32 cond = CPU.ITSTATE.advance();
u32 code = 0;
switch (type)
{
case T1:
{
code = data & 0xffff;
break;
}
case A1:
{
cond = data >> 28;
code = (data & 0xfff00) >> 4 | (data & 0xf);
break;
}
default: throw __FUNCTION__;
}
if (ConditionPassed(cond))
{
//
}
}
void ARMv7Interpreter::ADC_IMM(const u32 data, const ARMv7_encoding type) void ARMv7Interpreter::ADC_IMM(const u32 data, const ARMv7_encoding type)
{ {
switch (type) switch (type)
@ -1689,11 +1716,80 @@ void ARMv7Interpreter::STMIB(const u32 data, const ARMv7_encoding type)
void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type) void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type)
{ {
u32 cond = CPU.ITSTATE.advance();
u32 t = 16;
u32 n = 13;
u32 imm32 = 0;
bool index = true;
bool add = true;
bool wback = false;
switch (type) switch (type)
{ {
case T1:
{
t = (data & 0x7);
n = (data & 0x38) >> 3;
imm32 = (data & 0x7c0) >> 4;
break;
}
case T2:
{
t = (data & 0x700) >> 8;
imm32 = (data & 0xff) << 2;
break;
}
case T3:
{
t = (data & 0xf000) >> 12;
n = (data & 0xf0000) >> 16;
imm32 = (data & 0xfff);
if (n == 0xf)
{
throw "STR_IMM_T3 UNDEFINED";
}
break;
}
case T4:
{
t = (data & 0xf000) >> 12;
n = (data & 0xf0000) >> 16;
imm32 = (data & 0xff);
index = (data & 0x400);
add = (data & 0x200);
wback = (data & 0x100);
if (index && add && !wback)
{
throw "STRT";
}
if (n == 13 && index && !add && wback && imm32 == 4)
{
throw "PUSH";
}
if (n == 15 || (!index && !wback))
{
throw "STR_IMM_T4 UNDEFINED";
}
break;
}
case A1: throw __FUNCTION__; case A1: throw __FUNCTION__;
default: throw __FUNCTION__; default: throw __FUNCTION__;
} }
if (ConditionPassed(cond))
{
const u32 offset_addr = add ? CPU.read_gpr(n) + imm32 : CPU.read_gpr(n) - imm32;
const u32 addr = index ? offset_addr : CPU.read_gpr(n);
vm::psv::write32(addr, CPU.read_gpr(t));
if (wback)
{
CPU.write_gpr(n, offset_addr);
}
}
} }
void ARMv7Interpreter::STR_REG(const u32 data, const ARMv7_encoding type) void ARMv7Interpreter::STR_REG(const u32 data, const ARMv7_encoding type)
@ -1821,16 +1917,6 @@ void ARMv7Interpreter::SVC(const u32 data, const ARMv7_encoding type)
} }
void ARMv7Interpreter::SWP_(const u32 data, const ARMv7_encoding type)
{
switch (type)
{
case A1: throw __FUNCTION__;
default: throw __FUNCTION__;
}
}
void ARMv7Interpreter::SXTAB(const u32 data, const ARMv7_encoding type) void ARMv7Interpreter::SXTAB(const u32 data, const ARMv7_encoding type)
{ {
switch (type) switch (type)

View file

@ -262,6 +262,8 @@ protected:
virtual void NULL_OP(const u32 data, const ARMv7_encoding type); virtual void NULL_OP(const u32 data, const ARMv7_encoding type);
virtual void HACK(const u32 data, const ARMv7_encoding type);
virtual void ADC_IMM(const u32 data, const ARMv7_encoding type); virtual void ADC_IMM(const u32 data, const ARMv7_encoding type);
virtual void ADC_REG(const u32 data, const ARMv7_encoding type); virtual void ADC_REG(const u32 data, const ARMv7_encoding type);
virtual void ADC_RSR(const u32 data, const ARMv7_encoding type); virtual void ADC_RSR(const u32 data, const ARMv7_encoding type);
@ -478,8 +480,6 @@ protected:
virtual void SVC(const u32 data, const ARMv7_encoding type); virtual void SVC(const u32 data, const ARMv7_encoding type);
virtual void SWP_(const u32 data, const ARMv7_encoding type);
virtual void SXTAB(const u32 data, const ARMv7_encoding type); virtual void SXTAB(const u32 data, const ARMv7_encoding type);
virtual void SXTAB16(const u32 data, const ARMv7_encoding type); virtual void SXTAB16(const u32 data, const ARMv7_encoding type);
virtual void SXTAH(const u32 data, const ARMv7_encoding type); virtual void SXTAH(const u32 data, const ARMv7_encoding type);

View file

@ -49,6 +49,8 @@ public:
virtual void NULL_OP(const u32 data, const ARMv7_encoding type) = 0; virtual void NULL_OP(const u32 data, const ARMv7_encoding type) = 0;
virtual void HACK(const u32 data, const ARMv7_encoding type) = 0;
virtual void ADC_IMM(const u32 data, const ARMv7_encoding type) = 0; virtual void ADC_IMM(const u32 data, const ARMv7_encoding type) = 0;
virtual void ADC_REG(const u32 data, const ARMv7_encoding type) = 0; virtual void ADC_REG(const u32 data, const ARMv7_encoding type) = 0;
virtual void ADC_RSR(const u32 data, const ARMv7_encoding type) = 0; virtual void ADC_RSR(const u32 data, const ARMv7_encoding type) = 0;
@ -265,8 +267,6 @@ public:
virtual void SVC(const u32 data, const ARMv7_encoding type) = 0; virtual void SVC(const u32 data, const ARMv7_encoding type) = 0;
virtual void SWP_(const u32 data, const ARMv7_encoding type) = 0;
virtual void SXTAB(const u32 data, const ARMv7_encoding type) = 0; virtual void SXTAB(const u32 data, const ARMv7_encoding type) = 0;
virtual void SXTAB16(const u32 data, const ARMv7_encoding type) = 0; virtual void SXTAB16(const u32 data, const ARMv7_encoding type) = 0;
virtual void SXTAH(const u32 data, const ARMv7_encoding type) = 0; virtual void SXTAH(const u32 data, const ARMv7_encoding type) = 0;
@ -318,7 +318,7 @@ public:
virtual void UXTB16(const u32 data, const ARMv7_encoding type) = 0; virtual void UXTB16(const u32 data, const ARMv7_encoding type) = 0;
virtual void UXTH(const u32 data, const ARMv7_encoding type) = 0; virtual void UXTH(const u32 data, const ARMv7_encoding type) = 0;
// TODO: vector ops // TODO: vector ops + something
}; };
struct ARMv7_opcode_t struct ARMv7_opcode_t
@ -340,6 +340,9 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
{ {
ARMv7_OP2(0xffff, 0x0000, T1, NULL_OP), // ??? ARMv7_OP2(0xffff, 0x0000, T1, NULL_OP), // ???
ARMv7_OP4(0xffff, 0x0000, 0xf870, 0x0000, T1, HACK), // "Undefined" Thumb opcode
ARMv7_OP4(0x0ff0, 0x00f0, 0x0070, 0x0090, A1, HACK), // "Undefined" ARM opcode
ARMv7_OP4(0xfbe0, 0x8000, 0xf140, 0x0000, T1, ADC_IMM), ARMv7_OP4(0xfbe0, 0x8000, 0xf140, 0x0000, T1, ADC_IMM),
ARMv7_OP4(0x0fe0, 0x0000, 0x02a0, 0x0000, A1, ADC_IMM), ARMv7_OP4(0x0fe0, 0x0000, 0x02a0, 0x0000, A1, ADC_IMM),
ARMv7_OP2(0xffc0, 0x4040, T1, ADC_REG), ARMv7_OP2(0xffc0, 0x4040, T1, ADC_REG),
@ -565,7 +568,8 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
ARMv7_OP4(0x0fe0, 0x0010, 0x0180, 0x0000, A1, ORR_REG), ARMv7_OP4(0x0fe0, 0x0010, 0x0180, 0x0000, A1, ORR_REG),
ARMv7_OP4(0x0fe0, 0x0090, 0x0180, 0x0010, A1, ORR_RSR), ARMv7_OP4(0x0fe0, 0x0090, 0x0180, 0x0010, A1, ORR_RSR),
// TODO (PKH...) ARMv7_OP4(0xfff0, 0x8010, 0xeac0, 0x0000, T1, PKH),
ARMv7_OP4(0x0ff0, 0x0030, 0x0680, 0x0010, A1, PKH),
ARMv7_OP2(0xfe00, 0xbc00, T1, POP), ARMv7_OP2(0xfe00, 0xbc00, T1, POP),
ARMv7_OP4(0xffff, 0x0000, 0xe8bd, 0x0000, T2, POP), ARMv7_OP4(0xffff, 0x0000, 0xe8bd, 0x0000, T2, POP),
@ -581,6 +585,65 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
// TODO (Q*...) // TODO (Q*...)
ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf0a0, T1, RBIT),
ARMv7_OP4(0x0fff, 0x0ff0, 0x06ff, 0x0f30, A1, RBIT),
ARMv7_OP2(0xffc0, 0xba00, T1, REV),
ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf080, T2, REV),
ARMv7_OP4(0x0fff, 0x0ff0, 0x06bf, 0x0f30, A1, REV),
ARMv7_OP2(0xffc0, 0xba40, T1, REV16),
ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf090, T2, REV16),
ARMv7_OP4(0x0fff, 0x0ff0, 0x06bf, 0x0fb0, A1, REV16),
ARMv7_OP2(0xffc0, 0xbac0, T1, REVSH),
ARMv7_OP4(0xfff0, 0xf0f0, 0xfa90, 0xf0b0, T2, REVSH),
ARMv7_OP4(0x0fff, 0x0ff0, 0x06ff, 0x0fb0, A1, REVSH),
ARMv7_OP4(0xffef, 0x8030, 0xea4f, 0x0030, T1, ROR_IMM),
ARMv7_OP4(0x0fef, 0x0070, 0x01a0, 0x0060, A1, ROR_IMM),
ARMv7_OP2(0xffc0, 0x41c0, T1, ROR_REG),
ARMv7_OP4(0xffe0, 0xf0f0, 0xfa60, 0xf000, T2, ROR_REG),
ARMv7_OP4(0x0fef, 0x00f0, 0x01a0, 0x0070, A1, ROR_REG),
ARMv7_OP4(0xffef, 0xf0f0, 0xea4f, 0x0030, T1, RRX),
ARMv7_OP4(0x0fef, 0x0ff0, 0x01a0, 0x0060, A1, RRX),
ARMv7_OP2(0xffc0, 0x4240, T1, RSB_IMM),
ARMv7_OP4(0xfbe0, 0x8000, 0xf1c0, 0x0000, T2, RSB_IMM),
ARMv7_OP4(0x0fe0, 0x0000, 0x0260, 0x0000, A1, RSB_IMM),
ARMv7_OP4(0xffe0, 0x8000, 0xebc0, 0x0000, T1, RSB_REG),
ARMv7_OP4(0x0fe0, 0x0010, 0x0060, 0x0000, A1, RSB_REG),
ARMv7_OP4(0x0fe0, 0x0090, 0x0060, 0x0010, A1, RSB_RSR),
ARMv7_OP4(0x0fe0, 0x0000, 0x02e0, 0x0000, A1, RSC_IMM),
ARMv7_OP4(0x0fe0, 0x0010, 0x00e0, 0x0000, A1, RSC_REG),
ARMv7_OP4(0x0fe0, 0x0090, 0x00e0, 0x0010, A1, RSC_RSR),
// TODO (SADD16, SADD8, SASX)
ARMv7_OP4(0xfbe0, 0x8000, 0xf160, 0x0000, T1, SBC_IMM),
ARMv7_OP4(0x0fe0, 0x0000, 0x02c0, 0x0000, A1, SBC_IMM),
ARMv7_OP2(0xffc0, 0x4180, T1, SBC_REG),
ARMv7_OP4(0xffe0, 0x8000, 0xeb60, 0x0000, T2, SBC_REG),
ARMv7_OP4(0x0fe0, 0x0010, 0x00c0, 0x0000, A1, SBC_REG),
ARMv7_OP4(0x0fe0, 0x0090, 0x00c0, 0x0010, A1, SBC_RSR),
ARMv7_OP4(0xfff0, 0x8020, 0xf340, 0x0000, T1, SBFX),
ARMv7_OP4(0x0fe0, 0x0070, 0x07a0, 0x0050, A1, SBFX),
ARMv7_OP4(0xfff0, 0xf0f0, 0xfb90, 0xf0f0, T1, SDIV), // ???
ARMv7_OP4(0xfff0, 0xf0f0, 0xfaa0, 0xf080, T1, SEL),
ARMv7_OP4(0x0ff0, 0x0ff0, 0x0680, 0x0fb0, A1, SEL),
// TODO (SH*, SM*, SS*)
ARMv7_OP2(0xf800, 0xc000, T1, STM),
ARMv7_OP4(0xffd0, 0xa000, 0xe880, 0x0000, T2, STM),
ARMv7_OP4(0x0fd0, 0x0000, 0x0880, 0x0000, A1, STM),
ARMv7_OP4(0x0fd0, 0x0000, 0x0800, 0x0000, A1, STMDA),
ARMv7_OP4(0xffd0, 0xa000, 0xe900, 0x0000, T1, STMDB),
ARMv7_OP4(0x0fd0, 0x0000, 0x0900, 0x0000, A1, STMDB),
ARMv7_OP4(0x0fd0, 0x0000, 0x0980, 0x0000, A1, STMIB),
ARMv7_OP2(0xf800, 0x6000, T1, STR_IMM), ARMv7_OP2(0xf800, 0x6000, T1, STR_IMM),
ARMv7_OP2(0xf800, 0x9000, T2, STR_IMM), ARMv7_OP2(0xf800, 0x9000, T2, STR_IMM),
ARMv7_OP4(0xfff0, 0x0000, 0xf8c0, 0x0000, T3, STR_IMM), ARMv7_OP4(0xfff0, 0x0000, 0xf8c0, 0x0000, T3, STR_IMM),
@ -590,7 +653,25 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
ARMv7_OP4(0xfff0, 0x0fc0, 0xf840, 0x0000, T2, STR_REG), ARMv7_OP4(0xfff0, 0x0fc0, 0xf840, 0x0000, T2, STR_REG),
ARMv7_OP4(0x0e50, 0x0010, 0x0600, 0x0000, A1, STR_REG), ARMv7_OP4(0x0e50, 0x0010, 0x0600, 0x0000, A1, STR_REG),
// ARMv7_OP2(0xf800, 0x7000, T1, STRB_IMM),
ARMv7_OP4(0xfff0, 0x0000, 0xf880, 0x0000, T2, STRB_IMM),
ARMv7_OP4(0xfff0, 0x0800, 0xf800, 0x0800, T3, STRB_IMM),
ARMv7_OP4(0x0e50, 0x0000, 0x0440, 0x0000, A1, STRB_IMM),
ARMv7_OP2(0xfe00, 0x5400, T1, STRB_REG),
ARMv7_OP4(0xfff0, 0x0fc0, 0xf800, 0x0000, T2, STRB_REG),
ARMv7_OP4(0x0e50, 0x0010, 0x0640, 0x0000, A1, STRB_REG),
ARMv7_OP4(0xfe50, 0x0000, 0xe840, 0x0000, T1, STRD_IMM),
ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00f0, A1, STRD_IMM),
ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00f0, A1, STRD_REG),
ARMv7_OP2(0xf800, 0x8000, T1, STRH_IMM),
ARMv7_OP4(0xfff0, 0x0000, 0xf8a0, 0x0000, T2, STRH_IMM),
ARMv7_OP4(0xfff0, 0x0800, 0xf820, 0x0800, T3, STRH_IMM),
ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00b0, A1, STRH_IMM),
ARMv7_OP2(0xfe00, 0x5200, T1, STRH_REG),
ARMv7_OP4(0xfff0, 0x0fc0, 0xf820, 0x0000, T2, STRH_REG),
ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00b0, A1, STRH_REG),
ARMv7_OP2(0xfe00, 0x1e00, T1, SUB_IMM), ARMv7_OP2(0xfe00, 0x1e00, T1, SUB_IMM),
ARMv7_OP2(0xf800, 0x3800, T2, SUB_IMM), ARMv7_OP2(0xf800, 0x3800, T2, SUB_IMM),
@ -607,6 +688,28 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
ARMv7_OP4(0x0fef, 0x0000, 0x024d, 0x0000, A1, SUB_SPI), ARMv7_OP4(0x0fef, 0x0000, 0x024d, 0x0000, A1, SUB_SPI),
ARMv7_OP4(0xffef, 0x8000, 0xebad, 0x0000, T1, SUB_SPR), ARMv7_OP4(0xffef, 0x8000, 0xebad, 0x0000, T1, SUB_SPR),
ARMv7_OP4(0x0fef, 0x0010, 0x004d, 0x0000, A1, SUB_SPR), ARMv7_OP4(0x0fef, 0x0010, 0x004d, 0x0000, A1, SUB_SPR),
ARMv7_OP2(0xff00, 0xdf00, T1, SVC),
ARMv7_OP4(0x0f00, 0x0000, 0x0f00, 0x0000, A1, SVC),
// TODO (SX*)
ARMv7_OP4(0xfff0, 0xffe0, 0xe8d0, 0xf000, T1, TB_),
ARMv7_OP4(0xfbf0, 0x8f00, 0xf090, 0x0f00, T1, TEQ_IMM),
ARMv7_OP4(0x0ff0, 0xf000, 0x0330, 0x0000, A1, TEQ_IMM),
ARMv7_OP4(0xfff0, 0x8f00, 0xea90, 0x0f00, T1, TEQ_REG),
ARMv7_OP4(0x0ff0, 0xf010, 0x0130, 0x0000, A1, TEQ_REG),
ARMv7_OP4(0x0ff0, 0xf090, 0x0130, 0x0010, A1, TEQ_RSR),
ARMv7_OP4(0xfbf0, 0x8f00, 0xf010, 0x0f00, T1, TST_IMM),
ARMv7_OP4(0x0ff0, 0xf000, 0x0310, 0x0000, A1, TST_IMM),
ARMv7_OP2(0xffc0, 0x4200, T1, TST_REG),
ARMv7_OP4(0xfff0, 0x8f00, 0xea10, 0x0f00, T2, TST_REG),
ARMv7_OP4(0x0ff0, 0xf010, 0x0110, 0x0000, A1, TST_REG),
ARMv7_OP4(0x0ff0, 0xf090, 0x0110, 0x0010, A1, TST_RSR),
// TODO (U*, V*)
}; };
#undef ARMv7_OP #undef ARMv7_OP