Commit b4e27346 authored by Matthias Braun's avatar Matthias Braun
Browse files

sparc: fix unsigned compares and cleanup cmp attributes

[r27786]
parent a0792e93
......@@ -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("\tb%s ", suffix);
be_emit_cstring("\tb");
be_emit_string(suffix);
be_emit_char(' ');
sparc_emit_cfop_target(proj_true);
be_emit_finish_line_gas(proj_true);
......
......@@ -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);
......
......@@ -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.
*/
......
......@@ -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
......@@ -140,7 +140,6 @@ $default_copy_attr = "sparc_copy_attr";
"\tinit_sparc_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);",
sparc_symconst_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
"\tinit_sparc_symconst_attributes(res, entity);",
sparc_cmp_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n",
sparc_jmp_cond_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
sparc_jmp_switch_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
sparc_save_attr_t => "\tinit_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);" .
"\tinit_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 => "\tset_sparc_jmp_cond_proj_num(res, proj_num);",
init_attr => "\tinit_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 => {
......
......@@ -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);
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment