From: David Edelsohn Date: Tue, 25 Jul 2000 18:46:54 +0000 (+0000) Subject: rs6000.c (print_operand, case 'T'): New case. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cccf3bdc5c87885124ff12b812e2819a5bd574e4;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f8c0441b137..d391b95b08e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2000-07-25 David Edelsohn + + * 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 * config/ia64/ia64.c (ia64_print_operand): Handle "%,". diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5c411410476..623a47d1d31 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 4dfe6ba4a23..52ef7983153 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")])