diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -23,6 +23,7 @@ class RISCVAsmBackend : public MCAsmBackend { const MCSubtargetInfo &STI; + const MCRegisterInfo &MRI; uint8_t OSABI; bool Is64Bit; bool ForceRelocs = false; @@ -30,10 +31,10 @@ RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown; public: - RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit, - const MCTargetOptions &Options) - : MCAsmBackend(support::little), STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), - TargetOptions(Options) { + RISCVAsmBackend(const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, + uint8_t OSABI, bool Is64Bit, const MCTargetOptions &Options) + : MCAsmBackend(support::little), STI(STI), MRI(MRI), OSABI(OSABI), + Is64Bit(Is64Bit), TargetOptions(Options) { TargetABI = RISCVABI::computeTargetABI( STI.getTargetTriple(), STI.getFeatureBits(), Options.getABIName()); RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits()); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -23,6 +23,10 @@ using namespace llvm; +// Include the auto-generated portion of the uncompress emitter. +#define GEN_UNCOMPRESS_INSTR +#include "RISCVGenCompressInstEmitter.inc" + Optional RISCVAsmBackend::getFixupKind(StringRef Name) const { if (STI.getTargetTriple().isOSBinFormatELF()) { unsigned Type; @@ -141,60 +145,18 @@ void RISCVAsmBackend::relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const { - // TODO: replace this with call to auto generated uncompressinstr() function. - MCInst Res; - switch (Inst.getOpcode()) { - default: - llvm_unreachable("Opcode not expected!"); - case RISCV::C_BEQZ: - // c.beqz $rs1, $imm -> beq $rs1, X0, $imm. - Res.setOpcode(RISCV::BEQ); - Res.addOperand(Inst.getOperand(0)); - Res.addOperand(MCOperand::createReg(RISCV::X0)); - Res.addOperand(Inst.getOperand(1)); - break; - case RISCV::C_BNEZ: - // c.bnez $rs1, $imm -> bne $rs1, X0, $imm. - Res.setOpcode(RISCV::BNE); - Res.addOperand(Inst.getOperand(0)); - Res.addOperand(MCOperand::createReg(RISCV::X0)); - Res.addOperand(Inst.getOperand(1)); - break; - case RISCV::C_J: - // c.j $imm -> jal X0, $imm. - Res.setOpcode(RISCV::JAL); - Res.addOperand(MCOperand::createReg(RISCV::X0)); - Res.addOperand(Inst.getOperand(0)); - break; - case RISCV::C_JAL: - // c.jal $imm -> jal X1, $imm. - Res.setOpcode(RISCV::JAL); - Res.addOperand(MCOperand::createReg(RISCV::X1)); - Res.addOperand(Inst.getOperand(0)); - break; - } - Inst = std::move(Res); -} - -// Given a compressed control flow instruction this function returns -// the expanded instruction. -unsigned RISCVAsmBackend::getRelaxedOpcode(unsigned Op) const { - switch (Op) { - default: - return Op; - case RISCV::C_BEQZ: - return RISCV::BEQ; - case RISCV::C_BNEZ: - return RISCV::BNE; - case RISCV::C_J: - case RISCV::C_JAL: // fall through. - return RISCV::JAL; - } + MCInst UncompressedMI; + bool Res = uncompressInst(UncompressedMI, Inst, MRI, STI); + if (Res) + Inst = std::move(UncompressedMI); } bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const { - return getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode(); + // TODO: This is inefficient, we need to generate a `isUncompressibleInst()` + // function in tablegen. + MCInst UncompressedMI; + return uncompressInst(UncompressedMI, Inst, MRI, STI); } bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { @@ -472,5 +434,5 @@ const MCTargetOptions &Options) { const Triple &TT = STI.getTargetTriple(); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); - return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options); + return new RISCVAsmBackend(STI, MRI, OSABI, TT.isArch64Bit(), Options); } diff --git a/llvm/test/MC/RISCV/rv64-relax-all.s b/llvm/test/MC/RISCV/rv64-relax-all.s --- a/llvm/test/MC/RISCV/rv64-relax-all.s +++ b/llvm/test/MC/RISCV/rv64-relax-all.s @@ -4,12 +4,18 @@ ## Check the instructions are relaxed correctly -NEAR: +# INSTR: c.nop +# RELAX-INSTR: addi zero, zero, 0 +c.nop -# INSTR: c.beqz a0, 0 -# RELAX-INSTR: beq a0, zero, 0 -c.beqz a0, NEAR +NEAR1: -# INSTR: c.j -2 -# RELAX-INSTR: jal zero, -4 -c.j NEAR +# INSTR: c.beqz a0, 0 +# RELAX-INSTR: beq a0, zero, 0 +c.beqz a0, NEAR1 + +NEAR2: + +# INSTR: c.j 0 +# RELAX-INSTR: jal zero, 0 +c.j NEAR2