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
7bea35e7
Commit
7bea35e7
authored
Dec 16, 1992
by
Michael Meissner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rework large stack frame support.
From-SVN: r2884
parent
f49acdb4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
283 additions
and
151 deletions
+283
-151
gcc/config/mips/mips.c
+263
-131
gcc/config/mips/mips.h
+20
-20
No files found.
gcc/config/mips/mips.c
View file @
7bea35e7
...
...
@@ -3732,6 +3732,72 @@ mips_output_float (stream, value)
}
/* Return TRUE if any register used in the epilogue is used. This to insure
any insn put into the epilogue delay slots is safe. */
int
epilogue_reg_mentioned_p
(
insn
)
rtx
insn
;
{
register
char
*
fmt
;
register
int
i
;
register
enum
rtx_code
code
;
register
int
regno
;
if
(
insn
==
(
rtx
)
0
)
return
0
;
if
(
GET_CODE
(
insn
)
==
LABEL_REF
)
return
0
;
code
=
GET_CODE
(
insn
);
switch
(
code
)
{
case
REG
:
regno
=
REGNO
(
insn
);
if
(
regno
==
STACK_POINTER_REGNUM
)
return
1
;
if
(
regno
==
FRAME_POINTER_REGNUM
&&
frame_pointer_needed
)
return
1
;
if
(
!
call_used_regs
[
regno
])
return
1
;
if
(
regno
!=
MIPS_TEMP1_REGNUM
&&
regno
!=
MIPS_TEMP2_REGNUM
)
return
0
;
if
(
!
current_frame_info
.
initialized
)
compute_frame_size
(
get_frame_size
());
return
(
current_frame_info
.
total_size
>=
32768
);
case
SCRATCH
:
case
CC0
:
case
PC
:
case
CONST_INT
:
case
CONST_DOUBLE
:
return
0
;
}
fmt
=
GET_RTX_FORMAT
(
code
);
for
(
i
=
GET_RTX_LENGTH
(
code
)
-
1
;
i
>=
0
;
i
--
)
{
if
(
fmt
[
i
]
==
'E'
)
{
register
int
j
;
for
(
j
=
XVECLEN
(
insn
,
i
)
-
1
;
j
>=
0
;
j
--
)
if
(
epilogue_reg_mentioned_p
(
XVECEXP
(
insn
,
i
,
j
)))
return
1
;
}
else
if
(
fmt
[
i
]
==
'e'
&&
epilogue_reg_mentioned_p
(
XEXP
(
insn
,
i
)))
return
1
;
}
return
0
;
}
/* Return the bytes needed to compute the frame pointer from the current
stack pointer.
...
...
@@ -3785,22 +3851,22 @@ mips_output_float (stream, value)
*/
unsigned
long
long
compute_frame_size
(
size
)
int
size
;
/* # of var. bytes allocated */
{
int
regno
;
unsigned
long
total_size
;
/* # bytes that the entire frame takes up */
unsigned
long
var_size
;
/* # bytes that variables take up */
unsigned
long
args_size
;
/* # bytes that outgoing arguments take up */
unsigned
long
extra_size
;
/* # extra bytes */
unsigned
int
gp_reg_rounded
;
/* # bytes needed to store gp after rounding */
unsigned
int
gp_reg_size
;
/* # bytes needed to store gp regs */
unsigned
int
fp_reg_size
;
/* # bytes needed to store fp regs */
unsigned
long
mask
;
/* mask of saved gp registers */
unsigned
long
fmask
;
/* mask of saved fp registers */
int
fp_inc
;
/* 1 or 2 depending on the size of fp regs */
int
fp_bits
;
/* bitmask to use for each fp register */
long
total_size
;
/* # bytes that the entire frame takes up */
long
var_size
;
/* # bytes that variables take up */
long
args_size
;
/* # bytes that outgoing arguments take up */
long
extra_size
;
/* # extra bytes */
long
gp_reg_rounded
;
/* # bytes needed to store gp after rounding */
long
gp_reg_size
;
/* # bytes needed to store gp regs */
long
fp_reg_size
;
/* # bytes needed to store fp regs */
long
mask
;
/* mask of saved gp registers */
long
fmask
;
/* mask of saved fp registers */
int
fp_inc
;
/* 1 or 2 depending on the size of fp regs */
long
fp_bits
;
/* bitmask to use for each fp register */
gp_reg_size
=
0
;
fp_reg_size
=
0
;
...
...
@@ -3826,7 +3892,7 @@ compute_frame_size (size)
if
(
MUST_SAVE_REGISTER
(
regno
))
{
gp_reg_size
+=
UNITS_PER_WORD
;
mask
|=
1
<<
(
regno
-
GP_REG_FIRST
);
mask
|=
1
L
<<
(
regno
-
GP_REG_FIRST
);
}
}
...
...
@@ -3900,156 +3966,213 @@ compute_frame_size (size)
}
/* Save/restore registers printing out the instructions to a file. */
/* Common code to emit the insns (or to write the instructions to a file)
to save/restore registers.
void
save_restore
(
file
,
gp_op
,
gp_2word_op
,
fp_op
)
FILE
*
file
;
/* stream to write to */
char
*
gp_op
;
/* operation to do on gp registers */
char
*
gp_2word_op
;
/* 2 word op to do on gp registers */
char
*
fp_op
;
/* operation to do on fp registers */
Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg)
is not modified within save_restore_insns. */
#define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0)
static
void
save_restore_insns
(
store_p
,
large_reg
,
large_offset
,
file
)
int
store_p
;
/* true if this is prologue */
rtx
large_reg
;
/* register holding large offset constant or NULL */
long
large_offset
;
/* large constant offset value */
FILE
*
file
;
/* file to write instructions to instead of making RTL */
{
long
mask
=
current_frame_info
.
mask
;
long
fmask
=
current_frame_info
.
fmask
;
int
regno
;
unsigned
long
mask
=
current_frame_info
.
mask
;
unsigned
long
fmask
=
current_frame_info
.
fmask
;
unsigned
long
gp_offset
;
unsigned
long
fp_offset
;
unsigned
long
min_offset
;
char
*
base_reg
;
rtx
base_reg_rtx
;
long
base_offset
;
long
gp_offset
;
long
fp_offset
;
long
end_offset
;
if
(
frame_pointer_needed
&&
!
BITSET_P
(
mask
,
FRAME_POINTER_REGNUM
-
GP_REG_FIRST
))
abort
();
if
(
mask
==
0
&&
fmask
==
0
)
return
;
base_reg
=
reg_names
[
STACK_POINTER_REGNUM
];
gp_offset
=
current_frame_info
.
gp_sp_offset
;
fp_offset
=
current_frame_info
.
fp_sp_offset
;
min_offset
=
(
gp_offset
<
fp_offset
&&
mask
!=
0
)
?
gp_offset
:
fp_offset
;
/* Deal with calling functions with a large structure. */
if
(
min_offset
>=
32768
)
{
char
*
temp
=
reg_names
[
MIPS_TEMP2_REGNUM
];
fprintf
(
file
,
"
\t
li
\t
%s,%ld
\n
"
,
temp
,
min_offset
);
fprintf
(
file
,
"
\t
addu
\t
%s,%s,%s
\n
"
,
temp
,
temp
,
base_reg
);
base_reg
=
temp
;
gp_offset
=
min_offset
-
gp_offset
;
fp_offset
=
min_offset
-
fp_offset
;
}
/* Save registers starting from high to low. The debuggers prefer
at least the return register be stored at func+4, and also it
allows us not to need a nop in the epilog if at least one
register is reloaded in addition to return address. */
if
(
mask
||
frame_pointer_needed
)
/* Save GP registers if needed. */
if
(
mask
)
{
for
(
regno
=
GP_REG_LAST
;
regno
>=
GP_REG_FIRST
;
regno
--
)
{
if
((
mask
&
(
1L
<<
(
regno
-
GP_REG_FIRST
)))
!=
0
||
(
regno
==
FRAME_POINTER_REGNUM
&&
frame_pointer_needed
))
{
fprintf
(
file
,
"
\t
%s
\t
%s,%d(%s)
\n
"
,
gp_op
,
reg_names
[
regno
],
gp_offset
,
base_reg
);
/* Pick which pointer to use as a base register. For small
frames, just use the stack pointer. Otherwise, use a
temporary register. Save 2 cycles if the save area is near
the end of a large frame, by reusing the constant created in
the prologue/epilogue to adjust the stack frame. */
gp_offset
-=
UNITS_PER_WORD
;
}
gp_offset
=
current_frame_info
.
gp_sp_offset
;
end_offset
=
gp_offset
-
(
current_frame_info
.
gp_reg_size
-
UNITS_PER_WORD
);
if
(
gp_offset
<
0
||
end_offset
<
0
)
fatal
(
"gp_offset (%ld) or end_offset (%ld) is less than zero."
,
gp_offset
,
end_offset
);
else
if
(
gp_offset
<
32768
)
{
base_reg_rtx
=
stack_pointer_rtx
;
base_offset
=
0
;
}
}
if
(
fmask
)
{
int
fp_inc
=
(
TARGET_FLOAT64
)
?
1
:
2
;
else
if
(
large_reg
!=
(
rtx
)
0
&&
(((
unsigned
long
)(
large_offset
-
gp_offset
))
<
32768
)
&&
(((
unsigned
long
)(
large_offset
-
end_offset
))
<
32768
))
{
base_reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
MIPS_TEMP2_REGNUM
);
base_offset
=
large_offset
;
if
(
file
==
(
FILE
*
)
0
)
emit_insn
(
gen_addsi3
(
base_reg_rtx
,
large_reg
,
stack_pointer_rtx
));
else
fprintf
(
file
,
"
\t
addu
\t
%s,%s,%s
\n
"
,
reg_names
[
MIPS_TEMP2_REGNUM
],
reg_names
[
REGNO
(
large_reg
)],
reg_names
[
STACK_POINTER_REGNUM
]);
}
for
(
regno
=
FP_REG_LAST
-
1
;
regno
>=
FP_REG_FIRST
;
regno
-=
fp_inc
)
else
{
if
((
fmask
&
(
1L
<<
(
regno
-
FP_REG_FIRST
)))
!=
0
)
base_reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
MIPS_TEMP2_REGNUM
);
base_offset
=
gp_offset
;
if
(
file
==
(
FILE
*
)
0
)
{
fprintf
(
file
,
"
\t
%s
\t
%s,%d(%s)
\n
"
,
fp_op
,
reg_names
[
regno
],
fp_offset
,
base_reg
);
fp_offset
-=
2
*
UNITS_PER_WORD
;
emit_move_insn
(
base_reg_rtx
,
GEN_INT
(
gp_offset
));
emit_insn
(
gen_addsi3
(
base_reg_rtx
,
base_reg_rtx
,
stack_pointer_rtx
));
}
else
fprintf
(
file
,
"
\t
li
\t
%s,0x%.08lx
\t
# %ld
\n\t
addu
\t
%s,%s,%s
\n
"
,
reg_names
[
MIPS_TEMP2_REGNUM
],
(
long
)
base_offset
,
(
long
)
base_offset
,
reg_names
[
MIPS_TEMP2_REGNUM
],
reg_names
[
MIPS_TEMP2_REGNUM
],
reg_names
[
STACK_POINTER_REGNUM
]);
}
}
}
/* Common code to emit the insns to save/restore registers. */
static
void
save_restore_insns
(
store_p
)
int
store_p
;
/* true if this is prologue */
{
int
regno
;
rtx
base_reg_rtx
=
stack_pointer_rtx
;
unsigned
long
mask
=
current_frame_info
.
mask
;
unsigned
long
fmask
=
current_frame_info
.
fmask
;
unsigned
long
gp_offset
;
unsigned
long
fp_offset
;
unsigned
long
min_offset
;
if
(
mask
==
0
&&
fmask
==
0
)
return
;
gp_offset
=
current_frame_info
.
gp_sp_offset
;
fp_offset
=
current_frame_info
.
fp_sp_offset
;
min_offset
=
(
gp_offset
<
fp_offset
&&
mask
!=
0
)
?
gp_offset
:
fp_offset
;
/* Deal with calling functions with a large structure. */
if
(
min_offset
>=
32768
)
{
base_reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
MIPS_TEMP2_REGNUM
);
emit_move_insn
(
base_reg_rtx
,
GEN_INT
(
min_offset
));
emit_insn
(
gen_addsi3
(
base_reg_rtx
,
base_reg_rtx
,
stack_pointer_rtx
));
gp_offset
=
min_offset
-
gp_offset
;
fp_offset
=
min_offset
-
fp_offset
;
}
/* Save registers starting from high to low. The debuggers prefer
at least the return register be stored at func+4, and also it
allows us not to need a nop in the epilog if at least one
register is reloaded in addition to return address. */
if
(
mask
||
frame_pointer_needed
)
{
for
(
regno
=
GP_REG_LAST
;
regno
>=
GP_REG_FIRST
;
regno
--
)
{
if
((
mask
&
(
1L
<<
(
regno
-
GP_REG_FIRST
)))
!=
0
||
(
regno
==
FRAME_POINTER_REGNUM
&&
frame_pointer_needed
))
if
(
BITSET_P
(
mask
,
regno
-
GP_REG_FIRST
))
{
rtx
reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
regno
);
rtx
mem_rtx
=
gen_rtx
(
MEM
,
Pmode
,
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
GEN_INT
(
gp_offset
)));
if
(
file
==
(
FILE
*
)
0
)
{
rtx
reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
regno
);
rtx
mem_rtx
=
gen_rtx
(
MEM
,
Pmode
,
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
GEN_INT
(
gp_offset
-
base_offset
)));
if
(
store_p
)
emit_move_insn
(
mem_rtx
,
reg_rtx
);
if
(
store_p
)
emit_move_insn
(
mem_rtx
,
reg_rtx
);
else
emit_move_insn
(
reg_rtx
,
mem_rtx
);
}
else
emit_move_insn
(
reg_rtx
,
mem_rtx
);
fprintf
(
file
,
"
\t
%s
\t
%s,%ld(%s)
\n
"
,
(
store_p
)
?
"sw"
:
"lw"
,
reg_names
[
regno
],
gp_offset
-
base_offset
,
reg_names
[
REGNO
(
base_reg_rtx
)]);
gp_offset
-=
UNITS_PER_WORD
;
}
}
}
else
{
base_reg_rtx
=
(
rtx
)
0
;
/* Make sure these are initialzed */
base_offset
=
0
;
}
/* Save floating point registers if needed. */
if
(
fmask
)
{
int
fp_inc
=
(
TARGET_FLOAT64
)
?
1
:
2
;
/* Pick which pointer to use as a base register. */
fp_offset
=
current_frame_info
.
fp_sp_offset
;
end_offset
=
fp_offset
-
(
current_frame_info
.
fp_reg_size
-
UNITS_PER_WORD
);
if
(
fp_offset
<
0
||
end_offset
<
0
)
fatal
(
"fp_offset (%ld) or end_offset (%ld) is less than zero."
,
fp_offset
,
end_offset
);
else
if
(
fp_offset
<
32768
)
{
base_reg_rtx
=
stack_pointer_rtx
;
base_offset
=
0
;
}
else
if
(
base_reg_rtx
!=
(
rtx
)
0
&&
(((
unsigned
long
)(
base_offset
-
fp_offset
))
<
32768
)
&&
(((
unsigned
long
)(
base_offset
-
end_offset
))
<
32768
))
{
;
/* already set up for gp registers above */
}
else
if
(
large_reg
!=
(
rtx
)
0
&&
(((
unsigned
long
)(
large_offset
-
fp_offset
))
<
32768
)
&&
(((
unsigned
long
)(
large_offset
-
end_offset
))
<
32768
))
{
base_reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
MIPS_TEMP2_REGNUM
);
base_offset
=
large_offset
;
if
(
file
==
(
FILE
*
)
0
)
emit_insn
(
gen_addsi3
(
base_reg_rtx
,
large_reg
,
stack_pointer_rtx
));
else
fprintf
(
file
,
"
\t
addu
\t
%s,%s,%s
\n
"
,
reg_names
[
MIPS_TEMP2_REGNUM
],
reg_names
[
REGNO
(
large_reg
)],
reg_names
[
STACK_POINTER_REGNUM
]);
}
else
{
base_reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
MIPS_TEMP2_REGNUM
);
base_offset
=
fp_offset
;
if
(
file
==
(
FILE
*
)
0
)
{
emit_move_insn
(
base_reg_rtx
,
GEN_INT
(
fp_offset
));
emit_insn
(
gen_addsi3
(
base_reg_rtx
,
base_reg_rtx
,
stack_pointer_rtx
));
}
else
fprintf
(
file
,
"
\t
li
\t
%s,0x%.08lx
\t
# %ld
\n\t
addu
\t
%s,%s,%s
\n
"
,
reg_names
[
MIPS_TEMP2_REGNUM
],
(
long
)
base_offset
,
(
long
)
base_offset
,
reg_names
[
MIPS_TEMP2_REGNUM
],
reg_names
[
MIPS_TEMP2_REGNUM
],
reg_names
[
STACK_POINTER_REGNUM
]);
}
for
(
regno
=
FP_REG_LAST
-
1
;
regno
>=
FP_REG_FIRST
;
regno
-=
fp_inc
)
{
if
(
(
fmask
&
(
1L
<<
(
regno
-
FP_REG_FIRST
)))
!=
0
)
if
(
BITSET_P
(
fmask
,
regno
-
FP_REG_FIRST
)
)
{
rtx
reg_rtx
=
gen_rtx
(
REG
,
DFmode
,
regno
);
rtx
mem_rtx
=
gen_rtx
(
MEM
,
DFmode
,
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
GEN_INT
(
fp_offset
)));
if
(
file
==
(
FILE
*
)
0
)
{
rtx
reg_rtx
=
gen_rtx
(
REG
,
DFmode
,
regno
);
rtx
mem_rtx
=
gen_rtx
(
MEM
,
DFmode
,
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
GEN_INT
(
fp_offset
-
base_offset
)));
if
(
store_p
)
emit_move_insn
(
mem_rtx
,
reg_rtx
);
if
(
store_p
)
emit_move_insn
(
mem_rtx
,
reg_rtx
);
else
emit_move_insn
(
reg_rtx
,
mem_rtx
);
}
else
emit_move_insn
(
reg_rtx
,
mem_rtx
);
fprintf
(
file
,
"
\t
%s
\t
%s,%ld(%s)
\n
"
,
(
store_p
)
?
"s.d"
:
"l.d"
,
reg_names
[
regno
],
fp_offset
-
base_offset
,
reg_names
[
REGNO
(
base_reg_rtx
)]);
fp_offset
-=
2
*
UNITS_PER_WORD
;
}
...
...
@@ -4065,7 +4188,7 @@ function_prologue (file, size)
FILE
*
file
;
int
size
;
{
int
tsize
=
current_frame_info
.
total_size
;
long
tsize
=
current_frame_info
.
total_size
;
ASM_OUTPUT_SOURCE_FILENAME
(
file
,
DECL_SOURCE_FILE
(
current_function_decl
));
...
...
@@ -4076,6 +4199,7 @@ function_prologue (file, size)
fputs
(
"
\t
.ent
\t
"
,
file
);
assemble_name
(
file
,
current_function_name
);
fputs
(
"
\n
"
,
file
);
assemble_name
(
file
,
current_function_name
);
fputs
(
":
\n
"
,
file
);
...
...
@@ -4112,7 +4236,7 @@ void
mips_expand_prologue
()
{
int
regno
;
int
tsize
;
long
tsize
;
tree
fndecl
=
current_function_decl
;
/* current... is tooo long */
tree
fntype
=
TREE_TYPE
(
fndecl
);
tree
fnargs
=
(
TREE_CODE
(
fntype
)
!=
METHOD_TYPE
)
...
...
@@ -4120,6 +4244,7 @@ mips_expand_prologue ()
:
0
;
tree
next_arg
;
tree
cur_arg
;
rtx
tmp_rtx
=
(
rtx
)
0
;
char
*
arg_name
=
(
char
*
)
0
;
CUMULATIVE_ARGS
args_so_far
;
...
...
@@ -4200,14 +4325,14 @@ mips_expand_prologue ()
if
(
tsize
>
32767
)
{
rtx
tmp_rtx
=
gen_rtx
(
REG
,
SImode
,
MIPS_TEMP1_REGNUM
);
tmp_rtx
=
gen_rtx
(
REG
,
SImode
,
MIPS_TEMP1_REGNUM
);
emit_move_insn
(
tmp_rtx
,
tsize_rtx
);
tsize_rtx
=
tmp_rtx
;
}
emit_insn
(
gen_subsi3
(
stack_pointer_rtx
,
stack_pointer_rtx
,
tsize_rtx
));
save_restore_insns
(
TRUE
);
save_restore_insns
(
TRUE
,
tmp_rtx
,
tsize
,
(
FILE
*
)
0
);
if
(
frame_pointer_needed
)
emit_insn
(
gen_movsi
(
frame_pointer_rtx
,
stack_pointer_rtx
));
...
...
@@ -4228,7 +4353,7 @@ function_epilogue (file, size)
FILE
*
file
;
int
size
;
{
int
tsize
;
long
tsize
;
char
*
sp_str
=
reg_names
[
STACK_POINTER_REGNUM
];
char
*
t1_str
=
reg_names
[
MIPS_TEMP1_REGNUM
];
rtx
epilogue_delay
=
current_function_epilogue_delay_list
;
...
...
@@ -4236,6 +4361,9 @@ function_epilogue (file, size)
int
noepilogue
=
FALSE
;
int
load_nop
=
FALSE
;
int
load_only_r31
;
rtx
tmp_rtx
=
(
rtx
)
0
;
rtx
restore_rtx
;
int
i
;
/* The epilogue does not depend on any registers, but the stack
registers, so we assume that if we have 1 pending nop, it can be
...
...
@@ -4316,13 +4444,16 @@ function_epilogue (file, size)
fprintf
(
file
,
"
\t
.set
\t
noreorder
\n
"
);
if
(
tsize
>
32767
)
fprintf
(
file
,
"
\t
li
\t
%s,%d
\n
"
,
t1_str
,
tsize
);
{
fprintf
(
file
,
"
\t
li
\t
%s,0x%.08lx
\t
# %ld
\n
"
,
t1_str
,
(
long
)
tsize
,
(
long
)
tsize
);
tmp_rtx
=
gen_rtx
(
REG
,
Pmode
,
MIPS_TEMP1_REGNUM
);
}
if
(
frame_pointer_needed
)
fprintf
(
file
,
"
\t
move
\t
%s,%s
\t\t\t
# sp not trusted here
\n
"
,
sp_str
,
reg_names
[
FRAME_POINTER_REGNUM
]);
save_restore
(
file
,
"lw"
,
"ld"
,
"l.d"
);
save_restore
_insns
(
FALSE
,
tmp_rtx
,
tsize
,
file
);
load_only_r31
=
(
current_frame_info
.
mask
==
(
1
<<
31
)
&&
current_frame_info
.
fmask
==
0
);
...
...
@@ -4469,12 +4600,13 @@ function_epilogue (file, size)
void
mips_expand_epilogue
()
{
int
tsize
=
current_frame_info
.
total_size
;
long
tsize
=
current_frame_info
.
total_size
;
rtx
tsize_rtx
=
GEN_INT
(
tsize
);
rtx
tmp_rtx
=
(
rtx
)
0
;
if
(
tsize
>
32767
)
{
rtx
tmp_rtx
=
gen_rtx
(
REG
,
SImode
,
MIPS_TEMP1_REGNUM
);
tmp_rtx
=
gen_rtx
(
REG
,
SImode
,
MIPS_TEMP1_REGNUM
);
emit_move_insn
(
tmp_rtx
,
tsize_rtx
);
tsize_rtx
=
tmp_rtx
;
}
...
...
@@ -4484,7 +4616,7 @@ mips_expand_epilogue ()
if
(
frame_pointer_needed
)
emit_insn
(
gen_movsi
(
stack_pointer_rtx
,
frame_pointer_rtx
));
save_restore_insns
(
FALSE
);
save_restore_insns
(
FALSE
,
tmp_rtx
,
tsize
,
(
FILE
*
)
0
);
emit_insn
(
gen_addsi3
(
stack_pointer_rtx
,
stack_pointer_rtx
,
tsize_rtx
));
}
...
...
gcc/config/mips/mips.h
View file @
7bea35e7
...
...
@@ -126,7 +126,8 @@ extern int arith32_operand ();
extern
int
arith_operand
();
extern
int
cmp_op
();
extern
int
cmp2_op
();
extern
unsigned
long
compute_frame_size
();
extern
long
compute_frame_size
();
extern
int
epilogue_reg_mentioned_p
();
extern
void
expand_block_move
();
extern
int
equality_op
();
extern
int
fcmp_op
();
...
...
@@ -482,7 +483,7 @@ while (0)
/* Print subsidiary information on the compiler version in use. */
#define MIPS_VERSION "[AL 1.1, MM 3
1
]"
#define MIPS_VERSION "[AL 1.1, MM 3
2
]"
#ifndef MACHINE_TYPE
#define MACHINE_TYPE "BSD Mips"
...
...
@@ -1229,6 +1230,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
scratch register set, and not used for passing and returning
arguments and any other information used in the calling sequence
(such as pic). */
#define MIPS_TEMP1_REGNUM (GP_REG_FIRST + 8)
#define MIPS_TEMP2_REGNUM (GP_REG_FIRST + 9)
...
...
@@ -1540,21 +1542,21 @@ extern enum reg_class mips_char_to_class[];
struct
mips_frame_info
{
unsigned
long
total_size
;
/* # bytes that the entire frame takes up */
unsigned
long
var_size
;
/* # bytes that variables take up */
unsigned
long
args_size
;
/* # bytes that outgoing arguments take up */
unsigned
long
extra_size
;
/* # bytes of extra gunk */
unsigned
int
gp_reg_size
;
/* # bytes needed to store gp regs */
unsigned
int
fp_reg_size
;
/* # bytes needed to store fp regs */
unsigned
long
mask
;
/* mask of saved gp registers */
unsigned
long
fmask
;
/* mask of saved fp registers */
long
gp_save_offset
;
/* offset from vfp to store gp registers */
long
fp_save_offset
;
/* offset from vfp to store fp registers */
unsigned
long
gp_sp_offset
;
/* offset from new sp to store gp registers */
unsigned
long
fp_sp_offset
;
/* offset from new sp to store fp registers */
int
initialized
;
/* != 0 if frame size already calculated */
int
num_gp
;
/* number of gp registers saved */
int
num_fp
;
/* number of fp registers saved */
long
total_size
;
/* # bytes that the entire frame takes up */
long
var_size
;
/* # bytes that variables take up */
long
args_size
;
/* # bytes that outgoing arguments take up */
long
extra_size
;
/* # bytes of extra gunk */
int
gp_reg_size
;
/* # bytes needed to store gp regs */
int
fp_reg_size
;
/* # bytes needed to store fp regs */
long
mask
;
/* mask of saved gp registers */
long
fmask
;
/* mask of saved fp registers */
long
gp_save_offset
;
/* offset from vfp to store gp registers */
long
fp_save_offset
;
/* offset from vfp to store fp registers */
long
gp_sp_offset
;
/* offset from new sp to store gp registers */
long
fp_sp_offset
;
/* offset from new sp to store fp registers */
int
initialized
;
/* != 0 if frame size already calculated */
int
num_gp
;
/* number of gp registers saved */
int
num_fp
;
/* number of fp registers saved */
};
extern
struct
mips_frame_info
current_frame_info
;
...
...
@@ -1896,9 +1898,7 @@ typedef struct mips_args {
#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \
(get_attr_dslot (INSN) == DSLOT_NO \
&& get_attr_length (INSN) == 1 \
&& ! reg_mentioned_p (stack_pointer_rtx, PATTERN (INSN)) \
&& ! reg_mentioned_p (frame_pointer_rtx, PATTERN (INSN)) \
&& ! reg_mentioned_p (arg_pointer_rtx, PATTERN (INSN)))
&& ! epilogue_reg_mentioned_p (PATTERN (INSN)))
/* Tell prologue and epilogue if register REGNO should be saved / restored. */
...
...
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