Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
12b6cd69
Commit
12b6cd69
authored
Jan 09, 2013
by
Matthias Braun
Browse files
amd64: fix stack setup/destroy logic
parent
60a4bc30
Changes
4
Hide whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_emitter.c
View file @
12b6cd69
...
@@ -565,9 +565,20 @@ static void emit_be_IncSP(const ir_node *node)
...
@@ -565,9 +565,20 @@ static void emit_be_IncSP(const ir_node *node)
return
;
return
;
if
(
offs
>
0
)
{
if
(
offs
>
0
)
{
amd64_emitf
(
node
,
"sub
,
$%d, %D0"
,
offs
);
amd64_emitf
(
node
,
"sub
q
$%d, %D0"
,
offs
);
}
else
{
}
else
{
amd64_emitf
(
node
,
"add, $%d, %D0"
,
-
offs
);
amd64_emitf
(
node
,
"addq $%d, %D0"
,
-
offs
);
}
}
static
void
emit_be_Start
(
const
ir_node
*
node
)
{
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
size
=
get_type_size_bytes
(
frame_type
);
if
(
size
>
0
)
{
amd64_emitf
(
node
,
"subq $%u, %%rsp"
,
size
);
}
}
}
}
...
@@ -576,6 +587,14 @@ static void emit_be_IncSP(const ir_node *node)
...
@@ -576,6 +587,14 @@ static void emit_be_IncSP(const ir_node *node)
*/
*/
static
void
emit_be_Return
(
const
ir_node
*
node
)
static
void
emit_be_Return
(
const
ir_node
*
node
)
{
{
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
size
=
get_type_size_bytes
(
frame_type
);
if
(
size
>
0
)
{
amd64_emitf
(
node
,
"addq $%u, %%rsp"
,
size
);
}
be_emit_cstring
(
"
\t
ret"
);
be_emit_cstring
(
"
\t
ret"
);
be_emit_finish_line_gas
(
node
);
be_emit_finish_line_gas
(
node
);
}
}
...
@@ -603,10 +622,10 @@ static void amd64_register_emitters(void)
...
@@ -603,10 +622,10 @@ static void amd64_register_emitters(void)
be_set_emitter
(
op_be_IncSP
,
emit_be_IncSP
);
be_set_emitter
(
op_be_IncSP
,
emit_be_IncSP
);
be_set_emitter
(
op_be_Perm
,
emit_be_Perm
);
be_set_emitter
(
op_be_Perm
,
emit_be_Perm
);
be_set_emitter
(
op_be_Return
,
emit_be_Return
);
be_set_emitter
(
op_be_Return
,
emit_be_Return
);
be_set_emitter
(
op_be_Start
,
emit_be_Start
);
be_set_emitter
(
op_Phi
,
be_emit_nothing
);
be_set_emitter
(
op_Phi
,
be_emit_nothing
);
be_set_emitter
(
op_be_Keep
,
be_emit_nothing
);
be_set_emitter
(
op_be_Keep
,
be_emit_nothing
);
be_set_emitter
(
op_be_Start
,
be_emit_nothing
);
}
}
/**
/**
...
...
ir/be/amd64/amd64_transform.c
View file @
12b6cd69
...
@@ -425,6 +425,20 @@ static ir_node *gen_be_FrameAddr(ir_node *node)
...
@@ -425,6 +425,20 @@ static ir_node *gen_be_FrameAddr(ir_node *node)
return
new_node
;
return
new_node
;
}
}
static
ir_node
*
gen_be_Start
(
ir_node
*
node
)
{
ir_node
*
new_node
=
be_duplicate_node
(
node
);
be_start_set_setup_stackframe
(
new_node
,
true
);
return
new_node
;
}
static
ir_node
*
gen_be_Return
(
ir_node
*
node
)
{
ir_node
*
new_node
=
be_duplicate_node
(
node
);
be_return_set_destroy_stackframe
(
new_node
,
true
);
return
new_node
;
}
/* Boilerplate code for transformation: */
/* Boilerplate code for transformation: */
static
void
amd64_register_transformers
(
void
)
static
void
amd64_register_transformers
(
void
)
...
@@ -445,6 +459,8 @@ static void amd64_register_transformers(void)
...
@@ -445,6 +459,8 @@ static void amd64_register_transformers(void)
be_set_transform_function
(
op_Shrs
,
gen_Shrs
);
be_set_transform_function
(
op_Shrs
,
gen_Shrs
);
be_set_transform_function
(
op_be_Call
,
gen_be_Call
);
be_set_transform_function
(
op_be_Call
,
gen_be_Call
);
be_set_transform_function
(
op_be_FrameAddr
,
gen_be_FrameAddr
);
be_set_transform_function
(
op_be_FrameAddr
,
gen_be_FrameAddr
);
be_set_transform_function
(
op_be_Return
,
gen_be_Return
);
be_set_transform_function
(
op_be_Start
,
gen_be_Start
);
be_set_transform_function
(
op_Conv
,
gen_Conv
);
be_set_transform_function
(
op_Conv
,
gen_Conv
);
be_set_transform_function
(
op_Jmp
,
gen_Jmp
);
be_set_transform_function
(
op_Jmp
,
gen_Jmp
);
be_set_transform_function
(
op_Switch
,
gen_Switch
);
be_set_transform_function
(
op_Switch
,
gen_Switch
);
...
...
ir/be/benode.c
View file @
12b6cd69
...
@@ -50,12 +50,18 @@ typedef struct be_node_attr_t {
...
@@ -50,12 +50,18 @@ typedef struct be_node_attr_t {
except_attr
exc
;
except_attr
exc
;
}
be_node_attr_t
;
}
be_node_attr_t
;
typedef
struct
{
be_node_attr_t
base
;
bool
setup_stackframe
;
/**< set stackframe up */
}
be_start_attr_t
;
/** The be_Return nodes attribute type. */
/** The be_Return nodes attribute type. */
typedef
struct
{
typedef
struct
{
be_node_attr_t
base
;
be_node_attr_t
base
;
int
num_ret_vals
;
/**< number of return values */
int
num_ret_vals
;
/**< number of return values */
unsigned
pop
;
/**< number of bytes that should be popped */
unsigned
pop
;
/**< number of bytes that should be popped */
int
emit_pop
;
/**< if set, emit pop bytes, even if pop = 0 */
int
emit_pop
;
/**< if set, emit pop bytes, even if pop = 0 */
bool
destroy_stackframe
;
/**< if set destroys the stackframe */
}
be_return_attr_t
;
}
be_return_attr_t
;
/** The be_IncSP attribute type. */
/** The be_IncSP attribute type. */
...
@@ -536,6 +542,13 @@ ir_node *be_new_Return(dbg_info *const dbg, ir_node *const block, int const n_re
...
@@ -536,6 +542,13 @@ ir_node *be_new_Return(dbg_info *const dbg, ir_node *const block, int const n_re
return
res
;
return
res
;
}
}
void
be_return_set_destroy_stackframe
(
ir_node
*
node
,
bool
value
)
{
be_return_attr_t
*
attr
=
(
be_return_attr_t
*
)
get_irn_generic_attr
(
node
);
assert
(
be_is_Return
(
node
));
attr
->
destroy_stackframe
=
value
;
}
int
be_Return_get_n_rets
(
const
ir_node
*
ret
)
int
be_Return_get_n_rets
(
const
ir_node
*
ret
)
{
{
const
be_return_attr_t
*
a
=
(
const
be_return_attr_t
*
)
get_irn_generic_attr_const
(
ret
);
const
be_return_attr_t
*
a
=
(
const
be_return_attr_t
*
)
get_irn_generic_attr_const
(
ret
);
...
@@ -650,6 +663,13 @@ ir_node *be_new_Start(dbg_info *dbgi, ir_node *bl, int n_outs)
...
@@ -650,6 +663,13 @@ ir_node *be_new_Start(dbg_info *dbgi, ir_node *bl, int n_outs)
return
res
;
return
res
;
}
}
void
be_start_set_setup_stackframe
(
ir_node
*
node
,
bool
value
)
{
be_start_attr_t
*
attr
=
(
be_start_attr_t
*
)
get_irn_generic_attr
(
node
);
assert
(
be_is_Start
(
node
));
attr
->
setup_stackframe
=
value
;
}
ir_node
*
be_new_FrameAddr
(
const
arch_register_class_t
*
cls_frame
,
ir_node
*
bl
,
ir_node
*
frame
,
ir_entity
*
ent
)
ir_node
*
be_new_FrameAddr
(
const
arch_register_class_t
*
cls_frame
,
ir_node
*
bl
,
ir_node
*
frame
,
ir_entity
*
ent
)
{
{
be_frame_attr_t
*
a
;
be_frame_attr_t
*
a
;
...
@@ -933,6 +953,24 @@ static int be_node_get_sp_bias(const ir_node *irn)
...
@@ -933,6 +953,24 @@ static int be_node_get_sp_bias(const ir_node *irn)
return
be_get_IncSP_offset
(
irn
);
return
be_get_IncSP_offset
(
irn
);
if
(
be_is_Call
(
irn
))
if
(
be_is_Call
(
irn
))
return
-
(
int
)
be_Call_get_pop
(
irn
);
return
-
(
int
)
be_Call_get_pop
(
irn
);
if
(
be_is_Start
(
irn
))
{
const
be_start_attr_t
*
attr
=
(
const
be_start_attr_t
*
)
get_irn_generic_attr_const
(
irn
);
if
(
attr
->
setup_stackframe
)
{
ir_graph
*
irg
=
get_irn_irg
(
irn
);
ir_type
*
frame
=
get_irg_frame_type
(
irg
);
return
get_type_size_bytes
(
frame
);
}
}
if
(
be_is_Return
(
irn
))
{
const
be_return_attr_t
*
attr
=
(
const
be_return_attr_t
*
)
get_irn_generic_attr_const
(
irn
);
if
(
attr
->
destroy_stackframe
)
{
ir_graph
*
irg
=
get_irn_irg
(
irn
);
ir_type
*
frame
=
get_irg_frame_type
(
irg
);
return
-
(
int
)
get_type_size_bytes
(
frame
);
}
}
return
0
;
return
0
;
}
}
...
@@ -1235,7 +1273,7 @@ void be_init_op(void)
...
@@ -1235,7 +1273,7 @@ void be_init_op(void)
op_be_AddSP
=
new_be_op
(
beo_AddSP
,
"be_AddSP"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_node_attr_t
));
op_be_AddSP
=
new_be_op
(
beo_AddSP
,
"be_AddSP"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_node_attr_t
));
op_be_SubSP
=
new_be_op
(
beo_SubSP
,
"be_SubSP"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_node_attr_t
));
op_be_SubSP
=
new_be_op
(
beo_SubSP
,
"be_SubSP"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_node_attr_t
));
op_be_IncSP
=
new_be_op
(
beo_IncSP
,
"be_IncSP"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_incsp_attr_t
));
op_be_IncSP
=
new_be_op
(
beo_IncSP
,
"be_IncSP"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_incsp_attr_t
));
op_be_Start
=
new_be_op
(
beo_Start
,
"be_Start"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_zero
,
sizeof
(
be_
node
_attr_t
));
op_be_Start
=
new_be_op
(
beo_Start
,
"be_Start"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_zero
,
sizeof
(
be_
start
_attr_t
));
op_be_FrameAddr
=
new_be_op
(
beo_FrameAddr
,
"be_FrameAddr"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_frame_attr_t
));
op_be_FrameAddr
=
new_be_op
(
beo_FrameAddr
,
"be_FrameAddr"
,
op_pin_state_exc_pinned
,
irop_flag_none
,
oparity_unary
,
sizeof
(
be_frame_attr_t
));
op_be_Spill
->
ops
.
node_cmp_attr
=
FrameAddr_cmp_attr
;
op_be_Spill
->
ops
.
node_cmp_attr
=
FrameAddr_cmp_attr
;
...
...
ir/be/benode.h
View file @
12b6cd69
...
@@ -338,8 +338,12 @@ int be_Return_get_emit_pop(const ir_node *ret);
...
@@ -338,8 +338,12 @@ int be_Return_get_emit_pop(const ir_node *ret);
*/
*/
void
be_Return_set_emit_pop
(
ir_node
*
ret
,
int
emit_pop
);
void
be_Return_set_emit_pop
(
ir_node
*
ret
,
int
emit_pop
);
void
be_return_set_destroy_stackframe
(
ir_node
*
node
,
bool
value
);
ir_node
*
be_new_Start
(
dbg_info
*
dbgi
,
ir_node
*
block
,
int
n_out
);
ir_node
*
be_new_Start
(
dbg_info
*
dbgi
,
ir_node
*
block
,
int
n_out
);
void
be_start_set_setup_stackframe
(
ir_node
*
node
,
bool
value
);
enum
{
enum
{
n_be_CopyKeep_op
=
0
n_be_CopyKeep_op
=
0
};
};
...
...
Write
Preview
Supports
Markdown
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