backend_marked was a buggy/wrong concept, removed it
[libfirm] / ir / be / ia32 / ia32_emitter.c
index a74d9bf..4716f55 100644 (file)
@@ -282,11 +282,10 @@ void ia32_emit_source_register(const ir_node *node, int pos)
 
 static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
 {
-       set_entity_backend_marked(entity, 1);
        be_gas_emit_entity(entity);
 
        if (get_entity_owner(entity) == get_tls_type()) {
-               if (get_entity_visibility(entity) == visibility_external_allocated) {
+               if (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) {
                        be_emit_cstring("@INDNTPOFF");
                } else {
                        be_emit_cstring("@NTPOFF");
@@ -704,20 +703,20 @@ end_of_mods:
 
                        case 'A': {
                                switch (*fmt++) {
+emit_AM:
                                        case 'M':
                                                if (mod & EMIT_ALTERNATE_AM)
                                                        be_emit_char('*');
-
                                                ia32_emit_am(node);
                                                break;
 
                                        case 'R': {
                                                const arch_register_t *reg = va_arg(ap, const arch_register_t*);
-                                               if (mod & EMIT_ALTERNATE_AM)
-                                                       be_emit_char('*');
                                                if (get_ia32_op_type(node) == ia32_AddrModeS) {
-                                                       ia32_emit_am(node);
+                                                       goto emit_AM;
                                                } else {
+                                                       if (mod & EMIT_ALTERNATE_AM)
+                                                               be_emit_char('*');
                                                        emit_register(reg, NULL);
                                                }
                                                break;
@@ -725,10 +724,8 @@ end_of_mods:
 
                                        case 'S':
                                                if (get_ia32_op_type(node) == ia32_AddrModeS) {
-                                                       if (mod & EMIT_ALTERNATE_AM)
-                                                               be_emit_char('*');
-                                                       ia32_emit_am(node);
                                                        ++fmt;
+                                                       goto emit_AM;
                                                } else {
                                                        assert(get_ia32_op_type(node) == ia32_Normal);
                                                        goto emit_S;
@@ -959,8 +956,7 @@ static ir_node *find_original_value(ir_node *node)
        }
 }
 
-static int determine_final_pnc(const ir_node *node, int flags_pos,
-                               int pnc)
+static int determine_final_pnc(const ir_node *node, int flags_pos, int pnc)
 {
        ir_node           *flags = get_irn_n(node, flags_pos);
        const ia32_attr_t *flags_attr;
@@ -1188,13 +1184,16 @@ static void emit_ia32_Setcc(const ir_node *node)
 static void emit_ia32_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_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;
 
        pnc = determine_final_pnc(node, n_ia32_CMovcc_eflags, pnc);
+       /* although you can't set ins_permuted in the constructor it might still
+          be set by memory operand folding */
+       if (attr->data.ins_permuted)
+               pnc = ia32_get_negated_pnc(pnc);
 
        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));
@@ -1207,7 +1206,7 @@ static void emit_ia32_CMovcc(const ir_node *node)
 
                assert(get_ia32_op_type(node) == ia32_Normal);
 
-               ins_permuted = !ins_permuted;
+               pnc = ia32_get_negated_pnc(pnc);
 
                tmp      = in_true;
                in_true  = in_false;
@@ -1217,10 +1216,20 @@ static void emit_ia32_CMovcc(const ir_node *node)
                ia32_emitf(node, "\tmovl %R, %R\n", in_false, out);
        }
 
-       if (ins_permuted)
-               pnc = ia32_get_negated_pnc(pnc);
-
        /* TODO: handling of Nans isn't correct yet */
+       if (pnc & ia32_pn_Cmp_float) {
+               switch (pnc & 0x0f) {
+               case pn_Cmp_Uo:
+               case pn_Cmp_Leg:
+               case pn_Cmp_Eq:
+               case pn_Cmp_Lt:
+               case pn_Cmp_Le:
+               case pn_Cmp_Ug:
+               case pn_Cmp_Uge:
+               case pn_Cmp_Ne:
+                       panic("CMov with floatingpoint compare/parity not supported yet");
+               }
+       }
 
        ia32_emitf(node, "\tcmov%P %#AR, %#R\n", pnc, in_true, out);
 }
@@ -2234,6 +2243,8 @@ void ia32_gen_routine(ia32_code_gen_t *ia32_cg, ir_graph *irg)
        isa      = cg->isa;
        do_pic   = cg->birg->main_env->options->pic;
 
+       be_gas_elf_type_char = '@';
+
        ia32_register_emitters();
 
        get_unique_label(pic_base_label, sizeof(pic_base_label), ".PIC_BASE");
@@ -2403,11 +2414,10 @@ static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
        be_emit_cstring("\t.long ");
        if (entity_sign)
                be_emit_char('-');
-       set_entity_backend_marked(entity, 1);
        be_gas_emit_entity(entity);
 
        if (get_entity_owner(entity) == get_tls_type()) {
-               if (get_entity_visibility(entity) == visibility_external_allocated) {
+               if (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) {
                        be_emit_cstring("@INDNTPOFF");
                } else {
                        be_emit_cstring("@NTPOFF");