Skip to content

Commit

Permalink
[AVR] Add support for the -mdouble=x flag
Browse files Browse the repository at this point in the history
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
  • Loading branch information
aykevl committed Mar 17, 2020
1 parent 0818e6c commit 4add249
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 0 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/Basic/LangOptions.def
Expand Up @@ -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")
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/Options.td
Expand Up @@ -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}]>;
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Basic/TargetInfo.cpp
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Expand Up @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions 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
7 changes: 7 additions & 0 deletions 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'

0 comments on commit 4add249

Please sign in to comment.