configure.ac (mips*-*-*linux*, [...]): Use mt-mips-gnu.

* configure.ac (mips*-*-*linux*, mips*-*-gnu*): Use mt-mips-gnu.
	* configure: Regenerate.

config/
	* mt-mips16-compat: New file, taken from mt-mips-elfoabi.
	* mt-mips-elfoabi: Include mt-mips16-compat.
	* mt-mips-gnu: New file.

gcc/
	* config.gcc (mips*-*-linux*, mips64*-*-linux*): Add
	mips/t-libgcc-mips16 to tmake_file.
	* config/mips/mips-protos.h (mips_call_type): New enum.
	(mips_pic_base_register, mips_got_load): Declare.
	(mips_restore_gp): Take an rtx argument.
	(mips_use_pic_fn_addr_reg_p): Declare.
	(mips_expand_call): Replace the sibcall_p argument with
	a mips_call_type argument.  Add a lazy_p parameter.
	(mips_split_call): Declare.
	* config/mips/mips.h (MIPS16_PIC_TEMP_REGNUM): New macro.
	(MIPS16_PIC_TEMP): Likewise.
	(reg_class): Delete M16_NA_REGS.
	(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
	(SYMBOL_FLAG_BIND_NOW, SYMBOL_REF_BIND_NOW_P): New macros.
	(mips_split_hi_p): Declare.
	* config/mips/mips.c (mips_split_hi_p): New array.
	(mips_regno_to_class): Change M16_NA_REGS entries to M16_REGS.
	(mips_got_symbol_type_p): New function.
	(mips_global_symbol_p): Check SYMBOL_REF_EXTERNAL_P.
	(mips16_stub_function_p): New function.
	(mips16_local_function_p): Likewise.
	(mips_use_pic_fn_addr_reg_p): Likewise.
	(mips_cannot_force_const_mem): Return false for HIGHs.
	Extend CONST_INT and symbolic handling to MIPS16, using
	mips_symbol_insns to check that the base symbol type is a
	legitimate constant.  Reject GOT-based constants if
	TARGET_MIPS16_PCREL_LOADS.
	(mips_const_insns): Check targetm.cannot_force_const_mem when
	decomposing a symbolic base and a large offset.
	(mips_emit_call_insn): Add ORIG_ADDR and ADDR parameters.
	When calling a function that needs $25 from MIPS16 code,
	move the target address into $25 separately and add a USE
	to the call insn.
	(mips16_gp_pseudo_reg): Insert the initializer immediately
	before the first real insn.
	(mips_pic_base_register, mips_got_load): New functions.
	(mips_split_symbol): Generalize the name of the LO_SUM_OUT
	parameter to LOW_OUT.  Say that it can be any valid SET_SRC
	when splitting a load-address operation.  Split SYMBOL_GOT_DISP
	constants and highs of SYMBOL_GOT_PAGE_OFST constants.
	(mips_call_tls_get_addr): Update the call to mips_expand_call,
	also passing NULL_RTX rather than const0_rtx as the aux argument.
	(mips_rewrite_small_data_p): Check mips_lo_relocs and mips_split_p
	instead of TARGET_EXPLICIT_RELOCS.
	(mips_ok_for_lazy_binding_p): Check SYMBOL_REF_BIND_NOW_P.
	(mips_load_call_address): Replace the sibcall_p argument with
	a mips_call_type argument.  Use mips_got_load.
	(mips16_local_alias): New structure.
	(mips16_local_aliases): New variable.
	(mips16_local_aliases_hash): New function.
	(mips16_local_aliases_eq): Likewise.
	(mips16_local_alias): Likewise.
	(mips16_stub_function): Likewise.
	(mips16_build_function_stub): Create a local alias for the target
	function.  Handle TARGET_ABICALLS.  For PIC abicalls, emit a
	.cpload directive and an R_MIPS_NONE relocation for the target
	function, then load the alias rather than the function itself.
	Wrap the non-PIC abicalls version in ".option pic0/.option pic2".
	(mips16_copy_fpr_return_value): Use mips16_stub_function and
	mips_expand_call.  Set SYMBOL_REF_BIND_NOW on the symbol.
	(mips16_build_call_stub): Replace the FN parameter with an
	FN_PTR parameter.  Force the address into a register if it
	isn't a call_insn_operand; don't rely on the caller to do this.
	If a call to a locally-defined and locally-binding MIPS16
	function must be made indirectly, redirect the call to the
	function's local alias.  Use mips16_stub_function_p,
	mips16_stub_function, mips_expand_call and use_reg.
	Set SYMBOL_FLAG_BIND_NOW on __mips_call_* symbols.
	Use explicit %hi and %lo accesses where possible.
	Use MIPS_CALL to generate the correct code form of a
	jal instruction.  Add clobbers of $18 instead of uses.
	Update the call to mips_emit_call_insn.
	(mips_expand_call): Replace the SIBCALL_P argument with a
	mips_call_type argument and handle the new MIPS_CALL_EPILOGUE value.
	Take a LAZY_P parameter.  Call mips16_build_call_stub first,
	allowing it to modify the call address.  Update the calls to
	mips_load_call_address and mips_emit_call_insn.
	(mips_split_call): New function.
	(mips_init_relocs): Clear mips_split_hi_p.  Only use %gp_rel if
	!TARGET_MIPS16.  Split SYMBOL_GOT_DISP, and the high parts of
	SYMBOL_GOT_PAGE_OFST, for MIPS16 code.
	(mips_global_pointer): Check mips16_cfun_returns_in_fpr_p.
	(mips_extra_live_on_entry): Include MIPS16_PIC_TEMP_REGNUM
	if TARGET_MIPS16.
	(mips_cprestore_slot): New function.
	(mips_restore_gp): Take a TEMP parameter.  Handle TARGET_MIPS16
	and use mips_cprestore_slot.
	(mips_output_function_prologue): Handle TARGET_MIPS16 for
	LOADGP_OLDABI.
	(mips_emit_loadgp): Move into MIPS16_PIC_TEMP for MIPS16,
	then use a copygp_mips16 instruction to set up $28.
	(mips_expand_prologue): Initialize the cprestore slot for MIPS16 too.
	(mips16_lay_out_constants): Call split_all_insns_noflow.
	(mips_reorg_process_insns): Explicitly set all_noreorder_p to
	false if TARGET_MIPS16.
	(mips_reorg): Don't call vr4130_align_insns if TARGET_MIPS16.
	(mips_output_mi_thunk): Use mips_got_symbol_type_p.  Use the
	mips_dangerous_for_la25_p approach for MIPS16 PIC calls too.
	(mips_set_mips16_mode): Always set MASK_EXPLICIT_RELOCS for
	MIPS16 code.  Allow MIPS16 o32 PIC.
	(mips_override_options): Allow MIPS16 o32 PIC.
	* config/mips/mips.md: Lower CONST_GP_P moves into register moves
	after reload if TARGET_USE_GOT.
	(UNSPEC_COPYGP): New constant.
	(length): Use a default length of 8 for MIPS16 GOT loads.
	(*got_disp<mode>): Check mips_split_p instead of TARGET_XGOT.
	(*got_page<mode>): Check mips_split_hi_p.
	(*got_disp<mode>, *got_page<mode>): Use mips_got_load.
	(unspec_got<mode>, unspec_call<mode>): New expanders.
	(load_got<mode>, load_call<mode>): Remove the length attributes.
	Use a got attribute instead of a type attribute.
	(copygp_mips16): New insn.
	(restore_gp): Add a scratch clobber and pass it to mips_restore_gp.
	(load_call<mode>): Use a "d" constraint instead of an "r" constraint.
	(sibcall, sibcall_value, call, call_value): Update the calls
	to mips_expand_call.
	(call_internal, call_value_internal): Use mips_split_call.
	(call_value_multiple_internal): Likewise.
	(call_split): Move after call_internal (the insn it is split from).
	(call_internal_direct, call_value_internal_direct): Turn into
	define_insn_and_splits.  Split if TARGET_SPLIT_CALLS.
	(call_direct_split, call_value_direct_split): New patterns.
	* config/mips/constraints.md (c): Handle TARGET_MIPS16 first
	and use M16_REGS instead of M16_NA_REGS.
	* config/mips/predicates.md (const_call_insn_operand): Replace
	the TARGET_ABSOLUTE_ABICALLS-based check with a more general
	mips_use_pic_fn_addr_reg_p check.
	(move_operand): Reject HIGHs if mips_split_hi_p.
	* config/mips/mips16.S: Assembly as empty if the ABI is not suitable.
	(__mips16_floatunsisf): Inline __mips16_floatsisf.
	(CALL_STUB_NO_RET, CALL_STUB_REG): Copy the target register to $25.
	* config/mips/libgcc-mips16.ver: New file.
	* config/mips/t-libgcc-mips16 (SHLIB_MAPFILES): Add
	$(srcdir)/config/mips/libgcc-mips16.ver.

gcc/testsuite/
	* lib/target-supports.exp (check_profiling_available): Return false
	for -p and -pg on MIPS16 targets.

From-SVN: r138912
This commit is contained in:
Richard Sandiford 2008-08-09 19:08:15 +00:00 committed by Richard Sandiford
parent 7462a71535
commit 08d0963a0e
20 changed files with 1058 additions and 279 deletions

View File

@ -1,3 +1,8 @@
2008-08-09 Richard Sandiford <rdsandiford@googlemail.com>
* configure.ac (mips*-*-*linux*, mips*-*-gnu*): Use mt-mips-gnu.
* configure: Regenerate.
2008-07-30 Paolo Bonzini <bonzini@gnu.org>
* configure.ac: Add makefile fragments for hpux.

View File

@ -1,3 +1,9 @@
2008-08-09 Richard Sandiford <rdsandiford@googlemail.com>
* mt-mips16-compat: New file, taken from mt-mips-elfoabi.
* mt-mips-elfoabi: Include mt-mips16-compat.
* mt-mips-gnu: New file.
2008-08-03 Alan Modra <amodra@bigpond.net.au>
* mt-spu (all-ld): Update for ld Makefile changes.

View File

@ -1,6 +1 @@
# The *-elfoabi configurations are intended to be usable for both
# MIPS16 and non-MIPS16 code, but the libraries are all non-MIPS16.
# Add -minterlink-mips16 so that the libraries can be used with both
# ISA modes.
CFLAGS_FOR_TARGET += -minterlink-mips16
CXXFLAGS_FOR_TARGET += -minterlink-mips16
include $(srcdir)/config/mt-mips16-compat

2
config/mt-mips-gnu Normal file
View File

@ -0,0 +1,2 @@
include $(srcdir)/config/mt-gnu
include $(srcdir)/config/mt-mips16-compat

5
config/mt-mips16-compat Normal file
View File

@ -0,0 +1,5 @@
# Configurations use this fragment if they support MIPS16 and non-MIPS16 code,
# but if the libraries are all non-MIPS16. Add -minterlink-mips16 so
# that the libraries can be used with both ISA modes.
CFLAGS_FOR_TARGET += -minterlink-mips16
CXXFLAGS_FOR_TARGET += -minterlink-mips16

3
configure vendored
View File

@ -5448,6 +5448,9 @@ case "${target}" in
mipsisa*-*-elfoabi*)
target_makefile_frag="config/mt-mips-elfoabi"
;;
mips*-*-*linux* | mips*-*-gnu*)
target_makefile_frag="config/mt-mips-gnu"
;;
*-*-netware*)
target_makefile_frag="config/mt-netware"
;;

View File

@ -1904,6 +1904,9 @@ case "${target}" in
mipsisa*-*-elfoabi*)
target_makefile_frag="config/mt-mips-elfoabi"
;;
mips*-*-*linux* | mips*-*-gnu*)
target_makefile_frag="config/mt-mips-gnu"
;;
*-*-netware*)
target_makefile_frag="config/mt-netware"
;;

View File

@ -1,3 +1,140 @@
2008-08-09 Richard Sandiford <rdsandiford@googlemail.com>
* config.gcc (mips*-*-linux*, mips64*-*-linux*): Add
mips/t-libgcc-mips16 to tmake_file.
* config/mips/mips-protos.h (mips_call_type): New enum.
(mips_pic_base_register, mips_got_load): Declare.
(mips_restore_gp): Take an rtx argument.
(mips_use_pic_fn_addr_reg_p): Declare.
(mips_expand_call): Replace the sibcall_p argument with
a mips_call_type argument. Add a lazy_p parameter.
(mips_split_call): Declare.
* config/mips/mips.h (MIPS16_PIC_TEMP_REGNUM): New macro.
(MIPS16_PIC_TEMP): Likewise.
(reg_class): Delete M16_NA_REGS.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
(SYMBOL_FLAG_BIND_NOW, SYMBOL_REF_BIND_NOW_P): New macros.
(mips_split_hi_p): Declare.
* config/mips/mips.c (mips_split_hi_p): New array.
(mips_regno_to_class): Change M16_NA_REGS entries to M16_REGS.
(mips_got_symbol_type_p): New function.
(mips_global_symbol_p): Check SYMBOL_REF_EXTERNAL_P.
(mips16_stub_function_p): New function.
(mips16_local_function_p): Likewise.
(mips_use_pic_fn_addr_reg_p): Likewise.
(mips_cannot_force_const_mem): Return false for HIGHs.
Extend CONST_INT and symbolic handling to MIPS16, using
mips_symbol_insns to check that the base symbol type is a
legitimate constant. Reject GOT-based constants if
TARGET_MIPS16_PCREL_LOADS.
(mips_const_insns): Check targetm.cannot_force_const_mem when
decomposing a symbolic base and a large offset.
(mips_emit_call_insn): Add ORIG_ADDR and ADDR parameters.
When calling a function that needs $25 from MIPS16 code,
move the target address into $25 separately and add a USE
to the call insn.
(mips16_gp_pseudo_reg): Insert the initializer immediately
before the first real insn.
(mips_pic_base_register, mips_got_load): New functions.
(mips_split_symbol): Generalize the name of the LO_SUM_OUT
parameter to LOW_OUT. Say that it can be any valid SET_SRC
when splitting a load-address operation. Split SYMBOL_GOT_DISP
constants and highs of SYMBOL_GOT_PAGE_OFST constants.
(mips_call_tls_get_addr): Update the call to mips_expand_call,
also passing NULL_RTX rather than const0_rtx as the aux argument.
(mips_rewrite_small_data_p): Check mips_lo_relocs and mips_split_p
instead of TARGET_EXPLICIT_RELOCS.
(mips_ok_for_lazy_binding_p): Check SYMBOL_REF_BIND_NOW_P.
(mips_load_call_address): Replace the sibcall_p argument with
a mips_call_type argument. Use mips_got_load.
(mips16_local_alias): New structure.
(mips16_local_aliases): New variable.
(mips16_local_aliases_hash): New function.
(mips16_local_aliases_eq): Likewise.
(mips16_local_alias): Likewise.
(mips16_stub_function): Likewise.
(mips16_build_function_stub): Create a local alias for the target
function. Handle TARGET_ABICALLS. For PIC abicalls, emit a
.cpload directive and an R_MIPS_NONE relocation for the target
function, then load the alias rather than the function itself.
Wrap the non-PIC abicalls version in ".option pic0/.option pic2".
(mips16_copy_fpr_return_value): Use mips16_stub_function and
mips_expand_call. Set SYMBOL_REF_BIND_NOW on the symbol.
(mips16_build_call_stub): Replace the FN parameter with an
FN_PTR parameter. Force the address into a register if it
isn't a call_insn_operand; don't rely on the caller to do this.
If a call to a locally-defined and locally-binding MIPS16
function must be made indirectly, redirect the call to the
function's local alias. Use mips16_stub_function_p,
mips16_stub_function, mips_expand_call and use_reg.
Set SYMBOL_FLAG_BIND_NOW on __mips_call_* symbols.
Use explicit %hi and %lo accesses where possible.
Use MIPS_CALL to generate the correct code form of a
jal instruction. Add clobbers of $18 instead of uses.
Update the call to mips_emit_call_insn.
(mips_expand_call): Replace the SIBCALL_P argument with a
mips_call_type argument and handle the new MIPS_CALL_EPILOGUE value.
Take a LAZY_P parameter. Call mips16_build_call_stub first,
allowing it to modify the call address. Update the calls to
mips_load_call_address and mips_emit_call_insn.
(mips_split_call): New function.
(mips_init_relocs): Clear mips_split_hi_p. Only use %gp_rel if
!TARGET_MIPS16. Split SYMBOL_GOT_DISP, and the high parts of
SYMBOL_GOT_PAGE_OFST, for MIPS16 code.
(mips_global_pointer): Check mips16_cfun_returns_in_fpr_p.
(mips_extra_live_on_entry): Include MIPS16_PIC_TEMP_REGNUM
if TARGET_MIPS16.
(mips_cprestore_slot): New function.
(mips_restore_gp): Take a TEMP parameter. Handle TARGET_MIPS16
and use mips_cprestore_slot.
(mips_output_function_prologue): Handle TARGET_MIPS16 for
LOADGP_OLDABI.
(mips_emit_loadgp): Move into MIPS16_PIC_TEMP for MIPS16,
then use a copygp_mips16 instruction to set up $28.
(mips_expand_prologue): Initialize the cprestore slot for MIPS16 too.
(mips16_lay_out_constants): Call split_all_insns_noflow.
(mips_reorg_process_insns): Explicitly set all_noreorder_p to
false if TARGET_MIPS16.
(mips_reorg): Don't call vr4130_align_insns if TARGET_MIPS16.
(mips_output_mi_thunk): Use mips_got_symbol_type_p. Use the
mips_dangerous_for_la25_p approach for MIPS16 PIC calls too.
(mips_set_mips16_mode): Always set MASK_EXPLICIT_RELOCS for
MIPS16 code. Allow MIPS16 o32 PIC.
(mips_override_options): Allow MIPS16 o32 PIC.
* config/mips/mips.md: Lower CONST_GP_P moves into register moves
after reload if TARGET_USE_GOT.
(UNSPEC_COPYGP): New constant.
(length): Use a default length of 8 for MIPS16 GOT loads.
(*got_disp<mode>): Check mips_split_p instead of TARGET_XGOT.
(*got_page<mode>): Check mips_split_hi_p.
(*got_disp<mode>, *got_page<mode>): Use mips_got_load.
(unspec_got<mode>, unspec_call<mode>): New expanders.
(load_got<mode>, load_call<mode>): Remove the length attributes.
Use a got attribute instead of a type attribute.
(copygp_mips16): New insn.
(restore_gp): Add a scratch clobber and pass it to mips_restore_gp.
(load_call<mode>): Use a "d" constraint instead of an "r" constraint.
(sibcall, sibcall_value, call, call_value): Update the calls
to mips_expand_call.
(call_internal, call_value_internal): Use mips_split_call.
(call_value_multiple_internal): Likewise.
(call_split): Move after call_internal (the insn it is split from).
(call_internal_direct, call_value_internal_direct): Turn into
define_insn_and_splits. Split if TARGET_SPLIT_CALLS.
(call_direct_split, call_value_direct_split): New patterns.
* config/mips/constraints.md (c): Handle TARGET_MIPS16 first
and use M16_REGS instead of M16_NA_REGS.
* config/mips/predicates.md (const_call_insn_operand): Replace
the TARGET_ABSOLUTE_ABICALLS-based check with a more general
mips_use_pic_fn_addr_reg_p check.
(move_operand): Reject HIGHs if mips_split_hi_p.
* config/mips/mips16.S: Assembly as empty if the ABI is not suitable.
(__mips16_floatunsisf): Inline __mips16_floatsisf.
(CALL_STUB_NO_RET, CALL_STUB_REG): Copy the target register to $25.
* config/mips/libgcc-mips16.ver: New file.
* config/mips/t-libgcc-mips16 (SHLIB_MAPFILES): Add
$(srcdir)/config/mips/libgcc-mips16.ver.
2008-08-09 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (mips_unspec_address_offset): Move earlier in file.

