]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cris.c (cris_print_operand): New cases.
authorHans-Peter Nilsson <hp@axis.com>
Mon, 16 Jul 2012 03:11:31 +0000 (03:11 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Mon, 16 Jul 2012 03:11:31 +0000 (03:11 +0000)
* 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

gcc/ChangeLog
gcc/config/cris/cris.c
gcc/config/cris/sync.md

index 2ff638d466ad3f51014c7298dde5d19a794c0c1d..5d08b5ab93dae20c24cde5541afb2a4efdc65bfa 100644 (file)
@@ -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>")
index 1bc998165b1b1a4390844c17ef9a9d95c477cd9a..44e328bfb2ac84f5573401be336cd8852f17da3f 100644 (file)
@@ -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).
index baa2bebc7cb01d6f384fe2dfd4ba12e4cbaf28b5..b1dac815ddaf1be9989e73307a09d17d2faf1763 100644 (file)
 (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))]
   ""
   [(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"))]
       ".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.%=\;"
       ".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.%=\;"
        "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.%=:";
 {
   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
        "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\;"