aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1998-04-04 11:57:26 -0800
committerRichard Henderson <rth@gcc.gnu.org>1998-04-04 11:57:26 -0800
commitce1938523b2a93c11c46f6672c9b35f6b1d145d6 (patch)
tree2b2d25d4c661f6316c182c704ead16573b8c07ae
parente06e4d453410364f49563827274f50e46d8d64dc (diff)
downloadgcc-ce1938523b2a93c11c46f6672c9b35f6b1d145d6.zip
gcc-ce1938523b2a93c11c46f6672c9b35f6b1d145d6.tar.gz
gcc-ce1938523b2a93c11c46f6672c9b35f6b1d145d6.tar.bz2
i386.md (ffssi, ffshi): Rewrite as define_expands.
* 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. From-SVN: r18999
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c12
-rw-r--r--gcc/config/i386/i386.md121
3 files changed, 59 insertions, 80 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc20ed2..f7bb7c1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9f565ae..1232b4a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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;
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ea6a9c8..3a88982 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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.
;; 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:
}")
-(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);")
;; These patterns match the binary 387 instructions for addM3, subM3,
;; mulM3 and divM3. There are three patterns for each of DFmode and