mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-31 03:49:42 +08:00
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:
parent
358bdeeec7
commit
633e4eb4ae
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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 ();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user