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