This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[m32c] reject illegal subregs of hard regs


Applied.  Note to Ian: this makes gcc work without your lower-subreg
patch, which is how I tested it.

2007-02-08  DJ Delorie  <dj@redhat.com>

	* config/m32c/m32c-protos.h (m32c_illegal_subreg_p): New.
	* config/m32c/m32c.c (legal_subregs): New.
	(m32c_illegal_subreg_p): New.
	* config/m32c/predicates.md (m32c_any_operand): Use it to reject
	unsupported subregs of hard regs.

Index: config/m32c/predicates.md
===================================================================
--- config/m32c/predicates.md	(revision 121724)
+++ config/m32c/predicates.md	(working copy)
@@ -27,7 +27,11 @@
 
 (define_predicate "m32c_any_operand"
   (ior (match_operand 0 "general_operand")
-       (match_operand 1 "memory_operand")))
+       (match_operand 1 "memory_operand"))
+  {
+    return ! m32c_illegal_subreg_p (op);
+  }
+)
 
 ; Likewise for nonimmediate_operand.
 
Index: config/m32c/m32c.c
===================================================================
--- config/m32c/m32c.c	(revision 121724)
+++ config/m32c/m32c.c	(working copy)
@@ -2749,6 +2749,81 @@ m32c_insert_attributes (tree node ATTRIB
 
 /* Predicates */
 
+/* This is a list of legal subregs of hard regs.  */
+static struct {
+  enum machine_mode outer_mode_size;
+  enum machine_mode inner_mode_size;
+  unsigned int regno;
+  int byte_mask;
+  int legal_when;
+} legal_subregs[] = {
+  {1, 2, R0_REGNO, 0x03, 1}, /* r0h r0l */
+  {1, 2, R1_REGNO, 0x03, 1}, /* r1h r1l */
+  {1, 2, A0_REGNO, 0x01, 1},
+  {1, 2, A1_REGNO, 0x01, 1},
+
+  {1, 4, A0_REGNO, 0x01, 1},
+  {1, 4, A1_REGNO, 0x01, 1},
+
+  {2, 4, R0_REGNO, 0x05, 1}, /* r2 r0 */
+  {2, 4, R1_REGNO, 0x05, 1}, /* r3 r1 */
+  {2, 4, A0_REGNO, 0x05, 16}, /* a1 a0 */
+  {2, 4, A0_REGNO, 0x01, 24}, /* a1 a0 */
+  {2, 4, A1_REGNO, 0x01, 24}, /* a1 a0 */
+
+  {4, 8, R0_REGNO, 0x55, 1}, /* r3 r1 r2 r0 */
+};
+
+/* Returns TRUE if OP is a subreg of a hard reg which we don't
+   support.  */
+bool
+m32c_illegal_subreg_p (rtx op)
+{
+  rtx orig_op = op;
+  int offset;
+  unsigned int i;
+  int src_mode, dest_mode;
+
+  if (GET_CODE (op) != SUBREG)
+    return false;
+
+  dest_mode = GET_MODE (op);
+  offset = SUBREG_BYTE (op);
+  op = SUBREG_REG (op);
+  src_mode = GET_MODE (op);
+
+  if (GET_MODE_SIZE (dest_mode) == GET_MODE_SIZE (src_mode))
+    return false;
+  if (GET_CODE (op) != REG)
+    return false;
+  if (REGNO (op) >= MEM0_REGNO)
+    return false;
+
+  offset = (1 << offset);
+
+  for (i = 0; i < sizeof(legal_subregs)/sizeof(legal_subregs[0]); i ++)
+    if (legal_subregs[i].outer_mode_size == GET_MODE_SIZE (dest_mode)
+	&& legal_subregs[i].regno == REGNO (op)
+	&& legal_subregs[i].inner_mode_size == GET_MODE_SIZE (src_mode)
+	&& legal_subregs[i].byte_mask & offset)
+      {
+	switch (legal_subregs[i].legal_when)
+	  {
+	  case 1:
+	    return false;
+	  case 16:
+	    if (TARGET_A16)
+	      return false;
+	    break;
+	  case 24:
+	    if (TARGET_A24)
+	      return false;
+	    break;
+	  }
+      }
+  return true;
+}
+
 /* Returns TRUE if we support a move between the first two operands.
    At the moment, we just want to discourage mem to mem moves until
    after reload, because reload has a hard time with our limited
Index: config/m32c/m32c-protos.h
===================================================================
--- config/m32c/m32c-protos.h	(revision 121724)
+++ config/m32c/m32c-protos.h	(working copy)
@@ -74,6 +74,7 @@ int  m32c_extra_constraint_p (rtx, char,
 int  m32c_extra_constraint_p2 (rtx, char, const char *);
 int  m32c_hard_regno_nregs (int, MM);
 int  m32c_hard_regno_ok (int, MM);
+bool m32c_illegal_subreg_p (rtx);
 bool m32c_immd_dbl_mov (rtx *, MM);
 rtx  m32c_incoming_return_addr_rtx (void);
 void m32c_initialize_trampoline (rtx, rtx, rtx);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]