aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2000-07-25 18:46:54 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2000-07-25 14:46:54 -0400
commitcccf3bdc5c87885124ff12b812e2819a5bd574e4 (patch)
tree834e260c80a26db3f1adafbc75a3e216ee6e362a
parent69b1b29156c348ffd39c85043b21d0ffd6cb4a73 (diff)
downloadgcc-cccf3bdc5c87885124ff12b812e2819a5bd574e4.zip
gcc-cccf3bdc5c87885124ff12b812e2819a5bd574e4.tar.gz
gcc-cccf3bdc5c87885124ff12b812e2819a5bd574e4.tar.bz2
rs6000.c (print_operand, case 'T'): New case.
* 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. From-SVN: r35246
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/config/rs6000/rs6000.c14
-rw-r--r--gcc/config/rs6000/rs6000.md590
3 files changed, 319 insertions, 309 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f8c0441..d391b95 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2000-07-25 David Edelsohn <edelsohn@gnu.org>
+
+ * 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.
+
2000-07-24 Richard Henderson <rth@cygnus.com>
* config/ia64/ia64.c (ia64_print_operand): Handle "%,".
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5c41141..623a47d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3984,6 +3984,7 @@ print_operand (file, x, code)
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;
}
@@ -4010,10 +4011,23 @@ print_operand (file, x, code)
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. */
if (! INT_P (x))
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4dfe6ba..52ef798 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9298,122 +9298,96 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
;; 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"
@@ -9435,31 +9409,26 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
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 ();
}
}")
@@ -9483,33 +9452,28 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
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 ();
}
}")
@@ -9557,7 +9521,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
[(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")))
@@ -9578,7 +9542,7 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(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")))
@@ -9605,154 +9569,178 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
;; 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"
@@ -13226,19 +13214,15 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
}")
(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:
@@ -13285,22 +13269,18 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(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"
@@ -13898,21 +13878,17 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
"{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
@@ -14037,23 +14013,19 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
(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")])