aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2015-11-16 14:11:50 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2015-11-16 14:11:50 +0000
commit2fe8dfe863400674a41d2c7ee6aaba508e9c19a5 (patch)
tree203f3c978cb505b0a25cb83f4bee37ba4215f928 /gcc/config
parent0d334e376569c1585061f81e0b4ce80b1dfadd41 (diff)
downloadgcc-2fe8dfe863400674a41d2c7ee6aaba508e9c19a5.zip
gcc-2fe8dfe863400674a41d2c7ee6aaba508e9c19a5.tar.gz
gcc-2fe8dfe863400674a41d2c7ee6aaba508e9c19a5.tar.bz2
re PR target/68277 ([SH]: error: insn does not satisfy its constraints when compiling erlang)
gcc/ PR target/68277 * config/sh/sh.md (addsi3_scr): Handle reg overlap of operands[0] and operands[2]. (*addsi3): Add another insn_and_split variant for reload. Co-Authored-By: Kaz Kojima <kkojima@gcc.gnu.org> From-SVN: r230425
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/sh/sh.md42
1 files changed, 41 insertions, 1 deletions
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 5c748ce..083febe 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -2232,10 +2232,50 @@
}
}
else if (!reg_overlap_mentioned_p (operands[0], operands[1]))
- emit_move_insn (operands[0], operands[1]);
+ {
+ if (!reg_overlap_mentioned_p (operands[0], operands[2]))
+ emit_move_insn (operands[0], operands[1]);
+ else
+ operands[2] = operands[1];
+ }
}
[(set_attr "type" "arith")])
+;; Old reload might generate add insns directly (not through the expander) for
+;; the memory address of complex insns like atomic insns when reloading.
+(define_insn_and_split "*addsi3"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (plus:SI (match_operand:SI 1 "arith_reg_operand" "r")
+ (match_operand:SI 2 "arith_or_int_operand" "rn")))]
+ "TARGET_SH1 && !sh_lra_p ()
+ && reload_completed
+ && !reg_overlap_mentioned_p (operands[0], operands[1])"
+ "#"
+ "&& 1"
+ [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
+{
+ if (operands[2] == const0_rtx)
+ {
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+ }
+
+ if (CONST_INT_P (operands[2]))
+ {
+ if (satisfies_constraint_I08 (operands[2]))
+ emit_move_insn (operands[0], operands[1]);
+ else
+ {
+ emit_move_insn (operands[0], operands[2]);
+ operands[2] = operands[1];
+ }
+ }
+ else if (!reg_overlap_mentioned_p (operands[0], operands[2]))
+ emit_move_insn (operands[0], operands[1]);
+ else
+ operands[2] = operands[1];
+})
+
(define_insn_and_split "*addsi3"
[(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
(plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r")