i want to try to do it after the IRA phase, does anyone know if it makes
sence, and if so, is there a macro which tells me that i'm after that phase?

thanks.

On Thu, May 19, 2011 at 7:38 PM, Ilya Lesokhin <ilya.lesok...@gmail.com>wrote:

>
>
> On Thu, May 19, 2011 at 6:43 PM, Georg-Johann Lay <a...@gjlay.de> wrote:
>
>> Ilya Lesokhin schrieb:
>>
>> Hi,
>>>
>>> I would like to split a movhi instruction from an immediate to a const
>>> address to 2 movqi instructions.
>>> (I'm using gcc 4.5.3 but i dont think it matters in this case)
>>>
>>
>> The current development version is 4.7.0.
>>
>> It won't help to provida a patch against an old version. So you need an
>> up-to-date version anyway. This includes also the testsuite. Patches must
>> pass the testsuite without regressions.
>>
>>
>
> I'm doing it for myself at the moment, i dont think i've reached the stage
> i can contribute to the mainline branch yet, So i dont really care what the
> development branch is.
>
>
>>
>> My motivation is the following:
>>> Code in the form:
>>> OCR2RA = 1;
>>>
>>> compiles to:
>>>
>>> ldi r24, 0x01 ; 1
>>> ldi r25, 0x00 ; 0
>>> sts 0x00F7, r25
>>> sts 0x00F6, r24
>>>
>>> instead of
>>>
>>> ldi r24, 0x01 ; 1
>>> ldi r25, 0x00 ; 0
>>> sts 0x00F7, r25
>>> sts 0x00F6, __zero_reg__
>>>
>>
>> What's your intention? Is it an optimization issue?
>>
>
> yes, this is an optimazation issue, also i've already corrected myself and
> i intended the code to be:
>
> ldi r24, 0x01 ; 1
> sts 0x00F7, __zero_reg__
> sts 0x00F6, r24
>
>
>
>>  I'm pretty sure its caused by the following code:
>>>
>>> (define_expand "movhi"
>>> [(set (match_operand:HI 0 "nonimmediate_operand" "")
>>> (match_operand:HI 1 "general_operand" ""))]
>>> ""
>>> "
>>> {
>>>  /* One of the ops has to be in a register. */
>>> if (!register_operand(operand0, HImode)
>>> && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
>>> {
>>> operands[1] = copy_to_mode_reg(HImode, operand1);
>>> }
>>> }")
>>>
>>> i would like to fix it but i know very little about gcc internals.
>>>
>>>
>>>
>>> i tried to do something like:
>>>
>>> (define_expand "movhi"
>>> [(set (match_operand:HI 0 "nonimmediate_operand" "")
>>> (match_operand:HI 1 "general_operand" ""))]
>>> ""
>>> "
>>> {
>>> rtx base = XEXP (operands[0], 0);
>>> if (GET_CODE (operands[1]) == CONST_INT
>>> && CONSTANT_ADDRESS_P (base))
>>> {
>>> short value = INTVAL (operands[1]);
>>> short address = INTVAL (base);
>>>
>>
>> base is a constant, but not necessarily a CONST_INT, it can also be a
>> SYMBOL_REF or a CONST. If you add support for storing zero-extended values,
>> I see no reason why to excluse some flavours of address.
>>
>>
>
>>
>> emit_move_insn(gen_rtx_MEM(QImode,address+1), GEN_INT(value >> 8));
>>> emit_move_insn(gen_rtx_MEM(QImode,address), GEN_INT(value & 0xff));
>>>
>>
>> address+1 is wrong, because address in general is not a CONST_INT
>> Maybe plus_constant is what you looking for.
>>
>
> OK, thank you for pointing those things out.
>
>>
>> Moreover, there is no point in expanding some stuff if there is no insn
>> that will handle it.
>>
>>
> it seems its handles correcly by movqi and other relevet patterns.
>
>>
>> DONE;
>>> }
>>> else /* One of the ops has to be in a register. */
>>> if (!register_operand(operand0, HImode)
>>> && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
>>> {
>>> operands[1] = copy_to_mode_reg(HImode, operand1);
>>> }
>>> }")
>>>
>>> but then i get Segmentation fault when trying to compile code.
>>>
>>
>> You move expansion cannot work because you need at least a QI register
>> (except in the case when you like to store 0, which is already handled in
>> the implementation.
>>
>> Presumably, you want code like this:
>>
>> (set (reg:QI n)
>>     (const_int m))
>> (set (mem:HI (const_addr:P))
>>     (zero_extend:HI (reg:QI n)))
>>
>> You can do it in expand, but note that expand is called at different
>> stages of compilation. You need an intermediate register, so you must be
>> sure you can actually get one, i.e. can_create_pseudo_p is true.
>>
>> As an alternative, you can hook in after insn combine.
>> combine will synthesize such insns, so you can supply a combiner pattern
>> that matches and split it prior to register allocation by means of a split
>> pattern.
>>
>> Yet an other alternative is to extend zero_extendqihi to accept memory
>> operand in dest. Note that there is different handlich for volatiles.
>
>
> i belive that spliting the instruction into 2 instractions is supperior
> since its also hadles the cases where the low byte is zero or when the low
> byte and the high byte are equal as suppose to zero_extend.
>
> also what do you mean by handlich for volatiles?
>
>
> anyway, thanks for all your help, you've been  the most helpful so far.
>
> unfortently, the task seems alot more complicated the i first thought.
>
> OCR0SA = 1u;
> is at first converted to and indirect memory acces:
> ...
> (const_int 1 [0x1])) -1 (nil))
> (set (mem/v:HI (reg/f:HI 43) [2 S2 A8])
> (reg:HI 44)) -1 (nil))
>
> and only after the IRA phase its converted to something with a const
> address
> ...
> (set (mem/v:HI (const_int 210 [0xd2]) [2 S2 A8])
>   (reg:HI 24 r24 [44])) 10 {*movhi} (expr_list:REG_EQUAL (const_int 1
> [0x1] (nil)))
>
> which is the form that i tried to fix. so i think ill have to try
> a different approch.
>
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to