aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-07-28 08:43:44 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-07-28 08:43:44 -0400
commit1fdf73384d0ac48ba735153438ce53e6e8234822 (patch)
treef7b233b1c6d6a8664f3ef62a35fd5d2451af0191 /gcc
parent280fc31e5d1653a576aac4b0145729bf470c6c4c (diff)
downloadgcc-1fdf73384d0ac48ba735153438ce53e6e8234822.zip
gcc-1fdf73384d0ac48ba735153438ce53e6e8234822.tar.gz
gcc-1fdf73384d0ac48ba735153438ce53e6e8234822.tar.bz2
(movdi matchers): Support odd numbered regs.
From-SVN: r10177
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i960/i960.md82
1 files changed, 69 insertions, 13 deletions
diff --git a/gcc/config/i960/i960.md b/gcc/config/i960/i960.md
index a458aad..a86fb67 100644
--- a/gcc/config/i960/i960.md
+++ b/gcc/config/i960/i960.md
@@ -807,8 +807,8 @@
;; The store case can not be separate. See comment above.
(define_insn ""
- [(set (match_operand:DI 0 "general_operand" "=d,d,d,m,o")
- (match_operand:DI 1 "general_operand" "dI,i,m,d,J"))]
+ [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m,o")
+ (match_operand:DI 1 "general_operand" "d,I,i,m,d,J"))]
"(current_function_args_size == 0
&& current_function_varargs == 0
&& current_function_stdarg == 0
@@ -821,24 +821,52 @@
switch (which_alternative)
{
case 0:
- return \"movl %1,%0\";
+ if ((REGNO (operands[0]) & 1)
+ || (REGNO (operands[1]) & 1))
+ {
+ /* We normally copy the low-numbered register first. However, if
+ the second register operand 0 is the same as the first register
+ of operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
+ return \"mov %D0,%D1\;mov %0,%1\";
+ else
+ return \"mov %0,%1\;mov %D0,%D1\";
+ }
+ else
+ return \"movl %1,%0\";
case 1:
- return i960_output_ldconst (operands[0], operands[1]);
+ if (REGNO (operands[0]) & 1)
+ return \"mov %1,%0\;mov 0,%D0\";
+ else
+ return \"movl %1,%0\";
case 2:
- return \"ldl %1,%0\";
+ return i960_output_ldconst (operands[0], operands[1]);
case 3:
- return \"stl %1,%0\";
+ if (REGNO (operands[0]) & 1)
+ {
+ /* One can optimize a few cases here, but you have to be
+ careful of clobbering registers used in the address and
+ edge conditions. */
+ operands[2] = gen_rtx (REG, Pmode, REGNO (operands[0]) + 1);
+ operands[3] = gen_rtx (MEM, word_mode, operands[2]);
+ operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD);
+ return \"lda %1,%2\;ld %3,%0\;ld %4,%D0\";
+ }
+ else
+ return \"ldl %1,%0\";
case 4:
+ return \"stl %1,%0\";
+ case 5:
operands[1] = adj_offsettable_operand (operands[0], 4);
return \"st g14,%0\;st g14,%1\";
}
}"
- [(set_attr "type" "move,load,load,store,store")])
+ [(set_attr "type" "move,move,load,load,store,store")])
;; The store case can not be separate. See comment above.
(define_insn ""
- [(set (match_operand:DI 0 "general_operand" "=d,d,d,m")
- (match_operand:DI 1 "general_operand" "dI,i,m,d"))]
+ [(set (match_operand:DI 0 "general_operand" "=d,d,d,d,m")
+ (match_operand:DI 1 "general_operand" "d,I,i,m,d"))]
"(current_function_args_size != 0
|| current_function_varargs != 0
|| current_function_stdarg != 0
@@ -850,16 +878,44 @@
switch (which_alternative)
{
case 0:
- return \"movl %1,%0\";
+ if ((REGNO (operands[0]) & 1)
+ || (REGNO (operands[1]) & 1))
+ {
+ /* We normally copy the low-numbered register first. However, if
+ the second register operand 0 is the same as the first register
+ of operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
+ return \"mov %D0,%D1\;mov %0,%1\";
+ else
+ return \"mov %0,%1\;mov %D0,%D1\";
+ }
+ else
+ return \"movl %1,%0\";
case 1:
- return i960_output_ldconst (operands[0], operands[1]);
+ if (REGNO (operands[0]) & 1)
+ return \"mov %1,%0\;mov 0,%D0\";
+ else
+ return \"movl %1,%0\";
case 2:
- return \"ldl %1,%0\";
+ return i960_output_ldconst (operands[0], operands[1]);
case 3:
+ if (REGNO (operands[0]) & 1)
+ {
+ /* One can optimize a few cases here, but you have to be
+ careful of clobbering registers used in the address and
+ edge conditions. */
+ operands[2] = gen_rtx (REG, Pmode, REGNO (operands[0]) + 1);
+ operands[3] = gen_rtx (MEM, word_mode, operands[2]);
+ operands[4] = adj_offsettable_operand (operands[3], UNITS_PER_WORD);
+ return \"lda %1,%2\;ld %3,%0\;ld %4,%D0\";
+ }
+ else
+ return \"ldl %1,%0\";
+ case 4:
return \"stl %1,%0\";
}
}"
- [(set_attr "type" "move,load,load,store")])
+ [(set_attr "type" "move,move,load,load,store")])
(define_expand "movti"
[(set (match_operand:TI 0 "general_operand" "")