@@ -11514,6 +11514,52 @@ avr_rtx_costs (rtx x, machine_mode mode, int
outer_code,
}
+/* Implement `TARGET_INSN_COST'. */
+/* For some insns, it is not enough to look at the cost of the SET_SRC.
+ In that case, have a look at the entire insn, e.g. during insn
combine. */
+
+static int
+avr_insn_cost (rtx_insn *insn, bool speed)
+{
+ const int unknown_cost = -1;
+ int cost = unknown_cost;
+
+ rtx set = single_set (insn);
+
+ if (set
+ && ZERO_EXTRACT == GET_CODE (SET_DEST (set)))
+ {
+ // Try find anything that would flip the extracted bit.
+ bool not_bit_p = false;
+
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST)
+ {
+ enum rtx_code code = GET_CODE (*iter);
+ not_bit_p |= code == NOT || code == XOR || code == GE;
+ }
+
+ // Don't go too deep into the analysis. In almost all cases,
+ // using BLD/BST is the best we can do for single-bit moves,
+ // even considering CSE.
+ cost = COSTS_N_INSNS (2 + not_bit_p);
+ }
+
+ if (cost != unknown_cost)
+ {
+ if (avr_log.rtx_costs)
+ avr_edump ("\n%? (%s) insn_cost=%d\n%r\n",
+ speed ? "speed" : "size", cost, insn);
+ return cost;
+ }
+
+ // Resort to what rtlanal.cc::insn_cost() implements as a default
+ // when targetm.insn_cost() is not implemented.
+
+ return pattern_cost (PATTERN (insn), speed);
+}
+
+
/* Implement `TARGET_ADDRESS_COST'. */