move CC Lowering stuff to its own public interface
[oota-llvm.git] / include / llvm / CodeGen / CallingConvLower.h
1 //===-- llvm/CallingConvLower.h - Calling Conventions -----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Chris Lattner and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the CCState and CCValAssign classes, used for lowering
11 // and implementing calling conventions.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H
16 #define LLVM_CODEGEN_CALLINGCONVLOWER_H
17
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/ValueTypes.h"
20
21 namespace llvm {
22   class MRegisterInfo;
23   
24 /// CCState - This class holds information needed while lowering arguments and
25 /// return values.  It captures which registers are already assigned and which
26 /// stack slots are used.  It provides accessors to allocate these values.
27 class CCState {
28   unsigned StackOffset;
29   const MRegisterInfo &MRI;
30   SmallVector<uint32_t, 16> UsedRegs;
31 public:
32   CCState(const MRegisterInfo &mri);
33   
34   unsigned getNextStackOffset() const { return StackOffset; }
35
36   /// isAllocated - Return true if the specified register (or an alias) is
37   /// allocated.
38   bool isAllocated(unsigned Reg) const {
39     return UsedRegs[Reg/32] & (1 << (Reg&31));
40   }
41
42   /// getFirstUnallocated - Return the first unallocated register in the set, or
43   /// NumRegs if they are all allocated.
44   unsigned getFirstUnallocated(const unsigned *Regs, unsigned NumRegs) const {
45     for (unsigned i = 0; i != NumRegs; ++i)
46       if (!isAllocated(Regs[i]))
47         return i;
48     return NumRegs;
49   }
50   
51   /// AllocateReg - Attempt to allocate one of the specified registers.  If none
52   /// are available, return zero.  Otherwise, return the first one available,
53   /// marking it and any aliases as allocated.
54   unsigned AllocateReg(const unsigned *Regs, unsigned NumRegs) {
55     unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
56     if (FirstUnalloc == NumRegs)
57       return 0;    // Didn't find the reg.
58      
59     // Mark the register and any aliases as allocated.
60     unsigned Reg = Regs[FirstUnalloc];
61     MarkAllocated(Reg);
62     return Reg;
63   }
64   
65   /// AllocateStack - Allocate a chunk of stack space with the specified size
66   /// and alignment.
67   unsigned AllocateStack(unsigned Size, unsigned Align) {
68     assert(Align && ((Align-1) & Align) == 0); // Align is power of 2.
69     StackOffset = ((StackOffset + Align-1) & ~(Align-1));
70     unsigned Result = StackOffset;
71     StackOffset += Size;
72     return Result;
73   }
74 private:
75   /// MarkAllocated - Mark a register and all of its aliases as allocated.
76   void MarkAllocated(unsigned Reg);
77 };
78
79 /// CCValAssign - Represent assignment of one arg/retval to a location.
80 class CCValAssign {
81 public:
82   enum LocInfo {
83     Full,   // The value fills the full location.
84     SExt,   // The value is sign extended in the location.
85     ZExt,   // The value is zero extended in the location.
86     AExt    // The value is extended with undefined upper bits.
87     // TODO: a subset of the value is in the location.
88   };
89 private:
90   /// ValNo - This is the value number begin assigned (e.g. an argument number).
91   unsigned ValNo;
92   
93   /// Loc is either a stack offset or a register number.
94   unsigned Loc;
95   
96   /// isMem - True if this is a memory loc, false if it is a register loc.
97   bool isMem : 1;
98   
99   /// Information about how the value is assigned.
100   LocInfo HTP : 7;
101   
102   /// ValVT - The type of the value being assigned.
103   MVT::ValueType ValVT : 8;
104
105   /// LocVT - The type of the location being assigned to.
106   MVT::ValueType LocVT : 8;
107 public:
108     
109   static CCValAssign getReg(unsigned ValNo, MVT::ValueType ValVT,
110                             unsigned RegNo, MVT::ValueType LocVT,
111                             LocInfo HTP) {
112     CCValAssign Ret;
113     Ret.ValNo = ValNo;
114     Ret.Loc = RegNo;
115     Ret.isMem = false;
116     Ret.HTP = HTP;
117     Ret.ValVT = ValVT;
118     Ret.LocVT = LocVT;
119     return Ret;
120   }
121   static CCValAssign getMem(unsigned ValNo, MVT::ValueType ValVT,
122                             unsigned Offset, MVT::ValueType LocVT,
123                             LocInfo HTP) {
124     CCValAssign Ret;
125     Ret.ValNo = ValNo;
126     Ret.Loc = Offset;
127     Ret.isMem = true;
128     Ret.HTP = HTP;
129     Ret.ValVT = ValVT;
130     Ret.LocVT = LocVT;
131     return Ret;
132   }
133   
134   unsigned getValNo() const { return ValNo; }
135   MVT::ValueType getValVT() const { return ValVT; }
136
137   bool isRegLoc() const { return !isMem; }
138   bool isMemLoc() const { return isMem; }
139   
140   unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
141   unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
142   MVT::ValueType getLocVT() const { return LocVT; }
143   
144   LocInfo getLocInfo() const { return HTP; }
145 };
146
147 } // end namespace llvm
148
149 #endif