summaryrefslogtreecommitdiff
path: root/gcc/config/alpha/alpha.c
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-13 16:29:40 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-13 16:29:40 +0000
commitf9e3d239736f8e330063102ed274b548d0696e65 (patch)
tree475ad053bbfd931f6c9c53bed2daa0d31d1e8c86 /gcc/config/alpha/alpha.c
parent68ef907cd5704cca533b3cdf6db112b973e52b74 (diff)
downloadgcc-f9e3d239736f8e330063102ed274b548d0696e65.tar.gz
* config/alpha/alpha.c (alpha_pass_by_reference): Pass un-named
SFmode and SCmode arguments by reference. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240116 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/alpha/alpha.c')
-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 702cd277ede..81cef4ee387 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;
}