#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
#define LLVM_TARGET_TARGETCALLINGCONV_H
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <string>
+#include <limits.h>
+
namespace llvm {
namespace ISD {
static const uint64_t ByValOffs = 4;
static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
static const uint64_t NestOffs = 5;
- static const uint64_t ByValAlign = 0xFULL << 6; //< Struct alignment
- static const uint64_t ByValAlignOffs = 6;
- static const uint64_t Split = 1ULL << 10;
- static const uint64_t SplitOffs = 10;
+ static const uint64_t Returned = 1ULL<<6; ///< Always returned
+ static const uint64_t ReturnedOffs = 6;
+ static const uint64_t ByValAlign = 0xFULL<<7; ///< Struct alignment
+ static const uint64_t ByValAlignOffs = 7;
+ static const uint64_t Split = 1ULL<<11;
+ static const uint64_t SplitOffs = 11;
+ static const uint64_t InAlloca = 1ULL<<12; ///< Passed with inalloca
+ static const uint64_t InAllocaOffs = 12;
static const uint64_t OrigAlign = 0x1FULL<<27;
static const uint64_t OrigAlignOffs = 27;
- static const uint64_t ByValSize = 0xffffffffULL << 32; //< Struct size
+ static const uint64_t ByValSize = 0x3fffffffULL<<32; ///< Struct size
static const uint64_t ByValSizeOffs = 32;
+ static const uint64_t InConsecutiveRegsLast = 0x1ULL<<62; ///< Struct size
+ static const uint64_t InConsecutiveRegsLastOffs = 62;
+ static const uint64_t InConsecutiveRegs = 0x1ULL<<63; ///< Struct size
+ static const uint64_t InConsecutiveRegsOffs = 63;
- static const uint64_t One = 1ULL; //< 1 of this type, for shifts
+ static const uint64_t One = 1ULL; ///< 1 of this type, for shifts
uint64_t Flags;
public:
ArgFlagsTy() : Flags(0) { }
- bool isZExt() const { return Flags & ZExt; }
- void setZExt() { Flags |= One << ZExtOffs; }
+ bool isZExt() const { return Flags & ZExt; }
+ void setZExt() { Flags |= One << ZExtOffs; }
+
+ bool isSExt() const { return Flags & SExt; }
+ void setSExt() { Flags |= One << SExtOffs; }
+
+ bool isInReg() const { return Flags & InReg; }
+ void setInReg() { Flags |= One << InRegOffs; }
+
+ bool isSRet() const { return Flags & SRet; }
+ void setSRet() { Flags |= One << SRetOffs; }
- bool isSExt() const { return Flags & SExt; }
- void setSExt() { Flags |= One << SExtOffs; }
+ bool isByVal() const { return Flags & ByVal; }
+ void setByVal() { Flags |= One << ByValOffs; }
- bool isInReg() const { return Flags & InReg; }
- void setInReg() { Flags |= One << InRegOffs; }
+ bool isInAlloca() const { return Flags & InAlloca; }
+ void setInAlloca() { Flags |= One << InAllocaOffs; }
- bool isSRet() const { return Flags & SRet; }
- void setSRet() { Flags |= One << SRetOffs; }
+ bool isNest() const { return Flags & Nest; }
+ void setNest() { Flags |= One << NestOffs; }
- bool isByVal() const { return Flags & ByVal; }
- void setByVal() { Flags |= One << ByValOffs; }
+ bool isReturned() const { return Flags & Returned; }
+ void setReturned() { Flags |= One << ReturnedOffs; }
- bool isNest() const { return Flags & Nest; }
- void setNest() { Flags |= One << NestOffs; }
+ bool isInConsecutiveRegs() const { return Flags & InConsecutiveRegs; }
+ void setInConsecutiveRegs() { Flags |= One << InConsecutiveRegsOffs; }
+
+ bool isInConsecutiveRegsLast() const { return Flags & InConsecutiveRegsLast; }
+ void setInConsecutiveRegsLast() { Flags |= One << InConsecutiveRegsLastOffs; }
unsigned getByValAlign() const {
return (unsigned)
Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
}
- /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4".
- std::string getArgFlagsString();
-
/// getRawBits - Represent the flags as a bunch of bits.
uint64_t getRawBits() const { return Flags; }
};
///
struct InputArg {
ArgFlagsTy Flags;
- EVT VT;
+ MVT VT;
+ EVT ArgVT;
bool Used;
+ /// Index original Function's argument.
+ unsigned OrigArgIndex;
+ /// Sentinel value for implicit machine-level input arguments.
+ static const unsigned NoArgIndex = UINT_MAX;
+
+ /// Offset in bytes of current input value relative to the beginning of
+ /// original argument. E.g. if argument was splitted into four 32 bit
+ /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
+ unsigned PartOffset;
+
InputArg() : VT(MVT::Other), Used(false) {}
- InputArg(ArgFlagsTy flags, EVT vt, bool used)
- : Flags(flags), VT(vt), Used(used) {
- assert(VT.isSimple() &&
- "InputArg value type must be Simple!");
+ InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
+ unsigned origIdx, unsigned partOffs)
+ : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
+ VT = vt.getSimpleVT();
+ ArgVT = argvt;
+ }
+
+ bool isOrigArg() const {
+ return OrigArgIndex != NoArgIndex;
+ }
+
+ unsigned getOrigArgIndex() const {
+ assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
+ return OrigArgIndex;
}
};
///
struct OutputArg {
ArgFlagsTy Flags;
- EVT VT;
+ MVT VT;
+ EVT ArgVT;
/// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
bool IsFixed;
+ /// Index original Function's argument.
+ unsigned OrigArgIndex;
+
+ /// Offset in bytes of current output value relative to the beginning of
+ /// original argument. E.g. if argument was splitted into four 32 bit
+ /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
+ unsigned PartOffset;
+
OutputArg() : IsFixed(false) {}
- OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed)
- : Flags(flags), VT(vt), IsFixed(isfixed) {
- assert(VT.isSimple() &&
- "OutputArg value type must be Simple!");
+ OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed,
+ unsigned origIdx, unsigned partOffs)
+ : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
+ PartOffset(partOffs) {
+ VT = vt.getSimpleVT();
+ ArgVT = argvt;
}
};
-}
+} // namespace ISD
-} // end llvm namespace
+} // namespace llvm
#endif