@@ -212,6 +212,30 @@
;; no predicated insns.
(define_attr "predicated" "yes,no" (const_string "no"))
+;; Does this instruction use indexed (that is, reg+reg) addressing?
+;; This is used for load and store insns. If operand 0 or 1 is a MEM
+;; it is automatically set based on that. If a load or store instruction
+;; has fewer than two operands it needs to set this attribute manually
+;; or the compiler will crash.
+(define_attr "index" "no,yes"
+ (if_then_else (ior (match_operand 0 "index_address_mem")
+ (match_operand 1 "index_address_mem"))
+ (const_string "yes")
+ (const_string "no")))
+
+;; Does this instruction use update addressing?
+;; This is used for load and store insns. See the comments for "indexed".
+(define_attr "update" "no,yes"
+ (if_then_else (ior (match_operand 0 "update_address_mem")
+ (match_operand 1 "update_address_mem"))
+ (const_string "yes")
+ (const_string "no")))
+
+(define_attr "index_shift" "no,yes"
+ (if_then_else (ior (match_operand 0 "index_shift_address_mem")
+ (match_operand 1 "index_shift_address_mem"))
+ (const_string "yes")
+ (const_string "no")))
;; -------------------------------------------------------------------
;; Pipeline descriptions and scheduling
;; -------------------------------------------------------------------
@@ -546,7 +570,19 @@
operands[0] = gen_rtx_MEM (DImode, operands[0]);
return pftype[INTVAL(operands[1])][locality];
}
- [(set_attr "type" "load1")]
+ [(set_attr "type" "load1")
+ (set (attr "update")
+ (if_then_else (match_operand 0 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 0 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 0 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
(define_insn "trap"
@@ -1192,7 +1228,19 @@
ldp\\t%w0, %w2, %1
ldp\\t%s0, %s2, %1"
[(set_attr "type" "load2,neon_load1_2reg")
- (set_attr "fp" "*,yes")]
+ (set_attr "fp" "*,yes")
+ (set (attr "update")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
(define_insn "load_pairdi"
@@ -1208,7 +1256,19 @@
ldp\\t%x0, %x2, %1
ldp\\t%d0, %d2, %1"
[(set_attr "type" "load2,neon_load1_2reg")
- (set_attr "fp" "*,yes")]
+ (set_attr "fp" "*,yes")
+ (set (attr "update")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
@@ -1227,7 +1287,19 @@
stp\\t%w1, %w3, %0
stp\\t%s1, %s3, %0"
[(set_attr "type" "store2,neon_store1_2reg")
- (set_attr "fp" "*,yes")]
+ (set_attr "fp" "*,yes")
+ (set (attr "update")
+ (if_then_else (match_operand 0 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 0 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 0 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
(define_insn "store_pairdi"
@@ -1243,7 +1315,19 @@
stp\\t%x1, %x3, %0
stp\\t%d1, %d3, %0"
[(set_attr "type" "store2,neon_store1_2reg")
- (set_attr "fp" "*,yes")]
+ (set_attr "fp" "*,yes")
+ (set (attr "update")
+ (if_then_else (match_operand 0 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 0 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 0 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
;; Operands 1 and 3 are tied together by the final condition; so we allow
@@ -1261,7 +1345,19 @@
ldp\\t%s0, %s2, %1
ldp\\t%w0, %w2, %1"
[(set_attr "type" "neon_load1_2reg,load2")
- (set_attr "fp" "yes,*")]
+ (set_attr "fp" "yes,*")
+ (set (attr "update")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
(define_insn "load_pairdf"
@@ -1277,7 +1373,19 @@
ldp\\t%d0, %d2, %1
ldp\\t%x0, %x2, %1"
[(set_attr "type" "neon_load1_2reg,load2")
- (set_attr "fp" "yes,*")]
+ (set_attr "fp" "yes,*")
+ (set (attr "update")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
;; Operands 0 and 2 are tied together by the final condition; so we allow
@@ -1295,7 +1403,19 @@
stp\\t%s1, %s3, %0
stp\\t%w1, %w3, %0"
[(set_attr "type" "neon_store1_2reg,store2")
- (set_attr "fp" "yes,*")]
+ (set_attr "fp" "yes,*")
+ (set (attr "update")
+ (if_then_else (match_operand 0 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 0 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 0 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
(define_insn "store_pairdf"
@@ -1311,7 +1431,19 @@
stp\\t%d1, %d3, %0
stp\\t%x1, %x3, %0"
[(set_attr "type" "neon_store1_2reg,store2")
- (set_attr "fp" "yes,*")]
+ (set_attr "fp" "yes,*")
+ (set (attr "update")
+ (if_then_else (match_operand 0 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 0 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 0 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
;; Load pair with post-index writeback. This is primarily used in function
@@ -1328,7 +1460,8 @@
(match_operand:P 5 "const_int_operand" "n"))))])]
"INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
"ldp\\t%<w>2, %<w>3, [%1], %4"
- [(set_attr "type" "load2")]
+ [(set_attr "type" "load2")
+ (set_attr "update" "yes")]
)
(define_insn "loadwb_pair<GPF:mode>_<P:mode>"
@@ -1361,7 +1494,8 @@
(match_operand:GPI 3 "register_operand" "r"))])]
"INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
"stp\\t%<w>2, %<w>3, [%0, %4]!"
- [(set_attr "type" "store2")]
+ [(set_attr "type" "store2")
+ (set_attr "update" "yes")]
)
(define_insn "storewb_pair<GPF:mode>_<P:mode>"
@@ -1397,7 +1531,28 @@
"@
sxtw\t%0, %w1
ldrsw\t%0, %1"
- [(set_attr "type" "extend,load1")]
+ [(set_attr "type" "extend,load1")
+ (set (attr "update")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index_shift")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))]
)
(define_insn "*load_pair_extendsidi2_aarch64"
@@ -1410,7 +1565,19 @@
XEXP (operands[1], 0),
GET_MODE_SIZE (SImode)))"
"ldpsw\\t%0, %2, %1"
- [(set_attr "type" "load2")]
+ [(set_attr "type" "load2")
+ (set (attr "update")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
(define_insn "*zero_extendsidi2_aarch64"
@@ -1420,7 +1587,28 @@
"@
uxtw\t%0, %w1
ldr\t%w0, %1"
- [(set_attr "type" "extend,load1")]
+ [(set_attr "type" "extend,load1")
+ (set (attr "update")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index_shift")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))]
)
(define_insn "*load_pair_zero_extendsidi2_aarch64"
@@ -1433,7 +1621,19 @@
XEXP (operands[1], 0),
GET_MODE_SIZE (SImode)))"
"ldp\\t%w0, %w2, %1"
- [(set_attr "type" "load2")]
+ [(set_attr "type" "load2")
+ (set (attr "update")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "index_shift")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no")))]
)
(define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
@@ -1449,7 +1649,28 @@
"@
sxt<SHORT:size>\t%<GPI:w>0, %w1
ldrs<SHORT:size>\t%<GPI:w>0, %1"
- [(set_attr "type" "extend,load1")]
+ [(set_attr "type" "extend,load1")
+ (set (attr "update")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index_shift")
+ (cond [(eq_attr "alternative" "1")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))]
)
(define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
@@ -1460,7 +1681,28 @@
and\t%<GPI:w>0, %<GPI:w>1, <SHORT:short_mask>
ldr<SHORT:size>\t%w0, %1
ldr\t%<SHORT:size>0, %1"
- [(set_attr "type" "logic_imm,load1,load1")]
+ [(set_attr "type" "logic_imm,load1,load1")
+ (set (attr "update")
+ (cond [(eq_attr "alternative" "1,2")
+ (if_then_else (match_operand 1 "update_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index")
+ (cond [(eq_attr "alternative" "1,2")
+ (if_then_else (match_operand 1 "index_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))
+ (set (attr "index_shift")
+ (cond [(eq_attr "alternative" "1,2")
+ (if_then_else (match_operand 1 "index_shift_address_mem")
+ (const_string "yes")
+ (const_string "no"))
+ ]
+ (const_string "*")))]
)
(define_expand "<optab>qihi2"
@@ -5239,7 +5481,10 @@
UNSPEC_GOTSMALLPIC))]
""
"ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
- [(set_attr "type" "load1")]
+ [(set_attr "type" "load1")
+ (set_attr "update" "no")
+ (set_attr "index" "no")
+ (set_attr "index_shift" "no")]
)
(define_insn "ldr_got_small_sidi"
@@ -5251,7 +5496,10 @@
UNSPEC_GOTSMALLPIC)))]
"TARGET_ILP32"
"ldr\\t%w0, [%1, #:got_lo12:%a2]"
- [(set_attr "type" "load1")]
+ [(set_attr "type" "load1")
+ (set_attr "update" "no")
+ (set_attr "index" "no")
+ (set_attr "index_shift" "no")]
)
(define_insn "ldr_got_small_28k_<mode>"
@@ -5283,7 +5531,10 @@
UNSPEC_GOTTINYPIC))]
""
"ldr\\t%0, %L1"
- [(set_attr "type" "load1")]
+ [(set_attr "type" "load1")
+ (set_attr "update" "no")
+ (set_attr "index" "no")
+ (set_attr "index_shift" "no")]
)
(define_insn "aarch64_load_tp_hard"
@@ -5325,7 +5576,10 @@
""
"adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
[(set_attr "type" "load1")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "update" "no")
+ (set_attr "index" "no")
+ (set_attr "index_shift" "no")]
)
(define_insn "tlsie_small_sidi"
@@ -5336,7 +5590,10 @@
""
"adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
[(set_attr "type" "load1")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "update" "no")
+ (set_attr "index" "no")
+ (set_attr "index_shift" "no")]
)
(define_insn "tlsie_tiny_<mode>"
@@ -354,6 +354,44 @@
return aarch64_const_vec_all_same_int_p (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)) == POST_INC
+ || GET_CODE (XEXP (op, 0)) == POST_DEC
+ || GET_CODE (XEXP (op, 0)) == POST_MODIFY
+ || 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 an index-form address.
+(define_special_predicate "index_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 indexed-form address.
+(define_special_predicate "index_address_mem"
+ (match_test "(MEM_P (op)
+ && (index_address (XEXP (op, 0), mode)
+ || (GET_CODE (XEXP (op, 0)) == PRE_MODIFY
+ && index_address (XEXP (XEXP (op, 0), 1), mode))))"))
+
+;; Return 1 if the operand is an index-form address.
+(define_special_predicate "index_shift_address"
+ (match_test "(GET_CODE (op) == PLUS
+ && REG_P (XEXP (op, 0))
+ && GET_CODE (XEXP (op, 1)) == ASHIFT
+ && REG_P (XEXP (XEXP (op, 1), 0)))"))
+
+;; Return 1 if the operand is a MEM with an indexed-form address.
+(define_special_predicate "index_shift_address_mem"
+ (match_test "(MEM_P (op)
+ && (index_shift_address (XEXP (op, 0), mode)
+ || (GET_CODE (XEXP (op, 0)) == PRE_MODIFY
+ && index_shift_address (XEXP (XEXP (op, 0), 1), mode))))"))
+
;; Predicates used by the various SIMD shift operations. These
;; fall in to 3 categories.
;; Shifts with a range 0-(bit_size - 1) (aarch64_simd_shift_imm)