NoDSP, DSP1, DSP2
} DspRev;
bool HasMSA;
- bool HasFP64;
protected:
+ bool HasFP64;
std::string ABI;
public:
NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
}
virtual bool hasFeature(StringRef Feature) const {
- return Feature == "mips";
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("mips", true)
+ .Case("fp64", HasFP64)
+ .Default(false);
}
virtual BuiltinVaListKind getBuiltinVaListKind() const {
return TargetInfo::VoidPtrBuiltinVaList;
if (RegNo == 1) return 5;
return -1;
}
+
+ virtual unsigned getStackAlignment() const = 0;
};
const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
Aliases = GCCRegAliases;
NumAliases = llvm::array_lengthof(GCCRegAliases);
}
+
+ virtual unsigned getStackAlignment() const {
+ return HasFP64 ? 16 : 8;
+ }
};
class Mips32EBTargetInfo : public Mips32TargetInfoBase {
virtual void setDescriptionString() {
- DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
+ if (HasFP64)
+ DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S128";
+ else
+ DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
}
public:
class Mips32ELTargetInfo : public Mips32TargetInfoBase {
virtual void setDescriptionString() {
- DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
+ if (HasFP64)
+ DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S128";
+ else
+ DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
}
public:
Aliases = GCCRegAliases;
NumAliases = llvm::array_lengthof(GCCRegAliases);
}
+
+ virtual unsigned getStackAlignment() const {
+ return 16;
+ }
};
class Mips64EBTargetInfo : public Mips64TargetInfoBase {
llvm::Type* returnAggregateInRegs(QualType RetTy, uint64_t Size) const;
llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset) const;
public:
- MipsABIInfo(CodeGenTypes &CGT, bool _IsO32) :
+ MipsABIInfo(CodeGenTypes &CGT, bool _IsO32, bool HasFP64) :
ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8),
- StackAlignInBytes(IsO32 ? 8 : 16) {}
+ StackAlignInBytes(IsO32 && !HasFP64 ? 8 : 16) {}
ABIArgInfo classifyReturnType(QualType RetTy) const;
ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const;
class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
unsigned SizeOfUnwindException;
public:
- MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32)
- : TargetCodeGenInfo(new MipsABIInfo(CGT, IsO32)),
+ MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32, const TargetInfo &Info)
+ : TargetCodeGenInfo(new MipsABIInfo(CGT, IsO32, Info.hasFeature("fp64"))),
SizeOfUnwindException(IsO32 ? 24 : 32) {}
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
return *(TheTargetCodeGenInfo = new PNaClTargetCodeGenInfo(Types));
case llvm::Triple::mips:
case llvm::Triple::mipsel:
- return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, true));
-
+ return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, true,
+ getTarget()));
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
- return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, false));
-
+ return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, false,
+ getTarget()));
case llvm::Triple::aarch64:
return *(TheTargetCodeGenInfo = new AArch64TargetCodeGenInfo(Types));
// RUN: FileCheck %s -check-prefix=64EL
// RUN: %clang -target mips64-linux-gnu -o - -emit-llvm -S %s |\
// RUN: FileCheck %s -check-prefix=64EB
+// RUN: %clang -target mipsel-linux-gnu -o - -emit-llvm -S -mfp64 %s |\
+// RUN: FileCheck %s -check-prefix=32EL-FP64
// 32EL: e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
// 32EB: E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
// 64EL: e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v64:64:64-n32:64-S128
// 64EB: E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v64:64:64-n32:64-S128
+// 32EL-FP64: e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S128
// RUN: %clang -target mipsel-unknown-linux -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32
// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64
+// RUN: %clang -target mipsel-unknown-linux -mfp64 -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32-FP64
typedef struct {
double d;
foo8(a0 + 1.0f, a1 + 2.0);
}
+// O32-LABEL: define void @foo9()
+// O32: declare void @foo10(i32, i32
+// O32-FP64-LABEL: define void @foo9()
+// O32-FP64: declare void @foo10(i32, i96
+
+typedef struct __attribute__((aligned(16))) {
+ int a;
+} S16;
+
+S16 s16;
+
+void foo10(int, S16);
+
+void foo9(void) {
+ foo10(1, s16);
+}
+