summaryrefslogtreecommitdiff
path: root/disassembler
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2024-08-30 16:16:45 +0100
committer Santiago Aboy Solanes <solanes@google.com> 2024-11-04 09:57:58 +0000
commit6ffbee21288cb2902119f8611c62b7ab59729b34 (patch)
treee3a028bb9ffdb4d467dac27f4c9d71dfa26c2866 /disassembler
parent4b18e4025e9b61712609a23c9c9215e4e0d53f87 (diff)
riscv: define and use funct7 for Print32BinOp
It is similar to what we do in the assembler (e.g. https://cs.android.com/android/platform/superproject/main/+/main:art/compiler/utils/riscv64/assembler_riscv64.h;l=2357;drc=659009289bf47d9bc4138391d835c66c35559da3) and it helps in making sure we are using the right number. Test: LUCI run https://ci.chromium.org/b/8732569971872894225 Change-Id: I6314a6a2de87962a1c9601afb6cf30fad1095c95
Diffstat (limited to 'disassembler')
-rw-r--r--disassembler/disassembler_riscv64.cc28
1 files changed, 14 insertions, 14 deletions
diff --git a/disassembler/disassembler_riscv64.cc b/disassembler/disassembler_riscv64.cc
index c0c5986160..5d2b5b4d73 100644
--- a/disassembler/disassembler_riscv64.cc
+++ b/disassembler/disassembler_riscv64.cc
@@ -779,13 +779,13 @@ void DisassemblerRiscv64::Printer::Print32BinOp(uint32_t insn32) {
DCHECK_EQ(insn32 & 0x77u, 0x33u); // Note: Bit 0x8 selects narrow binop.
bool narrow = (insn32 & 0x8u) != 0u;
uint32_t funct3 = (insn32 >> 12) & 7u;
+ uint32_t funct7 = (insn32 >> 25) & 0x7Fu;
uint32_t rd = GetRd(insn32);
uint32_t rs1 = GetRs1(insn32);
uint32_t rs2 = GetRs2(insn32);
- uint32_t high_bits = insn32 & 0xfe000000u;
// Print shorter macro instruction notation if available.
- if (high_bits == 0x40000000u && funct3 == /*SUB*/ 0u && rs1 == Zero) {
+ if (funct7 == 0x20u && funct3 == /*SUB*/ 0u && rs1 == Zero) {
os_ << (narrow ? "negw " : "neg ") << XRegName(rd) << ", " << XRegName(rs2);
} else if (!narrow && funct3 == /*SLT*/ 2u && rs2 == Zero) {
os_ << "sltz " << XRegName(rd) << ", " << XRegName(rs1);
@@ -793,47 +793,47 @@ void DisassemblerRiscv64::Printer::Print32BinOp(uint32_t insn32) {
os_ << "sgtz " << XRegName(rd) << ", " << XRegName(rs2);
} else if (!narrow && funct3 == /*SLTU*/ 3u && rs1 == Zero) {
os_ << "snez " << XRegName(rd) << ", " << XRegName(rs2);
- } else if (narrow && high_bits == 0x08000000u && funct3 == /*ADD.UW*/ 0u && rs2 == Zero) {
+ } else if (narrow && funct7 == 4u && funct3 == /*ADD.UW*/ 0u && rs2 == Zero) {
os_ << "zext.w " << XRegName(rd) << ", " << XRegName(rs1);
- } else if (!narrow && high_bits == 0x48000000u &&
+ } else if (!narrow && funct7 == 0x24u &&
(funct3 == /*BCLR*/ 1u || funct3 == /*BEXT*/ 5u)) {
os_ << ((funct3 == /*BCLR*/ 1u) ? "bclr" : "bext");
- } else if (!narrow && high_bits == 0x68000000u && funct3 == /*BINV*/ 1u) {
+ } else if (!narrow && funct7 == 0x34u && funct3 == /*BINV*/ 1u) {
os_ << "binv";
- } else if (!narrow && high_bits == 0x28000000u && funct3 == /*BSET*/ 1u) {
+ } else if (!narrow && funct7 == 0x14u && funct3 == /*BSET*/ 1u) {
os_ << "bset";
} else {
bool bad_high_bits = false;
- if (high_bits == 0x40000000u && (funct3 == /*SUB*/ 0u || funct3 == /*SRA*/ 5u)) {
+ if (funct7 == 0x20u && (funct3 == /*SUB*/ 0u || funct3 == /*SRA*/ 5u)) {
os_ << ((funct3 == /*SUB*/ 0u) ? "sub" : "sra");
- } else if (high_bits == 0x02000000u &&
+ } else if (funct7 == 1u &&
(!narrow || (funct3 == /*MUL*/ 0u || funct3 >= /*DIV/DIVU/REM/REMU*/ 4u))) {
static const char* const kOpcodes[] = {
"mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu"
};
os_ << kOpcodes[funct3];
- } else if (high_bits == 0x08000000u && narrow && funct3 == /*ADD.UW*/ 0u) {
+ } else if (funct7 == 4u && narrow && funct3 == /*ADD.UW*/ 0u) {
os_ << "add.u"; // "w" is added below.
- } else if (high_bits == 0x20000000u && (funct3 & 1u) == 0u && funct3 != 0u) {
+ } else if (funct7 == 0x10u && (funct3 & 1u) == 0u && funct3 != 0u) {
static const char* const kZbaOpcodes[] = { nullptr, "sh1add", "sh2add", "sh3add" };
DCHECK(kZbaOpcodes[funct3 >> 1] != nullptr);
os_ << kZbaOpcodes[funct3 >> 1] << (narrow ? ".u" /* "w" is added below. */ : "");
- } else if (high_bits == 0x40000000u && !narrow && funct3 >= 4u && funct3 != 5u) {
+ } else if (funct7 == 0x20u && !narrow && funct3 >= 4u && funct3 != 5u) {
static const char* const kZbbNegOpcodes[] = { "xnor", nullptr, "orn", "andn" };
DCHECK(kZbbNegOpcodes[funct3 - 4u] != nullptr);
os_ << kZbbNegOpcodes[funct3 - 4u];
- } else if (high_bits == 0x0a000000u && !narrow && funct3 >= 4u) {
+ } else if (funct7 == 0x5u && !narrow && funct3 >= 4u) {
static const char* const kZbbMinMaxOpcodes[] = { "min", "minu", "max", "maxu" };
DCHECK(kZbbMinMaxOpcodes[funct3 - 4u] != nullptr);
os_ << kZbbMinMaxOpcodes[funct3 - 4u];
- } else if (high_bits == 0x60000000u && (funct3 == /*ROL*/ 1u || funct3 == /*ROL*/ 5u)) {
+ } else if (funct7 == 0x30u && (funct3 == /*ROL*/ 1u || funct3 == /*ROL*/ 5u)) {
os_ << (funct3 == /*ROL*/ 1u ? "rol" : "ror");
} else if (!narrow || (funct3 == /*ADD*/ 0u || funct3 == /*SLL*/ 1u || funct3 == /*SRL*/ 5u)) {
static const char* const kOpcodes[] = {
"add", "sll", "slt", "sltu", "xor", "srl", "or", "and"
};
os_ << kOpcodes[funct3];
- bad_high_bits = (high_bits != 0u);
+ bad_high_bits = funct7 != 0u;
} else {
DCHECK(narrow);
os_ << "<unknown32>"; // Some of the above instructions do not have a narrow version.