ptx4-i.h revision 50397
150397Sobrien/* Target definitions for GNU compiler for Intel 80386 running Dynix/ptx v4
250397Sobrien   Copyright (C) 1996 Free Software Foundation, Inc.
350397Sobrien
450397Sobrien   Modified from sysv4.h
550397Sobrien   Originally written by Ron Guilmette (rfg@netcom.com).
650397Sobrien   Modified by Tim Wright (timw@sequent.com).
750397Sobrien
850397SobrienThis file is part of GNU CC.
950397Sobrien
1050397SobrienGNU CC is free software; you can redistribute it and/or modify
1150397Sobrienit under the terms of the GNU General Public License as published by
1250397Sobrienthe Free Software Foundation; either version 2, or (at your option)
1350397Sobrienany later version.
1450397Sobrien
1550397SobrienGNU CC is distributed in the hope that it will be useful,
1650397Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1750397SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1850397SobrienGNU General Public License for more details.
1950397Sobrien
2050397SobrienYou should have received a copy of the GNU General Public License
2150397Sobrienalong with GNU CC; see the file COPYING.  If not, write to
2250397Sobrienthe Free Software Foundation, 59 Temple Place - Suite 330,
2350397SobrienBoston, MA 02111-1307, USA.  */
2450397Sobrien
2550397Sobrien#include "i386/i386.h"	/* Base i386 target machine definitions */
2650397Sobrien#include "i386/att.h"	/* Use the i386 AT&T assembler syntax */
2750397Sobrien#include "ptx4.h"	/* Rest of definitions (non architecture dependent) */
2850397Sobrien
2950397Sobrien#undef TARGET_VERSION
3050397Sobrien#define TARGET_VERSION fprintf (stderr, " (i386 Sequent Dynix/ptx Version 4)");
3150397Sobrien
3250397Sobrien/* The svr4 ABI for the i386 says that records and unions are returned
3350397Sobrien   in memory.  */
3450397Sobrien
3550397Sobrien#undef RETURN_IN_MEMORY
3650397Sobrien#define RETURN_IN_MEMORY(TYPE) \
3750397Sobrien  (TYPE_MODE (TYPE) == BLKmode)
3850397Sobrien
3950397Sobrien/* Define which macros to predefine.  _SEQUENT_ is our extension.  */
4050397Sobrien/* This used to define X86, but james@bigtex.cactus.org says that
4150397Sobrien   is supposed to be defined optionally by user programs--not by default.  */
4250397Sobrien#define CPP_PREDEFINES \
4350397Sobrien  "-Di386 -Dunix -D_SEQUENT_ -Asystem(unix) -Asystem(ptx4) -Acpu(i386) -Amachine(i386)"
4450397Sobrien
4550397Sobrien/* This is how to output assembly code to define a `float' constant.
4650397Sobrien   We always have to use a .long pseudo-op to do this because the native
4750397Sobrien   SVR4 ELF assembler is buggy and it generates incorrect values when we
4850397Sobrien   try to use the .float pseudo-op instead.  */
4950397Sobrien
5050397Sobrien#undef ASM_OUTPUT_FLOAT
5150397Sobrien#define ASM_OUTPUT_FLOAT(FILE,VALUE)					\
5250397Sobriendo { long value;							\
5350397Sobrien     REAL_VALUE_TO_TARGET_SINGLE ((VALUE), value);			\
5450397Sobrien     if (sizeof (int) == sizeof (long))					\
5550397Sobrien         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value);		\
5650397Sobrien     else								\
5750397Sobrien         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value);		\
5850397Sobrien   } while (0)
5950397Sobrien
6050397Sobrien/* This is how to output assembly code to define a `double' constant.
6150397Sobrien   We always have to use a pair of .long pseudo-ops to do this because
6250397Sobrien   the native SVR4 ELF assembler is buggy and it generates incorrect
6350397Sobrien   values when we try to use the .double pseudo-op instead.  */
6450397Sobrien
6550397Sobrien#undef ASM_OUTPUT_DOUBLE
6650397Sobrien#define ASM_OUTPUT_DOUBLE(FILE,VALUE)					\
6750397Sobriendo { long value[2];							\
6850397Sobrien     REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), value);			\
6950397Sobrien     if (sizeof (int) == sizeof (long))					\
7050397Sobrien       {								\
7150397Sobrien         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]);		\
7250397Sobrien         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]);		\
7350397Sobrien       }								\
7450397Sobrien     else								\
7550397Sobrien       {								\
7650397Sobrien         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]);		\
7750397Sobrien         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]);		\
7850397Sobrien       }								\
7950397Sobrien   } while (0)
8050397Sobrien
8150397Sobrien
8250397Sobrien#undef ASM_OUTPUT_LONG_DOUBLE
8350397Sobrien#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE)				\
8450397Sobriendo { long value[3];							\
8550397Sobrien     REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), value);			\
8650397Sobrien     if (sizeof (int) == sizeof (long))					\
8750397Sobrien       {								\
8850397Sobrien         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[0]);		\
8950397Sobrien         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[1]);		\
9050397Sobrien         fprintf((FILE), "%s\t0x%x\n", ASM_LONG, value[2]);		\
9150397Sobrien       }								\
9250397Sobrien     else								\
9350397Sobrien       {								\
9450397Sobrien         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[0]);		\
9550397Sobrien         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[1]);		\
9650397Sobrien         fprintf((FILE), "%s\t0x%lx\n", ASM_LONG, value[2]);		\
9750397Sobrien       }								\
9850397Sobrien   } while (0)
9950397Sobrien
10050397Sobrien/* Output at beginning of assembler file.  */
10150397Sobrien/* The .file command should always begin the output.  */
10250397Sobrien
10350397Sobrien#undef ASM_FILE_START
10450397Sobrien#define ASM_FILE_START(FILE)						\
10550397Sobrien  do {									\
10650397Sobrien	output_file_directive (FILE, main_input_filename);		\
10750397Sobrien	fprintf (FILE, "\t.version\t\"01.01\"\n");			\
10850397Sobrien  } while (0)
10950397Sobrien
11050397Sobrien/* Define the register numbers to be used in Dwarf debugging information.
11150397Sobrien   The SVR4 reference port C compiler uses the following register numbers
11250397Sobrien   in its Dwarf output code:
11350397Sobrien
11450397Sobrien	0 for %eax (gnu regno = 0)
11550397Sobrien	1 for %ecx (gnu regno = 2)
11650397Sobrien	2 for %edx (gnu regno = 1)
11750397Sobrien	3 for %ebx (gnu regno = 3)
11850397Sobrien	4 for %esp (gnu regno = 7)
11950397Sobrien	5 for %ebp (gnu regno = 6)
12050397Sobrien	6 for %esi (gnu regno = 4)
12150397Sobrien	7 for %edi (gnu regno = 5)
12250397Sobrien
12350397Sobrien   The following three DWARF register numbers are never generated by
12450397Sobrien   the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
12550397Sobrien   believes these numbers have these meanings.
12650397Sobrien
12750397Sobrien	8  for %eip    (no gnu equivalent)
12850397Sobrien	9  for %eflags (no gnu equivalent)
12950397Sobrien	10 for %trapno (no gnu equivalent)
13050397Sobrien
13150397Sobrien   It is not at all clear how we should number the FP stack registers
13250397Sobrien   for the x86 architecture.  If the version of SDB on x86/svr4 were
13350397Sobrien   a bit less brain dead with respect to floating-point then we would
13450397Sobrien   have a precedent to follow with respect to DWARF register numbers
13550397Sobrien   for x86 FP registers, but the SDB on x86/svr4 is so completely
13650397Sobrien   broken with respect to FP registers that it is hardly worth thinking
13750397Sobrien   of it as something to strive for compatibility with.
13850397Sobrien
13950397Sobrien   The version of x86/svr4 SDB I have at the moment does (partially)
14050397Sobrien   seem to believe that DWARF register number 11 is associated with
14150397Sobrien   the x86 register %st(0), but that's about all.  Higher DWARF
14250397Sobrien   register numbers don't seem to be associated with anything in
14350397Sobrien   particular, and even for DWARF regno 11, SDB only seems to under-
14450397Sobrien   stand that it should say that a variable lives in %st(0) (when
14550397Sobrien   asked via an `=' command) if we said it was in DWARF regno 11,
14650397Sobrien   but SDB still prints garbage when asked for the value of the
14750397Sobrien   variable in question (via a `/' command).
14850397Sobrien
14950397Sobrien   (Also note that the labels SDB prints for various FP stack regs
15050397Sobrien   when doing an `x' command are all wrong.)
15150397Sobrien
15250397Sobrien   Note that these problems generally don't affect the native SVR4
15350397Sobrien   C compiler because it doesn't allow the use of -O with -g and
15450397Sobrien   because when it is *not* optimizing, it allocates a memory
15550397Sobrien   location for each floating-point variable, and the memory
15650397Sobrien   location is what gets described in the DWARF AT_location
15750397Sobrien   attribute for the variable in question.
15850397Sobrien
15950397Sobrien   Regardless of the severe mental illness of the x86/svr4 SDB, we
16050397Sobrien   do something sensible here and we use the following DWARF
16150397Sobrien   register numbers.  Note that these are all stack-top-relative
16250397Sobrien   numbers.
16350397Sobrien
16450397Sobrien	11 for %st(0) (gnu regno = 8)
16550397Sobrien	12 for %st(1) (gnu regno = 9)
16650397Sobrien	13 for %st(2) (gnu regno = 10)
16750397Sobrien	14 for %st(3) (gnu regno = 11)
16850397Sobrien	15 for %st(4) (gnu regno = 12)
16950397Sobrien	16 for %st(5) (gnu regno = 13)
17050397Sobrien	17 for %st(6) (gnu regno = 14)
17150397Sobrien	18 for %st(7) (gnu regno = 15)
17250397Sobrien*/
17350397Sobrien
17450397Sobrien#undef DBX_REGISTER_NUMBER
17550397Sobrien#define DBX_REGISTER_NUMBER(n) \
17650397Sobrien((n) == 0 ? 0 \
17750397Sobrien : (n) == 1 ? 2 \
17850397Sobrien : (n) == 2 ? 1 \
17950397Sobrien : (n) == 3 ? 3 \
18050397Sobrien : (n) == 4 ? 6 \
18150397Sobrien : (n) == 5 ? 7 \
18250397Sobrien : (n) == 6 ? 5 \
18350397Sobrien : (n) == 7 ? 4 \
18450397Sobrien : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
18550397Sobrien : (-1))
18650397Sobrien
18750397Sobrien/* The routine used to output sequences of byte values.  We use a special
18850397Sobrien   version of this for most svr4 targets because doing so makes the
18950397Sobrien   generated assembly code more compact (and thus faster to assemble)
19050397Sobrien   as well as more readable.  Note that if we find subparts of the
19150397Sobrien   character sequence which end with NUL (and which are shorter than
19250397Sobrien   STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
19350397Sobrien
19450397Sobrien#undef ASM_OUTPUT_ASCII
19550397Sobrien#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH)				\
19650397Sobrien  do									\
19750397Sobrien    {									\
19850397Sobrien      register unsigned char *_ascii_bytes = (unsigned char *) (STR);	\
19950397Sobrien      register unsigned char *limit = _ascii_bytes + (LENGTH);		\
20050397Sobrien      register unsigned bytes_in_chunk = 0;				\
20150397Sobrien      for (; _ascii_bytes < limit; _ascii_bytes++)			\
20250397Sobrien        {								\
20350397Sobrien	  register unsigned char *p;					\
20450397Sobrien	  if (bytes_in_chunk >= 64)					\
20550397Sobrien	    {								\
20650397Sobrien	      fputc ('\n', (FILE));					\
20750397Sobrien	      bytes_in_chunk = 0;					\
20850397Sobrien	    }								\
20950397Sobrien	  for (p = _ascii_bytes; p < limit && *p != '\0'; p++)		\
21050397Sobrien	    continue;							\
21150397Sobrien	  if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT)		\
21250397Sobrien	    {								\
21350397Sobrien	      if (bytes_in_chunk > 0)					\
21450397Sobrien		{							\
21550397Sobrien		  fputc ('\n', (FILE));					\
21650397Sobrien		  bytes_in_chunk = 0;					\
21750397Sobrien		}							\
21850397Sobrien	      ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes);		\
21950397Sobrien	      _ascii_bytes = p;						\
22050397Sobrien	    }								\
22150397Sobrien	  else								\
22250397Sobrien	    {								\
22350397Sobrien	      if (bytes_in_chunk == 0)					\
22450397Sobrien		fprintf ((FILE), "\t.byte\t");				\
22550397Sobrien	      else							\
22650397Sobrien		fputc (',', (FILE));					\
22750397Sobrien	      fprintf ((FILE), "0x%02x", *_ascii_bytes);		\
22850397Sobrien	      bytes_in_chunk += 5;					\
22950397Sobrien	    }								\
23050397Sobrien	}								\
23150397Sobrien      if (bytes_in_chunk > 0)						\
23250397Sobrien        fprintf ((FILE), "\n");						\
23350397Sobrien    }									\
23450397Sobrien  while (0)
23550397Sobrien
23650397Sobrien/* This is how to output an element of a case-vector that is relative.
23750397Sobrien   This is only used for PIC code.  See comments by the `casesi' insn in
23850397Sobrien   i386.md for an explanation of the expression this outputs. */
23950397Sobrien
24050397Sobrien#undef ASM_OUTPUT_ADDR_DIFF_ELT
24150397Sobrien#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
24250397Sobrien  fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
24350397Sobrien
24450397Sobrien/* Indicate that jump tables go in the text section.  This is
24550397Sobrien   necessary when compiling PIC code.  */
24650397Sobrien
24750397Sobrien#define JUMP_TABLES_IN_TEXT_SECTION 1
248