mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
ARMv7 opcode table fixed
This commit is contained in:
parent
e01528137e
commit
cbd56fc4f5
2 changed files with 76 additions and 54 deletions
|
@ -14,12 +14,18 @@ struct ARMv7_opcode_t
|
|||
const char* name;
|
||||
ARMv7_encoding type;
|
||||
void(*func)(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
|
||||
bool(*skip)(u32 code);
|
||||
};
|
||||
|
||||
// single 16-bit value
|
||||
#define ARMv7_OP2(mask, code, type, name) { (u32)((mask) << 16), (u32)((code) << 16), 2, #name "_" #type, type, ARMv7_instrs::name }
|
||||
#define ARMv7_OP2(mask, code, type, name, ...) { (u32)((mask) << 16), (u32)((code) << 16), 2, #name "_" #type, type, ARMv7_instrs::name, __VA_ARGS__ }
|
||||
// two 16-bit values
|
||||
#define ARMv7_OP4(mask0, mask1, code0, code1, type, name) { (u32)((mask0) << 16) | (mask1), (u32)((code0) << 16) | (code1), 4, #name "_" #type, type, ARMv7_instrs::name }
|
||||
#define ARMv7_OP4(mask0, mask1, code0, code1, type, name, ...) { (u32)((mask0) << 16) | (mask1), (u32)((code0) << 16) | (code1), 4, #name "_" #type, type, ARMv7_instrs::name, __VA_ARGS__ }
|
||||
|
||||
#define SKIP_IF(cond) [](u32 c) -> bool { return cond; }
|
||||
|
||||
#define BF(start, end) ((c << (31 - (end))) >> ((start) + 31 - (end)))
|
||||
#define BT(pos) ((c >> (pos)) & 1)
|
||||
|
||||
const ARMv7_opcode_t ARMv7_opcode_table[] =
|
||||
{
|
||||
|
@ -35,6 +41,16 @@ const ARMv7_opcode_t ARMv7_opcode_table[] =
|
|||
ARMv7_OP4(0x0fe0, 0x0010, 0x00a0, 0x0000, A1, ADC_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0090, 0x00a0, 0x0010, A1, ADC_RSR),
|
||||
|
||||
ARMv7_OP2(0xfe00, 0x1c00, T1, ADD_IMM),
|
||||
ARMv7_OP2(0xf800, 0x3000, T2, ADD_IMM),
|
||||
ARMv7_OP4(0xfbe0, 0x8000, 0xf100, 0x0000, T3, ADD_IMM, SKIP_IF( (BF(8, 11) == 15 && BT(20)) || (BF(16, 19) == 13) )),
|
||||
ARMv7_OP4(0xfbf0, 0x8000, 0xf200, 0x0000, T4, ADD_IMM),
|
||||
ARMv7_OP4(0x0fe0, 0x0000, 0x0280, 0x0000, A1, ADD_IMM),
|
||||
ARMv7_OP2(0xfe00, 0x1800, T1, ADD_REG),
|
||||
ARMv7_OP2(0xff00, 0x4400, T2, ADD_REG, SKIP_IF( (c & 0x87) == 0x85 || BF(3, 6) == 13 )),
|
||||
ARMv7_OP4(0xffe0, 0x8000, 0xeb00, 0x0000, T3, ADD_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0010, 0x0080, 0x0000, A1, ADD_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0090, 0x0080, 0x0010, A1, ADD_RSR),
|
||||
ARMv7_OP2(0xf800, 0xa800, T1, ADD_SPI),
|
||||
ARMv7_OP2(0xff80, 0xb000, T2, ADD_SPI),
|
||||
ARMv7_OP4(0xfbef, 0x8000, 0xf10d, 0x0000, T3, ADD_SPI),
|
||||
|
@ -44,16 +60,6 @@ const ARMv7_opcode_t ARMv7_opcode_table[] =
|
|||
ARMv7_OP2(0xff87, 0x4485, T2, ADD_SPR),
|
||||
ARMv7_OP4(0xffef, 0x8000, 0xeb0d, 0x0000, T3, ADD_SPR),
|
||||
ARMv7_OP4(0x0fef, 0x0010, 0x008d, 0x0000, A1, ADD_SPR),
|
||||
ARMv7_OP2(0xfe00, 0x1c00, T1, ADD_IMM),
|
||||
ARMv7_OP2(0xf800, 0x3000, T2, ADD_IMM),
|
||||
ARMv7_OP4(0xfbe0, 0x8000, 0xf100, 0x0000, T3, ADD_IMM),
|
||||
ARMv7_OP4(0xfbf0, 0x8000, 0xf200, 0x0000, T4, ADD_IMM),
|
||||
ARMv7_OP4(0x0fe0, 0x0000, 0x0280, 0x0000, A1, ADD_IMM),
|
||||
ARMv7_OP2(0xfe00, 0x1800, T1, ADD_REG),
|
||||
ARMv7_OP2(0xff00, 0x4400, T2, ADD_REG),
|
||||
ARMv7_OP4(0xffe0, 0x8000, 0xeb00, 0x0000, T3, ADD_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0010, 0x0080, 0x0000, A1, ADD_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0090, 0x0080, 0x0010, A1, ADD_RSR),
|
||||
|
||||
ARMv7_OP2(0xf800, 0xa000, T1, ADR),
|
||||
ARMv7_OP4(0xfbff, 0x8000, 0xf2af, 0x0000, T2, ADR),
|
||||
|
@ -166,7 +172,7 @@ const ARMv7_opcode_t ARMv7_opcode_table[] =
|
|||
ARMv7_OP4(0xfff0, 0x0fc0, 0xf810, 0x0000, T2, LDRB_REG),
|
||||
ARMv7_OP4(0x0e50, 0x0010, 0x0650, 0x0000, A1, LDRB_REG),
|
||||
|
||||
ARMv7_OP4(0xfe50, 0x0000, 0xe850, 0x0000, T1, LDRD_IMM),
|
||||
ARMv7_OP4(0xfe50, 0x0000, 0xe850, 0x0000, T1, LDRD_IMM, SKIP_IF( (!BT(21) && !BT(24)) || BF(16, 19) == 15 )),
|
||||
ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00d0, A1, LDRD_IMM),
|
||||
ARMv7_OP4(0xfe7f, 0x0000, 0xe85f, 0x0000, T1, LDRD_LIT),
|
||||
ARMv7_OP4(0x0f7f, 0x00f0, 0x014f, 0x00d0, A1, LDRD_LIT),
|
||||
|
@ -488,7 +494,7 @@ const ARMv7_opcode_t ARMv7_opcode_table[] =
|
|||
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(0xfe50, 0x0000, 0xe840, 0x0000, T1, STRD_IMM, SKIP_IF(!BT(21) && !BT(24))),
|
||||
ARMv7_OP4(0x0e50, 0x00f0, 0x0040, 0x00f0, A1, STRD_IMM),
|
||||
ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00f0, A1, STRD_REG),
|
||||
|
||||
|
@ -509,21 +515,21 @@ const ARMv7_opcode_t ARMv7_opcode_table[] =
|
|||
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(0xf800, 0x3800, T2, SUB_IMM),
|
||||
ARMv7_OP4(0xfbe0, 0x8000, 0xf1a0, 0x0000, T3, SUB_IMM, SKIP_IF( (BF(8, 11) == 15 && BT(20)) || (BF(16, 19) == 13) )),
|
||||
ARMv7_OP4(0xfbf0, 0x8000, 0xf2a0, 0x0000, T4, SUB_IMM),
|
||||
ARMv7_OP4(0x0fe0, 0x0000, 0x0240, 0x0000, A1, SUB_IMM),
|
||||
ARMv7_OP2(0xfe00, 0x1a00, T1, SUB_REG),
|
||||
ARMv7_OP4(0xffe0, 0x8000, 0xeba0, 0x0000, T2, SUB_REG, SKIP_IF( (BF(8, 11) == 15 && BT(20)) || (BF(16, 19) == 13) )),
|
||||
ARMv7_OP4(0x0fe0, 0x0010, 0x0040, 0x0000, A1, SUB_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0090, 0x0040, 0x0010, A1, SUB_RSR),
|
||||
ARMv7_OP2(0xff80, 0xb080, T1, SUB_SPI),
|
||||
ARMv7_OP4(0xfbef, 0x8000, 0xf1ad, 0x0000, T2, SUB_SPI),
|
||||
ARMv7_OP4(0xfbff, 0x8000, 0xf2ad, 0x0000, T3, SUB_SPI),
|
||||
ARMv7_OP4(0x0fef, 0x0000, 0x024d, 0x0000, A1, SUB_SPI),
|
||||
ARMv7_OP4(0xffef, 0x8000, 0xebad, 0x0000, T1, SUB_SPR),
|
||||
ARMv7_OP4(0x0fef, 0x0010, 0x004d, 0x0000, A1, SUB_SPR),
|
||||
ARMv7_OP2(0xfe00, 0x1e00, T1, SUB_IMM),
|
||||
ARMv7_OP2(0xf800, 0x3800, T2, SUB_IMM),
|
||||
ARMv7_OP4(0xfbe0, 0x8000, 0xf1a0, 0x0000, T3, SUB_IMM),
|
||||
ARMv7_OP4(0xfbf0, 0x8000, 0xf2a0, 0x0000, T4, SUB_IMM),
|
||||
ARMv7_OP4(0x0fe0, 0x0000, 0x0240, 0x0000, A1, SUB_IMM),
|
||||
ARMv7_OP2(0xfe00, 0x1a00, T1, SUB_REG),
|
||||
ARMv7_OP4(0xffe0, 0x8000, 0xeba0, 0x0000, T2, SUB_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0010, 0x0040, 0x0000, A1, SUB_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0090, 0x0040, 0x0010, A1, SUB_RSR),
|
||||
|
||||
ARMv7_OP2(0xff00, 0xdf00, T1, SVC),
|
||||
ARMv7_OP4(0x0f00, 0x0000, 0x0f00, 0x0000, A1, SVC),
|
||||
|
@ -1091,6 +1097,12 @@ const ARMv7_opcode_t ARMv7_opcode_table[] =
|
|||
ARMv7_OP4(0x0fff, 0xffff, 0x0320, 0xf001, A1, YIELD),
|
||||
};
|
||||
|
||||
#undef ARMv7_OP2
|
||||
#undef ARMv7_OP4
|
||||
#undef SKIP_IF
|
||||
#undef BF
|
||||
#undef BT
|
||||
|
||||
struct ARMv7_op2_table_t
|
||||
{
|
||||
const ARMv7_opcode_t* data[0x10000];
|
||||
|
@ -1103,6 +1115,11 @@ struct ARMv7_op2_table_t
|
|||
{
|
||||
if (opcode.length == 2)
|
||||
{
|
||||
if (opcode.code & ~opcode.mask)
|
||||
{
|
||||
LOG_ERROR(GENERAL, "%s: wrong opcode mask (mask=0x%04x, code=0x%04x)", opcode.name, opcode.mask >> 16, opcode.code >> 16);
|
||||
}
|
||||
|
||||
t2.push_back(&opcode);
|
||||
}
|
||||
}
|
||||
|
@ -1113,7 +1130,7 @@ struct ARMv7_op2_table_t
|
|||
|
||||
for (auto& opcode : t2)
|
||||
{
|
||||
if (((i << 16) & opcode->mask) == opcode->code)
|
||||
if (((i << 16) & opcode->mask) == opcode->code && (!opcode->skip || !opcode->skip(i)))
|
||||
{
|
||||
data[i] = opcode;
|
||||
break;
|
||||
|
@ -1134,6 +1151,11 @@ struct ARMv7_op4t_table_t
|
|||
{
|
||||
if (opcode.length == 4 && opcode.type < A1)
|
||||
{
|
||||
if (opcode.code & ~opcode.mask)
|
||||
{
|
||||
LOG_ERROR(GENERAL, "%s: wrong opcode mask (mask=0x%04x 0x%04x, code=0x%04x 0x%04x)", opcode.name, opcode.mask >> 16, (u16)opcode.mask, opcode.code >> 16, (u16)opcode.code);
|
||||
}
|
||||
|
||||
table.push_back(&opcode);
|
||||
}
|
||||
}
|
||||
|
@ -1173,7 +1195,7 @@ void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump)
|
|||
{
|
||||
for (auto opcode : g_op4t.table)
|
||||
{
|
||||
if ((code.data & opcode->mask) == opcode->code)
|
||||
if ((code.data & opcode->mask) == opcode->code && (!opcode->skip || !opcode->skip(code.data)))
|
||||
{
|
||||
g_opct[code.data] = (found = opcode);
|
||||
break;
|
||||
|
|
|
@ -354,11 +354,11 @@ void ARMv7_instrs::ADD_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMN (immediate)";
|
||||
throw "ADD_IMM_T3: CMN (immediate)";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "ADD (SP plus immediate)";
|
||||
throw "ADD_IMM_T3: ADD (SP plus immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -371,11 +371,11 @@ void ARMv7_instrs::ADD_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "ADR";
|
||||
throw "ADD_IMM_T4: ADR";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "ADD (SP plus immediate)";
|
||||
throw "ADD_IMM_T4: ADD (SP plus immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ void ARMv7_instrs::ADD_REG(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (n == 13 || m == 13)
|
||||
{
|
||||
throw "ADD (SP plus register)";
|
||||
throw "ADD_REG_T2: ADD (SP plus register)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -443,11 +443,11 @@ void ARMv7_instrs::ADD_REG(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMN (register)";
|
||||
throw "ADD_REG_T3: CMN (register)";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "ADD (SP plus register)";
|
||||
throw "ADD_REG_T3: ADD (SP plus register)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -512,7 +512,7 @@ void ARMv7_instrs::ADD_SPI(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMN (immediate)";
|
||||
throw "ADD_SPI_T3: CMN (immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -674,7 +674,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en
|
|||
cond = (code.data >> 8) & 0xf;
|
||||
if (cond == 0xf)
|
||||
{
|
||||
throw "SVC";
|
||||
throw "B_T1: SVC";
|
||||
}
|
||||
|
||||
jump = 4 + sign<9, u32>((code.data & 0xff) << 1);
|
||||
|
@ -1165,7 +1165,7 @@ void ARMv7_instrs::LDR_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDR (literal)";
|
||||
throw "LDR_IMM_T3: LDR (literal)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1180,15 +1180,15 @@ void ARMv7_instrs::LDR_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDR (literal)";
|
||||
throw "LDR_IMM_T4: LDR (literal)";
|
||||
}
|
||||
if (index && add && !wback)
|
||||
{
|
||||
throw "LDRT";
|
||||
throw "LDR_IMM_T4: LDRT";
|
||||
}
|
||||
if (n == 13 && !index && add && wback && imm32 == 4)
|
||||
{
|
||||
throw "POP";
|
||||
throw "LDR_IMM_T4: POP";
|
||||
}
|
||||
if (!index && !wback)
|
||||
{
|
||||
|
@ -1252,7 +1252,7 @@ void ARMv7_instrs::LDR_REG(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDR (literal)";
|
||||
throw "LDR_REG_T2: LDR (literal)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1334,7 +1334,7 @@ void ARMv7_instrs::LDRD_IMM(ARMv7Context& context, const ARMv7Code code, const A
|
|||
}
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDRD (literal)";
|
||||
throw "LDRD_IMM_T1: LDRD (literal)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1538,7 +1538,7 @@ void ARMv7_instrs::LSL_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (!shift_n)
|
||||
{
|
||||
throw "MOV (register)";
|
||||
throw "LSL_IMM_T1: MOV (register)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1551,7 +1551,7 @@ void ARMv7_instrs::LSL_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (!shift_n)
|
||||
{
|
||||
throw "MOV (register)";
|
||||
throw "LSL_IMM_T2: MOV (register)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1949,7 +1949,7 @@ void ARMv7_instrs::POP(ARMv7Context& context, const ARMv7Code code, const ARMv7_
|
|||
reg_list = code.data & 0xffff;
|
||||
if (BitCount(reg_list) < 2)
|
||||
{
|
||||
throw "LDM / LDMIA / LDMFD";
|
||||
throw "POP_A1: LDM / LDMIA / LDMFD";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2006,7 +2006,7 @@ void ARMv7_instrs::PUSH(ARMv7Context& context, const ARMv7Code code, const ARMv7
|
|||
reg_list = code.data & 0xffff;
|
||||
if (BitCount(reg_list) < 2)
|
||||
{
|
||||
throw "STMDB / STMFD";
|
||||
throw "PUSH_A1: STMDB / STMFD";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2666,11 +2666,11 @@ void ARMv7_instrs::STR_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (index && add && !wback)
|
||||
{
|
||||
throw "STRT";
|
||||
throw "STR_IMM_T4: STRT";
|
||||
}
|
||||
if (n == 13 && index && !add && wback && imm32 == 4)
|
||||
{
|
||||
throw "PUSH";
|
||||
throw "STR_IMM_T4: PUSH";
|
||||
}
|
||||
if (n == 15 || (!index && !wback))
|
||||
{
|
||||
|
@ -2900,11 +2900,11 @@ void ARMv7_instrs::SUB_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMP (immediate)";
|
||||
throw "SUB_IMM_T3: CMP (immediate)";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "SUB (SP minus immediate)";
|
||||
throw "SUB_IMM_T3: SUB (SP minus immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2917,11 +2917,11 @@ void ARMv7_instrs::SUB_IMM(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (d == 15)
|
||||
{
|
||||
throw "ADR";
|
||||
throw "SUB_IMM_T4: ADR";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "SUB (SP minus immediate)";
|
||||
throw "SUB_IMM_T4: SUB (SP minus immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2977,11 +2977,11 @@ void ARMv7_instrs::SUB_REG(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMP (register)";
|
||||
throw "SUB_REG_T2: CMP (register)";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "SUB (SP minus register)";
|
||||
throw "SUB_REG_T2: SUB (SP minus register)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3040,7 +3040,7 @@ void ARMv7_instrs::SUB_SPI(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMP (immediate)";
|
||||
throw "SUB_SPI_T2: CMP (immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4773,7 +4773,7 @@ void ARMv7_instrs::MRC_(ARMv7Context& context, const ARMv7Code code, const ARMv7
|
|||
|
||||
if (cp - 10 < 2)
|
||||
{
|
||||
throw "Advanced SIMD and VFP";
|
||||
throw "MRC_(T1/A1): Advanced SIMD and VFP";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue