On 10/20/2015 02:26 PM, Steve Ellcey wrote:
I have a question about the TARGET_PROMOTE_PROTOTYPES macro. This macro
says that types like short or char should be promoted to ints when
passed as arguments, even if there is a prototype for the argument.
Now when I look at the code generated on MIPS or x86 it looks like there
is conversion code in both the caller and the callee. For example:
int foo(char a, short b) { return a+b; }
int bar (int a) { return foo(a,a); }
In the rtl expand dump (on MIPS) I see this in bar:
(insn 6 3 7 2 (set (reg:SI 200)
(sign_extend:SI (subreg:HI (reg/v:SI 199 [ a ]) 2))) x.c:2 -1
(nil))
(insn 7 6 8 2 (set (reg:SI 201)
(sign_extend:SI (subreg:QI (reg/v:SI 199 [ a ]) 3))) x.c:2 -1
(nil))
Which insures that we pass the arguments as ints.
And in foo we have:
(insn 8 9 10 2 (set (reg/v:SI 197 [ a+-3 ])
(sign_extend:SI (subreg:QI (reg:SI 198) 3))) x.c:1 -1
(nil))
(insn 10 8 11 2 (set (reg/v:SI 199 [ b+-2 ])
(sign_extend:SI (subreg:HI (reg:SI 200) 2))) x.c:1 -1
(nil))
Which makes sure we do a truncate/extend before using the values.
Now I know that we can't get rid of these truncation/extensions
entirely, but do we need both? It seems like foo could say that
if the original registers (198 and 200) are argument registers
that were extended to SImode due to TARGET_PROMOTE_PROTOTYPES
then we don't need to do the truncation/extension in the callee
and could just use the SImode values directly. Am I missing
something? Or are we doing both just to have belts and suspenders
and want to keep it that way?
From reading the docs for TARGET_PROMOTE_PROTYPES, it would seem like
it's the caller's responsibility.
However, it's not clear from the docs if it's something the callee can
rely on, particularly when interoperating with a non-GCC compiler.
Does the ABI say anything about sub-word argument handling on the caller
or callee side?
jeff