h8300.md (andhi3): If 2nd operand is a CONST_INT that meets the 'J' constraint...
authorJeff Law <law@gcc.gnu.org>
Tue, 16 Apr 1996 22:08:32 +0000 (16:08 -0600)
committerJeff Law <law@gcc.gnu.org>
Tue, 16 Apr 1996 22:08:32 +0000 (16:08 -0600)
        * h8300/h8300.md (andhi3): If 2nd operand is a CONST_INT that
        meets the 'J' constraint, then only two bytes are needed for
        this insn.  Improve code generated for the h8300h when both
        operands are registers.
        (iorhi3, xorhi3): Likewise.  Rework to be nearly identical to andhi3.
        (andsi3): If 2nd operand is a CONST_INT that meets the 'J'
        constraint, then only two bytes are need for this insn.
        Improve code generated for the h8300h regardless of the
        type of the 2nd operand.  Make this pattern work on the h8300 too.
        (iorsi3, xorsi3): Likewise.  Rework to be nearly identical to andsi3.
        (iorqi3_internal): Make this pattern look more like andqi3_internal.
        (one_cmplhi2, one_cmplsi2): Fix length computation for H8300H.

From-SVN: r11830

gcc/config/h8300/h8300.md

index 282710e..4c8f512 100644 (file)
 ;; would be more efficient time and space-wise.  Similar sequences
 ;; can be found using bit-set insns dec, etc
 
+;; Many logical operations should have "bit" variants if only one
+;; bit is going to be operated on.
+
+;; Should be HI & SImode tstXX insns which test one bit using btst.
+
 
 (define_attr "type" "branch,bcs,return,call,arith,move,float,multi"
   (const_string "arith"))
     DONE;
 }")
 
-;; ??? Should have a bclr case here also.
-;; ??? This should be symmetric with iorhi3.
-
 (define_insn "andhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (and:HI (match_operand:HI 1 "register_operand" "%0")
-               (match_operand:HI 2 "nonmemory_operand" "rn")))]
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+       (and:HI (match_operand:HI 1 "register_operand" "%0,0")
+               (match_operand:HI 2 "nonmemory_operand" "J,rn")))]
   ""
   "*
 {
   if (GET_CODE (operands[2]) == CONST_INT)
     {
       int i = INTVAL (operands[2]);
+
       if ((i & 0x00ff) != 0x00ff) 
        output_asm_insn (\"and  %s2,%s0\", operands);
       if ((i & 0xff00) != 0xff00) 
        output_asm_insn (\"and  %t2,%t0\", operands);
       return \"\";
     }
+  if (TARGET_H8300H)
+    return \"and.w %T2,%T0\";
   return \"and %s2,%s0\;and    %t2,%t0;\";
 }"
-  [(set_attr "type" "multi")
-   (set_attr "length" "4")
-   (set_attr "cc" "clobber")])
-
-;; ??? There is an iorsi3 for TARGET_H8300.  Should we have andsi3?
+  [(set_attr "type" "arith,multi")
+   (set_attr "length" "2,4")
+   (set_attr "cc" "clobber,clobber")])
 
 (define_insn "andsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
-               (match_operand:SI 2 "nonmemory_operand" "r,i")))]
-  "TARGET_H8300H"
-  "@
-   and %S2,%S0
-   and %S2,%S0"
-  [(set_attr "type" "arith")
-   (set_attr "length" "4,6")
-   (set_attr "cc" "set")])
+               (match_operand:SI 2 "nonmemory_operand" "J,rn")))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      int i = INTVAL (operands[2]);
+
+      /* ??? If we used e0..e7, then we could sub.w eX,eX to
+        clear the high word if (i & 0xffff0000) == 0.  */
+
+      /* The h8300h can't do byte-wise operations on the
+        upper 16bits of 32bit registers.  However, if
+        those bits aren't going to change, then we can
+        work on the low-order bits.  */
+      if (TARGET_H8300H
+         && (i & 0xffff0000) != 0xffff0000)
+        return \"and.l %S2,%S0\";
+
+      if ((i & 0x000000ff) != 0x000000ff) 
+       output_asm_insn (\"and  %w2,%w0\", operands);
+      if ((i & 0x0000ff00) != 0x0000ff00) 
+       output_asm_insn (\"and  %x2,%x0\", operands);
+      if ((i & 0x00ff0000) != 0x00ff0000) 
+       output_asm_insn (\"and  %y2,%y0\", operands);
+      if ((i & 0xff000000) != 0xff000000) 
+       output_asm_insn (\"and  %z2,%z0\", operands);
+      return \"\";
+    }
+  if (TARGET_H8300H)
+    return \"and.l     %S2,%S0\";
+  return \"and %w2,%w0\;and    %x2,%x0\;and    %y2,%y0\;and    %z2,%z0\;\";
+}"
+  [(set_attr "type" "arith,multi")
+   (set_attr "length" "2,8")
+   (set_attr "cc" "clobber,clobber")])
 
 ;; ----------------------------------------------------------------------
 ;; OR INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_insn "iorqi3_internal"
-  [(set (match_operand:QI 0 "bit_operand" "=U,r")
+  [(set (match_operand:QI 0 "bit_operand" "=r,U")
        (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
-               (match_operand:QI 2 "nonmemory_operand" "P,rn")))]
+               (match_operand:QI 2 "nonmemory_operand" "rn,P")))]
   "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)"
   "@
