> You would need some way to indicate that while Y does accept a mem,
> this particular mem can't be reloaded to match.  We don't have a way
> to do that.

As a test, I added this API.  It seems to work.  I suppose there could
be a better API where we determine if a constrain matches various
memory spaces, then compare with the memory space of the operand, but
I can't prove that's sufficiently flexible for all targets that
support memory spaces.  Heck, I'm not even sure what to call the
macro, and 
"TARGET_IS_THIS_MEMORY_ADDRESS_RELOADABLE_TO_MATCH_THIS_CONTRAINT_P()"
is a little long ;-)

What do we think of this direction?


Index: reload.c
===================================================================
RCS file: /cvs/cvsfiles/gnupro/gcc/reload.c,v
retrieving revision 1.33
diff -p -U 5 -r1.33 reload.c
--- reload.c    20 Feb 2014 16:40:26 -0000      1.33
+++ reload.c    15 Sep 2015 05:38:24 -0000
@@ -3517,20 +3517,26 @@ find_reloads (rtx insn, int replace, int
                                     && ((reg_equiv_mem (REGNO (operand)) != 0
                                          && EXTRA_CONSTRAINT_STR 
(reg_equiv_mem (REGNO (operand)), c, p))
                                         || (reg_equiv_address (REGNO 
(operand)) != 0)))
                              win = 1;
 
+#ifndef COMPATIBLE_CONSTRAINT_P
+#define COMPATIBLE_CONSTRAINT_P(c,p,op) 1
+#endif
+                           if (!MEM_P (operand) || COMPATIBLE_CONSTRAINT_P (c, 
p, operand))
+                             {
                            /* If we didn't already win, we can reload
                               constants via force_const_mem, and other
                               MEMs by reloading the address like for 'o'.  */
                            if (CONST_POOL_OK_P (operand_mode[i], operand)
                                || MEM_P (operand))
                              badop = 0;
                            constmemok = 1;
                            offmemok = 1;
                            break;
                          }
+                         }
                        if (EXTRA_ADDRESS_CONSTRAINT (c, p))
                          {
                            if (EXTRA_CONSTRAINT_STR (operand, c, p))
                              win = 1;
 

Index: config/rl78/rl78.c
===================================================================
RCS file: /cvs/cvsfiles/gnupro/gcc/config/rl78/rl78.c,v
retrieving revision 1.12.6.16
diff -p -U 5 -r1.12.6.16 rl78.c
--- config/rl78/rl78.c  5 Aug 2015 13:43:59 -0000       1.12.6.16
+++ config/rl78/rl78.c  15 Sep 2015 05:39:04 -0000
@@ -1041,10 +1041,18 @@ rl78_far_p (rtx x)
     return 0;
 
   return GET_MODE_BITSIZE (rl78_addr_space_address_mode (MEM_ADDR_SPACE (x))) 
== 32;
 }
 
+int
+rl78_compatible_constraint_p (char c, const char *p, rtx r)
+{
+  if (c == 'Y' && rl78_far_p (r))
+    return 0;
+  return 1;
+}
+
 /* Return the appropriate mode for a named address pointer.  */
 #undef  TARGET_ADDR_SPACE_POINTER_MODE
 #define TARGET_ADDR_SPACE_POINTER_MODE rl78_addr_space_pointer_mode
 
 static enum machine_mode

Index: config/rl78/rl78.h
===================================================================
RCS file: /cvs/cvsfiles/gnupro/gcc/config/rl78/rl78.h,v
retrieving revision 1.7.8.3
diff -p -U 5 -r1.7.8.3 rl78.h
--- config/rl78/rl78.h  17 Mar 2015 14:54:35 -0000      1.7.8.3
+++ config/rl78/rl78.h  15 Sep 2015 05:39:28 -0000
@@ -500,5 +500,7 @@ typedef unsigned int CUMULATIVE_ARGS;
 
 /* NOTE: defined but zero means dwarf2 debugging, but sjlj EH.  */
 #define DWARF2_UNWIND_INFO 0
 
 #define REGISTER_TARGET_PRAGMAS() rl78_register_pragmas()
+
+#define COMPATIBLE_CONSTRAINT_P(C,P,OP) rl78_compatible_constraint_p (C,P,OP)

Reply via email to