Le vendredi 11 avril 2008 à 11:14 -0700, Jim Wilson a écrit :
> Stelian Pop wrote:
> >     #define PREFERRED_RELOAD_CLASS(X, CLASS)        \
> >       ((CONSTANT_P(X)) ? EIGHT_REGS :               \
> >        (MEM_P(X)) ? EVEN_REGS : CLASS)
> > 
> >     #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \
> >       ((CONSTANT_P(X)) ? EIGHT_REGS :               \
> >        (MEM_P(X)) ? EVEN_REGS : CLASS)
> 
> I think most of your trouble is here.  Suppose we are trying to reload a 
> constant into an even-reg.  We call PREFERRED_RELOAD_CLASS, which says 
> to use eight_regs instead, and you get a fatal_insn error because you 
> didn't get the even-reg that the instruction needed.
[...]

I've tried the suggestion above and it did indeed help. However, I had a
few additional issues:
        - the stack pointer and the frame pointer MUST be placed into an
even-reg, or else reload will generate (mem (plus (reg) (const))) insn
(when eliminating the pointers).
        - I had to add a PLUS case in PREFERRED_RELOAD_CLASS() or else reload
kept generating incorrect insn (putting constants into EVEN_REGS for
example). I'm not sure this is correct or if it hides something else...

#define STACK_POINTER_REGNUM 30

#define FRAME_POINTER_REGNUM 28

#define PREFERRED_RELOAD_CLASS(X, CLASS) ardac_preferred_reload_class(X, CLASS)

#define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) ardac_preferred_reload_class(X, 
CLASS)

enum reg_class
ardac_preferred_reload_class(rtx x, enum reg_class class)
{
        if (CONSTANT_P(x)) {
                switch (class) {
                case NO_REGS:
                case STACK_REGS:
                        return NO_REGS;
                case EVEN_REGS:
                case EIGHTEVEN_REGS:
                        return EIGHTEVEN_REGS;
                case EIGHT_REGS:
                case GENERAL_REGS:
                        return EIGHT_REGS;
                default:
                        gcc_unreachable ();
                }
        }
        else if (MEM_P(x)) {
                switch (class) {
                case NO_REGS:
                case STACK_REGS:
                        return NO_REGS;
                case EIGHT_REGS:
                case EIGHTEVEN_REGS:
                        return EIGHTEVEN_REGS;
                case EVEN_REGS:
                case GENERAL_REGS:
                        return EVEN_REGS;
                default:
                        gcc_unreachable ();
                }
        }
        else {
                if (GET_CODE (x) == PLUS
                    && GET_CODE (XEXP (x, 0)) == REG
                    && GET_CODE (XEXP (x, 1)) == CONST_INT) {
                      return EIGHTEVEN_REGS;
                }
                return class;
        }
}

Now it compiler 100+ files from libgcc without error so I guess the
register assignment problem is solved. It now fails later:

/home/tiniou/LTD/LTD/aRDAC/wip/src/gcc-4.3.0/libgcc/../gcc/unwind-dw2-fde.c: In 
function ‘frame_heapsort’:
/home/tiniou/LTD/LTD/aRDAC/wip/src/gcc-4.3.0/libgcc/../gcc/unwind-dw2-fde.c:521:
 internal compiler error: in expand_call, at calls.c:3149

I haven't investigated why yet, but this is probably not related to the above.

Thanks,

-- 
Stelian Pop <[EMAIL PROTECTED]>

Reply via email to