ARM: cleanup formatting
[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   // LDRLIT pseudo instructions, they expand to LDR + PICADD
524   def : InstRW<[SwiftWriteP2ThreeCycle, WriteALU],
525         (instregex "t?LDRLIT_ga_abs", "t?LDRLIT_ga_pcrel")>;
526   // LDRLIT_ga_pcrel_ldr expands to LDR + PICLDR
527   def : InstRW<[SwiftWriteP2ThreeCycle, SwiftWriteP2ThreeCycle],
528         (instregex "LDRLIT_ga_pcrel_ldr")>;
529
530   // 4.2.26 Branch
531   def : WriteRes<WriteBr, [SwiftUnitP1]> { let Latency = 0; }
532   def : WriteRes<WriteBrL, [SwiftUnitP1]> { let Latency = 2; }
533   def : WriteRes<WriteBrTbl, [SwiftUnitP1, SwiftUnitP2]> { let Latency = 0; }
534
535   // 4.2.27 Not issued
536   def : WriteRes<WriteNoop, []> { let Latency = 0; let NumMicroOps = 0; }
537   def : InstRW<[WriteNoop], (instregex "t2IT", "IT", "NOP")>;
538
539   // 4.2.28 Advanced SIMD, Integer, 2 cycle
540   def : InstRW<[SwiftWriteP0TwoCycle],
541         (instregex "VADDv", "VSUBv", "VNEG(s|f|v)", "VADDL", "VSUBL",
542                    "VADDW", "VSUBW", "VHADD", "VHSUB", "VRHADD", "VPADDi",
543                    "VPADDL", "VAND", "VBIC", "VEOR", "VORN", "VORR", "VTST",
544                    "VSHL", "VSHR(s|u)", "VSHLL", "VQSHL", "VQSHLU", "VBIF",
545                    "VBIT", "VBSL", "VSLI", "VSRI", "VCLS", "VCLZ", "VCNT")>;
546
547   def : InstRW<[SwiftWriteP1TwoCycle],
548         (instregex "VEXT", "VREV16", "VREV32", "VREV64")>;
549
550   // 4.2.29 Advanced SIMD, Integer, 4 cycle
551   // 4.2.30 Advanced SIMD, Integer with Accumulate
552   def : InstRW<[SwiftWriteP0FourCycle],
553         (instregex "VABA", "VABAL", "VPADAL", "VRSRA", "VSRA", "VACGE", "VACGT",
554         "VACLE", "VACLT", "VCEQ", "VCGE", "VCGT", "VCLE", "VCLT", "VRSHL",
555         "VQRSHL", "VRSHR(u|s)", "VABS(f|v)", "VQABS", "VQNEG", "VQADD",
556         "VQSUB")>;
557   def : InstRW<[SwiftWriteP1FourCycle],
558         (instregex "VRECPE", "VRSQRTE")>;
559
560   // 4.2.31 Advanced SIMD, Add and Shift with Narrow
561   def : InstRW<[SwiftWriteP0P1FourCycle],
562         (instregex "VADDHN", "VSUBHN", "VSHRN")>;
563   def : InstRW<[SwiftWriteP0P1SixCycle],
564         (instregex "VRADDHN", "VRSUBHN", "VRSHRN", "VQSHRN", "VQSHRUN",
565                    "VQRSHRN", "VQRSHRUN")>;
566
567   // 4.2.32 Advanced SIMD, Vector Table Lookup
568   foreach Num = 1-4 in {
569     def SwiftWrite#Num#xP1TwoCycle : WriteSequence<[SwiftWriteP1TwoCycle], Num>;
570   }
571   def : InstRW<[SwiftWrite1xP1TwoCycle],
572         (instregex "VTB(L|X)1")>;
573   def : InstRW<[SwiftWrite2xP1TwoCycle],
574         (instregex "VTB(L|X)2")>;
575   def : InstRW<[SwiftWrite3xP1TwoCycle],
576         (instregex "VTB(L|X)3")>;
577   def : InstRW<[SwiftWrite4xP1TwoCycle],
578         (instregex "VTB(L|X)4")>;
579
580   // 4.2.33 Advanced SIMD, Transpose
581   def : InstRW<[SwiftWriteP1FourCycle, SwiftWriteP1FourCycle,
582                 SwiftWriteP1TwoCycle/*RsrcOnly*/, SchedReadAdvance<2>],
583         (instregex "VSWP", "VTRN", "VUZP", "VZIP")>;
584
585   // 4.2.34 Advanced SIMD and VFP, Floating Point
586   def : InstRW<[SwiftWriteP0TwoCycle], (instregex "VABS(S|D)$", "VNEG(S|D)$")>;
587   def : InstRW<[SwiftWriteP0FourCycle],
588         (instregex "VCMP(D|S|ZD|ZS)$", "VCMPE(D|S|ZD|ZS)")>;
589   def : InstRW<[SwiftWriteP0FourCycle],
590         (instregex "VADD(S|f)", "VSUB(S|f)", "VABD", "VPADDf", "VMAX", "VMIN", "VPMAX",
591                    "VPMIN")>;
592   def : InstRW<[SwiftWriteP0SixCycle], (instregex "VADDD$", "VSUBD$")>;
593   def : InstRW<[SwiftWriteP1EightCycle], (instregex "VRECPS", "VRSQRTS")>;
594
595   // 4.2.35 Advanced SIMD and VFP, Multiply
596   def : InstRW<[SwiftWriteP1FourCycle],
597         (instregex "VMUL(S|v|p|f|s)", "VNMULS", "VQDMULH", "VQRDMULH",
598                    "VMULL", "VQDMULL")>;
599   def : InstRW<[SwiftWriteP1SixCycle],
600         (instregex "VMULD", "VNMULD")>;
601   def : InstRW<[SwiftWriteP1FourCycle],
602         (instregex "VMLA", "VMLS", "VNMLA", "VNMLS", "VFMA(S|D)", "VFMS(S|D)",
603         "VFNMA", "VFNMS", "VMLAL", "VMLSL","VQDMLAL", "VQDMLSL")>;
604   def : InstRW<[SwiftWriteP1EightCycle], (instregex "VFMAfd", "VFMSfd")>;
605   def : InstRW<[SwiftWriteP1TwelveCyc], (instregex "VFMAfq", "VFMSfq")>;
606
607   // 4.2.36 Advanced SIMD and VFP, Convert
608   def : InstRW<[SwiftWriteP1FourCycle], (instregex "VCVT", "V(S|U)IT", "VTO(S|U)")>;
609   // Fixpoint conversions.
610   def : WriteRes<WriteCvtFP, [SwiftUnitP1]> { let Latency = 4; }
611
612   // 4.2.37 Advanced SIMD and VFP, Move
613   def : InstRW<[SwiftWriteP0TwoCycle],
614         (instregex "VMOVv", "VMOV(S|D)$", "VMOV(S|D)cc",
615                    "VMVNv", "VMVN(d|q)", "VMVN(S|D)cc",
616                    "FCONST(D|S)")>;
617   def : InstRW<[SwiftWriteP1TwoCycle], (instregex "VMOVN", "VMOVL")>;
618   def : InstRW<[WriteSequence<[SwiftWriteP0FourCycle, SwiftWriteP1TwoCycle]>],
619         (instregex "VQMOVN")>;
620   def : InstRW<[SwiftWriteP1TwoCycle], (instregex "VDUPLN", "VDUPf")>;
621   def : InstRW<[WriteSequence<[SwiftWriteP2FourCycle, SwiftWriteP1TwoCycle]>],
622         (instregex "VDUP(8|16|32)")>;
623   def : InstRW<[SwiftWriteP2ThreeCycle], (instregex "VMOVRS$")>;
624   def : InstRW<[WriteSequence<[SwiftWriteP2FourCycle, SwiftWriteP0TwoCycle]>],
625         (instregex "VMOVSR$", "VSETLN")>;
626   def : InstRW<[SwiftWriteP2ThreeCycle, SwiftWriteP2FourCycle],
627         (instregex "VMOVRR(D|S)$")>;
628   def : InstRW<[SwiftWriteP2FourCycle], (instregex "VMOVDRR$")>;
629   def : InstRW<[WriteSequence<[SwiftWriteP2FourCycle, SwiftWriteP1TwoCycle]>,
630                 WriteSequence<[SwiftWrite1Cycle, SwiftWriteP2FourCycle,
631                                SwiftWriteP1TwoCycle]>],
632                 (instregex "VMOVSRR$")>;
633   def : InstRW<[WriteSequence<[SwiftWriteP1TwoCycle, SwiftWriteP2ThreeCycle]>],
634         (instregex "VGETLN(u|i)")>;
635   def : InstRW<[WriteSequence<[SwiftWriteP1TwoCycle, SwiftWriteP2ThreeCycle,
636                                SwiftWriteP01OneCycle]>],
637         (instregex "VGETLNs")>;
638
639   // 4.2.38 Advanced SIMD and VFP, Move FPSCR
640   // Serializing instructions.
641   def SwiftWaitP0For15Cy : SchedWriteRes<[SwiftUnitP0]> {
642     let Latency = 15;
643     let ResourceCycles = [15];
644   }
645   def SwiftWaitP1For15Cy : SchedWriteRes<[SwiftUnitP1]> {
646     let Latency = 15;
647     let ResourceCycles = [15];
648   }
649   def SwiftWaitP2For15Cy : SchedWriteRes<[SwiftUnitP2]> {
650     let Latency = 15;
651     let ResourceCycles = [15];
652   }
653   def : InstRW<[SwiftWaitP0For15Cy, SwiftWaitP1For15Cy, SwiftWaitP2For15Cy],
654         (instregex "VMRS")>;
655   def : InstRW<[SwiftWaitP0For15Cy, SwiftWaitP1For15Cy, SwiftWaitP2For15Cy],
656         (instregex "VMSR")>;
657   // Not serializing.
658   def : InstRW<[SwiftWriteP0TwoCycle], (instregex "FMSTAT")>;
659
660   // 4.2.39 Advanced SIMD and VFP, Load Single Element
661   def : InstRW<[SwiftWriteLM4Cy], (instregex "VLDRD$", "VLDRS$")>;
662
663   // 4.2.40 Advanced SIMD and VFP, Store Single Element
664   def : InstRW<[SwiftWriteLM4Cy], (instregex "VSTRD$", "VSTRS$")>;
665
666   // 4.2.41 Advanced SIMD and VFP, Load Multiple
667   // 4.2.42 Advanced SIMD and VFP, Store Multiple
668
669   // Resource requirement for permuting, just reserves the resources.
670   foreach Num = 1-28 in {
671     def SwiftVLDMPerm#Num : SchedWriteRes<[SwiftUnitP1]> {
672       let Latency = 0;
673       let NumMicroOps = Num;
674       let ResourceCycles = [Num];
675     }
676   }
677
678   // Pre RA pseudos - load/store to a Q register as a D register pair.
679   def : InstRW<[SwiftWriteLM4Cy], (instregex "VLDMQIA$", "VSTMQIA$")>;
680
681   // Post RA not modelled accurately. We assume that register use of width 64
682   // bit maps to a D register, 128 maps to a Q register. Not all different kinds
683   // are accurately represented.
684   def SwiftWriteVLDM : SchedWriteVariant<[
685     // Load of one S register.
686     SchedVar<SwiftLMAddr1Pred, [SwiftWriteLM4Cy]>,
687     // Load of one D register.
688     SchedVar<SwiftLMAddr2Pred, [SwiftWriteLM4Cy, SwiftWriteLM4CyNo]>,
689     // Load of 3 S register.
690     SchedVar<SwiftLMAddr3Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
691                                 SwiftWriteLM13CyNo, SwiftWriteP01OneCycle,
692                                 SwiftVLDMPerm3]>,
693     // Load of a Q register (not necessarily true). We should not be mapping to
694     // 4 S registers, either.
695     SchedVar<SwiftLMAddr4Pred, [SwiftWriteLM4Cy, SwiftWriteLM4CyNo,
696                                 SwiftWriteLM4CyNo, SwiftWriteLM4CyNo]>,
697     // Load of 5 S registers.
698     SchedVar<SwiftLMAddr5Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
699                                 SwiftWriteLM13CyNo, SwiftWriteLM14CyNo,
700                                 SwiftWriteLM17CyNo,  SwiftWriteP01OneCycle,
701                                 SwiftVLDMPerm5]>,
702     // Load of 3 D registers. (Must also be able to handle s register list -
703     // though, not accurate)
704     SchedVar<SwiftLMAddr6Pred, [SwiftWriteLM7Cy, SwiftWriteLM8Cy,
705                                 SwiftWriteLM10Cy, SwiftWriteLM14CyNo,
706                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
707                                 SwiftWriteP01OneCycle, SwiftVLDMPerm5]>,
708     // Load of 7 S registers.
709     SchedVar<SwiftLMAddr7Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
710                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
711                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
712                                 SwiftWriteLM21CyNo, SwiftWriteP01OneCycle,
713                                 SwiftVLDMPerm7]>,
714     // Load of two Q registers.
715     SchedVar<SwiftLMAddr8Pred, [SwiftWriteLM7Cy, SwiftWriteLM8Cy,
716                                 SwiftWriteLM13Cy, SwiftWriteLM13CyNo,
717                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
718                                 SwiftWriteLM13CyNo, SwiftWriteLM13CyNo,
719                                 SwiftWriteP01OneCycle,  SwiftVLDMPerm2]>,
720     // Load of 9 S registers.
721     SchedVar<SwiftLMAddr9Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
722                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
723                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
724                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
725                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
726                                 SwiftVLDMPerm9]>,
727     // Load of 5 D registers.
728     SchedVar<SwiftLMAddr10Pred,[SwiftWriteLM7Cy, SwiftWriteLM8Cy,
729                                 SwiftWriteLM10Cy, SwiftWriteLM14Cy,
730                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
731                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
732                                 SwiftWriteLM14CyNo,  SwiftWriteLM14CyNo,
733                                 SwiftWriteP01OneCycle, SwiftVLDMPerm5]>,
734     // Inaccurate: reuse describtion from 9 S registers.
735     SchedVar<SwiftLMAddr11Pred,[SwiftWriteLM9Cy, SwiftWriteLM10Cy,
736                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
737                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
738                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
739                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
740                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
741                                 SwiftVLDMPerm9]>,
742     // Load of three Q registers.
743     SchedVar<SwiftLMAddr12Pred,[SwiftWriteLM7Cy, SwiftWriteLM8Cy,
744                                 SwiftWriteLM11Cy, SwiftWriteLM11Cy,
745                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
746                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
747                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
748                                 SwiftWriteLM11CyNo, SwiftWriteLM11CyNo,
749                                 SwiftWriteP01OneCycle, SwiftVLDMPerm3]>,
750     // Inaccurate: reuse describtion from 9 S registers.
751     SchedVar<SwiftLMAddr13Pred, [SwiftWriteLM9Cy, SwiftWriteLM10Cy,
752                                 SwiftWriteLM13Cy, SwiftWriteLM14CyNo,
753                                 SwiftWriteLM17CyNo, SwiftWriteLM18CyNo,
754                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
755                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
756                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
757                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
758                                 SwiftVLDMPerm9]>,
759     // Load of 7 D registers inaccurate.
760     SchedVar<SwiftLMAddr14Pred,[SwiftWriteLM7Cy, SwiftWriteLM8Cy,
761                                 SwiftWriteLM10Cy, SwiftWriteLM14Cy,
762                                 SwiftWriteLM14Cy, SwiftWriteLM14CyNo,
763                                 SwiftWriteLM14CyNo, SwiftWriteLM14CyNo,
764                                 SwiftWriteLM14CyNo,  SwiftWriteLM14CyNo,
765                                 SwiftWriteLM14CyNo,  SwiftWriteLM14CyNo,
766                                 SwiftWriteP01OneCycle, SwiftVLDMPerm7]>,
767     SchedVar<SwiftLMAddr15Pred,[SwiftWriteLM9Cy, SwiftWriteLM10Cy,
768                                 SwiftWriteLM13Cy, SwiftWriteLM14Cy,
769                                 SwiftWriteLM17Cy, SwiftWriteLM18CyNo,
770                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
771                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
772                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
773                                 SwiftWriteLM21CyNo, SwiftWriteLM22CyNo,
774                                 SwiftWriteLM25CyNo, SwiftWriteP01OneCycle,
775                                 SwiftVLDMPerm9]>,
776     // Load of 4 Q registers.
777     SchedVar<SwiftLMAddr16Pred,[SwiftWriteLM7Cy, SwiftWriteLM10Cy,
778                                 SwiftWriteLM11Cy, SwiftWriteLM14Cy,
779                                 SwiftWriteLM15Cy, SwiftWriteLM18CyNo,
780                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
781                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
782                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
783                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
784                                 SwiftWriteLM19CyNo, SwiftWriteLM22CyNo,
785                                 SwiftWriteP01OneCycle, SwiftVLDMPerm4]>,
786     // Unknow number of registers, just use resources for two registers.
787     SchedVar<NoSchedPred,      [SwiftWriteLM7Cy, SwiftWriteLM8Cy,
788                                 SwiftWriteLM13Cy, SwiftWriteLM13CyNo,
789                                 SwiftWriteLM13CyNo, 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                                 SwiftWriteP01OneCycle,  SwiftVLDMPerm2]>
804   ]> { let Variadic = 1; }
805
806   def : InstRW<[SwiftWriteVLDM], (instregex "VLDM[SD](IA|DB)$")>;
807
808   def : InstRW<[SwiftWriteP01OneCycle2x, SwiftWriteVLDM],
809         (instregex "VLDM[SD](IA|DB)_UPD$")>;
810
811   def SwiftWriteVSTM : SchedWriteVariant<[
812     // One S register.
813     SchedVar<SwiftLMAddr1Pred, [SwiftWriteSTM1]>,
814     // One D register.
815     SchedVar<SwiftLMAddr2Pred, [SwiftWriteSTM1]>,
816     // Three S registers.
817     SchedVar<SwiftLMAddr3Pred, [SwiftWriteSTM4]>,
818     // Assume one Q register.
819     SchedVar<SwiftLMAddr4Pred, [SwiftWriteSTM1]>,
820     SchedVar<SwiftLMAddr5Pred, [SwiftWriteSTM6]>,
821     // Assume three D registers.
822     SchedVar<SwiftLMAddr6Pred, [SwiftWriteSTM4]>,
823     SchedVar<SwiftLMAddr7Pred, [SwiftWriteSTM8]>,
824     // Assume two Q registers.
825     SchedVar<SwiftLMAddr8Pred, [SwiftWriteSTM3]>,
826     SchedVar<SwiftLMAddr9Pred, [SwiftWriteSTM10]>,
827     // Assume 5 D registers.
828     SchedVar<SwiftLMAddr10Pred, [SwiftWriteSTM6]>,
829     SchedVar<SwiftLMAddr11Pred, [SwiftWriteSTM12]>,
830     // Assume three Q registers.
831     SchedVar<SwiftLMAddr12Pred, [SwiftWriteSTM4]>,
832     SchedVar<SwiftLMAddr13Pred, [SwiftWriteSTM14]>,
833     // Assume 7 D registers.
834     SchedVar<SwiftLMAddr14Pred, [SwiftWriteSTM8]>,
835     SchedVar<SwiftLMAddr15Pred, [SwiftWriteSTM16]>,
836     // Assume four Q registers.
837     SchedVar<SwiftLMAddr16Pred, [SwiftWriteSTM5]>,
838     // Asumme two Q registers.
839     SchedVar<NoSchedPred, [SwiftWriteSTM3]>
840   ]> { let Variadic = 1; }
841
842   def : InstRW<[SwiftWriteVSTM], (instregex "VSTM[SD](IA|DB)$")>;
843
844   def : InstRW<[SwiftWriteP01OneCycle2x, SwiftWriteVSTM],
845         (instregex "VSTM[SD](IA|DB)_UPD")>;
846
847   // 4.2.43 Advanced SIMD, Element or Structure Load and Store
848   def SwiftWrite2xP2FourCy : SchedWriteRes<[SwiftUnitP2]> {
849       let Latency = 4;
850       let ResourceCycles = [2];
851   }
852   def SwiftWrite3xP2FourCy : SchedWriteRes<[SwiftUnitP2]> {
853       let Latency = 4;
854       let ResourceCycles = [3];
855   }
856   foreach Num = 1-2 in {
857     def SwiftExt#Num#xP0 : SchedWriteRes<[SwiftUnitP0]> {
858       let Latency = 0;
859       let NumMicroOps = Num;
860       let ResourceCycles = [Num];
861     }
862   }
863   // VLDx
864   // Multiple structures.
865   // Single element structure loads.
866   // We assume aligned.
867   // Single/two register.
868   def : InstRW<[SwiftWriteLM4Cy], (instregex "VLD1(d|q)(8|16|32|64)$")>;
869   def : InstRW<[SwiftWriteLM4Cy, SwiftWriteP01OneCycle],
870         (instregex "VLD1(d|q)(8|16|32|64)wb")>;
871   // Three register.
872   def : InstRW<[SwiftWrite3xP2FourCy],
873         (instregex "VLD1(d|q)(8|16|32|64)T$", "VLD1d64TPseudo")>;
874   def : InstRW<[SwiftWrite3xP2FourCy, SwiftWriteP01OneCycle],
875         (instregex "VLD1(d|q)(8|16|32|64)Twb")>;
876   /// Four Register.
877   def : InstRW<[SwiftWrite2xP2FourCy],
878         (instregex "VLD1(d|q)(8|16|32|64)Q$", "VLD1d64QPseudo")>;
879   def : InstRW<[SwiftWrite2xP2FourCy, SwiftWriteP01OneCycle],
880         (instregex "VLD1(d|q)(8|16|32|64)Qwb")>;
881   // Two element structure loads.
882   // Two/four register.
883   def : InstRW<[SwiftWriteLM9Cy, SwiftExt2xP0, SwiftVLDMPerm2],
884         (instregex "VLD2(d|q|b)(8|16|32)$", "VLD2q(8|16|32)Pseudo$")>;
885   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteP01OneCycle, SwiftExt2xP0,
886                 SwiftVLDMPerm2],
887         (instregex "VLD2(d|q|b)(8|16|32)wb", "VLD2q(8|16|32)PseudoWB")>;
888   // Three element structure.
889   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteLM9CyNo, SwiftWriteLM9CyNo,
890                 SwiftVLDMPerm3, SwiftWrite3xP2FourCy],
891         (instregex "VLD3(d|q)(8|16|32)$")>;
892   def : InstRW<[SwiftWriteLM9Cy, SwiftVLDMPerm3, SwiftWrite3xP2FourCy],
893         (instregex "VLD3(d|q)(8|16|32)(oddP|P)seudo$")>;
894
895   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteLM9CyNo, SwiftWriteLM9CyNo,
896                 SwiftWriteP01OneCycle, SwiftVLDMPerm3, SwiftWrite3xP2FourCy],
897         (instregex "VLD3(d|q)(8|16|32)_UPD$")>;
898   def : InstRW<[SwiftWriteLM9Cy, SwiftWriteP01OneCycle, SwiftVLDMPerm3,
899                 SwiftWrite3xP2FourCy],
900         (instregex "VLD3(d|q)(8|16|32)(oddP|P)seudo_UPD")>;
901   // Four element structure loads.
902   def : InstRW<[SwiftWriteLM11Cy, SwiftWriteLM11Cy, SwiftWriteLM11Cy,
903                 SwiftWriteLM11Cy, SwiftExt2xP0, SwiftVLDMPerm4,
904                 SwiftWrite3xP2FourCy],
905         (instregex "VLD4(d|q)(8|16|32)$")>;
906   def : InstRW<[SwiftWriteLM11Cy,  SwiftExt2xP0, SwiftVLDMPerm4,
907                 SwiftWrite3xP2FourCy],
908         (instregex "VLD4(d|q)(8|16|32)(oddP|P)seudo$")>;
909   def : InstRW<[SwiftWriteLM11Cy, SwiftWriteLM11Cy, SwiftWriteLM11Cy,
910                 SwiftWriteLM11Cy, SwiftWriteP01OneCycle, SwiftExt2xP0,
911                 SwiftVLDMPerm4, SwiftWrite3xP2FourCy],
912         (instregex "VLD4(d|q)(8|16|32)_UPD")>;
913   def : InstRW<[SwiftWriteLM11Cy, SwiftWriteP01OneCycle, SwiftExt2xP0,
914                 SwiftVLDMPerm4, SwiftWrite3xP2FourCy],
915         (instregex  "VLD4(d|q)(8|16|32)(oddP|P)seudo_UPD")>;
916
917   // Single all/lane loads.
918   // One element structure.
919   def : InstRW<[SwiftWriteLM6Cy, SwiftVLDMPerm2],
920         (instregex "VLD1(LN|DUP)(d|q)(8|16|32)$", "VLD1(LN|DUP)(d|q)(8|16|32)Pseudo$")>;
921   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteP01OneCycle, SwiftVLDMPerm2],
922         (instregex "VLD1(LN|DUP)(d|q)(8|16|32)(wb|_UPD)",
923                   "VLD1LNq(8|16|32)Pseudo_UPD")>;
924   // Two element structure.
925   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteLM6Cy, SwiftExt1xP0, SwiftVLDMPerm2],
926         (instregex "VLD2(DUP|LN)(d|q)(8|16|32|8x2|16x2|32x2)$",
927                    "VLD2LN(d|q)(8|16|32)Pseudo$")>;
928   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteLM6Cy, SwiftWriteP01OneCycle,
929                 SwiftExt1xP0, SwiftVLDMPerm2],
930         (instregex "VLD2LN(d|q)(8|16|32)_UPD$")>;
931   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteP01OneCycle, SwiftWriteLM6Cy,
932                 SwiftExt1xP0, SwiftVLDMPerm2],
933         (instregex "VLD2DUPd(8|16|32|8x2|16x2|32x2)wb")>;
934   def : InstRW<[SwiftWriteLM6Cy, SwiftWriteP01OneCycle, SwiftWriteLM6Cy,
935                 SwiftExt1xP0, SwiftVLDMPerm2],
936         (instregex "VLD2LN(d|q)(8|16|32)Pseudo_UPD")>;
937   // Three element structure.
938   def : InstRW<[SwiftWriteLM7Cy, SwiftWriteLM8Cy, SwiftWriteLM8Cy, SwiftExt1xP0,
939                 SwiftVLDMPerm3],
940         (instregex "VLD3(DUP|LN)(d|q)(8|16|32)$",
941                    "VLD3(LN|DUP)(d|q)(8|16|32)Pseudo$")>;
942   def : InstRW<[SwiftWriteLM7Cy, SwiftWriteLM8Cy, SwiftWriteLM8Cy,
943                 SwiftWriteP01OneCycle, SwiftExt1xP0, SwiftVLDMPerm3],
944         (instregex "VLD3(LN|DUP)(d|q)(8|16|32)_UPD")>;
945   def : InstRW<[SwiftWriteLM7Cy, SwiftWriteP01OneCycle, SwiftWriteLM8Cy,
946                 SwiftWriteLM8Cy, SwiftExt1xP0, SwiftVLDMPerm3],
947         (instregex "VLD3(LN|DUP)(d|q)(8|16|32)Pseudo_UPD")>;
948   // Four element struture.
949   def : InstRW<[SwiftWriteLM8Cy, SwiftWriteLM9Cy, SwiftWriteLM10CyNo,
950                 SwiftWriteLM10CyNo, SwiftExt1xP0, SwiftVLDMPerm5],
951         (instregex "VLD4(LN|DUP)(d|q)(8|16|32)$",
952                    "VLD4(LN|DUP)(d|q)(8|16|32)Pseudo$")>;
953   def : InstRW<[SwiftWriteLM8Cy, SwiftWriteLM9Cy, SwiftWriteLM10CyNo,
954                 SwiftWriteLM10CyNo, SwiftWriteP01OneCycle, SwiftExt1xP0,
955                 SwiftVLDMPerm5],
956         (instregex "VLD4(DUP|LN)(d|q)(8|16|32)_UPD")>;
957   def : InstRW<[SwiftWriteLM8Cy, SwiftWriteP01OneCycle, SwiftWriteLM9Cy,
958                 SwiftWriteLM10CyNo, SwiftWriteLM10CyNo, SwiftExt1xP0,
959                 SwiftVLDMPerm5],
960         (instregex "VLD4(DUP|LN)(d|q)(8|16|32)Pseudo_UPD")>;
961   // VSTx
962   // Multiple structures.
963   // Single element structure store.
964   def : InstRW<[SwiftWrite1xP2], (instregex "VST1d(8|16|32|64)$")>;
965   def : InstRW<[SwiftWrite2xP2], (instregex "VST1q(8|16|32|64)$")>;
966   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2],
967         (instregex "VST1d(8|16|32|64)wb")>;
968   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite2xP2],
969         (instregex "VST1q(8|16|32|64)wb")>;
970   def : InstRW<[SwiftWrite3xP2],
971         (instregex "VST1d(8|16|32|64)T$", "VST1d64TPseudo$")>;
972   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite3xP2],
973         (instregex "VST1d(8|16|32|64)Twb", "VST1d64TPseudoWB")>;
974   def : InstRW<[SwiftWrite4xP2],
975         (instregex "VST1d(8|16|32|64)(Q|QPseudo)$")>;
976   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2],
977         (instregex "VST1d(8|16|32|64)(Qwb|QPseudoWB)")>;
978   // Two element structure store.
979   def : InstRW<[SwiftWrite1xP2, SwiftVLDMPerm1],
980         (instregex "VST2(d|b)(8|16|32)$")>;
981   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2, SwiftVLDMPerm1],
982         (instregex "VST2(b|d)(8|16|32)wb")>;
983   def : InstRW<[SwiftWrite2xP2, SwiftVLDMPerm2],
984         (instregex "VST2q(8|16|32)$", "VST2q(8|16|32)Pseudo$")>;
985   def : InstRW<[SwiftWrite2xP2, SwiftVLDMPerm2],
986         (instregex "VST2q(8|16|32)wb", "VST2q(8|16|32)PseudoWB")>;
987   // Three element structure store.
988   def : InstRW<[SwiftWrite4xP2, SwiftVLDMPerm2],
989         (instregex "VST3(d|q)(8|16|32)$", "VST3(d|q)(8|16|32)(oddP|P)seudo$")>;
990   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2, SwiftVLDMPerm2],
991         (instregex "VST3(d|q)(8|16|32)_UPD",
992                    "VST3(d|q)(8|16|32)(oddP|P)seudo_UPD$")>;
993   // Four element structure store.
994   def : InstRW<[SwiftWrite4xP2, SwiftVLDMPerm2],
995         (instregex "VST4(d|q)(8|16|32)$", "VST4(d|q)(8|16|32)(oddP|P)seudo$")>;
996   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2, SwiftVLDMPerm4],
997         (instregex "VST4(d|q)(8|16|32)_UPD",
998                    "VST4(d|q)(8|16|32)(oddP|P)seudo_UPD$")>;
999   // Single/all lane store.
1000   // One element structure.
1001   def : InstRW<[SwiftWrite1xP2, SwiftVLDMPerm1],
1002         (instregex "VST1LNd(8|16|32)$", "VST1LNq(8|16|32)Pseudo$")>;
1003   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2, SwiftVLDMPerm1],
1004         (instregex "VST1LNd(8|16|32)_UPD", "VST1LNq(8|16|32)Pseudo_UPD")>;
1005   // Two element structure.
1006   def : InstRW<[SwiftWrite1xP2, SwiftVLDMPerm2],
1007         (instregex "VST2LN(d|q)(8|16|32)$", "VST2LN(d|q)(8|16|32)Pseudo$")>;
1008   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite1xP2, SwiftVLDMPerm2],
1009         (instregex "VST2LN(d|q)(8|16|32)_UPD",
1010                    "VST2LN(d|q)(8|16|32)Pseudo_UPD")>;
1011   // Three element structure.
1012   def : InstRW<[SwiftWrite4xP2, SwiftVLDMPerm2],
1013         (instregex "VST3LN(d|q)(8|16|32)$", "VST3LN(d|q)(8|16|32)Pseudo$")>;
1014   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite4xP2, SwiftVLDMPerm2],
1015         (instregex "VST3LN(d|q)(8|16|32)_UPD",
1016                    "VST3LN(d|q)(8|16|32)Pseudo_UPD")>;
1017   // Four element structure.
1018   def : InstRW<[SwiftWrite2xP2, SwiftVLDMPerm2],
1019         (instregex "VST4LN(d|q)(8|16|32)$", "VST4LN(d|q)(8|16|32)Pseudo$")>;
1020   def : InstRW<[SwiftWriteP01OneCycle, SwiftWrite2xP2, SwiftVLDMPerm2],
1021         (instregex "VST4LN(d|q)(8|16|32)_UPD",
1022                    "VST4LN(d|q)(8|16|32)Pseudo_UPD")>;
1023
1024   // 4.2.44 VFP, Divide and Square Root
1025   def SwiftDiv17 : SchedWriteRes<[SwiftUnitP0, SwiftUnitDiv]> {
1026     let NumMicroOps = 1;
1027     let Latency = 17;
1028     let ResourceCycles = [1, 15];
1029   }
1030   def SwiftDiv32 : SchedWriteRes<[SwiftUnitP0, SwiftUnitDiv]> {
1031     let NumMicroOps = 1;
1032     let Latency = 32;
1033     let ResourceCycles = [1, 30];
1034   }
1035   def : InstRW<[SwiftDiv17], (instregex "VDIVS", "VSQRTS")>;
1036   def : InstRW<[SwiftDiv32], (instregex "VDIVD", "VSQRTD")>;
1037
1038   // Not specified.
1039   def : InstRW<[SwiftWriteP01OneCycle2x], (instregex "ABS")>;
1040   // Preload.
1041   def : WriteRes<WritePreLd, [SwiftUnitP2]> { let Latency = 0;
1042     let ResourceCycles = [0];
1043   }
1044
1045 }