diff mbox

RFA: RL78: Add missing instruction patterns

Message ID 871tz57wfm.fsf@redhat.com
State New
Headers show

Commit Message

Nick Clifton Feb. 14, 2014, 11:42 a.m. UTC
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  <nickc@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.

Comments

DJ Delorie Feb. 14, 2014, 7:01 p.m. UTC | #1
I'm OK with adding patterns in general, but I wonder if gcc would
produce better code if they were split into QImode ops earlier?

+  [(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"

You can't use %Q with AX and AND.

+;; operations upon pointers.  Failure to provide these patterns
+;; results in GCC generating illegal subregs, eg: (SUBREG:QI (REG:HI 33) 1)

Why is that subreg illegal?

+(define_insn "*nandhi3_virt"

Is this one just an optimization?
diff mbox

Patch

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