Added LLVM project notice to the top of every C++ source file.
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9SchedInfo.cpp
1 //===-- UltraSparcSchedInfo.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
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SparcInternals.h"
15
16 /*---------------------------------------------------------------------------
17 Scheduling guidelines for SPARC IIi:
18
19 I-Cache alignment rules (pg 326)
20 -- Align a branch target instruction so that it's entire group is within
21    the same cache line (may be 1-4 instructions).
22 ** Don't let a branch that is predicted taken be the last instruction
23    on an I-cache line: delay slot will need an entire line to be fetched
24 -- Make a FP instruction or a branch be the 4th instruction in a group.
25    For branches, there are tradeoffs in reordering to make this happen
26    (see pg. 327).
27 ** Don't put a branch in a group that crosses a 32-byte boundary!
28    An artificial branch is inserted after every 32 bytes, and having
29    another branch will force the group to be broken into 2 groups. 
30
31 iTLB rules:
32 -- Don't let a loop span two memory pages, if possible
33
34 Branch prediction performance:
35 -- Don't make the branch in a delay slot the target of a branch
36 -- Try not to have 2 predicted branches within a group of 4 instructions
37    (because each such group has a single branch target field).
38 -- Try to align branches in slots 0, 2, 4 or 6 of a cache line (to avoid
39    the wrong prediction bits being used in some cases).
40
41 D-Cache timing constraints:
42 -- Signed int loads of less than 64 bits have 3 cycle latency, not 2
43 -- All other loads that hit in D-Cache have 2 cycle latency
44 -- All loads are returned IN ORDER, so a D-Cache miss will delay a later hit
45 -- Mis-aligned loads or stores cause a trap.  In particular, replace
46    mis-aligned FP double precision l/s with 2 single-precision l/s.
47 -- Simulations of integer codes show increase in avg. group size of
48    33% when code (including esp. non-faulting loads) is moved across
49    one branch, and 50% across 2 branches.
50
51 E-Cache timing constraints:
52 -- Scheduling for E-cache (D-Cache misses) is effective (due to load buffering)
53
54 Store buffer timing constraints:
55 -- Stores can be executed in same cycle as instruction producing the value
56 -- Stores are buffered and have lower priority for E-cache until
57    highwater mark is reached in the store buffer (5 stores)
58
59 Pipeline constraints:
60 -- Shifts can only use IEU0.
61 -- CC setting instructions can only use IEU1.
62 -- Several other instructions must only use IEU1:
63    EDGE(?), ARRAY(?), CALL, JMPL, BPr, PST, and FCMP.
64 -- Two instructions cannot store to the same register file in a single cycle
65    (single write port per file).
66
67 Issue and grouping constraints:
68 -- FP and branch instructions must use slot 4.
69 -- Shift instructions cannot be grouped with other IEU0-specific instructions.
70 -- CC setting instructions cannot be grouped with other IEU1-specific instrs.
71 -- Several instructions must be issued in a single-instruction group:
72         MOVcc or MOVr, MULs/x and DIVs/x, SAVE/RESTORE, many others
73 -- A CALL or JMPL breaks a group, ie, is not combined with subsequent instrs.
74 -- 
75 -- 
76
77 Branch delay slot scheduling rules:
78 -- A CTI couple (two back-to-back CTI instructions in the dynamic stream)
79    has a 9-instruction penalty: the entire pipeline is flushed when the
80    second instruction reaches stage 9 (W-Writeback).
81 -- Avoid putting multicycle instructions, and instructions that may cause
82    load misses, in the delay slot of an annulling branch.
83 -- Avoid putting WR, SAVE..., RESTORE and RETURN instructions in the
84    delay slot of an annulling branch.
85
86  *--------------------------------------------------------------------------- */
87
88 //---------------------------------------------------------------------------
89 // List of CPUResources for UltraSPARC IIi.
90 //---------------------------------------------------------------------------
91
92 static const CPUResource  AllIssueSlots(   "All Instr Slots", 4);
93 static const CPUResource  IntIssueSlots(   "Int Instr Slots", 3);
94 static const CPUResource  First3IssueSlots("Instr Slots 0-3", 3);
95 static const CPUResource  LSIssueSlots(    "Load-Store Instr Slot", 1);
96 static const CPUResource  CTIIssueSlots(   "Ctrl Transfer Instr Slot", 1);
97 static const CPUResource  FPAIssueSlots(   "FP Instr Slot 1", 1);
98 static const CPUResource  FPMIssueSlots(   "FP Instr Slot 2", 1);
99
100 // IEUN instructions can use either Alu and should use IAluN.
101 // IEU0 instructions must use Alu 1 and should use both IAluN and IAlu0. 
102 // IEU1 instructions must use Alu 2 and should use both IAluN and IAlu1. 
103 static const CPUResource  IAluN("Int ALU 1or2", 2);
104 static const CPUResource  IAlu0("Int ALU 1",    1);
105 static const CPUResource  IAlu1("Int ALU 2",    1);
106
107 static const CPUResource  LSAluC1("Load/Store Unit Addr Cycle", 1);
108 static const CPUResource  LSAluC2("Load/Store Unit Issue Cycle", 1);
109 static const CPUResource  LdReturn("Load Return Unit", 1);
110
111 static const CPUResource  FPMAluC1("FP Mul/Div Alu Cycle 1", 1);
112 static const CPUResource  FPMAluC2("FP Mul/Div Alu Cycle 2", 1);
113 static const CPUResource  FPMAluC3("FP Mul/Div Alu Cycle 3", 1);
114
115 static const CPUResource  FPAAluC1("FP Other Alu Cycle 1", 1);
116 static const CPUResource  FPAAluC2("FP Other Alu Cycle 2", 1);
117 static const CPUResource  FPAAluC3("FP Other Alu Cycle 3", 1);
118
119 static const CPUResource  IRegReadPorts("Int Reg ReadPorts", INT_MAX); // CHECK
120 static const CPUResource  IRegWritePorts("Int Reg WritePorts", 2);     // CHECK
121 static const CPUResource  FPRegReadPorts("FP Reg Read Ports", INT_MAX);// CHECK
122 static const CPUResource  FPRegWritePorts("FP Reg Write Ports", 1);    // CHECK
123
124 static const CPUResource  CTIDelayCycle( "CTI  delay cycle", 1);
125 static const CPUResource  FCMPDelayCycle("FCMP delay cycle", 1);
126
127
128
129 //---------------------------------------------------------------------------
130 // const InstrClassRUsage SparcRUsageDesc[]
131 // 
132 // Purpose:
133 //   Resource usage information for instruction in each scheduling class.
134 //   The InstrRUsage Objects for individual classes are specified first.
135 //   Note that fetch and decode are decoupled from the execution pipelines
136 //   via an instr buffer, so they are not included in the cycles below.
137 //---------------------------------------------------------------------------
138
139 static const InstrClassRUsage NoneClassRUsage = {
140   SPARC_NONE,
141   /*totCycles*/ 7,
142   
143   /* maxIssueNum */ 4,
144   /* isSingleIssue */ false,
145   /* breaksGroup */ false,
146   /* numBubbles */ 0,
147   
148   /*numSlots*/ 4,
149   /* feasibleSlots[] */ { 0, 1, 2, 3 },
150   
151   /*numEntries*/ 0,
152   /* V[] */ {
153     /*Cycle G */
154     /*Ccle E */
155     /*Cycle C */
156     /*Cycle N1*/
157     /*Cycle N1*/
158     /*Cycle N1*/
159     /*Cycle W */
160   }
161 };
162
163 static const InstrClassRUsage IEUNClassRUsage = {
164   SPARC_IEUN,
165   /*totCycles*/ 7,
166   
167   /* maxIssueNum */ 3,
168   /* isSingleIssue */ false,
169   /* breaksGroup */ false,
170   /* numBubbles */ 0,
171   
172   /*numSlots*/ 3,
173   /* feasibleSlots[] */ { 0, 1, 2 },
174   
175   /*numEntries*/ 4,
176   /* V[] */ {
177     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
178                  { IntIssueSlots.rid, 0, 1 },
179     /*Cycle E */ { IAluN.rid, 1, 1 },
180     /*Cycle C */
181     /*Cycle N1*/
182     /*Cycle N1*/
183     /*Cycle N1*/
184     /*Cycle W */ { IRegWritePorts.rid, 6, 1  }
185   }
186 };
187
188 static const InstrClassRUsage IEU0ClassRUsage = {
189   SPARC_IEU0,
190   /*totCycles*/ 7,
191   
192   /* maxIssueNum */ 1,
193   /* isSingleIssue */ false,
194   /* breaksGroup */ false,
195   /* numBubbles */ 0,
196   
197   /*numSlots*/ 3,
198   /* feasibleSlots[] */ { 0, 1, 2 },
199   
200   /*numEntries*/ 5,
201   /* V[] */ {
202     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
203                  { IntIssueSlots.rid, 0, 1 },
204     /*Cycle E */ { IAluN.rid, 1, 1 },
205                  { IAlu0.rid, 1, 1 },
206     /*Cycle C */
207     /*Cycle N1*/
208     /*Cycle N1*/
209     /*Cycle N1*/
210     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
211   }
212 };
213
214 static const InstrClassRUsage IEU1ClassRUsage = {
215   SPARC_IEU1,
216   /*totCycles*/ 7,
217   
218   /* maxIssueNum */ 1,
219   /* isSingleIssue */ false,
220   /* breaksGroup */ false,
221   /* numBubbles */ 0,
222   
223   /*numSlots*/ 3,
224   /* feasibleSlots[] */ { 0, 1, 2 },
225   
226   /*numEntries*/ 5,
227   /* V[] */ {
228     /*Cycle G */ { AllIssueSlots.rid, 0, 1 },
229                { IntIssueSlots.rid, 0, 1 },
230     /*Cycle E */ { IAluN.rid, 1, 1 },
231                { IAlu1.rid, 1, 1 },
232     /*Cycle C */
233     /*Cycle N1*/
234     /*Cycle N1*/
235     /*Cycle N1*/
236     /*Cycle W */ { IRegWritePorts.rid, 6, 1 }
237   }
238 };
239
240 static const InstrClassRUsage FPMClassRUsage = {
241   SPARC_FPM,
242   /*totCycles*/ 7,
243   
244   /* maxIssueNum */ 1,
245   /* isSingleIssue */ false,
246   /* breaksGroup */ false,
247   /* numBubbles */ 0,
248   
249   /*numSlots*/ 4,
250   /* feasibleSlots[] */ { 0, 1, 2, 3 },
251   
252   /*numEntries*/ 7,
253   /* V[] */ {
254     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
255                  { FPMIssueSlots.rid,   0, 1 },
256     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
257     /*Cycle C */ { FPMAluC1.rid,        2, 1 },
258     /*Cycle N1*/ { FPMAluC2.rid,        3, 1 },
259     /*Cycle N1*/ { FPMAluC3.rid,        4, 1 },
260     /*Cycle N1*/
261     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
262   }
263 };
264
265 static const InstrClassRUsage FPAClassRUsage = {
266   SPARC_FPA,
267   /*totCycles*/ 7,
268   
269   /* maxIssueNum */ 1,
270   /* isSingleIssue */ false,
271   /* breaksGroup */ false,
272   /* numBubbles */ 0,
273   
274   /*numSlots*/ 4,
275   /* feasibleSlots[] */ { 0, 1, 2, 3 },
276   
277   /*numEntries*/ 7,
278   /* V[] */ {
279     /*Cycle G */ { AllIssueSlots.rid,   0, 1 },
280                  { FPAIssueSlots.rid,   0, 1 },
281     /*Cycle E */ { FPRegReadPorts.rid,  1, 1 },
282     /*Cycle C */ { FPAAluC1.rid,        2, 1 },
283     /*Cycle N1*/ { FPAAluC2.rid,        3, 1 },
284     /*Cycle N1*/ { FPAAluC3.rid,        4, 1 },
285     /*Cycle N1*/
286     /*Cycle W */ { FPRegWritePorts.rid, 6, 1 }
287   }
288 };
289
290 static const InstrClassRUsage LDClassRUsage = {
291   SPARC_LD,
292   /*totCycles*/ 7,
293   
294   /* maxIssueNum */ 1,
295   /* isSingleIssue */ false,
296   /* breaksGroup */ false,
297   /* numBubbles */ 0,
298   
299   /*numSlots*/ 3,
300   /* feasibleSlots[] */ { 0, 1, 2, },
301   
302   /*numEntries*/ 6,
303   /* V[] */ {
304     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
305                  { First3IssueSlots.rid, 0, 1 },
306                  { LSIssueSlots.rid,     0, 1 },
307     /*Cycle E */ { LSAluC1.rid,          1, 1 },
308     /*Cycle C */ { LSAluC2.rid,          2, 1 },
309                  { LdReturn.rid,         2, 1 },
310     /*Cycle N1*/
311     /*Cycle N1*/
312     /*Cycle N1*/
313     /*Cycle W */ { IRegWritePorts.rid,   6, 1 }
314   }
315 };
316
317 static const InstrClassRUsage STClassRUsage = {
318   SPARC_ST,
319   /*totCycles*/ 7,
320   
321   /* maxIssueNum */ 1,
322   /* isSingleIssue */ false,
323   /* breaksGroup */ false,
324   /* numBubbles */ 0,
325   
326   /*numSlots*/ 3,
327   /* feasibleSlots[] */ { 0, 1, 2 },
328   
329   /*numEntries*/ 4,
330   /* V[] */ {
331     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
332                  { First3IssueSlots.rid, 0, 1 },
333                  { LSIssueSlots.rid,     0, 1 },
334     /*Cycle E */ { LSAluC1.rid,          1, 1 },
335     /*Cycle C */ { LSAluC2.rid,          2, 1 }
336     /*Cycle N1*/
337     /*Cycle N1*/
338     /*Cycle N1*/
339     /*Cycle W */
340   }
341 };
342
343 static const InstrClassRUsage CTIClassRUsage = {
344   SPARC_CTI,
345   /*totCycles*/ 7,
346   
347   /* maxIssueNum */ 1,
348   /* isSingleIssue */ false,
349   /* breaksGroup */ false,
350   /* numBubbles */ 0,
351   
352   /*numSlots*/ 4,
353   /* feasibleSlots[] */ { 0, 1, 2, 3 },
354   
355   /*numEntries*/ 4,
356   /* V[] */ {
357     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
358                  { CTIIssueSlots.rid,    0, 1 },
359     /*Cycle E */ { IAlu0.rid,            1, 1 },
360     /*Cycles E-C */ { CTIDelayCycle.rid, 1, 2 }
361     /*Cycle C */             
362     /*Cycle N1*/
363     /*Cycle N1*/
364     /*Cycle N1*/
365     /*Cycle W */
366   }
367 };
368
369 static const InstrClassRUsage SingleClassRUsage = {
370   SPARC_SINGLE,
371   /*totCycles*/ 7,
372   
373   /* maxIssueNum */ 1,
374   /* isSingleIssue */ true,
375   /* breaksGroup */ false,
376   /* numBubbles */ 0,
377   
378   /*numSlots*/ 1,
379   /* feasibleSlots[] */ { 0 },
380   
381   /*numEntries*/ 5,
382   /* V[] */ {
383     /*Cycle G */ { AllIssueSlots.rid,    0, 1 },
384                  { AllIssueSlots.rid,    0, 1 },
385                  { AllIssueSlots.rid,    0, 1 },
386                  { AllIssueSlots.rid,    0, 1 },
387     /*Cycle E */ { IAlu0.rid,            1, 1 }
388     /*Cycle C */
389     /*Cycle N1*/
390     /*Cycle N1*/
391     /*Cycle N1*/
392     /*Cycle W */
393   }
394 };
395
396
397 static const InstrClassRUsage SparcRUsageDesc[] = {
398   NoneClassRUsage,
399   IEUNClassRUsage,
400   IEU0ClassRUsage,
401   IEU1ClassRUsage,
402   FPMClassRUsage,
403   FPAClassRUsage,
404   CTIClassRUsage,
405   LDClassRUsage,
406   STClassRUsage,
407   SingleClassRUsage
408 };
409
410
411
412 //---------------------------------------------------------------------------
413 // const InstrIssueDelta  SparcInstrIssueDeltas[]
414 // 
415 // Purpose:
416 //   Changes to issue restrictions information in InstrClassRUsage for
417 //   instructions that differ from other instructions in their class.
418 //---------------------------------------------------------------------------
419
420 static const InstrIssueDelta  SparcInstrIssueDeltas[] = {
421
422   // opCode,  isSingleIssue,  breaksGroup,  numBubbles
423
424                                 // Special cases for single-issue only
425                                 // Other single issue cases are below.
426 //{ V9::LDDA,           true,   true,   0 },
427 //{ V9::STDA,           true,   true,   0 },
428 //{ V9::LDDF,           true,   true,   0 },
429 //{ V9::LDDFA,          true,   true,   0 },
430   { V9::ADDCr,          true,   true,   0 },
431   { V9::ADDCi,          true,   true,   0 },
432   { V9::ADDCccr,        true,   true,   0 },
433   { V9::ADDCcci,        true,   true,   0 },
434   { V9::SUBCr,          true,   true,   0 },
435   { V9::SUBCi,          true,   true,   0 },
436   { V9::SUBCccr,        true,   true,   0 },
437   { V9::SUBCcci,        true,   true,   0 },
438 //{ V9::LDSTUB,         true,   true,   0 },
439 //{ V9::SWAP,           true,   true,   0 },
440 //{ V9::SWAPA,          true,   true,   0 },
441 //{ V9::CAS,            true,   true,   0 },
442 //{ V9::CASA,           true,   true,   0 },
443 //{ V9::CASX,           true,   true,   0 },
444 //{ V9::CASXA,          true,   true,   0 },
445 //{ V9::LDFSR,          true,   true,   0 },
446 //{ V9::LDFSRA,         true,   true,   0 },
447 //{ V9::LDXFSR,         true,   true,   0 },
448 //{ V9::LDXFSRA,        true,   true,   0 },
449 //{ V9::STFSR,          true,   true,   0 },
450 //{ V9::STFSRA,         true,   true,   0 },
451 //{ V9::STXFSR,         true,   true,   0 },
452 //{ V9::STXFSRA,        true,   true,   0 },
453 //{ V9::SAVED,          true,   true,   0 },
454 //{ V9::RESTORED,       true,   true,   0 },
455 //{ V9::FLUSH,          true,   true,   9 },
456 //{ V9::FLUSHW,         true,   true,   9 },
457 //{ V9::ALIGNADDR,      true,   true,   0 },
458   { V9::RETURNr,        true,   true,   0 },
459   { V9::RETURNi,        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 SparcInstrUsageDeltas[]
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 SparcInstrUsageDeltas[] = {
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 UltraSparcSchedInfo)
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 UltraSparcSchedInfo 
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 UltraSparcSchedInfo::UltraSparcSchedInfo(const TargetMachine& tgt)
739   : TargetSchedInfo(tgt,
740                      (unsigned int) SPARC_NUM_SCHED_CLASSES,
741                      SparcRUsageDesc,
742                      SparcInstrUsageDeltas,
743                      SparcInstrIssueDeltas,
744                      sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
745                      sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
746 {
747   maxNumIssueTotal = 4;
748   longestIssueConflict = 0;             // computed from issuesGaps[]
749   
750   branchMispredictPenalty = 4;          // 4 for SPARC IIi
751   branchTargetUnknownPenalty = 2;       // 2 for SPARC IIi
752   l1DCacheMissPenalty = 8;              // 7 or 9 for SPARC IIi
753   l1ICacheMissPenalty = 8;              // ? for SPARC IIi
754   
755   inOrderLoads = true;                  // true for SPARC IIi
756   inOrderIssue = true;                  // true for SPARC IIi
757   inOrderExec  = false;                 // false for most architectures
758   inOrderRetire= true;                  // true for most architectures
759   
760   // must be called after above parameters are initialized.
761   initializeResources();
762 }
763
764 void
765 UltraSparcSchedInfo::initializeResources()
766 {
767   // Compute TargetSchedInfo::instrRUsages and TargetSchedInfo::issueGaps
768   TargetSchedInfo::initializeResources();
769   
770   // Machine-dependent fixups go here.  None for now.
771 }