On 07/18/2011 08:01 AM, Paulo J. Matos wrote: > The problem is, if addhi3 expands into two insn: > (define_insn "addqi3" > [(set (match_operand:HI 0 "nonimmediate_operand" "=c") > (plus:HI (match_operand:HI 1 "general_operand" "%0") > (match_operand:HI 2 "general_operand" "cwmi")))] > "get_attr_CARRY(insn) == 0" > "add %b0,%b2") > > (define_insn "addqi3_carry" > [(set (match_operand:HI 0 "nonimmediate_operand" "=c") > (plus:HI (match_operand:HI 1 "general_operand" "%0") > (match_operand:HI 2 "general_operand" "cwmi")))] > "get_attr_CARRY(insn) == 1" > "addc %t0,%t2") > > _One_ of the problems with this is that if GCC sees that op2 is 0, it will > remove the insn because it will see: R0 = R0 + 0. However, it can't do this > in this specific case because the plus is actually also adding the carry flag. > > Any suggestions on how to deal with this situation?
You need to specifically represent the other output, i.e. the carry flag. Depending on the constraints of your processor, you may or may not be able to expose this before reload. Reload requires the ability to issue move instructions (all of loads, stores, reg-reg) and addition instructions. It must be able to do this between any pair of instructions in order to handle register spilling. Therefore in order to expose the carry flag before reload, you must have an add instruction that does not modify the carry. Some processors have this in the form of a "load-effective-address" instruction. If you have an LEA-type insn, look at the way the i386 port splits its double-word addition before reload. Otherwise, have a look at the mn10300 and rx ports. There, we split the double-word register, but keep the double-word add as one insn until reload is complete. Those ports are also the only ones that use the brand new (4.6) post-reload comparison optimization pass. r~