View File

@ -1544,7 +1544,7 @@ mips*-*-netbsd*) # NetBSD/mips, either endian.
;;
mips64*-*-linux* | mipsisa64*-*-linux*)
tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h mips/linux64.h"
tmake_file="${tmake_file} mips/t-linux64"
tmake_file="${tmake_file} mips/t-linux64 mips/t-libgcc-mips16"
tm_defines="${tm_defines} MIPS_ABI_DEFAULT=ABI_N32"
case ${target} in
mips64el-st-linux-gnu)
@ -1561,6 +1561,7 @@ mips64*-*-linux* | mipsisa64*-*-linux*)
;;
mips*-*-linux*) # Linux MIPS, either endian.
tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h"
tmake_file="${tmake_file} mips/t-libgcc-mips16"
case ${target} in
mipsisa32r2*)
tm_defines="${tm_defines} MIPS_ISA_DEFAULT=33"

View File

@ -43,8 +43,10 @@
(define_register_constraint "b" "ALL_REGS"
"@internal")
(define_register_constraint "c" "TARGET_USE_PIC_FN_ADDR_REG ? PIC_FN_ADDR_REG
: TARGET_MIPS16 ? M16_NA_REGS
;; MIPS16 code always calls through a MIPS16 register; see mips_emit_call_insn
;; for details.
(define_register_constraint "c" "TARGET_MIPS16 ? M16_REGS
: TARGET_USE_PIC_FN_ADDR_REG ? PIC_FN_ADDR_REG
: GR_REGS"
"A register suitable for use in an indirect jump. This will always be
@code{$25} for @option{-mabicalls}.")

View File

@ -0,0 +1,68 @@
GCC_4.4.0 {
__mips16_addsf3
__mips16_subsf3
__mips16_mulsf3
__mips16_divsf3
__mips16_eqsf2
__mips16_nesf2
__mips16_gtsf2
__mips16_gesf2
__mips16_lesf2
__mips16_ltsf2
__mips16_floatsisf
__mips16_floatunsisf
__mips16_fix_truncsfsi
__mips16_adddf3
__mips16_subdf3
__mips16_muldf3
__mips16_divdf3
__mips16_extendsfdf2
__mips16_truncdfsf2
__mips16_eqdf2
__mips16_nedf2
__mips16_gtdf2
__mips16_gedf2
__mips16_ledf2
__mips16_ltdf2
__mips16_floatsidf
__mips16_floatunsidf
__mips16_fix_truncdfsi
__mips16_ret_sf
__mips16_ret_sc
__mips16_ret_df
__mips16_ret_dc
__mips16_call_stub_1
__mips16_call_stub_5
__mips16_call_stub_2
__mips16_call_stub_6
__mips16_call_stub_9
__mips16_call_stub_10
__mips16_call_stub_sf_0
__mips16_call_stub_sf_1
__mips16_call_stub_sf_5
__mips16_call_stub_sf_2
__mips16_call_stub_sf_6
__mips16_call_stub_sf_9
__mips16_call_stub_sf_10
__mips16_call_stub_sc_0
__mips16_call_stub_sc_1
__mips16_call_stub_sc_5
__mips16_call_stub_sc_2
__mips16_call_stub_sc_6
__mips16_call_stub_sc_9
__mips16_call_stub_sc_10
__mips16_call_stub_df_0
__mips16_call_stub_df_1
__mips16_call_stub_df_5
__mips16_call_stub_df_2
__mips16_call_stub_df_6
__mips16_call_stub_df_9
__mips16_call_stub_df_10
__mips16_call_stub_dc_0
__mips16_call_stub_dc_1
__mips16_call_stub_dc_5
__mips16_call_stub_dc_2
__mips16_call_stub_dc_6
__mips16_call_stub_dc_9
__mips16_call_stub_dc_10
}

View File

@ -164,6 +164,22 @@ enum mips_loadgp_style {
struct mips16e_save_restore_info;
/* Classifies a type of call.
MIPS_CALL_NORMAL
A normal call or call_value pattern.
MIPS_CALL_SIBCALL
A sibcall or sibcall_value pattern.
MIPS_CALL_EPILOGUE
A call inserted in the epilogue. */
enum mips_call_type {
MIPS_CALL_NORMAL,
MIPS_CALL_SIBCALL,
MIPS_CALL_EPILOGUE
};
extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_context,
enum mips_symbol_type *);
extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, bool);
@ -175,6 +191,8 @@ extern int mips_split_const_insns (rtx);
extern int mips_load_store_insns (rtx, rtx);
extern int mips_idiv_insns (void);
extern rtx mips_emit_move (rtx, rtx);
extern rtx mips_pic_base_register (rtx);
extern rtx mips_got_load (rtx, rtx, enum mips_symbol_type);
extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *);
extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
extern bool mips_legitimize_address (rtx *, enum machine_mode);
@ -202,7 +220,7 @@ extern rtx mips_subword (rtx, bool);
extern bool mips_split_64bit_move_p (rtx, rtx);
extern void mips_split_doubleword_move (rtx, rtx);
extern const char *mips_output_move (rtx, rtx);
extern void mips_restore_gp (void);
extern void mips_restore_gp (rtx);
#ifdef RTX_CODE
extern bool mips_expand_scc (enum rtx_code, rtx);
extern void mips_expand_conditional_branch (rtx *, enum rtx_code);
@ -210,7 +228,9 @@ extern void mips_expand_vcondv2sf (rtx, rtx, rtx, enum rtx_code, rtx, rtx);
extern void mips_expand_conditional_move (rtx *);
extern void mips_expand_conditional_trap (enum rtx_code);
#endif
extern rtx mips_expand_call (rtx, rtx, rtx, rtx, bool);
extern bool mips_use_pic_fn_addr_reg_p (const_rtx);
extern rtx mips_expand_call (enum mips_call_type, rtx, rtx, rtx, rtx, bool);
extern void mips_split_call (rtx, rtx);
extern void mips_expand_fcc_reload (rtx, rtx, rtx);
extern void mips_set_return_address (rtx, rtx);
extern bool mips_expand_block_move (rtx, rtx, rtx);

