]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix minor bugs in H8 port logical ops. Prepare for more compare/test removal
authorJeff Law <jeffreyalaw@gmail.com>
Wed, 2 Jun 2021 04:56:38 +0000 (00:56 -0400)
committerJeff Law <jeffreyalaw@gmail.com>
Wed, 2 Jun 2021 05:06:35 +0000 (01:06 -0400)
gcc/
* config/h8300/h8300-protos.h (compute_a_shift_length): Drop unused
argument from prototype.
(output_logical_op): Add rtx_code argument.
(compute_logical_op_length): Likewise.
* config/h8300/h8300.c (h8300_and_costs): Pass additional argument
to compute_a_shift_length.
(output_logical_op); New argument with the rtx code rather than
extracting it from an operand.  Handle QImode too.
(compute_logical_op_length): Similary.
(compute_a_shift_length): Drop unused argument.
* config/h8300/h8300.md (logicals): New code iterator.
* config/h8300/logical.md (<code><mode>3 expander): Combine
the "and" expander with the "ior"/"xor" expander.
(bclr<mode>msx): Combine the QI/HI mode patterns.
(<logical><mode>3 insns): Use code iterator rather than match_operator.
Handle QImode as well.   Update call to output_logical_op and
compute_logical_op_length to pass in rtx_code
Fix split condition on all define_insn_and_split patterns.
(one_cmpl<mode>2<cczn>): Use <cczn> to support both clobbering
the flags and setting ZN via existing define_subst.
* config/h8300/shiftrotate.md: Drop unused argument from
calls to compute_a_shift_length.

Signed-off-by: Jeff Law <jeffreyalaw@gmail.com>
gcc/config/h8300/h8300-protos.h
gcc/config/h8300/h8300.c
gcc/config/h8300/h8300.md
gcc/config/h8300/logical.md
gcc/config/h8300/shiftrotate.md

index 45e7dec3c7dc7ea8f29eb0923910ab7850d7721b..af653292a9db0ca323806050984f14c577bd7108 100644 (file)
@@ -29,16 +29,15 @@ extern unsigned int compute_mov_length (rtx *);
 extern const char *output_plussi (rtx *, bool);
 extern unsigned int compute_plussi_length (rtx *, bool);
 extern const char *output_a_shift (rtx *);
-extern unsigned int compute_a_shift_length (rtx, rtx *);
+extern unsigned int compute_a_shift_length (rtx *);
 extern const char *output_a_rotate (enum rtx_code, rtx *);
 extern unsigned int compute_a_rotate_length (rtx *);
 extern const char *output_simode_bld (int, rtx[]);
 extern void final_prescan_insn (rtx_insn *, rtx *, int);
 extern int h8300_expand_movsi (rtx[]);
 extern machine_mode  h8300_select_cc_mode (RTX_CODE, rtx, rtx);
-extern const char *output_logical_op (machine_mode, rtx *);
-extern unsigned int compute_logical_op_length (machine_mode,
-                                              rtx *);
+extern const char *output_logical_op (machine_mode, rtx_code code, rtx *);
+extern unsigned int compute_logical_op_length (machine_mode, rtx_code, rtx *);
 
 extern int compute_logical_op_cc (machine_mode, rtx *);
 extern int compute_a_shift_cc (rtx, rtx *);
index ba2b9daf4871098d1feba0501919961c4c551db1..ef947aa468ad108a3ae092de94ef84289bdada4a 100644 (file)
@@ -1100,7 +1100,7 @@ h8300_and_costs (rtx x)
   operands[1] = XEXP (x, 0);
   operands[2] = XEXP (x, 1);
   operands[3] = x;
-  return compute_logical_op_length (GET_MODE (x), operands) / 2;
+  return compute_logical_op_length (GET_MODE (x), AND, operands) / 2;
 }
 
 /* Compute the cost of a shift insn.  */
@@ -1119,7 +1119,7 @@ h8300_shift_costs (rtx x)
   operands[1] = NULL;
   operands[2] = XEXP (x, 1);
   operands[3] = x;
-  return compute_a_shift_length (NULL, operands) / 2;
+  return compute_a_shift_length (operands) / 2;
 }
 
 /* Worker function for TARGET_RTX_COSTS.  */
@@ -2879,10 +2879,8 @@ compute_plussi_cc (rtx *operands)
 /* Output a logical insn.  */
 
 const char *
