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