--- gcc/config/ns32k/ns32k.h 2018/04/24 18:14:50 1.1.1.2 +++ gcc/config/ns32k/ns32k.h 2018/04/24 18:21:14 1.1.1.3 @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler. NS32000 version. - Copyright (C) 1988 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@mcc.com) + Copyright (C) 1988, 1993, 1994 Free Software Foundation, Inc. + Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -81,6 +81,10 @@ extern int target_flags; /* Ok to use the static base register (and presume it's 0) */ #define TARGET_SB ((target_flags & 32) == 0) +#define TARGET_HIMEM (target_flags & 128) + +/* Compile using bitfield insns. */ +#define TARGET_BITFIELD ((target_flags & 64) == 0) /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, @@ -101,8 +105,21 @@ extern int target_flags; { "32032", -24}, \ { "sb", -32}, \ { "nosb", 32}, \ + { "bitfield", -64}, \ + { "nobitfield", 64}, \ + { "himem", 128}, \ + { "nohimem", -128}, \ { "", TARGET_DEFAULT}} /* TARGET_DEFAULT is defined in encore.h, pc532.h, etc. */ + +/* When we are generating PIC, the sb is used as a pointer + to the GOT. */ + +#define OVERRIDE_OPTIONS \ +{ \ + if (flag_pic || TARGET_HIMEM) target_flags |= 32; \ +} + /* target machine storage layout */ @@ -524,12 +541,20 @@ enum reg_class { NO_REGS, GENERAL_REGS, * . * . */ +#if defined(IMMEDIATE_PREFIX) && IMMEDIATE_PREFIX +#define ADJSP(FILE, n) \ + fprintf (FILE, "\tadjspd %c%d\n", IMMEDIATE_PREFIX, (n)) +#else +#define ADJSP(FILE, n) \ + fprintf (FILE, "\tadjspd %d\n", (n)) +#endif #define FUNCTION_PROLOGUE(FILE, SIZE) \ { register int regno, g_regs_used = 0; \ int used_regs_buf[8], *bufp = used_regs_buf; \ int used_fregs_buf[8], *fbufp = used_fregs_buf; \ extern char call_used_regs[]; \ + extern int current_function_uses_pic_offset_table, flag_pic; \ MAIN_FUNCTION_PROLOGUE; \ for (regno = 0; regno < 8; regno++) \ if (regs_ever_live[regno] \ @@ -550,7 +575,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, else \ { \ if (SIZE) \ - fprintf (FILE, "\tadjspd %$%d\n", SIZE + 4); \ + ADJSP (FILE, SIZE + 4); \ if (g_regs_used && g_regs_used > 4) \ fprintf (FILE, "\tsave ["); \ else \ @@ -581,6 +606,20 @@ enum reg_class { NO_REGS, GENERAL_REGS, fbufp += 2; \ } \ } \ + if (flag_pic && current_function_uses_pic_offset_table) \ + { \ + fprintf (FILE, "\tsprd sb,tos\n"); \ + if (TARGET_REGPARM) \ + { \ + fprintf (FILE, "\taddr __GLOBAL_OFFSET_TABLE_(pc),tos\n"); \ + fprintf (FILE, "\tlprd sb,tos\n"); \ + } \ + else \ + { \ + fprintf (FILE, "\taddr __GLOBAL_OFFSET_TABLE_(pc),r0\n"); \ + fprintf (FILE, "\tlprd sb,r0\n"); \ + } \ + } \ } /* Output assembler code to FILE to increment profiler label # LABELNO @@ -639,6 +678,9 @@ enum reg_class { NO_REGS, GENERAL_REGS, int used_regs_buf[8], *bufp = used_regs_buf; \ int used_fregs_buf[8], *fbufp = used_fregs_buf; \ extern char call_used_regs[]; \ + extern int current_function_uses_pic_offset_table, flag_pic; \ + if (flag_pic && current_function_uses_pic_offset_table) \ + fprintf (FILE, "\tlprd sb,tos\n"); \ *fbufp++ = -2; \ for (regno = 8; regno < 16; regno++) \ if (regs_ever_live[regno] && !call_used_regs[regno]) \ @@ -683,7 +725,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, if (g_regs_used || frame_pointer_needed) \ fprintf (FILE, "]\n"); \ if (SIZE && !frame_pointer_needed) \ - fprintf (FILE, "\tadjspd %$%d\n", -(SIZE + 4)); \ + ADJSP (FILE, -(SIZE + 4)); \ if (current_function_pops_args) \ fprintf (FILE, "\tret %d\n", current_function_pops_args); \ else fprintf (FILE, "\tret 0\n"); } @@ -697,9 +739,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, { \ int regno; \ int offset = -4; \ + extern int current_function_uses_pic_offset_table, flag_pic; \ for (regno = 0; regno < 16; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ offset += 4; \ + if (flag_pic && current_function_uses_pic_offset_table) \ + offset += 4; \ (DEPTH) = (offset + get_frame_size () \ + (get_frame_size () == 0 ? 0 : 4)); \ } @@ -868,7 +913,10 @@ __transfer_from_trampoline () \ || (GET_CODE (X) == PLUS \ && GET_CODE (XEXP (X, 0)) == REG \ && REG_OK_FOR_BASE_P (XEXP (X, 0)) \ - && CONSTANT_ADDRESS_P (XEXP (X, 1)) \ + && ((flag_pic || TARGET_HIMEM) ? \ + CONSTANT_ADDRESS_NO_LABEL_P (XEXP (X, 1)) \ + : \ + CONSTANT_ADDRESS_P (XEXP (X, 1))) \ && (GET_CODE (X) != CONST_INT || NS32K_DISPLACEMENT_P (INTVAL (X))))) /* 1 if integer I will fit in a 4 byte displacement field. @@ -921,6 +969,7 @@ __transfer_from_trampoline () \ #define GO_IF_INDEXABLE_ADDRESS(X, ADDR) \ { if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR; \ if (INDIRECTABLE_2_ADDRESS_P (X)) goto ADDR; \ + if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; \ } /* 1 if PROD is either a reg times size of mode MODE @@ -944,10 +993,14 @@ __transfer_from_trampoline () \ ((xfoo2 < 4 && xfoo2 != 2) || xfoo2 == 7)) /* Note that xfoo0, xfoo1, xfoo2 are used in some of the submacros above. */ -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ { register rtx xfooy, xfoo0, xfoo1; \ unsigned xfoo2; \ + extern int current_function_uses_pic_offset_table, flag_pic; \ xfooy = X; \ + if (flag_pic && ! current_function_uses_pic_offset_table \ + && global_symbolic_reference_mentioned_p (X, 1)) \ + current_function_uses_pic_offset_table = 1; \ GO_IF_NONINDEXED_ADDRESS (xfooy, ADDR); \ if (GET_CODE (xfooy) == PLUS) \ { \ @@ -983,6 +1036,40 @@ __transfer_from_trampoline () \ #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) {} +/* Nonzero if the constant value X is a legitimate general operand + when generating PIC code. It is given that flag_pic is on and + that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ + +extern int current_function_uses_pic_offset_table, flag_pic; +#define LEGITIMATE_PIC_OPERAND_P(X) \ + (((! current_function_uses_pic_offset_table \ + && global_symbolic_reference_mentioned_p (X, 1))? \ + (current_function_uses_pic_offset_table = 1):0 \ + ), 1) + +/* Define this macro if references to a symbol must be treated + differently depending on something about the variable or + function named by the symbol (such as what section it is in). + + On the ns32k, if using PIC, mark a SYMBOL_REF for a non-global + symbol or a code symbol. These symbols are referenced via pc + and not via sb. */ + +#define ENCODE_SECTION_INFO(DECL) \ +do \ + { \ + extern int flag_pic; \ + if (flag_pic) \ + { \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ + } \ + } \ +while (0) + /* Go to LABEL if ADDR (a legitimate address expression) has an effect that depends on the machine mode it is used for. On the ns32k, only predecrement and postincrement address depend thus @@ -1058,7 +1145,7 @@ __transfer_from_trampoline () \ #define CONST_COSTS(RTX,CODE,OUTER_CODE) \ case CONST_INT: \ if (INTVAL (RTX) <= 7 && INTVAL (RTX) >= -8) return 0; \ - if (INTVAL (RTX) < 0x4000 && INTVAL (RTX) >= -0x4000) \ + if (INTVAL (RTX) < 0x2000 && INTVAL (RTX) >= -0x2000) \ return 1; \ case CONST: \ case LABEL_REF: \ @@ -1380,6 +1467,7 @@ do { \ extern char *output_move_double (); extern char *output_shift_insn (); +extern char *output_move_dconst (); /* Local variables: