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