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