Commit 633e4eb4 by Bob Wilson Committed by Bob Wilson

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
parent 358bdeee
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)); ...@@ -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)); ...@@ -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) ...@@ -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 (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
return TRUE;
break;
if (mode == SImode) default:
return TARGET_CONST16 && CONSTANT_P (op); break;
}
return FALSE; return FALSE;
} }
...@@ -641,16 +654,6 @@ smalloffset_mem_p (op) ...@@ -641,16 +654,6 @@ smalloffset_mem_p (op)
int 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) constantpool_address_p (addr)
rtx addr; rtx addr;
{ {
...@@ -1014,7 +1017,7 @@ gen_float_relational (test_code, cmp0, cmp1) ...@@ -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) ...@@ -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) ...@@ -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 () ...@@ -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) ...@@ -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) ...@@ -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]; ...@@ -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]; ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment