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: i370 port


Ah, yes.  The problem is that reload assumes any valid address
can be loaded into a register with a single instruction, and
it will thus simply generate such instructions unconditionally
-- and if the target then doesn't actually provide such a pattern,
it will fail with "unrecognizable insn".

Hi Ulrich. Thanks for your reply.


This approach seems to be quite complicated. What do you think
about the option of NOT adding this (which triggers off errors I
hadn't seen before):

#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
  ((C) == 'S')

and instead making a change similar to what I have already put in
under "hack" below? Is that legitimate?

;
; movstrsi instruction pattern(s).
; block must be less than 16M (24 bits) in length

(define_expand "movstrsi"
 [(set (match_operand:BLK 0 "general_operand" "")
       (match_operand:BLK 1 "general_operand" ""))
  (use (match_operand:SI  2 "general_operand" ""))
  (match_operand 3 "" "")]
  ""
  "
{
 rtx op0, op1;

op0 = XEXP (operands[0], 0);
if (GET_CODE (op0) == REG
|| (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
&& GET_CODE (XEXP (op0, 1)) == CONST_INT
&& (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
op0 = operands[0];
else
op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, op0));


op1 = XEXP (operands[1], 0);
if (GET_CODE (op1) == REG
|| (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
&& GET_CODE (XEXP (op1, 1)) == CONST_INT
&& (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
op1 = operands[1];
else
op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, op1));


 /* first line is a hack - if target address involves two registers,
    we can't use an MVC, even if the length to move is less than 256,
    because MVC takes an S parameter. I'm unsure of the best way to
    distinguish a two-register target. */
 if (!((GET_CODE(op0) == MEM) && REG_P(XEXP(op0,0))) &&
     GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256)
   emit_insn (gen_rtx_PARALLEL (VOIDmode,
                       gen_rtvec (2,
                                  gen_rtx_SET (VOIDmode, op0, op1),
                                  gen_rtx_USE (VOIDmode, operands[2]))));

 else
   {
       /* implementation provided by  Richard Henderson <rth@cygnus.com> */
       rtx reg1 = gen_reg_rtx (DImode);
       rtx reg2 = gen_reg_rtx (DImode);
       rtx mem1 = operands[0];
       rtx mem2 = operands[1];
       rtx len = operands[2];
       if (!CONSTANT_P (len))
         len = force_reg (SImode, len);

/* Load up the address+length pairs. */
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
force_operand (XEXP (mem1, 0), NULL_RTX));
emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE (SImode)), len);


emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0),
force_operand (XEXP (mem2, 0), NULL_RTX));
emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE (SImode)), len);


       /* Copy! */
       emit_insn (gen_movstrsi_1 (reg1, reg2));
   }
 DONE;
}")


Thanks. Paul.



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