extern int frame_pointer_needed;
/* Declare functions in rs6000.c */
-extern int offsettable_mem_operand ();
extern void optimization_options ();
extern void output_options ();
extern void rs6000_override_options ();
extern void rs6000_file_start ();
extern struct rtx_def *rs6000_float_const ();
extern struct rtx_def *rs6000_got_register ();
+extern struct rtx_def *find_addr_reg();
extern int direct_return ();
extern int get_issue_rate ();
extern int any_operand ();
extern int num_insns_constant ();
extern int easy_fp_constant ();
extern int volatile_mem_operand ();
-extern int offsettable_addr_operand ();
+extern int offsettable_mem_operand ();
extern int mem_or_easy_const_operand ();
extern int add_operand ();
extern int non_add_cint_operand ();
;; The "??" is a kludge until we can figure out a more reasonable way
;; of handling these non-offsettable values.
(define_insn "*movdf_hardfloat32"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
- (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
+ (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
abort ();
case 0:
/* We normally copy the low-numbered register first. However, if
- the first register operand 0 is the same as the second register of
- operand 1, we must copy in the opposite order. */
+ the first register operand 0 is the same as the second register
+ of operand 1, we must copy in the opposite order. */
if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
return \"mr %L0,%L1\;mr %0,%1\";
else
return \"mr %0,%1\;mr %L0,%L1\";
case 1:
- /* If the low-address word is used in the address, we must load it
- last. Otherwise, load it first. Note that we cannot have
- auto-increment in that case since the address register is known to be
- dead. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands [1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
+ if (offsettable_memref_p (operands[1]))
+ {
+ /* If the low-address word is used in the address, we must load
+ it last. Otherwise, load it first. Note that we cannot have
+ auto-increment in that case since the address register is
+ known to be dead. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands[1], 0))
+ return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
+ else
+ return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
+ }
else
- return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
+ {
+ rtx addreg;
+
+ if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
+ || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
+ abort ();
+
+ addreg = find_addr_reg (XEXP (operands[1], 0));
+ if (refers_to_regno_p (REGNO (operands[0]),
+ REGNO (operands[0]) + 1,
+ operands[1], 0))
+ {
+ output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
+ output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+ output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
+ return \"{lx|lwzx} %0,%1\";
+ }
+ else
+ {
+ output_asm_insn (\"{lx|lwzx} %0,%1\", operands);
+ output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
+ output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
+ output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
+ return \"\";
+ }
+ }
case 2:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+ if (offsettable_memref_p (operands[0]))
+ return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+ else
+ {
+ rtx addreg;
+
+ if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
+ || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
+ abort ();
+
+ addreg = find_addr_reg (XEXP (operands[0], 0));
+ output_asm_insn (\"{stx|stwx} %1,%0\", operands);
+ output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
+ output_asm_insn (\"{stx|stwx} %L1,%0\", operands);
+ output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
+ return \"\";
+ }
case 3:
case 4:
case 5: