Hi, your guys:

Here is the cc1 the notation cc1 crashed:

mvx_audio_dec_mp3_test.c:112: error: unable to find a register to
spill in class 'R0_REG'
mvx_audio_dec_mp3_test.c:112: error: this is the insn:
(insn 185 134 133 6 (set (reg/f:SI 4 R4 [101])
        (const_int 2076 [0x81c])) 4 {load_imm_low_si} (nil)
    (expr_list:REG_EQUIV (const_int 2076 [0x81c])
        (nil)))

PS: there are 16 general registers in my RISC chip, from R0 to R15.
R14, and R15 are used for FP,SP. R0 register is special.
Every large immediate, larger than 512, must be moved into R0
register, which means that R0 is the only register to load large
immediate.
This is a thorny problem.

I have traced the rtl code, and RTL code was combined from two rtl
instructions(R14 is Frame pointer register):

(insn 129 127 168 6 (set (reg:SI 88)
        (const_int 2064 [0x810])) 4 {load_imm_low_si} (nil)
    (nil))

(insn 168 129 131 6 (set (reg/f:SI 101)
        (plus:SI (reg/f:SI 14 R14)
            (const_int 12 [0xc]))) 45 {rice_addsi3} (nil)
    (nil))

(insn 133 131 134 6 (set (reg:SI 4 R4)
        (plus:SI (reg/f:SI 101)
            (reg:SI 88))) 45 {rice_addsi3} (nil)
    (expr_list:REG_EQUAL (plus:SI (reg/f:SI 14 R14)
            (const_int 2076 [0x81c]))
        (nil)))

So before cc1 crashed, the unrecognized insn doesn't go through the
LEGITIMIZE_RELOAD_ADDRESS and PREFERRED_RELOAD_CLASS macro.
Is there any solution I can handle the similar problems?

And the following code is what I wrote in macro
LEGITIMIZE_RELOAD_ADDRESS and PREFERRED_RELOAD_CLASS:

#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)             
\
{       \
        if(rice_legitimize_reload_address(&X,MODE,OPNUM,TYPE,IND_LEVELS))       
\
                goto WIN;       \
}

/*constant value like immediate larger than 512,
 *symbol_ref, label_ref, should be moved into R0 register*/
#define PREFERRED_RELOAD_CLASS(X, CLASS)  rice_preferred_reload_class(X, CLASS)


enum reg_class rice_preferred_reload_class (rtx x, enum reg_class class)
{
        if((GET_CODE(x) == SYMBOL_REF) ||
           (GET_CODE(x) == LABEL_REF) ||
           (GET_CODE(x) == CONST) ||
           ((GET_CODE(x) == CONST_INT) && (!Bit10_constant_operand(x, 
GET_MODE(x)))))
        {
                return R0_REG;
        }
        return class;
}

