mips.md (UNSPEC_SYNC_NEW_OP_12, [...]): New define_constants.
2008-05-20 David Daney <ddaney@avtrex.com> * config/mips/mips.md (UNSPEC_SYNC_NEW_OP_12, UNSPEC_SYNC_OLD_OP_12, UNSPEC_SYNC_EXCHANGE_12): New define_constants. (UNSPEC_SYNC_EXCHANGE, UNSPEC_MEMORY_BARRIER, UNSPEC_SET_GOT_VERSION, UNSPEC_UPDATE_GOT_VERSION): Renumber. (optab, insn): Add 'plus' and 'minus' to define_code_attr. (atomic_hiqi_op): New define_code_iterator. (sync_compare_and_swap<mode>): Call mips_expand_atomic_qihi instead of mips_expand_compare_and_swap_12. (compare_and_swap_12): Use MIPS_COMPARE_AND_SWAP_12 instead of MIPS_COMPARE_AND_SWAP_12_0. Pass argument to MIPS_COMPARE_AND_SWAP_12. (sync_<optab><mode>, sync_old_<optab><mode>, sync_new_<optab><mode>, sync_nand<mode>, sync_old_nand<mode>, sync_new_nand<mode>): New define_expands for HI and QI mode operands. (sync_<optab>_12, sync_old_<optab>_12, sync_new_<optab>_12, sync_nand_12, sync_old_nand_12, sync_new_nand_12): New insns. (sync_lock_test_and_set<mode>): New define_expand for HI and QI modes. (test_and_set_12): New insn. (sync_old_add<mode>, sync_new_add<mode>, sync_old_<optab><mode>, sync_new_<optab><mode>, sync_old_nand<mode>, sync_new_nand<mode>, sync_lock_test_and_set<mode>): Add early clobber to operand 0 for SI and DI mode insns. * config/mips/mips-protos.h (mips_gen_fn_6, mips_gen_fn_5, mips_gen_fn_4): New typedefs. (mips_gen_fn_ptrs): Define new union type. (mips_expand_compare_and_swap_12): Remove declaration. (mips_expand_atomic_qihi): Declare function. * config/mips/mips.c (mips_expand_compare_and_swap_12): Rename to... (mips_expand_atomic_qihi): ... this. Use new generator function parameter. * config/mips/mips.h (MIPS_COMPARE_AND_SWAP_12): Add OPS parameter. (MIPS_COMPARE_AND_SWAP_12_0): Delete macro. (MIPS_COMPARE_AND_SWAP_12_ZERO_OP, MIPS_COMPARE_AND_SWAP_12_NONZERO_OP, MIPS_SYNC_OP_12, MIPS_SYNC_OP_12_NOT_NOP, MIPS_SYNC_OP_12_NOT_NOT, MIPS_SYNC_OLD_OP_12, MIPS_SYNC_OLD_OP_12_NOT_NOP, MIPS_SYNC_OLD_OP_12_NOT_NOP_REG, MIPS_SYNC_OLD_OP_12_NOT_NOT, MIPS_SYNC_OLD_OP_12_NOT_NOT_REG, MIPS_SYNC_NEW_OP_12, MIPS_SYNC_NEW_OP_12_NOT_NOP, MIPS_SYNC_NEW_OP_12_NOT_NOT, MIPS_SYNC_EXCHANGE_12, MIPS_SYNC_EXCHANGE_12_ZERO_OP, MIPS_SYNC_EXCHANGE_12_NONZERO_OP): New macros. From-SVN: r135684
This commit is contained in:
parent
a35f6a358e
commit
06d1961718
5 changed files with 499 additions and 52 deletions
|
@ -1,3 +1,53 @@
|
|||
2008-05-20 David Daney <ddaney@avtrex.com>
|
||||
|
||||
* config/mips/mips.md (UNSPEC_SYNC_NEW_OP_12,
|
||||
UNSPEC_SYNC_OLD_OP_12,
|
||||
UNSPEC_SYNC_EXCHANGE_12): New define_constants.
|
||||
(UNSPEC_SYNC_EXCHANGE, UNSPEC_MEMORY_BARRIER,
|
||||
UNSPEC_SET_GOT_VERSION,
|
||||
UNSPEC_UPDATE_GOT_VERSION): Renumber.
|
||||
(optab, insn): Add 'plus' and 'minus' to define_code_attr.
|
||||
(atomic_hiqi_op): New define_code_iterator.
|
||||
(sync_compare_and_swap<mode>): Call
|
||||
mips_expand_atomic_qihi instead of
|
||||
mips_expand_compare_and_swap_12.
|
||||
(compare_and_swap_12): Use MIPS_COMPARE_AND_SWAP_12 instead of
|
||||
MIPS_COMPARE_AND_SWAP_12_0. Pass argument to
|
||||
MIPS_COMPARE_AND_SWAP_12.
|
||||
(sync_<optab><mode>, sync_old_<optab><mode>,
|
||||
sync_new_<optab><mode>, sync_nand<mode>, sync_old_nand<mode>,
|
||||
sync_new_nand<mode>): New define_expands for HI and QI mode
|
||||
operands.
|
||||
(sync_<optab>_12, sync_old_<optab>_12, sync_new_<optab>_12,
|
||||
sync_nand_12, sync_old_nand_12, sync_new_nand_12): New insns.
|
||||
(sync_lock_test_and_set<mode>): New define_expand for HI and QI
|
||||
modes.
|
||||
(test_and_set_12): New insn.
|
||||
(sync_old_add<mode>, sync_new_add<mode>, sync_old_<optab><mode>,
|
||||
sync_new_<optab><mode>, sync_old_nand<mode>,
|
||||
sync_new_nand<mode>, sync_lock_test_and_set<mode>): Add early
|
||||
clobber to operand 0 for SI and DI mode insns.
|
||||
* config/mips/mips-protos.h (mips_gen_fn_6, mips_gen_fn_5,
|
||||
mips_gen_fn_4): New typedefs.
|
||||
(mips_gen_fn_ptrs): Define new union type.
|
||||
(mips_expand_compare_and_swap_12): Remove declaration.
|
||||
(mips_expand_atomic_qihi): Declare function.
|
||||
* config/mips/mips.c (mips_expand_compare_and_swap_12): Rename to...
|
||||
(mips_expand_atomic_qihi): ... this. Use new generator function
|
||||
parameter.
|
||||
* config/mips/mips.h (MIPS_COMPARE_AND_SWAP_12): Add OPS parameter.
|
||||
(MIPS_COMPARE_AND_SWAP_12_0): Delete macro.
|
||||
(MIPS_COMPARE_AND_SWAP_12_ZERO_OP,
|
||||
MIPS_COMPARE_AND_SWAP_12_NONZERO_OP,
|
||||
MIPS_SYNC_OP_12, MIPS_SYNC_OP_12_NOT_NOP,
|
||||
MIPS_SYNC_OP_12_NOT_NOT, MIPS_SYNC_OLD_OP_12,
|
||||
MIPS_SYNC_OLD_OP_12_NOT_NOP, MIPS_SYNC_OLD_OP_12_NOT_NOP_REG,
|
||||
MIPS_SYNC_OLD_OP_12_NOT_NOT, MIPS_SYNC_OLD_OP_12_NOT_NOT_REG,
|
||||
MIPS_SYNC_NEW_OP_12, MIPS_SYNC_NEW_OP_12_NOT_NOP,
|
||||
MIPS_SYNC_NEW_OP_12_NOT_NOT, MIPS_SYNC_EXCHANGE_12,
|
||||
MIPS_SYNC_EXCHANGE_12_ZERO_OP,
|
||||
MIPS_SYNC_EXCHANGE_12_NONZERO_OP): New macros.
|
||||
|
||||
2008-05-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* config/i386/i386.c (ix86_expand_vector_init_one_nonzero): Add
|
||||
|
|
|
@ -292,6 +292,14 @@ extern bool mips_use_ins_ext_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
|
|||
extern const char *mips16e_output_save_restore (rtx, HOST_WIDE_INT);
|
||||
extern bool mips16e_save_restore_pattern_p (rtx, HOST_WIDE_INT,
|
||||
struct mips16e_save_restore_info *);
|
||||
extern void mips_expand_compare_and_swap_12 (rtx, rtx, rtx, rtx);
|
||||
union mips_gen_fn_ptrs
|
||||
{
|
||||
rtx (*fn_6) (rtx, rtx, rtx, rtx, rtx, rtx);
|
||||
rtx (*fn_5) (rtx, rtx, rtx, rtx, rtx);
|
||||
rtx (*fn_4) (rtx, rtx, rtx, rtx);
|
||||
};
|
||||
|
||||
extern void mips_expand_atomic_qihi (union mips_gen_fn_ptrs,
|
||||
rtx, rtx, rtx, rtx);
|
||||
|
||||
#endif /* ! GCC_MIPS_PROTOS_H */
|
||||
|
|
|
@ -5873,14 +5873,29 @@ mips_expand_synci_loop (rtx begin, rtx end)
|
|||
emit_jump_insn (gen_condjump (cmp_result, label));
|
||||
}
|
||||
|
||||
/* Expand a QI or HI mode compare_and_swap. The operands are the same
|
||||
as for the generator function. */
|
||||
/* Expand a QI or HI mode atomic memory operation.
|
||||
|
||||
GENERATOR contains a pointer to the gen_* function that generates
|
||||
the SI mode underlying atomic operation using masks that we
|
||||
calculate.
|
||||
|
||||
RESULT is the return register for the operation. Its value is NULL
|
||||
if unused.
|
||||
|
||||
MEM is the location of the atomic access.
|
||||
|
||||
OLDVAL is the first operand for the operation.
|
||||
|
||||
NEWVAL is the optional second operand for the operation. Its value
|
||||
is NULL if unused. */
|
||||
|
||||
void
|
||||
mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
|
||||
mips_expand_atomic_qihi (union mips_gen_fn_ptrs generator,
|
||||
rtx result, rtx mem, rtx oldval, rtx newval)
|
||||
{
|
||||
rtx orig_addr, memsi_addr, memsi, shift, shiftsi, unshifted_mask;
|
||||
rtx unshifted_mask_reg, mask, inverted_mask, res;
|
||||
rtx unshifted_mask_reg, mask, inverted_mask, si_op;
|
||||
rtx res = NULL;
|
||||
enum machine_mode mode;
|
||||
|
||||
mode = GET_MODE (mem);
|
||||
|
@ -5927,7 +5942,7 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
|
|||
}
|
||||
|
||||
/* Do the same for the new value. */
|
||||
if (newval != const0_rtx)
|
||||
if (newval && newval != const0_rtx)
|
||||
{
|
||||
newval = convert_modes (SImode, mode, newval, true);
|
||||
newval = force_reg (SImode, newval);
|
||||
|
@ -5935,14 +5950,24 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
|
|||
}
|
||||
|
||||
/* Do the SImode atomic access. */
|
||||
res = gen_reg_rtx (SImode);
|
||||
emit_insn (gen_compare_and_swap_12 (res, memsi, mask, inverted_mask,
|
||||
oldval, newval));
|
||||
if (result)
|
||||
res = gen_reg_rtx (SImode);
|
||||
if (newval)
|
||||
si_op = generator.fn_6 (res, memsi, mask, inverted_mask, oldval, newval);
|
||||
else if (result)
|
||||
si_op = generator.fn_5 (res, memsi, mask, inverted_mask, oldval);
|
||||
else
|
||||
si_op = generator.fn_4 (memsi, mask, inverted_mask, oldval);
|
||||
|
||||
/* Shift and convert the result. */
|
||||
mips_emit_binary (AND, res, res, mask);
|
||||
mips_emit_binary (LSHIFTRT, res, res, shiftsi);
|
||||
mips_emit_move (result, gen_lowpart (GET_MODE (result), res));
|
||||
emit_insn (si_op);
|
||||
|
||||
if (result)
|
||||
{
|
||||
/* Shift and convert the result. */
|
||||
mips_emit_binary (AND, res, res, mask);
|
||||
mips_emit_binary (LSHIFTRT, res, res, shiftsi);
|
||||
mips_emit_move (result, gen_lowpart (GET_MODE (result), res));
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if it is possible to use left/right accesses for a
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Definitions of target machine for GNU compiler. MIPS version.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by A. Lichnewsky (lich@inria.inria.fr).
|
||||
Changed by Michael Meissner (meissner@osf.org).
|
||||
|
@ -2908,40 +2908,31 @@ while (0)
|
|||
/* 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.
|
||||
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.
|
||||
*/
|
||||
#define MIPS_COMPARE_AND_SWAP_12 \
|
||||
|
||||
OPS are the instructions needed to OR %5 with %@. */
|
||||
#define MIPS_COMPARE_AND_SWAP_12(OPS) \
|
||||
"%(%<%[%|sync\n" \
|
||||
"1:\tll\t%0,%1\n" \
|
||||
"\tand\t%@,%0,%2\n" \
|
||||
"\tbne\t%@,%z4,2f\n" \
|
||||
"\tand\t%@,%0,%3\n" \
|
||||
"\tor\t%@,%@,%5\n" \
|
||||
OPS \
|
||||
"\tsc\t%@,%1\n" \
|
||||
"\tbeq\t%@,%.,1b\n" \
|
||||
"\tnop\n" \
|
||||
"\tsync%-%]%>%)\n" \
|
||||
"2:\n"
|
||||
|
||||
/* Like MIPS_COMPARE_AND_SWAP_12, except %5 is a constant zero,
|
||||
so the OR can be omitted. */
|
||||
#define MIPS_COMPARE_AND_SWAP_12_0 \
|
||||
"%(%<%[%|sync\n" \
|
||||
"1:\tll\t%0,%1\n" \
|
||||
"\tand\t%@,%0,%2\n" \
|
||||
"\tbne\t%@,%z4,2f\n" \
|
||||
"\tand\t%@,%0,%3\n" \
|
||||
"\tsc\t%@,%1\n" \
|
||||
"\tbeq\t%@,%.,1b\n" \
|
||||
"\tnop\n" \
|
||||
"\tsync%-%]%>%)\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:
|
||||
|
||||
|
@ -2958,6 +2949,97 @@ while (0)
|
|||
"\tnop\n" \
|
||||
"\tsync%-%]%>%)"
|
||||
|
||||
/* 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.
|
||||
|
||||
NOT_OP are the optional instructions to do a bit-wise not
|
||||
operation in conjunction with an AND INSN to generate a sync_nand
|
||||
operation. */
|
||||
#define MIPS_SYNC_OP_12(INSN, NOT_OP) \
|
||||
"%(%<%[%|sync\n" \
|
||||
"1:\tll\t%4,%0\n" \
|
||||
"\tand\t%@,%4,%2\n" \
|
||||
NOT_OP \
|
||||
"\t" INSN "\t%4,%4,%z3\n" \
|
||||
"\tand\t%4,%4,%1\n" \
|
||||
"\tor\t%@,%@,%4\n" \
|
||||
"\tsc\t%@,%0\n" \
|
||||
"\tbeq\t%@,%.,1b\n" \
|
||||
"\tnop\n" \
|
||||
"\tsync%-%]%>%)"
|
||||
|
||||
#define MIPS_SYNC_OP_12_NOT_NOP ""
|
||||
#define MIPS_SYNC_OP_12_NOT_NOT "\tnor\t%4,%4,%.\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.
|
||||
|
||||
NOT_OP are the optional instructions to do a bit-wise not
|
||||
operation in conjunction with an AND INSN to generate a sync_nand
|
||||
operation.
|
||||
|
||||
REG is used in conjunction with NOT_OP and is used to select the
|
||||
register operated on by the INSN. */
|
||||
#define MIPS_SYNC_OLD_OP_12(INSN, NOT_OP, REG) \
|
||||
"%(%<%[%|sync\n" \
|
||||
"1:\tll\t%0,%1\n" \
|
||||
"\tand\t%@,%0,%3\n" \
|
||||
NOT_OP \
|
||||
"\t" INSN "\t%5," REG ",%z4\n" \
|
||||
"\tand\t%5,%5,%2\n" \
|
||||
"\tor\t%@,%@,%5\n" \
|
||||
"\tsc\t%@,%1\n" \
|
||||
"\tbeq\t%@,%.,1b\n" \
|
||||
"\tnop\n" \
|
||||
"\tsync%-%]%>%)"
|
||||
|
||||
#define MIPS_SYNC_OLD_OP_12_NOT_NOP ""
|
||||
#define MIPS_SYNC_OLD_OP_12_NOT_NOP_REG "%0"
|
||||
#define MIPS_SYNC_OLD_OP_12_NOT_NOT "\tnor\t%5,%0,%.\n"
|
||||
#define MIPS_SYNC_OLD_OP_12_NOT_NOT_REG "%5"
|
||||
|
||||
/* 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.
|
||||
|
||||
NOT_OP are the optional instructions to do a bit-wise not
|
||||
operation in conjunction with an AND INSN to generate a sync_nand
|
||||
operation. */
|
||||
#define MIPS_SYNC_NEW_OP_12(INSN, NOT_OP) \
|
||||
"%(%<%[%|sync\n" \
|
||||
"1:\tll\t%0,%1\n" \
|
||||
"\tand\t%@,%0,%3\n" \
|
||||
NOT_OP \
|
||||
"\t" INSN "\t%0,%0,%z4\n" \
|
||||
"\tand\t%0,%0,%2\n" \
|
||||
"\tor\t%@,%@,%0\n" \
|
||||
"\tsc\t%@,%1\n" \
|
||||
"\tbeq\t%@,%.,1b\n" \
|
||||
"\tnop\n" \
|
||||
"\tsync%-%]%>%)"
|
||||
|
||||
#define MIPS_SYNC_NEW_OP_12_NOT_NOP ""
|
||||
#define MIPS_SYNC_NEW_OP_12_NOT_NOT "\tnor\t%0,%0,%.\n"
|
||||
|
||||
/* Return an asm string that atomically:
|
||||
|
||||
- Sets memory reference %1 to %1 INSN %2.
|
||||
|
@ -3065,6 +3147,33 @@ while (0)
|
|||
"\tnop\n" \
|
||||
"\tsync%-%]%>%)"
|
||||
|
||||
/* 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\n" \
|
||||
"\tsync%-%]%>%)"
|
||||
|
||||
#define MIPS_SYNC_EXCHANGE_12_ZERO_OP ""
|
||||
#define MIPS_SYNC_EXCHANGE_12_NONZERO_OP "\tor\t%@,%@,%4\n"
|
||||
|
||||
#ifndef USED_FOR_TARGET
|
||||
extern const enum reg_class mips_regno_to_class[];
|
||||
extern bool mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;; Mips.md Machine Description for MIPS based processors
|
||||
;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
||||
;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by A. Lichnewsky, lich@inria.inria.fr
|
||||
;; Changes by Michael Meissner, meissner@osf.org
|
||||
|
@ -57,10 +57,13 @@
|
|||
(UNSPEC_COMPARE_AND_SWAP_12 38)
|
||||
(UNSPEC_SYNC_OLD_OP 39)
|
||||
(UNSPEC_SYNC_NEW_OP 40)
|
||||
(UNSPEC_SYNC_EXCHANGE 41)
|
||||
(UNSPEC_MEMORY_BARRIER 42)
|
||||
(UNSPEC_SET_GOT_VERSION 43)
|
||||
(UNSPEC_UPDATE_GOT_VERSION 44)
|
||||
(UNSPEC_SYNC_NEW_OP_12 41)
|
||||
(UNSPEC_SYNC_OLD_OP_12 42)
|
||||
(UNSPEC_SYNC_EXCHANGE 43)
|
||||
(UNSPEC_SYNC_EXCHANGE_12 44)
|
||||
(UNSPEC_MEMORY_BARRIER 45)
|
||||
(UNSPEC_SET_GOT_VERSION 46)
|
||||
(UNSPEC_UPDATE_GOT_VERSION 47)
|
||||
|
||||
(UNSPEC_ADDRESS_FIRST 100)
|
||||
|
||||
|
@ -639,7 +642,9 @@
|
|||
(lshiftrt "lshr")
|
||||
(ior "ior")
|
||||
(xor "xor")
|
||||
(and "and")])
|
||||
(and "and")
|
||||
(plus "add")
|
||||
(minus "sub")])
|
||||
|
||||
;; <insn> expands to the name of the insn that implements a particular code.
|
||||
(define_code_attr insn [(ashift "sll")
|
||||
|
@ -647,7 +652,9 @@
|
|||
(lshiftrt "srl")
|
||||
(ior "or")
|
||||
(xor "xor")
|
||||
(and "and")])
|
||||
(and "and")
|
||||
(plus "addu")
|
||||
(minus "subu")])
|
||||
|
||||
;; <fcond> is the c.cond.fmt condition associated with a particular code.
|
||||
(define_code_attr fcond [(unordered "un")
|
||||
|
@ -671,6 +678,8 @@
|
|||
;; a particular code to operate in immediate values.
|
||||
(define_code_attr immediate_insn [(ior "ori") (xor "xori") (and "andi")])
|
||||
|
||||
;; Atomic HI and QI operations
|
||||
(define_code_iterator atomic_hiqi_op [plus minus ior xor and])
|
||||
|
||||
;; .........................
|
||||
;;
|
||||
|
@ -4455,12 +4464,14 @@
|
|||
(match_operand:SHORT 3 "general_operand")]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
mips_expand_compare_and_swap_12 (operands[0], operands[1],
|
||||
operands[2], operands[3]);
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_6 = gen_compare_and_swap_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
operands[0], operands[1], operands[2], operands[3]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Helper insn for mips_expand_compare_and_swap_12.
|
||||
;; Helper insn for mips_expand_atomic_qihi.
|
||||
(define_insn "compare_and_swap_12"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&d,&d")
|
||||
(match_operand:SI 1 "memory_operand" "+R,R"))
|
||||
|
@ -4473,9 +4484,9 @@
|
|||
"GENERATE_LL_SC"
|
||||
{
|
||||
if (which_alternative == 0)
|
||||
return MIPS_COMPARE_AND_SWAP_12;
|
||||
return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP);
|
||||
else
|
||||
return MIPS_COMPARE_AND_SWAP_12_0;
|
||||
return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP);
|
||||
}
|
||||
[(set_attr "length" "40,36")])
|
||||
|
||||
|
@ -4483,8 +4494,8 @@
|
|||
[(set (match_operand:GPR 0 "memory_operand" "+R,R")
|
||||
(unspec_volatile:GPR
|
||||
[(plus:GPR (match_dup 0)
|
||||
(match_operand:GPR 1 "arith_operand" "I,d"))]
|
||||
UNSPEC_SYNC_OLD_OP))]
|
||||
(match_operand:GPR 1 "arith_operand" "I,d"))]
|
||||
UNSPEC_SYNC_OLD_OP))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
if (which_alternative == 0)
|
||||
|
@ -4494,6 +4505,220 @@
|
|||
}
|
||||
[(set_attr "length" "28")])
|
||||
|
||||
(define_expand "sync_<optab><mode>"
|
||||
[(set (match_operand:SHORT 0 "memory_operand")
|
||||
(unspec_volatile:SHORT
|
||||
[(atomic_hiqi_op:SHORT (match_dup 0)
|
||||
(match_operand:SHORT 1 "general_operand"))]
|
||||
UNSPEC_SYNC_OLD_OP))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_4 = gen_sync_<optab>_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
NULL, operands[0], operands[1], NULL);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Helper insn for sync_<optab><mode>
|
||||
(define_insn "sync_<optab>_12"
|
||||
[(set (match_operand:SI 0 "memory_operand" "+R")
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 1 "register_operand" "d")
|
||||
(match_operand:SI 2 "register_operand" "d")
|
||||
(atomic_hiqi_op:SI (match_dup 0)
|
||||
(match_operand:SI 3 "register_operand" "dJ"))]
|
||||
UNSPEC_SYNC_OLD_OP_12))
|
||||
(clobber (match_scratch:SI 4 "=&d"))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
return MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_NOT_NOP);
|
||||
}
|
||||
[(set_attr "length" "40")])
|
||||
|
||||
(define_expand "sync_old_<optab><mode>"
|
||||
[(parallel [
|
||||
(set (match_operand:SHORT 0 "register_operand")
|
||||
(match_operand:SHORT 1 "memory_operand"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SHORT [(atomic_hiqi_op:SHORT
|
||||
(match_dup 1)
|
||||
(match_operand:SHORT 2 "general_operand"))]
|
||||
UNSPEC_SYNC_OLD_OP))])]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_5 = gen_sync_old_<optab>_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
operands[0], operands[1], operands[2], NULL);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Helper insn for sync_old_<optab><mode>
|
||||
(define_insn "sync_old_<optab>_12"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&d")
|
||||
(match_operand:SI 1 "memory_operand" "+R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 2 "register_operand" "d")
|
||||
(match_operand:SI 3 "register_operand" "d")
|
||||
(atomic_hiqi_op:SI (match_dup 0)
|
||||
(match_operand:SI 4 "register_operand" "dJ"))]
|
||||
UNSPEC_SYNC_OLD_OP_12))
|
||||
(clobber (match_scratch:SI 5 "=&d"))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
return MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP,
|
||||
MIPS_SYNC_OLD_OP_12_NOT_NOP_REG);
|
||||
}
|
||||
[(set_attr "length" "40")])
|
||||
|
||||
(define_expand "sync_new_<optab><mode>"
|
||||
[(parallel [
|
||||
(set (match_operand:SHORT 0 "register_operand")
|
||||
(unspec_volatile:SHORT [(atomic_hiqi_op:SHORT
|
||||
(match_operand:SHORT 1 "memory_operand")
|
||||
(match_operand:SHORT 2 "general_operand"))]
|
||||
UNSPEC_SYNC_NEW_OP))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SHORT [(match_dup 1) (match_dup 2)]
|
||||
UNSPEC_SYNC_NEW_OP))])]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_5 = gen_sync_new_<optab>_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
operands[0], operands[1], operands[2], NULL);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Helper insn for sync_new_<optab><mode>
|
||||
(define_insn "sync_new_<optab>_12"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&d")
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 1 "memory_operand" "+R")
|
||||
(match_operand:SI 2 "register_operand" "d")
|
||||
(match_operand:SI 3 "register_operand" "d")
|
||||
(atomic_hiqi_op:SI (match_dup 0)
|
||||
(match_operand:SI 4 "register_operand" "dJ"))]
|
||||
UNSPEC_SYNC_NEW_OP_12))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SI
|
||||
[(match_dup 1)
|
||||
(match_dup 2)
|
||||
(match_dup 3)
|
||||
(match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
return MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_NOT_NOP);
|
||||
}
|
||||
[(set_attr "length" "40")])
|
||||
|
||||
(define_expand "sync_nand<mode>"
|
||||
[(set (match_operand:SHORT 0 "memory_operand")
|
||||
(unspec_volatile:SHORT
|
||||
[(match_dup 0)
|
||||
(match_operand:SHORT 1 "general_operand")]
|
||||
UNSPEC_SYNC_OLD_OP))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_4 = gen_sync_nand_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
NULL, operands[0], operands[1], NULL);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Helper insn for sync_nand<mode>
|
||||
(define_insn "sync_nand_12"
|
||||
[(set (match_operand:SI 0 "memory_operand" "+R")
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 1 "register_operand" "d")
|
||||
(match_operand:SI 2 "register_operand" "d")
|
||||
(match_dup 0)
|
||||
(match_operand:SI 3 "register_operand" "dJ")]
|
||||
UNSPEC_SYNC_OLD_OP_12))
|
||||
(clobber (match_scratch:SI 4 "=&d"))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
return MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT);
|
||||
}
|
||||
[(set_attr "length" "44")])
|
||||
|
||||
(define_expand "sync_old_nand<mode>"
|
||||
[(parallel [
|
||||
(set (match_operand:SHORT 0 "register_operand")
|
||||
(match_operand:SHORT 1 "memory_operand"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SHORT [(match_dup 1)
|
||||
(match_operand:SHORT 2 "general_operand")]
|
||||
UNSPEC_SYNC_OLD_OP))])]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_5 = gen_sync_old_nand_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
operands[0], operands[1], operands[2], NULL);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Helper insn for sync_old_nand<mode>
|
||||
(define_insn "sync_old_nand_12"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&d")
|
||||
(match_operand:SI 1 "memory_operand" "+R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 2 "register_operand" "d")
|
||||
(match_operand:SI 3 "register_operand" "d")
|
||||
(match_operand:SI 4 "register_operand" "dJ")]
|
||||
UNSPEC_SYNC_OLD_OP_12))
|
||||
(clobber (match_scratch:SI 5 "=&d"))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
return MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT,
|
||||
MIPS_SYNC_OLD_OP_12_NOT_NOT_REG);
|
||||
}
|
||||
[(set_attr "length" "44")])
|
||||
|
||||
(define_expand "sync_new_nand<mode>"
|
||||
[(parallel [
|
||||
(set (match_operand:SHORT 0 "register_operand")
|
||||
(unspec_volatile:SHORT [(match_operand:SHORT 1 "memory_operand")
|
||||
(match_operand:SHORT 2 "general_operand")]
|
||||
UNSPEC_SYNC_NEW_OP))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SHORT [(match_dup 1) (match_dup 2)]
|
||||
UNSPEC_SYNC_NEW_OP))])]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_5 = gen_sync_new_nand_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
operands[0], operands[1], operands[2], NULL);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Helper insn for sync_new_nand<mode>
|
||||
(define_insn "sync_new_nand_12"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&d")
|
||||
(unspec_volatile:SI
|
||||
[(match_operand:SI 1 "memory_operand" "+R")
|
||||
(match_operand:SI 2 "register_operand" "d")
|
||||
(match_operand:SI 3 "register_operand" "d")
|
||||
(match_operand:SI 4 "register_operand" "dJ")]
|
||||
UNSPEC_SYNC_NEW_OP_12))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SI
|
||||
[(match_dup 1)
|
||||
(match_dup 2)
|
||||
(match_dup 3)
|
||||
(match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
return MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT);
|
||||
}
|
||||
[(set_attr "length" "40")])
|
||||
|
||||
(define_insn "sync_sub<mode>"
|
||||
[(set (match_operand:GPR 0 "memory_operand" "+R")
|
||||
(unspec_volatile:GPR
|
||||
|
@ -4507,7 +4732,7 @@
|
|||
[(set_attr "length" "28")])
|
||||
|
||||
(define_insn "sync_old_add<mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d,&d")
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
|
||||
(match_operand:GPR 1 "memory_operand" "+R,R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:GPR
|
||||
|
@ -4538,7 +4763,7 @@
|
|||
[(set_attr "length" "28")])
|
||||
|
||||
(define_insn "sync_new_add<mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d,&d")
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
|
||||
(plus:GPR (match_operand:GPR 1 "memory_operand" "+R,R")
|
||||
(match_operand:GPR 2 "arith_operand" "I,d")))
|
||||
(set (match_dup 1)
|
||||
|
@ -4584,7 +4809,7 @@
|
|||
[(set_attr "length" "28")])
|
||||
|
||||
(define_insn "sync_old_<optab><mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d,&d")
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
|
||||
(match_operand:GPR 1 "memory_operand" "+R,R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:GPR
|
||||
|
@ -4601,7 +4826,7 @@
|
|||
[(set_attr "length" "28")])
|
||||
|
||||
(define_insn "sync_new_<optab><mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d,&d")
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
|
||||
(match_operand:GPR 1 "memory_operand" "+R,R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:GPR
|
||||
|
@ -4631,7 +4856,7 @@
|
|||
[(set_attr "length" "32")])
|
||||
|
||||
(define_insn "sync_old_nand<mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d,&d")
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
|
||||
(match_operand:GPR 1 "memory_operand" "+R,R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
|
||||
|
@ -4646,7 +4871,7 @@
|
|||
[(set_attr "length" "32")])
|
||||
|
||||
(define_insn "sync_new_nand<mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d,&d")
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
|
||||
(match_operand:GPR 1 "memory_operand" "+R,R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
|
||||
|
@ -4661,7 +4886,7 @@
|
|||
[(set_attr "length" "32")])
|
||||
|
||||
(define_insn "sync_lock_test_and_set<mode>"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d,&d")
|
||||
[(set (match_operand:GPR 0 "register_operand" "=&d,&d")
|
||||
(match_operand:GPR 1 "memory_operand" "+R,R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
|
||||
|
@ -4674,6 +4899,36 @@
|
|||
return MIPS_SYNC_EXCHANGE ("<d>", "move");
|
||||
}
|
||||
[(set_attr "length" "24")])
|
||||
|
||||
(define_expand "sync_lock_test_and_set<mode>"
|
||||
[(match_operand:SHORT 0 "register_operand")
|
||||
(match_operand:SHORT 1 "memory_operand")
|
||||
(match_operand:SHORT 2 "general_operand")]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
union mips_gen_fn_ptrs generator;
|
||||
generator.fn_5 = gen_test_and_set_12;
|
||||
mips_expand_atomic_qihi (generator,
|
||||
operands[0], operands[1], operands[2], NULL);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "test_and_set_12"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&d,&d")
|
||||
(match_operand:SI 1 "memory_operand" "+R,R"))
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d")
|
||||
(match_operand:SI 3 "register_operand" "d,d")
|
||||
(match_operand:SI 4 "arith_operand" "d,J")]
|
||||
UNSPEC_SYNC_EXCHANGE_12))]
|
||||
"GENERATE_LL_SC"
|
||||
{
|
||||
if (which_alternative == 0)
|
||||
return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP);
|
||||
else
|
||||
return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP);
|
||||
}
|
||||
[(set_attr "length" "28,24")])
|
||||
|
||||
;; Block moves, see mips.c for more details.
|
||||
;; Argument 0 is the destination
|
||||
|
|
Loading…
Add table
Reference in a new issue