addressmode for compares works now
authorMatthias Braun <matze@braunis.de>
Thu, 28 Jun 2007 22:27:32 +0000 (22:27 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 28 Jun 2007 22:27:32 +0000 (22:27 +0000)
[r14832]

ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_optimize.c
ir/be/ia32/ia32_transform.c

index 774f255..bcfa973 100644 (file)
@@ -804,6 +804,15 @@ static int ia32_possible_memory_operand(const void *self, const ir_node *irn, un
        return 1;
 }
 
+static void exchange_left_right(ir_node *node)
+{
+       ir_node *tmp = get_irn_n(node, 3);
+       set_irn_n(node, 3, get_irn_n(node, 2));
+       set_irn_n(node, 2, tmp);
+
+       set_ia32_pncode(node, get_inversed_pnc(get_ia32_pncode(node)));
+}
+
 static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node *spill, unsigned int i) {
        const ia32_irn_ops_t *ops = self;
        ia32_code_gen_t      *cg  = ops->cg;
@@ -811,9 +820,7 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node
        assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
 
        if (i == 2) {
-               ir_node *tmp = get_irn_n(irn, 3);
-               set_irn_n(irn, 3, get_irn_n(irn, 2));
-               set_irn_n(irn, 2, tmp);
+               exchange_left_right(irn);
        }
 
        set_ia32_op_type(irn, ia32_AddrModeS);
@@ -826,7 +833,10 @@ static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node
        set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
        set_irn_n(irn, 4, spill);
 
-       //FIXME DBG_OPT_AM_S(reload, irn);
+       /* immediates are only allowed on the right side */
+       if(i == 2 && is_ia32_Immediate(get_irn_n(irn, 2))) {
+               exchange_left_right(irn);
+       }
 }
 
 static const be_abi_callbacks_t ia32_abi_callbacks = {
index ca08ba6..0ed60ca 100644 (file)
@@ -401,11 +401,10 @@ void emit_ia32_Immediate(ia32_emit_env_t *env, const ir_node *node);
  */
 void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
        int            right_pos;
-       const ir_node *right_op;
+       const ir_node *right_op = get_irn_n(node, 3);
 
        switch(get_ia32_op_type(node)) {
        case ia32_Normal:
-               right_op = get_irn_n(node, 3);
                if(is_ia32_Immediate(right_op)) {
                        emit_ia32_Immediate(env, right_op);
                        be_emit_cstring(env, ", ");
@@ -438,19 +437,31 @@ void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
                }
                break;
        case ia32_AddrModeS:
-               ia32_emit_am(env, node);
-               be_emit_cstring(env, ", ");
                if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
-                       assert(!produces_result(node) && "Source AM with Const must not produce result");
+                       assert(!produces_result(node) &&
+                                       "Source AM with Const must not produce result");
                        ia32_emit_immediate(env, node);
+                       be_emit_cstring(env, ", ");
+                       ia32_emit_am(env, node);
+               } else if(is_ia32_Immediate(right_op)) {
+                       assert(!produces_result(node) &&
+                                       "Source AM with Const must not produce result");
+
+                       emit_ia32_Immediate(env, right_op);
+                       be_emit_cstring(env, ", ");
+                       ia32_emit_am(env, node);
                } else if (produces_result(node)) {
+                       ia32_emit_am(env, node);
+                       be_emit_cstring(env, ", ");
                        ia32_emit_dest_register(env, node, 0);
                } else {
+                       ia32_emit_am(env, node);
+                       be_emit_cstring(env, ", ");
                        ia32_emit_source_register(env, node, 2);
                }
                break;
        case ia32_AddrModeD:
-               right_pos = get_irn_arity(node) == 5 ? 3 : 2;
+               right_pos = get_irn_arity(node) >= 5 ? 3 : 2;
                right_op  = get_irn_n(node, right_pos);
                if(is_ia32_Immediate(right_op)) {
                        emit_ia32_Immediate(env, right_op);
@@ -821,7 +832,9 @@ void finish_CondJmp(ia32_emit_env_t *env, const ir_node *node, ir_mode *mode,
  */
 static
 void CondJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
-       be_emit_cstring(env, "\tcmp ");
+       be_emit_cstring(env, "\tcmp");
+       ia32_emit_mode_suffix(env, node);
+       be_emit_char(env, ' ');
        ia32_emit_binop(env, node);
        be_emit_finish_line_gas(env, node);
 
@@ -841,7 +854,10 @@ void emit_ia32_CondJmp(ia32_emit_env_t *env, const ir_node *node) {
  */
 static
 void TestJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
-       be_emit_cstring(env, "\ttest ");
+       be_emit_cstring(env, "\ttest");
+       ia32_emit_mode_suffix(env, node);
+       be_emit_char(env, ' ');
+
        ia32_emit_binop(env, node);
        be_emit_finish_line_gas(env, node);
 
index 50cd0c8..ffbe8df 100644 (file)
@@ -1135,7 +1135,9 @@ static void merge_loadstore_lea(ir_node *irn, ir_node *lea) {
  * Sets new_right index of irn to right and new_left index to left.
  * Also exchange left and right
  */
-static void exchange_left_right(ir_node *irn, ir_node **left, ir_node **right, int new_left, int new_right) {
+static void exchange_left_right(ir_node *irn, ir_node **left, ir_node **right,
+                                int new_left, int new_right)
+{
        ir_node *temp;
 
        set_irn_n(irn, new_right, *right);
@@ -1178,7 +1180,7 @@ static void optimize_lea(ia32_code_gen_t *cg, ir_node *irn) {
                        DB((dbg, LEVEL_1, "transformed into %+F\n", res));
                else
                        DB((dbg, LEVEL_1, "not transformed\n"));
-       } else if (is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn)) {
+       } else if (is_ia32_Ld(irn) || is_ia32_St(irn)) {
                /* - Load  -> LEA into Load  } TODO: If the LEA is used by more than one Load/Store */
                /* - Store -> LEA into Store }       it might be better to keep the LEA             */
                ir_node *left = get_irn_n(irn, 0);
@@ -1191,7 +1193,7 @@ static void optimize_lea(ia32_code_gen_t *cg, ir_node *irn) {
                        foreach_out_edge_safe(left, edge, ne) {
                                src = get_edge_src_irn(edge);
 
-                               if (src && (get_edge_src_pos(edge) == 0) && (is_ia32_Ld(src) || is_ia32_St(src) || is_ia32_Store8Bit(src))) {
+                               if (src && (get_edge_src_pos(edge) == 0) && (is_ia32_Ld(src) || is_ia32_St(src))) {
                                        DBG((dbg, LEVEL_1, "\nmerging %+F into %+F\n", left, irn));
                                        if (! is_ia32_got_lea(src))
                                                merge_loadstore_lea(src, left);
@@ -1345,7 +1347,7 @@ static void optimize_am(ir_node *irn, void *env) {
                &dest_out_reg_req_0
        };
 
-       if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn))
+       if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn))
                return;
        if (is_ia32_Lea(irn))
                return;
@@ -1623,6 +1625,11 @@ static void optimize_am(ir_node *irn, void *env) {
                }
                need_exchange_on_fail = 0;
 
+               /* immediates are only allowed on the right side */
+               if(is_ia32_Immediate(left)) {
+                       exchange_left_right(irn, &left, &right, 3, 2);
+               }
+
                DB((dbg, LEVEL_1, "merged with %+F into source AM\n", load));
        }
 
index 644bffa..e15582d 100644 (file)
@@ -1745,6 +1745,7 @@ static ir_node *try_create_TestJmp(ir_node *block, ir_node *node, long pnc)
 
        res = new_rd_ia32_TestJmp(dbgi, current_ir_graph, block, noreg, noreg,
                                  new_cmp_a, new_cmp_b, nomem, pnc);
+       set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
        SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
 
        return res;
@@ -1853,11 +1854,7 @@ static ir_node *gen_Cond(ir_node *node) {
                set_ia32_commutative(res);
        }
 
-       // Matze: disabled for now, because the default collect_spills_walker
-       // is not able to detect the mode of the spilled value
-       // moreover, the lea optimize phase freely exchanges left/right
-       // without updating the pnc
-       //set_ia32_am_support(res, ia32_am_Source | ia32_am_binary);
+       set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
 
        SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));