OSDN Git Service

* i386.md (ffssi, ffshi): Rewrite as define_expands.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 4 Apr 1998 19:57:26 +0000 (19:57 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 4 Apr 1998 19:57:26 +0000 (19:57 +0000)
(ffssi_1, ffshi_1): New (unspec [] 5) support patterns.
* i386.c (notice_update_cc): Recognize unspec 5.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@18999 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index fc20ed2..f7bb7c1 100644 (file)
@@ -1,3 +1,9 @@
+Sat Apr  4 19:08:37 1998  Richard Henderson  <rth@cygnus.com>
+
+       * i386.md (ffssi, ffshi): Rewrite as define_expands.
+       (ffssi_1, ffshi_1): New (unspec [] 5) support patterns.
+       * i386.c (notice_update_cc): Recognize unspec 5.
+
 Sat Apr  4 18:07:16 1998  David Mosberger-Tang  (davidm@mostang.com)
 
        * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Accept '(' for s/sv/svi.
index 9f565ae..1232b4a 100644 (file)
@@ -3646,6 +3646,18 @@ notice_update_cc (exp)
            cc_status.value2 = SET_DEST (exp);
            break;
 
+           /* This is the bsf pattern used by ffs.  */
+         case UNSPEC:
+           if (XINT (SET_SRC (exp), 1) == 5)
+             {
+               /* Only the Z flag is defined after bsf.  */
+               cc_status.flags
+                 = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
+               cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
+               break;
+             }
+           /* FALLTHRU */
+
          default:
            CC_STATUS_INIT;
          }
index ea6a9c8..3a88982 100644 (file)
@@ -63,6 +63,7 @@
 ;; 4  This is the source of a fake SET of the frame pointer which is used to
 ;;    prevent insns referencing it being scheduled across the initial
 ;;    decrement of the stack pointer.
+;; 5  This is a `bsf' operation.
 \f
 ;; This shadows the processor_type enumeration, so changes must be made
 ;; to i386.h at the same time.
@@ -6963,103 +6964,63 @@ byte_xor_operation:
 }")
 
 \f
-(define_expand "ffssi2"
-  [(set (match_dup 2)
-       (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
-                (const_int -1)))
-   (set (match_operand:SI 0 "general_operand" "")
-       (plus:SI (match_dup 2) (const_int 1)))]
-  ""
-  "operands[2] = gen_reg_rtx (SImode);")
-
 ;; Note, you cannot optimize away the branch following the bsfl by assuming
 ;; that the destination is not modified if the input is 0, since not all
 ;; x86 implementations do this.
 
-(define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=&r")
-       (plus:SI (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
-                (const_int -1)))]
+(define_expand "ffssi2"
+  [(set (match_operand:SI 0 "general_operand" "") 
+       (ffs:SI (match_operand:SI 1 "general_operand" "")))]
   ""
-  "*
+  "
 {
-  rtx xops[3];
-  static int ffssi_label_number;
-  char buffer[30];
+  rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode);
 
-  xops[0] = operands[0];
-  xops[1] = operands[1];
-  xops[2] = constm1_rtx;
-  output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
-#ifdef LOCAL_LABEL_PREFIX
-  sprintf (buffer, \"jnz %sLFFSSI%d\",
-          LOCAL_LABEL_PREFIX, ffssi_label_number);
-#else
-  sprintf (buffer, \"jnz %sLFFSSI%d\",
-          \"\", ffssi_label_number);
-#endif
-  output_asm_insn (buffer, xops);
-  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
-#ifdef LOCAL_LABEL_PREFIX
-  sprintf (buffer, \"%sLFFSSI%d:\",
-          LOCAL_LABEL_PREFIX, ffssi_label_number);
-#else
-  sprintf (buffer, \"%sLFFSSI%d:\",
-          \"\", ffssi_label_number);
-#endif
-  output_asm_insn (buffer, xops);
+  emit_insn (gen_ffssi_1 (temp, operands[1]));
+  emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0);
+  emit_jump_insn (gen_bne (label));
+  emit_move_insn (temp, constm1_rtx);
+  emit_label (label);
+  temp = expand_binop (SImode, add_optab, temp, const1_rtx,
+                      operands[0], 0, OPTAB_WIDEN);
 
-  ffssi_label_number++;
-  CC_STATUS_INIT;
-  return \"\";
+  if (temp != operands[0])
+    emit_move_insn (operands[0], temp);
+  DONE;  
 }")
 
-(define_expand "ffshi2"
-  [(set (match_dup 2)
-       (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
-                (const_int -1)))
-   (set (match_operand:HI 0 "general_operand" "")
-       (plus:HI (match_dup 2) (const_int 1)))]
+(define_insn "ffssi_1"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
   ""
-  "operands[2] = gen_reg_rtx (HImode);")
+  "* return AS2 (bsf%L0,%1,%0);")
 
-(define_insn ""
-  [(set (match_operand:HI 0 "register_operand" "=&r")
-       (plus:HI (ffs:HI (match_operand:SI 1 "nonimmediate_operand" "rm"))
-                (const_int -1)))]
+(define_expand "ffshi2"
+  [(set (match_operand:SI 0 "general_operand" "") 
+       (ffs:HI (match_operand:HI 1 "general_operand" "")))]
   ""
-  "*
+  "
 {
-  rtx xops[3];
-  static int ffshi_label_number;
-  char buffer[30];
+  rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode);
 
-  xops[0] = operands[0];
-  xops[1] = operands[1];
-  xops[2] = constm1_rtx;
-  output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
-#ifdef LOCAL_LABEL_PREFIX
-  sprintf (buffer, \"jnz %sLFFSHI%d\",
-          LOCAL_LABEL_PREFIX, ffshi_label_number);
-#else
-  sprintf (buffer, \"jnz %sLFFSHI%d\",
-          \"\", ffshi_label_number);
-#endif
-  output_asm_insn (buffer, xops);
-  output_asm_insn (AS2 (mov%W0,%2,%0), xops);
-#ifdef LOCAL_LABEL_PREFIX
-  sprintf (buffer, \"%sLFFSHI%d:\",
-          LOCAL_LABEL_PREFIX, ffshi_label_number);
-#else
-  sprintf (buffer, \"%sLFFSHI%d:\",
-          \"\", ffshi_label_number);
-#endif
-  output_asm_insn (buffer, xops);
+  emit_insn (gen_ffshi_1 (temp, operands[1]));
+  emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0);
+  emit_jump_insn (gen_bne (label));
+  emit_move_insn (temp, constm1_rtx);
+  emit_label (label);
+  temp = expand_binop (HImode, add_optab, temp, const1_rtx,
+                      operands[0], 0, OPTAB_WIDEN);
 
-  ffshi_label_number++;
-  CC_STATUS_INIT;
-  return \"\";
+  if (temp != operands[0])
+    emit_move_insn (operands[0], temp);
+  DONE;  
 }")
+
+(define_insn "ffshi_1"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+       (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
+  ""
+  "* return AS2 (bsf%W0,%1,%0);")
 \f
 ;; These patterns match the binary 387 instructions for addM3, subM3,
 ;; mulM3 and divM3.  There are three patterns for each of DFmode and