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)

 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__

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

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

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.

Can someone please point me to the right direction?

Thank,

Ilya.
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to