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:
parent
7462a71535
commit
08d0963a0e
20 changed files with 1058 additions and 279 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
2
config/mt-mips-gnu
Normal file
|
@ -0,0 +1,2 @@
|
|||
include $(srcdir)/config/mt-gnu
|
||||
include $(srcdir)/config/mt-mips16-compat
|
5
config/mt-mips16-compat
Normal file
5
config/mt-mips16-compat
Normal 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
3
configure
vendored
|
@ -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"
|
||||
;;
|
||||
|
|
|
@ -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"
|
||||
;;
|
||||
|
|
137
gcc/ChangeLog
137
gcc/ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}.")
|
||||
|
|
68
gcc/config/mips/libgcc-mips16.ver
Normal file
68
gcc/config/mips/libgcc-mips16.ver
Normal 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
|
||||
}
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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")])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue