This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch for ARM load/store multiple insns
- To: gcc-patches at gcc dot gnu dot org
- Subject: patch for ARM load/store multiple insns
- From: Richard Earnshaw <rearnsha at arm dot com>
- Date: Sun, 14 Jan 2001 19:44:26 +0000
- cc: rearnsha at arm dot com, rth at redhat dot com
- Organization: ARM Ltd.
- Reply-To: rearnsha at arm dot com
This patch will (with another one to genrecog.c that I hope RTH will be
committing soon) fix the problem of aborts while building the fortran
compiler during stage2 of a bootstrap. It simply expands the rtl of the
load/store multiple insns into multiple patterns so that all pseudos will
get correctly reloaded.
With RTH's patch (and after backing out the change to
move2add_note_store), this patch survives a bootstrap on arm-netbsd.
2001-01-14 Richard Earnshaw <rearnsha@arm.com>
* arm.md (ldmsi_postinc, ldmsi, stmsi_postinc, smsi): Delete. Replace
with ...
(ldmsi_postinc[432], ldmsi[432], stmsi_postinc[432], stmsi[432]): New.
Index: arm.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.md,v
retrieving revision 1.75
diff -p -r1.75 arm.md
*** arm.md 2001/01/08 15:33:06 1.75
--- arm.md 2001/01/14 19:33:28
***************
*** 5229,5279 ****
;; Load multiple with write-back
! (define_insn "*ldmsi_postinc"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:SI 1 "s_register_operand" "=r")
(plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (match_operand:SI 3 "const_int_operand" "n")))
(set (match_operand:SI 4 "arm_hard_register_operand" "")
! (mem:SI (match_dup 2)))])]
! "TARGET_ARM && (INTVAL (operands[3]) == 4 * (XVECLEN (operands[0], 0) - 1))"
! "*
! {
! rtx ops[3];
! int count = XVECLEN (operands[0], 0);
! ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
! ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1));
! ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
! output_asm_insn (\"ldm%?ia\\t%0!, {%1-%2}\\t%@ load multiple\", ops);
! return \"\";
! }
! "
[(set_attr "type" "load")
(set_attr "predicable" "yes")]
)
;; Ordinary load multiple
! (define_insn "*ldmsi"
[(match_parallel 0 "load_multiple_operation"
! [(set (match_operand:SI 1 "arm_hard_register_operand" "")
! (mem:SI (match_operand:SI 2 "s_register_operand" "r")))])]
! "TARGET_ARM"
! "*
! {
! rtx ops[3];
! int count = XVECLEN (operands[0], 0);
! ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
! ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0));
! ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1));
! output_asm_insn (\"ldm%?ia\\t%0, {%1-%2}\\t%@ load multiple\", ops);
! return \"\";
! }
! "
[(set_attr "type" "load")
(set_attr "predicable" "yes")]
)
--- 5229,5325 ----
;; Load multiple with write-back
! (define_insn "*ldmsi_postinc4"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:SI 1 "s_register_operand" "=r")
(plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (const_int 16)))
! (set (match_operand:SI 3 "arm_hard_register_operand" "")
! (mem:SI (match_dup 2)))
(set (match_operand:SI 4 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 2) (const_int 4))))
! (set (match_operand:SI 5 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 2) (const_int 8))))
! (set (match_operand:SI 6 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
! "ldm%?ia\\t%1!, {%3, %4, %5, %6}"
! [(set_attr "type" "load")
! (set_attr "predicable" "yes")]
! )
! (define_insn "*ldmsi_postinc3"
! [(match_parallel 0 "load_multiple_operation"
! [(set (match_operand:SI 1 "s_register_operand" "=r")
! (plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (const_int 12)))
! (set (match_operand:SI 3 "arm_hard_register_operand" "")
! (mem:SI (match_dup 2)))
! (set (match_operand:SI 4 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 2) (const_int 4))))
! (set (match_operand:SI 5 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
! "ldm%?ia\\t%1!, {%3, %4, %5}"
! [(set_attr "type" "load")
! (set_attr "predicable" "yes")]
! )
! (define_insn "*ldmsi_postinc2"
! [(match_parallel 0 "load_multiple_operation"
! [(set (match_operand:SI 1 "s_register_operand" "=r")
! (plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (const_int 8)))
! (set (match_operand:SI 3 "arm_hard_register_operand" "")
! (mem:SI (match_dup 2)))
! (set (match_operand:SI 4 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
! "ldm%?ia\\t%1!, {%3, %4}"
[(set_attr "type" "load")
(set_attr "predicable" "yes")]
)
;; Ordinary load multiple
! (define_insn "*ldmsi4"
[(match_parallel 0 "load_multiple_operation"
! [(set (match_operand:SI 2 "arm_hard_register_operand" "")
! (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
! (set (match_operand:SI 3 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 1) (const_int 4))))
! (set (match_operand:SI 4 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 1) (const_int 8))))
! (set (match_operand:SI 5 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
! "ldm%?ia\\t%1, {%2, %3, %4, %5}"
! [(set_attr "type" "load")
! (set_attr "predicable" "yes")]
! )
! (define_insn "*ldmsi3"
! [(match_parallel 0 "load_multiple_operation"
! [(set (match_operand:SI 2 "arm_hard_register_operand" "")
! (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
! (set (match_operand:SI 3 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 1) (const_int 4))))
! (set (match_operand:SI 4 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
! "ldm%?ia\\t%1, {%2, %3, %4}"
! [(set_attr "type" "load")
! (set_attr "predicable" "yes")]
! )
! (define_insn "*ldmsi2"
! [(match_parallel 0 "load_multiple_operation"
! [(set (match_operand:SI 2 "arm_hard_register_operand" "")
! (mem:SI (match_operand:SI 1 "s_register_operand" "r")))
! (set (match_operand:SI 3 "arm_hard_register_operand" "")
! (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
! "ldm%?ia\\t%1, {%2, %3}"
[(set_attr "type" "load")
(set_attr "predicable" "yes")]
)
***************
*** 5305,5367 ****
;; Store multiple with write-back
! (define_insn "*stmsi_postinc"
[(match_parallel 0 "store_multiple_operation"
[(set (match_operand:SI 1 "s_register_operand" "=r")
(plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (match_operand:SI 3 "const_int_operand" "n")))
(set (mem:SI (match_dup 2))
! (match_operand:SI 4 "arm_hard_register_operand" ""))])]
! "TARGET_ARM && (INTVAL (operands[3]) == 4 * (XVECLEN (operands[0], 0) - 1))"
! "*
! {
! rtx ops[3];
! int count = XVECLEN (operands[0], 0);
! ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0);
! ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1));
! ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
! output_asm_insn (\"stm%?ia\\t%0!, {%1-%2}\\t%@ str multiple\", ops);
! return \"\";
! }
! "
[(set_attr "predicable" "yes")
! (set (attr "type")
! (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
! (const_string "store2")
! (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
! (const_string "store3")]
! (const_string "store4")))]
)
;; Ordinary store multiple
! (define_insn "*stmsi"
[(match_parallel 0 "store_multiple_operation"
[(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
! (match_operand:SI 2 "arm_hard_register_operand" ""))])]
! "TARGET_ARM"
! "*
! {
! rtx ops[3];
! int count = XVECLEN (operands[0], 0);
! ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0);
! ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0));
! ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1));
! output_asm_insn (\"stm%?ia\\t%0, {%1-%2}\\t%@ str multiple\", ops);
! return \"\";
! }
! "
[(set_attr "predicable" "yes")
! (set (attr "type")
! (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3))
! (const_string "store2")
! (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4))
! (const_string "store3")]
! (const_string "store4")))]
)
;; Move a block of memory if it is word aligned and MORE than 2 words long.
--- 5351,5449 ----
;; Store multiple with write-back
! (define_insn "*stmsi_postinc4"
[(match_parallel 0 "store_multiple_operation"
[(set (match_operand:SI 1 "s_register_operand" "=r")
(plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (const_int 16)))
(set (mem:SI (match_dup 2))
! (match_operand:SI 3 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
! (match_operand:SI 4 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
! (match_operand:SI 5 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))
! (match_operand:SI 6 "arm_hard_register_operand" ""))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 5"
! "stm%?ia\\t%1!, {%3, %4, %5, %6}"
! [(set_attr "predicable" "yes")
! (set_attr "type" "store4")]
! )
! (define_insn "*stmsi_postinc3"
! [(match_parallel 0 "store_multiple_operation"
! [(set (match_operand:SI 1 "s_register_operand" "=r")
! (plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (const_int 12)))
! (set (mem:SI (match_dup 2))
! (match_operand:SI 3 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
! (match_operand:SI 4 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
! (match_operand:SI 5 "arm_hard_register_operand" ""))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
! "stm%?ia\\t%1!, {%3, %4, %5}"
! [(set_attr "predicable" "yes")
! (set_attr "type" "store3")]
! )
! (define_insn "*stmsi_postinc2"
! [(match_parallel 0 "store_multiple_operation"
! [(set (match_operand:SI 1 "s_register_operand" "=r")
! (plus:SI (match_operand:SI 2 "s_register_operand" "1")
! (const_int 8)))
! (set (mem:SI (match_dup 2))
! (match_operand:SI 3 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
! (match_operand:SI 4 "arm_hard_register_operand" ""))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
! "stm%?ia\\t%1!, {%3, %4}"
[(set_attr "predicable" "yes")
! (set_attr "type" "store2")]
)
;; Ordinary store multiple
! (define_insn "*stmsi4"
[(match_parallel 0 "store_multiple_operation"
[(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
! (match_operand:SI 2 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
! (match_operand:SI 3 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
! (match_operand:SI 4 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
! (match_operand:SI 5 "arm_hard_register_operand" ""))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 4"
! "stm%?ia\\t%1, {%2, %3, %4, %5}"
! [(set_attr "predicable" "yes")
! (set_attr "type" "store4")]
! )
! (define_insn "*stmsi3"
! [(match_parallel 0 "store_multiple_operation"
! [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
! (match_operand:SI 2 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
! (match_operand:SI 3 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
! (match_operand:SI 4 "arm_hard_register_operand" ""))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 3"
! "stm%?ia\\t%1, {%2, %3, %4}"
! [(set_attr "predicable" "yes")
! (set_attr "type" "store3")]
! )
! (define_insn "*stmsi2"
! [(match_parallel 0 "store_multiple_operation"
! [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
! (match_operand:SI 2 "arm_hard_register_operand" ""))
! (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
! (match_operand:SI 3 "arm_hard_register_operand" ""))])]
! "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
! "stm%?ia\\t%1, {%2, %3}"
[(set_attr "predicable" "yes")
! (set_attr "type" "store2")]
)
;; Move a block of memory if it is word aligned and MORE than 2 words long.
***************
*** 5393,5399 ****
"
)
! ;; Block-move insns
(define_insn "movmem12b"
[(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
--- 5475,5481 ----
"
)
! ;; Thumb block-move insns
(define_insn "movmem12b"
[(set (mem:SI (match_operand:SI 2 "register_operand" "0"))