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