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