diff options
author | Richard Henderson <rth@cygnus.com> | 1998-04-04 11:57:26 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1998-04-04 11:57:26 -0800 |
commit | ce1938523b2a93c11c46f6672c9b35f6b1d145d6 (patch) | |
tree | 2b2d25d4c661f6316c182c704ead16573b8c07ae /gcc | |
parent | e06e4d453410364f49563827274f50e46d8d64dc (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 12 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 121 |
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 |