mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2003-05-27 Danny Smith <dannysmith@users.sourceforge.net>
|
||||||
|
|
||||||
* config.gcc (i[34567]86-*-mingw32*): Add host makefile
|
* 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 call_insn_operand PARAMS ((rtx, enum machine_mode));
|
||||||
extern int move_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_mem_p PARAMS ((rtx));
|
||||||
extern int smalloffset_double_mem_p PARAMS ((rtx));
|
|
||||||
extern int constantpool_address_p PARAMS ((rtx));
|
extern int constantpool_address_p PARAMS ((rtx));
|
||||||
extern int constantpool_mem_p PARAMS ((rtx));
|
extern int constantpool_mem_p PARAMS ((rtx));
|
||||||
extern int const_float_1_operand PARAMS ((rtx, enum machine_mode));
|
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_conditional_move PARAMS ((rtx *, int));
|
||||||
extern int xtensa_expand_scc PARAMS ((rtx *));
|
extern int xtensa_expand_scc PARAMS ((rtx *));
|
||||||
extern int xtensa_expand_block_move 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 int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode));
|
||||||
extern bool xtensa_copy_incoming_a7 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));
|
extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int));
|
||||||
|
|
|
@ -599,19 +599,32 @@ move_operand (op, mode)
|
||||||
|| memory_operand (op, mode))
|
|| memory_operand (op, mode))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (mode == SFmode)
|
switch (mode)
|
||||||
return TARGET_CONST16 && CONSTANT_P (op);
|
{
|
||||||
|
case DFmode:
|
||||||
|
case SFmode:
|
||||||
|
return TARGET_CONST16 && CONSTANT_P (op);
|
||||||
|
|
||||||
/* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
|
case DImode:
|
||||||
result in 0/1. */
|
case SImode:
|
||||||
if (GET_CODE (op) == CONSTANT_P_RTX)
|
if (TARGET_CONST16)
|
||||||
return TRUE;
|
return CONSTANT_P (op);
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
|
case HImode:
|
||||||
return TRUE;
|
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)
|
if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
|
||||||
return TARGET_CONST16 && CONSTANT_P (op);
|
return TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
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
|
int
|
||||||
constantpool_address_p (addr)
|
constantpool_address_p (addr)
|
||||||
rtx 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 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 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;
|
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));
|
fatal_insn ("bad test", gen_rtx (test_code, VOIDmode, cmp0, cmp1));
|
||||||
reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
|
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].
|
/* Emit insns to move operands[1] into operands[0].
|
||||||
Return 1 if we have written out everything that needs to be done to
|
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
|
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 regno;
|
||||||
{
|
{
|
||||||
int first = -1;
|
int first = -1;
|
||||||
|
|
||||||
if (GP_REG_P (regno)) {
|
if (GP_REG_P (regno))
|
||||||
regno -= GP_REG_FIRST;
|
{
|
||||||
first = 0;
|
regno -= GP_REG_FIRST;
|
||||||
}
|
first = 0;
|
||||||
else if (BR_REG_P (regno)) {
|
}
|
||||||
regno -= BR_REG_FIRST;
|
else if (BR_REG_P (regno))
|
||||||
first = 16;
|
{
|
||||||
}
|
regno -= BR_REG_FIRST;
|
||||||
else if (FP_REG_P (regno)) {
|
first = 16;
|
||||||
regno -= FP_REG_FIRST;
|
}
|
||||||
/* The current numbering convention is that TIE registers are
|
else if (FP_REG_P (regno))
|
||||||
numbered in libcc order beginning with 256. We can't guarantee
|
{
|
||||||
that the FP registers will come first, so the following is just
|
regno -= FP_REG_FIRST;
|
||||||
a guess. It seems like we should make a special case for FP
|
/* The current numbering convention is that TIE registers are
|
||||||
registers and give them fixed numbers < 256. */
|
numbered in libcc order beginning with 256. We can't guarantee
|
||||||
first = 256;
|
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))
|
else if (ACC_REG_P (regno))
|
||||||
{
|
{
|
||||||
first = 0;
|
first = 0;
|
||||||
|
@ -1885,7 +1938,7 @@ override_options ()
|
||||||
a null pointer for X and the punctuation character for CODE.
|
a null pointer for X and the punctuation character for CODE.
|
||||||
|
|
||||||
'a', 'c', 'l', and 'n' are reserved.
|
'a', 'c', 'l', and 'n' are reserved.
|
||||||
|
|
||||||
The Xtensa specific codes are:
|
The Xtensa specific codes are:
|
||||||
|
|
||||||
'd' CONST_INT, print as signed decimal
|
'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);
|
print_operand (file, XEXP (XEXP (x, 0), 1), 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output_addr_const (file, x);
|
output_addr_const (file, x);
|
||||||
fputs (letter == 't' ? "@h" : "@l", file);
|
fputs (letter == 't' ? "@h" : "@l", file);
|
||||||
}
|
}
|
||||||
|
@ -2608,7 +2661,7 @@ xtensa_va_arg (valist, type)
|
||||||
|
|
||||||
size = gen_reg_rtx (SImode);
|
size = gen_reg_rtx (SImode);
|
||||||
emit_move_insn (size, va_size);
|
emit_move_insn (size, va_size);
|
||||||
|
|
||||||
if (BYTES_BIG_ENDIAN)
|
if (BYTES_BIG_ENDIAN)
|
||||||
{
|
{
|
||||||
rtx lab_use_va_size = gen_label_rtx ();
|
rtx lab_use_va_size = gen_label_rtx ();
|
||||||
|
|
|
@ -691,7 +691,6 @@ extern enum reg_class xtensa_char_to_class[256];
|
||||||
operand types.
|
operand types.
|
||||||
|
|
||||||
R = memory that can be accessed with a 4-bit unsigned offset
|
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)
|
T = memory in a constant pool (addressable with a pc-relative load)
|
||||||
U = memory *NOT* in a constant pool
|
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 \
|
&& reload_in_progress && GET_CODE (OP) == REG \
|
||||||
&& REGNO (OP) >= FIRST_PSEUDO_REGISTER) \
|
&& REGNO (OP) >= FIRST_PSEUDO_REGISTER) \
|
||||||
: ((CODE) == 'R') ? smalloffset_mem_p (OP) \
|
: ((CODE) == 'R') ? smalloffset_mem_p (OP) \
|
||||||
: ((CODE) == 'S') ? smalloffset_double_mem_p (OP) \
|
|
||||||
: ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP) \
|
: ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP) \
|
||||||
: ((CODE) == 'U') ? !constantpool_mem_p (OP) \
|
: ((CODE) == 'U') ? !constantpool_mem_p (OP) \
|
||||||
: FALSE)
|
: FALSE)
|
||||||
|
|
|
@ -922,83 +922,35 @@
|
||||||
""
|
""
|
||||||
"
|
"
|
||||||
{
|
{
|
||||||
if (CONSTANT_P (operands[1])
|
if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
|
||||||
&& register_operand (operands[0], DImode))
|
operands[1] = force_const_mem (DImode, operands[1]);
|
||||||
{
|
|
||||||
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 (!(reload_in_progress | reload_completed))
|
if (!register_operand (operands[0], DImode)
|
||||||
{
|
&& !register_operand (operands[1], DImode))
|
||||||
if (!register_operand (operands[0], DImode)
|
operands[1] = force_reg (DImode, operands[1]);
|
||||||
&& !register_operand (operands[1], DImode))
|
|
||||||
operands[1] = force_reg (DImode, operands[1]);
|
|
||||||
|
|
||||||
if (xtensa_copy_incoming_a7 (operands, DImode))
|
if (xtensa_copy_incoming_a7 (operands, DImode))
|
||||||
DONE;
|
DONE;
|
||||||
}
|
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_insn "movdi_internal"
|
(define_insn_and_split "movdi_internal"
|
||||||
[(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,U")
|
[(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
|
||||||
(match_operand:DI 1 "nonimmed_operand" "d,S,d,r,U,r"))]
|
(match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
|
||||||
"register_operand (operands[0], DImode)
|
"register_operand (operands[0], DImode)
|
||||||
|| register_operand (operands[1], DImode)"
|
|| register_operand (operands[1], DImode)"
|
||||||
"*
|
"#"
|
||||||
|
"reload_completed"
|
||||||
|
[(set (match_dup 0) (match_dup 2))
|
||||||
|
(set (match_dup 1) (match_dup 3))]
|
||||||
{
|
{
|
||||||
rtx dstreg;
|
xtensa_split_operand_pair (operands, SImode);
|
||||||
switch (which_alternative)
|
if (reg_overlap_mentioned_p (operands[0], operands[3]))
|
||||||
{
|
{
|
||||||
case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
|
rtx tmp;
|
||||||
case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
|
tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
|
||||||
case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
|
tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
|
||||||
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\";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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
|
;; 32-bit Integer moves
|
||||||
|
@ -1122,7 +1074,7 @@
|
||||||
|
|
||||||
(define_insn "movsf_internal"
|
(define_insn "movsf_internal"
|
||||||
[(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
|
[(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[0], SFmode)
|
||||||
|| register_operand (operands[1], SFmode))
|
|| register_operand (operands[1], SFmode))
|
||||||
&& !(FP_REG_P (xt_true_regnum (operands[0]))
|
&& !(FP_REG_P (xt_true_regnum (operands[0]))
|
||||||
|
@ -1187,82 +1139,36 @@
|
||||||
""
|
""
|
||||||
"
|
"
|
||||||
{
|
{
|
||||||
if (CONSTANT_P (operands[1]))
|
if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
|
||||||
{
|
operands[1] = force_const_mem (DFmode, 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 (!(reload_in_progress | reload_completed))
|
if (!register_operand (operands[0], DFmode)
|
||||||
{
|
&& !register_operand (operands[1], DFmode))
|
||||||
if (!register_operand (operands[0], DFmode)
|
operands[1] = force_reg (DFmode, operands[1]);
|
||||||
&& !register_operand (operands[1], DFmode))
|
|
||||||
operands[1] = force_reg (DFmode, operands[1]);
|
|
||||||
|
|
||||||
if (xtensa_copy_incoming_a7 (operands, DFmode))
|
if (xtensa_copy_incoming_a7 (operands, DFmode))
|
||||||
DONE;
|
DONE;
|
||||||
}
|
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_insn "movdf_internal"
|
(define_insn_and_split "movdf_internal"
|
||||||
[(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,U")
|
[(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
|
||||||
(match_operand:DF 1 "nonimmed_operand" "d,S,d,r,U,r"))]
|
(match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
|
||||||
"register_operand (operands[0], DFmode)
|
"register_operand (operands[0], DFmode)
|
||||||
|| register_operand (operands[1], DFmode)"
|
|| register_operand (operands[1], DFmode)"
|
||||||
"*
|
"#"
|
||||||
|
"reload_completed"
|
||||||
|
[(set (match_dup 0) (match_dup 2))
|
||||||
|
(set (match_dup 1) (match_dup 3))]
|
||||||
{
|
{
|
||||||
rtx dstreg;
|
xtensa_split_operand_pair (operands, SFmode);
|
||||||
switch (which_alternative)
|
if (reg_overlap_mentioned_p (operands[0], operands[3]))
|
||||||
{
|
{
|
||||||
case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
|
rtx tmp;
|
||||||
case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
|
tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
|
||||||
case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
|
tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
|
||||||
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\";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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
|
;; Block moves
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue