diff options
author | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-16 03:11:31 +0000 |
---|---|---|
committer | hp <hp@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-16 03:11:31 +0000 |
commit | 71b2d56aa61074317b51946510fc1300a84eb9d3 (patch) | |
tree | 95852ac2a4dd58be6e832f6ef73a96e45b8f50c2 | |
parent | 6c9930b077fe61c5c1470f3b65c85548b0e617bf (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/config/cris/cris.c | 47 | ||||
-rw-r--r-- | gcc/config/cris/sync.md | 70 |
3 files changed, 107 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ff638d466a..5d08b5ab93d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,23 @@ 2012-07-16 Hans-Peter Nilsson <hp@axis.com> - * config/cris/sync.md ("atomic_compare_and_swap<mode>"): Change - predicate to nonmemory_operand for operand 3. Add FIXME. + * 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. + ("atomic_compare_and_swap<mode>"): Change predicate to + nonmemory_operand for operand 3. Add FIXME. ("cris_atomic_compare_and_swap<mode>_1"): Change predicates and constraints for operand 3 to exclude memory. ("atomic_fetch_<atomic_op_name><mode>") diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index 1bc998165b1..44e328bfb2a 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -981,6 +981,53 @@ cris_print_operand (FILE *file, rtx x, int code) fprintf (file, INTVAL (operand) < 0 ? "adds.w" : "addq"); return; + case 'P': + /* For const_int operands, print the additive mnemonic and the + modified operand (byte-sized operands don't save anything): + N=MIN_INT..-65536: add.d N + -65535..-64: subu.w -N + -63..-1: subq -N + 0..63: addq N + 64..65535: addu.w N + 65536..MAX_INT: add.d N. + (Emitted mnemonics are capitalized to simplify testing.) + For anything else (N.B: only register is valid), print "add.d". */ + if (REG_P (operand)) + { + fprintf (file, "Add.d "); + + /* Deal with printing the operand by dropping through to the + normal path. */ + break; + } + else + { + int val; + gcc_assert (CONST_INT_P (operand)); + + val = INTVAL (operand); + if (!IN_RANGE (val, -65535, 65535)) + fprintf (file, "Add.d %d", val); + else if (val <= -64) + fprintf (file, "Subu.w %d", -val); + else if (val <= -1) + fprintf (file, "Subq %d", -val); + else if (val <= 63) + fprintf (file, "Addq %d", val); + else if (val <= 65535) + fprintf (file, "Addu.w %d", val); + return; + } + break; + + case 'q': + /* If the operand is an integer -31..31, print "q" else ".d". */ + if (CONST_INT_P (operand) && IN_RANGE (INTVAL (operand), -31, 31)) + fprintf (file, "q"); + else + fprintf (file, ".d"); + return; + case 'd': /* If this is a GOT symbol, force it to be emitted as :GOT and :GOTPLT regardless of -fpic (i.e. not as :GOT16, :GOTPLT16). 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\;" |