sysv4.h revision 50397
118334Speter/* Target definitions for GNU compiler for Intel 80386 running System V.4
218334Speter   Copyright (C) 1991 Free Software Foundation, Inc.
318334Speter
418334Speter   Written by Ron Guilmette (rfg@netcom.com).
518334Speter
618334SpeterThis file is part of GNU CC.
718334Speter
818334SpeterGNU CC is free software; you can redistribute it and/or modify
918334Speterit under the terms of the GNU General Public License as published by
1018334Speterthe Free Software Foundation; either version 2, or (at your option)
1118334Speterany later version.
1218334Speter
1318334SpeterGNU CC is distributed in the hope that it will be useful,
1418334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1518334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1618334SpeterGNU General Public License for more details.
1718334Speter
1818334SpeterYou should have received a copy of the GNU General Public License
1918334Speteralong with GNU CC; see the file COPYING.  If not, write to
2018334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
2118334SpeterBoston, MA 02111-1307, USA.  */
2218334Speter
2318334Speter#include "i386/i386.h"	/* Base i386 target machine definitions */
2418334Speter#include "i386/att.h"	/* Use the i386 AT&T assembler syntax */
2518334Speter#include "svr4.h"	/* Definitions common to all SVR4 targets */
2618334Speter
2718334Speter#undef TARGET_VERSION
2818334Speter#define TARGET_VERSION fprintf (stderr, " (i386 System V Release 4)");
2918334Speter
3018334Speter/* The svr4 ABI for the i386 says that records and unions are returned
3118334Speter   in memory.  */
3218334Speter
3318334Speter#undef RETURN_IN_MEMORY
3418334Speter#define RETURN_IN_MEMORY(TYPE) \
3518334Speter  (TYPE_MODE (TYPE) == BLKmode)
3618334Speter
3718334Speter/* Define which macros to predefine.  __svr4__ is our extension.  */
3818334Speter/* This used to define X86, but james@bigtex.cactus.org says that
3918334Speter   is supposed to be defined optionally by user programs--not by default.  */
4018334Speter#define CPP_PREDEFINES \
4118334Speter  "-Di386 -Dunix -D__svr4__ -Asystem(unix) -Asystem(svr4) -Acpu(i386) -Amachine(i386)"
4218334Speter
4318334Speter/* This is how to output assembly code to define a `float' constant.
4418334Speter   We always have to use a .long pseudo-op to do this because the native
4518334Speter   SVR4 ELF assembler is buggy and it generates incorrect values when we
4618334Speter   try to use the .float pseudo-op instead.  */
4718334Speter
4818334Speter#undef ASM_OUTPUT_FLOAT
4918334Speter#define ASM_OUTPUT_FLOAT(FILE,VALUE)					\
5018334Speterdo { long value;							\
5118334Speter     REAL_VALUE_TO_TARGET_SINGLE ((VALUE), value);			\
5218334Speter     if (sizeof (int) == sizeof (long))					\
5318334Speter         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value);		\
5418334Speter     else								\
5518334Speter         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value);		\
5618334Speter   } while (0)
5718334Speter
5818334Speter/* This is how to output assembly code to define a `double' constant.
5918334Speter   We always have to use a pair of .long pseudo-ops to do this because
6018334Speter   the native SVR4 ELF assembler is buggy and it generates incorrect
6150397Sobrien   values when we try to use the .double pseudo-op instead.  */
6218334Speter
6318334Speter#undef ASM_OUTPUT_DOUBLE
6418334Speter#define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
6518334Speterdo { long value[2];							\
6618334Speter     REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value);			\
6718334Speter     if (sizeof (int) == sizeof (long))					\
6818334Speter       {								\
6918334Speter         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]);		\
7018334Speter         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]);		\
7118334Speter       }								\
7218334Speter     else								\
7318334Speter       {								\
7418334Speter         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]);		\
7518334Speter         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]);		\
7618334Speter       }								\
7718334Speter   } while (0)
7818334Speter
7918334Speter
8018334Speter#undef ASM_OUTPUT_LONG_DOUBLE
8118334Speter#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)				\
8218334Speterdo { long value[3];							\
8318334Speter     REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), value);			\
8418334Speter     if (sizeof (int) == sizeof (long))					\
8518334Speter       {								\
8618334Speter         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]);		\
8718334Speter         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]);		\
8818334Speter         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[2]);		\
8918334Speter       }								\
9018334Speter     else								\
9118334Speter       {								\
9218334Speter         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]);		\
9318334Speter         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]);		\
9418334Speter         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[2]);		\
9518334Speter       }								\
9618334Speter   } while (0)
9718334Speter
9818334Speter/* Output at beginning of assembler file.  */
9918334Speter/* The .file command should always begin the output.  */
10018334Speter
10118334Speter#undef ASM_FILE_START
10218334Speter#define ASM_FILE_START(FILE)						\
10318334Speter  do {									\
10418334Speter	output_file_directive (FILE, main_input_filename);		\
10518334Speter	fprintf (FILE, "\t.version\t\"01.01\"\n");			\
10618334Speter  } while (0)
10718334Speter
10818334Speter/* Define the register numbers to be used in Dwarf debugging information.
10918334Speter   The SVR4 reference port C compiler uses the following register numbers
11018334Speter   in its Dwarf output code:
11118334Speter
11218334Speter	0 for %eax (gnu regno = 0)
11318334Speter	1 for %ecx (gnu regno = 2)
11418334Speter	2 for %edx (gnu regno = 1)
11518334Speter	3 for %ebx (gnu regno = 3)
11618334Speter	4 for %esp (gnu regno = 7)
11718334Speter	5 for %ebp (gnu regno = 6)
11818334Speter	6 for %esi (gnu regno = 4)
11918334Speter	7 for %edi (gnu regno = 5)
12018334Speter
12118334Speter   The following three DWARF register numbers are never generated by
12218334Speter   the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
12318334Speter   believes these numbers have these meanings.
12418334Speter
12518334Speter	8  for %eip    (no gnu equivalent)
12618334Speter	9  for %eflags (no gnu equivalent)
12718334Speter	10 for %trapno (no gnu equivalent)
12818334Speter
12918334Speter   It is not at all clear how we should number the FP stack registers
13018334Speter   for the x86 architecture.  If the version of SDB on x86/svr4 were
13118334Speter   a bit less brain dead with respect to floating-point then we would
13218334Speter   have a precedent to follow with respect to DWARF register numbers
13318334Speter   for x86 FP registers, but the SDB on x86/svr4 is so completely
13418334Speter   broken with respect to FP registers that it is hardly worth thinking
13518334Speter   of it as something to strive for compatibility with.
13618334Speter
13718334Speter   The version of x86/svr4 SDB I have at the moment does (partially)
13818334Speter   seem to believe that DWARF register number 11 is associated with
13918334Speter   the x86 register %st(0), but that's about all.  Higher DWARF
14018334Speter   register numbers don't seem to be associated with anything in
14118334Speter   particular, and even for DWARF regno 11, SDB only seems to under-
14218334Speter   stand that it should say that a variable lives in %st(0) (when
14318334Speter   asked via an `=' command) if we said it was in DWARF regno 11,
14418334Speter   but SDB still prints garbage when asked for the value of the
14518334Speter   variable in question (via a `/' command).
14618334Speter
14718334Speter   (Also note that the labels SDB prints for various FP stack regs
14818334Speter   when doing an `x' command are all wrong.)
14918334Speter
15018334Speter   Note that these problems generally don't affect the native SVR4
15118334Speter   C compiler because it doesn't allow the use of -O with -g and
15218334Speter   because when it is *not* optimizing, it allocates a memory
15318334Speter   location for each floating-point variable, and the memory
15418334Speter   location is what gets described in the DWARF AT_location
15518334Speter   attribute for the variable in question.
15618334Speter
15718334Speter   Regardless of the severe mental illness of the x86/svr4 SDB, we
15818334Speter   do something sensible here and we use the following DWARF
15918334Speter   register numbers.  Note that these are all stack-top-relative
16018334Speter   numbers.
16118334Speter
16218334Speter	11 for %st(0) (gnu regno = 8)
16318334Speter	12 for %st(1) (gnu regno = 9)
16418334Speter	13 for %st(2) (gnu regno = 10)
16518334Speter	14 for %st(3) (gnu regno = 11)
16618334Speter	15 for %st(4) (gnu regno = 12)
16718334Speter	16 for %st(5) (gnu regno = 13)
16818334Speter	17 for %st(6) (gnu regno = 14)
16918334Speter	18 for %st(7) (gnu regno = 15)
17018334Speter*/
17118334Speter
17218334Speter#undef DBX_REGISTER_NUMBER
17318334Speter#define DBX_REGISTER_NUMBER(n) \
17418334Speter((n) == 0 ? 0 \
17518334Speter : (n) == 1 ? 2 \
17618334Speter : (n) == 2 ? 1 \
17718334Speter : (n) == 3 ? 3 \
17818334Speter : (n) == 4 ? 6 \
17918334Speter : (n) == 5 ? 7 \
18018334Speter : (n) == 6 ? 5 \
18118334Speter : (n) == 7 ? 4 \
18218334Speter : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
18318334Speter : (-1))
18418334Speter
18518334Speter/* The routine used to output sequences of byte values.  We use a special
18618334Speter   version of this for most svr4 targets because doing so makes the
18718334Speter   generated assembly code more compact (and thus faster to assemble)
18818334Speter   as well as more readable.  Note that if we find subparts of the
18918334Speter   character sequence which end with NUL (and which are shorter than
19018334Speter   STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
19118334Speter
19218334Speter#undef ASM_OUTPUT_ASCII
19318334Speter#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH)				\
19418334Speter  do									\
19518334Speter    {									\
19618334Speter      register unsigned char *_ascii_bytes = (unsigned char *) (STR);	\
19718334Speter      register unsigned char *limit = _ascii_bytes + (LENGTH);		\
19818334Speter      register unsigned bytes_in_chunk = 0;				\
19918334Speter      for (; _ascii_bytes < limit; _ascii_bytes++)			\
20018334Speter        {								\
20118334Speter	  register unsigned char *p;					\
20218334Speter	  if (bytes_in_chunk >= 64)					\
20318334Speter	    {								\
20418334Speter	      fputc ('\n', (FILE));					\
20518334Speter	      bytes_in_chunk = 0;					\
20618334Speter	    }								\
20718334Speter	  for (p = _ascii_bytes; p < limit && *p != '\0'; p++)		\
20818334Speter	    continue;							\
20918334Speter	  if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT)		\
21018334Speter	    {								\
21118334Speter	      if (bytes_in_chunk > 0)					\
21218334Speter		{							\
21318334Speter		  fputc ('\n', (FILE));					\
21418334Speter		  bytes_in_chunk = 0;					\
21518334Speter		}							\
21618334Speter	      ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes);		\
21718334Speter	      _ascii_bytes = p;						\
21818334Speter	    }								\
21918334Speter	  else								\
22018334Speter	    {								\
22118334Speter	      if (bytes_in_chunk == 0)					\
22218334Speter		fprintf ((FILE), "\t.byte\t");				\
22318334Speter	      else							\
22418334Speter		fputc (',', (FILE));					\
22518334Speter	      fprintf ((FILE), "0x%02x", *_ascii_bytes);		\
22618334Speter	      bytes_in_chunk += 5;					\
22718334Speter	    }								\
22818334Speter	}								\
22918334Speter      if (bytes_in_chunk > 0)						\
23018334Speter        fprintf ((FILE), "\n");						\
23118334Speter    }									\
23218334Speter  while (0)
23318334Speter
23418334Speter/* This is how to output an element of a case-vector that is relative.
23518334Speter   This is only used for PIC code.  See comments by the `casesi' insn in
23618334Speter   i386.md for an explanation of the expression this outputs. */
23718334Speter
23818334Speter#undef ASM_OUTPUT_ADDR_DIFF_ELT
23950397Sobrien#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
24018334Speter  fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
24118334Speter
24218334Speter/* Indicate that jump tables go in the text section.  This is
24318334Speter   necessary when compiling PIC code.  */
24418334Speter
24550397Sobrien#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
24650397Sobrien
24750397Sobrien/* A C statement (sans semicolon) to output to the stdio stream
24850397Sobrien   FILE the assembler definition of uninitialized global DECL named
24950397Sobrien   NAME whose size is SIZE bytes and alignment is ALIGN bytes.
25050397Sobrien   Try to use asm_output_aligned_bss to implement this macro.  */
25150397Sobrien
25250397Sobrien#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
25350397Sobrien  asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
254