summaryrefslogtreecommitdiff
path: root/src/core/arm/disassembler
diff options
context:
space:
mode:
authorGravatar aroulin2015-08-07 13:44:02 +0200
committerGravatar aroulin2015-08-09 01:31:10 +0200
commite4ff2442885e42ed5cfecb1ceadebf99da2cd2cf (patch)
treeceaf39f2fd6d361e9e2b87b0d1b07927addbe182 /src/core/arm/disassembler
parentarm_disasm: ARMv6 packing and sign-extend media instructions (diff)
downloadyuzu-e4ff2442885e42ed5cfecb1ceadebf99da2cd2cf.tar.gz
yuzu-e4ff2442885e42ed5cfecb1ceadebf99da2cd2cf.tar.xz
yuzu-e4ff2442885e42ed5cfecb1ceadebf99da2cd2cf.zip
arm_disasm: ARMv6 saturation media instructions
SSAT, SSAT16, USAT, USAT16
Diffstat (limited to 'src/core/arm/disassembler')
-rw-r--r--src/core/arm/disassembler/arm_disasm.cpp52
-rw-r--r--src/core/arm/disassembler/arm_disasm.h5
2 files changed, 55 insertions, 2 deletions
diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp
index 3ac867949..d73495fe9 100644
--- a/src/core/arm/disassembler/arm_disasm.cpp
+++ b/src/core/arm/disassembler/arm_disasm.cpp
@@ -76,6 +76,8 @@ static const char *opcode_names[] = {
76 "sev", 76 "sev",
77 "smlal", 77 "smlal",
78 "smull", 78 "smull",
79 "ssat",
80 "ssat16",
79 "stc", 81 "stc",
80 "stm", 82 "stm",
81 "str", 83 "str",
@@ -101,6 +103,8 @@ static const char *opcode_names[] = {
101 "tst", 103 "tst",
102 "umlal", 104 "umlal",
103 "umull", 105 "umull",
106 "usat",
107 "usat16",
104 "uxtab", 108 "uxtab",
105 "uxtab16", 109 "uxtab16",
106 "uxtah", 110 "uxtah",
@@ -257,6 +261,11 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn)
257 return DisassemblePLD(insn); 261 return DisassemblePLD(insn);
258 case OP_SEL: 262 case OP_SEL:
259 return DisassembleSEL(insn); 263 return DisassembleSEL(insn);
264 case OP_SSAT:
265 case OP_SSAT16:
266 case OP_USAT:
267 case OP_USAT16:
268 return DisassembleSAT(opcode, insn);
260 case OP_STC: 269 case OP_STC:
261 return "stc"; 270 return "stc";
262 case OP_SWI: 271 case OP_SWI:
@@ -793,8 +802,35 @@ std::string ARM_Disasm::DisassembleREX(Opcode opcode, uint32_t insn) {
793 } 802 }
794} 803}
795 804
796std::string ARM_Disasm::DisassembleSEL(uint32_t insn) 805std::string ARM_Disasm::DisassembleSAT(Opcode opcode, uint32_t insn) {
797{ 806 uint32_t cond = BITS(insn, 28, 31);
807 uint32_t sat_imm = BITS(insn, 16, 20);
808 uint32_t rd = BITS(insn, 12, 15);
809 uint32_t imm5 = BITS(insn, 7, 11);
810 uint32_t sh = BIT(insn, 6);
811 uint32_t rn = BITS(insn, 0, 3);
812
813 std::string shift_part = "";
814 bool opcode_has_shift = (opcode == OP_SSAT) || (opcode == OP_USAT);
815 if (opcode_has_shift && !(sh == 0 && imm5 == 0)) {
816 if (sh == 0)
817 shift_part += ", LSL #";
818 else
819 shift_part += ", ASR #";
820
821 if (imm5 == 0)
822 imm5 = 32;
823 shift_part += std::to_string(imm5);
824 }
825
826 if (opcode == OP_SSAT || opcode == OP_SSAT16)
827 sat_imm++;
828
829 return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], cond_to_str(cond), rd,
830 sat_imm, rn, shift_part.c_str());
831}
832
833std::string ARM_Disasm::DisassembleSEL(uint32_t insn) {
798 uint32_t cond = BITS(insn, 28, 31); 834 uint32_t cond = BITS(insn, 28, 31);
799 uint32_t rn = BITS(insn, 16, 19); 835 uint32_t rn = BITS(insn, 16, 19);
800 uint32_t rd = BITS(insn, 12, 15); 836 uint32_t rd = BITS(insn, 12, 15);
@@ -1048,12 +1084,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) {
1048 return OP_SEL; 1084 return OP_SEL;
1049 break; 1085 break;
1050 case 0x2: 1086 case 0x2:
1087 if (BIT(op2, 0) == 0)
1088 return OP_SSAT;
1089 if (op2 == 0x1)
1090 return OP_SSAT16;
1051 if (op2 == 0x3 && a != 0xf) 1091 if (op2 == 0x3 && a != 0xf)
1052 return OP_SXTAB; 1092 return OP_SXTAB;
1053 if (op2 == 0x3 && a == 0xf) 1093 if (op2 == 0x3 && a == 0xf)
1054 return OP_SXTB; 1094 return OP_SXTB;
1055 break; 1095 break;
1056 case 0x3: 1096 case 0x3:
1097 if (BIT(op2, 0) == 0)
1098 return OP_SSAT;
1057 if (op2 == 0x3 && a != 0xf) 1099 if (op2 == 0x3 && a != 0xf)
1058 return OP_SXTAH; 1100 return OP_SXTAH;
1059 if (op2 == 0x3 && a == 0xf) 1101 if (op2 == 0x3 && a == 0xf)
@@ -1066,12 +1108,18 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(uint32_t insn) {
1066 return OP_UXTB16; 1108 return OP_UXTB16;
1067 break; 1109 break;
1068 case 0x6: 1110 case 0x6:
1111 if (BIT(op2, 0) == 0)
1112 return OP_USAT;
1113 if (op2 == 0x1)
1114 return OP_USAT16;
1069 if (op2 == 0x3 && a != 0xf) 1115 if (op2 == 0x3 && a != 0xf)
1070 return OP_UXTAB; 1116 return OP_UXTAB;
1071 if (op2 == 0x3 && a == 0xf) 1117 if (op2 == 0x3 && a == 0xf)
1072 return OP_UXTB; 1118 return OP_UXTB;
1073 break; 1119 break;
1074 case 0x7: 1120 case 0x7:
1121 if (BIT(op2, 0) == 0)
1122 return OP_USAT;
1075 if (op2 == 0x3 && a != 0xf) 1123 if (op2 == 0x3 && a != 0xf)
1076 return OP_UXTAH; 1124 return OP_UXTAH;
1077 if (op2 == 0x3 && a == 0xf) 1125 if (op2 == 0x3 && a == 0xf)
diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h
index 20e92fd0e..d8d4faf95 100644
--- a/src/core/arm/disassembler/arm_disasm.h
+++ b/src/core/arm/disassembler/arm_disasm.h
@@ -57,6 +57,8 @@ enum Opcode {
57 OP_SEV, 57 OP_SEV,
58 OP_SMLAL, 58 OP_SMLAL,
59 OP_SMULL, 59 OP_SMULL,
60 OP_SSAT,
61 OP_SSAT16,
60 OP_STC, 62 OP_STC,
61 OP_STM, 63 OP_STM,
62 OP_STR, 64 OP_STR,
@@ -82,6 +84,8 @@ enum Opcode {
82 OP_TST, 84 OP_TST,
83 OP_UMLAL, 85 OP_UMLAL,
84 OP_UMULL, 86 OP_UMULL,
87 OP_USAT,
88 OP_USAT16,
85 OP_UXTAB, 89 OP_UXTAB,
86 OP_UXTAB16, 90 OP_UXTAB16,
87 OP_UXTAH, 91 OP_UXTAH,
@@ -171,6 +175,7 @@ class ARM_Disasm {
171 static std::string DisassemblePKH(uint32_t insn); 175 static std::string DisassemblePKH(uint32_t insn);
172 static std::string DisassemblePLD(uint32_t insn); 176 static std::string DisassemblePLD(uint32_t insn);
173 static std::string DisassembleREX(Opcode opcode, uint32_t insn); 177 static std::string DisassembleREX(Opcode opcode, uint32_t insn);
178 static std::string DisassembleSAT(Opcode opcode, uint32_t insn);
174 static std::string DisassembleSEL(uint32_t insn); 179 static std::string DisassembleSEL(uint32_t insn);
175 static std::string DisassembleSWI(uint32_t insn); 180 static std::string DisassembleSWI(uint32_t insn);
176 static std::string DisassembleSWP(Opcode opcode, uint32_t insn); 181 static std::string DisassembleSWP(Opcode opcode, uint32_t insn);