aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@acm.org>2003-05-29 00:08:36 +0000
committerBob Wilson <bwilson@gcc.gnu.org>2003-05-29 00:08:36 +0000
commit633e4eb4aecc1658799c7647f73b050d12aafdfa (patch)
tree8f7556214a765d1d4d045594d3ee023ac5d2179b /gcc
parent358bdeeec758236bd004def191cdf947f88a45b4 (diff)
downloadgcc-633e4eb4aecc1658799c7647f73b050d12aafdfa.zip
gcc-633e4eb4aecc1658799c7647f73b050d12aafdfa.tar.gz
gcc-633e4eb4aecc1658799c7647f73b050d12aafdfa.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/config/xtensa/xtensa-protos.h2
-rw-r--r--gcc/config/xtensa/xtensa.c137
-rw-r--r--gcc/config/xtensa/xtensa.h2
-rw-r--r--gcc/config/xtensa/xtensa.md178
5 files changed, 156 insertions, 181 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f9541bb..3998831 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
index b5ca611..7800f0f 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -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));
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 18ed9d3..d3ec724 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -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 (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;
}
@@ -641,16 +654,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 ();
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 9b7f261..0322109 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -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)
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 40bf5c0..26bad87 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -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