diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2015-11-16 14:11:50 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2015-11-16 14:11:50 +0000 |
commit | 2fe8dfe863400674a41d2c7ee6aaba508e9c19a5 (patch) | |
tree | 203f3c978cb505b0a25cb83f4bee37ba4215f928 /gcc/config | |
parent | 0d334e376569c1585061f81e0b4ce80b1dfadd41 (diff) | |
download | gcc-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.md | 42 |
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") |