Commit b4a58f80 by Richard Earnshaw Committed by Richard Earnshaw

arm.c (arm_const_double_by_parts): New function.

	* arm.c (arm_const_double_by_parts): New function.
	* arm-protos.h (arm_const_double_by_parts): Add prototype.
	* arm.md (define_split for 64-bit constants): Add another one.

From-SVN: r97828
parent 3623aa70
2005-04-08 Richard Earnshaw <richard.earnshaw@arm.com>
* arm.c (arm_const_double_by_parts): New function.
* arm-protos.h (arm_const_double_by_parts): Add prototype.
* arm.md (define_split for 64-bit constants): Add another one.
2005-04-08 Andrew MacLeod <amacleod@redhat.com>
* tree-ssa-operands.c (correct_use_link): Remove linear scan.
......
......@@ -91,6 +91,7 @@ extern rtx arm_gen_return_addr_mask (void);
extern void arm_reload_in_hi (rtx *);
extern void arm_reload_out_hi (rtx *);
extern int arm_const_double_inline_cost (rtx);
extern bool arm_const_double_by_parts (rtx);
extern const char *fp_immediate_constant (rtx);
extern const char *output_call (rtx *);
extern const char *output_call_mem (rtx *);
......
......@@ -7418,6 +7418,41 @@ arm_const_double_inline_cost (rtx val)
NULL_RTX, NULL_RTX, 0, 0));
}
/* Return true if it is worthwile to split a 64-bit constant into two
32-bit operations. This is the case if optimizing for size, or
if we have load delay slots, or if one 32-bit part can be done with
a single data operation. */
bool
arm_const_double_by_parts (rtx val)
{
enum machine_mode mode = GET_MODE (val);
rtx part;
if (optimize_size || arm_ld_sched)
return true;
if (mode == VOIDmode)
mode = DImode;
part = gen_highpart_mode (SImode, mode, val);
gcc_assert (GET_CODE (part) == CONST_INT);
if (const_ok_for_arm (INTVAL (part))
|| const_ok_for_arm (~INTVAL (part)))
return true;
part = gen_lowpart (SImode, val);
gcc_assert (GET_CODE (part) == CONST_INT);
if (const_ok_for_arm (INTVAL (part))
|| const_ok_for_arm (~INTVAL (part)))
return true;
return false;
}
/* Scan INSN and note any of its operands that need fixing.
If DO_PUSHES is false we do not actually push any of the fixups
needed. The function returns TRUE if any fixups were needed/pushed.
......
......@@ -4192,6 +4192,30 @@
"
)
; If optimizing for size, or if we have load delay slots, then
; we want to split the constant into two separate operations.
; In both cases this may split a trivial part into a single data op
; leaving a single complex constant to load. We can also get longer
; offsets in a LDR which means we get better chances of sharing the pool
; entries. Finally, we can normally do a better job of scheduling
; LDR instructions than we can with LDM.
; This pattern will only match if the one above did not.
(define_split
[(set (match_operand:ANY64 0 "arm_general_register_operand" "")
(match_operand:ANY64 1 "const_double_operand" ""))]
"TARGET_ARM && reload_completed
&& arm_const_double_by_parts (operands[1])"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (match_dup 3))]
"
operands[2] = gen_highpart (SImode, operands[0]);
operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
operands[1]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
"
)
(define_split
[(set (match_operand:ANY64 0 "arm_general_register_operand" "")
(match_operand:ANY64 1 "arm_general_register_operand" ""))]
......
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