[mips] Align the stack to 16-bytes for -mfp64.
authorAkira Hatanaka <ahatanaka@mips.com>
Tue, 29 Oct 2013 19:00:35 +0000 (19:00 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Tue, 29 Oct 2013 19:00:35 +0000 (19:00 +0000)
llvm-svn: 193640

clang/lib/Basic/Targets.cpp
clang/lib/CodeGen/TargetInfo.cpp
clang/test/CodeGen/mips-target-data.c
clang/test/CodeGen/mips64-padding-arg.c

index 669cf91..dfeed93 100644 (file)
@@ -4802,9 +4802,9 @@ class MipsTargetInfoBase : public TargetInfo {
     NoDSP, DSP1, DSP2
   } DspRev;
   bool HasMSA;
-  bool HasFP64;
 
 protected:
+  bool HasFP64;
   std::string ABI;
 
 public:
@@ -4887,7 +4887,10 @@ 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;
@@ -4994,6 +4997,8 @@ public:
     if (RegNo == 1) return 5;
     return -1;
   }
+
+  virtual unsigned getStackAlignment() const = 0;
 };
 
 const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
@@ -5073,12 +5078,20 @@ public:
     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:
@@ -5095,8 +5108,12 @@ 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:
@@ -5200,6 +5217,10 @@ public:
     Aliases = GCCRegAliases;
     NumAliases = llvm::array_lengthof(GCCRegAliases);
   }
+
+  virtual unsigned getStackAlignment() const {
+    return 16;
+  }
 };
 
 class Mips64EBTargetInfo : public Mips64TargetInfoBase {
index f560213..fa66fcb 100644 (file)
@@ -4648,9 +4648,9 @@ class MipsABIInfo : public ABIInfo {
   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;
@@ -4662,8 +4662,8 @@ public:
 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 {
@@ -5508,12 +5508,12 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
     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));
 
index 88eadcb..fa03fb7 100644 (file)
@@ -6,9 +6,12 @@
 // 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
 
index b2403b2..2d635c3 100644 (file)
@@ -1,5 +1,6 @@
 // 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;
@@ -53,3 +54,20 @@ void foo7(float a0, double a1) {
   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);
+}
+