Reloading does not proper work on my new 8 bit target, please help

ildar ildar@unicore.ru
Thu Mar 18 09:43:00 GMT 2004


Thank you for advice a lot.

It seems that I begin to understand the reload entity.

I tried the constraints that you propose, but anyway I have the problem with
generation correct reload code. That is why I decide to simplify the
constraints as it possible.

 Now there is MOVHI pattern.



(define_insn "movhi_internal"

  [(set (match_operand:HI 0 "nonimmediate_operand" "=a, a, a, rt, m, f, f,
j")

        (match_operand:HI 1 "general_operand"       "a, f, i, m, rt, a, i,
R"))]

  "(register_operand (operands[0],HImode)

    || register_operand (operands[1],HImode) )"

"*{ 
   switch (which_alternative)

    { 

     case 0:

          return (AS2 (mov,%A0,%A1) CR_TAB

                  AS2 (mov,%B0,%B1));break;

     case 1:

          return (AS2 (mfpr,%A0,%A1) CR_TAB

                  AS2 (mfpr,%B0,%B1));break;

     case 2:

          return (AS2 (movl,%A0,low(%1)) CR_TAB

                  AS2 (movl,%B0,hi(%1)));break;

 

     case 3:

        {

         rtx d_x=XEXP(operands[1],0);  

         if (GET_CODE(d_x)==REG

          && true_regnum (d_x)>0)

            { 

             if(REGNO (d_x) == REG_DP1)

               {

                  return (AS2(mov,%A0,(dp1)) CR_TAB

                         AS2(addl,dp1L,1)   CR_TAB

                         AS1(adc,dp1H)      CR_TAB

                         AS2(mov,%B0,(dp1)) CR_TAB

                         AS2(subl,dp1L,1)   CR_TAB

                         AS1(sbb,dp1H));

               }         

             if(REGNO (d_x) == REG_DP2)

               {

                  return (AS2(mov,%A0,(dp2)) CR_TAB

                         AS2(addl,dp2L,1)   CR_TAB

                         AS1(adc,dp2H)      CR_TAB

                         AS2(mov,%B0,(dp2)) CR_TAB

                         AS2(subl,dp2L,1)   CR_TAB

                         AS1(sbb,dp2H));

               }         

            }          

 

          return AS2(REG_DP1,bug,movhi_r_m);       


         } break;

. . . so on

)



I forbid generating code to load registers of class DATA_POINTER_REGS direct
from memory explicitly.



But after compiling the test compile/20000211-1.c from gcc test suite I get
invalid instruction:

/home/t/compiler2/gcc-unc80-3-3-2/gcc/testsuite/gcc.c-torture/compile/200002
11-1.c: In function `doprnt_1':

/home/t/compiler2/gcc-unc80-3-3-2/gcc/testsuite/gcc.c-torture/compile/200002
11-1.c:81: error: insn does not satisfy its constraints:

(insn 445 144 146 0x0 (set (reg/f:HI 24 dp1L [142])

        (mem/f:HI (reg/f:HI 24 dp1L [144]) [0 lstr+0 S2 A16])) 8
{movhi_internal} (nil)

    (nil))

/home/t/compiler2/gcc-unc80-3-3-2/gcc/testsuite/gcc.c-torture/compile/200002
11-1.c:81: internal compiler error: in extract_constrain_insn_cached, at
recog.c:2090

Please submit a full bug report,

with preprocessed source if appropriate.

See <URL:http://gcc.gnu.org/bugs.html> for instructions.



There are the parts of dump listing in LREG phase.

. . .

  Register 142 costs: GENERAL_REGS:2000 POINTER_DP1:2000 POINTER_DP2:2000
DATA_POINTER_REGS:2000 NO_SYSTEM_REGS:4000 ALL_REGS:4000 MEM:8000

  Register 144 costs: GENERAL_REGS:6000 POINTER_DP1:4000 POINTER_DP2:4000
DATA_POINTER_REGS:4000 NO_SYSTEM_REGS:6000 ALL_REGS:8000 MEM:12000

. . .



  Register 142 pref DATA_POINTER_REGS

  Register 143 pref NO_SYSTEM_REGS or none

  Register 144 pref DATA_POINTER_REGS

. . .

Register 142 used 2 times across 2 insns in block 7; set 1 time; 2 bytes;
pref DATA_POINTER_REGS; pointer.

 Register 144 used 2 times across 2 insns in block 7; set 1 time; 2 bytes;
pref DATA_POINTER_REGS; pointer.

. . .

;; Register 142 in 24.

;; Register 144 in 24.

. . .

(insn 144 142 145 7 0xa0608d0 (set (reg/f:HI 144)

        (plus:HI (reg/f:HI 16 c0)

            (const_int -13 [0xfffffff3]))) 15 {addhi3} (nil)

    (nil))



(insn 145 144 146 7 0xa0608d0 (set (reg/f:HI 142)

        (mem/f:HI (reg/f:HI 144) [0 lstr+0 S2 A16])) 8 {movhi_internal}
(nil)

    (expr_list:REG_DEAD (reg/f:HI 144)

        (nil)))



(insn 146 145 147 7 0xa0608d0 (set (reg:HI 145)

        (mem/s:HI (reg/f:HI 142) [0 S2 A8])) 8 {movhi_internal} (nil)

    (expr_list:REG_DEAD (reg/f:HI 142)

        (nil)))

. . .



 The insn 144 load address in to reg/f:HI 144. This is the address of object
lying on the frame of current function.

The insn 145 get this object from memory and put it to reg/f:HI 142.

We can see that this object is a pointer, that is why reg:142 has preferred
DATA_POINTER_REGS.

The insn 146 get the object and reg:142 points where this object is in
memory.

I see that the price of class preference for reg:142 the same for
GENERAL_REGS and for one of the POINTERS. I suppose that is not correct,
because if class preference of reg/f:HI 142 is GENERAL_REGS then next phase
should generate additional insn to reload value to register of correct
class - one of POINTERs.



If I am right, how I can change the price of class preference for reg:142.



There are the parts of dump listing in GREG phase.

 . . .

Reloads for insn # 144

Reload 0: reload_in (HI) = (reg/f:HI 16 c0)

      reload_out (HI) = (reg/f:HI 24 dp1L [144])

      NO_SYSTEM_REGS, RELOAD_OTHER (opnum = 0)

      reload_in_reg: (reg/f:HI 16 c0)

      reload_out_reg: (reg/f:HI 24 dp1L [144])

      reload_reg_rtx: (reg/f:HI 24 dp1L [144])



Reloads for insn # 145

Reload 0: reload_in (HI) = (mem/f:HI (reg/f:HI 24 dp1L [144]) [0 lstr+0 S2
A16])

      NO_SYSTEM_REGS, RELOAD_FOR_INPUT (opnum = 1)

      reload_in_reg: (mem/f:HI (reg/f:HI 24 dp1L [144]) [0 lstr+0 S2 A16])

      reload_reg_rtx: (reg/f:HI 24 dp1L [142])

. . .

(insn 444 142 144 7 0x0 (set (reg/f:HI 24 dp1L [144])

        (reg/f:HI 16 c0)) 8 {movhi_internal} (nil)

    (nil))



(insn 144 444 445 7 0xa0608d0 (set (reg/f:HI 24 dp1L [144])

        (plus:HI (reg/f:HI 24 dp1L [144])

            (const_int -13 [0xfffffff3]))) 15 {addhi3} (nil)

    (nil))



(insn 445 144 145 7 0x0 (set (reg/f:HI 24 dp1L [142])

        (mem/f:HI (reg/f:HI 24 dp1L [144]) [0 lstr+0 S2 A16])) 8
{movhi_internal} (nil)

    (nil))



(insn 145 445 146 7 0xa0608d0 (set (reg/f:HI 24 dp1L [142])

        (reg/f:HI 24 dp1L [142])) 8 {movhi_internal} (nil)

    (nil))



(insn 146 145 147 7 0xa0608d0 (set (reg:HI 8 b0 [145])

        (mem/s:HI (reg/f:HI 24 dp1L [142]) [0 S2 A8])) 8 {movhi_internal}
(nil)

    (nil))

. . .



I see that incorrect instruction insn 445 is generated during reloading for
insn 145. How can I correct this situation?



Ildar F. Kaibyshev



More information about the Gcc mailing list