X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_emitter.c;h=4716f55f4d47ffeb26e288d806bde4c57f34ee52;hb=ebdaa596d904a0651c8d794481288d2d629bdb3a;hp=a74d9bfd3b83ad364ad228486f075ffe13d93b44;hpb=4137609950786f314fa679f833379ec63444c160;p=libfirm diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index a74d9bfd3..4716f55f4 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -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");