Commit 9840d30a by Bernd Schmidt Committed by Bernd Schmidt

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
parent be2c0fc9
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> 2009-09-03 H.J. Lu <hongjiu.lu@intel.com>
* tree-parloops.c (parallelize_loops): Cast to HOST_WIDE_INT * tree-parloops.c (parallelize_loops): Cast to HOST_WIDE_INT
......
...@@ -63,6 +63,7 @@ struct GTY(()) machine_function ...@@ -63,6 +63,7 @@ struct GTY(()) machine_function
/* Set if we are notified by the doloop pass that a hardware loop /* Set if we are notified by the doloop pass that a hardware loop
was created. */ was created. */
int has_hardware_loops; int has_hardware_loops;
/* Set if we create a memcpy pattern that uses loop registers. */ /* Set if we create a memcpy pattern that uses loop registers. */
int has_loopreg_clobber; int has_loopreg_clobber;
}; };
...@@ -81,6 +82,7 @@ const char *dregs_pair_names[] = DREGS_PAIR_NAMES; ...@@ -81,6 +82,7 @@ const char *dregs_pair_names[] = DREGS_PAIR_NAMES;
const char *byte_reg_names[] = BYTE_REGISTER_NAMES; const char *byte_reg_names[] = BYTE_REGISTER_NAMES;
static int arg_regs[] = FUNCTION_ARG_REGISTERS; static int arg_regs[] = FUNCTION_ARG_REGISTERS;
static int ret_regs[] = FUNCTION_RETURN_REGISTERS;
/* Nonzero if -mshared-library-id was given. */ /* Nonzero if -mshared-library-id was given. */
static int bfin_lib_id_given; static int bfin_lib_id_given;
...@@ -532,7 +534,14 @@ n_pregs_to_save (bool is_inthandler, bool consecutive) ...@@ -532,7 +534,14 @@ n_pregs_to_save (bool is_inthandler, bool consecutive)
static bool static bool
must_save_fp_p (void) 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 static bool
...@@ -844,13 +853,12 @@ n_regs_saved_by_prologue (void) ...@@ -844,13 +853,12 @@ n_regs_saved_by_prologue (void)
int i; int i;
if (all || stack_frame_needed_p ()) if (all || stack_frame_needed_p ())
/* We use a LINK instruction in this case. */
n += 2; n += 2;
else else
{ {
if (must_save_fp_p ()) if (must_save_fp_p ())
n++; n++;
if (! current_function_is_leaf) if (must_save_rets_p ())
n++; n++;
} }
...@@ -1092,12 +1100,13 @@ do_link (rtx spreg, HOST_WIDE_INT frame_size, bool all) ...@@ -1092,12 +1100,13 @@ do_link (rtx spreg, HOST_WIDE_INT frame_size, bool all)
{ {
frame_size += arg_area_size (); frame_size += arg_area_size ();
if (all || stack_frame_needed_p () if (all
|| (must_save_fp_p () && ! current_function_is_leaf)) || stack_frame_needed_p ()
|| (must_save_rets_p () && must_save_fp_p ()))
emit_link_insn (spreg, frame_size); emit_link_insn (spreg, frame_size);
else else
{ {
if (! current_function_is_leaf) if (must_save_rets_p ())
{ {
rtx pat = gen_movsi (gen_rtx_MEM (Pmode, rtx pat = gen_movsi (gen_rtx_MEM (Pmode,
gen_rtx_PRE_DEC (Pmode, spreg)), gen_rtx_PRE_DEC (Pmode, spreg)),
...@@ -1127,20 +1136,20 @@ do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all, int epilogue_p) ...@@ -1127,20 +1136,20 @@ do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all, int epilogue_p)
{ {
frame_size += arg_area_size (); frame_size += arg_area_size ();
if (all || stack_frame_needed_p ()) if (stack_frame_needed_p ())
emit_insn (gen_unlink ()); emit_insn (gen_unlink ());
else else
{ {
rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg)); rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg));
add_to_reg (spreg, frame_size, 0, epilogue_p); 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); rtx fpreg = gen_rtx_REG (Pmode, REG_FP);
emit_move_insn (fpreg, postinc); emit_move_insn (fpreg, postinc);
emit_use (fpreg); emit_use (fpreg);
} }
if (! current_function_is_leaf) if (all || must_save_rets_p ())
{ {
emit_move_insn (bfin_rets_rtx, postinc); emit_move_insn (bfin_rets_rtx, postinc);
emit_use (bfin_rets_rtx); emit_use (bfin_rets_rtx);
...@@ -1194,9 +1203,7 @@ expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind, bool all) ...@@ -1194,9 +1203,7 @@ expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind, bool all)
if (lookup_attribute ("nesting", attrs)) if (lookup_attribute ("nesting", attrs))
{ {
rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
: fkind == NMI_HANDLER ? REG_RETN
: REG_RETI));
insn = emit_move_insn (predec, srcreg); insn = emit_move_insn (predec, srcreg);
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
...@@ -1238,9 +1245,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all) ...@@ -1238,9 +1245,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all)
if (lookup_attribute ("nesting", attrs)) if (lookup_attribute ("nesting", attrs))
{ {
rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX rtx srcreg = gen_rtx_REG (Pmode, ret_regs[fkind]);
: fkind == NMI_HANDLER ? REG_RETN
: REG_RETI));
emit_move_insn (srcreg, postinc); emit_move_insn (srcreg, postinc);
} }
...@@ -1256,7 +1261,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all) ...@@ -1256,7 +1261,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all)
if (fkind == EXCPT_HANDLER) if (fkind == EXCPT_HANDLER)
emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (12))); 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 /* 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) ...@@ -1392,7 +1397,7 @@ bfin_expand_epilogue (int need_return, int eh_return, bool sibcall_p)
if (eh_return) if (eh_return)
emit_insn (gen_addsi3 (spreg, spreg, gen_rtx_REG (Pmode, REG_P2))); 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. */ /* 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) ...@@ -2193,9 +2198,10 @@ bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall)
{ {
rtx use = NULL, call; rtx use = NULL, call;
rtx callee = XEXP (fnaddr, 0); rtx callee = XEXP (fnaddr, 0);
int nelts = 2 + !!sibcall; int nelts = 3;
rtx pat; rtx pat;
rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REGNO); rtx picreg = get_hard_reg_initial_val (SImode, FDPIC_REGNO);
rtx retsreg = gen_rtx_REG (Pmode, REG_RETS);
int n; int n;
/* In an untyped call, we can get NULL for operand 2. */ /* 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) ...@@ -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); XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, cookie);
if (sibcall) if (sibcall)
XVECEXP (pat, 0, n++) = gen_rtx_RETURN (VOIDmode); XVECEXP (pat, 0, n++) = gen_rtx_RETURN (VOIDmode);
else
XVECEXP (pat, 0, n++) = gen_rtx_CLOBBER (VOIDmode, retsreg);
call = emit_call_insn (pat); call = emit_call_insn (pat);
if (use) if (use)
CALL_INSN_FUNCTION_USAGE (call) = use; CALL_INSN_FUNCTION_USAGE (call) = use;
......
...@@ -794,6 +794,7 @@ enum reg_class ...@@ -794,6 +794,7 @@ enum reg_class
typedef enum { typedef enum {
SUBROUTINE, INTERRUPT_HANDLER, EXCPT_HANDLER, NMI_HANDLER SUBROUTINE, INTERRUPT_HANDLER, EXCPT_HANDLER, NMI_HANDLER
} e_funkind; } 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 } #define FUNCTION_ARG_REGISTERS { REG_R0, REG_R1, REG_R2, -1 }
...@@ -1258,4 +1259,8 @@ extern int splitting_for_sched, splitting_loops; ...@@ -1258,4 +1259,8 @@ extern int splitting_for_sched, splitting_loops;
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) ((CHAR) == '!') #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) ((CHAR) == '!')
#ifndef TARGET_SUPPORTS_SYNC_CALLS
#define TARGET_SUPPORTS_SYNC_CALLS 0
#endif
#endif /* _BFIN_CONFIG */ #endif /* _BFIN_CONFIG */
...@@ -138,7 +138,8 @@ ...@@ -138,7 +138,8 @@
;; Distinguish a 32-bit version of an insn from a 16-bit version. ;; Distinguish a 32-bit version of an insn from a 16-bit version.
(UNSPEC_32BIT 11) (UNSPEC_32BIT 11)
(UNSPEC_NOP 12) (UNSPEC_NOP 12)
(UNSPEC_ONES 12)]) (UNSPEC_ONES 13)
(UNSPEC_ATOMIC 14)])
(define_constants (define_constants
[(UNSPEC_VOLATILE_CSYNC 1) [(UNSPEC_VOLATILE_CSYNC 1)
...@@ -2005,7 +2006,8 @@ ...@@ -2005,7 +2006,8 @@
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q")) [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
(match_operand 1 "general_operand" "g")) (match_operand 1 "general_operand" "g"))
(use (match_operand:SI 2 "register_operand" "Z")) (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) "! SIBLING_CALL_P (insn)
&& GET_CODE (operands[0]) == SYMBOL_REF && GET_CODE (operands[0]) == SYMBOL_REF
&& !bfin_longcall_p (operands[0], INTVAL (operands[3]))" && !bfin_longcall_p (operands[0], INTVAL (operands[3]))"
...@@ -2031,7 +2033,8 @@ ...@@ -2031,7 +2033,8 @@
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q")) (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
(match_operand 2 "general_operand" "g"))) (match_operand 2 "general_operand" "g")))
(use (match_operand:SI 3 "register_operand" "Z")) (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) "! SIBLING_CALL_P (insn)
&& GET_CODE (operands[1]) == SYMBOL_REF && GET_CODE (operands[1]) == SYMBOL_REF
&& !bfin_longcall_p (operands[1], INTVAL (operands[4]))" && !bfin_longcall_p (operands[1], INTVAL (operands[4]))"
...@@ -2057,7 +2060,8 @@ ...@@ -2057,7 +2060,8 @@
[(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y")) [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "Y"))
(match_operand 1 "general_operand" "g")) (match_operand 1 "general_operand" "g"))
(use (match_operand:SI 2 "register_operand" "Z")) (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)" "! SIBLING_CALL_P (insn)"
"call (%0);" "call (%0);"
[(set_attr "type" "call") [(set_attr "type" "call")
...@@ -2079,7 +2083,8 @@ ...@@ -2079,7 +2083,8 @@
(call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y")) (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "Y"))
(match_operand 2 "general_operand" "g"))) (match_operand 2 "general_operand" "g")))
(use (match_operand:SI 3 "register_operand" "Z")) (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)" "! SIBLING_CALL_P (insn)"
"call (%1);" "call (%1);"
[(set_attr "type" "call") [(set_attr "type" "call")
...@@ -2100,7 +2105,8 @@ ...@@ -2100,7 +2105,8 @@
(define_insn "*call_symbol" (define_insn "*call_symbol"
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q")) [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q"))
(match_operand 1 "general_operand" "g")) (match_operand 1 "general_operand" "g"))
(use (match_operand 2 "" ""))] (use (match_operand 2 "" ""))
(clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn) "! SIBLING_CALL_P (insn)
&& (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY) && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
&& GET_CODE (operands[0]) == SYMBOL_REF && GET_CODE (operands[0]) == SYMBOL_REF
...@@ -2126,7 +2132,8 @@ ...@@ -2126,7 +2132,8 @@
[(set (match_operand 0 "register_operand" "=d") [(set (match_operand 0 "register_operand" "=d")
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q")) (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q"))
(match_operand 2 "general_operand" "g"))) (match_operand 2 "general_operand" "g")))
(use (match_operand 3 "" ""))] (use (match_operand 3 "" ""))
(clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn) "! SIBLING_CALL_P (insn)
&& (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY) && (!TARGET_ID_SHARED_LIBRARY || TARGET_LEAF_ID_SHARED_LIBRARY)
&& GET_CODE (operands[1]) == SYMBOL_REF && GET_CODE (operands[1]) == SYMBOL_REF
...@@ -2152,7 +2159,8 @@ ...@@ -2152,7 +2159,8 @@
(define_insn "*call_insn" (define_insn "*call_insn"
[(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a")) [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a"))
(match_operand 1 "general_operand" "g")) (match_operand 1 "general_operand" "g"))
(use (match_operand 2 "" ""))] (use (match_operand 2 "" ""))
(clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)" "! SIBLING_CALL_P (insn)"
"call (%0);" "call (%0);"
[(set_attr "type" "call") [(set_attr "type" "call")
...@@ -2172,7 +2180,8 @@ ...@@ -2172,7 +2180,8 @@
[(set (match_operand 0 "register_operand" "=d") [(set (match_operand 0 "register_operand" "=d")
(call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a")) (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a"))
(match_operand 2 "general_operand" "g"))) (match_operand 2 "general_operand" "g")))
(use (match_operand 3 "" ""))] (use (match_operand 3 "" ""))
(clobber (reg:SI REG_RETS))]
"! SIBLING_CALL_P (insn)" "! SIBLING_CALL_P (insn)"
"call (%1);" "call (%1);"
[(set_attr "type" "call") [(set_attr "type" "call")
...@@ -2641,18 +2650,18 @@ ...@@ -2641,18 +2650,18 @@
(define_insn "return_internal" (define_insn "return_internal"
[(return) [(return)
(unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)] (use (match_operand 0 "register_operand" ""))]
"reload_completed" "reload_completed"
{ {
switch (INTVAL (operands[0])) switch (REGNO (operands[0]))
{ {
case EXCPT_HANDLER: case REG_RETX:
return "rtx;"; return "rtx;";
case NMI_HANDLER: case REG_RETN:
return "rtn;"; return "rtn;";
case INTERRUPT_HANDLER: case REG_RETI:
return "rti;"; return "rti;";
case SUBROUTINE: case REG_RETS:
return "rts;"; return "rts;";
} }
gcc_unreachable (); gcc_unreachable ();
...@@ -4106,3 +4115,5 @@ ...@@ -4106,3 +4115,5 @@
"DISALGNEXCPT || %0 = [%1];" "DISALGNEXCPT || %0 = [%1];"
[(set_attr "type" "mcld") [(set_attr "type" "mcld")
(set_attr "length" "8")]) (set_attr "length" "8")])
(include "sync.md")
...@@ -49,3 +49,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -49,3 +49,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
%{static}} -init __init -fini __fini" %{static}} -init __init -fini __fini"
#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h" #define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
#undef TARGET_SUPPORTS_SYNC_CALLS
#define TARGET_SUPPORTS_SYNC_CALLS 1
;; 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 ...@@ -36,3 +36,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
--wrap=mmap --wrap=munmap --wrap=alloca\ --wrap=mmap --wrap=munmap --wrap=alloca\
%{fmudflapth: --wrap=pthread_create\ %{fmudflapth: --wrap=pthread_create\
}} %{fmudflap|fmudflapth: --wrap=main}" }} %{fmudflap|fmudflapth: --wrap=main}"
#undef TARGET_SUPPORTS_SYNC_CALLS
#define TARGET_SUPPORTS_SYNC_CALLS 1
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> 2009-09-02 David Daney <ddaney@caviumnetworks.com>
* gcc.c-torture/compile/builtin_unreachable-1.c: New testcase. * gcc.c-torture/compile/builtin_unreachable-1.c: New testcase.
......
...@@ -2670,6 +2670,7 @@ proc check_effective_target_sync_int_long { } { ...@@ -2670,6 +2670,7 @@ proc check_effective_target_sync_int_long { } {
|| [istarget i?86-*-*] || [istarget i?86-*-*]
|| [istarget x86_64-*-*] || [istarget x86_64-*-*]
|| [istarget alpha*-*-*] || [istarget alpha*-*-*]
|| [istarget bfin*-*linux*]
|| [istarget s390*-*-*] || [istarget s390*-*-*]
|| [istarget powerpc*-*-*] || [istarget powerpc*-*-*]
|| [istarget sparc64-*-*] || [istarget sparc64-*-*]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment