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

clean up x86 call patterns


Pulls out all the duplicated code into an external function.

Adds %ebx to CALL_INSN_FUNCTION_USAGE when it's used by the
PLT thunk.  The reason will become apparent in the next patch;
for now it has no effect.


r~


        * config/i386/i386.c (ix86_expand_call): New function, extracted
        from md call patterns.  Add pic_offset_table_rtx to
        CALL_INSN_FUNCTION_USAGE when needed.
        * config/i386/i386.md (call_pop, call): Use ix86_expand_call.
        (call_value_pop, call_value, untyped_call): Likewise.
        (call_exp, call_value_exp): Remove.
        * config/i386/i386-protos.h: Update.

Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.71
diff -c -p -d -r1.71 i386-protos.h
*** config/i386/i386-protos.h	19 May 2002 08:31:50 -0000	1.71
--- config/i386/i386-protos.h	23 May 2002 05:15:57 -0000
*************** extern void ix86_expand_branch PARAMS ((
*** 121,126 ****
--- 121,127 ----
  extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
  extern int ix86_expand_int_movcc PARAMS ((rtx[]));
  extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
+ extern void ix86_expand_call PARAMS ((rtx, rtx, rtx, rtx, rtx));
  extern void x86_initialize_trampoline PARAMS ((rtx, rtx, rtx));
  extern rtx ix86_zero_extend_to_Pmode PARAMS ((rtx));
  extern void ix86_split_long_move PARAMS ((rtx[]));
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.403
diff -c -p -d -r1.403 i386.c
*** config/i386/i386.c	21 May 2002 23:51:59 -0000	1.403
--- config/i386/i386.c	23 May 2002 05:15:57 -0000
*************** ix86_expand_strlensi_unroll_1 (out, alig
*** 9850,9855 ****
--- 9850,9904 ----
  
    emit_label (end_0_label);
  }
+ 
+ void
+ ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
+      rtx retval, fnaddr, callarg1, callarg2, pop;
+ {
+   rtx use = NULL, call;
+ 
+   if (pop == const0_rtx)
+     pop = NULL;
+   if (TARGET_64BIT && pop)
+     abort ();
+ 
+   /* Static functions and indirect calls don't need the pic register.  */
+   if (! TARGET_64BIT && flag_pic
+       && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
+       && ! SYMBOL_REF_FLAG (XEXP (fnaddr, 0)))
+     {
+       current_function_uses_pic_offset_table = 1;
+       use_reg (&use, pic_offset_table_rtx);
+     }
+ 
+   if (TARGET_64BIT && INTVAL (callarg2) >= 0)
+     {
+       rtx al = gen_rtx_REG (QImode, 0);
+       emit_move_insn (al, callarg2);
+       use_reg (&use, al);
+     }
+ 
+   if (! call_insn_operand (XEXP (fnaddr, 0), Pmode))
+     {
+       fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
+       fnaddr = gen_rtx_MEM (QImode, fnaddr);
+     }
+ 
+   call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
+   if (retval)
+     call = gen_rtx_SET (VOIDmode, retval, call);
+   if (pop)
+     {
+       pop = gen_rtx_PLUS (Pmode, stack_pointer_rtx, pop);
+       pop = gen_rtx_SET (VOIDmode, stack_pointer_rtx, pop);
+       call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, pop));
+     }
+ 
+   call = emit_call_insn (call);
+   if (use)
+     CALL_INSN_FUNCTION_USAGE (call) = use;
+ }
+   
  
  /* Clear stack slot assignments remembered from previous functions.
     This is called from INIT_EXPANDERS once before RTL is emitted for each
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.362
diff -c -p -d -r1.362 i386.md
*** config/i386/i386.md	18 May 2002 22:26:33 -0000	1.362
--- config/i386/i386.md	23 May 2002 05:15:57 -0000
***************
*** 12891,12911 ****
  			    (match_operand:SI 3 "" "")))])]
    "!TARGET_64BIT"
  {
!   if (operands[3] == const0_rtx)
!     {
!       emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
!       DONE;
!     }
!   /* Static functions and indirect calls don't need
!      current_function_uses_pic_offset_table.  */
!   if (flag_pic
!       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
!       && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
!     current_function_uses_pic_offset_table = 1;
!   if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
!     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
!   if (TARGET_64BIT)
!     abort();
  })
  
  (define_insn "*call_pop_0"
--- 12891,12898 ----
  			    (match_operand:SI 3 "" "")))])]
    "!TARGET_64BIT"
  {
!   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3]);
!   DONE;
  })
  
  (define_insn "*call_pop_0"
***************
*** 12947,12983 ****
    [(call (match_operand:QI 0 "" "")
  	 (match_operand 1 "" ""))
     (use (match_operand 2 "" ""))]
-   ;; Operand 1 not used on the i386.
    ""
  {
!   rtx insn;
!   /* Static functions and indirect calls don't need
!      current_function_uses_pic_offset_table.  */
!   if (flag_pic
!       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
!       && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
!     current_function_uses_pic_offset_table = 1;
! 
!   if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
!     XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
!   if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
!     {
!       rtx reg = gen_rtx_REG (QImode, 0);
!       emit_move_insn (reg, operands[2]);
!       insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
!       use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
!       DONE;
!     }
!    insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
!    DONE;
  })
  
- (define_expand "call_exp"
-   [(call (match_operand:QI 0 "" "")
- 	 (match_operand 1 "" ""))]
-   ""
-   "")
- 
  (define_insn "*call_0"
    [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
  	 (match_operand 1 "" ""))]
--- 12934,12945 ----
    [(call (match_operand:QI 0 "" "")
  	 (match_operand 1 "" ""))
     (use (match_operand 2 "" ""))]
    ""
  {
!   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL);
!   DONE;
  })
  
  (define_insn "*call_0"
    [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
  	 (match_operand 1 "" ""))]
