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: expanding movdi into 2 x movsi


Jim Wilson <wilson@specifixinc.com> writes:

> Jan Hoogerbrugge wrote:
> > I this a gcc bug? Is there an easy workarond by defining a
> > define_expand "movdi" that maps the move to 2 SImode moves? Any
> > suggestions for a port where I can borrow some code from?
> 
> This does appear to be a gcc bug.  However, since you are the only one
> that has a copy of your port, you will probably have to be the one to
> debug it.
> 
> Yes, you can probably work around the problem by defining your own
> movdi pattern.  You can borrow a movdi pattern from any target that
> defines one.  Since I don't know your target, I can't suggest which
> one would be best to look at.  Most of them are pretty similar.  Try
> arm.  It is the first common 32-bit target alphabetically.  alpha is a
> 64-bit target, and arc isn't a common target.

Example of movdi from one 32 bits port.

(define_expand "movdi"
  [(set (match_operand:DI 0 "general_operand" "")
	(match_operand:DI 1 "general_operand" ""))]
  ""
  "{
     if ((GET_CODE (operands[1]) == CONST_INT
          || GET_CODE (operands[1]) == CONST_DOUBLE)
         && GET_CODE (operands[0]) == MEM
         && !no_new_pseudos)
       operands[1] = force_reg (DImode, operands[1]);
    }
  "
)

(define_insn "*movdi_internal"
  [(set (match_operand:DI 0 "move_operand" "=r,r,m,r,m")
	(match_operand:DI 1 "move_operand" " r,m,r,i,i"))]
  ""
  "@
   #
   #
   #
   #
   #")

(define_split
  [(set (match_operand:DI 0 "register_operand" "")
	(match_operand:DI 1 "register_operand" ""))]
  ""
  [(set (match_dup 2) (match_dup 3))
   (set (match_dup 4) (match_dup 5))]
  "{
     if (REGNO (operands[0]) < REGNO (operands[1]))
       {
         operands[2] = gen_highpart (SImode, operands[0]);
         operands[3] = gen_highpart (SImode, operands[1]);
         operands[4] = gen_lowpart (SImode, operands[0]);
         operands[5] = gen_lowpart (SImode, operands[1]);
       }
     else
       {
         operands[2] = gen_lowpart (SImode, operands[0]);
         operands[3] = gen_lowpart (SImode, operands[1]);
         operands[4] = gen_highpart (SImode, operands[0]);
         operands[5] = gen_highpart (SImode, operands[1]);
       }
   }")

(define_split
  [(set (match_operand:DI 0 "register_operand" "")
	(match_operand:DI 1 "memory_operand" ""))]
  ""
  [(set (match_dup 2) (match_dup 3))
   (set (match_dup 4) (match_dup 5))]
  "{
     operands[2] = gen_highpart (SImode, operands[0]);
     operands[3] = gen_highpart (SImode, operands[1]);
     operands[4] = gen_lowpart (SImode, operands[0]);
     operands[5] = gen_lowpart (SImode, operands[1]);
     if (reg_mentioned_p (operands[2], operands[3]))
       {
         rtx tem;
         tem = operands[4];
         operands[4] = operands[2];
         operands[2] = tem;
         tem = operands[5];
         operands[5] = operands[3];
         operands[3] = tem;
       }
   }")

(define_split
  [(set (match_operand:DI 0 "memory_operand" "")
	(match_operand:DI 1 "register_operand" ""))]
  ""
  [(set (match_dup 2) (match_dup 3))
   (set (match_dup 4) (match_dup 5))]
  "{
     operands[2] = gen_highpart (SImode, operands[0]);
     operands[3] = gen_highpart (SImode, operands[1]);
     operands[4] = gen_lowpart (SImode, operands[0]);
     operands[5] = gen_lowpart (SImode, operands[1]);
   }")

(define_split
  [(set (match_operand:DI 0 "register_operand" "")
	(match_operand:DI 1 "immediate_operand" ""))]
  ""
  [(set (match_dup 2) (match_dup 3))
   (set (match_dup 4) (match_dup 5))]
  "{
     operands[2] = gen_highpart (SImode, operands[0]);
     operands[4] = gen_lowpart (SImode, operands[0]);
     operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
     operands[5] = gen_lowpart (SImode, operands[1]);
   }")

(define_split
  [(set (match_operand:DI 0 "memory_operand" "")
	(match_operand:DI 1 "immediate_operand" ""))]
  ""
  [(set (match_dup 2) (match_dup 3))
   (set (match_dup 4) (match_dup 5))]
  "{
     operands[2] = gen_highpart (SImode, operands[0]);
     operands[4] = gen_lowpart (SImode, operands[0]);
     operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
     operands[5] = gen_lowpart (SImode, operands[1]);
   }")

Denis.


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