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
5c34afb8
Commit
5c34afb8
authored
Aug 22, 2011
by
Matthias Braun
Browse files
sparc: support va_start
parent
38929082
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/be/beabihelper.c
View file @
5c34afb8
...
...
@@ -669,10 +669,9 @@ void be_free_stackorder(be_stackorder_t *env)
free
(
env
);
}
void
be_add_parameter_entity_stores
(
ir_graph
*
irg
)
static
void
create_stores_for_type
(
ir_graph
*
irg
,
ir_type
*
type
)
{
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
size_t
n
=
get_compound_n_members
(
frame_type
);
size_t
n
=
get_compound_n_members
(
type
);
ir_node
*
frame
=
get_irg_frame
(
irg
);
ir_node
*
initial_mem
=
get_irg_initial_mem
(
irg
);
ir_node
*
mem
=
initial_mem
;
...
...
@@ -684,7 +683,7 @@ void be_add_parameter_entity_stores(ir_graph *irg)
/* all parameter entities left in the frame type require stores.
* (The ones passed on the stack have been moved to the arg type) */
for
(
i
=
0
;
i
<
n
;
++
i
)
{
ir_entity
*
entity
=
get_compound_member
(
frame_
type
,
i
);
ir_entity
*
entity
=
get_compound_member
(
type
,
i
);
ir_node
*
addr
;
size_t
arg
;
if
(
!
is_parameter_entity
(
entity
))
...
...
@@ -727,3 +726,15 @@ void be_add_parameter_entity_stores(ir_graph *irg)
set_Store_mem
(
first_store
,
initial_mem
);
}
}
void
be_add_parameter_entity_stores
(
ir_graph
*
irg
)
{
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
be_stack_layout_t
*
layout
=
be_get_irg_stack_layout
(
irg
);
ir_type
*
between_type
=
layout
->
between_type
;
create_stores_for_type
(
irg
,
frame_type
);
if
(
between_type
!=
NULL
)
{
create_stores_for_type
(
irg
,
between_type
);
}
}
ir/be/sparc/bearch_sparc_t.h
View file @
5c34afb8
...
...
@@ -78,6 +78,8 @@ extern const arch_irn_ops_t sparc_irn_ops;
#define SPARC_IMMEDIATE_MAX 4095
#define SPARC_MIN_STACKSIZE 92
#define SPARC_AGGREGATE_RETURN_OFFSET 64
#define SPARC_PARAMS_SPILL_OFFSET 68
#define SPARC_N_PARAM_REGS 6
static
inline
bool
sparc_is_value_imm_encodeable
(
int32_t
value
)
{
...
...
@@ -90,6 +92,7 @@ void sparc_introduce_prolog_epilog(ir_graph *irg);
void
sparc_lower_64bit
(
void
);
bool
sparc_variadic_fixups
(
ir_graph
*
irg
,
calling_convention_t
*
cconv
);
void
sparc_create_stacklayout
(
ir_graph
*
irg
,
calling_convention_t
*
cconv
);
void
sparc_fix_stack_bias
(
ir_graph
*
irg
);
...
...
ir/be/sparc/sparc_cconv.c
View file @
5c34afb8
...
...
@@ -60,6 +60,7 @@ static const arch_register_t* const param_regs[] = {
&
sparc_registers
[
REG_I4
],
&
sparc_registers
[
REG_I5
],
};
COMPILETIME_ASSERT
(
ARRAY_SIZE
(
param_regs
)
==
SPARC_N_PARAM_REGS
,
sparcparamregs
)
static
const
arch_register_t
*
const
float_result_regs
[]
=
{
&
sparc_registers
[
REG_F0
],
...
...
@@ -323,7 +324,6 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
struct
obstack
*
obst
=
&
birg
->
obst
;
size_t
r
;
assert
(
birg
->
allocatable_regs
==
NULL
);
birg
->
allocatable_regs
=
rbitset_obstack_alloc
(
obst
,
N_SPARC_REGISTERS
);
rbitset_set_all
(
birg
->
allocatable_regs
,
N_SPARC_REGISTERS
);
for
(
r
=
0
;
r
<
n_ignores
;
++
r
)
{
...
...
ir/be/sparc/sparc_stackframe.c
View file @
5c34afb8
...
...
@@ -48,7 +48,8 @@ static void set_irn_sp_bias(ir_node *node, int new_bias)
}
}
static
void
process_bias
(
ir_node
*
block
,
bool
sp_relative
,
int
bias
,
int
free_bytes
)
static
void
process_bias
(
ir_node
*
block
,
bool
sp_relative
,
int
bias
,
int
free_bytes
)
{
const
ir_edge_t
*
edge
;
ir_node
*
irn
;
...
...
@@ -114,12 +115,59 @@ static void adjust_entity_offsets(ir_type *type, long offset)
}
}
static
ir_type
*
compute_arg_type
(
ir_graph
*
irg
,
calling_convention_t
*
cconv
)
bool
sparc_variadic_fixups
(
ir_graph
*
irg
,
calling_convention_t
*
cconv
)
{
ir_entity
*
entity
=
get_irg_entity
(
irg
);
ir_type
*
mtp
=
get_entity_type
(
entity
);
size_t
n_params
=
get_method_n_params
(
mtp
);
ir_entity
**
param_map
=
ALLOCANZ
(
ir_entity
*
,
n_params
);
ir_entity
*
entity
=
get_irg_entity
(
irg
);
ir_type
*
mtp
=
get_entity_type
(
entity
);
if
(
get_method_variadicity
(
mtp
)
!=
variadicity_variadic
)
return
false
;
if
(
cconv
->
n_param_regs
>=
SPARC_N_PARAM_REGS
)
return
false
;
{
size_t
n_params
=
get_method_n_params
(
mtp
);
type_dbg_info
*
dbgi
=
get_type_dbg_info
(
mtp
);
size_t
n_ress
=
get_method_n_ress
(
mtp
);
size_t
new_n_params
=
n_params
+
(
SPARC_N_PARAM_REGS
-
cconv
->
n_param_regs
);
ir_type
*
new_mtp
=
new_d_type_method
(
new_n_params
,
n_ress
,
dbgi
);
ir_mode
*
gp_reg_mode
=
sparc_reg_classes
[
CLASS_sparc_gp
].
mode
;
ir_type
*
gp_reg_type
=
get_type_for_mode
(
gp_reg_mode
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
size_t
i
;
for
(
i
=
0
;
i
<
n_ress
;
++
i
)
{
ir_type
*
type
=
get_method_res_type
(
mtp
,
i
);
set_method_res_type
(
new_mtp
,
i
,
type
);
}
for
(
i
=
0
;
i
<
n_params
;
++
i
)
{
ir_type
*
type
=
get_method_param_type
(
mtp
,
i
);
set_method_param_type
(
new_mtp
,
i
,
type
);
}
for
(
;
i
<
new_n_params
;
++
i
)
{
set_method_param_type
(
new_mtp
,
i
,
gp_reg_type
);
new_parameter_entity
(
frame_type
,
i
,
gp_reg_type
);
}
set_method_variadicity
(
new_mtp
,
get_method_variadicity
(
mtp
));
set_method_calling_convention
(
new_mtp
,
get_method_calling_convention
(
mtp
));
set_method_additional_properties
(
new_mtp
,
get_method_additional_properties
(
mtp
));
set_lowered_type
(
mtp
,
new_mtp
);
set_entity_type
(
entity
,
new_mtp
);
}
return
true
;
}
static
ir_type
*
compute_arg_type
(
ir_graph
*
irg
,
calling_convention_t
*
cconv
,
ir_type
*
between_type
)
{
ir_entity
*
va_start_entity
=
NULL
;
const
ir_entity
*
entity
=
get_irg_entity
(
irg
);
const
ir_type
*
mtp
=
get_entity_type
(
entity
);
size_t
n_params
=
get_method_n_params
(
mtp
);
ir_entity
**
param_map
=
ALLOCANZ
(
ir_entity
*
,
n_params
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
size_t
n_frame_members
=
get_compound_n_members
(
frame_type
);
...
...
@@ -132,36 +180,65 @@ static ir_type *compute_arg_type(ir_graph *irg, calling_convention_t *cconv)
for
(
f
=
n_frame_members
;
f
>
0
;
)
{
ir_entity
*
member
=
get_compound_member
(
frame_type
,
--
f
);
size_t
num
;
const
reg_or_stackslot_t
*
param
;
if
(
!
is_parameter_entity
(
member
))
continue
;
num
=
get_entity_parameter_number
(
member
);
if
(
num
==
IR_VA_START_PARAMETER_NUMBER
)
{
if
(
va_start_entity
!=
NULL
)
panic
(
"multiple va_start entities found (%+F,%+F)"
,
va_start_entity
,
member
);
va_start_entity
=
member
;
continue
;
}
assert
(
num
<
n_params
);
if
(
param_map
[
num
]
!=
NULL
)
panic
(
"multiple entities for parameter %u in %+F found"
,
f
,
irg
);
param
=
&
cconv
->
parameters
[
num
];
if
(
param
->
reg0
!=
NULL
)
continue
;
param_map
[
num
]
=
member
;
/* move to new arg_type */
set_entity_owner
(
member
,
res
);
}
/* calculate offsets/create missing entities */
for
(
i
=
0
;
i
<
n_params
;
++
i
)
{
reg_or_stackslot_t
*
param
=
&
cconv
->
parameters
[
i
];
ir_entity
*
entity
;
if
(
param
->
reg0
!=
NULL
)
reg_or_stackslot_t
*
param
=
&
cconv
->
parameters
[
i
];
ir_entity
*
entity
=
param_map
[
i
];
if
(
param
->
reg0
!=
NULL
)
{
/* use reserved spill space on between type */
if
(
entity
!=
NULL
)
{
long
offset
=
SPARC_PARAMS_SPILL_OFFSET
+
i
*
4
;
assert
(
i
<
SPARC_N_PARAM_REGS
);
set_entity_owner
(
entity
,
between_type
);
set_entity_offset
(
entity
,
offset
);
}
continue
;
entity
=
param_map
[
i
];
}
if
(
entity
==
NULL
)
entity
=
new_parameter_entity
(
res
,
i
,
param
->
type
);
param
->
entity
=
entity
;
set_entity_offset
(
entity
,
param
->
offset
);
}
if
(
va_start_entity
!=
NULL
)
{
/* sparc_variadic_fixups() fiddled with our type, find out the
* original number of parameters */
ir_type
*
non_lowered
=
get_associated_type
(
mtp
);
size_t
orig_n_params
=
get_method_n_params
(
non_lowered
);
long
offset
;
assert
(
get_method_variadicity
(
mtp
)
==
variadicity_variadic
);
if
(
orig_n_params
<
n_params
)
{
assert
(
param_map
[
orig_n_params
]
!=
NULL
);
offset
=
get_entity_offset
(
param_map
[
orig_n_params
]);
set_entity_owner
(
va_start_entity
,
between_type
);
set_entity_offset
(
va_start_entity
,
offset
);
}
else
{
set_entity_owner
(
va_start_entity
,
res
);
set_entity_offset
(
va_start_entity
,
cconv
->
param_stack_size
);
}
}
set_type_size_bytes
(
res
,
cconv
->
param_stack_size
);
return
res
;
...
...
@@ -178,7 +255,7 @@ void sparc_create_stacklayout(ir_graph *irg, calling_convention_t *cconv)
layout
->
frame_type
=
get_irg_frame_type
(
irg
);
layout
->
between_type
=
between_type
;
layout
->
arg_type
=
compute_arg_type
(
irg
,
cconv
);
layout
->
arg_type
=
compute_arg_type
(
irg
,
cconv
,
between_type
);
layout
->
initial_offset
=
0
;
layout
->
initial_bias
=
0
;
layout
->
sp_relative
=
cconv
->
omit_fp
;
...
...
@@ -228,7 +305,7 @@ static void process_frame_types(ir_graph *irg)
void
sparc_fix_stack_bias
(
ir_graph
*
irg
)
{
ir_node
*
start_block
=
get_irg_start_block
(
irg
);
ir_node
*
start_block
=
get_irg_start_block
(
irg
);
process_frame_types
(
irg
);
...
...
ir/be/sparc/sparc_transform.c
View file @
5c34afb8
...
...
@@ -2061,16 +2061,13 @@ static ir_node *gen_Proj_Start(ir_node *node)
static
ir_node
*
gen_Proj_Proj_Start
(
ir_node
*
node
)
{
long
pn
=
get_Proj_proj
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_node
*
new_block
=
be_transform_node
(
block
);
ir_entity
*
entity
=
get_irg_entity
(
irg
);
ir_type
*
method_type
=
get_entity_type
(
entity
);
ir_type
*
param_type
=
get_method_param_type
(
method_type
,
pn
);
ir_node
*
args
=
get_Proj_pred
(
node
);
ir_node
*
start
=
get_Proj_pred
(
args
);
ir_node
*
new_start
=
be_transform_node
(
start
);
long
pn
=
get_Proj_proj
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_node
*
new_block
=
be_transform_node
(
block
);
ir_node
*
args
=
get_Proj_pred
(
node
);
ir_node
*
start
=
get_Proj_pred
(
args
);
ir_node
*
new_start
=
be_transform_node
(
start
);
const
reg_or_stackslot_t
*
param
;
/* Proj->Proj->Start must be a method argument */
...
...
@@ -2080,22 +2077,32 @@ static ir_node *gen_Proj_Proj_Start(ir_node *node)
if
(
param
->
reg0
!=
NULL
)
{
/* argument transmitted in register */
ir_mode
*
mode
=
get_type_mode
(
param_type
);
const
arch_register_t
*
reg
=
param
->
reg0
;
ir_mode
*
reg_mode
=
reg
->
reg_class
->
mode
;
long
pn
=
param
->
reg_offset
+
start_params_offset
;
ir_node
*
value
=
new_r_Proj
(
new_start
,
reg_mode
,
pn
);
long
new_pn
=
param
->
reg_offset
+
start_params_offset
;
ir_node
*
value
=
new_r_Proj
(
new_start
,
reg_mode
,
new_pn
);
bool
is_float
=
false
;
{
ir_entity
*
entity
=
get_irg_entity
(
irg
);
ir_type
*
method_type
=
get_entity_type
(
entity
);
if
(
pn
<
(
long
)
get_method_n_params
(
method_type
))
{
ir_type
*
param_type
=
get_method_param_type
(
method_type
,
pn
);
ir_mode
*
mode
=
get_type_mode
(
param_type
);
is_float
=
mode_is_float
(
mode
);
}
}
if
(
mode_
is_float
(
mode
)
)
{
if
(
is_float
)
{
const
arch_register_t
*
reg1
=
param
->
reg1
;
ir_node
*
value1
=
NULL
;
if
(
reg1
!=
NULL
)
{
ir_mode
*
reg1_mode
=
reg1
->
reg_class
->
mode
;
value1
=
new_r_Proj
(
new_start
,
reg1_mode
,
pn
+
1
);
value1
=
new_r_Proj
(
new_start
,
reg1_mode
,
new_
pn
+
1
);
}
else
if
(
param
->
entity
!=
NULL
)
{
ir_node
*
fp
=
get_initial_fp
(
irg
);
ir_node
*
mem
=
get_initial_mem
(
irg
);
ir_node
*
fp
=
get_initial_fp
(
irg
);
ir_node
*
mem
=
get_initial_mem
(
irg
);
ir_node
*
ld
=
new_bd_sparc_Ld_imm
(
NULL
,
new_block
,
fp
,
mem
,
mode_gp
,
param
->
entity
,
0
,
true
);
...
...
@@ -2108,11 +2115,11 @@ static ir_node *gen_Proj_Proj_Start(ir_node *node)
return
value
;
}
else
{
/* argument transmitted on stack */
ir_node
*
mem
=
get_initial_mem
(
irg
);
ir_mode
*
mode
=
get_type_mode
(
param
->
type
);
ir_node
*
base
=
get_frame_base
(
irg
);
ir_node
*
load
;
ir_node
*
value
;
ir_node
*
mem
=
get_initial_mem
(
irg
);
ir_mode
*
mode
=
get_type_mode
(
param
->
type
);
ir_node
*
base
=
get_frame_base
(
irg
);
ir_node
*
load
;
ir_node
*
value
;
if
(
mode_is_float
(
mode
))
{
load
=
create_ldf
(
NULL
,
new_block
,
base
,
mem
,
mode
,
...
...
@@ -2290,6 +2297,11 @@ void sparc_transform_graph(ir_graph *irg)
stackorder
=
be_collect_stacknodes
(
irg
);
current_cconv
=
sparc_decide_calling_convention
(
get_entity_type
(
entity
),
irg
);
if
(
sparc_variadic_fixups
(
irg
,
current_cconv
))
{
sparc_free_calling_convention
(
current_cconv
);
current_cconv
=
sparc_decide_calling_convention
(
get_entity_type
(
entity
),
irg
);
}
sparc_create_stacklayout
(
irg
,
current_cconv
);
be_add_parameter_entity_stores
(
irg
);
...
...
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