Add IsThumb1Only to most 16-bit thumb instructions since we want to isel 32-bit instr...
[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<0>;
23 def MulFrm        : Format<1>;
24 def BrFrm         : Format<2>;
25 def BrMiscFrm     : Format<3>;
26
27 def DPFrm         : Format<4>;
28 def DPSoRegFrm    : Format<5>;
29
30 def LdFrm         : Format<6>;
31 def StFrm         : Format<7>;
32 def LdMiscFrm     : Format<8>;
33 def StMiscFrm     : Format<9>;
34 def LdStMulFrm    : Format<10>;
35
36 def ArithMiscFrm  : Format<11>;
37 def ExtFrm        : Format<12>;
38
39 def VFPUnaryFrm   : Format<13>;
40 def VFPBinaryFrm  : Format<14>;
41 def VFPConv1Frm   : Format<15>;
42 def VFPConv2Frm   : Format<16>;
43 def VFPConv3Frm   : Format<17>;
44 def VFPConv4Frm   : Format<18>;
45 def VFPConv5Frm   : Format<19>;
46 def VFPLdStFrm    : Format<20>;
47 def VFPLdStMulFrm : Format<21>;
48 def VFPMiscFrm    : Format<22>;
49
50 def ThumbFrm      : Format<23>;
51
52 def NEONFrm       : Format<24>;
53 def NEONGetLnFrm  : Format<25>;
54 def NEONSetLnFrm  : Format<26>;
55 def NEONDupFrm    : Format<27>;
56
57 // Misc flag for data processing instructions that indicates whether
58 // the instruction has a Rn register operand.
59 class UnaryDP  { bit isUnaryDataProc = 1; }
60
61 //===----------------------------------------------------------------------===//
62
63 // ARM Instruction templates.
64 //
65
66 class InstARM<AddrMode am, SizeFlagVal sz, IndexMode im,
67               Format f, string cstr>
68   : Instruction {
69   field bits<32> Inst;
70
71   let Namespace = "ARM";
72
73   // TSFlagsFields
74   AddrMode AM = am;
75   bits<4> AddrModeBits = AM.Value;
76   
77   SizeFlagVal SZ = sz;
78   bits<3> SizeFlag = SZ.Value;
79
80   IndexMode IM = im;
81   bits<2> IndexModeBits = IM.Value;
82   
83   Format F = f;
84   bits<5> Form = F.Value;
85
86   //
87   // Attributes specific to ARM instructions...
88   //
89   bit isUnaryDataProc = 0;
90   
91   let Constraints = cstr;
92 }
93
94 class PseudoInst<dag oops, dag iops, string asm, list<dag> pattern>
95   : InstARM<AddrModeNone, SizeSpecial, IndexModeNone, Pseudo, ""> {
96   let OutOperandList = oops;
97   let InOperandList = iops;
98   let AsmString   = asm;
99   let Pattern = pattern;
100 }
101
102 // Almost all ARM instructions are predicable.
103 class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
104         IndexMode im, Format f, string opc, string asm, string cstr,
105         list<dag> pattern>
106   : InstARM<am, sz, im, f, cstr> {
107   let OutOperandList = oops;
108   let InOperandList = !con(iops, (ops pred:$p));
109   let AsmString   = !strconcat(opc, !strconcat("${p}", asm));
110   let Pattern = pattern;
111   list<Predicate> Predicates = [IsARM];
112 }
113
114 // Same as I except it can optionally modify CPSR. Note it's modeled as
115 // an input operand since by default it's a zero register. It will
116 // become an implicit def once it's "flipped".
117 class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
118          IndexMode im, Format f, string opc, string asm, string cstr,
119          list<dag> pattern>
120   : InstARM<am, sz, im, f, cstr> {
121   let OutOperandList = oops;
122   let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
123   let AsmString   = !strconcat(opc, !strconcat("${p}${s}", asm));
124   let Pattern = pattern;
125   list<Predicate> Predicates = [IsARM];
126 }
127
128 // Special cases
129 class XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
130          IndexMode im, Format f, string asm, string cstr, list<dag> pattern>
131   : InstARM<am, sz, im, f, cstr> {
132   let OutOperandList = oops;
133   let InOperandList = iops;
134   let AsmString   = asm;
135   let Pattern = pattern;
136   list<Predicate> Predicates = [IsARM];
137 }
138
139 class AI<dag oops, dag iops, Format f, string opc,
140          string asm, list<dag> pattern>
141   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
142       asm, "", pattern>;
143 class AsI<dag oops, dag iops, Format f, string opc,
144           string asm, list<dag> pattern>
145   : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, opc,
146        asm, "", pattern>;
147 class AXI<dag oops, dag iops, Format f, string asm,
148           list<dag> pattern>
149   : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, f, asm,
150        "", pattern>;
151
152 // Ctrl flow instructions
153 class ABI<bits<4> opcod, dag oops, dag iops, string opc,
154          string asm, list<dag> pattern>
155   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, opc,
156       asm, "", pattern> {
157   let Inst{27-24} = opcod;
158 }
159 class ABXI<bits<4> opcod, dag oops, dag iops, string asm, list<dag> pattern>
160   : XI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, asm,
161        "", pattern> {
162   let Inst{27-24} = opcod;
163 }
164 class ABXIx2<dag oops, dag iops, string asm, list<dag> pattern>
165   : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, asm,
166        "", pattern>;
167
168 // BR_JT instructions
169 class JTI<dag oops, dag iops, string asm, list<dag> pattern>
170   : XI<oops, iops, AddrModeNone, SizeSpecial, IndexModeNone, BrMiscFrm,
171        asm, "", pattern>;
172
173 // addrmode1 instructions
174 class AI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
175           string asm, list<dag> pattern>
176   : I<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
177       asm, "", pattern> {
178   let Inst{24-21} = opcod;
179   let Inst{27-26} = {0,0};
180 }
181 class AsI1<bits<4> opcod, dag oops, dag iops, Format f, string opc,
182            string asm, list<dag> pattern>
183   : sI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, opc,
184        asm, "", pattern> {
185   let Inst{24-21} = opcod;
186   let Inst{27-26} = {0,0};
187 }
188 class AXI1<bits<4> opcod, dag oops, dag iops, Format f, string asm,
189            list<dag> pattern>
190   : XI<oops, iops, AddrMode1, Size4Bytes, IndexModeNone, f, asm,
191        "", pattern> {
192   let Inst{24-21} = opcod;
193   let Inst{27-26} = {0,0};
194 }
195 class AI1x2<dag oops, dag iops, Format f, string opc,
196             string asm, list<dag> pattern>
197   : I<oops, iops, AddrMode1, Size8Bytes, IndexModeNone, f, opc,
198       asm, "", pattern>;
199
200
201 // addrmode2 loads and stores
202 class AI2<dag oops, dag iops, Format f, string opc,
203           string asm, list<dag> pattern>
204   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
205       asm, "", pattern> {
206   let Inst{27-26} = {0,1};
207 }
208
209 // loads
210 class AI2ldw<dag oops, dag iops, Format f, string opc,
211           string asm, list<dag> pattern>
212   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
213       asm, "", pattern> {
214   let Inst{20}    = 1; // L bit
215   let Inst{21}    = 0; // W bit
216   let Inst{22}    = 0; // B bit
217   let Inst{24}    = 1; // P bit
218   let Inst{27-26} = {0,1};
219 }
220 class AXI2ldw<dag oops, dag iops, Format f, string asm,
221            list<dag> pattern>
222   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
223        asm, "", pattern> {
224   let Inst{20}    = 1; // L bit
225   let Inst{21}    = 0; // W bit
226   let Inst{22}    = 0; // B bit
227   let Inst{24}    = 1; // P bit
228   let Inst{27-26} = {0,1};
229 }
230 class AI2ldb<dag oops, dag iops, Format f, string opc,
231           string asm, list<dag> pattern>
232   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
233       asm, "", pattern> {
234   let Inst{20}    = 1; // L bit
235   let Inst{21}    = 0; // W bit
236   let Inst{22}    = 1; // B bit
237   let Inst{24}    = 1; // P bit
238   let Inst{27-26} = {0,1};
239 }
240 class AXI2ldb<dag oops, dag iops, Format f, string asm,
241            list<dag> pattern>
242   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
243        asm, "", pattern> {
244   let Inst{20}    = 1; // L bit
245   let Inst{21}    = 0; // W bit
246   let Inst{22}    = 1; // B bit
247   let Inst{24}    = 1; // P bit
248   let Inst{27-26} = {0,1};
249 }
250
251 // stores
252 class AI2stw<dag oops, dag iops, Format f, string opc,
253           string asm, list<dag> pattern>
254   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
255       asm, "", pattern> {
256   let Inst{20}    = 0; // L bit
257   let Inst{21}    = 0; // W bit
258   let Inst{22}    = 0; // B bit
259   let Inst{24}    = 1; // P bit
260   let Inst{27-26} = {0,1};
261 }
262 class AXI2stw<dag oops, dag iops, Format f, string asm,
263            list<dag> pattern>
264   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
265        asm, "", pattern> {
266   let Inst{20}    = 0; // L bit
267   let Inst{21}    = 0; // W bit
268   let Inst{22}    = 0; // B bit
269   let Inst{24}    = 1; // P bit
270   let Inst{27-26} = {0,1};
271 }
272 class AI2stb<dag oops, dag iops, Format f, string opc,
273           string asm, list<dag> pattern>
274   : I<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f, opc,
275       asm, "", pattern> {
276   let Inst{20}    = 0; // L bit
277   let Inst{21}    = 0; // W bit
278   let Inst{22}    = 1; // B bit
279   let Inst{24}    = 1; // P bit
280   let Inst{27-26} = {0,1};
281 }
282 class AXI2stb<dag oops, dag iops, Format f, string asm,
283            list<dag> pattern>
284   : XI<oops, iops, AddrMode2, Size4Bytes, IndexModeNone, f,
285        asm, "", pattern> {
286   let Inst{20}    = 0; // L bit
287   let Inst{21}    = 0; // W bit
288   let Inst{22}    = 1; // B bit
289   let Inst{24}    = 1; // P bit
290   let Inst{27-26} = {0,1};
291 }
292
293 // Pre-indexed loads
294 class AI2ldwpr<dag oops, dag iops, Format f, string opc,
295             string asm, string cstr, list<dag> pattern>
296   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
297       asm, cstr, pattern> {
298   let Inst{20}    = 1; // L bit
299   let Inst{21}    = 1; // W bit
300   let Inst{22}    = 0; // B bit
301   let Inst{24}    = 1; // P bit
302   let Inst{27-26} = {0,1};
303 }
304 class AI2ldbpr<dag oops, dag iops, Format f, string opc,
305             string asm, string cstr, list<dag> pattern>
306   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
307       asm, cstr, pattern> {
308   let Inst{20}    = 1; // L bit
309   let Inst{21}    = 1; // W bit
310   let Inst{22}    = 1; // B bit
311   let Inst{24}    = 1; // P bit
312   let Inst{27-26} = {0,1};
313 }
314
315 // Pre-indexed stores
316 class AI2stwpr<dag oops, dag iops, Format f, string opc,
317             string asm, string cstr, list<dag> pattern>
318   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
319       asm, cstr, pattern> {
320   let Inst{20}    = 0; // L bit
321   let Inst{21}    = 1; // W bit
322   let Inst{22}    = 0; // B bit
323   let Inst{24}    = 1; // P bit
324   let Inst{27-26} = {0,1};
325 }
326 class AI2stbpr<dag oops, dag iops, Format f, string opc,
327             string asm, string cstr, list<dag> pattern>
328   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePre, f, opc,
329       asm, cstr, pattern> {
330   let Inst{20}    = 0; // L bit
331   let Inst{21}    = 1; // W bit
332   let Inst{22}    = 1; // B bit
333   let Inst{24}    = 1; // P bit
334   let Inst{27-26} = {0,1};
335 }
336
337 // Post-indexed loads
338 class AI2ldwpo<dag oops, dag iops, Format f, string opc,
339             string asm, string cstr, list<dag> pattern>
340   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
341       asm, cstr,pattern> {
342   let Inst{20}    = 1; // L bit
343   let Inst{21}    = 0; // W bit
344   let Inst{22}    = 0; // B bit
345   let Inst{24}    = 0; // P bit
346   let Inst{27-26} = {0,1};
347 }
348 class AI2ldbpo<dag oops, dag iops, Format f, string opc,
349             string asm, string cstr, list<dag> pattern>
350   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
351       asm, cstr,pattern> {
352   let Inst{20}    = 1; // L bit
353   let Inst{21}    = 0; // W bit
354   let Inst{22}    = 1; // B bit
355   let Inst{24}    = 0; // P bit
356   let Inst{27-26} = {0,1};
357 }
358
359 // Post-indexed stores
360 class AI2stwpo<dag oops, dag iops, Format f, string opc,
361             string asm, string cstr, list<dag> pattern>
362   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
363       asm, cstr,pattern> {
364   let Inst{20}    = 0; // L bit
365   let Inst{21}    = 0; // W bit
366   let Inst{22}    = 0; // B bit
367   let Inst{24}    = 0; // P bit
368   let Inst{27-26} = {0,1};
369 }
370 class AI2stbpo<dag oops, dag iops, Format f, string opc,
371             string asm, string cstr, list<dag> pattern>
372   : I<oops, iops, AddrMode2, Size4Bytes, IndexModePost, f, opc,
373       asm, cstr,pattern> {
374   let Inst{20}    = 0; // L bit
375   let Inst{21}    = 0; // W bit
376   let Inst{22}    = 1; // B bit
377   let Inst{24}    = 0; // P bit
378   let Inst{27-26} = {0,1};
379 }
380
381 // addrmode3 instructions
382 class AI3<dag oops, dag iops, Format f, string opc,
383           string asm, list<dag> pattern>
384   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
385       asm, "", pattern>;
386 class AXI3<dag oops, dag iops, Format f, string asm,
387            list<dag> pattern>
388   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, asm,
389        "", pattern>;
390
391 // loads
392 class AI3ldh<dag oops, dag iops, Format f, string opc,
393           string asm, list<dag> pattern>
394   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
395       asm, "", pattern> {
396   let Inst{4}     = 1;
397   let Inst{5}     = 1; // H bit
398   let Inst{6}     = 0; // S bit
399   let Inst{7}     = 1;
400   let Inst{20}    = 1; // L bit
401   let Inst{21}    = 0; // W bit
402   let Inst{24}    = 1; // P bit
403 }
404 class AXI3ldh<dag oops, dag iops, Format f, string asm,
405            list<dag> pattern>
406   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
407        asm, "", pattern> {
408   let Inst{4}     = 1;
409   let Inst{5}     = 1; // H bit
410   let Inst{6}     = 0; // S bit
411   let Inst{7}     = 1;
412   let Inst{20}    = 1; // L bit
413   let Inst{21}    = 0; // W bit
414   let Inst{24}    = 1; // P bit
415 }
416 class AI3ldsh<dag oops, dag iops, Format f, string opc,
417           string asm, list<dag> pattern>
418   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
419       asm, "", pattern> {
420   let Inst{4}     = 1;
421   let Inst{5}     = 1; // H bit
422   let Inst{6}     = 1; // S bit
423   let Inst{7}     = 1;
424   let Inst{20}    = 1; // L bit
425   let Inst{21}    = 0; // W bit
426   let Inst{24}    = 1; // P bit
427 }
428 class AXI3ldsh<dag oops, dag iops, Format f, string asm,
429            list<dag> pattern>
430   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
431        asm, "", pattern> {
432   let Inst{4}     = 1;
433   let Inst{5}     = 1; // H bit
434   let Inst{6}     = 1; // S bit
435   let Inst{7}     = 1;
436   let Inst{20}    = 1; // L bit
437   let Inst{21}    = 0; // W bit
438   let Inst{24}    = 1; // P bit
439 }
440 class AI3ldsb<dag oops, dag iops, Format f, string opc,
441           string asm, list<dag> pattern>
442   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
443       asm, "", pattern> {
444   let Inst{4}     = 1;
445   let Inst{5}     = 0; // H bit
446   let Inst{6}     = 1; // S bit
447   let Inst{7}     = 1;
448   let Inst{20}    = 1; // L bit
449   let Inst{21}    = 0; // W bit
450   let Inst{24}    = 1; // P bit
451 }
452 class AXI3ldsb<dag oops, dag iops, Format f, string asm,
453            list<dag> pattern>
454   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
455        asm, "", pattern> {
456   let Inst{4}     = 1;
457   let Inst{5}     = 0; // H bit
458   let Inst{6}     = 1; // S bit
459   let Inst{7}     = 1;
460   let Inst{20}    = 1; // L bit
461   let Inst{21}    = 0; // W bit
462   let Inst{24}    = 1; // P bit
463 }
464 class AI3ldd<dag oops, dag iops, Format f, string opc,
465           string asm, list<dag> pattern>
466   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
467       asm, "", pattern> {
468   let Inst{4}     = 1;
469   let Inst{5}     = 0; // H bit
470   let Inst{6}     = 1; // S bit
471   let Inst{7}     = 1;
472   let Inst{20}    = 0; // L bit
473   let Inst{21}    = 0; // W bit
474   let Inst{24}    = 1; // P bit
475 }
476
477 // stores
478 class AI3sth<dag oops, dag iops, Format f, string opc,
479           string asm, list<dag> pattern>
480   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
481       asm, "", pattern> {
482   let Inst{4}     = 1;
483   let Inst{5}     = 1; // H bit
484   let Inst{6}     = 0; // S bit
485   let Inst{7}     = 1;
486   let Inst{20}    = 0; // L bit
487   let Inst{21}    = 0; // W bit
488   let Inst{24}    = 1; // P bit
489 }
490 class AXI3sth<dag oops, dag iops, Format f, string asm,
491            list<dag> pattern>
492   : XI<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f,
493        asm, "", pattern> {
494   let Inst{4}     = 1;
495   let Inst{5}     = 1; // H bit
496   let Inst{6}     = 0; // S bit
497   let Inst{7}     = 1;
498   let Inst{20}    = 0; // L bit
499   let Inst{21}    = 0; // W bit
500   let Inst{24}    = 1; // P bit
501 }
502 class AI3std<dag oops, dag iops, Format f, string opc,
503           string asm, list<dag> pattern>
504   : I<oops, iops, AddrMode3, Size4Bytes, IndexModeNone, f, opc,
505       asm, "", pattern> {
506   let Inst{4}     = 1;
507   let Inst{5}     = 1; // H bit
508   let Inst{6}     = 1; // S bit
509   let Inst{7}     = 1;
510   let Inst{20}    = 0; // L bit
511   let Inst{21}    = 0; // W bit
512   let Inst{24}    = 1; // P bit
513 }
514
515 // Pre-indexed loads
516 class AI3ldhpr<dag oops, dag iops, Format f, string opc,
517             string asm, string cstr, list<dag> pattern>
518   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
519       asm, cstr, pattern> {
520   let Inst{4}     = 1;
521   let Inst{5}     = 1; // H bit
522   let Inst{6}     = 0; // S bit
523   let Inst{7}     = 1;
524   let Inst{20}    = 1; // L bit
525   let Inst{21}    = 1; // W bit
526   let Inst{24}    = 1; // P bit
527 }
528 class AI3ldshpr<dag oops, dag iops, Format f, string opc,
529             string asm, string cstr, list<dag> pattern>
530   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
531       asm, cstr, pattern> {
532   let Inst{4}     = 1;
533   let Inst{5}     = 1; // H bit
534   let Inst{6}     = 1; // S bit
535   let Inst{7}     = 1;
536   let Inst{20}    = 1; // L bit
537   let Inst{21}    = 1; // W bit
538   let Inst{24}    = 1; // P bit
539 }
540 class AI3ldsbpr<dag oops, dag iops, Format f, string opc,
541             string asm, string cstr, list<dag> pattern>
542   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
543       asm, cstr, pattern> {
544   let Inst{4}     = 1;
545   let Inst{5}     = 0; // H bit
546   let Inst{6}     = 1; // S bit
547   let Inst{7}     = 1;
548   let Inst{20}    = 1; // L bit
549   let Inst{21}    = 1; // W bit
550   let Inst{24}    = 1; // P bit
551 }
552
553 // Pre-indexed stores
554 class AI3sthpr<dag oops, dag iops, Format f, string opc,
555             string asm, string cstr, list<dag> pattern>
556   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePre, f, opc,
557       asm, cstr, pattern> {
558   let Inst{4}     = 1;
559   let Inst{5}     = 1; // H bit
560   let Inst{6}     = 0; // S bit
561   let Inst{7}     = 1;
562   let Inst{20}    = 0; // L bit
563   let Inst{21}    = 1; // W bit
564   let Inst{24}    = 1; // P bit
565 }
566
567 // Post-indexed loads
568 class AI3ldhpo<dag oops, dag iops, Format f, string opc,
569             string asm, string cstr, list<dag> pattern>
570   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
571       asm, cstr,pattern> {
572   let Inst{4}     = 1;
573   let Inst{5}     = 1; // H bit
574   let Inst{6}     = 0; // S bit
575   let Inst{7}     = 1;
576   let Inst{20}    = 1; // L bit
577   let Inst{21}    = 1; // W bit
578   let Inst{24}    = 0; // P bit
579 }
580 class AI3ldshpo<dag oops, dag iops, Format f, string opc,
581             string asm, string cstr, list<dag> pattern>
582   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
583       asm, cstr,pattern> {
584   let Inst{4}     = 1;
585   let Inst{5}     = 1; // H bit
586   let Inst{6}     = 1; // S bit
587   let Inst{7}     = 1;
588   let Inst{20}    = 1; // L bit
589   let Inst{21}    = 1; // W bit
590   let Inst{24}    = 0; // P bit
591 }
592 class AI3ldsbpo<dag oops, dag iops, Format f, string opc,
593             string asm, string cstr, list<dag> pattern>
594   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
595       asm, cstr,pattern> {
596   let Inst{4}     = 1;
597   let Inst{5}     = 0; // H bit
598   let Inst{6}     = 1; // S bit
599   let Inst{7}     = 1;
600   let Inst{20}    = 1; // L bit
601   let Inst{21}    = 1; // W bit
602   let Inst{24}    = 0; // P bit
603 }
604
605 // Post-indexed stores
606 class AI3sthpo<dag oops, dag iops, Format f, string opc,
607             string asm, string cstr, list<dag> pattern>
608   : I<oops, iops, AddrMode3, Size4Bytes, IndexModePost, f, opc,
609       asm, cstr,pattern> {
610   let Inst{4}     = 1;
611   let Inst{5}     = 1; // H bit
612   let Inst{6}     = 0; // S bit
613   let Inst{7}     = 1;
614   let Inst{20}    = 0; // L bit
615   let Inst{21}    = 1; // W bit
616   let Inst{24}    = 0; // P bit
617 }
618
619
620 // addrmode4 instructions
621 class AXI4ld<dag oops, dag iops, Format f, string asm, list<dag> pattern>
622   : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
623        "", pattern> {
624   let Inst{20}    = 1; // L bit
625   let Inst{22}    = 0; // S bit
626   let Inst{27-25} = 0b100;
627 }
628 class AXI4st<dag oops, dag iops, Format f, string asm, list<dag> pattern>
629   : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, asm,
630        "", pattern> {
631   let Inst{20}    = 0; // L bit
632   let Inst{22}    = 0; // S bit
633   let Inst{27-25} = 0b100;
634 }
635
636 // Unsigned multiply, multiply-accumulate instructions.
637 class AMul1I<bits<7> opcod, dag oops, dag iops, string opc,
638          string asm, list<dag> pattern>
639   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
640       asm, "", pattern> {
641   let Inst{7-4}   = 0b1001;
642   let Inst{20}    = 0; // S bit
643   let Inst{27-21} = opcod;
644 }
645 class AsMul1I<bits<7> opcod, dag oops, dag iops, string opc,
646           string asm, list<dag> pattern>
647   : sI<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
648        asm, "", pattern> {
649   let Inst{7-4}   = 0b1001;
650   let Inst{27-21} = opcod;
651 }
652
653 // Most significant word multiply
654 class AMul2I<bits<7> opcod, dag oops, dag iops, string opc,
655          string asm, list<dag> pattern>
656   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
657       asm, "", pattern> {
658   let Inst{7-4}   = 0b1001;
659   let Inst{20}    = 1;
660   let Inst{27-21} = opcod;
661 }
662
663 // SMUL<x><y> / SMULW<y> / SMLA<x><y> / SMLAW<x><y>
664 class AMulxyI<bits<7> opcod, dag oops, dag iops, string opc,
665          string asm, list<dag> pattern>
666   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc,
667       asm, "", pattern> {
668   let Inst{4}     = 0;
669   let Inst{7}     = 1;
670   let Inst{20}    = 0;
671   let Inst{27-21} = opcod;
672 }
673
674 // Extend instructions.
675 class AExtI<bits<8> opcod, dag oops, dag iops, string opc,
676             string asm, list<dag> pattern>
677   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ExtFrm, opc,
678       asm, "", pattern> {
679   let Inst{7-4}   = 0b0111;
680   let Inst{27-20} = opcod;
681 }
682
683 // Misc Arithmetic instructions.
684 class AMiscA1I<bits<8> opcod, dag oops, dag iops, string opc,
685                string asm, list<dag> pattern>
686   : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, ArithMiscFrm, opc,
687       asm, "", pattern> {
688   let Inst{27-20} = opcod;
689 }
690
691 //===----------------------------------------------------------------------===//
692
693 // ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
694 class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
695   list<Predicate> Predicates = [IsARM];
696 }
697 class ARMV5TEPat<dag pattern, dag result> : Pat<pattern, result> {
698   list<Predicate> Predicates = [IsARM, HasV5TE];
699 }
700 class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
701   list<Predicate> Predicates = [IsARM, HasV6];
702 }
703
704 //===----------------------------------------------------------------------===//
705 //
706 // Thumb Instruction Format Definitions.
707 //
708
709
710 // TI - Thumb instruction.
711
712 class ThumbI<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
713              string asm, string cstr, list<dag> pattern>
714   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
715   let OutOperandList = outs;
716   let InOperandList = ins;
717   let AsmString   = asm;
718   let Pattern = pattern;
719   list<Predicate> Predicates = [IsThumb];
720 }
721
722 class TI<dag outs, dag ins, string asm, list<dag> pattern>
723   : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
724 class TI1<dag outs, dag ins, string asm, list<dag> pattern>
725   : ThumbI<outs, ins, AddrModeT1, Size2Bytes, asm, "", pattern>;
726 class TI2<dag outs, dag ins, string asm, list<dag> pattern>
727   : ThumbI<outs, ins, AddrModeT2, Size2Bytes, asm, "", pattern>;
728 class TI4<dag outs, dag ins, string asm, list<dag> pattern>
729   : ThumbI<outs, ins, AddrModeT4, Size2Bytes, asm, "", pattern>;
730 class TIs<dag outs, dag ins, string asm, list<dag> pattern>
731   : ThumbI<outs, ins, AddrModeTs, Size2Bytes, asm, "", pattern>;
732
733 // Two-address instructions
734 class TIt<dag outs, dag ins, string asm, list<dag> pattern>
735   : ThumbI<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
736
737 // BL, BLX(1) are translated by assembler into two instructions
738 class TIx2<dag outs, dag ins, string asm, list<dag> pattern>
739   : ThumbI<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
740
741 // BR_JT instructions
742 class TJTI<dag outs, dag ins, string asm, list<dag> pattern>
743   : ThumbI<outs, ins, AddrModeNone, SizeSpecial, asm, "", pattern>;
744
745 // ThumbPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
746 class ThumbPat<dag pattern, dag result> : Pat<pattern, result> {
747   list<Predicate> Predicates = [IsThumb];
748 }
749
750 class ThumbV5Pat<dag pattern, dag result> : Pat<pattern, result> {
751   list<Predicate> Predicates = [IsThumb, HasV5T];
752 }
753
754 // Thumb1 only
755 class Thumb1I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
756              string asm, string cstr, list<dag> pattern>
757   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
758   let OutOperandList = outs;
759   let InOperandList = ins;
760   let AsmString   = asm;
761   let Pattern = pattern;
762   list<Predicate> Predicates = [IsThumb1Only];
763 }
764
765 class T1I<dag outs, dag ins, string asm, list<dag> pattern>
766   : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "", pattern>;
767
768 // Two-address instructions
769 class T1It<dag outs, dag ins, string asm, list<dag> pattern>
770   : Thumb1I<outs, ins, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
771
772 class Thumb1Pat<dag pattern, dag result> : Pat<pattern, result> {
773   list<Predicate> Predicates = [IsThumb1Only];
774 }
775
776 // T2I - Thumb2 instruction.
777
778 class Thumb2I<dag outs, dag ins, AddrMode am, SizeFlagVal sz,
779              string asm, string cstr, list<dag> pattern>
780   : InstARM<am, sz, IndexModeNone, ThumbFrm, cstr> {
781   let OutOperandList = outs;
782   let InOperandList = ins;
783   let AsmString   = asm;
784   let Pattern = pattern;
785   list<Predicate> Predicates = [IsThumb, HasThumb2];
786 }
787
788 class T2I<dag outs, dag ins, string asm, list<dag> pattern>
789   : Thumb2I<outs, ins, AddrModeNone, Size4Bytes, asm, "", pattern>;
790
791 // Thumb2Pat - Same as Pat<>, but requires that the compiler be in Thumb2 mode.
792 class Thumb2Pat<dag pattern, dag result> : Pat<pattern, result> {
793   list<Predicate> Predicates = [IsThumb, HasThumb2];
794 }
795
796 //===----------------------------------------------------------------------===//
797
798 //===----------------------------------------------------------------------===//
799 // ARM VFP Instruction templates.
800 //
801
802 // ARM VFP addrmode5 loads and stores
803 class ADI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
804            string opc, string asm, list<dag> pattern>
805   : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
806       VFPLdStFrm, opc, asm, "", pattern> {
807   // TODO: Mark the instructions with the appropriate subtarget info.
808   let Inst{27-24} = opcod1;
809   let Inst{21-20} = opcod2;
810   let Inst{11-8}  = 0b1011;
811 }
812
813 class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
814            string opc, string asm, list<dag> pattern>
815   : I<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
816       VFPLdStFrm, opc, asm, "", pattern> {
817   // TODO: Mark the instructions with the appropriate subtarget info.
818   let Inst{27-24} = opcod1;
819   let Inst{21-20} = opcod2;
820   let Inst{11-8}  = 0b1010;
821 }
822
823 // Load / store multiple
824 class AXSI5<dag oops, dag iops, string asm, list<dag> pattern>
825   : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
826        VFPLdStMulFrm, asm, "", pattern> {
827   // TODO: Mark the instructions with the appropriate subtarget info.
828   let Inst{27-25} = 0b110;
829   let Inst{11-8}  = 0b1011;
830 }
831
832 class AXDI5<dag oops, dag iops, string asm, list<dag> pattern>
833   : XI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
834        VFPLdStMulFrm, asm, "", pattern> {
835   // TODO: Mark the instructions with the appropriate subtarget info.
836   let Inst{27-25} = 0b110;
837   let Inst{11-8}  = 0b1010;
838 }
839
840
841 // Double precision, unary
842 class ADuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
843            string opc, string asm, list<dag> pattern>
844   : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
845   let Inst{27-20} = opcod1;
846   let Inst{19-16} = opcod2;
847   let Inst{11-8}  = 0b1011;
848   let Inst{7-4}   = opcod3;
849 }
850
851 // Double precision, binary
852 class ADbI<bits<8> opcod, dag oops, dag iops, string opc,
853            string asm, list<dag> pattern>
854   : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
855   let Inst{27-20} = opcod;
856   let Inst{11-8}  = 0b1011;
857 }
858
859 // Single precision, unary
860 class ASuI<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3, dag oops, dag iops,
861            string opc, string asm, list<dag> pattern>
862   : AI<oops, iops, VFPUnaryFrm, opc, asm, pattern> {
863   // Bits 22 (D bit) and 5 (M bit) will be changed during instruction encoding.
864   let Inst{27-20} = opcod1;
865   let Inst{19-16} = opcod2;
866   let Inst{11-8}  = 0b1010;
867   let Inst{7-4}   = opcod3;
868 }
869
870 // Single precision, binary
871 class ASbI<bits<8> opcod, dag oops, dag iops, string opc,
872            string asm, list<dag> pattern>
873   : AI<oops, iops, VFPBinaryFrm, opc, asm, pattern> {
874   // Bit 22 (D bit) can be changed during instruction encoding.
875   let Inst{27-20} = opcod;
876   let Inst{11-8}  = 0b1010;
877 }
878
879 // VFP conversion instructions
880 class AVConv1I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
881                dag oops, dag iops, string opc, string asm, list<dag> pattern>
882   : AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
883   let Inst{27-20} = opcod1;
884   let Inst{19-16} = opcod2;
885   let Inst{11-8}  = opcod3;
886   let Inst{6}     = 1;
887 }
888
889 class AVConvXI<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, Format f,
890              string opc, string asm, list<dag> pattern>
891   : AI<oops, iops, f, opc, asm, pattern> {
892   let Inst{27-20} = opcod1;
893   let Inst{11-8}  = opcod2;
894   let Inst{4}     = 1;
895 }
896
897 class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
898               string asm, list<dag> pattern>
899   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv2Frm, opc, asm, pattern>;
900
901 class AVConv3I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
902               string asm, list<dag> pattern>
903   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv3Frm, opc, asm, pattern>;
904
905 class AVConv4I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
906               string asm, list<dag> pattern>
907   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv4Frm, opc, asm, pattern>;
908
909 class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
910               string asm, list<dag> pattern>
911   : AVConvXI<opcod1, opcod2, oops, iops, VFPConv5Frm, opc, asm, pattern>;
912
913 //===----------------------------------------------------------------------===//
914
915 //===----------------------------------------------------------------------===//
916 // ARM NEON Instruction templates.
917 //
918
919 class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, string asm,
920             string cstr, list<dag> pattern>
921   : InstARM<am, Size4Bytes, im, NEONFrm, cstr> {
922   let OutOperandList = oops;
923   let InOperandList = iops;
924   let AsmString = asm;
925   let Pattern = pattern;
926   list<Predicate> Predicates = [HasNEON];
927 }
928
929 class NI<dag oops, dag iops, string asm, list<dag> pattern>
930   : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, "", pattern> {
931 }
932
933 class NDataI<dag oops, dag iops, string asm, string cstr, list<dag> pattern>
934   : NeonI<oops, iops, AddrModeNone, IndexModeNone, asm, cstr, pattern> {
935   let Inst{31-25} = 0b1111001;
936 }
937
938 // NEON "one register and a modified immediate" format.
939 class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6,
940                bit op5, bit op4,
941                dag oops, dag iops, string asm, string cstr, list<dag> pattern>
942   : NDataI<oops, iops, asm, cstr, pattern> {
943   let Inst{23} = op23;
944   let Inst{21-19} = op21_19;
945   let Inst{11-8} = op11_8;
946   let Inst{7} = op7;
947   let Inst{6} = op6;
948   let Inst{5} = op5;
949   let Inst{4} = op4;
950 }
951
952 // NEON 2 vector register format.
953 class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16,
954           bits<5> op11_7, bit op6, bit op4,
955           dag oops, dag iops, string asm, string cstr, list<dag> pattern>
956   : NDataI<oops, iops, asm, cstr, pattern> {
957   let Inst{24-23} = op24_23;
958   let Inst{21-20} = op21_20;
959   let Inst{19-18} = op19_18;
960   let Inst{17-16} = op17_16;
961   let Inst{11-7} = op11_7;
962   let Inst{6} = op6;
963   let Inst{4} = op4;
964 }
965
966 // NEON 2 vector register with immediate.
967 class N2VImm<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
968              bit op6, bit op4,
969              dag oops, dag iops, string asm, string cstr, list<dag> pattern>
970   : NDataI<oops, iops, asm, cstr, pattern> {
971   let Inst{24} = op24;
972   let Inst{23} = op23;
973   let Inst{21-16} = op21_16;
974   let Inst{11-8} = op11_8;
975   let Inst{7} = op7;
976   let Inst{6} = op6;
977   let Inst{4} = op4;
978 }
979
980 // NEON 3 vector register format.
981 class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4,
982           dag oops, dag iops, string asm, string cstr, list<dag> pattern>
983   : NDataI<oops, iops, asm, cstr, pattern> {
984   let Inst{24} = op24;
985   let Inst{23} = op23;
986   let Inst{21-20} = op21_20;
987   let Inst{11-8} = op11_8;
988   let Inst{6} = op6;
989   let Inst{4} = op4;
990 }
991
992 // NEON VMOVs between scalar and core registers.
993 class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
994                dag oops, dag iops, Format f, string opc, string asm,
995                list<dag> pattern>
996   : AI<oops, iops, f, opc, asm, pattern> {
997   let Inst{27-20} = opcod1;
998   let Inst{11-8} = opcod2;
999   let Inst{6-5} = opcod3;
1000   let Inst{4} = 1;
1001   list<Predicate> Predicates = [HasNEON];
1002 }
1003 class NVGetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1004                 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1005   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONGetLnFrm, opc, asm,
1006              pattern>;
1007 class NVSetLane<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1008                 dag oops, dag iops, string opc, string asm, list<dag> pattern>
1009   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONSetLnFrm, opc, asm,
1010              pattern>;
1011 class NVDup<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
1012             dag oops, dag iops, string opc, string asm, list<dag> pattern>
1013   : NVLaneOp<opcod1, opcod2, opcod3, oops, iops, NEONDupFrm, opc, asm, pattern>;