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
59257ff7
Commit
59257ff7
authored
May 06, 1992
by
Richard Kenner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r915
parent
a196f01f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
252 additions
and
39 deletions
+252
-39
gcc/calls.c
+9
-6
gcc/config/rs6000/rs6000.md
+58
-3
gcc/explow.c
+121
-0
gcc/expr.h
+9
-0
gcc/function.c
+9
-9
gcc/stmt.c
+46
-21
No files found.
gcc/calls.c
View file @
59257ff7
...
...
@@ -800,7 +800,7 @@ expand_call (exp, target, ignore)
if
(
old_stack_level
==
0
)
{
old_stack_level
=
copy_to_mode_reg
(
Pmode
,
stack_pointer_rtx
);
emit_stack_save
(
SAVE_BLOCK
,
&
old_stack_level
,
0
);
old_pending_adj
=
pending_stack_adjust
;
pending_stack_adjust
=
0
;
}
...
...
@@ -1060,7 +1060,7 @@ expand_call (exp, target, ignore)
{
if
(
old_stack_level
==
0
)
{
old_stack_level
=
copy_to_mode_reg
(
Pmode
,
stack_pointer_rtx
);
emit_stack_save
(
SAVE_BLOCK
,
&
old_stack_level
,
0
);
old_pending_adj
=
pending_stack_adjust
;
pending_stack_adjust
=
0
;
}
...
...
@@ -1520,7 +1520,7 @@ expand_call (exp, target, ignore)
if
(
old_stack_level
)
{
emit_
move_insn
(
stack_pointer_rtx
,
old_stack_level
);
emit_
stack_restore
(
SAVE_BLOCK
,
old_stack_level
,
0
);
pending_stack_adjust
=
old_pending_adj
;
}
...
...
@@ -1570,9 +1570,12 @@ expand_call (exp, target, ignore)
}
#endif
/* If this was alloca, record the new stack level for nonlocal gotos. */
if
(
may_be_alloca
&&
nonlocal_goto_stack_level
!=
0
)
emit_move_insn
(
nonlocal_goto_stack_level
,
stack_pointer_rtx
);
/* If this was alloca, record the new stack level for nonlocal gotos.
Check for the handler slots since we might not have a save area
for non-local gotos. */
if
(
may_be_alloca
&&
nonlocal_goto_handler_slot
!=
0
)
emit_stack_save
(
SAVE_NONLOCAL
,
&
nonlocal_goto_stack_level
,
0
);
pop_temp_slots
();
...
...
gcc/config/rs6000/rs6000.md
View file @
59257ff7
...
...
@@ -2835,9 +2835,7 @@
;; Next come insns related to the calling sequence.
;;
;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
;; We move the back-chain and decrement the stack pointer. This is slightly
;; less efficient than it needs to be for long constants, but that case
;; should be rare.
;; We move the back-chain and decrement the stack pointer.
(define_expand "allocate_stack"
[
(set (reg:SI 1)
...
...
@@ -2852,6 +2850,63 @@
emit_move_insn (stack_bot, chain);
DONE;
}")
;; These patterns say how to save and restore the stack pointer. We need not
;; save the stack pointer at function level since we are careful to
;; preserve the backchain. At block level, we have to restore the backchain
;; when we restore the stack pointer.
;;
;; For nonlocal gotos, we must save both the stack pointer and its
;; backchain and restore both. Note that in the nonlocal case, the
;; save area is a memory location.
(define_expand "save_stack_function"
[
(use (const_int 0))
]
""
"")
(define_expand "restore_stack_function"
[
(use (const_int 0))
]
""
"")
(define_expand "restore_stack_block"
[
(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
(set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
(set (mem:SI (match_dup 0)) (match_dup 2))]
""
"
{ operands
[
2
]
= gen_reg_rtx (SImode); }")
(define_expand "save_stack_nonlocal"
[
(match_operand:DI 0 "memory_operand" "")
(match_operand:SI 1 "register_operand" "")]
""
"
{
rtx temp = gen_reg_rtx (SImode);
/
* Copy the backchain to the first word, sp to the second. *
/
emit_move_insn (temp, gen_rtx (MEM, SImode, operands
[
1
]
));
emit_move_insn (operand_subword (operands
[
0
]
, 0, 0, DImode), temp);
emit_move_insn (operand_subword (operands
[
0
]
, 1, 0, DImode), operands
[
1
]
);
DONE;
}")
(define_expand "restore_stack_nonlocal"
[
(match_operand:SI 0 "register_operand" "")
(match_operand:DI 1 "memory_operand" "")]
""
"
{
rtx temp = gen_reg_rtx (SImode);
/
* Restore the backchain from the first word, sp from the second. *
/
emit_move_insn (temp, operand_subword (operands
[
1
]
, 0, 0, DImode));
emit_move_insn (operands
[
0
]
, operand_subword (operands
[
1
]
, 1, 0, DImode));
emit_move_insn (gen_rtx (MEM, SImode, operands
[
0
]
), temp);
DONE;
}")
;; A function pointer is a pointer to a data area whose first word contains
;; the actual address of the function, whose second word contains a pointer
...
...
gcc/explow.c
View file @
59257ff7
...
...
@@ -681,6 +681,127 @@ round_push (size)
return
size
;
}
/* Save the stack pointer for the purpose in SAVE_LEVEL. PSAVE is a pointer
to a previously-created save area. If no save area has been allocated,
this function will allocate one. If a save area is specified, it
must be of the proper mode.
The insns are emitted after insn AFTER, if nonzero, otherwise the insns
are emitted at the current position. */
void
emit_stack_save
(
save_level
,
psave
,
after
)
enum
save_level
save_level
;
rtx
*
psave
;
rtx
after
;
{
rtx
sa
=
*
psave
;
/* The default is that we use a move insn and save in a Pmode object. */
rtx
(
*
fcn
)
()
=
gen_move_insn
;
enum
machine_mode
mode
=
Pmode
;
/* See if this machine has anything special to do for this kind of save. */
switch
(
save_level
)
{
#ifdef HAVE_save_stack_block
case
SAVE_BLOCK
:
if
(
HAVE_save_stack_block
)
{
fcn
=
gen_save_stack_block
;
mode
=
insn_operand_mode
[
CODE_FOR_save_stack_block
][
0
];
}
break
;
#endif
#ifdef HAVE_save_stack_function
case
SAVE_FUNCTION
:
if
(
HAVE_save_stack_function
)
{
fcn
=
gen_save_stack_function
;
mode
=
insn_operand_mode
[
CODE_FOR_save_stack_function
][
0
];
}
break
;
#endif
#ifdef HAVE_save_stack_nonlocal
case
SAVE_NONLOCAL
:
if
(
HAVE_save_stack_nonlocal
)
{
fcn
=
gen_save_stack_nonlocal
;
mode
=
insn_operand_mode
[
CODE_FOR_save_stack_nonlocal
][
0
];
}
break
;
#endif
}
/* If there is no save area and we have to allocate one, do so. Otherwise
verify the save area is the proper mode. */
if
(
sa
==
0
)
{
if
(
mode
!=
VOIDmode
)
{
if
(
save_level
==
SAVE_NONLOCAL
)
*
psave
=
sa
=
assign_stack_local
(
mode
,
GET_MODE_SIZE
(
mode
),
0
);
else
*
psave
=
sa
=
gen_reg_rtx
(
mode
);
}
}
else
{
if
(
mode
==
VOIDmode
||
GET_MODE
(
sa
)
!=
mode
)
abort
();
}
if
(
after
)
emit_insn_after
(
fcn
(
sa
,
stack_pointer_rtx
),
after
);
else
emit_insn
(
fcn
(
sa
,
stack_pointer_rtx
));
}
/* Restore the stack pointer for the purpose in SAVE_LEVEL. SA is the save
area made by emit_stack_save. If it is zero, we have nothing to do.
Put any emitted insns after insn AFTER, if nonzero, otherwise at
current position. */
void
emit_stack_restore
(
save_level
,
sa
,
after
)
enum
save_level
save_level
;
rtx
after
;
rtx
sa
;
{
/* The default is that we use a move insn. */
rtx
(
*
fcn
)
()
=
gen_move_insn
;
/* See if this machine has anything special to do for this kind of save. */
switch
(
save_level
)
{
#ifdef HAVE_restore_stack_block
case
SAVE_BLOCK
:
if
(
HAVE_restore_stack_block
)
fcn
=
gen_restore_stack_block
;
break
;
#endif
#ifdef HAVE_restore_stack_function
case
SAVE_FUNCTION
:
if
(
HAVE_restore_stack_function
)
fcn
=
gen_restore_stack_function
;
break
;
#endif
#ifdef HAVE_restore_stack_nonlocal
case
SAVE_NONLOCAL
:
if
(
HAVE_restore_stack_nonlocal
)
fcn
=
gen_restore_stack_nonlocal
;
break
;
#endif
}
if
(
after
)
emit_insn_after
(
fcn
(
stack_pointer_rtx
,
sa
),
after
);
else
emit_insn
(
fcn
(
stack_pointer_rtx
,
sa
));
}
/* Return an rtx representing the address of an area of memory dynamically
pushed on the stack. This region of memory is always aligned to
a multiple of BIGGEST_ALIGNMENT.
...
...
gcc/expr.h
View file @
59257ff7
...
...
@@ -539,6 +539,15 @@ extern void adjust_stack ();
/* Add some bytes to the stack. An rtx says how many. */
extern
void
anti_adjust_stack
();
/* This enum is used for the following two functions. */
enum
save_level
{
SAVE_BLOCK
,
SAVE_FUNCTION
,
SAVE_NONLOCAL
};
/* Save the stack pointer at the specified level. */
extern
void
emit_stack_save
();
/* Restore the stack pointer from a save area of the specified level. */
extern
void
emit_stack_restore
();
/* Allocate some space on the stack dynamically and return its address. An rtx
says how many bytes. */
extern
rtx
allocate_dynamic_stack_space
();
...
...
gcc/function.c
View file @
59257ff7
...
...
@@ -2317,11 +2317,11 @@ delete_handlers ()
if
(
GET_CODE
(
insn
)
==
CODE_LABEL
)
LABEL_PRESERVE_P
(
insn
)
=
0
;
if
(
GET_CODE
(
insn
)
==
INSN
&&
GET_CODE
(
PATTERN
(
insn
))
==
SET
&&
(
SET_DEST
(
PATTERN
(
insn
))
==
nonlocal_goto_handler_slot
||
SET_SRC
(
PATTERN
(
insn
))
==
nonlocal_goto_handler_slot
||
SET_DEST
(
PATTERN
(
insn
))
==
nonlocal_goto_stack_level
||
SET_SRC
(
PATTERN
(
insn
))
==
nonlocal_goto_stack_level
))
&&
((
nonlocal_goto_handler_slot
!=
0
&&
reg_mentioned_p
(
nonlocal_goto_handler_slot
,
PATTERN
(
insn
)))
||
(
nonlocal_goto_stack_level
!=
0
&&
reg_mentioned_p
(
nonlocal_goto_stack_level
,
PATTERN
(
insn
)))
))
delete_insn
(
insn
);
}
}
...
...
@@ -3961,10 +3961,10 @@ expand_function_end (filename, line)
#endif
if
(
current_function_calls_alloca
)
{
rtx
tem
=
gen_reg_rtx
(
Pmode
)
;
emit_insn_after
(
gen_rtx
(
SET
,
VOIDmode
,
tem
,
stack_pointer_rtx
),
parm_birth_insn
);
emit_
insn
(
gen_rtx
(
SET
,
VOIDmode
,
stack_pointer_rtx
,
tem
)
);
rtx
tem
=
0
;
emit_stack_save
(
SAVE_FUNCTION
,
&
tem
,
parm_birth_insn
);
emit_
stack_restore
(
SAVE_FUNCTION
,
tem
,
0
);
}
/* If scalar return value was computed in a pseudo-reg,
...
...
gcc/stmt.c
View file @
59257ff7
...
...
@@ -586,11 +586,9 @@ declare_nonlocal_label (label)
{
nonlocal_goto_handler_slot
=
assign_stack_local
(
Pmode
,
GET_MODE_SIZE
(
Pmode
),
0
);
nonlocal_goto_stack_level
=
assign_stack_local
(
Pmode
,
GET_MODE_SIZE
(
Pmode
),
0
);
emit_insn_before
(
gen_move_insn
(
nonlocal_goto_stack_level
,
stack_pointer_rtx
),
tail_recursion_reentry
);
emit_stack_save
(
SAVE_NONLOCAL
,
&
nonlocal_goto_stack_level
,
PREV_INSN
(
tail_recursion_reentry
));
}
}
...
...
@@ -609,27 +607,50 @@ expand_goto (label)
struct
function
*
p
=
find_function_data
(
context
);
rtx
temp
;
p
->
has_nonlocal_label
=
1
;
/* Copy the rtl for the slots so that they won't be shared in
case the virtual stack vars register gets instantiated differently
in the parent than in the child. */
#if HAVE_nonlocal_goto
if
(
HAVE_nonlocal_goto
)
emit_insn
(
gen_nonlocal_goto
(
lookup_static_chain
(
label
),
p
->
nonlocal_goto_handler_slot
,
p
->
nonlocal_goto_stack_level
,
copy_rtx
(
p
->
nonlocal_goto_handler_slot
)
,
copy_rtx
(
p
->
nonlocal_goto_stack_level
)
,
gen_rtx
(
LABEL_REF
,
Pmode
,
label_rtx
(
label
))));
else
#endif
{
rtx
addr
;
/* Restore frame pointer for containing function.
This sets the actual hard register used for the frame pointer
to the location of the function's incoming static chain info.
The non-local goto handler will then adjust it to contain the
proper value and reload the argument pointer, if needed. */
emit_move_insn
(
frame_pointer_rtx
,
lookup_static_chain
(
label
));
/* We have now loaded the frame pointer hardware register with
the address of that corresponds to the start of the virtual
stack vars. So replace virtual_stack_vars_rtx in all
addresses we use with stack_pointer_rtx. */
/* Get addr of containing function's current nonlocal goto handler,
which will do any cleanups and then jump to the label. */
temp
=
copy_to_reg
(
p
->
nonlocal_goto_handler_slot
);
addr
=
copy_rtx
(
p
->
nonlocal_goto_handler_slot
);
temp
=
copy_to_reg
(
replace_rtx
(
addr
,
virtual_stack_vars_rtx
,
frame_pointer_rtx
));
/* Restore the stack pointer. Note this uses fp just restored. */
emit_move_insn
(
stack_pointer_rtx
,
p
->
nonlocal_goto_stack_level
);
addr
=
p
->
nonlocal_goto_stack_level
;
if
(
addr
)
addr
=
replace_rtx
(
copy_rtx
(
p
->
nonlocal_goto_stack_level
),
replace_rtx
(
addr
,
virtual_stack_vars_rtx
,
frame_pointer_rtx
));
emit_stack_restore
(
SAVE_NONLOCAL
,
addr
,
0
);
/* Put in the static chain register the nonlocal label address. */
emit_move_insn
(
static_chain_rtx
,
gen_rtx
(
LABEL_REF
,
Pmode
,
label_rtx
(
label
)));
...
...
@@ -691,7 +712,7 @@ expand_goto_internal (body, label, last_insn)
the stack pointer. This one should be deleted as dead by flow. */
clear_pending_stack_adjust
();
do_pending_stack_adjust
();
emit_
move_insn
(
stack_pointer_rtx
,
stack_level
);
emit_
stack_restore
(
SAVE_BLOCK
,
stack_level
,
0
);
}
if
(
body
!=
0
&&
DECL_TOO_LATE
(
body
))
...
...
@@ -902,8 +923,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
/* Restore stack level for the biggest contour that this
jump jumps out of. */
if
(
f
->
stack_level
)
emit_insn_after
(
gen_move_insn
(
stack_pointer_rtx
,
f
->
stack_level
),
f
->
before_jump
);
emit_stack_restore
(
SAVE_BLOCK
,
f
->
stack_level
,
f
->
before_jump
);
f
->
before_jump
=
0
;
}
}
...
...
@@ -2592,14 +2612,15 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
if
(
thisblock
->
data
.
block
.
stack_level
!=
0
)
{
emit_
move_insn
(
stack_pointer_rtx
,
thisblock
->
data
.
block
.
stack_level
);
if
(
nonlocal_goto_
stack_level
!=
0
)
emit_
move_insn
(
nonlocal_goto_stack_level
,
stack_pointer_rtx
);
emit_
stack_restore
(
thisblock
->
next
?
SAVE_BLOCK
:
SAVE_FUNCTION
,
thisblock
->
data
.
block
.
stack_level
,
0
);
if
(
nonlocal_goto_
handler_slot
!=
0
)
emit_
stack_save
(
SAVE_NONLOCAL
,
&
nonlocal_goto_stack_level
,
0
);
}
/* Any gotos out of this block must also do these things.
Also report any gotos with fixups that came to labels in this level. */
Also report any gotos with fixups that came to labels in this
level. */
fixup_gotos
(
thisblock
,
thisblock
->
data
.
block
.
stack_level
,
thisblock
->
data
.
block
.
cleanups
,
...
...
@@ -2753,8 +2774,9 @@ expand_decl (decl)
if
(
thisblock
->
data
.
block
.
stack_level
==
0
)
{
do_pending_stack_adjust
();
thisblock
->
data
.
block
.
stack_level
=
copy_to_reg
(
stack_pointer_rtx
);
emit_stack_save
(
thisblock
->
next
?
SAVE_BLOCK
:
SAVE_FUNCTION
,
&
thisblock
->
data
.
block
.
stack_level
,
thisblock
->
data
.
block
.
first_insn
);
stack_block_stack
=
thisblock
;
}
...
...
@@ -2765,11 +2787,14 @@ expand_decl (decl)
0
,
VOIDmode
,
0
);
free_temp_slots
();
/* This is equivalent to calling alloca. */
current_function_calls_alloca
=
1
;
/* Allocate space on the stack for the variable. */
address
=
allocate_dynamic_stack_space
(
size
,
0
,
DECL_ALIGN
(
decl
));
if
(
nonlocal_goto_
stack_level
!=
0
)
emit_
move_insn
(
nonlocal_goto_stack_level
,
stack_pointer_rtx
);
if
(
nonlocal_goto_
handler_slot
!=
0
)
emit_
stack_save
(
SAVE_NONLOCAL
,
&
nonlocal_goto_stack_level
,
0
);
/* Reference the variable indirect through that rtx. */
DECL_RTL
(
decl
)
=
gen_rtx
(
MEM
,
DECL_MODE
(
decl
),
address
);
...
...
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