I want to create a new instruction (pip it just passes info to the processor) similar to the U-type instruction in RISC-V. However, instead of it being
Opcode, dest, immediate this new instruction is Opcode, src, immediate. I want to insert this new instruction in IR.
So far I have created a new intrinsic function.
include/llvm/IR/IntrinsicsRISCV.td
let TargetPrefix = "riscv" in {
def int_riscv_pip : DefaultAttrsIntrinsic<
[], [llvm_i64_ty, llvm_i64_ty],
[IntrArgMemOnly, IntrSpeculatable]>;
}
Declared my new instruction format in llvm/lib/Target/RISCV/RISCVInstrFormats.td
class RVInstPIP<RISCVOpcode opcode, dag outs, dag ins, string opcodestr,
string argstr>
: RVInst<outs, ins, opcodestr, argstr, [], InstFormatPIP> {
bits<20> imm20;
bits<5> rs1;
let Inst{31-12} = imm20;
let Inst{11-7} = rs1;
let Opcode = opcode.Value;
}
I have added instruction logic in the llvm/lib/Target/RISCV/RISCVInstrInfo.td
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
def PIP : RVInstPIP< OPC_CUSTOM_1, (outs), (ins GPR:$rs1, uimm20_lui:$imm20),
"pip", "$rs1, $imm20">;
}
However when I try to get my new intrinsic function, it does not even recognize it and I get this error: ‘pip’ is not a member of ‘llvm::Intrinsic’
(not the full pass)
#include "llvm/IR/Intrinsics.h"
static bool safeRegion( Function &F, const TargetLibraryInfo &TLI)
for (auto& B : F) {
for (auto& I : B) {
if(auto *callInst = dyn_cast<CallInst>(&I)){
IRBuilder<> builder(callInst);
Function* new_func = Intrinsic::getDeclaration(F.getParent(), Intrinsic::pip);
}
}
}