Patchwork GCC 4.9 powerpc, fix insn type attribute for load/store insns

login
register
mail settings
Submitter Pat Haugen
Date Feb. 12, 2013, 2:36 a.m.
Message ID <5119AAB1.2000701@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/219727/
State New
Headers show

Comments

Pat Haugen - Feb. 12, 2013, 2:36 a.m.
The following patch fixes the assignment of the insn "type" attribute 
for loads and stores. Specifically, it will now appropriately assign 
update form and update-indexed form type attributes which allows for 
better instruction scheduling by honoring group formation restrictions 
and (to a lesser extent) insn latency for the updated address reg. The 
patch is based on Mike Meissner's prior 4.9 submissions for move pattern 
combinations.

Bootstrap/regtest on powerpc64-linux with no new regressions. Ok for 4.9 
when it opens up?


2013-02-12  Pat Haugen <pthaugen@us.ibm.com>
         * config/rs6000/predicates.md (indexed_address, update_address_mem
         update_indexed_address_mem): New predicates.
         * config/rs6000/vsx.md (vsx_extract_<mode>_zero): Set correct 
"type"
         attribute for load/store instructions.
         * config/rs6000/dfp.md (movsd_store): Likewise.
         (movsd_load): Likewise.
         * config/rs6000/rs6000.md (zero_extend<mode>di2_internal1): 
Likewise.
         (unnamed HI->DI extend define_insn): Likewise.
         (unnamed SI->DI extend define_insn): Likewise.
         (unnamed QI->SI extend define_insn): Likewise.
         (unnamed QI->HI extend define_insn): Likewise.
         (unnamed HI->SI extend define_insn): Likewise.
         (unnamed HI->SI extend define_insn): Likewise.
         (extendsfdf2_fpr): Likewise.
         (movsi_internal1): Likewise.
         (movsi_internal1_single): Likewise.
         (movhi_internal): Likewise.
         (movqi_internal): Likewise.
         (movcc_internal1): Correct mnemonic for stw insn. Set correct 
"type"
         attribute for load/store instructions.
         (mov<mode>_hardfloat): Set correct "type" attribute for load/store
         instructions.
         (mov<mode>_softfloat): Likewise.
         (mov<mode>_hardfloat32): Likewise.
         (mov<mode>_hardfloat64): Likewise.
         (mov<mode>_softfloat64): Likewise.
         (movdi_internal32): Likewise.
         (movdi_internal64): Likewise.
         (probe_stack_<mode>): Likewise.
David Edelsohn - Feb. 14, 2013, 5:01 p.m.
On Mon, Feb 11, 2013 at 9:36 PM, Pat Haugen <pthaugen@linux.vnet.ibm.com> wrote:
> The following patch fixes the assignment of the insn "type" attribute for
> loads and stores. Specifically, it will now appropriately assign update form
> and update-indexed form type attributes which allows for better instruction
> scheduling by honoring group formation restrictions and (to a lesser extent)
> insn latency for the updated address reg. The patch is based on Mike
> Meissner's prior 4.9 submissions for move pattern combinations.
>
> Bootstrap/regtest on powerpc64-linux with no new regressions. Ok for 4.9
> when it opens up?
>
>
> 2013-02-12  Pat Haugen <pthaugen@us.ibm.com>
>         * config/rs6000/predicates.md (indexed_address, update_address_mem
>         update_indexed_address_mem): New predicates.
>         * config/rs6000/vsx.md (vsx_extract_<mode>_zero): Set correct "type"
>         attribute for load/store instructions.
>         * config/rs6000/dfp.md (movsd_store): Likewise.
>         (movsd_load): Likewise.
>         * config/rs6000/rs6000.md (zero_extend<mode>di2_internal1):
> Likewise.
>         (unnamed HI->DI extend define_insn): Likewise.
>         (unnamed SI->DI extend define_insn): Likewise.
>         (unnamed QI->SI extend define_insn): Likewise.
>         (unnamed QI->HI extend define_insn): Likewise.
>         (unnamed HI->SI extend define_insn): Likewise.
>         (unnamed HI->SI extend define_insn): Likewise.
>         (extendsfdf2_fpr): Likewise.
>         (movsi_internal1): Likewise.
>         (movsi_internal1_single): Likewise.
>         (movhi_internal): Likewise.
>         (movqi_internal): Likewise.
>         (movcc_internal1): Correct mnemonic for stw insn. Set correct "type"
>         attribute for load/store instructions.
>         (mov<mode>_hardfloat): Set correct "type" attribute for load/store
>         instructions.
>         (mov<mode>_softfloat): Likewise.
>         (mov<mode>_hardfloat32): Likewise.
>         (mov<mode>_hardfloat64): Likewise.
>         (mov<mode>_softfloat64): Likewise.
>         (movdi_internal32): Likewise.
>         (movdi_internal64): Likewise.
>         (probe_stack_<mode>): Likewise.

