diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2016-09-13 18:29:40 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2016-09-13 18:29:40 +0200 |
commit | 809aff7457150eb0a4d0562ee67a9b826d65ea28 (patch) | |
tree | 475ad053bbfd931f6c9c53bed2daa0d31d1e8c86 /gcc/config | |
parent | 254830bab29913361ddd47358d3d90b7d4a49f3d (diff) | |
download | gcc-809aff7457150eb0a4d0562ee67a9b826d65ea28.zip gcc-809aff7457150eb0a4d0562ee67a9b826d65ea28.tar.gz gcc-809aff7457150eb0a4d0562ee67a9b826d65ea28.tar.bz2 |
alpha.c (alpha_pass_by_reference): Pass un-named SFmode and SCmode arguments by reference.
* config/alpha/alpha.c (alpha_pass_by_reference): Pass un-named
SFmode and SCmode arguments by reference.
From-SVN: r240116
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/alpha/alpha.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 702cd27..81cef4e 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -5754,8 +5754,29 @@ static bool alpha_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, machine_mode mode, const_tree type ATTRIBUTE_UNUSED, - bool named ATTRIBUTE_UNUSED) + bool named) { + /* Pass float and _Complex float variable arguments by reference. + This avoids 64-bit store from a FP register to a pretend args save area + and subsequent 32-bit load from the saved location to a FP register. + + Note that 32-bit loads and stores to/from a FP register on alpha reorder + bits to form a canonical 64-bit value in the FP register. This fact + invalidates compiler assumption that 32-bit FP value lives in the lower + 32-bits of the passed 64-bit FP value, so loading the 32-bit value from + the stored 64-bit location using 32-bit FP load is invalid on alpha. + + This introduces sort of ABI incompatibility, but until _Float32 was + introduced, C-family languages promoted 32-bit float variable arg to + a 64-bit double, and it was not allowed to pass float as a varible + argument. Passing _Complex float as a variable argument never + worked on alpha. Thus, we have no backward compatibility issues + to worry about, and passing unpromoted _Float32 and _Complex float + as a variable argument will actually work in the future. */ + + if (mode == SFmode || mode == SCmode) + return !named; + return mode == TFmode || mode == TCmode; } |