[parisc-linux] FWD: The problematic asm code

John David Anglin dave@hiauly1.hia.nrc.ca
Fri, 11 Jan 2002 17:37:27 -0500 (EST)


> #include <stdio.h>
> void	out(const char *str, double x)
> {
> 	printf("%s: %f\n", str, x);
> }
> int	main(int argc, char **argv)
> {
> 	void	(*f)(const char *, double) = out;
> 	f("Calling via function pointer", 3.1415926535);
> 	out("Calling directly", 3.1415926535);
> 	return 0;
> }
> 
> This gives:
> % ./realind
> Calling via function pointer: 0.000000
> Calling directly: 3.141593
> 
> The RTL and the disassembly shows that in the function pointer case gcc
> tries to load the floating point argument into an integer register.

Gcc's behavior is correct.  The ABI specifies that arguments are passed
in general registers in dynamic calls.  This is most likely a linker problem.
The linker has to create the correct stub to copy the argument to a floating
register.  The test runs as expected with HP's som linker.  With the HP
assembler, gcc passes floats in both general and floating registers because
there is no way to specifiy argument locations in static functions.  With
GAS, gcc uses .PARAM to specify argument locations in static functions.

See pa.c around line 7236 for more information on what is being done.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)