This is okay for GCC 4.9, when it opens.

Thanks, David

Patch

Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 195896)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -557,6 +557,28 @@  (define_special_predicate "indexed_or_in
 			&& REG_P (XEXP (op, 1)))")
        (match_operand 0 "address_operand")))
 
+;; Return 1 if the operand is an index-form address.
+(define_special_predicate "indexed_address"
+  (match_test "(GET_CODE (op) == PLUS
+		&& REG_P (XEXP (op, 0))
+		&& REG_P (XEXP (op, 1)))"))
+
+;; Return 1 if the operand is a MEM with an update-form address. This may
+;; also include update-indexed form.
+(define_special_predicate "update_address_mem"
+  (match_test "(MEM_P (op)
+		&& (GET_CODE (XEXP (op, 0)) == PRE_INC
+		    || GET_CODE (XEXP (op, 0)) == PRE_DEC
+		    || GET_CODE (XEXP (op, 0)) == PRE_MODIFY))"))
+
+;; Return 1 if the operand is a MEM with an update-indexed-form address. Note
+;; that PRE_INC/PRE_DEC will always be non-indexed (i.e. non X-form) since the
+;; increment is based on the mode size and will therefor always be a const.
+(define_special_predicate "update_indexed_address_mem"
+  (match_test "(MEM_P (op)
+		&& GET_CODE (XEXP (op, 0)) == PRE_MODIFY
+		&& indexed_address (XEXP (XEXP (op, 0), 1), mode))"))
+
 ;; Used for the destination of the fix_truncdfsi2 expander.
 ;; If stfiwx will be used, the result goes to memory; otherwise,
 ;; we're going to emit a store and a load of a subreg, so the dest is a
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 195896)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -1217,7 +1217,11 @@  (define_insn "*vsx_extract_<mode>_zero"
 	 (parallel [(const_int 0)])))]
   "VECTOR_MEM_VSX_P (<MODE>mode) && WORDS_BIG_ENDIAN"
   "lxsd%U1x %x0,%y1"
