diff options
author | 2023-08-17 09:53:57 +0000 | |
---|---|---|
committer | 2023-08-21 06:52:16 +0000 | |
commit | b1a0d105523f17449f8d41c44f8a714cb1b31902 (patch) | |
tree | c25fa599187f3bef559e48c0750081a9d3f5464b /disassembler | |
parent | 5655ec289c3ffd389a02108e2e601b16a9dedbd4 (diff) |
riscv64: Add support for Zba and Zbb extensions.
Test: m test-art-host-gtest
Test: Manually add calls to emit these instructions after
UNIMP in JNI assembler's `DeliverPendingException()`
and then `m dump-oat` and inspect the output.
Bug: 283082089
Change-Id: I4807d0b214e7896544dd74349e0637a1e37fc1bf
Diffstat (limited to 'disassembler')
-rw-r--r-- | disassembler/disassembler_riscv64.cc | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/disassembler/disassembler_riscv64.cc b/disassembler/disassembler_riscv64.cc index cdb0390ce0..1dcf1a31cd 100644 --- a/disassembler/disassembler_riscv64.cc +++ b/disassembler/disassembler_riscv64.cc @@ -393,6 +393,19 @@ void DisassemblerRiscv64::Printer::Print32BinOpImm(uint32_t insn32) { os_ << "zextb " << XRegName(rd) << ", " << XRegName(rs1); } else if (!narrow && funct3 == /*SLTIU*/ 3u && imm == 1) { os_ << "seqz " << XRegName(rd) << ", " << XRegName(rs1); + } else if ((insn32 & 0xfc00707fu) == 0x0800101bu) { + os_ << "slli.uw " << XRegName(rd) << ", " << XRegName(rs1) << ", " << (imm & 0x3fu); + } else if ((imm ^ 0x600u) < 3u && funct3 == 1u) { + static const char* const kBitOpcodes[] = { "clz", "ctz", "cpop" }; + os_ << kBitOpcodes[imm ^ 0x600u] << (narrow ? "w " : " ") + << XRegName(rd) << ", " << XRegName(rs1); + } else if ((imm ^ 0x600u) < (narrow ? 32 : 64) && funct3 == 5u) { + os_ << "rori" << (narrow ? "w " : " ") + << XRegName(rd) << ", " << XRegName(rs1) << ", " << (imm ^ 0x600u); + } else if (imm == 0x287u && !narrow && funct3 == 5u) { + os_ << "orc.b " << XRegName(rd) << ", " << XRegName(rs1); + } else if (imm == 0x6b8u && !narrow && funct3 == 5u) { + os_ << "rev8 " << XRegName(rd) << ", " << XRegName(rs1); } else { bool bad_high_bits = false; if (funct3 == /*SLLI*/ 1u || funct3 == /*SRLI/SRAI*/ 5u) { @@ -439,16 +452,34 @@ 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) { + os_ << "zext.w " << XRegName(rd) << ", " << XRegName(rs1); } else { bool bad_high_bits = false; if (high_bits == 0x40000000u && (funct3 == /*SUB*/ 0u || funct3 == /*SRA*/ 5u)) { os_ << ((funct3 == /*SUB*/ 0u) ? "sub" : "sra"); - } else if (high_bits == 0x02000000 && + } else if (high_bits == 0x02000000u && (!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) { + os_ << "add.u"; // "w" is added below. + } else if (high_bits == 0x20000000u && (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) { + 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) { + 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)) { + 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" |