This is the mail archive of the gcc-bugs@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]

i386.md TARGET_MOVE confusion / questions


I have some questions about the use of TARGET_MOVE in i386.md.

  1) Why do the following two patterns exist?  It would seem to me
     that one pattern that just checks for !TARGET_PUSH_MEMORY
     would enough.  BTW, these two patterns also exist for HI.

       (define_insn ""
         [(set (match_operand:SI 0 "push_operand" "=<")
               (match_operand:SI 1 "nonmemory_operand" "ri"))]
         "!TARGET_PUSH_MEMORY && TARGET_MOVE"
         "push%L0 %1")

       (define_insn ""
         [(set (match_operand:SI 0 "push_operand" "=<")
               (match_operand:SI 1 "nonmemory_operand" "ri"))]
         "!TARGET_PUSH_MEMORY && !TARGET_MOVE"
         "push%L0 %1")

  2) It appears from the following pattern that the intent of
     TARGET_MOVE is to cause RTL for memory to memory moves to
     appear as memory to register to memory moves.

       (define_expand "movsi"
         [(set (match_operand:SI 0 "general_operand" "")
               (match_operand:SI 1 "general_operand" ""))]
       ""
       "
       {
         extern int flag_pic;

         if (flag_pic && SYMBOLIC_CONST (operands[1]))
           emit_pic_move (operands, SImode);

         /* Don't generate memory->memory moves, go through a register */
         else if (TARGET_MOVE
	          && (reload_in_progress | reload_completed) == 0
	          && GET_CODE (operands[0]) == MEM
	          && GET_CODE (operands[1]) == MEM)
           {
             operands[1] = force_reg (SImode, operands[1]);
           }
       }")

     However the code for movsf seems to indicate that TARGET_MOVE means
     leave RTL for memory to memory transfer alone without changing the
     RTL to appear as memory to register to memory.

       (define_expand "movsf"
         [(set (match_operand:SF 0 "general_operand" "")
               (match_operand:SF 1 "general_operand" ""))]
       ""
       "
     {
       /* Special case memory->memory moves and pushes */
       if (TARGET_MOVE
           && (reload_in_progress | reload_completed) == 0
           && GET_CODE (operands[0]) == MEM
           && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
         {
           rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
						? gen_movsf_push
						: gen_movsf_mem;

           emit_insn ((*genfunc) (operands[0], operands[1]));
           DONE;
         }
       ...
     }")

     (define_insn "movsf_mem"
       [(set (match_operand:SF 0 "memory_operand" "=m")
             (match_operand:SF 1 "memory_operand" "m"))
        (clobber (match_scratch:SI 2 "=&r"))]
       ""
       "*
     {
       output_asm_insn (AS2 (mov%L2,%1,%2), operands);
       return AS2 (mov%L0,%2,%0);
     }")

     What exactly is the theory and meaning of TARGET_MOVE?

  3) This also brings up the question of why are push_operands handled
     differently for SI and SF.  In the case of SI patterns checking
     for push_operand are defined before movsi.  In the case of SF
     movsf checks for push_operand.  Any reason that SF can't be
     handled in the same fashion as SI for push_operand (i.e. put
     patterns for handling SF pushes before movsf and don't bother
     having movsf worry about pushes)?

-- John

PS: 1) I'm not on the egcs-bugs mailing list so please CC responses.
    2) I'm out of town Wednesday and Thursday.
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------



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