--- gcc/config/ns32k/ns32k.h 2018/04/24 18:10:24 1.1.1.1 +++ gcc/config/ns32k/ns32k.h 2018/04/24 18:28:36 1.1.1.4 @@ -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, 1995 Free Software Foundation, Inc. + Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -16,7 +16,8 @@ GNU General Public License for more deta 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Note that some other tm.h files include this one and then override @@ -26,7 +27,7 @@ extern enum reg_class secondary_reload_c /* Names to predefine in the preprocessor for this target machine. */ -#define CPP_PREDEFINES "-Dns32000 -Dunix" +#define CPP_PREDEFINES "-Dns32000 -Dunix -Asystem(unix) -Acpu(ns32k) -Amachine(ns32k)" /* Print subsidiary information on the compiler version in use. */ #define TARGET_VERSION fprintf (stderr, " (32000, GAS syntax)"); @@ -81,6 +82,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 +106,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 */ @@ -373,6 +391,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, /* Value is the number of byte of arguments automatically popped when returning from a subroutine call. + FUNDECL is the declaration node of the function (as a tree), FUNTYPE is the data type of the function (as a tree), or for a library call it is an identifier node for the subroutine name. SIZE is the number of bytes of arguments passed on the stack. @@ -385,7 +404,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, standard Unix calling sequences. If the option is not selected, the caller must always pop the args. */ -#define RETURN_POPS_ARGS(FUNTYPE,SIZE) \ +#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \ ((TARGET_RTD && TREE_CODE (FUNTYPE) != IDENTIFIER_NODE \ && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ @@ -511,6 +530,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, * . * * If a frame pointer is not needed we need assembler of the form + * + * # Make space on the stack + * + * adjspd + * * # Save any general purpose registers necessary * * save [] @@ -519,30 +543,50 @@ 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] \ && ! call_used_regs[regno]) \ - { \ - *bufp++ = regno; g_regs_used++; \ - } \ + { \ + *bufp++ = regno; g_regs_used++; \ + } \ *bufp = -1; \ for (; regno < 16; regno++) \ - if (regs_ever_live[regno] && !call_used_regs[regno]) { \ - *fbufp++ = regno; \ - } \ + if (regs_ever_live[regno] && !call_used_regs[regno]) \ + { \ + *fbufp++ = regno; \ + } \ *fbufp = -1; \ bufp = used_regs_buf; \ if (frame_pointer_needed) \ fprintf (FILE, "\tenter ["); \ - else if (g_regs_used) \ - fprintf (FILE, "\tsave ["); \ + else \ + { \ + if (SIZE) \ + ADJSP (FILE, SIZE + 4); \ + if (g_regs_used && g_regs_used > 4) \ + fprintf (FILE, "\tsave ["); \ + else \ + { \ + while (*bufp >= 0) \ + fprintf (FILE, "\tmovd r%d,tos\n", *bufp++); \ + g_regs_used = 0; \ + } \ + } \ while (*bufp >= 0) \ { \ fprintf (FILE, "r%d", *bufp++); \ @@ -564,6 +608,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 @@ -610,25 +668,34 @@ enum reg_class { NO_REGS, GENERAL_REGS, . . . - restore [] */ + restore [] + + # reclaim space allocated on stack + + adjspd <-(local stack space + 4)> */ + #define FUNCTION_EPILOGUE(FILE, SIZE) \ { register int regno, g_regs_used = 0, f_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; \ + 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]) { \ + if (regs_ever_live[regno] && !call_used_regs[regno]) \ + { \ *fbufp++ = regno; f_regs_used++; \ - } \ + } \ fbufp--; \ for (regno = 0; regno < 8; regno++) \ if (regs_ever_live[regno] \ && ! call_used_regs[regno]) \ - { \ - *bufp++ = regno; g_regs_used++; \ - } \ + { \ + *bufp++ = regno; g_regs_used++; \ + } \ while (fbufp > used_fregs_buf) \ { \ if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1) \ @@ -640,8 +707,17 @@ enum reg_class { NO_REGS, GENERAL_REGS, } \ if (frame_pointer_needed) \ fprintf (FILE, "\texit ["); \ - else if (g_regs_used) \ - fprintf (FILE, "\trestore ["); \ + else \ + { \ + if (g_regs_used && g_regs_used > 4) \ + fprintf (FILE, "\trestore ["); \ + else \ + { \ + while (bufp > used_regs_buf) \ + fprintf (FILE, "\tmovd tos,r%d\n", *--bufp); \ + g_regs_used = 0; \ + } \ + } \ while (bufp > used_regs_buf) \ { \ fprintf (FILE, "r%d", *--bufp); \ @@ -650,6 +726,8 @@ enum reg_class { NO_REGS, GENERAL_REGS, } \ if (g_regs_used || frame_pointer_needed) \ fprintf (FILE, "]\n"); \ + if (SIZE && !frame_pointer_needed) \ + ADJSP (FILE, -(SIZE + 4)); \ if (current_function_pops_args) \ fprintf (FILE, "\tret %d\n", current_function_pops_args); \ else fprintf (FILE, "\tret 0\n"); } @@ -663,10 +741,14 @@ 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; \ - (DEPTH) = offset - get_frame_size (); \ + if (flag_pic && current_function_uses_pic_offset_table) \ + offset += 4; \ + (DEPTH) = (offset + get_frame_size () \ + + (get_frame_size () == 0 ? 0 : 4)); \ } @@ -674,7 +756,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, of a trampoline, leaving space for the variable parts. */ /* On the 32k, the trampoline looks like this: - addr .,r2 + addr 0(pc),r2 jump @__trampoline .int STATIC .int FUNCTION @@ -684,7 +766,7 @@ operands on the 32k are stored). */ #define TRAMPOLINE_TEMPLATE(FILE) \ { \ - fprintf (FILE, "\taddr .,r2\n" ); \ + fprintf (FILE, "\taddr 0(pc),r2\n" ); \ fprintf (FILE, "\tjump " ); \ PUT_ABSOLUTE_PREFIX (FILE); \ fprintf (FILE, "__trampoline\n" ); \ @@ -717,9 +799,10 @@ operands on the 32k are stored). */ void \ __transfer_from_trampoline () \ { \ - asm ("___trampoline:"); \ + asm (".globl __trampoline"); \ + asm ("__trampoline:"); \ asm ("movd 16(r2),tos"); \ - asm ("movd 12(r2),r2"); \ + asm ("movd 12(r2),r1"); \ asm ("ret 0"); \ } @@ -833,7 +916,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. @@ -886,6 +972,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 @@ -909,10 +996,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) \ { \ @@ -948,6 +1039,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 @@ -959,8 +1084,9 @@ __transfer_from_trampoline () \ /* Specify the machine mode that this machine uses for the index in the tablejump instruction. - Can do SImode, but HI mode is more efficient. */ -#define CASE_VECTOR_MODE HImode + HI mode is more efficient but the range is not wide enough for + all programs. */ +#define CASE_VECTOR_MODE SImode /* Define this if the tablejump instruction expects the table to contain offsets from the address of the table. @@ -1022,7 +1148,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: \ @@ -1274,7 +1400,7 @@ do { \ /* This is how to output an element of a case-vector that is relative. */ /* ** Notice that the second element is LI format! */ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ - fprintf (FILE, "\t.word L%d-LI%d\n", VALUE, REL) + fprintf (FILE, "\t.long L%d-LI%d\n", VALUE, REL) /* This is how to output an assembler line that says to advance the location counter @@ -1344,6 +1470,7 @@ do { \ extern char *output_move_double (); extern char *output_shift_insn (); +extern char *output_move_dconst (); /* Local variables: