This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Calling convention that gets frame pointer register clobbered
- From: Etienne Lorrain <etienne_lorrain at yahoo dot fr>
- To: Falk Hueffner <falk dot hueffner at student dot uni-tuebingen dot de>
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 22 Dec 2003 11:59:58 +0100 (CET)
- Subject: Re: Calling convention that gets frame pointer register clobbered
--- Falk Hueffner wrote:
> You've hit PR inline-asm/8788. As I mentioned there, IMHO we should
> error out on this, but nobody else has commented on it yet...
But inline-asm/8788 is said to be invalid code.
Anything can be invalid-ated, but the code:
-------
typedef unsigned farptr;
typedef struct {
unsigned short buffersize;
unsigned short infobit;
unsigned nbcylinder;
unsigned nbhead;
unsigned nbsectorpertrack;
unsigned long long nbtotalsector;
unsigned short bytepersector;
/* V2.0+ : */
farptr configptr; /* for instance ebiosPhoenix realmode address */
/* V3.0+ : */
unsigned short signature0xBEDD;
unsigned char lendevicepath; /* 0x24 for v3.0 */
unsigned char reserved[3];
unsigned char bustype[4]; /* exactly "ISA" or "PCI" */
unsigned char Interface[8]; /* exactly "ATA", "ATAPI", "SCSI",
"USB"...*/
union interface_path_u {
struct {
unsigned short addr;
unsigned char pad[6];
} __attribute__ ((packed)) isa;
struct {
unsigned char busnr;
unsigned char devicenr;
unsigned char functionnr;
unsigned char pad[5];
} __attribute__ ((packed)) pci;
} bus;
union device_path_u {
struct {
unsigned char slave; /* 0 if master, 1 if slave */
unsigned char pad[7];
unsigned long long reserved; // Not present in some docs...
} __attribute__ ((packed)) ata;
struct {
unsigned char slave; /* 0 if master, 1 if slave */
unsigned char logical_unit_nr;
unsigned char pad[6];
unsigned long long reserved; // Not present in some docs...
} __attribute__ ((packed)) atapi;
struct {
unsigned char logical_unit_nr;
unsigned char pad[7];
unsigned long long reserved; // Not present in some docs...
} __attribute__ ((packed)) scsi;
struct {
unsigned char tobedefined;
unsigned char pad[7];
unsigned long long reserved; // Not present in some docs...
} __attribute__ ((packed)) usb;
struct {
unsigned long long FireWireGeneralUniqueID;
unsigned long long reserved; // Not present in some docs...
} __attribute__ ((packed)) ieee1394;
struct {
unsigned long long WorldWideNumber;
unsigned long long reserved; // Not present in some docs...
} __attribute__ ((packed)) FibreChannel;
} device;
unsigned char zero;
unsigned char bytechecksum; /* byte sum [0x1E..0x49] = 0 */
} __attribute__ ((packed)) ebiosinfo_t;
unsigned char
_EBIOSDISK_getparam (unsigned char disk, ebiosinfo_t *ebiosinfo,
unsigned char *status)
{
unsigned char carry;
asm (
" int $0x13 # _EBIOSDISK_getparam \n"
" mov %%ah,%1 \n"
" setc %0 \n"
: "=qm" (carry), "=qm" (*status), "=S" (*ebiosinfo)
: "a"((unsigned short)0x4800), "d" (disk)
);
return carry;
}
-------
This code has a real use in a real (at least for me) application...
$ gcc -O2 t.c
t.c: In function `_EBIOSDISK_getparam':
t.c:72: error: impossible constraint in `asm'
The change of error is because it is _EBIOSDISK_getparam() so it
is an output - for _EBIOSDISK_setparam() or equivalent it would
be an input.
Using output "=m" (*ebiosinfo) and input "S" (ebiosinfo) is not
completely equivalent because the output part may generate strange
code on some compiler version - but that is the best approximation.
Using "memory" after ": : :" does not have the intended effect if
the structure is declared locally in the current stack frame (and
if the _EBIOSDISK_getparam() function is inlined).
The system saying "if the structure fit in a register, it is
inside the register - else the register contains its base address"
seems to be already used in GCC when a real C function returns a
structure (C extension of GCC).
Etienne.
_________________________________________________________________
Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en français !
Yahoo! Mail : http://fr.mail.yahoo.com