Commit 56289ed2 by Sameera Deshpande Committed by Greta Yorsh

arm-protos.h (offset_ok_for_ldrd_strd): New declaration.

2012-10-22  Sameera Deshpande  <sameera.deshpande@arm.com>
	    Greta Yorsh  <Greta.Yorsh@arm.com>

        * config/arm/arm-protos.h (offset_ok_for_ldrd_strd): New
        declaration.
        (operands_ok_ldrd_strd): Likewise.
        * config/arm/arm.c (offset_ok_for_ldrd_strd): New function.
        (operands_ok_ldrd_strd): Likewise.
        * config/arm/arm.md (thumb2_ldrd, thumb2_ldrd_base): New patterns.
        (thumb2_ldrd_base_neg): Likewise.
        (thumb2_strd, thumb2_strd_base, thumb_strd_base_neg): Likewise.
        * predicates.md (ldrd_strd_offset_operand): New predicate.
        * config/arm/constraints.md (Do): New constraint.



Co-Authored-By: Greta Yorsh <greta.yorsh@arm.com>

From-SVN: r192678
parent a271e61c
2012-10-22 Sameera Deshpande <sameera.deshpande@arm.com>
Greta Yorsh <Greta.Yorsh@arm.com>
* config/arm/arm-protos.h (offset_ok_for_ldrd_strd): New
declaration.
(operands_ok_ldrd_strd): Likewise.
* config/arm/arm.c (offset_ok_for_ldrd_strd): New function.
(operands_ok_ldrd_strd): Likewise.
* config/arm/arm.md (thumb2_ldrd, thumb2_ldrd_base): New patterns.
(thumb2_ldrd_base_neg): Likewise.
(thumb2_strd, thumb2_strd_base, thumb_strd_base_neg): Likewise.
* predicates.md (ldrd_strd_offset_operand): New predicate.
* config/arm/constraints.md (Do): New constraint.
2012-10-22 Hans-Peter Nilsson <hp@bitrange.com>
* config/mmix/mmix.md ("nonlocal_goto_receiver"): Refer to the
......@@ -116,6 +116,8 @@ extern bool gen_stm_seq (rtx *, int);
extern bool gen_const_stm_seq (rtx *, int);
extern rtx arm_gen_load_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);
extern rtx arm_gen_store_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);
extern bool offset_ok_for_ldrd_strd (HOST_WIDE_INT);
extern bool operands_ok_ldrd_strd (rtx, rtx, rtx, HOST_WIDE_INT, bool, bool);
extern int arm_gen_movmemqi (rtx *);
extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx,
......
......@@ -12193,6 +12193,75 @@ arm_pad_reg_upward (enum machine_mode mode,
return !BYTES_BIG_ENDIAN;
}
/* Returns true iff OFFSET is valid for use in an LDRD/STRD instruction,
assuming that the address in the base register is word aligned. */
bool
offset_ok_for_ldrd_strd (HOST_WIDE_INT offset)
{
HOST_WIDE_INT max_offset;
/* Offset must be a multiple of 4 in Thumb mode. */
if (TARGET_THUMB2 && ((offset & 3) != 0))
return false;
if (TARGET_THUMB2)
max_offset = 1020;
else if (TARGET_ARM)
max_offset = 255;
else
gcc_unreachable ();
return ((offset <= max_offset) && (offset >= -max_offset));
}
/* Checks whether the operands are valid for use in an LDRD/STRD instruction.
Assumes that RT, RT2, and RN are REG. This is guaranteed by the patterns.
Assumes that the address in the base register RN is word aligned. Pattern
guarantees that both memory accesses use the same base register,
the offsets are constants within the range, and the gap between the offsets is 4.
If preload complete then check that registers are legal. WBACK indicates whether
address is updated. LOAD indicates whether memory access is load or store. */
bool
operands_ok_ldrd_strd (rtx rt, rtx rt2, rtx rn, HOST_WIDE_INT offset,
bool wback, bool load)
{
unsigned int t, t2, n;
if (!reload_completed)
return true;
if (!offset_ok_for_ldrd_strd (offset))
return false;
t = REGNO (rt);
t2 = REGNO (rt2);
n = REGNO (rn);
if ((TARGET_THUMB2)
&& ((wback && (n == t || n == t2))
|| (t == SP_REGNUM)
|| (t == PC_REGNUM)
|| (t2 == SP_REGNUM)
|| (t2 == PC_REGNUM)
|| (!load && (n == PC_REGNUM))
|| (load && (t == t2))
/* Triggers Cortex-M3 LDRD errata. */
|| (!wback && load && fix_cm3_ldrd && (n == t))))
return false;
if ((TARGET_ARM)
&& ((wback && (n == t || n == t2))
|| (t2 == PC_REGNUM)
|| (t % 2 != 0) /* First destination register is not even. */
|| (t2 != t + 1)
/* PC can be used as base register (for offset addressing only),
but it is depricated. */
|| (n == PC_REGNUM)))
return false;
return true;
}
/* Print a symbolic form of X to the debug file, F. */
static void
......
......@@ -11511,6 +11511,99 @@
""
)
;; Patterns for LDRD/STRD in Thumb2 mode
(define_insn "*thumb2_ldrd"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
(match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
(set (match_operand:SI 3 "s_register_operand" "=r")
(mem:SI (plus:SI (match_dup 1)
(match_operand:SI 4 "const_int_operand" ""))))]
"TARGET_LDRD && TARGET_THUMB2 && reload_completed
&& current_tune->prefer_ldrd_strd
&& ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
&& (operands_ok_ldrd_strd (operands[0], operands[3],
operands[1], INTVAL (operands[2]),
false, true))"
"ldrd%?\t%0, %3, [%1, %2]"
[(set_attr "type" "load2")
(set_attr "predicable" "yes")])
(define_insn "*thumb2_ldrd_base"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
(set (match_operand:SI 2 "s_register_operand" "=r")
(mem:SI (plus:SI (match_dup 1)
(const_int 4))))]
"TARGET_LDRD && TARGET_THUMB2 && reload_completed
&& current_tune->prefer_ldrd_strd
&& (operands_ok_ldrd_strd (operands[0], operands[2],
operands[1], 0, false, true))"
"ldrd%?\t%0, %2, [%1]"
[(set_attr "type" "load2")
(set_attr "predicable" "yes")])
(define_insn "*thumb2_ldrd_base_neg"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
(const_int -4))))
(set (match_operand:SI 2 "s_register_operand" "=r")
(mem:SI (match_dup 1)))]
"TARGET_LDRD && TARGET_THUMB2 && reload_completed
&& current_tune->prefer_ldrd_strd
&& (operands_ok_ldrd_strd (operands[0], operands[2],
operands[1], -4, false, true))"
"ldrd%?\t%0, %2, [%1, #-4]"
[(set_attr "type" "load2")
(set_attr "predicable" "yes")])
(define_insn "*thumb2_strd"
[(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
(match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
(match_operand:SI 2 "s_register_operand" "r"))
(set (mem:SI (plus:SI (match_dup 0)
(match_operand:SI 3 "const_int_operand" "")))
(match_operand:SI 4 "s_register_operand" "r"))]
"TARGET_LDRD && TARGET_THUMB2 && reload_completed
&& current_tune->prefer_ldrd_strd
&& ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
&& (operands_ok_ldrd_strd (operands[2], operands[4],
operands[0], INTVAL (operands[1]),
false, false))"
"strd%?\t%2, %4, [%0, %1]"
[(set_attr "type" "store2")
(set_attr "predicable" "yes")])
(define_insn "*thumb2_strd_base"
[(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
(match_operand:SI 1 "s_register_operand" "r"))
(set (mem:SI (plus:SI (match_dup 0)
(const_int 4)))
(match_operand:SI 2 "s_register_operand" "r"))]
"TARGET_LDRD && TARGET_THUMB2 && reload_completed
&& current_tune->prefer_ldrd_strd
&& (operands_ok_ldrd_strd (operands[1], operands[2],
operands[0], 0, false, false))"
"strd%?\t%1, %2, [%0]"
[(set_attr "type" "store2")
(set_attr "predicable" "yes")])
(define_insn "*thumb2_strd_base_neg"
[(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
(const_int -4)))
(match_operand:SI 1 "s_register_operand" "r"))
(set (mem:SI (match_dup 0))
(match_operand:SI 2 "s_register_operand" "r"))]
"TARGET_LDRD && TARGET_THUMB2 && reload_completed
&& current_tune->prefer_ldrd_strd
&& (operands_ok_ldrd_strd (operands[1], operands[2],
operands[0], -4, false, false))"
"strd%?\t%1, %2, [%0, #-4]"
[(set_attr "type" "store2")
(set_attr "predicable" "yes")])
;; Load the load/store multiple patterns
(include "ldmstm.md")
......
......@@ -31,7 +31,7 @@
;; 'H' was previously used for FPA.
;; The following multi-letter normal constraints have been used:
;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Dv, Dy, Di, Dt, Dz
;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Do, Dv, Dy, Di, Dt, Dz
;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe
;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py
......@@ -279,6 +279,12 @@
(match_test "TARGET_32BIT
&& imm_for_neon_inv_logic_operand (op, GET_MODE (op))")))
(define_constraint "Do"
"@internal
In ARM/Thumb2 state valid offset for an ldrd/strd instruction."
(and (match_code "const_int")
(match_test "TARGET_LDRD && offset_ok_for_ldrd_strd (ival)")))
(define_constraint "Dv"
"@internal
In ARM/Thumb-2 state a const_double which can be used with a VFP fconsts
......
......@@ -137,6 +137,10 @@
(match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) <= GET_MODE_BITSIZE (mode)
&& ((unsigned HOST_WIDE_INT) INTVAL (op)) > 0")))
(define_predicate "ldrd_strd_offset_operand"
(and (match_operand 0 "const_int_operand")
(match_test "TARGET_LDRD && offset_ok_for_ldrd_strd (INTVAL (op))")))
(define_predicate "arm_add_operand"
(ior (match_operand 0 "arm_rhs_operand")
(match_operand 0 "arm_neg_immediate_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