- Added some SSE2 128-bit packed integer ops.
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9SchedInfo.cpp
1 //===-- SparcV9SchedInfo.cpp ----------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Describe the scheduling characteristics of the UltraSparc IIi.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SparcV9Internals.h"
15
16 using namespace llvm;
17
18 /*---------------------------------------------------------------------------
19 Scheduling guidelines for SPARC IIi:
20
21 I-Cache alignment rules (pg 326)
22 -- Align a branch target instruction so that it's entire group is within
23    the same cache line (may be 1-4 instructions).
24 ** Don't let a branch that is predicted taken be the last instruction
25    on an I-cache line: delay slot will need an entire line to be fetched
26 -- Make a FP instruction or a branch be the 4th instruction in a group.
27    For branches, there are tradeoffs in reordering to make this happen
28    (see pg. 327).
29 ** Don't put a branch in a group that crosses a 32-byte boundary!
30    An artificial branch is inserted after every 32 bytes, and having
31    another branch will force the group to be broken into 2 groups.
32
33 iTLB rules:
34 -- Don't let a loop span two memory pages, if possible
35
36 Branch prediction performance:
37 -- Don't make the branch in a delay slot the target of a branch
38 -- Try not to have 2 predicted branches within a group of 4 instructions
39    (because each such group has a single branch target field).
40 -- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
41    the wrong prediction bits being used in some cases).
42
43 D-Cache timing constraints:
44 -- Signed int loads of less than 64 bits have 3 cycle latency, not 2
45 -- All other loads that hit in D-Cache have 2 cycle latency
46 -- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
47 -- Mis-aligned loads or stores cause a trap.  In particular, replace
48    mis-aligned FP double precision l/s with 2 single-precision l/s.
49 -- Simulations of integer codes show increase in avg. group size of
50    33% when code (including esp. non-faulting loads) is moved across
51    one branch, and 50% across 2 branches.
52
53 E-Cache timing constraints:
54 -- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
55
56 Store buffer timing constraints:
57 -- Stores can be executed in same cycle as instruction producing the value
58 -- Stores are buffered and have lower priority for E-cache until
59    highwater mark is reached in the store buffer (5 stores)
60
61 Pipeline constraints:
62 -- Shifts can only use IEU0.
63 -- CC setting instructions can only use IEU1.
64 -- Several other instructions must only use IEU1:
65    EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
66 -- Two instructions cannot store to the same register file in a single cycle
67    (single write port per file).
68
69 Issue and grouping constraints:
70 -- FP and branch instructions must use slot 4.
71 -- Shift instructions cannot be grouped with other IEU0-specific instructions.
72 -- CC setting instructions cannot be grouped with other IEU1-specific instrs.
73 -- Several instructions must be issued in a single-instruction group:
74         MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
75 -- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
76 --
77 --
78
79 Branch delay slot scheduling rules:
80 -- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
81    has a 9-instruction penalty: the entire pipeline is flushed when the
82    second instruction reaches stage 9 (W-Writeback).
83 -- Avoid putting multicycle instructions, and instructions that may cause
84    load misses, in the delay slot of an annulling branch.
85 -- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
86    delay slot of an annulling branch.
87
88  *--------------------------------------------------------------------------- */
89
90 //---------------------------------------------------------------------------
91 // List of CPUResources for UltraSPARC IIi.
92 //---------------------------------------------------------------------------
93
94 static const CPUResource  AllIssueSlots(   "All Instr Slots", 4);
95 static const CPUResource  IntIssueSlots(   "Int Instr Slots", 3);
96 static const CPUResource  First3IssueSlots("Instr Slots 0-3", 3);
97 static const CPUResource  LSIssueSlots(    "Load-Store Instr Slot", 1);
98 static const CPUResource  CTIIssueSlots(   "Ctrl Transfer Instr Slot", 1);
99 static const CPUResource  FPAIssueSlots(   "FP Instr Slot 1", 1);
100 static const CPUResource  FPMIssueSlots(   "FP Instr Slot 2", 1);
101
102 // IEUN instructions can use either Alu and should use IAluN.
103 // IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0.
104 // IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1.
105 static const CPUResource  IAluN("Int ALU 1or2", 2);
106 static const CPUResource  IAlu0("Int ALU 1",    1);
107 static const CPUResource  IAlu1("Int ALU 2",    1);
108
109 static const CPUResource  LSAluC1("Load/Store Unit Addr Cycle", 1);
110 static const CPUResource  LSAluC2("Load/Store Unit Issue Cycle", 1);
111 static const CPUResource  LdReturn("Load Return Unit", 1);
112
113 static const CPUResource  FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
114 static const CPUResource  FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
115 static const CPUResource  FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
116
117 static const CPUResource  FPAAluC1("FP Other Alu Cycle 1", 1);
118 static const CPUResource  FPAAluC2("FP Other Alu Cycle 2", 1);
119 static const CPUResource  FPAAluC3("FP Other Alu Cycle 3", 1);
120
121 static const CPUResource  IRegReadPorts("Int Reg ReadPorts", INT_MAX); // CHECK
122 static const CPUResource  IRegWritePorts("Int Reg WritePorts", 2);     // CHECK
123 static const CPUResource  FPRegReadPorts("FP Reg Read Ports", INT_MAX);// CHECK
124 static const CPUResource  FPRegWritePorts("FP Reg Write Ports", 1);    // CHECK
125
126 static const CPUResource  CTIDelayCycle( "CTI  delay cycle", 1);
127 static const CPUResource  FCMPDelayCycle("FCMP delay cycle", 1);
128
129
130
131 //---------------------------------------------------------------------------
132 // const InstrClassRUsage SparcV9RUsageDesc[]
133 //
134 // Purpose:
135 //   Resource usage information for instruction in each scheduling class.
136 //   The InstrRUsage Objects for individual classes are specified first.
137 //   Note that fetch and decode are decoupled from the execution pipelines
138 //   via an instr buffer, so they are not included in the cycles below.
139 //---------------------------------------------------------------------------
140
141 static const InstrClassRUsage NoneClassRUsage = {
142   SPARC_NONE,
143   /*totCycles*/ 7,
144
145   /* maxIssueNum */ 4,
146   /* isSingleIssue */ false,
147   /* breaksGroup */ false,
148   /* numBubbles */ 0,
149
150   /*numSlots*/ 4,
151   /* feasibleSlots[] */ { 0, 1, 2, 3 },
152
153   /*numEntries*/ 0,
154   /* V[] */ {
155     /*Cycle G */
156     /*Ccle E */
157     /*Cycle C */
158     /*Cycle N1*/
159     /*Cycle N1*/
160     /*Cycle N1*/
161     /*Cycle W */
162   }
163 };
164
165 static const InstrClassRUsage IEUNClassRUsage = {
166   SPARC_IEUN,
167   /*totCycles*/ 7,
168
169   /* maxIssueNum */ 3,
170   /* isSingleIssue */ false,
171   /* breaksGroup */ false,
172   /* numBubbles */ 0,
173
174   /*numSlots*/ 3,
175   /* feasibleSlots[] */ { 0, 1, 2 },
176
177   /*numEntries*/ 4,
178   /* V[] */ {
179     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
180                  { IntIssueSlots.rid, 0, 1 },
181     /*Cycle E */ { IAluN.rid, 1, 1 },
182     /*Cycle C */
183     /*Cycle N1*/
184     /*Cycle N1*/
185     /*Cycle N1*/
186     /*Cycle W */ { IRegWritePorts.rid, 6, 1  }
187   }
188 };
189
190 static const InstrClassRUsage IEU0ClassRUsage = {
191   SPARC_IEU0,
192   /*totCycles*/ 7,
193
194   /* maxIssueNum */ 1,
195   /* isSingleIssue */ false,
196   /* breaksGroup */ false,
197   /* numBubbles */ 0,
198
199   /*numSlots*/ 3,
200   /* feasibleSlots[] */ { 0, 1, 2 },
201
202   /*numEntries*/ 5,
203   /* V[] */ {
204     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
205                  { IntIssueSlots.rid, 0, 1 },
206     /*Cycle E */ { IAluN.rid, 1, 1 },
207                  { IAlu0.rid, 1, 1 },
208     /*Cycle C */
209     /*Cycle N1*/
210     /*Cycle N1*/
211     /*Cycle N1*/
212     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
213   }
214 };
215
216 static const InstrClassRUsage IEU1ClassRUsage = {
217   SPARC_IEU1,
218   /*totCycles*/ 7,
219
220   /* maxIssueNum */ 1,
221   /* isSingleIssue */ false,
222   /* breaksGroup */ false,
223   /* numBubbles */ 0,
224
225   /*numSlots*/ 3,
226   /* feasibleSlots[] */ { 0, 1, 2 },
227
228   /*numEntries*/ 5,
229   /* V[] */ {
230     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
231                { IntIssueSlots.rid, 0, 1 },
232     /*Cycle E */ { IAluN.rid, 1, 1 },
233                { IAlu1.rid, 1, 1 },
234     /*Cycle C */
235     /*Cycle N1*/
236     /*Cycle N1*/
237     /*Cycle N1*/
238     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
239   }
240 };
241
242 static const InstrClassRUsage FPMClassRUsage = {
243   SPARC_FPM,
244   /*totCycles*/ 7,
245
246   /* maxIssueNum */ 1,
247   /* isSingleIssue */ false,
248   /* breaksGroup */ false,
249   /* numBubbles */ 0,
250
251   /*numSlots*/ 4,
252   /* feasibleSlots[] */ { 0, 1, 2, 3 },
253
254   /*numEntries*/ 7,
255   /* V[] */ {
256     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
257                  { FPMIssueSlots.rid,   0, 1 },
258     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
259     /*Cycle C */ { FPMAluC1.rid,        2, 1 },
260     /*Cycle N1*/ { FPMAluC2.rid,        3, 1 },
261     /*Cycle N1*/ { FPMAluC3.rid,        4, 1 },
262     /*Cycle N1*/
263     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
264   }
265 };
266
267 static const InstrClassRUsage FPAClassRUsage = {
268   SPARC_FPA,
269   /*totCycles*/ 7,
270
271   /* maxIssueNum */ 1,
272   /* isSingleIssue */ false,
273   /* breaksGroup */ false,
274   /* numBubbles */ 0,
275
276   /*numSlots*/ 4,
277   /* feasibleSlots[] */ { 0, 1, 2, 3 },
278
279   /*numEntries*/ 7,
280   /* V[] */ {
281     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
282                  { FPAIssueSlots.rid,   0, 1 },
283     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
284     /*Cycle C */ { FPAAluC1.rid,        2, 1 },
285     /*Cycle N1*/ { FPAAluC2.rid,        3, 1 },
286     /*Cycle N1*/ { FPAAluC3.rid,        4, 1 },
287     /*Cycle N1*/
288     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
289   }
290 };
291
292 static const InstrClassRUsage LDClassRUsage = {
293   SPARC_LD,
294   /*totCycles*/ 7,
295
296   /* maxIssueNum */ 1,
297   /* isSingleIssue */ false,
298   /* breaksGroup */ false,
299   /* numBubbles */ 0,
300
301   /*numSlots*/ 3,
302   /* feasibleSlots[] */ { 0, 1, 2, },
303
304   /*numEntries*/ 6,
305   /* V[] */ {
306     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
307                  { First3IssueSlots.rid, 0, 1 },
308                  { LSIssueSlots.rid,     0, 1 },
309     /*Cycle E */ { LSAluC1.rid,          1, 1 },
310     /*Cycle C */ { LSAluC2.rid,          2, 1 },
311                  { LdReturn.rid,         2, 1 },
312     /*Cycle N1*/
313     /*Cycle N1*/
314     /*Cycle N1*/
315     /*Cycle W */ { IRegWritePorts.rid,   6, 1 }
316   }
317 };
318
319 static const InstrClassRUsage STClassRUsage = {
320   SPARC_ST,
321   /*totCycles*/ 7,
322
323   /* maxIssueNum */ 1,
324   /* isSingleIssue */ false,
325   /* breaksGroup */ false,
326   /* numBubbles */ 0,
327
328   /*numSlots*/ 3,
329   /* feasibleSlots[] */ { 0, 1, 2 },
330
331   /*numEntries*/ 4,
332   /* V[] */ {
333     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
334                  { First3IssueSlots.rid, 0, 1 },
335                  { LSIssueSlots.rid,     0, 1 },
336     /*Cycle E */ { LSAluC1.rid,          1, 1 },
337     /*Cycle C */ { LSAluC2.rid,          2, 1 }
338     /*Cycle N1*/
339     /*Cycle N1*/
340     /*Cycle N1*/
341     /*Cycle W */
342   }
343 };
344
345 static const InstrClassRUsage CTIClassRUsage = {
346   SPARC_CTI,
347   /*totCycles*/ 7,
348
349   /* maxIssueNum */ 1,
350   /* isSingleIssue */ false,
351   /* breaksGroup */ false,
352   /* numBubbles */ 0,
353
354   /*numSlots*/ 4,
355   /* feasibleSlots[] */ { 0, 1, 2, 3 },
356
357   /*numEntries*/ 4,
358   /* V[] */ {
359     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
360                  { CTIIssueSlots.rid,    0, 1 },
361     /*Cycle E */ { IAlu0.rid,            1, 1 },
362     /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
363     /*Cycle C */
364     /*Cycle N1*/
365     /*Cycle N1*/
366     /*Cycle N1*/
367     /*Cycle W */
368   }
369 };
370
371 static const InstrClassRUsage SingleClassRUsage = {
372   SPARC_SINGLE,
373   /*totCycles*/ 7,
374
375   /* maxIssueNum */ 1,
376   /* isSingleIssue */ true,
377   /* breaksGroup */ false,
378   /* numBubbles */ 0,
379
380   /*numSlots*/ 1,
381   /* feasibleSlots[] */ { 0 },
382
383   /*numEntries*/ 5,
384   /* V[] */ {
385     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
386                  { AllIssueSlots.rid,    0, 1 },
387                  { AllIssueSlots.rid,    0, 1 },
388                  { AllIssueSlots.rid,    0, 1 },
389     /*Cycle E */ { IAlu0.rid,            1, 1 }
390     /*Cycle C */
391     /*Cycle N1*/
392     /*Cycle N1*/
393     /*Cycle N1*/
394     /*Cycle W */
395   }
396 };
397
398
399 static const InstrClassRUsage SparcV9RUsageDesc[] = {
400   NoneClassRUsage,
401   IEUNClassRUsage,
402   IEU0ClassRUsage,
403   IEU1ClassRUsage,
404   FPMClassRUsage,
405   FPAClassRUsage,
406   CTIClassRUsage,
407   LDClassRUsage,
408   STClassRUsage,
409   SingleClassRUsage
410 };
411
412
413
414 //---------------------------------------------------------------------------
415 // const InstrIssueDelta  SparcV9InstrIssueDeltas[]
416 //
417 // Purpose:
418 //   Changes to issue restrictions information in InstrClassRUsage for
419 //   instructions that differ from other instructions in their class.
420 //---------------------------------------------------------------------------
421
422 static const InstrIssueDelta  SparcV9InstrIssueDeltas[] = {
423
424   // opCode,  isSingleIssue,  breaksGroup,  numBubbles
425
426                                 // Special cases for single-issue only
427                                 // Other single issue cases are below.
428 //{ V9::LDDA,           true,   true,   0 },
429 //{ V9::STDA,           true,   true,   0 },
430 //{ V9::LDDF,           true,   true,   0 },
431 //{ V9::LDDFA,          true,   true,   0 },
432   { V9::ADDCr,          true,   true,   0 },
433   { V9::ADDCi,          true,   true,   0 },
434   { V9::ADDCccr,        true,   true,   0 },
435   { V9::ADDCcci,        true,   true,   0 },
436   { V9::SUBCr,          true,   true,   0 },
437   { V9::SUBCi,          true,   true,   0 },
438   { V9::SUBCccr,        true,   true,   0 },
439   { V9::SUBCcci,        true,   true,   0 },
440 //{ V9::LDSTUB,         true,   true,   0 },
441 //{ V9::SWAP,           true,   true,   0 },
442 //{ V9::SWAPA,          true,   true,   0 },
443 //{ V9::CAS,            true,   true,   0 },
444 //{ V9::CASA,           true,   true,   0 },
445 //{ V9::CASX,           true,   true,   0 },
446 //{ V9::CASXA,          true,   true,   0 },
447 //{ V9::LDFSR,          true,   true,   0 },
448 //{ V9::LDFSRA,         true,   true,   0 },
449 //{ V9::LDXFSR,         true,   true,   0 },
450 //{ V9::LDXFSRA,        true,   true,   0 },
451 //{ V9::STFSR,          true,   true,   0 },
452 //{ V9::STFSRA,         true,   true,   0 },
453 //{ V9::STXFSR,         true,   true,   0 },
454 //{ V9::STXFSRA,        true,   true,   0 },
455 //{ V9::SAVED,          true,   true,   0 },
456 //{ V9::RESTORED,       true,   true,   0 },
457 //{ V9::FLUSH,          true,   true,   9 },
458 //{ V9::FLUSHW,         true,   true,   9 },
459 //{ V9::ALIGNADDR,      true,   true,   0 },
460 //{ V9::DONE,           true,   true,   0 },
461 //{ V9::RETRY,          true,   true,   0 },
462 //{ V9::TCC,            true,   true,   0 },
463 //{ V9::SHUTDOWN,       true,   true,   0 },
464
465                                 // Special cases for breaking group *before*
466                                 // CURRENTLY NOT SUPPORTED!
467   { V9::CALL,           false,  false,  0 },
468   { V9::JMPLCALLr,      false,  false,  0 },
469   { V9::JMPLCALLi,      false,  false,  0 },
470   { V9::JMPLRETr,       false,  false,  0 },
471   { V9::JMPLRETi,       false,  false,  0 },
472
473                                 // Special cases for breaking the group *after*
474   { V9::MULXr,          true,   true,   (4+34)/2 },
475   { V9::MULXi,          true,   true,   (4+34)/2 },
476   { V9::FDIVS,          false,  true,   0 },
477   { V9::FDIVD,          false,  true,   0 },
478   { V9::FDIVQ,          false,  true,   0 },
479   { V9::FSQRTS,         false,  true,   0 },
480   { V9::FSQRTD,         false,  true,   0 },
481   { V9::FSQRTQ,         false,  true,   0 },
482 //{ V9::FCMP{LE,GT,NE,EQ}, false, true, 0 },
483
484                                 // Instructions that introduce bubbles
485 //{ V9::MULScc,         true,   true,   2 },
486 //{ V9::SMULcc,         true,   true,   (4+18)/2 },
487 //{ V9::UMULcc,         true,   true,   (4+19)/2 },
488   { V9::SDIVXr,         true,   true,   68 },
489   { V9::SDIVXi,         true,   true,   68 },
490   { V9::UDIVXr,         true,   true,   68 },
491   { V9::UDIVXi,         true,   true,   68 },
492 //{ V9::SDIVcc,         true,   true,   36 },
493 //{ V9::UDIVcc,         true,   true,   37 },
494   { V9::WRCCRr,         true,   true,   4 },
495   { V9::WRCCRi,         true,   true,   4 },
496 //{ V9::WRPR,           true,   true,   4 },
497 //{ V9::RDCCR,          true,   true,   0 }, // no bubbles after, but see below
498 //{ V9::RDPR,           true,   true,   0 },
499 };
500
501
502
503
504 //---------------------------------------------------------------------------
505 // const InstrRUsageDelta SparcV9InstrUsageDeltas[]
506 //
507 // Purpose:
508 //   Changes to resource usage information in InstrClassRUsage for
509 //   instructions that differ from other instructions in their class.
510 //---------------------------------------------------------------------------
511
512 static const InstrRUsageDelta SparcV9InstrUsageDeltas[] = {
513
514   // MachineOpCode, Resource, Start cycle, Num cycles
515
516   //
517   // JMPL counts as a load/store instruction for issue!
518   //
519   { V9::JMPLCALLr, LSIssueSlots.rid,  0,  1 },
520   { V9::JMPLCALLi, LSIssueSlots.rid,  0,  1 },
521   { V9::JMPLRETr,  LSIssueSlots.rid,  0,  1 },
522   { V9::JMPLRETi,  LSIssueSlots.rid,  0,  1 },
523
524   //
525   // Many instructions cannot issue for the next 2 cycles after an FCMP
526   // We model that with a fake resource FCMPDelayCycle.
527   //
528   { V9::FCMPS,    FCMPDelayCycle.rid, 1, 3 },
529   { V9::FCMPD,    FCMPDelayCycle.rid, 1, 3 },
530   { V9::FCMPQ,    FCMPDelayCycle.rid, 1, 3 },
531
532   { V9::MULXr,     FCMPDelayCycle.rid, 1, 1 },
533   { V9::MULXi,     FCMPDelayCycle.rid, 1, 1 },
534   { V9::SDIVXr,    FCMPDelayCycle.rid, 1, 1 },
535   { V9::SDIVXi,    FCMPDelayCycle.rid, 1, 1 },
536   { V9::UDIVXr,    FCMPDelayCycle.rid, 1, 1 },
537   { V9::UDIVXi,    FCMPDelayCycle.rid, 1, 1 },
538 //{ V9::SMULcc,   FCMPDelayCycle.rid, 1, 1 },
539 //{ V9::UMULcc,   FCMPDelayCycle.rid, 1, 1 },
540 //{ V9::SDIVcc,   FCMPDelayCycle.rid, 1, 1 },
541 //{ V9::UDIVcc,   FCMPDelayCycle.rid, 1, 1 },
542   { V9::STDFr,    FCMPDelayCycle.rid, 1, 1 },
543   { V9::STDFi,    FCMPDelayCycle.rid, 1, 1 },
544   { V9::FMOVRSZ,  FCMPDelayCycle.rid, 1, 1 },
545   { V9::FMOVRSLEZ,FCMPDelayCycle.rid, 1, 1 },
546   { V9::FMOVRSLZ, FCMPDelayCycle.rid, 1, 1 },
547   { V9::FMOVRSNZ, FCMPDelayCycle.rid, 1, 1 },
548   { V9::FMOVRSGZ, FCMPDelayCycle.rid, 1, 1 },
549   { V9::FMOVRSGEZ,FCMPDelayCycle.rid, 1, 1 },
550
551   //
552   // Some instructions are stalled in the GROUP stage if a CTI is in
553   // the E or C stage.  We model that with a fake resource CTIDelayCycle.
554   //
555   { V9::LDDFr,    CTIDelayCycle.rid,  1, 1 },
556   { V9::LDDFi,    CTIDelayCycle.rid,  1, 1 },
557 //{ V9::LDDA,     CTIDelayCycle.rid,  1, 1 },
558 //{ V9::LDDSTUB,  CTIDelayCycle.rid,  1, 1 },
559 //{ V9::LDDSTUBA, CTIDelayCycle.rid,  1, 1 },
560 //{ V9::SWAP,     CTIDelayCycle.rid,  1, 1 },
561 //{ V9::SWAPA,    CTIDelayCycle.rid,  1, 1 },
562 //{ V9::CAS,      CTIDelayCycle.rid,  1, 1 },
563 //{ V9::CASA,     CTIDelayCycle.rid,  1, 1 },
564 //{ V9::CASX,     CTIDelayCycle.rid,  1, 1 },
565 //{ V9::CASXA,    CTIDelayCycle.rid,  1, 1 },
566
567   //
568   // Signed int loads of less than dword size return data in cycle N1 (not C)
569   // and put all loads in consecutive cycles into delayed load return mode.
570   //
571   { V9::LDSBr,    LdReturn.rid,  2, -1 },
572   { V9::LDSBr,    LdReturn.rid,  3,  1 },
573   { V9::LDSBi,    LdReturn.rid,  2, -1 },
574   { V9::LDSBi,    LdReturn.rid,  3,  1 },
575
576   { V9::LDSHr,    LdReturn.rid,  2, -1 },
577   { V9::LDSHr,    LdReturn.rid,  3,  1 },
578   { V9::LDSHi,    LdReturn.rid,  2, -1 },
579   { V9::LDSHi,    LdReturn.rid,  3,  1 },
580
581   { V9::LDSWr,    LdReturn.rid,  2, -1 },
582   { V9::LDSWr,    LdReturn.rid,  3,  1 },
583   { V9::LDSWi,    LdReturn.rid,  2, -1 },
584   { V9::LDSWi,    LdReturn.rid,  3,  1 },
585
586   //
587   // RDPR from certain registers and RD from any register are not dispatchable
588   // until four clocks after they reach the head of the instr. buffer.
589   // Together with their single-issue requirement, this means all four issue
590   // slots are effectively blocked for those cycles, plus the issue cycle.
591   // This does not increase the latency of the instruction itself.
592   //
593   { V9::RDCCR,   AllIssueSlots.rid,     0,  5 },
594   { V9::RDCCR,   AllIssueSlots.rid,     0,  5 },
595   { V9::RDCCR,   AllIssueSlots.rid,     0,  5 },
596   { V9::RDCCR,   AllIssueSlots.rid,     0,  5 },
597
598 #undef EXPLICIT_BUBBLES_NEEDED
599 #ifdef EXPLICIT_BUBBLES_NEEDED
600   //
601   // MULScc inserts one bubble.
602   // This means it breaks the current group (captured in UltraSparcV9SchedInfo)
603   // *and occupies all issue slots for the next cycle
604   //
605 //{ V9::MULScc,  AllIssueSlots.rid, 2, 2-1 },
606 //{ V9::MULScc,  AllIssueSlots.rid, 2, 2-1 },
607 //{ V9::MULScc,  AllIssueSlots.rid, 2, 2-1 },
608 //{ V9::MULScc,  AllIssueSlots.rid, 2, 2-1 },
609
610   //
611   // SMULcc inserts between 4 and 18 bubbles, depending on #leading 0s in rs1.
612   // We just model this with a simple average.
613   //
614 //{ V9::SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
615 //{ V9::SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
616 //{ V9::SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
617 //{ V9::SMULcc,  AllIssueSlots.rid, 2, ((4+18)/2)-1 },
618
619   // SMULcc inserts between 4 and 19 bubbles, depending on #leading 0s in rs1.
620 //{ V9::UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
621 //{ V9::UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
622 //{ V9::UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
623 //{ V9::UMULcc,  AllIssueSlots.rid, 2, ((4+19)/2)-1 },
624
625   //
626   // MULX inserts between 4 and 34 bubbles, depending on #leading 0s in rs1.
627   //
628   { V9::MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
629   { V9::MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
630   { V9::MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
631   { V9::MULX,    AllIssueSlots.rid, 2, ((4+34)/2)-1 },
632
633   //
634   // SDIVcc inserts 36 bubbles.
635   //
636 //{ V9::SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
637 //{ V9::SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
638 //{ V9::SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
639 //{ V9::SDIVcc,  AllIssueSlots.rid, 2, 36-1 },
640
641   // UDIVcc inserts 37 bubbles.
642 //{ V9::UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
643 //{ V9::UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
644 //{ V9::UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
645 //{ V9::UDIVcc,  AllIssueSlots.rid, 2, 37-1 },
646
647   //
648   // SDIVX inserts 68 bubbles.
649   //
650   { V9::SDIVX,   AllIssueSlots.rid, 2, 68-1 },
651   { V9::SDIVX,   AllIssueSlots.rid, 2, 68-1 },
652   { V9::SDIVX,   AllIssueSlots.rid, 2, 68-1 },
653   { V9::SDIVX,   AllIssueSlots.rid, 2, 68-1 },
654
655   //
656   // UDIVX inserts 68 bubbles.
657   //
658   { V9::UDIVX,   AllIssueSlots.rid, 2, 68-1 },
659   { V9::UDIVX,   AllIssueSlots.rid, 2, 68-1 },
660   { V9::UDIVX,   AllIssueSlots.rid, 2, 68-1 },
661   { V9::UDIVX,   AllIssueSlots.rid, 2, 68-1 },
662
663   //
664   // WR inserts 4 bubbles.
665   //
666 //{ V9::WR,     AllIssueSlots.rid, 2, 68-1 },
667 //{ V9::WR,     AllIssueSlots.rid, 2, 68-1 },
668 //{ V9::WR,     AllIssueSlots.rid, 2, 68-1 },
669 //{ V9::WR,     AllIssueSlots.rid, 2, 68-1 },
670
671   //
672   // WRPR inserts 4 bubbles.
673   //
674 //{ V9::WRPR,   AllIssueSlots.rid, 2, 68-1 },
675 //{ V9::WRPR,   AllIssueSlots.rid, 2, 68-1 },
676 //{ V9::WRPR,   AllIssueSlots.rid, 2, 68-1 },
677 //{ V9::WRPR,   AllIssueSlots.rid, 2, 68-1 },
678
679   //
680   // DONE inserts 9 bubbles.
681   //
682 //{ V9::DONE,   AllIssueSlots.rid, 2, 9-1 },
683 //{ V9::DONE,   AllIssueSlots.rid, 2, 9-1 },
684 //{ V9::DONE,   AllIssueSlots.rid, 2, 9-1 },
685 //{ V9::DONE,   AllIssueSlots.rid, 2, 9-1 },
686
687   //
688   // RETRY inserts 9 bubbles.
689   //
690 //{ V9::RETRY,   AllIssueSlots.rid, 2, 9-1 },
691 //{ V9::RETRY,   AllIssueSlots.rid, 2, 9-1 },
692 //{ V9::RETRY,   AllIssueSlots.rid, 2, 9-1 },
693 //{ V9::RETRY,   AllIssueSlots.rid, 2, 9-1 },
694
695 #endif  /*EXPLICIT_BUBBLES_NEEDED */
696 };
697
698 // Additional delays to be captured in code:
699 // 1. RDPR from several state registers (page 349)
700 // 2. RD   from *any* register (page 349)
701 // 3. Writes to TICK, PSTATE, TL registers and FLUSH{W} instr (page 349)
702 // 4. Integer store can be in same group as instr producing value to store.
703 // 5. BICC and BPICC can be in the same group as instr producing CC (pg 350)
704 // 6. FMOVr cannot be in the same or next group as an IEU instr (pg 351).
705 // 7. The second instr. of a CTI group inserts 9 bubbles (pg 351)
706 // 8. WR{PR}, SVAE, SAVED, RESTORE, RESTORED, RETURN, RETRY, and DONE that
707 //    follow an annulling branch cannot be issued in the same group or in
708 //    the 3 groups following the branch.
709 // 9. A predicted annulled load does not stall dependent instructions.
710 //    Other annulled delay slot instructions *do* stall dependents, so
711 //    nothing special needs to be done for them during scheduling.
712 //10. Do not put a load use that may be annulled in the same group as the
713 //    branch.  The group will stall until the load returns.
714 //11. Single-prec. FP loads lock 2 registers, for dependency checking.
715 //
716 //
717 // Additional delays we cannot or will not capture:
718 // 1. If DCTI is last word of cache line, it is delayed until next line can be
719 //    fetched.  Also, other DCTI alignment-related delays (pg 352)
720 // 2. Load-after-store is delayed by 7 extra cycles if load hits in D-Cache.
721 //    Also, several other store-load and load-store conflicts (pg 358)
722 // 3. MEMBAR, LD{X}FSR, LDD{A} and a bunch of other load stalls (pg 358)
723 // 4. There can be at most 8 outstanding buffered store instructions
724 //     (including some others like MEMBAR, LDSTUB, CAS{AX}, and FLUSH)
725
726
727
728 //---------------------------------------------------------------------------
729 // class SparcV9SchedInfo
730 //
731 // Purpose:
732 //   Scheduling information for the UltraSPARC.
733 //   Primarily just initializes machine-dependent parameters in
734 //   class TargetSchedInfo.
735 //---------------------------------------------------------------------------
736
737 /*ctor*/
738 SparcV9SchedInfo::SparcV9SchedInfo(const TargetMachine& tgt)
739   : TargetSchedInfo(tgt,
740                      (unsigned int) SPARC_NUM_SCHED_CLASSES,
741                      SparcV9RUsageDesc,
742                      SparcV9InstrUsageDeltas,
743                      SparcV9InstrIssueDeltas,
744                      sizeof(SparcV9InstrUsageDeltas)/sizeof(InstrRUsageDelta),
745                      sizeof(SparcV9InstrIssueDeltas)/sizeof(InstrIssueDelta))
746 {
747   maxNumIssueTotal = 4;
748   longestIssueConflict = 0;             // computed from issuesGaps[]
749
750   // must be called after above parameters are initialized.
751   initializeResources();
752 }
753
754 void
755 SparcV9SchedInfo::initializeResources()
756 {
757   // Compute TargetSchedInfo::instrRUsages and TargetSchedInfo::issueGaps
758   TargetSchedInfo::initializeResources();
759
760   // Machine-dependent fixups go here.  None for now.
761 }