--- gcc/config/rs6000/rs6000.h 2018/04/24 18:10:26 1.1 +++ gcc/config/rs6000/rs6000.h 2018/04/24 18:16:36 1.1.1.2 @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 1992 Free Software Foundation, Inc. + Copyright (C) 1992, 1993 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) This file is part of GNU CC. @@ -25,7 +25,7 @@ the Free Software Foundation, 675 Mass A /* Names to predefine in the preprocessor for this target machine. */ -#define CPP_PREDEFINES "-D_IBMR2 -D_AIX" +#define CPP_PREDEFINES "-D_IBMR2 -D_AIX -D_AIX32 -Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)" /* Print subsidiary information on the compiler version in use. */ #define TARGET_VERSION ; @@ -50,8 +50,8 @@ the Free Software Foundation, 675 Mass A -bnodelcsect undoes a poor choice of default relating to multiply-defined csects. See AIX documentation for more information about this. */ -#define LINK_SPEC "-T512 -H512 -btextro -bhalt:4 -bnodelcsect\ - %{static:-bnso -bI:/lib/syscalls.exp}" +#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ + %{static:-bnso -bI:/lib/syscalls.exp} %{g*:-bexport:/usr/lib/libg.exp}" /* Profiled library versions are used by linking with special directories. */ #define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\ @@ -63,29 +63,132 @@ the Free Software Foundation, 675 Mass A /* Don't turn -B into -L if the argument specifies a relative file name. */ #define RELATIVE_PREFIX_NOT_LINKDIR -/* Run-time compilation parameters selecting different hardware subsets. */ +/* Architecture type. */ -/* Flag to allow putting fp constants in the TOC; can be turned off when - the TOC overflows. */ +extern int target_flags; -#define TARGET_FP_IN_TOC (target_flags & 1) +/* Use POWER architecture instructions and MQ register. */ +#define MASK_POWER 0x01 -extern int target_flags; +/* Use POWER2 extensions to POWER architecture. */ +#define MASK_POWER2 0x02 + +/* Use PowerPC architecture instructions. */ +#define MASK_POWERPC 0x04 + +/* Use PowerPC square root instructions. */ +#define MASK_POWERPCSQR 0x08 + +/* Use PowerPC-64 architecture instructions. */ +#define MASK_POWERPC64 0x10 + +/* Use revised mnemonic names defined for PowerPC architecture. */ +#define MASK_NEW_MNEMONICS 0x20 + +/* Disable placing fp constants in the TOC; can be turned on when the + TOC overflows. */ +#define MASK_NO_FP_IN_TOC 0x40 + +/* Output only one TOC entry per module. Normally linking fails if + there are more than 16K unique variables/constants in an executable. With + this option, linking fails only if there are more than 16K modules, or + if there are more than 16K unique variables/constant in a single module. -/* Macro to define tables used to set the flags. + This is at the cost of having 2 extra loads and one extra store per + function, and one less allocatable register. */ +#define MASK_MINIMAL_TOC 0x80 + +#define TARGET_POWER (target_flags & MASK_POWER) +#define TARGET_POWER2 (target_flags & MASK_POWER2) +#define TARGET_POWERPC (target_flags & MASK_POWERPC) +#define TARGET_POWERPCSQR (target_flags & MASK_POWERPCSQR) +#define TARGET_POWERPC64 (target_flags & MASK_POWERPC64) +#define TARGET_NEW_MNEMONICS (target_flags & MASK_NEW_MNEMONICS) +#define TARGET_NO_FP_IN_TOC (target_flags & MASK_NO_FP_IN_TOC) +#define TARGET_MINIMAL_TOC (target_flags & MASK_MINIMAL_TOC) + +/* Run-time compilation parameters selecting different hardware subsets. + + Macro to define tables used to set the flags. This is a list in braces of pairs in braces, each pair being { "NAME", VALUE } where VALUE is the bits to set or minus the bits to clear. An empty string NAME is used to identify the default VALUE. */ -#define TARGET_SWITCHES \ - {{"fp-in-toc", 1}, \ - {"no-fp-in-toc", -1}, \ - { "", TARGET_DEFAULT}} +#define TARGET_SWITCHES \ + {{"power", MASK_POWER}, \ + {"power2", MASK_POWER | MASK_POWER2}, \ + {"no-power2", - MASK_POWER2}, \ + {"no-power", - (MASK_POWER | MASK_POWER2)}, \ + {"powerpc", MASK_POWERPC}, \ + {"no-powerpc", - (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64)}, \ + {"powerpc-sqr", MASK_POWERPC | MASK_POWERPCSQR}, \ + {"no-powerpc-sqr", - MASK_POWERPCSQR}, \ + {"powerpc64", MASK_POWERPC | MASK_POWERPC64}, \ + {"no-powerpc64", -MASK_POWERPC64}, \ + {"new-mnemonics", MASK_NEW_MNEMONICS}, \ + {"old-mnemonics", -MASK_NEW_MNEMONICS}, \ + {"normal-toc", - (MASK_NO_FP_IN_TOC | MASK_MINIMAL_TOC)}, \ + {"fp-in-toc", - MASK_NO_FP_IN_TOC}, \ + {"no-fp-in-toc", MASK_NO_FP_IN_TOC}, \ + {"minimal-toc", MASK_MINIMAL_TOC}, \ + {"no-minimal-toc", - MASK_MINIMAL_TOC}, \ + {"", TARGET_DEFAULT}} + +#define TARGET_DEFAULT MASK_POWER + +/* Processor type. */ +enum processor_type + {PROCESSOR_RIOS1, + PROCESSOR_RIOS2, + PROCESSOR_PPC601, + PROCESSOR_PPC603, + PROCESSOR_PPC604, + PROCESSOR_PPC620}; + +extern enum processor_type rs6000_cpu; + +/* Recast the processor type to the cpu attribute. */ +#define rs6000_cpu_attr ((enum attr_cpu)rs6000_cpu) + +/* Define the default processor. This is overridden by other tm.h files. */ +#define PROCESSOR_DEFAULT PROCESSOR_RIOS1 + +/* Specify the dialect of assembler to use. New mnemonics is dialect one + and the old mnemonics are dialect zero. */ +#define ASSEMBLER_DIALECT TARGET_NEW_MNEMONICS ? 1 : 0 + +/* This macro is similar to `TARGET_SWITCHES' but defines names of + command options that have values. Its definition is an + initializer with a subgrouping for each command option. + + Each subgrouping contains a string constant, that defines the + fixed part of the option name, and the address of a variable. + The variable, type `char *', is set to the variable part of the + given option if the fixed part matches. The actual option name + is made by appending `-m' to the specified name. + + Here is an example which defines `-mshort-data-NUMBER'. If the + given option is `-mshort-data-512', the variable `m88k_short_data' + will be set to the string `"512"'. + + extern char *m88k_short_data; + #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */ + +#define TARGET_OPTIONS \ +{ {"cpu=", &rs6000_cpu_string}} + +extern char *rs6000_cpu_string; + +/* Sometimes certain combinations of command options do not make sense + on a particular target machine. You can define a macro + `OVERRIDE_OPTIONS' to take account of this. This macro, if + defined, is executed once just after all the command options have + been parsed. -#define TARGET_DEFAULT 1 + On the RS/6000 this is used to define the target cpu type. */ -/* On the RS/6000, we turn on various flags if optimization is selected. */ +#define OVERRIDE_OPTIONS rs6000_override_options () #define OPTIMIZATION_OPTIONS(LEVEL) \ { \ @@ -95,13 +198,6 @@ extern int target_flags; flag_omit_frame_pointer = 1; \ } \ } - -/* Define this to modify the options specified by the user. */ - -#define OVERRIDE_OPTIONS \ -{ \ - profile_block_flag = 0; \ -} /* target machine storage layout */ @@ -308,7 +404,8 @@ extern int target_flags; #define HARD_REGNO_MODE_OK(REGNO, MODE) \ (FP_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_FLOAT \ : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \ - : ! INT_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_INT \ + : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \ + && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \ : 1) /* Value is 1 if it is a good idea to tie two pseudo registers @@ -364,6 +461,15 @@ extern int target_flags; if (REG_NOTE_KIND (LINK) != 0) \ (COST) = 0; /* Anti or output dependence. */ +/* Define this macro to change register usage conditional on target flags. + Set MQ register fixed (already call_used) if not POWER architecture + (RIOS1, RIOS2, and PPC601) so that it will not be allocated. + Provide alternate register names for ppcas assembler */ + +#define CONDITIONAL_REGISTER_USAGE \ + if (!TARGET_POWER) \ + fixed_regs[64] = 1; + /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ @@ -547,6 +653,12 @@ enum reg_class { NO_REGS, BASE_REGS, GEN #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ secondary_reload_class (CLASS, MODE, IN) +/* If we are copying between FP registers and anything else, we need a memory + location. */ + +#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ + ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS || (CLASS2) == FLOAT_REGS)) + /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. @@ -799,7 +911,7 @@ struct rs6000_args {int words, fregno, n gen_rtx (MEM, BLKmode, \ plus_constant (virtual_incoming_args_rtx, \ first_reg_offset * 4)), \ - 8 - first_reg_offset); \ + 8 - first_reg_offset, (8 - first_reg_offset) * UNITS_PER_WORD); \ PRETEND_SIZE = (8 - first_reg_offset) * UNITS_PER_WORD; \ } \ } @@ -884,7 +996,12 @@ struct rs6000_args {int words, fregno, n We have two registers that can be eliminated on the RS/6000. First, the frame pointer register can often be eliminated in favor of the stack pointer register. Secondly, the argument pointer register can always be - eliminated; it is replaced with either the stack or frame pointer. */ + eliminated; it is replaced with either the stack or frame pointer. + + In addition, we use the elimination mechanism to see if r30 is needed + Initially we assume that it isn't. If it is, we spill it. This is done + by making it an eliminable register. We replace it with itself so that + if it isn't needed, then existing uses won't be modified. */ /* This is an array of structures. Each structure initializes one pair of eliminable registers. The "from" register number is given first, @@ -893,17 +1010,22 @@ struct rs6000_args {int words, fregno, n #define ELIMINABLE_REGS \ {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM} } + { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ + { 30, 30} } /* Given FROM and TO register numbers, say whether this elimination is allowed. Frame pointer elimination is automatically handled. For the RS/6000, if frame pointer elimination is being done, we would like - to convert ap into fp, not sp. */ + to convert ap into fp, not sp. + + We need r30 if -mmininal-toc was specified, and there are constant pool + references. */ #define CAN_ELIMINATE(FROM, TO) \ ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ ? ! frame_pointer_needed \ + : (FROM) == 30 ? ! TARGET_MINIMAL_TOC || get_pool_size () == 0 \ : 1) /* Define the offset between two registers, one to be eliminated, and the other @@ -931,6 +1053,8 @@ struct rs6000_args {int words, fregno, n else \ (OFFSET) = 0; \ } \ + else if ((FROM) == 30) \ + (OFFSET) = 0; \ else \ abort (); \ } @@ -1190,9 +1314,15 @@ struct rs6000_args {int words, fregno, n is undesirable. */ #define SLOW_BYTE_ACCESS 1 -/* Define if normal loads of shorter-than-word items from memory clears - the rest of the bigs in the register. */ -#define BYTE_LOADS_ZERO_EXTEND +/* Define if operations between registers always perform the operation + on the full register even if a narrower mode is specified. */ +#define WORD_REGISTER_OPERATIONS + +/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD + will either zero-extend or sign-extend. The value of this macro should + be the code that says which one of the two operations is implicitly + done, NIL if none. */ +#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Define if loading short immediate values into registers sign extends. */ #define SHORT_IMMEDIATES_SIGN_EXTEND @@ -1237,9 +1367,13 @@ struct rs6000_args {int words, fregno, n but a CALL with constant address is cheap. */ #define NO_FUNCTION_CSE -/* Define this if shift instructions ignore all but the low-order - few bits. */ -#define SHIFT_COUNT_TRUNCATED +/* Define this to be nonzero if shift instructions ignore all but the low-order + few bits. + + The sle and sre instructions which allow SHIFT_COUNT_TRUNCATED + have been dropped from the PowerPC architecture. */ + +#define SHIFT_COUNT_TRUNCATED TARGET_POWER ? 1 : 0 /* Use atexit for static constructors/destructors, instead of defining our own exit function. */ @@ -1344,6 +1478,8 @@ extern int rs6000_trunc_used; Initialize the section names for the RS/6000 at this point. + Specify filename to assembler. + We want to go into the TOC section so at least one .toc will be emitted. Also, in order to output proper .bs/.es pairs, we need at least one static [RW] section emitted. @@ -1362,6 +1498,7 @@ extern int rs6000_trunc_used; rs6000_gen_section_name (&xcoff_read_only_section_name, \ main_input_filename, ".ro_"); \ \ + output_file_directive (FILE, main_input_filename); \ toc_section (); \ if (write_symbols != NO_DEBUG) \ private_data_section (); \ @@ -1410,6 +1547,16 @@ extern int rs6000_trunc_used; #define READONLY_DATA_SECTION read_only_data_section +/* If we are referencing a function that is static or is known to be + in this file, make the SYMBOL_REF special. We can use this to indicate + that we can branch to this function without emitting a no-op after the + call. */ + +#define ENCODE_SECTION_INFO(DECL) \ + if (TREE_CODE (DECL) == FUNCTION_DECL \ + && (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL))) \ + SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; + /* Indicate that jump tables go in the text section. */ #define JUMP_TABLES_IN_TEXT_SECTION @@ -1455,9 +1602,28 @@ read_only_private_data_section () \ void \ toc_section () \ { \ - if (in_section != toc) \ - fprintf (asm_out_file, ".toc\n"); \ + if (TARGET_MINIMAL_TOC) \ + { \ + static int toc_initialized = 0; \ + \ + /* toc_section is always called at least once from ASM_FILE_START, \ + so this is guaranteed to always be defined once and only once \ + in each file. */ \ + if (! toc_initialized) \ + { \ + fprintf (asm_out_file, ".toc\nLCTOC..0:\n"); \ + fprintf (asm_out_file, "\t.tc toc_table[TC],toc_table[RW]\n"); \ + toc_initialized = 1; \ + } \ \ + if (in_section != toc) \ + fprintf (asm_out_file, ".csect toc_table[RW]\n"); \ + } \ + else \ + { \ + if (in_section != toc) \ + fprintf (asm_out_file, ".toc\n"); \ + } \ in_section = toc; \ } @@ -1492,7 +1658,7 @@ toc_section () \ fprintf (FILE, "\t.long ."); \ RS6000_OUTPUT_BASENAME (FILE, NAME); \ fprintf (FILE, ", TOC[tc0], 0\n"); \ - fprintf (FILE, ".csect [PR]\n."); \ + fprintf (FILE, ".csect .text[PR]\n."); \ RS6000_OUTPUT_BASENAME (FILE, NAME); \ fprintf (FILE, ":\n"); \ if (write_symbols == XCOFF_DEBUG) \ @@ -1512,7 +1678,8 @@ toc_section () \ || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ || GET_CODE (X) == LABEL_REF \ - || (TARGET_FP_IN_TOC && GET_CODE (X) == CONST_DOUBLE \ + || (! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC) \ + && GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && BITS_PER_WORD == HOST_BITS_PER_INT)) @@ -1631,7 +1798,7 @@ toc_section () \ /* Output before instructions. */ -#define TEXT_SECTION_ASM_OP ".csect [PR]" +#define TEXT_SECTION_ASM_OP ".csect .text[PR]" /* Output before writable data. */ @@ -1680,6 +1847,10 @@ toc_section () \ #define DBX_REGISTER_NUMBER(REGNO) (REGNO) +/* Text to write out after a CALL that may be replaced by glue code by + the loader. This depends on the AIX version. */ +#define RS6000_CALL_GLUE "cror 31,31,31" + /* This is how to output the definition of a user-level label named NAME, such as the label on a static function or variable NAME. */ @@ -1722,13 +1893,44 @@ toc_section () \ /* This is how to output an assembler line defining a `double' constant. */ -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - fprintf (FILE, "\t.double 0d%.20e\n", (VALUE)) +#define ASM_OUTPUT_DOUBLE(FILE, VALUE) \ + { \ + if (REAL_VALUE_ISINF (VALUE) \ + || REAL_VALUE_ISNAN (VALUE) \ + || REAL_VALUE_MINUS_ZERO (VALUE)) \ + { \ + long t[2]; \ + REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ + fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", \ + t[0] & 0xffffffff, t[1] & 0xffffffff); \ + } \ + else \ + { \ + char str[30]; \ + REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str); \ + fprintf (FILE, "\t.double 0d%s\n", str); \ + } \ + } /* This is how to output an assembler line defining a `float' constant. */ -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ - fprintf (FILE, "\t.float 0d%.20e\n", (VALUE)) +#define ASM_OUTPUT_FLOAT(FILE, VALUE) \ + { \ + if (REAL_VALUE_ISINF (VALUE) \ + || REAL_VALUE_ISNAN (VALUE) \ + || REAL_VALUE_MINUS_ZERO (VALUE)) \ + { \ + long t; \ + REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ + fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff); \ + } \ + else \ + { \ + char str[30]; \ + REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ + fprintf (FILE, "\t.float 0d%s\n", str); \ + } \ + } /* This is how to output an assembler line defining an `int' constant. */ @@ -1763,13 +1965,14 @@ toc_section () \ It need not be very fast code. */ #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ - fprintf (FILE, "\tstu %s,-4(r1)\n", reg_names[REGNO]); + asm_fprintf (FILE, "\{tstu|stwu} %s,-4(r1)\n", reg_names[REGNO]); /* This is how to output an insn to pop a register from the stack. It need not be very fast code. */ #define ASM_OUTPUT_REG_POP(FILE,REGNO) \ - fprintf (FILE, "\tl %s,0(r1)\n\tai r1,r1,4\n", reg_names[REGNO]) + asm_fprintf (FILE, "\t{l|lwz} %s,0(r1)\n\t{ai|addic} r1,r1,4\n", \ + reg_names[REGNO]) /* This is how to output an element of a case-vector that is absolute. (RS/6000 does not use such vectors, but we must define this macro @@ -1842,7 +2045,7 @@ toc_section () \ /* Define which CODE values are valid. */ -#define PRINT_OPERAND_PUNCT_VALID_P(CODE) 0 +#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '.') /* Print a memory address as an operand to reference that memory location. */ @@ -1872,8 +2075,11 @@ toc_section () \ {"non_logical_cint_operand", {CONST_INT}}, \ {"mask_operand", {CONST_INT}}, \ {"call_operand", {SYMBOL_REF, REG}}, \ + {"current_file_function_operand", {SYMBOL_REF}}, \ {"input_operand", {SUBREG, MEM, REG, CONST_INT}}, \ - {"branch_comparison_operation", {EQ, NE, LE, LT, GE, \ - LT, LEU, LTU, GEU, GTU}}, \ - {"scc_comparison_operation", {EQ, NE, LE, LT, GE, \ - LT, LEU, LTU, GEU, GTU}}, + {"load_multiple_operation", {PARALLEL}}, \ + {"store_multiple_operation", {PARALLEL}}, \ + {"branch_comparison_operator", {EQ, NE, LE, LT, GE, \ + GT, LEU, LTU, GEU, GTU}}, \ + {"scc_comparison_operator", {EQ, NE, LE, LT, GE, \ + GT, LEU, LTU, GEU, GTU}},