environment: LLVM 10.0.0, Ubuntu 20.04
Input Command:
cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug -DLLVM_USE_LINKER=lld -G "Ninja" ../llvm
ninja -j4
error info:
home/dyy/llvm-project-llvmorg-10.0.0/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td:175:1: error: Pseudo result 'JIRL' operand count mismatch
def RET : RetBase<GPROut>;
^
Description:
The new backend LoongArch doesn’t have instruction like “JR $ra” as indirect branch instruction, so I tried to use “JIRL $zero $rj 0” instead.
“JIRL” 's formation is like:
jirl rd, rj, offs16
JIRL:
rd = PC+4
PC = rj + offs16
The question is, the “JR” instruction has only one parameter, but “JIRL” has 3. I use PseudoInstExpansion to solve this problem but it seems like I screwed up something. Here is my code in InstrInfo.td:
class JumpFR<bits<6> op, string instr_asm, RegisterClass RC>:
Fmt2RI16<op, (outs), (ins RC:$rj),
!strconcat(instr_asm, "\t$rj"), [(brind RC:$rj)], IIBranch> {
let rd = 0;
let imm16 = 0;
}
def JIRL : JumpFR<0b010011, "jirl", GPROut>;
/// Return instruction
class RetBase<RegisterClass RC>
: JumpFR<0b010011, "ret", RC>,
PseudoInstExpansion<(JIRL ZERO, RA, 0)>{
// ZERO and RA are defined in RegisterInfo.td
// ZERO represents r0 which is always 0,
//RA represents r1 used as return address register
let isReturn = 1;
let isCodeGenOnly = 1;
let hasCtrlDep = 1;
let hasExtraSrcRegAllocReq = 1;
}
def RET : RetBase<GPROut>;
Above, Fmt2RI16 is a LoongArch instruction formation which match with 2 Register and 1 Immediate number:
class Fmt2RI16<bits<6> op, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin>
: LAInst<outs, ins, asmstr, pattern, itin> {
bits<16> imm16;
bits<5> rj;
bits<5> rd;
let Inst{31-26} = op;
let Inst{25-10} = imm16;
let Inst{9-5} = rj;
let Inst{4-0} = rd;
}