]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/vax/builtins.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / vax / builtins.md
index e96ac3f52abd62f97979a829a448535b4576346b..b1b006b20c76c0f1058f3ac969bb5a2b3f33b8af 100644 (file)
@@ -1,5 +1,5 @@
 ;; builtin definitions for DEC VAX.
-;; Copyright (C) 2007-2020 Free Software Foundation, Inc.
+;; Copyright (C) 2007-2024 Free Software Foundation, Inc.
 ;;
 ;; This file is part of GCC.
 ;;
 {
   rtx label = gen_label_rtx ();
   rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
-  rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
+  rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx);
   rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
 
-  emit_insn (gen_ctz<mode>2 (operands[0], operands[1]));
+  emit_insn (gen_ctz<mode>2_ccz (operands[0], operands[1]));
   emit_jump_insn (gen_rtx_SET (pc_rtx, target));
   emit_insn (gen_neg<mode>2 (operands[0], const1_rtx));
   emit_label (label);
   DONE;
 }")
 
-(define_insn "ctz<mode>2"
+(define_insn_and_split "ctz<mode>2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+       (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
+  ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ctz:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ctz<mode>2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
        (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))
-   (set (cc0)
-       (compare (match_dup 1)
-                (const_int 0)))]
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "ffs $0,$<width>,%1,%0")
+
+(define_insn_and_split "ctz<mode>2_ccz"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+       (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+          (compare:CCZ (match_dup 1)
+                       (const_int 0)))
+      (set (match_dup 0)
+          (ctz:SI (match_dup 1)))])]
+  "")
+
+(define_insn "*ctz<mode>2_ccz"
+  [(set (reg:CCZ VAX_PSL_REGNUM)
+       (compare:CCZ (match_operand:VAXint 1 "general_operand" "nrQT")
+                    (const_int 0)))
+   (set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+       (ctz:SI (match_dup 1)))]
+  "reload_completed"
   "ffs $0,$<width>,%1,%0")
 
 ;; Our FFS hardware instruction supports any field width,
 ;; so handle narrower inputs directly as well.
 (define_peephole2
-  [(set (match_operand:SI 0 "register_operand")
-        (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+          (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
    (parallel
      [(set (match_operand:SI 2 "nonimmediate_operand")
           (ctz:SI (match_dup 0)))
-      (set (cc0)
-          (compare (match_dup 2)
-                   (const_int 0)))])]
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
   "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])"
   [(parallel
      [(set (match_dup 2)
           (ctz:SI (match_dup 1)))
-      (set (cc0)
-          (compare (match_dup 1)
-                   (const_int 0)))])]
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+;; The FFS hardware instruction sets the Z condition code based on
+;; the input field rather than the output operand, so the compare
+;; elimination pass cannot handle it.  Try to get rid of the extra
+;; operation by hand.
+;;
+;; The "ctz<mode>2_ccz" patterns require their `operands[1]' not to
+;; have a mode dependent address, so all we need to verify is that
+;; the two operands are not the same, in which case it's the FFS
+;; output rather than input that condition codes are checked for.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "nonimmediate_operand")
+          (ctz:SI (match_operand:VAXint 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:CCZ VAX_PSL_REGNUM)
+       (compare:CCZ (match_dup 1)
+                    (const_int 0)))]
+  "!rtx_equal_p (operands[0], operands[1])"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+          (compare:CCZ (match_dup 1)
+                       (const_int 0)))
+      (set (match_dup 0)
+          (ctz:SI (match_dup 1)))])]
+  "")
+
+;; This effectively combines the two peepholes above,
+;; matching the sequence produced by `ffs<mode>2'.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+          (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (parallel
+     [(set (match_operand:SI 2 "nonimmediate_operand")
+          (ctz:SI (match_dup 0)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:CCZ VAX_PSL_REGNUM)
+       (compare:CCZ (match_dup 0)
+                    (const_int 0)))]
+  "!rtx_equal_p (operands[0], operands[2])
+   && peep2_reg_dead_p (3, operands[0])"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+          (compare:CCZ (match_dup 1)
+                       (const_int 0)))
+      (set (match_dup 2)
+          (ctz:SI (match_dup 1)))])]
   "")
 
 (define_expand "sync_lock_test_and_set<mode>"
 
   label = gen_label_rtx ();
   emit_move_insn (operands[0], const1_rtx);
-  emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label,
-                                   operands[1]));
+  emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label));
   emit_move_insn (operands[0], const0_rtx);
   emit_label (label);
   DONE;
     FAIL;
 
   label = gen_label_rtx ();
-  emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label,
-                                   operands[0]));
+  emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label));
   emit_label (label);
   DONE;
 }")
     [(set (pc)
          (if_then_else
            (eq (zero_extract:SI
-                 (match_operand:VAXint 0 "any_memory_operand" "<bb_mem>")
+                 (match_operand:VAXint 0 "any_memory_operand" "+<bb_mem>")
                  (const_int 1)
                  (match_operand:SI 1 "general_operand" "nrmT"))
                (const_int bit))
            (label_ref (match_operand 2 "" ""))
            (pc)))
-     (set (zero_extract:SI (match_operand:VAXint 3 "any_memory_operand" "+0")
+     (set (zero_extract:SI (match_dup 0)
                           (const_int 1)
                           (match_dup 1))
          (const_int bit))]