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