File diff suppressed because it is too large Load Diff

View File

@ -1659,16 +1659,29 @@ enum mips_code_readable_setting {
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 15)
/* Registers used as temporaries in prologue/epilogue code. If we're
generating mips16 code, these registers must come from the core set
of 8. The prologue register mustn't conflict with any incoming
arguments, the static chain pointer, or the frame pointer. The
epilogue temporary mustn't conflict with the return registers, the
frame pointer, the EH stack adjustment, or the EH data registers. */
/* Registers used as temporaries in prologue/epilogue code:
- If a MIPS16 PIC function needs access to _gp, it first loads
the value into MIPS16_PIC_TEMP and then copies it to $gp.
- The prologue can use MIPS_PROLOGUE_TEMP as a general temporary
register. The register must not conflict with MIPS16_PIC_TEMP.
- The epilogue can use MIPS_EPILOGUE_TEMP as a general temporary
register.
If we're generating MIPS16 code, these registers must come from the
core set of 8. The prologue registers mustn't conflict with any
incoming arguments, the static chain pointer, or the frame pointer.
The epilogue temporary mustn't conflict with the return registers,
the PIC call register ($25), the frame pointer, the EH stack adjustment,
or the EH data registers. */
#define MIPS16_PIC_TEMP_REGNUM (GP_REG_FIRST + 2)
#define MIPS_PROLOGUE_TEMP_REGNUM (GP_REG_FIRST + 3)
#define MIPS_EPILOGUE_TEMP_REGNUM (GP_REG_FIRST + (TARGET_MIPS16 ? 6 : 8))
#define MIPS16_PIC_TEMP gen_rtx_REG (Pmode, MIPS16_PIC_TEMP_REGNUM)
#define MIPS_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, MIPS_PROLOGUE_TEMP_REGNUM)
#define MIPS_EPILOGUE_TEMP(MODE) gen_rtx_REG (MODE, MIPS_EPILOGUE_TEMP_REGNUM)
@ -1716,7 +1729,6 @@ enum mips_code_readable_setting {
enum reg_class
{
NO_REGS, /* no registers in set */
M16_NA_REGS, /* mips16 regs not used to pass args */
M16_REGS, /* mips16 directly accessible registers */
T_REG, /* mips16 T register ($24) */
M16_T_REGS, /* mips16 registers plus T register */
@ -1757,7 +1769,6 @@ enum reg_class
#define REG_CLASS_NAMES \
{ \
"NO_REGS", \
"M16_NA_REGS", \
"M16_REGS", \
"T_REG", \
"M16_T_REGS", \
@ -1801,7 +1812,6 @@ enum reg_class
#define REG_CLASS_CONTENTS \
{ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* no registers */ \
{ 0x0003000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 nonarg regs */\
{ 0x000300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 registers */ \
{ 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 T register */ \
{ 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 and T regs */ \
@ -2419,6 +2429,11 @@ typedef struct mips_args {
#define SYMBOL_REF_LONG_CALL_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
/* This flag marks functions that cannot be lazily bound. */
#define SYMBOL_FLAG_BIND_NOW (SYMBOL_FLAG_MACH_DEP << 1)
#define SYMBOL_REF_BIND_NOW_P(RTX) \
((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_BIND_NOW) != 0)
/* True if we're generating a form of MIPS16 code in which jump tables
are stored in the text section and encoded as 16-bit PC-relative
offsets. This is only possible when general text loads are allowed,
@ -3280,6 +3295,7 @@ extern int set_nomacro; /* # of nested .set nomacro's */
extern int mips_dbx_regno[];
extern int mips_dwarf_regno[];
extern bool mips_split_p[];
extern bool mips_split_hi_p[];
extern GTY(()) rtx cmp_operands[2];
extern enum processor_type mips_arch; /* which cpu to codegen for */
extern enum processor_type mips_tune; /* which cpu to schedule for */

View File

@ -66,6 +66,7 @@
(UNSPEC_MEMORY_BARRIER 45)
(UNSPEC_SET_GOT_VERSION 46)
(UNSPEC_UPDATE_GOT_VERSION 47)
(UNSPEC_COPYGP 48)
(UNSPEC_ADDRESS_FIRST 100)
@ -478,7 +479,9 @@
(const_int 0)
(eq_attr "got" "load")
(const_int 4)
(if_then_else (ne (symbol_ref "TARGET_MIPS16") (const_int 0))
(const_int 8)
(const_int 4))
(eq_attr "got" "xgot_high")
(const_int 8)
@ -3590,15 +3593,11 @@
(define_insn_and_split "*got_disp<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(match_operand:P 1 "got_disp_operand" ""))]
"TARGET_EXPLICIT_RELOCS && !TARGET_XGOT"
"TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
{
operands[2] = pic_offset_table_rtx;
operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP);
}
[(set (match_dup 0) (match_dup 2))]
{ operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); }
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
@ -3607,18 +3606,19 @@
(define_insn_and_split "*got_page<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(high:P (match_operand:P 1 "got_page_ofst_operand" "")))]
"TARGET_EXPLICIT_RELOCS"
"TARGET_EXPLICIT_RELOCS && !mips_split_hi_p[SYMBOL_GOT_PAGE_OFST]"
"#"
"&& reload_completed"
[(set (match_dup 0)
(unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))]
{
operands[2] = pic_offset_table_rtx;
operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE);
}
[(set (match_dup 0) (match_dup 2))]
{ operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_PAGE); }
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
;; Convenience expander that generates the rhs of a load_got<mode> insn.
(define_expand "unspec_got<mode>"
[(unspec:P [(match_operand:P 0)
(match_operand:P 1)] UNSPEC_LOAD_GOT)])
;; Lower-level instructions for loading an address from the GOT.
;; We could use MEMs, but an unspec gives more optimization
;; opportunities.
@ -3630,9 +3630,8 @@
UNSPEC_LOAD_GOT))]
""
"<load>\t%0,%R2(%1)"
[(set_attr "type" "load")
(set_attr "mode" "<MODE>")
(set_attr "length" "4")])
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
;; Instructions for adding the low 16 bits of an address to a register.
;; Operand 2 is the address: mips_print_operand works out which relocation
@ -3657,6 +3656,15 @@
(set_attr "mode" "<MODE>")
(set_attr "extended_mips16" "yes")])
;; Expose MIPS16 uses of the global pointer after reload if the function
;; is responsible for setting up the register itself.
(define_split
[(set (match_operand:GPR 0 "d_operand")
(const:GPR (unspec:GPR [(const_int 0)] UNSPEC_GP)))]
"TARGET_MIPS16 && TARGET_USE_GOT && reload_completed"
[(set (match_dup 0) (match_dup 1))]
{ operands[1] = pic_offset_table_rtx; })
;; Allow combine to split complex const_int load sequences, using operand 2
;; to store the intermediate results. See move_operand for details.
(define_split
@ -4521,6 +4529,18 @@
}
[(set_attr "length" "12")])
;; Initialize the global pointer for MIPS16 code. Operand 0 is the
;; global pointer and operand 1 is the MIPS16 register that holds
;; the required value.
(define_insn_and_split "copygp_mips16"
[(set (match_operand:SI 0 "register_operand" "=y")
(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
UNSPEC_COPYGP))]
"TARGET_MIPS16"
"#"
"&& reload_completed"
[(set (match_dup 0) (match_dup 1))])
;; 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.
@ -5981,16 +6001,17 @@
;; volatile until all uses of $28 are exposed.
(define_insn_and_split "restore_gp"
[(set (reg:SI 28)
(unspec_volatile:SI [(const_int 0)] UNSPEC_RESTORE_GP))]
(unspec_volatile:SI [(const_int 0)] UNSPEC_RESTORE_GP))
(clobber (match_scratch:SI 0 "=&d"))]
"TARGET_CALL_CLOBBERED_GP"
"#"
"&& reload_completed"
[(const_int 0)]
{
mips_restore_gp ();
mips_restore_gp (operands[0]);
DONE;
}
[(set_attr "type" "load")
[(set_attr "type" "load")
(set_attr "length" "12")])
;;
@ -6043,16 +6064,22 @@
;; - Leave GOT_VERSION_REGNUM out of all register classes.
;; The register is therefore not a valid register_operand
;; and cannot be moved to or from other registers.
;; Convenience expander that generates the rhs of a load_call<mode> insn.
(define_expand "unspec_call<mode>"
[(unspec:P [(match_operand:P 0)
(match_operand:P 1)
(reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL)])
(define_insn "load_call<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(unspec:P [(match_operand:P 1 "register_operand" "r")
(unspec:P [(match_operand:P 1 "register_operand" "d")
(match_operand:P 2 "immediate_operand" "")
(reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))]
"TARGET_USE_GOT"
"<load>\t%0,%R2(%1)"
[(set_attr "type" "load")
(set_attr "mode" "<MODE>")
(set_attr "length" "4")])
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
(define_insn "set_got_version"
[(set (reg:SI GOT_VERSION_REGNUM)
@ -6088,7 +6115,8 @@
(use (match_operand 3 ""))])] ;; struct_value_size_rtx
"TARGET_SIBCALLS"
{
mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true);
mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0),
operands[1], operands[2], false);
DONE;
})
@ -6106,8 +6134,8 @@
(use (match_operand 3 ""))])] ;; next_arg_reg
"TARGET_SIBCALLS"
{
mips_expand_call (operands[0], XEXP (operands[1], 0),
operands[2], operands[3], true);
mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0),
operands[2], operands[3], false);
DONE;
})
@ -6137,7 +6165,8 @@
(use (match_operand 3 ""))])] ;; struct_value_size_rtx
""
{
mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false);
mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0),
operands[1], operands[2], false);
DONE;
})
@ -6187,28 +6216,44 @@
"reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
[(const_int 0)]
{
emit_call_insn (gen_call_split (operands[0], operands[1]));
if (!find_reg_note (operands[2], REG_NORETURN, 0))
mips_restore_gp ();
mips_split_call (operands[2], gen_call_split (operands[0], operands[1]));
DONE;
}
[(set_attr "jal" "indirect,direct")])
(define_insn "call_split"
[(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
(match_operand 1 "" ""))
(clobber (reg:SI 31))
(clobber (reg:SI 28))]
"TARGET_SPLIT_CALLS"
{ return MIPS_CALL ("jal", operands, 0); }
[(set_attr "type" "call")])
;; A pattern for calls that must be made directly. It is used for
;; MIPS16 calls that the linker may need to redirect to a hard-float
;; stub; the linker relies on the call relocation type to detect when
;; such redirection is needed.
(define_insn "call_internal_direct"
(define_insn_and_split "call_internal_direct"
[(call (mem:SI (match_operand 0 "const_call_insn_operand"))
(match_operand 1))
(const_int 1)
(clobber (reg:SI 31))]
""
{ return MIPS_CALL ("jal", operands, 0); })
{ return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); }
"reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)"
[(const_int 0)]
{
mips_split_call (operands[2],
gen_call_direct_split (operands[0], operands[1]));
DONE;
}
[(set_attr "type" "call")])
(define_insn "call_split"
[(call (mem:SI (match_operand 0 "call_insn_operand" "cS"))
(match_operand 1 "" ""))
(define_insn "call_direct_split"
[(call (mem:SI (match_operand 0 "const_call_insn_operand"))
(match_operand 1))
(const_int 1)
(clobber (reg:SI 31))
(clobber (reg:SI 28))]
"TARGET_SPLIT_CALLS"
@ -6222,7 +6267,7 @@
(use (match_operand 3 ""))])] ;; next_arg_reg
""
{
mips_expand_call (operands[0], XEXP (operands[1], 0),
mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0),
operands[2], operands[3], false);
DONE;
})
@ -6238,10 +6283,9 @@
"reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
[(const_int 0)]
{
emit_call_insn (gen_call_value_split (operands[0], operands[1],
operands[2]));
if (!find_reg_note (operands[3], REG_NORETURN, 0))
mips_restore_gp ();
mips_split_call (operands[3],
gen_call_value_split (operands[0], operands[1],
operands[2]));
DONE;
}
[(set_attr "jal" "indirect,direct")])
@ -6257,14 +6301,34 @@
[(set_attr "type" "call")])
;; See call_internal_direct.
(define_insn "call_value_internal_direct"
(define_insn_and_split "call_value_internal_direct"
[(set (match_operand 0 "register_operand")
(call (mem:SI (match_operand 1 "const_call_insn_operand"))
(match_operand 2)))
(const_int 1)
(clobber (reg:SI 31))]
""
{ return MIPS_CALL ("jal", operands, 1); })
{ return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); }
"reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)"
[(const_int 0)]
{
mips_split_call (operands[3],
gen_call_value_direct_split (operands[0], operands[1],
operands[2]));
DONE;
}
[(set_attr "type" "call")])
(define_insn "call_value_direct_split"
[(set (match_operand 0 "register_operand")
(call (mem:SI (match_operand 1 "const_call_insn_operand"))
(match_operand 2)))
(const_int 1)
(clobber (reg:SI 31))
(clobber (reg:SI 28))]
"TARGET_SPLIT_CALLS"
{ return MIPS_CALL ("jal", operands, 1); }
[(set_attr "type" "call")])
;; See comment for call_internal.
(define_insn_and_split "call_value_multiple_internal"
@ -6280,10 +6344,9 @@
"reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)"
[(const_int 0)]
{
emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1],
operands[2], operands[3]));
if (!find_reg_note (operands[4], REG_NORETURN, 0))
mips_restore_gp ();
mips_split_call (operands[4],
gen_call_value_multiple_split (operands[0], operands[1],
operands[2], operands[3]));
DONE;
}
[(set_attr "jal" "indirect,direct")])

