citra-emu
/
citra-canary
Archived
1
0
Fork 0

arm_disasm: ARMv6 saturation media instructions

SSAT, SSAT16, USAT, USAT16
This commit is contained in:
aroulin 2015-08-07 13:44:02 +02:00
parent 47657a1817
commit e4ff244288
2 changed files with 55 additions and 2 deletions

View File

@ -76,6 +76,8 @@ static const char *opcode_names[] = {
"sev", "sev",
"smlal", "smlal",
"smull", "smull",
"ssat",
"ssat16",
"stc", "stc",
"stm", "stm",
"str", "str",
@ -101,6 +103,8 @@ static const char *opcode_names[] = {
"tst", "tst",
"umlal", "umlal",
"umull", "umull",
"usat",
"usat16",
"uxtab", "uxtab",
"uxtab16", "uxtab16",
"uxtah", "uxtah",
@ -257,6 +261,11 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn)
return DisassemblePLD(insn); return DisassemblePLD(insn);
case OP_SEL: case OP_SEL:
return DisassembleSEL(insn); return DisassembleSEL(insn);
case OP_SSAT:
case OP_SSAT16:
case OP_USAT:
case OP_USAT16:
return DisassembleSAT(opcode, insn);
case OP_STC: case OP_STC:
return "stc"; return "stc";
case OP_SWI: case OP_SWI:
@ -793,8 +802,35 @@ std::string ARM_Disasm::DisassembleREX(Opcode opcode, uint32_t insn) {
} }
} }
std::string ARM_Disasm::DisassembleSEL(uint32_t insn) std::string ARM_Disasm::DisassembleSAT(Opcode opcode, uint32_t insn) {
{ uint32_t cond = BITS(insn, 28, 31);
uint32_t sat_imm = BITS(insn, 16, 20);
uint32_t rd = BITS(insn, 12, 15);
uint32_t imm5 = BITS(insn, 7, 11);
uint32_t sh = BIT(insn, 6);
uint32_t rn = BITS(insn, 0, 3);
std::string shift_part = "";
bool opcode_has_shift = (opcode == OP_SSAT) || (opcode == OP_USAT);
if (opcode_has_shift && !(sh == 0 && imm5 == 0)) {
if (sh == 0)
shift_part += ", LSL #";
else
shift_part += ", ASR #";
if (imm5 == 0)
imm5 = 32;
shift_part += std::to_string(imm5);
}
if (opcode == OP_SSAT || opcode == OP_SSAT16)
sat_imm++;
return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], cond_to_str(cond), rd,
sat_imm, rn, shift_part.c_str());
}
std::string ARM_Disasm::DisassembleSEL(uint32_t insn) {
uint32_t cond = BITS(insn, 28, 31); uint32_t cond = BITS(insn, 28, 31);
uint32_t rn = BITS(insn, 16, 19); uint32_t rn = BITS(insn, 16, 19);
uint32_t rd = BITS(insn, 12, 15); uint32_t rd = BITS(insn, 12, 15);
@ -1048,12 +1084,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) {
return OP_SEL; return OP_SEL;
break; break;
case 0x2: case 0x2:
if (BIT(op2, 0) == 0)
return OP_SSAT;
if (op2 == 0x1)
return OP_SSAT16;
if (op2 == 0x3 && a != 0xf) if (op2 == 0x3 && a != 0xf)
return OP_SXTAB; return OP_SXTAB;
if (op2 == 0x3 && a == 0xf) if (op2 == 0x3 && a == 0xf)
return OP_SXTB; return OP_SXTB;
break; break;
case 0x3: case 0x3:
if (BIT(op2, 0) == 0)
return OP_SSAT;
if (op2 == 0x3 && a != 0xf) if (op2 == 0x3 && a != 0xf)
return OP_SXTAH; return OP_SXTAH;
if (op2 == 0x3 && a == 0xf) if (op2 == 0x3 && a == 0xf)
@ -1066,12 +1108,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) {
return OP_UXTB16; return OP_UXTB16;
break; break;
case 0x6: case 0x6:
if (BIT(op2, 0) == 0)
return OP_USAT;
if (op2 == 0x1)
return OP_USAT16;
if (op2 == 0x3 && a != 0xf) if (op2 == 0x3 && a != 0xf)
return OP_UXTAB; return OP_UXTAB;
if (op2 == 0x3 && a == 0xf) if (op2 == 0x3 && a == 0xf)
return OP_UXTB; return OP_UXTB;
break; break;
case 0x7: case 0x7:
if (BIT(op2, 0) == 0)
return OP_USAT;
if (op2 == 0x3 && a != 0xf) if (op2 == 0x3 && a != 0xf)
return OP_UXTAH; return OP_UXTAH;
if (op2 == 0x3 && a == 0xf) if (op2 == 0x3 && a == 0xf)

View File

@ -57,6 +57,8 @@ enum Opcode {
OP_SEV, OP_SEV,
OP_SMLAL, OP_SMLAL,
OP_SMULL, OP_SMULL,
OP_SSAT,
OP_SSAT16,
OP_STC, OP_STC,
OP_STM, OP_STM,
OP_STR, OP_STR,
@ -82,6 +84,8 @@ enum Opcode {
OP_TST, OP_TST,
OP_UMLAL, OP_UMLAL,
OP_UMULL, OP_UMULL,
OP_USAT,
OP_USAT16,
OP_UXTAB, OP_UXTAB,
OP_UXTAB16, OP_UXTAB16,
OP_UXTAH, OP_UXTAH,
@ -171,6 +175,7 @@ class ARM_Disasm {
static std::string DisassemblePKH(uint32_t insn); static std::string DisassemblePKH(uint32_t insn);
static std::string DisassemblePLD(uint32_t insn); static std::string DisassemblePLD(uint32_t insn);
static std::string DisassembleREX(Opcode opcode, uint32_t insn); static std::string DisassembleREX(Opcode opcode, uint32_t insn);
static std::string DisassembleSAT(Opcode opcode, uint32_t insn);
static std::string DisassembleSEL(uint32_t insn); static std::string DisassembleSEL(uint32_t insn);
static std::string DisassembleSWI(uint32_t insn); static std::string DisassembleSWI(uint32_t insn);
static std::string DisassembleSWP(Opcode opcode, uint32_t insn); static std::string DisassembleSWP(Opcode opcode, uint32_t insn);