-   bset        %V2,%R0
-   or  %X2,%X0"
+   or  %X2,%X0
+   bset        %V2,%R0"
   [(set_attr "type" "arith")
-   (set_attr "length" "4,2")
-   (set_attr "cc" "none_0hit,set")])
+   (set_attr "length" "2,4")
+   (set_attr "cc" "set,none_0hit")])
 
 (define_expand "iorqi3"
   [(set (match_operand:QI 0 "bit_operand" "=r,U")
     DONE;
 }")
 
-;; ??? Should have a bset case here also.
-;; ??? This should be symmetric with andhi3.
-
 (define_insn "iorhi3"
   [(set (match_operand:HI 0 "general_operand" "=r,r")
        (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
   ""
   "*
 {
-  if (TARGET_H8300)
-    {
-      if (GET_CODE (operands[2]) == CONST_INT)
-       {
-         int i = INTVAL (operands[2]);
-         if ((i & 0x00ff) != 0) 
-           output_asm_insn (\"or       %s2,%s0\", operands);
-         if ((i & 0xff00) != 0) 
-           output_asm_insn (\"or       %t2,%t0\", operands);
-         return \"\";
-       }
-      return \"or      %s2,%s0\;or     %t2,%t0; %2 or2\";
-    }
-  else
+  if (GET_CODE (operands[2]) == CONST_INT)
     {
-      return \"or      %S2,%S0\";
+      int i = INTVAL (operands[2]);
+
+      if ((i & 0x00ff) != 0) 
+       output_asm_insn (\"or   %s2,%s0\", operands);
+      if ((i & 0xff00) != 0) 
+       output_asm_insn (\"or   %t2,%t0\", operands);
+      return \"\";
     }
+  if (TARGET_H8300H)
+    return \"or.w      %T2,%T0\";
+  return \"or  %s2,%s0\;or     %t2,%t0; %2 or2\";
 }"
-  [(set_attr "type" "multi")
+  [(set_attr "type" "arith,multi")
    (set_attr "length" "2,4")
    (set_attr "cc" "clobber,clobber")])
 
 (define_insn "iorsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (ior:SI (match_operand:SI 1 "register_operand" "%0")
-               (match_operand:SI 2 "nonmemory_operand" "ri")))]
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+       (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
+               (match_operand:SI 2 "nonmemory_operand" "J,rn")))]
   ""
   "*
 {
-  if (TARGET_H8300)
-    {
-      if (GET_CODE (operands[2]) == CONST_INT)
-       {
-         int i = INTVAL (operands[2]);
-         if ((i & 0x000000ff) != 0) 
-           output_asm_insn (\"or       %w2,%w0\", operands);
-         if ((i & 0x0000ff00) != 0) 
-           output_asm_insn (\"or       %x2,%x0\", operands);
-         if ((i & 0x00ff0000) != 0) 
-           output_asm_insn (\"or       %y2,%y0\", operands);
-         if ((i & 0xff000000) != 0) 
-           output_asm_insn (\"or       %z2,%z0\", operands);
-         return \"\";
-       }
-      return \"or      %w2,%w0\;or     %x2,%x0\;or     %y2,%y0\;or     %z2,%z0\;\";
-    }
-  else
+  if (GET_CODE (operands[2]) == CONST_INT)
     {
-      return \"or      %S2,%S0\";
+      int i = INTVAL (operands[2]);
+
+      /* The h8300h can't do byte-wise operations on the
+        upper 16bits of 32bit registers.  However, if
+        those bits aren't going to change, then we can
+        work on the low-order bits.  */
+      if (TARGET_H8300H
+         && (i & 0xffff0000) != 0x00000000)
+        return \"or.l  %S2,%S0\";
+       
+      if ((i & 0x000000ff) != 0) 
+       output_asm_insn (\"or   %w2,%w0\", operands);
+      if ((i & 0x0000ff00) != 0) 
+       output_asm_insn (\"or   %x2,%x0\", operands);
+      if ((i & 0x00ff0000) != 0) 
+       output_asm_insn (\"or   %y2,%y0\", operands);
+      if ((i & 0xff000000) != 0) 
+       output_asm_insn (\"or   %z2,%z0\", operands);
+      return \"\";
     }
+  if (TARGET_H8300H)
+    return \"or.l      %S2,%S0\";
+  return \"or  %w2,%w0\;or     %x2,%x0\;or     %y2,%y0\;or     %z2,%z0\;\";
 }"
-  [(set_attr "type" "multi")
-   (set_attr "length" "8")
-   (set_attr "cc" "clobber")])
+  [(set_attr "type" "arith,multi")
+   (set_attr "length" "2,8")
+   (set_attr "cc" "clobber,clobber")])
 
 ;; ----------------------------------------------------------------------
 ;; XOR INSTRUCTIONS
     DONE;
 }")
 
-;; ??? This should be symmetric with andhi3.
-
 (define_insn "xorhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (xor:HI (match_operand:HI 1 "general_operand" "%0")
-               (match_operand:HI 2 "nonmemory_operand" "rn")))]
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+       (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
+               (match_operand:HI 2 "nonmemory_operand" "J,rn")))]
   ""
   "*
 {
-  if (TARGET_H8300)
-    return \"xor       %s2,%s0\;xor    %t2,%t0\";
-  else
-    return \"xor       %S2,%S0\";
-}"
-  [(set_attr "type" "multi")
-   (set_attr "length" "4")
-   (set_attr "cc" "clobber")])
+  if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      int i = INTVAL (operands[2]);
 
-;; ??? There is an iorsi3 for TARGET_H8300.  Should we have xorsi3?
+      if ((i & 0x00ff) != 0) 
+       output_asm_insn (\"xor  %s2,%s0\", operands);
+      if ((i & 0xff00) != 0) 
+       output_asm_insn (\"xor  %t2,%t0\", operands);
+      return \"\";
+    }
+  if (TARGET_H8300H)
+    return \"xor.w     %T2,%T0\";
+  return \"xor %s2,%s0\;xor    %t2,%t0\";
+}"
+  [(set_attr "type" "arith,multi")
+   (set_attr "length" "2,4")
+   (set_attr "cc" "clobber,clobber")])
 
 (define_insn "xorsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
        (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
-               (match_operand:SI 2 "nonmemory_operand" "r,i")))]
-  "TARGET_H8300H"
-  "@
-   xor %S2,%S0
-   xor %S2,%S0"
-  [(set_attr "type" "arith")
-   (set_attr "length" "4,6")
-   (set_attr "cc" "set")])
+               (match_operand:SI 2 "nonmemory_operand" "J,rn")))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      int i = INTVAL (operands[2]);
+
+      /* The h8300h can't do byte-wise operations on the
+        upper 16bits of 32bit registers.  However, if
+        those bits aren't going to change, then we can
+        work on the low-order bits.  */
+      if (TARGET_H8300H
+         && (i & 0xffff0000) != 0x00000000)
+        return \"xor.l %S2,%S0\";
+
+      if ((i & 0x000000ff) != 0) 
+       output_asm_insn (\"xor  %w2,%w0\", operands);
+      if ((i & 0x0000ff00) != 0) 
+       output_asm_insn (\"xor  %x2,%x0\", operands);
+      if ((i & 0x00ff0000) != 0) 
+       output_asm_insn (\"xor  %y2,%y0\", operands);
+      if ((i & 0xff000000) != 0) 
+       output_asm_insn (\"xor  %z2,%z0\", operands);
+      return \"\";
+    }
+  if (TARGET_H8300H)
+    return \"xor.l     %S2,%S0\";
+  return \"xor %w2,%w0\;xor    %x2,%x0\;xor    %y2,%y0\;xor    %z2,%z0\;\";
+}"
+  [(set_attr "type" "arith,multi")
+   (set_attr "length" "2,8")
+   (set_attr "cc" "clobber,clobber")])
 \f
 ;; ----------------------------------------------------------------------
 ;; NEGATION INSTRUCTIONS
     return \"not       %T0\";
 }"
   [(set_attr "type" "arith")
-   (set_attr "length" "4")
-   (set_attr "cc" "clobber")])
+   (set_attr "cc" "clobber")
+   (set (attr "length")
+       (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0))
+                     (const_int 8)
+                     (const_int 2)))])
 
 (define_insn "one_cmplsi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
    (set (attr "length")
        (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0))
                      (const_int 8)
-                     (const_int 4)))])
+                     (const_int 2)))])
                        
 \f
 ;; ----------------------------------------------------------------------