View File

@ -38,6 +38,8 @@ Boston, MA 02110-1301, USA. */
values using the soft-float calling convention, but do the actual
operation using the hard floating point instructions. */
#if defined _MIPS_SIM && (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIO64)
/* This file contains 32-bit assembly code. */
.set nomips16
@ -303,8 +305,12 @@ STARTFN (__mips16_floatsisf)
#ifdef L_m16fltunsisf
STARTFN (__mips16_floatunsisf)
.set noreorder
bltz $4,1f
j __mips16_floatsisf
MOVE_SF_BYTE0 (t)
.set reorder
cvt.s.w RET,ARG1
MOVE_SF_RET (f, $31)
1:
and $2,$4,1
srl $3,$4,1
@ -522,7 +528,10 @@ RET_FUNCTION (__mips16_ret_dc, DC)
#define CALL_STUB_NO_RET(NAME, CODE) \
STARTFN (NAME); \
STUB_ARGS_##CODE; \
.set noreorder; \
jr $2; \
move $25,$2; \
.set reorder; \
ENDFN (NAME)
#ifdef L_m16stub1
@ -569,7 +578,10 @@ CALL_STUB_NO_RET (__mips16_call_stub_10, 10)
STARTFN (NAME); \
move $18,$31; \
STUB_ARGS_##CODE; \
.set noreorder; \
jalr $2; \
move $25,$2; \
.set reorder; \
MOVE_##MODE##_RET (f, $18); \
ENDFN (NAME)
@ -705,3 +717,4 @@ CALL_STUB_RET (__mips16_call_stub_dc_9, 9, DC)
CALL_STUB_RET (__mips16_call_stub_dc_10, 10, DC)
#endif
#endif /* !__mips_single_float */
#endif

