re PR target/64661 ([SH] Allow @(disp,reg) address mode for atomics)

gcc/
	PR target/64661
	* config/sh/sh-protos.h (TARGET_ATOMIC_ANY, TARGET_ATOMIC_STRICT,
	TARGET_ATOMIC_SOFT_GUSA, TARGET_ATOMIC_HARD_LLCS,
	TARGET_ATOMIC_SOFT_TCB, TARGET_ATOMIC_SOFT_IMASK): Add parentheses.
	* config/sh/constraints.md (Ara, Add): New constraints.
	* config/sh/sync.md (atomic_mem_operand_0, atomic_mem_operand_1): New
	predicates.
	(atomic_compare_and_swap<mode>, atomic_exchange<mode>): Use
	atomic_mem_operand_0.  Don't use force_reg on the memory address.
	(atomic_compare_and_swapsi_hard): Use atomic_mem_operand_0 predicate and
	Sra constraint.  Convert to insn_and_split.  Add workaround for
	PR 64974.
	(atomic_compare_and_swap<mode>_hard): Copy to
	atomic_compare_and_swap<mode>_hard_1.  Convert to insn_and_split.
	Use atomic_mem_operand_0 predicate.
	(atomic_compare_and_swap<mode>_soft_gusa,
	atomic_exchange<mode>_soft_gusa): Use atomic_mem_operand_0 predicate and
	AraAdd constraints.
	(atomic_compare_and_swap<mode>_soft_tcb,
	atomic_compare_and_swap<mode>_soft_imask,
	atomic_exchange<mode>_soft_tcb, atomic_exchange<mode>_soft_imask): Use
	atomic_mem_operand_0 predicate and SraSdd constraints.
	(atomic_exchangesi_hard) Use atomic_mem_operand_0 predicate and Sra
	constraint.
	(atomic_exchange<mode>_hard): Copy to atomic_exchange<mode>_hard_1.
	Convert to insn_and_split.  Use atomic_mem_operand_0 predicate.
	(atomic_fetch_<fetchop_name><mode>, atomic_fetch_nand<mode>,
	atomic_<fetchop_name>_fetch<mode>): Use atomic_mem_operand_1.  Don't use
	force_reg on the memory address.
	(atomic_fetch_<fetchop_name>si_hard, atomic_fetch_notsi_hard,
	atomic_fetch_nandsi_hard, atomic_<fetchop_name>_fetchsi_hard,
	atomic_not_fetchsi_hard, atomic_nand_fetchsi_hard): Use
	atomic_mem_operand_1 predicate and Sra constraint.
	(atomic_fetch_<fetchop_name><mode>_hard): Copy to
	atomic_fetch_<fetchop_name><mode>_hard_1.  Convert to insn_and_split.
	Use atomic_mem_operand_1 predicate.
	(atomic_<fetchop_name><mode>_hard): Copy to
	atomic_<fetchop_name><mode>_hard_1.  Convert to insn_and_split.
	Use atomic_mem_operand_1 predicate.
	(atomic_fetch_nand<mode>_hard): Copy to atomic_fetch_nand<mode>_hard_1.
	Convert to insn_and_split.  Use atomic_mem_operand_1 predicate.
	(atomic_nand<mode>_hard): Copy to atomic_nand<mode>_hard_1.  Convert to
	insn_and_split.  Use atomic_mem_operand_1 predicate.
	(atomic_<fetchop_name>_fetch<mode>_hard): Copy to
	atomic_<fetchop_name>_fetch<mode>_hard_1.  Convert to insn_and_split.
	Use atomic_mem_operand_1 predicate.
	(atomic_nand_fetch<mode>_hard): Copy to atomic_nand_fetch<mode>_hard_1.
	Convert to insn_and_split.  Use atomic_mem_operand_1 predicate.
	(atomic_fetch_not<mode>_hard, atomic_not_fetch<mode>_hard): Replace mems
	in generated insn with original mem operand before emitting the insn.
	(atomic_fetch_<fetchop_name><mode>_soft_gusa,
	atomic_fetch_not<mode>_soft_gusa, atomic_fetch_nand<mode>_soft_gusa,
	atomic_<fetchop_name>_fetch<mode>_soft_gusa,
	atomic_not_fetch<mode>_soft_gusa, atomic_nand_fetch<mode>_soft_gusa):
	Use atomic_mem_operand_1 predicate and AraAdd constraints.
	(atomic_fetch_<fetchop_name><mode>_soft_tcb,
	atomic_<fetchop_name><mode>_soft_tcb, atomic_fetch_not<mode>_soft_tcb,
	atomic_not<mode>_soft_tcb, atomic_fetch_<fetchop_name><mode>_soft_imask,
	atomic_fetch_not<mode>_soft_imask, atomic_fetch_nand<mode>_soft_tcb,
	atomic_nand<mode>_soft_tcb, atomic_fetch_nand<mode>_soft_imask,
	atomic_<fetchop_name>_fetch<mode>_soft_tcb,
	atomic_not_fetch<mode>_soft_tcb,
	atomic_<fetchop_name>_fetch<mode>_soft_imask,
	atomic_not_fetch<mode>_soft_imask, atomic_nand_fetch<mode>,
	atomic_nand_fetch<mode>_soft_tcb, atomic_nand_fetch<mode>_soft_imask):
	Use atomic_mem_operand_1 predicate and SraSdd constraints.

