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)
...
@@ -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
/* Return the bytes needed to compute the frame pointer from the current
stack pointer.
stack pointer.
...
@@ -3785,22 +3851,22 @@ mips_output_float (stream, value)
...
@@ -3785,22 +3851,22 @@ mips_output_float (stream, value)
*/
*/
unsigned
long
long
compute_frame_size
(
size
)
compute_frame_size
(
size
)
int
size
;
/* # of var. bytes allocated */
int
size
;
/* # of var. bytes allocated */
{
{
int
regno
;
int
regno
;
unsigned
long
total_size
;
/* # bytes that the entire frame takes up */
long
total_size
;
/* # bytes that the entire frame takes up */
unsigned
long
var_size
;
/* # bytes that variables take up */
long
var_size
;
/* # bytes that variables take up */
unsigned
long
args_size
;
/* # bytes that outgoing arguments take up */
long
args_size
;
/* # bytes that outgoing arguments take up */
unsigned
long
extra_size
;
/* # extra bytes */
long
extra_size
;
/* # extra bytes */
unsigned
int
gp_reg_rounded
;
/* # bytes needed to store gp after rounding */
long
gp_reg_rounded
;
/* # bytes needed to store gp after rounding */
unsigned
int
gp_reg_size
;
/* # bytes needed to store gp regs */
long
gp_reg_size
;
/* # bytes needed to store gp regs */
unsigned
int
fp_reg_size
;
/* # bytes needed to store fp regs */
long
fp_reg_size
;
/* # bytes needed to store fp regs */
unsigned
long
mask
;
/* mask of saved gp registers */
long
mask
;
/* mask of saved gp registers */
unsigned
long
fmask
;
/* mask of saved fp registers */
long
fmask
;
/* mask of saved fp registers */
int
fp_inc
;
/* 1 or 2 depending on the size of fp regs */
int
fp_inc
;
/* 1 or 2 depending on the size of fp regs */
int
fp_bits
;
/* bitmask to use for each fp register */
long
fp_bits
;
/* bitmask to use for each fp register */
gp_reg_size
=
0
;
gp_reg_size
=
0
;
fp_reg_size
=
0
;
fp_reg_size
=
0
;
...
@@ -3826,7 +3892,7 @@ compute_frame_size (size)
...
@@ -3826,7 +3892,7 @@ compute_frame_size (size)
if
(
MUST_SAVE_REGISTER
(
regno
))
if
(
MUST_SAVE_REGISTER
(
regno
))
{
{
gp_reg_size
+=
UNITS_PER_WORD
;
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)
...
@@ -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
Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg)
save_restore
(
file
,
gp_op
,
gp_2word_op
,
fp_op
)
is not modified within save_restore_insns. */
FILE
*
file
;
/* stream to write to */
char
*
gp_op
;
/* operation to do on gp registers */
#define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0)
char
*
gp_2word_op
;
/* 2 word op to do on gp registers */
char
*
fp_op
;
/* operation to do on fp registers */
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
;
int
regno
;
unsigned
long
mask
=
current_frame_info
.
mask
;
rtx
base_reg_rtx
;
unsigned
long
fmask
=
current_frame_info
.
fmask
;
long
base_offset
;
unsigned
long
gp_offset
;
long
gp_offset
;
unsigned
long
fp_offset
;
long
fp_offset
;
unsigned
long
min_offset
;
long
end_offset
;
char
*
base_reg
;
if
(
frame_pointer_needed
&&
!
BITSET_P
(
mask
,
FRAME_POINTER_REGNUM
-
GP_REG_FIRST
))
abort
();
if
(
mask
==
0
&&
fmask
==
0
)
if
(
mask
==
0
&&
fmask
==
0
)
return
;
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
/* Save registers starting from high to low. The debuggers prefer
at least the return register be stored at func+4, and also it
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
allows us not to need a nop in the epilog if at least one
register is reloaded in addition to return address. */
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
--
)
/* Pick which pointer to use as a base register. For small
{
frames, just use the stack pointer. Otherwise, use a
if
((
mask
&
(
1L
<<
(
regno
-
GP_REG_FIRST
)))
!=
0
temporary register. Save 2 cycles if the save area is near
||
(
regno
==
FRAME_POINTER_REGNUM
&&
frame_pointer_needed
))
the end of a large frame, by reusing the constant created in
{
the prologue/epilogue to adjust the stack frame. */
fprintf
(
file
,
"
\t
%s
\t
%s,%d(%s)
\n
"
,
gp_op
,
reg_names
[
regno
],
gp_offset
,
base_reg
);
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
)
else
if
(
large_reg
!=
(
rtx
)
0
{
&&
(((
unsigned
long
)(
large_offset
-
gp_offset
))
<
32768
)
int
fp_inc
=
(
TARGET_FLOAT64
)
?
1
:
2
;
&&
(((
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
"
,
emit_move_insn
(
base_reg_rtx
,
GEN_INT
(
gp_offset
));
fp_op
,
reg_names
[
regno
],
fp_offset
,
base_reg
);
emit_insn
(
gen_addsi3
(
base_reg_rtx
,
base_reg_rtx
,
stack_pointer_rtx
));
fp_offset
-=
2
*
UNITS_PER_WORD
;
}
}
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
--
)
for
(
regno
=
GP_REG_LAST
;
regno
>=
GP_REG_FIRST
;
regno
--
)
{
{
if
((
mask
&
(
1L
<<
(
regno
-
GP_REG_FIRST
)))
!=
0
if
(
BITSET_P
(
mask
,
regno
-
GP_REG_FIRST
))
||
(
regno
==
FRAME_POINTER_REGNUM
&&
frame_pointer_needed
))
{
{
rtx
reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
regno
);
if
(
file
==
(
FILE
*
)
0
)
rtx
mem_rtx
=
gen_rtx
(
MEM
,
Pmode
,
{
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
rtx
reg_rtx
=
gen_rtx
(
REG
,
Pmode
,
regno
);
GEN_INT
(
gp_offset
)));
rtx
mem_rtx
=
gen_rtx
(
MEM
,
Pmode
,
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
GEN_INT
(
gp_offset
-
base_offset
)));
if
(
store_p
)
if
(
store_p
)
emit_move_insn
(
mem_rtx
,
reg_rtx
);
emit_move_insn
(
mem_rtx
,
reg_rtx
);
else
emit_move_insn
(
reg_rtx
,
mem_rtx
);
}
else
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
;
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
)
if
(
fmask
)
{
{
int
fp_inc
=
(
TARGET_FLOAT64
)
?
1
:
2
;
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
)
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
);
if
(
file
==
(
FILE
*
)
0
)
rtx
mem_rtx
=
gen_rtx
(
MEM
,
DFmode
,
{
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
rtx
reg_rtx
=
gen_rtx
(
REG
,
DFmode
,
regno
);
GEN_INT
(
fp_offset
)));
rtx
mem_rtx
=
gen_rtx
(
MEM
,
DFmode
,
gen_rtx
(
PLUS
,
Pmode
,
base_reg_rtx
,
GEN_INT
(
fp_offset
-
base_offset
)));
if
(
store_p
)
if
(
store_p
)
emit_move_insn
(
mem_rtx
,
reg_rtx
);
emit_move_insn
(
mem_rtx
,
reg_rtx
);
else
emit_move_insn
(
reg_rtx
,
mem_rtx
);
}
else
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
;
fp_offset
-=
2
*
UNITS_PER_WORD
;
}
}
...
@@ -4065,7 +4188,7 @@ function_prologue (file, size)
...
@@ -4065,7 +4188,7 @@ function_prologue (file, size)
FILE
*
file
;
FILE
*
file
;
int
size
;
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
));
ASM_OUTPUT_SOURCE_FILENAME
(
file
,
DECL_SOURCE_FILE
(
current_function_decl
));
...
@@ -4076,6 +4199,7 @@ function_prologue (file, size)
...
@@ -4076,6 +4199,7 @@ function_prologue (file, size)
fputs
(
"
\t
.ent
\t
"
,
file
);
fputs
(
"
\t
.ent
\t
"
,
file
);
assemble_name
(
file
,
current_function_name
);
assemble_name
(
file
,
current_function_name
);
fputs
(
"
\n
"
,
file
);
fputs
(
"
\n
"
,
file
);
assemble_name
(
file
,
current_function_name
);
assemble_name
(
file
,
current_function_name
);
fputs
(
":
\n
"
,
file
);
fputs
(
":
\n
"
,
file
);
...
@@ -4112,7 +4236,7 @@ void
...
@@ -4112,7 +4236,7 @@ void
mips_expand_prologue
()
mips_expand_prologue
()
{
{
int
regno
;
int
regno
;
int
tsize
;
long
tsize
;
tree
fndecl
=
current_function_decl
;
/* current... is tooo long */
tree
fndecl
=
current_function_decl
;
/* current... is tooo long */
tree
fntype
=
TREE_TYPE
(
fndecl
);
tree
fntype
=
TREE_TYPE
(
fndecl
);
tree
fnargs
=
(
TREE_CODE
(
fntype
)
!=
METHOD_TYPE
)
tree
fnargs
=
(
TREE_CODE
(
fntype
)
!=
METHOD_TYPE
)
...
@@ -4120,6 +4244,7 @@ mips_expand_prologue ()
...
@@ -4120,6 +4244,7 @@ mips_expand_prologue ()
:
0
;
:
0
;
tree
next_arg
;
tree
next_arg
;
tree
cur_arg
;
tree
cur_arg
;
rtx
tmp_rtx
=
(
rtx
)
0
;
char
*
arg_name
=
(
char
*
)
0
;
char
*
arg_name
=
(
char
*
)
0
;
CUMULATIVE_ARGS
args_so_far
;
CUMULATIVE_ARGS
args_so_far
;
...
@@ -4200,14 +4325,14 @@ mips_expand_prologue ()
...
@@ -4200,14 +4325,14 @@ mips_expand_prologue ()
if
(
tsize
>
32767
)
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
);
emit_move_insn
(
tmp_rtx
,
tsize_rtx
);
tsize_rtx
=
tmp_rtx
;
tsize_rtx
=
tmp_rtx
;
}
}
emit_insn
(
gen_subsi3
(
stack_pointer_rtx
,
stack_pointer_rtx
,
tsize_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
)
if
(
frame_pointer_needed
)
emit_insn
(
gen_movsi
(
frame_pointer_rtx
,
stack_pointer_rtx
));
emit_insn
(
gen_movsi
(
frame_pointer_rtx
,
stack_pointer_rtx
));
...
@@ -4228,7 +4353,7 @@ function_epilogue (file, size)
...
@@ -4228,7 +4353,7 @@ function_epilogue (file, size)
FILE
*
file
;
FILE
*
file
;
int
size
;
int
size
;
{
{
int
tsize
;
long
tsize
;
char
*
sp_str
=
reg_names
[
STACK_POINTER_REGNUM
];
char
*
sp_str
=
reg_names
[
STACK_POINTER_REGNUM
];
char
*
t1_str
=
reg_names
[
MIPS_TEMP1_REGNUM
];
char
*
t1_str
=
reg_names
[
MIPS_TEMP1_REGNUM
];
rtx
epilogue_delay
=
current_function_epilogue_delay_list
;
rtx
epilogue_delay
=
current_function_epilogue_delay_list
;
...
@@ -4236,6 +4361,9 @@ function_epilogue (file, size)
...
@@ -4236,6 +4361,9 @@ function_epilogue (file, size)
int
noepilogue
=
FALSE
;
int
noepilogue
=
FALSE
;
int
load_nop
=
FALSE
;
int
load_nop
=
FALSE
;
int
load_only_r31
;
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
/* 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
registers, so we assume that if we have 1 pending nop, it can be
...
@@ -4316,13 +4444,16 @@ function_epilogue (file, size)
...
@@ -4316,13 +4444,16 @@ function_epilogue (file, size)
fprintf
(
file
,
"
\t
.set
\t
noreorder
\n
"
);
fprintf
(
file
,
"
\t
.set
\t
noreorder
\n
"
);
if
(
tsize
>
32767
)
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
)
if
(
frame_pointer_needed
)
fprintf
(
file
,
"
\t
move
\t
%s,%s
\t\t\t
# sp not trusted here
\n
"
,
fprintf
(
file
,
"
\t
move
\t
%s,%s
\t\t\t
# sp not trusted here
\n
"
,
sp_str
,
reg_names
[
FRAME_POINTER_REGNUM
]);
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
)
load_only_r31
=
(
current_frame_info
.
mask
==
(
1
<<
31
)
&&
current_frame_info
.
fmask
==
0
);
&&
current_frame_info
.
fmask
==
0
);
...
@@ -4469,12 +4600,13 @@ function_epilogue (file, size)
...
@@ -4469,12 +4600,13 @@ function_epilogue (file, size)
void
void
mips_expand_epilogue
()
mips_expand_epilogue
()
{
{
int
tsize
=
current_frame_info
.
total_size
;
long
tsize
=
current_frame_info
.
total_size
;
rtx
tsize_rtx
=
GEN_INT
(
tsize
);
rtx
tsize_rtx
=
GEN_INT
(
tsize
);
rtx
tmp_rtx
=
(
rtx
)
0
;
if
(
tsize
>
32767
)
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
);
emit_move_insn
(
tmp_rtx
,
tsize_rtx
);
tsize_rtx
=
tmp_rtx
;
tsize_rtx
=
tmp_rtx
;
}
}
...
@@ -4484,7 +4616,7 @@ mips_expand_epilogue ()
...
@@ -4484,7 +4616,7 @@ mips_expand_epilogue ()
if
(
frame_pointer_needed
)
if
(
frame_pointer_needed
)
emit_insn
(
gen_movsi
(
stack_pointer_rtx
,
frame_pointer_rtx
));
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
));
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 ();
...
@@ -126,7 +126,8 @@ extern int arith32_operand ();
extern
int
arith_operand
();
extern
int
arith_operand
();
extern
int
cmp_op
();
extern
int
cmp_op
();
extern
int
cmp2_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
void
expand_block_move
();
extern
int
equality_op
();
extern
int
equality_op
();
extern
int
fcmp_op
();
extern
int
fcmp_op
();
...
@@ -482,7 +483,7 @@ while (0)
...
@@ -482,7 +483,7 @@ while (0)
/* Print subsidiary information on the compiler version in use. */
/* 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
#ifndef MACHINE_TYPE
#define MACHINE_TYPE "BSD Mips"
#define MACHINE_TYPE "BSD Mips"
...
@@ -1229,6 +1230,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
...
@@ -1229,6 +1230,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
scratch register set, and not used for passing and returning
scratch register set, and not used for passing and returning
arguments and any other information used in the calling sequence
arguments and any other information used in the calling sequence
(such as pic). */
(such as pic). */
#define MIPS_TEMP1_REGNUM (GP_REG_FIRST + 8)
#define MIPS_TEMP1_REGNUM (GP_REG_FIRST + 8)
#define MIPS_TEMP2_REGNUM (GP_REG_FIRST + 9)
#define MIPS_TEMP2_REGNUM (GP_REG_FIRST + 9)
...
@@ -1540,21 +1542,21 @@ extern enum reg_class mips_char_to_class[];
...
@@ -1540,21 +1542,21 @@ extern enum reg_class mips_char_to_class[];
struct
mips_frame_info
struct
mips_frame_info
{
{
unsigned
long
total_size
;
/* # bytes that the entire frame takes up */
long
total_size
;
/* # bytes that the entire frame takes up */
unsigned
long
var_size
;
/* # bytes that variables take up */
long
var_size
;
/* # bytes that variables take up */
unsigned
long
args_size
;
/* # bytes that outgoing arguments take up */
long
args_size
;
/* # bytes that outgoing arguments take up */
unsigned
long
extra_size
;
/* # bytes of extra gunk */
long
extra_size
;
/* # bytes of extra gunk */
unsigned
int
gp_reg_size
;
/* # bytes needed to store gp regs */
int
gp_reg_size
;
/* # bytes needed to store gp regs */
unsigned
int
fp_reg_size
;
/* # bytes needed to store fp regs */
int
fp_reg_size
;
/* # bytes needed to store fp regs */
unsigned
long
mask
;
/* mask of saved gp registers */
long
mask
;
/* mask of saved gp registers */
unsigned
long
fmask
;
/* mask of saved fp registers */
long
fmask
;
/* mask of saved fp registers */
long
gp_save_offset
;
/* offset from vfp to store gp registers */
long
gp_save_offset
;
/* offset from vfp to store gp registers */
long
fp_save_offset
;
/* offset from vfp to store fp 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 */
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 */
long
fp_sp_offset
;
/* offset from new sp to store fp registers */
int
initialized
;
/* != 0 if frame size already calculated */
int
initialized
;
/* != 0 if frame size already calculated */
int
num_gp
;
/* number of gp registers saved */
int
num_gp
;
/* number of gp registers saved */
int
num_fp
;
/* number of fp registers saved */
int
num_fp
;
/* number of fp registers saved */
};
};
extern
struct
mips_frame_info
current_frame_info
;
extern
struct
mips_frame_info
current_frame_info
;
...
@@ -1896,9 +1898,7 @@ typedef struct mips_args {
...
@@ -1896,9 +1898,7 @@ typedef struct mips_args {
#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \
#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \
(get_attr_dslot (INSN) == DSLOT_NO \
(get_attr_dslot (INSN) == DSLOT_NO \
&& get_attr_length (INSN) == 1 \
&& get_attr_length (INSN) == 1 \
&& ! reg_mentioned_p (stack_pointer_rtx, PATTERN (INSN)) \
&& ! epilogue_reg_mentioned_p (PATTERN (INSN)))
&& ! reg_mentioned_p (frame_pointer_rtx, PATTERN (INSN)) \
&& ! reg_mentioned_p (arg_pointer_rtx, PATTERN (INSN)))
/* Tell prologue and epilogue if register REGNO should be saved / restored. */
/* 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