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

started adding a relation to the Cmp node

parent 154104ce
......@@ -117,6 +117,29 @@ typedef ir_node *uninitialized_local_variable_func_t(ir_graph *irg, ir_mode *mod
# define ENUM_COUNTABLE(type)
#endif
/**
* Relations for comparing numbers
*/
typedef enum ir_relation {
ir_relation_false = 0, /**< always false */
ir_relation_equal = 1u << 0, /**< equal */
ir_relation_less = 1u << 1, /**< less */
ir_relation_greater = 1u << 2, /**< greater */
ir_relation_unordered = 1u << 3, /**< unordered */
ir_relation_less_equal = ir_relation_equal|ir_relation_less, /**< less or equal */
ir_relation_greater_equal = ir_relation_equal|ir_relation_greater, /**< greater or equal */
ir_relation_less_greater = ir_relation_less|ir_relation_greater, /** less or greater ('not equal' for integer numbers) */
ir_relation_less_equal_greater = ir_relation_equal|ir_relation_less|ir_relation_greater, /**< less equal or greater ('not unordered') */
ir_relation_unordered_equal = ir_relation_unordered|ir_relation_equal, /**< unordered or equal */
ir_relation_unordered_less = ir_relation_unordered|ir_relation_less, /**< unorderedor less */
ir_relation_unordered_less_equal = ir_relation_unordered|ir_relation_less|ir_relation_equal, /**< unordered, less or equal */
ir_relation_unordered_greater = ir_relation_unordered|ir_relation_greater, /**< unordered or greater */
ir_relation_unordered_greater_equal = ir_relation_unordered|ir_relation_greater|ir_relation_equal, /**< unordered, greater or equal */
ir_relation_unordered_less_greater = ir_relation_unordered|ir_relation_less|ir_relation_greater, /**< unordered, less or greater ('not equal' for floatingpoint numbers) */
ir_relation_true = ir_relation_equal|ir_relation_less|ir_relation_greater|ir_relation_unordered, /**< always true */
} ir_relation;
ENUM_BITSET(ir_relation)
/**
* constrained flags for memory operations.
*/
......
......@@ -493,17 +493,14 @@ FIRM_API void set_binop_left(ir_node *node, ir_node *left);
FIRM_API ir_node *get_binop_right(const ir_node *node);
FIRM_API void set_binop_right(ir_node *node, ir_node *right);
/** returns the pnc name from an pnc constant */
FIRM_API const char *get_pnc_string(int pnc);
/** returns the name of an ir_relation */
FIRM_API const char *get_relation_string(ir_relation relation);
/** Calculates the negated (Complement(R)) pnc condition. */
FIRM_API pn_Cmp get_negated_pnc(long pnc, ir_mode *mode);
/** Calculates the negated (Complement(R)) relation, i.e. "<" --> ">=" */
FIRM_API ir_relation get_negated_relation(ir_relation relation);
/** Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
FIRM_API pn_Cmp get_inversed_pnc(long pnc);
/** An alternative name for get_inversed_pnc() that can be better memorized. */
#define get_mirrored_pnc(pnc) get_inversed_pnc(pnc)
/** Calculates the inversed (R^-1) relation, i.e., "<" --> ">" */
FIRM_API ir_relation get_inversed_relation(ir_relation relation);
/** Checks for upcast.
*
......@@ -569,7 +566,6 @@ FIRM_API void add_Sync_pred(ir_node *node, ir_node *pred);
/** Return the projection number of a Proj node. */
FIRM_API long get_Proj_proj(const ir_node *node);
FIRM_API void set_Proj_proj(ir_node *node, long proj);
FIRM_API pn_Cmp get_Proj_pn_cmp(const ir_node*);
/**
* Returns non-zero if a node is a routine parameter.
......
......@@ -1097,13 +1097,13 @@ FIRM_API ir_value_classify_sign classify_value_sign(ir_node *n);
* Return the value of a Cmp if one or both predecessors
* are Confirm nodes.
*
* @param cmp the compare node that will be evaluated
* @param left the left operand of the Cmp
* @param right the right operand of the Cmp
* @param pnc the compare relation
* @param cmp the compare node that will be evaluated
* @param left the left operand of the Cmp
* @param right the right operand of the Cmp
* @param relation the compare relation
*/
FIRM_API ir_tarval *computed_value_Cmp_Confirm(
ir_node *cmp, ir_node *left, ir_node *right, pn_Cmp pnc);
const ir_node *cmp, ir_node *left, ir_node *right, ir_relation relation);
#include "end.h"
......
......@@ -45,13 +45,12 @@
* @sa
* Techreport 1999-14
* irmode.h for the modes definitions
* irnode.h for the pn_Cmp table
*/
#ifndef FIRM_TV_TV_H
#define FIRM_TV_TV_H
#include <stddef.h>
#include "firm_types.h"
#include "irnode.h"
#include "begin.h"
......@@ -406,23 +405,15 @@ FIRM_API tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void);
/**
* Compares two tarvals
*
* Compare a with b and return a pn_Cmp describing the relation
* between a and b. This is either pn_Cmp_Uo, pn_Cmp_Lt, pn_Cmp_Eq, pn_Cmp_Gt,
* or pn_Cmp_False if a or b are symbolic pointers which can not be compared at all.
* Compare a with b and return their relation.
* This is either ir_rel_unordered, ir_rel_less, ir_rel_greater, ir_rel_equal
* or ir_rel_false if a or b are symbolic pointers which can not be compared at
* all.
*
* @param a the first tarval to be compared
* @param b the second tarval to be compared
*
* @return
* The pn_Cmp best describing the relation between a and b is returned.
* This means the mode with the least bits set is returned, e.g. if the
* tarvals are equal the pn_Cmp 'pn_Cmp_Eq' is returned, not 'pn_Cmp_Ge' which
* indicates 'greater or equal'
*
* @sa
* irnode.h for the definition of pn_Cmp
*/
FIRM_API pn_Cmp tarval_cmp(ir_tarval *a, ir_tarval *b);
FIRM_API ir_relation tarval_cmp(ir_tarval *a, ir_tarval *b);
/**
* Converts a tarval to another mode.
......
......@@ -61,10 +61,9 @@ FIRM_API void set_vrp_data(ir_graph *irg);
*
* @param left: the left node
* @param right: the right node
*
* @return the pn_Cmp, if one can be derived
* @return all possible relations
*/
FIRM_API pn_Cmp vrp_cmp(const ir_node *left, const ir_node *right);
FIRM_API ir_relation vrp_cmp(const ir_node *left, const ir_node *right);
/*
* Return the vrp data for this node
......
......@@ -245,10 +245,10 @@ static void handle_modeb(ir_node *block, ir_node *selector, pn_Cond pnc, env_t *
*
* @param block the block which is entered by the branch
* @param cmp the Cmp node expressing the branch condition
* @param pnc the Compare relation for taking this branch
* @param rel the Compare relation for taking this branch
* @param env statistical environment
*/
static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
static void handle_if(ir_node *block, ir_node *cmp, ir_relation rel, env_t *env)
{
ir_node *left = get_Cmp_left(cmp);
ir_node *right = get_Cmp_right(cmp);
......@@ -274,14 +274,14 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
left = right;
right = t;
pnc = get_inversed_pnc(pnc);
rel = get_inversed_relation(rel);
}
/*
* First case: both values are identical.
* replace the left one by the right (potentially const) one.
*/
if (pnc == pn_Cmp_Eq) {
if (rel == ir_relation_equal) {
cond_block = get_Block_cfgpred_block(block, 0);
for (edge = get_irn_out_edge_first(left); edge; edge = next) {
ir_node *user = get_edge_src_irn(edge);
......@@ -339,7 +339,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
}
}
}
} else { /* not pn_Cmp_Eq cases */
} else { /* not ir_relation_equal cases */
ir_node *c = NULL;
foreach_out_edge_safe(left, edge, next) {
......@@ -354,7 +354,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
* We can replace the input with a Confirm(left, pnc, right).
*/
if (! c)
c = new_r_Confirm(block, left, right, pnc);
c = new_r_Confirm(block, left, right, rel);
pos = get_edge_src_pos(edge);
set_irn_n(succ, pos, c);
......@@ -368,7 +368,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
/* also construct inverse Confirms */
ir_node *rc = NULL;
pnc = get_inversed_pnc(pnc);
rel = get_inversed_relation(rel);
foreach_out_edge_safe(right, edge, next) {
ir_node *succ = get_edge_src_irn(edge);
int pos;
......@@ -384,10 +384,10 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env)
/*
* Ok, we found a usage of right in a block
* dominated by the branch block.
* We can replace the input with a Confirm(right, pnc^-1, left).
* We can replace the input with a Confirm(right, rel^-1, left).
*/
if (! rc)
rc = new_r_Confirm(block, right, left, pnc);
rc = new_r_Confirm(block, right, left, rel);
pos = get_edge_src_pos(edge);
set_irn_n(succ, pos, rc);
......@@ -429,7 +429,7 @@ static void insert_Confirm_in_block(ir_node *block, void *data)
if (mode == mode_b) {
ir_node *cmp;
pn_Cmp pnc;
ir_relation rel;
handle_modeb(block, selector, (pn_Cond) get_Proj_proj(proj), env);
......@@ -441,16 +441,16 @@ static void insert_Confirm_in_block(ir_node *block, void *data)
if (! is_Cmp(cmp))
return;
pnc = (pn_Cmp) get_Proj_proj(selector);
rel = get_Cmp_relation(cmp);
if (get_Proj_proj(proj) != pn_Cond_true) {
/* it's the false branch */
mode = get_irn_mode(get_Cmp_left(cmp));
pnc = get_negated_pnc(pnc, mode);
rel = get_negated_relation(rel);
}
DB((dbg, LEVEL_2, "At %+F using %+F Confirm %=\n", block, cmp, pnc));
DB((dbg, LEVEL_2, "At %+F using %+F Confirm %=\n", block, cmp, rel));
handle_if(block, cmp, pnc, env);
handle_if(block, cmp, rel, env);
} else if (mode_is_int(mode)) {
long proj_nr = get_Proj_proj(proj);
......@@ -470,7 +470,7 @@ static int is_non_null_Confirm(const ir_node *ptr)
for (;;) {
if (! is_Confirm(ptr))
break;
if (get_Confirm_cmp(ptr) == pn_Cmp_Lg) {
if (get_Confirm_relation(ptr) == ir_relation_less_greater) {
ir_node *bound = get_Confirm_bound(ptr);
if (is_Const(bound) && is_Const_null(bound))
......@@ -523,7 +523,7 @@ static void insert_non_null(ir_node *ptr, ir_node *block, env_t *env)
ir_mode *mode = get_irn_mode(ptr);
ir_graph *irg = get_irn_irg(block);
c = new_r_Const(irg, get_mode_null(mode));
c = new_r_Confirm(block, ptr, c, pn_Cmp_Lg);
c = new_r_Confirm(block, ptr, c, ir_relation_less_greater);
}
set_irn_n(succ, pos, c);
......
......@@ -133,7 +133,7 @@ static ir_alias_relation check_const(const ir_node *cns, int size)
if (size == 0)
return tarval_is_null(tv) ? ir_may_alias : ir_no_alias;
tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
return tarval_cmp(tv_size, tv) & (pn_Cmp_Eq|pn_Cmp_Lt) ? ir_no_alias : ir_may_alias;
return tarval_cmp(tv_size, tv) & (ir_relation_less_equal) ? ir_no_alias : ir_may_alias;
} /* check_const */
/**
......@@ -201,7 +201,7 @@ static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx
} else {
tv_size = new_tarval_from_long(size, m2);
if (tarval_cmp(tv2, tv_size) & (pn_Cmp_Eq|pn_Cmp_Gt)) {
if (tarval_cmp(tv2, tv_size) & (ir_relation_greater_equal)) {
/* tv1 is negative and tv2 >= tv_size, so the difference is bigger than size */
return ir_no_alias;
}
......@@ -215,11 +215,11 @@ static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx
tv1 = tarval_convert_to(tv1, m2);
/* now we can compare without overflow */
return tarval_cmp(tv1, tv2) & (pn_Cmp_Eq|pn_Cmp_Gt) ? ir_no_alias : ir_may_alias;
return tarval_cmp(tv1, tv2) & (ir_relation_greater_equal) ? ir_no_alias : ir_may_alias;
}
}
}
if (tarval_cmp(tv1, tv2) == pn_Cmp_Gt) {
if (tarval_cmp(tv1, tv2) == ir_relation_greater) {
ir_tarval *t = tv1;
tv1 = tv2;
tv2 = t;
......@@ -227,7 +227,7 @@ static ir_alias_relation different_index(const ir_node *idx1, const ir_node *idx
/* tv1 is now the "smaller" one */
tv = tarval_sub(tv2, tv1, NULL);
tv_size = new_tarval_from_long(size, get_tarval_mode(tv));
return tarval_cmp(tv_size, tv) & (pn_Cmp_Eq|pn_Cmp_Lt) ? ir_no_alias : ir_may_alias;
return tarval_cmp(tv_size, tv) & (ir_relation_less_equal) ? ir_no_alias : ir_may_alias;
}
/* Note: we rely here on the fact that normalization puts constants on the RIGHT side */
......
......@@ -283,29 +283,31 @@ static int vrp_update_node(ir_node *node)
new_bits_set = tarval_and(
new_bits_not_set, tarval_convert_to(vrp_pred->bits_set, new_mode));
if (tarval_cmp(vrp_pred->range_top, get_mode_max(new_mode)) == pn_Cmp_Le) {
/* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_less_equal */
if (tarval_cmp(vrp_pred->range_top, get_mode_max(new_mode)) == ir_relation_less_equal) {
vrp->range_top = vrp_pred->range_top;
}
if (tarval_cmp(vrp_pred->range_bottom, get_mode_min(new_mode)) == pn_Cmp_Ge) {
/* Matze: TODO, BUGGY, tarval_cmp never returns ir_relation_greater_equal */
if (tarval_cmp(vrp_pred->range_bottom, get_mode_min(new_mode)) == ir_relation_greater_equal) {
vrp->range_bottom = vrp_pred->range_bottom;
}
break;
}
case iro_Confirm: {
const pn_Cmp cmp = get_Confirm_cmp(node);
const ir_node *bound = get_Confirm_bound(node);
const ir_relation relation = get_Confirm_relation(node);
const ir_node *bound = get_Confirm_bound(node);
if (cmp == pn_Cmp_Lg) {
if (relation == ir_relation_less_greater) {
/** @todo: Handle non-Const bounds */
if (is_Const(bound)) {
new_range_type = VRP_ANTIRANGE;
new_range_top = get_Const_tarval(bound);
new_range_bottom = get_Const_tarval(bound);
}
} else if (cmp == pn_Cmp_Le) {
} else if (relation == ir_relation_less_equal) {
if (is_Const(bound)) {
new_range_type = VRP_RANGE;
new_range_top = get_Const_tarval(bound);
......@@ -319,7 +321,7 @@ static int vrp_update_node(ir_node *node)
/* combine all ranges*/
int num = get_Phi_n_preds(node);
pn_Cmp cmp;
ir_relation relation;
int i;
const ir_node *pred = get_Phi_pred(node,0);
......@@ -337,12 +339,12 @@ static int vrp_update_node(ir_node *node)
vrp_pred = get_vrp_attr(pred);
if (new_range_type == VRP_RANGE && vrp_pred->range_type ==
VRP_RANGE) {
cmp = tarval_cmp(new_range_top, vrp_pred->range_top);
if (cmp == pn_Cmp_Lt) {
relation = tarval_cmp(new_range_top, vrp_pred->range_top);
if (relation == ir_relation_less) {
new_range_top = vrp_pred->range_top;
}
cmp = tarval_cmp(new_range_bottom, vrp_pred->range_bottom);
if (cmp == pn_Cmp_Gt) {
relation = tarval_cmp(new_range_bottom, vrp_pred->range_bottom);
if (relation == ir_relation_greater) {
new_range_bottom = vrp_pred->range_bottom;
}
} else {
......@@ -395,7 +397,7 @@ static int vrp_update_node(ir_node *node)
/* Merge the newly calculated values with those that might already exist*/
if (new_bits_set != tarval_bad) {
new_bits_set = tarval_or(new_bits_set, vrp->bits_set);
if (tarval_cmp(new_bits_set, vrp->bits_set) != pn_Cmp_Eq) {
if (tarval_cmp(new_bits_set, vrp->bits_set) != ir_relation_equal) {
something_changed = 1;
vrp->bits_set = new_bits_set;
}
......@@ -403,7 +405,7 @@ static int vrp_update_node(ir_node *node)
if (new_bits_not_set != tarval_bad) {
new_bits_not_set = tarval_and(new_bits_not_set, vrp->bits_not_set);
if (tarval_cmp(new_bits_not_set, vrp->bits_not_set) != pn_Cmp_Eq) {
if (tarval_cmp(new_bits_not_set, vrp->bits_not_set) != ir_relation_equal) {
something_changed = 1;
vrp->bits_not_set = new_bits_not_set;
}
......@@ -418,11 +420,11 @@ static int vrp_update_node(ir_node *node)
} else if (vrp->range_type == VRP_RANGE) {
if (new_range_type == VRP_RANGE) {
if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Lt) {
if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_less) {
something_changed = 1;
vrp->range_bottom = new_range_bottom;
}
if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Gt) {
if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_greater) {
something_changed = 1;
vrp->range_top = new_range_top;
}
......@@ -431,13 +433,13 @@ static int vrp_update_node(ir_node *node)
if (new_range_type == VRP_ANTIRANGE) {
/* if they are overlapping, cut the range.*/
/* TODO: Maybe we can preserve more information here*/
if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt &&
tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) {
if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater &&
tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
something_changed = 1;
vrp->range_bottom = new_range_top;
} else if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Gt &&
tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) {
} else if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_greater &&
tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
something_changed = 1;
vrp->range_top = new_range_bottom;
}
......@@ -448,22 +450,22 @@ static int vrp_update_node(ir_node *node)
}
} else if (vrp->range_type == VRP_ANTIRANGE) {
if (new_range_type == VRP_ANTIRANGE) {
if (tarval_cmp(vrp->range_bottom, new_range_bottom) == pn_Cmp_Gt) {
if (tarval_cmp(vrp->range_bottom, new_range_bottom) == ir_relation_greater) {
something_changed = 1;
vrp->range_bottom = new_range_bottom;
}
if (tarval_cmp(vrp->range_top, new_range_top) == pn_Cmp_Lt) {
if (tarval_cmp(vrp->range_top, new_range_top) == ir_relation_less) {
something_changed = 1;
vrp->range_top = new_range_top;
}
}
if (new_range_type == VRP_RANGE) {
if (tarval_cmp(vrp->range_bottom, new_range_top) == pn_Cmp_Gt) {
if (tarval_cmp(vrp->range_bottom, new_range_top) == ir_relation_greater) {
something_changed = 1;
vrp->range_bottom = new_range_top;
}
if (tarval_cmp(vrp->range_top, new_range_bottom) == pn_Cmp_Lt) {
if (tarval_cmp(vrp->range_top, new_range_bottom) == ir_relation_less) {
something_changed = 1;
vrp->range_top = new_range_bottom;
}
......@@ -586,33 +588,32 @@ ir_graph_pass_t *set_vrp_pass(const char *name)
return def_graph_pass(name ? name : "set_vrp", set_vrp_data);
}
pn_Cmp vrp_cmp(const ir_node *left, const ir_node *right)
ir_relation vrp_cmp(const ir_node *left, const ir_node *right)
{
vrp_attr *vrp_left, *vrp_right;
vrp_left = vrp_get_info(left);
vrp_right = vrp_get_info(right);
if (!vrp_left || !vrp_right) {
return pn_Cmp_False;
}
if (!vrp_left || !vrp_right)
return ir_relation_true;
if (vrp_left->range_type == VRP_RANGE && vrp_right->range_type == VRP_RANGE) {
if (tarval_cmp(vrp_left->range_top, vrp_right->range_bottom) == pn_Cmp_Lt) {
return pn_Cmp_Lt;
if (tarval_cmp(vrp_left->range_top, vrp_right->range_bottom) == ir_relation_less) {
return ir_relation_less;
}
if (tarval_cmp(vrp_left->range_bottom, vrp_right->range_top) == pn_Cmp_Gt) {
return pn_Cmp_Gt;
if (tarval_cmp(vrp_left->range_bottom, vrp_right->range_top) == ir_relation_greater) {
return ir_relation_greater;
}
}
if (!tarval_is_null(tarval_and(vrp_left->bits_set, tarval_not(vrp_right->bits_not_set))) ||
!tarval_is_null(tarval_and(tarval_not(vrp_left->bits_not_set), vrp_right->bits_set))) {
return pn_Cmp_Lg;
return ir_relation_less_greater;
}
/* TODO: We can get way more information here*/
return pn_Cmp_False;
/* TODO: We can get way more information here*/
return ir_relation_true;
}
vrp_attr *vrp_get_info(const ir_node *node)
......
......@@ -278,7 +278,7 @@ static void emit_amd64_Jcc(const ir_node *irn)
const ir_node *next_block;
const char *suffix;
const amd64_attr_t *attr = get_amd64_attr_const(irn);
int proj_num = attr->ext.pnc;
ir_relation relation = attr->ext.relation;
ir_node *op1 = get_irn_n(irn, 0);
const amd64_attr_t *cmp_attr = get_amd64_attr_const(op1);
bool is_signed = !cmp_attr->data.cmp_unsigned;
......@@ -296,7 +296,7 @@ static void emit_amd64_Jcc(const ir_node *irn)
}
if (cmp_attr->data.ins_permuted) {
proj_num = get_mirrored_pnc(proj_num);
relation = get_inversed_relation(relation);
}
/* for now, the code works for scheduled and non-schedules blocks */
......@@ -305,8 +305,8 @@ static void emit_amd64_Jcc(const ir_node *irn)
/* we have a block schedule */
next_block = sched_next_block(block);
assert(proj_num != pn_Cmp_False);
assert(proj_num != pn_Cmp_True);
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 */
......@@ -314,17 +314,17 @@ static void emit_amd64_Jcc(const ir_node *irn)
proj_true = proj_false;
proj_false = t;
proj_num = get_negated_pnc(proj_num, mode_Lu);
relation = get_negated_relation(relation);
}
switch (proj_num) {
case pn_Cmp_Eq: suffix = "e"; break;
case pn_Cmp_Lt: suffix = is_signed ? "l" : "b"; break;
case pn_Cmp_Le: suffix = is_signed ? "le" : "be"; break;
case pn_Cmp_Gt: suffix = is_signed ? "g" : "a"; break;
case pn_Cmp_Ge: suffix = is_signed ? "ge" : "ae"; break;
case pn_Cmp_Lg: suffix = "ne"; break;
case pn_Cmp_Leg: suffix = "mp"; break;
switch (relation) {
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");
}
......
......@@ -138,7 +138,7 @@ static void init_amd64_attributes(ir_node *node, arch_irn_flags_t flags,
attr->data.ins_permuted = 0;
attr->data.cmp_unsigned = 0;
attr->ext.pnc = (pn_Cmp)0;
attr->ext.relation = ir_relation_false;
attr->ext.imm_value = 0;
}
......
......@@ -40,8 +40,8 @@ struct amd64_attr_t
unsigned cmp_unsigned : 1; /**< compare should be unsigned */
} data;
struct amd64_attr_extended {
pn_Cmp pnc; /**< type of compare operation >*/
unsigned imm_value; /**< immediate value to use >*/
ir_relation relation; /**< type of compare operation >*/
unsigned imm_value; /**< immediate value to use >*/
} ext;
};
......
......@@ -267,8 +267,8 @@ Jcc => {
reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
ins => [ "eflags" ],
outs => [ "false", "true" ],
attr => "pn_Cmp pnc",
init_attr => "attr->ext.pnc = pnc;",
attr => "ir_relation relation",
init_attr => "attr->ext.relation = relation;",
mode => "mode_T",
},
Load => {
......
......@@ -224,23 +224,25 @@ static ir_node *gen_Cmp(ir_node *node)
*/
static ir_node *gen_Cond(ir_node *node)
{
ir_node *selector = get_Cond_selector(node);
ir_mode *mode = get_irn_mode(selector);
ir_node *block;
ir_node *flag_node;
dbg_info *dbgi;
ir_node *selector = get_Cond_selector(node);
ir_mode *mode = get_irn_mode(selector);
ir_node *block;
ir_node *flag_node;
ir_relation relation;
dbg_info *dbgi;
if (mode != mode_b) {
panic ("create_Switch not implemented yet!");
// return gen_SwitchJmp(node);
}
assert(is_Proj(selector));
assert(is_Cmp(selector));
block = be_transform_node(get_nodes_block(node));
dbgi = get_irn_dbg_info(node);
flag_node = be_transform_node(get_Proj_pred(selector));
flag_node = be_transform_node(selector);
relation = get_Cmp_relation(selector);
return new_bd_amd64_Jcc(dbgi, block, flag_node, get_Proj_pn_cmp(selector));
return new_bd_amd64_Jcc(dbgi, block, flag_node, relation);
}
#if 0
......
......@@ -426,7 +426,7 @@ static void emit_arm_B(const ir_node *irn)
const ir_node *next_block;
ir_node *op1 = get_irn_n(irn, 0);
const char *suffix;
pn_Cmp pnc = get_arm_CondJmp_pnc(irn);
ir_relation relation = get_arm_CondJmp_relation(irn);
const arm_cmp_attr_t *cmp_attr = get_arm_cmp_attr_const(op1);