CallingConvLower.h revision 234353
1249997Swkoszek//===-- llvm/CallingConvLower.h - Calling Conventions -----------*- C++ -*-===// 2273645Sian// 3249997Swkoszek// The LLVM Compiler Infrastructure 4249997Swkoszek// 5249997Swkoszek// This file is distributed under the University of Illinois Open Source 6249997Swkoszek// License. See LICENSE.TXT for details. 7249997Swkoszek// 8249997Swkoszek//===----------------------------------------------------------------------===// 9249997Swkoszek// 10249997Swkoszek// This file declares the CCState and CCValAssign classes, used for lowering 11249997Swkoszek// and implementing calling conventions. 12249997Swkoszek// 13249997Swkoszek//===----------------------------------------------------------------------===// 14249997Swkoszek 15249997Swkoszek#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H 16249997Swkoszek#define LLVM_CODEGEN_CALLINGCONVLOWER_H 17249997Swkoszek 18249997Swkoszek#include "llvm/ADT/SmallVector.h" 19249997Swkoszek#include "llvm/CodeGen/MachineFunction.h" 20249997Swkoszek#include "llvm/CodeGen/ValueTypes.h" 21249997Swkoszek#include "llvm/Target/TargetCallingConv.h" 22249997Swkoszek#include "llvm/CallingConv.h" 23249997Swkoszek 24249997Swkoszeknamespace llvm { 25249997Swkoszek class TargetRegisterInfo; 26249997Swkoszek class TargetMachine; 27250015Swkoszek class CCState; 28250015Swkoszek 29249997Swkoszek/// CCValAssign - Represent assignment of one arg/retval to a location. 30249997Swkoszekclass CCValAssign { 31249997Swkoszekpublic: 32249997Swkoszek enum LocInfo { 33249997Swkoszek Full, // The value fills the full location. 34249997Swkoszek SExt, // The value is sign extended in the location. 35249997Swkoszek ZExt, // The value is zero extended in the location. 36249997Swkoszek AExt, // The value is extended with undefined upper bits. 37249997Swkoszek BCvt, // The value is bit-converted in the location. 38249997Swkoszek VExt, // The value is vector-widened in the location. 39249997Swkoszek // FIXME: Not implemented yet. Code that uses AExt to mean 40249997Swkoszek // vector-widen should be fixed to use VExt instead. 41249997Swkoszek Indirect // The location contains pointer to the value. 42249997Swkoszek // TODO: a subset of the value is in the location. 43249997Swkoszek }; 44249997Swkoszekprivate: 45249997Swkoszek /// ValNo - This is the value number begin assigned (e.g. an argument number). 46249997Swkoszek unsigned ValNo; 47249997Swkoszek 48249997Swkoszek /// Loc is either a stack offset or a register number. 49249997Swkoszek unsigned Loc; 50249997Swkoszek 51249997Swkoszek /// isMem - True if this is a memory loc, false if it is a register loc. 52249997Swkoszek bool isMem : 1; 53249997Swkoszek 54249997Swkoszek /// isCustom - True if this arg/retval requires special handling. 55249997Swkoszek bool isCustom : 1; 56249997Swkoszek 57249997Swkoszek /// Information about how the value is assigned. 58249997Swkoszek LocInfo HTP : 6; 59249997Swkoszek 60249997Swkoszek /// ValVT - The type of the value being assigned. 61249997Swkoszek MVT ValVT; 62249997Swkoszek 63249997Swkoszek /// LocVT - The type of the location being assigned to. 64249997Swkoszek MVT LocVT; 65249997Swkoszekpublic: 66249997Swkoszek 67249997Swkoszek static CCValAssign getReg(unsigned ValNo, MVT ValVT, 68249997Swkoszek unsigned RegNo, MVT LocVT, 69249997Swkoszek LocInfo HTP) { 70249997Swkoszek CCValAssign Ret; 71249997Swkoszek Ret.ValNo = ValNo; 72249997Swkoszek Ret.Loc = RegNo; 73249997Swkoszek Ret.isMem = false; 74249997Swkoszek Ret.isCustom = false; 75249997Swkoszek Ret.HTP = HTP; 76249997Swkoszek Ret.ValVT = ValVT; 77249997Swkoszek Ret.LocVT = LocVT; 78249997Swkoszek return Ret; 79249997Swkoszek } 80249997Swkoszek 81249997Swkoszek static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, 82249997Swkoszek unsigned RegNo, MVT LocVT, 83249997Swkoszek LocInfo HTP) { 84273645Sian CCValAssign Ret; 85273645Sian Ret = getReg(ValNo, ValVT, RegNo, LocVT, HTP); 86249997Swkoszek Ret.isCustom = true; 87249997Swkoszek return Ret; 88249997Swkoszek } 89249997Swkoszek 90249997Swkoszek static CCValAssign getMem(unsigned ValNo, MVT ValVT, 91249997Swkoszek unsigned Offset, MVT LocVT, 92273645Sian LocInfo HTP) { 93249997Swkoszek CCValAssign Ret; 94273645Sian Ret.ValNo = ValNo; 95249997Swkoszek Ret.Loc = Offset; 96249997Swkoszek Ret.isMem = true; 97249997Swkoszek Ret.isCustom = false; 98249997Swkoszek Ret.HTP = HTP; 99249997Swkoszek Ret.ValVT = ValVT; 100249997Swkoszek Ret.LocVT = LocVT; 101249997Swkoszek return Ret; 102249997Swkoszek } 103249997Swkoszek 104273645Sian static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, 105249997Swkoszek unsigned Offset, MVT LocVT, 106249997Swkoszek LocInfo HTP) { 107249997Swkoszek CCValAssign Ret; 108249997Swkoszek Ret = getMem(ValNo, ValVT, Offset, LocVT, HTP); 109249997Swkoszek Ret.isCustom = true; 110249997Swkoszek return Ret; 111273645Sian } 112249997Swkoszek 113249997Swkoszek unsigned getValNo() const { return ValNo; } 114249997Swkoszek MVT getValVT() const { return ValVT; } 115249997Swkoszek 116249997Swkoszek bool isRegLoc() const { return !isMem; } 117249997Swkoszek bool isMemLoc() const { return isMem; } 118249997Swkoszek 119249997Swkoszek bool needsCustom() const { return isCustom; } 120249997Swkoszek 121249997Swkoszek unsigned getLocReg() const { assert(isRegLoc()); return Loc; } 122249997Swkoszek unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; } 123249997Swkoszek MVT getLocVT() const { return LocVT; } 124249997Swkoszek 125249997Swkoszek LocInfo getLocInfo() const { return HTP; } 126249997Swkoszek bool isExtInLoc() const { 127273645Sian return (HTP == AExt || HTP == SExt || HTP == ZExt); 128273645Sian } 129273645Sian 130273645Sian}; 131273645Sian 132249997Swkoszek/// CCAssignFn - This function assigns a location for Val, updating State to 133249997Swkoszek/// reflect the change. It returns 'true' if it failed to handle Val. 134249997Swkoszektypedef bool CCAssignFn(unsigned ValNo, MVT ValVT, 135249997Swkoszek MVT LocVT, CCValAssign::LocInfo LocInfo, 136249997Swkoszek ISD::ArgFlagsTy ArgFlags, CCState &State); 137249997Swkoszek 138249997Swkoszek/// CCCustomFn - This function assigns a location for Val, possibly updating 139249997Swkoszek/// all args to reflect changes and indicates if it handled it. It must set 140249997Swkoszek/// isCustom if it handles the arg and returns true. 141249997Swkoszektypedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT, 142273645Sian MVT &LocVT, CCValAssign::LocInfo &LocInfo, 143273645Sian ISD::ArgFlagsTy &ArgFlags, CCState &State); 144273645Sian 145273645Sian/// ParmContext - This enum tracks whether calling convention lowering is in 146273645Sian/// the context of prologue or call generation. Not all backends make use of 147273645Sian/// this information. 148273645Siantypedef enum { Unknown, Prologue, Call } ParmContext; 149273645Sian 150273645Sian/// CCState - This class holds information needed while lowering arguments and 151273645Sian/// return values. It captures which registers are already assigned and which 152273645Sian/// stack slots are used. It provides accessors to allocate these values. 153273645Sianclass CCState { 154273645Sianprivate: 155273645Sian CallingConv::ID CallingConv; 156273645Sian bool IsVarArg; 157273645Sian MachineFunction &MF; 158273645Sian const TargetMachine &TM; 159273645Sian const TargetRegisterInfo &TRI; 160273645Sian SmallVector<CCValAssign, 16> &Locs; 161273645Sian LLVMContext &Context; 162273645Sian 163273645Sian unsigned StackOffset; 164273645Sian SmallVector<uint32_t, 16> UsedRegs; 165273645Sian unsigned FirstByValReg; 166273645Sian bool FirstByValRegValid; 167273645Sian 168273645Sianprotected: 169273645Sian ParmContext CallOrPrologue; 170273645Sian 171273645Sianpublic: 172273645Sian CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, 173273645Sian const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs, 174273645Sian LLVMContext &C); 175273645Sian 176273645Sian void addLoc(const CCValAssign &V) { 177273645Sian Locs.push_back(V); 178273645Sian } 179273645Sian 180273645Sian LLVMContext &getContext() const { return Context; } 181273645Sian const TargetMachine &getTarget() const { return TM; } 182273645Sian MachineFunction &getMachineFunction() const { return MF; } 183273645Sian CallingConv::ID getCallingConv() const { return CallingConv; } 184273645Sian bool isVarArg() const { return IsVarArg; } 185273645Sian 186273645Sian unsigned getNextStackOffset() const { return StackOffset; } 187273645Sian 188273645Sian /// isAllocated - Return true if the specified register (or an alias) is 189273645Sian /// allocated. 190273645Sian bool isAllocated(unsigned Reg) const { 191273645Sian return UsedRegs[Reg/32] & (1 << (Reg&31)); 192249997Swkoszek } 193249997Swkoszek 194249997Swkoszek /// AnalyzeFormalArguments - Analyze an array of argument values, 195249997Swkoszek /// incorporating info about the formals into this state. 196249997Swkoszek void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, 197249997Swkoszek CCAssignFn Fn); 198249997Swkoszek 199249997Swkoszek /// AnalyzeReturn - Analyze the returned values of a return, 200249997Swkoszek /// incorporating info about the result values into this state. 201249997Swkoszek void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, 202249997Swkoszek CCAssignFn Fn); 203249997Swkoszek 204249997Swkoszek /// CheckReturn - Analyze the return values of a function, returning 205249997Swkoszek /// true if the return can be performed without sret-demotion, and 206249997Swkoszek /// false otherwise. 207273645Sian bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, 208273645Sian CCAssignFn Fn); 209273645Sian 210249997Swkoszek /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, 211249997Swkoszek /// incorporating info about the passed values into this state. 212249997Swkoszek void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, 213249997Swkoszek CCAssignFn Fn); 214249997Swkoszek 215249997Swkoszek /// AnalyzeCallOperands - Same as above except it takes vectors of types 216249997Swkoszek /// and argument flags. 217249997Swkoszek void AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs, 218273645Sian SmallVectorImpl<ISD::ArgFlagsTy> &Flags, 219273645Sian CCAssignFn Fn); 220249997Swkoszek 221249997Swkoszek /// AnalyzeCallResult - Analyze the return values of a call, 222249997Swkoszek /// incorporating info about the passed values into this state. 223249997Swkoszek void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, 224249997Swkoszek CCAssignFn Fn); 225249997Swkoszek 226249997Swkoszek /// AnalyzeCallResult - Same as above except it's specialized for calls which 227249997Swkoszek /// produce a single value. 228249997Swkoszek void AnalyzeCallResult(MVT VT, CCAssignFn Fn); 229249997Swkoszek 230249997Swkoszek /// getFirstUnallocated - Return the first unallocated register in the set, or 231249997Swkoszek /// NumRegs if they are all allocated. 232249997Swkoszek unsigned getFirstUnallocated(const uint16_t *Regs, unsigned NumRegs) const { 233249997Swkoszek for (unsigned i = 0; i != NumRegs; ++i) 234249997Swkoszek if (!isAllocated(Regs[i])) 235249997Swkoszek return i; 236249997Swkoszek return NumRegs; 237249997Swkoszek } 238249997Swkoszek 239249997Swkoszek /// AllocateReg - Attempt to allocate one register. If it is not available, 240249997Swkoszek /// return zero. Otherwise, return the register, marking it and any aliases 241249997Swkoszek /// as allocated. 242249997Swkoszek unsigned AllocateReg(unsigned Reg) { 243249997Swkoszek if (isAllocated(Reg)) return 0; 244249997Swkoszek MarkAllocated(Reg); 245249997Swkoszek return Reg; 246249997Swkoszek } 247249997Swkoszek 248249997Swkoszek /// Version of AllocateReg with extra register to be shadowed. 249249997Swkoszek unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) { 250249997Swkoszek if (isAllocated(Reg)) return 0; 251249997Swkoszek MarkAllocated(Reg); 252249997Swkoszek MarkAllocated(ShadowReg); 253249997Swkoszek return Reg; 254249997Swkoszek } 255249997Swkoszek 256273645Sian /// AllocateReg - Attempt to allocate one of the specified registers. If none 257249997Swkoszek /// are available, return zero. Otherwise, return the first one available, 258273645Sian /// marking it and any aliases as allocated. 259273645Sian unsigned AllocateReg(const uint16_t *Regs, unsigned NumRegs) { 260273645Sian unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); 261273645Sian if (FirstUnalloc == NumRegs) 262273645Sian return 0; // Didn't find the reg. 263273645Sian 264273645Sian // Mark the register and any aliases as allocated. 265273645Sian unsigned Reg = Regs[FirstUnalloc]; 266249997Swkoszek MarkAllocated(Reg); 267249997Swkoszek return Reg; 268249997Swkoszek } 269249997Swkoszek 270249997Swkoszek /// Version of AllocateReg with list of registers to be shadowed. 271249997Swkoszek unsigned AllocateReg(const uint16_t *Regs, const uint16_t *ShadowRegs, 272249997Swkoszek unsigned NumRegs) { 273249997Swkoszek unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs); 274249997Swkoszek if (FirstUnalloc == NumRegs) 275249997Swkoszek return 0; // Didn't find the reg. 276249997Swkoszek 277249997Swkoszek // Mark the register and any aliases as allocated. 278249997Swkoszek unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc]; 279249997Swkoszek MarkAllocated(Reg); 280249997Swkoszek MarkAllocated(ShadowReg); 281249997Swkoszek return Reg; 282249997Swkoszek } 283249997Swkoszek 284249997Swkoszek /// AllocateStack - Allocate a chunk of stack space with the specified size 285249997Swkoszek /// and alignment. 286249997Swkoszek unsigned AllocateStack(unsigned Size, unsigned Align) { 287249997Swkoszek assert(Align && ((Align-1) & Align) == 0); // Align is power of 2. 288249997Swkoszek StackOffset = ((StackOffset + Align-1) & ~(Align-1)); 289249997Swkoszek unsigned Result = StackOffset; 290249997Swkoszek StackOffset += Size; 291249997Swkoszek return Result; 292249997Swkoszek } 293249997Swkoszek 294249997Swkoszek /// Version of AllocateStack with extra register to be shadowed. 295249997Swkoszek unsigned AllocateStack(unsigned Size, unsigned Align, unsigned ShadowReg) { 296249997Swkoszek MarkAllocated(ShadowReg); 297249997Swkoszek return AllocateStack(Size, Align); 298249997Swkoszek } 299249997Swkoszek 300249997Swkoszek // HandleByVal - Allocate a stack slot large enough to pass an argument by 301249997Swkoszek // value. The size and alignment information of the argument is encoded in its 302249997Swkoszek // parameter attribute. 303249997Swkoszek void HandleByVal(unsigned ValNo, MVT ValVT, 304249997Swkoszek MVT LocVT, CCValAssign::LocInfo LocInfo, 305249997Swkoszek int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); 306249997Swkoszek 307249997Swkoszek // First GPR that carries part of a byval aggregate that's split 308249997Swkoszek // between registers and memory. 309249997Swkoszek unsigned getFirstByValReg() const { return FirstByValRegValid ? FirstByValReg : 0; } 310249997Swkoszek void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; } 311249997Swkoszek void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; } 312249997Swkoszek bool isFirstByValRegValid() const { return FirstByValRegValid; } 313249997Swkoszek 314249997Swkoszek ParmContext getCallOrPrologue() const { return CallOrPrologue; } 315249997Swkoszek 316249997Swkoszekprivate: 317249997Swkoszek /// MarkAllocated - Mark a register and all of its aliases as allocated. 318249997Swkoszek void MarkAllocated(unsigned Reg); 319249997Swkoszek}; 320249997Swkoszek 321249997Swkoszek 322249997Swkoszek 323249997Swkoszek} // end namespace llvm 324249997Swkoszek 325249997Swkoszek#endif 326249997Swkoszek