X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_new_nodes.c;h=27caa2ffae578878c12cb767d3b3495850bf83d1;hb=662fc44c951bdb45a9b7d9563e9ffbb87101b9e4;hp=e716c5847fabab1017dc550902db7ca88e0a1743;hpb=2d61612857ee98aa3273e239833530c057ecd8d5;p=libfirm diff --git a/ir/be/ia32/ia32_new_nodes.c b/ir/be/ia32/ia32_new_nodes.c index e716c5847..27caa2ffa 100644 --- a/ir/be/ia32/ia32_new_nodes.c +++ b/ir/be/ia32/ia32_new_nodes.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -24,7 +24,7 @@ * @version $Id$ * * This file implements the creation of the achitecture specific firm opcodes - * and the coresponding node constructors for the ia32 assembler irg. + * and the corresponding node constructors for the ia32 assembler irg. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -96,11 +96,27 @@ static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, } if (reqs[i]->type & arch_register_req_type_should_be_same) { - ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same)); + unsigned other = reqs[i]->other_same; + int i; + + ir_fprintf(F, " same as"); + for (i = 0; 1U << i <= other; ++i) { + if (other & (1U << i)) { + ir_fprintf(F, " %+F", get_irn_n(n, i)); + } + } } - if (reqs[i]->type & arch_register_req_type_should_be_different) { - ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->other_different)); + if (reqs[i]->type & arch_register_req_type_must_be_different) { + unsigned other = reqs[i]->other_different; + int i; + + ir_fprintf(F, " different from"); + for (i = 0; 1U << i <= other; ++i) { + if (other & (1U << i)) { + ir_fprintf(F, " %+F", get_irn_n(n, i)); + } + } } fprintf(F, "\n"); @@ -137,7 +153,7 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { fputc(' ', F); if(attr->symconst) { - if(attr->attr.data.am_sc_sign) { + if(attr->sc_sign) { fputc('-', F); } fputs(get_entity_name(attr->symconst), F); @@ -149,8 +165,7 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { fprintf(F, "%ld", attr->offset); } } - - { + else { const ia32_attr_t *attr = get_ia32_attr_const(n); if(attr->am_sc != NULL || attr->am_offs != 0) @@ -248,12 +263,6 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { case ia32_am_Source: fprintf(F, "source only (Load)"); break; - case ia32_am_Dest: - fprintf(F, "dest only (Load+Store)"); - break; - case ia32_am_Full: - fprintf(F, "full"); - break; default: fprintf(F, "unknown (%d)", get_ia32_am_support(n)); break; @@ -276,17 +285,17 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { fprintf(F, "AM scale = %d\n", get_ia32_am_scale(n)); /* dump pn code */ - if(is_ia32_SwitchJmp(n)) { - fprintf(F, "pn_code = %ld\n", get_ia32_pncode(n)); - } else { - if(get_ia32_pncode(n) & ia32_pn_Cmp_Unsigned) { - long pnc = get_ia32_pncode(n); - fprintf(F, "pn_code = %ld (%s, unsigned)\n", - pnc, get_pnc_string(pnc & ~ia32_pn_Cmp_Unsigned)); - } else { - fprintf(F, "pn_code = %ld (%s)\n", get_ia32_pncode(n), - get_pnc_string(get_ia32_pncode(n))); - } + if (is_ia32_SwitchJmp(n)) { + fprintf(F, "pn_code = %ld\n", get_ia32_condcode(n)); + } else if (is_ia32_CMov(n) || is_ia32_Set(n) || is_ia32_Jcc(n)) { + ia32_attr_t *attr = get_ia32_attr(n); + long pnc = get_ia32_condcode(n); + fprintf(F, "pn_code = 0x%lX (%s)\n", pnc, get_pnc_string(pnc & pn_Cmp_True)); + fprintf(F, "ins_permuted = %u \n", attr->data.ins_permuted); + fprintf(F, "cmp_unsigned = %u \n", attr->data.cmp_unsigned); + } + else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) { + fprintf(F, "size = %u\n", get_ia32_copyb_size(n)); } /* dump n_res */ @@ -298,12 +307,12 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { /* commutative */ fprintf(F, "commutative = %d\n", is_ia32_commutative(n)); - /* got lea */ - fprintf(F, "got loea = %d\n", is_ia32_got_lea(n)); - /* need stackent */ fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n)); + /* need stackent */ + fprintf(F, "is reload = %d\n", is_ia32_is_reload(n)); + /* dump latency */ fprintf(F, "latency = %d\n", get_ia32_latency(n)); @@ -326,6 +335,9 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { if (flags & arch_irn_flags_modify_sp) { fprintf(F, " modify_sp"); } + if (flags & arch_irn_flags_modify_flags) { + fprintf(F, " modify_flags"); + } } fprintf(F, " (%d)\n", flags); @@ -411,13 +423,47 @@ const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node) { return asm_attr; } +ia32_immediate_attr_t *get_ia32_immediate_attr(ir_node *node) { + ia32_attr_t *attr = get_ia32_attr(node); + ia32_immediate_attr_t *imm_attr = CAST_IA32_ATTR(ia32_immediate_attr_t, attr); + + return imm_attr; +} + const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node) { - const ia32_attr_t *attr = get_ia32_attr_const(node); - const ia32_immediate_attr_t *immediate_attr - = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr); + const ia32_attr_t *attr = get_ia32_attr_const(node); + const ia32_immediate_attr_t *imm_attr = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr); + + return imm_attr; +} + +ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node) { + ia32_attr_t *attr = get_ia32_attr(node); + ia32_condcode_attr_t *cc_attr = CAST_IA32_ATTR(ia32_condcode_attr_t, attr); + + return cc_attr; +} + +const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node) { + const ia32_attr_t *attr = get_ia32_attr_const(node); + const ia32_condcode_attr_t *cc_attr = CONST_CAST_IA32_ATTR(ia32_condcode_attr_t, attr); + + return cc_attr; +} - return immediate_attr; +ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node) { + ia32_attr_t *attr = get_ia32_attr(node); + ia32_copyb_attr_t *copyb_attr = CAST_IA32_ATTR(ia32_copyb_attr_t, attr); + + return copyb_attr; +} + +const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node) { + const ia32_attr_t *attr = get_ia32_attr_const(node); + const ia32_copyb_attr_t *copyb_attr = CONST_CAST_IA32_ATTR(ia32_copyb_attr_t, attr); + + return copyb_attr; } /** @@ -536,10 +582,24 @@ int get_ia32_am_scale(const ir_node *node) { * Sets the index register scale for address mode. */ void set_ia32_am_scale(ir_node *node, int scale) { - ia32_attr_t *attr = get_ia32_attr(node); + ia32_attr_t *attr = get_ia32_attr(node); + assert(0 <= scale && scale < 4 && "AM scale out of range"); attr->data.am_scale = scale; } +void ia32_copy_am_attrs(ir_node *to, const ir_node *from) +{ + set_ia32_ls_mode(to, get_ia32_ls_mode(from)); + set_ia32_am_scale(to, get_ia32_am_scale(from)); + set_ia32_am_sc(to, get_ia32_am_sc(from)); + if(is_ia32_am_sc_sign(from)) + set_ia32_am_sc_sign(to); + add_ia32_am_offs_int(to, get_ia32_am_offs_int(from)); + set_ia32_frame_ent(to, get_ia32_frame_ent(from)); + if (is_ia32_use_frame(from)) + set_ia32_use_frame(to); +} + /** * Sets the uses_frame flag. */ @@ -588,30 +648,6 @@ int is_ia32_commutative(const ir_node *node) { return attr->data.is_commutative; } -/** - * Sets node got_lea. - */ -void set_ia32_got_lea(ir_node *node) { - ia32_attr_t *attr = get_ia32_attr(node); - attr->data.got_lea = 1; -} - -/** - * Clears node got_lea. - */ -void clear_ia32_got_lea(ir_node *node) { - ia32_attr_t *attr = get_ia32_attr(node); - attr->data.got_lea = 0; -} - -/** - * Checks if node got lea. - */ -int is_ia32_got_lea(const ir_node *node) { - const ia32_attr_t *attr = get_ia32_attr_const(node); - return attr->data.got_lea; -} - void set_ia32_need_stackent(ir_node *node) { ia32_attr_t *attr = get_ia32_attr(node); attr->data.need_stackent = 1; @@ -627,6 +663,16 @@ int is_ia32_need_stackent(const ir_node *node) { return attr->data.need_stackent; } +void set_ia32_is_reload(ir_node *node) { + ia32_attr_t *attr = get_ia32_attr(node); + attr->data.is_reload = 1; +} + +int is_ia32_is_reload(const ir_node *node) { + const ia32_attr_t *attr = get_ia32_attr_const(node); + return attr->data.is_reload; +} + /** * Gets the mode of the stored/loaded value (only set for Store/Load) */ @@ -668,16 +714,9 @@ void set_ia32_frame_ent(ir_node *node, ir_entity *ent) { * Gets the instruction latency. */ unsigned get_ia32_latency(const ir_node *node) { - const ia32_attr_t *attr = get_ia32_attr_const(node); - return attr->latency; -} - -/** -* Sets the instruction latency. -*/ -void set_ia32_latency(ir_node *node, unsigned latency) { - ia32_attr_t *attr = get_ia32_attr(node); - attr->latency = latency; + const ir_op *op = get_irn_op(node); + const ia32_op_attr_t *op_attr = (ia32_op_attr_t*) get_op_attr(op); + return op_attr->latency; } /** @@ -766,6 +805,11 @@ void set_ia32_flags(ir_node *node, arch_irn_flags_t flags) { attr->data.flags = flags; } +void add_ia32_flags(ir_node *node, arch_irn_flags_t flags) { + ia32_attr_t *attr = get_ia32_attr(node); + attr->data.flags |= flags; +} + /** * Returns the result register slots of an ia32 node. */ @@ -783,37 +827,30 @@ int get_ia32_n_res(const ir_node *node) { } /** - * Returns the flavour of an ia32 node, + * Returns the condition code of a node. */ -ia32_op_flavour_t get_ia32_flavour(const ir_node *node) { - const ia32_attr_t *attr = get_ia32_attr_const(node); - return attr->data.op_flav; -} - -/** - * Sets the flavour of an ia32 node to flavour_Div/Mod/DivMod/Mul/Mulh. - */ -void set_ia32_flavour(ir_node *node, ia32_op_flavour_t op_flav) { - ia32_attr_t *attr = get_ia32_attr(node); - attr->data.op_flav = op_flav; +long get_ia32_condcode(const ir_node *node) +{ + const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node); + return attr->pn_code; } /** - * Returns the projnum code. + * Sets the condition code of a node */ -long get_ia32_pncode(const ir_node *node) +void set_ia32_condcode(ir_node *node, long code) { - const ia32_attr_t *attr = get_ia32_attr_const(node); - return attr->pn_code; + ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node); + attr->pn_code = code; } /** - * Sets the projnum code + * Returns the condition code of a node. */ -void set_ia32_pncode(ir_node *node, long code) +unsigned get_ia32_copyb_size(const ir_node *node) { - ia32_attr_t *attr = get_ia32_attr(node); - attr->pn_code = code; + const ia32_copyb_attr_t *attr = get_ia32_copyb_attr_const(node); + return attr->size; } /** @@ -847,7 +884,7 @@ const be_execution_unit_t ***get_ia32_exec_units(const ir_node *node) { */ unsigned get_ia32_exc_label(const ir_node *node) { const ia32_attr_t *attr = get_ia32_attr_const(node); - return attr->data.except_label; + return attr->data.has_except_label; } /** @@ -855,7 +892,27 @@ unsigned get_ia32_exc_label(const ir_node *node) { */ void set_ia32_exc_label(ir_node *node, unsigned flag) { ia32_attr_t *attr = get_ia32_attr(node); - attr->data.except_label = flag; + attr->data.has_except_label = flag; +} + +/** + * Return the exception label id. + */ +ir_label_t get_ia32_exc_label_id(const ir_node *node) { + const ia32_attr_t *attr = get_ia32_attr_const(node); + + assert(attr->data.has_except_label); + return attr->exc_label; +} + +/** + * Assign the exception label id. + */ +void set_ia32_exc_label_id(ir_node *node, ir_label_t id) { + ia32_attr_t *attr = get_ia32_attr(node); + + assert(attr->data.has_except_label); + attr->exc_label = id; } #ifndef NDEBUG @@ -889,24 +946,6 @@ void set_ia32_orig_node(ir_node *node, const char *name) { * |_| ******************************************************************************************************/ -/** - * Sets the AddrMode(S|D) attribute - */ -void set_ia32_AddrMode(ir_node *node, char direction) { - ia32_attr_t *attr = get_ia32_attr(node); - - switch (direction) { - case 'D': - attr->data.tp = ia32_AddrModeD; - break; - case 'S': - attr->data.tp = ia32_AddrModeS; - break; - default: - assert(0 && "wrong AM type"); - } -} - /** * Returns whether or not the node is an AddrModeS node. */ @@ -973,12 +1012,14 @@ int get_ia32_out_regnr(const ir_node *node, int pos) { void ia32_swap_left_right(ir_node *node) { - ir_node *left = get_irn_n(node, 2); - ir_node *right = get_irn_n(node, 3); + ia32_attr_t *attr = get_ia32_attr(node); + ir_node *left = get_irn_n(node, n_ia32_binary_left); + ir_node *right = get_irn_n(node, n_ia32_binary_right); + assert(is_ia32_commutative(node)); - set_irn_n(node, 2, right); - set_irn_n(node, 3, left); - set_ia32_pncode(node, get_inversed_pnc(get_ia32_pncode(node))); + attr->data.ins_permuted = !attr->data.ins_permuted; + set_irn_n(node, n_ia32_binary_left, right); + set_irn_n(node, n_ia32_binary_right, left); } /** @@ -1000,17 +1041,15 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags, const arch_register_req_t **in_reqs, const arch_register_req_t **out_reqs, const be_execution_unit_t ***execution_units, - int n_res, unsigned latency) + int n_res) { - ir_graph *irg = get_irn_irg(node); - struct obstack *obst = get_irg_obstack(irg); - ia32_attr_t *attr = get_ia32_attr(node); - arch_register_t**slots; + ir_graph *irg = get_irn_irg(node); + struct obstack *obst = get_irg_obstack(irg); + ia32_attr_t *attr = get_ia32_attr(node); set_ia32_flags(node, flags); set_ia32_in_req_all(node, in_reqs); set_ia32_out_req_all(node, out_reqs); - set_ia32_latency(node, latency); attr->exec_units = execution_units; #ifndef NDEBUG @@ -1020,8 +1059,9 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags, attr->out_flags = NEW_ARR_D(int, obst, n_res); memset(attr->out_flags, 0, n_res * sizeof(attr->out_flags[0])); - attr->slots = slots = NEW_ARR_D(arch_register_t*, obst, n_res); - memset(slots, 0, n_res * sizeof(slots[0])); + attr->slots = NEW_ARR_D(const arch_register_t*, obst, n_res); + /* void* cast to suppress an incorrect warning on MSVC */ + memset((void*)attr->slots, 0, n_res * sizeof(attr->slots[0])); } void @@ -1030,6 +1070,8 @@ init_ia32_x87_attributes(ir_node *res) #ifndef NDEBUG ia32_attr_t *attr = get_ia32_attr(res); attr->attr_type |= IA32_ATTR_ia32_x87_attr_t; +#else + (void) res; #endif ia32_current_cg->do_x87_sim = 1; } @@ -1040,6 +1082,8 @@ init_ia32_asm_attributes(ir_node *res) #ifndef NDEBUG ia32_attr_t *attr = get_ia32_attr(res); attr->attr_type |= IA32_ATTR_ia32_asm_attr_t; +#else + (void) res; #endif } @@ -1050,11 +1094,31 @@ init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst, ia32_immediate_attr_t *attr = get_irn_generic_attr(res); #ifndef NDEBUG - attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t; + attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t; +#endif + attr->symconst = symconst; + attr->sc_sign = symconst_sign; + attr->offset = offset; +} + +void +init_ia32_copyb_attributes(ir_node *res, unsigned size) { + ia32_copyb_attr_t *attr = get_irn_generic_attr(res); + +#ifndef NDEBUG + attr->attr.attr_type |= IA32_ATTR_ia32_copyb_attr_t; +#endif + attr->size = size; +} + +void +init_ia32_condcode_attributes(ir_node *res, long pnc) { + ia32_condcode_attr_t *attr = get_irn_generic_attr(res); + +#ifndef NDEBUG + attr->attr.attr_type |= IA32_ATTR_ia32_condcode_attr_t; #endif - attr->symconst = symconst; - attr->attr.data.am_sc_sign = symconst_sign; - attr->offset = offset; + attr->pn_code = pnc; } ir_node *get_ia32_result_proj(const ir_node *node) @@ -1103,19 +1167,20 @@ int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b) { || a->frame_ent != b->frame_ent) return 1; - if(a->pn_code != b->pn_code) + if (a->data.tp != b->data.tp) return 1; - if (a->data.tp != b->data.tp - || a->data.op_flav != b->data.op_flav) + if (a->data.has_except_label != b->data.has_except_label) return 1; - if (a->data.except_label != b->data.except_label) + if (a->data.ins_permuted != b->data.ins_permuted + || a->data.cmp_unsigned != b->data.cmp_unsigned) return 1; return 0; } +/** Compare nodes attributes for all "normal" nodes. */ static int ia32_compare_nodes_attr(ir_node *a, ir_node *b) { @@ -1125,12 +1190,46 @@ int ia32_compare_nodes_attr(ir_node *a, ir_node *b) return ia32_compare_attr(attr_a, attr_b); } +/** Compare node attributes for nodes with condition code. */ static -int ia32_compare_x87_attr(ir_node *a, ir_node *b) +int ia32_compare_condcode_attr(ir_node *a, ir_node *b) { - return ia32_compare_nodes_attr(a, b); + const ia32_condcode_attr_t *attr_a; + const ia32_condcode_attr_t *attr_b; + + if (ia32_compare_nodes_attr(a, b)) + return 1; + + attr_a = get_ia32_condcode_attr_const(a); + attr_b = get_ia32_condcode_attr_const(b); + + if(attr_a->pn_code != attr_b->pn_code) + return 1; + + return 0; +} + +/** Compare node attributes for CopyB nodes. */ +static +int ia32_compare_copyb_attr(ir_node *a, ir_node *b) +{ + const ia32_copyb_attr_t *attr_a; + const ia32_copyb_attr_t *attr_b; + + if (ia32_compare_nodes_attr(a, b)) + return 1; + + attr_a = get_ia32_copyb_attr_const(a); + attr_b = get_ia32_copyb_attr_const(b); + + if(attr_a->size != attr_b->size) + return 1; + + return 0; } + +/** Compare ASM node attributes. */ static int ia32_compare_asm_attr(ir_node *a, ir_node *b) { @@ -1149,6 +1248,16 @@ int ia32_compare_asm_attr(ir_node *a, ir_node *b) return 0; } +/** + * Hash function for Immediates + */ +static unsigned ia32_hash_Immediate(const ir_node *irn) { + const ia32_immediate_attr_t *a = get_ia32_immediate_attr_const(irn); + + return HASH_PTR(a->symconst) + (a->sc_sign << 16) + a->offset; +} + +/** Compare node attributes for Immediates. */ static int ia32_compare_immediate_attr(ir_node *a, ir_node *b) { @@ -1156,13 +1265,21 @@ int ia32_compare_immediate_attr(ir_node *a, ir_node *b) const ia32_immediate_attr_t *attr_b = get_ia32_immediate_attr_const(b); if(attr_a->symconst != attr_b->symconst || - attr_a->attr.data.am_sc_sign != attr_b->attr.data.am_sc_sign || + attr_a->sc_sign != attr_b->sc_sign || attr_a->offset != attr_b->offset) return 1; return 0; } +/** Compare node attributes for x87 nodes. */ +static +int ia32_compare_x87_attr(ir_node *a, ir_node *b) +{ + return ia32_compare_nodes_attr(a, b); +} + + /* copies the ia32 attributes */ static void ia32_copy_attr(const ir_node *old_node, ir_node *new_node) {