[comp.sys.mips] Varargs is broken

allan@smsc.sony.com (Allan McNaughton) (06/08/90)

Mister Mips:

Varargs appears to be broken.  We are running a M2000 with RISC/OS 4.5b
and the 2.0 version of the C compiler.

Your call/return standard says that if the first argument is a float, then 
the argument will be passed in one of the fp registers.  Works just fine,
except when you want to pass it to a function that is expecting a varargs
list.  Varargs, assumes all arguments are on the stack and forces them to
be by saving a0...a3 to the stack.  However, it knows nothing about the fp
registers at all.  

How could this have ever worked?  What has been done to fix the problem?  
This failure was found because System V.4 SVVS tests use it all over the 
place.

Allan Mc Naughton
Sony Microsystem Company
San Jose, CA

allan@sony.com
(408)434-6644 x4069

-------------------------------------------------------------------------------
#include <varargs.h>
double a;
main()
{
	func(a);
}

func(va_alist)
va_dcl
{
	va_list	ap; 	
	double  x;

	va_start(ap);
	x = va_arg(ap, double);
	va_end(ap);
}	

-------------------------------------------------------------------------------

	.verstamp	2 0
	.comm	a 8
	.text	
	.align	2
	.file	2 "var.c"
	.globl	main
	.loc	2 6
 #   1	#include <varargs.h>
 #   2	
 #   3	double a;
 #   4	
 #   5	main()
 #   6	{
	.ent	main 2
main:
	.option	O1
	subu	$sp, 24
	sw	$31, 20($sp)
	.mask	0x80000000, -4
	.frame	$sp, 24, $31
	.loc	2 7
 #   7		func(a);
	l.d	$f12, a		>>>> pass "a" in f12,f13
	jal	func		>>>> call func
	.loc	2 8
 #   8	}
	lw	$31, 20($sp)
	addu	$sp, 24
	j	$31
	.end	main
	.text	
	.align	2
	.file	2 "var.c"
	.globl	func
	.loc	2 12
 #   9	
 #  10	func(va_alist)
 #  11	va_dcl
 #  12	{
	.ent	func 2
func:
	.option	O1
	subu	$sp, 16
	sd	$4, 16($sp)	>>>> function prologue for varargs routines
	sd	$6, 24($sp)	>>>> saves the arg registers on the stack so
	.frame	$sp, 16, $31	>>>> the varargs macros can access them
	.loc	2 16
 #  13		va_list	ap; 	
 #  14		double  x;
 #  15	
 #  16		va_start(ap);
	addu	$14, $sp, 16	>>>> get address of arg list
	sw	$14, 12($sp)
	.loc	2 18
 #  17	
 #  18		x = va_arg(ap, double);
	addu	$15, $14, 15	>>>> how would this ever work????  my argument
	and	$24, $15, -8	>>>> is in a fp register, not on the stack!
	sw	$24, 12($sp)	
	l.d	$f4, -8($24)
	s.d	$f4, 4($sp)
	.loc	2 21
 #  19	
 #  20		va_end(ap);
 #  21	}	
	addu	$sp, 16
	j	$31
	.end	func

rogerk@mips.COM (Roger B.A. Klorese) (06/08/90)

In article <1990Jun8.000213.5271@smsc.sony.com> allan@smsc.Sony.COM (Allan McNaughton) writes:
>Mister Mips:

Oh, you flatter me.

Oh, you meant *Mash*?!  *snif*

>Varargs appears to be broken.  We are running a M2000 with RISC/OS 4.5b
>and the 2.0 version of the C compiler.
>
>Your call/return standard says that if the first argument is a float, then 
>the argument will be passed in one of the fp registers.  Works just fine,
>except when you want to pass it to a function that is expecting a varargs
>list.  Varargs, assumes all arguments are on the stack and forces them to
>be by saving a0...a3 to the stack.  However, it knows nothing about the fp
>registers at all.  
>
>How could this have ever worked?  What has been done to fix the problem?  
>This failure was found because System V.4 SVVS tests use it all over the 
>place.

Never did, (probably) never will.  Quoting from the Mips-C release 2.10
and 2.11 release notes (2.11 is the release that will be shipped with
RISC/os 4.50 -- 2.10 is the version that contains most of the same fixes
but is compatible only with 4.0-thru-4.30, and is available by special
order from the Customer Response Center for contract customers):

	"MIPS version of 'varargs' does not work when the first
	argument is a double.  Since the MIPS compiler is migrating to ANSI,
	stdarg should be used which fixes the problem.  'stdarg.h' use is
	fully supported by the 2.10 compiler.  The caller needs the 
	prototype to be visible (a requirement of ANSI for 'stdarg' calls)"
-- 
ROGER B.A. KLORESE      MIPS Computer Systems, Inc.      phone: +1 408 720-2939
MS 4-02    950 DeGuigne Dr.   Sunnyvale, CA  94086   voicemail: +1 408 524-7421 
rogerk@mips.COM         {ames,decwrl,pyramid}!mips!rogerk         "I'm the NLA"
"Maybe this world is another planet's hell." -- Aldous Huxley