More missing config.h
[libfirm] / ir / be / ia32 / ia32_emitter.c
index 4cd44f1..0afa23d 100644 (file)
@@ -272,18 +272,22 @@ static int ia32_get_reg_name(lc_appendable_t *app,
 static int ia32_get_x87_name(lc_appendable_t *app,
     const lc_arg_occ_t *occ, const lc_arg_value_t *arg)
 {
-       const char *buf;
+       const char  *buf;
        ir_node     *irn = arg->v_ptr;
        int         nr = occ->width - 1;
        ia32_attr_t *attr;
+       int         res = 0;
 
        if (! irn)
                return lc_appendable_snadd(app, "(null)", 6);
 
        attr = get_ia32_attr(irn);
-       buf = attr->x87[nr]->name;
-       lc_appendable_chadd(app, '%');
-       return lc_appendable_snadd(app, buf, strlen(buf));
+       buf  = attr->x87[nr]->name;
+
+       res += lc_appendable_chadd(app, '%');
+       res += lc_appendable_snadd(app, buf, strlen(buf));
+
+       return res;
 }
 
 /**
@@ -525,13 +529,12 @@ const char *ia32_emit_x87_binop(const ir_node *n, ia32_emit_env_t *env) {
                                const arch_register_t *in2 = attr->x87[1];
                                const arch_register_t *out = attr->x87[2];
                                const arch_register_t *in;
-                               const char            *in_name;
 
-                               in      = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
-                               out     = out ? out : in1;
-                               in_name = arch_register_get_name(in);
+                               in  = out ? (REGS_ARE_EQUAL(out, in2) ? in1 : in2) : in2;
+                               out = out ? out : in1;
 
-                               snprintf(buf, SNPRINTF_BUF_LEN, "%%%s, %%%s", arch_register_get_name(out), in_name);
+                               snprintf(buf, SNPRINTF_BUF_LEN, "%%%s, %%%s",
+                                       arch_register_get_name(out), arch_register_get_name(in));
                        }
                        break;
                case ia32_AddrModeS:
@@ -871,15 +874,23 @@ static void finish_CondJmp(FILE *F, const ir_node *irn, ir_mode *mode) {
        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;
 
-               flipped = 1;
-               pnc = get_negated_pnc(pnc, mode);
+               proj_true  = proj_false;
+               proj_false = t;
+               flipped    = 1;
+               pnc        = get_negated_pnc(pnc, mode);
        }
 
        /* the first Proj must always be created */
        is_unsigned = mode_is_float(mode) || ! mode_is_signed(mode);
+
+       /* in case of unordered compare, check for parity */
+       if (pnc & pn_Cmp_Uo) {
+               snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jp %s", get_cfop_target(proj_true, buf));
+               snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* jump to false if result is unordered */");
+               IA32_DO_EMIT(irn);
+       }
+
        snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
                 get_cmp_suffix(pnc, is_unsigned),
                 get_cfop_target(proj_true, buf));
@@ -981,12 +992,13 @@ static void emit_ia32_xCondJmp(ir_node *irn, ia32_emit_env_t *env) {
        FILE *F = env->out;
        char cmd_buf[SNPRINTF_BUF_LEN];
        char cmnt_buf[SNPRINTF_BUF_LEN];
+       const lc_arg_env_t *arg_env = ia32_get_arg_env();
 
-       lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %s", irn, ia32_emit_binop(irn, env));
-       lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
+       lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %s", irn, ia32_emit_binop(irn, env));
+       lc_esnprintf(arg_env, cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
        IA32_DO_EMIT(irn);
-       finish_CondJmp(F, irn, mode_F);
 
+       finish_CondJmp(F, irn, mode_F);
 }
 
 /**
@@ -1139,8 +1151,7 @@ static void Set_emitter(ir_node *irn, ir_mode *mode, ia32_emit_env_t *env) {
                lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "ucomis%M %s", get_irn_n(irn, 2), ia32_emit_binop(irn, env));
        }
        else if (is_ia32_PsiCondSet(irn)) {
-               /* omit compare because flags are already set by And/Or */
-               snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
+               lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "cmp %1S, 0", irn);
        }
        else {
                assert(0 && "unsupported Set");
@@ -1775,9 +1786,10 @@ static void emit_be_Perm(const ir_node *irn, ia32_emit_env_t *emit_env) {
        assert(cls1 == cls2 && "Register class mismatch at Perm");
 
        if (cls1 == &ia32_reg_classes[CLASS_ia32_gp]) {
+#if 0
                if(emit_env->isa->opt_arch == arch_athlon) {
                        // xchg commands are Vector path on athlons and therefore stall the DirectPath pipeline
-                       // it is nearly always beneficial to use the 3 xor trick instead of an xchg
+                       // it is often beneficial to use the 3 xor trick instead of an xchg
                        cmnt_buf[0] = 0;
                        lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "xor %1S, %2S", irn, irn);
                        IA32_DO_EMIT(irn);
@@ -1785,8 +1797,11 @@ static void emit_be_Perm(const ir_node *irn, ia32_emit_env_t *emit_env) {
                        IA32_DO_EMIT(irn);
                        lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "xor %1S, %2S", irn, irn);
                } else {
+#endif
                        lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "xchg %1S, %2S", irn, irn);
+#if 0
                }
+#endif
        }
        else if (cls1 == &ia32_reg_classes[CLASS_ia32_xmm]) {
                lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN,
@@ -2021,6 +2036,9 @@ static void ia32_emit_dbg(const ir_node *irn, ia32_emit_env_t *env) {
        unsigned lineno;
        const char *fname = be_retrieve_dbg_info(db, &lineno);
 
+       if (! env->cg->birg->main_env->options->stabs_debug_support)
+               return;
+
        if (fname) {
                if (last_name != fname) {
                        last_line = -1;