Xref: utzoo comp.sys.mips:398 comp.sys.dec:2413 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!shadooby!samsung!think!snorkelwacker!bloom-beacon!athena.mit.edu!raeburn From: raeburn@athena.mit.edu (Ken Raeburn) Newsgroups: comp.sys.mips,comp.sys.dec Subject: Re: ANSI-C style variadic functions on MIPS Message-ID: <1990Jan6.062805.23863@athena.mit.edu> Date: 6 Jan 90 06:28:05 GMT References: <1990Jan5.085205.12473@athena.mit.edu> <15370@boulder.Colorado.EDU> Sender: news@athena.mit.edu (News system) Reply-To: raeburn@athena.mit.edu (Ken Raeburn) Organization: Massachusetts Institute of Technology Lines: 65 In article <15370@boulder.Colorado.EDU> grunwald@foobar.colorado.edu writes: >You might want to check the documentation for the Gnu C compiler; it >documents a little state machine that implements the MIPS convention. I didn't mention it in my previous posting, but in my test file (using stdarg.h and a function taking "(double, ...)"), gcc botches it even worse than the standard compiler. At least with /bin/cc I can read integer arguments following the double; with gcc I get zeros for integers as well as doubles (following the explicitly declared double argument, that is). The MIPS configuration files are fairly conservative about following the rules about passing arguments and writing back all the interesting registers to the stack for functions that are even suspected of using varargs, but they don't do much about retrieving the information. >Also, check stdarg.h & the version of varargs for the mips (va-mips.h). These macros assume that the compiler will write back the registers to the stack, or that (in the case of the GNU version, on some architectures) there's a __builtin_saveregs available that can be called to do that. That doesn't tell you where you are in the argument list. I.e., if the first argument you try to retrieve is a double, will it be on the stack or in registers? The varargs version seems to make use of the idea that you're supposed to use "va_alist" as the only thing(s) in the argument list, so you know where you're starting from, and you know when to switch from gee-which-registers-do-I-use-for-this-one to now-I-look-on-the-stack. With stdarg.h, you don't have this; the state machine doesn't help if you don't know what state to start in. And as I think I mentioned in my previous posting, I don't think stdarg.h works as provided. (In fact, a large part of my reason for posting is that I'd like to get a stdarg.h that works with gcc on the pmax.) > In general, if you're going to pass varidic args to >something like printf, the ``varargs'' package flushs the registers to >memory. Yes, but varargs is in better control in this respect. It may be less efficient than letting the programmer specify the types of leading arguments, but the same constraints make it easier to locate the arguments -- e.g., by forcing all registers that could be used as arguments to be written out to memory in a known format, with a known variable located at a known position within that block. Maybe I should point it out again: The troublesome case is a function declared: foo (double d, ...) How does it know, when you ask for a "double", that it should look at the second FP reg save slot? All that's available to the macros is the address of d; but since the macros can't tell the difference between foo's declaration above and foo2 (double d1, double d2, ...) (for which it should start with the first stack argument) how does it know when to switch from FP reg save slots to regular stack arguments? It needs to know, if they aren't contiguous in memory. I should rephrase that: How _should_ it know? My claim is that (lacking more information from the compiler) it does not. -- Ken