-output_logical_op (machine_mode mode, rtx *operands)
+output_logical_op (machine_mode mode, rtx_code code, rtx *operands)
 {
-  /* Figure out the logical op that we need to perform.  */
-  enum rtx_code code = GET_CODE (operands[3]);
   /* Pretend that every byte is affected if both operands are registers.  */
   const unsigned HOST_WIDE_INT intval =
     (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
@@ -2923,6 +2921,10 @@ output_logical_op (machine_mode mode, rtx *operands)
 
   switch (mode)
     {
+    case E_QImode:
+      sprintf (insn_buf, "%s.b\t%%X2,%%X0", opname);
+      output_asm_insn (insn_buf, operands);
+      break;
     case E_HImode:
       /* First, see if we can finish with one insn.  */
       if (b0 != 0 && b1 != 0)
@@ -3033,10 +3035,8 @@ output_logical_op (machine_mode mode, rtx *operands)
 /* Compute the length of a logical insn.  */
 
 unsigned int
-compute_logical_op_length (machine_mode mode, rtx *operands)
+compute_logical_op_length (machine_mode mode, rtx_code code, rtx *operands)
 {
-  /* Figure out the logical op that we need to perform.  */
-  enum rtx_code code = GET_CODE (operands[3]);
   /* Pretend that every byte is affected if both operands are registers.  */
   const unsigned HOST_WIDE_INT intval =
     (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
@@ -3061,6 +3061,9 @@ compute_logical_op_length (machine_mode mode, rtx *operands)
 
   switch (mode)
     {
+    case E_QImode:
+      return 2;
+
     case E_HImode:
       /* First, see if we can finish with one insn.  */
       if (b0 != 0 && b1 != 0)
@@ -4189,7 +4192,7 @@ h8300_asm_insn_count (const char *templ)
 /* Compute the length of a shift insn.  */
 
 unsigned int
-compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
+compute_a_shift_length (rtx *operands)
 {
   rtx shift = operands[3];
   machine_mode mode = GET_MODE (shift);
index 9a42547a92c926506753c41d059a59f93e513c06..e596987a6a613a03d10a2feea1f25706d99cb9fd 100644 (file)
 
 (define_code_iterator shifts [ashift ashiftrt lshiftrt])
 
+(define_code_iterator logicals [ior xor and])
+
 (define_code_iterator ors [ior xor])
 \f
 (include "movepush.md")
index eb99c20b55d6e69eb65971fecbcafe04be6aa168..d778d24c580f757c51ff22d24427c83a07e89139 100644 (file)
@@ -1,11 +1,20 @@
+;; Generic for binary logicals across the supported integer modes
+(define_expand "<code><mode>3"
+  [(set (match_operand:QHSI 0 "register_operand" "")
+       (logicals:QHSI (match_operand:QHSI 1 "register_operand" "")
+                      (match_operand:QHSI 2 "h8300_src_operand" "")))]
+  ""
+  "")
+
+;; There's a ton of cleanup to do from here below.
 ;; ----------------------------------------------------------------------
 ;; AND INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "bclrqi_msx"
-  [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
-       (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
-               (match_operand:QI 2 "single_zero_operand" "Y0")))]
+(define_insn "bclr<mode>_msx"
+  [(set (match_operand:QHI 0 "bit_register_indirect_operand" "=WU")
+       (and:QHI (match_operand:QHI 1 "bit_register_indirect_operand" "%0")
+                (match_operand:QHI 2 "single_zero_operand" "Y0")))]
   "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
   "bclr\\t%W2,%0"
   [(set_attr "length" "8")])
     operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
   })
 
-(define_insn "bclrhi_msx"
-  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
-       (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
-               (match_operand:HI 2 "single_zero_operand" "Y0")))]
-  "TARGET_H8300SX"
-  "bclr\\t%W2,%0"
-  [(set_attr "length" "8")])
-
 (define_insn_and_split "*andqi3_2"
   [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
        (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
                (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
   "TARGET_H8300SX"
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
              (clobber (reg:CC CC_REG))])])
 
@@ -62,7 +63,7 @@
   "register_operand (operands[0], QImode)
    || single_zero_operand (operands[2], QImode)"
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
              (clobber (reg:CC CC_REG))])])
 
    and  %X2,%X0"
   [(set_attr "length" "2,8")])
 
