Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions clang/lib/CodeGen/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9474,6 +9474,28 @@ class SparcV8TargetCodeGenInfo : public TargetCodeGenInfo {
public:
SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
: TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}

llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const override {
int Offset;
if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
Offset = 12;
else
Offset = 8;
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
llvm::ConstantInt::get(CGF.Int32Ty, Offset));
}

llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const override {
int Offset;
if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
Offset = -12;
else
Offset = -8;
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
llvm::ConstantInt::get(CGF.Int32Ty, Offset));
}
};
} // end anonymous namespace

Expand Down Expand Up @@ -9748,6 +9770,18 @@ class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo {

bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const override;

llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const override {
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
llvm::ConstantInt::get(CGF.Int32Ty, 8));
}

llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
llvm::Value *Address) const override {
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
llvm::ConstantInt::get(CGF.Int32Ty, -8));
}
};
} // end anonymous namespace

Expand Down
25 changes: 22 additions & 3 deletions clang/test/CodeGen/builtins-sparc.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
// REQUIRES: sparc-registered-target
// RUN: %clang_cc1 -triple sparc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple sparc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple sparc64-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix CHECK-V9 %s

void test_eh_return_data_regno(void)
{
volatile int res;
res = __builtin_eh_return_data_regno(0); // CHECK: store volatile i32 24
res = __builtin_eh_return_data_regno(1); // CHECK: store volatile i32 25
res = __builtin_eh_return_data_regno(0); // CHECK,CHECKV9: store volatile i32 24
res = __builtin_eh_return_data_regno(1); // CHECK,CHECKV9: store volatile i32 25
}

void *test_extract_return_address(void)
{
// CHECK,CHECKV9: getelementptr i8, i8* %0, i32 8
return __builtin_extract_return_addr(__builtin_return_address(0));
}

struct s {
void *p;
};

struct s test_extract_struct_return_address(void)
{
struct s s;
// CHECK: getelementptr i8, i8* %0, i32 12
// CHECK-V9: getelementptr i8, i8* %0, i32 8
s.p = __builtin_extract_return_addr(__builtin_return_address(0));
return s;
}