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
ff73e39f
Commit
ff73e39f
authored
Mar 12, 2006
by
Christian Würdig
Browse files
addapted to new be abi and added code changes
parent
65c24f5f
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/be/TEMPLATE/TEMPLATE_emitter.c
View file @
ff73e39f
...
...
@@ -86,8 +86,6 @@ static const arch_register_t *get_out_reg(ir_node *irn, int pos) {
ir_node
*
proj
;
const
arch_register_t
*
reg
=
NULL
;
assert
(
get_irn_n_edges
(
irn
)
>
pos
&&
"Invalid OUT position"
);
/* 1st case: irn is not of mode_T, so it has only */
/* one OUT register -> good */
/* 2nd case: irn is of mode_T -> collect all Projs and ask the */
...
...
@@ -168,8 +166,7 @@ static int TEMPLATE_get_reg_name(lc_appendable_t *app,
buf
=
get_TEMPLATE_reg_name
(
X
,
nr
,
0
);
}
lc_appendable_chadd
(
app
,
'%'
);
return
lc_arg_append
(
app
,
occ
,
buf
,
strlen
(
buf
));
return
buf
?
lc_arg_append
(
app
,
occ
,
buf
,
strlen
(
buf
))
:
0
;
}
/**
...
...
@@ -270,66 +267,49 @@ static char *get_cfop_target(const ir_node *irn, char *buf) {
***********************************************************************************/
/**
* Emits code for a node.
* Enters the emitter functions for handled nodes into the generic
* pointer of an opcode.
*/
void
TEMPLATE_emit_node
(
ir_node
*
irn
,
void
*
env
)
{
emit_env_t
*
emit_env
=
env
;
firm_dbg_module_t
*
mod
=
emit_env
->
mod
;
FILE
*
F
=
emit_env
->
out
;
DBG
((
mod
,
LEVEL_1
,
"emitting code for %+F
\n
"
,
irn
));
#define BE_EMIT(a) if (is_TEMPLATE_##a(irn)) { emit_TEMPLATE_##a(irn, emit_env); return; }
BE_EMIT
(
Const
);
BE_EMIT
(
Add
);
BE_EMIT
(
Add_i
);
BE_EMIT
(
Sub
);
BE_EMIT
(
Sub_i
);
BE_EMIT
(
Minus
);
BE_EMIT
(
Inc
);
BE_EMIT
(
Dec
);
BE_EMIT
(
And
);
BE_EMIT
(
And_i
);
BE_EMIT
(
Or
);
BE_EMIT
(
Or_i
);
BE_EMIT
(
Eor
);
BE_EMIT
(
Eor_i
);
BE_EMIT
(
Not
);
static
void
TEMPLATE_register_emitters
(
void
)
{
BE_EMIT
(
Shl
);
BE_EMIT
(
Shl_i
);
BE_EMIT
(
Shr
);
BE_EMIT
(
Shr_i
);
BE_EMIT
(
RotL
);
BE_EMIT
(
RotL_i
);
BE_EMIT
(
RotR
);
/* some convienience macros to register additional emitter functions
(other than the generated ones) */
#define TEMPLATE_EMIT(a) op_TEMPLATE_##a->ops.generic = (op_func)emit_TEMPLATE_##a
#define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
#define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
BE_EMIT
(
Mul
);
BE_EMIT
(
Mul_i
);
/* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func
(
);
BE_EMIT
(
Store
);
BE_EMIT
(
Load
);
/* register all emitter functions defined in spec */
TEMPLATE_register_spec_emitters
(
);
/* generated floating point emitter */
BE_EMIT
(
fConst
);
/* register addtional emitter functions if needed */
BE_EMIT
(
fAdd
);
BE_EMIT
(
fSub
);
BE_EMIT
(
fMinus
);
#undef TEMPLATE_EMIT
#undef BE_EMIT
#undef EMIT
}
BE_EMIT
(
fMul
);
BE_EMIT
(
fDiv
);
BE_EMIT
(
fMin
);
BE_EMIT
(
fMax
);
/**
* Emits code for a node.
*/
void
TEMPLATE_emit_node
(
ir_node
*
irn
,
void
*
env
)
{
emit_env_t
*
emit_env
=
env
;
firm_dbg_module_t
*
mod
=
emit_env
->
mod
;
FILE
*
F
=
emit_env
->
out
;
ir_op
*
op
=
get_irn_op
(
irn
);
BE_EMIT
(
fLoad
);
BE_EMIT
(
fStore
);
DBG
((
mod
,
LEVEL_1
,
"emitting code for %+F
\n
"
,
irn
));
ir_fprintf
(
F
,
"
\t\t\t\t\t
/* %+F */
\n
"
,
irn
);
if
(
op
->
ops
.
generic
)
{
void
(
*
emit
)(
const
ir_node
*
,
void
*
)
=
(
void
(
*
)(
const
ir_node
*
,
void
*
))
op
->
ops
.
generic
;
(
*
emit
)(
irn
,
env
);
}
else
{
ir_fprintf
(
F
,
"
\t\t\t\t\t
/* %+F */
\n
"
,
irn
);
}
}
/**
...
...
@@ -352,7 +332,7 @@ void TEMPLATE_gen_block(ir_node *block, void *env) {
/**
* Emits code for function start.
*/
void
TEMPLATE_emit_
start
(
FILE
*
F
,
ir_graph
*
irg
)
{
void
TEMPLATE_emit_
func_prolog
(
FILE
*
F
,
ir_graph
*
irg
)
{
const
char
*
irg_name
=
get_entity_name
(
get_irg_entity
(
irg
));
/* TODO: emit function header */
...
...
@@ -361,7 +341,7 @@ void TEMPLATE_emit_start(FILE *F, ir_graph *irg) {
/**
* Emits code for function end
*/
void
TEMPLATE_emit_
end
(
FILE
*
F
,
ir_graph
*
irg
)
{
void
TEMPLATE_emit_
func_epilog
(
FILE
*
F
,
ir_graph
*
irg
)
{
const
char
*
irg_name
=
get_entity_name
(
get_irg_entity
(
irg
));
/* TODO: emit function end */
...
...
@@ -395,8 +375,11 @@ void TEMPLATE_gen_routine(FILE *F, ir_graph *irg, const TEMPLATE_code_gen_t *cg)
/* set the global arch_env (needed by print hooks) */
arch_env
=
cg
->
arch_env
;
TEMPLATE_emit_start
(
F
,
irg
);
/* register all emitter functions */
TEMPLATE_register_emitters
();
TEMPLATE_emit_func_prolog
(
F
,
irg
);
irg_block_walk_graph
(
irg
,
TEMPLATE_gen_labels
,
NULL
,
&
emit_env
);
irg_walk_blkwise_graph
(
irg
,
NULL
,
TEMPLATE_gen_block
,
&
emit_env
);
TEMPLATE_emit_
end
(
F
,
irg
);
TEMPLATE_emit_
func_epilog
(
F
,
irg
);
}
ir/be/TEMPLATE/bearch_TEMPLATE.c
View file @
ff73e39f
...
...
@@ -278,49 +278,14 @@ static void TEMPLATE_before_sched(void *self) {
}
static
void
TEMPLATE_before_ra
(
void
*
self
)
{
/* Some stuff you need to do
immediatly after
register allocation */
/* Some stuff you need to do
after scheduling but before
register allocation */
}
/**
* Creates a Store for a Spill
*/
static
ir_node
*
TEMPLATE_lower_spill
(
void
*
self
,
ir_node
*
spill
)
{
TEMPLATE_code_gen_t
*
cg
=
self
;
dbg_info
*
dbg
=
get_irn_dbg_info
(
spill
);
ir_node
*
block
=
get_nodes_block
(
spill
);
ir_node
*
ptr
=
get_irg_frame
(
cg
->
irg
);
ir_node
*
val
=
be_get_Spill_context
(
spill
);
ir_node
*
mem
=
new_rd_NoMem
(
cg
->
irg
);
ir_mode
*
mode
=
get_irn_mode
(
spill
);
ir_node
*
res
;
entity
*
ent
=
be_get_spill_entity
(
spill
);
unsigned
offs
=
get_entity_offset_bytes
(
ent
);
DB
((
cg
->
mod
,
LEVEL_1
,
"lower_spill: got offset %d for %+F
\n
"
,
offs
,
ent
));
/* TODO: create Store */
return
res
;
static
void
TEMPLATE_after_ra
(
void
*
self
)
{
/* Some stuff you need to do immediatly after register allocation */
}
/**
* Create a Load for a Spill
*/
static
ir_node
*
TEMPLATE_lower_reload
(
void
*
self
,
ir_node
*
reload
)
{
TEMPLATE_code_gen_t
*
cg
=
self
;
dbg_info
*
dbg
=
get_irn_dbg_info
(
reload
);
ir_node
*
block
=
get_nodes_block
(
reload
);
ir_node
*
ptr
=
get_irg_frame
(
cg
->
irg
);
ir_mode
*
mode
=
get_irn_mode
(
reload
);
ir_node
*
pred
=
get_irn_n
(
reload
,
0
);
tarval
*
tv
;
ir_node
*
res
;
/* TODO: create Load */
return
res
;
}
/**
* Emits the code, closes the output file and frees
...
...
@@ -354,8 +319,7 @@ static const arch_code_generator_if_t TEMPLATE_code_gen_if = {
TEMPLATE_prepare_graph
,
TEMPLATE_before_sched
,
/* before scheduling hook */
TEMPLATE_before_ra
,
/* before register allocation hook */
TEMPLATE_lower_spill
,
TEMPLATE_lower_reload
,
TEMPLATE_after_ra
,
/* after register allocation hook */
TEMPLATE_emit_and_done
};
...
...
@@ -504,12 +468,20 @@ void TEMPLATE_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t
ir_mode
*
mode
;
int
i
,
n
=
get_method_n_params
(
method_type
);
const
arch_register_t
*
reg
;
be_abi_call_flags_t
call_flags
;
/* set abi flags for calls */
call_flags
.
bits
.
left_to_right
=
0
;
call_flags
.
bits
.
store_args_sequential
=
1
;
call_flags
.
bits
.
try_omit_fp
=
1
;
call_flags
.
bits
.
fp_free
=
0
;
call_flags
.
bits
.
call_has_imm
=
1
;
/* get the between type and the frame pointer save entity */
between_type
=
get_between_type
();
/* set stack parameter passing style */
be_abi_call_set_flags
(
abi
,
BE_ABI_NONE
,
between_type
);
be_abi_call_set_flags
(
abi
,
call_flags
,
between_type
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
/* TODO: implement register parameter: */
...
...
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