gcc/testsuite/
	PR target/64661
	* gcc.taget/sh/pr64661-0.h: New.
	* gcc.taget/sh/pr64661-1.c: New.
	* gcc.taget/sh/pr64661-2.c: New.
	* gcc.taget/sh/pr64661-3.c: New.
	* gcc.taget/sh/pr64661-4.c: New.

From-SVN: r220594
This commit is contained in:
Oleg Endo 2015-02-10 20:47:33 +00:00
parent afa208748d
commit 2fdc039982
10 changed files with 847 additions and 242 deletions

View file

@ -1,3 +1,72 @@
2015-02-10 Oleg Endo <olegendo@gcc.gnu.org>
PR target/64661
* config/sh/sh-protos.h (TARGET_ATOMIC_ANY, TARGET_ATOMIC_STRICT,
TARGET_ATOMIC_SOFT_GUSA, TARGET_ATOMIC_HARD_LLCS,
TARGET_ATOMIC_SOFT_TCB, TARGET_ATOMIC_SOFT_IMASK): Add parentheses.
* config/sh/constraints.md (Ara, Add): New constraints.
* config/sh/sync.md (atomic_mem_operand_0, atomic_mem_operand_1): New
predicates.
(atomic_compare_and_swap<mode>, atomic_exchange<mode>): Use
atomic_mem_operand_0. Don't use force_reg on the memory address.
(atomic_compare_and_swapsi_hard): Use atomic_mem_operand_0 predicate and
Sra constraint. Convert to insn_and_split. Add workaround for
PR 64974.
(atomic_compare_and_swap<mode>_hard): Copy to
atomic_compare_and_swap<mode>_hard_1. Convert to insn_and_split.
Use atomic_mem_operand_0 predicate.
(atomic_compare_and_swap<mode>_soft_gusa,
atomic_exchange<mode>_soft_gusa): Use atomic_mem_operand_0 predicate and
AraAdd constraints.
(atomic_compare_and_swap<mode>_soft_tcb,
atomic_compare_and_swap<mode>_soft_imask,
atomic_exchange<mode>_soft_tcb, atomic_exchange<mode>_soft_imask): Use
atomic_mem_operand_0 predicate and SraSdd constraints.
(atomic_exchangesi_hard) Use atomic_mem_operand_0 predicate and Sra
constraint.
(atomic_exchange<mode>_hard): Copy to atomic_exchange<mode>_hard_1.
Convert to insn_and_split. Use atomic_mem_operand_0 predicate.
(atomic_fetch_<fetchop_name><mode>, atomic_fetch_nand<mode>,
atomic_<fetchop_name>_fetch<mode>): Use atomic_mem_operand_1. Don't use
force_reg on the memory address.
(atomic_fetch_<fetchop_name>si_hard, atomic_fetch_notsi_hard,
atomic_fetch_nandsi_hard, atomic_<fetchop_name>_fetchsi_hard,
atomic_not_fetchsi_hard, atomic_nand_fetchsi_hard): Use
atomic_mem_operand_1 predicate and Sra constraint.
(atomic_fetch_<fetchop_name><mode>_hard): Copy to
atomic_fetch_<fetchop_name><mode>_hard_1. Convert to insn_and_split.
Use atomic_mem_operand_1 predicate.
(atomic_<fetchop_name><mode>_hard): Copy to
atomic_<fetchop_name><mode>_hard_1. Convert to insn_and_split.
Use atomic_mem_operand_1 predicate.
(atomic_fetch_nand<mode>_hard): Copy to atomic_fetch_nand<mode>_hard_1.
Convert to insn_and_split. Use atomic_mem_operand_1 predicate.
(atomic_nand<mode>_hard): Copy to atomic_nand<mode>_hard_1. Convert to
insn_and_split. Use atomic_mem_operand_1 predicate.
(atomic_<fetchop_name>_fetch<mode>_hard): Copy to
atomic_<fetchop_name>_fetch<mode>_hard_1. Convert to insn_and_split.
Use atomic_mem_operand_1 predicate.
(atomic_nand_fetch<mode>_hard): Copy to atomic_nand_fetch<mode>_hard_1.
Convert to insn_and_split. Use atomic_mem_operand_1 predicate.
(atomic_fetch_not<mode>_hard, atomic_not_fetch<mode>_hard): Replace mems
in generated insn with original mem operand before emitting the insn.
(atomic_fetch_<fetchop_name><mode>_soft_gusa,
atomic_fetch_not<mode>_soft_gusa, atomic_fetch_nand<mode>_soft_gusa,
atomic_<fetchop_name>_fetch<mode>_soft_gusa,
atomic_not_fetch<mode>_soft_gusa, atomic_nand_fetch<mode>_soft_gusa):
Use atomic_mem_operand_1 predicate and AraAdd constraints.
(atomic_fetch_<fetchop_name><mode>_soft_tcb,
atomic_<fetchop_name><mode>_soft_tcb, atomic_fetch_not<mode>_soft_tcb,
atomic_not<mode>_soft_tcb, atomic_fetch_<fetchop_name><mode>_soft_imask,
atomic_fetch_not<mode>_soft_imask, atomic_fetch_nand<mode>_soft_tcb,
atomic_nand<mode>_soft_tcb, atomic_fetch_nand<mode>_soft_imask,
atomic_<fetchop_name>_fetch<mode>_soft_tcb,
atomic_not_fetch<mode>_soft_tcb,
atomic_<fetchop_name>_fetch<mode>_soft_imask,
atomic_not_fetch<mode>_soft_imask, atomic_nand_fetch<mode>,
atomic_nand_fetch<mode>_soft_tcb, atomic_nand_fetch<mode>_soft_imask):
Use atomic_mem_operand_1 predicate and SraSdd constraints.
2015-02-10 Uros Bizjak <ubizjak@gmail.com>
* config/alpha/alpha.md (reload_out<mode>_aligned): Make operands 2

