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"
+)

Reply via email to