Addr1 instructions opcodes are encoded in bits 21-24; encode S bit.
[oota-llvm.git] / lib / Target / ARM / ARMInstrFormats.td
1 //===- ARMInstrFormats.td - ARM Instruction Formats --*- tablegen -*---------=//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9
10 //===----------------------------------------------------------------------===//
11 //
12 // ARM Instruction Format Definitions.
13 //
14
15 // Format specifies the encoding used by the instruction.  This is part of the
16 // ad-hoc solution used to emit machine instruction encodings by our machine
17 // code emitter.
18 class Format<bits<5> val> {
19   bits<5> Value = val;
20 }
21
22 def Pseudo      : Format<1>;
23 def MulFrm      : Format<2>;
24 def MulSMLAW    : Format<3>;
25 def MulSMULW    : Format<4>;
26 def MulSMLA     : Format<5>;
27 def MulSMUL     : Format<6>;
28 def Branch      : Format<7>;
29 def BranchMisc  : Format<8>;
30
31 def DPRdIm      : Format<9>;
32 def DPRdReg     : Format<10>;
33 def DPRdSoReg   : Format<11>;
34 def DPRdMisc    : Format<12>;
35 def DPRnIm      : Format<13>;
36 def DPRnReg     : Format<14>;
37 def DPRnSoReg   : Format<15>;
38 def DPRIm       : Format<16>;
39 def DPRReg      : Format<17>;
40 def DPRSoReg    : Format<18>;
41 def DPRImS      : Format<19>;
42 def DPRRegS     : Format<20>;
43 def DPRSoRegS   : Format<21>;
44
45 def LdFrm       : Format<22>;
46 def StFrm       : Format<23>;
47
48 def ArithMisc   : Format<24>;
49 def ThumbFrm    : Format<25>;
50 def VFPFrm      : Format<26>;
51
52
53 //===----------------------------------------------------------------------===//
54
55 // ARM Instruction templates.
56 //
57
58 class InstARM<bits<4> opcod, AddrMode am, SizeFlagVal sz, IndexMode im,
59               Format f, string cstr>
60   : Instruction {
61   field bits<32> Inst;
62
63   let Namespace = "ARM";
64
65   bits<4> Opcode = opcod;
66   AddrMode AM = am;
67   bits<4> AddrModeBits = AM.Value;
68   
69   SizeFlagVal SZ = sz;
70   bits<3> SizeFlag = SZ.Value;
71
72   IndexMode IM = im;
73   bits<2> IndexModeBits = IM.Value;
74   
75   Format F = f;
76   bits<5> Form = F.Value;
77   
78   let Constraints = cstr;
79 }
80
81 class PseudoInst<dag oops, dag iops, string asm, list<dag> pattern>
82   : InstARM<0, AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, ""> {
83   let OutOperandList = oops;
84   let InOperandList = iops;
85   let AsmString   = asm;
86   let Pattern = pattern;
87 }
88
89 // Almost all ARM instructions are predicable.
90 class I<bits<4> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
91         IndexMode im, Format f, string opc, string asm, string cstr,
92         list<dag> pattern>
93   : InstARM<opcod, am, sz, im, f, cstr> {
94   let OutOperandList = oops;
95   let InOperandList = !con(iops, (ops pred:$p));
96   let AsmString   = !strconcat(opc, !strconcat("${p}", asm));
97   let Pattern = pattern;
98   list<Predicate> Predicates = [IsARM];
99 }
100
101 // Same as I except it can optionally modify CPSR. Note it's modeled as
102 // an input operand since by default it's a zero register. It will
103 // become an implicit def once it's "flipped".
104 class sI<bits<4> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
105          IndexMode im, Format f, string opc, string asm, string cstr,
106          list<dag> pattern>
107   : InstARM<opcod, am, sz, im, f, cstr> {
108   let OutOperandList = oops;
109   let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
110   let AsmString   = !strconcat(opc, !strconcat("${p}${s}", asm));
111   let Pattern = pattern;
112   list<Predicate> Predicates = [IsARM];
113 }
114
115 class AI<bits<4> opcod, dag oops, dag iops, Format f, string opc,
116          string asm, list<dag> pattern>
117   : I<opcod, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
118       asm,"",pattern>;
119 class AsI<bits<4> opcod, dag oops, dag iops, Format f, string opc,
120           string asm, list<dag> pattern>
121   : sI<opcod, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
122        asm,"",pattern>;
123 class AI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
124           string asm, list<dag> pattern>
125   : I<opcod, oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
126       asm, "", pattern> {
127   let Inst{21-24} = opcod;
128   let Inst{26-27} = 0;
129 }
130 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
131            string asm, list<dag> pattern>
132   : sI<opcod, oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
133        asm, "", pattern> {
134   let Inst{20}    = 1;
135   let Inst{21-24} = opcod;
136   let Inst{26-27} = 0;
137 }
138 class AI2<bits<4> opcod, dag oops, dag iops, Format f, string opc,
139           string asm, list<dag> pattern>
140   : I<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
141       asm, "", pattern>;
142 class AI3<bits<4> opcod, dag oops, dag iops, Format f, string opc,
143           string asm, list<dag> pattern>
144   : I<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
145       asm, "", pattern>;
146 class AI4<bits<4> opcod, dag oops, dag iops, Format f, string opc,
147           string asm, list<dag> pattern>
148   : I<opcod, oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, opc,
149       asm, "", pattern>;
150 class AI1x2<bits<4> opcod, dag oops, dag iops, Format f, string opc,
151             string asm, list<dag> pattern>
152   : I<opcod, oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, opc,
153       asm, "", pattern>;
154
155 // Pre-indexed ops
156 class AI2pr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
157             string asm, string cstr, list<dag> pattern>
158   : I<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
159       asm, cstr, pattern>;
160 class AI3pr<bits<4> opcod, dag oops, dag iops, Format f, string opc,
161             string asm, string cstr, list<dag> pattern>
162   : I<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
163       asm, cstr, pattern>;
164
165 // Post-indexed ops
166 class AI2po<bits<4> opcod, dag oops, dag iops, Format f, string opc,
167             string asm, string cstr, list<dag> pattern>
168   : I<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
169       asm, cstr,pattern>;
170 class AI3po<bits<4> opcod, dag oops, dag iops, Format f, string opc,
171             string asm, string cstr, list<dag> pattern>
172   : I<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
173       asm, cstr,pattern>;
174
175
176 // Special cases.
177 class XI<bits<4> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
178          IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
179   : InstARM<opcod, am, sz, im, f, cstr> {
180   let OutOperandList = oops;
181   let InOperandList = iops;
182   let AsmString   = asm;
183   let Pattern = pattern;
184   list<Predicate> Predicates = [IsARM];
185 }
186
187 class AXI<bits<4> opcod, dag oops, dag iops, Format f, string asm,
188           list<dag> pattern>
189   : XI<opcod, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
190        "", pattern>;
191 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, string asm,
192            list<dag> pattern>
193   : XI<opcod, oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, asm,
194        "", pattern>;
195 class AXI2<bits<4> opcod, dag oops, dag iops, Format f, string asm,
196            list<dag> pattern>
197   : XI<opcod, oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, asm,
198        "", pattern>;
199 class AXI3<bits<4> opcod, dag oops, dag iops, Format f, string asm,
200            list<dag> pattern>
201   : XI<opcod, oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
202        "", pattern>;
203 class AXI4<bits<4> opcod, dag oops, dag iops, Format f, string asm,
204            list<dag> pattern>
205   : XI<opcod, oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
206        "", pattern>;
207
208 class AXIx2<bits<4> opcod, dag oops, dag iops, Format f, string asm,
209             list<dag> pattern>
210   : XI<opcod, oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, f, asm,
211        "", pattern>;
212
213 // BR_JT instructions
214 class JTI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
215   : XI<opcod, oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BranchMisc,
216        asm, "", pattern>;
217 class JTI1<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
218   : XI<opcod, oops, iops, AddrMode1, SizeSpecial, IndexModeNone, BranchMisc,
219        asm, "", pattern>;
220 class JTI2<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
221   : XI<opcod, oops, iops, AddrMode2, SizeSpecial, IndexModeNone, BranchMisc,
222        asm, "", pattern>;
223
224
225 //===----------------------------------------------------------------------===//
226
227 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
228 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
229   list<Predicate> Predicates = [IsARM];
230 }
231 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
232   list<Predicate> Predicates = [IsARM, HasV5TE];
233 }
234 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
235   list<Predicate> Predicates = [IsARM, HasV6];
236 }
237
238 //===----------------------------------------------------------------------===//
239 //
240 // Thumb Instruction Format Definitions.
241 //
242
243
244 // TI - Thumb instruction.
245
246 class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
247              string asm, string cstr, list<dag> pattern>
248   // FIXME: Set all opcodes to 0 for now.
249   : InstARM<0, am, sz, IndexModeNone, ThumbFrm, cstr> {
250   let OutOperandList = outs;
251   let InOperandList = ins;
252   let AsmString   = asm;
253   let Pattern = pattern;
254   list<Predicate> Predicates = [IsThumb];
255 }
256
257 class TI<dag outs, dag ins, string asm, list<dag> pattern>
258   : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
259 class TI1<dag outs, dag ins, string asm, list<dag> pattern>
260   : ThumbI<outs, ins, AddrModeT1, Size2Bytes, asm, "", pattern>;
261 class TI2<dag outs, dag ins, string asm, list<dag> pattern>
262   : ThumbI<outs, ins, AddrModeT2, Size2Bytes, asm, "", pattern>;
263 class TI4<dag outs, dag ins, string asm, list<dag> pattern>
264   : ThumbI<outs, ins, AddrModeT4, Size2Bytes, asm, "", pattern>;
265 class TIs<dag outs, dag ins, string asm, list<dag> pattern>
266   : ThumbI<outs, ins, AddrModeTs, Size2Bytes, asm, "", pattern>;
267
268 // Two-address instructions
269 class TIt<dag outs, dag ins, string asm, list<dag> pattern>
270   : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
271
272 // BL, BLX(1) are translated by assembler into two instructions
273 class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
274   : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
275
276 // BR_JT instructions
277 class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
278   : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
279
280
281 //===----------------------------------------------------------------------===//
282
283
284 // ThumbPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
285 class ThumbPat<dag pattern, dag result> : Pat<pattern, result> {
286   list<Predicate> Predicates = [IsThumb];
287 }
288
289 class ThumbV5Pat<dag pattern, dag result> : Pat<pattern, result> {
290   list<Predicate> Predicates = [IsThumb, HasV5T];
291 }