This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Modifying ARM code generator for elimination of 8bit writes - need help
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