-  [(set_attr "type" "fpload")
+  [(set (attr "type")
+      (if_then_else
+	(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	(const_string "fpload_ux")
+	(const_string "fpload")))
    (set_attr "length" "4")])  
 
 ;; Extract a SF element from V4SF
Index: gcc/config/rs6000/dfp.md
===================================================================
--- gcc/config/rs6000/dfp.md	(revision 195896)
+++ gcc/config/rs6000/dfp.md	(working copy)
@@ -37,7 +37,14 @@  (define_insn "movsd_store"
    || gpc_reg_operand (operands[1], SDmode))
    && TARGET_HARD_FLOAT && TARGET_FPRS"
   "stfd%U0%X0 %1,%0"
-  [(set_attr "type" "fpstore")
+  [(set (attr "type")
+      (if_then_else
+	(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	(const_string "fpstore_ux")
+	(if_then_else
+	  (match_test "update_address_mem (operands[0], VOIDmode)")
+	  (const_string "fpstore_u")
+	  (const_string "fpstore"))))
    (set_attr "length" "4")])
 
 (define_insn "movsd_load"
@@ -48,7 +55,14 @@  (define_insn "movsd_load"
    || gpc_reg_operand (operands[1], DDmode))
    && TARGET_HARD_FLOAT && TARGET_FPRS"
   "lfd%U1%X1 %0,%1"
-  [(set_attr "type" "fpload")
+  [(set (attr "type")
+      (if_then_else
+	(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	(const_string "fpload_ux")
+	(if_then_else
+	  (match_test "update_address_mem (operands[1], VOIDmode)")
+	  (const_string "fpload_u")
+	  (const_string "fpload"))))
    (set_attr "length" "4")])
 
 ;; Hardware support for decimal floating point operations.
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 195896)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -369,7 +369,15 @@  (define_insn "*zero_extend<mode>di2_inte
   "@
    l<wd>z%U1%X1 %0,%1
    rldicl %0,%1,0,<dbits>"
-  [(set_attr "type" "load,*")])
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (const_string "*")])])
 
 (define_insn "*zero_extend<mode>di2_internal2"
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -495,7 +503,15 @@  (define_insn ""
   "@
    lha%U1%X1 %0,%1
    extsh %0,%1"
-  [(set_attr "type" "load_ext,exts")])
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ext_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_ext_u")
+	   (const_string "load_ext")))
+       (const_string "exts")])])
 
 (define_insn ""
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
@@ -569,7 +585,15 @@  (define_insn ""
   "@
    lwa%U1%X1 %0,%1
    extsw %0,%1"
-  [(set_attr "type" "load_ext,exts")])
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ext_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_ext_u")
+	   (const_string "load_ext")))
+       (const_string "exts")])])
 
 (define_insn ""
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
@@ -643,7 +667,15 @@  (define_insn ""
   "@
    lbz%U1%X1 %0,%1
    rlwinm %0,%1,0,0xff"
-  [(set_attr "type" "load,*")])
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (const_string "*")])])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -763,7 +795,15 @@  (define_insn ""
   "@
    lbz%U1%X1 %0,%1
    rlwinm %0,%1,0,0xff"
-  [(set_attr "type" "load,*")])
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (const_string "*")])])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -889,7 +929,15 @@  (define_insn ""
   "@
    lhz%U1%X1 %0,%1
    rlwinm %0,%1,0,0xffff"
-  [(set_attr "type" "load,*")])
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (const_string "*")])])
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -956,7 +1004,15 @@  (define_insn ""
   "@
    lha%U1%X1 %0,%1
    extsh %0,%1"
-  [(set_attr "type" "load_ext,exts")])
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ext_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_ext_u")
+	   (const_string "load_ext")))
+       (const_string "exts")])])
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -4539,7 +4595,16 @@  (define_insn_and_split "*extendsfdf2_fpr
   emit_note (NOTE_INSN_DELETED);
   DONE;
 }
