Hi, It seems like CodeEmitterGen gets confused when we use named suboperands.
sample code:
def memsrc : Operand {
let PrintMethod = “printSrcMemOperand”;
let MIOperandInfo = (ops GR16:$ra, i16imm:$imm_i16);
let ParserMatchClass = memAsmOperand;
}
def LOAD16m : Inst32rri<0x0, (outs GR16:$rb), (ins memsrc:$src2),
“ldi16 {$rb, $src2}”,
[(set GR16:$rb, (load addr:$src2))]>;
class Inst32rri<bits<6> opcode, dag outs, dag ins, string asmstr, list pattern>
: TargetInst32<opcode, outs, ins, asmstr, pattern> {
bits<5> rb;
bits<5> ra;
bits<16> imm_i16;
let Inst{9-5} = rb; // operand 0
let Inst{4-0} = ra; // operand 1
let Inst{31-16} = imm_i16; // operand 2
}
And this code was generated
// op: rb – Operand #0
op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
Value |= (op & UINT64_C(31)) << 5;
// op: ra – Operand #0
op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI);
Value |= op & UINT64_C(31);
// op: imm_i16 – Operand #1
op = getMachineOpValue(MI, MI.getOperand(1), Fixups, STI);
Value |= (op & UINT64_C(65535)) << 16;