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