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> 2003-12-13 Steven Bosscher <stevenb@suse.de>
* ggc-zone.c (struct alloc_zone): Don't pre-declare, it already * 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); ...@@ -64,6 +64,7 @@ extern struct rtx_def *gen_cmp_fp (enum rtx_code, rtx, rtx);
extern void hppa_encode_label (rtx); extern void hppa_encode_label (rtx);
extern int arith11_operand (rtx, enum machine_mode); extern int arith11_operand (rtx, enum machine_mode);
extern int adddi3_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_expression_p (rtx);
extern int symbolic_memory_operand (rtx, enum machine_mode); extern int symbolic_memory_operand (rtx, enum machine_mode);
extern int pa_adjust_insn_length (rtx, int); extern int pa_adjust_insn_length (rtx, int);
...@@ -73,16 +74,16 @@ extern int arith5_operand (rtx, enum machine_mode); ...@@ -73,16 +74,16 @@ extern int arith5_operand (rtx, enum machine_mode);
extern int uint5_operand (rtx, enum machine_mode); extern int uint5_operand (rtx, enum machine_mode);
extern int pic_label_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 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 shadd_operand (rtx, enum machine_mode);
extern int arith_operand (rtx, enum machine_mode); extern int arith_operand (rtx, enum machine_mode);
extern int read_only_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 and_operand (rtx, enum machine_mode);
extern int ior_operand (rtx, enum machine_mode); extern int ior_operand (rtx, enum machine_mode);
extern int arith32_operand (rtx, enum machine_mode); extern int arith32_operand (rtx, enum machine_mode);
extern int uint32_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_before_reload_operand (rtx, enum machine_mode);
extern int reg_or_0_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); 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) ...@@ -94,6 +94,7 @@ hppa_fpstore_bypass_p (rtx out_insn, rtx in_insn)
#endif #endif
#endif #endif
static void copy_reg_pointer (rtx, rtx);
static int hppa_address_cost (rtx); static int hppa_address_cost (rtx);
static bool hppa_rtx_costs (rtx, int, int, int *); static bool hppa_rtx_costs (rtx, int, int, int *);
static inline rtx force_mode (enum machine_mode, rtx); static inline rtx force_mode (enum machine_mode, rtx);
...@@ -381,6 +382,16 @@ pa_init_builtins (void) ...@@ -381,6 +382,16 @@ pa_init_builtins (void)
#endif #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, /* Return nonzero only if OP is a register of mode MODE,
or CONST0_RTX. */ or CONST0_RTX. */
int int
...@@ -448,21 +459,6 @@ symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -448,21 +459,6 @@ symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|| GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF); || 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 /* Return 1 if the operand is either a register, zero, or a memory operand
that is not symbolic. */ that is not symbolic. */
...@@ -475,10 +471,24 @@ reg_or_0_or_nonsymb_mem_operand (rtx op, enum machine_mode mode) ...@@ -475,10 +471,24 @@ reg_or_0_or_nonsymb_mem_operand (rtx op, enum machine_mode mode)
if (op == CONST0_RTX (mode)) if (op == CONST0_RTX (mode))
return 1; return 1;
if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode)) if (GET_CODE (op) == SUBREG)
return 1; 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 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 /* 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) ...@@ -499,7 +509,7 @@ reg_before_reload_operand (rtx op, enum machine_mode mode)
if (reload_completed if (reload_completed
&& memory_operand (op, mode) && memory_operand (op, mode)
&& ! symbolic_memory_operand (op, mode)) && !symbolic_memory_operand (op, mode))
return 1; return 1;
return 0; return 0;
...@@ -516,10 +526,54 @@ cint_ok_for_move (HOST_WIDE_INT intval) ...@@ -516,10 +526,54 @@ cint_ok_for_move (HOST_WIDE_INT intval)
|| CONST_OK_FOR_LETTER_P (intval, 'K')); || CONST_OK_FOR_LETTER_P (intval, 'K'));
} }
/* Accept anything that can be moved in one instruction into a general /* Return 1 iff OP is an indexed memory operand. */
register. */
int 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)) if (register_operand (op, mode))
return 1; return 1;
...@@ -530,41 +584,26 @@ move_operand (rtx op, enum machine_mode mode) ...@@ -530,41 +584,26 @@ move_operand (rtx op, enum machine_mode mode)
if (GET_CODE (op) == CONST_INT) if (GET_CODE (op) == CONST_INT)
return cint_ok_for_move (INTVAL (op)); return cint_ok_for_move (INTVAL (op));
if (GET_MODE (op) != mode)
return 0;
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op); op = SUBREG_REG (op);
if (GET_CODE (op) != MEM) if (GET_CODE (op) != MEM)
return 0; return 0;
op = XEXP (op, 0); /* Until problems with management of the REG_POINTER flag are resolved,
we need to delay creating move insns with unscaled indexed addresses
/* We consider a LO_SUM DLT reference a move_operand now since it has until CSE is not expected. */
been merged into the normal movsi/movdi patterns. */ if (!TARGET_NO_SPACE_REGS
if (GET_CODE (op) == LO_SUM && !cse_not_expected
&& GET_CODE (XEXP (op, 0)) == REG && GET_CODE (XEXP (op, 0)) == PLUS
&& REG_OK_FOR_BASE_P (XEXP (op, 0)) && REG_P (XEXP (XEXP (op, 0), 0))
&& GET_CODE (XEXP (op, 1)) == UNSPEC && REG_P (XEXP (XEXP (op, 0), 1)))
&& GET_MODE (op) == Pmode) return 0;
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;
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 /* 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) ...@@ -575,10 +614,7 @@ reg_or_cint_move_operand (rtx op, enum machine_mode mode)
if (register_operand (op, mode)) if (register_operand (op, mode))
return 1; return 1;
if (GET_CODE (op) == CONST_INT) return (GET_CODE (op) == CONST_INT && cint_ok_for_move (INTVAL (op)));
return cint_ok_for_move (INTVAL (op));
return 0;
} }
int int
...@@ -831,6 +867,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg) ...@@ -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 So instead we just emit the raw set, which avoids the movXX
expanders completely. */ expanders completely. */
mark_reg_pointer (reg, BITS_PER_UNIT);
emit_insn (gen_rtx_SET (VOIDmode, reg, orig)); emit_insn (gen_rtx_SET (VOIDmode, reg, orig));
current_function_uses_pic_offset_table = 1; current_function_uses_pic_offset_table = 1;
return reg; return reg;
...@@ -861,6 +898,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg) ...@@ -861,6 +898,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
current_function_uses_pic_offset_table = 1; current_function_uses_pic_offset_table = 1;
MEM_NOTRAP_P (pic_ref) = 1; MEM_NOTRAP_P (pic_ref) = 1;
RTX_UNCHANGING_P (pic_ref) = 1; RTX_UNCHANGING_P (pic_ref) = 1;
mark_reg_pointer (reg, BITS_PER_UNIT);
insn = emit_move_insn (reg, pic_ref); insn = emit_move_insn (reg, pic_ref);
/* Put a REG_EQUAL note on this insn, so that it can be optimized. */ /* 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) ...@@ -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, orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
base == reg ? 0 : reg); base == reg ? 0 : reg);
} }
else abort (); else
abort ();
if (GET_CODE (orig) == CONST_INT) if (GET_CODE (orig) == CONST_INT)
{ {
if (INT_14_BITS (orig)) if (INT_14_BITS (orig))
...@@ -895,6 +935,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg) ...@@ -895,6 +935,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
pic_ref = gen_rtx_PLUS (Pmode, base, orig); pic_ref = gen_rtx_PLUS (Pmode, base, orig);
/* Likewise, should we set special REG_NOTEs here? */ /* Likewise, should we set special REG_NOTEs here? */
} }
return pic_ref; return pic_ref;
} }
...@@ -955,6 +996,18 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -955,6 +996,18 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
{ {
rtx orig = x; 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) if (flag_pic)
return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode)); 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) ...@@ -1423,6 +1476,36 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
register rtx operand1 = operands[1]; register rtx operand1 = operands[1];
register rtx tem; 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 if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == REG && reload_in_progress && GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER) && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
...@@ -1461,6 +1544,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg) ...@@ -1461,6 +1544,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
&& ((tem = find_replacement (&XEXP (operand0, 0))) && ((tem = find_replacement (&XEXP (operand0, 0)))
!= XEXP (operand0, 0))) != XEXP (operand0, 0)))
operand0 = gen_rtx_MEM (GET_MODE (operand0), tem); operand0 = gen_rtx_MEM (GET_MODE (operand0), tem);
if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM
&& ((tem = find_replacement (&XEXP (operand1, 0))) && ((tem = find_replacement (&XEXP (operand1, 0)))
!= XEXP (operand1, 0))) != XEXP (operand1, 0)))
...@@ -1471,7 +1555,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg) ...@@ -1471,7 +1555,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
(subreg (mem (addr))) cases. */ (subreg (mem (addr))) cases. */
if (fp_reg_operand (operand0, mode) if (fp_reg_operand (operand0, mode)
&& ((GET_CODE (operand1) == MEM && ((GET_CODE (operand1) == MEM
&& ! memory_address_p (DFmode, XEXP (operand1, 0))) && !memory_address_p (DFmode, XEXP (operand1, 0)))
|| ((GET_CODE (operand1) == SUBREG || ((GET_CODE (operand1) == SUBREG
&& GET_CODE (XEXP (operand1, 0)) == MEM && GET_CODE (XEXP (operand1, 0)) == MEM
&& !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0))))) && !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) ...@@ -1490,7 +1574,8 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
if (!memory_address_p (Pmode, XEXP (operand1, 0))) if (!memory_address_p (Pmode, XEXP (operand1, 0)))
{ {
emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1)); 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, Pmode,
XEXP (XEXP (operand1, 0), 0), XEXP (XEXP (operand1, 0), 0),
scratch_reg)); scratch_reg));
...@@ -1506,7 +1591,8 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx 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))) && ! memory_address_p (DFmode, XEXP (operand0, 0)))
|| ((GET_CODE (operand0) == SUBREG) || ((GET_CODE (operand0) == SUBREG)
&& GET_CODE (XEXP (operand0, 0)) == MEM && 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) && scratch_reg)
{ {
if (GET_CODE (operand0) == SUBREG) if (GET_CODE (operand0) == SUBREG)
...@@ -1618,7 +1704,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg) ...@@ -1618,7 +1704,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
emit_move_insn (operand0, scratch_reg); emit_move_insn (operand0, scratch_reg);
return 1; 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)) else if (register_operand (operand0, mode))
{ {
if (register_operand (operand1, mode) if (register_operand (operand1, mode)
...@@ -1630,7 +1716,67 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg) ...@@ -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. */ /* Only `general_operands' can come here, so MEM is ok. */
|| GET_CODE (operand1) == MEM) || 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)); emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1));
return 1; return 1;
} }
...@@ -1777,6 +1923,8 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg) ...@@ -1777,6 +1923,8 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
else else
{ {
operands[1] = legitimize_pic_address (operand1, mode, temp); 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])); 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) ...@@ -1804,9 +1952,10 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
Don't mark hard registers though. That loses. */ Don't mark hard registers though. That loses. */
if (GET_CODE (operand0) == REG if (GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER) && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
REG_POINTER (operand0) = 1; mark_reg_pointer (operand0, BITS_PER_UNIT);
if (REGNO (temp) >= FIRST_PSEUDO_REGISTER) if (REGNO (temp) >= FIRST_PSEUDO_REGISTER)
REG_POINTER (temp) = 1; mark_reg_pointer (temp, BITS_PER_UNIT);
if (ishighonly) if (ishighonly)
set = gen_rtx_SET (mode, operand0, temp); set = gen_rtx_SET (mode, operand0, temp);
else else
...@@ -4829,7 +4978,13 @@ print_operand (FILE *file, rtx x, int code) ...@@ -4829,7 +4978,13 @@ print_operand (FILE *file, rtx x, int code)
fputs (",ma", file); fputs (",ma", file);
break; break;
case PLUS: 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) || GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
{ {
if (ASSEMBLER_DIALECT == 0) if (ASSEMBLER_DIALECT == 0)
...@@ -4905,20 +5060,33 @@ print_operand (FILE *file, rtx x, int code) ...@@ -4905,20 +5060,33 @@ print_operand (FILE *file, rtx x, int code)
base = XEXP (XEXP (x, 0), 0); base = XEXP (XEXP (x, 0), 0);
fprintf (file, "%d(%s)", size, reg_names [REGNO (base)]); fprintf (file, "%d(%s)", size, reg_names [REGNO (base)]);
break; break;
default: case PLUS:
if (GET_CODE (XEXP (x, 0)) == PLUS if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
fprintf (file, "%s(%s)", fprintf (file, "%s(%s)",
reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0))], reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0))],
reg_names [REGNO (XEXP (XEXP (x, 0), 1))]); reg_names [REGNO (XEXP (XEXP (x, 0), 1))]);
else if (GET_CODE (XEXP (x, 0)) == PLUS else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
fprintf (file, "%s(%s)", fprintf (file, "%s(%s)",
reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 1), 0))], reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 1), 0))],
reg_names [REGNO (XEXP (XEXP (x, 0), 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 else
output_address (XEXP (x, 0)); output_address (XEXP (x, 0));
break; break;
default:
output_address (XEXP (x, 0));
break;
} }
} }
else else
...@@ -7844,32 +8012,33 @@ shadd_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -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 (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 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 if (GET_CODE (op) != REG)
generally isn't a win on the PA, so avoid creating unscaled
indexed addresses until after cse is finished. */
if (!cse_not_expected)
return 0; return 0;
/* Allow any register when TARGET_NO_SPACE_REGS is in effect since /* We must reject virtual registers as the only expressions that
we don't have to worry about the braindamaged implicit space can be instantiated are REG and REG+CONST. */
register selection from the basereg. */ if (op == virtual_incoming_args_rtx
if (TARGET_NO_SPACE_REGS) || op == virtual_stack_vars_rtx
return (GET_CODE (op) == REG); || 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 /* While it's always safe to index off the frame pointer, it's not
always profitable, particularly when the frame pointer is being profitable to do so when the frame pointer is being eliminated. */
eliminated. */ if (!reload_completed
if (! flag_omit_frame_pointer && op == frame_pointer_rtx) && flag_omit_frame_pointer
return 1; && !current_function_calls_alloca
&& op == frame_pointer_rtx)
return 0;
return (GET_CODE (op) == REG return register_operand (op, mode);
&& REG_POINTER (op)
&& register_operand (op, mode));
} }
/* Return 1 if this operand is anything other than a hard register. */ /* 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); ...@@ -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. */ in some cases it is preferable to use a more restrictive class. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS) #define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
/* Return the register class of a scratch register needed to copy IN into /* Return the register class of a scratch register needed to copy
or out of a register in CLASS in MODE. If it can be done directly IN into a register in CLASS in MODE, or a register in CLASS in MODE
NO_REGS is returned. to IN. If it can be done directly NO_REGS is returned.
Avoid doing any work for the common case calls. */ Avoid doing any work for the common case calls. */
...@@ -1199,83 +1199,87 @@ extern int may_call_alloca; ...@@ -1199,83 +1199,87 @@ extern int may_call_alloca;
|| cint_ok_for_move (INTVAL (X)))) \ || cint_ok_for_move (INTVAL (X)))) \
&& !function_label_operand (X, VOIDmode)) && !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 Return 1 iff OP is a pseudo which did not get a hard register and
we are running the reload pass. */ we are running the reload pass. */
#define IS_RELOADING_PSEUDO_P(OP) \ #define IS_RELOADING_PSEUDO_P(OP) \
((reload_in_progress \ ((reload_in_progress \
&& GET_CODE (OP) == REG \ && GET_CODE (OP) == REG \
&& REGNO (OP) >= FIRST_PSEUDO_REGISTER \ && REGNO (OP) >= FIRST_PSEUDO_REGISTER \
&& reg_renumber [REGNO (OP)] < 0)) && 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. /* Optional extra constraints for this machine. Borrowed from sparc.h.
For the HPPA, `Q' means that this is a memory operand but not a `A' is a LO_SUM DLT memory operand.
symbolic memory operand. Note that an unassigned pseudo register
is such a memory operand. Needed because reload will generate `Q' is any memory operand that isn't a symbolic, indexed or lo_sum
these things in insns and then not re-recognize the insns, causing memory operand. Note that an unassigned pseudo register is such a
constrain_operands to fail. 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. `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) \ #define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? \ ((C) == 'Q' ? \
(IS_RELOADING_PSEUDO_P (OP) \ (IS_RELOADING_PSEUDO_P (OP) \
|| (GET_CODE (OP) == MEM \ || (GET_CODE (OP) == MEM \
&& (memory_address_p (GET_MODE (OP), XEXP (OP, 0))\ && (reload_in_progress \
|| reload_in_progress) \ || memory_address_p (GET_MODE (OP), XEXP (OP, 0))) \
&& ! symbolic_memory_operand (OP, VOIDmode) \ && !symbolic_memory_operand (OP, VOIDmode) \
&& !(GET_CODE (XEXP (OP, 0)) == PLUS \ && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \
&& (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT\ && !IS_INDEX_ADDR_P (XEXP (OP, 0)))) \
|| GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT))))\ : ((C) == 'A' ? \
(GET_CODE (OP) == MEM \
&& IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0))) \
: ((C) == 'R' ? \ : ((C) == 'R' ? \
(GET_CODE (OP) == MEM \ (GET_CODE (OP) == MEM \
&& GET_CODE (XEXP (OP, 0)) == PLUS \ && IS_INDEX_ADDR_P (XEXP (OP, 0))) \
&& (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' ? \ : ((C) == 'T' ? \
(GET_CODE (OP) == MEM \ (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 \ /* Using DFmode forces only short displacements \
to be recognized as valid in reg+d addresses. \ 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. \ it has long FP loads/stores. \
\ \
FIXME: the ELF32 linker clobbers the LSB of \ FIXME: the ELF32 linker clobbers the LSB of \
the FP register number in {fldw,fstw} insns. \ the FP register number in {fldw,fstw} insns. \
Thus, we only allow long FP loads/stores on \ Thus, we only allow long FP loads/stores on \
TARGET_64BIT. */ \ TARGET_64BIT. */ \
&& memory_address_p ((TARGET_PA_20 \ && memory_address_p ((TARGET_PA_20 && !TARGET_ELF32 \
&& !TARGET_ELF32 \
? GET_MODE (OP) \ ? GET_MODE (OP) \
: DFmode), \ : DFmode), \
XEXP (OP, 0)) \ 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' ? \ : ((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 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
...@@ -1311,16 +1315,53 @@ extern int may_call_alloca; ...@@ -1311,16 +1315,53 @@ extern int may_call_alloca;
#endif #endif
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
that is a valid memory address for an instruction. valid memory address for an instruction. The MODE argument is the
The MODE argument is the machine mode for the MEM expression machine mode for the MEM expression that wants to use this address.
that wants to use this address.
On HP PA-RISC, the legitimate address forms are REG+SMALLINT,
On the HP-PA, the actual legitimate addresses must be REG+REG, and REG+(REG*SCALE). The indexed address forms are only
REG+REG, REG+(REG*SCALE) or REG+SMALLINT. available with floating point loads and stores, and integer loads.
But we can treat a SYMBOL_REF as legitimate if it is part of this We get better code by allowing indexed addresses in the initial
function's constant-pool, because such addresses can actually RTL generation.
be output as REG+SMALLINT.
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; 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 doing so avoids losing for loading/storing a FP register at an address
...@@ -1338,6 +1379,21 @@ extern int may_call_alloca; ...@@ -1338,6 +1379,21 @@ extern int may_call_alloca;
#define VAL_14_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x2000 < 0x4000) #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 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) \ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \ { \
if ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \ if ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
...@@ -1349,33 +1405,47 @@ extern int may_call_alloca; ...@@ -1349,33 +1405,47 @@ extern int may_call_alloca;
else if (GET_CODE (X) == PLUS) \ else if (GET_CODE (X) == PLUS) \
{ \ { \
rtx base = 0, index = 0; \ rtx base = 0, index = 0; \
if (REG_P (XEXP (X, 0)) \ if (REG_P (XEXP (X, 1)) \
&& 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))) \ && REG_OK_FOR_BASE_P (XEXP (X, 1))) \
base = XEXP (X, 1), index = XEXP (X, 0); \ base = XEXP (X, 1), index = XEXP (X, 0); \
if (base != 0) \ else if (REG_P (XEXP (X, 0)) \
if (GET_CODE (index) == CONST_INT \ && 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) \ && ((INT_14_BITS (index) \
&& (TARGET_SOFT_FLOAT \ && (TARGET_SOFT_FLOAT \
|| (TARGET_PA_20 \ || (TARGET_PA_20 \
&& ((MODE == SFmode \ && ((MODE == SFmode \
&& (INTVAL (index) % 4) == 0)\ && (INTVAL (index) % 4) == 0) \
|| (MODE == DFmode \ || (MODE == DFmode \
&& (INTVAL (index) % 8) == 0)))\ && (INTVAL (index) % 8) == 0))) \
|| ((MODE) != SFmode && (MODE) != DFmode))) \ || ((MODE) != SFmode && (MODE) != DFmode))) \
|| INT_5_BITS (index))) \ || INT_5_BITS (index))) \
goto ADDR; \ goto ADDR; \
if (! TARGET_SOFT_FLOAT \ if (!TARGET_DISABLE_INDEXING \
&& ! 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 \ && base \
&& ((MODE) == SFmode || (MODE) == DFmode) \
&& GET_CODE (index) == MULT \ && GET_CODE (index) == MULT \
&& GET_CODE (XEXP (index, 0)) == REG \ && MODE_OK_FOR_SCALED_INDEXING_P (MODE) \
&& REG_OK_FOR_BASE_P (XEXP (index, 0)) \ && 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 \ && 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; \ goto ADDR; \
} \ } \
else if (GET_CODE (X) == LO_SUM \ else if (GET_CODE (X) == LO_SUM \
...@@ -1383,25 +1453,23 @@ extern int may_call_alloca; ...@@ -1383,25 +1453,23 @@ extern int may_call_alloca;
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \ && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
&& CONSTANT_P (XEXP (X, 1)) \ && CONSTANT_P (XEXP (X, 1)) \
&& (TARGET_SOFT_FLOAT \ && (TARGET_SOFT_FLOAT \
/* We can allow symbolic LO_SUM addresses\ /* We can allow symbolic LO_SUM addresses for PA2.0. */ \
for PA2.0. */ \
|| (TARGET_PA_20 \ || (TARGET_PA_20 \
&& !TARGET_ELF32 \ && !TARGET_ELF32 \
&& GET_CODE (XEXP (X, 1)) != CONST_INT)\ && GET_CODE (XEXP (X, 1)) != CONST_INT) \
|| ((MODE) != SFmode \ || ((MODE) != SFmode \
&& (MODE) != DFmode))) \ && (MODE) != DFmode))) \
goto ADDR; \ goto ADDR; \
else if (GET_CODE (X) == LO_SUM \ else if (GET_CODE (X) == LO_SUM \
&& GET_CODE (XEXP (X, 0)) == SUBREG \ && GET_CODE (XEXP (X, 0)) == SUBREG \
&& GET_CODE (SUBREG_REG (XEXP (X, 0))) == REG\ && GET_CODE (SUBREG_REG (XEXP (X, 0))) == REG \
&& REG_OK_FOR_BASE_P (SUBREG_REG (XEXP (X, 0)))\ && REG_OK_FOR_BASE_P (SUBREG_REG (XEXP (X, 0))) \
&& CONSTANT_P (XEXP (X, 1)) \ && CONSTANT_P (XEXP (X, 1)) \
&& (TARGET_SOFT_FLOAT \ && (TARGET_SOFT_FLOAT \
/* We can allow symbolic LO_SUM addresses\ /* We can allow symbolic LO_SUM addresses for PA2.0. */ \
for PA2.0. */ \
|| (TARGET_PA_20 \ || (TARGET_PA_20 \
&& !TARGET_ELF32 \ && !TARGET_ELF32 \
&& GET_CODE (XEXP (X, 1)) != CONST_INT)\ && GET_CODE (XEXP (X, 1)) != CONST_INT) \
|| ((MODE) != SFmode \ || ((MODE) != SFmode \
&& (MODE) != DFmode))) \ && (MODE) != DFmode))) \
goto ADDR; \ goto ADDR; \
...@@ -1872,16 +1940,17 @@ do { \ ...@@ -1872,16 +1940,17 @@ do { \
#define JMP_BUF_SIZE 50 #define JMP_BUF_SIZE 50
#define PREDICATE_CODES \ #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, \ {"call_operand_address", {LABEL_REF, SYMBOL_REF, CONST_INT, \
CONST_DOUBLE, CONST, HIGH, CONSTANT_P_RTX}}, \ CONST_DOUBLE, CONST, HIGH, CONSTANT_P_RTX}}, \
{"indexed_memory_operand", {SUBREG, MEM}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \ {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"symbolic_memory_operand", {SUBREG, MEM}}, \ {"symbolic_memory_operand", {SUBREG, MEM}}, \
{"reg_before_reload_operand", {REG, 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, \ {"reg_or_0_or_nonsymb_mem_operand", {SUBREG, REG, MEM, CONST_INT, \
CONST_DOUBLE}}, \ 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}}, \ {"reg_or_cint_move_operand", {SUBREG, REG, CONST_INT}}, \
{"pic_label_operand", {LABEL_REF, CONST}}, \ {"pic_label_operand", {LABEL_REF, CONST}}, \
{"fp_reg_operand", {REG}}, \ {"fp_reg_operand", {REG}}, \
...@@ -1905,7 +1974,6 @@ do { \ ...@@ -1905,7 +1974,6 @@ do { \
{"pc_or_label_operand", {PC, LABEL_REF}}, \ {"pc_or_label_operand", {PC, LABEL_REF}}, \
{"plus_xor_ior_operator", {PLUS, XOR, IOR}}, \ {"plus_xor_ior_operator", {PLUS, XOR, IOR}}, \
{"shadd_operand", {CONST_INT}}, \ {"shadd_operand", {CONST_INT}}, \
{"basereg_operand", {REG}}, \
{"div_operand", {REG, CONST_INT}}, \ {"div_operand", {REG, CONST_INT}}, \
{"ireg_operand", {REG}}, \ {"ireg_operand", {REG}}, \
{"cmpib_comparison_operator", {EQ, NE, LT, LE, LEU, \ {"cmpib_comparison_operator", {EQ, NE, LT, LE, LEU, \
......
...@@ -2263,13 +2263,13 @@ ...@@ -2263,13 +2263,13 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" [(set (match_operand:SI 0 "move_dest_operand"
"=r,r,r,r,r,r,Q,!*q,!f,f,*TR") "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
(match_operand:SI 1 "move_operand" (match_operand:SI 1 "move_src_operand"
"A,r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))] "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
"(register_operand (operands[0], SImode) "(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode)) || reg_or_0_operand (operands[1], SImode))
&& ! TARGET_SOFT_FLOAT" && !TARGET_SOFT_FLOAT"
"@ "@
ldw RT'%A1,%0 ldw RT'%A1,%0
copy %1,%0 copy %1,%0
...@@ -2287,9 +2287,154 @@ ...@@ -2287,9 +2287,154 @@
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")]) (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
(define_insn "" (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") "=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"))] "A,r,J,N,K,RQ,rM,!rM"))]
"(register_operand (operands[0], SImode) "(register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode)) || reg_or_0_operand (operands[1], SImode))
...@@ -2307,26 +2452,32 @@ ...@@ -2307,26 +2452,32 @@
(set_attr "pa_combine_type" "addmove") (set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4,4,4")]) (set_attr "length" "4,4,4,4,4,4,4,4")])
;; Load or store with base-register modification.
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r") (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
(match_operand:SI 2 "register_operand" "r"))))] (match_operand:DI 2 "int5_operand" "L"))))
"! TARGET_DISABLE_INDEXING" (set (match_dup 1)
"{ldwx|ldw} %2(%1),%0" (plus:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"ldw,mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
; And a zero extended variant.
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") (zero_extend:DI (mem:SI
(match_operand:SI 2 "basereg_operand" "r"))))] (plus:DI
"! TARGET_DISABLE_INDEXING" (match_operand:DI 1 "register_operand" "+r")
"{ldwx|ldw} %1(%2),%0" (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 "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
;; Load or store with base-register modification.
(define_expand "pre_load" (define_expand "pre_load"
[(parallel [(set (match_operand:SI 0 "register_operand" "") [(parallel [(set (match_operand:SI 0 "register_operand" "")
(mem (plus (match_operand 1 "register_operand" "") (mem (plus (match_operand 1 "register_operand" "")
...@@ -2715,8 +2866,10 @@ ...@@ -2715,8 +2866,10 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,!*q,!*f") [(set (match_operand:HI 0 "move_dest_operand"
(match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,!rM,!*fM"))] "=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) "register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode)" || reg_or_0_operand (operands[1], HImode)"
"@ "@
...@@ -2734,31 +2887,37 @@ ...@@ -2734,31 +2887,37 @@
(define_insn "" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
(mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r") (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
(match_operand:SI 2 "register_operand" "r"))))] (match_operand:SI 2 "int5_operand" "L"))))
"! TARGET_DISABLE_INDEXING" (set (match_dup 1)
"{ldhx|ldh} %2(%1),%0" (plus:SI (match_dup 1) (match_dup 2)))]
""
"{ldhs|ldh},mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r") [(set (match_operand:HI 0 "register_operand" "=r")
(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r") (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
(match_operand:SI 2 "basereg_operand" "r"))))] (match_operand:DI 2 "int5_operand" "L"))))
"! TARGET_DISABLE_INDEXING" (set (match_dup 1)
"{ldhx|ldh} %1(%2),%0" (plus:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"ldh,mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
; Now zero extended variants. ; And a zero extended variant.
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:SI (mem:HI (zero_extend:DI (mem:HI
(plus:SI (plus:DI
(match_operand:SI 1 "basereg_operand" "r") (match_operand:DI 1 "register_operand" "+r")
(match_operand:SI 2 "register_operand" "r")))))] (match_operand:DI 2 "int5_operand" "L")))))
"! TARGET_DISABLE_INDEXING" (set (match_dup 1)
"{ldhx|ldh} %2(%1),%0" (plus:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT"
"ldh,mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
...@@ -2766,17 +2925,8 @@ ...@@ -2766,17 +2925,8 @@
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (mem:HI (zero_extend:SI (mem:HI
(plus:SI (plus:SI
(match_operand:SI 1 "register_operand" "r") (match_operand:SI 1 "register_operand" "+r")
(match_operand:SI 2 "basereg_operand" "r")))))] (match_operand:SI 2 "int5_operand" "L")))))
"! 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"))))
(set (match_dup 1) (set (match_dup 1)
(plus:SI (match_dup 1) (match_dup 2)))] (plus:SI (match_dup 1) (match_dup 2)))]
"" ""
...@@ -2784,17 +2934,16 @@ ...@@ -2784,17 +2934,16 @@
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
; And a zero extended variant.
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (mem:HI (zero_extend:SI (mem:HI
(plus:SI (plus:DI
(match_operand:SI 1 "register_operand" "+r") (match_operand:DI 1 "register_operand" "+r")
(match_operand:SI 2 "int5_operand" "L"))))) (match_operand:DI 2 "int5_operand" "L")))))
(set (match_dup 1) (set (match_dup 1)
(plus:SI (match_dup 1) (match_dup 2)))] (plus:DI (match_dup 1) (match_dup 2)))]
"" "TARGET_64BIT"
"{ldhs|ldh},mb %2(%1),%0" "ldh,mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
...@@ -2810,6 +2959,17 @@ ...@@ -2810,6 +2959,17 @@
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "" (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") [(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (match_operand:HI 1 "register_operand" "r") (plus:HI (match_operand:HI 1 "register_operand" "r")
(match_operand 2 "const_int_operand" "J")))] (match_operand 2 "const_int_operand" "J")))]
...@@ -2830,8 +2990,10 @@ ...@@ -2830,8 +2990,10 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,!*q,!*f") [(set (match_operand:QI 0 "move_dest_operand"
(match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,!rM,!*fM"))] "=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) "register_operand (operands[0], QImode)
|| reg_or_0_operand (operands[1], QImode)" || reg_or_0_operand (operands[1], QImode)"
"@ "@
...@@ -2849,86 +3011,55 @@ ...@@ -2849,86 +3011,55 @@
(define_insn "" (define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r") [(set (match_operand:QI 0 "register_operand" "=r")
(mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r") (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
(match_operand:SI 2 "register_operand" "r"))))] (match_operand:SI 2 "int5_operand" "L"))))
"! TARGET_DISABLE_INDEXING" (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
"{ldbx|ldb} %2(%1),%0" ""
"{ldbs|ldb},mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "" (define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r") [(set (match_operand:QI 0 "register_operand" "=r")
(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r") (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
(match_operand:SI 2 "basereg_operand" "r"))))] (match_operand:DI 2 "int5_operand" "L"))))
"! TARGET_DISABLE_INDEXING" (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
"{ldbx|ldb} %1(%2),%0" "TARGET_64BIT"
"ldb,mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
; Indexed byte load with zero extension to SImode or HImode. ; Now the same thing with zero extensions.
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:SI (mem:QI (zero_extend:DI (mem:QI (plus:DI
(plus:SI (match_operand:DI 1 "register_operand" "+r")
(match_operand:SI 1 "basereg_operand" "r") (match_operand:DI 2 "int5_operand" "L")))))
(match_operand:SI 2 "register_operand" "r")))))] (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
"! TARGET_DISABLE_INDEXING" "TARGET_64BIT"
"{ldbx|ldb} %2(%1),%0" "ldb,mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (mem:QI (zero_extend:SI (mem:QI (plus:SI
(plus:SI (match_operand:SI 1 "register_operand" "+r")
(match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "int5_operand" "L")))))
(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"))))
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
"" ""
"{ldbs|ldb},mb %2(%1),%0" "{ldbs|ldb},mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
; Now the same thing with zero extensions.
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (mem:QI (plus:SI (zero_extend:SI (mem:QI (plus:DI
(match_operand:SI 1 "register_operand" "+r") (match_operand:DI 1 "register_operand" "+r")
(match_operand:SI 2 "int5_operand" "L"))))) (match_operand:DI 2 "int5_operand" "L")))))
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))] (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
"" "TARGET_64BIT"
"{ldbs|ldb},mb %2(%1),%0" "ldb,mb %2(%1),%0"
[(set_attr "type" "load") [(set_attr "type" "load")
(set_attr "length" "4")]) (set_attr "length" "4")])
...@@ -2944,6 +3075,17 @@ ...@@ -2944,6 +3075,17 @@
(set_attr "length" "4")]) (set_attr "length" "4")])
(define_insn "" (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") [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "int5_operand" "L"))) (match_operand:SI 1 "int5_operand" "L")))
(match_operand:QI 2 "reg_or_0_operand" "rM")) (match_operand:QI 2 "reg_or_0_operand" "rM"))
...@@ -2954,6 +3096,17 @@ ...@@ -2954,6 +3096,17 @@
[(set_attr "type" "store") [(set_attr "type" "store")
(set_attr "length" "4")]) (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, ;; The definition of this insn does not really explain what it does,
;; but it should suffice that anything generated as this insn will be ;; but it should suffice that anything generated as this insn will be
;; recognized as a movstrsi operation, and that it will not successfully ;; recognized as a movstrsi operation, and that it will not successfully
...@@ -3503,7 +3656,7 @@ ...@@ -3503,7 +3656,7 @@
"GET_CODE (operands[1]) == CONST_DOUBLE "GET_CODE (operands[1]) == CONST_DOUBLE
&& operands[1] != CONST0_RTX (DFmode) && operands[1] != CONST0_RTX (DFmode)
&& !TARGET_64BIT && !TARGET_64BIT
&& ! TARGET_SOFT_FLOAT" && !TARGET_SOFT_FLOAT"
"* return (which_alternative == 0 ? output_move_double (operands) "* return (which_alternative == 0 ? output_move_double (operands)
: \"fldd%F1 %1,%0\");" : \"fldd%F1 %1,%0\");"
[(set_attr "type" "move,fpload") [(set_attr "type" "move,fpload")
...@@ -3556,16 +3709,16 @@ ...@@ -3556,16 +3709,16 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" [(set (match_operand:DF 0 "move_dest_operand"
"=f,*r,RQ,?o,?Q,f,*r,*r") "=f,*r,Q,?o,?Q,f,*r,*r")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
"fG,*rG,f,*r,*r,RQ,o,RQ"))] "fG,*rG,f,*r,*r,RQ,o,RQ"))]
"(register_operand (operands[0], DFmode) "(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], 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) && GET_CODE (operands[0]) == MEM)
&& ! TARGET_64BIT && !TARGET_64BIT
&& ! TARGET_SOFT_FLOAT" && !TARGET_SOFT_FLOAT"
"* "*
{ {
if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
...@@ -3577,13 +3730,156 @@ ...@@ -3577,13 +3730,156 @@
(set_attr "length" "4,8,4,8,16,4,8,16")]) (set_attr "length" "4,8,4,8,16,4,8,16")])
(define_insn "" (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") "=r,?o,?Q,r,r")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" (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) "(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode)) || reg_or_0_operand (operands[1], DFmode))
&& ! TARGET_64BIT && !TARGET_64BIT
&& TARGET_SOFT_FLOAT" && TARGET_SOFT_FLOAT"
"* "*
{ {
...@@ -3593,13 +3889,13 @@ ...@@ -3593,13 +3889,13 @@
(set_attr "length" "8,8,16,8,16")]) (set_attr "length" "8,8,16,8,16")])
(define_insn "" (define_insn ""
[(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" [(set (match_operand:DF 0 "move_dest_operand"
"=r,r,r,r,r,Q,!*q,!f,f,*TR") "=!*r,*r,*r,*r,*r,Q,!*q,f,f,T")
(match_operand:DF 1 "move_operand" (match_operand:DF 1 "move_src_operand"
"r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))] "!*r,J,N,K,RQ,*rM,!*rM,fM,RT,f"))]
"(register_operand (operands[0], DFmode) "(register_operand (operands[0], DFmode)
|| reg_or_0_operand (operands[1], DFmode)) || reg_or_0_operand (operands[1], DFmode))
&& ! TARGET_SOFT_FLOAT && TARGET_64BIT" && !TARGET_SOFT_FLOAT && TARGET_64BIT"
"@ "@
copy %1,%0 copy %1,%0
ldi %1,%0 ldi %1,%0
...@@ -3615,44 +3911,9 @@ ...@@ -3615,44 +3911,9 @@
(set_attr "pa_combine_type" "addmove") (set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4,4,4,4,4")]) (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" (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" ""))] (match_operand:DI 1 "general_operand" ""))]
"" ""
" "
...@@ -3733,14 +3994,14 @@ ...@@ -3733,14 +3994,14 @@
(set_attr "length" "8")]) (set_attr "length" "8")])
(define_insn "" (define_insn ""
[(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" [(set (match_operand:DI 0 "move_dest_operand"
"=r,o,Q,r,r,r,f,f,*TR") "=r,o,Q,r,r,r,*f,*f,T")
(match_operand:DI 1 "general_operand" (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) "(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode)) || reg_or_0_operand (operands[1], DImode))
&& ! TARGET_64BIT && !TARGET_64BIT
&& ! TARGET_SOFT_FLOAT" && !TARGET_SOFT_FLOAT"
"* "*
{ {
if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
...@@ -3752,13 +4013,13 @@ ...@@ -3752,13 +4013,13 @@
(set_attr "length" "8,8,16,8,16,16,4,4,4")]) (set_attr "length" "8,8,16,8,16,16,4,4,4")])
(define_insn "" (define_insn ""
[(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" [(set (match_operand:DI 0 "move_dest_operand"
"=r,r,r,r,r,r,Q,!*q,!f,f,*TR") "=r,r,r,r,r,r,Q,!*q,!*f,*f,T")
(match_operand:DI 1 "move_operand" (match_operand:DI 1 "move_src_operand"
"A,r,J,N,K,RQ,rM,!rM,!fM,*RT,f"))] "A,r,J,N,K,RQ,rM,!rM,!*fM,RT,*f"))]
"(register_operand (operands[0], DImode) "(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode)) || reg_or_0_operand (operands[1], DImode))
&& ! TARGET_SOFT_FLOAT && TARGET_64BIT" && !TARGET_SOFT_FLOAT && TARGET_64BIT"
"@ "@
ldd RT'%A1,%0 ldd RT'%A1,%0
copy %1,%0 copy %1,%0
...@@ -3776,13 +4037,93 @@ ...@@ -3776,13 +4037,93 @@
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")]) (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
(define_insn "" (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") "=r,o,Q,r,r,r")
(match_operand:DI 1 "general_operand" (match_operand:DI 1 "general_operand"
"rM,r,r,o,Q,i"))] "rM,r,r,o,Q,i"))]
"(register_operand (operands[0], DImode) "(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode)) || reg_or_0_operand (operands[1], DImode))
&& ! TARGET_64BIT && !TARGET_64BIT
&& TARGET_SOFT_FLOAT" && TARGET_SOFT_FLOAT"
"* "*
{ {
...@@ -3873,26 +4214,169 @@ ...@@ -3873,26 +4214,169 @@
}") }")
(define_insn "" (define_insn ""
[(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" [(set (match_operand:SF 0 "move_dest_operand"
"=f,r,f,r,RQ,Q") "=f,!*r,f,*r,Q,Q")
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" (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) "(register_operand (operands[0], SFmode)
|| reg_or_0_operand (operands[1], SFmode)) || reg_or_0_operand (operands[1], SFmode))
&& ! TARGET_SOFT_FLOAT" && !TARGET_SOFT_FLOAT"
"@ "@
fcpy,sgl %f1,%0 fcpy,sgl %f1,%0
copy %r1,%0 copy %r1,%0
fldw%F1 %1,%0 fldw%F1 %1,%0
ldw%M1 %1,%0 ldw%M1 %1,%0
fstw%F0 %r1,%0 fstw%F0 %1,%0
stw%M0 %r1,%0" stw%M0 %r1,%0"
[(set_attr "type" "fpalu,move,fpload,load,fpstore,store") [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
(set_attr "pa_combine_type" "addmove") (set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4,4,4,4")]) (set_attr "length" "4,4,4,4,4,4")])
(define_insn "" (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") "=r,r,Q")
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
"rG,RQ,rG"))] "rG,RQ,rG"))]
...@@ -3907,41 +4391,6 @@ ...@@ -3907,41 +4391,6 @@
(set_attr "pa_combine_type" "addmove") (set_attr "pa_combine_type" "addmove")
(set_attr "length" "4,4,4")]) (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 ;;- zero extension instructions
...@@ -3950,24 +4399,6 @@ ...@@ -3950,24 +4399,6 @@
;; memory operands. This gives us better overall code than just ;; memory operands. This gives us better overall code than just
;; having a pattern that does or does not accept memory operands. ;; 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" (define_expand "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "") [(set (match_operand:HI 0 "register_operand" "")
(zero_extend:HI (zero_extend:HI
...@@ -3978,7 +4409,7 @@ ...@@ -3978,7 +4409,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r") [(set (match_operand:HI 0 "register_operand" "=r,r")
(zero_extend:HI (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" "GET_CODE (operands[1]) != CONST_INT"
"@ "@
{extru|extrw,u} %1,31,8,%0 {extru|extrw,u} %1,31,8,%0
...@@ -3996,7 +4427,7 @@ ...@@ -3996,7 +4427,7 @@
(define_insn "" (define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r") [(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (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" "GET_CODE (operands[1]) != CONST_INT"
"@ "@
{extru|extrw,u} %1,31,8,%0 {extru|extrw,u} %1,31,8,%0
...@@ -4004,29 +4435,77 @@ ...@@ -4004,29 +4435,77 @@
[(set_attr "type" "shift,load") [(set_attr "type" "shift,load")
(set_attr "length" "4,4")]) (set_attr "length" "4,4")])
(define_insn "zero_extendqidi2" (define_expand "zero_extendhisi2"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "")
(zero_extend:DI (match_operand:QI 1 "register_operand" "r")))] (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" "TARGET_64BIT"
"extrd,u %1,63,8,%0" "")
[(set_attr "type" "shift")
(set_attr "length" "4")])
(define_insn "zero_extendhidi2" (define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (match_operand:HI 1 "register_operand" "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" "TARGET_64BIT"
"extrd,u %1,63,16,%0" "")
[(set_attr "type" "shift")
(set_attr "length" "4")])
(define_insn "zero_extendsidi2" (define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (match_operand:SI 1 "register_operand" "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" "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 ;;- sign extension instructions
...@@ -4331,7 +4810,7 @@ ...@@ -4331,7 +4810,7 @@
(match_operand:DI 2 "arith_operand" "r,J")))] (match_operand:DI 2 "arith_operand" "r,J")))]
"TARGET_64BIT" "TARGET_64BIT"
"@ "@
{addl|add,l} %1,%2,%0 add,l %1,%2,%0
ldo %2(%1),%0" ldo %2(%1),%0"
[(set_attr "type" "binary,binary") [(set_attr "type" "binary,binary")
(set_attr "pa_combine_type" "addmove") (set_attr "pa_combine_type" "addmove")
...@@ -4496,8 +4975,8 @@ ...@@ -4496,8 +4975,8 @@
;; The mulsi3 insns set up registers for the millicode call. ;; The mulsi3 insns set up registers for the millicode call.
(define_expand "mulsi3" (define_expand "mulsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_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))) (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3)) (clobber (match_dup 3))
(clobber (reg:SI 26)) (clobber (reg:SI 26))
...@@ -4508,14 +4987,15 @@ ...@@ -4508,14 +4987,15 @@
" "
{ {
operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31); 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); rtx scratch = gen_reg_rtx (DImode);
operands[1] = force_reg (SImode, operands[1]); operands[1] = force_reg (SImode, operands[1]);
operands[2] = force_reg (SImode, operands[2]); operands[2] = force_reg (SImode, operands[2]);
emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2])); emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
emit_insn (gen_rtx_SET (VOIDmode, operands[0], emit_insn (gen_movsi (operands[0],
gen_rtx_SUBREG (SImode, scratch, GET_MODE_SIZE (SImode)))); gen_rtx_SUBREG (SImode, scratch,
GET_MODE_SIZE (SImode))));
DONE; DONE;
} }
operands[3] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode);
...@@ -4620,8 +5100,8 @@ ...@@ -4620,8 +5100,8 @@
;;; Division and mod. ;;; Division and mod.
(define_expand "divsi3" (define_expand "divsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_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))) (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3)) (clobber (match_dup 3))
(clobber (match_dup 4)) (clobber (match_dup 4))
...@@ -4676,8 +5156,8 @@ ...@@ -4676,8 +5156,8 @@
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
(define_expand "udivsi3" (define_expand "udivsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_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))) (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3)) (clobber (match_dup 3))
(clobber (match_dup 4)) (clobber (match_dup 4))
...@@ -4733,8 +5213,8 @@ ...@@ -4733,8 +5213,8 @@
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
(define_expand "modsi3" (define_expand "modsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_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))) (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3)) (clobber (match_dup 3))
(clobber (match_dup 4)) (clobber (match_dup 4))
...@@ -4785,8 +5265,8 @@ ...@@ -4785,8 +5265,8 @@
(set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))]) (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
(define_expand "umodsi3" (define_expand "umodsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" "")) [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_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))) (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
(clobber (match_dup 3)) (clobber (match_dup 3))
(clobber (match_dup 4)) (clobber (match_dup 4))
...@@ -8274,11 +8754,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" ...@@ -8274,11 +8754,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; Clean up turds left by reload. ;; Clean up turds left by reload.
(define_peephole (define_peephole
[(set (match_operand 0 "reg_or_nonsymb_mem_operand" "") [(set (match_operand 0 "move_dest_operand" "")
(match_operand 1 "register_operand" "fr")) (match_operand 1 "register_operand" "fr"))
(set (match_operand 2 "register_operand" "fr") (set (match_operand 2 "register_operand" "fr")
(match_dup 0))] (match_dup 0))]
"! TARGET_SOFT_FLOAT "!TARGET_SOFT_FLOAT
&& GET_CODE (operands[0]) == MEM && GET_CODE (operands[0]) == MEM
&& ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[0])
&& GET_MODE (operands[0]) == GET_MODE (operands[1]) && GET_MODE (operands[0]) == GET_MODE (operands[1])
...@@ -8314,10 +8794,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" ...@@ -8314,10 +8794,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(define_peephole (define_peephole
[(set (match_operand 0 "register_operand" "fr") [(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") (set (match_operand 2 "register_operand" "fr")
(match_dup 1))] (match_dup 1))]
"! TARGET_SOFT_FLOAT "!TARGET_SOFT_FLOAT
&& GET_CODE (operands[1]) == MEM && GET_CODE (operands[1]) == MEM
&& ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[1])
&& GET_MODE (operands[0]) == GET_MODE (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