linux.h (TARGET_SUPPORTS_SYNC_CALLS): Define to 1.
gcc/ * config/bfin/linux.h (TARGET_SUPPORTS_SYNC_CALLS): Define to 1. * config/bfin/uclinux.h (TARGET_SUPPORTS_SYNC_CALLS): Define to 1. * config/bfin/bfin.h (TARGET_SUPPORTS_SYNC_CALLS): Provide default of 0. * config/bfin/sync.md: New file. * config/bfin/bfin.md: Include it. (UNSPEC_ATOMIC): New. (UNSPEC_ONES): Provide a unique number. From Jie Zhang <jie.zhang@analog.com>: * config/bfin/bfin.c (ret_regs): New. (must_save_fp_p): Don't return true because of frame_pointer_needed. (must_save_rets_p): New. (n_regs_saved_by_prologue): Use must_save_rets_p instead of current_function_is_leaf. (do_link): Likewise. (do_unlink): Likewise. (expand_interrupt_handler_prologue): Use ret_regs array. (expand_interrupt_handler_epilogue): Use ret_regs array and pass return register to gen_return_internal. (bfin_expand_epilogue): Pass return register to gen_return_internal. (bfin_expand_call): Explicitly clobber RETS. * config/bfin/bfin.h (FUNCTION_RETURN_REGISTERS): Define. * config/bfin/bfin.md (call_symbol_fdpic, call_value_symbol_fdpic, call_insn_fdpic, call_value_insn_fdpic, call_symbol, call_value_symbol, call_insn, call_value_insn): Explicitly clobber RETS. (return_internal): Take a reg rtx rather than the register number. gcc/testsuite/ * lib/target-supports.exp (check_effective_target_sync_int_long): Supported on Blackfin Linux targets. From-SVN: r151381
This commit is contained in:
parent
be2c0fc941
commit
9840d30abf
9 changed files with 279 additions and 33 deletions
|
@ -1,3 +1,35 @@
|
|||
2009-09-03 Bernd Schmidt <bernd.schmidt@analog.com>
|
||||
|
||||
* config/bfin/linux.h (TARGET_SUPPORTS_SYNC_CALLS): Define to 1.
|
||||
* config/bfin/uclinux.h (TARGET_SUPPORTS_SYNC_CALLS): Define to 1.
|
||||
* config/bfin/bfin.h (TARGET_SUPPORTS_SYNC_CALLS): Provide default of
|
||||
0.
|
||||
* config/bfin/sync.md: New file.
|
||||
* config/bfin/bfin.md: Include it.
|
||||
(UNSPEC_ATOMIC): New.
|
||||
(UNSPEC_ONES): Provide a unique number.
|
||||
|
||||
From Jie Zhang <jie.zhang@analog.com>:
|
||||
* config/bfin/bfin.c (ret_regs): New.
|
||||
(must_save_fp_p): Don't return true because of frame_pointer_needed.
|
||||
(must_save_rets_p): New.
|
||||
(n_regs_saved_by_prologue): Use must_save_rets_p instead of
|
||||
current_function_is_leaf.
|
||||
(do_link): Likewise.
|
||||
(do_unlink): Likewise.
|
||||
(expand_interrupt_handler_prologue): Use ret_regs array.
|
||||
(expand_interrupt_handler_epilogue): Use ret_regs array and
|
||||
pass return register to gen_return_internal.
|
||||
(bfin_expand_epilogue): Pass return register to
|
||||
gen_return_internal.
|
||||
(bfin_expand_call): Explicitly clobber RETS.
|
||||
* config/bfin/bfin.h (FUNCTION_RETURN_REGISTERS): Define.
|
||||
* config/bfin/bfin.md (call_symbol_fdpic, call_value_symbol_fdpic,
|
||||
call_insn_fdpic, call_value_insn_fdpic, call_symbol,
|
||||
call_value_symbol, call_insn, call_value_insn): Explicitly clobber
|
||||
RETS.
|
||||
(return_internal): Take a reg rtx rather than the register number.
|
||||
|
||||
2009-09-03 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* tree-parloops.c (parallelize_loops): Cast to HOST_WIDE_INT
|
||||
|
|
|
@ -63,6 +63,7 @@ struct GTY(()) machine_function
|
|||
/* Set if we are notified by the doloop pass that a hardware loop
|
||||
was created. */
|
||||
int has_hardware_loops;
|
||||
|
||||
/* Set if we create a memcpy pattern that uses loop registers. */
|
||||
int has_loopreg_clobber;
|
||||
};
|
||||
|
@ -81,6 +82,7 @@ const char *dregs_pair_names[] = DREGS_PAIR_NAMES;
|
|||
const char *byte_reg_names[] = BYTE_REGISTER_NAMES;
|
||||
|
||||
static int arg_regs[] = FUNCTION_ARG_REGISTERS;
|
||||
static int ret_regs[] = FUNCTION_RETURN_REGISTERS;
|
||||
|
||||
/* Nonzero if -mshared-library-id was given. */
|
||||
static int bfin_lib_id_given;
|
||||
|
@ -532,7 +534,14 @@ n_pregs_to_save (bool is_inthandler, bool consecutive)
|
|||
static bool
|
||||
must_save_fp_p (void)
|
||||
{
|
||||
return frame_pointer_needed || df_regs_ever_live_p (REG_FP);
|
||||
return df_regs_ever_live_p (REG_FP);
|
||||
}
|
||||
|
||||
/* Determine if we are going to save the RETS register. */
|
||||
static bool
|
||||
must_save_rets_p (void)
|
||||
{
|
||||
return df_regs_ever_live_p (REG_RETS);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -844,13 +853,12 @@ n_regs_saved_by_prologue (void)
|
|||
int i;
|
||||
|
||||
if (all || stack_frame_needed_p ())
|
||||
/* We use a LINK instruction in this case. */
|
||||
n += 2;
|
||||
else
|
||||
{
|
||||
if (must_save_fp_p ())
|
||||
n++;
|
||||
if (! current_function_is_leaf)
|
||||
if (must_save_rets_p ())
|
||||
n++;
|
||||
}
|
||||
|
||||
|
@ -1092,12 +1100,13 @@ do_link (rtx spreg, HOST_WIDE_INT frame_size, bool all)
|
|||
{
|
||||
frame_size += arg_area_size ();
|
||||
|
||||
if (all || stack_frame_needed_p ()
|
||||
|| (must_save_fp_p () && ! current_function_is_leaf))
|
||||
if (all
|
||||
|| stack_frame_needed_p ()
|
||||
|| (must_save_rets_p () && must_save_fp_p ()))
|
||||
emit_link_insn (spreg, frame_size);
|
||||
else
|
||||
{
|
||||
if (! current_function_is_leaf)
|
||||
if (must_save_rets_p ())
|
||||
{
|
||||
rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
|
||||
gen_rtx_PRE_DEC (Pmode, spreg)),
|
||||
|
@ -1127,20 +1136,20 @@ do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all, int epilogue_p)
|
|||
{
|
||||
frame_size += arg_area_size ();
|
||||
|
||||
if (all || stack_frame_needed_p ())
|
||||
if (stack_frame_needed_p ())
|
||||
emit_insn (gen_unlink ());
|
||||
else
|
||||
{
|
||||
rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg));
|
||||
|
||||
add_to_reg (spreg, frame_size, 0, epilogue_p);
|
||||
if (must_save_fp_p ())
|
||||
if (all || must_save_fp_p ())
|
||||
{
|
||||
rtx fpreg = gen_rtx_REG (Pmode, REG_FP);
|
||||
emit_move_insn (fpreg, postinc);
|
||||
emit_use (fpreg);
|
||||
}
|
||||
if (! current_function_is_leaf)
|
||||
if (all || must_save_rets_p ())
|
||||
{
|
||||
emit_move_insn (bfin_rets_rtx, postinc);
|
||||
emit_use (bfin_rets_rtx);
|
||||
|
@ -1194,9 +1203,7 @@ expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind, bool all)
|
|||
|
||||
if (lookup_attribute ("nesting", attrs))
|
||||
{
|
||||
rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX
|
||||
: fkind == NMI_HANDLER ? REG_RETN
|
||||
: REG_RETI));
|
||||
rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
|
||||
insn = emit_move_insn (predec, srcreg);
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
|
@ -1238,9 +1245,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all)
|
|||
|
||||
if (lookup_attribute ("nesting", attrs))
|
||||
{
|
||||
rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX
|
||||
: fkind == NMI_HANDLER ? REG_RETN
|
||||
: REG_RETI));
|
||||
rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
|
||||
emit_move_insn (srcreg, postinc);
|
||||
}
|
||||
|
||||
|
@ -1256,7 +1261,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all)
|
|||
if (fkind == EXCPT_HANDLER)
|
||||
emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (12)));
|
||||
|
||||
emit_jump_insn (gen_return_internal (GEN_INT (fkind)));
|
||||
emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, ret_regs[fkind])));
|
||||
}
|
||||
|
||||
/* Used while emitting the prologue to generate code to load the correct value
|
||||
|
@ -1392,7 +1397,7 @@ bfin_expand_epilogue (int need_return, int eh_return, bool sibcall_p)
|
|||
if (eh_return)
|
||||
emit_insn (gen_addsi3 (spreg, spreg, gen_rtx_REG (Pmode, REG_P2)));
|
||||
|
||||
emit_jump_insn (gen_return_internal (GEN_INT (SUBROUTINE)));
|
||||
emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, REG_RETS)));
|
||||
}
|
||||
|
||||
/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
|
||||
|
@ -2193,9 +2198,10 @@ bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall)
|
|||
{
|
||||
rtx use = NULL, call;
|
||||
rtx callee = XEXP (fnaddr, 0);
|
||||
int nelts = 2 + !!sibcall;
|
||||
int nelts = 3;
|
||||
rtx pat;
|
||||
rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REGNO);
|
||||
rtx retsreg = gen_rtx_REG (Pmode, REG_RETS);
|
||||
int n;
|
||||
|
||||
/* In an untyped call, we can get NULL for operand 2. */
|
||||
|
@ -2272,6 +2278,8 @@ bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall)
|
|||
XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, cookie);
|
||||
if (sibcall)
|
||||
XVECEXP (pat, 0, n++) = gen_rtx_RETURN (VOIDmode);
|
||||
else
|
||||
XVECEXP (pat, 0, n++) = gen_rtx_CLOBBER (VOIDmode, retsreg);
|
||||
call = emit_call_insn (pat);
|
||||
if (use)
|
||||
CALL_INSN_FUNCTION_USAGE (call) = use;
|
||||
|
|
|
@ -794,6 +794,7 @@ enum reg_class
|
|||
typedef enum {
|
||||
SUBROUTINE, INTERRUPT_HANDLER, EXCPT_HANDLER, NMI_HANDLER
|
||||
} e_funkind;
|
||||
#define FUNCTION_RETURN_REGISTERS { REG_RETS, REG_RETI, REG_RETX, REG_RETN }
|
||||
|
||||
#define FUNCTION_ARG_REGISTERS { REG_R0, REG_R1, REG_R2, -1 }
|
||||
|
||||
|
@ -1258,4 +1259,8 @@ extern int splitting_for_sched, splitting_loops;
|
|||
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) ((CHAR) == '!')
|
||||
|
||||
#ifndef TARGET_SUPPORTS_SYNC_CALLS
|
||||
#define TARGET_SUPPORTS_SYNC_CALLS 0
|
||||
#endif
|
||||
|
||||
#endif /* _BFIN_CONFIG */
|
||||
|
|
|
@ -138,7 +138,8 @@
|
|||
;; Distinguish a 32-bit version of an insn from a 16-bit version.
|
||||
(UNSPEC_32BIT 11)
|
||||
(UNSPEC_NOP 12)
|
||||
(UNSPEC_ONES 12)])
|
||||
(UNSPEC_ONES 13)
|
||||
(UNSPEC_ATOMIC 14)])
|
||||
|
||||
(define_constants
|
||||
[(UNSPEC_VOLATILE_CSYNC 1)
|
||||
|
@ -2005,7 +2006,8 @@
|
|||
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
|
||||
(match_operand 1 "general_operand" "g"))
|
||||
(use (match_operand:SI 2 "register_operand" "Z"))
|
||||
(use (match_operand 3 "" ""))]
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)
|
||||
&& GET_CODE (operands[0]) == SYMBOL_REF
|
||||
&& !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
|
||||
|
@ -2031,7 +2033,8 @@
|
|||
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
|
||||
(match_operand 2 "general_operand" "g")))
|
||||
(use (match_operand:SI 3 "register_operand" "Z"))
|
||||
(use (match_operand 4 "" ""))]
|
||||
(use (match_operand 4 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)
|
||||
&& GET_CODE (operands[1]) == SYMBOL_REF
|
||||
&& !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
|
||||
|
@ -2057,7 +2060,8 @@
|
|||
[(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
|
||||
(match_operand 1 "general_operand" "g"))
|
||||
(use (match_operand:SI 2 "register_operand" "Z"))
|
||||
(use (match_operand 3 "" ""))]
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)"
|
||||
"call (%0);"
|
||||
[(set_attr "type" "call")
|
||||
|
@ -2079,7 +2083,8 @@
|
|||
(call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
|
||||
(match_operand 2 "general_operand" "g")))
|
||||
(use (match_operand:SI 3 "register_operand" "Z"))
|
||||
(use (match_operand 4 "" ""))]
|
||||
(use (match_operand 4 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)"
|
||||
"call (%1);"
|
||||
[(set_attr "type" "call")
|
||||
|
@ -2100,7 +2105,8 @@
|
|||
(define_insn "*call_symbol"
|
||||
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
|
||||
(match_operand 1 "general_operand" "g"))
|
||||
(use (match_operand 2 "" ""))]
|
||||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)
|
||||
&& (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
|
||||
&& GET_CODE (operands[0]) == SYMBOL_REF
|
||||
|
@ -2126,7 +2132,8 @@
|
|||
[(set (match_operand 0 "register_operand" "=d")
|
||||
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
|
||||
(match_operand 2 "general_operand" "g")))
|
||||
(use (match_operand 3 "" ""))]
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)
|
||||
&& (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
|
||||
&& GET_CODE (operands[1]) == SYMBOL_REF
|
||||
|
@ -2152,7 +2159,8 @@
|
|||
(define_insn "*call_insn"
|
||||
[(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
|
||||
(match_operand 1 "general_operand" "g"))
|
||||
(use (match_operand 2 "" ""))]
|
||||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)"
|
||||
"call (%0);"
|
||||
[(set_attr "type" "call")
|
||||
|
@ -2172,7 +2180,8 @@
|
|||
[(set (match_operand 0 "register_operand" "=d")
|
||||
(call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
|
||||
(match_operand 2 "general_operand" "g")))
|
||||
(use (match_operand 3 "" ""))]
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"! SIBLING_CALL_P (insn)"
|
||||
"call (%1);"
|
||||
[(set_attr "type" "call")
|
||||
|
@ -2641,18 +2650,18 @@
|
|||
|
||||
(define_insn "return_internal"
|
||||
[(return)
|
||||
(unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)]
|
||||
(use (match_operand 0 "register_operand" ""))]
|
||||
"reload_completed"
|
||||
{
|
||||
switch (INTVAL (operands[0]))
|
||||
switch (REGNO (operands[0]))
|
||||
{
|
||||
case EXCPT_HANDLER:
|
||||
case REG_RETX:
|
||||
return "rtx;";
|
||||
case NMI_HANDLER:
|
||||
case REG_RETN:
|
||||
return "rtn;";
|
||||
case INTERRUPT_HANDLER:
|
||||
case REG_RETI:
|
||||
return "rti;";
|
||||
case SUBROUTINE:
|
||||
case REG_RETS:
|
||||
return "rts;";
|
||||
}
|
||||
gcc_unreachable ();
|
||||
|
@ -4106,3 +4115,5 @@
|
|||
"DISALGNEXCPT || %0 = [%1];"
|
||||
[(set_attr "type" "mcld")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(include "sync.md")
|
||||
|
|
|
@ -49,3 +49,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
%{static}} -init __init -fini __fini"
|
||||
|
||||
#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
|
||||
|
||||
#undef TARGET_SUPPORTS_SYNC_CALLS
|
||||
#define TARGET_SUPPORTS_SYNC_CALLS 1
|
||||
|
|
178
gcc/config/bfin/sync.md
Normal file
178
gcc/config/bfin/sync.md
Normal file
|
@ -0,0 +1,178 @@
|
|||
;; GCC machine description for Blackfin synchronization instructions.
|
||||
;; Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
;; Contributed by Analog Devices.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 3, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING3. If not see
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define_code_iterator FETCHOP [plus minus ior and xor])
|
||||
(define_code_attr fetchop_name
|
||||
[(plus "add") (minus "sub") (ior "ior") (and "and") (xor "xor")])
|
||||
(define_code_attr fetchop_addr
|
||||
[(plus "1072") (minus "1088") (ior "1104") (and "1120") (xor "1136")])
|
||||
|
||||
(define_insn "sync_<fetchop_name>si_internal"
|
||||
[(set (mem:SI (match_operand:SI 0 "register_operand" "qA"))
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (mem:SI (match_dup 0))
|
||||
(match_operand:SI 1 "register_operand" "q0"))
|
||||
(match_operand:SI 2 "register_no_elim_operand" "a")]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:SI 3 "=q0"))
|
||||
(clobber (match_scratch:SI 4 "=q1"))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
"call (%2);"
|
||||
[(set_attr "type" "call")])
|
||||
|
||||
(define_expand "sync_<fetchop_name>si"
|
||||
[(parallel
|
||||
[(set (match_operand:SI 0 "memory_operand" "+m")
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (match_dup 0)
|
||||
(match_operand:SI 1 "register_operand" "q0"))
|
||||
(match_dup 2)]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:SI 3 ""))
|
||||
(clobber (match_scratch:SI 4 ""))
|
||||
(clobber (reg:SI REG_RETS))])]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
{
|
||||
if (!REG_P (XEXP (operands[0], 0)))
|
||||
{
|
||||
operands[0] = shallow_copy_rtx (operands[0]);
|
||||
XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
|
||||
}
|
||||
operands[2] = force_reg (Pmode, GEN_INT (<fetchop_addr>));
|
||||
})
|
||||
|
||||
(define_insn "sync_old_<fetchop_name>si_internal"
|
||||
[(set (match_operand:SI 0 "register_operand" "=q1")
|
||||
(mem:SI (match_operand:SI 1 "register_operand" "qA")))
|
||||
(set (mem:SI (match_dup 1))
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (mem:SI (match_dup 1))
|
||||
(match_operand:SI 2 "register_operand" "q0"))
|
||||
(match_operand:SI 3 "register_no_elim_operand" "a")]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:SI 4 "=q0"))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
"call (%3);"
|
||||
[(set_attr "type" "call")])
|
||||
|
||||
(define_expand "sync_old_<fetchop_name>si"
|
||||
[(parallel
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(match_operand:SI 1 "memory_operand" ""))
|
||||
(set (match_dup 1)
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (match_dup 1)
|
||||
(match_operand:SI 2 "register_operand" ""))
|
||||
(match_dup 3)]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:SI 4 ""))
|
||||
(clobber (reg:SI REG_RETS))])]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
{
|
||||
if (!REG_P (XEXP (operands[1], 0)))
|
||||
{
|
||||
operands[1] = shallow_copy_rtx (operands[1]);
|
||||
XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
|
||||
}
|
||||
operands[3] = force_reg (Pmode, GEN_INT (<fetchop_addr>));
|
||||
})
|
||||
|
||||
(define_insn "sync_new_<fetchop_name>si_internal"
|
||||
[(set (match_operand:SI 0 "register_operand" "=q0")
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI
|
||||
(mem:SI (match_operand:SI 1 "register_operand" "qA"))
|
||||
(match_operand:SI 2 "register_operand" "q0"))
|
||||
(match_operand:SI 3 "register_no_elim_operand" "a")]
|
||||
UNSPEC_ATOMIC))
|
||||
(set (mem:SI (match_dup 1))
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (mem:SI (match_dup 1)) (match_dup 2))
|
||||
(match_dup 3)]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:SI 4 "=q1"))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
"call (%3);"
|
||||
[(set_attr "type" "call")])
|
||||
|
||||
(define_expand "sync_new_<fetchop_name>si"
|
||||
[(parallel
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (match_operand:SI 1 "memory_operand" "")
|
||||
(match_operand:SI 2 "register_operand" ""))
|
||||
(match_dup 3)]
|
||||
UNSPEC_ATOMIC))
|
||||
(set (match_dup 1)
|
||||
(unspec:SI
|
||||
[(FETCHOP:SI (match_dup 1) (match_dup 2))
|
||||
(match_dup 3)]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (match_scratch:SI 4 ""))
|
||||
(clobber (reg:SI REG_RETS))])]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
{
|
||||
if (!REG_P (XEXP (operands[1], 0)))
|
||||
{
|
||||
operands[1] = shallow_copy_rtx (operands[1]);
|
||||
XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
|
||||
}
|
||||
operands[3] = force_reg (Pmode, GEN_INT (<fetchop_addr>));
|
||||
})
|
||||
|
||||
(define_insn "sync_compare_and_swapsi_internal"
|
||||
[(set (match_operand:SI 0 "register_operand" "=q0")
|
||||
(mem:SI (match_operand:SI 1 "register_operand" "qA")))
|
||||
(set (mem:SI (match_dup 1))
|
||||
(unspec:SI
|
||||
[(mem:SI (match_dup 1))
|
||||
(match_operand:SI 2 "register_operand" "q1")
|
||||
(match_operand:SI 3 "register_operand" "q2")
|
||||
(match_operand:SI 4 "register_no_elim_operand" "a")]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (reg:SI REG_RETS))]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
"call (%4);"
|
||||
[(set_attr "type" "call")])
|
||||
|
||||
(define_expand "sync_compare_and_swapsi"
|
||||
[(parallel
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(match_operand:SI 1 "memory_operand" ""))
|
||||
(set (match_dup 1)
|
||||
(unspec:SI
|
||||
[(match_dup 1)
|
||||
(match_operand:SI 2 "register_operand" "")
|
||||
(match_operand:SI 3 "register_operand" "")
|
||||
(match_dup 4)]
|
||||
UNSPEC_ATOMIC))
|
||||
(clobber (reg:SI REG_RETS))])]
|
||||
"TARGET_SUPPORTS_SYNC_CALLS"
|
||||
{
|
||||
if (!REG_P (XEXP (operands[1], 0)))
|
||||
{
|
||||
operands[1] = shallow_copy_rtx (operands[1]);
|
||||
XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
|
||||
}
|
||||
operands[4] = force_reg (Pmode, GEN_INT (0x420));
|
||||
})
|
|
@ -36,3 +36,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
--wrap=mmap --wrap=munmap --wrap=alloca\
|
||||
%{fmudflapth: --wrap=pthread_create\
|
||||
}} %{fmudflap|fmudflapth: --wrap=main}"
|
||||
|
||||
#undef TARGET_SUPPORTS_SYNC_CALLS
|
||||
#define TARGET_SUPPORTS_SYNC_CALLS 1
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-09-03 Bernd Schmidt <bernd.schmidt@analog.com>
|
||||
|
||||
* lib/target-supports.exp (check_effective_target_sync_int_long):
|
||||
Supported on Blackfin Linux targets.
|
||||
|
||||
2009-09-02 David Daney <ddaney@caviumnetworks.com>
|
||||
|
||||
* gcc.c-torture/compile/builtin_unreachable-1.c: New testcase.
|
||||
|
|
|
@ -2670,6 +2670,7 @@ proc check_effective_target_sync_int_long { } {
|
|||
|| [istarget i?86-*-*]
|
||||
|| [istarget x86_64-*-*]
|
||||
|| [istarget alpha*-*-*]
|
||||
|| [istarget bfin*-*linux*]
|
||||
|| [istarget s390*-*-*]
|
||||
|| [istarget powerpc*-*-*]
|
||||
|| [istarget sparc64-*-*]
|
||||
|
|
Loading…
Add table
Reference in a new issue