View file

@ -18,6 +18,9 @@
;; <http://www.gnu.org/licenses/>.
;; Overview of uppercase letter constraints:
;; Axx: atomic memory operand constraints
;; Ara: Same as Sra but disallows r15
;; Add: Same as Sdd but disallows r15
;; Bxx: miscellaneous constraints
;; Bsc: SCRATCH - for the scratch register in movsi_ie in the
;; fldi0 / fldi0 cases
@ -322,3 +325,19 @@
(and (match_test "MEM_P (op)")
(match_test "REG_P (XEXP (op, 0))")))
(define_memory_constraint "Ara"
"A memory reference that uses simple register addressing suitable for
gusa atomic operations."
(and (match_code "mem")
(match_code "reg" "0")
(match_test "REGNO (XEXP (op, 0)) != SP_REG")))
(define_memory_constraint "Add"
"A memory reference that uses displacement addressing suitable for
gusa atomic operations."
(and (match_code "mem")
(match_test "GET_MODE (op) == SImode")
(match_code "plus" "0")
(match_code "reg" "00")
(match_code "const_int" "01")
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) != SP_REG")))

View file

@ -68,25 +68,25 @@ extern const sh_atomic_model& selected_atomic_model (void);
/* Shortcuts to check the currently selected atomic model. */
#define TARGET_ATOMIC_ANY \
selected_atomic_model ().type != sh_atomic_model::none
(selected_atomic_model ().type != sh_atomic_model::none)
#define TARGET_ATOMIC_STRICT \
selected_atomic_model ().strict
(selected_atomic_model ().strict)
#define TARGET_ATOMIC_SOFT_GUSA \
selected_atomic_model ().type == sh_atomic_model::soft_gusa
(selected_atomic_model ().type == sh_atomic_model::soft_gusa)
#define TARGET_ATOMIC_HARD_LLCS \
selected_atomic_model ().type == sh_atomic_model::hard_llcs
(selected_atomic_model ().type == sh_atomic_model::hard_llcs)
#define TARGET_ATOMIC_SOFT_TCB \
selected_atomic_model ().type == sh_atomic_model::soft_tcb
(selected_atomic_model ().type == sh_atomic_model::soft_tcb)
#define TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX \
GEN_INT (selected_atomic_model ().tcb_gbr_offset)
#define TARGET_ATOMIC_SOFT_IMASK \
selected_atomic_model ().type == sh_atomic_model::soft_imask
(selected_atomic_model ().type == sh_atomic_model::soft_imask)
#ifdef RTX_CODE
extern rtx sh_fsca_sf2int (void);

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,12 @@
2015-02-10 Oleg Endo <olegendo@gcc.gnu.org>
PR target/64661
* gcc.taget/sh/pr64661-0.h: New.
* gcc.taget/sh/pr64661-1.c: New.
* gcc.taget/sh/pr64661-2.c: New.
* gcc.taget/sh/pr64661-3.c: New.
* gcc.taget/sh/pr64661-4.c: New.
2015-02-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/64995

View file

@ -0,0 +1,171 @@
/* Check that addressing modes for atomics are generated as expected. */
#define concat_1(x, y) x ## y
#define concat(x, y) concat_1 (x, y)
#define makefuncname(name) concat (concat (test_, __LINE__), name)
#define emitfuncs(name,val,off)\
char makefuncname (_0) (char* mem)\
{\
return name (mem + off, val, __ATOMIC_ACQ_REL);\
}\
char makefuncname (_1) (void)\
{\
char* mem = (char*)__builtin_thread_pointer ();\
return name (mem + off, val, __ATOMIC_ACQ_REL);\
}\
short makefuncname (_2) (short* mem)\
{\
return name (mem + off, val, __ATOMIC_ACQ_REL);\
}\
short makefuncname (_3) (void)\
{\
short* mem = (short*)__builtin_thread_pointer ();\
return name (mem + off, val, __ATOMIC_ACQ_REL);\
}\
int makefuncname (_4) (int* mem)\
{\
return name (mem + off, val, __ATOMIC_ACQ_REL);\
}\
int makefuncname (_5) (void)\
{\
int* mem = (int*)__builtin_thread_pointer ();\
return name (mem + off, val, __ATOMIC_ACQ_REL);\
}\
emitfuncs (__atomic_add_fetch, 1, 0)
emitfuncs (__atomic_add_fetch, 1, 4)
emitfuncs (__atomic_fetch_add, 1, 0)
emitfuncs (__atomic_fetch_add, 1, 4)
emitfuncs (__atomic_sub_fetch, 1, 0)
emitfuncs (__atomic_sub_fetch, 1, 4)
emitfuncs (__atomic_fetch_sub, 1, 0)
emitfuncs (__atomic_fetch_sub, 1, 4)
emitfuncs (__atomic_and_fetch, 1, 0)
emitfuncs (__atomic_and_fetch, 1, 4)
emitfuncs (__atomic_fetch_and, 1, 0)
emitfuncs (__atomic_fetch_and, 1, 4)
emitfuncs (__atomic_or_fetch, 1, 0)
emitfuncs (__atomic_or_fetch, 1, 4)
emitfuncs (__atomic_fetch_or, 1, 0)
emitfuncs (__atomic_fetch_or, 1, 4)
emitfuncs (__atomic_xor_fetch, 1, 0)
emitfuncs (__atomic_xor_fetch, 1, 4)
emitfuncs (__atomic_fetch_xor, 1, 0)
emitfuncs (__atomic_fetch_xor, 1, 4)
emitfuncs (__atomic_nand_fetch, 1, 0)
emitfuncs (__atomic_nand_fetch, 1, 4)
emitfuncs (__atomic_fetch_nand, 1, 0)
emitfuncs (__atomic_fetch_nand, 1, 4)
emitfuncs (__atomic_xor_fetch, -1, 0)
emitfuncs (__atomic_xor_fetch, -1, 4)
emitfuncs (__atomic_fetch_xor, -1, 0)
emitfuncs (__atomic_fetch_xor, -1, 4)
emitfuncs (__atomic_nand_fetch, -1, 0)
emitfuncs (__atomic_nand_fetch, -1, 4)
emitfuncs (__atomic_fetch_nand, -1, 0)
emitfuncs (__atomic_fetch_nand, -1, 4)
#undef emitfuncs
#define emitfuncs(off)\
char makefuncname (_6) (char* mem)\
{\
char expected = 1;\
char desired = 5;\
return __atomic_compare_exchange (mem + off, &expected, &desired, 0,\
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED);\
}\
char makefuncname (_7) (void)\
{\
char* mem = (char*)__builtin_thread_pointer ();\
char expected = 1;\
char desired = 5;\
return __atomic_compare_exchange (mem + off, &expected, &desired, 0,\
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED);\
}\
short makefuncname (_8) (short* mem)\
{\
short expected = 1;\
short desired = 5;\
return __atomic_compare_exchange (mem + off, &expected, &desired, 0,\
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED);\
}\
short makefuncname (_9) (void)\
{\
short* mem = (short*)__builtin_thread_pointer ();\
short expected = 1;\
short desired = 5;\
return __atomic_compare_exchange (mem + off, &expected, &desired, 0,\
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED);\
}\
int makefuncname (_10) (int* mem)\
{\
int expected = 1;\
int desired = 5;\
return __atomic_compare_exchange (mem + off, &expected, &desired, 0,\
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED);\
}\
int makefuncname (_11) (void)\
{\
int* mem = (int*)__builtin_thread_pointer ();\
int expected = 1;\
int desired = 5;\
return __atomic_compare_exchange (mem + off, &expected, &desired, 0,\
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED);\
}\
char makefuncname (_12) (char* mem)\
{\
char newval = 5;\
char prevval;\
__atomic_exchange (mem + off, &newval, &prevval, __ATOMIC_ACQ_REL);\
return prevval;\
}\
char makefuncname (_13) (void)\
{\
char* mem = (char*)__builtin_thread_pointer ();\
char newval = 5;\
char prevval;\
__atomic_exchange (mem + off, &newval, &prevval, __ATOMIC_ACQ_REL);\
return prevval;\
}\
short makefuncname (_14) (short* mem)\
{\
short newval = 5;\
short prevval;\
__atomic_exchange (mem + off, &newval, &prevval, __ATOMIC_ACQ_REL);\
return prevval;\
}\
short makefuncname (_15) (void)\
{\
short* mem = (short*)__builtin_thread_pointer ();\
short newval = 5;\
short prevval;\
__atomic_exchange (mem + off, &newval, &prevval, __ATOMIC_ACQ_REL);\
return prevval;\
}\
int makefuncname (_16) (int* mem)\
{\
int newval = 5;\
int prevval;\
__atomic_exchange (mem + off, &newval, &prevval, __ATOMIC_ACQ_REL);\
return prevval;\
}\
int makefuncname (_17) (void)\
{\
int* mem = (int*)__builtin_thread_pointer ();\
int newval = 5;\
int prevval;\
__atomic_exchange (mem + off, &newval, &prevval, __ATOMIC_ACQ_REL);\
return prevval;\
}\
emitfuncs (0)
emitfuncs (4)

View file

@ -0,0 +1,6 @@
/* Check that addressing modes for atomics are generated as expected. */
/* { dg-do compile { target { atomic_model_soft_gusa_available } } } */
/* { dg-options "-O2 -matomic-model=soft-gusa,strict" } */
/* { dg-final { scan-assembler-times "@\\(16,r\[0-9\]\\)" 72 } } */
#include "pr64661-0.h"

View file

@ -0,0 +1,11 @@
/* Check that addressing modes for atomics are generated as expected. */
/* { dg-do compile { target { atomic_model_soft_tcb_available } } } */
/* { dg-options "-O2 -matomic-model=soft-tcb,gbr-offset=128,strict" } */
/* { dg-final { scan-assembler-times "@\\(16,r\[0-9\]\\)" 44 } } */
/* { dg-final { scan-assembler-times "@\\(8,r\[0-9\]\\)" 36 } } */
/* { dg-final { scan-assembler-times "@\\(4,r\[0-9\]\\)" 36 } } */
/* { dg-final { scan-assembler-times "@\\(16,gbr\\)" 28 } } */
/* { dg-final { scan-assembler-times "@\\(8,gbr\\)" 28 } } */
/* { dg-final { scan-assembler-times "@\\(4,gbr\\)" 28 } } */
#include "pr64661-0.h"

View file

@ -0,0 +1,11 @@
/* Check that addressing modes for atomics are generated as expected. */
/* { dg-do compile { target { atomic_model_soft_imask_available } } } */
/* { dg-options "-O2 -matomic-model=soft-imask,strict -mno-usermode" } */
/* { dg-final { scan-assembler-times "@\\(16,r\[0-9\]\\)" 44 } } */
/* { dg-final { scan-assembler-times "@\\(8,r\[0-9\]\\)" 36 } } */
/* { dg-final { scan-assembler-times "@\\(4,r\[0-9\]\\)" 36 } } */
/* { dg-final { scan-assembler-times "@\\(16,gbr\\)" 28 } } */
/* { dg-final { scan-assembler-times "@\\(8,gbr\\)" 28 } } */
/* { dg-final { scan-assembler-times "@\\(4,gbr\\)" 28 } } */
#include "pr64661-0.h"

View file

@ -0,0 +1,8 @@
/* Check that addressing modes for atomics are generated as expected.
The LLCS patterns are limited to simple register addresses, so there's not
much to check here. */
/* { dg-do compile { target { atomic_model_hard_llcs_available } } } */
/* { dg-options "-dp -O2 -matomic-model=hard-llcs,strict" } */
/* { dg-final { scan-assembler-times "hard_1" 112 } } */
#include "pr64661-0.h"