Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
b4e27346
Commit
b4e27346
authored
Jul 22, 2010
by
Matthias Braun
Browse files
sparc: fix unsigned compares and cleanup cmp attributes
[r27786]
parent
a0792e93
Changes
6
Hide whitespace changes
Inline
Side-by-side
ir/be/sparc/sparc_emitter.c
View file @
b4e27346
...
...
@@ -591,22 +591,19 @@ static void emit_sparc_FrameAddr(const ir_node *irn)
/**
* Emits code for Branch
*/
static
void
emit_sparc_BXX
(
const
ir_node
*
irn
)
static
void
emit_sparc_BXX
(
const
ir_node
*
node
)
{
const
sparc_jmp_cond_attr_t
*
attr
=
get_sparc_jmp_cond_attr_const
(
node
);
int
proj_num
=
attr
->
proj_num
;
bool
is_unsigned
=
attr
->
is_unsigned
;
const
ir_node
*
proj_true
=
NULL
;
const
ir_node
*
proj_false
=
NULL
;
const
ir_edge_t
*
edge
;
const
ir_node
*
proj_true
=
NULL
;
const
ir_node
*
proj_false
=
NULL
;
const
ir_node
*
block
;
const
ir_node
*
next_block
;
ir_node
*
op1
=
get_irn_n
(
irn
,
0
);
const
char
*
suffix
;
int
proj_num
=
get_sparc_jmp_cond_proj_num
(
irn
);
const
sparc_cmp_attr_t
*
cmp_attr
=
get_irn_generic_attr_const
(
op1
);
// bool is_signed = !cmp_attr->is_unsigned;
assert
(
is_sparc_Cmp
(
op1
)
||
is_sparc_Tst
(
op1
));
foreach_out_edge
(
irn
,
edge
)
{
const
ir_node
*
block
;
const
ir_node
*
next_block
;
const
char
*
suffix
;
foreach_out_edge
(
node
,
edge
)
{
ir_node
*
proj
=
get_edge_src_irn
(
edge
);
long
nr
=
get_Proj_proj
(
proj
);
if
(
nr
==
pn_Cond_true
)
{
...
...
@@ -616,12 +613,8 @@ static void emit_sparc_BXX(const ir_node *irn)
}
}
if
(
cmp_attr
->
ins_permuted
)
{
proj_num
=
get_mirrored_pnc
(
proj_num
);
}
/* for now, the code works for scheduled and non-schedules blocks */
block
=
get_nodes_block
(
irn
);
block
=
get_nodes_block
(
node
);
/* we have a block schedule */
next_block
=
get_irn_link
(
block
);
...
...
@@ -638,20 +631,32 @@ static void emit_sparc_BXX(const ir_node *irn)
proj_num
=
get_negated_pnc
(
proj_num
,
mode_Iu
);
}
switch
(
proj_num
)
{
case
pn_Cmp_Eq
:
suffix
=
"e"
;
break
;
case
pn_Cmp_Lt
:
suffix
=
"l"
;
break
;
case
pn_Cmp_Le
:
suffix
=
"le"
;
break
;
case
pn_Cmp_Gt
:
suffix
=
"g"
;
break
;
case
pn_Cmp_Ge
:
suffix
=
"ge"
;
break
;
case
pn_Cmp_Lg
:
suffix
=
"ne"
;
break
;
case
pn_Cmp_Leg
:
suffix
=
"a"
;
break
;
default:
panic
(
"Cmp has unsupported pnc"
);
if
(
is_unsigned
)
{
switch
(
proj_num
)
{
case
pn_Cmp_Eq
:
suffix
=
"e"
;
break
;
case
pn_Cmp_Lt
:
suffix
=
"lu"
;
break
;
case
pn_Cmp_Le
:
suffix
=
"leu"
;
break
;
case
pn_Cmp_Gt
:
suffix
=
"gu"
;
break
;
case
pn_Cmp_Ge
:
suffix
=
"geu"
;
break
;
case
pn_Cmp_Lg
:
suffix
=
"ne"
;
break
;
default:
panic
(
"Cmp has unsupported pnc"
);
}
}
else
{
switch
(
proj_num
)
{
case
pn_Cmp_Eq
:
suffix
=
"e"
;
break
;
case
pn_Cmp_Lt
:
suffix
=
"l"
;
break
;
case
pn_Cmp_Le
:
suffix
=
"le"
;
break
;
case
pn_Cmp_Gt
:
suffix
=
"g"
;
break
;
case
pn_Cmp_Ge
:
suffix
=
"ge"
;
break
;
case
pn_Cmp_Lg
:
suffix
=
"ne"
;
break
;
default:
panic
(
"Cmp has unsupported pnc"
);
}
}
/* emit the true proj */
be_emit_irprintf
(
"
\t
b%s "
,
suffix
);
be_emit_cstring
(
"
\t
b"
);
be_emit_string
(
suffix
);
be_emit_char
(
' '
);
sparc_emit_cfop_target
(
proj_true
);
be_emit_finish_line_gas
(
proj_true
);
...
...
ir/be/sparc/sparc_new_nodes.c
View file @
b4e27346
...
...
@@ -55,11 +55,6 @@ static bool has_load_store_attr(const ir_node *node)
return
is_sparc_Ld
(
node
)
||
is_sparc_St
(
node
);
}
static
bool
has_cmp_attr
(
const
ir_node
*
node
)
{
return
is_sparc_Cmp
(
node
)
||
is_sparc_Tst
(
node
);
}
static
bool
has_jmp_cond_attr
(
const
ir_node
*
node
)
{
return
is_sparc_BXX
(
node
);
...
...
@@ -115,10 +110,12 @@ static void sparc_set_attr_imm(ir_node *res, int immediate_value)
attr
->
immediate_value
=
immediate_value
;
}
void
set_sparc_jmp_cond_proj_num
(
ir_node
*
node
,
int
proj_num
)
static
void
init_sparc_jmp_cond_attr
(
ir_node
*
node
,
int
proj_num
,
bool
is_unsigned
)
{
sparc_jmp_cond_attr_t
*
attr
=
get_sparc_jmp_cond_attr
(
node
);
attr
->
proj_num
=
proj_num
;
attr
->
proj_num
=
proj_num
;
attr
->
is_unsigned
=
is_unsigned
;
}
void
set_sparc_jmp_switch_n_projs
(
ir_node
*
node
,
int
n_projs
)
...
...
@@ -135,12 +132,6 @@ void set_sparc_jmp_switch_default_proj_num(ir_node *node, long def_proj_num)
int
get_sparc_jmp_cond_proj_num
(
const
ir_node
*
node
)
{
const
sparc_jmp_cond_attr_t
*
attr
=
get_sparc_jmp_cond_attr_const
(
node
);
return
attr
->
proj_num
;
}
int
get_sparc_jmp_switch_n_projs
(
const
ir_node
*
node
)
{
const
sparc_jmp_switch_attr_t
*
attr
=
get_sparc_jmp_switch_attr_const
(
node
);
...
...
@@ -213,18 +204,6 @@ const sparc_jmp_switch_attr_t *get_sparc_jmp_switch_attr_const(const ir_node *no
return
(
const
sparc_jmp_switch_attr_t
*
)
get_irn_generic_attr_const
(
node
);
}
sparc_cmp_attr_t
*
get_sparc_cmp_attr
(
ir_node
*
node
)
{
assert
(
has_cmp_attr
(
node
));
return
(
sparc_cmp_attr_t
*
)
get_irn_generic_attr_const
(
node
);
}
const
sparc_cmp_attr_t
*
get_sparc_cmp_attr_const
(
const
ir_node
*
node
)
{
assert
(
has_cmp_attr
(
node
));
return
(
const
sparc_cmp_attr_t
*
)
get_irn_generic_attr_const
(
node
);
}
sparc_save_attr_t
*
get_sparc_save_attr
(
ir_node
*
node
)
{
assert
(
has_save_attr
(
node
));
...
...
@@ -302,13 +281,6 @@ static void init_sparc_load_store_attributes(ir_node *res, ir_mode *ls_mode,
attr
->
base
.
is_load_store
=
true
;
}
static
void
init_sparc_cmp_attr
(
ir_node
*
res
,
bool
ins_permuted
,
bool
is_unsigned
)
{
sparc_cmp_attr_t
*
attr
=
get_sparc_cmp_attr
(
res
);
attr
->
ins_permuted
=
ins_permuted
;
attr
->
is_unsigned
=
is_unsigned
;
}
static
void
init_sparc_symconst_attributes
(
ir_node
*
res
,
ir_entity
*
entity
)
{
sparc_symconst_attr_t
*
attr
=
get_sparc_symconst_attr
(
res
);
...
...
@@ -390,7 +362,8 @@ static int cmp_attr_sparc_jmp_cond(ir_node *a, ir_node *b)
if
(
cmp_attr_sparc
(
a
,
b
))
return
1
;
return
attr_a
->
proj_num
!=
attr_b
->
proj_num
;
return
attr_a
->
proj_num
!=
attr_b
->
proj_num
||
attr_a
->
is_unsigned
!=
attr_b
->
is_unsigned
;
}
static
int
cmp_attr_sparc_jmp_switch
(
ir_node
*
a
,
ir_node
*
b
)
...
...
@@ -405,18 +378,6 @@ static int cmp_attr_sparc_jmp_switch(ir_node *a, ir_node *b)
||
attr_a
->
n_projs
!=
attr_b
->
n_projs
;
}
static
int
cmp_attr_sparc_cmp
(
ir_node
*
a
,
ir_node
*
b
)
{
const
sparc_cmp_attr_t
*
attr_a
=
get_sparc_cmp_attr_const
(
a
);
const
sparc_cmp_attr_t
*
attr_b
=
get_sparc_cmp_attr_const
(
b
);
if
(
cmp_attr_sparc
(
a
,
b
))
return
1
;
return
attr_a
->
ins_permuted
!=
attr_b
->
ins_permuted
||
attr_a
->
is_unsigned
!=
attr_b
->
is_unsigned
;
}
static
int
cmp_attr_sparc_save
(
ir_node
*
a
,
ir_node
*
b
)
{
const
sparc_save_attr_t
*
attr_a
=
get_sparc_save_attr_const
(
a
);
...
...
ir/be/sparc/sparc_new_nodes.h
View file @
b4e27346
...
...
@@ -45,9 +45,6 @@ const sparc_jmp_cond_attr_t *get_sparc_jmp_cond_attr_const(const ir_node *node);
sparc_jmp_switch_attr_t
*
get_sparc_jmp_switch_attr
(
ir_node
*
node
);
const
sparc_jmp_switch_attr_t
*
get_sparc_jmp_switch_attr_const
(
const
ir_node
*
node
);
sparc_cmp_attr_t
*
get_sparc_cmp_attr
(
ir_node
*
node
);
const
sparc_cmp_attr_t
*
get_sparc_cmp_attr_const
(
const
ir_node
*
node
);
sparc_save_attr_t
*
get_sparc_save_attr
(
ir_node
*
node
);
const
sparc_save_attr_t
*
get_sparc_save_attr_const
(
const
ir_node
*
node
);
...
...
@@ -66,18 +63,6 @@ const arch_register_req_t *get_sparc_in_req(const ir_node *node, int pos);
*/
void
set_sparc_req_in
(
ir_node
*
node
,
const
arch_register_req_t
*
req
,
int
pos
);
/**
* Returns the proj num
*/
int
get_sparc_jmp_cond_proj_num
(
const
ir_node
*
node
);
/**
* Sets the proj num
*/
void
set_sparc_jmp_cond_proj_num
(
ir_node
*
node
,
int
proj_num
);
/**
* Returns the number of projs of a SwitchJmp.
*/
...
...
ir/be/sparc/sparc_nodes_attr.h
View file @
b4e27346
...
...
@@ -88,6 +88,7 @@ typedef struct sparc_jmp_cond_attr_t sparc_jmp_cond_attr_t;
struct
sparc_jmp_cond_attr_t
{
sparc_attr_t
base
;
/**< generic attribute */
int
proj_num
;
bool
is_unsigned
:
1
;
};
/**
...
...
@@ -100,14 +101,4 @@ struct sparc_jmp_switch_attr_t {
long
default_proj_num
;
};
/**
* attributes for Cmp
*/
typedef
struct
sparc_cmp_attr_t
sparc_cmp_attr_t
;
struct
sparc_cmp_attr_t
{
sparc_attr_t
base
;
/**< generic attribute */
bool
ins_permuted
:
1
;
bool
is_unsigned
:
1
;
};
#endif
ir/be/sparc/sparc_spec.pl
View file @
b4e27346
...
...
@@ -140,7 +140,6 @@ $default_copy_attr = "sparc_copy_attr";
"
\t
init_sparc_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);
",
sparc_symconst_attr_t
=>
"
\t
init_sparc_attributes(res, flags, in_reqs, exec_units, n_res);
\n
"
.
"
\t
init_sparc_symconst_attributes(res, entity);
",
sparc_cmp_attr_t
=>
"
\t
init_sparc_attributes(res, flags, in_reqs, exec_units, n_res);
\n
",
sparc_jmp_cond_attr_t
=>
"
\t
init_sparc_attributes(res, flags, in_reqs, exec_units, n_res);
",
sparc_jmp_switch_attr_t
=>
"
\t
init_sparc_attributes(res, flags, in_reqs, exec_units, n_res);
",
sparc_save_attr_t
=>
"
\t
init_sparc_attributes(res, flags, in_reqs, exec_units, n_res);
",
...
...
@@ -153,7 +152,6 @@ $default_copy_attr = "sparc_copy_attr";
sparc_symconst_attr_t
=>
"
cmp_attr_sparc_symconst
",
sparc_jmp_cond_attr_t
=>
"
cmp_attr_sparc_jmp_cond
",
sparc_jmp_switch_attr_t
=>
"
cmp_attr_sparc_jmp_switch
",
sparc_cmp_attr_t
=>
"
cmp_attr_sparc_cmp
",
sparc_save_attr_t
=>
"
cmp_attr_sparc_save
",
);
...
...
@@ -162,15 +160,12 @@ $default_copy_attr = "sparc_copy_attr";
my
%cmp_operand_constructors
=
(
imm
=>
{
attr
=>
"
int immediate_value, bool ins_permuted, bool is_unsigned
",
custominit
=>
"
sparc_set_attr_imm(res, immediate_value);
"
.
"
\t
init_sparc_cmp_attr(res, ins_permuted, is_unsigned);
",
attr
=>
"
int immediate_value
",
custominit
=>
"
sparc_set_attr_imm(res, immediate_value);
",
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
flags
"
]
},
ins
=>
[
"
left
"
],
ins
=>
[
"
left
"
],
},
reg
=>
{
attr
=>
"
bool ins_permuted, bool is_unsigned
",
custominit
=>
"
init_sparc_cmp_attr(res, ins_permuted, is_unsigned);
",
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
flags
"
]
},
ins
=>
[
"
left
",
"
right
"
],
},
...
...
@@ -321,9 +316,9 @@ BXX => {
state
=>
"
pinned
",
mode
=>
"
mode_T
",
reg_req
=>
{
in
=>
[
"
flags
"
],
out
=>
[
"
none
",
"
none
"
]
},
attr
=>
"
int proj_num
",
attr
=>
"
int proj_num
, bool is_unsigned
",
attr_type
=>
"
sparc_jmp_cond_attr_t
",
init_attr
=>
"
\t
se
t_sparc_jmp_cond_
proj_num
(res, proj_num);
",
init_attr
=>
"
\t
ini
t_sparc_jmp_cond_
attr
(res, proj_num
, is_unsigned
);
",
},
Ba
=>
{
...
...
@@ -338,7 +333,6 @@ Cmp => {
irn_flags
=>
[
"
rematerializable
",
"
modify_flags
"
],
emit
=>
'
. cmp %S1, %R2I
',
mode
=>
$mode_flags
,
attr_type
=>
"
sparc_cmp_attr_t
",
constructors
=>
\
%cmp_operand_constructors
,
},
...
...
@@ -346,11 +340,8 @@ Tst => {
irn_flags
=>
[
"
rematerializable
",
"
modify_flags
"
],
emit
=>
'
. tst %S1
',
mode
=>
$mode_flags
,
attr_type
=>
"
sparc_cmp_attr_t
",
attr
=>
"
bool ins_permuted, bool is_unsigned
",
custominit
=>
"
init_sparc_cmp_attr(res, ins_permuted, is_unsigned);
",
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
flags
"
]
},
ins
=>
[
"
left
"
],
ins
=>
[
"
val
"
],
},
SwitchJmp
=>
{
...
...
ir/be/sparc/sparc_transform.c
View file @
b4e27346
...
...
@@ -709,6 +709,20 @@ static ir_node *gen_SwitchJmp(ir_node *node)
return
new_bd_sparc_SwitchJmp
(
dbgi
,
block
,
sub
,
n_projs
,
get_Cond_default_proj
(
node
)
-
translation
);
}
static
bool
is_cmp_unsigned
(
ir_node
*
b_value
)
{
ir_node
*
pred
;
ir_node
*
op
;
if
(
!
is_Proj
(
b_value
))
panic
(
"can't determine cond signednes"
);
pred
=
get_Proj_pred
(
b_value
);
if
(
!
is_Cmp
(
pred
))
panic
(
"can't determine cond signednes (no cmp)"
);
op
=
get_Cmp_left
(
pred
);
return
!
mode_is_signed
(
get_irn_mode
(
op
));
}
/**
* Transform Cond nodes
*/
...
...
@@ -718,6 +732,8 @@ static ir_node *gen_Cond(ir_node *node)
ir_mode
*
mode
=
get_irn_mode
(
selector
);
ir_node
*
block
;
ir_node
*
flag_node
;
bool
is_unsigned
;
pn_Cmp
pnc
;
dbg_info
*
dbgi
;
// switch/case jumps
...
...
@@ -727,11 +743,14 @@ static ir_node *gen_Cond(ir_node *node)
// regular if/else jumps
assert
(
is_Proj
(
selector
));
block
=
be_transform_node
(
get_nodes_block
(
node
));
dbgi
=
get_irn_dbg_info
(
node
);
flag_node
=
be_transform_node
(
get_Proj_pred
(
selector
));
return
new_bd_sparc_BXX
(
dbgi
,
block
,
flag_node
,
get_Proj_proj
(
selector
));
assert
(
is_Cmp
(
get_Proj_pred
(
selector
)));
block
=
be_transform_node
(
get_nodes_block
(
node
));
dbgi
=
get_irn_dbg_info
(
node
);
flag_node
=
be_transform_node
(
get_Proj_pred
(
selector
));
pnc
=
get_Proj_proj
(
selector
);
is_unsigned
=
is_cmp_unsigned
(
selector
);
return
new_bd_sparc_BXX
(
dbgi
,
block
,
flag_node
,
pnc
,
is_unsigned
);
}
/**
...
...
@@ -746,7 +765,6 @@ static ir_node *gen_Cmp(ir_node *node)
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
new_op1
;
ir_node
*
new_op2
;
bool
is_unsigned
;
if
(
mode_is_float
(
cmp_mode
))
{
panic
(
"FloatCmp not implemented"
);
...
...
@@ -759,7 +777,6 @@ static ir_node *gen_Cmp(ir_node *node)
*/
assert
(
get_irn_mode
(
op2
)
==
cmp_mode
);
is_unsigned
=
!
mode_is_signed
(
cmp_mode
);
/* compare with 0 can be done with Tst */
/*
...
...
@@ -781,7 +798,7 @@ static ir_node *gen_Cmp(ir_node *node)
new_op1
=
gen_extension
(
dbgi
,
block
,
new_op1
,
cmp_mode
);
new_op2
=
be_transform_node
(
op2
);
new_op2
=
gen_extension
(
dbgi
,
block
,
new_op2
,
cmp_mode
);
return
new_bd_sparc_Cmp_reg
(
dbgi
,
block
,
new_op1
,
new_op2
,
false
,
is_unsigned
);
return
new_bd_sparc_Cmp_reg
(
dbgi
,
block
,
new_op1
,
new_op2
);
}
/**
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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