aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2016-09-13 18:29:40 +0200
committerUros Bizjak <uros@gcc.gnu.org>2016-09-13 18:29:40 +0200
commit809aff7457150eb0a4d0562ee67a9b826d65ea28 (patch)
tree475ad053bbfd931f6c9c53bed2daa0d31d1e8c86 /gcc/config
parent254830bab29913361ddd47358d3d90b7d4a49f3d (diff)
downloadgcc-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.c23
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;
}