mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 00:55:49 +03:00
93 lines
2.9 KiB
C++
93 lines
2.9 KiB
C++
//===-- abi-ppc64.cpp -----------------------------------------------------===//
|
|
//
|
|
// LDC ? the LLVM D compiler
|
|
//
|
|
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
|
// file for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// The ABI implementation used for 32/64 bit big-endian PowerPC targets.
|
|
//
|
|
// The System V Application Binary Interface PowerPC Processor Supplement can be
|
|
// found here:
|
|
// http://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf
|
|
//
|
|
// The PowerOpen 64bit ABI can be found here:
|
|
// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
|
|
// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.pdf
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "gen/abi.h"
|
|
#include "gen/abi-generic.h"
|
|
#include "gen/abi-ppc.h"
|
|
#include "gen/dvalue.h"
|
|
#include "gen/irstate.h"
|
|
#include "gen/llvmhelpers.h"
|
|
#include "gen/tollvm.h"
|
|
|
|
struct PPCTargetABI : TargetABI {
|
|
ExplicitByvalRewrite byvalRewrite;
|
|
IntegerRewrite integerRewrite;
|
|
const bool Is64Bit;
|
|
|
|
explicit PPCTargetABI(const bool Is64Bit) : Is64Bit(Is64Bit) {}
|
|
|
|
bool returnInArg(TypeFunction *tf) override {
|
|
if (tf->isref) {
|
|
return false;
|
|
}
|
|
|
|
// Return structs and static arrays on the stack. The latter is needed
|
|
// because otherwise LLVM tries to actually return the array in a number
|
|
// of physical registers, which leads, depending on the target, to
|
|
// either horrendous codegen or backend crashes.
|
|
Type *rt = tf->next->toBasetype();
|
|
return (rt->ty == Tstruct || rt->ty == Tsarray);
|
|
}
|
|
|
|
bool passByVal(Type *t) override {
|
|
TY ty = t->toBasetype()->ty;
|
|
return ty == Tstruct || ty == Tsarray;
|
|
}
|
|
|
|
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
|
|
// EXPLICIT PARAMETERS
|
|
for (auto arg : fty.args) {
|
|
if (!arg->byref) {
|
|
rewriteArgument(fty, *arg);
|
|
}
|
|
}
|
|
}
|
|
|
|
void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override {
|
|
Type *ty = arg.type->toBasetype();
|
|
|
|
if (ty->ty == Tstruct || ty->ty == Tsarray) {
|
|
if (canRewriteAsInt(ty, Is64Bit)) {
|
|
if (!IntegerRewrite::isObsoleteFor(arg.ltype)) {
|
|
arg.rewrite = &integerRewrite;
|
|
arg.ltype = integerRewrite.type(arg.type);
|
|
}
|
|
} else {
|
|
// these types are passed byval:
|
|
// the caller allocates a copy and then passes a pointer to the copy
|
|
arg.rewrite = &byvalRewrite;
|
|
arg.ltype = byvalRewrite.type(arg.type);
|
|
|
|
// the copy is treated as a local variable of the callee
|
|
// hence add the NoAlias and NoCapture attributes
|
|
arg.attrs.clear()
|
|
.add(LLAttribute::NoAlias)
|
|
.add(LLAttribute::NoCapture)
|
|
.addAlignment(byvalRewrite.alignment(arg.type));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// The public getter for abi.cpp
|
|
TargetABI *getPPCTargetABI(bool Is64Bit) {
|
|
return new PPCTargetABI(Is64Bit);
|
|
}
|