On Thu, Jul 20, 2006 at 08:02:45AM +0200, Wolfgang Mües wrote: > But it's not the only function which uses gen_rtx_SET. There are also > much places with > > > emit_constant_insn (cond, > > gen_rtx_SET (VOIDmode, target, source)); > > Isn't it better to replace gen_rtx_SET?
gen_rtx_SET() is OK if, for example, the source is a PLUS, MINUS, ASHIFT, etc. expression instead of REG, MEM or CONST. Anyway, disregard the patch to emit_set_insn(). It causes an endless loop between the movsi expander and arm_gen_constant(). There are two ways that the clobberless movqi insns are generated. One is the "storeinthi" expander (and some similiar ones around it): ;; Subroutine to store a half word integer constant into memory. (define_expand "storeinthi" [(set (match_operand 0 "" "") (match_operand 1 "" "")) (set (match_dup 3) (match_dup 2))] "TARGET_ARM" [...] operands[3] = adjust_address (op0, QImode, 1); operands[0] = adjust_address (operands[0], QImode, 0); operands[2] = gen_lowpart (QImode, operands[2]); operands[1] = gen_lowpart (QImode, operands[1]); }" ) This function isn't used with -march=armv4 or better, so a workaround is to change -march=armv3 to -march=armv4 if the CPU supports that. The other way is the "reload_outqi" pattern. First, the one I posted was missing a (parallel [...]) and would produce an insn which didn't match "_arm_movqi_insn_swp". Second, GCC uses it for reg->stack moves for pseudo registers allocated on the stack, so the address wouldn't have satisfied the "Q" constraint in many cases. It should look like this: ;; The earlyclobber is required by default_secondary_reload() in targhooks.c. ;; We may be asked to generate reg->stack moves from what was reg->reg moves. ;; This requires both a QImode scratch register to trash and a SImode scratch ;; register to hold the address. Since we can get only one scratch register, ;; we ask for a DImode scratch register and split it up. (define_expand "reload_outqi" [(clobber (match_operand:QI 0 "memory_operand" "=Q")) (clobber (match_operand:DI 2 "register_operand" "=&r")) (set (match_dup 4) (match_dup 5)) (parallel [ (set (match_dup 6) (match_operand:QI 1 "register_operand" "r")) (clobber (match_dup 3))] )] "TARGET_ARM && TARGET_SWP_BYTE_WRITES" { operands[3] = simplify_gen_subreg (QImode, operands[2], DImode, 0); operands[4] = simplify_gen_subreg (Pmode, operands[2], DImode, 4); /* If necessary, reload the address. */ if (REG_P (XEXP (operands[0], 0))) { operands[5] = operands[4]; operands[6] = operands[0]; } else { operands[5] = XEXP (operands[0], 0); operands[6] = gen_rtx_MEM (QImode, operands[4]); } }) (Is it OK to use gen_rtx_MEM() during reload? Should I use replace_equiv_address() instead?) -- Rask Ingemann Lambertsen