#endif
#endif
+static void copy_reg_pointer (rtx, rtx);
static int hppa_address_cost (rtx);
static bool hppa_rtx_costs (rtx, int, int, int *);
static inline rtx force_mode (enum machine_mode, rtx);
#endif
}
+/* If FROM is a probable pointer register, mark TO as a probable
+ pointer register with the same pointer alignment as FROM. */
+
+static void
+copy_reg_pointer (rtx to, rtx from)
+{
+ if (REG_POINTER (from))
+ mark_reg_pointer (to, REGNO_POINTER_ALIGN (REGNO (from)));
+}
+
/* Return nonzero only if OP is a register of mode MODE,
or CONST0_RTX. */
int
|| GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
}
-/* Return 1 if the operand is either a register or a memory operand that is
- not symbolic. */
-
-int
-reg_or_nonsymb_mem_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
- return 1;
-
- return 0;
-}
-
/* Return 1 if the operand is either a register, zero, or a memory operand
that is not symbolic. */
if (op == CONST0_RTX (mode))
return 1;
- if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
- return 1;
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
- return 0;
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ /* Until problems with management of the REG_POINTER flag are resolved,
+ we need to delay creating move insns with unscaled indexed addresses
+ until CSE is not expected. */
+ if (!TARGET_NO_SPACE_REGS
+ && !cse_not_expected
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && REG_P (XEXP (XEXP (op, 0), 0))
+ && REG_P (XEXP (XEXP (op, 0), 1)))
+ return 0;
+
+ return (!symbolic_memory_operand (op, mode)
+ && memory_address_p (mode, XEXP (op, 0)));
}
/* Return 1 if the operand is a register operand or a non-symbolic memory
if (reload_completed
&& memory_operand (op, mode)
- && ! symbolic_memory_operand (op, mode))
+ && !symbolic_memory_operand (op, mode))
return 1;
return 0;
|| CONST_OK_FOR_LETTER_P (intval, 'K'));
}
-/* Accept anything that can be moved in one instruction into a general
- register. */
+/* Return 1 iff OP is an indexed memory operand. */
+int
+indexed_memory_operand (rtx op, enum machine_mode mode)
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+
+ /* Before reload, a (SUBREG (MEM...)) forces reloading into a register. */
+ if (reload_completed && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (GET_CODE (op) != MEM || symbolic_memory_operand (op, mode))
+ return 0;
+
+ op = XEXP (op, 0);
+
+ return (memory_address_p (mode, op) && IS_INDEX_ADDR_P (op));
+}
+
+/* Accept anything that can be used as a destination operand for a
+ move instruction. We don't accept indexed memory operands since
+ they are supported only for floating point stores. */
+int
+move_dest_operand (rtx op, enum machine_mode mode)
+{
+ if (register_operand (op, mode))
+ return 1;
+
+ if (GET_MODE (op) != mode)
+ return 0;
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (GET_CODE (op) != MEM || symbolic_memory_operand (op, mode))
+ return 0;
+
+ op = XEXP (op, 0);
+
+ return (memory_address_p (mode, op)
+ && !IS_INDEX_ADDR_P (op)
+ && !IS_LO_SUM_DLT_ADDR_P (op));
+}
+
+/* Accept anything that can be used as a source operand for a move
+ instruction. */
int
-move_operand (rtx op, enum machine_mode mode)
+move_src_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
if (GET_CODE (op) == CONST_INT)
return cint_ok_for_move (INTVAL (op));
+ if (GET_MODE (op) != mode)
+ return 0;
+
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
+
if (GET_CODE (op) != MEM)
return 0;
- op = XEXP (op, 0);
-
- /* We consider a LO_SUM DLT reference a move_operand now since it has
- been merged into the normal movsi/movdi patterns. */
- if (GET_CODE (op) == LO_SUM
- && GET_CODE (XEXP (op, 0)) == REG
- && REG_OK_FOR_BASE_P (XEXP (op, 0))
- && GET_CODE (XEXP (op, 1)) == UNSPEC
- && GET_MODE (op) == Pmode)
- return 1;
-
- /* Since move_operand is only used for source operands, we can always
- allow scaled indexing! */
- if (! TARGET_DISABLE_INDEXING
- && GET_CODE (op) == PLUS
- && ((GET_CODE (XEXP (op, 0)) == MULT
- && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
- && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (op, 0), 1))
- == (HOST_WIDE_INT) GET_MODE_SIZE (mode)
- && GET_CODE (XEXP (op, 1)) == REG)
- || (GET_CODE (XEXP (op, 1)) == MULT
- &&GET_CODE (XEXP (XEXP (op, 1), 0)) == REG
- && GET_CODE (XEXP (XEXP (op, 1), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (op, 1), 1))
- == (HOST_WIDE_INT) GET_MODE_SIZE (mode)
- && GET_CODE (XEXP (op, 0)) == REG)))
- return 1;
+ /* Until problems with management of the REG_POINTER flag are resolved,
+ we need to delay creating move insns with unscaled indexed addresses
+ until CSE is not expected. */
+ if (!TARGET_NO_SPACE_REGS
+ && !cse_not_expected
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && REG_P (XEXP (XEXP (op, 0), 0))
+ && REG_P (XEXP (XEXP (op, 0), 1)))
+ return 0;
- return memory_address_p (mode, op);
+ return memory_address_p (mode, XEXP (op, 0));
}
/* Accept REG and any CONST_INT that can be moved in one instruction into a
if (register_operand (op, mode))
return 1;
- if (GET_CODE (op) == CONST_INT)
- return cint_ok_for_move (INTVAL (op));
-
- return 0;
+ return (GET_CODE (op) == CONST_INT && cint_ok_for_move (INTVAL (op)));
}
int
So instead we just emit the raw set, which avoids the movXX
expanders completely. */
+ mark_reg_pointer (reg, BITS_PER_UNIT);
emit_insn (gen_rtx_SET (VOIDmode, reg, orig));
current_function_uses_pic_offset_table = 1;
return reg;
current_function_uses_pic_offset_table = 1;
MEM_NOTRAP_P (pic_ref) = 1;
RTX_UNCHANGING_P (pic_ref) = 1;
+ mark_reg_pointer (reg, BITS_PER_UNIT);
insn = emit_move_insn (reg, pic_ref);
/* Put a REG_EQUAL note on this insn, so that it can be optimized. */
orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
base == reg ? 0 : reg);
}
- else abort ();
+ else
+ abort ();
+
if (GET_CODE (orig) == CONST_INT)
{
if (INT_14_BITS (orig))
pic_ref = gen_rtx_PLUS (Pmode, base, orig);
/* Likewise, should we set special REG_NOTEs here? */
}
+
return pic_ref;
}
{
rtx orig = x;
+ /* We need to canonicalize the order of operands in unscaled indexed
+ addresses since the code that checks if an address is valid doesn't
+ always try both orders. */
+ if (!TARGET_NO_SPACE_REGS
+ && GET_CODE (x) == PLUS
+ && GET_MODE (x) == Pmode
+ && REG_P (XEXP (x, 0))
+ && REG_P (XEXP (x, 1))
+ && REG_POINTER (XEXP (x, 0))
+ && !REG_POINTER (XEXP (x, 1)))
+ return gen_rtx_PLUS (Pmode, XEXP (x, 1), XEXP (x, 0));
+
if (flag_pic)
return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
register rtx operand1 = operands[1];
register rtx tem;
+ /* We can only handle indexed addresses in the destination operand
+ of floating point stores. Thus, we need to break out indexed
+ addresses from the destination operand. */
+ if (GET_CODE (operand0) == MEM && IS_INDEX_ADDR_P (XEXP (operand0, 0)))
+ {
+ /* This is only safe up to the beginning of life analysis. */
+ if (no_new_pseudos)
+ abort ();
+
+ tem = copy_to_mode_reg (Pmode, XEXP (operand0, 0));
+ operand0 = replace_equiv_address (operand0, tem);
+ }
+
+ /* On targets with non-equivalent space registers, break out unscaled
+ indexed addresses from the source operand before the final CSE.
+ We have to do this because the REG_POINTER flag is not correctly
+ carried through various optimization passes and CSE may substitute
+ a pseudo without the pointer set for one with the pointer set. As
+ a result, we loose various opportunites to create insns with
+ unscaled indexed addresses. */
+ if (!TARGET_NO_SPACE_REGS
+ && !cse_not_expected
+ && GET_CODE (operand1) == MEM
+ && GET_CODE (XEXP (operand1, 0)) == PLUS
+ && REG_P (XEXP (XEXP (operand1, 0), 0))
+ && REG_P (XEXP (XEXP (operand1, 0), 1)))
+ operand1
+ = replace_equiv_address (operand1,
+ copy_to_mode_reg (Pmode, XEXP (operand1, 0)));
+
if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
&& ((tem = find_replacement (&XEXP (operand0, 0)))
!= XEXP (operand0, 0)))
operand0 = gen_rtx_MEM (GET_MODE (operand0), tem);
+
if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM
&& ((tem = find_replacement (&XEXP (operand1, 0)))
!= XEXP (operand1, 0)))
(subreg (mem (addr))) cases. */
if (fp_reg_operand (operand0, mode)
&& ((GET_CODE (operand1) == MEM
- && ! memory_address_p (DFmode, XEXP (operand1, 0)))
+ && !memory_address_p (DFmode, XEXP (operand1, 0)))
|| ((GET_CODE (operand1) == SUBREG
&& GET_CODE (XEXP (operand1, 0)) == MEM
&& !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
if (!memory_address_p (Pmode, XEXP (operand1, 0)))
{
emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
- emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1, 0)),
- Pmode,
- XEXP (XEXP (operand1, 0), 0),
- scratch_reg));
+ emit_move_insn (scratch_reg,
+ gen_rtx_fmt_ee (GET_CODE (XEXP (operand1, 0)),
+ Pmode,
+ XEXP (XEXP (operand1, 0), 0),
+ scratch_reg));
}
else
emit_move_insn (scratch_reg, XEXP (operand1, 0));
&& ! memory_address_p (DFmode, XEXP (operand0, 0)))
|| ((GET_CODE (operand0) == SUBREG)
&& GET_CODE (XEXP (operand0, 0)) == MEM
- && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
+ && !memory_address_p (DFmode,
+ XEXP (XEXP (operand0, 0), 0))))
&& scratch_reg)
{
if (GET_CODE (operand0) == SUBREG)
emit_move_insn (operand0, scratch_reg);
return 1;
}
- /* Handle most common case: storing into a register. */
+ /* Handle the most common case: storing into a register. */
else if (register_operand (operand0, mode))
{
if (register_operand (operand1, mode)
/* Only `general_operands' can come here, so MEM is ok. */
|| GET_CODE (operand1) == MEM)
{
- /* Run this case quickly. */
+ /* Various sets are created during RTL generation which don't
+ have the REG_POINTER flag correctly set. After the CSE pass,
+ instruction recognition can fail if we don't consistently
+ set this flag when performing register copies. This should
+ also improve the opportunities for creating insns that use
+ unscaled indexing. */
+ if (REG_P (operand0) && REG_P (operand1))
+ {
+ if (REG_POINTER (operand1)
+ && !REG_POINTER (operand0)
+ && !HARD_REGISTER_P (operand0))
+ copy_reg_pointer (operand0, operand1);
+ else if (REG_POINTER (operand0)
+ && !REG_POINTER (operand1)
+ && !HARD_REGISTER_P (operand1))
+ copy_reg_pointer (operand1, operand0);
+ }
+
+ /* When MEMs are broken out, the REG_POINTER flag doesn't
+ get set. In some cases, we can set the REG_POINTER flag
+ from the declaration for the MEM. */
+ if (REG_P (operand0)
+ && GET_CODE (operand1) == MEM
+ && !REG_POINTER (operand0))
+ {
+ tree decl = MEM_EXPR (operand1);
+
+ /* Set the register pointer flag and register alignment
+ if the declaration for this memory reference is a
+ pointer type. Fortran indirect argument references
+ are ignored. */
+ if (decl
+ && !(flag_argument_noalias > 1
+ && TREE_CODE (decl) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (decl, 0)) == PARM_DECL))
+ {
+ tree type;
+
+ /* If this is a COMPONENT_REF, use the FIELD_DECL from
+ tree operand 1. */
+ if (TREE_CODE (decl) == COMPONENT_REF)
+ decl = TREE_OPERAND (decl, 1);
+
+ type = TREE_TYPE (decl);
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ type = get_inner_array_type (type);
+
+ if (POINTER_TYPE_P (type))
+ {
+ int align;
+
+ type = TREE_TYPE (type);
+ /* Using TYPE_ALIGN_OK is rather conservative as
+ only the ada frontend actually sets it. */
+ align = (TYPE_ALIGN_OK (type) ? TYPE_ALIGN (type)
+ : BITS_PER_UNIT);
+ mark_reg_pointer (operand0, align);
+ }
+ }
+ }
+
emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1));
return 1;
}
else
{
operands[1] = legitimize_pic_address (operand1, mode, temp);
+ if (REG_P (operand0) && REG_P (operands[1]))
+ copy_reg_pointer (operand0, operands[1]);
emit_insn (gen_rtx_SET (VOIDmode, operand0, operands[1]));
}
}
Don't mark hard registers though. That loses. */
if (GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
- REG_POINTER (operand0) = 1;
+ mark_reg_pointer (operand0, BITS_PER_UNIT);
if (REGNO (temp) >= FIRST_PSEUDO_REGISTER)
- REG_POINTER (temp) = 1;
+ mark_reg_pointer (temp, BITS_PER_UNIT);
+
if (ishighonly)
set = gen_rtx_SET (mode, operand0, temp);
else
fputs (",ma", file);
break;
case PLUS:
- if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
- || GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
+ if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG)
+ {
+ if (ASSEMBLER_DIALECT == 0)
+ fputs ("x", file);
+ }
+ else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
+ || GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
{
if (ASSEMBLER_DIALECT == 0)
fputs ("x,s", file);
base = XEXP (XEXP (x, 0), 0);
fprintf (file, "%d(%s)", size, reg_names [REGNO (base)]);
break;
- default:
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
+ case PLUS:
+ if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
fprintf (file, "%s(%s)",
reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0))],
reg_names [REGNO (XEXP (XEXP (x, 0), 1))]);
- else if (GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
+ else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
fprintf (file, "%s(%s)",
reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 1), 0))],
reg_names [REGNO (XEXP (XEXP (x, 0), 0))]);
+ else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG)
+ {
+ /* Because the REG_POINTER flag can get lost during reload,
+ GO_IF_LEGITIMATE_ADDRESS canonicalizes the order of the
+ index and base registers in the combined move patterns. */
+ rtx base = XEXP (XEXP (x, 0), 1);
+ rtx index = XEXP (XEXP (x, 0), 0);
+
+ fprintf (file, "%s(%s)",
+ reg_names [REGNO (index)], reg_names [REGNO (base)]);
+ }
else
output_address (XEXP (x, 0));
break;
+ default:
+ output_address (XEXP (x, 0));
+ break;
}
}
else
return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
}
-/* Return 1 if OP is valid as a base register in a reg + reg address. */
+/* Return 1 if OP is valid as a base or index register in a
+ REG+REG address. */
int
-basereg_operand (rtx op, enum machine_mode mode)
+borx_reg_operand (rtx op, enum machine_mode mode)
{
- /* cse will create some unscaled indexed addresses, however; it
- generally isn't a win on the PA, so avoid creating unscaled
- indexed addresses until after cse is finished. */
- if (!cse_not_expected)
+ if (GET_CODE (op) != REG)
return 0;
- /* Allow any register when TARGET_NO_SPACE_REGS is in effect since
- we don't have to worry about the braindamaged implicit space
- register selection from the basereg. */
- if (TARGET_NO_SPACE_REGS)
- return (GET_CODE (op) == REG);
+ /* We must reject virtual registers as the only expressions that
+ can be instantiated are REG and REG+CONST. */
+ if (op == virtual_incoming_args_rtx
+ || op == virtual_stack_vars_rtx
+ || op == virtual_stack_dynamic_rtx
+ || op == virtual_outgoing_args_rtx
+ || op == virtual_cfa_rtx)
+ return 0;
/* While it's always safe to index off the frame pointer, it's not
- always profitable, particularly when the frame pointer is being
- eliminated. */
- if (! flag_omit_frame_pointer && op == frame_pointer_rtx)
- return 1;
+ profitable to do so when the frame pointer is being eliminated. */
+ if (!reload_completed
+ && flag_omit_frame_pointer
+ && !current_function_calls_alloca
+ && op == frame_pointer_rtx)
+ return 0;
- return (GET_CODE (op) == REG
- && REG_POINTER (op)
- && register_operand (op, mode));
+ return register_operand (op, mode);
}
/* Return 1 if this operand is anything other than a hard register. */
in some cases it is preferable to use a more restrictive class. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
-/* Return the register class of a scratch register needed to copy IN into
- or out of a register in CLASS in MODE. If it can be done directly
- NO_REGS is returned.
+/* Return the register class of a scratch register needed to copy
+ IN into a register in CLASS in MODE, or a register in CLASS in MODE
+ to IN. If it can be done directly NO_REGS is returned.
Avoid doing any work for the common case calls. */
|| cint_ok_for_move (INTVAL (X)))) \
&& !function_label_operand (X, VOIDmode))
-/* Subroutine for EXTRA_CONSTRAINT.
+/* Subroutines for EXTRA_CONSTRAINT.
Return 1 iff OP is a pseudo which did not get a hard register and
we are running the reload pass. */
-
#define IS_RELOADING_PSEUDO_P(OP) \
((reload_in_progress \
&& GET_CODE (OP) == REG \
&& REGNO (OP) >= FIRST_PSEUDO_REGISTER \
&& reg_renumber [REGNO (OP)] < 0))
+/* Return 1 iff OP is a scaled or unscaled index address. */
+#define IS_INDEX_ADDR_P(OP) \
+ (GET_CODE (OP) == PLUS \
+ && GET_MODE (OP) == Pmode \
+ && (GET_CODE (XEXP (OP, 0)) == MULT \
+ || GET_CODE (XEXP (OP, 1)) == MULT \
+ || (REG_P (XEXP (OP, 0)) \
+ && REG_P (XEXP (OP, 1)))))
+
+/* Return 1 iff OP is a LO_SUM DLT address. */
+#define IS_LO_SUM_DLT_ADDR_P(OP) \
+ (GET_CODE (OP) == LO_SUM \
+ && GET_MODE (OP) == Pmode \
+ && REG_P (XEXP (OP, 0)) \
+ && REG_OK_FOR_BASE_P (XEXP (OP, 0)) \
+ && GET_CODE (XEXP (OP, 1)) == UNSPEC)
+
/* Optional extra constraints for this machine. Borrowed from sparc.h.
- For the HPPA, `Q' means that this is a memory operand but not a
- symbolic memory operand. Note that an unassigned pseudo register
- is such a memory operand. Needed because reload will generate
- these things in insns and then not re-recognize the insns, causing
- constrain_operands to fail.
+ `A' is a LO_SUM DLT memory operand.
+
+ `Q' is any memory operand that isn't a symbolic, indexed or lo_sum
+ memory operand. Note that an unassigned pseudo register is such a
+ memory operand. Needed because reload will generate these things
+ and then not re-recognize the insn, causing constrain_operands to
+ fail.
- `R' is used for scaled indexed addresses.
+ `R' is a scaled/unscaled indexed memory operand.
`S' is the constant 31.
- `T' is for fp loads and stores. */
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? \
- (IS_RELOADING_PSEUDO_P (OP) \
- || (GET_CODE (OP) == MEM \
- && (memory_address_p (GET_MODE (OP), XEXP (OP, 0))\
- || reload_in_progress) \
- && ! symbolic_memory_operand (OP, VOIDmode) \
- && !(GET_CODE (XEXP (OP, 0)) == PLUS \
- && (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT\
- || GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT))))\
- : ((C) == 'R' ? \
- (GET_CODE (OP) == MEM \
- && GET_CODE (XEXP (OP, 0)) == PLUS \
- && (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT \
- || GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT) \
- && (move_operand (OP, GET_MODE (OP)) \
- || memory_address_p (GET_MODE (OP), XEXP (OP, 0))\
- || reload_in_progress)) \
- : ((C) == 'T' ? \
- (GET_CODE (OP) == MEM \
- /* Using DFmode forces only short displacements \
- to be recognized as valid in reg+d addresses. \
- However, this is not necessary for PA2.0 since\
- it has long FP loads/stores. \
- \
- FIXME: the ELF32 linker clobbers the LSB of \
- the FP register number in {fldw,fstw} insns. \
- Thus, we only allow long FP loads/stores on \
- TARGET_64BIT. */ \
- && memory_address_p ((TARGET_PA_20 \
- && !TARGET_ELF32 \
- ? GET_MODE (OP) \
- : DFmode), \
- XEXP (OP, 0)) \
- && !(GET_CODE (XEXP (OP, 0)) == LO_SUM \
- && GET_CODE (XEXP (XEXP (OP, 0), 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (XEXP (OP, 0), 0))\
- && GET_CODE (XEXP (XEXP (OP, 0), 1)) == UNSPEC\
- && GET_MODE (XEXP (OP, 0)) == Pmode) \
- && !(GET_CODE (XEXP (OP, 0)) == PLUS \
- && (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT\
- || GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT)))\
- : ((C) == 'U' ? \
- (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) \
- : ((C) == 'A' ? \
- (GET_CODE (OP) == MEM \
- && GET_CODE (XEXP (OP, 0)) == LO_SUM \
- && GET_CODE (XEXP (XEXP (OP, 0), 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (XEXP (OP, 0), 0)) \
- && GET_CODE (XEXP (XEXP (OP, 0), 1)) == UNSPEC \
- && GET_MODE (XEXP (OP, 0)) == Pmode) \
- : ((C) == 'S' ? \
- (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31) : 0))))))
+ `T' is for fp loads and stores.
+
+ `U' is the constant 63. */
+
+#define EXTRA_CONSTRAINT(OP, C) \
+ ((C) == 'Q' ? \
+ (IS_RELOADING_PSEUDO_P (OP) \
+ || (GET_CODE (OP) == MEM \
+ && (reload_in_progress \
+ || memory_address_p (GET_MODE (OP), XEXP (OP, 0))) \
+ && !symbolic_memory_operand (OP, VOIDmode) \
+ && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \
+ && !IS_INDEX_ADDR_P (XEXP (OP, 0)))) \
+ : ((C) == 'A' ? \
+ (GET_CODE (OP) == MEM \
+ && IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0))) \
+ : ((C) == 'R' ? \
+ (GET_CODE (OP) == MEM \
+ && IS_INDEX_ADDR_P (XEXP (OP, 0))) \
+ : ((C) == 'T' ? \
+ (GET_CODE (OP) == MEM \
+ && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \
+ && !IS_INDEX_ADDR_P (XEXP (OP, 0)) \
+ /* Using DFmode forces only short displacements \
+ to be recognized as valid in reg+d addresses. \
+ However, this is not necessary for PA2.0 since \
+ it has long FP loads/stores. \
+ \
+ FIXME: the ELF32 linker clobbers the LSB of \
+ the FP register number in {fldw,fstw} insns. \
+ Thus, we only allow long FP loads/stores on \
+ TARGET_64BIT. */ \
+ && memory_address_p ((TARGET_PA_20 && !TARGET_ELF32 \
+ ? GET_MODE (OP) \
+ : DFmode), \
+ XEXP (OP, 0))) \
+ : ((C) == 'S' ? \
+ (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31) \
+ : ((C) == 'U' ? \
+ (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) : 0))))))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
#endif
\f
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- On the HP-PA, the actual legitimate addresses must be
- REG+REG, REG+(REG*SCALE) or REG+SMALLINT.
- But we can treat a SYMBOL_REF as legitimate if it is part of this
- function's constant-pool, because such addresses can actually
- be output as REG+SMALLINT.
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
+ valid memory address for an instruction. The MODE argument is the
+ machine mode for the MEM expression that wants to use this address.
+
+ On HP PA-RISC, the legitimate address forms are REG+SMALLINT,
+ REG+REG, and REG+(REG*SCALE). The indexed address forms are only
+ available with floating point loads and stores, and integer loads.
+ We get better code by allowing indexed addresses in the initial
+ RTL generation.
+
+ The acceptance of indexed addresses as legitimate implies that we
+ must provide patterns for doing indexed integer stores, or the move
+ expanders must force the address of an indexed store to a register.
+ We have adopted the latter approach.
+
+ Another function of GO_IF_LEGITIMATE_ADDRESS is to ensure that
+ the base register is a valid pointer for indexed instructions.
+ On targets that have non-equivalent space registers, we have to
+ know at the time of assembler output which register in a REG+REG
+ pair is the base register. The REG_POINTER flag is sometimes lost
+ in reload and the following passes, so it can't be relied on during
+ code generation. Thus, we either have to canonicalize the order
+ of the registers in REG+REG indexed addresses, or treat REG+REG
+ addresses separately and provide patterns for both permutations.
+
+ The latter approach requires several hundred additional lines of
+ code in pa.md. The downside to canonicalizing is that a PLUS
+ in the wrong order can't combine to form to make a scaled indexed
+ memory operand. As we won't need to canonicalize the operands if
+ the REG_POINTER lossage can be fixed, it seems better canonicalize.
+
+ We initially break out scaled indexed addresses in canonical order
+ in emit_move_sequence. LEGITIMIZE_ADDRESS also canonicalizes
+ scaled indexed addresses during RTL generation. However, fold_rtx
+ has its own opinion on how the operands of a PLUS should be ordered.
+ If one of the operands is equivalent to a constant, it will make
+ that operand the second operand. As the base register is likely to
+ be equivalent to a SYMBOL_REF, we have made it the second operand.
+
+ GO_IF_LEGITIMATE_ADDRESS accepts REG+REG as legitimate when the
+ operands are in the order INDEX+BASE on targets with non-equivalent
+ space registers, and in any order on targets with equivalent space
+ registers. It accepts both MULT+BASE and BASE+MULT for scaled indexing.
+
+ We treat a SYMBOL_REF as legitimate if it is part of the current
+ function's constant-pool, because such addresses can actually be
+ output as REG+SMALLINT.
Note we only allow 5 bit immediates for access to a constant address;
doing so avoids losing for loading/storing a FP register at an address
#define VAL_14_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x2000 < 0x4000)
#define INT_14_BITS(X) VAL_14_BITS_P (INTVAL (X))
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
+/* These are the modes that we allow for scaled indexing. */
+#define MODE_OK_FOR_SCALED_INDEXING_P(MODE) \
+ ((TARGET_64BIT && (MODE) == DImode) \
+ || (MODE) == SImode \
+ || (MODE) == HImode \
+ || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+
+/* These are the modes that we allow for unscaled indexing. */
+#define MODE_OK_FOR_UNSCALED_INDEXING_P(MODE) \
+ ((TARGET_64BIT && (MODE) == DImode) \
+ || (MODE) == SImode \
+ || (MODE) == HImode \
+ || (MODE) == QImode \
+ || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
|| ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC \
|| GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC) \
- && REG_P (XEXP (X, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)))) \
- goto ADDR; \
- else if (GET_CODE (X) == PLUS) \
- { \
- rtx base = 0, index = 0; \
- if (REG_P (XEXP (X, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 0))) \
- base = XEXP (X, 0), index = XEXP (X, 1); \
- else if (REG_P (XEXP (X, 1)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 1))) \
- base = XEXP (X, 1), index = XEXP (X, 0); \
- if (base != 0) \
- if (GET_CODE (index) == CONST_INT \
- && ((INT_14_BITS (index) \
- && (TARGET_SOFT_FLOAT \
- || (TARGET_PA_20 \
- && ((MODE == SFmode \
- && (INTVAL (index) % 4) == 0)\
- || (MODE == DFmode \
- && (INTVAL (index) % 8) == 0)))\
- || ((MODE) != SFmode && (MODE) != DFmode))) \
- || INT_5_BITS (index))) \
- goto ADDR; \
- if (! TARGET_SOFT_FLOAT \
- && ! TARGET_DISABLE_INDEXING \
- && base \
- && ((MODE) == SFmode || (MODE) == DFmode) \
- && GET_CODE (index) == MULT \
- && GET_CODE (XEXP (index, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (index, 0)) \
- && GET_CODE (XEXP (index, 1)) == CONST_INT \
- && INTVAL (XEXP (index, 1)) == ((MODE) == SFmode ? 4 : 8))\
- goto ADDR; \
- } \
- else if (GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && CONSTANT_P (XEXP (X, 1)) \
- && (TARGET_SOFT_FLOAT \
- /* We can allow symbolic LO_SUM addresses\
- for PA2.0. */ \
- || (TARGET_PA_20 \
- && !TARGET_ELF32 \
- && GET_CODE (XEXP (X, 1)) != CONST_INT)\
- || ((MODE) != SFmode \
- && (MODE) != DFmode))) \
- goto ADDR; \
- else if (GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == SUBREG \
- && GET_CODE (SUBREG_REG (XEXP (X, 0))) == REG\
- && REG_OK_FOR_BASE_P (SUBREG_REG (XEXP (X, 0)))\
- && CONSTANT_P (XEXP (X, 1)) \
- && (TARGET_SOFT_FLOAT \
- /* We can allow symbolic LO_SUM addresses\
- for PA2.0. */ \
- || (TARGET_PA_20 \
- && !TARGET_ELF32 \
- && GET_CODE (XEXP (X, 1)) != CONST_INT)\
- || ((MODE) != SFmode \
- && (MODE) != DFmode))) \
- goto ADDR; \
- else if (GET_CODE (X) == LABEL_REF \
- || (GET_CODE (X) == CONST_INT \
- && INT_5_BITS (X))) \
- goto ADDR; \
- /* Needed for -fPIC */ \
- else if (GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && GET_CODE (XEXP (X, 1)) == UNSPEC \
- && (TARGET_SOFT_FLOAT \
- || (TARGET_PA_20 && !TARGET_ELF32) \
- || ((MODE) != SFmode \
- && (MODE) != DFmode))) \
- goto ADDR; \
+ && REG_P (XEXP (X, 0)) \
+ && REG_OK_FOR_BASE_P (XEXP (X, 0)))) \
+ goto ADDR; \
+ else if (GET_CODE (X) == PLUS) \
+ { \
+ rtx base = 0, index = 0; \
+ if (REG_P (XEXP (X, 1)) \
+ && REG_OK_FOR_BASE_P (XEXP (X, 1))) \
+ base = XEXP (X, 1), index = XEXP (X, 0); \
+ else if (REG_P (XEXP (X, 0)) \
+ && REG_OK_FOR_BASE_P (XEXP (X, 0))) \
+ base = XEXP (X, 0), index = XEXP (X, 1); \
+ if (base \
+ && GET_CODE (index) == CONST_INT \
+ && ((INT_14_BITS (index) \
+ && (TARGET_SOFT_FLOAT \
+ || (TARGET_PA_20 \
+ && ((MODE == SFmode \
+ && (INTVAL (index) % 4) == 0) \
+ || (MODE == DFmode \
+ && (INTVAL (index) % 8) == 0))) \
+ || ((MODE) != SFmode && (MODE) != DFmode))) \
+ || INT_5_BITS (index))) \
+ goto ADDR; \
+ if (!TARGET_DISABLE_INDEXING \
+ /* Only accept the "canonical" INDEX+BASE operand order \
+ on targets with non-equivalent space registers. */ \
+ && (TARGET_NO_SPACE_REGS \
+ ? (base && REG_P (index)) \
+ : (base == XEXP (X, 1) && REG_P (index) \
+ && REG_POINTER (base) && !REG_POINTER (index))) \
+ && MODE_OK_FOR_UNSCALED_INDEXING_P (MODE) \
+ && REG_OK_FOR_INDEX_P (index) \
+ && borx_reg_operand (base, Pmode) \
+ && borx_reg_operand (index, Pmode)) \
+ goto ADDR; \
+ if (!TARGET_DISABLE_INDEXING \
+ && base \
+ && GET_CODE (index) == MULT \
+ && MODE_OK_FOR_SCALED_INDEXING_P (MODE) \
+ && REG_P (XEXP (index, 0)) \
+ && GET_MODE (XEXP (index, 0)) == Pmode \
+ && REG_OK_FOR_INDEX_P (XEXP (index, 0)) \
+ && GET_CODE (XEXP (index, 1)) == CONST_INT \
+ && INTVAL (XEXP (index, 1)) \
+ == (HOST_WIDE_INT) GET_MODE_SIZE (MODE) \
+ && borx_reg_operand (base, Pmode)) \
+ goto ADDR; \
+ } \
+ else if (GET_CODE (X) == LO_SUM \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && CONSTANT_P (XEXP (X, 1)) \
+ && (TARGET_SOFT_FLOAT \
+ /* We can allow symbolic LO_SUM addresses for PA2.0. */ \
+ || (TARGET_PA_20 \
+ && !TARGET_ELF32 \
+ && GET_CODE (XEXP (X, 1)) != CONST_INT) \
+ || ((MODE) != SFmode \
+ && (MODE) != DFmode))) \
+ goto ADDR; \
+ else if (GET_CODE (X) == LO_SUM \
+ && GET_CODE (XEXP (X, 0)) == SUBREG \
+ && GET_CODE (SUBREG_REG (XEXP (X, 0))) == REG \
+ && REG_OK_FOR_BASE_P (SUBREG_REG (XEXP (X, 0))) \
+ && CONSTANT_P (XEXP (X, 1)) \
+ && (TARGET_SOFT_FLOAT \
+ /* We can allow symbolic LO_SUM addresses for PA2.0. */ \
+ || (TARGET_PA_20 \
+ && !TARGET_ELF32 \
+ && GET_CODE (XEXP (X, 1)) != CONST_INT) \
+ || ((MODE) != SFmode \
+ && (MODE) != DFmode))) \
+ goto ADDR; \
+ else if (GET_CODE (X) == LABEL_REF \
+ || (GET_CODE (X) == CONST_INT \
+ && INT_5_BITS (X))) \
+ goto ADDR; \
+ /* Needed for -fPIC */ \
+ else if (GET_CODE (X) == LO_SUM \
+ && GET_CODE (XEXP (X, 0)) == REG \
+ && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && GET_CODE (XEXP (X, 1)) == UNSPEC \
+ && (TARGET_SOFT_FLOAT \
+ || (TARGET_PA_20 && !TARGET_ELF32) \
+ || ((MODE) != SFmode \
+ && (MODE) != DFmode))) \
+ goto ADDR; \
}
/* Look for machine dependent ways to make the invalid address AD a
#define JMP_BUF_SIZE 50
#define PREDICATE_CODES \
- {"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
+ {"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
{"call_operand_address", {LABEL_REF, SYMBOL_REF, CONST_INT, \
CONST_DOUBLE, CONST, HIGH, CONSTANT_P_RTX}}, \
+ {"indexed_memory_operand", {SUBREG, MEM}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"symbolic_memory_operand", {SUBREG, MEM}}, \
{"reg_before_reload_operand", {REG, MEM}}, \
- {"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}}, \
{"reg_or_0_or_nonsymb_mem_operand", {SUBREG, REG, MEM, CONST_INT, \
CONST_DOUBLE}}, \
- {"move_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, MEM}}, \
+ {"move_dest_operand", {SUBREG, REG, MEM}}, \
+ {"move_src_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, MEM}}, \
{"reg_or_cint_move_operand", {SUBREG, REG, CONST_INT}}, \
{"pic_label_operand", {LABEL_REF, CONST}}, \
{"fp_reg_operand", {REG}}, \
{"pc_or_label_operand", {PC, LABEL_REF}}, \
{"plus_xor_ior_operator", {PLUS, XOR, IOR}}, \
{"shadd_operand", {CONST_INT}}, \
- {"basereg_operand", {REG}}, \
{"div_operand", {REG, CONST_INT}}, \
{"ireg_operand", {REG}}, \
{"cmpib_comparison_operator", {EQ, NE, LT, LE, LEU, \
}")
(define_insn ""
- [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
- "=r,r,r,r,r,r,Q,!*q,!f,f,*TR")
- (match_operand:SI 1 "move_operand"
- "A,r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))]
+ [(set (match_operand:SI 0 "move_dest_operand"
+ "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
+ (match_operand:SI 1 "move_src_operand"
+ "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))
- && ! TARGET_SOFT_FLOAT"
+ && !TARGET_SOFT_FLOAT"
"@
ldw RT'%A1,%0
copy %1,%0
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
(define_insn ""
- [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
- "=r,r,r,r,r,r,Q,!*q")
- (match_operand:SI 1 "move_operand"
- "A,r,J,N,K,RQ,rM,!rM"))]
+ [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
+ (match_operand:SI 1 "register_operand" "f"))]
+ "!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
+ && reload_completed"
+ "fstw%F0 %1,%0"
+ [(set_attr "type" "fpstore")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4")])
+
+; Rewrite RTL using an indexed store. This will allow the insn that
+; computes the address to be deleted if the register it sets is dead.
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 4))
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "reg_or_0_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 2 "register_operand" "")
+ (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 4))))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 4))
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 2 "register_operand" "")
+ (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 4))))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[1])
+ && (TARGET_NO_SPACE_REGS
+ || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && (TARGET_NO_SPACE_REGS
+ || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[1])
+ && (TARGET_NO_SPACE_REGS
+ || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:SI (match_dup 0))
+ (match_operand:SI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && (TARGET_NO_SPACE_REGS
+ || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "move_dest_operand"
+ "=r,r,r,r,r,r,Q,!*q")
+ (match_operand:SI 1 "move_src_operand"
+ "A,r,J,N,K,RQ,rM,!rM"))]
"(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))
&& TARGET_SOFT_FLOAT"
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4,4,4")])
+;; Load or store with base-register modification.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldwx|ldw} %2(%1),%0"
+ (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L"))))
+ (set (match_dup 1)
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldw,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
+; And a zero extended variant.
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldwx|ldw} %1(%2),%0"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:SI
+ (plus:DI
+ (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L")))))
+ (set (match_dup 1)
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldw,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
-;; Load or store with base-register modification.
-
(define_expand "pre_load"
[(parallel [(set (match_operand:SI 0 "register_operand" "")
(mem (plus (match_operand 1 "register_operand" "")
}")
(define_insn ""
- [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,!*q,!*f")
- (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,!rM,!*fM"))]
+ [(set (match_operand:HI 0 "move_dest_operand"
+ "=r,r,r,r,r,Q,!*q,!*f")
+ (match_operand:HI 1 "move_src_operand"
+ "r,J,N,K,RQ,rM,!rM,!*fM"))]
"register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode)"
"@
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
- (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldhx|ldh} %2(%1),%0"
+ (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
+ (match_operand:SI 2 "int5_operand" "L"))))
+ (set (match_dup 1)
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "{ldhs|ldh},mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
- (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldhx|ldh} %1(%2),%0"
+ (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L"))))
+ (set (match_dup 1)
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldh,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
-; Now zero extended variants.
+; And a zero extended variant.
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:HI
- (plus:SI
- (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldhx|ldh} %2(%1),%0"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:HI
+ (plus:DI
+ (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L")))))
+ (set (match_dup 1)
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldh,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (mem:HI
(plus:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldhx|ldh} %1(%2),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L"))))
+ (match_operand:SI 1 "register_operand" "+r")
+ (match_operand:SI 2 "int5_operand" "L")))))
(set (match_dup 1)
(plus:SI (match_dup 1) (match_dup 2)))]
""
[(set_attr "type" "load")
(set_attr "length" "4")])
-; And a zero extended variant.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (mem:HI
- (plus:SI
- (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L")))))
+ (plus:DI
+ (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L")))))
(set (match_dup 1)
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "{ldhs|ldh},mb %2(%1),%0"
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldh,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
(set_attr "length" "4")])
(define_insn ""
+ [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
+ (match_operand:DI 1 "int5_operand" "L")))
+ (match_operand:HI 2 "reg_or_0_operand" "rM"))
+ (set (match_dup 0)
+ (plus:DI (match_dup 0) (match_dup 1)))]
+ "TARGET_64BIT"
+ "sth,mb %r2,%1(%0)"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")])
+
+(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (match_operand:HI 1 "register_operand" "r")
(match_operand 2 "const_int_operand" "J")))]
}")
(define_insn ""
- [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,!*q,!*f")
- (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,!rM,!*fM"))]
+ [(set (match_operand:QI 0 "move_dest_operand"
+ "=r,r,r,r,r,Q,!*q,!*f")
+ (match_operand:QI 1 "move_src_operand"
+ "r,J,N,K,RQ,rM,!rM,!*fM"))]
"register_operand (operands[0], QImode)
|| reg_or_0_operand (operands[1], QImode)"
"@
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldbx|ldb} %2(%1),%0"
+ (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
+ (match_operand:SI 2 "int5_operand" "L"))))
+ (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
+ ""
+ "{ldbs|ldb},mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldbx|ldb} %1(%2),%0"
+ (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L"))))
+ (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldb,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
-; Indexed byte load with zero extension to SImode or HImode.
+; Now the same thing with zero extensions.
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:QI
- (plus:SI
- (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldbx|ldb} %2(%1),%0"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:QI (plus:DI
+ (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L")))))
+ (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldb,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:QI
- (plus:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldbx|ldb} %1(%2),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (mem:QI
- (plus:SI
- (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldbx|ldb} %2(%1),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (mem:QI
- (plus:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "{ldbx|ldb} %1(%2),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L"))))
+ (zero_extend:SI (mem:QI (plus:SI
+ (match_operand:SI 1 "register_operand" "+r")
+ (match_operand:SI 2 "int5_operand" "L")))))
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
""
"{ldbs|ldb},mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
-; Now the same thing with zero extensions.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:QI (plus:SI
- (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L")))))
- (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "{ldbs|ldb},mb %2(%1),%0"
+ (zero_extend:SI (mem:QI (plus:DI
+ (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L")))))
+ (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldb,mb %2(%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
(set_attr "length" "4")])
(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (mem:QI (plus:DI
+ (match_operand:DI 1 "register_operand" "+r")
+ (match_operand:DI 2 "int5_operand" "L")))))
+ (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_64BIT"
+ "ldb,mb %2(%1),%0"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")])
+
+(define_insn ""
[(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "int5_operand" "L")))
(match_operand:QI 2 "reg_or_0_operand" "rM"))
[(set_attr "type" "store")
(set_attr "length" "4")])
+(define_insn ""
+ [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
+ (match_operand:DI 1 "int5_operand" "L")))
+ (match_operand:QI 2 "reg_or_0_operand" "rM"))
+ (set (match_dup 0)
+ (plus:DI (match_dup 0) (match_dup 1)))]
+ "TARGET_64BIT"
+ "stb,mb %r2,%1(%0)"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")])
+
;; The definition of this insn does not really explain what it does,
;; but it should suffice that anything generated as this insn will be
;; recognized as a movstrsi operation, and that it will not successfully
"GET_CODE (operands[1]) == CONST_DOUBLE
&& operands[1] != CONST0_RTX (DFmode)
&& !TARGET_64BIT
- && ! TARGET_SOFT_FLOAT"
+ && !TARGET_SOFT_FLOAT"
"* return (which_alternative == 0 ? output_move_double (operands)
: \"fldd%F1 %1,%0\");"
[(set_attr "type" "move,fpload")
"
{
if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
- operands[1] = force_const_mem (DFmode, operands[1]);
+ operands[1] = force_const_mem (DFmode, operands[1]);
if (emit_move_sequence (operands, DFmode, 0))
DONE;
}")
(define_insn ""
- [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
- "=f,*r,RQ,?o,?Q,f,*r,*r")
+ [(set (match_operand:DF 0 "move_dest_operand"
+ "=f,*r,Q,?o,?Q,f,*r,*r")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
"fG,*rG,f,*r,*r,RQ,o,RQ"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
- && ! (GET_CODE (operands[1]) == CONST_DOUBLE
- && GET_CODE (operands[0]) == MEM)
- && ! TARGET_64BIT
- && ! TARGET_SOFT_FLOAT"
+ && !(GET_CODE (operands[1]) == CONST_DOUBLE
+ && GET_CODE (operands[0]) == MEM)
+ && !TARGET_64BIT
+ && !TARGET_SOFT_FLOAT"
"*
{
if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
(set_attr "length" "4,8,4,8,16,4,8,16")])
(define_insn ""
- [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
+ [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
+ (match_operand:DF 1 "reg_or_0_operand" "f"))]
+ "!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
+ && reload_completed"
+ "fstd%F0 %1,%0"
+ [(set_attr "type" "fpstore")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4")])
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 8))
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 2 "register_operand" "")
+ (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 8))))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 8))
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 2 "register_operand" "")
+ (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 8))))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[1])
+ && (TARGET_NO_SPACE_REGS
+ || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && (TARGET_NO_SPACE_REGS
+ || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[1])
+ && (TARGET_NO_SPACE_REGS
+ || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:DF (match_dup 0))
+ (match_operand:DF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && (TARGET_NO_SPACE_REGS
+ || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "move_dest_operand"
"=r,?o,?Q,r,r")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
- "rG,r,r,o,Q"))]
+ "rG,r,r,o,RQ"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
- && ! TARGET_64BIT
+ && !TARGET_64BIT
&& TARGET_SOFT_FLOAT"
"*
{
(set_attr "length" "8,8,16,8,16")])
(define_insn ""
- [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
- "=r,r,r,r,r,Q,!*q,!f,f,*TR")
- (match_operand:DF 1 "move_operand"
- "r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))]
+ [(set (match_operand:DF 0 "move_dest_operand"
+ "=!*r,*r,*r,*r,*r,Q,!*q,f,f,T")
+ (match_operand:DF 1 "move_src_operand"
+ "!*r,J,N,K,RQ,*rM,!*rM,fM,RT,f"))]
"(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode))
- && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
+ && !TARGET_SOFT_FLOAT && TARGET_64BIT"
"@
copy %1,%0
ldi %1,%0
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=fx")
- (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{flddx|fldd} %2(%1),%0"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=fx")
- (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{flddx|fldd} %1(%2),%0"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))
- (match_operand:DF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{fstdx|fstd} %0,%2(%1)"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))
- (match_operand:DF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{fstdx|fstd} %0,%1(%2)"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
-
+\f
(define_expand "movdi"
- [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
+ [(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
"
{
if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
- operands[1] = force_const_mem (DImode, operands[1]);
+ operands[1] = force_const_mem (DImode, operands[1]);
if (emit_move_sequence (operands, DImode, 0))
DONE;
(set_attr "length" "8")])
(define_insn ""
- [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
- "=r,o,Q,r,r,r,f,f,*TR")
+ [(set (match_operand:DI 0 "move_dest_operand"
+ "=r,o,Q,r,r,r,*f,*f,T")
(match_operand:DI 1 "general_operand"
- "rM,r,r,o*R,Q,i,fM,*TR,f"))]
+ "rM,r,r,o*R,Q,i,*fM,RT,*f"))]
"(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))
- && ! TARGET_64BIT
- && ! TARGET_SOFT_FLOAT"
+ && !TARGET_64BIT
+ && !TARGET_SOFT_FLOAT"
"*
{
if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
(set_attr "length" "8,8,16,8,16,16,4,4,4")])
(define_insn ""
- [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
- "=r,r,r,r,r,r,Q,!*q,!f,f,*TR")
- (match_operand:DI 1 "move_operand"
- "A,r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))]
+ [(set (match_operand:DI 0 "move_dest_operand"
+ "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
+ (match_operand:DI 1 "move_src_operand"
+ "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
"(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))
- && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
+ && !TARGET_SOFT_FLOAT && TARGET_64BIT"
"@
ldd RT'%A1,%0
copy %1,%0
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
(define_insn ""
- [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
+ [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
+ (match_operand:DI 1 "register_operand" "f"))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && !TARGET_DISABLE_INDEXING
+ && reload_completed"
+ "fstd%F0 %1,%0"
+ [(set_attr "type" "fpstore")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4")])
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 8))
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:DI (match_dup 0))
+ (match_operand:DI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 2 "register_operand" "")
+ (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 8))))
+ (set (mem:DI (match_dup 0))
+ (match_operand:DI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:DI (match_dup 0))
+ (match_operand:DI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[1])
+ && (TARGET_NO_SPACE_REGS
+ || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:DI (match_dup 0))
+ (match_operand:DI 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && (TARGET_NO_SPACE_REGS
+ || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "move_dest_operand"
"=r,o,Q,r,r,r")
(match_operand:DI 1 "general_operand"
"rM,r,r,o,Q,i"))]
"(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))
- && ! TARGET_64BIT
+ && !TARGET_64BIT
&& TARGET_SOFT_FLOAT"
"*
{
}")
(define_insn ""
- [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
- "=f,r,f,r,RQ,Q")
+ [(set (match_operand:SF 0 "move_dest_operand"
+ "=f,!*r,f,*r,Q,Q")
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
- "fG,rG,RQ,RQ,f,rG"))]
+ "fG,!*rG,RQ,RQ,f,*rG"))]
"(register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode))
- && ! TARGET_SOFT_FLOAT"
+ && !TARGET_SOFT_FLOAT"
"@
fcpy,sgl %f1,%0
copy %r1,%0
fldw%F1 %1,%0
ldw%M1 %1,%0
- fstw%F0 %r1,%0
+ fstw%F0 %1,%0
stw%M0 %r1,%0"
[(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4")])
(define_insn ""
- [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
+ [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
+ (match_operand:SF 1 "register_operand" "f"))]
+ "!TARGET_SOFT_FLOAT
+ && !TARGET_DISABLE_INDEXING
+ && reload_completed"
+ "fstw%F0 %1,%0"
+ [(set_attr "type" "fpstore")
+ (set_attr "pa_combine_type" "addmove")
+ (set_attr "length" "4")])
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 4))
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 2 "register_operand" "")
+ (mult:SI (match_operand:SI 1 "register_operand" "")
+ (const_int 4))))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 4))
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 2 "register_operand" "")
+ (mult:DI (match_operand:DI 1 "register_operand" "")
+ (const_int 4))))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
+ (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[1])
+ && (TARGET_NO_SPACE_REGS
+ || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && (TARGET_NO_SPACE_REGS
+ || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[1])
+ && (TARGET_NO_SPACE_REGS
+ || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (set (mem:SF (match_dup 0))
+ (match_operand:SF 3 "register_operand" ""))]
+ "!TARGET_SOFT_FLOAT
+ && TARGET_64BIT
+ && REG_OK_FOR_BASE_P (operands[2])
+ && (TARGET_NO_SPACE_REGS
+ || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
+ && FP_REGNO_P (REGNO (operands[3]))"
+ [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
+ (match_dup 3))
+ (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "move_dest_operand"
"=r,r,Q")
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
"rG,RQ,rG"))]
(set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4")])
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=fx")
- (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{fldwx|fldw} %2(%1),%0"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=fx")
- (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{fldwx|fldw} %1(%2),%0"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))
- (match_operand:SF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{fstwx|fstw} %0,%2(%1)"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
-\f
-(define_insn ""
- [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))
- (match_operand:SF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "{fstwx|fstw} %0,%1(%2)"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
\f
;;- zero extension instructions
;; memory operands. This gives us better overall code than just
;; having a pattern that does or does not accept memory operands.
-(define_expand "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI
- (match_operand:HI 1 "register_operand" "")))]
- ""
- "")
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:HI 1 "move_operand" "r,RQ")))]
- "GET_CODE (operands[1]) != CONST_INT"
- "@
- {extru|extrw,u} %1,31,16,%0
- ldh%M1 %1,%0"
- [(set_attr "type" "shift,load")
- (set_attr "length" "4,4")])
-
(define_expand "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "")
(zero_extend:HI
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(zero_extend:HI
- (match_operand:QI 1 "move_operand" "r,RQ")))]
+ (match_operand:QI 1 "move_src_operand" "r,RQ")))]
"GET_CODE (operands[1]) != CONST_INT"
"@
{extru|extrw,u} %1,31,8,%0
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI
- (match_operand:QI 1 "move_operand" "r,RQ")))]
+ (match_operand:QI 1 "move_src_operand" "r,RQ")))]
"GET_CODE (operands[1]) != CONST_INT"
"@
{extru|extrw,u} %1,31,8,%0
[(set_attr "type" "shift,load")
(set_attr "length" "4,4")])
-(define_insn "zero_extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
+(define_expand "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI
+ (match_operand:HI 1 "register_operand" "")))]
+ ""
+ "")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (zero_extend:SI
+ (match_operand:HI 1 "move_src_operand" "r,RQ")))]
+ "GET_CODE (operands[1]) != CONST_INT"
+ "@
+ {extru|extrw,u} %1,31,16,%0
+ ldh%M1 %1,%0"
+ [(set_attr "type" "shift,load")
+ (set_attr "length" "4,4")])
+
+(define_expand "zero_extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI
+ (match_operand:QI 1 "register_operand" "")))]
"TARGET_64BIT"
- "extrd,u %1,63,8,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
+ "")
-(define_insn "zero_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (zero_extend:DI
+ (match_operand:QI 1 "move_src_operand" "r,RQ")))]
+ "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
+ "@
+ extrd,u %1,63,8,%0
+ ldb%M1 %1,%0"
+ [(set_attr "type" "shift,load")
+ (set_attr "length" "4,4")])
+
+(define_expand "zero_extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI
+ (match_operand:HI 1 "register_operand" "")))]
"TARGET_64BIT"
- "extrd,u %1,63,16,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
+ "")
-(define_insn "zero_extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (zero_extend:DI
+ (match_operand:HI 1 "move_src_operand" "r,RQ")))]
+ "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
+ "@
+ extrd,u %1,63,16,%0
+ ldh%M1 %1,%0"
+ [(set_attr "type" "shift,load")
+ (set_attr "length" "4,4")])
+
+(define_expand "zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI
+ (match_operand:SI 1 "register_operand" "")))]
"TARGET_64BIT"
- "extrd,u %1,63,32,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (zero_extend:DI
+ (match_operand:SI 1 "move_src_operand" "r,RQ")))]
+ "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
+ "@
+ extrd,u %1,63,32,%0
+ ldw%M1 %1,%0"
+ [(set_attr "type" "shift,load")
+ (set_attr "length" "4,4")])
;;- sign extension instructions
(match_operand:DI 2 "arith_operand" "r,J")))]
"TARGET_64BIT"
"@
- {addl|add,l} %1,%2,%0
+ add,l %1,%2,%0
ldo %2(%1),%0"
[(set_attr "type" "binary,binary")
(set_attr "pa_combine_type" "addmove")
;; The mulsi3 insns set up registers for the millicode call.
(define_expand "mulsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
+ [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
+ (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
(parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3))
(clobber (reg:SI 26))
"
{
operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
- if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
+ if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
{
rtx scratch = gen_reg_rtx (DImode);
operands[1] = force_reg (SImode, operands[1]);
operands[2] = force_reg (SImode, operands[2]);
emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_SUBREG (SImode, scratch, GET_MODE_SIZE (SImode))));
+ emit_insn (gen_movsi (operands[0],
+ gen_rtx_SUBREG (SImode, scratch,
+ GET_MODE_SIZE (SImode))));
DONE;
}
operands[3] = gen_reg_rtx (SImode);
;;; Division and mod.
(define_expand "divsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
+ [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
+ (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
(parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3))
(clobber (match_dup 4))
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
(define_expand "udivsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
+ [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
+ (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
(parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3))
(clobber (match_dup 4))
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
(define_expand "modsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
+ [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
+ (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
(parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3))
(clobber (match_dup 4))
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
(define_expand "umodsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
+ [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
+ (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
(parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3))
(clobber (match_dup 4))
;; Clean up turds left by reload.
(define_peephole
- [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
+ [(set (match_operand 0 "move_dest_operand" "")
(match_operand 1 "register_operand" "fr"))
(set (match_operand 2 "register_operand" "fr")
(match_dup 0))]
- "! TARGET_SOFT_FLOAT
+ "!TARGET_SOFT_FLOAT
&& GET_CODE (operands[0]) == MEM
&& ! MEM_VOLATILE_P (operands[0])
&& GET_MODE (operands[0]) == GET_MODE (operands[1])
(define_peephole
[(set (match_operand 0 "register_operand" "fr")
- (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
+ (match_operand 1 "move_src_operand" ""))
(set (match_operand 2 "register_operand" "fr")
(match_dup 1))]
- "! TARGET_SOFT_FLOAT
+ "!TARGET_SOFT_FLOAT
&& GET_CODE (operands[1]) == MEM
&& ! MEM_VOLATILE_P (operands[1])
&& GET_MODE (operands[0]) == GET_MODE (operands[1])