Hi DJ, The patch below adds some missing instruction patterns to the RL78 backend. Missing in the sense that gcc generates the RTL even if the patterns are not present in the backend and then triggers an ICE because they cannot be matched. It is not clear to me why this should be happening, but adding the patterns was the easiest fix.
Applying the patch resolves these tests in the gcc testsuite, and does not introduce any regressions. gcc.c-torture/execute/20020226-1.c gcc.c-torture/execute/20020508-1.c gcc.c-torture/execute/pr57321.c gcc.c-torture/unsorted/bf.c gcc.dg/20050922-1.c OK to apply ? Cheers Nick gcc/ChangeLog 2014-02-14 Nick Clifton <ni...@redhat.com> * config/rl78/rl78-expand.md (xorhi3): New pattern. * config/rl78/rl78-virt.md (andhi3_virt): New pattern. (nandhi3_virt): New pattern. (xorhi3_virt): New pattern. * config/rl78/rl78-real.md (andhi3_real): New pattern. (nandhi3_real): New pattern. (xorhi3_real): New pattern. Index: gcc/config/rl78/rl78-expand.md =================================================================== --- gcc/config/rl78/rl78-expand.md (revision 207762) +++ gcc/config/rl78/rl78-expand.md (working copy) @@ -304,3 +304,15 @@ "1" "rl78_expand_compare (operands);" ) + +(define_expand "xorhi3" + [(set (match_operand:HI 0 "register_operand") + (xor:HI (match_operand:HI 1 "register_operand") + (match_operand:HI 2 "nonmemory_operand"))) + ] + "" + "if (GET_CODE (operands[2]) == SYMBOL_REF) + operands[2] = force_reg (HImode, operands[2]); + if (rl78_force_nonfar_3 (operands, gen_xorhi3)) + DONE;" +) Index: gcc/config/rl78/rl78-real.md =================================================================== --- gcc/config/rl78/rl78-real.md (revision 207762) +++ gcc/config/rl78/rl78-real.md (working copy) @@ -549,3 +576,34 @@ [(set (reg:QI A_REG) (and:QI (reg:QI A_REG) (match_dup 1)))] ) +(define_insn "*andhi3_real" + [(set (match_operand:HI 0 "register_operand" "=Av") + (and:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:HI 2 "immediate_operand" "n"))) + ] + "rl78_real_insns_ok ()" + "and\t%q0, %q2 \; and\t%Q0, %Q2" +) + +(define_insn "*nandhi3_real" + [(set (match_operand:HI 0 "register_operand" "=A") + (and:HI (neg:HI (match_operand:HI 1 "register_operand" "0")) + (match_operand:HI 2 "immediate_operand" "n"))) + ] + "rl78_real_insns_ok ()" + "xor a, #0xff @ xch a, x @ xor a, #0xff @ xch a, x @ addw ax, #1 @ and a, %Q2 @ xch a, x @ and a, %q2 @ xch a, x" +) + +;; Necessary because GCC insists upon being able to perform binary +;; operations upon pointers. Failure to provide these patterns +;; results in GCC generating illegal subregs, eg: (SUBREG:QI (REG:HI 33) 1) + +(define_insn "*xorhi3_real" + [(set (match_operand:HI 0 "register_operand" "=A") + (xor:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:HI 2 "nonmemory_operand" "ABDTn"))) + ] + "rl78_real_insns_ok ()" + "xor a, %Q2 \; xch a, x \; xor a, %q2 \; xch a, x" +) + Index: gcc/config/rl78/rl78-virt.md =================================================================== --- gcc/config/rl78/rl78-virt.md (revision 207762) +++ gcc/config/rl78/rl78-virt.md (working copy) @@ -405,3 +405,34 @@ ] "rl78_setup_peep_movhi (operands);" ) + +(define_insn "*andhi3_virt" + [(set (match_operand:HI 0 "register_operand" "=v") + (and:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:HI 2 "immediate_operand" "n"))) + ] + "rl78_virt_insns_ok ()" + "v.and\t%0, %1, %2" +) + +(define_insn "*nandhi3_virt" + [(set (match_operand:HI 0 "register_operand" "=v") + (and:HI (neg:HI (match_operand:HI 1 "register_operand" "0")) + (match_operand:HI 2 "immediate_operand" "n"))) + ] + "rl78_virt_insns_ok ()" + "v.nand\t%0, %1, %2" +) + +;; Necessary because GCC insists upon being able to perform binary +;; operations upon pointers. Failure to provide these patterns +;; results in GCC generating illegal subregs, eg: (SUBREG:QI (REG:HI 33) 1) + +(define_insn "*xorhi3_virt" + [(set (match_operand:HI 0 "register_operand" "=v") + (xor:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:HI 2 "nonmemory_operand" "vn"))) + ] + "rl78_virt_insns_ok () && GET_CODE (operands[2]) != SYMBOL_REF" + "v.xor.hi\t%0, %1, %2" +)