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]

schedule AIX rs6000 calls and use CTR


	The following patch restores scheduling of function pointer calls
in AIX now that dependencies on r2 are present in the RTL.  This patch
also preferences CTR for branches and jumps and LR for returns which works
better with PowerPC processor branch history stacks.  Finally this patch
reorganizes SysV calls so that non-local calls via pointer and via symbol
are in the same define_insn and removes some unused SysV machinery from
the AIX patterns.

	This patch was bootstrapped on both AIX and PowerPC Linux and run
through the testsuite.

David


	* rs6000.c (print_operand, case 'T'): New case.

	* rs6000.md (call_indirect_aix32): Convert to expander of
	scheduled instructions.
	(call_indirect_aix64): Likewise.
	(call_value_indirect_aix{32,64}): Likewise.
	(call, call_value): Invoke expanders for AIX.  Fall through to
	matchers for SysV.
	(call_indirect_nonlocal_aix{32,64}): New patterns (ctr and lr).
	(call_value_indirect_nonlocal_aix{32,64}): New patterns.
	(call_nonlocal_aix32): Remove CALL_LONG alternative.  Operand 1
	only "g" constraint.
	(call_nonlocal_aix64): Likewise.
	(call_value_nonlocal_aix{32,64}): Likewise.
	(call_nonlocal_sysv): New pattern for ctr, lr, and symbolic
	operands.
	(call_value_nonlocal_sysv): New pattern.
	(indirect_jump{si,di}): Use new 'T' modifier.
	(tablejump{si,di} matchers): Likewise.
	(return_internal_{si,di}): Likewise.
	(return_eh_{si,di}): Likewise.


Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.134
diff -c -p -r1.134 rs6000.c
*** rs6000.c	2000/07/21 00:46:23	1.134
--- rs6000.c	2000/07/25 03:30:28
*************** print_operand (file, x, code)
*** 3984,3989 ****
--- 3985,3991 ----
  	   mask begins at 63 - i from left */
  	  if (i > 63)
  	    output_operand_lossage ("%%S computed all 1's mask");
+ 
  	  fprintf (file, "%d", 63 - i);
  	  return;
  	}
*************** print_operand (file, x, code)
*** 4010,4018 ****
--- 4012,4033 ----
  	   mask ends at 62 - i from left */
  	  if (i > 62)
  	    output_operand_lossage ("%%S computed all 0's mask");
+ 
  	  fprintf (file, "%d", 62 - i);
  	  return;
  	}
+ 
+     case 'T':
+       /* Print the symbolic name of a branch target register.  */
+       if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
+ 				  && REGNO (x) != COUNT_REGISTER_REGNUM))
+ 	output_operand_lossage ("invalid %%T value");
+ 
+       if (REGNO (x) == LINK_REGISTER_REGNUM)
+ 	fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
+       else
+ 	fputs ("ctr", file);
+       return;
  
      case 'u':
        /* High-order 16 bits of constant for use in unsigned operand.  */
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.94
diff -c -p -r1.94 rs6000.md
*** rs6000.md	2000/07/03 20:00:44	1.94
--- rs6000.md	2000/07/25 03:30:30
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9298,9419 ****
  ;; pointer to its TOC, and whose third word contains a value to place in the
  ;; static chain register (r11).  Note that if we load the static chain, our
  ;; "trampoline" need not have any executable code.
