diff options
Diffstat (limited to 'gcc/config/vax')
-rw-r--r-- | gcc/config/vax/elf.h | 95 | ||||
-rw-r--r-- | gcc/config/vax/netbsd-elf.h | 61 | ||||
-rw-r--r-- | gcc/config/vax/vax-protos.h | 7 | ||||
-rw-r--r-- | gcc/config/vax/vax.c | 435 | ||||
-rw-r--r-- | gcc/config/vax/vax.h | 164 | ||||
-rw-r--r-- | gcc/config/vax/vax.md | 94 | ||||
-rw-r--r-- | gcc/config/vax/vaxv.h | 2 | ||||
-rw-r--r-- | gcc/config/vax/vms.h | 274 | ||||
-rw-r--r-- | gcc/config/vax/xm-vms.h | 174 |
9 files changed, 372 insertions, 934 deletions
diff --git a/gcc/config/vax/elf.h b/gcc/config/vax/elf.h new file mode 100644 index 00000000000..fe00d22336c --- /dev/null +++ b/gcc/config/vax/elf.h @@ -0,0 +1,95 @@ +/* Target definitions for GNU compiler for VAX using ELF + Copyright (C) 2002 Free Software Foundation, Inc. + Contributed by Matt Thomas (matt@3am-software.com) + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#undef REGISTER_PREFIX +#undef REGISTER_NAMES +#define REGISTER_PREFIX "%" +#define REGISTER_NAMES \ +{"%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \ + "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc"} + +#undef SIZE_TYPE +#define SIZE_TYPE "long unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* Profiling routine. */ +#undef VAX_FUNCTION_PROFILER_NAME +#define VAX_FUNCTION_PROFILER_NAME "__mcount" + +/* Let's be re-entrant. */ +#undef PCC_STATIC_STRUCT_RETURN + +/* Make sure .stabs for a function are always the same section. */ +#define DBX_OUTPUT_FUNCTION_END(file,decl) function_section(decl) + +/* Before the prologue, the top of the frame is below the argument + count pushed by the CALLS and before the start of the saved registers. */ +#define INCOMING_FRAME_SP_OFFSET 0 + +/* We use R2-R5 (call-clobbered) registers for exceptions. */ +#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 2 : INVALID_REGNUM) + +/* Place the top of the stack for the DWARF2 EH stackadj value. */ +#define EH_RETURN_STACKADJ_RTX \ + gen_rtx_MEM (SImode, \ + plus_constant (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), \ + -4)) + +/* Simple store the return handler into the call frame. */ +#define EH_RETURN_HANDLER_RTX \ + gen_rtx_MEM (Pmode, \ + plus_constant (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), \ + 16)) + + +/* Reserve the top of the stack for exception handler stackadj value. */ +#undef STARTING_FRAME_OFFSET +#define STARTING_FRAME_OFFSET -4 + +/* The VAX wants no space between the case instruction and the jump table. */ +#undef ASM_OUTPUT_BEFORE_CASE_LABEL +#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) + +/* Get the udiv/urem calls out of the user's namespace. */ +#undef UDIVSI3_LIBCALL +#define UDIVSI3_LIBCALL "*__udiv" +#undef UMODSI3_LIBCALL +#define UMODSI3_LIBCALL "*__urem" + +#undef OVERRIDE_OPTIONS +#define OVERRIDE_OPTIONS \ + do \ + { \ + /* Do generic VAX overrides. */ \ + override_options (); \ + \ + /* Turn off function CSE if we're \ + doing PIC. */ \ + if (flag_pic) flag_no_function_cse = 1; \ + } \ + while (0) + +/* VAX ELF is always gas; override the generic VAX ASM_SPEC. */ + +#undef ASM_SPEC +#define ASM_SPEC "" diff --git a/gcc/config/vax/netbsd-elf.h b/gcc/config/vax/netbsd-elf.h new file mode 100644 index 00000000000..e28d1a15743 --- /dev/null +++ b/gcc/config/vax/netbsd-elf.h @@ -0,0 +1,61 @@ +/* Definitions of target machine for GNU compiler, + for NetBSD/vax ELF systems. + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Names to predefine in the preprocessor for this target OS. */ +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + NETBSD_OS_CPP_BUILTINS_ELF(); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC NETBSD_CPP_SPEC + +#define NETBSD_ENTRY_POINT "__start" + +#undef LINK_SPEC +#if 1 +/* FIXME: We must link all executables statically until PIC support + is added to the compiler. */ +#define LINK_SPEC \ + "%{assert*} %{R*} %{rpath*} \ + %{shared:%eThe -shared option is not currently supported for VAX ELF.} \ + %{!shared: \ + -dc -dp \ + %{!nostdlib: \ + %{!r*: \ + %{!e*:-e %(netbsd_entry_point)}}} \ + %{!static:-static} \ + %{static:-static}}" +#else +#define LINK_SPEC NETBSD_LINK_SPEC_ELF +#endif + +#define EXTRA_SPECS \ + { "netbsd_entry_point", NETBSD_ENTRY_POINT }, + +/* We use gas, not the UNIX assembler. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT 0 + +#undef ASM_FINAL_SPEC diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index f3a239d76c6..307f5eb40ef 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler. VAX version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2002 Free Software Foundation, Inc. This file is part of GNU CC. @@ -18,6 +18,8 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +extern void override_options PARAMS ((void)); + #ifdef RTX_CODE extern const char *rev_cond_name PARAMS ((rtx)); extern void split_quadword_operands PARAMS ((rtx *, rtx *, int)); @@ -33,8 +35,7 @@ extern int check_float_value PARAMS ((enum machine_mode, REAL_VALUE_TYPE *, int) #endif /* REAL_VALUE_TYPE */ #ifdef TREE_CODE -extern void vms_check_external PARAMS ((tree, const char *, int)); +extern void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree)); #endif /* TREE_CODE */ -extern void vms_flush_pending_externals PARAMS ((FILE *)); extern void const_section PARAMS ((void)); diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 9c929cc4d9f..69b175fd818 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -21,7 +21,10 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "rtl.h" +#include "tree.h" #include "regs.h" #include "hard-reg-set.h" #include "real.h" @@ -30,23 +33,18 @@ Boston, MA 02111-1307, USA. */ #include "function.h" #include "output.h" #include "insn-attr.h" -#include "tree.h" #include "recog.h" #include "expr.h" #include "flags.h" +#include "debug.h" #include "tm_p.h" #include "target.h" #include "target-def.h" static int follows_p PARAMS ((rtx, rtx)); static void vax_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT)); -#if VMS_TARGET -static void vms_asm_out_constructor PARAMS ((rtx, int)); -static void vms_asm_out_destructor PARAMS ((rtx, int)); -static void vms_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT)); -static void vms_encode_section_info PARAMS ((tree, int)); -static void vms_globalize_label PARAMS ((FILE *, const char *)); -#endif +static void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, + HOST_WIDE_INT, tree)); /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -55,17 +53,25 @@ static void vms_globalize_label PARAMS ((FILE *, const char *)); #undef TARGET_ASM_FUNCTION_PROLOGUE #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue -#if VMS_TARGET -#undef TARGET_ASM_SELECT_SECTION -#define TARGET_ASM_SELECT_SECTION vms_select_section -#undef TARGET_ENCODE_SECTION_INFO -#define TARGET_ENCODE_SECTION_INFO vms_encode_section_info -#undef TARGET_ASM_GLOBALIZE_LABEL -#define TARGET_ASM_GLOBALIZE_LABEL vms_globalize_label -#endif +#undef TARGET_ASM_OUTPUT_MI_THUNK +#define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall struct gcc_target targetm = TARGET_INITIALIZER; +/* Set global variables as needed for the options enabled. */ + +void +override_options () +{ + /* We're VAX floating point, not IEEE floating point. */ + memset (real_format_for_mode, 0, sizeof real_format_for_mode); + real_format_for_mode[SFmode - QFmode] = &vax_f_format; + real_format_for_mode[DFmode - QFmode] + = (TARGET_G_FLOAT ? &vax_g_format : &vax_d_format); +} + /* Generate the assembly code for function entry. FILE is a stdio stream to output the code to. SIZE is an int: how many units of temporary storage to allocate. @@ -89,50 +95,26 @@ vax_output_function_prologue (file, size) fprintf (file, "\t.word 0x%x\n", mask); - if (VMS_TARGET) + if (dwarf2out_do_frame ()) { - /* - * This works for both gcc and g++. It first checks to see if - * the current routine is "main", which will only happen for - * GCC, and add the jsb if it is. If is not the case then try - * and see if __MAIN_NAME is part of current_function_name, - * which will only happen if we are running g++, and add the jsb - * if it is. In gcc there should never be a paren in the - * function name, and in g++ there is always a "(" in the - * function name, thus there should never be any confusion. - * - * Adjusting the stack pointer by 4 before calling C$MAIN_ARGS - * is required when linking with the VMS POSIX version of the C - * run-time library; using `subl2 $4,r0' is adequate but we use - * `clrl -(sp)' instead. The extra 4 bytes could be removed - * after the call because STARTING_FRAME_OFFSET's setting of -4 - * will end up adding them right back again, but don't bother. - */ - - const char *p = current_function_name; - int is_main = strcmp ("main", p) == 0; -# define __MAIN_NAME " main(" - - while (!is_main && *p != '\0') - { - if (*p == *__MAIN_NAME - && strncmp (p, __MAIN_NAME, sizeof __MAIN_NAME - sizeof "") == 0) - is_main = 1; - else - p++; - } + const char *label = dwarf2out_cfi_label (); + int offset = 0; - if (is_main) - fprintf (file, "\tclrl -(%ssp)\n\tjsb _C$MAIN_ARGS\n", - REGISTER_PREFIX); + for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno) + if (regs_ever_live[regno] && !call_used_regs[regno]) + dwarf2out_reg_save (label, regno, offset -= 4); + + dwarf2out_reg_save (label, PC_REGNUM, offset -= 4); + dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4); + dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4); + dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4)); } size -= STARTING_FRAME_OFFSET; if (size >= 64) - fprintf (file, "\tmovab %d(%ssp),%ssp\n", -size, REGISTER_PREFIX, - REGISTER_PREFIX); + asm_fprintf (file, "\tmovab %d(%Rsp),%Rsp\n", -size); else if (size) - fprintf (file, "\tsubl2 $%d,%ssp\n", size, REGISTER_PREFIX); + asm_fprintf (file, "\tsubl2 $%d,%Rsp\n", size); } /* This is like nonimmediate_operand with a restriction on the type of MEM. */ @@ -318,7 +300,7 @@ print_operand_address (file, addr) else abort (); - /* If REG1 is non-zero, figure out if it is a base or index register. */ + /* If REG1 is nonzero, figure out if it is a base or index register. */ if (reg1) { if (breg != 0 || (offset && GET_CODE (offset) == MEM)) @@ -696,335 +678,7 @@ vax_rtx_cost (x) } return c; } - -/* Check a `double' value for validity for a particular machine mode. */ - -static const char *const float_strings[] = -{ - "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */ - "-1.70141173319264430e+38", - "2.93873587705571877e-39", /* 2^-128 */ - "-2.93873587705571877e-39" -}; - -static REAL_VALUE_TYPE float_values[4]; - -static int inited_float_values = 0; - - -int -check_float_value (mode, d, overflow) - enum machine_mode mode; - REAL_VALUE_TYPE *d; - int overflow; -{ - if (inited_float_values == 0) - { - int i; - for (i = 0; i < 4; i++) - { - float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode); - } - - inited_float_values = 1; - } - - if (overflow) - { - memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE)); - return 1; - } - - if ((mode) == SFmode) - { - REAL_VALUE_TYPE r; - memcpy (&r, d, sizeof (REAL_VALUE_TYPE)); - if (REAL_VALUES_LESS (float_values[0], r)) - { - memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE)); - return 1; - } - else if (REAL_VALUES_LESS (r, float_values[1])) - { - memcpy (d, &float_values[1], sizeof (REAL_VALUE_TYPE)); - return 1; - } - else if (REAL_VALUES_LESS (dconst0, r) - && REAL_VALUES_LESS (r, float_values[2])) - { - memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE)); - return 1; - } - else if (REAL_VALUES_LESS (r, dconst0) - && REAL_VALUES_LESS (float_values[3], r)) - { - memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE)); - return 1; - } - } - - return 0; -} - -#if VMS_TARGET -/* Additional support code for VMS target. */ - -/* Linked list of all externals that are to be emitted when optimizing - for the global pointer if they haven't been declared by the end of - the program with an appropriate .comm or initialization. */ - -static -struct extern_list { - struct extern_list *next; /* next external */ - const char *name; /* name of the external */ - int size; /* external's actual size */ - int in_const; /* section type flag */ -} *extern_head = 0, *pending_head = 0; - -/* Check whether NAME is already on the external definition list. If not, - add it to either that list or the pending definition list. */ - -void -vms_check_external (decl, name, pending) - tree decl; - const char *name; - int pending; -{ - register struct extern_list *p, *p0; - - for (p = extern_head; p; p = p->next) - if (!strcmp (p->name, name)) - return; - - for (p = pending_head, p0 = 0; p; p0 = p, p = p->next) - if (!strcmp (p->name, name)) - { - if (pending) - return; - - /* Was pending, but has now been defined; move it to other list. */ - if (p == pending_head) - pending_head = p->next; - else - p0->next = p->next; - p->next = extern_head; - extern_head = p; - return; - } - - /* Not previously seen; create a new list entry. */ - p = (struct extern_list *) xmalloc (sizeof (struct extern_list)); - p->name = name; - - if (pending) - { - /* Save the size and section type and link to `pending' list. */ - p->size = (DECL_SIZE (decl) == 0) ? 0 : - TREE_INT_CST_LOW (size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl), - size_int (BITS_PER_UNIT))); - p->in_const = (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl)); - - p->next = pending_head; - pending_head = p; - } - else - { - /* Size and section type don't matter; link to `declared' list. */ - p->size = p->in_const = 0; /* arbitrary init */ - - p->next = extern_head; - extern_head = p; - } - return; -} - -void -vms_flush_pending_externals (file) - FILE *file; -{ - register struct extern_list *p; - - while (pending_head) - { - /* Move next pending declaration to the "done" list. */ - p = pending_head; - pending_head = p->next; - p->next = extern_head; - extern_head = p; - - /* Now output the actual declaration. */ - if (p->in_const) - const_section (); - else - data_section (); - fputs (".comm ", file); - assemble_name (file, p->name); - fprintf (file, ",%d\n", p->size); - } -} - -static void -vms_asm_out_constructor (symbol, priority) - rtx symbol; - int priority ATTRIBUTE_UNUSED; -{ - fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_init_1\n"); - data_section(); - fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_init_1:\n\t.long\t"); - assemble_name (asm_out_file, XSTR (symbol, 0)); - fputc ('\n', asm_out_file); -} - -static void -vms_asm_out_destructor (symbol, priority) - rtx symbol; - int priority ATTRIBUTE_UNUSED; -{ - fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_clean_1\n"); - data_section(); - fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_clean_1:\n\t.long\t"); - assemble_name (asm_out_file, XSTR (symbol, 0)); - fputc ('\n', asm_out_file); -} - -static void -vms_select_section (exp, reloc, align) - tree exp; - int reloc ATTRIBUTE_UNUSED; - unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED; -{ - if (TREE_CODE (exp) == VAR_DECL) - { - if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp) - && DECL_INITIAL (exp) - && (DECL_INITIAL (exp) == error_mark_node - || TREE_CONSTANT (DECL_INITIAL (exp)))) - { - if (TREE_PUBLIC (exp)) - const_section (); - else - text_section (); - } - else - data_section (); - } - if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c') - { - if (TREE_CODE (exp) == STRING_CST && flag_writable_strings) - data_section (); - else - text_section (); - } -} - -/* Make sure that external variables are correctly addressed. Under VMS - there is some brain damage in the linker that requires us to do this. */ - -static void -vms_encode_section_info (decl, first) - tree decl; - int first ATTRIBUTE_UNUSED; -{ - if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)) - SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1; -} - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ -static void -vms_globalize_label (stream, name) - FILE *stream; - const char *name; -{ - default_globalize_label (stream, name); - vms_check_external (NULL_TREE, name, 0); -} -#endif /* VMS_TARGET */ -/* Additional support code for VMS host. */ -/* ??? This should really be in libiberty; vax.c is a target file. */ -#ifdef QSORT_WORKAROUND - /* - Do not use VAXCRTL's qsort() due to a severe bug: once you've - sorted something which has a size that's an exact multiple of 4 - and is longword aligned, you cannot safely sort anything which - is either not a multiple of 4 in size or not longword aligned. - A static "move-by-longword" optimization flag inside qsort() is - never reset. This is known to affect VMS V4.6 through VMS V5.5-1, - and was finally fixed in VMS V5.5-2. - - In this work-around an insertion sort is used for simplicity. - The qsort code from glibc should probably be used instead. - */ -void -not_qsort (array, count, size, compare) - void *array; - unsigned count, size; - int (*compare)(); -{ - - if (size == sizeof (short)) - { - register int i; - register short *next, *prev; - short tmp, *base = array; - - for (next = base, i = count - 1; i > 0; i--) - { - prev = next++; - if ((*compare)(next, prev) < 0) - { - tmp = *next; - do *(prev + 1) = *prev; - while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0); - *(prev + 1) = tmp; - } - } - } - else if (size == sizeof (long)) - { - register int i; - register long *next, *prev; - long tmp, *base = array; - - for (next = base, i = count - 1; i > 0; i--) - { - prev = next++; - if ((*compare)(next, prev) < 0) - { - tmp = *next; - do *(prev + 1) = *prev; - while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0); - *(prev + 1) = tmp; - } - } - } - else /* arbitrary size */ - { - register int i; - register char *next, *prev, *tmp = alloca (size), *base = array; - - for (next = base, i = count - 1; i > 0; i--) - { /* count-1 forward iterations */ - prev = next, next += size; /* increment front pointer */ - if ((*compare)(next, prev) < 0) - { /* found element out of order; move others up then re-insert */ - memcpy (tmp, next, size); /* save smaller element */ - do { memcpy (prev + size, prev, size); /* move larger elem. up */ - prev -= size; /* decrement back pointer */ - } while (prev >= base ? (*compare)(tmp, prev) < 0 : 0); - memcpy (prev + size, tmp, size); /* restore small element */ - } - } -#ifdef USE_C_ALLOCA - alloca (0); -#endif - } - - return; -} -#endif /* QSORT_WORKAROUND */ - /* Return 1 if insn A follows B. */ static int @@ -1059,3 +713,20 @@ reg_was_0_p (insn, op) /* Make sure the reg hasn't been clobbered. */ && ! reg_set_between_p (op, XEXP (link, 0), insn)); } + +static void +vax_output_mi_thunk (file, thunk, delta, vcall_offset, function) + FILE *file; + tree thunk ATTRIBUTE_UNUSED; + HOST_WIDE_INT delta; + HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED; + tree function; +{ + fprintf (file, "\t.word 0x0ffc\n"); + fprintf (file, "\taddl2 $"); + fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta); + asm_fprintf (file, ",4(%Rap)\n"); + fprintf (file, "\tjmp "); + assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0)); + fprintf (file, "+2\n"); +} diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index 80fbd4770a8..ec08c0eeb55 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -106,6 +106,9 @@ extern int target_flags; #ifndef TARGET_DEFAULT #define TARGET_DEFAULT (MASK_UNIX_ASM) #endif + +#define OVERRIDE_OPTIONS override_options () + /* Target machine storage layout */ @@ -138,7 +141,7 @@ extern int target_flags; /* Every structure's size must be a multiple of this. */ #define STRUCTURE_SIZE_BOUNDARY 8 -/* A bitfield declared as `int' forces `int' alignment for the struct. */ +/* A bit-field declared as `int' forces `int' alignment for the struct. */ #define PCC_BITFIELD_TYPE_MATTERS (! TARGET_VAXC_ALIGNMENT) /* No data type wants to be aligned rounder than this. */ @@ -285,16 +288,28 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define REG_CLASS_FROM_LETTER(C) NO_REGS -/* The letters I, J, K, L and M in a register constraint string +/* The letters I, J, K, L, M, N, and O in a register constraint string can be used to stand for particular ranges of immediate operands. This macro defines what the ranges are. C is the letter, and VALUE is a constant value. Return 1 if VALUE is in the range specified by C. - `I' is the constant zero. */ + `I' is the constant zero. + `J' is a value between 0 .. 63 (inclusive) + `K' is a value between -128 and 127 (inclusive) + 'L' is a value between -32768 and 32767 (inclusive) + `M' is a value between 0 and 255 (inclusive) + 'N' is a value between 0 and 65535 (inclusive) + `O' is a value between -63 and -1 (inclusive) */ #define CONST_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'I' ? (VALUE) == 0 \ + ( (C) == 'I' ? (VALUE) == 0 \ + : (C) == 'J' ? 0 <= (VALUE) && (VALUE) < 64 \ + : (C) == 'O' ? -63 <= (VALUE) && (VALUE) < 0 \ + : (C) == 'K' ? -128 <= (VALUE) && (VALUE) < 128 \ + : (C) == 'M' ? 0 <= (VALUE) && (VALUE) < 256 \ + : (C) == 'L' ? -32768 <= (VALUE) && (VALUE) < 32768 \ + : (C) == 'N' ? 0 <= (VALUE) && (VALUE) < 65536 \ : 0) /* Similar, but for floating constants, and defining letters G and H. @@ -455,9 +470,18 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tmovab LP%d,%s\n\tjsb mcount\n", (LABELNO), \ - reg_names[0]); +#define VAX_FUNCTION_PROFILER_NAME "mcount" +#define FUNCTION_PROFILER(FILE, LABELNO) \ + do \ + { \ + char label[256]; \ + ASM_GENERATE_INTERNAL_LABEL (label, "LP", (LABELNO)); \ + fprintf (FILE, "\tmovab "); \ + assemble_name (FILE, label); \ + asm_fprintf (FILE, ",%Rr0\n\tjsb %s\n", \ + VAX_FUNCTION_PROFILER_NAME); \ + } \ + while (0) /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the stack pointer does not matter. The value is tested only in @@ -502,9 +526,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; FNADDR is an RTX for the address of the function's pure code. CXT is an RTX for the static chain value for the function. */ -/* Allow this be overriden with the correct register prefixes. */ -#define VAX_ISTREAM_SYNC "movpsl -(sp)\n\tpushal 1(pc)\n\trei" - /* We copy the register-mask from the function's pure code to the start of the trampoline. */ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ @@ -514,7 +535,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 4)), CXT); \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 11)), \ plus_constant (FNADDR, 2)); \ - emit_insn (gen_rtx_ASM_INPUT (VOIDmode, VAX_ISTREAM_SYNC)); \ + emit_insn (gen_sync_istream ()); \ } /* Byte offset of return address in a stack frame. The "saved PC" field @@ -536,10 +557,8 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; /* Addressing modes, and classification of registers for them. */ #define HAVE_POST_INCREMENT 1 -/* #define HAVE_POST_DECREMENT 0 */ #define HAVE_PRE_DECREMENT 1 -/* #define HAVE_PRE_INCREMENT 0 */ /* Macros to check register numbers against specific register classes. */ @@ -630,7 +649,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; || GET_CODE (X) == CONST_INT) -/* Non-zero if X is an address which can be indirected. External symbols +/* Nonzero if X is an address which can be indirected. External symbols could be in a sharable image library, so we disallow those. */ #define INDIRECTABLE_ADDRESS_P(X) \ @@ -645,7 +664,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define INDIRECTABLE_CONSTANT_ADDRESS_P(X) CONSTANT_ADDRESS_P(X) -/* Non-zero if X is an address which can be indirected. */ +/* Nonzero if X is an address which can be indirected. */ #define INDIRECTABLE_ADDRESS_P(X) \ (CONSTANT_ADDRESS_P (X) \ || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ @@ -784,6 +803,10 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; jumps to the default label instead. */ #define CASE_DROPS_THROUGH +/* Indicate that jump tables go in the text section. This is + necessary when compiling PIC code. */ +#define JUMP_TABLES_IN_TEXT_SECTION 1 + /* Define this as 1 if `char' should by default be signed; else as 0. */ #define DEFAULT_SIGNED_CHAR 1 @@ -885,32 +908,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define UDIVSI3_LIBCALL "*udiv" #define UMODSI3_LIBCALL "*urem" - -/* Check a `double' value for validity for a particular machine mode. */ - -/* note that it is very hard to accidentally create a number that fits in a - double but not in a float, since their ranges are almost the same */ - -#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \ - ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW)) - -/* For future reference: - D Float: 9 bit, sign magnitude, excess 128 binary exponent - normalized 56 bit fraction, redundant bit not represented - approximately 16 decimal digits of precision - - The values to use if we trust decimal to binary conversions: -#define MAX_D_FLOAT 1.7014118346046923e+38 -#define MIN_D_FLOAT .29387358770557188e-38 - - G float: 12 bit, sign magnitude, excess 1024 binary exponent - normalized 53 bit fraction, redundant bit not represented - approximately 15 decimal digits precision - - The values to use if we trust decimal to binary conversions: -#define MAX_G_FLOAT .898846567431157e+308 -#define MIN_G_FLOAT .556268464626800e-308 -*/ /* Tell final.c how to eliminate redundant test instructions. */ @@ -1028,7 +1025,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; /* This is BSD, so it wants DBX format. */ -#define DBX_DEBUGGING_INFO +#define DBX_DEBUGGING_INFO 1 /* Do not break .stabs pseudos into continuations. */ @@ -1061,12 +1058,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define USER_LABEL_PREFIX "_" -/* This is how to output an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. */ - -#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ - fprintf (FILE, "%s%d:\n", PREFIX, NUM) - /* This is how to store into the string LABEL the symbol_ref name of an internal numbered label where PREFIX is the class of label and NUM is the number within the class. @@ -1085,19 +1076,39 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; It need not be very fast code. */ #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - fprintf (FILE, "\tmovl (sp)+,%s\n", reg_names[REGNO]) + fprintf (FILE, "\tmovl (%s)+,%s\n", reg_names[STACK_POINTER_REGNUM], \ + reg_names[REGNO]) /* This is how to output an element of a case-vector that is absolute. (The VAX does not use such vectors, but we must define this macro anyway.) */ -#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ - fprintf (FILE, "\t.long L%d\n", VALUE) +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ + do \ + { \ + char label[256]; \ + ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));\ + fprintf (FILE, "\t.long "); \ + assemble_name (FILE, label); \ + fprintf (FILE, "\n"); \ + } \ + while (0) /* This is how to output an element of a case-vector that is relative. */ -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - fprintf (FILE, "\t.word L%d-L%d\n", VALUE, REL) +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ + do \ + { \ + char label[256]; \ + ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ + fprintf (FILE, "\t.word "); \ + assemble_name (FILE, label); \ + ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \ + fprintf (FILE, "-"); \ + assemble_name (FILE, label); \ + fprintf (FILE, "\n"); \ + } \ + while (0) /* This is how to output an assembler line that says to advance the location counter @@ -1128,6 +1139,14 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", (ROUNDED))) +/* Output code to add DELTA to the first argument, and then jump to FUNCTION. + Used for C++ multiple inheritance. + .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask + addl2 $DELTA, 4(ap) #adjust first argument + jmp FUNCTION+2 #jump beyond FUNCTION's entry mask + */ +#define ASM_OUTPUT_MI_THUNK vax_output_mi_thunk + /* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable named NAME. LABELNO is an integer which is different for each call. */ @@ -1136,21 +1155,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) -/* Output code to add DELTA to the first argument, and then jump to FUNCTION. - Used for C++ multiple inheritance. - .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask - addl2 $DELTA, 4(ap) #adjust first argument - jmp FUNCTION+2 #jump beyond FUNCTION's entry mask - */ -#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \ -do { \ - fprintf (FILE, "\t.word 0x0ffc\n"); \ - fprintf (FILE, "\taddl2 $%d,4(%sap)\n", DELTA, REGISTER_PREFIX); \ - fprintf (FILE, "\tjmp "); \ - assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ - fprintf (FILE, "+2\n"); \ -} while (0) - /* Print an instruction operand X on file FILE. CODE is the code from the %-spec that requested printing this operand; if `%z3' was used to print operand 3, then CODE is 'z'. @@ -1168,17 +1172,20 @@ VAX operand formatting codes: R 32 - constant operand b the low 8 bits of a negated constant operand h the low 16 bits of a negated constant operand - # 'd' or 'g' depending on whether dfloat or gfloat is used */ + # 'd' or 'g' depending on whether dfloat or gfloat is used + | register prefix */ /* The purpose of D is to get around a quirk or bug in VAX assembler whereby -1 in a 64-bit immediate operand means 0x00000000ffffffff, which is not a 64-bit minus one. */ #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ - ((CODE) == '#') + ((CODE) == '#' || (CODE) == '|') #define PRINT_OPERAND(FILE, X, CODE) \ { if (CODE == '#') fputc (ASM_DOUBLE_CHAR, FILE); \ + else if (CODE == '|') \ + fputs (REGISTER_PREFIX, FILE); \ else if (CODE == 'C') \ fputs (rev_cond_name (X), FILE); \ else if (CODE == 'D' && GET_CODE (X) == CONST_INT && INTVAL (X) < 0) \ @@ -1205,14 +1212,14 @@ VAX operand formatting codes: else if (GET_CODE (X) == MEM) \ output_address (XEXP (X, 0)); \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode) \ - { REAL_VALUE_TYPE r; char dstr[30]; \ - REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ - REAL_VALUE_TO_DECIMAL (r, "%.20e", dstr); \ + { char dstr[30]; \ + real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X), \ + sizeof (dstr), 0, 1); \ fprintf (FILE, "$0f%s", dstr); } \ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode) \ - { REAL_VALUE_TYPE r; char dstr[30]; \ - REAL_VALUE_FROM_CONST_DOUBLE (r, X); \ - REAL_VALUE_TO_DECIMAL (r, "%.20e", dstr); \ + { char dstr[30]; \ + real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X), \ + sizeof (dstr), 0, 1); \ fprintf (FILE, "$0%c%s", ASM_DOUBLE_CHAR, dstr); } \ else { putc ('$', FILE); output_addr_const (FILE, X); }} @@ -1221,3 +1228,8 @@ VAX operand formatting codes: #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ print_operand_address (FILE, ADDR) + +/* This is a blatent lie. However, it's good enough, since we don't + actually have any code whatsoever for which this isn't overridden + by the proper FDE definition. */ +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM) diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 56e18a06391..1a163ad7763 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -28,6 +28,15 @@ ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code ;;- updates for most instructions. +;; UNSPEC_VOLATILE usage: + +(define_constants + [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an + ; insn in the code. + (VUNSPEC_SYNC_ISTREAM 1) ; sequence of insns to sync the I-stream + ] +) + ;; We don't want to allow a constant operand for test insns because ;; (set (cc0) (const_int foo)) has no mode information. Such insns will ;; be folded while optimizing anyway. @@ -1798,11 +1807,6 @@ "" "decl %0\;jgequ %l1") -;; Note that operand 1 is total size of args, in bytes, -;; and what the call insn wants is the number of words. -;; It is used in the call instruction as a byte, but in the addl2 as -;; a word. Since the only time we actually use it in the call instruction -;; is when it is a constant, SImode (for addl2) is the proper mode. (define_expand "call_pop" [(parallel [(call (match_operand:QI 0 "memory_operand" "") (match_operand:SI 1 "const_int_operand" "")) @@ -1810,12 +1814,15 @@ (plus:SI (reg:SI 14) (match_operand:SI 3 "immediate_operand" "")))])] "" - " { - if (INTVAL (operands[1]) > 255 * 4) + if (INTVAL (operands[3]) > 255 * 4 || INTVAL (operands[3]) % 4) abort (); - operands[1] = GEN_INT ((INTVAL (operands[1]) + 3)/ 4); -}") + + /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[1] = GEN_INT (INTVAL (operands[3]) + 4); +}) (define_insn "*call_pop" [(call (match_operand:QI 0 "memory_operand" "m") @@ -1823,7 +1830,10 @@ (set (reg:SI 14) (plus:SI (reg:SI 14) (match_operand:SI 2 "immediate_operand" "i")))] "" - "calls %1,%0") +{ + operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4); + return "calls %1,%0"; +}) (define_expand "call_value_pop" [(parallel [(set (match_operand 0 "" "") @@ -1833,12 +1843,15 @@ (plus:SI (reg:SI 14) (match_operand:SI 4 "immediate_operand" "")))])] "" - " { - if (INTVAL (operands[2]) > 255 * 4) - abort (); - operands[2] = GEN_INT ((INTVAL (operands[2]) + 3)/ 4); -}") + if (INTVAL (operands[4]) > 255 * 4 || INTVAL (operands[4]) % 4) + abort (); + + /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[2] = GEN_INT (INTVAL (operands[4]) + 4); +}) (define_insn "*call_value_pop" [(set (match_operand 0 "" "") @@ -1847,20 +1860,47 @@ (set (reg:SI 14) (plus:SI (reg:SI 14) (match_operand:SI 3 "immediate_operand" "i")))] "" - "calls %2,%1") + "* +{ + operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4); + return \"calls %2,%1\"; +}") + +(define_expand "call" + [(call (match_operand:QI 0 "memory_operand" "") + (match_operand:SI 1 "const_int_operand" ""))] + "" + " +{ + /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[1] = GEN_INT (INTVAL (operands[1]) + 4); +}") -;; Define another set of these for the case of functions with no operands. -;; These will allow the optimizers to do a slightly better job. -(define_insn "call" - [(call (match_operand:QI 0 "memory_operand" "m") - (const_int 0))] +(define_insn "*call" + [(call (match_operand:QI 0 "memory_operand" "m") + (match_operand:SI 1 "const_int_operand" ""))] "" "calls $0,%0") -(define_insn "call_value" +(define_expand "call_value" + [(set (match_operand 0 "" "") + (call (match_operand:QI 1 "memory_operand" "") + (match_operand:SI 2 "const_int_operand" "")))] + "" + " +{ + /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size + during EH unwinding. We must include the argument count pushed by + the calls instruction. */ + operands[2] = GEN_INT (INTVAL (operands[2]) + 4); +}") + +(define_insn "*call_value" [(set (match_operand 0 "" "") (call (match_operand:QI 1 "memory_operand" "m") - (const_int 0)))] + (match_operand:SI 2 "const_int_operand" "")))] "" "calls $0,%1") @@ -1897,7 +1937,7 @@ ;; all of memory. This blocks insns from being moved across this point. (define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] + [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] "" "") @@ -2121,3 +2161,9 @@ = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1)); return \"rotl %2,%1,%0\;bicl2 %N3,%0\"; }") + +;; Instruction sequence to sync the VAX instruction stream. +(define_insn "sync_istream" + [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)] + "" + "movpsl -(%|sp)\;pushal 1(%|pc)\;rei") diff --git a/gcc/config/vax/vaxv.h b/gcc/config/vax/vaxv.h index 7b8e7fff5ff..7b322307ba0 100644 --- a/gcc/config/vax/vaxv.h +++ b/gcc/config/vax/vaxv.h @@ -35,7 +35,7 @@ Boston, MA 02111-1307, USA. */ #define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME); #undef DBX_DEBUGGING_INFO -#define SDB_DEBUGGING_INFO +#define SDB_DEBUGGING_INFO 1 #undef LIB_SPEC diff --git a/gcc/config/vax/vms.h b/gcc/config/vax/vms.h deleted file mode 100644 index 870ebaf04eb..00000000000 --- a/gcc/config/vax/vms.h +++ /dev/null @@ -1,274 +0,0 @@ -/* Output variables, constants and external declarations, for GNU compiler. - Copyright (C) 1988, 1994, 1995, 1996, 1997, 1999, 2001, 2002 - Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#define TARGET_EXECUTABLE_SUFFIX ".exe" -#define TARGET_OBJECT_SUFFIX ".obj" - -/* This enables certain macros in vax.h, which will make an indirect - reference to an external symbol an invalid address. This needs to be - defined before we include vax.h, since it determines which macros - are used for GO_IF_*. */ - -#define NO_EXTERNAL_INDIRECT_ADDRESS - -#include "vax/vax.h" - -#undef VMS_TARGET -#define VMS_TARGET 1 - -#undef LIB_SPEC -#undef TARGET_NAME -#undef TARGET_DEFAULT -#undef CALL_USED_REGISTERS -#undef STARTING_FRAME_OFFSET - -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define_std ("vms"); \ - builtin_define_std ("VMS"); \ - builtin_assert ("system=vms"); \ - \ - builtin_define_std ("vax"); \ - if (TARGET_G_FLOAT) \ - builtin_define_std ("GFLOAT"); \ - } \ - while (0) - -/* These match the definitions used in VAXCRTL, the VMS C run-time library */ - -#define SIZE_TYPE "unsigned int" -#define PTRDIFF_TYPE "int" -#define WCHAR_TYPE "unsigned int" -#define WCHAR_TYPE_SIZE 32 /* in bits */ - -/* Use memcpy for structure copying, and so forth. */ -#define TARGET_MEM_FUNCTIONS - -/* Strictly speaking, VMS does not use DBX at all, but the interpreter built - into gas only speaks straight DBX. */ - -#define DEFAULT_GDB_EXTENSIONS 0 - -#define TARGET_DEFAULT 1 -#define TARGET_NAME "vax/vms" - -/* The structure return address arrives as an "argument" on VMS. */ -#undef STRUCT_VALUE_REGNUM -#define STRUCT_VALUE 0 -#undef PCC_STATIC_STRUCT_RETURN - -#define CALL_USED_REGISTERS {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} - -/* The run-time library routine VAXC$ESTABLISH (necessary when mixing - VMS exception handling and setjmp/longjmp in the same program) requires - that a hidden automatic variable at the top of the stack be reserved - for its use. We accomplish this by simply adding 4 bytes to the local - stack for all functions, and making sure that normal local variables - are 4 bytes lower on the stack then they would otherwise have been. */ - -#define STARTING_FRAME_OFFSET -4 - -/* This macro definition sets up a default value for `main' to return. */ -#define DEFAULT_MAIN_RETURN c_expand_return (integer_one_node) - -/* Globalizing directive for a label. */ -#define GLOBAL_ASM_OP ".globl " - -/* Under VMS we write the actual size of the storage to be allocated even - though the symbol is external. Although it is possible to give external - symbols a size of 0 (as unix does), the VMS linker does not make the - distinction between a variable definition and an external reference of a - variable, and thus the linker will not complain about a missing definition. - If we followed the unix example of giving external symbols a size of - zero, you tried to link a program where a given variable was externally - defined but none of the object modules contained a non-extern definition, - the linker would allocate 0 bytes for the variable, and any attempt to - use that variable would use the storage allocated to some other variable. - - We must also select either const_section or data_section: this will indicate - whether or not the variable will get the readonly bit set. Since the - VMS linker does not distinguish between a variable's definition and an - external reference, all usages of a given variable must have the readonly - bit set the same way, or the linker will get confused and give warning - messages. */ - -/* We used to round the size up to a multiple of 4, - but that causes linker errors sometimes when the variable was initialized - since the size of its definition was not likewise rounded up. */ - -/* Note: the original ASM_OUTPUT_EXTERNAL code has been moved into - vms_check_external and vms_flush_pending_externals. */ - -#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \ -{ if (DECL_INITIAL (DECL) == 0 && TREE_CODE (DECL) != FUNCTION_DECL) \ - vms_check_external ((DECL), (NAME), 1); \ -} - -/* ASM_OUTPUT_EXTERNAL will have wait until after an initializer is - completed in order to switch sections for an external object, so - use the DECLARE_OBJECT hooks to manage deferred declarations. */ - -/* This is the default action for ASM_DECLARE_OBJECT_NAME, but if it - is explicitly defined, then ASM_FINISH_DECLARE_OBJECT will be used. */ - -#define ASM_DECLARE_OBJECT_NAME(ASM_OUT_FILE,NAME,DECL) \ - ASM_OUTPUT_LABEL ((ASM_OUT_FILE), (NAME)) - -/* We don't need to do anything special to finish the current object, but it - should now be safe to output any deferred external global declarations. */ - -#define ASM_FINISH_DECLARE_OBJECT(FILE,DECL,TOPLVL,ATEND) \ - vms_flush_pending_externals(FILE) - -/* Anything still pending must be flushed at the very end. */ - -#define ASM_FILE_END(STREAM) \ - vms_flush_pending_externals(STREAM) - -/* Here we redefine ASM_OUTPUT_COMMON to select the data_section or the - const_section before writing the ".const" assembler directive. - If we were specifying a size of zero for external variables, we would - not have to select a section, since the assembler can assume that - when the size > 0, the storage is for a non-external, uninitialized - variable (for which a "const" declaration would be senseless), - and the assembler can make the storage read/write. - - Since the ".const" directive specifies the actual size of the storage used - for both external and non-external variables, the assembler cannot - make this assumption, and thus it has no way of deciding if storage should - be read/write or read-only. To resolve this, we give the assembler some - assistance, in the form of a ".const" or a ".data" directive. - - Under GCC 1.40, external variables were declared with a size of zero. - The GNU assembler, GAS, will recognize the "-2" switch when built for VMS; - when compiling programs with GCC 2.n this switch should be used or the - assembler will not give the read-only attribute to external constants. - Failure to use this switch will result in linker warning messages about - mismatched psect attributes. */ - -#undef ASM_OUTPUT_COMMON - -#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ -( ((TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl)) \ - ? (const_section (), 0) : (data_section (), 0)), \ - fputs (".comm ", (FILE)), \ - assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u\n", (SIZE))) - -/* We define this to prevent the name mangler from putting dollar signs into - function names. This isn't really needed, but it has been here for - some time and removing it would cause the object files generated by the - compiler to be incompatible with the object files from a compiler that - had this defined. Since it does no harm, we leave it in. */ - -#define NO_DOLLAR_IN_LABEL - -/* Add a "const" section. This is viewed by the assembler as being nearly - the same as the "data" section, with the only difference being that a - flag is set for variables declared while in the const section. This - flag is used to determine whether or not the read/write bit should be - set in the Psect definition. */ - -#define EXTRA_SECTIONS in_const - -#define EXTRA_SECTION_FUNCTIONS \ -void \ -const_section () \ -{ \ - if (in_section != in_const) { \ - fprintf(asm_out_file,".const\n"); \ - in_section = in_const; \ - } \ -} - -/* This is used by a hook in varasm.c to write the assembler directives - that are needed to tell the startup code which constructors need to - be run. */ - -#define TARGET_ASM_CONSTRUCTOR vms_asm_out_constructor -#define TARGET_ASM_DESTRUCTOR vms_asm_out_destructor - -/* The following definitions are used in libgcc2.c with the __main - function. The _SHR symbol is used when the sharable image library - for the C++ library is used - this is picked up automatically by the linker - and this symbol points to the start of __CTOR_LIST__ from the C++ library. - If the C++ library is not used, then __CTOR_LIST_SHR__ occurs just after - __CTOR_LIST__, and essentially points to the same list as __CTOR_LIST. */ - -#ifdef L__main - -#define __CTOR_LIST__ __gxx_init_0 -#define __CTOR_LIST_END__ __gxx_init_2 - -#define __CTOR_LIST_SHR__ $$PsectAttributes_NOSHR$$__gxx_init_0_shr -#define __CTOR_LIST_SHR_END__ $$PsectAttributes_NOSHR$$__gxx_init_2_shr - -#define DO_GLOBAL_CTORS_BODY \ -do { \ - func_ptr *p; \ - extern func_ptr __CTOR_LIST__[1], __CTOR_LIST_END__[1]; \ - extern func_ptr __CTOR_LIST_SHR__[1], __CTOR_LIST_SHR_END__[1]; \ - if (&__CTOR_LIST_SHR__[0] != &__CTOR_LIST__[1]) \ - for (p = __CTOR_LIST_SHR__ + 1; p < __CTOR_LIST_SHR_END__ ; p++ ) \ - if (*p) (*p) (); \ - for (p = __CTOR_LIST__ + 1; p < __CTOR_LIST_END__ ; p++ ) \ - if (*p) (*p) (); \ - do { /* arrange for `return' from main() to pass through exit() */ \ - __label__ foo; \ - int *callers_caller_fp = (int *) __builtin_frame_address (3); \ - register int retval asm ("r0"); \ - callers_caller_fp[4] = (int) && foo; \ - break; /* out of do-while block */ \ - foo: \ - exit (retval); \ - } while (0); \ -} while (0) - -#define __DTOR_LIST__ __gxx_clean_0 -#define __DTOR_LIST_END__ __gxx_clean_2 - -#define __DTOR_LIST_SHR__ $$PsectAttributes_NOSHR$$__gxx_clean_0_shr -#define __DTOR_LIST_SHR_END__ $$PsectAttributes_NOSHR$$__gxx_clean_2_shr - -#define DO_GLOBAL_DTORS_BODY \ -do { \ - func_ptr *p; \ - extern func_ptr __DTOR_LIST__[1], __DTOR_LIST_END__[1]; \ - extern func_ptr __DTOR_LIST_SHR__[1], __DTOR_LIST_SHR_END__[1]; \ - for (p = __DTOR_LIST__ + 1; p < __DTOR_LIST_END__ ; p++ ) \ - if (*p) (*p) (); \ - if (&__DTOR_LIST_SHR__[0] != &__DTOR_LIST__[1]) \ - for (p = __DTOR_LIST_SHR__ + 1; p < __DTOR_LIST_SHR_END__ ; p++ ) \ - if (*p) (*p) (); \ -} while (0) - -#endif /* L__main */ - -/* Specify the list of include file directories. */ -#define INCLUDE_DEFAULTS \ -{ \ - { "GNU_GXX_INCLUDE:", "G++", 1, 1 }, \ - { "GNU_CC_INCLUDE:", "GCC", 0, 0 }, /* GNU includes */ \ - { "SYS$SYSROOT:[SYSLIB.]", 0, 0, 0 }, /* VAX-11 "C" includes */ \ - { ".", 0, 0, 1 }, /* Make normal VMS filespecs work. */ \ - { 0, 0, 0, 0 } \ -} diff --git a/gcc/config/vax/xm-vms.h b/gcc/config/vax/xm-vms.h deleted file mode 100644 index eaf5f3bf510..00000000000 --- a/gcc/config/vax/xm-vms.h +++ /dev/null @@ -1,174 +0,0 @@ -/* Configuration for GNU C-compiler for VAX. - Copyright (C) 1987, 1994, 1995, 1996, 1997, 2001 - Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Other configurations get these via autoconfig. */ -#define STDC_HEADERS 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRING_H 1 -#ifdef __DECC -#define HAVE_UNISTD_H 1 -#endif - -#if defined(VAXC) || defined(__DECC) -/* if compiling with VAXC, need to fix problem with <stdio.h> - which defines a macro called FILE_TYPE that breaks "tree.h". - Fortunately it uses #ifndef to suppress multiple inclusions. - Three possible cases: - 1) <stdio.h> has already been included -- ours will be no-op; - 2) <stdio.h> will be included after us -- "theirs" will be no-op; - 3) <stdio.h> isn't needed -- including it here shouldn't hurt. - In all three cases, the problem macro will be removed here. */ -#include <stdio.h> -#undef FILE_TYPE -#endif - -#define SUCCESS_EXIT_CODE 1 -#define FATAL_EXIT_CODE (44 | 0x10000000) /* Abort, and no DCL message. */ - -/* A couple of conditionals for execution machine are controlled here. */ -#ifndef VMS -#define VMS -#endif - -#define GCC_INCLUDE_DIR "///not used with VMS///" /* nonsense string for now */ - -/* and define a local equivalent (sort of) for unlink */ -#define unlink remove - -/* Under VMS a directory specification can be enclosed either in square - brackets or in angle brackets. Thus we need to check both. This - macro is used to help compare filenames in cp-lex.c. - - We also need to make sure that the names are all lower case, because - we must be able to compare filenames to determine if a file implements - a class. */ - -#define FILE_NAME_NONDIRECTORY(C) \ -({ \ - char * pnt_ = (C), * pnt1_; \ - pnt1_ = pnt_ - 1; \ - while (*++pnt1_) \ - if (ISUPPER (*pnt1_)) *pnt1_ = TOLOWER (*pnt1_); \ - pnt1_ = strrchr (pnt_, ']'); \ - pnt1_ = (pnt1_ == 0 ? strrchr (pnt_, '>') : pnt1_); \ - pnt1_ = (pnt1_ == 0 ? strrchr (pnt_, ':') : pnt1_); \ - (pnt1_ == 0 ? pnt_ : pnt1_ + 1); \ - }) - -/* Macro to generate the name of the cross reference file. The standard - one does not work, since it was written assuming that the conventions - of a unix style filesystem will work on the host system. */ - -#define XREF_FILE_NAME(BUFF, NAME) \ - s = FILE_NAME_NONDIRECTORY (NAME); \ - if (s == NAME) sprintf(BUFF, "%s_gxref", NAME); \ - else { \ - strcpy(BUFF, NAME); \ - strcat(BUFF, "_gxref"); \ - } - -/* Macro that is used in cp-xref.c to determine whether a file name is - absolute or not. */ - -#define FILE_NAME_ABSOLUTE_P(NAME) \ - (FILE_NAME_NONDIRECTORY (NAME) != (&NAME[1])) - -/* FILE_NAME_JOINER is defined to be the characters that are inserted between - a directory name and a filename in order to make an absolute file - specification. Under VMS the directory specification contains all of the - required characters, so we define this to be a null string. */ - -#define FILE_NAME_JOINER "" - -/* vprintf() has been available since VMS V4.6. */ - -#define HAVE_VPRINTF - -/* Early versions of VAX C for VMS do not have putenv. Comment out - the following define if your system doesn't have putenv. */ -#define HAVE_PUTENV - -#ifndef HAVE_PUTENV -#define putenv(x) -#endif - -#if defined(VAXC) || defined(__DECC) - -/* Customizations/kludges for building with DEC's VAX C compiler - rather than GCC. */ - -#define QSORT_WORKAROUND /* do not use VAXCRTL's qsort */ - -/* use ANSI/SYSV style byte manipulation routines instead of BSD ones */ -/* rename all too-long external symbol names to avoid warnings */ -#define check_for_full_enumeration_handling check_for_full_enum_handling -#define current_function_contains_functions curfunc_contains_functions -#define current_function_epilogue_delay_list curfunc_epilogue_delay_list -#define current_function_has_nonlocal_goto curfunc_has_nonlocal_goto -#define current_function_has_nonlocal_label curfunc_has_nonlocal_label -#define current_function_internal_arg_pointer curfunc_internal_arg_pointer -#define current_function_outgoing_args_size curfunc_outgoing_args_size -#define current_function_pretend_args_size curfunc_pretend_args_size -#define current_function_returns_pcc_struct curfunc_returns_pcc_struct -#define current_function_returns_pointer curfunc_returns_pointer -#define current_function_uses_const_pool curfunc_uses_const_pool -#define current_function_uses_pic_offset_table curfunc_uses_pic_offset_table -#define dbxout_resume_previous_source_file dbxout_resume_previous_src_file -#define expand_builtin_extract_return_addr expand_builtin_extract_ret_addr -#define expand_builtin_set_return_addr_reg expand_builtin_set_ret_addr_reg -#define expand_start_loop_continue_elsewhere expnd_start_loop_cont_elsewhere -#define flag_schedule_insns_after_reload flag_sched_insns_after_reload -#define get_dynamic_handler_chain_libfunc get_dynamic_hndlr_chain_libfunc -#define lookup_name_current_level_global lookup_name_current_level_gbl -#define maybe_building_objc_message_expr maybe_building_objc_msg_expr -#define mesg_implicit_function_declaration mesg_implicit_func_declaration -#define output_deferred_addressed_constants output_deferred_addr_constants -#define protect_cleanup_actions_with_terminate protect_cleanup_act_w_terminate -#define reg_overlap_mentioned_for_reload_p reg_overlap_mtnd_for_reload_p -#define reposition_prologue_and_epilogue_notes repos_prolog_and_epilog_notes -#define rtx_equal_function_value_matters rtx_equal_func_value_matters -#define set_new_first_and_last_label_num set_new_first_and_last_lbl_num -#define thread_prologue_and_epilogue_insns thread_prolog_and_epilog_insns -#endif - -/* We need to avoid the library qsort routine, due to a serious bug - in VAXCRTL. (Sorting anything with size that's not a multiple of 4 - after having previously sorted something that was a multiple of 4 - can produce wrong results and result in data corruption.) We'll - use our own substitute (in vax.c) instead. */ -#ifdef QSORT_WORKAROUND -#define qsort not_qsort -#endif - -#ifdef __DECC -/* DECC$SHR doesn't have VAXCRTL's bugs. */ -#undef QSORT_WORKAROUND -#undef qsort -/* Avoid a lot of informational level diagnostics about implicitly - declared functions. */ -#include <stdlib.h> -#include <string.h> -/* this is for genopinit.c */ - #pragma message disable (undefescap) -#endif - -#define HOST_EXECUTABLE_SUFFIX ".exe" -#define HOST_OBJECT_SUFFIX ".obj" |