diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp')
| -rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 32e9f4e3a6c..0fc775f63ed 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -88,19 +88,29 @@ MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII, return new RISCVMCCodeEmitter(Ctx, MCII); } -// Expand PseudoCALL and PseudoTAIL to AUIPC and JALR with relocation types. -// We expand PseudoCALL and PseudoTAIL while encoding, meaning AUIPC and JALR -// won't go through RISCV MC to MC compressed instruction transformation. This -// is acceptable because AUIPC has no 16-bit form and C_JALR have no immediate -// operand field. We let linker relaxation deal with it. When linker -// relaxation enabled, AUIPC and JALR have chance relax to JAL. If C extension -// is enabled, JAL has chance relax to C_JAL. +// Expand PseudoCALL(Reg) and PseudoTAIL to AUIPC and JALR with relocation +// types. We expand PseudoCALL(Reg) and PseudoTAIL while encoding, meaning AUIPC +// and JALR won't go through RISCV MC to MC compressed instruction +// transformation. This is acceptable because AUIPC has no 16-bit form and +// C_JALR have no immediate operand field. We let linker relaxation deal with +// it. When linker relaxation enabled, AUIPC and JALR have chance relax to JAL. +// If C extension is enabled, JAL has chance relax to C_JAL. void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { MCInst TmpInst; - MCOperand Func = MI.getOperand(0); - unsigned Ra = (MI.getOpcode() == RISCV::PseudoTAIL) ? RISCV::X6 : RISCV::X1; + MCOperand Func; + unsigned Ra; + if (MI.getOpcode() == RISCV::PseudoTAIL) { + Func = MI.getOperand(0); + Ra = RISCV::X6; + } else if (MI.getOpcode() == RISCV::PseudoCALLReg) { + Func = MI.getOperand(1); + Ra = MI.getOperand(0).getReg(); + } else { + Func = MI.getOperand(0); + Ra = RISCV::X1; + } uint32_t Binary; assert(Func.isExpr() && "Expected expression"); @@ -118,7 +128,7 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS, // Emit JALR X0, X6, 0 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0); else - // Emit JALR X1, X1, 0 + // Emit JALR Ra, Ra, 0 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0); Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); support::endian::write(OS, Binary, support::little); @@ -169,7 +179,8 @@ void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, // Get byte count of instruction. unsigned Size = Desc.getSize(); - if (MI.getOpcode() == RISCV::PseudoCALL || + if (MI.getOpcode() == RISCV::PseudoCALLReg || + MI.getOpcode() == RISCV::PseudoCALL || MI.getOpcode() == RISCV::PseudoTAIL) { expandFunctionCall(MI, OS, Fixups, STI); MCNumEmitted += 2; |

