mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
239e9806ff
Calls with inalloca are lowered by skipping all stores for arguments passed in memory and the initial stack adjustment to allocate argument memory. Now the frontend is responsible for the memory layout, and the backend doesn't have to do any work. As a result these changes are pretty minimal. Reviewers: echristo Differential Revision: http://llvm-reviews.chandlerc.com/D2637 llvm-svn: 200596
175 lines
6.0 KiB
C++
175 lines
6.0 KiB
C++
//===-- llvm/Target/TargetCallingConv.h - Calling Convention ----*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines types for working with calling-convention information.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
|
|
#define LLVM_TARGET_TARGETCALLINGCONV_H
|
|
|
|
#include "llvm/Support/DataTypes.h"
|
|
#include "llvm/Support/MathExtras.h"
|
|
#include <string>
|
|
|
|
namespace llvm {
|
|
|
|
namespace ISD {
|
|
struct ArgFlagsTy {
|
|
private:
|
|
static const uint64_t NoFlagSet = 0ULL;
|
|
static const uint64_t ZExt = 1ULL<<0; ///< Zero extended
|
|
static const uint64_t ZExtOffs = 0;
|
|
static const uint64_t SExt = 1ULL<<1; ///< Sign extended
|
|
static const uint64_t SExtOffs = 1;
|
|
static const uint64_t InReg = 1ULL<<2; ///< Passed in register
|
|
static const uint64_t InRegOffs = 2;
|
|
static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr
|
|
static const uint64_t SRetOffs = 3;
|
|
static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value
|
|
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 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 ByValSizeOffs = 32;
|
|
|
|
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 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 isByVal() const { return Flags & ByVal; }
|
|
void setByVal() { Flags |= One << ByValOffs; }
|
|
|
|
bool isInAlloca() const { return Flags & InAlloca; }
|
|
void setInAlloca() { Flags |= One << InAllocaOffs; }
|
|
|
|
bool isNest() const { return Flags & Nest; }
|
|
void setNest() { Flags |= One << NestOffs; }
|
|
|
|
bool isReturned() const { return Flags & Returned; }
|
|
void setReturned() { Flags |= One << ReturnedOffs; }
|
|
|
|
unsigned getByValAlign() const {
|
|
return (unsigned)
|
|
((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2);
|
|
}
|
|
void setByValAlign(unsigned A) {
|
|
Flags = (Flags & ~ByValAlign) |
|
|
(uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
|
|
}
|
|
|
|
bool isSplit() const { return Flags & Split; }
|
|
void setSplit() { Flags |= One << SplitOffs; }
|
|
|
|
unsigned getOrigAlign() const {
|
|
return (unsigned)
|
|
((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
|
|
}
|
|
void setOrigAlign(unsigned A) {
|
|
Flags = (Flags & ~OrigAlign) |
|
|
(uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
|
|
}
|
|
|
|
unsigned getByValSize() const {
|
|
return (unsigned)((Flags & ByValSize) >> ByValSizeOffs);
|
|
}
|
|
void setByValSize(unsigned S) {
|
|
Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
|
|
}
|
|
|
|
/// getRawBits - Represent the flags as a bunch of bits.
|
|
uint64_t getRawBits() const { return Flags; }
|
|
};
|
|
|
|
/// InputArg - This struct carries flags and type information about a
|
|
/// single incoming (formal) argument or incoming (from the perspective
|
|
/// of the caller) return value virtual register.
|
|
///
|
|
struct InputArg {
|
|
ArgFlagsTy Flags;
|
|
MVT VT;
|
|
EVT ArgVT;
|
|
bool Used;
|
|
|
|
/// Index original Function's argument.
|
|
unsigned OrigArgIndex;
|
|
|
|
/// 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, EVT argvt, bool used,
|
|
unsigned origIdx, unsigned partOffs)
|
|
: Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
|
|
VT = vt.getSimpleVT();
|
|
ArgVT = argvt;
|
|
}
|
|
};
|
|
|
|
/// OutputArg - This struct carries flags and a value for a
|
|
/// single outgoing (actual) argument or outgoing (from the perspective
|
|
/// of the caller) return value virtual register.
|
|
///
|
|
struct OutputArg {
|
|
ArgFlagsTy Flags;
|
|
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, EVT argvt, bool isfixed,
|
|
unsigned origIdx, unsigned partOffs)
|
|
: Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
|
|
PartOffset(partOffs) {
|
|
VT = vt.getSimpleVT();
|
|
ArgVT = argvt;
|
|
}
|
|
};
|
|
}
|
|
|
|
} // end llvm namespace
|
|
|
|
#endif
|