@@ -11786,6 +11786,55 @@ arc_can_use_return_insn (void)
&& !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
}
+/* Helper for INSN_COST.
+
+ Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an
+ insn, a set, a set source, any random piece of one). set_src_cost,
+ set_rtx_cost, etc. are helper functions that use that.
+
+ Those functions do not work for parallels. Also, costs are not
+ additive like this simplified model assumes. Also, more complex
+ backends tend to miss many cases in their rtx_costs function.
+
+ Many passes that want costs want to know the cost of a full insn. Like
+ combine. That's why I created insn_cost: it solves all of the above
+ problems. */
+
+static int
+arc_insn_cost (rtx_insn *insn, bool speed)
+{
+ int cost;
+ if (recog_memoized (insn) < 0)
+ return 0;
+
+ /* If optimizing for size, we want the insn size. */
+ if (!speed)
+ return get_attr_length (insn);
+
+ /* Use cost if provided. */
+ cost = get_attr_cost (insn);
+ if (cost > 0)
+ return cost;
+
+ /* For speed make a simple cost model: memory access is more
+ expensive than any other instruction. */
+ enum attr_type type = get_attr_type (insn);
+
+ switch (type)
+ {
+ case TYPE_LOAD:
+ case TYPE_STORE:
+ cost = COSTS_N_INSNS (2);
+ break;
+
+ default:
+ cost = COSTS_N_INSNS (1);
+ break;
+ }
+
+ return cost;
+}
+
#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
#define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
@@ -11807,6 +11856,9 @@ arc_can_use_return_insn (void)
#undef TARGET_MEMORY_MOVE_COST
#define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST arc_insn_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-arc.h"
@@ -229,6 +229,10 @@
]
)
+;; What is the insn_cost for this insn? The target hook can still override
+;; this. For optimizing for size the "length" attribute is used instead.
+(define_attr "cost" "" (const_int 0))
+
(define_attr "is_sfunc" "no,yes" (const_string "no"))
;; Insn type. Used to default other attribute values.
@@ -3140,9 +3144,9 @@ archs4x, archs4xd"
[(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r")
(match_operand:SI 2 "_2_4_8_operand" ""))
- (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))]
+ (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
""
- "add%z2%?\\t%0,%3,%1%&"
+ "add%z2%?\\t%0,%3,%1"
[(set_attr "type" "shift")
(set_attr "length" "*,4,8")
(set_attr "predicable" "yes,no,no")
@@ -3573,26 +3577,26 @@ archs4x, archs4xd"
; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
; provide one alternatice for this, without condexec support.
(define_insn "*ashlsi3_insn"
- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
- (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCsz")
- (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
+ [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
+ (ashift:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
+ (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
"TARGET_BARREL_SHIFTER
&& (register_operand (operands[1], SImode)
|| register_operand (operands[2], SImode))"
- "asl%? %0,%1,%2%&"
+ "asl%?\\t%0,%1,%2"
[(set_attr "type" "shift")
(set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
(set_attr "predicable" "no,no,no,yes,no,no")
(set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
(define_insn "*ashrsi3_insn"
- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
- (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCsz")
- (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
+ [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
+ (ashiftrt:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
+ (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
"TARGET_BARREL_SHIFTER
&& (register_operand (operands[1], SImode)
|| register_operand (operands[2], SImode))"
- "asr%? %0,%1,%2%&"
+ "asr%?\\t%0,%1,%2"
[(set_attr "type" "shift")
(set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
(set_attr "predicable" "no,no,no,yes,no,no")
@@ -3613,11 +3617,11 @@ archs4x, archs4xd"
(set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
(define_insn "rotrsi3"
- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
- (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCsz")
- (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
+ [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
+ (rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand" " 0,rL,rCsz")
+ (match_operand:SI 2 "nonmemory_operand" "rL,rL,rCal")))]
"TARGET_BARREL_SHIFTER"
- "ror%? %0,%1,%2"
+ "ror%?\\t%0,%1,%2"
[(set_attr "type" "shift,shift,shift")
(set_attr "predicable" "yes,no,no")
(set_attr "length" "4,4,8")])
@@ -4349,16 +4353,15 @@ archs4x, archs4xd"
(ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "_1_2_3_operand" "")))
(set (match_operand:SI 3 "dest_reg_operand" "")
- (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
- (match_operand:SI 5 "nonmemory_operand" "")))]
+ (plus:SI (match_operand:SI 4 "arc_nonmemory_operand" "")
+ (match_operand:SI 5 "arc_nonmemory_operand" "")))]
"(true_regnum (operands[4]) == true_regnum (operands[0])
|| true_regnum (operands[5]) == true_regnum (operands[0]))
&& (peep2_reg_dead_p (2, operands[0])
- || (true_regnum (operands[3]) == true_regnum (operands[0])))
- && !(optimize_size && satisfies_constraint_I (operands[4]))
- && !(optimize_size && satisfies_constraint_I (operands[5]))"
- ;; the preparation statements take care to put proper operand in operands[4]
- ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
+ || (true_regnum (operands[3]) == true_regnum (operands[0])))"
+ ;; the preparation statements take care to put proper operand in
+ ;; operands[4] operands[4] will always contain the correct
+ ;; operand. This is added to satisfy commutativity
[(set (match_dup 3)
(plus:SI (mult:SI (match_dup 1)
(match_dup 2))
@@ -6435,7 +6438,7 @@ archs4x, archs4xd"
[(set (match_operand:SI 0 "register_operand" "=q,r,r")
(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
(match_operand:SI 2 "_1_2_3_operand" ""))
- (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))]
+ (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
""
"add%2%?\\t%0,%3,%1"
[(set_attr "length" "*,4,8")
@@ -795,3 +795,8 @@
{
return arc_check_multi (op, false);
})
+
+(define_predicate "arc_nonmemory_operand"
+ (ior (match_test "register_operand (op, mode)")
+ (and (match_code "const_int, symbol_ref")
+ (match_test "!optimize_size"))))
@@ -9,4 +9,4 @@ int foo (void)
}
/* { dg-final { scan-assembler "tst" } } */
-/* { dg-final { scan-assembler "bset.eq" } } */
+/* { dg-final { scan-assembler "bset" } } */