Commit 4baed155 authored by Matthias Braun's avatar Matthias Braun
Browse files

share x86 cc code between ia32 and amd64 backend

parent bf4b3419
......@@ -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 */");
}
}
......
......@@ -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,
......
......@@ -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
......
......@@ -52,7 +52,7 @@ $default_copy_attr = "amd64_copy_attr";
. "\tinit_amd64_switch_attributes(res, table, table_entity);",
amd64_cc_attr_t =>
"\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
. "\tinit_amd64_cc_attributes(res, relation, is_unsigned);",
. "\tinit_amd64_cc_attributes(res, cc);",
amd64_movimm_attr_t =>
"\tinit_amd64_attributes(res, irn_flags_, in_reqs, n_res);"
. "\tinit_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",
},
......
......@@ -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, flags, cc);
}
static ir_node *gen_Phi(ir_node *node)
......
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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*/
};
/**
......
......@@ -214,12 +214,12 @@ static void peephole_ia32_Test(ir_node *node)