cris.c (cris_print_operand): New cases.
* 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. From-SVN: r189503
This commit is contained in:
parent
c3a3b5b55d
commit
24ddb79c2d
|
@ -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>")
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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\;"
|
||||
|
|
Loading…
Reference in New Issue