@@ -1950,7 +1950,7 @@ h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
|| GET_CODE (op0) == NEG || GET_CODE (op0) == AND
|| GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
|| GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT
- || GET_CODE (op0) == MULT
+ || GET_CODE (op0) == MULT || GET_CODE (op0) == SYMBOL_REF
|| GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND
|| REG_P (op0) || MEM_P (op0)))
return CCZNmode;
@@ -4,7 +4,27 @@
(logicals:QHSI (match_operand:QHSI 1 "register_operand" "")
(match_operand:QHSI 2 "h8300_src_operand" "")))]
""
- "")
+ "
+ {
+ enum machine_mode mode = GET_MODE (operands[0]);
+ /* DImodes are not considered tieable, as a result operations involving
+ subregs of DImode objects are considered expensive which can prevent
+ CSE from doing obvious simplifications.
+
+ We may ultimately change what is tieable, but this is an immediate
+ workaround while we evaluate changes to tieable modes.
+
+ The key in terms of what we want to handle is then the result of
+ the operation is not a constant. */
+ if ((<CODE> == AND && operands[2] == CONSTM1_RTX (mode))
+ || (<CODE> == IOR && operands[2] == CONST0_RTX (mode))
+ || (<CODE> == XOR && operands[2] == CONST0_RTX (mode))
+ || ((<CODE> == AND || <CODE> == IOR) && operands[1] == operands[2]))
+ {
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+ }
+ }")
;; There's a ton of cleanup to do from here below.
;; ----------------------------------------------------------------------