19eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// 29eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// 39eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// The LLVM Compiler Infrastructure 49eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// 59eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// This file is distributed under the University of Illinois Open Source 69eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// License. See LICENSE.TXT for details. 79eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar// 89eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar//===----------------------------------------------------------------------===// 99eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar 109eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar#ifndef CLANG_CODEGEN_ABIINFO_H 119eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar#define CLANG_CODEGEN_ABIINFO_H 129eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar 13c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov#include "clang/AST/Type.h" 14958c53c369b2e96b7638f170a3fcb4ff43382ff1Chris Lattner#include "llvm/Type.h" 15c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov 1688c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbarnamespace llvm { 17c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov class Value; 18f21efe9088a0b3eda1209d1706529f6cb2073092Benjamin Kramer class LLVMContext; 19ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner class TargetData; 2088c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar} 2188c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar 229eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbarnamespace clang { 236bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar class ASTContext; 246bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar 256bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar namespace CodeGen { 266bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar class CGFunctionInfo; 27b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar class CodeGenFunction; 28ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner class CodeGenTypes; 296bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar } 306bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar 312eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner // FIXME: All of this stuff should be part of the target interface 322eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner // somehow. It is currently here because it is not clear how to factor 332eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner // the targets to support this, since the Targets currently live in a 342eb9cdd5922c6fe48af185bee1988dabb5bd644eChris Lattner // layer below types n'stuff. 359eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar 369eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar /// ABIArgInfo - Helper class to encapsulate information about how a 379eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar /// specific C type should be passed to or returned from a function. 389eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar class ABIArgInfo { 399eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar public: 409eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar enum Kind { 41117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// Direct - Pass the argument directly using the normal converted LLVM 42117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// type, or by coercing to another specified type stored in 43117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// 'CoerceToType'). If an offset is specified (in UIntData), then the 44117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// argument passed is offset by some number of bytes in the memory 45f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka /// representation. A dummy argument is emitted before the real argument 46f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka /// if the specified type stored in "PaddingType" is not zero. 47117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner Direct, 48117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner 49117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// Extend - Valid only for integer argument types. Same as 'direct' 50117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// but also emit a zero/sign extension attribute. 51117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner Extend, 52117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner 53117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// Indirect - Pass the argument indirectly via a hidden pointer 54117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// with the specified alignment (0 indicates default alignment). 55117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner Indirect, 56117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner 57117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// Ignore - Ignore the argument (treat as void). Useful for void and 58117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// empty structs. 59117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner Ignore, 60117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner 61117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// Expand - Only valid for aggregate argument types. The structure should 62117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// be expanded into consecutive arguments for its constituent fields. 63117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// Currently expand is only allowed on structures whose fields 64117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner /// are all scalar types or are themselves expandable types. 65117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner Expand, 66c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov 670bcc52114e37a8d152d9a05095ee7f7687c9aa94Daniel Dunbar KindFirst=Direct, KindLast=Expand 689eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar }; 69c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov 709eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar private: 719eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar Kind TheKind; 729cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *TypeData; 73f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka llvm::Type *PaddingType; // Currently allowed only for Direct. 749eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar unsigned UIntData; 75cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar bool BoolData0; 76cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar bool BoolData1; 77b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola bool InReg; 78c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov 79b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR, 8057bc51cfec0f39376ad78c03432a12137cd26c2aRafael Espindola llvm::Type* P) 81f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0), 82b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola BoolData1(B1), InReg(IR) {} 830a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson 849eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar public: 850bcc52114e37a8d152d9a05095ee7f7687c9aa94Daniel Dunbar ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} 8688c2fa96be989571b4afb6229f0ef5a3ef4450cbDaniel Dunbar 87f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0, 88f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka llvm::Type *Padding = 0) { 89b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Direct, T, Offset, false, false, false, Padding); 90b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola } 91b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola static ABIArgInfo getDirectInReg(llvm::Type *T) { 92b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Direct, T, 0, false, false, true, 0); 9346327aaf031529be2cf8bb21bc76d7a5ae0d43cdDaniel Dunbar } 949cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner static ABIArgInfo getExtend(llvm::Type *T = 0) { 95b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Extend, T, 0, false, false, false, 0); 96b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola } 97b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola static ABIArgInfo getExtendInReg(llvm::Type *T = 0) { 98b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Extend, T, 0, false, false, true, 0); 99cc6fa88666ca2f287df4a600eb31a4087bab9c13Anton Korobeynikov } 1009eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar static ABIArgInfo getIgnore() { 101b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Ignore, 0, 0, false, false, false, 0); 1029eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar } 103cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true 104cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar , bool Realign = false) { 105b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, 0); 106b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola } 107b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true 108b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola , bool Realign = false) { 109b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, 0); 1109eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar } 1119eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar static ABIArgInfo getExpand() { 112b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return ABIArgInfo(Expand, 0, 0, false, false, false, 0); 1139eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar } 114c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov 1159eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar Kind getKind() const { return TheKind; } 11646327aaf031529be2cf8bb21bc76d7a5ae0d43cdDaniel Dunbar bool isDirect() const { return TheKind == Direct; } 117cc6fa88666ca2f287df4a600eb31a4087bab9c13Anton Korobeynikov bool isExtend() const { return TheKind == Extend; } 1189eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar bool isIgnore() const { return TheKind == Ignore; } 11911e383aa491a23ebd4a49688a09984c5e16a2e34Daniel Dunbar bool isIndirect() const { return TheKind == Indirect; } 1209eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar bool isExpand() const { return TheKind == Expand; } 121c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov 122800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner bool canHaveCoerceToType() const { 123800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner return TheKind == Direct || TheKind == Extend; 124800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner } 1259cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 126800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner // Direct/Extend accessors 127117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner unsigned getDirectOffset() const { 128117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 129117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner return UIntData; 130117e3f4cd4d6ea41c3202da8729f94168c5c8239Chris Lattner } 131f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka 132f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka llvm::Type *getPaddingType() const { 133f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka return PaddingType; 134f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka } 135f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka 1369cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *getCoerceToType() const { 137800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner assert(canHaveCoerceToType() && "Invalid kind!"); 1389eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar return TypeData; 1399eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar } 1409cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 1419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner void setCoerceToType(llvm::Type *T) { 142800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner assert(canHaveCoerceToType() && "Invalid kind!"); 143800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner TypeData = T; 144800588fd230d2c37ddce8fbf4a3881352715d700Chris Lattner } 1459cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 146b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola bool getInReg() const { 147b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); 148b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola return InReg; 149b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola } 150b48280ba1790122cd3fa6e17c88ecd6a4571a4ebRafael Espindola 1510a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson // Indirect accessors 15211e383aa491a23ebd4a49688a09984c5e16a2e34Daniel Dunbar unsigned getIndirectAlign() const { 15311e383aa491a23ebd4a49688a09984c5e16a2e34Daniel Dunbar assert(TheKind == Indirect && "Invalid kind!"); 1549eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar return UIntData; 1559eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar } 1566f7279bf98e31356306386b2c200820a76b491cfDaniel Dunbar 1570a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson bool getIndirectByVal() const { 1580a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson assert(TheKind == Indirect && "Invalid kind!"); 159cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar return BoolData0; 160cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar } 161cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar 162cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar bool getIndirectRealign() const { 163cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar assert(TheKind == Indirect && "Invalid kind!"); 164cf3b6f2504596812db1fcef0df8ce5b3449c4aacDaniel Dunbar return BoolData1; 1650a8f847e97f40cce51dc69051b964732333dc028Anders Carlsson } 1669cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 1676f7279bf98e31356306386b2c200820a76b491cfDaniel Dunbar void dump() const; 1689eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar }; 1699eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar 1709eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar /// ABIInfo - Target specific hooks for defining how a type should be 1719eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar /// passed or returned from functions. 1729eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar class ABIInfo { 1739eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar public: 174ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner CodeGen::CodeGenTypes &CGT; 1759cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 176ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner ABIInfo(CodeGen::CodeGenTypes &cgt) : CGT(cgt) {} 1779eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar virtual ~ABIInfo(); 1789cac4942b920d4c5514e71949e3062ed626bfbdfMichael J. Spencer 179ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner ASTContext &getContext() const; 180ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner llvm::LLVMContext &getVMContext() const; 181ea0443212e7ec6ff82e2f174e8e948a6eb0e0876Chris Lattner const llvm::TargetData &getTargetData() const; 1826bad2658b48264629db595f944a3fbe07f61b4e9Daniel Dunbar 183ee5dcd064a811edc90f6c1fb31a837b6c961fed7Chris Lattner virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const = 0; 184b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar 185b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar /// EmitVAArg - Emit the target dependent code to load a value of 186b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar /// \arg Ty from the va_list pointed to by \arg VAListAddr. 187c4a59eb306efeb4bffa3cefecd1e6392fc5c4144Anton Korobeynikov 188b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar // FIXME: This is a gaping layering violation if we wanted to drop 189b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar // the ABI information any lower than CodeGen. Of course, for 190b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar // VAArg handling it has to be at this level; there is no way to 191b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar // abstract this out. 192b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, 193b53e3e71383233ebb68a6a736cbe8af6d8065700Daniel Dunbar CodeGen::CodeGenFunction &CGF) const = 0; 1949eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar }; 1959eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar} // end namespace clang 1969eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar 1979eb5c6d3242d85359b2d669564c5e2826efb1931Daniel Dunbar#endif 198