bool rice_legitimize_reload_address(rtx* x,
                                 enum machine_mode mode ATTRIBUTE_UNUSED,
                                 int opnum, int type,
                                 int ind_levels ATTRIBUTE_UNUSED)
{
        printf("Come to rice_legitimize_reload_address! \n");
        if((GET_CODE(*x) == SYMBOL_REF) ||
           (GET_CODE(*x) == LABEL_REF) ||
           (GET_CODE(*x) == CONST) ||
           ((GET_CODE(*x) == CONST_INT) && (!Bit10_constant_operand(*x,
GET_MODE(*x)))))
        {
#ifdef DEBUG_RICE_GCC
                printf("Come to rice_legitimize_reload_address: R0 Reload! \n");
#endif
                push_reload (*x, NULL_RTX, x, NULL,
                   R0_REG, GET_MODE (*x), GET_MODE (*x), 0, 0,
                   opnum, type);
        return RICE_YES;
        }
        // We must re-recognize what we created before.                 
        if (GET_CODE (*x) == PLUS                                               
           && (GET_MODE_SIZE (mode) == 4)       
           && GET_CODE (XEXP (*x, 0)) == PLUS                           
           && GET_CODE (XEXP (XEXP (*x, 0), 1)) == CONST_INT            
           && rice_reg_ok_for_base (XEXP (XEXP (*x, 0), 0), 1)          
           && GET_CODE (XEXP (*x, 1)) == CONST_INT)                     
    {                                                                   
            rtx sum;
#ifdef DEBUG_RICE_GCC
                printf("Come to rice_legitimize_reload_address: Offset 
re-recognize! \n");
#endif
                push_reload (XEXP ((*x), 0), NULL_RTX, &XEXP ((*x), 0), NULL,   
                                        BASE_REG_CLASS, GET_MODE (*x), 
VOIDmode, 0, 0,
                                        (opnum), (type));
                sum = XEXP (*x, 0);
                sum = XEXP (*x, 1);
                sum = XEXP(XEXP (*x, 0), 0);
                sum = XEXP(XEXP (*x, 0), 1);
                return RICE_YES;                                                
                
    }           
        //Offset >= 256
        if (GET_CODE (*x) == PLUS                                               
                && GET_MODE_SIZE (mode) == 4    
                && (GET_CODE (XEXP (*x, 1)) == CONST_INT && INTVAL(XEXP (*x, 
1)) > 255)                         
                && rice_reg_ok_for_base (XEXP (*x, 0), 0))      
    {                                                                   
                rtx index_rtx = XEXP (*x, 1);                                   
                HOST_WIDE_INT high_part, low_part, offset = INTVAL (index_rtx); 
        
                rtx sum;                                                        
        
#ifdef DEBUG_RICE_GCC
                printf("Come to rice_legitimize_reload_address: Offset %d ! 
\n", offset);
#endif
                                                        
                high_part = offset & (~0xFF);
                low_part  = offset & (0xFF);
                
                sum = gen_rtx_PLUS (Pmode, XEXP (*x, 0), GEN_INT (high_part));  
                
                *x = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_part));
                //Reload
                push_reload (XEXP (*x, 0), NULL_RTX, &XEXP (*x, 0), NULL,       
        
                                         BASE_REG_CLASS, GET_MODE (*x), 
VOIDmode, 0, 0, (opnum), (type));
                sum = XEXP (*x, 0);
                sum = XEXP (*x, 1);
                sum = XEXP(XEXP (*x, 0), 0);
                sum = XEXP(XEXP (*x, 0), 1);
                return RICE_YES;                                                
        
                                                                        
    }                                                                   
                        
        return RICE_NO;
}

I have a few questions.
1 It will split the immediate offset being larger than 255 into pieces
,a  high part and a low part., right? But how to deal with the high
part, especially, when it is still larger than 255.
  Used the above code, will the larger immediate be force into R0
register, and finally generate the right addess code?

2. similar problem, I have define the LEGITIMIZE_RELOAD_ADDRESS and
PREFERRED_RELOAD_CLASS macro. Does the code will take effect to force
the large immediate, symbol and CONST into R0_REG?
   I mean whether I have wrote the right code. Because I found cc1
still crash to allocate the R0 register.

Thank you for your guys advices.



Daniel.Tian

2009/6/16 Jeff Law <l...@redhat.com>:
> Ian Lance Taylor wrote:
>>
>> Jeff Law <l...@redhat.com> writes:
>>
>>
>>>>
>>>> I would fix this in LEGITIMIZE_RELOAD_ADDRESS or in
>>>> TARGET_SECONDARY_RELOAD.  I don't know why cc1 crashed, you will have to
>>>> debug that.
>>>>
>>>
>>> LEGITIMIZE_RELOAD_ADDRESS is not the right place to handle this --
>>> LEGITIMIZE_RELOAD_ADDRESS is to be used when target specific
>>> approaches for reloading can generate more efficient code than the
>>> generic code in reload.   The generic code should be producing
>>> correct, though potentially inefficient code.
>>>
>>
>> I will just note that this is a long-standing point of disagreement
>> between Jeff and me.
>>
>
> True.  But in this specific case we're talking about an out of range offset
> that requires a specific register for the secondary reload.  That's a case
> reload should already be handling correctly.
>>
>> Ian
>>
>
>

Reply via email to