xtensa-protos.h (smalloffset_double_mem_p): Delete.

* config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete.
        (xtensa_split_operand_pair): New proto.
        * config/xtensa/xtensa.c (move_operand): Handle DFmode and DImode.
        (smalloffset_double_mem_p): Delete.
        (gen_float_relational, printx, print_operand, xtensa_va_arg):
        Fix whitespace.
        (xtensa_split_operand_pair): New.
        (xtensa_dbx_register_number): Fix formatting.
        * config/xtensa/xtensa.h (EXTRA_CONSTRAINT): Remove 'S' constraint.
        * config/xtensa/xtensa.md (movdi, movdf): Force constants to memory
        instead of splitting them into single-word moves.  Remove unnecessary
        checks for reload_in_progress and reload_completed.
        (movdi_internal, movdf_internal): Change to post-reload split patterns.
        Add constraints to allow constant operands.
        (movsf_internal): Allow CONST_INT operands.

From-SVN: r67215
This commit is contained in:
Bob Wilson 2003-05-29 00:08:36 +00:00 committed by Bob Wilson
parent 358bdeeec7
commit 633e4eb4ae
5 changed files with 156 additions and 181 deletions

View file

@ -1,3 +1,21 @@
2003-05-28 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete.
(xtensa_split_operand_pair): New proto.
* config/xtensa/xtensa.c (move_operand): Handle DFmode and DImode.
(smalloffset_double_mem_p): Delete.
(gen_float_relational, printx, print_operand, xtensa_va_arg):
Fix whitespace.
(xtensa_split_operand_pair): New.
(xtensa_dbx_register_number): Fix formatting.
* config/xtensa/xtensa.h (EXTRA_CONSTRAINT): Remove 'S' constraint.
* config/xtensa/xtensa.md (movdi, movdf): Force constants to memory
instead of splitting them into single-word moves. Remove unnecessary
checks for reload_in_progress and reload_completed.
(movdi_internal, movdf_internal): Change to post-reload split patterns.
Add constraints to allow constant operands.
(movsf_internal): Allow CONST_INT operands.
2003-05-27 Danny Smith <dannysmith@users.sourceforge.net>
* config.gcc (i[34567]86-*-mingw32*): Add host makefile

View file

@ -54,7 +54,6 @@ extern int ubranch_operand PARAMS ((rtx, enum machine_mode));
extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
extern int move_operand PARAMS ((rtx, enum machine_mode));
extern int smalloffset_mem_p PARAMS ((rtx));
extern int smalloffset_double_mem_p PARAMS ((rtx));
extern int constantpool_address_p PARAMS ((rtx));
extern int constantpool_mem_p PARAMS ((rtx));
extern int const_float_1_operand PARAMS ((rtx, enum machine_mode));
@ -67,6 +66,7 @@ extern void xtensa_expand_conditional_branch PARAMS ((rtx *, enum rtx_code));
extern int xtensa_expand_conditional_move PARAMS ((rtx *, int));
extern int xtensa_expand_scc PARAMS ((rtx *));
extern int xtensa_expand_block_move PARAMS ((rtx *));
extern void xtensa_split_operand_pair PARAMS ((rtx *, enum machine_mode));
extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode));
extern bool xtensa_copy_incoming_a7 PARAMS ((rtx *, enum machine_mode));
extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int));

View file

