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
60b3885b
Commit
60b3885b
authored
Jul 18, 2012
by
Matthias Braun
Browse files
introduce arm_emitf
parent
ba5f45d1
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/arm/arm_emitter.c
View file @
60b3885b
...
...
@@ -67,19 +67,19 @@ static void arm_emit_register(const arch_register_t *reg)
be_emit_string
(
arch_register_get_name
(
reg
));
}
void
arm_emit_source_register
(
const
ir_node
*
node
,
int
pos
)
static
void
arm_emit_source_register
(
const
ir_node
*
node
,
int
pos
)
{
const
arch_register_t
*
reg
=
arch_get_irn_register_in
(
node
,
pos
);
arm_emit_register
(
reg
);
}
void
arm_emit_dest_register
(
const
ir_node
*
node
,
int
pos
)
static
void
arm_emit_dest_register
(
const
ir_node
*
node
,
int
pos
)
{
const
arch_register_t
*
reg
=
arch_get_irn_register_out
(
node
,
pos
);
arm_emit_register
(
reg
);
}
void
arm_emit_offset
(
const
ir_node
*
node
)
static
void
arm_emit_offset
(
const
ir_node
*
node
)
{
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
assert
(
attr
->
base
.
is_load_store
);
...
...
@@ -102,19 +102,19 @@ static void arm_emit_fpa_postfix(const ir_mode *mode)
be_emit_char
(
c
);
}
void
arm_emit_float_load_store_mode
(
const
ir_node
*
node
)
static
void
arm_emit_float_load_store_mode
(
const
ir_node
*
node
)
{
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
arm_emit_fpa_postfix
(
attr
->
load_store_mode
);
}
void
arm_emit_float_arithmetic_mode
(
const
ir_node
*
node
)
static
void
arm_emit_float_arithmetic_mode
(
const
ir_node
*
node
)
{
const
arm_farith_attr_t
*
attr
=
get_arm_farith_attr_const
(
node
);
arm_emit_fpa_postfix
(
attr
->
mode
);
}
void
arm_emit_symconst
(
const
ir_node
*
node
)
static
void
arm_emit_symconst
(
const
ir_node
*
node
)
{
const
arm_SymConst_attr_t
*
symconst
=
get_arm_SymConst_attr_const
(
node
);
ir_entity
*
entity
=
symconst
->
entity
;
...
...
@@ -124,7 +124,7 @@ void arm_emit_symconst(const ir_node *node)
/* TODO do something with offset */
}
void
arm_emit_load_mode
(
const
ir_node
*
node
)
static
void
arm_emit_load_mode
(
const
ir_node
*
node
)
{
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
ir_mode
*
mode
=
attr
->
load_store_mode
;
...
...
@@ -139,7 +139,7 @@ void arm_emit_load_mode(const ir_node *node)
}
}
void
arm_emit_store_mode
(
const
ir_node
*
node
)
static
void
arm_emit_store_mode
(
const
ir_node
*
node
)
{
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
ir_mode
*
mode
=
attr
->
load_store_mode
;
...
...
@@ -178,7 +178,7 @@ static void emit_shf_mod_name(arm_shift_modifier_t mod)
panic
(
"can't emit this shf_mod_name %d"
,
(
int
)
mod
);
}
void
arm_emit_shifter_operand
(
const
ir_node
*
node
)
static
void
arm_emit_shifter_operand
(
const
ir_node
*
node
)
{
const
arm_shifter_operand_t
*
attr
=
get_arm_shifter_operand_attr_const
(
node
);
...
...
@@ -250,6 +250,146 @@ static void emit_constant_name(const sym_or_tv_t *entry)
be_emit_irprintf
(
"%sC%u"
,
be_gas_get_private_prefix
(),
entry
->
label
);
}
/**
* Returns the target block for a control flow node.
*/
static
ir_node
*
get_cfop_target_block
(
const
ir_node
*
irn
)
{
return
(
ir_node
*
)
get_irn_link
(
irn
);
}
/**
* Emit the target label for a control flow node.
*/
static
void
arm_emit_cfop_target
(
const
ir_node
*
irn
)
{
ir_node
*
block
=
get_cfop_target_block
(
irn
);
be_gas_emit_block_name
(
block
);
}
void
arm_emitf
(
const
ir_node
*
node
,
const
char
*
format
,
...)
{
va_list
ap
;
va_start
(
ap
,
format
);
be_emit_char
(
'\t'
);
for
(;;)
{
const
char
*
start
=
format
;
while
(
*
format
!=
'%'
&&
*
format
!=
'\0'
)
++
format
;
be_emit_string_len
(
start
,
format
-
start
);
if
(
*
format
==
'\0'
)
break
;
++
format
;
switch
(
*
format
++
)
{
case
'%'
:
be_emit_char
(
'%'
);
break
;
case
'S'
:
{
if
(
*
format
<
'0'
||
'9'
<=
*
format
)
goto
unknown
;
unsigned
const
pos
=
*
format
++
-
'0'
;
arm_emit_source_register
(
node
,
pos
);
break
;
}
case
'D'
:
{
if
(
*
format
<
'0'
||
'9'
<=
*
format
)
goto
unknown
;
unsigned
const
pos
=
*
format
++
-
'0'
;
arm_emit_dest_register
(
node
,
pos
);
break
;
}
case
'I'
:
arm_emit_symconst
(
node
);
break
;
case
'o'
:
arm_emit_offset
(
node
);
break
;
case
'O'
:
arm_emit_shifter_operand
(
node
);
break
;
case
'C'
:
{
const
sym_or_tv_t
*
name
=
va_arg
(
ap
,
const
sym_or_tv_t
*
);
emit_constant_name
(
name
);
break
;
}
case
'm'
:
{
ir_mode
*
mode
=
va_arg
(
ap
,
ir_mode
*
);
arm_emit_fpa_postfix
(
mode
);
break
;
}
case
'M'
:
switch
(
*
format
++
)
{
case
'L'
:
arm_emit_load_mode
(
node
);
break
;
case
'S'
:
arm_emit_store_mode
(
node
);
break
;
case
'A'
:
arm_emit_float_arithmetic_mode
(
node
);
break
;
case
'F'
:
arm_emit_float_load_store_mode
(
node
);
break
;
default:
--
format
;
goto
unknown
;
}
break
;
case
'X'
:
{
int
num
=
va_arg
(
ap
,
int
);
be_emit_irprintf
(
"%X"
,
num
);
break
;
}
case
'u'
:
{
unsigned
num
=
va_arg
(
ap
,
unsigned
);
be_emit_irprintf
(
"%u"
,
num
);
break
;
}
case
'd'
:
{
int
num
=
va_arg
(
ap
,
int
);
be_emit_irprintf
(
"%d"
,
num
);
break
;
}
case
's'
:
{
const
char
*
string
=
va_arg
(
ap
,
const
char
*
);
be_emit_string
(
string
);
break
;
}
case
'r'
:
{
arch_register_t
*
reg
=
va_arg
(
ap
,
arch_register_t
*
);
arm_emit_register
(
reg
);
break
;
}
case
't'
:
{
const
ir_node
*
n
=
va_arg
(
ap
,
const
ir_node
*
);
arm_emit_cfop_target
(
n
);
break
;
}
case
'\n'
:
be_emit_char
(
'\n'
);
be_emit_write_line
();
be_emit_char
(
'\t'
);
break
;
default:
unknown:
panic
(
"unknown format conversion in arm_emitf()"
);
}
}
va_end
(
ap
);
be_emit_finish_line_gas
(
node
);
}
/**
* Emit a SymConst.
*/
...
...
@@ -268,24 +408,13 @@ static void emit_arm_SymConst(const ir_node *irn)
}
/* load the symbol indirect */
be_emit_cstring
(
"
\t
ldr "
);
arm_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
emit_constant_name
(
entry
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"ldr %D0, %C"
,
entry
);
}
static
void
emit_arm_FrameAddr
(
const
ir_node
*
irn
)
{
const
arm_SymConst_attr_t
*
attr
=
get_arm_SymConst_attr_const
(
irn
);
be_emit_cstring
(
"
\t
add "
);
arm_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
be_emit_irprintf
(
"#0x%X"
,
attr
->
fp_offset
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"add %D0, %S0, #0x%X"
,
attr
->
fp_offset
);
}
/**
...
...
@@ -293,28 +422,20 @@ static void emit_arm_FrameAddr(const ir_node *irn)
*/
static
void
emit_arm_fConst
(
const
ir_node
*
irn
)
{
sym_or_tv_t
key
,
*
entry
;
ir_mode
*
mode
;
sym_or_tv_t
key
;
key
.
u
.
tv
=
get_fConst_value
(
irn
);
key
.
is_entity
=
false
;
key
.
label
=
0
;
entry
=
set_insert
(
sym_or_tv_t
,
sym_or_tv
,
&
key
,
sizeof
(
key
),
hash_ptr
(
key
.
u
.
generic
));
sym_or_tv_t
*
entry
=
set_insert
(
sym_or_tv_t
,
sym_or_tv
,
&
key
,
sizeof
(
key
),
hash_ptr
(
key
.
u
.
generic
));
if
(
entry
->
label
==
0
)
{
/* allocate a label */
entry
->
label
=
get_unique_label
();
}
/* load the tarval indirect */
mode
=
get_irn_mode
(
irn
);
be_emit_cstring
(
"
\t
ldf"
);
arm_emit_fpa_postfix
(
mode
);
be_emit_char
(
' '
);
arm_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
emit_constant_name
(
entry
);
be_emit_finish_line_gas
(
irn
);
ir_mode
*
mode
=
get_irn_mode
(
irn
);
arm_emitf
(
irn
,
"ldf%m %D0, %C"
,
mode
,
entry
);
}
/**
...
...
@@ -325,24 +446,6 @@ static ir_node *sched_next_block(const ir_node *block)
return
(
ir_node
*
)
get_irn_link
(
block
);
}
/**
* Returns the target block for a control flow node.
*/
static
ir_node
*
get_cfop_target_block
(
const
ir_node
*
irn
)
{
return
(
ir_node
*
)
get_irn_link
(
irn
);
}
/**
* Emit the target label for a control flow node.
*/
static
void
arm_emit_cfop_target
(
const
ir_node
*
irn
)
{
ir_node
*
block
=
get_cfop_target_block
(
irn
);
be_gas_emit_block_name
(
block
);
}
/**
* Emit a Compare with conditional branch.
*/
...
...
@@ -404,21 +507,14 @@ static void emit_arm_B(const ir_node *irn)
}
/* emit the true proj */
be_emit_irprintf
(
"
\t
b%s "
,
suffix
);
arm_emit_cfop_target
(
proj_true
);
be_emit_finish_line_gas
(
proj_true
);
arm_emitf
(
irn
,
"b%s %t"
,
suffix
,
proj_true
);
if
(
get_cfop_target_block
(
proj_false
)
==
next_block
)
{
if
(
be_options
.
verbose_asm
)
{
be_emit_cstring
(
"
\t
/* fallthrough to "
);
arm_emit_cfop_target
(
proj_false
);
be_emit_cstring
(
" */"
);
be_emit_finish_line_gas
(
proj_false
);
arm_emitf
(
irn
,
"/* fallthrough to %t */"
,
proj_false
);
}
}
else
{
be_emit_cstring
(
"
\t
b "
);
arm_emit_cfop_target
(
proj_false
);
be_emit_finish_line_gas
(
proj_false
);
arm_emitf
(
irn
,
"b %t"
,
proj_false
);
}
}
...
...
@@ -438,11 +534,6 @@ static void emit_arm_CopyB(const ir_node *irn)
{
const
arm_CopyB_attr_t
*
attr
=
get_arm_CopyB_attr_const
(
irn
);
unsigned
size
=
attr
->
size
;
const
char
*
tgt
=
arch_register_get_name
(
arch_get_irn_register_in
(
irn
,
0
));
const
char
*
src
=
arch_register_get_name
(
arch_get_irn_register_in
(
irn
,
1
));
const
char
*
t0
,
*
t1
,
*
t2
,
*
t3
;
const
arch_register_t
*
tmpregs
[
4
];
/* collect the temporary registers and sort them, we need ascending order */
...
...
@@ -454,27 +545,9 @@ static void emit_arm_CopyB(const ir_node *irn)
/* Note: R12 is always the last register because the RA did not assign higher ones */
qsort
((
void
*
)
tmpregs
,
3
,
sizeof
(
tmpregs
[
0
]),
reg_cmp
);
/* need ascending order */
t0
=
arch_register_get_name
(
tmpregs
[
0
]);
t1
=
arch_register_get_name
(
tmpregs
[
1
]);
t2
=
arch_register_get_name
(
tmpregs
[
2
]);
t3
=
arch_register_get_name
(
tmpregs
[
3
]);
if
(
be_options
.
verbose_asm
)
{
be_emit_cstring
(
"/* MemCopy ("
);
be_emit_string
(
src
);
be_emit_cstring
(
")->("
);
arm_emit_source_register
(
irn
,
0
);
be_emit_irprintf
(
" [%u bytes], Uses "
,
size
);
be_emit_string
(
t0
);
be_emit_cstring
(
", "
);
be_emit_string
(
t1
);
be_emit_cstring
(
", "
);
be_emit_string
(
t2
);
be_emit_cstring
(
", and "
);
be_emit_string
(
t3
);
be_emit_cstring
(
"*/"
);
be_emit_finish_line_gas
(
NULL
);
arm_emitf
(
irn
,
"/* MemCopy (%S1)->(%S0) [%u bytes], Uses %r, %r, %r and %r */"
,
size
,
tmpregs
[
0
],
tmpregs
[
1
],
tmpregs
[
2
],
tmpregs
[
3
]);
}
assert
(
size
>
0
&&
"CopyB needs size > 0"
);
...
...
@@ -489,90 +562,22 @@ static void emit_arm_CopyB(const ir_node *irn)
case
0
:
break
;
case
1
:
be_emit_cstring
(
"
\t
ldr "
);
be_emit_string
(
t3
);
be_emit_cstring
(
", ["
);
be_emit_string
(
src
);
be_emit_cstring
(
", #0]"
);
be_emit_finish_line_gas
(
NULL
);
be_emit_cstring
(
"
\t
str "
);
be_emit_string
(
t3
);
be_emit_cstring
(
", ["
);
be_emit_string
(
tgt
);
be_emit_cstring
(
", #0]"
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"ldr %r, [%S1, #0]"
,
tmpregs
[
3
]);
arm_emitf
(
irn
,
"str %r, [%S0, #0]"
,
tmpregs
[
3
]);
break
;
case
2
:
be_emit_cstring
(
"
\t
ldmia "
);
be_emit_string
(
src
);
be_emit_cstring
(
"!, {"
);
be_emit_string
(
t0
);
be_emit_cstring
(
", "
);
be_emit_string
(
t1
);
be_emit_char
(
'}'
);
be_emit_finish_line_gas
(
NULL
);
be_emit_cstring
(
"
\t
stmia "
);
be_emit_string
(
tgt
);
be_emit_cstring
(
"!, {"
);
be_emit_string
(
t0
);
be_emit_cstring
(
", "
);
be_emit_string
(
t1
);
be_emit_char
(
'}'
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"ldmia %S1!, {%r, %r}"
,
tmpregs
[
0
],
tmpregs
[
1
]);
arm_emitf
(
irn
,
"stmia %S0!, {%r, %r}"
,
tmpregs
[
0
],
tmpregs
[
1
]);
break
;
case
3
:
be_emit_cstring
(
"
\t
ldmia "
);
be_emit_string
(
src
);
be_emit_cstring
(
"!, {"
);
be_emit_string
(
t0
);
be_emit_cstring
(
", "
);
be_emit_string
(
t1
);
be_emit_cstring
(
", "
);
be_emit_string
(
t2
);
be_emit_char
(
'}'
);
be_emit_finish_line_gas
(
NULL
);
be_emit_cstring
(
"
\t
stmia "
);
be_emit_string
(
tgt
);
be_emit_cstring
(
"!, {"
);
be_emit_string
(
t0
);
be_emit_cstring
(
", "
);
be_emit_string
(
t1
);
be_emit_cstring
(
", "
);
be_emit_string
(
t2
);
be_emit_char
(
'}'
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"ldmia %S1!, {%r, %r, %r}"
,
tmpregs
[
0
],
tmpregs
[
1
],
tmpregs
[
2
]);
arm_emitf
(
irn
,
"stmia %S0!, {%r, %r, %r}"
,
tmpregs
[
0
],
tmpregs
[
1
],
tmpregs
[
2
]);
break
;
}
size
>>=
2
;
while
(
size
)
{
be_emit_cstring
(
"
\t
ldmia "
);
be_emit_string
(
src
);
be_emit_cstring
(
"!, {"
);
be_emit_string
(
t0
);
be_emit_cstring
(
", "
);
be_emit_string
(
t1
);
be_emit_cstring
(
", "
);
be_emit_string
(
t2
);
be_emit_cstring
(
", "
);
be_emit_string
(
t3
);
be_emit_char
(
'}'
);
be_emit_finish_line_gas
(
NULL
);
be_emit_cstring
(
"
\t
stmia "
);
be_emit_string
(
tgt
);
be_emit_cstring
(
"!, {"
);
be_emit_string
(
t0
);
be_emit_cstring
(
", "
);
be_emit_string
(
t1
);
be_emit_cstring
(
", "
);
be_emit_string
(
t2
);
be_emit_cstring
(
", "
);
be_emit_string
(
t3
);
be_emit_char
(
'}'
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"ldmia %S1!, {%r, %r, %r}"
,
tmpregs
[
0
],
tmpregs
[
1
],
tmpregs
[
2
],
tmpregs
[
3
]);
arm_emitf
(
irn
,
"stmia %S0!, {%r, %r, %r}"
,
tmpregs
[
0
],
tmpregs
[
1
],
tmpregs
[
2
],
tmpregs
[
3
]);
--
size
;
}
}
...
...
@@ -580,10 +585,7 @@ static void emit_arm_CopyB(const ir_node *irn)
static
void
emit_arm_SwitchJmp
(
const
ir_node
*
irn
)
{
const
arm_SwitchJmp_attr_t
*
attr
=
get_arm_SwitchJmp_attr_const
(
irn
);
be_emit_cstring
(
"
\t
ldrls pc, [pc, "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", asl #2]"
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"ldrls pc, [pc, %S0, asl #2]"
);
be_emit_jump_table
(
irn
,
attr
->
table
,
NULL
,
get_cfop_target_block
);
}
...
...
@@ -593,22 +595,15 @@ static void emit_be_IncSP(const ir_node *irn)
{
int
offs
=
-
be_get_IncSP_offset
(
irn
);
if
(
offs
!=
0
)
{
if
(
offs
<
0
)
{
be_emit_cstring
(
"
\t
sub "
);
offs
=
-
offs
;
}
else
{
be_emit_cstring
(
"
\t
add "
);
}
arm_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_irprintf
(
", #0x%X"
,
offs
);
be_emit_finish_line_gas
(
irn
);
}
else
{
/* omitted IncSP(0) */
if
(
offs
==
0
)
return
;
const
char
*
op
=
"add"
;
if
(
offs
<
0
)
{
op
=
"sub"
;
offs
=
-
offs
;
}
arm_emitf
(
irn
,
"%s %D0, %S0, #0x%X"
,
op
,
offs
);
}
static
void
emit_be_Copy
(
const
ir_node
*
irn
)
...
...
@@ -622,21 +617,12 @@ static void emit_be_Copy(const ir_node *irn)
if
(
mode_is_float
(
mode
))
{
if
(
USE_FPA
(
isa
))
{
be_emit_cstring
(
"
\t
mvf"
);
be_emit_char
(
' '
);
arm_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"mvf %D0, %S0"
);
}
else
{
panic
(
"emit_be_Copy: move not supported for this mode"
);
}
}
else
if
(
mode_is_data
(
mode
))
{
be_emit_cstring
(
"
\t
mov "
);
arm_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"mov %D0, %S0"
);
}
else
{
panic
(
"emit_be_Copy: move not supported for this mode"
);
}
...
...
@@ -644,29 +630,10 @@ static void emit_be_Copy(const ir_node *irn)
static
void
emit_be_Perm
(
const
ir_node
*
irn
)
{
be_emit_cstring
(
"
\t
eor "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
1
);
be_emit_finish_line_gas
(
NULL
);
be_emit_cstring
(
"
\t
eor "
);
arm_emit_source_register
(
irn
,
1
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
1
);
be_emit_finish_line_gas
(
NULL
);
be_emit_cstring
(
"
\t
eor "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
arm_emit_source_register
(
irn
,
1
);
be_emit_finish_line_gas
(
irn
);
arm_emitf
(
irn
,
"eor %S0, %S0, %S1
\n
"
"eor %S1, %S0, %S1
\n
"
"eor %S0, %S0, %S1"
);
}
static
void
emit_be_MemPerm
(
const
ir_node
*
node
)
...
...
@@ -683,31 +650,23 @@ static void emit_be_MemPerm(const ir_node *node)
panic
(
"memperm with more than 12 inputs not supported yet"
);
for
(
i
=
0
;
i
<
memperm_arity
;
++
i
)
{
int
offset
;
ir_entity
*
entity
=
be_get_MemPerm_in_entity
(
node
,
i
);
/* spill register */
be_emit_irprintf
(
"
\t
str r%d, [sp, #-4]!"
,
i
);
be_emit_finish_line_gas
(
node
);
arm_emitf
(
node
,
"str r%d, [sp, #-4]!"
,
i
);
sp_change
+=
4
;
/* load from entity */
offset
=
get_entity_offset
(
entity
)
+
sp_change
;
be_emit_irprintf
(
"
\t
ldr r%d, [sp, #%d]"
,
i
,
offset
)
;
be
_emit
_finish_line_gas
(
node
);
ir_entity
*
entity
=
be_get_MemPerm_in_entity
(
node
,
i
)
;
int
offset
=
get_entity_offset
(
entity
)
+
sp_change
;
arm
_emit
f
(
node
,
"ldr r%d, [sp, #%d]"
,
i
,
offset
);
}
for
(
i
=
memperm_arity
-
1
;
i
>=
0
;
--
i
)
{
int
offset
;
ir_entity
*
entity
=
be_get_MemPerm_out_entity
(
node
,
i
);
/* store to new entity */
offset
=
get_entity_offset
(
entity
)
+
sp_change
;
be_emit_irprintf
(
"
\t
str r%d, [sp, #%d]"
,
i
,
offset
)
;
be
_emit
_finish_line_gas
(
node
);
ir_entity
*
entity
=
be_get_MemPerm_out_entity
(
node
,
i
)
;
int
offset
=
get_entity_offset
(
entity
)
+
sp_change
;
arm
_emit
f
(
node
,
"str r%d, [sp, #%d]"
,
i
,
offset
);
/* restore register */
be
_emit
_irprintf
(
"
\t
ldr r%d, [sp], #4"
,
i
);
arm
_emit
f
(
node
,
"
ldr r%d, [sp], #4"
,
i
);
sp_change
-=
4
;
be_emit_finish_line_gas
(
node
);
}
assert
(
sp_change
==
0
);
}
...
...
@@ -720,12 +679,7 @@ static void emit_be_Start(const ir_node *node)
/* allocate stackframe */
if
(
size
>
0
)
{
be_emit_cstring
(
"
\t
sub "
);
arm_emit_register
(
&
arm_registers
[
REG_SP
]);
be_emit_cstring
(
", "
);
arm_emit_register
(
&
arm_registers
[
REG_SP
]);
be_emit_irprintf
(
", #0x%X"
,
size
);
be_emit_finish_line_gas
(
node
);
arm_emitf
(
node
,
"sub sp, sp, #0x%X"
,
size
);
}
}
...
...
@@ -737,16 +691,9 @@ static void emit_be_Return(const ir_node *node)
/* deallocate stackframe */
if
(
size
>
0
)
{
be_emit_cstring
(
"
\t
add "
);
arm_emit_register
(
&
arm_registers
[
REG_SP
]);
be_emit_cstring
(
", "
);