зеркало из https://github.com/microsoft/clang-1.git
Implement __builtin_dwarf_sp_column for i386 (Darwin and not), x86-64 (all),
and ARM. Implement __builtin_init_dwarf_reg_size_table for i386 (both) and x86-64 (all). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97859 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
6d1828949d
Коммит
6374c3307e
|
@ -387,6 +387,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
Value *Result = getTargetHooks().encodeReturnAddress(*this, Address);
|
||||
return RValue::get(Result);
|
||||
}
|
||||
case Builtin::BI__builtin_dwarf_sp_column: {
|
||||
const llvm::IntegerType *Ty
|
||||
= cast<llvm::IntegerType>(ConvertType(E->getType()));
|
||||
int Column = getTargetHooks().getDwarfEHStackPointer(CGM);
|
||||
if (Column == -1) {
|
||||
CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column");
|
||||
return RValue::get(llvm::UndefValue::get(Ty));
|
||||
}
|
||||
return RValue::get(llvm::ConstantInt::get(Ty, Column, true));
|
||||
}
|
||||
case Builtin::BI__builtin_init_dwarf_reg_size_table: {
|
||||
Value *Address = EmitScalarExpr(E->getArg(0));
|
||||
if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address))
|
||||
CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table");
|
||||
return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
|
||||
}
|
||||
case Builtin::BI__builtin_eh_return: {
|
||||
Value *Int = EmitScalarExpr(E->getArg(0));
|
||||
Value *Ptr = EmitScalarExpr(E->getArg(1));
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "llvm/Module.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
using namespace clang;
|
||||
|
@ -89,6 +90,10 @@ void CodeGenModule::Release() {
|
|||
EmitLLVMUsed();
|
||||
}
|
||||
|
||||
bool CodeGenModule::isTargetDarwin() const {
|
||||
return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin;
|
||||
}
|
||||
|
||||
/// ErrorUnsupported - Print out an error that codegen doesn't support the
|
||||
/// specified stmt yet.
|
||||
void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
|
||||
|
|
|
@ -204,6 +204,7 @@ public:
|
|||
const llvm::TargetData &getTargetData() const { return TheTargetData; }
|
||||
llvm::LLVMContext &getLLVMContext() { return VMContext; }
|
||||
const TargetCodeGenInfo &getTargetCodeGenInfo() const;
|
||||
bool isTargetDarwin() const;
|
||||
|
||||
/// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
|
||||
LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const;
|
||||
|
|
|
@ -328,6 +328,16 @@ public:
|
|||
|
||||
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const;
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
|
||||
// Darwin uses different dwarf register numbers for EH.
|
||||
if (CGM.isTargetDarwin()) return 5;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -568,6 +578,51 @@ void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
|
|||
}
|
||||
}
|
||||
|
||||
bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable(
|
||||
CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const {
|
||||
CodeGen::CGBuilderTy &Builder = CGF.Builder;
|
||||
llvm::LLVMContext &Context = CGF.getLLVMContext();
|
||||
|
||||
const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
|
||||
llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
|
||||
|
||||
// 0-7 are the eight integer registers; the order is different
|
||||
// on Darwin (for EH), but the range is the same.
|
||||
// 8 is %eip.
|
||||
for (unsigned I = 0, E = 9; I != E; ++I) {
|
||||
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
|
||||
Builder.CreateStore(Four8, Slot);
|
||||
}
|
||||
|
||||
if (CGF.CGM.isTargetDarwin()) {
|
||||
// 12-16 are st(0..4). Not sure why we stop at 4.
|
||||
// These have size 16, which is sizeof(long double) on
|
||||
// platforms with 8-byte alignment for that type.
|
||||
llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
|
||||
for (unsigned I = 12, E = 17; I != E; ++I) {
|
||||
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
|
||||
Builder.CreateStore(Sixteen8, Slot);
|
||||
}
|
||||
|
||||
} else {
|
||||
// 9 is %eflags, which doesn't get a size on Darwin for some
|
||||
// reason.
|
||||
Builder.CreateStore(Four8, Builder.CreateConstInBoundsGEP1_32(Address, 9));
|
||||
|
||||
// 11-16 are st(0..5). Not sure why we stop at 5.
|
||||
// These have size 12, which is sizeof(long double) on
|
||||
// platforms with 4-byte alignment for that type.
|
||||
llvm::Value *Twelve8 = llvm::ConstantInt::get(i8, 12);
|
||||
for (unsigned I = 11, E = 17; I != E; ++I) {
|
||||
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
|
||||
Builder.CreateStore(Twelve8, Slot);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// X86_64ABIInfo - The X86_64 ABI information.
|
||||
class X86_64ABIInfo : public ABIInfo {
|
||||
|
@ -656,6 +711,28 @@ public:
|
|||
class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {}
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
|
||||
return 7;
|
||||
}
|
||||
|
||||
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const {
|
||||
CodeGen::CGBuilderTy &Builder = CGF.Builder;
|
||||
llvm::LLVMContext &Context = CGF.getLLVMContext();
|
||||
|
||||
const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
|
||||
llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
|
||||
|
||||
// 0-16 are the 16 integer registers.
|
||||
// 17 is %rip.
|
||||
for (unsigned I = 0, E = 17; I != E; ++I) {
|
||||
llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
|
||||
Builder.CreateStore(Eight8, Slot);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1559,6 +1636,10 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
|
|||
public:
|
||||
ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K)
|
||||
:TargetCodeGenInfo(new ARMABIInfo(K)) {}
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
|
||||
return 13;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,23 @@ namespace clang {
|
|||
/// through such registers.
|
||||
virtual bool extendPointerWithSExt() const { return false; }
|
||||
|
||||
/// Determines the DWARF register number for the stack pointer, for
|
||||
/// exception-handling purposes. Implements __builtin_dwarf_sp_column.
|
||||
///
|
||||
/// Returns -1 if the operation is unsupported by this target.
|
||||
virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Initializes the given DWARF EH register-size table, a char*.
|
||||
/// Implements __builtin_init_dwarf_reg_size_table.
|
||||
///
|
||||
/// Returns true if the operation is unsupported by this target.
|
||||
virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
|
||||
llvm::Value *Address) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Performs the code-generation required to convert a return
|
||||
/// address as stored by the system into the actual address of the
|
||||
/// next instruction that will be executed.
|
||||
|
|
Загрузка…
Ссылка в новой задаче