@ -599,9 +599,20 @@ move_operand (op, mode)
|| memory_operand (op, mode))
return TRUE;
if (mode == SFmode)
switch (mode)
{
case DFmode:
case SFmode:
return TARGET_CONST16 && CONSTANT_P (op);
case DImode:
case SImode:
if (TARGET_CONST16)
return CONSTANT_P (op);
/* fall through */
case HImode:
case QImode:
/* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
result in 0/1. */
if (GET_CODE (op) == CONSTANT_P_RTX)
@ -609,9 +620,11 @@ move_operand (op, mode)
if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
return TRUE;
break;
if (mode == SImode)
return TARGET_CONST16 && CONSTANT_P (op);
default:
break;
}
return FALSE;
}
@ -640,16 +653,6 @@ smalloffset_mem_p (op)
}
int
smalloffset_double_mem_p (op)
rtx op;
{
if (!smalloffset_mem_p (op))
return FALSE;
return smalloffset_mem_p (adjust_address (op, GET_MODE (op), 4));
}
int
constantpool_address_p (addr)
rtx addr;
@ -1207,6 +1210,53 @@ xtensa_expand_scc (operands)
}
/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
for the output, i.e., the input operands are twice as big as MODE. */
void
xtensa_split_operand_pair (operands, mode)
rtx operands[4];
enum machine_mode mode;
{
switch (GET_CODE (operands[1]))
{
case REG:
operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
break;
case MEM:
operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
operands[2] = adjust_address (operands[1], mode, 0);
break;
case CONST_INT:
case CONST_DOUBLE:
split_double (operands[1], &operands[2], &operands[3]);
break;
default:
abort ();
}
switch (GET_CODE (operands[0]))
{
case REG:
operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
break;
case MEM:
operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
operands[0] = adjust_address (operands[0], mode, 0);
break;
default:
abort ();
}
}
/* Emit insns to move operands[1] into operands[0].
Return 1 if we have written out everything that needs to be done to
do the move. Otherwise, return 0 and the caller will emit the move
@ -1659,15 +1709,18 @@ xtensa_dbx_register_number (regno)
{
int first = -1;
if (GP_REG_P (regno)) {
if (GP_REG_P (regno))
{
regno -= GP_REG_FIRST;
first = 0;
}
else if (BR_REG_P (regno)) {
else if (BR_REG_P (regno))
{
regno -= BR_REG_FIRST;
first = 16;
}
else if (FP_REG_P (regno)) {
else if (FP_REG_P (regno))
{
regno -= FP_REG_FIRST;
/* The current numbering convention is that TIE registers are
numbered in libcc order beginning with 256. We can't guarantee

View file

@ -691,7 +691,6 @@ extern enum reg_class xtensa_char_to_class[256];
operand types.
R = memory that can be accessed with a 4-bit unsigned offset
S = memory where the second word can be addressed with a 4-bit offset
T = memory in a constant pool (addressable with a pc-relative load)
U = memory *NOT* in a constant pool
@ -713,7 +712,6 @@ extern enum reg_class xtensa_char_to_class[256];
&& reload_in_progress && GET_CODE (OP) == REG \
&& REGNO (OP) >= FIRST_PSEUDO_REGISTER) \
: ((CODE) == 'R') ? smalloffset_mem_p (OP) \
: ((CODE) == 'S') ? smalloffset_double_mem_p (OP) \
: ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP) \
: ((CODE) == 'U') ? !constantpool_mem_p (OP) \
: FALSE)

View file

@ -922,83 +922,35 @@
""
"
{
if (CONSTANT_P (operands[1])
&& register_operand (operands[0], DImode))
{
rtx src0, src1, dst0, dst1;
dst0 = operand_subword (operands[0], 0, 1, DImode);
src0 = operand_subword (operands[1], 0, 1, DImode);
dst1 = operand_subword (operands[0], 1, 1, DImode);
src1 = operand_subword (operands[1], 1, 1, DImode);
if (!dst0 || !src0 || !dst1 || !src1)
abort ();
emit_insn (gen_movsi (dst0, src0));
emit_insn (gen_movsi (dst1, src1));
DONE;
}
if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
operands[1] = force_const_mem (DImode, operands[1]);
if (!(reload_in_progress | reload_completed))
{
if (!register_operand (operands[0], DImode)
&& !register_operand (operands[1], DImode))
operands[1] = force_reg (DImode, operands[1]);
if (xtensa_copy_incoming_a7 (operands, DImode))
DONE;
}
}")
(define_insn "movdi_internal"
[(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,U")
(match_operand:DI 1 "nonimmed_operand" "d,S,d,r,U,r"))]
(define_insn_and_split "movdi_internal"
[(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
(match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
"register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)"
"*
"#"
"reload_completed"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 1) (match_dup 3))]
{
rtx dstreg;
switch (which_alternative)
xtensa_split_operand_pair (operands, SImode);
if (reg_overlap_mentioned_p (operands[0], operands[3]))
{
case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
case 1:
case 4:
/* Check if the first half of the destination register is used
in the source address. If so, reverse the order of the loads
so that the source address doesn't get clobbered until it is
no longer needed. */
dstreg = operands[0];
if (GET_CODE (dstreg) == SUBREG)
dstreg = SUBREG_REG (dstreg);
if (GET_CODE (dstreg) != REG)
abort();
if (reg_mentioned_p (dstreg, operands[1]))
{
switch (which_alternative)
{
case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
rtx tmp;
tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
}
}
else
{
switch (which_alternative)
{
case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
}
}
}
abort ();
return \"\";
}"
[(set_attr "type" "move,load,store,move,load,store")
(set_attr "mode" "DI")
(set_attr "length" "4,4,4,6,6,6")])
})
;; 32-bit Integer moves
@ -1122,7 +1074,7 @@
(define_insn "movsf_internal"
[(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,F,T,U,r"))]
(match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
"((register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode))
&& !(FP_REG_P (xt_true_regnum (operands[0]))
@ -1187,82 +1139,36 @@
""
"
{
if (CONSTANT_P (operands[1]))
{
rtx src0, src1, dst0, dst1;
dst0 = operand_subword (operands[0], 0, 1, DFmode);
src0 = operand_subword (operands[1], 0, 1, DFmode);
dst1 = operand_subword (operands[0], 1, 1, DFmode);
src1 = operand_subword (operands[1], 1, 1, DFmode);
if (!dst0 || !src0 || !dst1 || !src1)
abort ();
emit_insn (gen_movsi (dst0, src0));
emit_insn (gen_movsi (dst1, src1));
DONE;
}
if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
operands[1] = force_const_mem (DFmode, operands[1]);
if (!(reload_in_progress | reload_completed))
{
if (!register_operand (operands[0], DFmode)
&& !register_operand (operands[1], DFmode))
operands[1] = force_reg (DFmode, operands[1]);
if (xtensa_copy_incoming_a7 (operands, DFmode))
DONE;
}
}")
(define_insn "movdf_internal"
[(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,U")
(match_operand:DF 1 "nonimmed_operand" "d,S,d,r,U,r"))]
(define_insn_and_split "movdf_internal"
[(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
(match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
"register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode)"
"*
"#"
"reload_completed"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 1) (match_dup 3))]
{
rtx dstreg;
switch (which_alternative)
xtensa_split_operand_pair (operands, SFmode);
if (reg_overlap_mentioned_p (operands[0], operands[3]))
{
case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
rtx tmp;
tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
}
})
case 1:
case 4:
/* Check if the first half of the destination register is used
in the source address. If so, reverse the order of the loads
so that the source address doesn't get clobbered until it is
no longer needed. */
dstreg = operands[0];
if (GET_CODE (dstreg) == SUBREG)
dstreg = SUBREG_REG (dstreg);
if (GET_CODE (dstreg) != REG)
abort ();
if (reg_mentioned_p (dstreg, operands[1]))
{
switch (which_alternative)
{
case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
}
}
else
{
switch (which_alternative)
{
case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
}
}
}
abort ();
return \"\";
}"
[(set_attr "type" "move,load,store,move,load,store")
(set_attr "mode" "DF")
(set_attr "length" "4,4,4,6,6,6")])
;; Block moves