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,19 +599,32 @@ move_operand (op, mode)
|| memory_operand (op, mode))
return TRUE;
if (mode == SFmode)
return TARGET_CONST16 && CONSTANT_P (op);
switch (mode)
{
case DFmode:
case SFmode:
return TARGET_CONST16 && CONSTANT_P (op);
/* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
result in 0/1. */
if (GET_CODE (op) == CONSTANT_P_RTX)
return TRUE;
case DImode:
case SImode:
if (TARGET_CONST16)
return CONSTANT_P (op);
/* fall through */
if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
return TRUE;
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)
return TRUE;
if (mode == SImode)
return TARGET_CONST16 && CONSTANT_P (op);
if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
return TRUE;
break;
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;
@ -1014,7 +1017,7 @@ gen_float_relational (test_code, cmp0, cmp1)
case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
default:
default:
fatal_insn ("bad test", gen_rtx (test_code, VOIDmode, cmp0, cmp1));
reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
}
@ -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
@ -1658,24 +1708,27 @@ xtensa_dbx_register_number (regno)
int regno;
{
int first = -1;
if (GP_REG_P (regno)) {
regno -= GP_REG_FIRST;
first = 0;
}
else if (BR_REG_P (regno)) {
regno -= BR_REG_FIRST;
first = 16;
}
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
that the FP registers will come first, so the following is just
a guess. It seems like we should make a special case for FP
registers and give them fixed numbers < 256. */
first = 256;
}
if (GP_REG_P (regno))
{
regno -= GP_REG_FIRST;
first = 0;
}
else if (BR_REG_P (regno))
{
regno -= BR_REG_FIRST;
first = 16;
}
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
that the FP registers will come first, so the following is just
a guess. It seems like we should make a special case for FP
registers and give them fixed numbers < 256. */
first = 256;
}
else if (ACC_REG_P (regno))
{
first = 0;
@ -1885,7 +1938,7 @@ override_options ()
a null pointer for X and the punctuation character for CODE.
'a', 'c', 'l', and 'n' are reserved.
The Xtensa specific codes are:
'd' CONST_INT, print as signed decimal
@ -2041,7 +2094,7 @@ print_operand (file, x, letter)
print_operand (file, XEXP (XEXP (x, 0), 1), 0);
}
else
{
{
output_addr_const (file, x);
fputs (letter == 't' ? "@h" : "@l", file);
}
@ -2608,7 +2661,7 @@ xtensa_va_arg (valist, type)
size = gen_reg_rtx (SImode);
emit_move_insn (size, va_size);
if (BYTES_BIG_ENDIAN)
{
rtx lab_use_va_size = gen_label_rtx ();

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 (!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;
}
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\";
}
}
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\";
}
}
rtx tmp;
tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
}
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 (!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;
}
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\";
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\";
}
}
rtx tmp;
tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
}
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