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
4baed155
Commit
4baed155
authored
Oct 06, 2013
by
Matthias Braun
Browse files
share x86 cc code between ia32 and amd64 backend
parent
bf4b3419
Changes
13
Hide whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_emitter.c
View file @
4baed155
...
...
@@ -329,6 +329,18 @@ end_of_mods:
break
;
}
case
'P'
:
{
x86_condition_code_t
cc
;
if
(
*
fmt
==
'X'
)
{
++
fmt
;
cc
=
(
x86_condition_code_t
)
va_arg
(
ap
,
int
);
}
else
{
panic
(
"unknown modifier"
);
}
x86_emit_condition_code
(
cc
);
break
;
}
case
'R'
:
reg
=
va_arg
(
ap
,
arch_register_t
const
*
);
emit_R:
...
...
@@ -450,10 +462,8 @@ static void emit_amd64_Jcc(const ir_node *irn)
const
ir_node
*
proj_false
=
NULL
;
const
ir_node
*
block
;
const
ir_node
*
next_block
;
const
char
*
suffix
;
const
amd64_cc_attr_t
*
attr
=
get_amd64_cc_attr_const
(
irn
);
ir_relation
relation
=
attr
->
relation
;
bool
is_signed
=
!
attr
->
is_unsigned
;
const
amd64_cc_attr_t
*
attr
=
get_amd64_cc_attr_const
(
irn
);
x86_condition_code_t
cc
=
attr
->
cc
;
foreach_out_edge
(
irn
,
edge
)
{
ir_node
*
proj
=
get_edge_src_irn
(
edge
);
...
...
@@ -471,36 +481,23 @@ static void emit_amd64_Jcc(const ir_node *irn)
/* we have a block schedule */
next_block
=
sched_next_block
(
block
);
assert
(
relation
!=
ir_relation_false
);
assert
(
relation
!=
ir_relation_true
);
if
(
get_cfop_target_block
(
proj_true
)
==
next_block
)
{
/* exchange both proj's so the second one can be omitted */
const
ir_node
*
t
=
proj_true
;
proj_true
=
proj_false
;
proj_false
=
t
;
relation
=
get_negated_relation
(
relation
);
}
switch
(
relation
&
ir_relation_less_equal_greater
)
{
case
ir_relation_equal
:
suffix
=
"e"
;
break
;
case
ir_relation_less
:
suffix
=
is_signed
?
"l"
:
"b"
;
break
;
case
ir_relation_less_equal
:
suffix
=
is_signed
?
"le"
:
"be"
;
break
;
case
ir_relation_greater
:
suffix
=
is_signed
?
"g"
:
"a"
;
break
;
case
ir_relation_greater_equal
:
suffix
=
is_signed
?
"ge"
:
"ae"
;
break
;
case
ir_relation_less_greater
:
suffix
=
"ne"
;
break
;
case
ir_relation_less_equal_greater
:
suffix
=
"mp"
;
break
;
default:
panic
(
"Cmp has unsupported pnc"
);
cc
=
x86_negate_condition_code
(
cc
);
}
/* emit the true proj */
amd64_emitf
(
proj_true
,
"j%
s
%L"
,
suffix
);
amd64_emitf
(
proj_true
,
"j%
PX
%L"
,
(
int
)
cc
);
if
(
get_cfop_target_block
(
proj_false
)
!=
next_block
)
{
if
(
get_cfop_target_block
(
proj_false
)
==
next_block
)
{
if
(
be_options
.
verbose_asm
)
amd64_emitf
(
proj_false
,
"/* fallthrough to %L */"
);
}
else
{
amd64_emitf
(
proj_false
,
"jmp %L"
);
}
else
if
(
be_options
.
verbose_asm
)
{
amd64_emitf
(
proj_false
,
"/* fallthrough to %L */"
);
}
}
...
...
ir/be/amd64/amd64_new_nodes.c
View file @
4baed155
...
...
@@ -155,12 +155,10 @@ static void init_amd64_switch_attributes(ir_node *node, const ir_switch_table *t
}
}
static
void
init_amd64_cc_attributes
(
ir_node
*
node
,
ir_relation
relation
,
bool
is_unsigned
)
static
void
init_amd64_cc_attributes
(
ir_node
*
node
,
x86_condition_code_t
cc
)
{
amd64_cc_attr_t
*
attr
=
get_amd64_cc_attr
(
node
);
attr
->
relation
=
relation
;
attr
->
is_unsigned
=
is_unsigned
;
attr
->
cc
=
cc
;
}
static
void
init_amd64_movimm_attributes
(
ir_node
*
node
,
ir_entity
*
symconst
,
...
...
@@ -210,8 +208,7 @@ static int cmp_amd64_cc_attr(const ir_node *const a,
return
true
;
const
amd64_cc_attr_t
*
const
attr_a
=
get_amd64_cc_attr_const
(
a
);
const
amd64_cc_attr_t
*
const
attr_b
=
get_amd64_cc_attr_const
(
b
);
return
attr_a
->
relation
!=
attr_b
->
relation
||
attr_a
->
is_unsigned
!=
attr_b
->
is_unsigned
;
return
attr_a
->
cc
!=
attr_b
->
cc
;
}
static
int
cmp_amd64_switch_jmp_attr
(
const
ir_node
*
const
a
,
...
...
ir/be/amd64/amd64_nodes_attr.h
View file @
4baed155
...
...
@@ -14,6 +14,7 @@
#include "bearch.h"
#include "compiler.h"
#include "../ia32/x86_cc.h"
typedef
struct
amd64_attr_t
amd64_attr_t
;
typedef
struct
amd64_switch_jmp_attr_t
amd64_switch_jmp_attr_t
;
...
...
@@ -72,8 +73,8 @@ struct amd64_movimm_attr_t
struct
amd64_cc_attr_t
{
ir_relation
relation
;
bool
is_unsigned
:
1
;
amd64_attr_t
base
;
x86_condition_code_t
cc
;
};
struct
amd64_switch_jmp_attr_t
...
...
ir/be/amd64/amd64_spec.pl
View file @
4baed155
...
...
@@ -52,7 +52,7 @@ $default_copy_attr = "amd64_copy_attr";
.
"
\t
init_amd64_switch_attributes(res, table, table_entity);
",
amd64_cc_attr_t
=>
"
\t
init_amd64_attributes(res, irn_flags_, in_reqs, n_res);
"
.
"
\t
init_amd64_cc_attributes(res,
relation, is_unsigned
);
",
.
"
\t
init_amd64_cc_attributes(res,
cc
);
",
amd64_movimm_attr_t
=>
"
\t
init_amd64_attributes(res, irn_flags_, in_reqs, n_res);
"
.
"
\t
init_amd64_movimm_attributes(res, symconst, offset);
",
...
...
@@ -330,7 +330,7 @@ Jcc => {
reg_req
=>
{
in
=>
[
"
eflags
"
],
out
=>
[
"
none
",
"
none
"
]
},
ins
=>
[
"
eflags
"
],
outs
=>
[
"
false
",
"
true
"
],
attr
=>
"
ir_relation relation, bool is_unsigned
",
attr
=>
"
x86_condition_code_t cc
",
attr_type
=>
"
amd64_cc_attr_t
",
mode
=>
"
mode_T
",
},
...
...
ir/be/amd64/amd64_transform.c
View file @
4baed155
...
...
@@ -858,15 +858,43 @@ static ir_node *gen_Cmp(ir_node *node)
return
new_bd_amd64_Cmp
(
dbgi
,
block
,
new_op1
,
new_op2
,
insn_mode
);
}
static
ir_node
*
get_flags_node
(
ir_node
*
cmp
,
x86_condition_code_t
*
cc_out
)
{
/* must have a Cmp as input */
ir_relation
relation
=
get_Cmp_relation
(
cmp
);
ir_node
*
l
=
get_Cmp_left
(
cmp
);
ir_node
*
r
=
get_Cmp_right
(
cmp
);
ir_mode
*
mode
=
get_irn_mode
(
l
);
/* the middle-end tries to eliminate impossible relations, so a ptr <> 0
* test becomes ptr > 0. But for x86 an equal comparison is preferable to
* a >0 (we can sometimes eliminate the cmp in favor of flags produced by
* a predecessor node). So add the < bit.
* (Note that we do not want to produce <=> (which can happen for
* unoptimized code), because no x86 flag can represent that */
if
(
!
(
relation
&
ir_relation_equal
)
&&
relation
&
ir_relation_less_greater
)
relation
|=
get_negated_relation
(
ir_get_possible_cmp_relations
(
l
,
r
))
&
ir_relation_less_greater
;
bool
overflow_possible
=
true
;
if
(
is_Const
(
r
)
&&
is_Const_null
(
r
))
overflow_possible
=
false
;
/* just do a normal transformation of the Cmp */
*
cc_out
=
ir_relation_to_x86_condition_code
(
relation
,
mode
,
overflow_possible
);
ir_node
*
flags
=
be_transform_node
(
cmp
);
return
flags
;
}
static
ir_node
*
gen_Cond
(
ir_node
*
node
)
{
ir_node
*
const
block
=
be_transform_node
(
get_nodes_block
(
node
)
)
;
dbg_info
*
const
dbgi
=
get_irn_dbg_info
(
node
)
;
ir_node
*
const
selector
=
get_Cond_selector
(
node
);
ir_node
*
const
flag_node
=
be_transform_node
(
selector
);
ir_relation
const
relation
=
get_Cmp_relation
(
selector
);
bool
const
is_unsigned
=
!
mode_is_signed
(
get_irn_mode
(
get_Cmp_left
(
selector
)
));
return
new_bd_amd64_Jcc
(
dbgi
,
block
,
flag
_node
,
relation
,
is_unsigned
);
ir_node
*
sel
=
get_Cond_selector
(
node
);
x86_condition_code_t
cc
;
ir_node
*
flags
=
get_flags_node
(
sel
,
&
cc
);
dbg_info
*
const
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
const
block
=
be_transform_node
(
get_nodes_block
(
node
));
return
new_bd_amd64_Jcc
(
dbgi
,
block
,
flag
s
,
cc
);
}
static
ir_node
*
gen_Phi
(
ir_node
*
node
)
...
...
ir/be/ia32/ia32_emitter.c
View file @
4baed155
...
...
@@ -309,40 +309,37 @@ static void ia32_emit_cfop_target(const ir_node *node)
be_gas_emit_block_name
(
block
);
}
/**
* Emit the suffix for a compare instruction.
*/
static
void
ia32_emit_condition_code
(
ia32_condition_code_t
cc
)
void
x86_emit_condition_code
(
x86_condition_code_t
cc
)
{
switch
(
cc
)
{
case
ia32
_cc_overflow
:
be_emit_cstring
(
"o"
);
return
;
case
ia32
_cc_not_overflow
:
be_emit_cstring
(
"no"
);
return
;
case
ia32
_cc_float_below
:
case
ia32
_cc_float_unordered_below
:
case
ia32
_cc_below
:
be_emit_cstring
(
"b"
);
return
;
case
ia32
_cc_float_above_equal
:
case
ia32
_cc_float_unordered_above_equal
:
case
ia32
_cc_above_equal
:
be_emit_cstring
(
"ae"
);
return
;
case
ia32
_cc_float_equal
:
case
ia32
_cc_equal
:
be_emit_cstring
(
"e"
);
return
;
case
ia32
_cc_float_not_equal
:
case
ia32
_cc_not_equal
:
be_emit_cstring
(
"ne"
);
return
;
case
ia32
_cc_float_below_equal
:
case
ia32
_cc_float_unordered_below_equal
:
case
ia32
_cc_below_equal
:
be_emit_cstring
(
"be"
);
return
;
case
ia32
_cc_float_above
:
case
ia32
_cc_float_unordered_above
:
case
ia32
_cc_above
:
be_emit_cstring
(
"a"
);
return
;
case
ia32
_cc_sign
:
be_emit_cstring
(
"s"
);
return
;
case
ia32
_cc_not_sign
:
be_emit_cstring
(
"ns"
);
return
;
case
ia32
_cc_parity
:
be_emit_cstring
(
"p"
);
return
;
case
ia32
_cc_not_parity
:
be_emit_cstring
(
"np"
);
return
;
case
ia32
_cc_less
:
be_emit_cstring
(
"l"
);
return
;
case
ia32
_cc_greater_equal
:
be_emit_cstring
(
"ge"
);
return
;
case
ia32
_cc_less_equal
:
be_emit_cstring
(
"le"
);
return
;
case
ia32
_cc_greater
:
be_emit_cstring
(
"g"
);
return
;
case
ia32
_cc_float_parity_cases
:
case
ia32
_cc_additional_float_cases
:
case
x86
_cc_overflow
:
be_emit_cstring
(
"o"
);
return
;
case
x86
_cc_not_overflow
:
be_emit_cstring
(
"no"
);
return
;
case
x86
_cc_float_below
:
case
x86
_cc_float_unordered_below
:
case
x86
_cc_below
:
be_emit_cstring
(
"b"
);
return
;
case
x86
_cc_float_above_equal
:
case
x86
_cc_float_unordered_above_equal
:
case
x86
_cc_above_equal
:
be_emit_cstring
(
"ae"
);
return
;
case
x86
_cc_float_equal
:
case
x86
_cc_equal
:
be_emit_cstring
(
"e"
);
return
;
case
x86
_cc_float_not_equal
:
case
x86
_cc_not_equal
:
be_emit_cstring
(
"ne"
);
return
;
case
x86
_cc_float_below_equal
:
case
x86
_cc_float_unordered_below_equal
:
case
x86
_cc_below_equal
:
be_emit_cstring
(
"be"
);
return
;
case
x86
_cc_float_above
:
case
x86
_cc_float_unordered_above
:
case
x86
_cc_above
:
be_emit_cstring
(
"a"
);
return
;
case
x86
_cc_sign
:
be_emit_cstring
(
"s"
);
return
;
case
x86
_cc_not_sign
:
be_emit_cstring
(
"ns"
);
return
;
case
x86
_cc_parity
:
be_emit_cstring
(
"p"
);
return
;
case
x86
_cc_not_parity
:
be_emit_cstring
(
"np"
);
return
;
case
x86
_cc_less
:
be_emit_cstring
(
"l"
);
return
;
case
x86
_cc_greater_equal
:
be_emit_cstring
(
"ge"
);
return
;
case
x86
_cc_less_equal
:
be_emit_cstring
(
"le"
);
return
;
case
x86
_cc_greater
:
be_emit_cstring
(
"g"
);
return
;
case
x86
_cc_float_parity_cases
:
case
x86
_cc_additional_float_cases
:
break
;
}
panic
(
"Invalid ia32 condition code"
);
...
...
@@ -420,7 +417,7 @@ static void ia32_emit_am(ir_node const *const node)
}
}
static
ia32
_condition_code_t
determine_final_cc
(
ir_node
const
*
node
,
int
flags_pos
,
ia32
_condition_code_t
cc
);
static
x86
_condition_code_t
determine_final_cc
(
ir_node
const
*
node
,
int
flags_pos
,
x86
_condition_code_t
cc
);
void
ia32_emitf
(
ir_node
const
*
const
node
,
char
const
*
fmt
,
...)
{
...
...
@@ -616,10 +613,10 @@ emit_I:
}
case
'P'
:
{
ia32
_condition_code_t
cc
;
x86
_condition_code_t
cc
;
if
(
*
fmt
==
'X'
)
{
++
fmt
;
cc
=
(
ia32
_condition_code_t
)
va_arg
(
ap
,
int
);
cc
=
(
x86
_condition_code_t
)
va_arg
(
ap
,
int
);
}
else
if
(
'0'
<=
*
fmt
&&
*
fmt
<=
'9'
)
{
cc
=
get_ia32_condcode
(
node
);
cc
=
determine_final_cc
(
node
,
*
fmt
-
'0'
,
cc
);
...
...
@@ -627,7 +624,7 @@ emit_I:
}
else
{
goto
unknown
;
}
ia32
_emit_condition_code
(
cc
);
x86
_emit_condition_code
(
cc
);
break
;
}
...
...
@@ -760,8 +757,9 @@ static ir_node *find_original_value(ir_node *node)
}
}
static
ia32_condition_code_t
determine_final_cc
(
const
ir_node
*
node
,
int
flags_pos
,
ia32_condition_code_t
cc
)
static
x86_condition_code_t
determine_final_cc
(
const
ir_node
*
node
,
int
flags_pos
,
x86_condition_code_t
cc
)
{
ir_node
*
flags
=
get_irn_n
(
node
,
flags_pos
);
const
ia32_attr_t
*
flags_attr
;
...
...
@@ -783,7 +781,7 @@ static ia32_condition_code_t determine_final_cc(const ir_node *node,
}
if
(
flags_attr
->
data
.
ins_permuted
)
cc
=
ia32
_invert_condition_code
(
cc
);
cc
=
x86
_invert_condition_code
(
cc
);
return
cc
;
}
...
...
@@ -808,8 +806,8 @@ static int can_be_fallthrough(const ir_node *node)
*/
static
void
emit_ia32_Jcc
(
const
ir_node
*
node
)
{
int
need_parity_label
=
0
;
ia32
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
int
need_parity_label
=
0
;
x86
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
cc
=
determine_final_cc
(
node
,
0
,
cc
);
...
...
@@ -826,13 +824,13 @@ static void emit_ia32_Jcc(const ir_node *node)
proj_true
=
proj_false
;
proj_false
=
t
;
cc
=
ia32
_negate_condition_code
(
cc
);
cc
=
x86
_negate_condition_code
(
cc
);
}
if
(
cc
&
ia32
_cc_float_parity_cases
)
{
if
(
cc
&
x86
_cc_float_parity_cases
)
{
/* Some floating point comparisons require a test of the parity flag,
* which indicates that the result is unordered */
if
(
cc
&
ia32
_cc_negated
)
{
if
(
cc
&
x86
_cc_negated
)
{
ia32_emitf
(
proj_true
,
"jp %L"
);
}
else
{
/* we need a local label if the false proj is a fallthrough
...
...
@@ -868,10 +866,10 @@ static void emit_ia32_Setcc(const ir_node *node)
{
const
arch_register_t
*
dreg
=
arch_get_irn_register_out
(
node
,
pn_ia32_Setcc_res
);
ia32
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
x86
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
cc
=
determine_final_cc
(
node
,
n_ia32_Setcc_eflags
,
cc
);
if
(
cc
&
ia32
_cc_float_parity_cases
)
{
if
(
cc
&
ia32
_cc_negated
)
{
if
(
cc
&
x86
_cc_float_parity_cases
)
{
if
(
cc
&
x86
_cc_negated
)
{
ia32_emitf
(
node
,
"set%PX %<R"
,
(
int
)
cc
,
dreg
);
ia32_emitf
(
node
,
"setp %>R"
,
dreg
);
ia32_emitf
(
node
,
"orb %>R, %<R"
,
dreg
,
dreg
);
...
...
@@ -889,7 +887,7 @@ static void emit_ia32_CMovcc(const ir_node *node)
{
const
ia32_attr_t
*
attr
=
get_ia32_attr_const
(
node
);
const
arch_register_t
*
out
=
arch_get_irn_register_out
(
node
,
pn_ia32_res
);
ia32
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
x86
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
const
arch_register_t
*
in_true
;
const
arch_register_t
*
in_false
;
...
...
@@ -899,7 +897,7 @@ static void emit_ia32_CMovcc(const ir_node *node)
* Permuting inputs of a cmov means the condition is negated!
*/
if
(
attr
->
data
.
ins_permuted
)
cc
=
ia32
_negate_condition_code
(
cc
);
cc
=
x86
_negate_condition_code
(
cc
);
in_true
=
arch_get_irn_register
(
get_irn_n
(
node
,
n_ia32_CMovcc_val_true
));
in_false
=
arch_get_irn_register
(
get_irn_n
(
node
,
n_ia32_CMovcc_val_false
));
...
...
@@ -912,7 +910,7 @@ static void emit_ia32_CMovcc(const ir_node *node)
assert
(
get_ia32_op_type
(
node
)
==
ia32_Normal
);
cc
=
ia32
_negate_condition_code
(
cc
);
cc
=
x86
_negate_condition_code
(
cc
);
tmp
=
in_true
;
in_true
=
in_false
;
...
...
@@ -922,7 +920,7 @@ static void emit_ia32_CMovcc(const ir_node *node)
ia32_emitf
(
node
,
"movl %R, %R"
,
in_false
,
out
);
}
if
(
cc
&
ia32
_cc_float_parity_cases
)
{
if
(
cc
&
x86
_cc_float_parity_cases
)
{
panic
(
"CMov with floatingpoint compare/parity not supported yet"
);
}
...
...
@@ -1759,7 +1757,7 @@ static const lc_opt_table_entry_t ia32_emitter_options[] = {
/* ==== Experimental binary emitter ==== */
/** Returns the encoding for a pnc field. */
static
unsigned
char
pnc2cc
(
ia32
_condition_code_t
cc
)
static
unsigned
char
pnc2cc
(
x86
_condition_code_t
cc
)
{
return
cc
&
0xf
;
}
...
...
@@ -2344,10 +2342,10 @@ static void bemit_setcc(const ir_node *node)
{
const
arch_register_t
*
dreg
=
arch_get_irn_register_out
(
node
,
pn_ia32_Setcc_res
);
ia32
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
x86
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
cc
=
determine_final_cc
(
node
,
n_ia32_Setcc_eflags
,
cc
);
if
(
cc
&
ia32
_cc_float_parity_cases
)
{
if
(
cc
&
ia32
_cc_negated
)
{
if
(
cc
&
x86
_cc_float_parity_cases
)
{
if
(
cc
&
x86
_cc_negated
)
{
/* set%PNC <dreg */
bemit8
(
0x0F
);
bemit8
(
0x90
|
pnc2cc
(
cc
));
...
...
@@ -2424,7 +2422,7 @@ static void bemit_cmovcc(const ir_node *node)
const
ia32_attr_t
*
attr
=
get_ia32_attr_const
(
node
);
int
ins_permuted
=
attr
->
data
.
ins_permuted
;
const
arch_register_t
*
out
=
arch_get_irn_register_out
(
node
,
pn_ia32_res
);
ia32
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
x86
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
const
arch_register_t
*
in_true
;
const
arch_register_t
*
in_false
;
...
...
@@ -2447,9 +2445,9 @@ static void bemit_cmovcc(const ir_node *node)
}
if
(
ins_permuted
)
cc
=
ia32
_negate_condition_code
(
cc
);
cc
=
x86
_negate_condition_code
(
cc
);
if
(
cc
&
ia32
_cc_float_parity_cases
)
if
(
cc
&
x86
_cc_float_parity_cases
)
panic
(
"cmov can't handle parity float cases"
);
bemit8
(
0x0F
);
...
...
@@ -2881,7 +2879,7 @@ static void bemit_jump(const ir_node *node)
bemit_jmp
(
get_cfop_target_block
(
node
));
}
static
void
bemit_jcc
(
ia32
_condition_code_t
pnc
,
const
ir_node
*
dest_block
)
static
void
bemit_jcc
(
x86
_condition_code_t
pnc
,
const
ir_node
*
dest_block
)
{
unsigned
char
cc
=
pnc2cc
(
pnc
);
bemit8
(
0x0F
);
...
...
@@ -2898,7 +2896,7 @@ static void bemit_jp(bool odd, const ir_node *dest_block)
static
void
bemit_ia32_jcc
(
const
ir_node
*
node
)
{
ia32
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
x86
_condition_code_t
cc
=
get_ia32_condcode
(
node
);
const
ir_node
*
dest_true
;
const
ir_node
*
dest_false
;
...
...
@@ -2917,16 +2915,16 @@ static void bemit_ia32_jcc(const ir_node *node)
proj_true
=
proj_false
;
proj_false
=
t
;
cc
=
ia32
_negate_condition_code
(
cc
);
cc
=
x86
_negate_condition_code
(
cc
);
}
dest_true
=
get_cfop_target_block
(
proj_true
);
dest_false
=
get_cfop_target_block
(
proj_false
);
if
(
cc
&
ia32
_cc_float_parity_cases
)
{
if
(
cc
&
x86
_cc_float_parity_cases
)
{
/* Some floating point comparisons require a test of the parity flag,
* which indicates that the result is unordered */
if
(
cc
&
ia32
_cc_negated
)
{
if
(
cc
&
x86
_cc_negated
)
{
bemit_jp
(
false
,
dest_true
);
}
else
{
/* we need a local label if the false proj is a fallthrough
...
...
ir/be/ia32/ia32_new_nodes.c
View file @
4baed155
...
...
@@ -654,7 +654,7 @@ const ir_switch_table *get_ia32_switch_table(const ir_node *node)
return
attr
->
table
;
}
ia32
_condition_code_t
get_ia32_condcode
(
const
ir_node
*
node
)
x86
_condition_code_t
get_ia32_condcode
(
const
ir_node
*
node
)
{
const
ia32_condcode_attr_t
*
attr
=
get_ia32_condcode_attr_const
(
node
);
return
attr
->
condition_code
;
...
...
@@ -663,7 +663,7 @@ ia32_condition_code_t get_ia32_condcode(const ir_node *node)
/**
* Sets the condition code of a node
*/
void
set_ia32_condcode
(
ir_node
*
node
,
ia32
_condition_code_t
code
)
void
set_ia32_condcode
(
ir_node
*
node
,
x86
_condition_code_t
code
)
{
ia32_condcode_attr_t
*
attr
=
get_ia32_condcode_attr
(
node
);
attr
->
condition_code
=
code
;
...
...
@@ -836,7 +836,7 @@ static void init_ia32_copyb_attributes(ir_node *res, unsigned size)
}
static
void
init_ia32_condcode_attributes
(
ir_node
*
res
,
ia32
_condition_code_t
cc
)
x86
_condition_code_t
cc
)
{
ia32_condcode_attr_t
*
attr
=
(
ia32_condcode_attr_t
*
)
get_irn_generic_attr
(
res
);
...
...
ir/be/ia32/ia32_new_nodes.h
View file @
4baed155
...
...
@@ -230,12 +230,12 @@ void set_ia32_frame_ent(ir_node *node, ir_entity *ent);
/**
* Returns the condition code of a node.
*/
ia32
_condition_code_t
get_ia32_condcode
(
const
ir_node
*
node
);
x86
_condition_code_t
get_ia32_condcode
(
const
ir_node
*
node
);
/**
* Sets the condition code of a node
*/
void
set_ia32_condcode
(
ir_node
*
node
,
ia32
_condition_code_t
code
);
void
set_ia32_condcode
(
ir_node
*
node
,
x86
_condition_code_t
code
);
const
ir_switch_table
*
get_ia32_switch_table
(
const
ir_node
*
node
);
...
...
ir/be/ia32/ia32_nodes_attr.h
View file @
4baed155
...
...
@@ -14,88 +14,7 @@
#include "firm_types.h"
#include "bearch.h"
#include "irnode_t.h"
/** ia32 condition codes (the numbers correspond to the real encoding order) */
typedef
enum
ia32_condition_code_t
{
ia32_cc_negated
=
0x01
,
/**< negates condition */
ia32_cc_overflow
=
0x00
,
/**< OF=1 */
ia32_cc_below
=
0x02
,
/**< CF=1 */
ia32_cc_equal
=
0x04
,
/**< ZF=1 */
ia32_cc_below_equal
=
0x06
,
/**< ZF=1 or CF=1 */
ia32_cc_sign
=
0x08
,
/**< SF=1 */
ia32_cc_parity
=
0x0A
,
/**< PF=1 */
ia32_cc_less
=
0x0C
,
/**< SF!=OF */
ia32_cc_less_equal
=
0x0E
,
/**< ZF=1 or SF!=OF */
ia32_cc_not_overflow
=
ia32_cc_negated
|
ia32_cc_overflow
,
/**< OF=0 */
ia32_cc_above_equal
=
ia32_cc_negated
|
ia32_cc_below
,
/**< CF=0 */
ia32_cc_not_equal
=
ia32_cc_negated
|
ia32_cc_equal
,
/**< ZF=0 */
ia32_cc_above
=
ia32_cc_negated
|
ia32_cc_below_equal
,
/**< ZF=0 and CF=0 */
ia32_cc_not_sign
=
ia32_cc_negated
|
ia32_cc_sign
,
/**< SF=0 */
ia32_cc_not_parity
=
ia32_cc_negated
|
ia32_cc_parity
,
/**< PF=0 */
ia32_cc_greater_equal
=
ia32_cc_negated
|
ia32_cc_less
,
/**< SF=OF */
ia32_cc_greater
=
ia32_cc_negated
|
ia32_cc_less_equal
,
/**< ZF=0 and SF=OF */
/* the following codes are (unfortunately) NOT real hardware codes but
* simplify our backend as you need these combinations for some
* floatingpoint compares (the emitter will split them into multiple
* instructions) */
ia32_cc_float_parity_cases
=
0x20
,
/* we need even more cases as inversing the cc is different for float
* comparisons (though for the following we need no special
* parity+x combinations) */
ia32_cc_additional_float_cases
=
0x10
,
/* make sure that the lower 4 bit correspond to the real encoding
* (of the comparison not involving the parity special) */
ia32_cc_float_equal
=
0x34
,
/**< PF=0 and ZF=1 */
ia32_cc_float_below
=
0x32
,
/**< PF=0 and CF=1 */
ia32_cc_float_below_equal
=
0x36
,
/**< PF=0 and (ZF=1 or CF=1) */
ia32_cc_float_not_equal
=
ia32_cc_negated
|
ia32_cc_float_equal
,
/**< PF=1 or ZF=0 */
ia32_cc_float_unordered_above_equal
=
ia32_cc_negated
|
ia32_cc_float_below
,
/**< PF=1 or CF=0 */
ia32_cc_float_unordered_above
=
ia32_cc_negated
|
ia32_cc_float_below_equal
,
/**< PF=1 or (ZF=0 and CF=0) */
ia32_cc_float_unordered_below_equal
=
0x16
,
/**< ZF=1 or CF=1 */
ia32_cc_float_unordered_below
=
0x12
,
/**< CF=1 */
ia32_cc_float_above
=
ia32_cc_negated
|
ia32_cc_float_unordered_below_equal
,
/**< ZF=0 and CF=0 */
ia32_cc_float_above_equal
=
ia32_cc_negated
|
ia32_cc_float_unordered_below
,
/**< CF=0 */
}
ia32_condition_code_t
;
ENUM_BITSET
(
ia32_condition_code_t
)
static
inline
ia32_condition_code_t
ia32_negate_condition_code
(
ia32_condition_code_t
code
)
{
return
code
^
ia32_cc_negated
;
}
static
inline
ia32_condition_code_t
ia32_invert_condition_code
(
ia32_condition_code_t
code
)
{
/* doesn't appear to have any systematic, so use a table */
switch
(
code
)
{
case
ia32_cc_below
:
return
ia32_cc_above
;
case
ia32_cc_below_equal
:
return
ia32_cc_above_equal
;
case
ia32_cc_above
:
return
ia32_cc_below
;
case
ia32_cc_above_equal
:
return
ia32_cc_below_equal
;
case
ia32_cc_less
:
return
ia32_cc_greater
;
case
ia32_cc_less_equal
:
return
ia32_cc_greater_equal
;
case
ia32_cc_greater
:
return
ia32_cc_less
;
case
ia32_cc_greater_equal
:
return
ia32_cc_less_equal
;
case
ia32_cc_float_below
:
return
ia32_cc_float_above
;
case
ia32_cc_float_below_equal
:
return
ia32_cc_float_above_equal
;
case
ia32_cc_float_above
:
return
ia32_cc_float_below
;
case
ia32_cc_float_above_equal
:
return
ia32_cc_float_below_equal
;
case
ia32_cc_float_unordered_below
:
return
ia32_cc_float_unordered_above
;
case
ia32_cc_float_unordered_below_equal
:
return
ia32_cc_float_unordered_above_equal
;
case
ia32_cc_float_unordered_above
:
return
ia32_cc_float_unordered_below
;
case
ia32_cc_float_unordered_above_equal
:
return
ia32_cc_float_unordered_below_equal
;
default:
return
code
;
}
}
#include "x86_cc.h"
typedef
enum
{
ia32_Normal
,
...
...
@@ -215,8 +134,8 @@ struct ia32_call_attr_t {
*/
typedef
struct
ia32_condcode_attr_t
ia32_condcode_attr_t
;
struct
ia32_condcode_attr_t
{
ia32_attr_t
attr
;
/**< generic attribute */
ia32
_condition_code_t
condition_code
;
/**< condition code*/
ia32_attr_t
attr
;
/**< generic attribute */
x86
_condition_code_t
condition_code
;
/**< condition code*/
};
/**
...
...
ir/be/ia32/ia32_optimize.c
View file @
4baed155
...
...
@@ -214,12 +214,12 @@ static void peephole_ia32_Test(ir_node *node)