diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 28 | ||||
| -rw-r--r-- | gcc/Makefile.in | 2 | ||||
| -rw-r--r-- | gcc/config/mips/mips-protos.h | 19 | ||||
| -rw-r--r-- | gcc/config/mips/mips.c | 30 | ||||
| -rw-r--r-- | gcc/config/mips/mips.h | 22 | ||||
| -rw-r--r-- | gcc/config/mips/mips.md | 33 | ||||
| -rw-r--r-- | gcc/config/mips/predicates.md | 3 | ||||
| -rw-r--r-- | gcc/config/mips/vxworks.h | 3 | ||||
| -rw-r--r-- | gcc/genemit.c | 1 | 
9 files changed, 128 insertions, 13 deletions
| diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aff3184..1003b0f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,33 @@  2007-04-12  Richard Sandiford  <richard@codesourcery.com> +	* Makefile.in (insn-emit.o): Depend on $(INTEGRATE_H). +	* genemit.c (main): Emit #include "integrate.h". +	* config/mips/mips-protos.h (SYMBOL_HALF): New mips_symbol_type. +	(LOADGP_RTP): New mips_loadgp_style. +	* config/mips/mips.h: Include config/vxworks-dummy.h. +	(TARGET_RTP_PIC): New macro. +	(TARGET_USE_GOT): Return true for TARGET_RTP_PIC. +	(TARGET_USE_PIC_FN_ADDR_REG): Return true for TARGET_VXWORKS_RTP. +	(ASM_OUTPUT_ADDR_DIFF_ELT): Emit function-relative case tables +	for TARGET_RTP_PIC. +	* config/mips/vxworks.h (SUBTARGET_ASM_SPEC): Define.  Pass down +	-mvxworks-pic when using -mrtp and a PIC option. +	* config/mips/mips.c (mips_classify_symbol): Return SYMBOL_GOT_DISP +	for RTP PIC. +	(mips_symbolic_constant_p, mips_symbolic_address_p) +	(mips_symbol_insns): Handle SYMBOL_HALF. +	(override_options): Warn about -G and -mrtp being used together. +	Initialize mips_lo_relocs[SYMBOL_HALF]. +	(mips_current_loadgp_style): Return LOADGP_RTP for RTP PIC. +	(mips_emit_loadgp): Handle LOADGP_RTP. +	(mips_in_small_data_p): Return false for TARGET_VXWORKS_RTP. +	* config/mips/mips.md (loadgp_rtp): New insn and splitter. +	(tablejump): Handle function-relative case table entries if +	TARGET_RTP_PIC. +	* config/mips/predicates.md (symbol_ref_operand): New predicate. + +2007-04-12  Richard Sandiford  <richard@codesourcery.com> +  	* config/mips/mips.md (load_call<mode>): Allow any general register.  	destination.  	(sibcall_value_internal, sibcall_value_multiple_internal) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index eeca0dc..9d9146e 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2847,7 +2847,7 @@ insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	\  insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	\    $(RTL_H) $(EXPR_H) $(REAL_H) output.h insn-config.h $(OPTABS_H)	\    reload.h $(RECOG_H) toplev.h $(FUNCTION_H) $(FLAGS_H) hard-reg-set.h	\ -  $(RESOURCE_H) $(TM_P_H) $(BASIC_BLOCK_H) tm-constrs.h +  $(RESOURCE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) tm-constrs.h  insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	\    $(TM_H) $(RTL_H) toplev.h insn-config.h $(RECOG_H)  insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	$(TM_H) \ diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 78cdc1a..94fe227 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -82,7 +82,11 @@ Boston, MA 02110-1301, USA.  */     SYMBOL_64_LOW         For a 64-bit symbolic address X, this is the value of -       (%hi(X) << 16) + %lo(X).  */ +       (%hi(X) << 16) + %lo(X). + +   SYMBOL_HALF +       An UNSPEC wrapper around any kind of address.  It represents the +       low 16 bits of that address.  */  enum mips_symbol_type {    SYMBOL_GENERAL,    SYMBOL_SMALL_DATA, @@ -101,9 +105,10 @@ enum mips_symbol_type {    SYMBOL_TPREL,    SYMBOL_64_HIGH,    SYMBOL_64_MID, -  SYMBOL_64_LOW +  SYMBOL_64_LOW, +  SYMBOL_HALF  }; -#define NUM_SYMBOL_TYPES (SYMBOL_64_LOW + 1) +#define NUM_SYMBOL_TYPES (SYMBOL_HALF + 1)  /* Identifiers a style of $gp initialization sequence. @@ -119,12 +124,16 @@ enum mips_symbol_type {  	by .cpsetup).     LOADGP_ABSOLUTE -	The GNU absolute sequence, as generated by loadgp_absolute.  */ +	The GNU absolute sequence, as generated by loadgp_absolute. + +   LOADGP_RTP +	The VxWorks RTP PIC sequence, as generated by loadgp_rtp.  */  enum mips_loadgp_style {    LOADGP_NONE,    LOADGP_OLDABI,    LOADGP_NEWABI, -  LOADGP_ABSOLUTE +  LOADGP_ABSOLUTE, +  LOADGP_RTP  };  extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_type *); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 9100e99..b672109 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1245,6 +1245,9 @@ mips_symbol_binds_local_p (rtx x)  static enum mips_symbol_type  mips_classify_symbol (rtx x)  { +  if (TARGET_RTP_PIC) +    return SYMBOL_GOT_DISP; +    if (GET_CODE (x) == LABEL_REF)      {        if (TARGET_MIPS16) @@ -1385,6 +1388,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)      case SYMBOL_TPREL:      case SYMBOL_GOTTPREL:      case SYMBOL_TLS: +    case SYMBOL_HALF:        return false;      }    gcc_unreachable (); @@ -1484,6 +1488,7 @@ mips_symbolic_address_p (enum mips_symbol_type symbol_type,      case SYMBOL_64_HIGH:      case SYMBOL_64_MID:      case SYMBOL_64_LOW: +    case SYMBOL_HALF:        return true;      }    gcc_unreachable (); @@ -1630,6 +1635,7 @@ mips_symbol_insns (enum mips_symbol_type type)        return (ABI_HAS_64BIT_SYMBOLS ? 6 : 2);      case SYMBOL_SMALL_DATA: +    case SYMBOL_HALF:        return 1;      case SYMBOL_CONSTANT_POOL: @@ -4886,6 +4892,9 @@ override_options (void)  	warning (0, "%<-G%> is incompatible with %<-mabicalls%>");      } +  if (TARGET_VXWORKS_RTP && mips_section_threshold > 0) +    warning (0, "-G and -mrtp are incompatible"); +    /* mips_split_addresses is a half-way house between explicit       relocations and the traditional assembler macros.  It can       split absolute 32-bit symbolic constants into a high/lo_sum @@ -5192,6 +5201,8 @@ override_options (void)    mips_hi_relocs[SYMBOL_TPREL] = "%tprel_hi(";    mips_lo_relocs[SYMBOL_TPREL] = "%tprel_lo("; +  mips_lo_relocs[SYMBOL_HALF] = "%half("; +    /* We don't have a thread pointer access instruction on MIPS16, or       appropriate TLS relocations.  */    if (TARGET_MIPS16) @@ -6573,6 +6584,9 @@ mips_current_loadgp_style (void)    if (!TARGET_USE_GOT || cfun->machine->global_pointer == 0)      return LOADGP_NONE; +  if (TARGET_RTP_PIC) +    return LOADGP_RTP; +    if (TARGET_ABSOLUTE_ABICALLS)      return LOADGP_ABSOLUTE; @@ -6589,7 +6603,7 @@ static GTY(()) rtx mips_gnu_local_gp;  static void  mips_emit_loadgp (void)  { -  rtx addr, offset, incoming_address; +  rtx addr, offset, incoming_address, base, index;    switch (mips_current_loadgp_style ())      { @@ -6611,6 +6625,14 @@ mips_emit_loadgp (void)  	emit_insn (gen_loadgp_blockage ());        break; +    case LOADGP_RTP: +      base = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (VXWORKS_GOTT_BASE)); +      index = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (VXWORKS_GOTT_INDEX)); +      emit_insn (gen_loadgp_rtp (base, index)); +      if (!TARGET_EXPLICIT_RELOCS) +	emit_insn (gen_loadgp_blockage ()); +      break; +      default:        break;      } @@ -7313,9 +7335,9 @@ mips_in_small_data_p (tree decl)    if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)      return false; -  /* We don't yet generate small-data references for -mabicalls.  See related -     -G handling in override_options.  */ -  if (TARGET_ABICALLS) +  /* We don't yet generate small-data references for -mabicalls or +     VxWorks RTP code.  See the related -G handling in override_options.  */ +  if (TARGET_ABICALLS || TARGET_VXWORKS_RTP)      return false;    if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0) diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index af8a7f4..6cf42a7 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -24,6 +24,8 @@ the Free Software Foundation, 51 Franklin Street, Fifth Floor,  Boston, MA 02110-1301, USA.  */ +#include "config/vxworks-dummy.h" +  /* MIPS external variables defined in mips.c.  */  /* Which processor to schedule for.  Since there is no difference between @@ -143,6 +145,9 @@ extern const struct mips_rtx_cost_data *mips_cost;  /* Run-time compilation parameters selecting different hardware subsets.  */ +/* True if we are generating position-independent VxWorks RTP code.  */ +#define TARGET_RTP_PIC (TARGET_VXWORKS_RTP && flag_pic) +  /* True if the call patterns should be split into a jalr followed by     an instruction to restore $gp.  It is only safe to split the load     from the call when every use of $gp is explicit.  */ @@ -178,7 +183,7 @@ extern const struct mips_rtx_cost_data *mips_cost;    (!TARGET_MIPS16 && (!TARGET_USE_GOT || TARGET_EXPLICIT_RELOCS))  /* True if we need to use a global offset table to access some symbols.  */ -#define TARGET_USE_GOT TARGET_ABICALLS +#define TARGET_USE_GOT (TARGET_ABICALLS || TARGET_RTP_PIC)  /* True if TARGET_USE_GOT and if $gp is a call-clobbered register.  */  #define TARGET_CALL_CLOBBERED_GP (TARGET_ABICALLS && TARGET_OLDABI) @@ -186,8 +191,9 @@ extern const struct mips_rtx_cost_data *mips_cost;  /* True if TARGET_USE_GOT and if $gp is a call-saved register.  */  #define TARGET_CALL_SAVED_GP (TARGET_USE_GOT && !TARGET_CALL_CLOBBERED_GP) -/* True if indirect calls must use register class PIC_FN_ADDR_REG.  */ -#define TARGET_USE_PIC_FN_ADDR_REG TARGET_ABICALLS +/* True if indirect calls must use register class PIC_FN_ADDR_REG. +   This is true for both the PIC and non-PIC VxWorks RTP modes.  */ +#define TARGET_USE_PIC_FN_ADDR_REG (TARGET_ABICALLS || TARGET_VXWORKS_RTP)  /* True if .gpword or .gpdword should be used for switch tables. @@ -2578,6 +2584,16 @@ do {									\      fprintf (STREAM, "\t%s\t%sL%d\n",					\  	     ptr_mode == DImode ? ".gpdword" : ".gpword",		\  	     LOCAL_LABEL_PREFIX, VALUE);				\ +  else if (TARGET_RTP_PIC)						\ +    {									\ +      /* Make the entry relative to the start of the function.  */	\ +      rtx fnsym = XEXP (DECL_RTL (current_function_decl), 0);		\ +      fprintf (STREAM, "\t%s\t%sL%d-",					\ +	       Pmode == DImode ? ".dword" : ".word",			\ +	       LOCAL_LABEL_PREFIX, VALUE);				\ +      assemble_name (STREAM, XSTR (fnsym, 0));				\ +      fprintf (STREAM, "\n");						\ +    }									\    else									\      fprintf (STREAM, "\t%s\t%sL%d\n",					\  	     ptr_mode == DImode ? ".dword" : ".word",			\ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 8fb78ca..2178481 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -4125,6 +4125,30 @@     (set_attr "mode"	"none")     (set_attr "length"	"0")]) +;; Initialize $gp for RTP PIC.  Operand 0 is the __GOTT_BASE__ symbol +;; and operand 1 is the __GOTT_INDEX__ symbol. +(define_insn "loadgp_rtp" +  [(unspec_volatile [(match_operand 0 "symbol_ref_operand") +		     (match_operand 1 "symbol_ref_operand")] UNSPEC_LOADGP)] +  "mips_current_loadgp_style () == LOADGP_RTP" +  "#" +  [(set_attr "length" "12")]) + +(define_split +  [(unspec_volatile [(match_operand:P 0 "symbol_ref_operand") +		     (match_operand:P 1 "symbol_ref_operand")] UNSPEC_LOADGP)] +  "mips_current_loadgp_style () == LOADGP_RTP" +  [(set (match_dup 2) (high:P (match_dup 3))) +   (set (match_dup 2) (unspec:P [(match_dup 2) +				 (match_dup 3)] UNSPEC_LOAD_GOT)) +   (set (match_dup 2) (unspec:P [(match_dup 2) +				 (match_dup 4)] UNSPEC_LOAD_GOT))] +{ +  operands[2] = pic_offset_table_rtx; +  operands[3] = mips_unspec_address (operands[0], SYMBOL_GENERAL); +  operands[4] = mips_unspec_address (operands[1], SYMBOL_HALF); +}) +  ;; Emit a .cprestore directive, which normally expands to a single store  ;; instruction.  Note that we continue to use .cprestore for explicit reloc  ;; code so that jals inside inline asms will work correctly. @@ -4931,6 +4955,15 @@    else if (TARGET_GPWORD)      operands[0] = expand_binop (Pmode, add_optab, operands[0],  				pic_offset_table_rtx, 0, 0, OPTAB_WIDEN); +  else if (TARGET_RTP_PIC) +    { +      /* When generating RTP PIC, we use case table entries that are relative +	 to the start of the function.  Add the function's address to the +	 value we loaded.  */ +      rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM); +      operands[0] = expand_binop (ptr_mode, add_optab, operands[0], +				  start, 0, 0, OPTAB_WIDEN); +    }    if (Pmode == SImode)      emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md index 9f6cc95..16035c8 100644 --- a/gcc/config/mips/predicates.md +++ b/gcc/config/mips/predicates.md @@ -251,6 +251,9 @@    return mips_symbolic_constant_p (op, &type) && type == SYMBOL_GOT_PAGE_OFST;  }) +(define_predicate "symbol_ref_operand" +  (match_code "symbol_ref")) +  (define_predicate "stack_operand"    (and (match_code "mem")         (match_test "mips_stack_address_p (XEXP (op, 0), GET_MODE (op))"))) diff --git a/gcc/config/mips/vxworks.h b/gcc/config/mips/vxworks.h index 574221f..5b6b026e 100644 --- a/gcc/config/mips/vxworks.h +++ b/gcc/config/mips/vxworks.h @@ -86,3 +86,6 @@ VXWORKS_LINK_SPEC  /* No _mcount profiling on VxWorks.  */  #undef FUNCTION_PROFILER  #define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER + +#undef SUBTARGET_ASM_SPEC +#define SUBTARGET_ASM_SPEC "%{mrtp:%{fPIC|fpic:-mvxworks-pic}}" diff --git a/gcc/genemit.c b/gcc/genemit.c index a367f46..64fb312 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -857,6 +857,7 @@ from the machine description file `md'.  */\n\n");    printf ("#include \"tm-constrs.h\"\n");    printf ("#include \"ggc.h\"\n\n");    printf ("#include \"basic-block.h\"\n\n"); +  printf ("#include \"integrate.h\"\n\n");    printf ("#define FAIL return (end_sequence (), _val)\n");    printf ("#define DONE return (_val = get_insns (), end_sequence (), _val)\n\n"); | 
