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
d266f572
Commit
d266f572
authored
Dec 18, 2008
by
Michael Beck
Browse files
- implemented __builtin_return_address(0)
[r24793]
parent
1da43c38
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/bearch_ia32.c
View file @
d266f572
...
...
@@ -101,6 +101,14 @@ static set *cur_reg_set = NULL;
ir_mode
*
mode_fpcw
=
NULL
;
ia32_code_gen_t
*
ia32_current_cg
=
NULL
;
/** The current omit-fp state */
static
unsigned
ia32_curr_fp_ommitted
=
0
;
static
ir_type
*
omit_fp_between_type
=
NULL
;
static
ir_type
*
between_type
=
NULL
;
static
ir_entity
*
old_bp_ent
=
NULL
;
static
ir_entity
*
ret_addr_ent
=
NULL
;
static
ir_entity
*
omit_fp_ret_addr_ent
=
NULL
;
/**
* The environment for the intrinsic mapping.
*/
...
...
@@ -337,6 +345,7 @@ static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap
ia32_code_gen_t
*
cg
=
ia32_current_cg
;
const
arch_env_t
*
arch_env
=
env
->
aenv
;
ia32_curr_fp_ommitted
=
env
->
flags
.
try_omit_fp
;
if
(
!
env
->
flags
.
try_omit_fp
)
{
ir_graph
*
irg
=
env
->
irg
;
ir_node
*
bl
=
get_irg_start_block
(
irg
);
...
...
@@ -464,23 +473,11 @@ static void ia32_abi_done(void *self) {
}
/**
* Produces the type which sits between the stack args and the locals on the stack.
* it will contain the return address and space to store the old base pointer.
* @return The Firm type modeling the ABI between type.
* Build the between type and entities if not already build.
*/
static
ir_type
*
ia32_abi_get_between_type
(
void
*
self
)
{
static
void
ia32_build_between_type
(
void
)
{
#define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
static
ir_type
*
omit_fp_between_type
=
NULL
;
static
ir_type
*
between_type
=
NULL
;
ia32_abi_env_t
*
env
=
self
;
if
(
!
between_type
)
{
ir_entity
*
old_bp_ent
;
ir_entity
*
ret_addr_ent
;
ir_entity
*
omit_fp_ret_addr_ent
;
ir_type
*
old_bp_type
=
new_type_primitive
(
IDENT
(
"bp"
),
mode_Iu
);
ir_type
*
ret_addr_type
=
new_type_primitive
(
IDENT
(
"return_addr"
),
mode_Iu
);
...
...
@@ -500,9 +497,28 @@ static ir_type *ia32_abi_get_between_type(void *self)
set_type_size_bytes
(
omit_fp_between_type
,
get_type_size_bytes
(
ret_addr_type
));
set_type_state
(
omit_fp_between_type
,
layout_fixed
);
}
#undef IDENT
}
/**
* Produces the type which sits between the stack args and the locals on the stack.
* it will contain the return address and space to store the old base pointer.
* @return The Firm type modeling the ABI between type.
*/
static
ir_type
*
ia32_abi_get_between_type
(
void
*
self
)
{
ia32_abi_env_t
*
env
=
self
;
ia32_build_between_type
();
return
env
->
flags
.
try_omit_fp
?
omit_fp_between_type
:
between_type
;
#undef IDENT
}
/**
* Return the stack entity that contains the return address.
*/
ir_entity
*
ia32_get_return_address_entity
(
void
)
{
ia32_build_between_type
();
return
ia32_curr_fp_ommitted
?
omit_fp_ret_addr_ent
:
ret_addr_ent
;
}
/**
...
...
ir/be/ia32/bearch_ia32_t.h
View file @
d266f572
...
...
@@ -176,4 +176,9 @@ ir_entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op,
const
ir_mode
*
imode
,
const
ir_mode
*
omode
,
void
*
context
);
/**
* Return the stack entity that contains the return address.
*/
ir_entity
*
ia32_get_return_address_entity
(
void
);
#endif
ir/be/ia32/ia32_transform.c
View file @
d266f572
...
...
@@ -90,8 +90,6 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
static
ir_node
*
initial_fpcw
=
NULL
;
extern
ir_op
*
get_op_Mulh
(
void
);
typedef
ir_node
*
construct_binop_func
(
dbg_info
*
db
,
ir_node
*
block
,
ir_node
*
base
,
ir_node
*
index
,
ir_node
*
mem
,
ir_node
*
op1
,
ir_node
*
op2
);
...
...
@@ -4520,6 +4518,82 @@ static ir_node *gen_be_Call(ir_node *node)
return
call
;
}
/**
* Transform Builtin return_address
*/
static
ir_node
*
gen_return_address
(
ir_node
*
node
)
{
ir_node
*
param
=
get_Builtin_param
(
node
,
0
);
ir_node
*
frame
=
get_Builtin_param
(
node
,
1
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
tarval
*
tv
=
get_Const_tarval
(
param
);
long
value
=
get_tarval_long
(
tv
);
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
if
(
value
==
0
)
{
/* the return address of the current function */
ir_node
*
new_op
=
be_transform_node
(
frame
);
ir_node
*
noreg
=
ia32_new_NoReg_gp
(
env_cg
);
ir_node
*
new_node
;
new_node
=
new_bd_ia32_Load
(
dbgi
,
block
,
new_op
,
noreg
,
get_irg_no_mem
(
current_ir_graph
));
set_irn_pinned
(
new_node
,
get_irn_pinned
(
node
));
set_ia32_op_type
(
new_node
,
ia32_AddrModeS
);
set_ia32_ls_mode
(
new_node
,
mode_Iu
);
set_ia32_am_offs_int
(
new_node
,
0
);
set_ia32_use_frame
(
new_node
);
set_ia32_frame_ent
(
new_node
,
ia32_get_return_address_entity
());
if
(
get_irn_pinned
(
node
)
==
op_pin_state_floats
)
{
assert
(
pn_ia32_xLoad_res
==
pn_ia32_vfld_res
&&
pn_ia32_vfld_res
==
pn_ia32_Load_res
&&
pn_ia32_Load_res
==
pn_ia32_res
);
arch_irn_add_flags
(
new_node
,
arch_irn_flags_rematerializable
);
}
SET_IA32_ORIG_NODE
(
new_node
,
node
);
return
new_rd_Proj
(
dbgi
,
current_ir_graph
,
block
,
new_node
,
mode_Iu
,
pn_ia32_Load_res
);
}
panic
(
"builtin_return_address(%ld) not supported in IA32"
,
value
);
}
/**
* Transform Builtin node.
*/
static
ir_node
*
gen_Builtin
(
ir_node
*
node
)
{
ir_builtin_kind
kind
=
get_Builtin_kind
(
node
);
switch
(
kind
)
{
case
ir_bk_return_address
:
return
gen_return_address
(
node
);
case
ir_bk_frame_addess
:
case
ir_bk_prefetch
:
break
;
}
panic
(
"Builtin %s not implemented in IA32"
,
get_builtin_kind_name
(
kind
));
}
/**
* Transform Proj(Builtin) node.
*/
static
ir_node
*
gen_Proj_Builtin
(
ir_node
*
proj
)
{
ir_node
*
node
=
get_Proj_pred
(
proj
);
ir_node
*
new_node
=
be_transform_node
(
node
);
ir_builtin_kind
kind
=
get_Builtin_kind
(
node
);
switch
(
kind
)
{
case
ir_bk_return_address
:
case
ir_bk_frame_addess
:
assert
(
get_Proj_proj
(
proj
)
==
pn_Builtin_1_result
);
return
new_node
;
case
ir_bk_prefetch
:
break
;
}
panic
(
"Builtin %s not implemented in IA32"
,
get_builtin_kind_name
(
kind
));
}
static
ir_node
*
gen_be_IncSP
(
ir_node
*
node
)
{
ir_node
*
res
=
be_duplicate_node
(
node
);
...
...
@@ -4725,6 +4799,8 @@ static ir_node *gen_Proj(ir_node *node)
return
gen_Proj_Load
(
node
);
case
iro_ASM
:
return
gen_Proj_ASM
(
node
);
case
iro_Builtin
:
return
gen_Proj_Builtin
(
node
);
case
iro_Div
:
case
iro_Mod
:
case
iro_DivMod
:
...
...
@@ -4868,7 +4944,7 @@ static void register_transformers(void)
BAD
(
EndExcept
);
/* handle builtins */
BAD
(
Builtin
);
GEN
(
Builtin
);
/* handle generic backend nodes */
GEN
(
be_FrameAddr
);
...
...
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