;; 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_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_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);
+(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); }")
- else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
- output_asm_insn (\"creqv 6,6,6\", operands);
+(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); }")
- return \"{brl|blrl}\";
-}"
- [(set_attr "type" "jmpreg")
- (set_attr "length" "4,8")])
+(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"
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_V4
+ || DEFAULT_ABI == ABI_AIX_NODESC
+ || DEFAULT_ABI == ABI_SOLARIS)
+ operands[0] = force_reg (Pmode, operands[0]);
- 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 ();
+ 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;
}
- DONE;
+ else
+ abort ();
}
}")
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_V4
+ || DEFAULT_ABI == ABI_AIX_NODESC
+ || DEFAULT_ABI == ABI_SOLARIS)
+ operands[0] = force_reg (Pmode, operands[0]);
- 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 ();
+ 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;
}
- DONE;
+ else
+ abort ();
}
}")
[(set_attr "type" "branch")
(set_attr "length" "4,8")])
-(define_insn "*ret_call_local32"
+(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")))
(set_attr "length" "4,8")])
-(define_insn "*ret_call_local64"
+(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")))
;; 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,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
+ [(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"
- "*
-{
- /* 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\;%.\";
-}"
+ "bl %z0\;%."
[(set_attr "type" "branch")
- (set_attr "length" "8,12")])
+ (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,s"))
- (match_operand 1 "" "fg,fg"))
- (use (match_operand:SI 2 "immediate_operand" "O,n"))
- (clobber (match_scratch:SI 3 "=l,l"))]
+ [(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"
- "*
-{
- /* 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\;%.\";
-}"
+ "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);
+ (set_attr "length" "8")])
- return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\";
-}"
- [(set_attr "type" "branch")
- (set_attr "length" "4,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 "*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
+(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"
- "*
-{
- /* 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\;%.\";
-}"
+ "bl %z1\;%."
[(set_attr "type" "branch")
- (set_attr "length" "8,12")])
+ (set_attr "length" "8")])
-(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"))]
+(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"
"*
{
- /* This should be handled by call_value_indirect */
- if (GET_CODE (operands[1]) == REG)
- abort ();
-
- if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
+ if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
output_asm_insn (\"crxor 6,6,6\", operands);
- else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
+ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (\"creqv 6,6,6\", operands);
- return \"bl %z1\;%.\";
+ 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" "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"
+ [(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"
"*
{
- /* 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\";
+ 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" "branch")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "jmpreg,jmpreg,branch,branch")
+ (set_attr "length" "4,8,4,8")])
;; Call subroutine returning any type.
(define_expand "untyped_call"
}")
(define_insn "indirect_jumpsi"
- [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
+ [(set (pc) (match_operand:SI 0 "register_operand" "cl"))]
"TARGET_32BIT"
- "@
- bctr
- {br|blr}"
+ "b%T0"
[(set_attr "type" "jmpreg")])
(define_insn "indirect_jumpdi"
- [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
+ [(set (pc) (match_operand:DI 0 "register_operand" "cl"))]
"TARGET_64BIT"
- "@
- bctr
- {br|blr}"
+ "b%T0"
[(set_attr "type" "jmpreg")])
;; Table jump for switch statements:
(define_insn ""
[(set (pc)
- (match_operand:SI 0 "register_operand" "c,l"))
+ (match_operand:SI 0 "register_operand" "cl"))
(use (label_ref (match_operand 1 "" "")))]
"TARGET_32BIT"
- "@
- bctr
- {br|blr}"
+ "b%T0"
[(set_attr "type" "jmpreg")])
(define_insn ""
[(set (pc)
- (match_operand:DI 0 "register_operand" "c,l"))
+ (match_operand:DI 0 "register_operand" "cl"))
(use (label_ref (match_operand 1 "" "")))]
"TARGET_64BIT"
- "@
- bctr
- {br|blr}"
+ "b%T0"
[(set_attr "type" "jmpreg")])
(define_insn "nop"
"{lm|lmw} %1,%2")
(define_insn "*return_internal_si"
- [(use (match_operand:SI 0 "register_operand" "l,c"))
+ [(use (match_operand:SI 0 "register_operand" "lc"))
(return)]
"TARGET_32BIT"
- "@
- {br|blr}
- bctr"
+ "b%T0"
[(set_attr "type" "jmpreg")])
(define_insn "*return_internal_di"
- [(use (match_operand:DI 0 "register_operand" "l,c"))
+ [(use (match_operand:DI 0 "register_operand" "lc"))
(return)]
"TARGET_64BIT"
- "@
- {br|blr}
- bctr"
+ "b%T0"
[(set_attr "type" "jmpreg")])
; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
(define_insn "return_eh_si"
- [(use (match_operand:SI 0 "register_operand" "l,c"))
+ [(use (match_operand:SI 0 "register_operand" "lc"))
(return)
(use (reg:SI 2))
(use (reg:SI 3))]
"TARGET_32BIT"
- "@
- {br|blr}
- bctr"
+ "b%T0"
[(set_attr "type" "jmpreg")])
(define_insn "return_eh_di"
- [(use (match_operand:DI 0 "register_operand" "l,c"))
+ [(use (match_operand:DI 0 "register_operand" "lc"))
(return)
(use (reg:DI 2))
(use (reg:DI 3))]
"TARGET_64BIT"
- "@
- {br|blr}
- bctr"
+ "b%T0"
[(set_attr "type" "jmpreg")])