On 09/01/2015 01:44 AM, DJ Delorie wrote:
Given this test case for rl78-elf:

extern __far int a, b;
void ffr (int x)
{
   a = b + x;
}

I'm trying to use this patch:

Index: gcc/config/rl78/rl78-virt.md
===================================================================
--- gcc/config/rl78/rl78-virt.md      (revision 227360)
+++ gcc/config/rl78/rl78-virt.md        (working copy)
@@ -92,15 +92,15 @@
     ]
    "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")
-                 (match_operand:QHI 2 "rl78_general_operand" "vim,i")))
+  [(set (match_operand:QHI           0 "rl78_nonimmediate_operand" "=vY,S,Wfr")
+       (plus:QHI (match_operand:QHI 1 "rl78_general_operand" "viY,0,0")
+                 (match_operand:QHI 2 "rl78_general_operand" "vim,i,vi")))
     ]
    "rl78_virt_insns_ok ()"
    "v.add\t%0, %1, %2"
  )

  (define_insn "*sub<mode>3_virt"


To allow the rl78 port to generate the "Wfr/0/r" case (alternative 3).
(Wfr = far MEM, v = virtual regs).

I expected gcc to see that the operation doesn't meet the constraints,
and move operands into registers to make it work (alternative 1,
"v/v/v").
That'd be my expectation as well. Note that addXX patterns may be special. I can recall a fair amount of pain with them on oddball ports.




Instead, it just complains and dies.

dj.c:42:1: error: insn does not satisfy its constraints:
  }
  ^
(insn 10 15 13 2 (set (mem/c:HI (reg:SI 8 r8) [1 a+0 S2 A16 AS2])
         (plus:HI (mem/c:HI (plus:HI (reg/f:HI 32 sp)
                     (const_int 4 [0x4])) [1 x+0 S2 A16])
             (mem/c:HI (symbol_ref:SI ("b") <var_decl 0x7f676f97d3f0 b>) [1 b+0 
S2 A16 AS2]))) dj.c:41 13 {*addhi3_virt}
      (nil))
dj.c:42:1: internal compiler error: in extract_constrain_insn, at recog.c:2200


Reloads for insn # 10
Reload 0: reload_in (SI) = (symbol_ref:SI ("a")  <var_decl 0x7fb91247e390 a>)
         V_REGS, RELOAD_FOR_INPUT (opnum = 0), inc by 2
         reload_in_reg: (symbol_ref:SI ("a")  <var_decl 0x7fb91247e390 a>)
         reload_reg_rtx: (reg:SI 8 r8)
Reload 1: reload_in (HI) = (mem/c:HI (plus:HI (reg/f:HI 32 sp)
                                                         (const_int 4 [0x4])) 
[2 x+0 S2 A16])
         reload_out (HI) = (mem/c:HI (plus:HI (reg/f:HI 32 sp)
                                                         (const_int 4 [0x4])) 
[2 x+0 S2 A16])
         V_REGS, RELOAD_OTHER (opnum = 1), optional
         reload_in_reg: (mem/c:HI (plus:HI (reg/f:HI 32 sp)
                                                         (const_int 4 [0x4])) 
[2 x+0 S2 A16])
         reload_out_reg: (mem/c:HI (plus:HI (reg/f:HI 32 sp)
                                                         (const_int 4 [0x4])) 
[2 x+0 S2 A16])
Reload 2: reload_in (HI) = (mem/c:HI (symbol_ref:SI ("b")  <var_decl 
0x7fb91247e428 b>) [2 b+0 S2 A16 AS2])
         V_REGS, RELOAD_FOR_INPUT (opnum = 2), optional
         reload_in_reg: (mem/c:HI (symbol_ref:SI ("b")  <var_decl 0x7fb91247e428 
b>) [2 b+0 S2 A16 AS2])
Note that reload 1 and reload 2 do not have a reload_reg_rtx. My memories of reload are fading fast (thank goodness), but I believe that's an indication that it's not reloading into a hard register.

So I'd start with looking at find_reloads/push_reload and figure out why it's not getting a suitable register. It might be good to know what alternative is being targeted by reload. ie, you'll be looking at goal_alternative* in find_reloads.

Again, my memories are getting stale here, so double-check the meaning of reload_reg_rtx ;-)


jeff

Reply via email to