Home | History | Annotate | Download | only in TableGen
      1 // This test describes how we eventually want to describe instructions in
      2 // the target independent code generators.
      3 // RUN: llvm-tblgen %s
      4 // XFAIL: vg_leak
      5 
      6 // Target indep stuff.
      7 class Instruction {   // Would have other stuff eventually
      8   bit isTwoAddress = 0;
      9   string AssemblyString;
     10 }
     11 class RegisterClass;
     12 
     13 class RTLNode;
     14 
     15 def ops;                 // Marker for operand list.
     16 
     17 // Various expressions used in RTL descriptions.
     18 def imm8    : RTLNode;
     19 def imm32   : RTLNode;
     20 def addr    : RTLNode;
     21 
     22 def set     : RTLNode;
     23 def signext : RTLNode;
     24 def zeroext : RTLNode;
     25 def plus    : RTLNode;
     26 def and     : RTLNode;
     27 def xor     : RTLNode;
     28 def shl     : RTLNode;
     29 def load    : RTLNode;
     30 def store   : RTLNode;
     31 def unspec  : RTLNode;
     32 
     33 // Start of X86 specific stuff.
     34 
     35 def R8  : RegisterClass;
     36 def R16 : RegisterClass;
     37 def R32 : RegisterClass;
     38 
     39 def CL;  // As are currently defined
     40 def AL;
     41 def AX;
     42 def EDX;
     43 
     44 class Format<bits<5> val> {
     45   bits<5> Value = val;
     46 }
     47 
     48 def Pseudo     : Format<0>; def RawFrm     : Format<1>;
     49 def AddRegFrm  : Format<2>; def MRMDestReg : Format<3>;
     50 def MRMDestMem : Format<4>; def MRMSrcReg  : Format<5>;
     51 def MRMSrcMem  : Format<6>;
     52 def MRM0r  : Format<16>; def MRM1r  : Format<17>; def MRM2r  : Format<18>;
     53 def MRM3r  : Format<19>; def MRM4r  : Format<20>; def MRM5r  : Format<21>;
     54 def MRM6r  : Format<22>; def MRM7r  : Format<23>;
     55 def MRM0m  : Format<24>; def MRM1m  : Format<25>; def MRM2m  : Format<26>;
     56 def MRM3m  : Format<27>; def MRM4m  : Format<28>; def MRM5m  : Format<29>;
     57 def MRM6m  : Format<30>; def MRM7m  : Format<31>;
     58 
     59 
     60 class Inst<dag opnds, string asmstr, bits<8> opcode,
     61            Format f, list<dag> rtl> : Instruction {
     62   dag Operands = opnds;
     63   string AssemblyString = asmstr;
     64   bits<8> Opcode = opcode;
     65   Format Format = f;
     66   list<dag> RTL = rtl;
     67 }
     68 
     69 
     70 // Start of instruction definitions, the real point of this file.
     71 //
     72 // Note that these patterns show a couple of important things:
     73 //  1. The order and contents of the operands of the MachineInstr are
     74 //     described here.  Eventually we can do away with this when everything
     75 //     is generated from the description.
     76 //  2. The asm string is captured here, which makes it possible to get rid of
     77 //     a ton of hacks in the various printers and a bunch of flags.
     78 //  3. Target specific properties (e.g. Format) can still be captured as
     79 //     needed.
     80 //  4. We capture the behavior of the instruction with a simplified RTL-like
     81 //     expression.
     82 //  5. The use/def properties for each operand are automatically inferred from
     83 //     the pattern.
     84 //  6. Address expressions should become first-class entities.
     85 
     86 // Simple copy instruction.
     87 def MOV8rr : Inst<(ops R8:$dst, R8:$src),
     88                   "mov $dst, $src", 0x88, MRMDestReg,
     89                   [(set R8:$dst, R8:$src)]>;
     90 
     91 // Simple immediate initialization.
     92 def MOV8ri : Inst<(ops R8:$dst, imm8:$src),
     93                   "mov $dst, $src", 0xB0, AddRegFrm,
     94                   [(set R8:$dst, imm8:$src)]>;
     95 
     96 // Two address instructions are described as three-addr instructions, with
     97 // the special target-independent isTwoAddress flag set.  The asm pattern
     98 // should not refer to the $src1, this would be enforced by the
     99 // TargetInstrInfo tablegen backend.
    100 let isTwoAddress = 1 in
    101 def AND8rr : Inst<(ops R8:$dst, R8:$src1, R8:$src2),
    102                   "and $dst, $src2", 0x20, MRMDestReg,
    103                   [(set R8:$dst, (and R8:$src1, R8:$src2))]>;
    104 
    105 // Instructions that have explicit uses/defs make them explicit in the RTL.
    106 // Instructions that need extra stuff emitted in the assembly can, trivially.
    107 let isTwoAddress = 1 in
    108 def SHL32rCL : Inst<(ops R32:$dst, R32:$src),
    109                   "shl $dst, CL", 0xD2, MRM4r,
    110                   [(set R32:$dst, (shl R32:$src, CL))]>;
    111 
    112 // The RTL list is a list, allowing complex instructions to be defined easily.
    113 // Temporary 'internal' registers can be used to break instructions apart.
    114 let isTwoAddress = 1 in
    115 def XOR32mi : Inst<(ops addr:$addr, imm32:$imm),
    116                    "xor $dst, $src2", 0x81, MRM6m,
    117                    [(set R32:$tmp1, (load addr:$addr)),
    118                     (set R32:$tmp2, (xor R32:$tmp1, imm32:$imm)),
    119                     (store addr:$addr, R32:$tmp2)]>;
    120 
    121 // Alternatively, if each tmporary register is only used once, the instruction
    122 // can just be described in nested form.  This would be the canonical 
    123 // representation the target generator would convert the above into.  Pick your
    124 // favorite indentation scheme.
    125 let isTwoAddress = 1 in
    126 def AND32mr : Inst<(ops addr:$addr, R32:$src),
    127                    "xor $dst, $src2", 0x81, MRM6m,
    128                    [(store addr:$addr,
    129                        (and
    130                             (load addr:$addr),
    131                             R32:$src)
    132                        )
    133                    ]>;
    134 
    135 // Describing complex instructions is not too hard!  Note how implicit uses/defs
    136 // become explicit here.
    137 def CBW : Inst<(ops),
    138                "cbw", 0x98, RawFrm,
    139                [(set AX, (signext AL))]>;
    140 
    141 // Noop, does nothing.
    142 def NOOP : Inst<(ops), "nop", 0x90, RawFrm, []>;
    143 
    144 
    145 // Instructions that don't expect optimization can use unspec.
    146 def IN8rr : Inst<(ops), "in AL, EDX", 0xEC, RawFrm,
    147                  [(set AL, (unspec EDX))]>;
    148 
    149