View File

@ -104,14 +104,9 @@
switch (symbol_type)
{
case SYMBOL_ABSOLUTE:
/* We can only use direct calls for TARGET_ABSOLUTE_ABICALLS if we
are sure that the target function does not need $25 to be live
on entry. This is true for any locally-defined function because
any such function will use %hi/%lo accesses to set up $gp. */
if (TARGET_ABSOLUTE_ABICALLS
&& !(GET_CODE (op) == SYMBOL_REF
&& SYMBOL_REF_DECL (op)
&& !DECL_EXTERNAL (SYMBOL_REF_DECL (op))))
/* We can only use direct calls if we're sure that the target
function does not need $25 to be valid on entry. */
if (mips_use_pic_fn_addr_reg_p (op))
return false;
/* If -mlong-calls or if this function has an explicit long_call
@ -206,6 +201,11 @@
return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
&& !mips_split_p[symbol_type]);
case HIGH:
op = XEXP (op, 0);
return (mips_symbolic_constant_p (op, SYMBOL_CONTEXT_LEA, &symbol_type)
&& !mips_split_hi_p[symbol_type]);
default:
return true;
}

View File

@ -22,3 +22,6 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
LIBGCC_SYNC = yes
LIBGCC_SYNC_CFLAGS = -mno-mips16
# Version these symbols if building libgcc.so.
SHLIB_MAPFILES += $(srcdir)/config/mips/libgcc-mips16.ver

View File

@ -1,3 +1,8 @@
2008-08-09 Richard Sandiford <rdsandiford@googlemail.com>
* lib/target-supports.exp (check_profiling_available): Return false
for -p and -pg on MIPS16 targets.
2008-08-09 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/inline-2.c: New testcase.

View File

@ -439,6 +439,14 @@ proc check_profiling_available { test_what } {
return 0
}
# We don't yet support profiling for MIPS16.
if { [istarget mips*-*-*]
&& ![check_effective_target_nomips16]
&& ([lindex $test_what 1] == "-p"
|| [lindex $test_what 1] == "-pg") } {
return 0
}
# MinGW does not support -p.
if { [istarget *-*-mingw*] && [lindex $test_what 1] == "-p" } {
return 0