diff options
author | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-13 16:29:40 +0000 |
---|---|---|
committer | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-13 16:29:40 +0000 |
commit | f9e3d239736f8e330063102ed274b548d0696e65 (patch) | |
tree | 475ad053bbfd931f6c9c53bed2daa0d31d1e8c86 /gcc/config/alpha/alpha.c | |
parent | 68ef907cd5704cca533b3cdf6db112b973e52b74 (diff) | |
download | gcc-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.c | 23 |
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; } |