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
50102ed2
Commit
50102ed2
authored
Jan 02, 2009
by
Michael Beck
Browse files
- correct lowering of the the value parameter type helps beabi ...
[r25033]
parent
d05a8de2
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/lower/lower_dw.c
View file @
50102ed2
...
...
@@ -110,13 +110,19 @@ enum lower_flags {
typedef
struct
_lower_env_t
{
node_entry_t
**
entries
;
/**< entries per node */
struct
obstack
obst
;
/**< an obstack holding the temporary data */
ir_type
*
l_mtp
;
/**< lowered method type of the current method */
tarval
*
tv_mode_bytes
;
/**< a tarval containing the number of bytes in the lowered modes */
tarval
*
tv_mode_bits
;
/**< a tarval containing the number of bits in the lowered modes */
pdeq
*
waitq
;
/**< a wait queue of all nodes that must be handled later */
pmap
*
proj_2_block
;
/**< a map from ProjX to its destination blocks */
ident
*
first_id
;
/**< .l for little and .h for big endian */
ident
*
next_id
;
/**< .h for little and .l for big endian */
const
lwrdw_param_t
*
params
;
/**< transformation parameter */
unsigned
flags
;
/**< some flags */
int
n_entries
;
/**< number of entries */
#ifndef NDEBUG
ir_type
*
value_param_tp
;
/**< the old value param type */
#endif
}
lower_env_t
;
/**
...
...
@@ -1692,11 +1698,16 @@ static void lower_Conv(ir_node *node, ir_mode *mode, lower_env_t *env) {
/**
* Lower the method type.
*
* @param mtp the method type to lower
* @param ent the lower environment
*
* @return the lowered type
*/
static
ir_type
*
lower_mtp
(
ir_type
*
mtp
,
lower_env_t
*
env
)
{
pmap_entry
*
entry
;
ident
*
id
;
ir_type
*
res
;
ident
*
id
,
*
lid
;
ir_type
*
res
,
*
value_type
;
if
(
is_lowered_type
(
mtp
))
return
mtp
;
...
...
@@ -1733,7 +1744,7 @@ static ir_type *lower_mtp(ir_type *mtp, lower_env_t *env) {
}
/* if */
}
/* for */
id
=
id_mangle_u
(
new_id_from_chars
(
"L"
,
1
),
get_type_ident
(
mtp
));
id
=
id_mangle_u
(
new_id_from_chars
(
"L"
,
1
),
get_type_ident
(
mtp
));
res
=
new_type_method
(
id
,
n_param
,
n_res
);
/* set param types and result types */
...
...
@@ -1777,6 +1788,44 @@ static ir_type *lower_mtp(ir_type *mtp, lower_env_t *env) {
}
/* for */
set_lowered_type
(
mtp
,
res
);
pmap_insert
(
lowered_type
,
mtp
,
res
);
value_type
=
get_method_value_param_type
(
mtp
);
if
(
value_type
!=
NULL
)
{
/* this creates a new value parameter type */
(
void
)
get_method_value_param_ent
(
res
,
0
);
/* set new param positions */
for
(
i
=
n_param
=
0
;
i
<
n
;
++
i
)
{
ir_type
*
tp
=
get_method_param_type
(
mtp
,
i
);
ident
*
id
=
get_method_param_ident
(
mtp
,
i
);
ir_entity
*
ent
=
get_method_value_param_ent
(
mtp
,
i
);
set_entity_link
(
ent
,
INT_TO_PTR
(
n_param
));
if
(
is_Primitive_type
(
tp
))
{
ir_mode
*
mode
=
get_type_mode
(
tp
);
if
(
mode
==
env
->
params
->
high_signed
||
mode
==
env
->
params
->
high_unsigned
)
{
if
(
id
!=
NULL
)
{
lid
=
id_mangle
(
id
,
env
->
first_id
);
set_method_param_ident
(
res
,
n_param
,
lid
);
set_entity_ident
(
get_method_value_param_ent
(
res
,
n_param
),
lid
);
lid
=
id_mangle
(
id
,
env
->
next_id
);
set_method_param_ident
(
res
,
n_param
+
1
,
lid
);
set_entity_ident
(
get_method_value_param_ent
(
res
,
n_param
+
1
),
lid
);
}
/* if */
n_param
+=
2
;
continue
;
}
/* if */
}
/* if */
if
(
id
!=
NULL
)
{
set_method_param_ident
(
res
,
n_param
,
id
);
set_entity_ident
(
get_method_value_param_ent
(
res
,
n_param
),
id
);
}
/* if */
++
n_param
;
}
/* for */
set_lowered_type
(
value_type
,
get_method_value_param_type
(
res
));
}
/* if */
}
else
{
res
=
entry
->
value
;
}
/* if */
...
...
@@ -2201,8 +2250,10 @@ static void lower_Mux(ir_node *mux, ir_mode *mode, lower_env_t *env) {
env
->
entries
[
idx
]
->
high_word
=
new_rd_Mux
(
dbg
,
irg
,
block
,
sel
,
false_h
,
true_h
,
mode
);
}
/* lower_Mux */
static
void
lower_ASM
(
ir_node
*
asmn
,
ir_mode
*
mode
,
lower_env_t
*
env
)
{
/**
* Translate an ASM node.
*/
static
void
lower_ASM
(
ir_node
*
asmn
,
ir_mode
*
mode
,
lower_env_t
*
env
)
{
ir_mode
*
his
=
env
->
params
->
high_signed
;
ir_mode
*
hiu
=
env
->
params
->
high_unsigned
;
int
i
;
...
...
@@ -2214,8 +2265,8 @@ static void lower_ASM(ir_node *asmn, ir_mode *mode, lower_env_t *env)
ir_mode
*
op_mode
=
get_irn_mode
(
get_irn_n
(
asmn
,
i
));
if
(
op_mode
==
his
||
op_mode
==
hiu
)
{
panic
(
"lowering ASM unimplemented"
);
}
}
}
/* if */
}
/* for */
for
(
n
=
asmn
;;)
{
ir_mode
*
proj_mode
;
...
...
@@ -2227,9 +2278,26 @@ static void lower_ASM(ir_node *asmn, ir_mode *mode, lower_env_t *env)
proj_mode
=
get_irn_mode
(
n
);
if
(
proj_mode
==
his
||
proj_mode
==
hiu
)
{
panic
(
"lowering ASM unimplemented"
);
}
}
}
}
/* if */
}
/* for */
}
/* lower_ASM */
/**
* Translate a Sel node.
*/
static
void
lower_Sel
(
ir_node
*
sel
,
ir_mode
*
mode
,
lower_env_t
*
env
)
{
ir_node
*
ptr
=
get_Sel_ptr
(
sel
);
if
(
ptr
==
get_irg_value_param_base
(
current_ir_graph
))
{
ir_entity
*
ent
=
get_Sel_entity
(
sel
);
int
pos
=
PTR_TO_INT
(
get_entity_link
(
ent
));
assert
(
get_entity_owner
(
ent
)
==
env
->
value_param_tp
);
ent
=
get_method_value_param_ent
(
env
->
l_mtp
,
pos
);
set_Sel_entity
(
sel
,
ent
);
}
/* if */
}
/* lower_Sel */
/**
* check for opcodes that must always be lowered.
...
...
@@ -2243,6 +2311,7 @@ static int always_lower(ir_opcode code) {
case
iro_Return
:
case
iro_Cond
:
case
iro_Conv
:
case
iro_Sel
:
return
1
;
default:
return
0
;
...
...
@@ -2395,14 +2464,41 @@ static int cmp_conv_tp(const void *elt, const void *key, size_t size) {
(
void
)
size
;
return
(
e1
->
imode
-
e2
->
imode
)
|
(
e1
->
omode
-
e2
->
omode
);
}
/*
static int
cmp_conv_tp */
}
/* cmp_conv_tp */
/**
* Enter a lowering function into an ir_op.
*/
static
void
enter_lower_func
(
ir_op
*
op
,
lower_func
func
)
{
op
->
ops
.
generic
=
(
op_func
)
func
;
}
}
/* enter_lower_func */
/**
* Returns non-zero if a method type must be lowered.
*
* @param mtp the method type
*/
static
int
mtp_must_to_lowered
(
ir_type
*
mtp
,
lower_env_t
*
env
)
{
int
i
,
n_params
;
n_params
=
get_method_n_params
(
mtp
);
if
(
n_params
<=
0
)
return
0
;
/* first check if we have parameters that must be fixed */
for
(
i
=
0
;
i
<
n_params
;
++
i
)
{
ir_type
*
tp
=
get_method_param_type
(
mtp
,
i
);
if
(
is_Primitive_type
(
tp
))
{
ir_mode
*
mode
=
get_type_mode
(
tp
);
if
(
mode
==
env
->
params
->
high_signed
||
mode
==
env
->
params
->
high_unsigned
)
return
1
;
}
/* if */
}
/* for */
return
0
;
}
/* mtp_must_to_lowered */
/*
* Do the lowering.
...
...
@@ -2410,8 +2506,8 @@ static void enter_lower_func(ir_op *op, lower_func func) {
void
lower_dw_ops
(
const
lwrdw_param_t
*
param
)
{
lower_env_t
lenv
;
int
i
;
ir_graph
*
rem
;
int
i
;
ir_graph
*
rem
;
if
(
!
param
)
return
;
...
...
@@ -2495,6 +2591,8 @@ void lower_dw_ops(const lwrdw_param_t *param)
lenv
.
tv_mode_bits
=
new_tarval_from_long
(
get_mode_size_bits
(
param
->
low_unsigned
),
param
->
low_unsigned
);
lenv
.
waitq
=
new_pdeq
();
lenv
.
params
=
param
;
lenv
.
first_id
=
new_id_from_chars
(
param
->
little_endian
?
".l"
:
".h"
,
2
);
lenv
.
next_id
=
new_id_from_chars
(
param
->
little_endian
?
".h"
:
".l"
,
2
);
/* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func
();
...
...
@@ -2531,6 +2629,7 @@ void lower_dw_ops(const lwrdw_param_t *param)
LOWER
(
DivMod
);
LOWER
(
Div
);
LOWER
(
Mod
);
LOWER
(
Sel
);
LOWER_UN
(
Abs
);
LOWER_UN
(
Minus
);
...
...
@@ -2544,7 +2643,9 @@ void lower_dw_ops(const lwrdw_param_t *param)
/* transform all graphs */
rem
=
current_ir_graph
;
for
(
i
=
get_irp_n_irgs
()
-
1
;
i
>=
0
;
--
i
)
{
ir_graph
*
irg
=
get_irp_irg
(
i
);
ir_graph
*
irg
=
get_irp_irg
(
i
);
ir_entity
*
ent
;
ir_type
*
mtp
;
int
n_idx
;
obstack_init
(
&
lenv
.
obst
);
...
...
@@ -2555,12 +2656,28 @@ void lower_dw_ops(const lwrdw_param_t *param)
lenv
.
entries
=
NEW_ARR_F
(
node_entry_t
*
,
n_idx
);
memset
(
lenv
.
entries
,
0
,
n_idx
*
sizeof
(
lenv
.
entries
[
0
]));
/* first step: link all nodes and allocate data */
lenv
.
flags
=
0
;
lenv
.
l_mtp
=
NULL
;
lenv
.
flags
=
0
;
lenv
.
proj_2_block
=
pmap_create
();
#ifndef NDEBUG
lenv
.
value_param_tp
=
NULL
;
#endif
ir_reserve_resources
(
irg
,
IR_RESOURCE_PHI_LIST
|
IR_RESOURCE_IRN_LINK
);
ent
=
get_irg_entity
(
irg
);
mtp
=
get_entity_type
(
ent
);
if
(
mtp_must_to_lowered
(
mtp
,
&
lenv
))
{
ir_type
*
ltp
=
lower_mtp
(
mtp
,
&
lenv
);
lenv
.
flags
|=
MUST_BE_LOWERED
;
set_entity_type
(
ent
,
ltp
);
lenv
.
l_mtp
=
ltp
;
#ifndef NDEBUG
lenv
.
value_param_tp
=
get_method_value_param_type
(
mtp
);
#endif
}
/* if */
/* first step: link all nodes and allocate data */
irg_walk_graph
(
irg
,
firm_clear_node_and_phi_links
,
prepare_links_and_handle_rotl
,
&
lenv
);
if
(
lenv
.
flags
&
MUST_BE_LOWERED
)
{
...
...
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