-  [(set_attr "type" "fp,fp,fpload")])
+  [(set_attr_alternative "type"
+      [(const_string "fp")
+       (const_string "fp")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "fpload_u")
+	   (const_string "fpload")))])])
 
 (define_expand "truncdfsf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
@@ -7764,7 +7829,31 @@  (define_insn "*movsi_internal1"
    mt%0 %1
    mt%0 %1
    nop"
-  [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*")
+  [(set_attr_alternative "type"
+      [(const_string "*")
+       (const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "mfjmpr")
+       (const_string "mtjmpr")
+       (const_string "*")
+       (const_string "*")])
+
    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")])
 
 (define_insn "*movsi_internal1_single"
@@ -7786,7 +7875,44 @@  (define_insn "*movsi_internal1_single"
    nop
    stfs%U0%X0 %1,%0
    lfs%U1%X1 %0,%1"
-  [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,*,*")
+  [(set_attr_alternative "type"
+      [(const_string "*")
+       (const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "mfjmpr")
+       (const_string "mtjmpr")
+       (const_string "*")
+       (const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "fpstore_u")
+	   (const_string "fpstore")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "fpload_u")
+	   (const_string "fpload")))])
    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
 
 ;; Split a load of a large constant into the appropriate two-insn
@@ -7849,7 +7975,26 @@  (define_insn "*movhi_internal"
    mf%1 %0
    mt%0 %1
    nop"
-  [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
+  [(set_attr_alternative "type"
+      [(const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (const_string "*")
+       (const_string "mfjmpr")
+       (const_string "mtjmpr")
+       (const_string "*")])])
 
 (define_expand "mov<mode>"
   [(set (match_operand:INT 0 "general_operand" "")
@@ -7870,7 +8015,26 @@  (define_insn "*movqi_internal"
    mf%1 %0
    mt%0 %1
    nop"
-  [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")])
+  [(set_attr_alternative "type"
+      [(const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (const_string "*")
+       (const_string "mfjmpr")
+       (const_string "mtjmpr")
+       (const_string "*")])])
 
 ;; Here is how to move condition codes around.  When we store CC data in
 ;; an integer register or memory, we store just the high-order 4 bits.
@@ -7898,7 +8062,7 @@  (define_insn "*movcc_internal1"
    mf%1 %0
    mt%0 %1
    lwz%U1%X1 %0,%1
-   stw%U0%U1 %1,%0"
+   stw%U0%X0 %1,%0"
   [(set (attr "type")
      (cond [(eq_attr "alternative" "0,3")
 		(const_string "cr_logical")
@@ -7911,9 +8075,23 @@  (define_insn "*movcc_internal1"
 	    (eq_attr "alternative" "9")
 		(const_string "mtjmpr")
 	    (eq_attr "alternative" "10")
-		(const_string "load")
+		(if_then_else
+		  (match_test "update_indexed_address_mem (operands[1],
+							   VOIDmode)")
+		  (const_string "load_ux")
+		  (if_then_else
+		    (match_test "update_address_mem (operands[1], VOIDmode)")
+		    (const_string "load_u")
+		    (const_string "load")))
 	    (eq_attr "alternative" "11")
-		(const_string "store")
+		(if_then_else
+		  (match_test "update_indexed_address_mem (operands[0],
+							   VOIDmode)")
+		  (const_string "store_ux")
+		  (if_then_else
+		    (match_test "update_address_mem (operands[0], VOIDmode)")
+		    (const_string "store_u")
+		    (const_string "store")))
 	    (match_test "TARGET_MFCRF")
 		(const_string "mfcrf")
 	   ]
@@ -7978,7 +8156,44 @@  (define_insn "mov<mode>_hardfloat"
    nop
    #
    #"
-  [(set_attr "type"   "*,load,store,fp,vecsimple,vecsimple,fpload,fpstore,mtjmpr,mfjmpr,*,*,*")
+  [(set_attr_alternative "type"
+      [(const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (const_string "fp")
+       (const_string "vecsimple")
+       (const_string "vecsimple")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "fpload_u")
+	   (const_string "fpload")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "fpstore_u")
+	   (const_string "fpstore")))
+       (const_string "mtjmpr")
+       (const_string "mfjmpr")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")])
    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8")])
 
 (define_insn "*mov<mode>_softfloat"
@@ -7998,7 +8213,29 @@  (define_insn "*mov<mode>_softfloat"
    #
    #
    nop"
-  [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
+  [(set_attr_alternative "type"
+      [(const_string "*")
+       (const_string "mtjmpr")
+       (const_string "mfjmpr")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")])
    (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
 
 
@@ -8126,7 +8363,47 @@  (define_insn "*mov<mode>_hardfloat32"
    #
    #
    #"
-  [(set_attr "type" "fpstore,fpload,fp,fpload,fpload,fpstore,fpstore,vecsimple,vecsimple,vecsimple,store,load,two,fp,fp,*")
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "fpstore_u")
+	   (const_string "fpstore")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "fpload_u")
+	   (const_string "fpload")))
+       (const_string "fp")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (const_string "fpload"))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (const_string "fpload"))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (const_string "fpstore"))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (const_string "fpstore"))
+       (const_string "vecsimple")
+       (const_string "vecsimple")
+       (const_string "vecsimple")
+       (const_string "store")
+       (const_string "load")
+       (const_string "two")
+       (const_string "fp")
+       (const_string "fp")
+       (const_string "*")])
    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,8,8,8,12,16")])
 
 (define_insn "*mov<mode>_softfloat32"
@@ -8171,7 +8448,64 @@  (define_insn "*mov<mode>_hardfloat64"
    #
    mftgpr %0,%1
    mffgpr %0,%1"
-  [(set_attr "type" "fpstore,fpload,fp,fpload,fpload,fpstore,fpstore,vecsimple,vecsimple,vecsimple,store,load,*,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "fpstore_u")
+	   (const_string "fpstore")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "fpload_u")
+	   (const_string "fpload")))
+       (const_string "fp")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (const_string "fpload"))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (const_string "fpload"))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (const_string "fpstore"))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (const_string "fpstore"))
+       (const_string "vecsimple")
+       (const_string "vecsimple")
+       (const_string "vecsimple")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (const_string "*")
+       (const_string "mtjmpr")
+       (const_string "mfjmpr")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "mftgpr")
+       (const_string "mffgpr")])
    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
 
 (define_insn "*mov<mode>_softfloat64"
@@ -8190,7 +8524,28 @@  (define_insn "*mov<mode>_softfloat64"
    #
    #
    nop"
-  [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (const_string "*")
+       (const_string "mtjmpr")
+       (const_string "mfjmpr")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")])
    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
 
 (define_expand "mov<mode>"
@@ -8553,7 +8908,27 @@  (define_insn "*movdi_internal32"
    fmr %0,%1
    #
    xxlxor %x0,%x0,%x0"
-  [(set_attr "type" "store,load,*,fpstore,fpload,fp,*,vecsimple")])
+  [(set_attr_alternative "type"
+      [(const_string "store")
+       (const_string "load")
+       (const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "fpstore_u")
+	   (const_string "fpstore")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "fpload_u")
+	   (const_string "fpload")))
+       (const_string "fp")
+       (const_string "*")
+       (const_string "vecsimple")])])
 
 (define_split
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
@@ -8610,7 +8985,55 @@  (define_insn "*movdi_internal64"
    xxlxor %x0,%x0,%x0
    mftgpr %0,%1
    mffgpr %0,%1"
-  [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,fpstore,fpload,vecsimple,mfjmpr,mtjmpr,*,vecsimple,mftgpr,mffgpr")
+  [(set_attr_alternative "type"
+      [(if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "store_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "store_u")
+	   (const_string "store")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "load_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "load_u")
+	   (const_string "load")))
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (const_string "*")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[0], VOIDmode)")
+	   (const_string "fpstore_u")
+	   (const_string "fpstore")))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (if_then_else
+	   (match_test "update_address_mem (operands[1], VOIDmode)")
+	   (const_string "fpload_u")
+	   (const_string "fpload")))
+       (const_string "fp")
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	 (const_string "fpstore_ux")
+	 (const_string "fpstore"))
+       (if_then_else
+	 (match_test "update_indexed_address_mem (operands[1], VOIDmode)")
+	 (const_string "fpload_ux")
+	 (const_string "fpload"))
+       (const_string "vecsimple")
+       (const_string "mfjmpr")
+       (const_string "mtjmpr")
+       (const_string "*")
+       (const_string "vecsimple")
+       (const_string "mftgpr")
+       (const_string "mffgpr")])
    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4,4")])
 
 ;; immediate value valid for a single instruction hiding in a const_double
@@ -11252,7 +11675,14 @@  (define_insn "probe_stack_<mode>"
   operands[1] = gen_rtx_REG (Pmode, 0);
   return "st<wd>%U0%X0 %1,%0";
 }
-  [(set_attr "type" "store")
+  [(set (attr "type")
+      (if_then_else
+	(match_test "update_indexed_address_mem (operands[0], VOIDmode)")
+	(const_string "store_ux")
+	(if_then_else
+	  (match_test "update_address_mem (operands[0], VOIDmode)")
+	  (const_string "store_u")
+	  (const_string "store"))))
    (set_attr "length" "4")])
 
 (define_insn "probe_stack_range<P:mode>"