[LLVMdev] Tablegen to match a literal in an instruction

Villmow, Micah Micah.Villmow at amd.com
Thu Apr 19 15:07:28 PDT 2012


I am trying to make some modifications to our code generator that will produce better code, but require adding new patterns.

What I am trying to do is take a register/register pattern and change it to a register/immediate.
So for example, I have this pattern:
class ILFormat<ILOpCode op, dag outs, dag ins, string asmstr, list<dag> pattern>
: Instruction {
     let Namespace = "AMDIL";
     dag OutOperandList = outs;
     dag InOperandList = ins;
     ILOpCode operation = op;
     let Pattern = pattern;
     let AsmString = !strconcat(asmstr, "\n");
     bit hasIEEEFlag = 0;
     bit hasZeroOpFlag = 0;
}
class BinaryOp<ILOpCode op, SDNode OpNode, RegisterClass dReg,
      RegisterClass sReg0, RegisterClass sReg1>
      : ILFormat<op, (outs dReg:$dst), (ins sReg0:$src0, sReg1:$src1),
      !strconcat(op.Text, " $dst, $src0, $src1"),
      [(set dReg:$dst, (OpNode sReg0:$src0, sReg1:$src1))]>;
multiclass BinaryOpMCInt<ILOpCode OpCode, SDNode OpNode> {
  def _i8    : BinaryOp<OpCode, OpNode, GPRI8, GPRI8, GPRI8>;

  def _i16    : BinaryOp<OpCode, OpNode, GPRI16, GPRI16, GPRI16>;
  def _i32    : BinaryOp<OpCode, OpNode, GPRI32, GPRI32, GPRI32>;
  def _i64    : BinaryOp<OpCode, OpNode, GPRI64, GPRI64, GPRI64>;
}
defm AND        : BinaryOpMCInt<IL_OP_AND, and>;

I want to turn this into a register/immediate pattern by changing it to:
class ILFormat<dag outs, dag ins, string asmstr, list<dag> pattern>
: Instruction {
     let Namespace = "AMDIL";
     dag OutOperandList = outs;
     dag InOperandList = ins;
     let Pattern = pattern;
     let AsmString = !strconcat(asmstr, "\n");
}
multiclass BinaryOp<SDNode OpNode, RegisterClass dReg,
      RegisterClass sReg0, RegisterClass sReg1, Operand lit>
{
def _rr: ILFormat<op, (outs dReg:$dst), (ins sReg0:$src0, sReg1:$src1),
      !strconcat(op.Text, " $dst, $src0, $src1"),
      [(set dReg:$dst, (OpNode sReg0:$src0, sReg1:$src1))]>;
def _ri : ILFormat<op, (outs dReg:$dst), (ins sReg0:$src0, lit:$src1),
      "and  $dst, $src0, $src1"),
      [(set dReg:$dst, (OpNode sReg0:$src0, imm:$src1))]>;

}
multiclass BinaryOpMCInt<SDNode OpNode> {
  defm _i32  : BinaryOp<OpNode, GPRI32, GPRI32, GPRI32, i32imm>;
}
defm AND        : BinaryOpMCInt<and>;


When I run on a simple program which just ands a value and writes to memory, I get this error:
LLVM ERROR: Cannot select: 0x99555d0: i32 = Constant<2> [ORD=7] [ID=8]

Where 0x99555d0 is only used as the second operand of the 'and' node.

So, how can I figure out what I'm doing wrong? Does anyone see anything majorly wrong here?

Thanks,
Micah
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120419/2292b1cd/attachment.html>


More information about the llvm-dev mailing list