[llvm-commits] CVS: llvm/test/Regression/TableGen/TargetInstrInfo.td
Chris Lattner
lattner at cs.uiuc.edu
Sun Jul 25 05:13:45 PDT 2004
Changes in directory llvm/test/Regression/TableGen:
TargetInstrInfo.td added (r1.1)
---
Log message:
Codify my thoughts on where we want to end up with the target-independent
code generator. Comments welcome.
---
Diffs of the changes: (+148 -0)
Index: llvm/test/Regression/TableGen/TargetInstrInfo.td
diff -c /dev/null llvm/test/Regression/TableGen/TargetInstrInfo.td:1.1
*** /dev/null Sun Jul 25 07:13:45 2004
--- llvm/test/Regression/TableGen/TargetInstrInfo.td Sun Jul 25 07:13:35 2004
***************
*** 0 ****
--- 1,148 ----
+ // This test describes how we eventually want to describe instructions in
+ // the target independent code generators.
+ // RUN: tblgen %s
+
+ // Target indep stuff.
+ class Instruction { // Would have other stuff eventually
+ bit isTwoAddress = 0;
+ string AssemblyString;
+ }
+ class RegisterClass;
+
+ class RTLNode;
+
+ def ops; // Marker for operand list.
+
+ // Various expressions used in RTL descriptions.
+ def imm8 : RTLNode;
+ def imm32 : RTLNode;
+ def addr : RTLNode;
+
+ def set : RTLNode;
+ def signext : RTLNode;
+ def zeroext : RTLNode;
+ def plus : RTLNode;
+ def and : RTLNode;
+ def xor : RTLNode;
+ def shl : RTLNode;
+ def load : RTLNode;
+ def store : RTLNode;
+ def unspec : RTLNode;
+
+ // Start of X86 specific stuff.
+
+ def R8 : RegisterClass;
+ def R16 : RegisterClass;
+ def R32 : RegisterClass;
+
+ def CL; // As are currently defined
+ def AL;
+ def AX;
+ def EDX;
+
+ class Format<bits<5> val> {
+ bits<5> Value = val;
+ }
+
+ def Pseudo : Format<0>; def RawFrm : Format<1>;
+ def AddRegFrm : Format<2>; def MRMDestReg : Format<3>;
+ def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
+ def MRMSrcMem : Format<6>;
+ def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
+ def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
+ def MRM6r : Format<22>; def MRM7r : Format<23>;
+ def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
+ def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
+ def MRM6m : Format<30>; def MRM7m : Format<31>;
+
+
+ class Inst<dag opnds, string asmstr, bits<8> opcode,
+ Format f, list<dag> rtl> : Instruction {
+ dag Operands = opnds;
+ string AssemblyString = asmstr;
+ bits<8> Opcode = opcode;
+ Format Format = f;
+ list<dag> RTL = rtl;
+ }
+
+
+ // Start of instruction definitions, the real point of this file.
+ //
+ // Note that these patterns show a couple of important things:
+ // 1. The order and contents of the operands of the MachineInstr are
+ // described here. Eventually we can do away with this when everything
+ // is generated from the description.
+ // 2. The asm string is captured here, which makes it possible to get rid of
+ // a ton of hacks in the various printers and a bunch of flags.
+ // 3. Target specific properties (e.g. Format) can still be captured as
+ // needed.
+ // 4. We capture the behavior of the instruction with a simplified RTL-like
+ // expression.
+ // 5. The use/def properties for each operand are automatically inferred from
+ // the pattern.
+ // 6. Address expressions should become first-class entities.
+
+ // Simple copy instruction. isMoveInstr could easily be inferred from this,
+ // as could MRegisterInfo::copyRegToReg.
+ def MOV8rr : Inst<(ops R8:$dst, R8:$src),
+ "mov $dst, $src", 0x88, MRMDestReg,
+ [(set R8:$dst, R8:$src)]>;
+
+ // Simple immediate initialization.
+ def MOV8ri : Inst<(ops R8:$dst, imm8:$src),
+ "mov $dst, $src", 0xB0, AddRegFrm,
+ [(set R8:$dst, imm8:$src)]>;
+
+ // Two address instructions are described as three-addr instructions, with
+ // the special target-independent isTwoAddress flag set. The asm pattern
+ // should not refer to the $src1, this would be enforced by the
+ // TargetInstrInfo tablegen backend.
+ let isTwoAddress = 1 in
+ def AND8rr : Inst<(ops R8:$dst, R8:$src1, R8:$src2),
+ "and $dst, $src2", 0x20, MRMDestReg,
+ [(set R8:$dst, (and R8:$src1, R8:$src2))]>;
+
+ // Instructions that have explicit uses/defs make them explicit in the RTL.
+ // Instructions that need extra stuff emitted in the assembly can, trivially.
+ let isTwoAddress = 1 in
+ def SHL32rCL : Inst<(ops R32:$dst, R32:$src),
+ "shl $dst, CL", 0xD2, MRM4r,
+ [(set R32:$dst, (shl R32:$src, CL))]>;
+
+ // The RTL list is a list, allowing complex instructions to be defined easily.
+ // Temporary 'internal' registers can be used to break instructions appart.
+ let isTwoAddress = 1 in
+ def XOR32mi : Inst<(ops addr:$addr, imm32:$imm),
+ "xor $dst, $src2", 0x81, MRM6m,
+ [(set R32:$tmp1, (load addr:$addr)),
+ (set R32:$tmp2, (xor R32:$tmp1, imm32:$imm)),
+ (store addr:$addr, R32:$tmp2)]>;
+
+ // Alternatively, if each tmporary register is only used once, the instruction
+ // can just be described in nested form. This would be the canonical
+ // representation the target generator would convert the above into. Pick your
+ // favorite indentation scheme.
+ let isTwoAddress = 1 in
+ def AND32mr : Inst<(ops addr:$addr, R32:$src),
+ "xor $dst, $src2", 0x81, MRM6m,
+ [(store addr:$addr,
+ (and
+ (load addr:$addr),
+ R32:$src)
+ )
+ ]>;
+
+ // Describing complex instructions is not too hard! Note how implicit uses/defs
+ // become explicit here.
+ def CBW : Inst<(ops),
+ "cbw", 0x98, RawFrm,
+ [(set AX, (signext AL))]>;
+
+ // Noop, does nothing.
+ def NOOP : Inst<(ops), "nop", 0x90, RawFrm, []>;
+
+
+ // Instructions that don't expect optimization can use unspec.
+ def IN8rr : Inst<(ops), "in AL, EDX", 0xEC, RawFrm,
+ [(set AL, (unspec EDX))]>;
+
More information about the llvm-commits
mailing list