Commit 6f5a62e9 by Richard Sandiford Committed by Richard Sandiford

mips-protos.h (mips_output_sync): Declare.

gcc/
	* config/mips/mips-protos.h (mips_output_sync): Declare.
	(mips_sync_loop_insns): Likewise.
	(mips_output_sync_loop): Replace first two parameters with an rtx.
	* config/mips/mips.c (mips_multi_member): New structure.
	(mips_multi_members): New variable.
	(mips_multi_start): New function.
	(mips_multi_add): Likewise.
	(mips_multi_add_insn): Likewise.
	(mips_multi_add_label): Likewise.
	(mips_multi_last_index): Likewise.
	(mips_multi_copy_insn): Likewise.
	(mips_multi_set_operand): Likewise.
	(mips_multi_write): Likewise.
	(mips_print_operand_punctuation): Remove '%|' and '%-'.
	(mips_init_print_operand_punct): Update accordingly.
	(mips_start_ll_sc_sync_block): New function.
	(mips_end_ll_sc_sync_block): Likewise.
	(mips_output_sync): Likewise.
	(mips_sync_insn1_template): Likewise.
	(mips_sync_insn2_template): Likewise.
	(mips_get_sync_operand): Likewise.
	(mips_process_sync_loop): Likewise.
	(mips_output_sync_loop): Use mips_process_sync_loop.
	(mips_sync_loop_insns): New function.
	* config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Delete.
	(MIPS_COMPARE_AND_SWAP_12): Likewise.
	(MIPS_COMPARE_AND_SWAP_12_ZERO_OP): Likewise.
	(MIPS_COMPARE_AND_SWAP_12_NONZERO_OP): Likewise.
	(MIPS_SYNC_OP, MIPS_SYNC_OP_12): Likewise.
	(MIPS_SYNC_OP_12_AND, MIPS_SYNC_OP_12_XOR): Likewise.
	(MIPS_SYNC_OLD_OP_12): Likewise.
	(MIPS_SYNC_OLD_OP_12_AND, MIPS_SYNC_OLD_OP_12_XOR): Likewise.
	(MIPS_SYNC_NEW_OP_12): Likewise.
	(MIPS_SYNC_NEW_OP_12_AND, MIPS_SYNC_NEW_OP_12_XOR): Likewise.
	(MIPS_SYNC_OLD_OP, MIPS_SYNC_NEW_OP): Likewise.
	(MIPS_SYNC_NAND, MIPS_SYNC_OLD_NAND, MIPS_SYNC_NEW_NAND): Likewise.
	(MIPS_SYNC_EXCHANGE, MIPS_SYNC_EXCHANGE_12): Likewise.
	(MIPS_SYNC_EXCHANGE_12_ZERO_OP): Likewise.
	(MIPS_SYNC_EXCHANGE_12_NONZER_OP): Likewise.
	* config/mips/mips.md (sync_mem): New attribute.
	(sync_oldval, sync_newval, sync_inclusive_mask): Likewise.
	(sync_exclusive_mask, sync_required_oldval): Likewise.
	(sync_insn1_op2, sync_insn1, sync_insn2): Likewise.
	(sync_release_barrier): Likewise.
	(length): Handle sync loops.
	(sync): Use mips_output_sync.
	* config/mips/sync.md (*memory_barrier): Use mips_output_sync.
	(sync_compare_and_swap<mode>): Set the new sync_* attributes
	and use mips_output_sync_loop.
	(compare_and_swap_12, sync_add<mode>, sync_<optab>_12): Likewise.
	(sync_old_<optab>_12, sync_new_<optab>_12, sync_nand_12): Likewise.
	(sync_old_nand_12, sync_new_nand_12, sync_sub<mode>): Likewise.
	(sync_old_add<mode>, sync_old_sub<mode>): Likewise.
	(sync_new_add<mode>, sync_new_sub<mode>): Likewise.
	(sync_<optab><mode>, sync_old_<optab><mode>): Likewise.
	(sync_new_<optab><mode>, sync_nand<mode>): Likewise.
	(sync_old_nand<mode>, sync_new_nand<mode>): Likewise.
	(sync_lock_test_and_set<mode>, test_and_set_12): Likewise.

From-SVN: r151128
parent 41bc3c4a
2009-08-26 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips-protos.h (mips_output_sync): Declare.
(mips_sync_loop_insns): Likewise.
(mips_output_sync_loop): Replace first two parameters with an rtx.
* config/mips/mips.c (mips_multi_member): New structure.
(mips_multi_members): New variable.
(mips_multi_start): New function.
(mips_multi_add): Likewise.
(mips_multi_add_insn): Likewise.
(mips_multi_add_label): Likewise.
(mips_multi_last_index): Likewise.
(mips_multi_copy_insn): Likewise.
(mips_multi_set_operand): Likewise.
(mips_multi_write): Likewise.
(mips_print_operand_punctuation): Remove '%|' and '%-'.
(mips_init_print_operand_punct): Update accordingly.
(mips_start_ll_sc_sync_block): New function.
(mips_end_ll_sc_sync_block): Likewise.
(mips_output_sync): Likewise.
(mips_sync_insn1_template): Likewise.
(mips_sync_insn2_template): Likewise.
(mips_get_sync_operand): Likewise.
(mips_process_sync_loop): Likewise.
(mips_output_sync_loop): Use mips_process_sync_loop.
(mips_sync_loop_insns): New function.
* config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Delete.
(MIPS_COMPARE_AND_SWAP_12): Likewise.
(MIPS_COMPARE_AND_SWAP_12_ZERO_OP): Likewise.
(MIPS_COMPARE_AND_SWAP_12_NONZERO_OP): Likewise.
(MIPS_SYNC_OP, MIPS_SYNC_OP_12): Likewise.
(MIPS_SYNC_OP_12_AND, MIPS_SYNC_OP_12_XOR): Likewise.
(MIPS_SYNC_OLD_OP_12): Likewise.
(MIPS_SYNC_OLD_OP_12_AND, MIPS_SYNC_OLD_OP_12_XOR): Likewise.
(MIPS_SYNC_NEW_OP_12): Likewise.
(MIPS_SYNC_NEW_OP_12_AND, MIPS_SYNC_NEW_OP_12_XOR): Likewise.
(MIPS_SYNC_OLD_OP, MIPS_SYNC_NEW_OP): Likewise.
(MIPS_SYNC_NAND, MIPS_SYNC_OLD_NAND, MIPS_SYNC_NEW_NAND): Likewise.
(MIPS_SYNC_EXCHANGE, MIPS_SYNC_EXCHANGE_12): Likewise.
(MIPS_SYNC_EXCHANGE_12_ZERO_OP): Likewise.
(MIPS_SYNC_EXCHANGE_12_NONZER_OP): Likewise.
* config/mips/mips.md (sync_mem): New attribute.
(sync_oldval, sync_newval, sync_inclusive_mask): Likewise.
(sync_exclusive_mask, sync_required_oldval): Likewise.
(sync_insn1_op2, sync_insn1, sync_insn2): Likewise.
(sync_release_barrier): Likewise.
(length): Handle sync loops.
(sync): Use mips_output_sync.
* config/mips/sync.md (*memory_barrier): Use mips_output_sync.
(sync_compare_and_swap<mode>): Set the new sync_* attributes
and use mips_output_sync_loop.
(compare_and_swap_12, sync_add<mode>, sync_<optab>_12): Likewise.
(sync_old_<optab>_12, sync_new_<optab>_12, sync_nand_12): Likewise.
(sync_old_nand_12, sync_new_nand_12, sync_sub<mode>): Likewise.
(sync_old_add<mode>, sync_old_sub<mode>): Likewise.
(sync_new_add<mode>, sync_new_sub<mode>): Likewise.
(sync_<optab><mode>, sync_old_<optab><mode>): Likewise.
(sync_new_<optab><mode>, sync_nand<mode>): Likewise.
(sync_old_nand<mode>, sync_new_nand<mode>): Likewise.
(sync_lock_test_and_set<mode>, test_and_set_12): Likewise.
2009-08-26 Richard Guenther <rguenther@suse.de>
PR middle-end/41163
......
......@@ -300,7 +300,9 @@ extern const char *mips_output_load_label (void);
extern const char *mips_output_conditional_branch (rtx, rtx *, const char *,
const char *);
extern const char *mips_output_order_conditional_branch (rtx, rtx *, bool);
extern const char *mips_output_sync_loop (bool, const char *, rtx *);
extern const char *mips_output_sync (void);
extern const char *mips_output_sync_loop (rtx, rtx *);
extern unsigned int mips_sync_loop_insns (rtx, rtx *);
extern const char *mips_output_division (const char *, rtx *);
extern unsigned int mips_hard_regno_nregs (int, enum machine_mode);
extern bool mips_linked_madd_p (rtx, rtx);
......
......@@ -3113,270 +3113,6 @@ while (0)
#define HAVE_AS_TLS 0
#endif
/* Return an asm string that atomically:
- Compares memory reference %1 to register %2 and, if they are
equal, changes %1 to %3.
- Sets register %0 to the old value of memory reference %1.
SUFFIX is the suffix that should be added to "ll" and "sc" instructions
and OP is the instruction that should be used to load %3 into a
register. */
#define MIPS_COMPARE_AND_SWAP(SUFFIX, OP) \
"%(%<%[%|1:\tll" SUFFIX "\t%0,%1\n" \
"\tbne\t%0,%z2,2f\n" \
"\t" OP "\t%@,%3\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)\n" \
"2:\n"
/* Return an asm string that atomically:
- Given that %2 contains a bit mask and %3 the inverted mask and
that %4 and %5 have already been ANDed with %2.
- Compares the bits in memory reference %1 selected by mask %2 to
register %4 and, if they are equal, changes the selected bits
in memory to %5.
- Sets register %0 to the old value of memory reference %1.
OPS are the instructions needed to OR %5 with %@. */
#define MIPS_COMPARE_AND_SWAP_12(OPS) \
"%(%<%[%|1:\tll\t%0,%1\n" \
"\tand\t%@,%0,%2\n" \
"\tbne\t%@,%z4,2f\n" \
"\tand\t%@,%0,%3\n" \
OPS \
"\tsc\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)\n" \
"2:\n"
#define MIPS_COMPARE_AND_SWAP_12_ZERO_OP ""
#define MIPS_COMPARE_AND_SWAP_12_NONZERO_OP "\tor\t%@,%@,%5\n"
/* Return an asm string that atomically:
- Sets memory reference %0 to %0 INSN %1.
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_OP(SUFFIX, INSN) \
"%(%<%[%|1:\tll" SUFFIX "\t%@,%0\n" \
"\t" INSN "\t%@,%@,%1\n" \
"\tsc" SUFFIX "\t%@,%0\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
/* Return an asm string that atomically:
- Given that %1 contains a bit mask and %2 the inverted mask and
that %3 has already been ANDed with %1.
- Sets the selected bits of memory reference %0 to %0 INSN %3.
- Uses scratch register %4.
AND_OP is an instruction done after INSN to mask INSN's result
with the mask. For most operations, this is an AND with the
inclusive mask (%1). For nand operations -- where the result of
INSN is already correctly masked -- it instead performs a bitwise
not. */
#define MIPS_SYNC_OP_12(INSN, AND_OP) \
"%(%<%[%|1:\tll\t%4,%0\n" \
"\tand\t%@,%4,%2\n" \
"\t" INSN "\t%4,%4,%z3\n" \
AND_OP \
"\tor\t%@,%@,%4\n" \
"\tsc\t%@,%0\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
#define MIPS_SYNC_OP_12_AND "\tand\t%4,%4,%1\n"
#define MIPS_SYNC_OP_12_XOR "\txor\t%4,%4,%1\n"
/* Return an asm string that atomically:
- Given that %2 contains a bit mask and %3 the inverted mask and
that %4 has already been ANDed with %2.
- Sets the selected bits of memory reference %1 to %1 INSN %4.
- Sets %0 to the original value of %1.
- Uses scratch register %5.
AND_OP is an instruction done after INSN to mask INSN's result
with the mask. For most operations, this is an AND with the
inclusive mask (%1). For nand operations -- where the result of
INSN is already correctly masked -- it instead performs a bitwise
not. */
#define MIPS_SYNC_OLD_OP_12(INSN, AND_OP) \
"%(%<%[%|1:\tll\t%0,%1\n" \
"\tand\t%@,%0,%3\n" \
"\t" INSN "\t%5,%0,%z4\n" \
AND_OP \
"\tor\t%@,%@,%5\n" \
"\tsc\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
#define MIPS_SYNC_OLD_OP_12_AND "\tand\t%5,%5,%2\n"
#define MIPS_SYNC_OLD_OP_12_XOR "\txor\t%5,%5,%2\n"
/* Return an asm string that atomically:
- Given that %2 contains a bit mask and %3 the inverted mask and
that %4 has already been ANDed with %2.
- Sets the selected bits of memory reference %1 to %1 INSN %4.
- Sets %0 to the new value of %1.
AND_OP is an instruction done after INSN to mask INSN's result
with the mask. For most operations, this is an AND with the
inclusive mask (%1). For nand operations -- where the result of
INSN is already correctly masked -- it instead performs a bitwise
not. */
#define MIPS_SYNC_NEW_OP_12(INSN, AND_OP) \
"%(%<%[%|1:\tll\t%0,%1\n" \
"\tand\t%@,%0,%3\n" \
"\t" INSN "\t%0,%0,%z4\n" \
AND_OP \
"\tor\t%@,%@,%0\n" \
"\tsc\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
#define MIPS_SYNC_NEW_OP_12_AND "\tand\t%0,%0,%2\n"
#define MIPS_SYNC_NEW_OP_12_XOR "\txor\t%0,%0,%2\n"
/* Return an asm string that atomically:
- Sets memory reference %1 to %1 INSN %2.
- Sets register %0 to the old value of memory reference %1.
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_OLD_OP(SUFFIX, INSN) \
"%(%<%[%|1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
/* Return an asm string that atomically:
- Sets memory reference %1 to %1 INSN %2.
- Sets register %0 to the new value of memory reference %1.
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_NEW_OP(SUFFIX, INSN) \
"%(%<%[%|1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b%~\n" \
"\t" INSN "\t%0,%0,%2%-%]%>%)"
/* Return an asm string that atomically:
- Sets memory reference %0 to ~(%0 AND %1).
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_NAND(SUFFIX, INSN) \
"%(%<%[%|1:\tll" SUFFIX "\t%@,%0\n" \
"\t" INSN "\t%@,%@,%1\n" \
"\tnor\t%@,%@,%.\n" \
"\tsc" SUFFIX "\t%@,%0\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
/* Return an asm string that atomically:
- Sets memory reference %1 to ~(%1 AND %2).
- Sets register %0 to the old value of memory reference %1.
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_OLD_NAND(SUFFIX, INSN) \
"%(%<%[%|1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
"\tnor\t%@,%@,%.\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
/* Return an asm string that atomically:
- Sets memory reference %1 to ~(%1 AND %2).
- Sets register %0 to the new value of memory reference %1.
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_NEW_NAND(SUFFIX, INSN) \
"%(%<%[%|1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%0,%0,%2\n" \
"\tnor\t%@,%0,%.\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b%~\n" \
"\tnor\t%0,%0,%.%-%]%>%)"
/* Return an asm string that atomically:
- Sets memory reference %1 to %2.
- Sets register %0 to the old value of memory reference %1.
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. OP is the and instruction that should be used to
load %2 into a register. */
#define MIPS_SYNC_EXCHANGE(SUFFIX, OP) \
"%(%<%[%|\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" OP "\t%@,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
/* Return an asm string that atomically:
- Given that %2 contains an inclusive mask, %3 and exclusive mask
and %4 has already been ANDed with the inclusive mask.
- Sets bits selected by the inclusive mask of memory reference %1
to %4.
- Sets register %0 to the old value of memory reference %1.
OPS are the instructions needed to OR %4 with %@.
Operand %2 is unused, but needed as to give the test_and_set_12
insn the five operands expected by the expander. */
#define MIPS_SYNC_EXCHANGE_12(OPS) \
"%(%<%[%|\n" \
"1:\tll\t%0,%1\n" \
"\tand\t%@,%0,%3\n" \
OPS \
"\tsc\t%@,%1\n" \
"\tbeq%?\t%@,%.,1b\n" \
"\tnop%-%]%>%)"
#define MIPS_SYNC_EXCHANGE_12_ZERO_OP ""
#define MIPS_SYNC_EXCHANGE_12_NONZERO_OP "\tor\t%@,%@,%4\n"
#ifndef USED_FOR_TARGET
/* Information about ".set noFOO; ...; .set FOO" blocks. */
struct mips_asm_switch {
......
......@@ -449,6 +449,49 @@
(const_string "yes")
(const_string "no")))
;; Attributes describing a sync loop. These loops have the form:
;;
;; if (RELEASE_BARRIER == YES) sync
;; 1: OLDVAL = *MEM
;; if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
;; $TMP1 = OLDVAL & EXCLUSIVE_MASK
;; $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
;; $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
;; $AT |= $TMP1 | $TMP3
;; if (!commit (*MEM = $AT)) goto 1.
;; if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
;; sync
;; 2:
;;
;; where "$" values are temporaries and where the other values are
;; specified by the attributes below. Values are specified as operand
;; numbers and insns are specified as enums. If no operand number is
;; specified, the following values are used instead:
;;
;; - OLDVAL: $AT
;; - NEWVAL: $AT
;; - INCLUSIVE_MASK: -1
;; - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
;; - EXCLUSIVE_MASK: 0
;;
;; MEM and INSN1_OP2 are required.
;;
;; Ideally, the operand attributes would be integers, with -1 meaning "none",
;; but the gen* programs don't yet support that.
(define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
(define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
(define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
(define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
(define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
(define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
(define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
(define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
(const_string "move"))
(define_attr "sync_insn2" "nop,and,xor,not"
(const_string "nop"))
(define_attr "sync_release_barrier" "yes,no"
(const_string "yes"))
;; Length of instruction in bytes.
(define_attr "length" ""
(cond [(and (eq_attr "extended_mips16" "yes")
......@@ -572,6 +615,9 @@
(eq_attr "type" "idiv,idiv3")
(symbol_ref "mips_idiv_insns () * 4")
(not (eq_attr "sync_mem" "none"))
(symbol_ref "mips_sync_loop_insns (insn, operands) * 4")
] (const_int 4)))
;; Attribute describing the processor. This attribute must match exactly
......@@ -4826,7 +4872,7 @@
(define_insn "sync"
[(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
"GENERATE_SYNC"
"%|sync%-")
{ return mips_output_sync (); })
(define_insn "synci"
[(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
......
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