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
2a474c6c
Commit
2a474c6c
authored
May 16, 2014
by
Matthias Braun
Browse files
arm: perform prolog/epilogue lowering
parent
23b80d8b
Changes
6
Hide whitespace changes
Inline
Side-by-side
ir/be/arm/arm_emitter.c
View file @
2a474c6c
...
@@ -657,32 +657,6 @@ static void emit_be_MemPerm(const ir_node *node)
...
@@ -657,32 +657,6 @@ static void emit_be_MemPerm(const ir_node *node)
assert
(
sp_change
==
0
);
assert
(
sp_change
==
0
);
}
}
static
void
emit_arm_Start
(
const
ir_node
*
node
)
{
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
size
=
get_type_size_bytes
(
frame_type
);
/* allocate stackframe */
if
(
size
>
0
)
{
arm_emitf
(
node
,
"sub sp, sp, #0x%X"
,
size
);
}
}
static
void
emit_arm_Return
(
const
ir_node
*
node
)
{
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
size
=
get_type_size_bytes
(
frame_type
);
/* deallocate stackframe */
if
(
size
>
0
)
{
arm_emitf
(
node
,
"add sp, sp, #0x%X"
,
size
);
}
arm_emitf
(
node
,
"mov pc, lr"
);
}
static
void
emit_arm_Jmp
(
const
ir_node
*
node
)
static
void
emit_arm_Jmp
(
const
ir_node
*
node
)
{
{
ir_node
*
block
,
*
next_block
;
ir_node
*
block
,
*
next_block
;
...
@@ -720,18 +694,15 @@ static void arm_register_emitters(void)
...
@@ -720,18 +694,15 @@ static void arm_register_emitters(void)
be_set_emitter
(
op_arm_fConst
,
emit_arm_fConst
);
be_set_emitter
(
op_arm_fConst
,
emit_arm_fConst
);
be_set_emitter
(
op_arm_FrameAddr
,
emit_arm_FrameAddr
);
be_set_emitter
(
op_arm_FrameAddr
,
emit_arm_FrameAddr
);
be_set_emitter
(
op_arm_Jmp
,
emit_arm_Jmp
);
be_set_emitter
(
op_arm_Jmp
,
emit_arm_Jmp
);
be_set_emitter
(
op_arm_Return
,
emit_arm_Return
);
be_set_emitter
(
op_arm_Start
,
be_emit_nothing
);
be_set_emitter
(
op_arm_Start
,
emit_arm_Start
);
be_set_emitter
(
op_arm_SwitchJmp
,
emit_arm_SwitchJmp
);
be_set_emitter
(
op_arm_SwitchJmp
,
emit_arm_SwitchJmp
);
be_set_emitter
(
op_be_Copy
,
emit_be_Copy
);
be_set_emitter
(
op_be_Copy
,
emit_be_Copy
);
be_set_emitter
(
op_be_CopyKeep
,
emit_be_Copy
);
be_set_emitter
(
op_be_CopyKeep
,
emit_be_Copy
);
be_set_emitter
(
op_be_IncSP
,
emit_be_IncSP
);
be_set_emitter
(
op_be_IncSP
,
emit_be_IncSP
);
be_set_emitter
(
op_be_Keep
,
be_emit_nothing
);
be_set_emitter
(
op_be_MemPerm
,
emit_be_MemPerm
);
be_set_emitter
(
op_be_MemPerm
,
emit_be_MemPerm
);
be_set_emitter
(
op_be_Perm
,
emit_be_Perm
);
be_set_emitter
(
op_be_Perm
,
emit_be_Perm
);
be_set_emitter
(
op_Phi
,
be_emit_nothing
);
/* no need to emit anything for the following nodes */
be_set_emitter
(
op_Phi
,
be_emit_nothing
);
be_set_emitter
(
op_be_Keep
,
be_emit_nothing
);
}
}
/**
/**
...
...
ir/be/arm/arm_finish.c
0 → 100644
View file @
2a474c6c
/*
* This file is part of libFirm.
* Copyright (C) 2014 University of Karlsruhe.
*/
/**
* @file
* @brief arm graph touchups before emitting
* @author Matthias Braun
*/
#include "bearch_arm_t.h"
#include "firm_types.h"
#include "irgwalk.h"
#include "bespillslots.h"
#include "bestack.h"
#include "be_types.h"
#include "beirg.h"
#include "benode.h"
#include "besched.h"
#include "arm_new_nodes.h"
#include "gen_arm_regalloc_if.h"
#include "arm_optimize.h"
static
bool
is_frame_load
(
const
ir_node
*
node
)
{
return
is_arm_Ldr
(
node
)
||
is_arm_Ldf
(
node
);
}
static
void
arm_collect_frame_entity_nodes
(
ir_node
*
node
,
void
*
data
)
{
if
(
!
is_frame_load
(
node
))
return
;
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
if
(
!
attr
->
is_frame_entity
)
return
;
const
ir_entity
*
entity
=
attr
->
entity
;
if
(
entity
!=
NULL
)
return
;
const
ir_mode
*
mode
=
attr
->
load_store_mode
;
const
ir_type
*
type
=
get_type_for_mode
(
mode
);
be_fec_env_t
*
env
=
(
be_fec_env_t
*
)
data
;
be_load_needs_frame_entity
(
env
,
node
,
type
);
}
static
void
arm_set_frame_entity
(
ir_node
*
node
,
ir_entity
*
entity
,
const
ir_type
*
type
)
{
(
void
)
type
;
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr
(
node
);
attr
->
entity
=
entity
;
}
static
void
introduce_epilog
(
ir_node
*
ret
)
{
arch_register_t
const
*
const
sp_reg
=
&
arm_registers
[
REG_SP
];
assert
(
arch_get_irn_register_req_in
(
ret
,
n_arm_Return_sp
)
==
sp_reg
->
single_req
);
ir_node
*
const
sp
=
get_irn_n
(
ret
,
n_arm_Return_sp
);
ir_node
*
const
block
=
get_nodes_block
(
ret
);
ir_graph
*
const
irg
=
get_irn_irg
(
ret
);
ir_type
*
const
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
const
frame_size
=
get_type_size_bytes
(
frame_type
);
ir_node
*
const
incsp
=
be_new_IncSP
(
sp_reg
,
block
,
sp
,
-
frame_size
,
0
);
set_irn_n
(
ret
,
n_arm_Return_sp
,
incsp
);
sched_add_before
(
ret
,
incsp
);
}
static
void
introduce_prolog_epilog
(
ir_graph
*
irg
)
{
/* introduce epilog for every return node */
foreach_irn_in
(
get_irg_end_block
(
irg
),
i
,
ret
)
{
assert
(
is_arm_Return
(
ret
));
introduce_epilog
(
ret
);
}
const
arch_register_t
*
sp_reg
=
&
arm_registers
[
REG_SP
];
ir_node
*
start
=
get_irg_start
(
irg
);
ir_node
*
block
=
get_nodes_block
(
start
);
ir_node
*
initial_sp
=
be_get_initial_reg_value
(
irg
,
sp_reg
);
ir_node
*
schedpoint
=
start
;
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
frame_size
=
get_type_size_bytes
(
frame_type
);
while
(
be_is_Keep
(
sched_next
(
schedpoint
)))
schedpoint
=
sched_next
(
schedpoint
);
ir_node
*
const
incsp
=
be_new_IncSP
(
sp_reg
,
block
,
initial_sp
,
frame_size
,
0
);
edges_reroute_except
(
initial_sp
,
incsp
,
incsp
);
sched_add_after
(
schedpoint
,
incsp
);
}
void
arm_finish_graph
(
ir_graph
*
irg
)
{
be_stack_layout_t
*
stack_layout
=
be_get_irg_stack_layout
(
irg
);
bool
at_begin
=
stack_layout
->
sp_relative
;
be_fec_env_t
*
fec_env
=
be_new_frame_entity_coalescer
(
irg
);
irg_walk_graph
(
irg
,
NULL
,
arm_collect_frame_entity_nodes
,
fec_env
);
be_assign_entities
(
fec_env
,
arm_set_frame_entity
,
at_begin
);
be_free_frame_entity_coalescer
(
fec_env
);
introduce_prolog_epilog
(
irg
);
/* fix stack entity offsets */
be_abi_fix_stack_nodes
(
irg
);
be_abi_fix_stack_bias
(
irg
);
/* do peephole optimizations and fix stack offsets */
arm_peephole_optimization
(
irg
);
}
ir/be/arm/arm_nodes_attr.h
View file @
2a474c6c
...
@@ -46,6 +46,11 @@ enum fpa_immediates {
...
@@ -46,6 +46,11 @@ enum fpa_immediates {
fpa_max
fpa_max
};
};
enum
n_arm_Return
{
n_arm_Return_mem
=
0
,
n_arm_Return_sp
=
1
,
};
/** Generic ARM node attributes. */
/** Generic ARM node attributes. */
typedef
struct
arm_attr_t
{
typedef
struct
arm_attr_t
{
except_attr
exc
;
/**< the exception attribute. MUST be the first one. */
except_attr
exc
;
/**< the exception attribute. MUST be the first one. */
...
...
ir/be/arm/arm_spec.pl
View file @
2a474c6c
...
@@ -556,6 +556,7 @@ Return => {
...
@@ -556,6 +556,7 @@ Return => {
arity
=>
"
variable
",
arity
=>
"
variable
",
mode
=>
"
mode_X
",
mode
=>
"
mode_X
",
reg_req
=>
{
out
=>
[
"
none
"
]
},
reg_req
=>
{
out
=>
[
"
none
"
]
},
emit
=>
"
bx lr
",
},
},
);
# end of %nodes
);
# end of %nodes
ir/be/arm/bearch_arm.c
View file @
2a474c6c
...
@@ -31,7 +31,6 @@
...
@@ -31,7 +31,6 @@
#include "be.h"
#include "be.h"
#include "bemodule.h"
#include "bemodule.h"
#include "beirg.h"
#include "beirg.h"
#include "bespillslots.h"
#include "bespillutil.h"
#include "bespillutil.h"
#include "beutil.h"
#include "beutil.h"
#include "begnuas.h"
#include "begnuas.h"
...
@@ -84,14 +83,7 @@ static void arm_set_stack_bias(ir_node *irn, int bias)
...
@@ -84,14 +83,7 @@ static void arm_set_stack_bias(ir_node *irn, int bias)
static
int
arm_get_sp_bias
(
const
ir_node
*
node
)
static
int
arm_get_sp_bias
(
const
ir_node
*
node
)
{
{
if
(
is_arm_Start
(
node
))
{
(
void
)
node
;
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
size
=
get_type_size_bytes
(
frame_type
);
return
size
;
}
else
if
(
is_arm_Return
(
node
))
{
return
SP_BIAS_RESET
;
}
return
0
;
return
0
;
}
}
...
@@ -124,37 +116,6 @@ static void arm_prepare_graph(ir_graph *irg)
...
@@ -124,37 +116,6 @@ static void arm_prepare_graph(ir_graph *irg)
place_code
(
irg
);
place_code
(
irg
);
}
}
static
bool
is_frame_load
(
const
ir_node
*
node
)
{
return
is_arm_Ldr
(
node
)
||
is_arm_Ldf
(
node
);
}
static
void
arm_collect_frame_entity_nodes
(
ir_node
*
node
,
void
*
data
)
{
if
(
!
is_frame_load
(
node
))
return
;
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
if
(
!
attr
->
is_frame_entity
)
return
;
const
ir_entity
*
entity
=
attr
->
entity
;
if
(
entity
!=
NULL
)
return
;
const
ir_mode
*
mode
=
attr
->
load_store_mode
;
const
ir_type
*
type
=
get_type_for_mode
(
mode
);
be_fec_env_t
*
env
=
(
be_fec_env_t
*
)
data
;
be_load_needs_frame_entity
(
env
,
node
,
type
);
}
static
void
arm_set_frame_entity
(
ir_node
*
node
,
ir_entity
*
entity
,
const
ir_type
*
type
)
{
(
void
)
type
;
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr
(
node
);
attr
->
entity
=
entity
;
}
static
ir_node
*
arm_new_reload
(
ir_node
*
value
,
ir_node
*
spill
,
ir_node
*
before
)
static
ir_node
*
arm_new_reload
(
ir_node
*
value
,
ir_node
*
spill
,
ir_node
*
before
)
{
{
ir_node
*
block
=
get_block
(
before
);
ir_node
*
block
=
get_block
(
before
);
...
@@ -185,22 +146,7 @@ static ir_node *arm_new_spill(ir_node *value, ir_node *after)
...
@@ -185,22 +146,7 @@ static ir_node *arm_new_spill(ir_node *value, ir_node *after)
static
void
arm_emit
(
ir_graph
*
irg
)
static
void
arm_emit
(
ir_graph
*
irg
)
{
{
be_stack_layout_t
*
stack_layout
=
be_get_irg_stack_layout
(
irg
);
arm_finish_graph
(
irg
);
bool
at_begin
=
stack_layout
->
sp_relative
;
be_fec_env_t
*
fec_env
=
be_new_frame_entity_coalescer
(
irg
);
irg_walk_graph
(
irg
,
NULL
,
arm_collect_frame_entity_nodes
,
fec_env
);
be_assign_entities
(
fec_env
,
arm_set_frame_entity
,
at_begin
);
be_free_frame_entity_coalescer
(
fec_env
);
/* fix stack entity offsets */
be_abi_fix_stack_nodes
(
irg
);
be_abi_fix_stack_bias
(
irg
);
/* do peephole optimizations and fix stack offsets */
arm_peephole_optimization
(
irg
);
/* emit code */
arm_emit_function
(
irg
);
arm_emit_function
(
irg
);
}
}
...
...
ir/be/arm/bearch_arm_t.h
View file @
2a474c6c
...
@@ -121,4 +121,6 @@ struct arm_isa_t {
...
@@ -121,4 +121,6 @@ struct arm_isa_t {
int
fpu_arch
;
/**< FPU architecture */
int
fpu_arch
;
/**< FPU architecture */
};
};
void
arm_finish_graph
(
ir_graph
*
irg
);
#endif
#endif
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