summaryrefslogtreecommitdiff
path: root/gcc/config/cris/sync.md
diff options
context:
space:
mode:
authorhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-16 03:11:31 +0000
committerhp <hp@138bc75d-0d04-0410-961f-82ee72b054a4>2012-07-16 03:11:31 +0000
commit71b2d56aa61074317b51946510fc1300a84eb9d3 (patch)
tree95852ac2a4dd58be6e832f6ef73a96e45b8f50c2 /gcc/config/cris/sync.md
parent6c9930b077fe61c5c1470f3b65c85548b0e617bf (diff)
downloadgcc-71b2d56aa61074317b51946510fc1300a84eb9d3.tar.gz
* config/cris/cris.c (cris_print_operand) <case 'P', 'q'>: New cases.
* config/cris/sync.md (atomic_op_op_cnstr): New code_attr. (atomic_op_op_pred): Ditto. (atomic_op_mnem_pre_op2): Renamed from atomic_op_mnem_pre; to reflect the change to include %2 in expansion. All callers changed. (qm3): New mode_attr. ("atomic_fetch_<atomic_op_name><mode>"): Use <atomic_op_op_pred> as predicate for operand 2. ("cris_atomic_fetch_<atomic_op_name><mode>_1"): Update FIXME. Use "<atomic_op_op_pred>" "<atomic_op_op_cnstr>" for predicate and constraint for operand 2. ("atomic_compare_and_swap<mode>"): Add FIXME. Change predicate to nonmemory_operand for operand 3. ("cris_atomic_compare_and_swap<mode>_1"): Change operand 3 to exclude memory. Improve emitted sync code for v10 and v32. Use <qm3> instead of <m> for size designator for cmp. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189503 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/cris/sync.md')
-rw-r--r--gcc/config/cris/sync.md70
1 files changed, 42 insertions, 28 deletions
diff --git a/gcc/config/cris/sync.md b/gcc/config/cris/sync.md
index baa2bebc7cb..b1dac815dda 100644
--- a/gcc/config/cris/sync.md
+++ b/gcc/config/cris/sync.md
@@ -73,17 +73,32 @@
(define_code_attr atomic_op_name
[(plus "add") (minus "sub") (and "and") (ior "or") (xor "xor") (mult "nand")])
+;; The operator nonatomic-operand can be memory, constant or register
+;; for all but xor. We can't use memory or addressing modes with
+;; side-effects though, so just use registers and literal constants.
+(define_code_attr atomic_op_op_cnstr
+ [(plus "ri") (minus "ri") (and "ri") (ior "ri") (xor "r") (mult "ri")])
+
+(define_code_attr atomic_op_op_pred
+ [(plus "nonmemory_operand") (minus "nonmemory_operand")
+ (and "nonmemory_operand") (ior "nonmemory_operand")
+ (xor "register_operand") (mult "nonmemory_operand")])
+
;; Pairs of these are used to insert the "not" after the "and" for nand.
-(define_code_attr atomic_op_mnem_pre ;; Upper-case only to sinplify testing.
- [(plus "Add.d") (minus "Sub.d") (and "And.d") (ior "Or.d") (xor "Xor")
- (mult "aNd.d")])
+(define_code_attr atomic_op_mnem_pre_op2 ;; Upper-case only to simplify testing.
+ [(plus "%P2") (minus "Sub.d %2") (and "And%q2 %2") (ior "Or%q2 %2") (xor "Xor %2")
+ (mult "aNd%q2 %2")])
+
(define_code_attr atomic_op_mnem_post_op3
[(plus "") (minus "") (and "") (ior "") (xor "") (mult "not %3\;")])
+;; For SImode, emit "q" for operands -31..31.
+(define_mode_attr qm3 [(SI "%q3") (HI ".w") (QI ".b")])
+
(define_expand "atomic_fetch_<atomic_op_name><mode>"
[(match_operand:BWD 0 "register_operand")
(match_operand:BWD 1 "memory_operand")
- (match_operand:BWD 2 "register_operand")
+ (match_operand:BWD 2 "<atomic_op_op_pred>")
(match_operand 3)
(atomic_op:BWD (match_dup 0) (match_dup 1))]
""
@@ -109,8 +124,9 @@
[(set (match_operand:BWD 1 "memory_operand" "+Q")
(atomic_op:BWD
(unspec_volatile:BWD [(match_dup 1)] CRIS_UNSPEC_ATOMIC_OP)
- ;; FIXME: relax this for plus, minus, and, ior.
- (match_operand:BWD 2 "register_operand" "r")))
+ ;; FIXME: improve constants more for plus, minus, and, ior.
+ ;; FIXME: handle memory operands without side-effects.
+ (match_operand:BWD 2 "<atomic_op_op_pred>" "<atomic_op_op_cnstr>")))
(set (match_operand:BWD 0 "register_operand" "=&r")
(match_dup 1))
(clobber (match_scratch:SI 3 "=&r"))]
@@ -125,7 +141,7 @@
".Lsync.%=:\;"
"move<m> %1,%0\;"
"move.d %0,%3\;"
- "<atomic_op_mnem_pre> %2,%3\;<atomic_op_mnem_post_op3>"
+ "<atomic_op_mnem_pre_op2>,%3\;<atomic_op_mnem_post_op3>"
"ax\;"
"move<m> %3,%1\;"
"bcs .Lsync.%=\;"
@@ -136,7 +152,7 @@
".Lsync.%=:\;"
"move<m> %1,%0\;"
"move.d %0,%3\;"
- "<atomic_op_mnem_pre> %2,%3\;<atomic_op_mnem_post_op3>"
+ "<atomic_op_mnem_pre_op2>,%3\;<atomic_op_mnem_post_op3>"
"ax\;"
"move<m> %3,%1\;"
"bwf .Lsync.%=\;"
@@ -167,12 +183,12 @@
"bmi .Lsync.irqon.%=\;"
"move.d %0,%3\;"
- "<atomic_op_mnem_pre> %2,%3\;<atomic_op_mnem_post_op3>"
+ "<atomic_op_mnem_pre_op2>,%3\;<atomic_op_mnem_post_op3>"
"ba .Lsync.irqoff.%=\;"
"move<m> %3,%1\n"
".Lsync.irqon.%=:\;"
- "<atomic_op_mnem_pre> %2,%3\;<atomic_op_mnem_post_op3>"
+ "<atomic_op_mnem_pre_op2>,%3\;<atomic_op_mnem_post_op3>"
"move<m> %3,%1\;"
"ei\n"
".Lsync.irqoff.%=:";
@@ -232,32 +248,30 @@
{
if (TARGET_V32)
return
- "clearf p\n"
- ".Lsync.repeat.%=:\;"
+ "\n.Lsync.repeat.%=:\;"
+ "clearf p\;"
"move<m> %2,%1\;"
- "cmp<m> %3,%1\;"
+ "cmp<qm3> %3,%1\;"
"bne .Lsync.after.%=\;"
- "seq %0\;"
-
"ax\;"
+
"move<m> %4,%2\;"
- "bcs .Lsync.repeat.%=\;"
- "clearf p\n"
- ".Lsync.after.%=:";
+ "bcs .Lsync.repeat.%=\n"
+ ".Lsync.after.%=:\;"
+ "seq %0";
else if (cris_cpu_version == 10)
return
- "clearf\n"
- ".Lsync.repeat.%=:\;"
+ "\n.Lsync.repeat.%=:\;"
+ "clearf\;"
"move<m> %2,%1\;"
- "cmp<m> %3,%1\;"
+ "cmp<qm3> %3,%1\;"
"bne .Lsync.after.%=\;"
- "seq %0\;"
-
"ax\;"
+
"move<m> %4,%2\;"
- "bwf .Lsync.repeat.%=\;"
- "clearf\n"
- ".Lsync.after.%=:";
+ "bwf .Lsync.repeat.%=\n"
+ ".Lsync.after.%=:\;"
+ "seq %0";
else
{
/* This one is for CRIS versions without load-locked-store-conditional
@@ -284,14 +298,14 @@
"bmi .Lsync.irqon.%=\;"
"nop\;"
- "cmp<m> %3,%1\;"
+ "cmp<qm3> %3,%1\;"
"bne .Lsync.after.%=\;"
"seq %0\;"
"ba .Lsync.after.%=\;"
"move<m> %4,%2\n"
".Lsync.irqon.%=:\;"
- "cmp<m> %3,%1\;"
+ "cmp<qm3> %3,%1\;"
"bne .Lsync.after.%=\;"
"seq %0\;"
"move<m> %4,%2\;"