forked from OSchip/llvm-project
Add SystemZ support
This patch then adds all the usual platform-specific pieces for SystemZ: driver support, basic target info, register names and constraints, ABI info and vararg support. It also adds new tests to verify pre-defined macros and inline asm, and updates a test for the minimum alignment change. This version of the patch incorporates feedback from reviews by Eric Christopher and John McCall. Thanks to all reviewers! Patch by Richard Sandiford. llvm-svn: 181211
This commit is contained in:
parent
fa80642205
commit
47445073f8
|
@ -157,7 +157,16 @@ public:
|
|||
/// __builtin_va_list as defined by ARM AAPCS ABI
|
||||
/// http://infocenter.arm.com
|
||||
// /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
|
||||
AAPCSABIBuiltinVaList
|
||||
AAPCSABIBuiltinVaList,
|
||||
|
||||
// typedef struct __va_list_tag
|
||||
// {
|
||||
// long __gpr;
|
||||
// long __fpr;
|
||||
// void *__overflow_arg_area;
|
||||
// void *__reg_save_area;
|
||||
// } va_list[1];
|
||||
SystemZBuiltinVaList
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
|
@ -5980,6 +5980,80 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
|
|||
return VaListTypeDecl;
|
||||
}
|
||||
|
||||
static TypedefDecl *
|
||||
CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
|
||||
// typedef struct __va_list_tag {
|
||||
RecordDecl *VaListTagDecl;
|
||||
VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
|
||||
Context->getTranslationUnitDecl(),
|
||||
&Context->Idents.get("__va_list_tag"));
|
||||
VaListTagDecl->startDefinition();
|
||||
|
||||
const size_t NumFields = 4;
|
||||
QualType FieldTypes[NumFields];
|
||||
const char *FieldNames[NumFields];
|
||||
|
||||
// long __gpr;
|
||||
FieldTypes[0] = Context->LongTy;
|
||||
FieldNames[0] = "__gpr";
|
||||
|
||||
// long __fpr;
|
||||
FieldTypes[1] = Context->LongTy;
|
||||
FieldNames[1] = "__fpr";
|
||||
|
||||
// void *__overflow_arg_area;
|
||||
FieldTypes[2] = Context->getPointerType(Context->VoidTy);
|
||||
FieldNames[2] = "__overflow_arg_area";
|
||||
|
||||
// void *__reg_save_area;
|
||||
FieldTypes[3] = Context->getPointerType(Context->VoidTy);
|
||||
FieldNames[3] = "__reg_save_area";
|
||||
|
||||
// Create fields
|
||||
for (unsigned i = 0; i < NumFields; ++i) {
|
||||
FieldDecl *Field = FieldDecl::Create(const_cast<ASTContext &>(*Context),
|
||||
VaListTagDecl,
|
||||
SourceLocation(),
|
||||
SourceLocation(),
|
||||
&Context->Idents.get(FieldNames[i]),
|
||||
FieldTypes[i], /*TInfo=*/0,
|
||||
/*BitWidth=*/0,
|
||||
/*Mutable=*/false,
|
||||
ICIS_NoInit);
|
||||
Field->setAccess(AS_public);
|
||||
VaListTagDecl->addDecl(Field);
|
||||
}
|
||||
VaListTagDecl->completeDefinition();
|
||||
QualType VaListTagType = Context->getRecordType(VaListTagDecl);
|
||||
Context->VaListTagTy = VaListTagType;
|
||||
|
||||
// } __va_list_tag;
|
||||
TypedefDecl *VaListTagTypedefDecl
|
||||
= TypedefDecl::Create(const_cast<ASTContext &>(*Context),
|
||||
Context->getTranslationUnitDecl(),
|
||||
SourceLocation(), SourceLocation(),
|
||||
&Context->Idents.get("__va_list_tag"),
|
||||
Context->getTrivialTypeSourceInfo(VaListTagType));
|
||||
QualType VaListTagTypedefType =
|
||||
Context->getTypedefType(VaListTagTypedefDecl);
|
||||
|
||||
// typedef __va_list_tag __builtin_va_list[1];
|
||||
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
|
||||
QualType VaListTagArrayType
|
||||
= Context->getConstantArrayType(VaListTagTypedefType,
|
||||
Size, ArrayType::Normal,0);
|
||||
TypeSourceInfo *TInfo
|
||||
= Context->getTrivialTypeSourceInfo(VaListTagArrayType);
|
||||
TypedefDecl *VaListTypedefDecl
|
||||
= TypedefDecl::Create(const_cast<ASTContext &>(*Context),
|
||||
Context->getTranslationUnitDecl(),
|
||||
SourceLocation(), SourceLocation(),
|
||||
&Context->Idents.get("__builtin_va_list"),
|
||||
TInfo);
|
||||
|
||||
return VaListTypedefDecl;
|
||||
}
|
||||
|
||||
static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
|
||||
TargetInfo::BuiltinVaListKind Kind) {
|
||||
switch (Kind) {
|
||||
|
@ -5997,6 +6071,8 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
|
|||
return CreatePNaClABIBuiltinVaListDecl(Context);
|
||||
case TargetInfo::AAPCSABIBuiltinVaList:
|
||||
return CreateAAPCSABIBuiltinVaListDecl(Context);
|
||||
case TargetInfo::SystemZBuiltinVaList:
|
||||
return CreateSystemZBuiltinVaListDecl(Context);
|
||||
}
|
||||
|
||||
llvm_unreachable("Unhandled __builtin_va_list type kind");
|
||||
|
|
|
@ -4314,6 +4314,100 @@ public:
|
|||
};
|
||||
} // end anonymous namespace.
|
||||
|
||||
namespace {
|
||||
class SystemZTargetInfo : public TargetInfo {
|
||||
static const char *const GCCRegNames[];
|
||||
|
||||
public:
|
||||
SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
|
||||
TLSSupported = true;
|
||||
IntWidth = IntAlign = 32;
|
||||
LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
|
||||
PointerWidth = PointerAlign = 64;
|
||||
LongDoubleWidth = 128;
|
||||
LongDoubleAlign = 64;
|
||||
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
||||
MinGlobalAlign = 16;
|
||||
DescriptionString = "E-p:64:64:64-i1:8:16-i8:8:16-i16:16-i32:32-i64:64"
|
||||
"-f32:32-f64:64-f128:64-a0:8:16-n32:64";
|
||||
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
||||
}
|
||||
virtual void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const {
|
||||
Builder.defineMacro("__s390__");
|
||||
Builder.defineMacro("__s390x__");
|
||||
Builder.defineMacro("__zarch__");
|
||||
Builder.defineMacro("__LONG_DOUBLE_128__");
|
||||
}
|
||||
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
||||
unsigned &NumRecords) const {
|
||||
// FIXME: Implement.
|
||||
Records = 0;
|
||||
NumRecords = 0;
|
||||
}
|
||||
|
||||
virtual void getGCCRegNames(const char *const *&Names,
|
||||
unsigned &NumNames) const;
|
||||
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
||||
unsigned &NumAliases) const {
|
||||
// No aliases.
|
||||
Aliases = 0;
|
||||
NumAliases = 0;
|
||||
}
|
||||
virtual bool validateAsmConstraint(const char *&Name,
|
||||
TargetInfo::ConstraintInfo &info) const;
|
||||
virtual const char *getClobbers() const {
|
||||
// FIXME: Is this really right?
|
||||
return "";
|
||||
}
|
||||
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
||||
return TargetInfo::SystemZBuiltinVaList;
|
||||
}
|
||||
};
|
||||
|
||||
const char *const SystemZTargetInfo::GCCRegNames[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7",
|
||||
"f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15"
|
||||
};
|
||||
|
||||
void SystemZTargetInfo::getGCCRegNames(const char *const *&Names,
|
||||
unsigned &NumNames) const {
|
||||
Names = GCCRegNames;
|
||||
NumNames = llvm::array_lengthof(GCCRegNames);
|
||||
}
|
||||
|
||||
bool SystemZTargetInfo::
|
||||
validateAsmConstraint(const char *&Name,
|
||||
TargetInfo::ConstraintInfo &Info) const {
|
||||
switch (*Name) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
case 'a': // Address register
|
||||
case 'd': // Data register (equivalent to 'r')
|
||||
case 'f': // Floating-point register
|
||||
Info.setAllowsRegister();
|
||||
return true;
|
||||
|
||||
case 'I': // Unsigned 8-bit constant
|
||||
case 'J': // Unsigned 12-bit constant
|
||||
case 'K': // Signed 16-bit constant
|
||||
case 'L': // Signed 20-bit displacement (on all targets we support)
|
||||
case 'M': // 0x7fffffff
|
||||
return true;
|
||||
|
||||
case 'Q': // Memory with base and unsigned 12-bit displacement
|
||||
case 'R': // Likewise, plus an index
|
||||
case 'S': // Memory with base and signed 20-bit displacement
|
||||
case 'T': // Likewise, plus an index
|
||||
Info.setAllowsMemory();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class MSP430TargetInfo : public TargetInfo {
|
||||
static const char * const GCCRegNames[];
|
||||
|
@ -5281,6 +5375,14 @@ static TargetInfo *AllocateTarget(const std::string &T) {
|
|||
return new SparcV9TargetInfo(T);
|
||||
}
|
||||
|
||||
case llvm::Triple::systemz:
|
||||
switch (os) {
|
||||
case llvm::Triple::Linux:
|
||||
return new LinuxTargetInfo<SystemZTargetInfo>(T);
|
||||
default:
|
||||
return new SystemZTargetInfo(T);
|
||||
}
|
||||
|
||||
case llvm::Triple::tce:
|
||||
return new TCETargetInfo(T);
|
||||
|
||||
|
|
|
@ -4116,6 +4116,293 @@ void NVPTXTargetCodeGenInfo::addKernelMetadata(llvm::Function *F) {
|
|||
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SystemZ ABI Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace {
|
||||
|
||||
class SystemZABIInfo : public ABIInfo {
|
||||
public:
|
||||
SystemZABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
|
||||
|
||||
bool isPromotableIntegerType(QualType Ty) const;
|
||||
bool isCompoundType(QualType Ty) const;
|
||||
bool isFPArgumentType(QualType Ty) const;
|
||||
|
||||
ABIArgInfo classifyReturnType(QualType RetTy) const;
|
||||
ABIArgInfo classifyArgumentType(QualType ArgTy) const;
|
||||
|
||||
virtual void computeInfo(CGFunctionInfo &FI) const {
|
||||
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
|
||||
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
|
||||
it != ie; ++it)
|
||||
it->info = classifyArgumentType(it->type);
|
||||
}
|
||||
|
||||
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
CodeGenFunction &CGF) const;
|
||||
};
|
||||
|
||||
class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
public:
|
||||
SystemZTargetCodeGenInfo(CodeGenTypes &CGT)
|
||||
: TargetCodeGenInfo(new SystemZABIInfo(CGT)) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const {
|
||||
// Treat an enum type as its underlying type.
|
||||
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
|
||||
Ty = EnumTy->getDecl()->getIntegerType();
|
||||
|
||||
// Promotable integer types are required to be promoted by the ABI.
|
||||
if (Ty->isPromotableIntegerType())
|
||||
return true;
|
||||
|
||||
// 32-bit values must also be promoted.
|
||||
if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
|
||||
switch (BT->getKind()) {
|
||||
case BuiltinType::Int:
|
||||
case BuiltinType::UInt:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SystemZABIInfo::isCompoundType(QualType Ty) const {
|
||||
return Ty->isAnyComplexType() || isAggregateTypeForABI(Ty);
|
||||
}
|
||||
|
||||
bool SystemZABIInfo::isFPArgumentType(QualType Ty) const {
|
||||
if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
|
||||
switch (BT->getKind()) {
|
||||
case BuiltinType::Float:
|
||||
case BuiltinType::Double:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const RecordType *RT = Ty->getAsStructureType()) {
|
||||
const RecordDecl *RD = RT->getDecl();
|
||||
bool Found = false;
|
||||
|
||||
// If this is a C++ record, check the bases first.
|
||||
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
|
||||
for (CXXRecordDecl::base_class_const_iterator I = CXXRD->bases_begin(),
|
||||
E = CXXRD->bases_end(); I != E; ++I) {
|
||||
QualType Base = I->getType();
|
||||
|
||||
// Empty bases don't affect things either way.
|
||||
if (isEmptyRecord(getContext(), Base, true))
|
||||
continue;
|
||||
|
||||
if (Found)
|
||||
return false;
|
||||
Found = isFPArgumentType(Base);
|
||||
if (!Found)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the fields.
|
||||
for (RecordDecl::field_iterator I = RD->field_begin(),
|
||||
E = RD->field_end(); I != E; ++I) {
|
||||
const FieldDecl *FD = *I;
|
||||
|
||||
// Empty bitfields don't affect things either way.
|
||||
// Unlike isSingleElementStruct(), empty structure and array fields
|
||||
// do count. So do anonymous bitfields that aren't zero-sized.
|
||||
if (FD->isBitField() && FD->getBitWidthValue(getContext()) == 0)
|
||||
return true;
|
||||
|
||||
// Unlike isSingleElementStruct(), arrays do not count.
|
||||
// Nested isFPArgumentType structures still do though.
|
||||
if (Found)
|
||||
return false;
|
||||
Found = isFPArgumentType(FD->getType());
|
||||
if (!Found)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unlike isSingleElementStruct(), trailing padding is allowed.
|
||||
// An 8-byte aligned struct s { float f; } is passed as a double.
|
||||
return Found;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
|
||||
CodeGenFunction &CGF) const {
|
||||
// Assume that va_list type is correct; should be pointer to LLVM type:
|
||||
// struct {
|
||||
// i64 __gpr;
|
||||
// i64 __fpr;
|
||||
// i8 *__overflow_arg_area;
|
||||
// i8 *__reg_save_area;
|
||||
// };
|
||||
|
||||
// Every argument occupies 8 bytes and is passed by preference in either
|
||||
// GPRs or FPRs.
|
||||
Ty = CGF.getContext().getCanonicalType(Ty);
|
||||
ABIArgInfo AI = classifyArgumentType(Ty);
|
||||
bool InFPRs = isFPArgumentType(Ty);
|
||||
|
||||
llvm::Type *APTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty));
|
||||
bool IsIndirect = AI.isIndirect();
|
||||
unsigned UnpaddedBitSize;
|
||||
if (IsIndirect) {
|
||||
APTy = llvm::PointerType::getUnqual(APTy);
|
||||
UnpaddedBitSize = 64;
|
||||
} else
|
||||
UnpaddedBitSize = getContext().getTypeSize(Ty);
|
||||
unsigned PaddedBitSize = 64;
|
||||
assert((UnpaddedBitSize <= PaddedBitSize) && "Invalid argument size.");
|
||||
|
||||
unsigned PaddedSize = PaddedBitSize / 8;
|
||||
unsigned Padding = (PaddedBitSize - UnpaddedBitSize) / 8;
|
||||
|
||||
unsigned MaxRegs, RegCountField, RegSaveIndex, RegPadding;
|
||||
if (InFPRs) {
|
||||
MaxRegs = 4; // Maximum of 4 FPR arguments
|
||||
RegCountField = 1; // __fpr
|
||||
RegSaveIndex = 16; // save offset for f0
|
||||
RegPadding = 0; // floats are passed in the high bits of an FPR
|
||||
} else {
|
||||
MaxRegs = 5; // Maximum of 5 GPR arguments
|
||||
RegCountField = 0; // __gpr
|
||||
RegSaveIndex = 2; // save offset for r2
|
||||
RegPadding = Padding; // values are passed in the low bits of a GPR
|
||||
}
|
||||
|
||||
llvm::Value *RegCountPtr =
|
||||
CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr");
|
||||
llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count");
|
||||
llvm::Type *IndexTy = RegCount->getType();
|
||||
llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
|
||||
llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
|
||||
"fits_in_regs");
|
||||
|
||||
llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
|
||||
llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
|
||||
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
|
||||
CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
|
||||
|
||||
// Emit code to load the value if it was passed in registers.
|
||||
CGF.EmitBlock(InRegBlock);
|
||||
|
||||
// Work out the address of an argument register.
|
||||
llvm::Value *PaddedSizeV = llvm::ConstantInt::get(IndexTy, PaddedSize);
|
||||
llvm::Value *ScaledRegCount =
|
||||
CGF.Builder.CreateMul(RegCount, PaddedSizeV, "scaled_reg_count");
|
||||
llvm::Value *RegBase =
|
||||
llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize + RegPadding);
|
||||
llvm::Value *RegOffset =
|
||||
CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset");
|
||||
llvm::Value *RegSaveAreaPtr =
|
||||
CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr");
|
||||
llvm::Value *RegSaveArea =
|
||||
CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area");
|
||||
llvm::Value *RawRegAddr =
|
||||
CGF.Builder.CreateGEP(RegSaveArea, RegOffset, "raw_reg_addr");
|
||||
llvm::Value *RegAddr =
|
||||
CGF.Builder.CreateBitCast(RawRegAddr, APTy, "reg_addr");
|
||||
|
||||
// Update the register count
|
||||
llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
|
||||
llvm::Value *NewRegCount =
|
||||
CGF.Builder.CreateAdd(RegCount, One, "reg_count");
|
||||
CGF.Builder.CreateStore(NewRegCount, RegCountPtr);
|
||||
CGF.EmitBranch(ContBlock);
|
||||
|
||||
// Emit code to load the value if it was passed in memory.
|
||||
CGF.EmitBlock(InMemBlock);
|
||||
|
||||
// Work out the address of a stack argument.
|
||||
llvm::Value *OverflowArgAreaPtr =
|
||||
CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
|
||||
llvm::Value *OverflowArgArea =
|
||||
CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area");
|
||||
llvm::Value *PaddingV = llvm::ConstantInt::get(IndexTy, Padding);
|
||||
llvm::Value *RawMemAddr =
|
||||
CGF.Builder.CreateGEP(OverflowArgArea, PaddingV, "raw_mem_addr");
|
||||
llvm::Value *MemAddr =
|
||||
CGF.Builder.CreateBitCast(RawMemAddr, APTy, "mem_addr");
|
||||
|
||||
// Update overflow_arg_area_ptr pointer
|
||||
llvm::Value *NewOverflowArgArea =
|
||||
CGF.Builder.CreateGEP(OverflowArgArea, PaddedSizeV, "overflow_arg_area");
|
||||
CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
|
||||
CGF.EmitBranch(ContBlock);
|
||||
|
||||
// Return the appropriate result.
|
||||
CGF.EmitBlock(ContBlock);
|
||||
llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(APTy, 2, "va_arg.addr");
|
||||
ResAddr->addIncoming(RegAddr, InRegBlock);
|
||||
ResAddr->addIncoming(MemAddr, InMemBlock);
|
||||
|
||||
if (IsIndirect)
|
||||
return CGF.Builder.CreateLoad(ResAddr, "indirect_arg");
|
||||
|
||||
return ResAddr;
|
||||
}
|
||||
|
||||
|
||||
ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
|
||||
if (RetTy->isVoidType())
|
||||
return ABIArgInfo::getIgnore();
|
||||
if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
return (isPromotableIntegerType(RetTy) ?
|
||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||
}
|
||||
|
||||
ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
|
||||
// Handle the generic C++ ABI.
|
||||
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT))
|
||||
return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
|
||||
|
||||
// Integers and enums are extended to full register width.
|
||||
if (isPromotableIntegerType(Ty))
|
||||
return ABIArgInfo::getExtend();
|
||||
|
||||
// Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.
|
||||
uint64_t Size = getContext().getTypeSize(Ty);
|
||||
if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
|
||||
// Handle small structures.
|
||||
if (const RecordType *RT = Ty->getAs<RecordType>()) {
|
||||
// Structures with flexible arrays have variable length, so really
|
||||
// fail the size test above.
|
||||
const RecordDecl *RD = RT->getDecl();
|
||||
if (RD->hasFlexibleArrayMember())
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
|
||||
// The structure is passed as an unextended integer, a float, or a double.
|
||||
llvm::Type *PassTy;
|
||||
if (isFPArgumentType(Ty)) {
|
||||
assert(Size == 32 || Size == 64);
|
||||
if (Size == 32)
|
||||
PassTy = llvm::Type::getFloatTy(getVMContext());
|
||||
else
|
||||
PassTy = llvm::Type::getDoubleTy(getVMContext());
|
||||
} else
|
||||
PassTy = llvm::IntegerType::get(getVMContext(), Size);
|
||||
return ABIArgInfo::getDirect(PassTy);
|
||||
}
|
||||
|
||||
// Non-structure compounds are passed indirectly.
|
||||
if (isCompoundType(Ty))
|
||||
return ABIArgInfo::getIndirect(0);
|
||||
|
||||
return ABIArgInfo::getDirect(0);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MBlaze ABI Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -4860,6 +5147,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
|
|||
case llvm::Triple::msp430:
|
||||
return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types));
|
||||
|
||||
case llvm::Triple::systemz:
|
||||
return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types));
|
||||
|
||||
case llvm::Triple::tce:
|
||||
return *(TheTargetCodeGenInfo = new TCETargetCodeGenInfo(Types));
|
||||
|
||||
|
|
|
@ -1146,6 +1146,15 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
|
|||
"ppc64-redhat-linux"
|
||||
};
|
||||
|
||||
static const char *const SystemZLibDirs[] = { "/lib64", "/lib" };
|
||||
static const char *const SystemZTriples[] = {
|
||||
"s390x-linux-gnu",
|
||||
"s390x-unknown-linux-gnu",
|
||||
"s390x-ibm-linux-gnu",
|
||||
"s390x-suse-linux",
|
||||
"s390x-redhat-linux"
|
||||
};
|
||||
|
||||
switch (TargetTriple.getArch()) {
|
||||
case llvm::Triple::aarch64:
|
||||
LibDirs.append(AArch64LibDirs, AArch64LibDirs
|
||||
|
@ -1246,6 +1255,12 @@ Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
|
|||
MultiarchTripleAliases.append(
|
||||
PPCTriples, PPCTriples + llvm::array_lengthof(PPCTriples));
|
||||
break;
|
||||
case llvm::Triple::systemz:
|
||||
LibDirs.append(
|
||||
SystemZLibDirs, SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs));
|
||||
TripleAliases.append(
|
||||
SystemZTriples, SystemZTriples + llvm::array_lengthof(SystemZTriples));
|
||||
break;
|
||||
|
||||
default:
|
||||
// By default, just rely on the standard lib directories and the original
|
||||
|
@ -1349,7 +1364,8 @@ static bool findTargetMultiarchSuffix(std::string &Suffix,
|
|||
}
|
||||
|
||||
if (TargetArch == llvm::Triple::x86_64 ||
|
||||
TargetArch == llvm::Triple::ppc64)
|
||||
TargetArch == llvm::Triple::ppc64 ||
|
||||
TargetArch == llvm::Triple::systemz)
|
||||
Suffix = "/64";
|
||||
else
|
||||
Suffix = "/32";
|
||||
|
|
|
@ -545,6 +545,9 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) {
|
|||
if (Triple.isOSDarwin())
|
||||
return true;
|
||||
return false;
|
||||
|
||||
case llvm::Triple::systemz:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5820,6 +5823,9 @@ void gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
LastPICArg->getOption().matches(options::OPT_fpie))) {
|
||||
CmdArgs.push_back("-KPIC");
|
||||
}
|
||||
} else if (getToolChain().getArch() == llvm::Triple::systemz) {
|
||||
// At the moment we always produce z10 code.
|
||||
CmdArgs.push_back("-march=z10");
|
||||
}
|
||||
|
||||
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
|
||||
|
@ -5951,6 +5957,8 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
else
|
||||
CmdArgs.push_back("elf64ltsmip");
|
||||
}
|
||||
else if (ToolChain.getArch() == llvm::Triple::systemz)
|
||||
CmdArgs.push_back("elf64_s390");
|
||||
else
|
||||
CmdArgs.push_back("elf_x86_64");
|
||||
|
||||
|
@ -5997,7 +6005,8 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
}
|
||||
else if (ToolChain.getArch() == llvm::Triple::ppc)
|
||||
CmdArgs.push_back("/lib/ld.so.1");
|
||||
else if (ToolChain.getArch() == llvm::Triple::ppc64)
|
||||
else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
|
||||
ToolChain.getArch() == llvm::Triple::systemz)
|
||||
CmdArgs.push_back("/lib64/ld64.so.1");
|
||||
else
|
||||
CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2");
|
||||
|
|
|
@ -3,12 +3,19 @@
|
|||
// Should be 3 hello strings, two global (of different sizes), the rest are
|
||||
// shared.
|
||||
|
||||
// CHECK: @align = global i8 [[ALIGN:[0-9]+]]
|
||||
// CHECK: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
|
||||
// CHECK: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)
|
||||
// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align 1
|
||||
// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align 1
|
||||
// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align [[ALIGN]]
|
||||
// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align [[ALIGN]]
|
||||
// CHECK: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) }
|
||||
// CHECK: @x = global [3 x i8] c"ola", align 1
|
||||
// CHECK: @x = global [3 x i8] c"ola", align [[ALIGN]]
|
||||
|
||||
#if defined(__s390x__)
|
||||
unsigned char align = 2;
|
||||
#else
|
||||
unsigned char align = 1;
|
||||
#endif
|
||||
|
||||
void bar(const char *);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
// RUN: %clang_cc1 -triple mipsel %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple powerpc %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple powerpc64 %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple s390x %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple sparc %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple sparcv9 %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
// RUN: %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
unsigned int gi;
|
||||
unsigned long gl;
|
||||
|
||||
void test_store_m(unsigned int i) {
|
||||
asm("st %1, %0" : "=m" (gi) : "r" (i));
|
||||
// CHECK: define void @test_store_m(i32 zeroext %i)
|
||||
// CHECK: call void asm "st $1, $0", "=*m,r"(i32* @gi, i32 %i)
|
||||
}
|
||||
|
||||
void test_store_Q(unsigned int i) {
|
||||
asm("st %1, %0" : "=Q" (gi) : "r" (i));
|
||||
// CHECK: define void @test_store_Q(i32 zeroext %i)
|
||||
// CHECK: call void asm "st $1, $0", "=*Q,r"(i32* @gi, i32 %i)
|
||||
}
|
||||
|
||||
void test_store_R(unsigned int i) {
|
||||
asm("st %1, %0" : "=R" (gi) : "r" (i));
|
||||
// CHECK: define void @test_store_R(i32 zeroext %i)
|
||||
// CHECK: call void asm "st $1, $0", "=*R,r"(i32* @gi, i32 %i)
|
||||
}
|
||||
|
||||
void test_store_S(unsigned int i) {
|
||||
asm("st %1, %0" : "=S" (gi) : "r" (i));
|
||||
// CHECK: define void @test_store_S(i32 zeroext %i)
|
||||
// CHECK: call void asm "st $1, $0", "=*S,r"(i32* @gi, i32 %i)
|
||||
}
|
||||
|
||||
void test_store_T(unsigned int i) {
|
||||
asm("st %1, %0" : "=T" (gi) : "r" (i));
|
||||
// CHECK: define void @test_store_T(i32 zeroext %i)
|
||||
// CHECK: call void asm "st $1, $0", "=*T,r"(i32* @gi, i32 %i)
|
||||
}
|
||||
|
||||
int test_load_m() {
|
||||
unsigned int i;
|
||||
asm("l %0, %1" : "=r" (i) : "m" (gi));
|
||||
return i;
|
||||
// CHECK: define signext i32 @test_load_m()
|
||||
// CHECK: call i32 asm "l $0, $1", "=r,*m"(i32* @gi)
|
||||
}
|
||||
|
||||
int test_load_Q() {
|
||||
unsigned int i;
|
||||
asm("l %0, %1" : "=r" (i) : "Q" (gi));
|
||||
return i;
|
||||
// CHECK: define signext i32 @test_load_Q()
|
||||
// CHECK: call i32 asm "l $0, $1", "=r,*Q"(i32* @gi)
|
||||
}
|
||||
|
||||
int test_load_R() {
|
||||
unsigned int i;
|
||||
asm("l %0, %1" : "=r" (i) : "R" (gi));
|
||||
return i;
|
||||
// CHECK: define signext i32 @test_load_R()
|
||||
// CHECK: call i32 asm "l $0, $1", "=r,*R"(i32* @gi)
|
||||
}
|
||||
|
||||
int test_load_S() {
|
||||
unsigned int i;
|
||||
asm("l %0, %1" : "=r" (i) : "S" (gi));
|
||||
return i;
|
||||
// CHECK: define signext i32 @test_load_S()
|
||||
// CHECK: call i32 asm "l $0, $1", "=r,*S"(i32* @gi)
|
||||
}
|
||||
|
||||
int test_load_T() {
|
||||
unsigned int i;
|
||||
asm("l %0, %1" : "=r" (i) : "T" (gi));
|
||||
return i;
|
||||
// CHECK: define signext i32 @test_load_T()
|
||||
// CHECK: call i32 asm "l $0, $1", "=r,*T"(i32* @gi)
|
||||
}
|
||||
|
||||
void test_mI(unsigned char *c) {
|
||||
asm volatile("cli %0, %1" :: "Q" (*c), "I" (100));
|
||||
// CHECK: define void @test_mI(i8* %c)
|
||||
// CHECK: call void asm sideeffect "cli $0, $1", "*Q,I"(i8* %c, i32 100)
|
||||
}
|
||||
|
||||
unsigned int test_dJa(unsigned int i, unsigned int j) {
|
||||
asm("sll %0, %2(%3)" : "=d" (i) : "0" (i), "J" (1000), "a" (j));
|
||||
return i;
|
||||
// CHECK: define zeroext i32 @test_dJa(i32 zeroext %i, i32 zeroext %j)
|
||||
// CHECK: call i32 asm "sll $0, $2($3)", "=d,0,J,a"(i32 %i, i32 1000, i32 %j)
|
||||
}
|
||||
|
||||
unsigned long test_rK(unsigned long i) {
|
||||
asm("aghi %0, %2" : "=r" (i) : "0" (i), "K" (-30000));
|
||||
return i;
|
||||
// CHECK: define i64 @test_rK(i64 %i)
|
||||
// CHECK: call i64 asm "aghi $0, $2", "=r,0,K"(i64 %i, i32 -30000)
|
||||
}
|
||||
|
||||
unsigned long test_rL(unsigned long i) {
|
||||
asm("sllg %0, %1, %2" : "=r" (i) : "r" (i), "L" (500000));
|
||||
return i;
|
||||
// CHECK: define i64 @test_rL(i64 %i)
|
||||
// CHECK: call i64 asm "sllg $0, $1, $2", "=r,r,L"(i64 %i, i32 500000)
|
||||
}
|
||||
|
||||
void test_M() {
|
||||
asm volatile("#FOO %0" :: "M"(0x7fffffff));
|
||||
// CHECK: define void @test_M()
|
||||
// CHECK: call void asm sideeffect "#FOO $0", "M"(i32 2147483647)
|
||||
}
|
||||
|
||||
float test_f32(float f, float g) {
|
||||
asm("aebr %0, %2" : "=f" (f) : "0" (f), "f" (g));
|
||||
return f;
|
||||
// CHECK: define float @test_f32(float %f, float %g)
|
||||
// CHECK: call float asm "aebr $0, $2", "=f,0,f"(float %f, float %g)
|
||||
}
|
||||
|
||||
double test_f64(double f, double g) {
|
||||
asm("adbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
|
||||
return f;
|
||||
// CHECK: define double @test_f64(double %f, double %g)
|
||||
// CHECK: call double asm "adbr $0, $2", "=f,0,f"(double %f, double %g)
|
||||
}
|
||||
|
||||
long double test_f128(long double f, long double g) {
|
||||
asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
|
||||
return f;
|
||||
// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* byval nocapture, fp128* byval nocapture)
|
||||
// CHECK: %f = load fp128* %0
|
||||
// CHECK: %g = load fp128* %1
|
||||
// CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
|
||||
// CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
|
||||
}
|
|
@ -2177,6 +2177,98 @@
|
|||
// PPC-LINUX:#define __powerpc__ 1
|
||||
// PPC-LINUX:#define __ppc__ 1
|
||||
//
|
||||
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=s390x-none-none -fno-signed-char < /dev/null | FileCheck -check-prefix S390X %s
|
||||
//
|
||||
// S390X:#define __CHAR16_TYPE__ unsigned short
|
||||
// S390X:#define __CHAR32_TYPE__ unsigned int
|
||||
// S390X:#define __CHAR_BIT__ 8
|
||||
// S390X:#define __CHAR_UNSIGNED__ 1
|
||||
// S390X:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// S390X:#define __DBL_DIG__ 15
|
||||
// S390X:#define __DBL_EPSILON__ 2.2204460492503131e-16
|
||||
// S390X:#define __DBL_HAS_DENORM__ 1
|
||||
// S390X:#define __DBL_HAS_INFINITY__ 1
|
||||
// S390X:#define __DBL_HAS_QUIET_NAN__ 1
|
||||
// S390X:#define __DBL_MANT_DIG__ 53
|
||||
// S390X:#define __DBL_MAX_10_EXP__ 308
|
||||
// S390X:#define __DBL_MAX_EXP__ 1024
|
||||
// S390X:#define __DBL_MAX__ 1.7976931348623157e+308
|
||||
// S390X:#define __DBL_MIN_10_EXP__ (-307)
|
||||
// S390X:#define __DBL_MIN_EXP__ (-1021)
|
||||
// S390X:#define __DBL_MIN__ 2.2250738585072014e-308
|
||||
// S390X:#define __DECIMAL_DIG__ 36
|
||||
// S390X:#define __FLT_DENORM_MIN__ 1.40129846e-45F
|
||||
// S390X:#define __FLT_DIG__ 6
|
||||
// S390X:#define __FLT_EPSILON__ 1.19209290e-7F
|
||||
// S390X:#define __FLT_EVAL_METHOD__ 0
|
||||
// S390X:#define __FLT_HAS_DENORM__ 1
|
||||
// S390X:#define __FLT_HAS_INFINITY__ 1
|
||||
// S390X:#define __FLT_HAS_QUIET_NAN__ 1
|
||||
// S390X:#define __FLT_MANT_DIG__ 24
|
||||
// S390X:#define __FLT_MAX_10_EXP__ 38
|
||||
// S390X:#define __FLT_MAX_EXP__ 128
|
||||
// S390X:#define __FLT_MAX__ 3.40282347e+38F
|
||||
// S390X:#define __FLT_MIN_10_EXP__ (-37)
|
||||
// S390X:#define __FLT_MIN_EXP__ (-125)
|
||||
// S390X:#define __FLT_MIN__ 1.17549435e-38F
|
||||
// S390X:#define __FLT_RADIX__ 2
|
||||
// S390X:#define __INT16_TYPE__ short
|
||||
// S390X:#define __INT32_TYPE__ int
|
||||
// S390X:#define __INT64_C_SUFFIX__ L
|
||||
// S390X:#define __INT64_TYPE__ long long int
|
||||
// S390X:#define __INT8_TYPE__ char
|
||||
// S390X:#define __INTMAX_MAX__ 9223372036854775807LL
|
||||
// S390X:#define __INTMAX_TYPE__ long long int
|
||||
// S390X:#define __INTMAX_WIDTH__ 64
|
||||
// S390X:#define __INTPTR_TYPE__ long int
|
||||
// S390X:#define __INTPTR_WIDTH__ 64
|
||||
// S390X:#define __INT_MAX__ 2147483647
|
||||
// S390X:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
|
||||
// S390X:#define __LDBL_DIG__ 33
|
||||
// S390X:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
|
||||
// S390X:#define __LDBL_HAS_DENORM__ 1
|
||||
// S390X:#define __LDBL_HAS_INFINITY__ 1
|
||||
// S390X:#define __LDBL_HAS_QUIET_NAN__ 1
|
||||
// S390X:#define __LDBL_MANT_DIG__ 113
|
||||
// S390X:#define __LDBL_MAX_10_EXP__ 4932
|
||||
// S390X:#define __LDBL_MAX_EXP__ 16384
|
||||
// S390X:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
|
||||
// S390X:#define __LDBL_MIN_10_EXP__ (-4931)
|
||||
// S390X:#define __LDBL_MIN_EXP__ (-16381)
|
||||
// S390X:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
|
||||
// S390X:#define __LONG_LONG_MAX__ 9223372036854775807LL
|
||||
// S390X:#define __LONG_MAX__ 9223372036854775807L
|
||||
// S390X:#define __NO_INLINE__ 1
|
||||
// S390X:#define __POINTER_WIDTH__ 64
|
||||
// S390X:#define __PTRDIFF_TYPE__ long int
|
||||
// S390X:#define __PTRDIFF_WIDTH__ 64
|
||||
// S390X:#define __SCHAR_MAX__ 127
|
||||
// S390X:#define __SHRT_MAX__ 32767
|
||||
// S390X:#define __SIG_ATOMIC_WIDTH__ 32
|
||||
// S390X:#define __SIZEOF_DOUBLE__ 8
|
||||
// S390X:#define __SIZEOF_FLOAT__ 4
|
||||
// S390X:#define __SIZEOF_INT__ 4
|
||||
// S390X:#define __SIZEOF_LONG_DOUBLE__ 16
|
||||
// S390X:#define __SIZEOF_LONG_LONG__ 8
|
||||
// S390X:#define __SIZEOF_LONG__ 8
|
||||
// S390X:#define __SIZEOF_POINTER__ 8
|
||||
// S390X:#define __SIZEOF_PTRDIFF_T__ 8
|
||||
// S390X:#define __SIZEOF_SHORT__ 2
|
||||
// S390X:#define __SIZEOF_SIZE_T__ 8
|
||||
// S390X:#define __SIZEOF_WCHAR_T__ 4
|
||||
// S390X:#define __SIZEOF_WINT_T__ 4
|
||||
// S390X:#define __SIZE_TYPE__ long unsigned int
|
||||
// S390X:#define __SIZE_WIDTH__ 64
|
||||
// S390X:#define __UINTMAX_TYPE__ long long unsigned int
|
||||
// S390X:#define __USER_LABEL_PREFIX__ _
|
||||
// S390X:#define __WCHAR_MAX__ 2147483647
|
||||
// S390X:#define __WCHAR_TYPE__ int
|
||||
// S390X:#define __WCHAR_WIDTH__ 32
|
||||
// S390X:#define __WINT_TYPE__ int
|
||||
// S390X:#define __WINT_WIDTH__ 32
|
||||
// S390X:#define __s390__ 1
|
||||
// S390X:#define __s390x__ 1
|
||||
//
|
||||
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc-none-none < /dev/null | FileCheck -check-prefix SPARC %s
|
||||
//
|
||||
// SPARC-NOT:#define _LP64
|
||||
|
|
|
@ -528,6 +528,113 @@
|
|||
// PPC:INTMAX_C_(0) 0LL
|
||||
// PPC:UINTMAX_C_(0) 0ULL
|
||||
//
|
||||
// RUN: %clang_cc1 -E -ffreestanding -triple=s390x-none-none %s | FileCheck -check-prefix S390X %s
|
||||
//
|
||||
// S390X:typedef signed long long int int64_t;
|
||||
// S390X:typedef unsigned long long int uint64_t;
|
||||
// S390X:typedef int64_t int_least64_t;
|
||||
// S390X:typedef uint64_t uint_least64_t;
|
||||
// S390X:typedef int64_t int_fast64_t;
|
||||
// S390X:typedef uint64_t uint_fast64_t;
|
||||
//
|
||||
// S390X:typedef signed int int32_t;
|
||||
// S390X:typedef unsigned int uint32_t;
|
||||
// S390X:typedef int32_t int_least32_t;
|
||||
// S390X:typedef uint32_t uint_least32_t;
|
||||
// S390X:typedef int32_t int_fast32_t;
|
||||
// S390X:typedef uint32_t uint_fast32_t;
|
||||
//
|
||||
// S390X:typedef signed short int16_t;
|
||||
// S390X:typedef unsigned short uint16_t;
|
||||
// S390X:typedef int16_t int_least16_t;
|
||||
// S390X:typedef uint16_t uint_least16_t;
|
||||
// S390X:typedef int16_t int_fast16_t;
|
||||
// S390X:typedef uint16_t uint_fast16_t;
|
||||
//
|
||||
// S390X:typedef signed char int8_t;
|
||||
// S390X:typedef unsigned char uint8_t;
|
||||
// S390X:typedef int8_t int_least8_t;
|
||||
// S390X:typedef uint8_t uint_least8_t;
|
||||
// S390X:typedef int8_t int_fast8_t;
|
||||
// S390X:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// S390X:typedef int64_t intptr_t;
|
||||
// S390X:typedef uint64_t uintptr_t;
|
||||
//
|
||||
// S390X:typedef long long int intmax_t;
|
||||
// S390X:typedef long long unsigned int uintmax_t;
|
||||
//
|
||||
// S390X:INT8_MAX_ 127
|
||||
// S390X:INT8_MIN_ (-127 -1)
|
||||
// S390X:UINT8_MAX_ 255
|
||||
// S390X:INT_LEAST8_MIN_ (-127 -1)
|
||||
// S390X:INT_LEAST8_MAX_ 127
|
||||
// S390X:UINT_LEAST8_MAX_ 255
|
||||
// S390X:INT_FAST8_MIN_ (-127 -1)
|
||||
// S390X:INT_FAST8_MAX_ 127
|
||||
// S390X:UINT_FAST8_MAX_ 255
|
||||
//
|
||||
// S390X:INT16_MAX_ 32767
|
||||
// S390X:INT16_MIN_ (-32767 -1)
|
||||
// S390X:UINT16_MAX_ 65535
|
||||
// S390X:INT_LEAST16_MIN_ (-32767 -1)
|
||||
// S390X:INT_LEAST16_MAX_ 32767
|
||||
// S390X:UINT_LEAST16_MAX_ 65535
|
||||
// S390X:INT_FAST16_MIN_ (-32767 -1)
|
||||
// S390X:INT_FAST16_MAX_ 32767
|
||||
// S390X:UINT_FAST16_MAX_ 65535
|
||||
//
|
||||
// S390X:INT32_MAX_ 2147483647
|
||||
// S390X:INT32_MIN_ (-2147483647 -1)
|
||||
// S390X:UINT32_MAX_ 4294967295U
|
||||
// S390X:INT_LEAST32_MIN_ (-2147483647 -1)
|
||||
// S390X:INT_LEAST32_MAX_ 2147483647
|
||||
// S390X:UINT_LEAST32_MAX_ 4294967295U
|
||||
// S390X:INT_FAST32_MIN_ (-2147483647 -1)
|
||||
// S390X:INT_FAST32_MAX_ 2147483647
|
||||
// S390X:UINT_FAST32_MAX_ 4294967295U
|
||||
//
|
||||
// S390X:INT64_MAX_ 9223372036854775807L
|
||||
// S390X:INT64_MIN_ (-9223372036854775807LL -1)
|
||||
// S390X:UINT64_MAX_ 18446744073709551615UL
|
||||
// S390X:INT_LEAST64_MIN_ (-9223372036854775807LL -1)
|
||||
// S390X:INT_LEAST64_MAX_ 9223372036854775807L
|
||||
// S390X:UINT_LEAST64_MAX_ 18446744073709551615UL
|
||||
// S390X:INT_FAST64_MIN_ (-9223372036854775807LL -1)
|
||||
// S390X:INT_FAST64_MAX_ 9223372036854775807L
|
||||
// S390X:UINT_FAST64_MAX_ 18446744073709551615UL
|
||||
//
|
||||
// S390X:INTPTR_MIN_ (-9223372036854775807LL -1)
|
||||
// S390X:INTPTR_MAX_ 9223372036854775807L
|
||||
// S390X:UINTPTR_MAX_ 18446744073709551615UL
|
||||
// S390X:PTRDIFF_MIN_ (-9223372036854775807LL -1)
|
||||
// S390X:PTRDIFF_MAX_ 9223372036854775807L
|
||||
// S390X:SIZE_MAX_ 18446744073709551615UL
|
||||
//
|
||||
// S390X:INTMAX_MIN_ (-9223372036854775807LL -1)
|
||||
// S390X:INTMAX_MAX_ 9223372036854775807L
|
||||
// S390X:UINTMAX_MAX_ 18446744073709551615UL
|
||||
//
|
||||
// S390X:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// S390X:SIG_ATOMIC_MAX_ 2147483647
|
||||
// S390X:WINT_MIN_ (-2147483647 -1)
|
||||
// S390X:WINT_MAX_ 2147483647
|
||||
//
|
||||
// S390X:WCHAR_MAX_ 2147483647
|
||||
// S390X:WCHAR_MIN_ (-2147483647 -1)
|
||||
//
|
||||
// S390X:INT8_C_(0) 0
|
||||
// S390X:UINT8_C_(0) 0U
|
||||
// S390X:INT16_C_(0) 0
|
||||
// S390X:UINT16_C_(0) 0U
|
||||
// S390X:INT32_C_(0) 0
|
||||
// S390X:UINT32_C_(0) 0U
|
||||
// S390X:INT64_C_(0) 0L
|
||||
// S390X:UINT64_C_(0) 0UL
|
||||
//
|
||||
// S390X:INTMAX_C_(0) 0L
|
||||
// S390X:UINTMAX_C_(0) 0UL
|
||||
//
|
||||
// RUN: %clang_cc1 -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s
|
||||
//
|
||||
// SPARC:typedef signed long long int int64_t;
|
||||
|
|
Loading…
Reference in New Issue