This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]