This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

patch for ARM load/store multiple insns



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"))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]