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
2f4aa534
Commit
2f4aa534
authored
May 31, 1992
by
Richard Stallman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r1132
parent
8ac9cb56
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
100 additions
and
6 deletions
+100
-6
gcc/calls.c
+100
-6
No files found.
gcc/calls.c
View file @
2f4aa534
...
...
@@ -87,6 +87,13 @@ static char *stack_usage_map;
/* Size of STACK_USAGE_MAP. */
static
int
highest_outgoing_arg_in_use
;
/* stack_arg_under_construction is nonzero when an argument may be
initialized with a constructor call (including a C function that
returns a BLKmode struct) and expand_call must take special action
to make sure the object being constructed does not overlap the
argument list for the constructor call. */
int
stack_arg_under_construction
;
#endif
static
void
store_one_arg
();
...
...
@@ -468,6 +475,7 @@ expand_call (exp, target, ignore)
rtx
old_stack_level
=
0
;
int
old_pending_adj
;
int
old_stack_arg_under_construction
;
int
old_inhibit_defer_pop
=
inhibit_defer_pop
;
tree
old_cleanups
=
cleanups_this_call
;
...
...
@@ -576,6 +584,7 @@ expand_call (exp, target, ignore)
if
(
is_integrable
)
{
rtx
temp
;
rtx
before_call
=
get_last_insn
();
temp
=
expand_inline_function
(
fndecl
,
actparms
,
target
,
ignore
,
TREE_TYPE
(
exp
),
...
...
@@ -584,6 +593,39 @@ expand_call (exp, target, ignore)
/* If inlining succeeded, return. */
if
((
int
)
temp
!=
-
1
)
{
int
i
;
/* If the outgoing argument list must be preserved, push
the stack before executing the inlined function if it
makes any calls. */
for
(
i
=
reg_parm_stack_space
-
1
;
i
>=
0
;
i
--
)
if
(
i
<
highest_outgoing_arg_in_use
&&
stack_usage_map
[
i
]
!=
0
)
break
;
if
(
stack_arg_under_construction
||
i
>=
0
)
{
rtx
insn
,
seq
;
for
(
insn
=
NEXT_INSN
(
before_call
);
insn
;
insn
=
NEXT_INSN
(
insn
))
if
(
GET_CODE
(
insn
)
==
CALL_INSN
)
break
;
if
(
insn
)
{
start_sequence
();
emit_stack_save
(
SAVE_BLOCK
,
&
old_stack_level
,
0
);
allocate_dynamic_stack_space
(
gen_rtx
(
CONST_INT
,
VOIDmode
,
highest_outgoing_arg_in_use
),
0
,
BITS_PER_UNIT
);
seq
=
get_insns
();
end_sequence
();
emit_insns_before
(
seq
,
NEXT_INSN
(
before_call
));
emit_stack_restore
(
SAVE_BLOCK
,
old_stack_level
,
0
);
}
}
/* Perform all cleanups needed for the arguments of this call
(i.e. destructors in C++). It is ok if these destructors
clobber RETURN_VALUE_REG, because the only time we care about
...
...
@@ -701,10 +743,15 @@ expand_call (exp, target, ignore)
as if it were an extra parameter. */
if
(
structure_value_addr
&&
struct_value_rtx
==
0
)
{
/* If the stack will be adjusted, make sure the structure address
does not refer to virtual_outgoing_args_rtx. */
rtx
temp
=
(
stack_arg_under_construction
?
copy_addr_to_reg
(
structure_value_addr
)
:
force_reg
(
Pmode
,
structure_value_addr
));
actparms
=
tree_cons
(
error_mark_node
,
make_tree
(
build_pointer_type
(
TREE_TYPE
(
funtype
)),
force_reg
(
Pmode
,
structure_value_addr
)
),
temp
),
actparms
);
structure_value_addr_parm
=
1
;
}
...
...
@@ -1064,6 +1111,11 @@ expand_call (exp, target, ignore)
emit_stack_save
(
SAVE_BLOCK
,
&
old_stack_level
,
0
);
old_pending_adj
=
pending_stack_adjust
;
pending_stack_adjust
=
0
;
/* stack_arg_under_construction says whether a stack arg is
being constructed at the old stack level. Pushing the stack
gets a clean outgoing argument block. */
old_stack_arg_under_construction
=
stack_arg_under_construction
;
stack_arg_under_construction
=
0
;
}
argblock
=
push_block
(
ARGS_SIZE_RTX
(
args_size
),
0
,
0
);
}
...
...
@@ -1118,10 +1170,24 @@ expand_call (exp, target, ignore)
bzero
(
&
stack_usage_map
[
initial_highest_arg_in_use
],
highest_outgoing_arg_in_use
-
initial_highest_arg_in_use
);
needed
=
0
;
/* No need to copy this virtual register; the space we're
using gets preallocated at the start of the function
so the stack pointer won't change here. */
/* The only way the stack pointer can change here is if some arguments
which are passed in memory are constructed in place in the outgoing
argument area. All objects which are constructed in place have
pass_on_stack == 1 (see store_one_arg ()).
The test for arguments being constructed on the stack is just an
optimization: it would be correct but suboptimal to call
copy_addr_to_reg () unconditionally. */
argblock
=
virtual_outgoing_args_rtx
;
for
(
i
=
0
;
i
<
num_actuals
;
i
++
)
if
(
args
[
i
].
pass_on_stack
)
{
argblock
=
copy_addr_to_reg
(
argblock
);
break
;
}
#else
/* not ACCUMULATE_OUTGOING_ARGS */
if
(
inhibit_defer_pop
==
0
)
{
...
...
@@ -1207,6 +1273,31 @@ expand_call (exp, target, ignore)
#endif
#endif
/* The save/restore code in store_one_arg handles all cases except one:
a constructor call (including a C function returning a BLKmode struct)
to initialize an argument. */
if
(
stack_arg_under_construction
)
{
rtx
push_size
=
gen_rtx
(
CONST_INT
,
VOIDmode
,
highest_outgoing_arg_in_use
);
if
(
old_stack_level
==
0
)
{
emit_stack_save
(
SAVE_BLOCK
,
&
old_stack_level
,
0
);
old_pending_adj
=
pending_stack_adjust
;
pending_stack_adjust
=
0
;
/* stack_arg_under_construction says whether a stack arg is
being constructed at the old stack level. Pushing the stack
gets a clean outgoing argument block. */
old_stack_arg_under_construction
=
stack_arg_under_construction
;
stack_arg_under_construction
=
0
;
/* Make a new map for the new argument list. */
stack_usage_map
=
(
char
*
)
alloca
(
highest_outgoing_arg_in_use
);
bzero
(
stack_usage_map
,
highest_outgoing_arg_in_use
);
highest_outgoing_arg_in_use
=
0
;
}
allocate_dynamic_stack_space
(
push_size
,
0
,
BITS_PER_UNIT
);
}
/* Don't try to defer pops if preallocating, not even from the first arg,
since ARGBLOCK probably refers to the SP. */
if
(
argblock
)
...
...
@@ -1537,14 +1628,17 @@ expand_call (exp, target, ignore)
(i.e. destructors in C++). */
expand_cleanups_to
(
old_cleanups
);
/* If size of args is variable, restore saved stack-pointer value. */
/* If size of args is variable or this was a constructor call for a stack
argument, restore saved stack-pointer value. */
if
(
old_stack_level
)
{
emit_stack_restore
(
SAVE_BLOCK
,
old_stack_level
,
0
);
pending_stack_adjust
=
old_pending_adj
;
stack_arg_under_construction
=
old_stack_arg_under_construction
;
highest_outgoing_arg_in_use
=
initial_highest_arg_in_use
;
stack_usage_map
=
initial_stack_usage_map
;
}
#ifdef ACCUMULATE_OUTGOING_ARGS
else
{
...
...
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