blob: e6c563b06aa521d43beaf98b83bf735c3fe15795 [file] [log] [blame]
Chris Lattner3afbb932004-07-25 12:13:35 +00001// This test describes how we eventually want to describe instructions in
2// the target independent code generators.
Peter Collingbourne7f7f2e92011-10-06 13:39:59 +00003// RUN: llvm-tblgen %s
Jeffrey Yasskin2f87b542010-03-20 23:08:45 +00004// XFAIL: vg_leak
Chris Lattner3afbb932004-07-25 12:13:35 +00005
6// Target indep stuff.
7class Instruction { // Would have other stuff eventually
8 bit isTwoAddress = 0;
9 string AssemblyString;
10}
11class RegisterClass;
12
13class RTLNode;
14
15def ops; // Marker for operand list.
16
17// Various expressions used in RTL descriptions.
18def imm8 : RTLNode;
19def imm32 : RTLNode;
20def addr : RTLNode;
21
22def set : RTLNode;
23def signext : RTLNode;
24def zeroext : RTLNode;
25def plus : RTLNode;
26def and : RTLNode;
27def xor : RTLNode;
28def shl : RTLNode;
29def load : RTLNode;
30def store : RTLNode;
31def unspec : RTLNode;
32
33// Start of X86 specific stuff.
34
35def R8 : RegisterClass;
36def R16 : RegisterClass;
37def R32 : RegisterClass;
38
39def CL; // As are currently defined
40def AL;
41def AX;
42def EDX;
43
44class Format<bits<5> val> {
45 bits<5> Value = val;
46}
47
48def Pseudo : Format<0>; def RawFrm : Format<1>;
49def AddRegFrm : Format<2>; def MRMDestReg : Format<3>;
50def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
51def MRMSrcMem : Format<6>;
52def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
53def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
54def MRM6r : Format<22>; def MRM7r : Format<23>;
55def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
56def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
57def MRM6m : Format<30>; def MRM7m : Format<31>;
58
59
60class 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
Jakob Stoklund Olesenc4227f12010-07-11 17:01:17 +000086// Simple copy instruction.
Chris Lattner3afbb932004-07-25 12:13:35 +000087def MOV8rr : Inst<(ops R8:$dst, R8:$src),
88 "mov $dst, $src", 0x88, MRMDestReg,
89 [(set R8:$dst, R8:$src)]>;
90
91// Simple immediate initialization.
92def 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.
100let isTwoAddress = 1 in
101def 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.
107let isTwoAddress = 1 in
108def 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.
Chris Lattner0ab5e2c2011-04-15 05:18:47 +0000113// Temporary 'internal' registers can be used to break instructions apart.
Chris Lattner3afbb932004-07-25 12:13:35 +0000114let isTwoAddress = 1 in
115def 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.
125let isTwoAddress = 1 in
126def 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.
137def CBW : Inst<(ops),
138 "cbw", 0x98, RawFrm,
139 [(set AX, (signext AL))]>;
140
141// Noop, does nothing.
142def NOOP : Inst<(ops), "nop", 0x90, RawFrm, []>;
143
144
145// Instructions that don't expect optimization can use unspec.
146def IN8rr : Inst<(ops), "in AL, EDX", 0xEC, RawFrm,
147 [(set AL, (unspec EDX))]>;
148