;; 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
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
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" "")