[ARM] Enable shrink-wrapping by default.
[oota-llvm.git] / lib / Target / ARM / ARMScheduleSwift.td
1 //=- ARMScheduleSwift.td - Swift Scheduling Definitions -*- 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 // This file defines the itinerary class data for the Swift processor..
11 //
12 //===----------------------------------------------------------------------===//
13
14 // ===---------------------------------------------------------------------===//
15 // This section contains legacy support for itineraries. This is
16 // required until SD and PostRA schedulers are replaced by MachineScheduler.
17
18 def SW_DIS0 : FuncUnit;
19 def SW_DIS1 : FuncUnit;
20 def SW_DIS2 : FuncUnit;
21
22 def SW_ALU0 : FuncUnit;
23 def SW_ALU1 : FuncUnit;
24 def SW_LS   : FuncUnit;
25 def SW_IDIV : FuncUnit;
26 def SW_FDIV : FuncUnit;
27
28 // FIXME: Need bypasses.
29 // FIXME: Model the multiple stages of IIC_iMOVix2, IIC_iMOVix2addpc, and
30 //        IIC_iMOVix2ld better.
31 // FIXME: Model the special immediate shifts that are not microcoded.
32 // FIXME: Do we need to model the fact that uses of r15 in a micro-op force it
33 //        to issue on pipe 1?
34 // FIXME: Model the pipelined behavior of CMP / TST instructions.
35 // FIXME: Better model the microcode stages of multiply instructions, especially
36 //        conditional variants.
37 // FIXME: Add preload instruction when it is documented.
38 // FIXME: Model non-pipelined nature of FP div / sqrt unit.
39
40 // Swift machine model for scheduling and other instruction cost heuristics.
41 def SwiftModel : SchedMachineModel {
42   let IssueWidth = 3; // 3 micro-ops are dispatched per cycle.
43   let MicroOpBufferSize = 45; // Based on NEON renamed registers.
44   let LoadLatency = 3;
45   let MispredictPenalty = 14; // A branch direction mispredict.
46   let CompleteModel = 0;      // FIXME: Remove if all instructions are covered.
47 }
48
49 // Swift predicates.
50 def IsFastImmShiftSwiftPred : SchedPredicate<[{TII->isSwiftFastImmShift(MI)}]>;
51
52 // Swift resource mapping.
53 let SchedModel = SwiftModel in {
54   // Processor resources.
55   def SwiftUnitP01 : ProcResource<2>; // ALU unit.
56   def SwiftUnitP0 : ProcResource<1> { let Super = SwiftUnitP01; } // Mul unit.
57   def SwiftUnitP1 : ProcResource<1> { let Super = SwiftUnitP01; } // Br unit.
58   def SwiftUnitP2 : ProcResource<1>; // LS unit.
59   def SwiftUnitDiv : ProcResource<1>;
60
61   // Generic resource requirements.
62   def SwiftWriteP0OneCycle : SchedWriteRes<[SwiftUnitP0]>;
63   def SwiftWriteP0TwoCycle : SchedWriteRes<[SwiftUnitP0]> { let Latency = 2; }
64   def SwiftWriteP0FourCycle : SchedWriteRes<[SwiftUnitP0]> { let Latency = 4; }
65   def SwiftWriteP0SixCycle : SchedWriteRes<[SwiftUnitP0]> { let Latency = 6; }
66   def SwiftWriteP0P1FourCycle : SchedWriteRes<[SwiftUnitP0, SwiftUnitP1]> {
67     let Latency = 4;
68   }
69   def SwiftWriteP0P1SixCycle : SchedWriteRes<[SwiftUnitP0, SwiftUnitP1]> {
70     let Latency = 6;
71   }
72   def SwiftWriteP01OneCycle : SchedWriteRes<[SwiftUnitP01]>;
73   def SwiftWriteP1TwoCycle : SchedWriteRes<[SwiftUnitP1]> { let Latency = 2; }
74   def SwiftWriteP1FourCycle : SchedWriteRes<[SwiftUnitP1]> { let Latency = 4; }
75   def SwiftWriteP1SixCycle : SchedWriteRes<[SwiftUnitP1]> { let Latency = 6; }
76   def SwiftWriteP1EightCycle : SchedWriteRes<[SwiftUnitP1]> { let Latency = 8; }
77   def SwiftWriteP1TwelveCyc : SchedWriteRes<[SwiftUnitP1]> { let Latency = 12; }
78   def SwiftWriteP01OneCycle2x : WriteSequence<[SwiftWriteP01OneCycle], 2>;
79   def SwiftWriteP01OneCycle3x : WriteSequence<[SwiftWriteP01OneCycle], 3>;
80   def SwiftWriteP01TwoCycle : SchedWriteRes<[SwiftUnitP01]> { let Latency = 2; }
81   def SwiftWriteP01ThreeCycleTwoUops : SchedWriteRes<[SwiftUnitP01,
82                                                       SwiftUnitP01]> {
83     let Latency = 3;
84     let NumMicroOps = 2;
85   }
86   def SwiftWriteP0ThreeCycleThreeUops : SchedWriteRes<[SwiftUnitP0]> {
87     let Latency = 3;
88     let NumMicroOps = 3;
89     let ResourceCycles = [3];
90   }
91   // Plain load without writeback.
92   def SwiftWriteP2ThreeCycle : SchedWriteRes<[SwiftUnitP2]> {
93     let Latency = 3;
94   }
95   def SwiftWriteP2FourCycle : SchedWriteRes<[SwiftUnitP2]> {
96     let Latency = 4;
97   }
98   // A store does not write to a register.
99   def SwiftWriteP2 : SchedWriteRes<[SwiftUnitP2]> {
100     let Latency = 0;
101   }
102   foreach Num = 1-4 in {
103     def SwiftWrite#Num#xP2 : WriteSequence<[SwiftWriteP2], Num>;
104   }
105   def SwiftWriteP01OneCycle2x_load : WriteSequence<[SwiftWriteP01OneCycle,
106                                                     SwiftWriteP01OneCycle,
107                                                     SwiftWriteP2ThreeCycle]>;
108   // 4.2.4 Arithmetic and Logical.
109   // ALU operation register shifted by immediate variant.
110   def SwiftWriteALUsi : SchedWriteVariant<[
111     // lsl #2, lsl #1, or lsr #1.
112     SchedVar<IsFastImmShiftSwiftPred, [SwiftWriteP01TwoCycle]>,
113     SchedVar<NoSchedPred,             [WriteALU]>
114   ]>;
115   def SwiftWriteALUsr : SchedWriteVariant<[
116     SchedVar<IsPredicatedPred, [SwiftWriteP01ThreeCycleTwoUops]>,
117     SchedVar<NoSchedPred,      [SwiftWriteP01TwoCycle]>
118   ]>;
119   def SwiftWriteALUSsr : SchedWriteVariant<[
120     SchedVar<IsPredicatedPred, [SwiftWriteP0ThreeCycleThreeUops]>,
121     SchedVar<NoSchedPred,      [SwiftWriteP01TwoCycle]>
122   ]>;
123   def SwiftReadAdvanceALUsr : SchedReadVariant<[
124     SchedVar<IsPredicatedPred, [SchedReadAdvance<2>]>,
125     SchedVar<NoSchedPred,      [NoReadAdvance]>
126   ]>;
127   // ADC,ADD,NEG,RSB,RSC,SBC,SUB,ADR
128   // AND,BIC,EOR,ORN,ORR
129   // CLZ,RBIT,REV,REV16,REVSH,PKH
130   def : WriteRes<WriteALU, [SwiftUnitP01]>;
131   def : SchedAlias<WriteALUsi, SwiftWriteALUsi>;
132   def : SchedAlias<WriteALUsr, SwiftWriteALUsr>;
133   def : SchedAlias<WriteALUSsr, SwiftWriteALUSsr>;
134   def : ReadAdvance<ReadALU, 0>;
135   def : SchedAlias<ReadALUsr, SwiftReadAdvanceALUsr>;
136
137
138   def SwiftChooseShiftKindP01OneOrTwoCycle : SchedWriteVariant<[
139     SchedVar<IsFastImmShiftSwiftPred, [SwiftWriteP01OneCycle]>,
140     SchedVar<NoSchedPred,             [SwiftWriteP01TwoCycle]>
141   ]>;
142
143   // 4.2.5 Integer comparison
144   def : WriteRes<WriteCMP, [SwiftUnitP01]>;
145   def : SchedAlias<WriteCMPsi, SwiftChooseShiftKindP01OneOrTwoCycle>;
146   def : SchedAlias<WriteCMPsr, SwiftWriteP01TwoCycle>;
147
148   // 4.2.6 Shift, Move
149   // Shift
150   //  ASR,LSL,ROR,RRX
151   //  MOV(register-shiftedregister)  MVN(register-shiftedregister)
152   // Move
153   //  MOV,MVN
154   //  MOVT
155   // Sign/Zero extension
156   def : InstRW<[SwiftWriteP01OneCycle],
157                (instregex "SXTB", "SXTH", "SXTB16", "UXTB", "UXTH", "UXTB16",
158                           "t2SXTB", "t2SXTH", "t2SXTB16", "t2UXTB", "t2UXTH",
159                           "t2UXTB16")>;
160   // Pseudo instructions.
161   def : InstRW<[SwiftWriteP01OneCycle2x],
162         (instregex "MOVCCi32imm", "MOVi32imm", "MOV_ga_dyn", "t2MOVCCi32imm",
163                    "t2MOVi32imm", "t2MOV_ga_dyn")>;
164   def : InstRW<[SwiftWriteP01OneCycle3x],
165         (instregex "MOV_ga_pcrel", "t2MOV_ga_pcrel", "t2MOVi16_ga_pcrel")>;
166   def : InstRW<[SwiftWriteP01OneCycle2x_load],
167         (instregex "MOV_ga_pcrel_ldr", "t2MOV_ga_pcrel_ldr")>;
168
169   def SwiftWriteP0TwoCyleTwoUops : WriteSequence<[SwiftWriteP0OneCycle], 2>;
170
171   def SwiftPredP0OneOrTwoCycle : SchedWriteVariant<[
172     SchedVar<IsPredicatedPred, [ SwiftWriteP0TwoCyleTwoUops ]>,
173     SchedVar<NoSchedPred,     [ SwiftWriteP0OneCycle ]>
174   ]>;
175
176   // 4.2.7 Select
177   // SEL
178   def : InstRW<[SwiftPredP0OneOrTwoCycle], (instregex "SEL", "t2SEL")>;
179
180   // 4.2.8 Bitfield
181   // BFI,BFC, SBFX,UBFX
182   def : InstRW< [SwiftWriteP01TwoCycle],
183         (instregex "BFC", "BFI", "UBFX", "SBFX", "(t|t2)BFC", "(t|t2)BFI",
184         "(t|t2)UBFX", "(t|t2)SBFX")>;
185
186   // 4.2.9 Saturating arithmetic
187   def : InstRW< [SwiftWriteP01TwoCycle],
188         (instregex "QADD", "QSUB", "QDADD", "QDSUB", "SSAT", "SSAT16", "USAT",
189         "USAT16", "QADD8", "QADD16", "QSUB8", "QSUB16", "QASX", "QSAX",
190         "UQADD8", "UQADD16","UQSUB8","UQSUB16","UQASX","UQSAX", "t2QADD",
191         "t2QSUB", "t2QDADD", "t2QDSUB", "t2SSAT", "t2SSAT16", "t2USAT",
192         "t2QADD8", "t2QADD16", "t2QSUB8", "t2QSUB16", "t2QASX", "t2QSAX",
193         "t2UQADD8", "t2UQADD16","t2UQSUB8","t2UQSUB16","t2UQASX","t2UQSAX")>;
194
195   // 4.2.10 Parallel Arithmetic
196   // Not flag setting.
197   def : InstRW< [SwiftWriteALUsr],
198         (instregex "SADD8", "SADD16", "SSUB8", "SSUB16", "SASX", "SSAX",
199         "UADD8", "UADD16", "USUB8", "USUB16", "UASX", "USAX", "t2SADD8",
200         "t2SADD16", "t2SSUB8", "t2SSUB16", "t2SASX", "t2SSAX", "t2UADD8",
201         "t2UADD16", "t2USUB8", "t2USUB16", "t2UASX", "t2USAX")>;
202   // Flag setting.
203   def : InstRW< [SwiftWriteP01TwoCycle],
204        (instregex "SHADD8", "SHADD16", "SHSUB8", "SHSUB16", "SHASX", "SHSAX",
205        "SXTAB", "SXTAB16", "SXTAH", "UHADD8", "UHADD16", "UHSUB8", "UHSUB16",
206        "UHASX", "UHSAX", "UXTAB", "UXTAB16", "UXTAH", "t2SHADD8", "t2SHADD16",
207        "t2SHSUB8", "t2SHSUB16", "t2SHASX", "t2SHSAX", "t2SXTAB", "t2SXTAB16",
208        "t2SXTAH", "t2UHADD8", "t2UHADD16", "t2UHSUB8", "t2UHSUB16", "t2UHASX",
209        "t2UHSAX", "t2UXTAB", "t2UXTAB16", "t2UXTAH")>;
210
211   // 4.2.11 Sum of Absolute Difference
212   def : InstRW< [SwiftWriteP0P1FourCycle], (instregex "USAD8") >;
213   def : InstRW<[SwiftWriteP0P1FourCycle, ReadALU, ReadALU, SchedReadAdvance<2>],
214         (instregex "USADA8")>;
215
216   // 4.2.12 Integer Multiply (32-bit result)
217   // Two sources.
218   def : InstRW< [SwiftWriteP0FourCycle],
219         (instregex "MULS", "MUL", "SMMUL", "SMMULR", "SMULBB", "SMULBT",
220         "SMULTB", "SMULTT", "SMULWB", "SMULWT", "SMUSD", "SMUSDXi", "t2MUL",
221         "t2SMMUL", "t2SMMULR", "t2SMULBB", "t2SMULBT", "t2SMULTB", "t2SMULTT",
222         "t2SMULWB", "t2SMULWT", "t2SMUSD")>;
223
224   def SwiftWriteP0P01FiveCycleTwoUops :
225       SchedWriteRes<[SwiftUnitP0, SwiftUnitP01]>  {
226     let Latency = 5;
227   }
228
229   def SwiftPredP0P01FourFiveCycle : SchedWriteVariant<[
230     SchedVar<IsPredicatedPred, [ SwiftWriteP0P01FiveCycleTwoUops ]>,
231     SchedVar<NoSchedPred,      [ SwiftWriteP0FourCycle ]>
232   ]>;
233
234   def SwiftReadAdvanceFourCyclesPred : SchedReadVariant<[
235      SchedVar<IsPredicatedPred, [SchedReadAdvance<4>]>,
236      SchedVar<NoSchedPred,      [ReadALU]>
237   ]>;
238
239   // Multiply accumulate, three sources
240   def : InstRW< [SwiftPredP0P01FourFiveCycle, ReadALU, ReadALU,
241                  SwiftReadAdvanceFourCyclesPred],
242         (instregex "MLAS", "MLA", "MLS", "SMMLA", "SMMLAR", "SMMLS", "SMMLSR",
243         "t2MLA", "t2MLS", "t2MLAS", "t2SMMLA", "t2SMMLAR", "t2SMMLS",
244         "t2SMMLSR")>;
245
246   // 4.2.13 Integer Multiply (32-bit result, Q flag)
247   def : InstRW< [SwiftWriteP0FourCycle],
248         (instregex "SMUAD", "SMUADX", "t2SMUAD", "t2SMUADX")>;
249   def : InstRW< [SwiftPredP0P01FourFiveCycle, ReadALU, ReadALU,
250                  SwiftReadAdvanceFourCyclesPred],
251         (instregex "SMLABB", "SMLABT", "SMLATB", "SMLATT", "SMLSD", "SMLSDX",
252         "SMLAWB", "SMLAWT", "t2SMLABB", "t2SMLABT", "t2SMLATB", "t2SMLATT",
253         "t2SMLSD", "t2SMLSDX", "t2SMLAWB", "t2SMLAWT")>;
254   def : InstRW< [SwiftPredP0P01FourFiveCycle],
255         (instregex "SMLAD", "SMLADX", "t2SMLAD", "t2SMLADX")>;
256
257   def SwiftP0P0P01FiveCycle : SchedWriteRes<[SwiftUnitP0, SwiftUnitP01]> {
258     let Latency = 5;
259     let NumMicroOps = 3;
260     let ResourceCycles = [2, 1];
261   }
262   def SwiftWrite1Cycle : SchedWriteRes<[]> {
263     let Latency = 1;
264     let NumMicroOps = 0;
265   }
266   def SwiftWrite5Cycle : SchedWriteRes<[]> {
267     let Latency = 5;
268     let NumMicroOps = 0;
269   }
270   def SwiftWrite6Cycle : SchedWriteRes<[]> {
271     let Latency = 6;
272     let NumMicroOps = 0;
273   }
274
275   // 4.2.14 Integer Multiply, Long
276   def : InstRW< [SwiftP0P0P01FiveCycle, SwiftWrite5Cycle],
277         (instregex "SMULL$", "UMULL$", "t2SMULL$", "t2UMULL$")>;
278
279   def Swift2P03P01FiveCycle : SchedWriteRes<[SwiftUnitP0, SwiftUnitP01]> {
280     let Latency = 7;
281     let NumMicroOps = 5;
282     let ResourceCycles = [2, 3];
283   }
284
285   // 4.2.15 Integer Multiply Accumulate, Long
286   // 4.2.16 Integer Multiply Accumulate, Dual
287   // 4.2.17 Integer Multiply Accumulate Accumulate, Long
288   // We are being a bit inaccurate here.
289   def : InstRW< [SwiftWrite5Cycle, Swift2P03P01FiveCycle, ReadALU, ReadALU,
290                  SchedReadAdvance<4>, SchedReadAdvance<3>],
291         (instregex "SMLALS", "UMLALS", "SMLAL", "UMLAL", "MLALBB", "SMLALBT",
292         "SMLALTB", "SMLALTT", "SMLALD", "SMLALDX", "SMLSLD", "SMLSLDX",
293         "UMAAL", "t2SMLALS", "t2UMLALS", "t2SMLAL", "t2UMLAL", "t2MLALBB", "t2SMLALBT",
294         "t2SMLALTB", "t2SMLALTT", "t2SMLALD", "t2SMLALDX", "t2SMLSLD", "t2SMLSLDX",
295         "t2UMAAL")>;
296
297   def SwiftDiv : SchedWriteRes<[SwiftUnitP0, SwiftUnitDiv]> {
298     let NumMicroOps = 1;
299     let Latency = 14;
300     let ResourceCycles = [1, 14];
301   }
302   // 4.2.18 Integer Divide
303   def : WriteRes<WriteDiv, [SwiftUnitDiv]>; // Workaround.
304   def : InstRW <[SwiftDiv],
305         (instregex "SDIV", "UDIV", "t2SDIV", "t2UDIV")>;
306
307   // 4.2.19 Integer Load Single Element
308   // 4.2.20 Integer Load Signextended
309   def SwiftWriteP2P01ThreeCycle : SchedWriteRes<[SwiftUnitP2, SwiftUnitP01]> {
310     let Latency = 3;
311     let NumMicroOps = 2;
312   }
313   def SwiftWriteP2P01FourCyle : SchedWriteRes<[SwiftUnitP2, SwiftUnitP01]> {
314     let Latency = 4;
315     let NumMicroOps = 2;
316   }
317   def SwiftWriteP2P01P01FourCycle : SchedWriteRes<[SwiftUnitP2, SwiftUnitP01,
318                                                    SwiftUnitP01]> {
319     let Latency = 4;
320     let NumMicroOps = 3;
321   }
322   def SwiftWriteP2P2ThreeCycle : SchedWriteRes<[SwiftUnitP2, SwiftUnitP2]> {
323     let Latency = 3;
324     let NumMicroOps = 2;
325   }
326   def SwiftWriteP2P2P01ThreeCycle : SchedWriteRes<[SwiftUnitP2, SwiftUnitP2,
327                                                    SwiftUnitP01]> {
328     let Latency = 3;
329     let NumMicroOps = 3;
330   }
331   def SwiftWrBackOne : SchedWriteRes<[]> {
332     let Latency = 1;
333     let NumMicroOps = 0;
334   }
335   def SwiftWriteLdFour : SchedWriteRes<[]> {
336     let Latency = 4;
337     let NumMicroOps = 0;
338   }
339    // Not accurate.
340   def : InstRW<[SwiftWriteP2ThreeCycle],
341         (instregex "LDR(i12|rs)$", "LDRB(i12|rs)$", "t2LDR(i8|i12|s|pci)",
342         "t2LDR(H|B)(i8|i12|s|pci)", "LDREX", "tLDR[BH](r|i|spi|pci|pciASM)",
343         "tLDR(r|i|spi|pci|pciASM)")>;
344   def : InstRW<[SwiftWriteP2ThreeCycle],
345         (instregex "LDRH$",  "PICLDR$", "PICLDR(H|B)$", "LDRcp$")>;
346   def : InstRW<[SwiftWriteP2P01FourCyle],
347         (instregex "PICLDRS(H|B)$", "t2LDRS(H|B)(i|r|p|s)", "LDRS(H|B)$",
348         "t2LDRpci_pic", "tLDRS(B|H)")>;
349   def : InstRW<[SwiftWriteP2P01ThreeCycle,  SwiftWrBackOne],
350         (instregex "LD(RB|R)(_|T_)(POST|PRE)_(IMM|REG)", "LDRH(_PRE|_POST)",
351         "LDR(T|BT)_POST_(REG|IMM)", "LDRHT(i|r)",
352         "t2LD(R|RB|RH)_(PRE|POST)", "t2LD(R|RB|RH)T")>;
353   def : InstRW<[SwiftWriteP2P01P01FourCycle, SwiftWrBackOne],
354         (instregex "LDR(SH|SB)(_POST|_PRE)", "t2LDR(SH|SB)(_POST|_PRE)",
355         "LDRS(B|H)T(i|r)", "t2LDRS(B|H)T(i|r)", "t2LDRS(B|H)T")>;
356
357   // 4.2.21 Integer Dual Load
358   // Not accurate.
359   def : InstRW<[SwiftWriteP2P2ThreeCycle, SwiftWriteLdFour],
360         (instregex "t2LDRDi8", "LDRD$")>;
361   def : InstRW<[SwiftWriteP2P2P01ThreeCycle, SwiftWriteLdFour, SwiftWrBackOne],
362         (instregex "LDRD_(POST|PRE)", "t2LDRD_(POST|PRE)")>;
363
364   // 4.2.22 Integer Load, Multiple
365   // NumReg = 1 .. 16
366   foreach Lat = 3-25 in {
367     def SwiftWriteLM#Lat#Cy : SchedWriteRes<[SwiftUnitP2]> {
368       let Latency = Lat;
369     }
370     def SwiftWriteLM#Lat#CyNo : SchedWriteRes<[]> {
371       let Latency = Lat;
372       let NumMicroOps = 0;
373     }
374   }
375   // Predicate.
376   foreach NumAddr = 1-16 in {
377     def SwiftLMAddr#NumAddr#Pred : SchedPredicate<"TII->getNumLDMAddresses(MI) == "#NumAddr>;
378   }
379   def SwiftWriteLDMAddrNoWB : SchedWriteRes<[SwiftUnitP01]> { let Latency = 0; }
380   def SwiftWriteLDMAddrWB : SchedWriteRes<[SwiftUnitP01, SwiftUnitP01]>;
381   def SwiftWriteLM : SchedWriteVariant<[
382     SchedVar<SwiftLMAddr2Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy]>,
383     SchedVar<SwiftLMAddr3Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
384                                 SwiftWriteLM5Cy]>,
385     SchedVar<SwiftLMAddr4Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
386                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy]>,
387     SchedVar<SwiftLMAddr5Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
388                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
389                                 SwiftWriteLM7Cy]>,
390     SchedVar<SwiftLMAddr6Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
391                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
392                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy]>,
393     SchedVar<SwiftLMAddr7Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
394                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
395                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
396                                 SwiftWriteLM9Cy]>,
397     SchedVar<SwiftLMAddr8Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
398                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
399                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
400                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy]>,
401     SchedVar<SwiftLMAddr9Pred, [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
402                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
403                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
404                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
405                                 SwiftWriteLM11Cy]>,
406     SchedVar<SwiftLMAddr10Pred,[SwiftWriteLM3Cy, SwiftWriteLM4Cy,
407                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
408                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
409                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
410                                 SwiftWriteLM11Cy, SwiftWriteLM12Cy]>,
411     SchedVar<SwiftLMAddr11Pred,[SwiftWriteLM3Cy, SwiftWriteLM4Cy,
412                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
413                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
414                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
415                                 SwiftWriteLM11Cy, SwiftWriteLM12Cy,
416                                 SwiftWriteLM13Cy]>,
417     SchedVar<SwiftLMAddr12Pred,[SwiftWriteLM3Cy, SwiftWriteLM4Cy,
418                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
419                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
420                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
421                                 SwiftWriteLM11Cy, SwiftWriteLM12Cy,
422                                 SwiftWriteLM13Cy, SwiftWriteLM14Cy]>,
423     SchedVar<SwiftLMAddr13Pred,[SwiftWriteLM3Cy, SwiftWriteLM4Cy,
424                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
425                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
426                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
427                                 SwiftWriteLM11Cy, SwiftWriteLM12Cy,
428                                 SwiftWriteLM13Cy, SwiftWriteLM14Cy,
429                                 SwiftWriteLM15Cy]>,
430     SchedVar<SwiftLMAddr14Pred,[SwiftWriteLM3Cy, SwiftWriteLM4Cy,
431                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
432                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
433                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
434                                 SwiftWriteLM11Cy, SwiftWriteLM12Cy,
435                                 SwiftWriteLM13Cy, SwiftWriteLM14Cy,
436                                 SwiftWriteLM15Cy, SwiftWriteLM16Cy]>,
437     SchedVar<SwiftLMAddr15Pred,[SwiftWriteLM3Cy, SwiftWriteLM4Cy,
438                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
439                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
440                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
441                                 SwiftWriteLM11Cy, SwiftWriteLM12Cy,
442                                 SwiftWriteLM13Cy, SwiftWriteLM14Cy,
443                                 SwiftWriteLM15Cy, SwiftWriteLM16Cy,
444                                 SwiftWriteLM17Cy]>,
445     SchedVar<SwiftLMAddr16Pred,[SwiftWriteLM3Cy, SwiftWriteLM4Cy,
446                                 SwiftWriteLM5Cy, SwiftWriteLM6Cy,
447                                 SwiftWriteLM7Cy, SwiftWriteLM8Cy,
448                                 SwiftWriteLM9Cy, SwiftWriteLM10Cy,
449                                 SwiftWriteLM11Cy, SwiftWriteLM12Cy,
450                                 SwiftWriteLM13Cy, SwiftWriteLM14Cy,
451                                 SwiftWriteLM15Cy, SwiftWriteLM16Cy,
452                                 SwiftWriteLM17Cy, SwiftWriteLM18Cy]>,
453     // Unknow number of registers, just use resources for two registers.
454     SchedVar<NoSchedPred,      [SwiftWriteLM3Cy, SwiftWriteLM4Cy,
455                                 SwiftWriteLM5CyNo, SwiftWriteLM6CyNo,
456                                 SwiftWriteLM7CyNo, SwiftWriteLM8CyNo,
457                                 SwiftWriteLM9CyNo, SwiftWriteLM10CyNo,
458                                 SwiftWriteLM11CyNo, SwiftWriteLM12CyNo,
459                                 SwiftWriteLM13CyNo, SwiftWriteLM14CyNo,
460                                 SwiftWriteLM15CyNo, SwiftWriteLM16CyNo,
461                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo]>
462
463   ]> { let Variadic=1; }
464
465   def : InstRW<[SwiftWriteLM, SwiftWriteLDMAddrNoWB],
466         (instregex "LDM(IA|DA|DB|IB)$", "t2LDM(IA|DA|DB|IB)$",
467         "(t|sys)LDM(IA|DA|DB|IB)$")>;
468   def : InstRW<[SwiftWriteLDMAddrWB, SwiftWriteLM],
469         (instregex /*"t2LDMIA_RET", "tLDMIA_RET", "LDMIA_RET",*/
470         "LDM(IA|DA|DB|IB)_UPD", "(t2|sys|t)LDM(IA|DA|DB|IB)_UPD")>;
471   def : InstRW<[SwiftWriteLDMAddrWB, SwiftWriteLM, SwiftWriteP1TwoCycle],
472         (instregex "LDMIA_RET", "(t|t2)LDMIA_RET", "POP", "tPOP")>;
473   // 4.2.23 Integer Store, Single Element
474   def : InstRW<[SwiftWriteP2],
475         (instregex "PICSTR", "STR(i12|rs)", "STRB(i12|rs)", "STRH$", "STREX",
476         "t2STR(i12|i8|s)$", "t2STR[BH](i12|i8|s)$", "tSTR[BH](i|r)", "tSTR(i|r)", "tSTRspi")>;
477
478   def : InstRW<[SwiftWriteP01OneCycle, SwiftWriteP2],
479         (instregex "STR(B_|_|BT_|T_)(PRE_IMM|PRE_REG|POST_REG|POST_IMM)",
480         "STR(i|r)_preidx", "STRB(i|r)_preidx", "STRH_preidx", "STR(H_|HT_)(PRE|POST)",
481         "STR(BT|HT|T)", "t2STR_(PRE|POST)", "t2STR[BH]_(PRE|POST)",
482         "t2STR_preidx", "t2STR[BH]_preidx", "t2ST(RB|RH|R)T")>;
483
484   // 4.2.24 Integer Store, Dual
485   def : InstRW<[SwiftWriteP2, SwiftWriteP2, SwiftWriteP01OneCycle],
486         (instregex "STRD$", "t2STRDi8")>;
487   def : InstRW<[SwiftWriteP01OneCycle, SwiftWriteP2, SwiftWriteP2,
488                 SwiftWriteP01OneCycle],
489         (instregex "(t2|t)STRD_(POST|PRE)", "STRD_(POST|PRE)")>;
490
491   // 4.2.25 Integer Store, Multiple
492   def SwiftWriteStIncAddr : SchedWriteRes<[SwiftUnitP2, SwiftUnitP01]> {
493     let Latency = 0;
494     let NumMicroOps = 2;
495   }
496   foreach NumAddr = 1-16 in {
497      def SwiftWriteSTM#NumAddr : WriteSequence<[SwiftWriteStIncAddr], NumAddr>;
498   }
499   def SwiftWriteSTM : SchedWriteVariant<[
500     SchedVar<SwiftLMAddr2Pred, [SwiftWriteSTM2]>,
501     SchedVar<SwiftLMAddr3Pred, [SwiftWriteSTM3]>,
502     SchedVar<SwiftLMAddr4Pred, [SwiftWriteSTM4]>,
503     SchedVar<SwiftLMAddr5Pred, [SwiftWriteSTM5]>,
504     SchedVar<SwiftLMAddr6Pred, [SwiftWriteSTM6]>,
505     SchedVar<SwiftLMAddr7Pred, [SwiftWriteSTM7]>,
506     SchedVar<SwiftLMAddr8Pred, [SwiftWriteSTM8]>,
507     SchedVar<SwiftLMAddr9Pred, [SwiftWriteSTM9]>,
508     SchedVar<SwiftLMAddr10Pred,[SwiftWriteSTM10]>,
509     SchedVar<SwiftLMAddr11Pred,[SwiftWriteSTM11]>,
510     SchedVar<SwiftLMAddr12Pred,[SwiftWriteSTM12]>,
511     SchedVar<SwiftLMAddr13Pred,[SwiftWriteSTM13]>,
512     SchedVar<SwiftLMAddr14Pred,[SwiftWriteSTM14]>,
513     SchedVar<SwiftLMAddr15Pred,[SwiftWriteSTM15]>,
514     SchedVar<SwiftLMAddr16Pred,[SwiftWriteSTM16]>,
515     // Unknow number of registers, just use resources for two registers.
516     SchedVar<NoSchedPred,      [SwiftWriteSTM2]>
517   ]>;
518   def : InstRW<[SwiftWriteSTM],
519         (instregex "STM(IB|IA|DB|DA)$", "(t2|sys|t)STM(IB|IA|DB|DA)$")>;
520   def : InstRW<[SwiftWriteP01OneCycle, SwiftWriteSTM],
521         (instregex "STM(IB|IA|DB|DA)_UPD", "(t2|sys|t)STM(IB|IA|DB|DA)_UPD",
522         "PUSH", "tPUSH")>;
523
524   // LDRLIT pseudo instructions, they expand to LDR + PICADD
525   def : InstRW<[SwiftWriteP2ThreeCycle, WriteALU],
526         (instregex "t?LDRLIT_ga_abs", "t?LDRLIT_ga_pcrel")>;
527   // LDRLIT_ga_pcrel_ldr expands to LDR + PICLDR
528   def : InstRW<[SwiftWriteP2ThreeCycle, SwiftWriteP2ThreeCycle],
529         (instregex "LDRLIT_ga_pcrel_ldr")>;
530
531   // 4.2.26 Branch
532   def : WriteRes<WriteBr, [SwiftUnitP1]> { let Latency = 0; }
533   def : WriteRes<WriteBrL, [SwiftUnitP1]> { let Latency = 2; }
534   def : WriteRes<WriteBrTbl, [SwiftUnitP1, SwiftUnitP2]> { let Latency = 0; }
535
536   // 4.2.27 Not issued
537   def : WriteRes<WriteNoop, []> { let Latency = 0; let NumMicroOps = 0; }
538   def : InstRW<[WriteNoop], (instregex "t2IT", "IT", "NOP")>;
539
540   // 4.2.28 Advanced SIMD, Integer, 2 cycle
541   def : InstRW<[SwiftWriteP0TwoCycle],
542         (instregex "VADDv", "VSUBv", "VNEG(s|f|v)", "VADDL", "VSUBL",
543                    "VADDW", "VSUBW", "VHADD", "VHSUB", "VRHADD", "VPADDi",
544                    "VPADDL", "VAND", "VBIC", "VEOR", "VORN", "VORR", "VTST",
545                    "VSHL", "VSHR(s|u)", "VSHLL", "VQSHL", "VQSHLU", "VBIF",
546                    "VBIT", "VBSL", "VSLI", "VSRI", "VCLS", "VCLZ", "VCNT")>;
547
548   def : InstRW<[SwiftWriteP1TwoCycle],
549         (instregex "VEXT", "VREV16", "VREV32", "VREV64")>;
550
551   // 4.2.29 Advanced SIMD, Integer, 4 cycle
552   // 4.2.30 Advanced SIMD, Integer with Accumulate
553   def : InstRW<[SwiftWriteP0FourCycle],
554         (instregex "VABA", "VABAL", "VPADAL", "VRSRA", "VSRA", "VACGE", "VACGT",
555         "VACLE", "VACLT", "VCEQ", "VCGE", "VCGT", "VCLE", "VCLT", "VRSHL",
556         "VQRSHL", "VRSHR(u|s)", "VABS(f|v)", "VQABS", "VQNEG", "VQADD",
557         "VQSUB")>;
558   def : InstRW<[SwiftWriteP1FourCycle],
559         (instregex "VRECPE", "VRSQRTE")>;
560
561   // 4.2.31 Advanced SIMD, Add and Shift with Narrow
562   def : InstRW<[SwiftWriteP0P1FourCycle],
563         (instregex "VADDHN", "VSUBHN", "VSHRN")>;
564   def : InstRW<[SwiftWriteP0P1SixCycle],
565         (instregex "VRADDHN", "VRSUBHN", "VRSHRN", "VQSHRN", "VQSHRUN",
566                    "VQRSHRN", "VQRSHRUN")>;
567
568   // 4.2.32 Advanced SIMD, Vector Table Lookup
569   foreach Num = 1-4 in {
570     def SwiftWrite#Num#xP1TwoCycle : WriteSequence<[SwiftWriteP1TwoCycle], Num>;
571   }
572   def : InstRW<[SwiftWrite1xP1TwoCycle],
573         (instregex "VTB(L|X)1")>;
574   def : InstRW<[SwiftWrite2xP1TwoCycle],
575         (instregex "VTB(L|X)2")>;
576   def : InstRW<[SwiftWrite3xP1TwoCycle],
577         (instregex "VTB(L|X)3")>;
578   def : InstRW<[SwiftWrite4xP1TwoCycle],
579         (instregex "VTB(L|X)4")>;
580
581   // 4.2.33 Advanced SIMD, Transpose
582   def : InstRW<[SwiftWriteP1FourCycle, SwiftWriteP1FourCycle,
583                 SwiftWriteP1TwoCycle/*RsrcOnly*/, SchedReadAdvance<2>],
584         (instregex "VSWP", "VTRN", "VUZP", "VZIP")>;
585
586   // 4.2.34 Advanced SIMD and VFP, Floating Point
587   def : InstRW<[SwiftWriteP0TwoCycle], (instregex "VABS(S|D)$", "VNEG(S|D)$")>;
588   def : InstRW<[SwiftWriteP0FourCycle],
589         (instregex "VCMP(D|S|ZD|ZS)$", "VCMPE(D|S|ZD|ZS)")>;
590   def : InstRW<[SwiftWriteP0FourCycle],
591         (instregex "VADD(S|f)", "VSUB(S|f)", "VABD", "VPADDf", "VMAX", "VMIN", "VPMAX",
592                    "VPMIN")>;
593   def : InstRW<[SwiftWriteP0SixCycle], (instregex "VADDD$", "VSUBD$")>;
594   def : InstRW<[SwiftWriteP1EightCycle], (instregex "VRECPS", "VRSQRTS")>;
595
596   // 4.2.35 Advanced SIMD and VFP, Multiply
597   def : InstRW<[SwiftWriteP1FourCycle],
598         (instregex "VMUL(S|v|p|f|s)", "VNMULS", "VQDMULH", "VQRDMULH",
599                    "VMULL", "VQDMULL")>;
600   def : InstRW<[SwiftWriteP1SixCycle],
601         (instregex "VMULD", "VNMULD")>;
602   def : InstRW<[SwiftWriteP1FourCycle],
603         (instregex "VMLA", "VMLS", "VNMLA", "VNMLS", "VFMA(S|D)", "VFMS(S|D)",
604         "VFNMA", "VFNMS", "VMLAL", "VMLSL","VQDMLAL", "VQDMLSL")>;
605   def : InstRW<[SwiftWriteP1EightCycle], (instregex "VFMAfd", "VFMSfd")>;
606   def : InstRW<[SwiftWriteP1TwelveCyc], (instregex "VFMAfq", "VFMSfq")>;
607
608   // 4.2.36 Advanced SIMD and VFP, Convert
609   def : InstRW<[SwiftWriteP1FourCycle], (instregex "VCVT", "V(S|U)IT", "VTO(S|U)")>;
610   // Fixpoint conversions.
611   def : WriteRes<WriteCvtFP, [SwiftUnitP1]> { let Latency = 4; }
612
613   // 4.2.37 Advanced SIMD and VFP, Move
614   def : InstRW<[SwiftWriteP0TwoCycle],
615         (instregex "VMOVv", "VMOV(S|D)$", "VMOV(S|D)cc",
616                    "VMVNv", "VMVN(d|q)", "VMVN(S|D)cc",
617                    "FCONST(D|S)")>;
618   def : InstRW<[SwiftWriteP1TwoCycle], (instregex "VMOVN", "VMOVL")>;
619   def : InstRW<[WriteSequence<[SwiftWriteP0FourCycle, SwiftWriteP1TwoCycle]>],
620         (instregex "VQMOVN")>;
621   def : InstRW<[SwiftWriteP1TwoCycle], (instregex "VDUPLN", "VDUPf")>;
622   def : InstRW<[WriteSequence<[SwiftWriteP2FourCycle, SwiftWriteP1TwoCycle]>],
623         (instregex "VDUP(8|16|32)")>;
624   def : InstRW<[SwiftWriteP2ThreeCycle], (instregex "VMOVRS$")>;
625   def : InstRW<[WriteSequence<[SwiftWriteP2FourCycle, SwiftWriteP0TwoCycle]>],
626         (instregex "VMOVSR$", "VSETLN")>;
627   def : InstRW<[SwiftWriteP2ThreeCycle, SwiftWriteP2FourCycle],
628         (instregex "VMOVRR(D|S)$")>;
629   def : InstRW<[SwiftWriteP2FourCycle], (instregex "VMOVDRR$")>;
630   def : InstRW<[WriteSequence<[SwiftWriteP2FourCycle, SwiftWriteP1TwoCycle]>,
631                 WriteSequence<[SwiftWrite1Cycle, SwiftWriteP2FourCycle,
632                                SwiftWriteP1TwoCycle]>],
633                 (instregex "VMOVSRR$")>;
634   def : InstRW<[WriteSequence<[SwiftWriteP1TwoCycle, SwiftWriteP2ThreeCycle]>],
635         (instregex "VGETLN(u|i)")>;
636   def : InstRW<[WriteSequence<[SwiftWriteP1TwoCycle, SwiftWriteP2ThreeCycle,
637                                SwiftWriteP01OneCycle]>],
638         (instregex "VGETLNs")>;
639
640   // 4.2.38 Advanced SIMD and VFP, Move FPSCR
641   // Serializing instructions.
642   def SwiftWaitP0For15Cy : SchedWriteRes<[SwiftUnitP0]> {
643     let Latency = 15;
644     let ResourceCycles = [15];
645   }
646   def SwiftWaitP1For15Cy : SchedWriteRes<[SwiftUnitP1]> {
647     let Latency = 15;
648     let ResourceCycles = [15];
649   }
650   def SwiftWaitP2For15Cy : SchedWriteRes<[SwiftUnitP2]> {
651     let Latency = 15;
652     let ResourceCycles = [15];
653   }
654   def : InstRW<[SwiftWaitP0For15Cy, SwiftWaitP1For15Cy, SwiftWaitP2For15Cy],
655         (instregex "VMRS")>;
656   def : InstRW<[SwiftWaitP0For15Cy, SwiftWaitP1For15Cy, SwiftWaitP2For15Cy],
657         (instregex "VMSR")>;
658   // Not serializing.
659   def : InstRW<[SwiftWriteP0TwoCycle], (instregex "FMSTAT")>;
660
661   // 4.2.39 Advanced SIMD and VFP, Load Single Element
662   def : InstRW<[SwiftWriteLM4Cy], (instregex "VLDRD$", "VLDRS$")>;
663
664   // 4.2.40 Advanced SIMD and VFP, Store Single Element
665   def : InstRW<[SwiftWriteLM4Cy], (instregex "VSTRD$", "VSTRS$")>;
666
667   // 4.2.41 Advanced SIMD and VFP, Load Multiple
668   // 4.2.42 Advanced SIMD and VFP, Store Multiple
669
670   // Resource requirement for permuting, just reserves the resources.
671   foreach Num = 1-28 in {
672     def SwiftVLDMPerm#Num : SchedWriteRes<[SwiftUnitP1]> {
673       let Latency = 0;
674       let NumMicroOps = Num;
675       let ResourceCycles = [Num];
676     }
677   }
678
679   // Pre RA pseudos - load/store to a Q register as a D register pair.
680   def : InstRW<[SwiftWriteLM4Cy], (instregex "VLDMQIA$", "VSTMQIA$")>;
681
682   // Post RA not modelled accurately. We assume that register use of width 64
683   // bit maps to a D register, 128 maps to a Q register. Not all different kinds
684   // are accurately represented.
685   def SwiftWriteVLDM : SchedWriteVariant<[
686     // Load of one S register.
687     SchedVar<SwiftLMAddr1Pred, [SwiftWriteLM4Cy]>,
688     // Load of one D register.
689     SchedVar<SwiftLMAddr2Pred, [SwiftWriteLM4Cy, SwiftWriteLM4CyNo]>,
690     // Load of 3 S register.
691     SchedVar<SwiftLMAddr3Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
692                                 SwiftWriteLM13CyNo, SwiftWriteP01OneCycle,
693                                 SwiftVLDMPerm3]>,
694     // Load of a Q register (not necessarily true). We should not be mapping to
695     // 4 S registers, either.
696     SchedVar<SwiftLMAddr4Pred, [SwiftWriteLM4Cy, SwiftWriteLM4CyNo,
697                                 SwiftWriteLM4CyNo, SwiftWriteLM4CyNo]>,
698     // Load of 5 S registers.
699     SchedVar<SwiftLMAddr5Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
700                                 SwiftWriteLM13CyNo, SwiftWriteLM14CyNo,
701                                 SwiftWriteLM17CyNo,  SwiftWriteP01OneCycle,
702                                 SwiftVLDMPerm5]>,
703     // Load of 3 D registers. (Must also be able to handle s register list -
704     // though, not accurate)
705     SchedVar<SwiftLMAddr6Pred, [SwiftWriteLM7Cy, SwiftWriteLM8Cy,
706                                 SwiftWriteLM10Cy, SwiftWriteLM14CyNo,
707                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
708                                 SwiftWriteP01OneCycle, SwiftVLDMPerm5]>,
709     // Load of 7 S registers.
710     SchedVar<SwiftLMAddr7Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
711                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
712                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
713                                 SwiftWriteLM21CyNo, SwiftWriteP01OneCycle,
714                                 SwiftVLDMPerm7]>,
715     // Load of two Q registers.
716     SchedVar<SwiftLMAddr8Pred, [SwiftWriteLM7Cy, SwiftWriteLM8Cy,
717                                 SwiftWriteLM13Cy, SwiftWriteLM13CyNo,
718                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
719                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
720                                 SwiftWriteP01OneCycle,  SwiftVLDMPerm2]>,
721     // Load of 9 S registers.
722     SchedVar<SwiftLMAddr9Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
723                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
724                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
725                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
726                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
727                                 SwiftVLDMPerm9]>,
728     // Load of 5 D registers.
729     SchedVar<SwiftLMAddr10Pred,[SwiftWriteLM7Cy, SwiftWriteLM8Cy,
730                                 SwiftWriteLM10Cy, SwiftWriteLM14Cy,
731                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
732                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
733                                 SwiftWriteLM14CyNo,  SwiftWriteLM14CyNo,
734                                 SwiftWriteP01OneCycle, SwiftVLDMPerm5]>,
735     // Inaccurate: reuse describtion from 9 S registers.
736     SchedVar<SwiftLMAddr11Pred,[SwiftWriteLM9Cy, SwiftWriteLM10Cy,
737                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
738                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
739                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
740                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
741                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
742                                 SwiftVLDMPerm9]>,
743     // Load of three Q registers.
744     SchedVar<SwiftLMAddr12Pred,[SwiftWriteLM7Cy, SwiftWriteLM8Cy,
745                                 SwiftWriteLM11Cy, SwiftWriteLM11Cy,
746                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
747                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
748                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
749                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
750                                 SwiftWriteP01OneCycle, SwiftVLDMPerm3]>,
751     // Inaccurate: reuse describtion from 9 S registers.
752     SchedVar<SwiftLMAddr13Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
753                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
754                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
755                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
756                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
757                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
758                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
759                                 SwiftVLDMPerm9]>,
760     // Load of 7 D registers inaccurate.
761     SchedVar<SwiftLMAddr14Pred,[SwiftWriteLM7Cy, SwiftWriteLM8Cy,
762                                 SwiftWriteLM10Cy, SwiftWriteLM14Cy,
763                                 SwiftWriteLM14Cy, SwiftWriteLM14CyNo,
764                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
765                                 SwiftWriteLM14CyNo,  SwiftWriteLM14CyNo,
766                                 SwiftWriteLM14CyNo,  SwiftWriteLM14CyNo,
767                                 SwiftWriteP01OneCycle, SwiftVLDMPerm7]>,
768     SchedVar<SwiftLMAddr15Pred,[SwiftWriteLM9Cy, SwiftWriteLM10Cy,
769                                 SwiftWriteLM13Cy, SwiftWriteLM14Cy,
770                                 SwiftWriteLM17Cy, SwiftWriteLM18CyNo,
771                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
772                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
773                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
774                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
775                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
776                                 SwiftVLDMPerm9]>,
777     // Load of 4 Q registers.
778     SchedVar<SwiftLMAddr16Pred,[SwiftWriteLM7Cy, SwiftWriteLM10Cy,
779                                 SwiftWriteLM11Cy, SwiftWriteLM14Cy,
780                                 SwiftWriteLM15Cy, SwiftWriteLM18CyNo,
781                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
782                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
783                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
784                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
785                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
786                                 SwiftWriteP01OneCycle, SwiftVLDMPerm4]>,
787     // Unknow number of registers, just use resources for two registers.
788     SchedVar<NoSchedPred,      [SwiftWriteLM7Cy, SwiftWriteLM8Cy,
789                                 SwiftWriteLM13Cy, SwiftWriteLM13CyNo,
790                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
791                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
792                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
793                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
794                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
795                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
796                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
797                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
798                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
799                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
800                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
801                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
802                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
803                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
804                                 SwiftWriteP01OneCycle,  SwiftVLDMPerm2]>
805   ]> { let Variadic = 1; }
806
807   def : InstRW<[SwiftWriteVLDM], (instregex "VLDM[SD](IA|DB)$")>;
808
809   def : InstRW<[SwiftWriteP01OneCycle2x, SwiftWriteVLDM],
810         (instregex "VLDM[SD](IA|DB)_UPD$")>;
811
812   def SwiftWriteVSTM : SchedWriteVariant<[
813     // One S register.
814     SchedVar<SwiftLMAddr1Pred, [SwiftWriteSTM1]>,
815     // One D register.
816     SchedVar<SwiftLMAddr2Pred, [SwiftWriteSTM1]>,
817     // Three S registers.
818     SchedVar<SwiftLMAddr3Pred, [SwiftWriteSTM4]>,
819     // Assume one Q register.
820     SchedVar<SwiftLMAddr4Pred, [SwiftWriteSTM1]>,
821     SchedVar<SwiftLMAddr5Pred, [SwiftWriteSTM6]>,
822     // Assume three D registers.
823     SchedVar<SwiftLMAddr6Pred, [SwiftWriteSTM4]>,
824     SchedVar<SwiftLMAddr7Pred, [SwiftWriteSTM8]>,
825     // Assume two Q registers.
826     SchedVar<SwiftLMAddr8Pred, [SwiftWriteSTM3]>,
827     SchedVar<SwiftLMAddr9Pred, [SwiftWriteSTM10]>,
828     // Assume 5 D registers.
829     SchedVar<SwiftLMAddr10Pred, [SwiftWriteSTM6]>,
830     SchedVar<SwiftLMAddr11Pred, [SwiftWriteSTM12]>,
831     // Assume three Q registers.
832     SchedVar<SwiftLMAddr12Pred, [SwiftWriteSTM4]>,
833     SchedVar<SwiftLMAddr13Pred, [SwiftWriteSTM14]>,
834     // Assume 7 D registers.
835     SchedVar<SwiftLMAddr14Pred, [SwiftWriteSTM8]>,
836     SchedVar<SwiftLMAddr15Pred, [SwiftWriteSTM16]>,
837     // Assume four Q registers.
838     SchedVar<SwiftLMAddr16Pred, [SwiftWriteSTM5]>,
839     // Asumme two Q registers.
840     SchedVar<NoSchedPred, [SwiftWriteSTM3]>
841   ]> { let Variadic = 1; }
842
843   def : InstRW<[SwiftWriteVSTM], (instregex "VSTM[SD](IA|DB)$")>;
844
845   def : InstRW<[SwiftWriteP01OneCycle2x, SwiftWriteVSTM],
846         (instregex "VSTM[SD](IA|DB)_UPD")>;
847
848   // 4.2.43 Advanced SIMD, Element or Structure Load and Store
849   def SwiftWrite2xP2FourCy : SchedWriteRes<[SwiftUnitP2]> {
850       let Latency = 4;
851       let ResourceCycles = [2];
852   }
853   def SwiftWrite3xP2FourCy : SchedWriteRes<[SwiftUnitP2]> {
854       let Latency = 4;
855       let ResourceCycles = [3];
856   }
857   foreach Num = 1-2 in {
858     def SwiftExt#Num#xP0 : SchedWriteRes<[SwiftUnitP0]> {
859       let Latency = 0;
860       let NumMicroOps = Num;
861       let ResourceCycles = [Num];
862     }
863   }
864   // VLDx
865   // Multiple structures.
866   // Single element structure loads.
867   // We assume aligned.
868   // Single/two register.
869   def : InstRW<[SwiftWriteLM4Cy], (instregex "VLD1(d|q)(8|16|32|64)$")>;
870   def : InstRW<[SwiftWriteLM4Cy, SwiftWriteP01OneCycle],
871         (instregex "VLD1(d|q)(8|16|32|64)wb")>;
872   // Three register.
873   def : InstRW<[SwiftWrite3xP2FourCy],
874         (instregex "VLD1(d|q)(8|16|32|64)T$", "VLD1d64TPseudo")>;
875   def : InstRW<[SwiftWrite3xP2FourCy, SwiftWriteP01OneCycle],
876         (instregex "VLD1(d|q)(8|16|32|64)Twb")>;
877   /// Four Register.
878   def : InstRW<[SwiftWrite2xP2FourCy],
879         (instregex "VLD1(d|q)(8|16|32|64)Q$", "VLD1d64QPseudo")>;
880   def : InstRW<[SwiftWrite2xP2FourCy, SwiftWriteP01OneCycle],
881         (instregex "VLD1(d|q)(8|16|32|64)Qwb")>;
882   // Two element structure loads.
883   // Two/four register.
884   def : InstRW<[SwiftWriteLM9Cy, SwiftExt2xP0, SwiftVLDMPerm2],
885         (instregex "VLD2(d|q|b)(8|16|32)$", "VLD2q(8|16|32)Pseudo$")>;
886   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteP01OneCycle, SwiftExt2xP0,
887                 SwiftVLDMPerm2],
888         (instregex "VLD2(d|q|b)(8|16|32)wb", "VLD2q(8|16|32)PseudoWB")>;
889   // Three element structure.
890   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteLM9CyNo, SwiftWriteLM9CyNo,
891                 SwiftVLDMPerm3, SwiftWrite3xP2FourCy],
892         (instregex "VLD3(d|q)(8|16|32)$")>;
893   def : InstRW<[SwiftWriteLM9Cy, SwiftVLDMPerm3, SwiftWrite3xP2FourCy],
894         (instregex "VLD3(d|q)(8|16|32)(oddP|P)seudo$")>;
895
896   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteLM9CyNo, SwiftWriteLM9CyNo,
897                 SwiftWriteP01OneCycle, SwiftVLDMPerm3, SwiftWrite3xP2FourCy],
898         (instregex "VLD3(d|q)(8|16|32)_UPD$")>;
899   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteP01OneCycle, SwiftVLDMPerm3,
900                 SwiftWrite3xP2FourCy],
901         (instregex "VLD3(d|q)(8|16|32)(oddP|P)seudo_UPD")>;
902   // Four element structure loads.
903   def : InstRW<[SwiftWriteLM11Cy, SwiftWriteLM11Cy, SwiftWriteLM11Cy,
904                 SwiftWriteLM11Cy, SwiftExt2xP0, SwiftVLDMPerm4,
905                 SwiftWrite3xP2FourCy],
906         (instregex "VLD4(d|q)(8|16|32)$")>;
907   def : InstRW<[SwiftWriteLM11Cy,  SwiftExt2xP0, SwiftVLDMPerm4,
908                 SwiftWrite3xP2FourCy],
909         (instregex "VLD4(d|q)(8|16|32)(oddP|P)seudo$")>;
910   def : InstRW<[SwiftWriteLM11Cy, SwiftWriteLM11Cy, SwiftWriteLM11Cy,
911                 SwiftWriteLM11Cy, SwiftWriteP01OneCycle, SwiftExt2xP0,
912                 SwiftVLDMPerm4, SwiftWrite3xP2FourCy],
913         (instregex "VLD4(d|q)(8|16|32)_UPD")>;
914   def : InstRW<[SwiftWriteLM11Cy, SwiftWriteP01OneCycle, SwiftExt2xP0,
915                 SwiftVLDMPerm4, SwiftWrite3xP2FourCy],
916         (instregex  "VLD4(d|q)(8|16|32)(oddP|P)seudo_UPD")>;
917
918   // Single all/lane loads.
919   // One element structure.
920   def : InstRW<[SwiftWriteLM6Cy, SwiftVLDMPerm2],
921         (instregex "VLD1(LN|DUP)(d|q)(8|16|32)$", "VLD1(LN|DUP)(d|q)(8|16|32)Pseudo$")>;
922   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteP01OneCycle, SwiftVLDMPerm2],
923         (instregex "VLD1(LN|DUP)(d|q)(8|16|32)(wb|_UPD)",
924                   "VLD1LNq(8|16|32)Pseudo_UPD")>;
925   // Two element structure.
926   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteLM6Cy, SwiftExt1xP0, SwiftVLDMPerm2],
927         (instregex "VLD2(DUP|LN)(d|q)(8|16|32|8x2|16x2|32x2)$",
928                    "VLD2LN(d|q)(8|16|32)Pseudo$")>;
929   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteLM6Cy, SwiftWriteP01OneCycle,
930                 SwiftExt1xP0, SwiftVLDMPerm2],
931         (instregex "VLD2LN(d|q)(8|16|32)_UPD$")>;
932   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteP01OneCycle, SwiftWriteLM6Cy,
933                 SwiftExt1xP0, SwiftVLDMPerm2],
934         (instregex "VLD2DUPd(8|16|32|8x2|16x2|32x2)wb")>;
935   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteP01OneCycle, SwiftWriteLM6Cy,
936                 SwiftExt1xP0, SwiftVLDMPerm2],
937         (instregex "VLD2LN(d|q)(8|16|32)Pseudo_UPD")>;
938   // Three element structure.
939   def : InstRW<[SwiftWriteLM7Cy, SwiftWriteLM8Cy, SwiftWriteLM8Cy, SwiftExt1xP0,
940                 SwiftVLDMPerm3],
941         (instregex "VLD3(DUP|LN)(d|q)(8|16|32)$",
942                    "VLD3(LN|DUP)(d|q)(8|16|32)Pseudo$")>;
943   def : InstRW<[SwiftWriteLM7Cy, SwiftWriteLM8Cy, SwiftWriteLM8Cy,
944                 SwiftWriteP01OneCycle, SwiftExt1xP0, SwiftVLDMPerm3],
945         (instregex "VLD3(LN|DUP)(d|q)(8|16|32)_UPD")>;
946   def : InstRW<[SwiftWriteLM7Cy, SwiftWriteP01OneCycle, SwiftWriteLM8Cy,
947                 SwiftWriteLM8Cy, SwiftExt1xP0, SwiftVLDMPerm3],
948         (instregex "VLD3(LN|DUP)(d|q)(8|16|32)Pseudo_UPD")>;
949   // Four element struture.
950   def : InstRW<[SwiftWriteLM8Cy, SwiftWriteLM9Cy, SwiftWriteLM10CyNo,
951                 SwiftWriteLM10CyNo, SwiftExt1xP0, SwiftVLDMPerm5],
952         (instregex "VLD4(LN|DUP)(d|q)(8|16|32)$",
953                    "VLD4(LN|DUP)(d|q)(8|16|32)Pseudo$")>;
954   def : InstRW<[SwiftWriteLM8Cy, SwiftWriteLM9Cy, SwiftWriteLM10CyNo,
955                 SwiftWriteLM10CyNo, SwiftWriteP01OneCycle, SwiftExt1xP0,
956                 SwiftVLDMPerm5],
957         (instregex "VLD4(DUP|LN)(d|q)(8|16|32)_UPD")>;
958   def : InstRW<[SwiftWriteLM8Cy, SwiftWriteP01OneCycle, SwiftWriteLM9Cy,
959                 SwiftWriteLM10CyNo, SwiftWriteLM10CyNo, SwiftExt1xP0,
960                 SwiftVLDMPerm5],
961         (instregex "VLD4(DUP|LN)(d|q)(8|16|32)Pseudo_UPD")>;
962   // VSTx
963   // Multiple structures.
964   // Single element structure store.
965   def : InstRW<[SwiftWrite1xP2], (instregex "VST1d(8|16|32|64)$")>;
966   def : InstRW<[SwiftWrite2xP2], (instregex "VST1q(8|16|32|64)$")>;
967   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2],
968         (instregex "VST1d(8|16|32|64)wb")>;
969   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite2xP2],
970         (instregex "VST1q(8|16|32|64)wb")>;
971   def : InstRW<[SwiftWrite3xP2],
972         (instregex "VST1d(8|16|32|64)T$", "VST1d64TPseudo$")>;
973   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite3xP2],
974         (instregex "VST1d(8|16|32|64)Twb", "VST1d64TPseudoWB")>;
975   def : InstRW<[SwiftWrite4xP2],
976         (instregex "VST1d(8|16|32|64)(Q|QPseudo)$")>;
977   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2],
978         (instregex "VST1d(8|16|32|64)(Qwb|QPseudoWB)")>;
979   // Two element structure store.
980   def : InstRW<[SwiftWrite1xP2, SwiftVLDMPerm1],
981         (instregex "VST2(d|b)(8|16|32)$")>;
982   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2, SwiftVLDMPerm1],
983         (instregex "VST2(b|d)(8|16|32)wb")>;
984   def : InstRW<[SwiftWrite2xP2, SwiftVLDMPerm2],
985         (instregex "VST2q(8|16|32)$", "VST2q(8|16|32)Pseudo$")>;
986   def : InstRW<[SwiftWrite2xP2, SwiftVLDMPerm2],
987         (instregex "VST2q(8|16|32)wb", "VST2q(8|16|32)PseudoWB")>;
988   // Three element structure store.
989   def : InstRW<[SwiftWrite4xP2, SwiftVLDMPerm2],
990         (instregex "VST3(d|q)(8|16|32)$", "VST3(d|q)(8|16|32)(oddP|P)seudo$")>;
991   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2, SwiftVLDMPerm2],
992         (instregex "VST3(d|q)(8|16|32)_UPD",
993                    "VST3(d|q)(8|16|32)(oddP|P)seudo_UPD$")>;
994   // Four element structure store.
995   def : InstRW<[SwiftWrite4xP2, SwiftVLDMPerm2],
996         (instregex "VST4(d|q)(8|16|32)$", "VST4(d|q)(8|16|32)(oddP|P)seudo$")>;
997   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2, SwiftVLDMPerm4],
998         (instregex "VST4(d|q)(8|16|32)_UPD",
999                    "VST4(d|q)(8|16|32)(oddP|P)seudo_UPD$")>;
1000   // Single/all lane store.
1001   // One element structure.
1002   def : InstRW<[SwiftWrite1xP2, SwiftVLDMPerm1],
1003         (instregex "VST1LNd(8|16|32)$", "VST1LNq(8|16|32)Pseudo$")>;
1004   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2, SwiftVLDMPerm1],
1005         (instregex "VST1LNd(8|16|32)_UPD", "VST1LNq(8|16|32)Pseudo_UPD")>;
1006   // Two element structure.
1007   def : InstRW<[SwiftWrite1xP2, SwiftVLDMPerm2],
1008         (instregex "VST2LN(d|q)(8|16|32)$", "VST2LN(d|q)(8|16|32)Pseudo$")>;
1009   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2, SwiftVLDMPerm2],
1010         (instregex "VST2LN(d|q)(8|16|32)_UPD",
1011                    "VST2LN(d|q)(8|16|32)Pseudo_UPD")>;
1012   // Three element structure.
1013   def : InstRW<[SwiftWrite4xP2, SwiftVLDMPerm2],
1014         (instregex "VST3LN(d|q)(8|16|32)$", "VST3LN(d|q)(8|16|32)Pseudo$")>;
1015   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2, SwiftVLDMPerm2],
1016         (instregex "VST3LN(d|q)(8|16|32)_UPD",
1017                    "VST3LN(d|q)(8|16|32)Pseudo_UPD")>;
1018   // Four element structure.
1019   def : InstRW<[SwiftWrite2xP2, SwiftVLDMPerm2],
1020         (instregex "VST4LN(d|q)(8|16|32)$", "VST4LN(d|q)(8|16|32)Pseudo$")>;
1021   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite2xP2, SwiftVLDMPerm2],
1022         (instregex "VST4LN(d|q)(8|16|32)_UPD",
1023                    "VST4LN(d|q)(8|16|32)Pseudo_UPD")>;
1024
1025   // 4.2.44 VFP, Divide and Square Root
1026   def SwiftDiv17 : SchedWriteRes<[SwiftUnitP0, SwiftUnitDiv]> {
1027     let NumMicroOps = 1;
1028     let Latency = 17;
1029     let ResourceCycles = [1, 15];
1030   }
1031   def SwiftDiv32 : SchedWriteRes<[SwiftUnitP0, SwiftUnitDiv]> {
1032     let NumMicroOps = 1;
1033     let Latency = 32;
1034     let ResourceCycles = [1, 30];
1035   }
1036   def : InstRW<[SwiftDiv17], (instregex "VDIVS", "VSQRTS")>;
1037   def : InstRW<[SwiftDiv32], (instregex "VDIVD", "VSQRTD")>;
1038
1039   // Not specified.
1040   def : InstRW<[SwiftWriteP01OneCycle2x], (instregex "ABS")>;
1041   // Preload.
1042   def : WriteRes<WritePreLd, [SwiftUnitP2]> { let Latency = 0;
1043     let ResourceCycles = [0];
1044   }
1045
1046 }