***************
*** 13029,13035 ****
    [(set_attr "type" "call")])
  
  ;; Call subroutine, returning value in operand 0
- ;; (which must be a hard register).
  
  (define_expand "call_value_pop"
    [(parallel [(set (match_operand 0 "" "")
--- 12991,12996 ----
***************
*** 13040,13059 ****
  			    (match_operand:SI 4 "" "")))])]
    "!TARGET_64BIT"
  {
!   if (operands[4] == const0_rtx)
!     {
!       emit_insn (gen_call_value (operands[0], operands[1], operands[2],
! 				 constm1_rtx));
!       DONE;
!     }
!   /* Static functions and indirect calls don't need
!      current_function_uses_pic_offset_table.  */
!   if (flag_pic
!       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
!       && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
!     current_function_uses_pic_offset_table = 1;
!   if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
!     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  })
  
  (define_expand "call_value"
--- 13001,13009 ----
  			    (match_operand:SI 4 "" "")))])]
    "!TARGET_64BIT"
  {
!   ix86_expand_call (operands[0], operands[1], operands[2],
! 		    operands[3], operands[4]);
!   DONE;
  })
  
  (define_expand "call_value"
***************
*** 13064,13099 ****
    ;; Operand 2 not used on the i386.
    ""
  {
!   rtx insn;
!   /* Static functions and indirect calls don't need
!      current_function_uses_pic_offset_table.  */
!   if (flag_pic
!       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
!       && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
!     current_function_uses_pic_offset_table = 1;
!   if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
!     XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
!   if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
!     {
!       rtx reg = gen_rtx_REG (QImode, 0);
!       emit_move_insn (reg, operands[3]);
!       insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
! 						 operands[2]));
!       use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
!       DONE;
!     }
!   insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
! 					     operands[2]));
    DONE;
  })
  
- (define_expand "call_value_exp"
-   [(set (match_operand 0 "" "")
- 	(call (match_operand:QI 1 "" "")
- 	      (match_operand:SI 2 "" "")))]
-   ""
-   "")
- 
  ;; Call subroutine returning any type.
  
  (define_expand "untyped_call"
--- 13014,13023 ----
    ;; Operand 2 not used on the i386.
    ""
  {
!   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL);
    DONE;
  })
  
  ;; Call subroutine returning any type.
  
  (define_expand "untyped_call"
***************
*** 13110,13121 ****
       simply pretend the untyped call returns a complex long double
       value.  */
  
!   emit_call_insn (TARGET_FLOAT_RETURNS_IN_80387
!                   ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
! 				    operands[0], const0_rtx,
! 				    GEN_INT (SSE_REGPARM_MAX - 1))
!                   : gen_call (operands[0], const0_rtx,
! 			      GEN_INT (SSE_REGPARM_MAX - 1)));
  
    for (i = 0; i < XVECLEN (operands[2], 0); i++)
      {
--- 13034,13043 ----
       simply pretend the untyped call returns a complex long double
       value.  */
  
!   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
! 		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
! 		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
! 		    NULL);
  
    for (i = 0; i < XVECLEN (operands[2], 0); i++)
      {


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