alpha.c (alpha_split_tfmode_frobsign): New.

* config/alpha/alpha.c (alpha_split_tfmode_frobsign): New.
        * config/alpha/alpha-protos.h: Declare it.
        * config/alpha/alpha.md (abstf_internal): Use it.
        (negtf_internal): Likewise.
        (andnotdi3): Unstar the name.
        (movtf_internal): Add o/G alternative.

From-SVN: r37634
This commit is contained in:
Richard Henderson 2000-11-21 16:59:12 -08:00 committed by Richard Henderson
parent dfc5597093
commit f940c352de
4 changed files with 67 additions and 49 deletions

View File

@ -1,3 +1,12 @@
2000-11-21 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (alpha_split_tfmode_frobsign): New.
* config/alpha/alpha-protos.h: Declare it.
* config/alpha/alpha.md (abstf_internal): Use it.
(negtf_internal): Likewise.
(andnotdi3): Unstar the name.
(movtf_internal): Add o/G alternative.
2000-11-21 Zack Weinberg <zack@wolery.stanford.edu>
* stringpool.c (stringpool_statistics): Also report number and

View File

@ -90,6 +90,8 @@ extern int alpha_split_conditional_move PARAMS ((enum rtx_code, rtx, rtx,
extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[]));
extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[]));
extern void alpha_split_tfmode_pair PARAMS ((rtx[]));
extern void alpha_split_tfmode_frobsign PARAMS ((rtx[],
rtx (*)(rtx, rtx, rtx)));
extern void alpha_expand_unaligned_load PARAMS ((rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT, int));
extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,

View File

@ -2357,6 +2357,10 @@ alpha_emit_xfloating_cvt (code, operands)
operands[1]));
}
/* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
OP[0] into OP[0,1]. Naturally, output operand ordering is
little-endian. */
void
alpha_split_tfmode_pair (operands)
rtx operands[4];
@ -2391,6 +2395,52 @@ alpha_split_tfmode_pair (operands)
else
abort ();
}
/* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
op2 is a register containing the sign bit, operation is the
logical operation to be performed. */
void
alpha_split_tfmode_frobsign (operands, operation)
rtx operands[3];
rtx (*operation) PARAMS ((rtx, rtx, rtx));
{
rtx high_bit = operands[2];
rtx scratch;
int move;
alpha_split_tfmode_pair (operands);
/* Detect three flavours of operand overlap. */
move = 1;
if (rtx_equal_p (operands[0], operands[2]))
move = 0;
else if (rtx_equal_p (operands[1], operands[2]))
{
if (rtx_equal_p (operands[0], high_bit))
move = 2;
else
move = -1;
}
if (move < 0)
emit_move_insn (operands[0], operands[2]);
/* ??? If the destination overlaps both source tf and high_bit, then
assume source tf is dead in its entirety and use the other half
for a scratch register. Otherwise "scratch" is just the proper
destination register. */
scratch = operands[move < 2 ? 1 : 3];
emit_insn ((*operation) (scratch, high_bit, operands[3]));
if (move > 0)
{
emit_move_insn (operands[0], operands[2]);
if (move > 1)
emit_move_insn (operands[1], scratch);
}
}
/* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
unaligned data:

View File

@ -1187,7 +1187,7 @@
"zapnot %1,15,%0"
[(set_attr "type" "shift")])
(define_insn "*andnot"
(define_insn "andnotdi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
@ -1876,35 +1876,12 @@
(define_insn_and_split "*abstf_internal"
[(set (match_operand:TF 0 "register_operand" "=r")
(abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
(use (match_operand:DI 2 "register_operand" "=r"))]
(use (match_operand:DI 2 "register_operand" "r"))]
"TARGET_HAS_XFLOATING_LIBS"
"#"
"&& reload_completed"
[(const_int 0)]
"
{
int move;
rtx tmp;
alpha_split_tfmode_pair (operands);
move = 1;
if (rtx_equal_p (operands[0], operands[2]))
move = 0;
else if (rtx_equal_p (operands[1], operands[2]))
move = -1;
if (move < 0)
emit_move_insn (operands[0], operands[2]);
tmp = gen_rtx_NOT (DImode, operands[4]);
tmp = gen_rtx_AND (DImode, tmp, operands[3]);
emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
if (move > 0)
emit_move_insn (operands[0], operands[2]);
DONE;
}")
"alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
(define_insn "negsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
@ -1937,32 +1914,12 @@
(define_insn_and_split "*negtf_internal"
[(set (match_operand:TF 0 "register_operand" "=r")
(neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
(use (match_operand:DI 2 "register_operand" "=r"))]
(use (match_operand:DI 2 "register_operand" "r"))]
"TARGET_HAS_XFLOATING_LIBS"
"#"
"&& reload_completed"
[(const_int 0)]
"
{
int move;
alpha_split_tfmode_pair (operands);
move = 1;
if (rtx_equal_p (operands[0], operands[2]))
move = 0;
else if (rtx_equal_p (operands[1], operands[2]))
move = -1;
if (move < 0)
emit_move_insn (operands[0], operands[2]);
emit_insn (gen_xordi3 (operands[1], operands[3], operands[4]));
if (move > 0)
emit_move_insn (operands[0], operands[2]);
DONE;
}")
"alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
(define_insn "*addsf_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
@ -4595,7 +4552,7 @@
(define_insn_and_split "*movtf_internal"
[(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
(match_operand:TF 1 "input_operand" "roG,r"))]
(match_operand:TF 1 "input_operand" "roG,rG"))]
"register_operand (operands[0], TFmode)
|| reg_or_fp0_operand (operands[1], TFmode)"
"#"