Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
816e7e07
Commit
816e7e07
authored
Apr 09, 2008
by
Matthias Braun
Browse files
- add support for stack alignment on calls
- fix pic trampolines not being generated twice [r19205]
parent
5e7c369c
Changes
11
Hide whitespace changes
Inline
Side-by-side
ir/be/TEMPLATE/bearch_TEMPLATE.c
View file @
816e7e07
...
...
@@ -373,6 +373,7 @@ static TEMPLATE_isa_t TEMPLATE_isa_template = {
&
TEMPLATE_general_purpose_regs
[
REG_SP
],
/* stack pointer register */
&
TEMPLATE_general_purpose_regs
[
REG_BP
],
/* base pointer register */
-
1
,
/* stack direction */
1
,
/* stack alignment for calls */
NULL
,
/* main environment */
7
,
/* costs for a spill instruction */
5
,
/* costs for a reload instruction */
...
...
ir/be/arm/bearch_arm.c
View file @
816e7e07
...
...
@@ -769,6 +769,7 @@ static arm_isa_t arm_isa_template = {
&
arm_gp_regs
[
REG_SP
],
/* stack pointer */
&
arm_gp_regs
[
REG_R11
],
/* base pointer */
-
1
,
/* stack direction */
1
,
/* stack alignment for calls */
NULL
,
/* main environment */
7
,
/* spill costs */
5
,
/* reload costs */
...
...
@@ -972,7 +973,7 @@ static void arm_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_m
// TODO: Activate Omit fp in epilogue
if
(
env
->
flags
.
try_omit_fp
)
{
curr_sp
=
be_new_IncSP
(
env
->
isa
->
sp
,
env
->
irg
,
bl
,
curr_sp
,
BE_STACK_FRAME_SIZE_SHRINK
);
curr_sp
=
be_new_IncSP
(
env
->
isa
->
sp
,
env
->
irg
,
bl
,
curr_sp
,
BE_STACK_FRAME_SIZE_SHRINK
,
0
);
add_irn_dep
(
curr_sp
,
*
mem
);
curr_lr
=
be_new_CopyKeep_single
(
&
arm_reg_classes
[
CLASS_arm_gp
],
env
->
irg
,
bl
,
curr_lr
,
curr_sp
,
get_irn_mode
(
curr_lr
));
...
...
ir/be/be_t.h
View file @
816e7e07
...
...
@@ -31,6 +31,7 @@
#include
"debug.h"
#include
"bitset.h"
#include
"timing.h"
#include
"pmap.h"
#include
"be.h"
#include
"bearch.h"
...
...
@@ -84,7 +85,9 @@ struct be_main_env_t {
arch_code_generator_t
*
cg
;
arch_irn_handler_t
*
phi_handler
;
const
char
*
cup_name
;
pmap
*
ent_trampoline_map
;
ir_type
*
pic_trampolines_type
;
pmap
*
ent_pic_symbol_map
;
ir_type
*
pic_symbols_type
;
};
...
...
ir/be/beabi.c
View file @
816e7e07
...
...
@@ -108,7 +108,7 @@ struct _be_abi_irg_t {
arch_register_req_t
sp_req
;
arch_register_req_t
sp_cls_req
;
DEBUG_ONLY
(
firm_dbg_module_t
*
dbg
;)
/**< The debugging module. */
DEBUG_ONLY
(
firm_dbg_module_t
*
dbg
;)
/**< The debugging module. */
};
static
heights_t
*
ir_heights
;
...
...
@@ -271,7 +271,8 @@ static void be_abi_call_free(be_abi_call_t *call)
and the spills.
*/
static
int
get_stack_entity_offset
(
be_stack_layout_t
*
frame
,
ir_entity
*
ent
,
int
bias
)
static
int
get_stack_entity_offset
(
be_stack_layout_t
*
frame
,
ir_entity
*
ent
,
int
bias
)
{
ir_type
*
t
=
get_entity_owner
(
ent
);
int
ofs
=
get_entity_offset
(
ent
);
...
...
@@ -427,6 +428,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
struct
obstack
*
obst
=
&
env
->
obst
;
int
no_alloc
=
call
->
flags
.
bits
.
frame_is_setup_on_call
;
int
n_res
=
get_method_n_ress
(
call_tp
);
int
do_seq
=
call
->
flags
.
bits
.
store_args_sequential
&&
!
no_alloc
;
ir_node
*
res_proj
=
NULL
;
int
n_reg_params
=
0
;
...
...
@@ -473,10 +475,22 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
}
reg_param_idxs
=
obstack_finish
(
obst
);
/*
* If the stack is decreasing and we do not want to store sequentially,
* or someone else allocated the call frame
* we allocate as much space on the stack all parameters need, by
* moving the stack pointer along the stack's direction.
*
* Note: we also have to do this for stack_size == 0, because we may have
* to adjust stack alignment for the call.
*/
if
(
stack_dir
<
0
&&
!
do_seq
&&
!
no_alloc
)
{
curr_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
curr_sp
,
stack_size
,
1
);
}
/* If there are some parameters which shall be passed on the stack. */
if
(
n_stack_params
>
0
)
{
int
curr_ofs
=
0
;
int
do_seq
=
call
->
flags
.
bits
.
store_args_sequential
&&
!
no_alloc
;
/*
* Reverse list of stack parameters if call arguments are from left to right.
...
...
@@ -492,16 +506,6 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
}
}
/*
* If the stack is decreasing and we do not want to store sequentially,
* or someone else allocated the call frame
* we allocate as much space on the stack all parameters need, by
* moving the stack pointer along the stack's direction.
*/
if
(
stack_dir
<
0
&&
!
do_seq
&&
!
no_alloc
)
{
curr_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
curr_sp
,
stack_size
);
}
curr_mem
=
get_Call_mem
(
irn
);
if
(
!
do_seq
)
{
obstack_ptr_grow
(
obst
,
curr_mem
);
...
...
@@ -523,7 +527,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
*/
if
(
do_seq
)
{
curr_ofs
=
0
;
addr
=
curr_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
curr_sp
,
param_size
+
arg
->
space_before
);
addr
=
curr_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
curr_sp
,
param_size
+
arg
->
space_before
,
0
);
add_irn_dep
(
curr_sp
,
curr_mem
);
}
else
{
...
...
@@ -805,11 +809,10 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
mem_proj
=
new_r_Proj
(
irg
,
bl
,
low_call
,
mode_M
,
pn_be_Call_M_regular
);
keep_alive
(
mem_proj
);
}
/* Clean up the stack frame if we allocated it */
if
(
!
no_alloc
)
{
curr_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
curr_sp
,
-
stack_size
);
}
}
/* Clean up the stack frame or revert alignment fixes if we allocated it */
if
(
!
no_alloc
)
{
curr_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
curr_sp
,
-
stack_size
,
0
);
}
be_abi_call_free
(
call
);
...
...
@@ -836,6 +839,7 @@ static ir_node *adjust_alloc_size(unsigned stack_alignment, ir_node *size,
ir_graph
*
irg
,
ir_node
*
block
,
dbg_info
*
dbg
)
{
if
(
stack_alignment
>
1
)
{
assert
(
is_po2
(
stack_alignment
));
ir_mode
*
mode
=
get_irn_mode
(
size
);
tarval
*
tv
=
new_tarval_from_long
(
stack_alignment
-
1
,
mode
);
ir_node
*
mask
=
new_r_Const
(
irg
,
block
,
mode
,
tv
);
...
...
@@ -918,9 +922,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp
We cannot omit it. */
env
->
call
->
flags
.
bits
.
try_omit_fp
=
0
;
/* FIXME: size must be here round up for the stack alignment, but
this must be transmitted from the backend. */
stack_alignment
=
4
;
stack_alignment
=
env
->
isa
->
stack_alignment
;
size
=
adjust_alloc_size
(
stack_alignment
,
size
,
irg
,
block
,
dbg
);
new_alloc
=
be_new_AddSP
(
env
->
isa
->
sp
,
irg
,
block
,
curr_sp
,
size
);
set_irn_dbg_info
(
new_alloc
,
dbg
);
...
...
@@ -989,10 +991,8 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
size
=
get_Free_size
(
free
);
}
/* FIXME: size must be here round up for the stack alignment, but
this must be transmitted from the backend. */
stack_alignment
=
4
;
size
=
adjust_alloc_size
(
stack_alignment
,
size
,
irg
,
block
,
dbg
);
stack_alignment
=
env
->
isa
->
stack_alignment
;
size
=
adjust_alloc_size
(
stack_alignment
,
size
,
irg
,
block
,
dbg
);
/* The stack pointer will be modified in an unknown manner.
We cannot omit it. */
...
...
@@ -1864,7 +1864,7 @@ static void modify_irg(be_abi_irg_t *env)
/* do the stack allocation BEFORE the barrier, or spill code
might be added before it */
env
->
init_sp
=
be_abi_reg_map_get
(
env
->
regs
,
sp
);
env
->
init_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
env
->
init_sp
,
BE_STACK_FRAME_SIZE_EXPAND
);
env
->
init_sp
=
be_new_IncSP
(
sp
,
irg
,
bl
,
env
->
init_sp
,
BE_STACK_FRAME_SIZE_EXPAND
,
0
);
be_abi_reg_map_set
(
env
->
regs
,
sp
,
env
->
init_sp
);
create_barrier
(
env
,
bl
,
&
mem
,
env
->
regs
,
0
);
...
...
@@ -2015,6 +2015,17 @@ static ir_entity *create_trampoline(be_main_env_t *be, ir_entity *method)
return
ent
;
}
static
ir_entity
*
get_trampoline
(
be_main_env_t
*
env
,
ir_entity
*
method
)
{
ir_entity
*
result
=
pmap_get
(
env
->
ent_trampoline_map
,
method
);
if
(
result
==
NULL
)
{
result
=
create_trampoline
(
env
,
method
);
pmap_insert
(
env
->
ent_trampoline_map
,
method
,
result
);
}
return
result
;
}
static
int
can_address_relative
(
ir_entity
*
entity
)
{
return
get_entity_variability
(
entity
)
==
variability_initialized
...
...
@@ -2058,7 +2069,7 @@ static void fix_pic_symconsts(ir_node *node, void *data)
continue
;
dbgi
=
get_irn_dbg_info
(
pred
);
trampoline
=
create
_trampoline
(
be
,
entity
);
trampoline
=
get
_trampoline
(
be
,
entity
);
trampoline_const
=
new_rd_SymConst_addr_ent
(
dbgi
,
irg
,
mode_P_code
,
trampoline
,
NULL
);
set_irn_n
(
node
,
i
,
trampoline_const
);
continue
;
...
...
@@ -2286,11 +2297,12 @@ void be_abi_fix_stack_nodes(be_abi_irg_t *env)
DEL_ARR_F
(
walker_env
.
sp_nodes
);
}
static
int
process_stack_bias
(
be_abi_irg_t
*
env
,
ir_node
*
bl
,
int
bias
)
static
int
process_stack_bias
(
be_abi_irg_t
*
env
,
ir_node
*
bl
,
int
real_
bias
)
{
const
arch_env_t
*
arch_env
=
env
->
birg
->
main_env
->
arch_env
;
int
omit_fp
=
env
->
call
->
flags
.
bits
.
try_omit_fp
;
ir_node
*
irn
;
int
omit_fp
=
env
->
call
->
flags
.
bits
.
try_omit_fp
;
ir_node
*
irn
;
int
wanted_bias
=
real_bias
;
sched_foreach
(
bl
,
irn
)
{
int
ofs
;
...
...
@@ -2302,34 +2314,59 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias)
*/
ir_entity
*
ent
=
arch_get_frame_entity
(
arch_env
,
irn
);
if
(
ent
)
{
int
bias
=
omit_fp
?
real_bias
:
0
;
int
offset
=
get_stack_entity_offset
(
env
->
frame
,
ent
,
bias
);
arch_set_frame_offset
(
arch_env
,
irn
,
offset
);
DBG
((
env
->
dbg
,
LEVEL_2
,
"%F has offset %d (including bias %d)
\n
"
,
ent
,
offset
,
bias
));
DBG
((
env
->
dbg
,
LEVEL_2
,
"%F has offset %d (including bias %d)
\n
"
,
ent
,
offset
,
bias
));
}
if
(
omit_fp
||
be_is_IncSP
(
irn
))
{
/*
* If the node modifies the stack pointer by a constant offset,
* record that in the bias.
*/
ofs
=
arch_get_sp_bias
(
arch_env
,
irn
);
if
(
be_is_IncSP
(
irn
))
{
if
(
ofs
==
BE_STACK_FRAME_SIZE_EXPAND
)
{
ofs
=
(
int
)
get_type_size_bytes
(
get_irg_frame_type
(
env
->
birg
->
irg
));
be_set_IncSP_offset
(
irn
,
ofs
);
}
else
if
(
ofs
==
BE_STACK_FRAME_SIZE_SHRINK
)
{
ofs
=
-
(
int
)
get_type_size_bytes
(
get_irg_frame_type
(
env
->
birg
->
irg
));
be_set_IncSP_offset
(
irn
,
ofs
);
/*
* If the node modifies the stack pointer by a constant offset,
* record that in the bias.
*/
ofs
=
arch_get_sp_bias
(
arch_env
,
irn
);
if
(
be_is_IncSP
(
irn
))
{
/* fill in real stack frame size */
if
(
ofs
==
BE_STACK_FRAME_SIZE_EXPAND
)
{
ir_type
*
frame_type
=
get_irg_frame_type
(
env
->
birg
->
irg
);
ofs
=
(
int
)
get_type_size_bytes
(
frame_type
);
be_set_IncSP_offset
(
irn
,
ofs
);
}
else
if
(
ofs
==
BE_STACK_FRAME_SIZE_SHRINK
)
{
ir_type
*
frame_type
=
get_irg_frame_type
(
env
->
birg
->
irg
);
ofs
=
-
(
int
)
get_type_size_bytes
(
frame_type
);
be_set_IncSP_offset
(
irn
,
ofs
);
}
else
{
if
(
be_get_IncSP_align
(
irn
))
{
/* patch IncSP to produce an aligned stack pointer */
ir_type
*
between_type
=
env
->
frame
->
between_type
;
int
between_size
=
get_type_size_bytes
(
between_type
);
int
alignment
=
env
->
isa
->
stack_alignment
;
int
delta
=
(
real_bias
+
ofs
+
between_size
)
%
env
->
isa
->
stack_alignment
;
assert
(
ofs
>=
0
);
if
(
delta
>
0
)
{
be_set_IncSP_offset
(
irn
,
ofs
+
alignment
-
delta
);
real_bias
+=
alignment
-
delta
;
}
}
else
{
/* adjust so real_bias corresponds with wanted_bias */
int
delta
=
wanted_bias
-
real_bias
;
assert
(
delta
<=
0
);
if
(
delta
!=
0
)
{
be_set_IncSP_offset
(
irn
,
ofs
+
delta
);
real_bias
+=
delta
;
}
}
}
if
(
omit_fp
)
bias
+=
ofs
;
}
real_bias
+=
ofs
;
wanted_bias
+=
ofs
;
}
return
bias
;
assert
(
real_bias
==
wanted_bias
);
return
real_bias
;
}
/**
...
...
@@ -2337,8 +2374,9 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias)
*/
struct
bias_walk
{
be_abi_irg_t
*
env
;
/**< The ABI irg environment. */
int
start_block_bias
;
/**< The bias at the end of the start block. */
ir_node
*
start_block
;
/**< The start block of the current graph. */
int
start_block_bias
;
/**< The bias at the end of the start block. */
int
between_size
;
ir_node
*
start_block
;
/**< The start block of the current graph. */
};
/**
...
...
@@ -2362,6 +2400,7 @@ void be_abi_fix_stack_bias(be_abi_irg_t *env)
/* Determine the stack bias at the end of the start block. */
bw
.
start_block_bias
=
process_stack_bias
(
env
,
get_irg_start_block
(
irg
),
0
);
bw
.
between_size
=
get_type_size_bytes
(
env
->
frame
->
between_type
);
/* fix the bias is all other blocks */
bw
.
env
=
env
;
...
...
ir/be/bearch_t.h
View file @
816e7e07
...
...
@@ -409,10 +409,11 @@ struct arch_isa_t {
const
arch_isa_if_t
*
impl
;
const
arch_register_t
*
sp
;
/** The stack pointer register. */
const
arch_register_t
*
bp
;
/** The base pointer register. */
const
int
stack_dir
;
/** -1 for decreasing, 1 for increasing. */
int
stack_dir
;
/** -1 for decreasing, 1 for increasing. */
int
stack_alignment
;
/** stack alignment */
const
be_main_env_t
*
main_env
;
/** the be main environment */
const
int
spill_cost
;
/** cost for a be_Spill node */
const
int
reload_cost
;
/** cost for a be_Reload node */
int
spill_cost
;
/** cost for a be_Spill node */
int
reload_cost
;
/** cost for a be_Reload node */
};
#define arch_isa_stack_dir(isa) ((isa)->stack_dir)
...
...
ir/be/bemain.c
View file @
816e7e07
...
...
@@ -251,8 +251,10 @@ static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle)
obstack_init
(
&
env
->
obst
);
env
->
arch_env
=
obstack_alloc
(
&
env
->
obst
,
sizeof
(
env
->
arch_env
[
0
]));
env
->
options
=
&
be_options
;
env
->
ent_trampoline_map
=
pmap_create
();
env
->
pic_trampolines_type
=
new_type_class
(
new_id_from_str
(
"$PIC_TRAMPOLINE_TYPE"
));
env
->
ent_pic_symbol_map
=
pmap_create
();
env
->
pic_symbols_type
=
new_type_struct
(
new_id_from_str
(
"$PIC_SYMBOLS_TYPE"
));
...
...
@@ -286,6 +288,8 @@ static void be_done_env(be_main_env_t *env)
be_phi_handler_free
(
env
->
phi_handler
);
obstack_free
(
&
env
->
obst
,
NULL
);
pmap_destroy
(
env
->
ent_trampoline_map
);
pmap_destroy
(
env
->
ent_pic_symbol_map
);
free_type
(
env
->
pic_trampolines_type
);
free_type
(
env
->
pic_symbols_type
);
}
...
...
ir/be/benode.c
View file @
816e7e07
...
...
@@ -73,8 +73,8 @@ typedef struct {
typedef
struct
{
const
arch_register_t
*
reg
;
be_req_t
req
;
be_req_t
in_req
;
be_req_t
req
;
be_req_t
in_req
;
}
be_reg_data_t
;
/** The generic be nodes attribute type. */
...
...
@@ -92,28 +92,30 @@ typedef struct {
/** The be_IncSP attribute type. */
typedef
struct
{
be_node_attr_t
node_attr
;
/**< base attributes of every be node. */
int
offset
;
/**< The offset by which the stack shall be expanded/shrinked. */
int
offset
;
/**< The offset by which the stack shall be expanded/shrinked. */
int
align
;
/**< wether stack should be aligned after the
IncSP */
}
be_incsp_attr_t
;
/** The be_Frame attribute type. */
typedef
struct
{
be_node_attr_t
node_attr
;
/**< base attributes of every be node. */
ir_entity
*
ent
;
int
offset
;
be_node_attr_t
node_attr
;
/**< base attributes of every be node. */
ir_entity
*
ent
;
int
offset
;
}
be_frame_attr_t
;
/** The be_Call attribute type. */
typedef
struct
{
be_node_attr_t
node_attr
;
/**< base attributes of every be node. */
ir_entity
*
ent
;
/**< The called entity if this is a static call. */
unsigned
pop
;
ir_type
*
call_tp
;
/**< The call type, copied from the original Call node. */
be_node_attr_t
node_attr
;
/**< base attributes of every be node. */
ir_entity
*
ent
;
/**< The called entity if this is a static call. */
unsigned
pop
;
ir_type
*
call_tp
;
/**< The call type, copied from the original Call node. */
}
be_call_attr_t
;
typedef
struct
{
be_node_attr_t
node_attr
;
/**< base attributes of every be node. */
ir_entity
**
in_entities
;
ir_entity
**
out_entities
;
be_node_attr_t
node_attr
;
/**< base attributes of every be node. */
ir_entity
**
in_entities
;
ir_entity
**
out_entities
;
}
be_memperm_attr_t
;
ir_op
*
op_be_Spill
;
...
...
@@ -722,16 +724,19 @@ int be_Return_append_node(ir_node *ret, ir_node *node)
return
pos
;
}
ir_node
*
be_new_IncSP
(
const
arch_register_t
*
sp
,
ir_graph
*
irg
,
ir_node
*
bl
,
ir_node
*
old_sp
,
int
offset
)
ir_node
*
be_new_IncSP
(
const
arch_register_t
*
sp
,
ir_graph
*
irg
,
ir_node
*
bl
,
ir_node
*
old_sp
,
int
offset
,
int
align
)
{
be_incsp_attr_t
*
a
;
ir_node
*
irn
;
ir_node
*
in
[
1
];
in
[
0
]
=
old_sp
;
irn
=
new_ir_node
(
NULL
,
irg
,
bl
,
op_be_IncSP
,
sp
->
reg_class
->
mode
,
sizeof
(
in
)
/
sizeof
(
in
[
0
]),
in
);
irn
=
new_ir_node
(
NULL
,
irg
,
bl
,
op_be_IncSP
,
sp
->
reg_class
->
mode
,
sizeof
(
in
)
/
sizeof
(
in
[
0
]),
in
);
a
=
init_node_attr
(
irn
,
1
);
a
->
offset
=
offset
;
a
->
align
=
align
;
be_node_set_flags
(
irn
,
-
1
,
arch_irn_flags_ignore
|
arch_irn_flags_modify_sp
);
...
...
@@ -1110,6 +1115,13 @@ int be_get_IncSP_offset(const ir_node *irn)
return
a
->
offset
;
}
int
be_get_IncSP_align
(
const
ir_node
*
irn
)
{
const
be_incsp_attr_t
*
a
=
get_irn_attr_const
(
irn
);
assert
(
be_is_IncSP
(
irn
));
return
a
->
align
;
}
ir_node
*
be_spill
(
const
arch_env_t
*
arch_env
,
ir_node
*
block
,
ir_node
*
irn
)
{
ir_graph
*
irg
=
get_irn_irg
(
block
);
...
...
ir/be/benode_t.h
View file @
816e7e07
...
...
@@ -259,7 +259,8 @@ ir_node *be_new_SubSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_
* @return A new stack pointer increment/decrement node.
* @note This node sets a register constraint to the @p sp register on its output.
*/
ir_node
*
be_new_IncSP
(
const
arch_register_t
*
sp
,
ir_graph
*
irg
,
ir_node
*
bl
,
ir_node
*
old_sp
,
int
offset
);
ir_node
*
be_new_IncSP
(
const
arch_register_t
*
sp
,
ir_graph
*
irg
,
ir_node
*
bl
,
ir_node
*
old_sp
,
int
offset
,
int
align
);
/** Returns the previous node that computes the stack pointer. */
ir_node
*
be_get_IncSP_pred
(
ir_node
*
incsp
);
...
...
@@ -277,6 +278,7 @@ void be_set_IncSP_offset(ir_node *irn, int offset);
/** Gets the offset from a IncSP node. */
int
be_get_IncSP_offset
(
const
ir_node
*
irn
);
int
be_get_IncSP_align
(
const
ir_node
*
irn
);
/** Gets the call entity or NULL if this is no static call. */
ir_entity
*
be_Call_get_entity
(
const
ir_node
*
call
);
...
...
ir/be/ia32/bearch_ia32.c
View file @
816e7e07
...
...
@@ -377,22 +377,23 @@ static void ia32_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent
set_ia32_frame_ent
(
irn
,
ent
);
}
static
void
ia32_set_frame_offset
(
const
void
*
self
,
ir_node
*
irn
,
int
bias
)
{
static
void
ia32_set_frame_offset
(
const
void
*
self
,
ir_node
*
irn
,
int
bias
)
{
const
ia32_irn_ops_t
*
ops
=
self
;
if
(
get_ia32_frame_ent
(
irn
))
{
if
(
is_ia32_Pop
(
irn
))
{
int
omit_fp
=
be_abi_omit_fp
(
ops
->
cg
->
birg
->
abi
);
if
(
omit_fp
)
{
/* Pop nodes modify the stack pointer before calculating the destination
* address, so fix this here
*/
bias
-=
4
;
}
}
if
(
get_ia32_frame_ent
(
irn
)
==
NULL
)
return
;
add_ia32_am_offs_int
(
irn
,
bias
);
if
(
is_ia32_Pop
(
irn
))
{
int
omit_fp
=
be_abi_omit_fp
(
ops
->
cg
->
birg
->
abi
);
if
(
omit_fp
)
{
/* Pop nodes modify the stack pointer before calculating the
* destination address, so fix this here
*/
bias
-=
4
;
}
}
add_ia32_am_offs_int
(
irn
,
bias
);
}
static
int
ia32_get_sp_bias
(
const
void
*
self
,
const
ir_node
*
node
)
...
...
@@ -496,7 +497,7 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_
if
(
env
->
flags
.
try_omit_fp
)
{
/* simply remove the stack frame here */
curr_sp
=
be_new_IncSP
(
env
->
isa
->
sp
,
env
->
irg
,
bl
,
curr_sp
,
BE_STACK_FRAME_SIZE_SHRINK
);
curr_sp
=
be_new_IncSP
(
env
->
isa
->
sp
,
env
->
irg
,
bl
,
curr_sp
,
BE_STACK_FRAME_SIZE_SHRINK
,
0
);
add_irn_dep
(
curr_sp
,
*
mem
);
}
else
{
const
ia32_isa_t
*
isa
=
(
ia32_isa_t
*
)
env
->
isa
;
...
...
@@ -1632,6 +1633,7 @@ static ia32_isa_t ia32_isa_template = {
&
ia32_gp_regs
[
REG_ESP
],
/* stack pointer register */
&
ia32_gp_regs
[
REG_EBP
],
/* base pointer register */
-
1
,
/* stack direction */
16
,
/* stack alignment */
NULL
,
/* main environment */
7
,
/* costs for a spill instruction */
5
,
/* costs for a reload instruction */
...
...
@@ -2127,6 +2129,8 @@ static lc_opt_enum_int_var_t gas_var = {
static
const
lc_opt_table_entry_t
ia32_options
[]
=
{
LC_OPT_ENT_ENUM_INT
(
"gasmode"
,
"set the GAS compatibility mode"
,
&
gas_var
),
LC_OPT_ENT_INT
(
"stackalign"
,
"set stack alignment for calls"
,
&
ia32_isa_template
.
arch_isa
.
stack_alignment
),
LC_OPT_LAST
};
...
...
ir/be/mips/bearch_mips.c
View file @
816e7e07
...
...
@@ -606,6 +606,7 @@ static mips_isa_t mips_isa_template = {
&
mips_gp_regs
[
REG_SP
],
&
mips_gp_regs
[
REG_FP
],
-
1
,
/* stack direction */
1
,
/* stack alignment for calls */
NULL
,
/* main environment */
7
,
/* spill costs */
5
,
/* reload costs */
...
...
ir/be/ppc32/bearch_ppc32.c
View file @
816e7e07
...
...
@@ -649,6 +649,7 @@ static ppc32_isa_t ppc32_isa_template = {
&
ppc32_gp_regs
[
REG_R1
],
/* stack pointer */
&
ppc32_gp_regs
[
REG_R31
],
/* base pointer */
-
1
,
/* stack is decreasing */
1
,
/* call stack alignment */
NULL
,
/* main environment */
7
,
/* spill costs */
5
,
/* reload costs */
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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