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

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


So this is where I've been banging my head against the
sources... where is the magic that tells gcc to try to copy everything
into registers to meet the constraints?

Note: expand is ok, the initial add insn is:

(insn 9 3 10 2 (set (reg:HI 48 [ D.1375 ])
        (plus:HI (reg/v:HI 45 [ x ])
            (mem/c:HI (symbol_ref:SI ("b")  <var_decl 0x7f1123d89428 b>) [2 b+0 
S2 A16 AS2]))) dj.c:43 -1
     (nil))

and just before reload:

(insn 10 9 0 2 (set (mem/c:HI (symbol_ref:SI ("a")  <var_decl 0x7f1123d89390 
a>) [2 a+0 S2 A16 AS2])
        (plus:HI (mem/c:HI (reg/f:HI 33 ap) [2 x+0 S2 A16])
            (mem/c:HI (symbol_ref:SI ("b")  <var_decl 0x7f1123d89428 b>) [2 b+0 
S2 A16 AS2]))) dj.c:43 13 {*addhi3_virt}
     (nil))

Reply via email to