Commit d8f95bed by John David Anglin Committed by John David Anglin

re PR target/13054 (compile/980310-3.f: insn does not satisfy its constraints)

	PR target/13054
	* pa-protos.h (indexed_memory_operand, borx_reg_operand,
	move_dest_operand, move_src_operand): New protypes.
	(basereg_operand, move_operand, reg_or_nonsymb_mem_operand): Deleted.
	* pa.c (copy_reg_pointer, indexed_memory_operand, move_dest_operand,
	move_src_operand): New functions.
	(basereg_operand, reg_or_nonsymb_mem_operand, move_operand): Delete.
	(reg_or_0_or_nonsymb_mem_operand): Return false for unscaled indexed
	address until cse is not expected on targets with non-equivalent
	space registers.
	(hppa_legitimize_address): Canonicalize unscaled indexed addresses
	on targets non-equivalent space registers.
	(emit_move_sequence): Break out indexed addresses from destination
	operand.  Similarly, break out unscaled indexed addresses from
	source operand on targets with non-equivalent space registers.  Fix
	REG_POINTER flag when possible.  Mark register pointer when creating
	new pointers.
	(print_operand): Handle unscaled index addresses.
	* pa.h (IS_INDEX_ADDR_P, IS_LO_SUM_DLT_ADDR_P): New macro subroutines
	for EXTRA_CONSTRAINT.
	(EXTRA_CONSTRAINT): Rework to make more readable.
	(MODE_OK_FOR_SCALED_INDEXING_P, MODE_OK_FOR_UNSCALED_INDEXING_P): New
	subroutines for GO_IF_LEGITIMATE_ADDRESS.
	(GO_IF_LEGITIMATE_ADDRESS): Rework using new subroutines.  Allow scaled
	and unscaled addresses.  Canonicalize unscaled indexed addresses on
	targets with non-equivalent space registers.  Document issues in
	handling indexed address modes on PA-RISC.
	(PREDICATE_CODES): Update for new and deleted predicates.
	* pa.md (move_dest_operand, move_src_operand, indexed_memory_operand):
	Use new predicates in move patterns.
	Add peephole2 patterns to optimize floating point stores.  Fix
	constrain preferencing in move patterns.  Delete patterns for handling
	unscaled indexed memory loads.  Add missing load and store with
	base-register modification patterns.  Correct SFmode floating point
	store pattern.  Add missing zero extension loads.

From-SVN: r74614
parent 9ec31db3
2003-12-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/13054
* pa-protos.h (indexed_memory_operand, borx_reg_operand,
move_dest_operand, move_src_operand): New protypes.
(basereg_operand, move_operand, reg_or_nonsymb_mem_operand): Deleted.
* pa.c (copy_reg_pointer, indexed_memory_operand, move_dest_operand,
move_src_operand): New functions.
(basereg_operand, reg_or_nonsymb_mem_operand, move_operand): Delete.
(reg_or_0_or_nonsymb_mem_operand): Return false for unscaled indexed
address until cse is not expected on targets with non-equivalent
space registers.
(hppa_legitimize_address): Canonicalize unscaled indexed addresses
on targets non-equivalent space registers.
(emit_move_sequence): Break out indexed addresses from destination
operand. Similarly, break out unscaled indexed addresses from
source operand on targets with non-equivalent space registers. Fix
REG_POINTER flag when possible. Mark register pointer when creating
new pointers.
(print_operand): Handle unscaled index addresses.
* pa.h (IS_INDEX_ADDR_P, IS_LO_SUM_DLT_ADDR_P): New macro subroutines
for EXTRA_CONSTRAINT.
(EXTRA_CONSTRAINT): Rework to make more readable.
(MODE_OK_FOR_SCALED_INDEXING_P, MODE_OK_FOR_UNSCALED_INDEXING_P): New
subroutines for GO_IF_LEGITIMATE_ADDRESS.
(GO_IF_LEGITIMATE_ADDRESS): Rework using new subroutines. Allow scaled
and unscaled addresses. Canonicalize unscaled indexed addresses on
targets with non-equivalent space registers. Document issues in
handling indexed address modes on PA-RISC.
(PREDICATE_CODES): Update for new and deleted predicates.
* pa.md (move_dest_operand, move_src_operand, indexed_memory_operand):
Use new predicates in move patterns.
Add peephole2 patterns to optimize floating point stores. Fix
constrain preferencing in move patterns. Delete patterns for handling
unscaled indexed memory loads. Add missing load and store with
base-register modification patterns. Correct SFmode floating point
store pattern. Add missing zero extension loads.
2003-12-13 Steven Bosscher <stevenb@suse.de>
* ggc-zone.c (struct alloc_zone): Don't pre-declare, it already
......
......@@ -64,6 +64,7 @@ extern struct rtx_def *gen_cmp_fp (enum rtx_code, rtx, rtx);
extern void hppa_encode_label (rtx);
extern int arith11_operand (rtx, enum machine_mode);
extern int adddi3_operand (rtx, enum machine_mode);
extern int indexed_memory_operand (rtx, enum machine_mode);
extern int symbolic_expression_p (rtx);
extern int symbolic_memory_operand (rtx, enum machine_mode);
extern int pa_adjust_insn_length (rtx, int);
......@@ -73,16 +74,16 @@ extern int arith5_operand (rtx, enum machine_mode);
extern int uint5_operand (rtx, enum machine_mode);
extern int pic_label_operand (rtx, enum machine_mode);
extern int plus_xor_ior_operator (rtx, enum machine_mode);
extern int basereg_operand (rtx, enum machine_mode);
extern int borx_reg_operand (rtx, enum machine_mode);
extern int shadd_operand (rtx, enum machine_mode);
extern int arith_operand (rtx, enum machine_mode);
extern int read_only_operand (rtx, enum machine_mode);
extern int move_operand (rtx, enum machine_mode);
extern int move_dest_operand (rtx, enum machine_mode);
extern int move_src_operand (rtx, enum machine_mode);
extern int and_operand (rtx, enum machine_mode);
extern int ior_operand (rtx, enum machine_mode);
extern int arith32_operand (rtx, enum machine_mode);
extern int uint32_operand (rtx, enum machine_mode);
extern int reg_or_nonsymb_mem_operand (rtx, enum machine_mode);
extern int reg_before_reload_operand (rtx, enum machine_mode);
extern int reg_or_0_operand (rtx, enum machine_mode);
extern int reg_or_0_or_nonsymb_mem_operand (rtx, enum machine_mode);
......
......@@ -94,6 +94,7 @@ hppa_fpstore_bypass_p (rtx out_insn, rtx in_insn)
#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);
......@@ -381,6 +382,16 @@ pa_init_builtins (void)
#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
......@@ -448,21 +459,6 @@ symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|| 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. */
......@@ -475,10 +471,24 @@ reg_or_0_or_nonsymb_mem_operand (rtx op, enum machine_mode mode)
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);
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
......@@ -499,7 +509,7 @@ reg_before_reload_operand (rtx op, enum machine_mode mode)
if (reload_completed
&& memory_operand (op, mode)
&& ! symbolic_memory_operand (op, mode))
&& !symbolic_memory_operand (op, mode))
return 1;
return 0;
......@@ -516,10 +526,54 @@ cint_ok_for_move (HOST_WIDE_INT intval)
|| 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
move_operand (rtx op, enum machine_mode mode)
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_src_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
......@@ -530,41 +584,26 @@ move_operand (rtx op, enum machine_mode mode)
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
......@@ -575,10 +614,7 @@ reg_or_cint_move_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));
return 0;
return (GET_CODE (op) == CONST_INT && cint_ok_for_move (INTVAL (op)));
}
int
......@@ -831,6 +867,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
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;
......@@ -861,6 +898,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx 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. */
......@@ -885,7 +923,9 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
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))
......@@ -895,6 +935,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
pic_ref = gen_rtx_PLUS (Pmode, base, orig);
/* Likewise, should we set special REG_NOTEs here? */
}
return pic_ref;
}
......@@ -955,6 +996,18 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
{
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));
......@@ -1423,6 +1476,36 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
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)
......@@ -1461,6 +1544,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
&& ((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)))
......@@ -1471,7 +1555,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
(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)))))
......@@ -1490,7 +1574,8 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
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)),
emit_move_insn (scratch_reg,
gen_rtx_fmt_ee (GET_CODE (XEXP (operand1, 0)),
Pmode,
XEXP (XEXP (operand1, 0), 0),
scratch_reg));
......@@ -1506,7 +1591,8 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
&& ! 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)
......@@ -1618,7 +1704,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
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)
......@@ -1630,7 +1716,67 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
/* 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;
}
......@@ -1777,6 +1923,8 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
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]));
}
}
......@@ -1804,9 +1952,10 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
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
......@@ -4829,7 +4978,13 @@ print_operand (FILE *file, rtx x, int code)
fputs (",ma", file);
break;
case PLUS:
if (GET_CODE (XEXP (XEXP (x, 0), 0)) == 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)
......@@ -4905,20 +5060,33 @@ print_operand (FILE *file, rtx x, int code)
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
......@@ -7844,32 +8012,33 @@ shadd_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
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. */
......
......@@ -641,9 +641,9 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
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. */
......@@ -1199,83 +1199,87 @@ extern int may_call_alloca;
|| 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. */
`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 \
&& (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))))\
&& (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 \
&& 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)) \
&& 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\
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 \
&& 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) \
XEXP (OP, 0))) \
: ((C) == 'S' ? \
(GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31) : 0))))))
(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
......@@ -1311,16 +1315,53 @@ extern int may_call_alloca;
#endif
/* 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
......@@ -1338,6 +1379,21 @@ extern int may_call_alloca;
#define VAL_14_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x2000 < 0x4000)
#define INT_14_BITS(X) VAL_14_BITS_P (INTVAL (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)) \
......@@ -1349,33 +1405,47 @@ extern int may_call_alloca;
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)) \
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 \
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)\
&& (INTVAL (index) % 4) == 0) \
|| (MODE == DFmode \
&& (INTVAL (index) % 8) == 0)))\
&& (INTVAL (index) % 8) == 0))) \
|| ((MODE) != SFmode && (MODE) != DFmode))) \
|| INT_5_BITS (index))) \
goto ADDR; \
if (! TARGET_SOFT_FLOAT \
&& ! TARGET_DISABLE_INDEXING \
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 \
&& ((MODE) == SFmode || (MODE) == DFmode) \
&& GET_CODE (index) == MULT \
&& GET_CODE (XEXP (index, 0)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (index, 0)) \
&& 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)) == ((MODE) == SFmode ? 4 : 8))\
&& 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 \
......@@ -1383,25 +1453,23 @@ extern int may_call_alloca;
&& 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. */ \
/* We can allow symbolic LO_SUM addresses for PA2.0. */ \
|| (TARGET_PA_20 \
&& !TARGET_ELF32 \
&& GET_CODE (XEXP (X, 1)) != CONST_INT)\
&& 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)))\
&& 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. */ \
/* We can allow symbolic LO_SUM addresses for PA2.0. */ \
|| (TARGET_PA_20 \
&& !TARGET_ELF32 \
&& GET_CODE (XEXP (X, 1)) != CONST_INT)\
&& GET_CODE (XEXP (X, 1)) != CONST_INT) \
|| ((MODE) != SFmode \
&& (MODE) != DFmode))) \
goto ADDR; \
......@@ -1872,16 +1940,17 @@ do { \
#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}}, \
......@@ -1905,7 +1974,6 @@ do { \
{"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, \
......
......@@ -2263,13 +2263,13 @@
}")
(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
......@@ -2287,9 +2287,154 @@
(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"
[(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_operand"
(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))
......@@ -2307,26 +2452,32 @@
(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" "")
......@@ -2715,8 +2866,10 @@
}")
(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)"
"@
......@@ -2734,31 +2887,37 @@
(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")])
......@@ -2766,17 +2925,8 @@
[(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)))]
""
......@@ -2784,17 +2934,16 @@
[(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")])
......@@ -2810,6 +2959,17 @@
(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")))]
......@@ -2830,8 +2990,10 @@
}")
(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)"
"@
......@@ -2849,86 +3011,55 @@
(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")])
......@@ -2944,6 +3075,17 @@
(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"))
......@@ -2954,6 +3096,17 @@
[(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
......@@ -3503,7 +3656,7 @@
"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")
......@@ -3556,16 +3709,16 @@
}")
(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[1]) == CONST_DOUBLE
&& GET_CODE (operands[0]) == MEM)
&& ! TARGET_64BIT
&& ! TARGET_SOFT_FLOAT"
&& !TARGET_64BIT
&& !TARGET_SOFT_FLOAT"
"*
{
if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
......@@ -3577,13 +3730,156 @@
(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"
"*
{
......@@ -3593,13 +3889,13 @@
(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
......@@ -3615,44 +3911,9 @@
(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")])
(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" ""))]
""
"
......@@ -3733,14 +3994,14 @@
(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])
......@@ -3752,13 +4013,13 @@
(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
......@@ -3776,13 +4037,93 @@
(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"
"*
{
......@@ -3873,26 +4214,169 @@
}")
(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"))]
......@@ -3907,41 +4391,6 @@
(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")])
(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")])
;;- zero extension instructions
......@@ -3950,24 +4399,6 @@
;; 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
......@@ -3978,7 +4409,7 @@
(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
......@@ -3996,7 +4427,7 @@
(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
......@@ -4004,29 +4435,77 @@
[(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
......@@ -4331,7 +4810,7 @@
(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")
......@@ -4496,8 +4975,8 @@
;; 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))
......@@ -4508,14 +4987,15 @@
"
{
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);
......@@ -4620,8 +5100,8 @@
;;; 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))
......@@ -4676,8 +5156,8 @@
(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))
......@@ -4733,8 +5213,8 @@
(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))
......@@ -4785,8 +5265,8 @@
(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))
......@@ -8274,11 +8754,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; 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])
......@@ -8314,10 +8794,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(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])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment