rl78-real.md (*addqi_real): Allow SADDR types for inc/dec.
authorDJ Delorie <dj@redhat.com>
Tue, 3 Mar 2015 21:57:40 +0000 (16:57 -0500)
committerDJ Delorie <dj@gcc.gnu.org>
Tue, 3 Mar 2015 21:57:40 +0000 (16:57 -0500)
* config/rl78/rl78-real.md (*addqi_real): Allow SADDR types for
inc/dec.
(*addhi3_real): Likewise.
* config/rl78/rl78-virt.md (*inc<mode>3_virt): Additional
pattern to match incrementing memory.
* config/rl78/predicates.md (rl78_1_2_operand): New.
* config/rl78/rl78.c (rl78_force_nonfar_3): Allow far mem-mem if
it's the same and only mem.
(rl78_alloc_physical_registers_op2): If there's effectively only
one MEM, transcode it into HL.
(rl78_far_p): Reject addresses that aren't legitimate.

From-SVN: r221164

gcc/ChangeLog
gcc/config/rl78/predicates.md
gcc/config/rl78/rl78-real.md
gcc/config/rl78/rl78-virt.md
gcc/config/rl78/rl78.c

index a562ee79d180849090c898d08d05400a794eed48..10f36fa3558747ceb3b5f4cd36b4c91f239a586a 100644 (file)
@@ -1,3 +1,17 @@
+2015-03-03  DJ Delorie  <dj@redhat.com>
+
+       * config/rl78/rl78-real.md (*addqi_real): Allow SADDR types for
+       inc/dec.
+       (*addhi3_real): Likewise.
+       * config/rl78/rl78-virt.md (*inc<mode>3_virt): Additional
+       pattern to match incrementing memory.
+       * config/rl78/predicates.md (rl78_1_2_operand): New.
+       * config/rl78/rl78.c (rl78_force_nonfar_3): Allow far mem-mem if
+       it's the same and only mem.
+       (rl78_alloc_physical_registers_op2): If there's effectively only
+       one MEM, transcode it into HL.
+       (rl78_far_p): Reject addresses that aren't legitimate.
+
 2015-03-03  Eric Botcazou  <ebotcazou@adacore.com>
 
        * fold-const.c (round_up_loc): Cast divisor to HOST_WIDE_INT before
index b89eed22400a3b0c92a9e67d244dd38a540bcd1f..66e7e44827d08f192b3d1c1b148f3e8fe00d4c51 100644 (file)
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
 
+(define_predicate "rl78_incdec_memory_operand"
+  (and (match_code "mem")
+       (match_test "rl78_far_p (op)
+|| satisfies_constraint_Wsa (op)
+|| satisfies_constraint_Whl (op)
+|| satisfies_constraint_Wh1 (op)
+|| satisfies_constraint_Wab (op)")
+  )
+)
+
+(define_predicate "rl78_1_2_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 1, 2)
+                  || IN_RANGE (INTVAL (op), -2, -1)")))
+
 (define_predicate "rl78_24_operand"
   (and (match_code "const_int")
        (match_test "INTVAL (op) == 2 || INTVAL (op) == 4")))
index 8ec2f3d6a6f5a2f91bbb7f522aaa3dceb179a100..cfd9742a5d7090f0d5d83a8b1d401cac41daeddb 100644 (file)
 ;;---------- Arithmetic ------------------------
 
 (define_insn "*addqi3_real"
-  [(set (match_operand:QI          0 "rl78_nonimmediate_operand"  "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl,Wsa")
+  [(set (match_operand:QI          0 "rl78_nonimmediate_operand"  "=rvWabWhlWh1Wsa,rvWabWhlWh1Wsa,a,*bcdehl,Wsa")
        (plus:QI (match_operand:QI 1 "rl78_general_operand"  "%0,0,0,0,0")
                 (match_operand:QI 2 "rl78_general_operand" "K,L,RWhlWh1Wabi,a,i")))
    ]
   "rl78_real_insns_ok ()"
   "@
-    inc\t%0
-    dec\t%0
+    inc\t%p0
+    dec\t%p0
     add\t%0, %2
     add\t%0, %2
     add\t%0, %2"
 )
 
 (define_insn "*addhi3_real"
-  [(set (match_operand:HI          0 "rl78_nonimmediate_operand"  "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A")
+  [(set (match_operand:HI          0 "rl78_nonimmediate_operand"  "=vABDTWhlWh1WabWsa,vABDTWhlWh1WabWsa,v,v,A,S,S,A")
        (plus:HI (match_operand:HI 1 "rl78_general_operand"  "%0,0,0,0,0,0,0,S")
                 (match_operand:HI 2 "" "K,L,N,O,RWh1WhlWabiv,Int8Qs8,J,Ri")))
    ]
index fadcbc5043301a0cf306ca4930851b35b9e4c74b..c29db26da80509164b82b8b368f0e6c94da9d266 100644 (file)
 
 ;;---------- Arithmetic ------------------------
 
+(define_insn "*inc<mode>3_virt"
+  [(set (match_operand:QHI           0 "rl78_incdec_memory_operand" "=vm")
+       (plus:QHI (match_operand:QHI 1 "rl78_incdec_memory_operand" "0")
+                 (match_operand:QHI 2 "rl78_1_2_operand" "KLNO")))
+   ]
+  "rl78_virt_insns_ok ()"
+  "v.inc\t%0, %1, %2"
+)
+
 (define_insn "*add<mode>3_virt"
   [(set (match_operand:QHI           0 "rl78_nonfar_nonimm_operand" "=vY,S")
        (plus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "viY,0")
index 40772dad03fb0caaa165a7ebbf89a21ec18bd385..0c577c4414e02c421d1a3c845337db5d4e036cd0 100644 (file)
@@ -579,6 +579,13 @@ rl78_force_nonfar_3 (rtx *operands, rtx (*gen)(rtx,rtx,rtx))
   int did = 0;
   rtx temp_reg = NULL;
 
+  /* As an exception, we allow two far operands if they're identical
+     and the third operand is not a MEM.  This allows global variables
+     to be incremented, for example.  */
+  if (rtx_equal_p (operands[0], operands[1])
+      && ! MEM_P (operands[2]))
+    return 0;
+
   /* FIXME: Likewise.  */
   if (rl78_far_p (operands[1]))
     {
@@ -970,6 +977,12 @@ rl78_far_p (rtx x)
   fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x);
   fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
 #endif
+
+  /* Not all far addresses are legitimate, because the devirtualizer
+     can't handle them.  */
+  if (! rl78_as_legitimate_address (GET_MODE (x), XEXP (x, 0), false, ADDR_SPACE_FAR))
+    return 0;
+
   return GET_MODE_BITSIZE (rl78_addr_space_address_mode (MEM_ADDR_SPACE (x))) == 32;
 }
 
@@ -3007,9 +3020,18 @@ rl78_alloc_physical_registers_op2 (rtx_insn * insn)
 
   if (rtx_equal_p (OP (0), OP (1)))
     {
-      OP (0) =
-      OP (1) = transcode_memory_rtx (OP (1), DE, insn);
-      OP (2) = transcode_memory_rtx (OP (2), HL, insn);
+      if (MEM_P (OP (2)))
+       {
+         OP (0) =
+         OP (1) = transcode_memory_rtx (OP (1), DE, insn);
+         OP (2) = transcode_memory_rtx (OP (2), HL, insn);
+       }
+      else
+       {
+         OP (0) =
+         OP (1) = transcode_memory_rtx (OP (1), HL, insn);
+         OP (2) = transcode_memory_rtx (OP (2), DE, insn);
+       }
     }
   else if (rtx_equal_p (OP (0), OP (2)))
     {