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
fbc27d3a
Commit
fbc27d3a
authored
Apr 20, 2006
by
Michael Beck
Browse files
Implemented basic FPA support
parent
57c3b255
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
ir/be/arm/arm_emitter.c
View file @
fbc27d3a
...
...
@@ -264,15 +264,15 @@ static int arm_shift_str(lc_appendable_t *app,
const
lc_arg_occ_t
*
occ
,
const
lc_arg_value_t
*
arg
)
{
char
buffer
[
SNPRINTF_BUF_LEN
];
ir_node
*
X
=
arg
->
v_ptr
;
ir_node
*
irn
=
arg
->
v_ptr
;
arm_shift_modifier
mod
;
if
(
!
X
)
if
(
!
irn
)
return
lc_appendable_snadd
(
app
,
"(null)"
,
6
);
mod
=
get_arm_shift_modifier
(
X
);
mod
=
get_arm_shift_modifier
(
irn
);
if
(
ARM_HAS_SHIFT
(
mod
))
{
long
v
=
get_tarval_long
(
get_arm_value
(
X
));
long
v
=
get_tarval_long
(
get_arm_value
(
irn
));
snprintf
(
buffer
,
sizeof
(
buffer
),
" %s #%ld"
,
arm_shf_mod_name
(
mod
),
v
);
return
lc_appendable_snadd
(
app
,
buffer
,
strlen
(
buffer
));
...
...
@@ -286,15 +286,24 @@ static int arm_shift_str(lc_appendable_t *app,
static
int
arm_get_mode_suffix
(
lc_appendable_t
*
app
,
const
lc_arg_occ_t
*
occ
,
const
lc_arg_value_t
*
arg
)
{
ir_node
*
X
=
arg
->
v_ptr
;
ir_node
*
irn
=
arg
->
v_ptr
;
arm_attr_t
*
attr
;
ir_mode
*
mode
;
int
bits
;
if
(
!
X
)
if
(
!
irn
)
return
lc_appendable_snadd
(
app
,
"(null)"
,
6
);
if
(
get_mode_size_bits
(
get_irn_mode
(
X
))
==
32
)
attr
=
get_arm_attr
(
irn
);
mode
=
attr
->
op_mode
?
attr
->
op_mode
:
get_irn_mode
(
irn
);
bits
=
get_mode_size_bits
(
mode
);
if
(
bits
==
32
)
return
lc_appendable_chadd
(
app
,
's'
);
else
else
if
(
bits
==
64
)
return
lc_appendable_chadd
(
app
,
'd'
);
else
return
lc_appendable_chadd
(
app
,
'e'
);
}
/**
...
...
@@ -332,13 +341,12 @@ static void arm_fprintf_format(FILE *F, char *cmd_buf, char *cmnt_buf, ir_node *
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F (%G) */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
,
irn
);
}
/*
*
Add a number to a prefix
. This number will not be used a second time.
/*
*
*
Returns a unique label
. This number will not be used a second time.
*/
static
char
*
get_unique_label
(
char
*
buf
,
size_t
buflen
,
const
char
*
prefix
)
{
static
unsigned
long
id
=
0
;
snprintf
(
buf
,
buflen
,
"%s%lu"
,
prefix
,
++
id
);
return
buf
;
static
unsigned
get_unique_label
(
void
)
{
static
unsigned
id
=
0
;
return
++
id
;
}
...
...
@@ -352,24 +360,20 @@ static char *get_cfop_target(const ir_node *irn, char *buf) {
return
buf
;
}
/************************************************************************/
/* emit_arm */
/************************************************************************/
/**
* Emit a SymConst
*/
static
void
emit_arm_SymConst
(
ir_node
*
irn
,
void
*
env
)
{
arm_emit_env_t
*
emit_env
=
env
;
FILE
*
out
=
emit_env
->
out
;
char
buffer1
[
SNPRINTF_BUF_LEN
];
char
*
skip_label
=
get_unique_label
(
buffer1
,
SNPRINTF_BUF_LEN
,
".L"
);
char
buffer2
[
SNPRINTF_BUF_LEN
];
char
*
indi_label
=
get_unique_label
(
buffer2
,
SNPRINTF_BUF_LEN
,
".L"
);
fprintf
(
out
,
"
\t
B %s
\t\t\t\t\t
/* start of indirect SymConst */
\n
"
,
skip_label
);
fprintf
(
out
,
"
\t
.align 2
\n
"
);
fprintf
(
out
,
"%s:
\n
"
,
indi_label
);
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
.word
\t
%C
\n
"
,
irn
);
fprintf
(
out
,
"
\t
.align 2
\n
"
);
fprintf
(
out
,
"%s:
\n
"
,
skip_label
);
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
LDR %1D, %s
\t\t\t
/* end of indirect SymConst */
\n
"
,
irn
,
indi_label
);
SymConstEntry
*
entry
=
obstack_alloc
(
&
emit_env
->
obst
,
sizeof
(
*
entry
));
entry
->
label
=
get_unique_label
();
entry
->
symconst
=
irn
;
entry
->
next
=
emit_env
->
symbols
;
emit_env
->
symbols
=
entry
;
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
ldr %1D, .L%u
\t\t\t
/* end of indirect SymConst */
\n
"
,
irn
,
entry
->
label
);
}
/**
...
...
@@ -410,21 +414,21 @@ static void emit_arm_CondJmp(ir_node *irn, void *env) {
if
(
proj_num
==
pn_Cmp_False
)
{
/* always false: should not happen */
fprintf
(
out
,
"
\t
B
BLOCK_%ld
\t\t\t
/* false case */
\n
"
,
get_irn_node_nr
(
false_block
));
fprintf
(
out
,
"
\t
b
BLOCK_%ld
\t\t\t
/* false case */
\n
"
,
get_irn_node_nr
(
false_block
));
}
else
if
(
proj_num
==
pn_Cmp_True
)
{
/* always true: should not happen */
fprintf
(
out
,
"
\t
B
BLOCK_%ld
\t\t\t
/* true case */
\n
"
,
get_irn_node_nr
(
true_block
));
fprintf
(
out
,
"
\t
b
BLOCK_%ld
\t\t\t
/* true case */
\n
"
,
get_irn_node_nr
(
true_block
));
}
else
{
ir_node
*
block
=
get_nodes_block
(
irn
);
if
(
mode_is_float
(
opmode
))
{
suffix
=
"ICHWILLIMPLEMENTIERTWERDEN"
;
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
FCMP
%1S, %2S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
fcmp
%1S, %2S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* Compare(%1S, %2S) -> FCPSR */"
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
FMSTAT
"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
fmstat
"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* FCSPR -> CPSR */"
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
}
else
{
...
...
@@ -433,23 +437,23 @@ static void emit_arm_CondJmp(ir_node *irn, void *env) {
proj_num
=
get_negated_pnc
(
proj_num
,
opmode
);
}
switch
(
proj_num
)
{
case
pn_Cmp_Eq
:
suffix
=
"
EQ
"
;
break
;
case
pn_Cmp_Lt
:
suffix
=
"
LT
"
;
break
;
case
pn_Cmp_Le
:
suffix
=
"
LE
"
;
break
;
case
pn_Cmp_Gt
:
suffix
=
"
GT
"
;
break
;
case
pn_Cmp_Ge
:
suffix
=
"
GE
"
;
break
;
case
pn_Cmp_Lg
:
suffix
=
"
NE
"
;
break
;
case
pn_Cmp_Leg
:
suffix
=
"
AL
"
;
break
;
default:
assert
(
0
&&
"komische Dinge geschehen"
);
suffix
=
"
AL
"
;
case
pn_Cmp_Eq
:
suffix
=
"
eq
"
;
break
;
case
pn_Cmp_Lt
:
suffix
=
"
lt
"
;
break
;
case
pn_Cmp_Le
:
suffix
=
"
le
"
;
break
;
case
pn_Cmp_Gt
:
suffix
=
"
gt
"
;
break
;
case
pn_Cmp_Ge
:
suffix
=
"
ge
"
;
break
;
case
pn_Cmp_Lg
:
suffix
=
"
ne
"
;
break
;
case
pn_Cmp_Leg
:
suffix
=
"
al
"
;
break
;
default:
assert
(
0
&&
"komische Dinge geschehen"
);
suffix
=
"
al
"
;
}
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
CMP
%1S, %2S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
cmp
%1S, %2S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* Compare(%1S, %2S) -> CPSR */"
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
}
if
(
true_block
==
sched_next_block
(
block
))
{
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
B
%s BLOCK_%d"
,
suffix
,
get_irn_node_nr
(
true_block
));
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
b
%s BLOCK_%d"
,
suffix
,
get_irn_node_nr
(
true_block
));
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* false case */"
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
...
...
@@ -457,7 +461,7 @@ static void emit_arm_CondJmp(ir_node *irn, void *env) {
arm_fprintf_format
(
out
,
""
,
cmnt_buf
,
irn
);
}
else
{
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
B
%s BLOCK_%d"
,
suffix
,
get_irn_node_nr
(
true_block
));
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
b
%s BLOCK_%d"
,
suffix
,
get_irn_node_nr
(
true_block
));
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* true case */"
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
...
...
@@ -466,7 +470,7 @@ static void emit_arm_CondJmp(ir_node *irn, void *env) {
arm_fprintf_format
(
out
,
""
,
cmnt_buf
,
irn
);
}
else
{
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
B
BLOCK_%d"
,
get_irn_node_nr
(
false_block
));
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
b
BLOCK_%d"
,
get_irn_node_nr
(
false_block
));
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* false case */"
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
}
...
...
@@ -491,29 +495,29 @@ static void emit_arm_CopyB(ir_node *irn, void *env) {
case
0
:
break
;
case
1
:
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDR
%%r12, [%2S, #0]!"
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldr
%%r12, [%2S, #0]!"
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
STR
%%r12, [%1S, #0]!"
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
str
%%r12, [%1S, #0]!"
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
break
;
case
2
:
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDMIA
%2S!, {%%r12, %3S}"
,
irn
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldmia
%2S!, {%%r12, %3S}"
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
STMIA
%1S!, {%%r12, %3S}"
,
irn
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
stmia
%1S!, {%%r12, %3S}"
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
break
;
case
3
:
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDMIA
%2S!, {%%r12, %3S, %4S}"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldmia
%2S!, {%%r12, %3S, %4S}"
,
irn
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
STMIA
%1S!, {%%r12, %3S, %4S}"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
stmia
%1S!, {%%r12, %3S, %4S}"
,
irn
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
break
;
}
size
>>=
2
;
while
(
size
)
{
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDMIA
%2S!, {%%r12, %3S, %4S, %5S}"
,
irn
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldmia
%2S!, {%%r12, %3S, %4S, %5S}"
,
irn
,
irn
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
STMIA
%1S!, {%%r12, %3S, %4S, %5S}"
,
irn
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
stmia
%1S!, {%%r12, %3S, %4S, %5S}"
,
irn
,
irn
,
irn
,
irn
);
arm_fprintf_format
(
out
,
cmd_buf
,
cmnt_buf
,
irn
);
--
size
;
}
...
...
@@ -551,24 +555,24 @@ static void emit_arm_SwitchJmp(ir_node *irn, void *env) {
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
CMP
%1S, #%u"
,
irn
,
n_projs
-
1
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
cmp
%1S, #%u"
,
irn
,
n_projs
-
1
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
""
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
BHI
BLOCK_%d"
,
default_block_num
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
bhi
BLOCK_%d"
,
default_block_num
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
""
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDR
%%r12, TABLE_%d_START"
,
block_nr
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldr
%%r12, TABLE_%d_START"
,
block_nr
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
""
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ADD
%%r12, %%r12, %1S, LSL #2"
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
add
%%r12, %%r12, %1S, LSL #2"
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
""
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDR
%%r15, [%%r12, #0]"
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldr
%%r15, [%%r12, #0]"
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
""
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
out
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
...
...
@@ -607,7 +611,7 @@ static void emit_be_Call(ir_node *irn, void *env) {
char
cmd_buf
[
SNPRINTF_BUF_LEN
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
if
(
ent
)
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
BL
%s"
,
get_entity_ld_name
(
ent
));
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
bl
%s"
,
get_entity_ld_name
(
ent
));
else
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"%1D"
,
get_irn_n
(
irn
,
be_pos_Call_ptr
));
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* %+F (be_Call) */"
,
irn
);
...
...
@@ -620,7 +624,7 @@ static void emit_be_IncSP(const ir_node *irn, arm_emit_env_t *emit_env) {
unsigned
offs
=
be_get_IncSP_offset
(
irn
);
if
(
offs
)
{
char
cmd_buf
[
SNPRINTF_BUF_LEN
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ADD
%1D, %1S, #%O"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
add
%1D, %1S, #%O"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* IncSP(%O) */"
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
}
else
{
...
...
@@ -652,17 +656,17 @@ static void emit_be_Copy(const ir_node *irn, arm_emit_env_t *emit_env) {
if
(
mode
==
mode_F
)
{
char
cmd_buf
[
SNPRINTF_BUF_LEN
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
FCPYS
%1D, %1S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
fcpys
%1D, %1S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* Copy: %1S -> %1D */"
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
}
else
if
(
mode
==
mode_D
)
{
char
cmd_buf
[
SNPRINTF_BUF_LEN
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
FCPYD
%1D, %1S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
fcpyd
%1D, %1S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* Copy: %1S -> %1D */"
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
}
else
if
(
mode_is_numP
(
mode
))
{
char
cmd_buf
[
SNPRINTF_BUF_LEN
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
MOV
%1D, %1S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
mov
%1D, %1S"
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* Copy: %1S -> %1D */"
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
}
else
{
...
...
@@ -677,7 +681,7 @@ static void emit_be_Spill(const ir_node *irn, arm_emit_env_t *emit_env) {
assert
(
(
mode
!=
mode_E
)
&&
"IEEE Extended FP not supported"
);
if
(
mode_is_dataM
(
mode
))
{
char
cmd_buf
[
SNPRINTF_BUF_LEN
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
STR
%2S, [%1S, #%O]"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
str
%2S, [%1S, #%O]"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* Spill(%2S) -> (%1S) */"
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
}
else
{
...
...
@@ -691,7 +695,7 @@ static void emit_be_Reload(const ir_node* irn, arm_emit_env_t *emit_env) {
assert
(
(
mode
!=
mode_E
)
&&
"IEEE Extended FP not supported"
);
if
(
mode_is_dataM
(
mode
))
{
char
cmd_buf
[
SNPRINTF_BUF_LEN
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDR
%1D, [%1S, #%O]"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldr
%1D, [%1S, #%O]"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* Reload(%1S) -> (%1D) */"
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
}
else
{
...
...
@@ -703,9 +707,9 @@ static void emit_be_Perm(const ir_node* irn, arm_emit_env_t *emit_env) {
FILE
*
F
=
emit_env
->
out
;
ir_mode
*
mode
=
get_irn_mode
(
irn
);
assert
(
(
mode
!=
mode_E
)
&&
"IEEE Extended FP not supported"
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
EOR
%1S, %1S, %2S
\t\t\t
/* begin Perm(%1S, %2S) */
\n
"
,
irn
,
irn
,
irn
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
EOR
%2S, %1S, %2S
\n
"
,
irn
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
EOR
%1S, %1S, %2S
\t\t\t
/* end Perm(%1S, %2S) */
\n
"
,
irn
,
irn
,
irn
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
eor
%1S, %1S, %2S
\t\t\t
/* begin Perm(%1S, %2S) */
\n
"
,
irn
,
irn
,
irn
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
eor
%2S, %1S, %2S
\n
"
,
irn
,
irn
,
irn
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
eor
%1S, %1S, %2S
\t\t\t
/* end Perm(%1S, %2S) */
\n
"
,
irn
,
irn
,
irn
,
irn
,
irn
);
}
static
void
emit_be_StackParam
(
const
ir_node
*
irn
,
arm_emit_env_t
*
emit_env
)
{
...
...
@@ -714,7 +718,7 @@ static void emit_be_StackParam(const ir_node *irn, arm_emit_env_t *emit_env) {
char
cmd_buf
[
256
],
cmnt_buf
[
SNPRINTF_BUF_LEN
];
assert
(
(
mode
!=
mode_E
)
&&
"IEEE Extended FP not supported"
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
LDR
%1D, [%1S, #%O]"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmd_buf
,
SNPRINTF_BUF_LEN
,
"
ldr
%1D, [%1S, #%O]"
,
irn
,
irn
,
irn
);
lc_esnprintf
(
arm_get_arg_env
(),
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* StackParam: (%1S + %O) -> %1D */"
,
irn
,
irn
,
irn
,
get_irn_n
(
irn
,
0
));
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
%-35s %-60s /* %+F */
\n
"
,
cmd_buf
,
cmnt_buf
,
irn
);
}
...
...
@@ -728,13 +732,24 @@ static void emit_Jmp(ir_node *irn, void *env) {
FILE
*
out
=
emit_env
->
out
;
const
ir_edge_t
*
edge
=
get_irn_out_edge_first
(
irn
);
ir_node
*
target_block
=
get_edge_src_irn
(
edge
);
fprintf
(
out
,
"
\t
B
BLOCK_%ld
\t\t\t
/* unconditional Jump */
\n
"
,
get_irn_node_nr
(
target_block
));
fprintf
(
out
,
"
\t
b
BLOCK_%ld
\t\t\t
/* unconditional Jump */
\n
"
,
get_irn_node_nr
(
target_block
));
}
static
void
emit_silence
(
ir_node
*
irn
,
void
*
env
)
{
static
void
emit_arm_fpaDbl2GP
(
const
ir_node
*
n
,
arm_emit_env_t
*
env
)
{
FILE
*
F
=
env
->
out
;
char
cmd_buf
[
256
];
const
lc_arg_env_t
*
arg_env
=
arm_get_arg_env
();
lc_esnprintf
(
arg_env
,
cmd_buf
,
256
,
"stfd %1S, [sp, #-8]! "
,
n
);
lc_efprintf
(
arg_env
,
F
,
"
\t
%-35s %-60s /* %+F (%+G) */
\n
"
,
cmd_buf
,
"/* Push fp to stack */"
,
n
,
n
);
lc_esnprintf
(
arg_env
,
cmd_buf
,
256
,
"ldmfd sp!, {%2D, %1D} "
,
n
,
n
);
lc_efprintf
(
arg_env
,
F
,
"
\t
%-35s %-60s /* %+F (%+G) */
\n
"
,
cmd_buf
,
"/* Pop destination */"
,
n
,
n
);
}
static
void
emit_silence
(
ir_node
*
irn
,
void
*
env
)
{
}
/***********************************************************************************
...
...
@@ -771,6 +786,7 @@ static void arm_register_emitters(void) {
// ARM_EMIT(Const);
ARM_EMIT
(
SymConst
);
ARM_EMIT
(
SwitchJmp
);
ARM_EMIT
(
fpaDbl2GP
);
/* benode emitter */
BE_EMIT
(
Call
);
...
...
@@ -853,6 +869,7 @@ void arm_emit_start(FILE *F, ir_graph *irg) {
* Emits code for function end
*/
void
arm_emit_end
(
FILE
*
F
,
ir_graph
*
irg
)
{
fprintf
(
F
,
"
\t
.ident
\"
firmcc
\"\n
"
);
}
/**
...
...
@@ -871,9 +888,10 @@ void arm_gen_labels(ir_node *block, void *env) {
/**
* Main driver. Emits the code for one routine.
* Main driver. Emits the code for one routine.
*/
void
arm_gen_routine
(
FILE
*
F
,
ir_graph
*
irg
,
const
arm_code_gen_t
*
cg
)
{
SymConstEntry
*
entry
;
arm_emit_env_t
emit_env
;
ir_node
**
blk_sched
;
int
i
,
n
;
...
...
@@ -881,6 +899,8 @@ void arm_gen_routine(FILE *F, ir_graph *irg, const arm_code_gen_t *cg) {
emit_env
.
out
=
F
;
emit_env
.
arch_env
=
cg
->
arch_env
;
emit_env
.
cg
=
cg
;
emit_env
.
symbols
=
NULL
;
obstack_init
(
&
emit_env
.
obst
);
FIRM_DBG_REGISTER
(
emit_env
.
mod
,
"firm.be.arm.emit"
);
/* set the global arch_env (needed by print hooks) */
...
...
@@ -907,5 +927,14 @@ void arm_gen_routine(FILE *F, ir_graph *irg, const arm_code_gen_t *cg) {
arm_gen_block
(
block
,
&
emit_env
);
}
arm_emit_end
(
F
,
irg
);
/* emit SymConst values */
if
(
emit_env
.
symbols
)
fprintf
(
F
,
"
\t
.align 2
\n
"
);
for
(
entry
=
emit_env
.
symbols
;
entry
;
entry
=
entry
->
next
)
{
fprintf
(
F
,
".L%u:
\n
"
,
entry
->
label
);
lc_efprintf
(
arm_get_arg_env
(),
F
,
"
\t
.word
\t
%C
\n
"
,
entry
->
symconst
);
}
obstack_free
(
&
emit_env
.
obst
,
NULL
);
}
ir/be/arm/arm_emitter.h
View file @
fbc27d3a
#ifndef _ARM_EMITTER_H_
#define _ARM_EMITTER_H_
#include "ir
args_t.h" // this also inlucdes <libcore/lc_print
.h
>
#include "ir
node
.h"
#include "
f
ir
m_types
.h
"
#include "ir
args_t
.h"
#include "debug.h"
#include "../bearch.h"
#include "bearch_arm_t.h"
/**
* A SymConst entry.
*/
typedef
struct
_SymConstEntry
{
unsigned
label
;
/**< a label number for this label */
ir_node
*
symconst
;
/**< the node holding this label */
struct
_SymConstEntry
*
next
;
/**< links all entries */
}
SymConstEntry
;
/**
* The ARM emitter environment.
*/
typedef
struct
_arm_emit_env_t
{
FILE
*
out
;
const
arch_env_t
*
arch_env
;
const
arm_code_gen_t
*
cg
;
FILE
*
out
;
/**< the output stream */
const
arch_env_t
*
arch_env
;
/**< the architecture environment */
const
arm_code_gen_t
*
cg
;
/**< the code generator object */
struct
obstack
obst
;
/**< an temporary store for SymConstEntries */
SymConstEntry
*
symbols
;
/**< list containing all SymConstEntries */
DEBUG_ONLY
(
firm_dbg_module_t
*
mod
;)
}
arm_emit_env_t
;
...
...
@@ -25,12 +39,15 @@ const char *get_arm_in_reg_name(ir_node *irn, int pos);
void
arm_gen_routine
(
FILE
*
F
,
ir_graph
*
irg
,
const
arm_code_gen_t
*
cg
);
/**
* Sections.
*/
typedef
enum
sections
{
NO_SECTION
,
/**< no section selected yet. */
SECTION_TEXT
,
/**< text section */
SECTION_DATA
,
/**< data section */
SECTION_RODATA
,
/**< rodata section */
SECTION_COMMON
,
/**< common section */
NO_SECTION
,
/**< no section selected yet. */
SECTION_TEXT
,
/**< text section */
SECTION_DATA
,
/**< data section */
SECTION_RODATA
,
/**< rodata section */
SECTION_COMMON
,
/**< common section */
}
sections
;
/**
...
...
ir/be/arm/arm_map_regs.c
View file @
fbc27d3a
...
...
@@ -71,15 +71,15 @@ long arm_translate_proj_pos(const ir_node *proj) {
ir_node
*
pred
=
get_Proj_pred
(
proj
);
long
nr
=
get_Proj_proj
(
proj
);
if
(
is_arm_Load
(
pred
)
||
is_arm_f
Load
(
pred
))
{
if
(
is_arm_Load
(
pred
)
||
is_arm_f
paLdf
(
pred
))
{
if
(
nr
==
pn_Load_res
)
return
0
;
assert
(
0
&&
"unsupported Proj(Load) number"
);
}
else
if
(
is_arm_Store
(
pred
)
||
is_arm_f
Store
(
pred
))
{
else
if
(
is_arm_Store
(
pred
)
||
is_arm_f
paStf
(
pred
))
{
return
0
;
}
else
if
(
is_arm_f
Di
v
(
pred
))
{
else
if
(
is_arm_f
paDiv
(
pred
)
||
is_arm_fpaRd
v
(
pred
))
{
if
(
nr
==
pn_Quot_res
)
return
0
;
else
...
...
ir/be/arm/arm_nodes_attr.h
View file @
fbc27d3a
...
...
@@ -71,8 +71,9 @@ typedef struct _arm_attr_t {
const
arch_register_t
**
slots
;
/**< register slots for assigned registers */
unsigned
instr_fl
;
/**< condition code, shift modifier */
tarval
*
value
;
/**< immediate */
ir_mode
*
op_mode
;
/**< operation mode */
unsigned
instr_fl
;
/**< condition code, shift modifier */
tarval
*
value
;
/**< immediate */
const
char
*
symconst_label
;
int
proj_num
;
int
n_projs
;
...
...
ir/be/arm/arm_spec.pl
View file @
fbc27d3a
This diff is collapsed.
Click to expand it.
ir/be/arm/arm_transform.c
View file @
fbc27d3a
/* The codegenrator (transform FIRM into arm FIRM */
/* The codegen
e
rator (transform FIRM into arm FIRM */
/* $Id$ */
#ifdef HAVE_CONFIG_H
...
...
@@ -182,24 +182,25 @@ static ir_node *create_const_graph(ir_node *irn, ir_node *block) {
}
/**
* Creates code for a Firm Const node.
*/
static
ir_node
*
gen_Const
(
ir_node
*
irn
,
arm_code_gen_t
*
cg
)
{
ir_node
*
result
;
ir_graph
*
irg
=
current_ir_graph
;
ir_node
*
block
=
get_nodes_block
(
irn
);
ir_mode
*
mode
=
get_irn_mode
(
irn
);
dbg_info
*
dbg
=
get_irn_dbg_info
(
irn
);
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
if
(
mode
==
mode_F
)
result
=
new_rd_arm_fConst
(
dbg
,
irg
,
block
,
mode
,
get_Const_tarval
(
irn
));
else
if
(
mode
==
mode_D
)
result
=
new_rd_arm_fConst
(
dbg
,
irg
,
block
,
mode
,
get_Const_tarval
(
irn
));
else
if
(
mode
==
mode_P
)
if
(
mode_is_float
(
mode
))
{
if
(
USE_FPA
(
cg
->
isa
))
return
new_rd_arm_fpaConst
(
dbg
,
irg
,
block
,
mode
,
get_Const_tarval
(
irn
));
else
if
(
USE_VFP
(
cg
->
isa
))
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
assert
(
0
&&
"NYI"
);
}
else
if
(
mode_is_reference
(
mode
))
return
irn
;
else
result
=
create_const_graph
(
irn
,
block
);
return
result
;
return
create_const_graph
(
irn
,
block
);
}
static
ir_node
*
gen_mask
(
ir_node
*
irn
,
ir_node
*
op
,
int
result_bits
)
{
...
...
@@ -235,21 +236,34 @@ static ir_node *gen_Conv(ir_node *irn, arm_code_gen_t *cg) {
ir_mode
*
out_mode
=
get_irn_mode
(
irn
);
dbg_info
*
dbg
=
get_irn_dbg_info
(
irn
);
assert
(
in_mode
!=
mode_E
&&
""
);
assert
(
in_mode
!=
mode_Ls
&&
""
);
assert
(
in_mode
!=
mode_Lu
&&
""
);
assert
(
out_mode
!=
mode_E
&&
""
);
assert
(
out_mode
!=
mode_Ls
&&
""
);
assert
(
out_mode
!=
mode_Lu
&&
""
);
if
(
in_mode
==
out_mode
)
return
op
;
if
((
mode_is_int
(
in_mode
)
||
mode_is_reference
(
in_mode
))
&&
(
mode_is_reference
(
out_mode
)
||
mode_is_int
(
out_mode
)))
{
int
in_bits
=
get_mode_size_bits
(
in_mode
);
if
(
mode_is_float
(
in_mode
)
||
mode_is_float
(
out_mode
))
{
cg
->
have_fp
=
1
;
if
(
USE_FPA
(
cg
->
isa
))
{
if
(
mode_is_float
(
in_mode
))
{
if
(
mode_is_float
(
out_mode
))
{
/* from float to float */
return
new_rd_arm_fpaMov
(
dbg
,
irg
,
block
,
op
,
out_mode
);
}
else
{
/* from float to int */
return
new_rd_arm_fpaFix
(
dbg
,
irg
,
block
,
op
,
out_mode
);
}
}
else
{
/* from int to float */
return
new_rd_arm_fpaFlt
(
dbg
,
irg
,
block
,
op
,
out_mode
);
}
}
assert
(
0
&&
"NYI"
);
}
else
{
/* complete in gp registers */
int
in_bits
=
get_mode_size_bits
(
in_mode
);
int
out_bits
=
get_mode_size_bits
(
out_mode
);
int
in_sign
=
get_mode_sign
(
in_mode
);
int
in_sign
=
get_mode_sign
(
in_mode
);
int
out_sign
=
get_mode_sign
(
out_mode
);
// 32 -> 32
...
...
@@ -309,20 +323,8 @@ static ir_node *gen_Conv(ir_node *irn, arm_code_gen_t *cg) {
}
assert
(
0
&&
"recheck integer conversion logic!"
);
return
irn
;
}
else
if
(
in_mode
==
mode_D
&&
out_mode
==
mode_F
)
{
return
new_rd_arm_fConvD2S
(
dbg
,
irg
,
block
,
op
,
out_mode
);
}
else
if
(
in_mode
==
mode_F
&&
out_mode
==
mode_D
)
{
return
new_rd_arm_fConvS2D
(
dbg
,
irg
,
block
,
op
,
out_mode
);
}
else
if
(
mode_is_int
(
in_mode
)
&&
mode_is_float
(
out_mode
))
{
cg
->
have_fp
=
1
;
return
irn
;
/* TODO: implement int->float conversion*/
}
else
if
(
mode_is_float
(
in_mode
)
&&
mode_is_int
(
out_mode
))
{
cg
->
have_fp
=
1
;
return
irn
;
/* TODO: implement float->int conversion*/
}
else
{
assert
(
0
&&
"not implemented conversion"
);
return
irn
;
}