forked from ShuriZma/suyu
arm_disasm: ARMv6 saturation media instructions
SSAT, SSAT16, USAT, USAT16
This commit is contained in:
parent
47657a1817
commit
e4ff244288
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue