reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
// This test describes how we eventually want to describe instructions in
// the target independent code generators.
// RUN: llvm-tblgen %s
// XFAIL: vg_leak

// 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.
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 apart.
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))]>;