/**
* 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) {
}
}
- 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);
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);
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);
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)
-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);
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));
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);
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)
|| 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);
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);
*/
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.
*/
struct sparc_jmp_cond_attr_t {
sparc_attr_t base; /**< generic attribute */
int proj_num;
+ bool is_unsigned : 1;
};
/**
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
"\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);",
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",
);
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" ],
},
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 => {
irn_flags => [ "rematerializable", "modify_flags" ],
emit => '. cmp %S1, %R2I',
mode => $mode_flags,
- attr_type => "sparc_cmp_attr_t",
constructors => \%cmp_operand_constructors,
},
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 => {
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
*/
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
// 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);
}
/**
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");
*/
assert(get_irn_mode(op2) == cmp_mode);
- is_unsigned = !mode_is_signed(cmp_mode);
/* compare with 0 can be done with Tst */
/*
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);
}
/**