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