Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
5e1bf043
Commit
5e1bf043
authored
Aug 09, 2002
by
Dale Johannesen
Committed by
Dale Johannesen
Aug 09, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add sibcall handling for rs6000 target.
From-SVN: r56166
parent
3971a4d2
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
317 additions
and
6 deletions
+317
-6
gcc/ChangeLog
+8
-0
gcc/config/rs6000/rs6000-protos.h
+1
-0
gcc/config/rs6000/rs6000.c
+63
-6
gcc/config/rs6000/rs6000.h
+4
-0
gcc/config/rs6000/rs6000.md
+241
-0
No files found.
gcc/ChangeLog
View file @
5e1bf043
2002-08-09 Dale Johannesen <dalej@apple.com>
* config/rs6000/rs6000.md: Add sibcall patterns.
* config/rs6000/rs6000.h (FUNCTION_OK_FOR_SIBCALL): Define.
* config/rs6000/rs6000.c (rs6000_ra_ever_killed):
Rewritten to handle sibcalls.
* config/rs6000/rs6000.c (function_ok_for_sibcall): New.
* config/rs6000/rs6000-protos.h (function_ok_for_sibcall): New.
2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
* profile.c (da_file_name): New static var.
...
...
gcc/config/rs6000/rs6000-protos.h
View file @
5e1bf043
...
...
@@ -151,6 +151,7 @@ extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
int
*
,
int
));
extern
struct
rtx_def
*
rs6000_va_arg
PARAMS
((
tree
,
tree
));
extern
void
output_mi_thunk
PARAMS
((
FILE
*
,
tree
,
int
,
tree
));
extern
int
function_ok_for_sibcall
PARAMS
((
tree
));
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
extern
enum
direction
function_arg_padding
PARAMS
((
enum
machine_mode
,
tree
));
...
...
gcc/config/rs6000/rs6000.c
View file @
5e1bf043
...
...
@@ -9412,25 +9412,82 @@ rs6000_return_addr (count, frame)
return
get_hard_reg_initial_val
(
Pmode
,
LINK_REGISTER_REGNUM
);
}
/* Say whether a function is a candidate for sibcall handling or not.
We do not allow indirect calls to be optimized into sibling calls.
Also, we can't do it if there are any vector parameters; there's
nowhere to put the VRsave code so it works; note that functions with
vector parameters are required to have a prototype, so the argument
type info must be available here. (The tail recursion case can work
with vector parameters, but there's no way to distinguish here.) */
int
function_ok_for_sibcall
(
fndecl
)
tree
fndecl
;
{
tree
type
;
if
(
fndecl
)
{
if
(
TARGET_ALTIVEC_VRSAVE
)
{
for
(
type
=
TYPE_ARG_TYPES
(
TREE_TYPE
(
fndecl
));
type
;
type
=
TREE_CHAIN
(
type
))
{
if
(
TREE_CODE
(
TREE_VALUE
(
type
))
==
VECTOR_TYPE
)
return
0
;
}
}
if
(
DEFAULT_ABI
==
ABI_DARWIN
||
(
TREE_ASM_WRITTEN
(
fndecl
)
&&
!
flag_pic
)
||
!
TREE_PUBLIC
(
fndecl
))
return
1
;
}
return
0
;
}
/* function rewritten to handle sibcalls */
static
int
rs6000_ra_ever_killed
()
{
rtx
top
;
rtx
reg
;
rtx
insn
;
#ifdef ASM_OUTPUT_MI_THUNK
if
(
current_function_is_thunk
)
return
0
;
#endif
if
(
!
has_hard_reg_initial_val
(
Pmode
,
LINK_REGISTER_REGNUM
)
||
cfun
->
machine
->
ra_needs_full_frame
)
return
regs_ever_live
[
LINK_REGISTER_REGNUM
];
/* regs_ever_live has LR marked as used if any sibcalls
are present. Which it is, but this should not force
saving and restoring in the prologue/epilog. Likewise,
reg_set_between_p thinks a sibcall clobbers LR, so
that is inappropriate. */
/* Also, the prologue can generate a store into LR that
doesn't really count, like this:
move LR->R0
bcl to set PIC register
move LR->R31
move R0->LR
When we're called from the epilog, we need to avoid counting
this as a store; thus we ignore any insns with a REG_MAYBE_DEAD note. */
push_topmost_sequence
();
top
=
get_insns
();
pop_topmost_sequence
();
reg
=
gen_rtx_REG
(
Pmode
,
LINK_REGISTER_REGNUM
);
return
reg_set_between_p
(
gen_rtx_REG
(
Pmode
,
LINK_REGISTER_REGNUM
),
top
,
NULL_RTX
);
for
(
insn
=
NEXT_INSN
(
top
);
insn
!=
NULL_RTX
;
insn
=
NEXT_INSN
(
insn
))
{
if
(
INSN_P
(
insn
))
{
if
(
FIND_REG_INC_NOTE
(
insn
,
reg
))
return
1
;
else
if
(
GET_CODE
(
insn
)
==
CALL_INSN
&&
!
SIBLING_CALL_P
(
insn
))
return
1
;
else
if
(
set_of
(
reg
,
insn
)
!=
NULL_RTX
&&
find_reg_note
(
insn
,
REG_MAYBE_DEAD
,
NULL_RTX
)
==
0
)
return
1
;
}
}
return
0
;
}
/* Add a REG_MAYBE_DEAD note to the insn. */
...
...
gcc/config/rs6000/rs6000.h
View file @
5e1bf043
...
...
@@ -1798,6 +1798,10 @@ typedef struct rs6000_args
argument is passed depends on whether or not it is a named argument. */
#define STRICT_ARGUMENT_NAMING 1
/* We do not allow indirect calls to be optimized into sibling calls, nor
do we allow calls with vector parameters. */
#define FUNCTION_OK_FOR_SIBCALL(DECL) function_ok_for_sibcall ((DECL))
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
...
...
gcc/config/rs6000/rs6000.md
View file @
5e1bf043
...
...
@@ -10710,6 +10710,247 @@
DONE;
}")
;; sibling call patterns
(define_expand "sibcall"
[
(parallel
[
(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(use (scratch:SI))
(return)])]
""
"
{
#if TARGET_MACHO
if (flag_pic)
operands
[
0
]
= machopic_indirect_call_target (operands
[
0
]
);
#endif
if (GET_CODE (operands
[
0
]
) != MEM || GET_CODE (operands
[
1
]
) != CONST_INT)
abort ();
operands
[
0
]
= XEXP (operands
[
0
]
, 0);
}")
;; this and similar patterns must be marked as using LR, otherwise
;; dataflow will try to delete the store into it. This is true
;; even when the actual reg to jump to is in CTR, when LR was
;; saved and restored around the PIC-setting BCL.
(define_insn "
*
sibcall_local32"
[
(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(use (match_scratch:SI 3 "=l,l"))
(return)]
"(INTVAL (operands
[
2
]
) & CALL_LONG) == 0"
"
*
{
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) ?
\"
b %z0@local
\"
:
\"
b %z0
\"
;
}"
[
(set_attr "type" "branch")
(set_attr "length" "4,8")])
(define_insn "
*
sibcall_local64"
[
(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(use (match_scratch:SI 3 "=l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands
[
2
]
) & CALL_LONG) == 0"
"
*
{
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) ?
\"
b %z0@local
\"
:
\"
b %z0
\"
;
}"
[
(set_attr "type" "branch")
(set_attr "length" "4,8")])
(define_insn "
*
sibcall_value_local32"
[
(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(use (match_scratch:SI 4 "=l,l"))
(return)]
"(INTVAL (operands
[
3
]
) & CALL_LONG) == 0"
"
*
{
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) ?
\"
b %z1@local
\"
:
\"
b %z1
\"
;
}"
[
(set_attr "type" "branch")
(set_attr "length" "4,8")])
(define_insn "
*
sibcall_value_local64"
[
(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(use (match_scratch:SI 4 "=l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands
[
3
]
) & CALL_LONG) == 0"
"
*
{
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) ?
\"
b %z1@local
\"
:
\"
b %z1
\"
;
}"
[
(set_attr "type" "branch")
(set_attr "length" "4,8")])
(define_insn "
*
sibcall_nonlocal_aix32"
[
(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
(use (match_scratch:SI 3 "=l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands
[
2
]
) & CALL_LONG) == 0"
"b %z0"
[
(set_attr "type" "branch")
(set_attr "length" "4")])
(define_insn "
*
sibcall_nonlocal_aix64"
[
(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
(use (match_scratch:SI 3 "=l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands
[
2
]
) & CALL_LONG) == 0"
"b %z0"
[
(set_attr "type" "branch")
(set_attr "length" "4")])
(define_insn "
*
sibcall_value_nonlocal_aix32"
[
(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
(use (match_scratch:SI 4 "=l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands
[
3
]
) & CALL_LONG) == 0"
"b %z1"
[
(set_attr "type" "branch")
(set_attr "length" "4")])
(define_insn "
*
sibcall_value_nonlocal_aix64"
[
(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
(use (match_scratch:SI 4 "=l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands
[
3
]
) & CALL_LONG) == 0"
"b %z1"
[
(set_attr "type" "branch")
(set_attr "length" "4")])
(define_insn "
*
sibcall_nonlocal_sysv"
[
(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
(match_operand 1 "" ""))
(use (match_operand 2 "immediate_operand" "O,n"))
(use (match_scratch:SI 3 "=l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_AIX_NODESC)
&& (INTVAL (operands
[
2
]
) & CALL_LONG) == 0"
"
*
{
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) ?
\"
b %z0@plt
\"
:
\"
b %z0
\"
;
}"
[
(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
(define_expand "sibcall_value"
[
(parallel
[
(set (match_operand 0 "register_operand" "")
(call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(use (scratch:SI))
(return)])]
""
"
{
#if TARGET_MACHO
if (flag_pic)
operands
[
1
]
= machopic_indirect_call_target (operands
[
1
]
);
#endif
if (GET_CODE (operands
[
1
]
) != MEM || GET_CODE (operands
[
2
]
) != CONST_INT)
abort ();
operands
[
1
]
= XEXP (operands
[
1
]
, 0);
}")
(define_insn "
*
sibcall_value_nonlocal_sysv"
[
(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
(match_operand 2 "" "")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(use (match_scratch:SI 4 "=l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_AIX_NODESC)
&& (INTVAL (operands
[
3
]
) & CALL_LONG) == 0"
"
*
{
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) ?
\"
b %z1@plt
\"
:
\"
b %z1
\"
;
}"
[
(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
(define_expand "sibcall_epilogue"
[
(use (const_int 0))
]
"TARGET_SCHED_PROLOG"
"
{
rs6000_emit_epilogue (TRUE);
DONE;
}")
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
;; all of memory. This blocks insns from being moved across this point.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment