* @author Christian Wuerdig, Matthias Braun
* @version $Id$
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
#include <limits.h>
assert(pos == 0);
reg = arch_get_irn_register(irn);
} else if (is_ia32_irn(irn)) {
- reg = get_ia32_out_reg(irn, pos);
+ reg = arch_irn_get_register(irn, pos);
} else {
const ir_edge_t *edge;
ia32_emit_block_name(block);
}
-/*
- * coding of conditions
- */
-struct cmp2conditon_t {
- const char *name;
- int num;
-};
-
/*
* positive conditions for signed compares
*/
-static const struct cmp2conditon_t cmp2condition_s[] = {
- { NULL, pn_Cmp_False }, /* always false */
- { "e", pn_Cmp_Eq }, /* == */
- { "l", pn_Cmp_Lt }, /* < */
- { "le", pn_Cmp_Le }, /* <= */
- { "g", pn_Cmp_Gt }, /* > */
- { "ge", pn_Cmp_Ge }, /* >= */
- { "ne", pn_Cmp_Lg }, /* != */
- { NULL, pn_Cmp_Leg}, /* always true */
+static const char *const cmp2condition_s[] = {
+ NULL, /* always false */
+ "e", /* == */
+ "l", /* < */
+ "le", /* <= */
+ "g", /* > */
+ "ge", /* >= */
+ "ne", /* != */
+ NULL /* always true */
};
/*
* positive conditions for unsigned compares
*/
-static const struct cmp2conditon_t cmp2condition_u[] = {
- { NULL, pn_Cmp_False }, /* always false */
- { "e", pn_Cmp_Eq }, /* == */
- { "b", pn_Cmp_Lt }, /* < */
- { "be", pn_Cmp_Le }, /* <= */
- { "a", pn_Cmp_Gt }, /* > */
- { "ae", pn_Cmp_Ge }, /* >= */
- { "ne", pn_Cmp_Lg }, /* != */
- { NULL, pn_Cmp_Leg }, /* always true */
+static const char *const cmp2condition_u[] = {
+ NULL, /* always false */
+ "e", /* == */
+ "b", /* < */
+ "be", /* <= */
+ "a", /* > */
+ "ae", /* >= */
+ "ne", /* != */
+ NULL /* always true */
};
static void ia32_emit_cmp_suffix(int pnc)
{
const char *str;
- if ((pnc & ia32_pn_Cmp_float) || (pnc & ia32_pn_Cmp_unsigned)) {
- pnc = pnc & 7;
- assert(cmp2condition_u[pnc].num == pnc);
- str = cmp2condition_u[pnc].name;
+ if (pnc & ia32_pn_Cmp_float || pnc & ia32_pn_Cmp_unsigned) {
+ str = cmp2condition_u[pnc & 7];
} else {
- pnc = pnc & 7;
- assert(cmp2condition_s[pnc].num == pnc);
- str = cmp2condition_s[pnc].name;
+ str = cmp2condition_s[pnc & 7];
}
be_emit_string(str);
return pnc;
}
+static pn_Cmp ia32_get_negated_pnc(pn_Cmp pnc)
+{
+ ir_mode *mode = pnc & ia32_pn_Cmp_float ? mode_F : mode_Iu;
+ return get_negated_pnc(pnc, mode);
+}
+
void ia32_emit_cmp_suffix_node(const ir_node *node,
int flags_pos)
{
pn_Cmp pnc = get_ia32_condcode(node);
pnc = determine_final_pnc(node, flags_pos, pnc);
- if (attr->data.ins_permuted) {
- if (pnc & ia32_pn_Cmp_float) {
- pnc = get_negated_pnc(pnc, mode_F);
- } else {
- pnc = get_negated_pnc(pnc, mode_Iu);
- }
- }
+ if (attr->data.ins_permuted)
+ pnc = ia32_get_negated_pnc(pnc);
ia32_emit_cmp_suffix(pnc);
}
proj_true = proj_false;
proj_false = t;
- if (pnc & ia32_pn_Cmp_float) {
- pnc = get_negated_pnc(pnc, mode_F);
- } else {
- pnc = get_negated_pnc(pnc, mode_Iu);
- }
+ pnc = ia32_get_negated_pnc(pnc);
}
if (pnc & ia32_pn_Cmp_float) {
{
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(node);
+ const arch_register_t *out = arch_irn_get_register(node, pn_ia32_res);
pn_Cmp pnc = get_ia32_condcode(node);
const arch_register_t *in_true;
const arch_register_t *in_false;
ia32_emitf(node, "\tmovl %R, %R\n", in_false, out);
}
- if (ins_permuted) {
- if (pnc & ia32_pn_Cmp_float) {
- pnc = get_negated_pnc(pnc, mode_F);
- } else {
- pnc = get_negated_pnc(pnc, mode_Iu);
- }
- }
+ if (ins_permuted)
+ pnc = ia32_get_negated_pnc(pnc);
/* TODO: handling of Nans isn't correct yet */
- ia32_emitf(node, "\tcmov%P %AR, %#R\n", pnc, in_true, out);
+ ia32_emitf(node, "\tcmov%P %#AR, %#R\n", pnc, in_true, out);
}
/*********************************************************
/* parse modifiers */
switch(c) {
case 0:
- ir_fprintf(stderr, "Warning: asm text (%+F) ends with %\n", node);
+ ir_fprintf(stderr, "Warning: asm text (%+F) ends with %%\n", node);
be_emit_char('%');
return s + 1;
case '%':
case '9':
break;
default:
- ir_fprintf(stderr, "Warning: asm text (%+F) contains unknown modifier "
- "'%c' for asm op\n", node, c);
+ ir_fprintf(stderr,
+ "Warning: asm text (%+F) contains unknown modifier '%c' for asm op\n",
+ node, c);
++s;
break;
}
s += p;
}
- if (num < 0 || num >= ARR_LEN(asm_regs)) {
- ir_fprintf(stderr, "Error: Custom assembler references invalid "
- "input/output (%+F)\n", node);
+ if (num < 0 || ARR_LEN(asm_regs) <= num) {
+ ir_fprintf(stderr,
+ "Error: Custom assembler references invalid input/output (%+F)\n",
+ node);
return s;
}
asm_reg = & asm_regs[num];
reg = get_in_reg(node, asm_reg->inout_pos);
}
if (reg == NULL) {
- ir_fprintf(stderr, "Warning: no register assigned for %d asm op "
- "(%+F)\n", num, node);
+ ir_fprintf(stderr,
+ "Warning: no register assigned for %d asm op (%+F)\n",
+ num, node);
return s;
}
/**
* Emit code for conversions (I, FP), (FP, I) and (FP, FP).
*/
-static void emit_ia32_Conv_with_FP(const ir_node *node)
+static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
+ const char* conv_d)
{
ir_mode *ls_mode = get_ia32_ls_mode(node);
int ls_bits = get_mode_size_bits(ls_mode);
- const char *conv;
-
- if (is_ia32_Conv_I2FP(node)) {
- if (ls_bits == 32) {
- conv = "si2ss";
- } else {
- conv = "si2sd";
- }
- } else if (is_ia32_Conv_FP2I(node)) {
- if (ls_bits == 32) {
- conv = "ss2si";
- } else {
- conv = "sd2si";
- }
- } else {
- assert(is_ia32_Conv_FP2FP(node));
- if (ls_bits == 32) {
- conv = "sd2ss";
- } else {
- conv = "ss2sd";
- }
- }
+ const char *conv = ls_bits == 32 ? conv_f : conv_d;
ia32_emitf(node, "\tcvt%s %AS3, %D0\n", conv);
}
static void emit_ia32_Conv_I2FP(const ir_node *node)
{
- emit_ia32_Conv_with_FP(node);
+ emit_ia32_Conv_with_FP(node, "si2ss", "si2sd");
}
static void emit_ia32_Conv_FP2I(const ir_node *node)
{
- emit_ia32_Conv_with_FP(node);
+ emit_ia32_Conv_with_FP(node, "ss2si", "sd2si");
}
static void emit_ia32_Conv_FP2FP(const ir_node *node)
{
- emit_ia32_Conv_with_FP(node);
+ emit_ia32_Conv_with_FP(node, "sd2ss", "ss2sd");
}
/**
static void emit_ia32_Conv_I2I(const ir_node *node)
{
ir_mode *smaller_mode = get_ia32_ls_mode(node);
- int smaller_bits = get_mode_size_bits(smaller_mode);
int signed_mode = mode_is_signed(smaller_mode);
+ const char *sign_suffix;
assert(!mode_is_float(smaller_mode));
- assert(smaller_bits == 8 || smaller_bits == 16);
-
- if (signed_mode &&
- smaller_bits == 16 &&
- &ia32_gp_regs[REG_EAX] == get_out_reg(node, 0) &&
- &ia32_gp_regs[REG_EAX] == arch_get_irn_register(get_irn_n(node, n_ia32_unary_op))) {
- /* argument and result are both in EAX and signedness is ok: use the
- * smaller cwtl opcode */
- ia32_emitf(node, "\tcwtl\n");
- } else {
- const char *sign_suffix = signed_mode ? "s" : "z";
- ia32_emitf(node, "\tmov%s%Ml %#AS3, %D0\n", sign_suffix);
- }
+
+ sign_suffix = signed_mode ? "s" : "z";
+ ia32_emitf(node, "\tmov%s%Ml %#AS3, %D0\n", sign_suffix);
}
/**
int i, n;
cg = ia32_cg;
- isa = (const ia32_isa_t*) cg->arch_env;
+ isa = cg->isa;
do_pic = cg->birg->main_env->options->pic;
ia32_register_emitters();