Author: Ayke van Laethem
Date: 2020-03-17T13:21:03+01:00
New Revision: 4add24920550beeaed15b24e6427154a58b02e50

URL: 
https://github.com/llvm/llvm-project/commit/4add24920550beeaed15b24e6427154a58b02e50
DIFF: 
https://github.com/llvm/llvm-project/commit/4add24920550beeaed15b24e6427154a58b02e50.diff

LOG: [AVR] Add support for the -mdouble=x flag

This flag is used by avr-gcc (starting with v10) to set the width of the
double type. The double type is by default interpreted as a 32-bit
floating point number in avr-gcc instead of a 64-bit floating point
number as is common on other architectures. Starting with GCC 10, a new
option has been added to control this behavior:
https://gcc.gnu.org/wiki/avr-gcc#Deviations_from_the_Standard

This commit keeps the default double at 32 bits but adds support for the
-mdouble flag (-mdouble=32 and -mdouble=64) to control this behavior.

Differential Revision: https://reviews.llvm.org/D76181

Added: 
    clang/test/CodeGen/mdouble.c
    clang/test/Driver/mdouble.c

Modified: 
    clang/include/clang/Basic/LangOptions.def
    clang/include/clang/Driver/Options.td
    clang/lib/Basic/TargetInfo.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Frontend/CompilerInvocation.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 53b87b737568..4ba8c766269c 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -176,6 +176,7 @@ VALUE_LANGOPT(PackStruct  , 32, 0,
 VALUE_LANGOPT(MaxTypeAlign  , 32, 0,
               "default maximum alignment for types")
 VALUE_LANGOPT(AlignDouble            , 1, 0, "Controls if doubles should be 
aligned to 8 bytes (x86 only)")
+VALUE_LANGOPT(DoubleSize            , 32, 0, "width of double")
 VALUE_LANGOPT(LongDoubleSize        , 32, 0, "width of long double")
 LANGOPT(PPCIEEELongDouble            , 1, 0, "use IEEE 754 quadruple-precision 
for long double")
 COMPATIBLE_VALUE_LANGOPT(PICLevel    , 2, 0, "__PIC__ level")

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index bdcd771ff713..3a4830c84483 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2179,6 +2179,8 @@ def mbranches_within_32B_boundaries : Flag<["-"], 
"mbranches-within-32B-boundari
 def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, 
Group<clang_ignored_m_Group>;
 def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_Group>,
   HelpText<"Generate branches with extended addressability, usually via 
indirect jumps.">;
+def mdouble_EQ : Joined<["-"], "mdouble=">, Group<m_Group>, Values<"32,64">, 
Flags<[CC1Option]>,
+  HelpText<"Force double to be 32 bits or 64 bits">;
 def LongDouble_Group : OptionGroup<"<LongDouble group>">, Group<m_Group>,
   DocName<"Long double flags">,
   DocBrief<[{Selects the long double implementation}]>;

diff  --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 58d018c5bd3e..2330339bedfb 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -380,6 +380,20 @@ void TargetInfo::adjust(LangOptions &Opts) {
     LongDoubleFormat = &llvm::APFloat::IEEEquad();
   }
 
+  if (Opts.DoubleSize) {
+    if (Opts.DoubleSize == 32) {
+      DoubleWidth = 32;
+      LongDoubleWidth = 32;
+      DoubleFormat = &llvm::APFloat::IEEEsingle();
+      LongDoubleFormat = &llvm::APFloat::IEEEsingle();
+    } else if (Opts.DoubleSize == 64) {
+      DoubleWidth = 64;
+      LongDoubleWidth = 64;
+      DoubleFormat = &llvm::APFloat::IEEEdouble();
+      LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+    }
+  }
+
   if (Opts.LongDoubleSize) {
     if (Opts.LongDoubleSize == DoubleWidth) {
       LongDoubleWidth = DoubleWidth;

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index cb993e75b88c..1193dde5a679 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4580,6 +4580,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs,
                              JA.getOffloadingDeviceKind());
 
+  if (Arg *A = Args.getLastArg(options::OPT_mdouble_EQ)) {
+    if (TC.getArch() == llvm::Triple::avr)
+      A->render(Args, CmdArgs);
+    else
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+          << A->getAsString(Args) << TripleStr;
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
     if (TC.getTriple().isX86())
       A->render(Args, CmdArgs);

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 08a0b9831e0c..e2b24f0cfcea 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2937,6 +2937,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList 
&Args, InputKind IK,
   Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags);
   Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, 
Diags);
   Opts.AlignDouble = Args.hasArg(OPT_malign_double);
+  Opts.DoubleSize = getLastArgIntValue(Args, OPT_mdouble_EQ, 0, Diags);
   Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128)
                             ? 128
                             : Args.hasArg(OPT_mlong_double_64) ? 64 : 0;

diff  --git a/clang/test/CodeGen/mdouble.c b/clang/test/CodeGen/mdouble.c
new file mode 100644
index 000000000000..8399919f7025
--- /dev/null
+++ b/clang/test/CodeGen/mdouble.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=avr-unknown-unknown -mdouble=64 
| \
+// RUN:   FileCheck --check-prefix=AVR-FP64 %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=avr-unknown-unknown -mdouble=32 
| \
+// RUN:   FileCheck --check-prefix=AVR-FP32 %s
+
+double x = 0;
+int size = sizeof(x);
+
+// FIXME: the double should have an alignment of 1 on AVR, not 4 or 8.
+// AVR-FP64: @x = global double {{.*}}, align 8
+// AVR-FP64: @size = global i16 8
+// AVR-FP32: @x = global float {{.*}}, align 4
+// AVR-FP32: @size = global i16 4

diff  --git a/clang/test/Driver/mdouble.c b/clang/test/Driver/mdouble.c
new file mode 100644
index 000000000000..408d90705316
--- /dev/null
+++ b/clang/test/Driver/mdouble.c
@@ -0,0 +1,7 @@
+// RUN: %clang -target avr -c -### %s -mdouble=64 2>&1 | FileCheck %s
+
+// CHECK: "-mdouble=64"
+
+// RUN: %clang -target aarch64 -c -### %s -mdouble=64 2>&1 | FileCheck 
--check-prefix=ERR %s
+
+// ERR: error: unsupported option '-mdouble=64' for target 'aarch64'


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to