diff options
author | 2024-08-30 16:16:45 +0100 | |
---|---|---|
committer | 2024-11-04 09:57:58 +0000 | |
commit | 6ffbee21288cb2902119f8611c62b7ab59729b34 (patch) | |
tree | e3a028bb9ffdb4d467dac27f4c9d71dfa26c2866 /disassembler | |
parent | 4b18e4025e9b61712609a23c9c9215e4e0d53f87 (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.cc | 28 |
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. |