Make a new llvm/Target #include directory.
[oota-llvm.git] / include / llvm / Target / Machine.h
1 //===-- llvm/Target/Machine.h - General Target Information -------*- C++ -*-==//
2 //
3 // This file describes the general parts of a Target machine.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #ifndef LLVM_TARGET_MACHINE_H
8 #define LLVM_TARGET_MACHINE_H
9
10 #include "llvm/Target/Data.h"
11 #include "llvm/Support/NonCopyable.h"
12 #include "llvm/Support/DataTypes.h"
13 #include <string>
14 #include <hash_map>
15 #include <hash_set>
16 #include <algorithm>
17
18 class StructType;
19 struct MachineInstrDescriptor;
20 class TargetMachine;
21
22 //---------------------------------------------------------------------------
23 // Data types used to define information about a single machine instruction
24 //---------------------------------------------------------------------------
25
26 typedef int MachineOpCode;
27 typedef int OpCodeMask;
28 typedef int InstrSchedClass;
29
30 static const unsigned MAX_OPCODE_SIZE = 16;
31
32 typedef long long cycles_t; 
33 const cycles_t HUGE_LATENCY = ~((unsigned long long) 1 << sizeof(cycles_t)-1);
34 const cycles_t INVALID_LATENCY = -HUGE_LATENCY; 
35
36
37 class OpCodePair {
38 public:
39   long val;                     // make long by concatenating two opcodes
40   OpCodePair(MachineOpCode op1, MachineOpCode op2)
41     : val((op1 < 0 || op2 < 0)?
42         -1 : (long)((((unsigned) op1) << MAX_OPCODE_SIZE) | (unsigned) op2)) {}
43   bool operator==(const OpCodePair& op) const {
44     return val == op.val;
45   }
46 private:
47   OpCodePair();                 // disable for now
48 };
49
50
51 template <> struct hash<OpCodePair> {
52   size_t operator()(const OpCodePair& pair) const {
53     return hash<long>()(pair.val);
54   }
55 };
56
57
58 // Global variable holding an array of descriptors for machine instructions.
59 // The actual object needs to be created separately for each target machine.
60 // This variable is initialized and reset by class MachineInstrInfo.
61 // 
62 extern const MachineInstrDescriptor* TargetInstrDescriptors;
63
64
65 //---------------------------------------------------------------------------
66 // struct MachineInstrDescriptor:
67 //      Predefined information about each machine instruction.
68 //      Designed to initialized statically.
69 // 
70 // class MachineInstructionInfo
71 //      Interface to description of machine instructions
72 // 
73 //---------------------------------------------------------------------------
74
75
76 const unsigned int      M_NOP_FLAG              = 1;
77 const unsigned int      M_BRANCH_FLAG           = 1 << 1;
78 const unsigned int      M_CALL_FLAG             = 1 << 2;
79 const unsigned int      M_RET_FLAG              = 1 << 3;
80 const unsigned int      M_ARITH_FLAG            = 1 << 4;
81 const unsigned int      M_CC_FLAG               = 1 << 6;
82 const unsigned int      M_LOGICAL_FLAG          = 1 << 6;
83 const unsigned int      M_INT_FLAG              = 1 << 7;
84 const unsigned int      M_FLOAT_FLAG            = 1 << 8;
85 const unsigned int      M_CONDL_FLAG            = 1 << 9;
86 const unsigned int      M_LOAD_FLAG             = 1 << 10;
87 const unsigned int      M_PREFETCH_FLAG         = 1 << 11;
88 const unsigned int      M_STORE_FLAG            = 1 << 12;
89 const unsigned int      M_DUMMY_PHI_FLAG        = 1 << 13;
90
91
92 struct MachineInstrDescriptor {
93   string        opCodeString;   // Assembly language mnemonic for the opcode.
94   int           numOperands;    // Number of args; -1 if variable #args
95   int           resultPos;      // Position of the result; -1 if no result
96   unsigned int  maxImmedConst;  // Largest +ve constant in IMMMED field or 0.
97   bool          immedIsSignExtended;    // Is IMMED field sign-extended? If so,
98                                 //   smallest -ve value is -(maxImmedConst+1).
99   unsigned int  numDelaySlots;  // Number of delay slots after instruction
100   unsigned int  latency;        // Latency in machine cycles
101   InstrSchedClass schedClass;   // enum  identifying instr sched class
102   unsigned int    iclass;       // flags identifying machine instr class
103 };
104
105
106 class MachineInstrInfo : public NonCopyableV {
107 protected:
108   const MachineInstrDescriptor* desc;   // raw array to allow static init'n
109   unsigned int descSize;                // number of entries in the desc array
110   unsigned int numRealOpCodes;          // number of non-dummy op codes
111   
112 public:
113   /*ctor*/              MachineInstrInfo(const MachineInstrDescriptor* _desc,
114                                          unsigned int _descSize,
115                                          unsigned int _numRealOpCodes);
116   /*dtor*/ virtual      ~MachineInstrInfo();
117   
118   unsigned int          getNumRealOpCodes() const {
119     return numRealOpCodes;
120   }
121   
122   unsigned int          getNumTotalOpCodes() const {
123     return descSize;
124   }
125   
126   const MachineInstrDescriptor& getDescriptor(MachineOpCode opCode) const {
127     assert(opCode >= 0 && opCode < (int) descSize);
128     return desc[opCode];
129   }
130   
131   int                   getNumOperands  (MachineOpCode opCode) const {
132     return getDescriptor(opCode).numOperands;
133   }
134   
135   int                   getResultPos    (MachineOpCode opCode) const {
136     return getDescriptor(opCode).resultPos;
137   }
138   
139   unsigned int          getNumDelaySlots(MachineOpCode opCode) const {
140     return getDescriptor(opCode).numDelaySlots;
141   }
142   
143   InstrSchedClass       getSchedClass   (MachineOpCode opCode) const {
144     return getDescriptor(opCode).schedClass;
145   }
146   
147   //
148   // Query instruction class flags according to the machine-independent
149   // flags listed above.
150   // 
151   unsigned int  getIClass               (MachineOpCode opCode) const {
152     return getDescriptor(opCode).iclass;
153   }
154   bool          isNop                   (MachineOpCode opCode) const {
155     return getDescriptor(opCode).iclass & M_NOP_FLAG;
156   }
157   bool          isBranch                (MachineOpCode opCode) const {
158     return getDescriptor(opCode).iclass & M_BRANCH_FLAG;
159   }
160   bool          isCall                  (MachineOpCode opCode) const {
161     return getDescriptor(opCode).iclass & M_CALL_FLAG;
162   }
163   bool          isReturn                (MachineOpCode opCode) const {
164     return getDescriptor(opCode).iclass & M_RET_FLAG;
165   }
166   bool          isControlFlow           (MachineOpCode opCode) const {
167     return getDescriptor(opCode).iclass & M_BRANCH_FLAG
168         || getDescriptor(opCode).iclass & M_CALL_FLAG
169         || getDescriptor(opCode).iclass & M_RET_FLAG;
170   }
171   bool          isArith                 (MachineOpCode opCode) const {
172     return getDescriptor(opCode).iclass & M_RET_FLAG;
173   }
174   bool          isCCInstr               (MachineOpCode opCode) const {
175     return getDescriptor(opCode).iclass & M_CC_FLAG;
176   }
177   bool          isLogical               (MachineOpCode opCode) const {
178     return getDescriptor(opCode).iclass & M_LOGICAL_FLAG;
179   }
180   bool          isIntInstr              (MachineOpCode opCode) const {
181     return getDescriptor(opCode).iclass & M_INT_FLAG;
182   }
183   bool          isFloatInstr            (MachineOpCode opCode) const {
184     return getDescriptor(opCode).iclass & M_FLOAT_FLAG;
185   }
186   bool          isConditional           (MachineOpCode opCode) const {
187     return getDescriptor(opCode).iclass & M_CONDL_FLAG;
188   }
189   bool          isLoad                  (MachineOpCode opCode) const {
190     return getDescriptor(opCode).iclass & M_LOAD_FLAG;
191   }
192   bool          isPrefetch              (MachineOpCode opCode) const {
193     return getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
194   }
195   bool          isLoadOrPrefetch        (MachineOpCode opCode) const {
196     return getDescriptor(opCode).iclass & M_LOAD_FLAG
197         || getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
198   }
199   bool          isStore                 (MachineOpCode opCode) const {
200     return getDescriptor(opCode).iclass & M_STORE_FLAG;
201   }
202   bool          isMemoryAccess          (MachineOpCode opCode) const {
203     return getDescriptor(opCode).iclass & M_LOAD_FLAG
204         || getDescriptor(opCode).iclass & M_PREFETCH_FLAG
205         || getDescriptor(opCode).iclass & M_STORE_FLAG;
206   }
207   bool          isDummyPhiInstr         (MachineOpCode opCode) const {
208     return getDescriptor(opCode).iclass & M_DUMMY_PHI_FLAG;
209   }
210
211
212   // delete this later *******
213   bool isPhi(MachineOpCode opCode) { return isDummyPhiInstr(opCode); }  
214   
215
216
217   // Check if an instruction can be issued before its operands are ready,
218   // or if a subsequent instruction that uses its result can be issued
219   // before the results are ready.
220   // Default to true since most instructions on many architectures allow this.
221   // 
222   virtual bool          hasOperandInterlock(MachineOpCode opCode) const {
223     return true;
224   }
225   
226   virtual bool          hasResultInterlock(MachineOpCode opCode) const {
227     return true;
228   }
229   
230   // 
231   // Latencies for individual instructions and instruction pairs
232   // 
233   virtual int           minLatency      (MachineOpCode opCode) const {
234     return getDescriptor(opCode).latency;
235   }
236   
237   virtual int           maxLatency      (MachineOpCode opCode) const {
238     return getDescriptor(opCode).latency;
239   }
240   
241   // Check if the specified constant fits in the immediate field
242   // of this machine instruction
243   // 
244   virtual bool          constantFitsInImmedField(MachineOpCode opCode,
245                                                  int64_t intValue) const;
246   
247   // Return the largest +ve constant that can be held in the IMMMED field
248   // of this machine instruction.
249   // isSignExtended is set to true if the value is sign-extended before use
250   // (this is true for all immediate fields in SPARC instructions).
251   // Return 0 if the instruction has no IMMED field.
252   // 
253   virtual uint64_t      maxImmedConstant(MachineOpCode opCode,
254                                          bool& isSignExtended) const {
255     isSignExtended = getDescriptor(opCode).immedIsSignExtended;
256     return getDescriptor(opCode).maxImmedConst;
257   }
258 };
259
260
261 //---------------------------------------------------------------------------
262 // class MachineResource 
263 // class CPUResource
264 // 
265 // Purpose:
266 //   Representation of a single machine resource used in specifying
267 //   resource usages of machine instructions for scheduling.
268 //---------------------------------------------------------------------------
269
270
271 typedef unsigned int resourceId_t;
272
273 class MachineResource {
274 public:
275   const string  rname;
276   resourceId_t  rid;
277   
278   /*ctor*/      MachineResource(const string& resourceName)
279                         : rname(resourceName), rid(nextId++) {}
280   
281 private:
282   static resourceId_t nextId;
283   MachineResource();                    // disable
284 };
285
286
287 class CPUResource : public MachineResource {
288 public:
289   int           maxNumUsers;            // MAXINT if no restriction
290   
291   /*ctor*/      CPUResource(const string& rname, int maxUsers)
292                         : MachineResource(rname), maxNumUsers(maxUsers) {}
293 };
294
295
296 //---------------------------------------------------------------------------
297 // struct InstrClassRUsage
298 // struct InstrRUsageDelta 
299 // struct InstrIssueDelta 
300 // struct InstrRUsage 
301 // 
302 // Purpose:
303 //   The first three are structures used to specify machine resource 
304 //   usages for each instruction in a machine description file:
305 //    InstrClassRUsage : resource usages common to all instrs. in a class
306 //    InstrRUsageDelta : add/delete resource usage for individual instrs. 
307 //    InstrIssueDelta  : add/delete instr. issue info for individual instrs 
308 //   
309 //   The last one (InstrRUsage) is the internal representation of
310 //   instruction resource usage constructed from the above three.
311 //---------------------------------------------------------------------------
312
313 const int MAX_NUM_SLOTS  = 32;
314 const int MAX_NUM_CYCLES = 32;
315
316 struct InstrClassRUsage {
317   InstrSchedClass schedClass;
318   int           totCycles;
319   
320   // Issue restrictions common to instructions in this class
321   unsigned int  maxNumIssue;
322   bool          isSingleIssue;
323   bool          breaksGroup;
324   cycles_t      numBubbles;
325   
326   // Feasible slots to use for instructions in this class.
327   // The size of vector S[] is `numSlots'.
328   unsigned int  numSlots;
329   unsigned int  feasibleSlots[MAX_NUM_SLOTS];
330   
331   // Resource usages common to instructions in this class.
332   // The size of vector V[] is `numRUEntries'.
333   unsigned int  numRUEntries;
334   struct {
335     resourceId_t resourceId;
336     unsigned int startCycle;
337     int          numCycles;
338   }             V[MAX_NUM_CYCLES];
339 };
340
341 struct InstrRUsageDelta {
342   MachineOpCode opCode;
343   resourceId_t  resourceId;
344   unsigned int  startCycle;
345   int           numCycles;
346 };
347
348 // Specify instruction issue restrictions for individual instructions
349 // that differ from the common rules for the class.
350 // 
351 struct InstrIssueDelta {
352   MachineOpCode opCode;
353   bool          isSingleIssue;
354   bool          breaksGroup;
355   cycles_t      numBubbles;
356 };
357
358
359 struct InstrRUsage {
360   /*ctor*/      InstrRUsage     () {}
361   /*ctor*/      InstrRUsage     (const InstrRUsage& instrRU);
362   InstrRUsage&  operator=       (const InstrRUsage& instrRU);
363   
364   bool          sameAsClass;
365   
366   // Issue restrictions for this instruction
367   bool          isSingleIssue;
368   bool          breaksGroup;
369   cycles_t      numBubbles;
370   
371   // Feasible slots to use for this instruction.
372   vector<bool>  feasibleSlots;
373   
374   // Resource usages for this instruction, with one resource vector per cycle.
375   cycles_t      numCycles;
376   vector<vector<resourceId_t> > resourcesByCycle;
377   
378 private:
379   // Conveniences for initializing this structure
380   InstrRUsage&  operator=       (const InstrClassRUsage& classRU);
381   void          addIssueDelta   (const InstrIssueDelta& delta);
382   void          addUsageDelta   (const InstrRUsageDelta& delta);
383   void          setMaxSlots     (int maxNumSlots);
384   
385   friend class MachineSchedInfo;        // give access to these functions
386 };
387
388
389 inline void
390 InstrRUsage::setMaxSlots(int maxNumSlots)
391 {
392   feasibleSlots.resize(maxNumSlots);
393 }
394
395 inline InstrRUsage&
396 InstrRUsage::operator=(const InstrRUsage& instrRU)
397 {
398   sameAsClass      = instrRU.sameAsClass;
399   isSingleIssue    = instrRU.isSingleIssue;
400   breaksGroup      = instrRU.breaksGroup; 
401   numBubbles       = instrRU.numBubbles;
402   feasibleSlots    = instrRU.feasibleSlots;
403   numCycles        = instrRU.numCycles;
404   resourcesByCycle = instrRU.resourcesByCycle;
405   return *this;
406 }
407
408 inline /*ctor*/
409 InstrRUsage::InstrRUsage(const InstrRUsage& instrRU)
410 {
411   *this = instrRU;
412 }
413
414 inline InstrRUsage&
415 InstrRUsage::operator=(const InstrClassRUsage& classRU)
416 {
417   sameAsClass   = true;
418   isSingleIssue = classRU.isSingleIssue;
419   breaksGroup   = classRU.breaksGroup; 
420   numBubbles    = classRU.numBubbles;
421   
422   for (unsigned i=0; i < classRU.numSlots; i++)
423     {
424       unsigned slot = classRU.feasibleSlots[i];
425       assert(slot < feasibleSlots.size() && "Invalid slot specified!");
426       this->feasibleSlots[slot] = true;
427     }
428   
429   this->numCycles   = classRU.totCycles;
430   this->resourcesByCycle.resize(this->numCycles);
431   
432   for (unsigned i=0; i < classRU.numRUEntries; i++)
433     for (unsigned c=classRU.V[i].startCycle, NC = c + classRU.V[i].numCycles;
434          c < NC; c++)
435       this->resourcesByCycle[c].push_back(classRU.V[i].resourceId);
436   
437   // Sort each resource usage vector by resourceId_t to speed up conflict checking
438   for (unsigned i=0; i < this->resourcesByCycle.size(); i++)
439     sort(resourcesByCycle[i].begin(), resourcesByCycle[i].end());
440   
441   return *this;
442 }
443
444
445 inline void
446 InstrRUsage::addIssueDelta(const InstrIssueDelta&  delta)
447 {
448   sameAsClass = false;
449   isSingleIssue = delta.isSingleIssue;
450   breaksGroup = delta.breaksGroup;
451   numBubbles = delta.numBubbles;
452 }
453
454
455 // Add the extra resource usage requirements specified in the delta.
456 // Note that a negative value of `numCycles' means one entry for that
457 // resource should be deleted for each cycle.
458 // 
459 inline void
460 InstrRUsage::addUsageDelta(const InstrRUsageDelta& delta)
461 {
462   int NC = delta.numCycles;
463     
464   this->sameAsClass = false;
465   
466   // resize the resources vector if more cycles are specified
467   unsigned maxCycles = this->numCycles;
468   maxCycles = max(maxCycles, delta.startCycle + abs(NC) - 1);
469   if (maxCycles > this->numCycles)
470     {
471       this->resourcesByCycle.resize(maxCycles);
472       this->numCycles = maxCycles;
473     }
474     
475   if (NC >= 0)
476     for (unsigned c=delta.startCycle, last=c+NC-1; c <= last; c++)
477       this->resourcesByCycle[c].push_back(delta.resourceId);
478   else
479     // Remove the resource from all NC cycles.
480     for (unsigned c=delta.startCycle, last=(c-NC)-1; c <= last; c++)
481       {
482         // Look for the resource backwards so we remove the last entry
483         // for that resource in each cycle.
484         vector<resourceId_t>& rvec = this->resourcesByCycle[c];
485         int r;
486         for (r = (int) rvec.size(); r >= 0; r--)
487           if (rvec[r] == delta.resourceId)
488             {// found last entry for the resource
489               rvec.erase(rvec.begin() + r);
490               break;
491             }
492         assert(r >= 0 && "Resource to remove was unused in cycle c!");
493       }
494 }
495
496
497 //---------------------------------------------------------------------------
498 // class MachineSchedInfo
499 //
500 // Purpose:
501 //   Common interface to machine information for instruction scheduling
502 //---------------------------------------------------------------------------
503
504 class MachineSchedInfo : public NonCopyableV {
505 public:
506   unsigned int  maxNumIssueTotal;
507   int   longestIssueConflict;
508   
509   int   branchMispredictPenalty;        // 4 for SPARC IIi
510   int   branchTargetUnknownPenalty;     // 2 for SPARC IIi
511   int   l1DCacheMissPenalty;            // 7 or 9 for SPARC IIi
512   int   l1ICacheMissPenalty;            // ? for SPARC IIi
513   
514   bool  inOrderLoads;                   // true for SPARC IIi
515   bool  inOrderIssue;                   // true for SPARC IIi
516   bool  inOrderExec;                    // false for most architectures
517   bool  inOrderRetire;                  // true for most architectures
518   
519 protected:
520   inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
521     assert(opCode >= 0 && opCode < (int) instrRUsages.size());
522     return instrRUsages[opCode];
523   }
524   inline const InstrClassRUsage&
525                         getClassRUsage(const InstrSchedClass& sc) const {
526     assert(sc >= 0 && sc < numSchedClasses);
527     return classRUsages[sc];
528   }
529   
530 public:
531   /*ctor*/         MachineSchedInfo     (int _numSchedClasses,
532                                          const MachineInstrInfo* _mii,
533                                          const InstrClassRUsage* _classRUsages,
534                                          const InstrRUsageDelta* _usageDeltas,
535                                          const InstrIssueDelta*  _issueDeltas,
536                                          unsigned int _numUsageDeltas,
537                                          unsigned int _numIssueDeltas);
538   /*dtor*/ virtual ~MachineSchedInfo    () {}
539   
540   inline const MachineInstrInfo& getInstrInfo() const {
541     return *mii;
542   }
543   
544   inline int            getNumSchedClasses()  const {
545     return numSchedClasses;
546   }  
547   
548   inline  unsigned int  getMaxNumIssueTotal() const {
549     return maxNumIssueTotal;
550   }
551   
552   inline  unsigned int  getMaxIssueForClass(const InstrSchedClass& sc) const {
553     assert(sc >= 0 && sc < numSchedClasses);
554     return classRUsages[sc].maxNumIssue;
555   }
556
557   inline InstrSchedClass getSchedClass  (MachineOpCode opCode) const {
558     return getInstrInfo().getSchedClass(opCode);
559   } 
560   
561   inline  bool  instrCanUseSlot         (MachineOpCode opCode,
562                                          unsigned s) const {
563     assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
564     return getInstrRUsage(opCode).feasibleSlots[s];
565   }
566   
567   inline int    getLongestIssueConflict () const {
568     return longestIssueConflict;
569   }
570   
571   inline  int   getMinIssueGap          (MachineOpCode fromOp,
572                                          MachineOpCode toOp)   const {
573     hash_map<OpCodePair,int>::const_iterator
574       I = issueGaps.find(OpCodePair(fromOp, toOp));
575     return (I == issueGaps.end())? 0 : (*I).second;
576   }
577   
578   inline const vector<MachineOpCode>*
579                 getConflictList(MachineOpCode opCode) const {
580     hash_map<MachineOpCode,vector<MachineOpCode> >::const_iterator
581       I = conflictLists.find(opCode);
582     return (I == conflictLists.end())? NULL : & (*I).second;
583   }
584   
585   inline  bool  isSingleIssue           (MachineOpCode opCode) const {
586     return getInstrRUsage(opCode).isSingleIssue;
587   }
588   
589   inline  bool  breaksIssueGroup        (MachineOpCode opCode) const {
590     return getInstrRUsage(opCode).breaksGroup;
591   }
592   
593   inline  unsigned int  numBubblesAfter (MachineOpCode opCode) const {
594     return getInstrRUsage(opCode).numBubbles;
595   }
596   
597 protected:
598   virtual void  initializeResources     ();
599   
600 private:
601   void computeInstrResources(const vector<InstrRUsage>& instrRUForClasses);
602   void computeIssueGaps(const vector<InstrRUsage>& instrRUForClasses);
603   
604 protected:
605   int                      numSchedClasses;
606   const MachineInstrInfo*  mii;
607   const InstrClassRUsage*  classRUsages;        // raw array by sclass
608   const InstrRUsageDelta*  usageDeltas;         // raw array [1:numUsageDeltas]
609   const InstrIssueDelta*   issueDeltas;         // raw array [1:numIssueDeltas]
610   unsigned int             numUsageDeltas;
611   unsigned int             numIssueDeltas;
612   
613   vector<InstrRUsage>      instrRUsages;        // indexed by opcode
614   hash_map<OpCodePair,int> issueGaps;           // indexed by opcode pair
615   hash_map<MachineOpCode,vector<MachineOpCode> >
616                            conflictLists;       // indexed by opcode
617 };
618
619
620
621 //-----------------------------------------------------------------------------
622 // class MachineRegClassInfo
623 // 
624 // Purpose:
625 //   Interface to description of machine register class (e.g., int reg class
626 //   float reg class etc)
627 // 
628 //--------------------------------------------------------------------------
629
630 class IGNode;
631
632
633 class MachineRegClassInfo {
634
635 protected:
636   
637   const unsigned RegClassID;        // integer ID of a reg class
638   const unsigned NumOfAvailRegs;    // # of avail for coloring -without SP etc.
639   const unsigned NumOfAllRegs;      // # of all registers -including SP,g0 etc.
640
641 public:
642   
643   inline unsigned getRegClassID() const { return RegClassID; }
644   inline unsigned getNumOfAvailRegs() const { return NumOfAvailRegs; }
645   inline unsigned getNumOfAllRegs() const { return NumOfAllRegs; }
646
647
648
649   // This method should find a color which is not used by neighbors
650   // (i.e., a false position in IsColorUsedArr) and 
651   virtual void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const = 0;
652
653
654   MachineRegClassInfo(const unsigned ID, const unsigned NVR, 
655                       const unsigned NAR): RegClassID(ID), NumOfAvailRegs(NVR),
656                                            NumOfAllRegs(NAR)
657   { }                         // empty constructor
658
659 };
660
661
662
663
664 //---------------------------------------------------------------------------
665 // class MachineRegInfo
666 // 
667 // Purpose:
668 //   Interface to register info of target machine
669 // 
670 //--------------------------------------------------------------------------
671
672 class LiveRangeInfo;
673 class Method;
674 class Instruction;
675 class LiveRange;
676 class AddedInstrns;
677 class MachineInstr;
678 typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
679
680 // A vector of all machine register classes
681 typedef vector<const MachineRegClassInfo *> MachineRegClassArrayType;
682
683
684 class MachineRegInfo : public NonCopyableV {
685
686 protected:
687
688   MachineRegClassArrayType MachineRegClassArr;    
689
690   
691 public:
692
693
694   inline unsigned int getNumOfRegClasses() const { 
695     return MachineRegClassArr.size(); 
696   }  
697
698   const MachineRegClassInfo *const getMachineRegClass(unsigned i) const { 
699     return MachineRegClassArr[i]; 
700   }
701
702
703   virtual unsigned getRegClassIDOfValue (const Value *const Val) const = 0;
704
705   virtual void colorArgs(const Method *const Meth, 
706                          LiveRangeInfo & LRI) const = 0;
707
708   virtual void colorCallArgs(vector<const Instruction *> & CallInstrList, 
709                              LiveRangeInfo& LRI, 
710                              AddedInstrMapType& AddedInstrMap ) const = 0;
711
712   virtual int getUnifiedRegNum(int RegClassID, int reg) const = 0;
713
714   virtual const string getUnifiedRegName(int reg) const = 0;
715
716   //virtual void printReg(const LiveRange *const LR) const =0;
717
718   MachineRegInfo() { }
719
720 };
721
722
723
724
725
726 //---------------------------------------------------------------------------
727 // class TargetMachine
728 // 
729 // Purpose:
730 //   Primary interface to machine description for the target machine.
731 // 
732 //---------------------------------------------------------------------------
733
734 class TargetMachine : public NonCopyableV {
735 public:
736   const string     TargetName;
737   const TargetData DataLayout;          // Calculates type size & alignment
738   int              optSizeForSubWordData;
739   int              minMemOpWordSize;
740   int              maxAtomicMemOpWordSize;
741   
742   // Register information.  This needs to be reorganized into a single class.
743   int           zeroRegNum;     // register that gives 0 if any (-1 if none)
744   
745 public:
746   TargetMachine(const string &targetname,
747                 unsigned char PtrSize = 8, unsigned char PtrAl = 8,
748                 unsigned char DoubleAl = 8, unsigned char FloatAl = 4,
749                 unsigned char LongAl = 8, unsigned char IntAl = 4,
750                 unsigned char ShortAl = 2, unsigned char ByteAl = 1)
751     : TargetName(targetname), DataLayout(targetname, PtrSize, PtrAl,
752                                          DoubleAl, FloatAl, LongAl, IntAl, 
753                                          ShortAl, ByteAl) { }
754   virtual ~TargetMachine() {}
755   
756   virtual const MachineInstrInfo& getInstrInfo() const = 0;
757   
758   virtual unsigned int  findOptimalStorageSize  (const Type* ty) const;
759   
760   // This really should be in the register info class
761   virtual bool          regsMayBeAliased        (unsigned int regNum1,
762                                                  unsigned int regNum2) const {
763     return (regNum1 == regNum2);
764   }
765   
766   // compileMethod - This does everything neccesary to compile a method into the
767   // built in representation.  This allows the target to have complete control
768   // over how it does compilation.  This does not emit assembly or output
769   // machine code however, this is done later.
770   //
771   virtual bool compileMethod(Method *M) = 0;
772
773   // emitAssembly - Output assembly language code (a .s file) for the specified
774   // method. The specified method must have been compiled before this may be
775   // used.
776   //
777   virtual void emitAssembly(Method *M, ostream &OutStr) {  /* todo */ }
778 };
779
780 #endif