[rl78] add bit test/branch insns
diff mbox

Message ID 201309180058.r8I0wJRA023963@greed.delorie.com
State New
Headers show

Commit Message

DJ Delorie Sept. 18, 2013, 12:58 a.m. UTC
A few new patterns.  Committed.


2013-09-17  Nick Clifton  <nickc@redhat.com>

	* config/rl78/rl78-real.md (bf): New pattern.
	(bt): New pattern.
	* config/rl78/rl78.c (rl78_print_operand_1): Handle %B.
	(rl78_print_operand): Do not put a # before a %B.
	* config/rl78/rl78.opt: Tweak doc strings.

Patch
diff mbox

Index: config/rl78/rl78-real.md
===================================================================
--- config/rl78/rl78-real.md	(revision 202675)
+++ config/rl78/rl78-real.md	(working copy)
@@ -456,6 +456,61 @@ 
    (set (reg:HI AX_REG)
 	(match_dup 0))]
   ""
   [(set (match_dup 0) (reg:HI AX_REG))]
   )
 
+;; Bit test and branch insns.
+
+;; NOTE: These patterns will work for bits in other places, not just A.
+
+(define_insn "bf"
+  [(set (pc)
+	(if_then_else (eq (and (reg:QI A_REG)
+			       (match_operand 0 "immediate_operand" "n"))
+			  (const_int 0))
+		      (label_ref (match_operand 1 "" ""))
+		      (pc)))]
+  ""
+  "bf\tA.%B0, $%1"
+)
+
+(define_insn "bt"
+  [(set (pc)
+	(if_then_else (ne (and (reg:QI A_REG)
+			       (match_operand 0 "immediate_operand" "n"))
+			  (const_int 0))
+		      (label_ref (match_operand 1 "" ""))
+		      (pc)))]
+  ""
+  "bt\tA.%B0, $%1"
+)
+
+;; NOTE: These peepholes are fragile.  They rely upon GCC generating
+;; a specific sequence on insns, based upon examination of test code.
+;; Improvements to GCC or using code other than the test code can result
+;; in the peephole not matching and the optimization being missed.
+
+(define_peephole2
+  [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG))
+   (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand")))
+   (set (pc) (if_then_else (eq (match_dup 1) (const_int 0))
+			   (label_ref (match_operand 3 ""))
+			   (pc)))]
+  "peep2_regno_dead_p (3, REGNO (operands[1]))
+   && exact_log2 (INTVAL (operands[2])) >= 0"
+  [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup 2)) (const_int 0))
+			   (label_ref (match_dup 3)) (pc)))]
+  )
+
+(define_peephole2
+  [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG))
+   (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand")))
+   (set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
+			   (label_ref (match_operand 3 ""))
+			   (pc)))]
+  "peep2_regno_dead_p (3, REGNO (operands[1]))
+   && exact_log2 (INTVAL (operands[2])) >= 0"
+  [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup 2)) (const_int 0))
+			   (label_ref (match_dup 3)) (pc)))]
+  )
+
Index: config/rl78/rl78.c
===================================================================
--- config/rl78/rl78.c	(revision 202675)
+++ config/rl78/rl78.c	(working copy)
@@ -1283,12 +1283,13 @@  rl78_function_arg_boundary (enum machine
    m - minus - negative of CONST_INT value.
    c - inverse of a conditional (NE vs EQ for example)
    z - collapsed conditional
    s - shift count mod 8
    S - shift count mod 16
    r - reverse shift count (8-(count mod 8))
+   B - bit position
 
    h - bottom HI of an SI
    H - top HI of an SI
    q - bottom QI of an HI
    Q - top QI of an HI
    e - third QI of an SI (i.e. where the ES register gets values from)
@@ -1409,12 +1410,14 @@  rl78_print_operand_1 (FILE * file, rtx o
       else if (letter == 'q')
 	fprintf (file, "%ld", INTVAL (op) & 0xff);
       else if (letter == 'h')
 	fprintf (file, "%ld", INTVAL (op) & 0xffff);
       else if (letter == 'e')
 	fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff);
+      else if (letter == 'B')
+	fprintf (file, "%d", exact_log2 (INTVAL (op)));
       else if (letter == 'E')
 	fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff);
       else if (letter == 'm')
 	fprintf (file, "%ld", - INTVAL (op));
       else if (letter == 's')
 	fprintf (file, "%ld", INTVAL (op) % 8);
@@ -1602,13 +1605,13 @@  rl78_print_operand_1 (FILE * file, rtx o
 #undef  TARGET_PRINT_OPERAND
 #define TARGET_PRINT_OPERAND		rl78_print_operand
 
 static void
 rl78_print_operand (FILE * file, rtx op, int letter)
 {
-  if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S')
+  if (CONSTANT_P (op) && letter != 'u' && letter != 's' && letter != 'r' && letter != 'S' && letter != 'B')
     fprintf (file, "#");
   rl78_print_operand_1 (file, op, letter);
 }
 
 #undef  TARGET_TRAMPOLINE_INIT
 #define TARGET_TRAMPOLINE_INIT rl78_trampoline_init
Index: config/rl78/rl78.opt
===================================================================
--- config/rl78/rl78.opt	(revision 202675)
+++ config/rl78/rl78.opt	(working copy)
@@ -20,13 +20,13 @@ 
 ;---------------------------------------------------
 
 HeaderInclude
 config/rl78/rl78-opts.h
 
 msim
-Target
+Target Report
 Use the simulator runtime.
 
 mmul=
 Target RejectNegative Joined Var(rl78_mul_type) Report Tolower Enum(rl78_mul_types) Init(MUL_NONE)
 Select hardware or software multiplication support.
 
@@ -40,16 +40,16 @@  EnumValue
 Enum(rl78_mul_types) String(rl78) Value(MUL_RL78)
 
 EnumValue
 Enum(rl78_mul_types) String(g13) Value(MUL_G13)
 
 mallregs
-Target Mask(ALLREGS)
+Target Mask(ALLREGS) Report Optimization
 Use all registers, reserving none for interrupt handlers.
 
 mrelax
-Target
-Enable assembler and linker relaxation.
+Target Report Optimization
+Enable assembler and linker relaxation.  Enabled by default at -Os.
 
 mg10
-Target Mask(G10)
+Target Mask(G10) Report
 Target the RL78/G10 series