Makefile.in (insn-emit.o): Depend on $(INTEGRATE_H).
gcc/ * 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. From-SVN: r123757
This commit is contained in:
parent
f28d806256
commit
8cb6400cda
@ -1,3 +1,31 @@
|
||||
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.
|
||||
|
@ -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) \
|
||||
|
@ -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 *);
|
||||
|
@ -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)
|
||||
|
@ -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", \
|
||||
|
@ -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]));
|
||||
|
@ -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))")))
|
||||
|
@ -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}}"
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user