- ;;
- ;; operands[0] is a register pointing to the 3 word descriptor (aka, the function address)
- ;; operands[1] is the stack size to clean up
- ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument (must be 0 for AIX)
- ;; operands[3] is location to store the TOC
- ;; operands[4] is the TOC register
- ;; operands[5] is the static chain register
- ;;
- ;; We do not break this into separate insns, so that the scheduler will not try
- ;; to move the load of the new TOC before any loads from the TOC.
- 
- (define_insn "call_indirect_aix32"
-   [(call (mem:SI (match_operand:SI 0 "gpc_reg_operand" "b"))
- 	 (match_operand 1 "const_int_operand" "n"))
-    (use (match_operand 2 "const_int_operand" "n"))
-    (use (match_operand 3 "offsettable_mem_operand" "o"))
-    (use (match_operand 4 "gpc_reg_operand" "r"))
-    (clobber (match_operand 5 "gpc_reg_operand" "=r"))
-    (clobber (match_scratch:SI 6 "=&r"))
-    (clobber (match_scratch:SI 7 "=l"))]
-   "DEFAULT_ABI == ABI_AIX
-    && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
-   "{st|stw} %4,%3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%3"
-   [(set_attr "type" "load")
-    (set_attr "length" "28")])
- 
- (define_insn "call_indirect_aix64"
-   [(call (mem:SI (match_operand:DI 0 "gpc_reg_operand" "b"))
- 	 (match_operand 1 "const_int_operand" "n"))
-    (use (match_operand 2 "const_int_operand" "n"))
-    (use (match_operand 3 "offsettable_mem_operand" "o"))
-    (use (match_operand 4 "gpc_reg_operand" "r"))
-    (clobber (match_operand 5 "gpc_reg_operand" "=r"))
-    (clobber (match_scratch:SI 6 "=&r"))
-    (clobber (match_scratch:SI 7 "=l"))]
-   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX
-    && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
-   "std %4,%3\;ld %6,0(%0)\;ld %4,8(%0)\;mt%7 %6\;ld %5,16(%0)\;blrl\;ld %4,%3"
-   [(set_attr "type" "load")
-    (set_attr "length" "28")])
- 
- (define_insn "call_value_indirect_aix32"
-   [(set (match_operand 0 "" "")
- 	(call (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
- 	      (match_operand 2 "const_int_operand" "n")))
-    (use (match_operand 3 "const_int_operand" "n"))
-    (use (match_operand 4 "offsettable_mem_operand" "o"))
-    (use (match_operand 5 "gpc_reg_operand" "r"))
-    (clobber (match_operand 6 "gpc_reg_operand" "=r"))
-    (clobber (match_scratch:SI 7 "=&r"))
-    (clobber (match_scratch:SI 8 "=l"))]
-   "DEFAULT_ABI == ABI_AIX
-    && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
-   "{st|stw} %5,%4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1)\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%4"
-   [(set_attr "type" "load")
-    (set_attr "length" "28")])
- 
- (define_insn "call_value_indirect_aix64"
-   [(set (match_operand 0 "" "")
- 	(call (mem:SI (match_operand:DI 1 "gpc_reg_operand" "b"))
- 	      (match_operand 2 "const_int_operand" "n")))
-    (use (match_operand 3 "const_int_operand" "n"))
-    (use (match_operand 4 "offsettable_mem_operand" "o"))
-    (use (match_operand 5 "gpc_reg_operand" "r"))
-    (clobber (match_operand 6 "gpc_reg_operand" "=r"))
-    (clobber (match_scratch:SI 7 "=&r"))
-    (clobber (match_scratch:SI 8 "=l"))]
-   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX
-    && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
-   "std %5,%4\;ld %7,0(%1)\;ld %5,8(%1)\;mt%8 %7\;ld %6,16(%1)\;blrl\;ld %5,%4"
-   [(set_attr "type" "load")
-    (set_attr "length" "28")])
- 
- ;; A function pointer under System V is just a normal pointer
- ;; operands[0] is the function pointer
- ;; operands[1] is the stack size to clean up
- ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument which indicates how to set cr1
  
! (define_insn "call_indirect_sysv"
!   [(call (mem:SI (match_operand:SI 0 "register_operand" "l,l"))
! 	 (match_operand 1 "const_int_operand" "n,n"))
!    (use (match_operand 2 "const_int_operand" "O,n"))
!    (clobber (match_scratch:SI 3 "=l,l"))]
!   "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
!   "*
! {
!   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
!     output_asm_insn (\"crxor 6,6,6\", operands);
! 
!   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
!     output_asm_insn (\"creqv 6,6,6\", operands);
! 
!   return \"{brl|blrl}\";
! }"
!   [(set_attr "type" "jmpreg")
!    (set_attr "length" "4,8")])
  
! (define_insn "call_value_indirect_sysv"
!   [(set (match_operand 0 "register_operand" "=fg,fg")
! 	(call (mem:SI (match_operand:SI 1 "register_operand" "l,l"))
! 	      (match_operand 2 "const_int_operand" "n,n")))
!    (use (match_operand 3 "const_int_operand" "O,n"))
!    (clobber (match_scratch:SI 4 "=l,l"))]
!   "DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS || DEFAULT_ABI == ABI_AIX_NODESC"
!   "*
! {
!   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
!     output_asm_insn (\"crxor 6,6,6\", operands);
  
!   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
!     output_asm_insn (\"creqv 6,6,6\", operands);
  
!   return \"{brl|blrl}\";
! }"
!   [(set_attr "type" "jmpreg")
!    (set_attr "length" "4,8")])
  
  ;; Now the definitions for the call and call_value insns
  (define_expand "call"
--- 9298,9393 ----
  ;; pointer to its TOC, and whose third word contains a value to place in the
  ;; static chain register (r11).  Note that if we load the static chain, our
  ;; "trampoline" need not have any executable code.
  
! (define_expand "call_indirect_aix32"
!   [(set (match_dup 2)
! 	(mem:SI (match_operand:SI 0 "gpc_reg_operand" "")))
!    (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
! 	(reg:SI 2))
!    (set (reg:SI 2)
! 	(mem:SI (plus:SI (match_dup 0)
! 			 (const_int 4))))
!    (set (reg:SI 11)
! 	(mem:SI (plus:SI (match_dup 0)
! 			 (const_int 8))))
!    (parallel [(call (mem:SI (match_dup 2))
! 		    (match_operand 1 "" ""))
! 	      (use (reg:SI 2))
! 	      (use (reg:SI 11))
! 	      (set (reg:SI 2)
! 		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
! 	      (clobber (scratch:SI))])]
!   "TARGET_32BIT"
!   "
! { operands[2] = gen_reg_rtx (SImode); }")
  
! (define_expand "call_indirect_aix64"
!   [(set (match_dup 2)
! 	(mem:DI (match_operand:DI 0 "gpc_reg_operand" "")))
!    (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
! 	(reg:DI 2))
!    (set (reg:DI 2)
! 	(mem:DI (plus:DI (match_dup 0)
! 			 (const_int 8))))
!    (set (reg:DI 11)
! 	(mem:DI (plus:DI (match_dup 0)
! 			 (const_int 16))))
!    (parallel [(call (mem:SI (match_dup 2))
! 		    (match_operand 1 "" ""))
! 	      (use (reg:DI 2))
! 	      (use (reg:DI 11))
! 	      (set (reg:DI 2)
! 		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
! 	      (clobber (scratch:SI))])]
!   "TARGET_64BIT"
!   "
! { operands[2] = gen_reg_rtx (DImode); }")
  
! (define_expand "call_value_indirect_aix32"
!   [(set (match_dup 3)
! 	(mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
!    (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
! 	(reg:SI 2))
!    (set (reg:SI 2)
! 	(mem:SI (plus:SI (match_dup 1)
! 			 (const_int 4))))
!    (set (reg:SI 11)
! 	(mem:SI (plus:SI (match_dup 1)
! 			 (const_int 8))))
!    (parallel [(set (match_operand 0 "" "")
! 		   (call (mem:SI (match_dup 3))
! 			 (match_operand 2 "" "")))
! 	      (use (reg:SI 2))
! 	      (use (reg:SI 11))
! 	      (set (reg:SI 2)
! 		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
! 	      (clobber (scratch:SI))])]
!   "TARGET_32BIT"
!   "
! { operands[3] = gen_reg_rtx (SImode); }")
  
! (define_expand "call_value_indirect_aix64"
!   [(set (match_dup 3)
! 	(mem:DI (match_operand:DI 1 "gpc_reg_operand" "")))
!    (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
! 	(reg:DI 2))
!    (set (reg:DI 2)
! 	(mem:DI (plus:DI (match_dup 1)
! 			 (const_int 8))))
!    (set (reg:DI 11)
! 	(mem:DI (plus:DI (match_dup 1)
! 			 (const_int 16))))
!    (parallel [(set (match_operand 0 "" "")
! 		   (call (mem:SI (match_dup 3))
! 			 (match_operand 2 "" "")))
! 	      (use (reg:DI 2))
! 	      (use (reg:DI 11))
! 	      (set (reg:DI 2)
! 		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
! 	      (clobber (scratch:SI))])]
!   "TARGET_64BIT"
!   "
! { operands[3] = gen_reg_rtx (DImode); }")
  
  ;; Now the definitions for the call and call_value insns
  (define_expand "call"
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9435,9465 ****
        if (INTVAL (operands[2]) & CALL_LONG)
  	operands[0] = rs6000_longcall_ref (operands[0]);
  
!       if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
! 	emit_call_insn (gen_call_indirect_sysv (force_reg (Pmode, operands[0]),
! 						operands[1], operands[2]));
!       else
! 	{
! 	  rtx toc_reg = gen_rtx_REG (Pmode, 2);
! 	  rtx toc_addr = RS6000_SAVE_TOC;
  
! 	  if (DEFAULT_ABI == ABI_AIX)
! 	    {
! 	      /* AIX function pointers are really pointers to a three word
! 		 area.  */
! 	      rtx static_chain = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
! 	      emit_call_insn (TARGET_32BIT
! 			      ? gen_call_indirect_aix32 (force_reg (Pmode, operands[0]),
! 						         operands[1], operands[2],
! 						         toc_addr, toc_reg, static_chain)
! 			      : gen_call_indirect_aix64 (force_reg (Pmode, operands[0]),
! 						         operands[1], operands[2],
! 						         toc_addr, toc_reg, static_chain));
! 	    }
! 	  else
! 	    abort ();
  	}
!       DONE;
      }
  }")
  
--- 9409,9434 ----
        if (INTVAL (operands[2]) & CALL_LONG)
  	operands[0] = rs6000_longcall_ref (operands[0]);
  
!       if (DEFAULT_ABI == ABI_V4
!           || DEFAULT_ABI == ABI_AIX_NODESC
! 	  || DEFAULT_ABI == ABI_SOLARIS)
! 	operands[0] = force_reg (Pmode, operands[0]);
  
!       else if (DEFAULT_ABI == ABI_AIX)
! 	{
! 	  /* AIX function pointers are really pointers to a three word
! 	     area.  */
! 	  emit_call_insn (TARGET_32BIT
! 			  ? gen_call_indirect_aix32 (force_reg (SImode,
! 							        operands[0]),
! 						     operands[1])
! 			  : gen_call_indirect_aix64 (force_reg (DImode,
! 							        operands[0]),
! 						     operands[1]));
! 	  DONE;
  	}
!       else
! 	abort ();
      }
  }")
  
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9483,9515 ****
        if (INTVAL (operands[3]) & CALL_LONG)
  	operands[1] = rs6000_longcall_ref (operands[1]);
  
!       if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
! 	emit_call_insn (gen_call_value_indirect_sysv (operands[0], operands[1],
! 						      operands[2], operands[3]));
!       else
! 	{
! 	  rtx toc_reg = gen_rtx_REG (Pmode, 2);
! 	  rtx toc_addr = RS6000_SAVE_TOC;
  
! 	  if (DEFAULT_ABI == ABI_AIX)
! 	    {
! 	      /* AIX function pointers are really pointers to a three word
! 		 area.  */
! 	      rtx static_chain = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
! 	      emit_call_insn (TARGET_32BIT
! 			      ? gen_call_value_indirect_aix32 (operands[0],
! 							       force_reg (Pmode, operands[1]),
! 							       operands[2], operands[3],
! 							       toc_addr, toc_reg, static_chain)
! 			      : gen_call_value_indirect_aix64 (operands[0],
! 							       force_reg (Pmode, operands[1]),
! 							       operands[2], operands[3],
! 							       toc_addr, toc_reg, static_chain));
! 	    }
! 	  else
! 	    abort ();
  	}
!       DONE;
      }
  }")
  
--- 9452,9479 ----
        if (INTVAL (operands[3]) & CALL_LONG)
  	operands[1] = rs6000_longcall_ref (operands[1]);
  
!       if (DEFAULT_ABI == ABI_V4
! 	  || DEFAULT_ABI == ABI_AIX_NODESC
! 	  || DEFAULT_ABI == ABI_SOLARIS)
! 	operands[0] = force_reg (Pmode, operands[0]);
  
!       else if (DEFAULT_ABI == ABI_AIX)
! 	{
! 	  /* AIX function pointers are really pointers to a three word
! 	     area.  */
! 	  emit_call_insn (TARGET_32BIT
! 			  ? gen_call_value_indirect_aix32 (operands[0],
! 							   force_reg (SImode,
! 								      operands[1]),
! 							   operands[2])
! 			  : gen_call_value_indirect_aix64 (operands[0],
! 							   force_reg (DImode,
! 								      operands[1]),
! 							   operands[2]));
! 	  DONE;
  	}
!       else
! 	abort ();
      }
  }")
  
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9557,9563 ****
    [(set_attr "type" "branch")
     (set_attr "length" "4,8")])
  
! (define_insn "*ret_call_local32"
    [(set (match_operand 0 "" "=fg,fg")
  	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
  	      (match_operand 2 "" "g,g")))
--- 9521,9527 ----
    [(set_attr "type" "branch")
     (set_attr "length" "4,8")])
  
! (define_insn "*call_value_local32"
    [(set (match_operand 0 "" "=fg,fg")
  	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
  	      (match_operand 2 "" "g,g")))
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9578,9584 ****
     (set_attr "length" "4,8")])
  
  
! (define_insn "*ret_call_local64"
    [(set (match_operand 0 "" "=fg,fg")
  	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
  	      (match_operand 2 "" "g,g")))
--- 9542,9548 ----
     (set_attr "length" "4,8")])
  
  
! (define_insn "*call_value_local64"
    [(set (match_operand 0 "" "=fg,fg")
  	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
  	      (match_operand 2 "" "g,g")))
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 9605,9758 ****
  ;; variable argument function.  It is > 0 if FP registers were passed
  ;; and < 0 if they were not.
  
  (define_insn "*call_nonlocal_aix32"
!   [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
! 	 (match_operand 1 "" "fg,fg"))
!    (use (match_operand:SI 2 "immediate_operand" "O,n"))
!    (clobber (match_scratch:SI 3 "=l,l"))]
!   "DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[2]) & CALL_LONG) == 0"
!   "*
! {
!   /* Indirect calls should go through call_indirect */
!   if (GET_CODE (operands[0]) == REG)
!     abort ();
! 
!   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
!     output_asm_insn (\"crxor 6,6,6\", operands);
! 
!   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
!     output_asm_insn (\"creqv 6,6,6\", operands);
! 
!   return \"bl %z0\;%.\";
! }"
    [(set_attr "type" "branch")
!    (set_attr "length" "8,12")])
  
  (define_insn "*call_nonlocal_aix64"
!   [(call (mem:SI (match_operand:DI 0 "call_operand" "s,s"))
! 	 (match_operand 1 "" "fg,fg"))
!    (use (match_operand:SI 2 "immediate_operand" "O,n"))
!    (clobber (match_scratch:SI 3 "=l,l"))]
    "TARGET_64BIT 
     && DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[2]) & CALL_LONG) == 0"
!   "*
! {
!   /* Indirect calls should go through call_indirect */
!   if (GET_CODE (operands[0]) == REG)
!     abort ();
! 
!   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
!     output_asm_insn (\"crxor 6,6,6\", operands);
! 
!   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
!     output_asm_insn (\"creqv 6,6,6\", operands);
! 
!   return \"bl %z0\;%.\";
! }"
    [(set_attr "type" "branch")
!    (set_attr "length" "8,12")])
! 
! (define_insn "*call_nonlocal_sysv"
!   [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
! 	 (match_operand 1 "" "fg,fg"))
!    (use (match_operand:SI 2 "immediate_operand" "O,n"))
!    (clobber (match_scratch:SI 3 "=l,l"))]
!   "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
!    && (INTVAL (operands[2]) & CALL_LONG) == 0"
!   "*
! {
!   /* Indirect calls should go through call_indirect */
!   if (GET_CODE (operands[0]) == REG)
!     abort ();
! 
!   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
!     output_asm_insn (\"crxor 6,6,6\", operands);
! 
!   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
!     output_asm_insn (\"creqv 6,6,6\", operands);
  
!   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\";
! }"
!   [(set_attr "type" "branch")
!    (set_attr "length" "4,8")])
  
! (define_insn "*ret_call_nonlocal_aix32"
!   [(set (match_operand 0 "" "=fg,fg")
! 	(call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
! 	      (match_operand 2 "" "fg,fg")))
!    (use (match_operand:SI 3 "immediate_operand" "O,n"))
!    (clobber (match_scratch:SI 4 "=l,l"))]
!   "DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[3]) & CALL_LONG) == 0"
!   "*
! {
!   /* This should be handled by call_value_indirect */
!   if (GET_CODE (operands[1]) == REG)
!     abort ();
! 
!   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
!     output_asm_insn (\"crxor 6,6,6\", operands);
! 
!   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
!     output_asm_insn (\"creqv 6,6,6\", operands);
! 
!   return \"bl %z1\;%.\";
! }"
    [(set_attr "type" "branch")
!    (set_attr "length" "8,12")])
  
! (define_insn "*ret_call_nonlocal_aix64"
!   [(set (match_operand 0 "" "=fg,fg")
! 	(call (mem:SI (match_operand:DI 1 "call_operand" "s,s"))
! 	      (match_operand 2 "" "fg,fg")))
!    (use (match_operand:SI 3 "immediate_operand" "O,n"))
!    (clobber (match_scratch:SI 4 "=l,l"))]
    "TARGET_64BIT 
     && DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[3]) & CALL_LONG) == 0"
    "*
  {
!   /* This should be handled by call_value_indirect */
!   if (GET_CODE (operands[1]) == REG)
!     abort ();
! 
!   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
      output_asm_insn (\"crxor 6,6,6\", operands);
  
!   else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
      output_asm_insn (\"creqv 6,6,6\", operands);
  
!   return \"bl %z1\;%.\";
  }"
!   [(set_attr "type" "branch")
!    (set_attr "length" "8,12")])
  
! (define_insn "*ret_call_nonlocal_sysv"
!   [(set (match_operand 0 "" "=fg,fg")
! 	(call (mem:SI (match_operand:SI 1 "call_operand" "s,s"))
! 	      (match_operand 2 "" "fg,fg")))
!    (use (match_operand:SI 3 "immediate_operand" "O,n"))
!    (clobber (match_scratch:SI 4 "=l,l"))]
!   "(DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
!    && (INTVAL (operands[3]) & CALL_LONG) == 0"
    "*
  {
-   /* This should be handled by call_value_indirect */
-   if (GET_CODE (operands[1]) == REG)
-     abort ();
- 
    if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
      output_asm_insn (\"crxor 6,6,6\", operands);
  
    else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
      output_asm_insn (\"creqv 6,6,6\", operands);
  
!   return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@plt\" : \"bl %z1\";
  }"
!   [(set_attr "type" "branch")
!    (set_attr "length" "4,8")])
  
  ;; Call subroutine returning any type.
  (define_expand "untyped_call"
--- 9569,9746 ----
  ;; variable argument function.  It is > 0 if FP registers were passed
  ;; and < 0 if they were not.
  
+ (define_insn "*call_indirect_nonlocal_aix32"
+   [(call (mem:SI (match_operand:SI 0 "register_operand" "cl"))
+ 	 (match_operand 1 "" "g"))
+    (use (reg:SI 2))
+    (use (reg:SI 11))
+    (set (reg:SI 2)
+ 	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
+    (clobber (match_scratch:SI 3 "=l"))]
+   "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
+   "b%T0l\;{l|lwz} 2,20(1)"
+   [(set_attr "type" "jmpreg")
+    (set_attr "length" "8")])
+ 
  (define_insn "*call_nonlocal_aix32"
!   [(call (mem:SI (match_operand:SI 0 "call_operand" "s"))
! 	 (match_operand 1 "" "g"))
!    (use (match_operand:SI 2 "immediate_operand" "O"))
!    (clobber (match_scratch:SI 3 "=l"))]
!   "TARGET_32BIT
!    && DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[2]) & CALL_LONG) == 0"
!   "bl %z0\;%."
    [(set_attr "type" "branch")
!    (set_attr "length" "8")])
  
+ (define_insn "*call_indirect_nonlocal_aix64"
+   [(call (mem:SI (match_operand:DI 0 "register_operand" "cl"))
+ 	 (match_operand 1 "" "g"))
+    (use (reg:DI 2))
+    (use (reg:DI 11))
+    (set (reg:DI 2)
+ 	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
+    (clobber (match_scratch:SI 3 "=l"))]
+   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
+   "b%T0l\;ld 2,40(1)"
+   [(set_attr "type" "jmpreg")
+    (set_attr "length" "8")])
+ 
  (define_insn "*call_nonlocal_aix64"
!   [(call (mem:SI (match_operand:DI 0 "call_operand" "s"))
! 	 (match_operand 1 "" "g"))
!    (use (match_operand:SI 2 "immediate_operand" "O"))
!    (clobber (match_scratch:SI 3 "=l"))]
    "TARGET_64BIT 
     && DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[2]) & CALL_LONG) == 0"
!   "bl %z0\;%."
    [(set_attr "type" "branch")
!    (set_attr "length" "8")])
  
! (define_insn "*call_value_indirect_nonlocal_aix32"
!   [(set (match_operand 0 "" "=fg")
! 	(call (mem:SI (match_operand:SI 1 "register_operand" "cl"))
! 	      (match_operand 2 "" "g")))
!    (use (reg:SI 2))
!    (use (reg:SI 11))
!    (set (reg:SI 2)
! 	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
!    (clobber (match_scratch:SI 3 "=l"))]
!   "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
!   "b%T1l\;{l|lwz} 2,20(1)"
!   [(set_attr "type" "jmpreg")
!    (set_attr "length" "8")])
  
! (define_insn "*call_value_nonlocal_aix32"
!   [(set (match_operand 0 "" "=fg")
! 	(call (mem:SI (match_operand:SI 1 "call_operand" "s"))
! 	      (match_operand 2 "" "g")))
!    (use (match_operand:SI 3 "immediate_operand" "O"))
!    (clobber (match_scratch:SI 4 "=l"))]
!   "TARGET_32BIT
!    && DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[3]) & CALL_LONG) == 0"
!   "bl %z1\;%."
    [(set_attr "type" "branch")
!    (set_attr "length" "8")])
  
! (define_insn "*call_value_indirect_nonlocal_aix64"
!   [(set (match_operand 0 "" "=fg")
! 	(call (mem:SI (match_operand:DI 1 "register_operand" "cl"))
! 	      (match_operand 2 "" "g")))
!    (use (reg:DI 2))
!    (use (reg:DI 11))
!    (set (reg:DI 2)
! 	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
!    (clobber (match_scratch:SI 3 "=l"))]
!   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
!   "b%T1l\;ld 2,40(1)"
!   [(set_attr "type" "jmpreg")
!    (set_attr "length" "8")])
! 
! (define_insn "*call_value_nonlocal_aix64"
!   [(set (match_operand 0 "" "=fg")
! 	(call (mem:SI (match_operand:DI 1 "call_operand" "s"))
! 	      (match_operand 2 "" "g")))
!    (use (match_operand:SI 3 "immediate_operand" "O"))
!    (clobber (match_scratch:SI 4 "=l"))]
    "TARGET_64BIT 
     && DEFAULT_ABI == ABI_AIX
     && (INTVAL (operands[3]) & CALL_LONG) == 0"
+   "bl %z1\;%."
+   [(set_attr "type" "branch")
+    (set_attr "length" "8")])
+ 
+ ;; A function pointer under System V is just a normal pointer
+ ;; operands[0] is the function pointer
+ ;; operands[1] is the stack size to clean up
+ ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
+ ;; which indicates how to set cr1
+ 
+ (define_insn "*call_nonlocal_sysv"
+   [(call (mem:SI (match_operand:SI 0 "call_operand" "cl,cl,s,s"))
+ 	 (match_operand 1 "" "g,g,g,g"))
+    (use (match_operand:SI 2 "immediate_operand" "O,n,O,n"))
+    (clobber (match_scratch:SI 3 "=l,l,l,l"))]
+   "DEFAULT_ABI == ABI_AIX_NODESC
+    || DEFAULT_ABI == ABI_V4
+    || DEFAULT_ABI == ABI_SOLARIS"
    "*
  {
!   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
      output_asm_insn (\"crxor 6,6,6\", operands);
  
!   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
      output_asm_insn (\"creqv 6,6,6\", operands);
  
!   switch (which_alternative)
!     {
!     default:
!       abort ();
!     case 0:
!     case 1:
!       return \"b%T0l\";
!     case 2:
!     case 3:
!       return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\";
!     }
  }"
!   [(set_attr "type" "jmpreg,jmpreg,branch,branch")
!    (set_attr "length" "4,8,4,8")])
  
! (define_insn "*call_value_nonlocal_sysv"
!   [(set (match_operand 0 "" "=fg,fg,fg,fg")
! 	(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
! 	      (match_operand 2 "" "g,g,g,g")))
!    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
!    (clobber (match_scratch:SI 4 "=l,l,l,l"))]
!   "DEFAULT_ABI == ABI_AIX_NODESC
!    || DEFAULT_ABI == ABI_V4
!    || DEFAULT_ABI == ABI_SOLARIS"
    "*
  {
    if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
      output_asm_insn (\"crxor 6,6,6\", operands);
  
    else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
      output_asm_insn (\"creqv 6,6,6\", operands);
  
!   switch (which_alternative)
!     {
!     default:
!       abort ();
!     case 0:
!     case 1:
!       return \"b%T1l\";
!     case 2:
!     case 3:
!       return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@plt\" : \"bl %z1\";
!     }
  }"
!   [(set_attr "type" "jmpreg,jmpreg,branch,branch")
!    (set_attr "length" "4,8,4,8")])
  
  ;; Call subroutine returning any type.
  (define_expand "untyped_call"
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 13226,13244 ****
  }")
  
  (define_insn "indirect_jumpsi"
!   [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
    "TARGET_32BIT"
!   "@
!    bctr
!    {br|blr}"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "indirect_jumpdi"
!   [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
    "TARGET_64BIT"
!   "@
!    bctr
!    {br|blr}"
    [(set_attr "type" "jmpreg")])
  
  ;; Table jump for switch statements:
--- 13214,13228 ----
  }")
  
  (define_insn "indirect_jumpsi"
!   [(set (pc) (match_operand:SI 0 "register_operand" "cl"))]
    "TARGET_32BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "indirect_jumpdi"
!   [(set (pc) (match_operand:DI 0 "register_operand" "cl"))]
    "TARGET_64BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])
  
  ;; Table jump for switch statements:
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 13285,13306 ****
  
  (define_insn ""
    [(set (pc)
! 	(match_operand:SI 0 "register_operand" "c,l"))
     (use (label_ref (match_operand 1 "" "")))]
    "TARGET_32BIT"
!   "@
!    bctr
!    {br|blr}"
    [(set_attr "type" "jmpreg")])
  
  (define_insn ""
    [(set (pc)
! 	(match_operand:DI 0 "register_operand" "c,l"))
     (use (label_ref (match_operand 1 "" "")))]
    "TARGET_64BIT"
!   "@
!    bctr
!    {br|blr}"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "nop"
--- 13269,13286 ----
  
  (define_insn ""
    [(set (pc)
! 	(match_operand:SI 0 "register_operand" "cl"))
     (use (label_ref (match_operand 1 "" "")))]
    "TARGET_32BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])
  
  (define_insn ""
    [(set (pc)
! 	(match_operand:DI 0 "register_operand" "cl"))
     (use (label_ref (match_operand 1 "" "")))]
    "TARGET_64BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "nop"
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 13898,13918 ****
   "{lm|lmw} %1,%2")
   
  (define_insn "*return_internal_si"
!   [(use (match_operand:SI 0 "register_operand" "l,c"))
     (return)]
    "TARGET_32BIT"
!   "@
!    {br|blr}
!    bctr"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "*return_internal_di"
!   [(use (match_operand:DI 0 "register_operand" "l,c"))
     (return)]
    "TARGET_64BIT"
!   "@
!    {br|blr}
!    bctr"
    [(set_attr "type" "jmpreg")])
  
  ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
--- 13878,13894 ----
   "{lm|lmw} %1,%2")
   
  (define_insn "*return_internal_si"
!   [(use (match_operand:SI 0 "register_operand" "lc"))
     (return)]
    "TARGET_32BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "*return_internal_di"
!   [(use (match_operand:DI 0 "register_operand" "lc"))
     (return)]
    "TARGET_64BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])
  
  ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
*************** operands[2] = GEN_INT (INTVAL (operands[
*** 14037,14059 ****
  
  
  (define_insn "return_eh_si"
!   [(use (match_operand:SI 0 "register_operand" "l,c"))
     (return)
     (use (reg:SI 2))
     (use (reg:SI 3))]
    "TARGET_32BIT"
!   "@
!    {br|blr}
!    bctr"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "return_eh_di"
!   [(use (match_operand:DI 0 "register_operand" "l,c"))
     (return)
     (use (reg:DI 2))
     (use (reg:DI 3))]
    "TARGET_64BIT"
!   "@
!    {br|blr}
!    bctr"
    [(set_attr "type" "jmpreg")])
--- 14013,14031 ----
  
  
  (define_insn "return_eh_si"
!   [(use (match_operand:SI 0 "register_operand" "lc"))
     (return)
     (use (reg:SI 2))
     (use (reg:SI 3))]
    "TARGET_32BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])
  
  (define_insn "return_eh_di"
!   [(use (match_operand:DI 0 "register_operand" "lc"))
     (return)
     (use (reg:DI 2))
     (use (reg:DI 3))]
    "TARGET_64BIT"
!   "b%T0"
    [(set_attr "type" "jmpreg")])

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