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
4ec0521f
Commit
4ec0521f
authored
Jul 22, 2010
by
Matthias Braun
Browse files
implement sparc floatingpoint constants
[r27787]
parent
b4e27346
Changes
4
Hide whitespace changes
Inline
Side-by-side
ir/be/sparc/bearch_sparc.c
View file @
4ec0521f
...
...
@@ -298,10 +298,11 @@ static void *sparc_cg_init(ir_graph *irg)
sparc_isa_t
*
isa
=
(
sparc_isa_t
*
)
be_get_irg_arch_env
(
irg
);
sparc_code_gen_t
*
cg
=
XMALLOCZ
(
sparc_code_gen_t
);
cg
->
impl
=
&
sparc_code_gen_if
;
cg
->
irg
=
irg
;
cg
->
isa
=
isa
;
cg
->
dump
=
(
be_get_irg_options
(
irg
)
->
dump_flags
&
DUMP_BE
)
!=
0
;
cg
->
impl
=
&
sparc_code_gen_if
;
cg
->
irg
=
irg
;
cg
->
isa
=
isa
;
cg
->
dump
=
(
be_get_irg_options
(
irg
)
->
dump_flags
&
DUMP_BE
)
!=
0
;
cg
->
constants
=
pmap_create
();
/* enter the current code generator */
isa
->
cg
=
cg
;
...
...
@@ -618,31 +619,42 @@ static void sparc_get_call_abi(const void *self, ir_type *method_type,
be_abi_call_set_flags
(
abi
,
call_flags
,
&
sparc_abi_callbacks
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
/* reg = get reg for param i; */
/* be_abi_call_param_reg(abi, i, reg); */
/* pass outgoing params 0-5 via registers, remaining via stack */
/* on sparc we need to set the ABI context since register names of parameters change to i0-i5 if we are the callee */
if
(
i
<
6
)
{
be_abi_call_param_reg
(
abi
,
i
,
sparc_get_RegParamOut_reg
(
i
),
ABI_CONTEXT_CALLER
);
be_abi_call_param_reg
(
abi
,
i
,
sparc_get_RegParamIn_reg
(
i
),
ABI_CONTEXT_CALLEE
);
}
else
{
tp
=
get_method_param_type
(
method_type
,
i
);
mode
=
get_type_mode
(
tp
);
be_abi_call_param_stack
(
abi
,
i
,
mode
,
4
,
0
,
0
,
ABI_CONTEXT_BOTH
);
/*< stack args have no special context >*/
ir_type
*
type
=
get_method_param_type
(
method_type
,
i
);
ir_mode
*
mode
=
get_type_mode
(
type
);
if
(
mode_is_float
(
mode
)
||
i
>=
6
)
{
unsigned
align
=
get_type_size_bytes
(
type
);
be_abi_call_param_stack
(
abi
,
i
,
mode
,
align
,
0
,
0
,
ABI_CONTEXT_BOTH
);
continue
;
}
/* pass integer params 0-5 via registers.
* On sparc we need to set the ABI context since register names of
* parameters change to i0-i5 if we are the callee */
be_abi_call_param_reg
(
abi
,
i
,
sparc_get_RegParamOut_reg
(
i
),
ABI_CONTEXT_CALLER
);
be_abi_call_param_reg
(
abi
,
i
,
sparc_get_RegParamIn_reg
(
i
),
ABI_CONTEXT_CALLEE
);
}
/* set return value register: return value is in i0 resp. f0 */
if
(
get_method_n_ress
(
method_type
)
>
0
)
{
tp
=
get_method_res_type
(
method_type
,
0
);
n
=
get_method_n_ress
(
method_type
);
/* more than 1 result not supported */
assert
(
n
<=
1
);
for
(
i
=
0
;
i
<
n
;
++
i
)
{
tp
=
get_method_res_type
(
method_type
,
i
);
mode
=
get_type_mode
(
tp
);
be_abi_call_res_reg
(
abi
,
0
,
mode_is_float
(
mode
)
?
&
sparc_fp_regs
[
REG_F0
]
:
&
sparc_gp_regs
[
REG_I0
],
ABI_CONTEXT_CALLEE
);
/*< return has no special context >*/
be_abi_call_res_reg
(
abi
,
0
,
mode_is_float
(
mode
)
?
&
sparc_fp_regs
[
REG_F0
]
:
&
sparc_gp_regs
[
REG_O0
],
ABI_CONTEXT_CALLER
);
/*< return has no special context >*/
/* set return value register: return value is in i0 resp. f0 */
if
(
mode_is_float
(
mode
))
{
be_abi_call_res_reg
(
abi
,
i
,
&
sparc_fp_regs
[
REG_F0
],
ABI_CONTEXT_BOTH
);
}
else
{
be_abi_call_res_reg
(
abi
,
i
,
&
sparc_gp_regs
[
REG_I0
],
ABI_CONTEXT_CALLEE
);
be_abi_call_res_reg
(
abi
,
i
,
&
sparc_gp_regs
[
REG_O0
],
ABI_CONTEXT_CALLER
);
}
}
}
...
...
ir/be/sparc/bearch_sparc_t.h
View file @
4ec0521f
...
...
@@ -38,6 +38,7 @@ typedef struct sparc_code_gen_t {
sparc_isa_t
*
isa
;
/**< the isa instance */
bool
dump
;
/**< set to 1 if graphs should
be dumped */
pmap
*
constants
;
}
sparc_code_gen_t
;
struct
sparc_isa_t
{
...
...
ir/be/sparc/sparc_spec.pl
View file @
4ec0521f
...
...
@@ -503,4 +503,15 @@ FdTOi => {
emit
=>
'
. FdTOi %S1, %D1
'
},
Ldf
=>
{
op_flags
=>
[
"
labeled
",
"
fragile
"
],
state
=>
"
exc_pinned
",
ins
=>
[
"
ptr
",
"
mem
"
],
outs
=>
[
"
res
",
"
M
"
],
reg_req
=>
{
in
=>
[
"
gp
",
"
none
"
],
out
=>
[
"
fp
",
"
none
"
]
},
attr_type
=>
"
sparc_load_store_attr_t
",
attr
=>
"
ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity
",
emit
=>
'
. ld [%S1%O], %D1
'
},
);
# end of %nodes
ir/be/sparc/sparc_transform.c
View file @
4ec0521f
...
...
@@ -173,17 +173,6 @@ static ir_node *create_const_graph(ir_node *irn, ir_node *block)
return
create_const_graph_value
(
dbgi
,
block
,
value
);
}
/**
* create a DAG to load fp constant. sparc only supports loading from global memory
*/
static
ir_node
*
create_fp_const_graph
(
ir_node
*
irn
,
ir_node
*
block
)
{
(
void
)
block
;
(
void
)
irn
;
panic
(
"FP constants not implemented"
);
}
typedef
enum
{
MATCH_NONE
=
0
,
MATCH_COMMUTATIVE
=
1
<<
0
,
...
...
@@ -557,6 +546,42 @@ static ir_node *gen_Minus(ir_node *node)
return
new_bd_sparc_Minus
(
dbgi
,
block
,
new_op
);
}
static
ir_node
*
make_addr
(
dbg_info
*
dbgi
,
ir_entity
*
entity
)
{
ir_node
*
block
=
get_irg_start_block
(
current_ir_graph
);
ir_node
*
node
=
new_bd_sparc_SymConst
(
dbgi
,
block
,
entity
);
be_dep_on_frame
(
node
);
return
node
;
}
/**
* Create an entity for a given (floatingpoint) tarval
*/
static
ir_entity
*
create_float_const_entity
(
tarval
*
tv
)
{
ir_entity
*
entity
=
(
ir_entity
*
)
pmap_get
(
env_cg
->
constants
,
tv
);
ir_initializer_t
*
initializer
;
ir_mode
*
mode
;
ir_type
*
type
;
ir_type
*
glob
;
if
(
entity
!=
NULL
)
return
entity
;
mode
=
get_tarval_mode
(
tv
);
type
=
get_type_for_mode
(
mode
);
glob
=
get_glob_type
();
entity
=
new_entity
(
glob
,
id_unique
(
"C%u"
),
type
);
set_entity_visibility
(
entity
,
ir_visibility_private
);
add_entity_linkage
(
entity
,
IR_LINKAGE_CONSTANT
);
initializer
=
create_initializer_tarval
(
tv
);
set_entity_initializer
(
entity
,
initializer
);
pmap_insert
(
env_cg
->
constants
,
tv
,
entity
);
return
entity
;
}
/**
* Transforms a Const node.
*
...
...
@@ -565,14 +590,20 @@ static ir_node *gen_Minus(ir_node *node)
*/
static
ir_node
*
gen_Const
(
ir_node
*
node
)
{
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
ir_mode
*
mode
=
get_irn_mode
(
node
);
dbg_info
*
dbg
=
get_irn_dbg_info
(
node
);
(
void
)
dbg
;
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
ir_mode
*
mode
=
get_irn_mode
(
node
);
if
(
mode_is_float
(
mode
))
{
return
create_fp_const_graph
(
node
,
block
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
tarval
*
tv
=
get_Const_tarval
(
node
);
ir_entity
*
entity
=
create_float_const_entity
(
tv
);
ir_node
*
addr
=
make_addr
(
dbgi
,
entity
);
ir_node
*
mem
=
new_NoMem
();
ir_node
*
new_op
=
new_bd_sparc_Ldf
(
dbgi
,
block
,
addr
,
mem
,
mode
,
NULL
,
0
,
0
,
false
);
ir_node
*
proj
=
new_Proj
(
new_op
,
mode
,
pn_sparc_Ldf_res
);
return
proj
;
}
return
create_const_graph
(
node
,
block
);
...
...
@@ -806,14 +837,10 @@ static ir_node *gen_Cmp(ir_node *node)
*/
static
ir_node
*
gen_SymConst
(
ir_node
*
node
)
{
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
ir_entity
*
entity
=
get_SymConst_entity
(
node
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
new_node
;
new_node
=
new_bd_sparc_SymConst
(
dbgi
,
block
,
entity
);
be_dep_on_frame
(
new_node
);
return
new_node
;
return
make_addr
(
dbgi
,
entity
);
}
/**
...
...
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