-(define_expand "and<mode>3"
-  [(set (match_operand:QHSI 0 "register_operand" "")
-       (and:QHSI (match_operand:QHSI 1 "register_operand" "")
-                 (match_operand:QHSI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
 (define_insn_and_split "*andor<mode>3"
   [(set (match_operand:QHSI 0 "register_operand" "=r")
        (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
@@ -95,7 +89,7 @@
     || (<MODE>mode == SImode
        && (INTVAL (operands[3]) & 0xffff) != 0))"
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(parallel [(set (match_dup 0) (ior:QHSI (and:QHSI (match_dup 2)
                                                     (match_dup 3))
                                           (match_dup 1)))
                (match_operand:SI 1 "register_operand" "0")))]
   ""
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(parallel [(set (match_dup 0) (ior:SI (and:SI (ashift:SI (match_dup 2)
                                                            (const_int 8))
                                                 (const_int 65280))
   "TARGET_H8300SX || register_operand (operands[0], QImode)
    || single_one_operand (operands[2], QImode)"
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2)))
              (clobber (reg:CC CC_REG))])])
 
   [(set_attr "length" "8,*")
    (set_attr "length_table" "*,logicb")])
 
-(define_expand "<code><mode>3"
-  [(set (match_operand:QHSI 0 "register_operand" "")
-       (ors:QHSI (match_operand:QHSI 1 "register_operand" "")
-                 (match_operand:QHSI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
 ;; ----------------------------------------------------------------------
 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
 ;; ----------------------------------------------------------------------
 
 (define_insn_and_split "*logical<mode>3"
-  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
-       (match_operator:HSI 3 "bit_operator"
-         [(match_operand:HSI 1 "h8300_dst_operand" "%0")
-          (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
+  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+       (logicals:QHSI
+         (match_operand:QHSI 1 "h8300_dst_operand" "%0")
+         (match_operand:QHSI 2 "h8300_src_operand" "rQi")))]
   "h8300_operands_match_p (operands)"
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(parallel [(set (match_dup 0)
                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
              (clobber (reg:CC CC_REG))])])
 
-(define_insn "*logical<mode>3_clobber_flags"
-  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
-       (match_operator:HSI 3 "bit_operator"
-         [(match_operand:HSI 1 "h8300_dst_operand" "%0")
-          (match_operand:HSI 2 "h8300_src_operand" "rQi")]))
+(define_insn "*<code><mode>3_clobber_flags"
+  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+       (logicals:QHSI
+         (match_operand:QHSI 1 "h8300_dst_operand" "%0")
+         (match_operand:QHSI 2 "h8300_src_operand" "rQi")))
    (clobber (reg:CC CC_REG))]
   "h8300_operands_match_p (operands)"
-  { return output_logical_op (<MODE>mode, operands); }
+  { return output_logical_op (<MODE>mode, <CODE>, operands); }
   [(set (attr "length")
-       (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))])
+       (symbol_ref "compute_logical_op_length (<MODE>mode, <CODE>, operands)"))])
 
 \f
 ;; ----------------------------------------------------------------------
        (not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
   ""
   "#"
-  "reload_completed"
+  "&& reload_completed"
   [(parallel [(set (match_dup 0) (not:QHSI (match_dup 1)))
              (clobber (reg:CC CC_REG))])])
 
-(define_insn "one_cmpl<mode>2_clobber_flags"
+(define_insn "one_cmpl<mode>2_<cczn>"
   [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
        (not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
    (clobber (reg:CC CC_REG))]
index f1c86f7da1c489064d2f8bb5ffdc25c8674fb933..4bf8fe14e0ba05f2939e8c1c2f0633c45e728650 100644 (file)
   return output_a_shift (operands);
 }
   [(set (attr "length")
-       (symbol_ref "compute_a_shift_length (insn, operands)"))])
+       (symbol_ref "compute_a_shift_length (operands)"))])
 
 (define_insn_and_split "*shiftqi_noscratch"
   [(set (match_operand:QI 0 "register_operand" "=r,r")
   return output_a_shift (operands);
 }
   [(set (attr "length")
-       (symbol_ref "compute_a_shift_length (insn, operands)"))])
+       (symbol_ref "compute_a_shift_length (operands)"))])
 
 (define_insn_and_split "*shifthi"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
   return output_a_shift (operands);
 }
   [(set (attr "length")
-       (symbol_ref "compute_a_shift_length (insn, operands)"))])
+       (symbol_ref "compute_a_shift_length (operands)"))])
 
 (define_insn_and_split "*shifthi_noscratch"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
   return output_a_shift (operands);
 }
   [(set (attr "length")
-       (symbol_ref "compute_a_shift_length (insn, operands)"))])
+       (symbol_ref "compute_a_shift_length (operands)"))])
 
 (define_insn_and_split "*shiftsi"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
   return output_a_shift (operands);
 }
   [(set (attr "length")
-       (symbol_ref "compute_a_shift_length (insn, operands)"))])
+       (symbol_ref "compute_a_shift_length (operands)"))])
 
 (define_insn_and_split "*shiftsi_noscratch"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
   return output_a_shift (operands);
 }
   [(set (attr "length")
-       (symbol_ref "compute_a_shift_length (insn, operands)"))])
+       (symbol_ref "compute_a_shift_length (operands)"))])
 
 ;; Split a variable shift into a loop.  If the register containing
 ;; the shift count dies, then we just use that register.