fixed some minor bugs
authorChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Thu, 9 Mar 2006 09:07:09 +0000 (09:07 +0000)
committerChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Thu, 9 Mar 2006 09:07:09 +0000 (09:07 +0000)
code cleanups
added new magic (register generic functions at op's)

ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_map_regs.c
ir/be/ia32/ia32_new_nodes.c
ir/be/ia32/ia32_new_nodes.h
ir/be/ia32/ia32_optimize.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c

index d69e0fd..412f3b2 100644 (file)
@@ -190,8 +190,6 @@ static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
        irn = my_skip_proj(irn);
        if (is_cfop(irn))
                return arch_irn_class_branch;
-       else if (is_ia32_Call(irn))
-               return arch_irn_class_call;
        else if (is_ia32_irn(irn))
                return arch_irn_class_normal;
        else
index 8a1f35f..6ad0765 100644 (file)
@@ -15,6 +15,7 @@
 #include "irprog_t.h"
 
 #include "../besched.h"
+#include "../benode_t.h"
 
 #include "ia32_emitter.h"
 #include "gen_ia32_emitter.h"
@@ -58,11 +59,21 @@ char *ia32_emit_binop(const ir_node *n) {
                                lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %4S", n, n);
                        }
                        break;
-               case ia32_am_Source:
+               case ia32_AddrModeS:
                        lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %s", n, ia32_emit_am(n));
                        break;
-               case ia32_am_Dest:
-                       lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %4S", ia32_emit_am(n), n);
+               case ia32_AddrModeD:
+                       if (get_ia32_cnst(n)) {
+                               lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %s", ia32_emit_am(n), get_ia32_cnst(n));
+                       }
+                       else {
+                               if (is_ia32_St(n)) {
+                                       lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %3S", ia32_emit_am(n), n);
+                               }
+                               else {
+                                       lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %4S", ia32_emit_am(n), n);
+                               }
+                       }
                        break;
                default:
                        assert(0 && "unsupported op type");
@@ -172,7 +183,7 @@ static int ia32_get_arg_type(const lc_arg_occ_t *occ) {
 /**
  * Returns the register at in position pos.
  */
-static const arch_register_t *get_in_reg(ir_node *irn, int pos) {
+static const arch_register_t *get_in_reg(const ir_node *irn, int pos) {
        ir_node                *op;
        const arch_register_t  *reg = NULL;
 
@@ -191,7 +202,7 @@ static const arch_register_t *get_in_reg(ir_node *irn, int pos) {
 /**
  * Returns the register at out position pos.
  */
-static const arch_register_t *get_out_reg(ir_node *irn, int pos) {
+static const arch_register_t *get_out_reg(const ir_node *irn, int pos) {
        ir_node                *proj;
        const arch_register_t  *reg = NULL;
 
@@ -275,9 +286,8 @@ static int ia32_get_reg_name(lc_appendable_t *app,
        if (!X)
                return lc_arg_append(app, occ, "(null)", 6);
 
-  buf = get_ia32_reg_name(X, nr, occ->conversion == 'S' ? IN_REG : OUT_REG);
+       buf = get_ia32_reg_name(X, nr, occ->conversion == 'S' ? IN_REG : OUT_REG);
 
-       lc_appendable_chadd(app, '%');
        return lc_arg_append(app, occ, buf, strlen(buf));
 }
 
@@ -314,10 +324,7 @@ static int ia32_get_mode_suffix(lc_appendable_t *app,
        if (!X)
                return lc_arg_append(app, occ, "(null)", 6);
 
-       if (get_mode_size_bits(get_irn_mode(X)) == 32)
-               return lc_appendable_chadd(app, 's');
-       else
-               return lc_appendable_chadd(app, 'd');
+       return lc_appendable_chadd(app, get_mode_size_bits(get_irn_mode(X)) == 32 ? 's' : 'd');
 }
 
 /**
@@ -334,7 +341,6 @@ const lc_arg_env_t *ia32_get_arg_env(void) {
        if(env == NULL) {
                /* extend the firm printer */
                env = firm_get_arg_env();
-                       //lc_arg_new_env();
 
                lc_arg_register(env, "ia32:sreg", 'S', &ia32_reg_handler);
                lc_arg_register(env, "ia32:dreg", 'D', &ia32_reg_handler);
@@ -443,7 +449,7 @@ static char *get_cfop_target(const ir_node *irn, char *buf) {
 /**
  * Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
  */
-static void finish_CondJmp(FILE *F, ir_node *irn) {
+static void finish_CondJmp(FILE *F, const ir_node *irn) {
        const ir_node   *proj;
        const ir_edge_t *edge;
        char buf[SNPRINTF_BUF_LEN];
@@ -474,7 +480,7 @@ static void finish_CondJmp(FILE *F, ir_node *irn) {
 /**
  * Emits code for conditional jump with two variables.
  */
-static void emit_ia32_CondJmp(ir_node *irn, emit_env_t *env) {
+static void emit_ia32_CondJmp(const ir_node *irn, emit_env_t *env) {
        FILE *F = env->out;
 
        lc_efprintf(ia32_get_arg_env(), F, "\tcmp %2S, %1S\t\t\t/* CondJmp(%+F, %+F) */\n", irn, irn,
@@ -485,7 +491,7 @@ static void emit_ia32_CondJmp(ir_node *irn, emit_env_t *env) {
 /**
  * Emits code for conditional jump with immediate.
  */
-void emit_ia32_CondJmp_i(ir_node *irn, emit_env_t *env) {
+void emit_ia32_CondJmp_i(const ir_node *irn, emit_env_t *env) {
        FILE *F = env->out;
 
        lc_efprintf(ia32_get_arg_env(), F, "\tcmp %C, %1S\t\t\t/* CondJmp_i(%+F) */\n", irn, irn, get_irn_n(irn, 0));
@@ -601,12 +607,11 @@ void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
        if (do_jmp_tbl) {
                /* emit the table */
                if (tbl.min_value != 0) {
-                       fprintf(F, "\tcmpl %lu, -%d", interval, tbl.min_value);
-                       lc_efprintf(env, F, "(%1S)\t\t/* first switch value is not 0 */\n", irn);
+                       lc_efprintf(env, F, "\tcmpl %lu, -%d(%1S)\t\t/* first switch value is not 0 */\n",
+                               interval, tbl.min_value, irn);
                }
                else {
-                       fprintf(F, "\tcmpl %lu, ", interval);
-                       lc_efprintf(env, F, "%1S\t\t\t/* compare for switch */\n", irn);
+                       lc_efprintf(env, F, "\tcmpl %lu, %1S\t\t\t/* compare for switch */\n", interval, irn);
                }
 
                fprintf(F, "\tja %s\t\t\t/* default jump if out of range  */\n", get_cfop_target(tbl.defProj, buf));
@@ -614,7 +619,6 @@ void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
                if (tbl.num_branches > 1) {
                        /* create table */
 
-                       //fprintf(F, "\tjmp *%s", tbl.label);
                        lc_efprintf(env, F, "\tjmp *%s(,%1S,4)\t\t/* get jump table entry as target */\n", tbl.label, irn);
 
                        fprintf(F, "\t.section\t.rodata\t\t/* start jump table */\n");
@@ -640,9 +644,7 @@ void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
        }
        else { // no jump table
                for (i = 0; i < tbl.num_branches; ++i) {
-                       fprintf(F, "\tcmpl %d, ", tbl.branches[i].value);
-                       lc_efprintf(env, F, "%1S", irn);
-                       fprintf(F, "\t\t\t/* case %d */\n", tbl.branches[i].value);
+                       lc_efprintf(env, F, "\tcmpl %d, %1S\t\t\t/* case %d */\n", tbl.branches[i].value, irn, i);
                        fprintf(F, "\tje %s\n", get_cfop_target(tbl.branches[i].target, buf));
                }
 
@@ -658,7 +660,7 @@ void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
 /**
  * Emits code for a unconditional jump.
  */
-void emit_Jmp(ir_node *irn, emit_env_t *env) {
+void emit_Jmp(const ir_node *irn, emit_env_t *env) {
        FILE *F = env->out;
 
        char buf[SNPRINTF_BUF_LEN];
@@ -681,7 +683,7 @@ void emit_Jmp(ir_node *irn, emit_env_t *env) {
 /**
  * Emits code for a proj -> node
  */
-void emit_Proj(ir_node *irn, emit_env_t *env) {
+void emit_Proj(const ir_node *irn, emit_env_t *env) {
        ir_node *pred = get_Proj_pred(irn);
 
        if (get_irn_op(pred) == op_Start) {
@@ -724,7 +726,7 @@ static void emit_CopyB_prolog(FILE *F, int rem, int size) {
        }
 }
 
-void emit_ia32_CopyB(ir_node *irn, emit_env_t *emit_env) {
+void emit_ia32_CopyB(const ir_node *irn, emit_env_t *emit_env) {
        FILE   *F    = emit_env->out;
        tarval *tv   = get_ia32_Immop_tarval(irn);
        int     rem  = get_tarval_long(tv);
@@ -735,7 +737,7 @@ void emit_ia32_CopyB(ir_node *irn, emit_env_t *emit_env) {
        fprintf(F, "\trep movsd\t\t\t\t/* memcopy */\n");
 }
 
-void emit_ia32_CopyB_i(ir_node *irn, emit_env_t *emit_env) {
+void emit_ia32_CopyB_i(const ir_node *irn, emit_env_t *emit_env) {
        tarval *tv   = get_ia32_Immop_tarval(irn);
        int     size = get_tarval_long(tv);
        FILE   *F    = emit_env->out;
@@ -748,17 +750,41 @@ void emit_ia32_CopyB_i(ir_node *irn, emit_env_t *emit_env) {
        }
 }
 
-/********************
- *   _____      _ _
- *  / ____|    | | |
- * | |     __ _| | |
- * | |    / _` | | |
- * | |___| (_| | | |
- *  \_____\__,_|_|_|
+
+
+/*******************************************
+ *  _                          _
+ * | |                        | |
+ * | |__   ___ _ __   ___   __| | ___  ___
+ * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
+ * | |_) |  __/ | | | (_) | (_| |  __/\__ \
+ * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
  *
- ********************/
+ *******************************************/
+
+void emit_be_Call(const ir_node *irn, emit_env_t *emit_env) {
+       FILE *F = emit_env->out;
 
-void emit_ia32_Call(ir_node *irn, emit_env_t *emit_env) {
+       lc_efprintf(ia32_get_arg_env(), F, "\tcall %3S\t\t\t/* %+F(%+F) (be_Call) */\n", irn, irn, get_irn_n(irn, 2));
+}
+
+void emit_be_IncSP(const ir_node *irn, emit_env_t *emit_env) {
+       FILE          *F    = emit_env->out;
+       unsigned       offs = be_get_IncSP_offset(irn);
+       be_stack_dir_t dir  = be_get_IncSP_direction(irn);
+
+       if (offs) {
+               lc_efprintf(ia32_get_arg_env(), F, "\tadd %1S,%s%u\t\t\t/* %+F (IncSP) */\n", irn,
+                       (dir == be_stack_dir_along) ? " -" : " ", offs, irn);
+       }
+       else {
+               fprintf(F, "\t\t\t\t\t/* omitted IncSP with 0 */\n");
+       }
+}
+
+void emit_be_AddSP(const ir_node *irn, emit_env_t *emit_env) {
+       FILE *F = emit_env->out;
+       lc_efprintf(ia32_get_arg_env(), F, "\tadd %1D, %1S\t\t\t/* %+F (AddSP) */\n", irn, irn, irn);
 }
 
 
@@ -778,98 +804,52 @@ void emit_ia32_Call(ir_node *irn, emit_env_t *emit_env) {
  * pointer of an opcode.
  */
 void ia32_register_emitters(void) {
-       int i;
 
 #define IA32_EMIT(a) op_ia32_##a->ops.generic = (op_func)emit_ia32_##a
 #define EMIT(a)      op_##a->ops.generic = (op_func)emit_##a
+#define BE_EMIT(a)   op_be_##a->ops.generic = (op_func)emit_be_##a
 
-       /* first clear all generic operations */
-       for (i = get_irp_n_opcodes() - 1; i >= 0; --i) {
-               ir_op *op = get_irp_opcode(i);
-               op->ops.generic = (op_func)NULL;
-       }
-
-       /* generated int emitter functions */
-       IA32_EMIT(Const);
-
-       IA32_EMIT(Add);
-       IA32_EMIT(Sub);
-       IA32_EMIT(Minus);
-       IA32_EMIT(Inc);
-       IA32_EMIT(Dec);
-
-       IA32_EMIT(Max);
-       IA32_EMIT(Min);
-       IA32_EMIT(CMov);
-
-       IA32_EMIT(And);
-       IA32_EMIT(Or);
-       IA32_EMIT(Eor);
-       IA32_EMIT(Not);
-
-       IA32_EMIT(Shl);
-       IA32_EMIT(Shr);
-       IA32_EMIT(Shrs);
-       IA32_EMIT(RotL);
-       IA32_EMIT(RotR);
-
-       IA32_EMIT(Lea);
-
-       IA32_EMIT(Mul);
-
-       IA32_EMIT(Cdq);
-       IA32_EMIT(DivMod);
-
-       IA32_EMIT(Store);
-       IA32_EMIT(Load);
-
-       IA32_EMIT(CopyB);
-       IA32_EMIT(CopyB_i);
-
-       /* generated floating point emitter */
-       IA32_EMIT(fConst);
-
-       IA32_EMIT(fAdd);
-       IA32_EMIT(fSub);
-
-       IA32_EMIT(fMul);
-       IA32_EMIT(fDiv);
-
-       IA32_EMIT(fMin);
-       IA32_EMIT(fMax);
-
-       IA32_EMIT(fLoad);
-       IA32_EMIT(fStore);
+       /* register all emitter functions defined in spec */
+       ia32_register_spec_emitters();
 
        /* other emitter functions */
        IA32_EMIT(CondJmp);
        IA32_EMIT(SwitchJmp);
-       IA32_EMIT(Call);
+       IA32_EMIT(CopyB);
+       IA32_EMIT(CopyB_i);
+
+       /* benode emitter */
+       BE_EMIT(Call);
+       BE_EMIT(IncSP);
+       BE_EMIT(AddSP);
 
+       /* firm emitter */
        EMIT(Jmp);
        EMIT(Proj);
 
 #undef IA32_EMIT
+#undef BE_EMIT
 #undef EMIT
 }
 
 /**
  * Emits code for a node.
  */
-static void ia32_emit_node(ir_node *irn, void *env) {
-       emit_env_t *emit_env   = env;
-       firm_dbg_module_t *mod = emit_env->mod;
-       FILE              *F   = emit_env->out;
-       ir_op             *op = get_irn_op(irn);
+static void ia32_emit_node(const ir_node *irn, void *env) {
+       emit_env_t        *emit_env = env;
+       firm_dbg_module_t *mod      = emit_env->mod;
+       FILE              *F        = emit_env->out;
+       ir_op             *op       = get_irn_op(irn);
 
        DBG((mod, LEVEL_1, "emitting code for %+F\n", irn));
 
        if (op->ops.generic) {
-               void (*emit)(ir_node *, void *) = (void (*)(ir_node *, void *))op->ops.generic;
+               void (*emit)(const ir_node *, void *) = (void (*)(const ir_node *, void *))op->ops.generic;
                (*emit)(irn, env);
        }
-
-       ir_fprintf(F, "\t\t\t\t\t/* %+F */\n", irn);
+       else {
+               ir_fprintf(F, "\t\t\t\t\t/* %+F */\n", irn);
+       }
 }
 
 /**
@@ -877,7 +857,7 @@ static void ia32_emit_node(ir_node *irn, void *env) {
  * and emits code for each node.
  */
 static void ia32_gen_block(ir_node *block, void *env) {
-       ir_node *irn;
+       const ir_node *irn;
 
        if (! is_Block(block))
                return;
@@ -892,7 +872,7 @@ static void ia32_gen_block(ir_node *block, void *env) {
 /**
  * Emits code for function start.
  */
-void ia32_emit_start(FILE *F, ir_graph *irg) {
+static void ia32_emit_func_prolog(FILE *F, ir_graph *irg) {
        const char *irg_name = get_entity_name(get_irg_entity(irg));
 
        fprintf(F, "\t.text\n");
@@ -904,7 +884,7 @@ void ia32_emit_start(FILE *F, ir_graph *irg) {
 /**
  * Emits code for function end
  */
-void ia32_emit_end(FILE *F, ir_graph *irg) {
+static void ia32_emit_func_epilog(FILE *F, ir_graph *irg) {
        const char *irg_name = get_entity_name(get_irg_entity(irg));
 
        fprintf(F, "\tret\n");
@@ -915,7 +895,7 @@ void ia32_emit_end(FILE *F, ir_graph *irg) {
  * Sets labels for control flow nodes (jump target)
  * TODO: Jump optimization
  */
-void ia32_gen_labels(ir_node *block, void *env) {
+static void ia32_gen_labels(ir_node *block, void *env) {
        ir_node *pred;
        int n = get_Block_n_cfgpreds(block);
 
@@ -939,8 +919,8 @@ void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg) {
        /* set the global arch_env (needed by print hooks) */
        arch_env = cg->arch_env;
 
-       ia32_emit_start(F, irg);
+       ia32_emit_func_prolog(F, irg);
        irg_block_walk_graph(irg, ia32_gen_labels, NULL, &emit_env);
        irg_walk_blkwise_graph(irg, NULL, ia32_gen_block, &emit_env);
-       ia32_emit_end(F, irg);
+       ia32_emit_func_epilog(F, irg);
 }
index 45fa91d..16051a0 100644 (file)
@@ -233,9 +233,6 @@ long ia32_translate_proj_pos(const ir_node *proj) {
                else
                        assert(0 && "there should be no more Projs for a fDiv");
        }
-       else if (is_ia32_Call(pred)) {
-               return 0;
-       }
        else if (get_irn_mode(proj) == mode_X && nr == pn_Start_X_initial_exec) {
                return 0;
        }
index 05bfde5..f5b5627 100644 (file)
@@ -180,7 +180,6 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
        ir_mode     *mode = NULL;
        int          bad  = 0;
        int          i, n_res, am_flav, flags;
-       ia32_attr_t *attr;
        const ia32_register_req_t **reqs;
        const arch_register_t     **slots;
 
@@ -192,23 +191,15 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
                case dump_node_mode_txt:
                        mode = get_irn_mode(n);
 
-                       if (is_ia32_Load(n) || is_ia32_Store(n)) {
+                       if (is_ia32_Ld(n) || is_ia32_St(n)) {
                                mode = get_ia32_ls_mode(n);
                        }
 
-                       if (mode) {
-                               fprintf(F, "[%s]", get_mode_name(mode));
-                       }
-                       else {
-                               fprintf(F, "[?NOMODE?]");
-                       }
+                       fprintf(F, "[%s]", mode ? get_mode_name(mode) : "?NOMODE?");
                        break;
 
                case dump_node_nodeattr_txt:
-                       if (is_ia32_Call(n)) {
-                               fprintf(F, "&%s ", get_ia32_sc(n));
-                       }
-                       else if (get_ia32_cnst(n)) {
+                       if (get_ia32_cnst(n)) {
                                char *pref = "";
 
                                if (get_ia32_sc(n)) {
@@ -230,7 +221,6 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
                        break;
 
                case dump_node_info_txt:
-                       attr  = get_ia32_attr(n);
                        n_res = get_ia32_n_res(n);
                        fprintf(F, "=== IA32 attr begin ===\n");
 
@@ -250,15 +240,10 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
                        slots = get_ia32_slots(n);
                        if (slots && n_res > 0) {
                                for (i = 0; i < n_res; i++) {
-                                       if (slots[i]) {
-                                               fprintf(F, "reg #%d = %s\n", i, slots[i]->name);
-                                       }
-                                       else {
-                                               fprintf(F, "reg #%d = n/a\n", i);
-                                       }
+                                       fprintf(F, "reg #%d = %s\n", i, slots[i] ? slots[i]->name : "n/a");
                                }
+                               fprintf(F, "\n");
                        }
-                       fprintf(F, "\n");
 
                        /* dump op type */
                        fprintf(F, "op = ");
@@ -510,15 +495,12 @@ static void extend_ia32_am_offs(ir_node *node, char *offset, char op) {
 
        /* offset could already have an explicit sign */
        /* -> supersede op if necessary               */
-       if (offset[0] == '-' && op == '-') {
-               op = '+';
-       }
-       else if (offset[0] == '-' && op == '+') {
-               op = '-';
-       }
-
-       /* skip explicit sign */
        if (offset[0] == '-' || offset[0] == '+') {
+               if (offset[0] == '-') {
+                       op = (op == '-') ? '+' : '-';
+               }
+
+               /* skip explicit sign */
                offset++;
        }
 
@@ -563,8 +545,8 @@ int get_ia32_am_scale(const ir_node *node) {
  * Sets the index register scale for addrmode.
  */
 void set_ia32_am_scale(ir_node *node, int scale) {
-       ia32_attr_t *attr = get_ia32_attr(node);
-       attr->data.am_scale    = scale;
+       ia32_attr_t *attr   = get_ia32_attr(node);
+       attr->data.am_scale = scale;
 }
 
 /**
@@ -617,7 +599,7 @@ char *get_ia32_cnst(const ir_node *node) {
  * Sets the uses_frame flag.
  */
 void set_ia32_use_frame(ir_node *node) {
-       ia32_attr_t *attr = get_ia32_attr(node);
+       ia32_attr_t *attr    = get_ia32_attr(node);
        attr->data.use_frame = 1;
 }
 
@@ -625,7 +607,7 @@ void set_ia32_use_frame(ir_node *node) {
  * Clears the uses_frame flag.
  */
 void clear_ia32_use_frame(ir_node *node) {
-       ia32_attr_t *attr = get_ia32_attr(node);
+       ia32_attr_t *attr    = get_ia32_attr(node);
        attr->data.use_frame = 0;
 }
 
@@ -658,7 +640,6 @@ void clear_ia32_commutative(ir_node *node) {
  */
 int is_ia32_commutative(const ir_node *node) {
        ia32_attr_t *attr = get_ia32_attr(node);
-
        return attr->data.is_commutative;
 }
 
@@ -848,7 +829,7 @@ void set_ia32_pncode(ir_node *node, long code) {
 unsigned get_ia32_Const_type(const ir_node *node) {
        ia32_attr_t *attr = get_ia32_attr(node);
 
-       assert((is_ia32_Const(node) || is_ia32_fConst(node)) && "Need ia32_Const to get type");
+       assert(is_ia32_Cnst(node) && "Need ia32_Const to get type");
 
        return attr->data.tp;
 }
@@ -859,7 +840,7 @@ unsigned get_ia32_Const_type(const ir_node *node) {
 void set_ia32_Const_type(ir_node *node, int type) {
        ia32_attr_t *attr = get_ia32_attr(node);
 
-       assert((is_ia32_Const(node) || is_ia32_fConst(node)) && "Need ia32_Const to set type");
+       assert(is_ia32_Cnst(node) && "Need ia32_Const to set type");
        assert((type == ia32_Const || type == ia32_SymConst) && "Unsupported ia32_Const type");
 
        attr->data.tp = type;
@@ -872,7 +853,7 @@ void set_ia32_Immop_attr(ir_node *node, ir_node *cnst) {
        ia32_attr_t *na = get_ia32_attr(node);
        ia32_attr_t *ca = get_ia32_attr(cnst);
 
-       assert((is_ia32_Const(cnst) || is_ia32_fConst(cnst)) && "Need ia32_Const to set Immop attr");
+       assert(is_ia32_Cnst(cnst) && "Need ia32_Const to set Immop attr");
 
        na->tv = ca->tv;
 
@@ -892,19 +873,19 @@ void set_ia32_Immop_attr(ir_node *node, ir_node *cnst) {
 void set_ia32_Const_attr(ir_node *ia32_cnst, ir_node *cnst) {
        ia32_attr_t *attr = get_ia32_attr(ia32_cnst);
 
-       assert((is_ia32_Const(ia32_cnst) || is_ia32_fConst(ia32_cnst)) && "Need ia32_Const to set Const attr");
+       assert(is_ia32_Cnst(ia32_cnst) && "Need ia32_Const to set Const attr");
 
        switch (get_irn_opcode(cnst)) {
                case iro_Const:
-                       attr->data.tp   = ia32_Const;
-                       attr->tv   = get_Const_tarval(cnst);
-                       attr->cnst = set_cnst_from_tv(attr->cnst, attr->tv);
+                       attr->data.tp = ia32_Const;
+                       attr->tv      = get_Const_tarval(cnst);
+                       attr->cnst    = set_cnst_from_tv(attr->cnst, attr->tv);
                        break;
                case iro_SymConst:
-                       attr->data.tp   = ia32_SymConst;
-                       attr->tv   = NULL;
-                       attr->sc   = copy_str(attr->sc, get_sc_name(cnst));
-                       attr->cnst = attr->sc;
+                       attr->data.tp = ia32_SymConst;
+                       attr->tv      = NULL;
+                       attr->sc      = copy_str(attr->sc, get_sc_name(cnst));
+                       attr->cnst    = attr->sc;
                        break;
                case iro_Unknown:
                        assert(0 && "Unknown Const NYI");
@@ -962,6 +943,13 @@ int is_ia32_St(const ir_node *node) {
        return is_ia32_Store(node) || is_ia32_fStore(node);
 }
 
+/**
+ * Checks if node is a Const or fConst.
+ */
+int is_ia32_Cnst(const ir_node *node) {
+       return is_ia32_Const(node) || is_ia32_fConst(node);
+}
+
 /**
  * Returns the name of the OUT register at position pos.
  */
@@ -1014,7 +1002,7 @@ void alloc_ia32_reg_slots(ir_node *node, int num) {
                attr->slots = NULL;
        }
 
-       attr->data.n_res;
+       attr->data.n_res = num;
 }
 
 /**
@@ -1039,5 +1027,17 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags, const ia32_regi
  *
  ***************************************************************************************/
 
+/* default compare operation to compare immediate ops */
+int ia32_compare_immop_attr(ia32_attr_t *a, ia32_attr_t *b) {
+       if (a->data.tp == b->data.tp) {
+               if (! a->cnst || ! b->cnst)
+                       return 1;
+
+               return strcmp(a->cnst, b->cnst);
+       }
+
+       return 1;
+}
+
 /* Include the generated constructor functions */
 #include "gen_ia32_new_nodes.c.inl"
index 620c6c9..6a0c174 100644 (file)
@@ -320,6 +320,11 @@ int is_ia32_Ld(const ir_node *node);
  */
 int is_ia32_St(const ir_node *node);
 
+/**
+ * Checks if node is a Const or fConst.
+ */
+int is_ia32_Cnst(const ir_node *node);
+
 /**
  * Allocates num register slots for node.
  */
index a2ee42c..376b327 100644 (file)
@@ -223,26 +223,7 @@ void ia32_place_consts(ir_node *irn, void *env) {
  ******************************************************************/
 
 static int node_is_comm(const ir_node *irn) {
-       if (is_ia32_Add(irn)  ||
-               is_ia32_fAdd(irn) ||
-               is_ia32_Mul(irn)  ||
-               is_ia32_Mulh(irn) ||
-               is_ia32_fMul(irn) ||
-               is_ia32_And(irn)  ||
-               is_ia32_fAnd(irn) ||
-               is_ia32_Or(irn)   ||
-               is_ia32_fOr(irn)  ||
-               is_ia32_Eor(irn)  ||
-               is_ia32_fEor(irn) ||
-               is_ia32_Min(irn)  ||
-               is_ia32_fMin(irn) ||
-               is_ia32_Max(irn)  ||
-               is_ia32_fMax(irn))
-       {
-               return 1;
-       }
-
-       return 0;
+       return is_ia32_irn(irn) ? is_ia32_commutative(irn) : 0;
 }
 
 static int ia32_get_irn_n_edges(const ir_node *irn) {
@@ -626,7 +607,8 @@ void ia32_optimize_am(ir_node *irn, void *env) {
                                add_ia32_am_offs(irn, get_ia32_am_offs(left));
                                set_ia32_am_scale(irn, get_ia32_am_scale(left));
                                set_ia32_am_flavour(irn, get_ia32_am_flavour(left));
-                               set_ia32_op_type(irn, get_ia32_op_type(left));
+
+                               set_ia32_op_type(irn, is_ia32_St(irn) ? ia32_AddrModeD : ia32_AddrModeS);
 
                                /* set base and index */
                                set_irn_n(irn, 0, get_irn_n(left, 0));
index dbfa32b..b8f35a1 100644 (file)
@@ -95,7 +95,7 @@ $arch = "ia32";
             { "name" => "esi", "type" => 2 },
             { "name" => "edi", "type" => 2 },
             { "name" => "ebp", "type" => 2 },
-            { "name" => "esp", "type" => 6 },
+            { "name" => "esp", "type" => 4 },
             { "name" => "xxx", "type" => 6 },  # we need a dummy register for NoReg and Unknown nodes
                        { "mode" => "mode_P" }
           ],
@@ -150,6 +150,7 @@ $arch = "ia32";
 "Add" => {
   "irn_flags" => "R",
   "comment"   => "construct Add: Add(a, b) = Add(b, a) = a + b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. add %ia32_emit_binop\t\t\t/* Add(%A1, %A2) -> %D1 */'
 },
@@ -157,6 +158,7 @@ $arch = "ia32";
 "Mul" => {
   "irn_flags" => "A",
   "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. imul %ia32_emit_binop\t\t\t/* Mul(%A1, %A2) -> %D1 */'
 },
@@ -164,6 +166,7 @@ $arch = "ia32";
 # Mulh is an exception from the 4 INs with AM because the target is always EAX:EDX
 "Mulh" => {
   "comment"   => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r1", "edx in_r2" ] },
   "emit"      => '. imul %ia32_emit_unop\t\t\t/* Mulh(%A1, %A2) -> %D1 */ '
 },
@@ -171,6 +174,7 @@ $arch = "ia32";
 "And" => {
   "irn_flags" => "R",
   "comment"   => "construct And: And(a, b) = And(b, a) = a AND b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. and %ia32_emit_binop\t\t\t/* And(%A1, %A2) -> %D1 */'
 },
@@ -178,6 +182,7 @@ $arch = "ia32";
 "Or" => {
   "irn_flags" => "R",
   "comment"   => "construct Or: Or(a, b) = Or(b, a) = a OR b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. or %ia32_emit_binop\t\t\t/* Or(%A1, %A2) -> %D1 */'
 },
@@ -185,6 +190,7 @@ $arch = "ia32";
 "Eor" => {
   "irn_flags" => "R",
   "comment"   => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. xor %ia32_emit_binop\t\t\t/* Xor(%A1, %A2) -> %D1 */'
 },
@@ -234,6 +240,7 @@ $arch = "ia32";
 "Sub" => {
   "irn_flags" => "R",
   "comment"   => "construct Sub: Sub(a, b) = a - b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. sub %ia32_emit_binop\t\t\t/* Sub(%A1, %A2) -> %D1 */'
 },
@@ -255,6 +262,7 @@ $arch = "ia32";
 "Shl" => {
   "irn_flags" => "R",
   "comment"   => "construct Shl: Shl(a, b) = a << b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. shl %ia32_emit_binop\t\t\t/* Shl(%A1, %A2) -> %D1 */'
 },
@@ -262,6 +270,7 @@ $arch = "ia32";
 "Shr" => {
   "irn_flags" => "R",
   "comment"   => "construct Shr: Shr(a, b) = a >> b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. shr %ia32_emit_binop\t\t\t/* Shr(%A1, %A2) -> %D1 */'
 },
@@ -269,6 +278,7 @@ $arch = "ia32";
 "Shrs" => {
   "irn_flags" => "R",
   "comment"   => "construct Shrs: Shrs(a, b) = a >> b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. sar %ia32_emit_binop\t\t\t/* Shrs(%A1, %A2) -> %D1 */'
 },
@@ -276,6 +286,7 @@ $arch = "ia32";
 "RotR" => {
   "irn_flags" => "R",
   "comment"     => "construct RotR: RotR(a, b) = a ROTR b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"     => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
   "emit"        => '. ror %ia32_emit_binop\t\t\t/* RotR(%A1, %A2) -> %D1 */'
 },
@@ -283,6 +294,7 @@ $arch = "ia32";
 "RotL" => {
   "irn_flags" => "R",
   "comment"   => "construct RotL: RotL(a, b) = a ROTL b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. rol %ia32_emit_binop\t\t\t/* RotL(%A1, %A2) -> %D1 */'
 },
@@ -292,6 +304,7 @@ $arch = "ia32";
 "Minus" => {
   "irn_flags" => "R",
   "comment"   => "construct Minus: Minus(a) = -a",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. neg %ia32_emit_unop\t\t\t/* Neg(%A1) -> %D1, (%A1) */'
 },
@@ -299,6 +312,7 @@ $arch = "ia32";
 "Inc" => {
   "irn_flags" => "R",
   "comment"   => "construct Increment: Inc(a) = a++",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. inc %ia32_emit_unop\t\t\t/* Inc(%S1) -> %D1, (%A1) */'
 },
@@ -306,6 +320,7 @@ $arch = "ia32";
 "Dec" => {
   "irn_flags" => "R",
   "comment"   => "construct Decrement: Dec(a) = a--",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. dec %ia32_emit_unop\t\t\t/* Dec(%S1) -> %D1, (%A1) */'
 },
@@ -313,6 +328,7 @@ $arch = "ia32";
 "Not" => {
   "irn_flags" => "R",
   "comment"   => "construct Not: Not(a) = !a",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. not %ia32_emit_unop\t\t\t/* Not(%S1) -> %D1, (%A1) */'
 },
@@ -327,12 +343,14 @@ $arch = "ia32";
 "CondJmp" => {
   "op_flags"  => "L|X|Y",
   "comment"   => "construct conditional jump: CMP A, B && JMPxx LABEL",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "none", "none" ] },
 },
 
 "SwitchJmp" => {
   "op_flags"  => "L|X|Y",
   "comment"   => "construct switch",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
 },
 
@@ -340,30 +358,9 @@ $arch = "ia32";
   "op_flags"  => "c",
   "irn_flags" => "R",
   "comment"   => "represents an integer constant",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "out" => [ "gp" ] },
   "emit"      => '. mov %D1, %C\t\t\t/* Mov Const into register */',
-  "cmp_attr"  =>
-'
-  if (attr_a->data.tp == attr_b->data.tp) {
-    if (attr_a->data.tp == ia32_SymConst) {
-      if (attr_a->sc == NULL || attr_b->sc == NULL)
-        return 1;
-      else
-        return strcmp(attr_a->sc, attr_b->sc);
-    }
-    else {
-      if (attr_a->tv == NULL || attr_b->tv == NULL)
-        return 1;
-
-      if (tarval_cmp(attr_a->tv, attr_b->tv) == pn_Cmp_Eq)
-        return 0;
-      else
-        return 1;
-    }
-  }
-  else
-    return 1;
-'
 },
 
 "Cdq" => {
@@ -380,6 +377,7 @@ $arch = "ia32";
   "irn_flags" => "R",
   "state"     => "exc_pinned",
   "comment"   => "construct Load: Load(ptr, mem) = LD ptr -> reg",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
   "emit"      => '. mov %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */'
 },
@@ -388,15 +386,17 @@ $arch = "ia32";
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "gp", "none" ] },
-  "emit"      => '. mov %ia32_emit_am, %S3\t\t\t/* Store(%A2) -> (%A1) */'
+  "emit"      => '. mov %ia32_emit_binop\t\t\t/* Store(%A3) -> (%A1) */'
 },
 
 "Lea" => {
   "irn_flags" => "R",
   "comment"   => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
-  "emit"      => '. lea %D1, %ia32_emit_am\t\t/* %D1 = %S1 + %S2 << %C + %O, (%A1, %A2) */'
+  "emit"      => '. lea %D1, %ia32_emit_am\t\t/* %D1 = %S1 + %S2 << scale + %O, (%A1, %A2) */'
 },
 
 #--------------------------------------------------------#
@@ -413,6 +413,7 @@ $arch = "ia32";
 "fAdd" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. adds%M %ia32_emit_binop\t\t\t/* SSE Add(%A1, %A2) -> %D1 */'
 },
@@ -420,6 +421,7 @@ $arch = "ia32";
 "fMul" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
   "emit"      => '. muls%M %ia32_emit_binop\t\t\t/* SSE Mul(%A1, %A2) -> %D1 */'
 },
@@ -427,6 +429,7 @@ $arch = "ia32";
 "fMax" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Max: Max(a, b) = Max(b, a) = a > b ? a : b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
   "emit"      => '. maxs%M %ia32_emit_binop\t\t\t/* SSE Max(%A1, %A2) -> %D1 */'
 },
@@ -434,6 +437,7 @@ $arch = "ia32";
 "fMin" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Min: Min(a, b) = Min(b, a) = a < b ? a : b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
   "emit"      => '. mins%M %ia32_emit_binop\t\t\t/* SSE Min(%A1, %A2) -> %D1 */'
 },
@@ -441,6 +445,7 @@ $arch = "ia32";
 "fAnd" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE And: And(a, b) = a AND b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
   "emit"      => '. andp%M %ia32_emit_binop\t\t\t/* SSE And(%A3, %A4) -> %D1 */'
 },
@@ -448,6 +453,7 @@ $arch = "ia32";
 "fOr" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Or: Or(a, b) = a OR b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
   "emit"      => '. orp%M %ia32_emit_binop\t\t\t/* SSE Or(%A3, %A4) -> %D1 */'
 },
@@ -455,6 +461,7 @@ $arch = "ia32";
 "fEor" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Eor: Eor(a, b) = a XOR b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
   "emit"      => '. xorp%M %ia32_emit_binop\t\t\t/* SSE Xor(%A3, %A4) -> %D1 */'
 },
@@ -464,6 +471,7 @@ $arch = "ia32";
 "fSub" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Sub: Sub(a, b) = a - b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. subs%M %ia32_emit_binop\t\t\t/* SSE Sub(%A1, %A2) -> %D1 */'
 },
@@ -471,6 +479,7 @@ $arch = "ia32";
 "fDiv" => {
   "irn_flags" => "R",
   "comment"   => "construct SSE Div: Div(a, b) = a / b",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
   "emit"      => '. divs%M %ia32_emit_binop\t\t\t/* SSE Div(%A1, %A2) -> %D1 */'
 },
@@ -485,6 +494,7 @@ $arch = "ia32";
 "fCondJmp" => {
   "op_flags"  => "L|X|Y",
   "comment"   => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "none", "none" ] },
 },
 
@@ -492,30 +502,9 @@ $arch = "ia32";
   "op_flags"  => "c",
   "irn_flags" => "R",
   "comment"   => "represents a SSE constant",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "out" => [ "fp" ] },
   "emit"      => '. mov%M %D1, %C\t\t\t/* Load fConst into register */',
-  "cmp_attr"  =>
-'
-  if (attr_a->data.tp == attr_b->data.tp) {
-    if (attr_a->data.tp == ia32_SymConst) {
-      if (attr_a->sc == NULL || attr_b->sc == NULL)
-        return 1;
-      else
-        return strcmp(attr_a->sc, attr_b->sc);
-    }
-    else {
-      if (attr_a->tv == NULL || attr_b->tv == NULL)
-        return 1;
-
-      if (tarval_cmp(attr_a->tv, attr_b->tv) == pn_Cmp_Eq)
-        return 0;
-      else
-        return 1;
-    }
-  }
-  else
-    return 1;
-'
 },
 
 # Load / Store
@@ -525,6 +514,7 @@ $arch = "ia32";
   "irn_flags" => "R",
   "state"     => "exc_pinned",
   "comment"   => "construct SSE Load: Load(ptr, mem) = LD ptr",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"   => { "in" => [ "gp", "gp", "none" ], "out" => [ "fp" ] },
   "emit"      => '. movs%M %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */'
 },
@@ -533,6 +523,7 @@ $arch = "ia32";
   "op_flags" => "L|F",
   "state"    => "exc_pinned",
   "comment"  => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
   "reg_req"  => { "in" => [ "gp", "gp", "fp", "none" ] },
   "emit"     => '. movs%M %ia32_emit_am, %S3\t\t\t/* Store(%S3) -> (%A1) */'
 },
@@ -540,34 +531,18 @@ $arch = "ia32";
 # CopyB
 
 "CopyB" => {
-       "op_flags" => "F|H",
-       "state"    => "pinned",
-       "comment"  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
-       "reg_req"  => { "in" => [ "edi", "esi", "ecx", "none" ], "out" => [ "none" ] },
+  "op_flags" => "F|H",
+  "state"    => "pinned",
+  "comment"  => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
+  "reg_req"  => { "in" => [ "edi", "esi", "ecx", "none" ], "out" => [ "none" ] },
 },
 
 "CopyB_i" => {
-       "op_flags" => "F|H",
-       "state"    => "pinned",
-       "comment"  => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
-       "reg_req"  => { "in" => [ "edi", "esi", "none" ], "out" => [ "none" ] },
-},
-
-# Call
-
-"Call" => {
-  "op_flags" => "L|F",
-  "state"    => "mem_pinned",
-  "arity"    => "variable",
-  "comment"  => "construct Call: Call(...)",
-  "args"     => [
-                  { "type" => "int",        "name" => "n" },
-                  { "type" => "ir_node **", "name" => "in" }
-                ],
-  "rd_constructor" =>
-"  if (!op_ia32_Call) assert(0);
-  return new_ir_node(db, irg, block, op_ia32_Call, mode_T, n, in);
-"
+  "op_flags" => "F|H",
+  "state"    => "pinned",
+  "comment"  => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
+  "cmp_attr"  => "  return ia32_compare_immop_attr(attr_a, attr_b);\n",
+  "reg_req"  => { "in" => [ "edi", "esi", "none" ], "out" => [ "none" ] },
 },
 
 ); # end of %nodes
index b73b359..1091475 100644 (file)
@@ -145,19 +145,17 @@ static char *gen_fp_known_const(ir_mode *mode, ia32_known_const_t kct) {
 }
 
 
-#undef is_cnst
-#define is_cnst(op) (is_ia32_Const(op) || is_ia32_fConst(op))
 
 /* determine if one operator is an Imm */
 static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
        if (op1)
-               return is_cnst(op1) ? op1 : (is_cnst(op2) ? op2 : NULL);
-       else return is_cnst(op2) ? op2 : NULL;
+               return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
+       else return is_ia32_Cnst(op2) ? op2 : NULL;
 }
 
 /* determine if one operator is not an Imm */
 static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
-       return !is_cnst(op1) ? op1 : (!is_cnst(op2) ? op2 : NULL);
+       return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
 }
 
 
@@ -231,6 +229,10 @@ static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2,
                }
        }
 
+       if (is_op_commutative(get_irn_op(env->irn))) {
+               set_ia32_commutative(new_op);
+       }
+
        return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
 }
 
@@ -1106,6 +1108,8 @@ static ir_node *gen_Load(ia32_transform_env_t *env) {
        }
 
        set_ia32_am_support(new_op, ia32_am_Source);
+       set_ia32_op_type(new_op, ia32_AddrModeS);
+       set_ia32_am_flavour(new_op, ia32_B);
        set_ia32_ls_mode(new_op, get_Load_mode(node));
 
        return new_op;
@@ -1125,17 +1129,33 @@ static ir_node *gen_Load(ia32_transform_env_t *env) {
 static ir_node *gen_Store(ia32_transform_env_t *env) {
        ir_node *node  = env->irn;
        ir_node *noreg = ia32_new_NoReg_gp(env->cg);
+       ir_node *val   = get_Store_value(node);
+       ir_node *ptr   = get_Store_ptr(node);
+       ir_node *mem   = get_Store_mem(node);
+       ir_node *sval  = val;
        ir_node *new_op;
 
+       /* in case of storing a const -> make it an attribute */
+       if (is_ia32_Cnst(val)) {
+               sval = noreg;
+       }
+
        if (mode_is_float(env->mode)) {
-               new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, get_Store_ptr(node), noreg, get_Store_value(node), get_Store_mem(node), env->mode);
+               new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, env->mode);
        }
        else {
-               new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, get_Store_ptr(node), noreg, get_Store_value(node), get_Store_mem(node), env->mode);
+               new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, env->mode);
+       }
+
+       /* stored const is an attribute (saves a register) */
+       if (is_ia32_Cnst(val)) {
+               set_ia32_Immop_attr(new_op, val);
        }
 
        set_ia32_am_support(new_op, ia32_am_Dest);
-       set_ia32_ls_mode(new_op, get_irn_mode(get_Store_value(node)));
+       set_ia32_op_type(new_op, ia32_AddrModeD);
+       set_ia32_am_flavour(new_op, ia32_B);
+       set_ia32_ls_mode(new_op, get_irn_mode(val));
        return new_op;
 }