--- gcc/config/alpha/alpha.h 2018/04/24 18:22:29 1.1.1.3 +++ gcc/config/alpha/alpha.h 2018/04/24 18:30:12 1.1.1.4 @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for DEC Alpha. - Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 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. */ /* Names to predefine in the preprocessor for this target machine. */ @@ -41,9 +42,6 @@ the Free Software Foundation, 675 Mass A #define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}" -/* No point in running CPP on our assembler output. */ -#define ASM_SPEC "-nocpp" - /* Under OSF/1, -p and -pg require -lprof1. */ #define LIB_SPEC "%{p:-lprof1} %{pg:-lprof1} %{a:-lprof2} -lc" @@ -52,8 +50,16 @@ the Free Software Foundation, 675 Mass A optimizing, -O1 if we are not. Pass -shared, -non_shared or -call_shared as appropriate. Also pass -pg. */ #define LINK_SPEC \ - "-G 8 %{O*:-O3} %{!O*:-O1} %{!shared:-init __main} %{static:-non_shared} \ - %{!static:%{shared:-shared} %{!shared:-call_shared}} %{pg}" + "-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} \ + %{!static:%{shared:-shared} %{!shared:-call_shared}} %{pg} %{taso} \ + %{rpath*}" + +#define WORD_SWITCH_TAKES_ARG(STR) \ + (!strcmp (STR, "rpath") || !strcmp (STR, "include") \ + || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ + || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ + || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ + || !strcmp (STR, "isystem")) #define STARTFILE_SPEC \ "%{!shared:%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}" @@ -61,6 +67,11 @@ the Free Software Foundation, 675 Mass A /* Print subsidiary information on the compiler version in use. */ #define TARGET_VERSION +/* Default this to not be compiling for Windows/NT. */ +#ifndef WINDOWS_NT +#define WINDOWS_NT 0 +#endif + /* Define the location for the startup file on OSF/1 for Alpha. */ #define MD_STARTFILE_PREFIX "/usr/lib/cmplrs/cc/" @@ -325,7 +336,7 @@ extern int target_flags; $28 (likewise) $0 (likewise, but return value) $21-$16 (likewise, but input args) - $27 (procedure value) + $27 (procedure value in OSF, nonsaved in NT) $9-$14 (saved integer registers) $26 (return PC) $15 (frame pointer) @@ -488,7 +499,9 @@ enum reg_class { NO_REGS, GENERAL_REGS, : (C) == 'J' ? (VALUE) == 0 \ : (C) == 'K' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \ : (C) == 'L' ? (((VALUE) & 0xffff) == 0 \ - && (((VALUE)) >> 31 == -1 || (VALUE) >> 31 == 0)) \ + && (((VALUE)) >> 31 == -1 || (VALUE) >> 31 == 0) \ + && ((HOST_BITS_PER_WIDE_INT == 64 \ + || (unsigned) (VALUE) != 0x80000000U))) \ : (C) == 'M' ? zap_mask (VALUE) \ : (C) == 'N' ? (unsigned HOST_WIDE_INT) (~ (VALUE)) < 0x100 \ : (C) == 'O' ? (unsigned HOST_WIDE_INT) (- (VALUE)) < 0x100 \ @@ -537,7 +550,8 @@ enum reg_class { NO_REGS, GENERAL_REGS, /* Loading and storing HImode or QImode values to and from memory usually requires a scratch register. The exceptions are loading QImode and HImode from an aligned address to a general register. - We also cannot load an unaligned address into an FP register. */ + We also cannot load an unaligned address or a paradoxical SUBREG into an + FP register. */ #define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,IN) \ (((GET_CODE (IN) == MEM \ @@ -553,6 +567,9 @@ enum reg_class { NO_REGS, GENERAL_REGS, ? GENERAL_REGS \ : ((CLASS) == FLOAT_REGS && GET_CODE (IN) == MEM \ && GET_CODE (XEXP (IN, 0)) == AND) ? GENERAL_REGS \ + : ((CLASS) == FLOAT_REGS && GET_CODE (IN) == SUBREG \ + && (GET_MODE_SIZE (GET_MODE (IN)) \ + > GET_MODE_SIZE (GET_MODE (SUBREG_REG (IN))))) ? GENERAL_REGS \ : NO_REGS) #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,OUT) \ @@ -567,7 +584,10 @@ enum reg_class { NO_REGS, GENERAL_REGS, ? GENERAL_REGS \ : ((CLASS) == FLOAT_REGS && GET_CODE (OUT) == MEM \ && GET_CODE (XEXP (OUT, 0)) == AND) ? GENERAL_REGS \ - : NO_REGS) + : ((CLASS) == FLOAT_REGS && GET_CODE (OUT) == SUBREG \ + && (GET_MODE_SIZE (GET_MODE (OUT)) \ + > GET_MODE_SIZE (GET_MODE (SUBREG_REG (OUT))))) ? GENERAL_REGS \ + : NO_REGS) /* If we are copying between general and FP registers, we need a memory location. */ @@ -581,6 +601,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, area is very tricky! */ #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE) \ + : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \ : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)) /* Return the maximum number of consecutive registers @@ -701,11 +722,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, /* Value is the number of bytes 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. */ -#define RETURN_POPS_ARGS(FUNTYPE,SIZE) 0 +#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). @@ -717,12 +739,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, #define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx (REG, \ - ((TREE_CODE (VALTYPE) == INTEGER_TYPE \ - || TREE_CODE (VALTYPE) == ENUMERAL_TYPE \ - || TREE_CODE (VALTYPE) == BOOLEAN_TYPE \ - || TREE_CODE (VALTYPE) == CHAR_TYPE \ - || TREE_CODE (VALTYPE) == POINTER_TYPE \ - || TREE_CODE (VALTYPE) == OFFSET_TYPE) \ + (INTEGRAL_MODE_P (TYPE_MODE (VALTYPE)) \ && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \ ? word_mode : TYPE_MODE (VALTYPE), \ TARGET_FPREGS && TREE_CODE (VALTYPE) == REAL_TYPE ? 32 : 0) @@ -882,6 +899,13 @@ enum reg_class { NO_REGS, GENERAL_REGS, } \ } +/* Try to output insns to set TARGET equal to the constant C if it can be + done in less than N insns. Do all computations in MODE. Returns the place + where the output has been placed if it can be done and the insns have been + emitted. If it would take more than N insns, zero is returned and no + insns and emitted. */ +extern struct rtx_def *alpha_emit_set_const (); + /* Generate necessary RTL for __builtin_saveregs(). ARGLIST is the argument list; see expr.c. */ extern struct rtx_def *alpha_builtin_saveregs (); @@ -915,19 +939,10 @@ extern char *alpha_function_name; #define FUNCTION_PROLOGUE(FILE, SIZE) output_prolog (FILE, SIZE) /* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. Profiling for gprof does not - require LABELNO so we don't reference it at all. This does, - however, mean that -p won't work. But OSF/1 doesn't support the - traditional prof anyways, so there is no good reason to be - backwards compatible. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - do { \ - fputs ("\tlda $28,_mcount\n", (FILE)); \ - fputs ("\tjsr $28,($28),_mcount\n", (FILE)); \ - fputs ("\tldgp $29,0($27)\n", (FILE)); \ - } while (0); + for profiling a function entry. Under OSF/1, profiling is enabled + by simply passing -pg to the assembler and linker. */ +#define FUNCTION_PROFILER(FILE, LABELNO) /* Output assembler code to FILE to initialize this source file's basic block profiling info, if that has not already been done. @@ -1070,6 +1085,20 @@ __enable_execute_stack (addr) \ if (mprotect (page, end - page, 7) < 0) \ perror ("mprotect of trampoline code"); \ } + +/* A C expression whose value is RTL representing the value of the return + address for the frame COUNT steps up from the current frame. + FRAMEADDR is the frame pointer of the COUNT frame, or the frame pointer of + the COUNT-1 frame if RETURN_ADDR_IN_PREVIOUS_FRAME} is defined. + + This definition for Alpha is broken, but is put in at the request of + Mike Stump. */ + +#define RETURN_ADDR_RTX(COUNT, FRAME) \ +((COUNT == 0 && alpha_sa_size () == 0 && 0 /* not right. */) \ + ? gen_rtx (REG, Pmode, 26) \ + : gen_rtx (MEM, Pmode, \ + memory_address (Pmode, FRAME))) /* Addressing modes, and classification of registers for them. */ @@ -1152,10 +1181,6 @@ __enable_execute_stack (addr) \ forms can be surrounded with an AND that clear the low-order three bits; this is an "unaligned" access. - We also allow a SYMBOL_REF that is the name of the current function as - valid address. This is for CALL_INSNs. It cannot be used in any other - context. - First define the basic valid address. */ #define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \ @@ -1173,8 +1198,6 @@ __enable_execute_stack (addr) \ /* Now accept the simple address, or, for DImode only, an AND of a simple address that turns off the low three bits. */ -extern char *current_function_name; - #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ { GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, X, ADDR); \ if ((MODE) == DImode \ @@ -1182,9 +1205,6 @@ extern char *current_function_name; && GET_CODE (XEXP (X, 1)) == CONST_INT \ && INTVAL (XEXP (X, 1)) == -8) \ GO_IF_LEGITIMATE_SIMPLE_ADDRESS (MODE, XEXP (X, 0), ADDR); \ - if ((MODE) == Pmode && GET_CODE (X) == SYMBOL_REF \ - && ! strcmp (XSTR (X, 0), current_function_name)) \ - goto ADDR; \ } /* Try machine-dependent ways of modifying an illegitimate address @@ -1291,7 +1311,7 @@ extern char *current_function_name; Do not define this if the table should contain absolute addresses. On the Alpha, the table is really GP-relative, not relative to the PC of the table, but we pretend that it is PC-relative; this should be OK, - but we hsould try to find some better way sometime. */ + but we should try to find some better way sometime. */ #define CASE_VECTOR_PC_RELATIVE /* Specify the tree operation to be used to convert reals to integers. */ @@ -1436,9 +1456,8 @@ extern char *current_function_name; switch on CODE. */ #define RTX_COSTS(X,CODE,OUTER_CODE) \ - case PLUS: \ - case MINUS: \ - if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ + case PLUS: case MINUS: \ + if (FLOAT_MODE_P (GET_MODE (X))) \ return COSTS_N_INSNS (6); \ else if (GET_CODE (XEXP (X, 0)) == MULT \ && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \ @@ -1446,7 +1465,7 @@ extern char *current_function_name; + rtx_cost (XEXP (X, 1), OUTER_CODE)); \ break; \ case MULT: \ - if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ + if (FLOAT_MODE_P (GET_MODE (X))) \ return COSTS_N_INSNS (6); \ return COSTS_N_INSNS (23); \ case ASHIFT: \ @@ -1456,10 +1475,7 @@ extern char *current_function_name; /* ... fall through ... */ \ case ASHIFTRT: case LSHIFTRT: case IF_THEN_ELSE: \ return COSTS_N_INSNS (2); \ - case DIV: \ - case UDIV: \ - case MOD: \ - case UMOD: \ + case DIV: case UDIV: case MOD: case UMOD: \ if (GET_MODE (X) == SFmode) \ return COSTS_N_INSNS (34); \ else if (GET_MODE (X) == DFmode) \ @@ -1467,7 +1483,14 @@ extern char *current_function_name; else \ return COSTS_N_INSNS (70); \ case MEM: \ - return COSTS_N_INSNS (3); + return COSTS_N_INSNS (3); \ + case FLOAT: case UNSIGNED_FLOAT: case FIX: case UNSIGNED_FIX: \ + case FLOAT_EXTEND: case FLOAT_TRUNCATE: \ + return COSTS_N_INSNS (6); \ + case NEG: case ABS: \ + if (FLOAT_MODE_P (GET_MODE (X))) \ + return COSTS_N_INSNS (6); \ + break; /* Control the assembler format that we output. */ @@ -1503,7 +1526,11 @@ extern char *current_function_name; #define DATA_SECTION_ASM_OP ".data" /* Define an extra section for read-only data, a routine to enter it, and - indicate that it is for read-only data. */ + indicate that it is for read-only data. + + The first time we enter the readonly data section for a file, we write + eight bytes of zero. This works around a bug in DEC's assembler in + some versions of OSF/1 V3.x. */ #define EXTRA_SECTIONS readonly_data @@ -1513,7 +1540,15 @@ literal_section () \ { \ if (in_section != readonly_data) \ { \ + static int firsttime = 1; \ + \ fprintf (asm_out_file, "%s\n", READONLY_DATA_SECTION_ASM_OP); \ + if (firsttime) \ + { \ + firsttime = 0; \ + ASM_OUTPUT_DOUBLE_INT (asm_out_file, const0_rtx); \ + } \ + \ in_section = readonly_data; \ } \ } \ @@ -1523,11 +1558,9 @@ literal_section () \ /* If we are referencing a function that is static, make the SYMBOL_REF special. We use this to see indicate we can branch to this function without setting PV or restoring GP. */ -/* For 2.6, don't do this if we're compiling C++. */ #define ENCODE_SECTION_INFO(DECL) \ - if (TREE_CODE (DECL) == FUNCTION_DECL && ! TREE_PUBLIC (DECL) \ - && strcmp (lang_identify (), "cplusplus") != 0) \ + if (TREE_CODE (DECL) == FUNCTION_DECL && ! TREE_PUBLIC (DECL)) \ SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; /* How to refer to registers in assembler output. @@ -1636,9 +1669,9 @@ literal_section () \ /* This is how to output an assembler line defining an `int' constant. */ #define ASM_OUTPUT_INT(FILE,VALUE) \ - fprintf (FILE, "\t.long %d\n", \ - (GET_CODE (VALUE) == CONST_INT \ - ? INTVAL (VALUE) & 0xffffffff : (abort (), 0))) +( fprintf (FILE, "\t.long "), \ + output_addr_const (FILE, (VALUE)), \ + fprintf (FILE, "\n")) /* This is how to output an assembler line defining a `long' constant. */ @@ -1696,7 +1729,7 @@ literal_section () \ can get it to parse the data properly. */ \ if (i < thissize - 1 \ && p[i + 1] >= '0' && p[i + 1] <= '9') \ - fprintf (asm_out_file, "\"\n\t.ascii \""); \ + _size_so_far = 0, fprintf (asm_out_file, "\"\n\t.ascii \""); \ } \ } \ fprintf (asm_out_file, "\"\n"); \ @@ -1732,8 +1765,13 @@ literal_section () \ /* This is how to output an element of a case-vector that is relative. */ +#if WINDOWS_NT +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ + fprintf (FILE, "\t.long $%d\n", (VALUE) + 32) +#else #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ fprintf (FILE, "\t.gprel32 $%d\n", (VALUE) + 32) +#endif /* This is how to output an assembler line that says to advance the location counter @@ -1884,8 +1922,8 @@ literal_section () \ from the virtual frame pointer and adjust the debugger arg/auto offsets accordingly. These debugger offsets are set up in output_prolog. */ -long alpha_arg_offset; -long alpha_auto_offset; +extern long alpha_arg_offset; +extern long alpha_auto_offset; #define DEBUGGER_AUTO_OFFSET(X) \ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) + alpha_auto_offset) #define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + alpha_arg_offset) @@ -1975,6 +2013,20 @@ do { \ #define PUT_SDB_EPILOGUE_END(NAME) +/* No point in running CPP on our assembler output. */ +#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_GAS) != 0 +/* Don't pass -g to GNU as, because some versions don't accept this option. */ +#define ASM_SPEC "%{malpha-as:-g} -nocpp %{pg}" +#else +/* In OSF/1 v3.2c, the assembler by default does not output file names which + causes mips-tfile to fail. Passing -g to the assembler fixes this problem. + ??? Stricly speaking, we only need -g if the user specifies -g. Passing + it always means that we get slightly larger than necessary object files + if the user does not specify -g. If we don't pass -g, then mips-tfile + will need to be fixed to work in this case. */ +#define ASM_SPEC "%{!mgas:-g} -nocpp %{pg}" +#endif + /* Specify to run a post-processor, mips-tfile after the assembler has run to stuff the ecoff debug information into the object file. This is needed because the Alpha assembler provides no way @@ -2026,5 +2078,8 @@ do { \ /* The linker will stick __main into the .init section. */ #define HAS_INIT_SECTION -#define INIT_NAME_FORMAT "__init_%s" -#define FINI_NAME_FORMAT "__fini_%s" +#define LD_INIT_SWITCH "-init" +#define LD_FINI_SWITCH "-fini" + +/* We do want to link in libgcc when building shared libraries under OSF/1. */ +#define LIBGCC_SPEC "-lgcc"