mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-13 09:04:31 +08:00
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
This commit is contained in:
parent
e06e4d4534
commit
ce1938523b
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_insn "ffssi_1"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))]
|
||||
""
|
||||
"* return AS2 (bsf%L0,%1,%0);")
|
||||
|
||||
(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)))]
|
||||
[(set (match_operand:SI 0 "general_operand" "")
|
||||
(ffs:HI (match_operand:HI 1 "general_operand" "")))]
|
||||
""
|
||||
"operands[2] = gen_reg_rtx (HImode);")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=&r")
|
||||
(plus:HI (ffs:HI (match_operand:SI 1 "nonimmediate_operand" "rm"))
|
||||
(const_int -1)))]
|
||||
""
|
||||
"*
|
||||
"
|
||||
{
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user