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
2e16fb5a
Commit
2e16fb5a
authored
Jun 26, 2007
by
Michael Beck
Browse files
more floating point immediate support
[r14775]
parent
82c1910c
Changes
6
Hide whitespace changes
Inline
Side-by-side
ir/be/arm/arm_emitter.c
View file @
2e16fb5a
...
...
@@ -213,21 +213,16 @@ void arm_emit_mode(arm_emit_env_t *env, const ir_node *node) {
arm_emit_fpa_postfix
(
env
->
emit
,
mode
);
}
/**
* Returns non-zero if a mode has a Immediate attribute.
*/
int
is_immediate_node
(
const
ir_node
*
irn
)
{
const
arm_attr_t
*
attr
=
get_arm_attr_const
(
irn
);
return
ARM_GET_SHF_MOD
(
attr
)
==
ARM_SHF_IMM
;
}
/**
* Emit a const or SymConst value.
*/
void
arm_emit_immediate
(
arm_emit_env_t
*
env
,
const
ir_node
*
node
)
{
if
(
is_immediate_node
(
node
))
{
const
arm_attr_t
*
attr
=
get_arm_attr_const
(
node
);
if
(
ARM_GET_SHF_MOD
(
attr
)
==
ARM_SHF_IMM
)
{
be_emit_irprintf
(
env
->
emit
,
"#0x%X"
,
arm_decode_imm_w_shift
(
get_arm_value
(
node
)));
}
else
if
(
ARM_GET_FPA_IMM
(
attr
))
{
be_emit_irprintf
(
env
->
emit
,
"#0x%F"
,
get_arm_value
(
node
));
}
else
if
(
is_arm_SymConst
(
node
))
be_emit_ident
(
env
->
emit
,
get_arm_symconst_id
(
node
));
else
{
...
...
ir/be/arm/arm_new_nodes.c
View file @
2e16fb5a
...
...
@@ -47,7 +47,6 @@
#include "arm_nodes_attr.h"
#include "arm_new_nodes.h"
#include "gen_arm_regalloc_if_t.h"
#include "../beabi.h"
#include "bearch_arm_t.h"
...
...
ir/be/arm/arm_nodes_attr.h
View file @
2e16fb5a
...
...
@@ -52,6 +52,12 @@ typedef enum _arm_shift_modifier {
/** set the shift modifier to flags */
#define ARM_SET_SHF_MOD(attr, mod) ((attr)->instr_fl = (((attr)->instr_fl & ~7) | (mod)))
/** fpa immediate bit */
#define ARM_FPA_IMM (1 << 3)
/**< fpa floating point immediate */
#define ARM_GET_FPA_IMM(attr) ((attr)->instr_fl & ARM_FPA_IMM)
#define ARM_SET_FPA_IMM(attr) ((attr)->instr_fl |= ARM_FPA_IMM)
#define ARM_CLR_FPA_IMM(attr) ((attr)->instr_fl &= ~ARM_FPA_IMM)
/**
* Possible ARM condition codes.
...
...
@@ -76,10 +82,10 @@ typedef enum _arm_condition {
}
arm_condition
;
/** Get the condition code from flags */
#define ARM_GET_COND(attr) (((attr)->instr_fl >>
3
) & 15)
#define ARM_GET_COND(attr) (((attr)->instr_fl >>
4
) & 15)
/** Set the condition code to flags */
#define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 <<
3
)) | ((code) <<
3
)))
#define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 <<
4
)) | ((code) <<
4
)))
/** Generic ARM node attributes. */
typedef
struct
_arm_attr_t
{
...
...
ir/be/arm/arm_spec.pl
View file @
2e16fb5a
...
...
@@ -704,7 +704,7 @@ LoadStackM3 => {
# commutative operations
fpaAd
d
=>
{
fpaAd
f
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Add: Add(a, b) = Add(b, a) = a + b
",
...
...
@@ -712,15 +712,39 @@ fpaAdd => {
emit
=>
'
. adf%M %D0, %S0, %S1
',
},
fpa
Mul
=>
{
fpa
Adf_i
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Add: Add(a, b) = Add(b, a) = a + b
",
attr
=>
"
tarval *tv
",
init_attr
=>
'
ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. adf%M %D0, %S0, %C
',
},
fpaMuf
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b
",
reg_req
=>
{
"
in
"
=>
[
"
fpa
",
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. muf%M %D0, %S0, %S1
',
},
fpaFMul
=>
{
fpaMuf_i
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b
",
attr
=>
"
tarval *tv
",
init_attr
=>
'
ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. muf%M %D0, %S0, %C
',
},
fpaFml
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b
",
reg_req
=>
{
"
in
"
=>
[
"
fpa
",
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. fml%M %D0, %S0, %S1
',
...
...
@@ -744,21 +768,41 @@ fpaMin => {
# not commutative operations
fpaSu
b
=>
{
fpaSu
f
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Sub: Sub(a, b) = a - b
",
reg_req
=>
{
"
in
"
=>
[
"
fpa
",
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. suf%M %D0, %S0, %S1
'
},
fpaRsb
=>
{
fpaSuf_i
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Sub: Sub(a, b) = a - b
",
attr
=>
"
tarval *tv
",
init_attr
=>
'
ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. suf%M %D0, %S0, %C
'
},
fpaRsf
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct FPA reverse Sub: Sub(a, b) = b - a
",
reg_req
=>
{
"
in
"
=>
[
"
fpa
",
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. rsf%M %D0, %S0, %S1
'
},
fpaDiv
=>
{
fpaRsf_i
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct FPA reverse Sub: Sub(a, b) = b - a
",
attr
=>
"
tarval *tv
",
init_attr
=>
'
ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. rsf%M %D0, %S0, %C
'
},
fpaDvf
=>
{
comment
=>
"
construct FPA Div: Div(a, b) = a / b
",
attr
=>
"
ir_mode *op_mode
",
init_attr
=>
"
attr->op_mode = op_mode;
",
...
...
@@ -767,7 +811,17 @@ fpaDiv => {
outs
=>
[
"
res
",
"
M
"
],
},
fpaRdv
=>
{
fpaDvf_i
=>
{
comment
=>
"
construct FPA Div: Div(a, b) = a / b
",
attr
=>
"
ir_mode *op_mode, tarval *tv
",
init_attr
=>
'
attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
",
"
none
"
]
},
emit
=>
'
. dvf%M %D0, %S0, %C
',
outs
=>
[
"
res
",
"
M
"
],
},
fpaRdf
=>
{
comment
=>
"
construct FPA reverse Div: Div(a, b) = b / a
",
attr
=>
"
ir_mode *op_mode
",
init_attr
=>
"
attr->op_mode = op_mode;
",
...
...
@@ -776,7 +830,17 @@ fpaRdv => {
outs
=>
[
"
res
",
"
M
"
],
},
fpaFDiv
=>
{
fpaRdf_i
=>
{
comment
=>
"
construct FPA reverse Div: Div(a, b) = b / a
",
attr
=>
"
ir_mode *op_mode, tarval *tv
",
init_attr
=>
'
attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
",
"
none
"
]
},
emit
=>
'
. rdf%M %D0, %S0, %S1
',
outs
=>
[
"
res
",
"
M
"
],
},
fpaFdv
=>
{
comment
=>
"
construct FPA Fast Div: Div(a, b) = a / b
",
attr
=>
"
ir_mode *op_mode
",
init_attr
=>
"
attr->op_mode = op_mode;
",
...
...
@@ -785,7 +849,17 @@ fpaFDiv => {
outs
=>
[
"
res
",
"
M
"
],
},
fpaFRdv
=>
{
fpaFdv_i
=>
{
comment
=>
"
construct FPA Fast Div: Div(a, b) = a / b
",
attr
=>
"
ir_mode *op_mode, tarval *tv
",
init_attr
=>
'
attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
",
"
none
"
]
},
emit
=>
'
. fdv%M %D0, %S0, %C
',
outs
=>
[
"
res
",
"
M
"
],
},
fpaFrd
=>
{
comment
=>
"
construct FPA Fast reverse Div: Div(a, b) = b / a
",
attr
=>
"
ir_mode *op_mode
",
init_attr
=>
"
attr->op_mode = op_mode;
",
...
...
@@ -794,20 +868,52 @@ fpaFRdv => {
outs
=>
[
"
res
",
"
M
"
],
},
fpaMov
=>
{
fpaFrd_i
=>
{
comment
=>
"
construct FPA Fast reverse Div: Div(a, b) = b / a
",
attr
=>
"
ir_mode *op_mode, tarval *tv
",
init_attr
=>
'
attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
',
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
",
"
none
"
]
},
emit
=>
'
. frd%M %D0, %S0, %C
',
outs
=>
[
"
res
",
"
M
"
],
},
fpaMvf
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Move: b = a
",
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. mvf%M %S0, %D0
',
},
fpaMnv
=>
{
fpaMvf_i
=>
{
irn_flags
=>
"
R
",
comment
=>
"
represents a float constant
",
attr
=>
"
tarval *tv
",
init_attr
=>
'
ARM_SET_FPA_IMM(attr); attr->value = tv;
',
reg_req
=>
{
"
out
"
=>
[
"
fpa
"
]
},
mode
=>
"
get_tarval_mode(tv)
",
emit
=>
'
. mvf %D0, %C
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
'
},
fpaMnf
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Move Negated: b = -a
",
reg_req
=>
{
"
in
"
=>
[
"
fpa
"
],
"
out
"
=>
[
"
fpa
"
]
},
emit
=>
'
. mnf%M %S0, %D0
',
},
fpaMnf_i
=>
{
irn_flags
=>
"
R
",
comment
=>
"
represents a float constant
",
attr
=>
"
tarval *tv
",
init_attr
=>
'
ARM_SET_FPA_IMM(attr); attr->value = tv;
',
reg_req
=>
{
"
out
"
=>
[
"
fpa
"
]
},
mode
=>
"
get_tarval_mode(tv)
",
emit
=>
'
. mnf %D0, %C
',
cmp_attr
=>
'
return attr_a->value != attr_b->value;
'
},
fpaAbs
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct FPA Absolute value: fAbsd(a) = |a|
",
...
...
@@ -939,7 +1045,7 @@ fpaConst => {
op_flags
=>
"
c
",
irn_flags
=>
"
R
",
comment
=>
"
construct a floating point constant
",
attr
=>
"
tarval *tv
, int is_imm
",
attr
=>
"
tarval *tv
",
init_attr
=>
"
attr->value = tv;
",
mode
=>
"
get_tarval_mode(tv)
",
reg_req
=>
{
"
out
"
=>
[
"
fpa
"
]
},
...
...
ir/be/arm/arm_transform.c
View file @
2e16fb5a
...
...
@@ -279,7 +279,7 @@ static ir_node *gen_Conv(ir_node *node) {
if
(
mode_is_float
(
src_mode
))
{
if
(
mode_is_float
(
dst_mode
))
{
/* from float to float */
return
new_rd_arm_fpaM
o
v
(
dbg
,
irg
,
block
,
new_op
,
dst_mode
);
return
new_rd_arm_fpaMv
f
(
dbg
,
irg
,
block
,
new_op
,
dst_mode
);
}
else
{
/* from float to int */
...
...
@@ -377,9 +377,13 @@ static ir_node *gen_Add(ir_node *node) {
if
(
mode_is_float
(
mode
))
{
env_cg
->
have_fp_insn
=
1
;
if
(
USE_FPA
(
env_cg
->
isa
))
return
new_rd_arm_fpaAdd
(
dbg
,
irg
,
block
,
new_op1
,
new_op2
,
mode
);
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
if
(
USE_FPA
(
env_cg
->
isa
))
{
if
(
is_arm_fpaMvf_i
(
new_op1
))
return
new_rd_arm_fpaAdf_i
(
dbg
,
irg
,
block
,
new_op2
,
mode
,
get_arm_value
(
new_op1
));
if
(
is_arm_fpaMvf_i
(
new_op2
))
return
new_rd_arm_fpaAdf_i
(
dbg
,
irg
,
block
,
new_op1
,
mode
,
get_arm_value
(
new_op2
));
return
new_rd_arm_fpaAdf
(
dbg
,
irg
,
block
,
new_op1
,
new_op2
,
mode
);
}
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
panic
(
"VFP not supported yet
\n
"
);
return
NULL
;
...
...
@@ -448,8 +452,13 @@ static ir_node *gen_Mul(ir_node *node) {
if
(
mode_is_float
(
mode
))
{
env_cg
->
have_fp_insn
=
1
;
if
(
USE_FPA
(
env_cg
->
isa
))
return
new_rd_arm_fpaMul
(
dbg
,
irg
,
block
,
new_op1
,
new_op2
,
mode
);
if
(
USE_FPA
(
env_cg
->
isa
))
{
if
(
is_arm_Mov_i
(
new_op1
))
return
new_rd_arm_fpaMuf_i
(
dbg
,
irg
,
block
,
new_op2
,
mode
,
get_arm_value
(
new_op1
));
if
(
is_arm_Mov_i
(
new_op2
))
return
new_rd_arm_fpaMuf_i
(
dbg
,
irg
,
block
,
new_op1
,
mode
,
get_arm_value
(
new_op2
));
return
new_rd_arm_fpaMuf
(
dbg
,
irg
,
block
,
new_op1
,
new_op2
,
mode
);
}
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
panic
(
"VFP not supported yet
\n
"
);
...
...
@@ -483,9 +492,13 @@ static ir_node *gen_Quot(ir_node *node) {
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
env_cg
->
have_fp_insn
=
1
;
if
(
USE_FPA
(
env_cg
->
isa
))
return
new_rd_arm_fpaDiv
(
dbg
,
current_ir_graph
,
block
,
new_op1
,
new_op2
,
mode
);
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
if
(
USE_FPA
(
env_cg
->
isa
))
{
if
(
is_arm_Mov_i
(
new_op1
))
return
new_rd_arm_fpaRdf_i
(
dbg
,
current_ir_graph
,
block
,
new_op2
,
mode
,
get_arm_value
(
new_op1
));
if
(
is_arm_Mov_i
(
new_op2
))
return
new_rd_arm_fpaDvf_i
(
dbg
,
current_ir_graph
,
block
,
new_op1
,
mode
,
get_arm_value
(
new_op2
));
return
new_rd_arm_fpaDvf
(
dbg
,
current_ir_graph
,
block
,
new_op1
,
new_op2
,
mode
);
}
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
panic
(
"VFP not supported yet
\n
"
);
}
...
...
@@ -573,9 +586,13 @@ static ir_node *gen_Sub(ir_node *node) {
if
(
mode_is_float
(
mode
))
{
env_cg
->
have_fp_insn
=
1
;
if
(
USE_FPA
(
env_cg
->
isa
))
return
new_rd_arm_fpaSub
(
dbg
,
irg
,
block
,
new_op1
,
new_op2
,
mode
);
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
if
(
USE_FPA
(
env_cg
->
isa
))
{
if
(
is_arm_Mov_i
(
new_op1
))
return
new_rd_arm_fpaRsf_i
(
dbg
,
irg
,
block
,
new_op2
,
mode
,
get_arm_value
(
new_op1
));
if
(
is_arm_Mov_i
(
new_op2
))
return
new_rd_arm_fpaSuf_i
(
dbg
,
irg
,
block
,
new_op1
,
mode
,
get_arm_value
(
new_op2
));
return
new_rd_arm_fpaSuf
(
dbg
,
irg
,
block
,
new_op1
,
new_op2
,
mode
);
}
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
panic
(
"VFP not supported yet
\n
"
);
return
NULL
;
...
...
@@ -738,7 +755,7 @@ static ir_node *gen_Minus(ir_node *node) {
if
(
mode_is_float
(
mode
))
{
env_cg
->
have_fp_insn
=
1
;
if
(
USE_FPA
(
env_cg
->
isa
))
return
new_rd_arm_fpaM
n
v
(
dbg
,
current_ir_graph
,
block
,
op
,
mode
);
return
new_rd_arm_fpaMv
f
(
dbg
,
current_ir_graph
,
block
,
op
,
mode
);
else
if
(
USE_VFP
(
env_cg
->
isa
))
{
assert
(
mode
!=
mode_E
&&
"IEEE Extended FP not supported"
);
panic
(
"VFP not supported yet
\n
"
);
...
...
@@ -969,10 +986,48 @@ static ident *get_sc_ident(ir_node *symc) {
return
NULL
;
}
enum
fpa_immediates
{
fpa_null
=
0
,
fpa_one
,
fpa_two
,
fpa_three
,
fpa_four
,
fpa_five
,
fpa_ten
,
fpa_half
,
fpa_max
};
static
tarval
*
fpa_imm
[
3
][
fpa_max
];
/**
* Check, if a floating point tarval is an fpa immediate, i.e.
* one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
*/
static
int
is_fpa_immediate
(
tarval
*
tv
)
{
ir_mode
*
mode
=
get_tarval_mode
(
tv
);
int
i
,
j
,
res
=
1
;
switch
(
get_mode_size_bits
(
mode
))
{
case
32
:
i
=
0
;
break
;
case
64
:
i
=
1
;
break
;
default:
i
=
2
;
}
if
(
tarval_cmp
(
tv
,
get_tarval_null
(
mode
))
&
pn_Cmp_Lt
)
{
tv
=
tarval_neg
(
tv
);
res
=
-
1
;
}
for
(
j
=
0
;
j
<
fpa_max
;
++
j
)
{
if
(
tv
==
fpa_imm
[
i
][
j
])
return
res
;
}
return
0
;
}
...
...
@@ -991,7 +1046,16 @@ static ir_node *gen_Const(ir_node *node) {
env_cg
->
have_fp_insn
=
1
;
if
(
USE_FPA
(
env_cg
->
isa
))
{
tarval
*
tv
=
get_Const_tarval
(
node
);
node
=
new_rd_arm_fpaConst
(
dbg
,
irg
,
block
,
tv
,
is_fpa_immediate
(
tv
));
int
imm
=
is_fpa_immediate
(
tv
);
if
(
imm
)
{
if
(
imm
>
0
)
node
=
new_rd_arm_fpaMvf_i
(
dbg
,
irg
,
block
,
tv
);
else
node
=
new_rd_arm_fpaMnf_i
(
dbg
,
irg
,
block
,
tv
);
}
else
{
node
=
new_rd_arm_fpaConst
(
dbg
,
irg
,
block
,
tv
);
}
/* ensure the const is schedules AFTER the barrier */
add_irn_dep
(
node
,
be_abi_get_start_barrier
(
env_cg
->
birg
->
abi
));
return
node
;
...
...
@@ -1318,25 +1382,25 @@ static ir_node *gen_Proj_Quot(ir_node *node) {
switch
(
proj
)
{
case
pn_Quot_M
:
if
(
is_arm_fpaD
i
v
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaD
i
v_M
);
}
else
if
(
is_arm_fpaRd
v
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaRd
v
_M
);
}
else
if
(
is_arm_fpaF
Div
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaF
Di
v_M
);
}
else
if
(
is_arm_fpaF
Rdv
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaF
Rdv
_M
);
if
(
is_arm_fpaDv
f
(
new_pred
)
||
is_arm_fpaDvf_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaDv
f
_M
);
}
else
if
(
is_arm_fpaRd
f
(
new_pred
)
||
is_arm_fpaRdf_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaRd
f
_M
);
}
else
if
(
is_arm_fpaF
dv
(
new_pred
)
||
is_arm_fpaFdv_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaF
d
v_M
);
}
else
if
(
is_arm_fpaF
rd
(
new_pred
)
||
is_arm_fpaFrd_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode_M
,
pn_arm_fpaF
rd
_M
);
}
break
;
case
pn_Quot_res
:
if
(
is_arm_fpaD
i
v
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaD
i
v_res
);
}
else
if
(
is_arm_fpa
FDiv
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaRd
v
_res
);
}
else
if
(
is_arm_fpaF
Div
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaF
Di
v_res
);
}
else
if
(
is_arm_fpaF
Div
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaF
Rdv
_res
);
if
(
is_arm_fpaDv
f
(
new_pred
)
||
is_arm_fpaDvf_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaDv
f
_res
);
}
else
if
(
is_arm_fpa
Rdf
(
new_pred
)
||
is_arm_fpaRdf_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaRd
f
_res
);
}
else
if
(
is_arm_fpaF
dv
(
new_pred
)
||
is_arm_fpaFdv_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaF
d
v_res
);
}
else
if
(
is_arm_fpaF
rd
(
new_pred
)
||
is_arm_fpaFrd_i
(
new_pred
))
{
return
new_rd_Proj
(
dbgi
,
irg
,
block
,
new_pred
,
mode
,
pn_arm_fpaF
rd
_res
);
}
break
;
default:
...
...
@@ -1681,10 +1745,49 @@ static void arm_pretransform_node(void *arch_cg) {
cg
->
unknown_fpa
=
be_pre_transform_node
(
cg
->
unknown_fpa
);
}
/**
* Initialize fpa Immediate support.
*/
static
void
arm_init_fpa_immediate
(
void
)
{
/* 0, 1, 2, 3, 4, 5, 10, or 0.5. */
fpa_imm
[
0
][
fpa_null
]
=
get_tarval_null
(
mode_F
);
fpa_imm
[
0
][
fpa_one
]
=
get_tarval_one
(
mode_F
);
fpa_imm
[
0
][
fpa_two
]
=
new_tarval_from_str
(
"2"
,
1
,
mode_F
);
fpa_imm
[
0
][
fpa_three
]
=
new_tarval_from_str
(
"3"
,
1
,
mode_F
);
fpa_imm
[
0
][
fpa_four
]
=
new_tarval_from_str
(
"4"
,
1
,
mode_F
);
fpa_imm
[
0
][
fpa_five
]
=
new_tarval_from_str
(
"5"
,
1
,
mode_F
);
fpa_imm
[
0
][
fpa_ten
]
=
new_tarval_from_str
(
"10"
,
2
,
mode_F
);
fpa_imm
[
0
][
fpa_half
]
=
new_tarval_from_str
(
"0.5"
,
3
,
mode_F
);
fpa_imm
[
1
][
fpa_null
]
=
get_tarval_null
(
mode_D
);
fpa_imm
[
1
][
fpa_one
]
=
get_tarval_one
(
mode_D
);
fpa_imm
[
1
][
fpa_two
]
=
new_tarval_from_str
(
"2"
,
1
,
mode_D
);
fpa_imm
[
1
][
fpa_three
]
=
new_tarval_from_str
(
"3"
,
1
,
mode_D
);
fpa_imm
[
1
][
fpa_four
]
=
new_tarval_from_str
(
"4"
,
1
,
mode_D
);
fpa_imm
[
1
][
fpa_five
]
=
new_tarval_from_str
(
"5"
,
1
,
mode_D
);
fpa_imm
[
1
][
fpa_ten
]
=
new_tarval_from_str
(
"10"
,
2
,
mode_D
);
fpa_imm
[
1
][
fpa_half
]
=
new_tarval_from_str
(
"0.5"
,
3
,
mode_D
);
fpa_imm
[
2
][
fpa_null
]
=
get_tarval_null
(
mode_E
);
fpa_imm
[
2
][
fpa_one
]
=
get_tarval_one
(
mode_E
);
fpa_imm
[
2
][
fpa_two
]
=
new_tarval_from_str
(
"2"
,
1
,
mode_E
);
fpa_imm
[
2
][
fpa_three
]
=
new_tarval_from_str
(
"3"
,
1
,
mode_E
);
fpa_imm
[
2
][
fpa_four
]
=
new_tarval_from_str
(
"4"
,
1
,
mode_E
);
fpa_imm
[
2
][
fpa_five
]
=
new_tarval_from_str
(
"5"
,
1
,
mode_E
);
fpa_imm
[
2
][
fpa_ten
]
=
new_tarval_from_str
(
"10"
,
2
,
mode_E
);
fpa_imm
[
2
][
fpa_half
]
=
new_tarval_from_str
(
"0.5"
,
3
,
mode_E
);
}
/**
* Transform a Firm graph into an ARM graph.
*/
void
arm_transform_graph
(
arm_code_gen_t
*
cg
)
{
static
int
imm_initialized
=
0
;
if
(
!
imm_initialized
)
{
arm_init_fpa_immediate
();
imm_initialized
=
1
;
}
arm_register_transformers
();
env_cg
=
cg
;
be_transform_graph
(
cg
->
birg
,
arm_pretransform_node
,
cg
);
...
...
@@ -1692,6 +1795,4 @@ void arm_transform_graph(arm_code_gen_t *cg) {
void
arm_init_transform
(
void
)
{
// FIRM_DBG_REGISTER(dbg, "firm.be.arm.transform");
/* 0, 1, 2, 3, 4, 5, 10, or 0.5. */
}
ir/be/arm/bearch_arm.c
View file @
2e16fb5a
...
...
@@ -1165,7 +1165,7 @@ static const backend_params *arm_get_libfirm_params(void) {
static
arch_dep_params_t
ad
=
{
1
,
/* allow subs */
1
,
/* Muls are fast enough on ARM but ... */
1
,
/* ... one shift would be possible better */
3
1
,
/* ... one shift would be possible better */
0
,
/* SMUL is needed, only in Arch M*/
0
,
/* UMUL is needed, only in Arch M */
32
,
/* SMUL & UMUL available for 32 bit */
...
...
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