use own mode for fpcw, fix constants for shift, xmm const assembler
authorMatthias Braun <matze@braunis.de>
Thu, 19 Apr 2007 15:43:25 +0000 (15:43 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 19 Apr 2007 15:43:25 +0000 (15:43 +0000)
[r13422]

ir/be/ia32/bearch_ia32.c
ir/be/ia32/bearch_ia32_t.h
ir/be/ia32/ia32_new_nodes.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c
ir/be/ia32/ia32_x87.c

index db79116..2c24f29 100644 (file)
@@ -65,6 +65,8 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 /* TODO: ugly */
 static set *cur_reg_set = NULL;
 
+ir_mode *mode_fpcw = NULL;
+
 typedef ir_node *(*create_const_node_func) (dbg_info *dbg, ir_graph *irg, ir_node *block);
 
 static INLINE ir_node *create_const(ia32_code_gen_t *cg, ir_node **place,
@@ -1510,6 +1512,10 @@ static void *ia32_init(FILE *file_handle) {
        isa = xmalloc(sizeof(*isa));
        memcpy(isa, &ia32_isa_template, sizeof(*isa));
 
+       if(mode_fpcw == NULL) {
+               mode_fpcw = new_ir_mode("Fpcw", irms_int_number, 16, 0, irma_none, 0);
+       }
+
        ia32_register_init(isa);
        ia32_create_opcodes();
        ia32_register_copy_attr_func();
index 947eba1..e46d711 100644 (file)
@@ -151,6 +151,9 @@ typedef struct _ia32_intrinsic_env_t {
        ir_entity *d_ll_conv;     /**< entity for converts d -> ll */
 } ia32_intrinsic_env_t;
 
+/** mode for the floating point control word */
+extern ir_mode *mode_fpcw;
+
 /**
  * Returns the unique per irg GP NoReg node.
  */
index f998087..a6d4add 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "../bearch_t.h"
 
+#include "bearch_ia32_t.h"
 #include "ia32_nodes_attr.h"
 #include "ia32_new_nodes.h"
 #include "gen_ia32_regalloc_if.h"
index 05cdfc7..6c1cfc3 100644 (file)
@@ -160,7 +160,7 @@ $arch = "ia32";
        ],
        fp_cw => [      # the floating point control word
                { name => "fpcw", type => 4 | 32},
-               { mode => "mode_Hu" }
+               { mode => "mode_fpcw" }
        ],
        flags => [
                { name => "eflags", type => 4 },
@@ -288,6 +288,7 @@ $default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);";
 
 $mode_xmm     = "mode_E";
 $mode_gp      = "mode_Iu";
+$mode_fpcw    = "mode_fpcw";
 $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
 $fpcw_flags   = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
                   "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
@@ -568,9 +569,9 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) {
        }
 } else {
        if (get_ia32_op_type(node) == ia32_AddrModeD) {
-               . shldl $%C, %S4, %AM
+               . shldl %C, %S4, %AM
        } else {
-               . shldl $%C, %S4, %S3
+               . shldl %C, %S4, %S3
        }
 }
 ',
@@ -623,9 +624,9 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) {
        }
 } else {
        if (get_ia32_op_type(node) == ia32_AddrModeD) {
-               . shrdl $%C, %S4, %AM
+               . shrdl %C, %S4, %AM
        } else {
-               . shrdl $%C, %S4, %S3
+               . shrdl %C, %S4, %S3
        }
 }
 ',
@@ -871,7 +872,7 @@ ChangeCW => {
        irn_flags => "I",
        comment   => "change floating point control word",
        reg_req   => { out => [ "fp_cw" ] },
-       mode      => "mode_Hu",
+       mode      => $mode_fpcw,
        latency   => 3,
        units     => [ "GP" ],
        modified_flags => $fpcw_flags
@@ -884,7 +885,7 @@ FldCW => {
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] },
        latency   => 5,
        emit      => ". fldcw %AM",
-       mode      => "mode_Hu",
+       mode      => $mode_fpcw,
        units     => [ "GP" ],
        modified_flags => $fpcw_flags
 },
@@ -1178,7 +1179,7 @@ xConst => {
        irn_flags => "R",
        comment   => "represents a SSE constant",
        reg_req   => { out => [ "xmm" ] },
-       emit      => '. mov%XXM $%C, %D1',
+       emit      => '. mov%XXM %C, %D1',
        latency   => 2,
        units     => [ "SSE" ],
        mode      => "mode_E",
index 40c0cfd..0d8a35b 100644 (file)
@@ -108,6 +108,14 @@ static ir_node *transform_node(ia32_transform_env_t *env, ir_node *node);
 static void duplicate_deps(ia32_transform_env_t *env, ir_node *old_node,
                            ir_node *new_node);
 
+static INLINE int mode_needs_gp_reg(ir_mode *mode)
+{
+       if(mode == mode_fpcw)
+               return 0;
+
+       return mode_is_int(mode) || mode_is_character(mode) || mode_is_reference(mode);
+}
+
 static INLINE void set_new_node(ir_node *old_node, ir_node *new_node)
 {
        set_irn_link(old_node, new_node);
@@ -1812,7 +1820,7 @@ static ir_node *gen_Cond(ia32_transform_env_t *env, ir_node *node) {
                                pnc = get_inversed_pnc(pnc);
                        }
 
-                       if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) {
+                       if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_needs_gp_reg(get_irn_mode(expr))) {
                                if (get_ia32_immop_type(cnst) == ia32_ImmConst &&
                                        classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL)
                                {
@@ -2723,7 +2731,7 @@ static ir_node *gen_Unknown(ia32_transform_env_t *env, ir_node *node) {
                        return ia32_new_Unknown_xmm(env->cg);
                else
                        return ia32_new_Unknown_vfp(env->cg);
-       } else if (mode_is_int(mode) || mode_is_reference(mode)) {
+       } else if (mode_needs_gp_reg(mode)) {
                return ia32_new_Unknown_gp(env->cg);
        } else {
                assert(0 && "unsupported Unknown-Mode");
@@ -2743,7 +2751,7 @@ static ir_node *gen_Phi(ia32_transform_env_t *env, ir_node *node) {
        ir_node *phi;
        int i, arity;
 
-       if(mode_is_int(mode) || mode_is_reference(mode)) {
+       if(mode_needs_gp_reg(mode)) {
                // we shouldn't have any 64bit stuff around anymore
                assert(get_mode_size_bits(mode) <= 32);
                // all integer operations are on 32bit registers now
@@ -3655,7 +3663,7 @@ static ir_node *gen_Proj(ia32_transform_env_t *env, ir_node *node) {
                ir_node *new_pred = transform_node(env, pred);
                ir_node *block    = transform_node(env, get_nodes_block(node));
                ir_mode *mode     = get_irn_mode(node);
-               if (mode_is_signed(mode) || mode_is_reference(mode)) {
+               if (mode_needs_gp_reg(mode)) {
                        return new_r_Proj(irg, block, new_pred, mode_Iu, get_Proj_proj(node));
                }
        }
index ac1d0d3..8291626 100644 (file)
@@ -1671,9 +1671,13 @@ static int sim_Copy(x87_state *state, ir_node *n) {
                } else {
                        /* just a virtual copy */
                        x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
+                       /* don't remove the node to keep the verifier quiet :),
+                          the emitter won't emit any code for the node */
+#if 0
                        sched_remove(n);
                        DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n)));
                        exchange(n, get_unop_op(n));
+#endif
                }
        }