reimplement the long long -> double, conversion. Removed broken double -> long long...
authorMatthias Braun <matze@braunis.de>
Mon, 17 Dec 2007 18:27:46 +0000 (18:27 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 17 Dec 2007 18:27:46 +0000 (18:27 +0000)
[r17007]

ir/be/ia32/ia32_intrinsics.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c

index 7abb56d..fa07a9f 100644 (file)
@@ -682,6 +682,8 @@ static int map_Conv(ir_node *call, void *ctx) {
        ir_node   *op_mem[2], *mem;
 
        if (n == 1) {
+               ir_node *float_to_ll;
+
                /* We have a Conv float -> long long here */
                ir_node *a_f        = params[0];
                ir_mode *l_res_mode = get_type_mode(get_method_res_type(method, 0));
@@ -689,60 +691,18 @@ static int map_Conv(ir_node *call, void *ctx) {
 
                assert(mode_is_float(get_irn_mode(a_f)) && "unexpected Conv call");
 
-               /* allocate memory on frame to store args */
-               ent = env->irg == irg ? env->d_ll_conv : NULL;
-               if (! ent) {
-                       ent      = env->d_ll_conv = frame_alloc_area(get_irg_frame_type(irg), 2 * gp_bytes, 16, 0);
-                       env->irg = irg;
-               }
+               float_to_ll = new_rd_ia32_l_FloattoLL(dbg, irg, block, a_f);
 
-               /* Store arg */
-               frame = get_irg_frame(irg);
-
-               /*
-                       Now we create a node to move the value from a XMM register into
-                       x87 FPU because it is unknown here, which FPU is used.
-                       This node is killed in transformation phase when not needed.
-                       Otherwise it is split up into a movsd + fld
-               */
-               a_f = new_rd_ia32_l_SSEtoX87(dbg, irg, block, frame, a_f, get_irg_no_mem(irg), mode_D);
-               set_ia32_frame_ent(a_f, ent);
-               set_ia32_use_frame(a_f);
-               set_ia32_ls_mode(a_f, mode_D);
-
-               if (mode_is_signed(h_res_mode)) {
-                       /* a float to signed conv, the simple case */
-
-                       /* store from FPU as Int */
-                       a_f = new_rd_ia32_l_vfist(dbg, irg, block, frame, a_f, get_irg_no_mem(irg));
-                       set_ia32_frame_ent(a_f, ent);
-                       set_ia32_use_frame(a_f);
-                       set_ia32_ls_mode(a_f, mode_Ls);
-                       mem = a_f;
-
-                       /* load low part of the result */
-                       l_res = new_rd_ia32_l_Load(dbg, irg, block, frame, mem);
-                       set_ia32_frame_ent(l_res, ent);
-                       set_ia32_use_frame(l_res);
-                       set_ia32_ls_mode(l_res, l_res_mode);
-                       l_res = new_r_Proj(irg, block, l_res, l_res_mode, pn_ia32_l_Load_res);
-
-                       /* load hight part of the result */
-                       h_res = new_rd_ia32_l_Load(dbg, irg, block, frame, mem);
-                       set_ia32_frame_ent(h_res, ent);
-                       add_ia32_am_offs_int(h_res, gp_bytes);
-                       set_ia32_use_frame(h_res);
-                       set_ia32_ls_mode(h_res, h_res_mode);
-                       h_res = new_r_Proj(irg, block, h_res, h_res_mode, pn_ia32_l_Load_res);
-               } else {
-                       /* a float to unsigned conv, more complicated */
-                       panic("Float->unsigned64 NYI\n");
-               }
+               l_res = new_r_Proj(irg, block, float_to_ll, l_res_mode,
+                                  pn_ia32_l_FloattoLL_res_low);
+               h_res = new_r_Proj(irg, block, float_to_ll, h_res_mode,
+                                  pn_ia32_l_FloattoLL_res_high);
 
                /* lower the call */
                resolve_call(call, l_res, h_res, irg, block);
-       }
-       else if (n == 2) {
+       } else if (n == 2) {
+               ir_node *ll_to_float;
+
                /* We have a Conv long long -> float here */
                ir_node *a_l       = params[BINOP_Left_Low];
                ir_node *a_h       = params[BINOP_Left_High];
@@ -751,57 +711,13 @@ static int map_Conv(ir_node *call, void *ctx) {
                assert(! mode_is_float(get_irn_mode(a_l))
                                && ! mode_is_float(get_irn_mode(a_h)));
 
-               /* allocate memory on frame to store args */
-               ent = env->irg == irg ? env->ll_d_conv : NULL;
-               if (! ent) {
-                       ent = env->ll_d_conv = frame_alloc_area(get_irg_frame_type(irg), 2 * gp_bytes, 16, 0);
-                       env->irg = irg;
-               }
-
-               /* Store arg */
-               frame = get_irg_frame(irg);
-
-               /* store first arg (low part) */
-               store_l   = new_rd_ia32_l_Store(dbg, irg, block, frame, a_l, get_irg_no_mem(irg));
-               set_ia32_frame_ent(store_l, ent);
-               set_ia32_use_frame(store_l);
-               set_ia32_ls_mode(store_l, get_irn_mode(a_l));
-               op_mem[0] = store_l;
-
-               /* store second arg (high part) */
-               store_h   = new_rd_ia32_l_Store(dbg, irg, block, frame, a_h, get_irg_no_mem(irg));
-               set_ia32_frame_ent(store_h, ent);
-               add_ia32_am_offs_int(store_h, gp_bytes);
-               set_ia32_use_frame(store_h);
-               set_ia32_ls_mode(store_h, get_irn_mode(a_h));
-               op_mem[1] = store_h;
-
-               mem = new_r_Sync(irg, block, 2, op_mem);
-
-               /* Load arg into x87 FPU (implicit convert) */
-               fres = new_rd_ia32_l_vfild(dbg, irg, block, frame, mem);
-               set_ia32_frame_ent(fres, ent);
-               set_ia32_use_frame(fres);
-               set_ia32_ls_mode(fres, mode_D);
-               mem  = new_r_Proj(irg, block, fres, mode_M, pn_ia32_l_vfild_M);
-               fres = new_r_Proj(irg, block, fres, fres_mode, pn_ia32_l_vfild_res);
-
-               /*
-                       Now we create a node to move the loaded value into a XMM
-                       register because it is unknown here, which FPU is used.
-                       This node is killed in transformation phase when not needed.
-                       Otherwise it is split up into a fst + movsd
-               */
-               fres = new_rd_ia32_l_X87toSSE(dbg, irg, block, frame, fres, mem, fres_mode);
-               set_ia32_frame_ent(fres, ent);
-               set_ia32_use_frame(fres);
-               set_ia32_ls_mode(fres, fres_mode);
+               ll_to_float = new_rd_ia32_l_LLtoFloat(dbg, irg, block, a_h, a_l,
+                                                     fres_mode);
 
                /* lower the call */
-               resolve_call(call, fres, NULL, irg, block);
-       }
-       else {
-               assert(0 && "unexpected Conv call");
+               resolve_call(call, ll_to_float, NULL, irg, block);
+       } else {
+               panic("unexpected Conv call %+F", call);
        }
 
        return 1;
index 05aeef4..9ee0999 100644 (file)
@@ -1637,16 +1637,17 @@ CvtSI2SD => {
 },
 
 
-l_X87toSSE => {
+l_LLtoFloat => {
        op_flags => "L|F",
        cmp_attr => "return 1;",
-       arity    => 3,
+       ins      => [ "val_high", "val_low" ],
 },
 
-l_SSEtoX87 => {
+l_FloattoLL => {
        op_flags => "L|F",
        cmp_attr => "return 1;",
-       arity    => 3,
+       ins      => [ "val" ],
+       outs     => [ "res_high", "res_low" ],
 },
 
 # CopyB
index a70c52e..ead958c 100644 (file)
@@ -4169,104 +4169,63 @@ static ir_node *gen_ia32_l_ShrD(ir_node *node)
        return gen_lowered_64bit_shifts(node, high, low, count);
 }
 
-/**
- * In case SSE Unit is used, the node is transformed into a vfst + xLoad.
- */
-static ir_node *gen_ia32_l_X87toSSE(ir_node *node) {
-       ir_node         *block   = be_transform_node(get_nodes_block(node));
-       ir_node         *val     = get_irn_n(node, 1);
-       ir_node         *new_val = be_transform_node(val);
-       ir_node         *res     = NULL;
-       ir_graph        *irg     = current_ir_graph;
-       dbg_info        *dbgi;
-       ir_node         *noreg, *new_ptr, *new_mem;
-       ir_node         *ptr, *mem;
+static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
+       ir_node  *src_block    = get_nodes_block(node);
+       ir_node  *block        = be_transform_node(src_block);
+       ir_graph *irg          = current_ir_graph;
+       dbg_info *dbgi         = get_irn_dbg_info(node);
+       ir_node  *frame        = get_irg_frame(irg);
+       ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
+       ir_node  *nomem        = new_NoMem();
+       ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
+       ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
+       ir_node  *new_val_low  = be_transform_node(val_low);
+       ir_node  *new_val_high = be_transform_node(val_high);
+       ir_node  *in[2];
+       ir_node  *sync;
+       ir_node  *fild;
+       ir_node  *store_low;
+       ir_node  *store_high;
 
-       if (ia32_cg_config.use_sse2) {
-               return new_val;
+       if(!mode_is_signed(get_irn_mode(val_high))) {
+               panic("unsigned long long -> float not supported yet (%+F)", node);
        }
 
-       mem     = get_irn_n(node, 2);
-       new_mem = be_transform_node(mem);
-       ptr     = get_irn_n(node, 0);
-       new_ptr = be_transform_node(ptr);
-       noreg   = ia32_new_NoReg_gp(env_cg);
-       dbgi    = get_irn_dbg_info(node);
-
-       /* Store x87 -> MEM */
-       res = new_rd_ia32_vfst(dbgi, irg, block, new_ptr, noreg, new_mem, new_val,
-                              get_ia32_ls_mode(node));
-       set_ia32_frame_ent(res, get_ia32_frame_ent(node));
-       set_ia32_use_frame(res);
-       set_ia32_ls_mode(res, get_ia32_ls_mode(node));
-       set_ia32_op_type(res, ia32_AddrModeD);
-
-       /* Load MEM -> SSE */
-       res = new_rd_ia32_xLoad(dbgi, irg, block, new_ptr, noreg, res,
-                               get_ia32_ls_mode(node));
-       set_ia32_frame_ent(res, get_ia32_frame_ent(node));
-       set_ia32_use_frame(res);
-       set_ia32_op_type(res, ia32_AddrModeS);
-       res = new_rd_Proj(dbgi, irg, block, res, mode_xmm, pn_ia32_xLoad_res);
+       /* do a store */
+       store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
+                                     new_val_low);
+       store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
+                                      new_val_high);
+       SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
+       SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
+
+       set_ia32_use_frame(store_low);
+       set_ia32_use_frame(store_high);
+       set_ia32_op_type(store_low, ia32_AddrModeD);
+       set_ia32_op_type(store_high, ia32_AddrModeD);
+       set_ia32_ls_mode(store_low, mode_Iu);
+       set_ia32_ls_mode(store_high, mode_Is);
+       add_ia32_am_offs_int(store_high, 4);
+
+       in[0] = store_low;
+       in[1] = store_high;
+       sync  = new_rd_Sync(dbgi, irg, block, 2, in);
 
-       return res;
-}
+       /* do a fild */
+       fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
 
-/**
- * In case SSE Unit is used, the node is transformed into a xStore + vfld.
- */
-static ir_node *gen_ia32_l_SSEtoX87(ir_node *node) {
-       ir_node         *block   = be_transform_node(get_nodes_block(node));
-       ir_node         *val     = get_irn_n(node, 1);
-       ir_node         *new_val = be_transform_node(val);
-       ir_graph        *irg     = current_ir_graph;
-       ir_node         *res     = NULL;
-       ir_entity       *fent    = get_ia32_frame_ent(node);
-       ir_mode         *lsmode  = get_ia32_ls_mode(node);
-       int             offs     = 0;
-       ir_node         *noreg, *new_ptr, *new_mem;
-       ir_node         *ptr, *mem;
-       dbg_info        *dbgi;
-
-       if (! ia32_cg_config.use_sse2) {
-               /* SSE unit is not used -> skip this node. */
-               return new_val;
-       }
+       set_ia32_use_frame(fild);
+       set_ia32_op_type(fild, ia32_AddrModeS);
+       set_ia32_ls_mode(fild, mode_Ls);
 
-       ptr     = get_irn_n(node, 0);
-       new_ptr = be_transform_node(ptr);
-       mem     = get_irn_n(node, 2);
-       new_mem = be_transform_node(mem);
-       noreg   = ia32_new_NoReg_gp(env_cg);
-       dbgi    = get_irn_dbg_info(node);
-
-       /* Store SSE -> MEM */
-       if (is_ia32_xLoad(skip_Proj(new_val))) {
-               ir_node *ld = skip_Proj(new_val);
-
-               /* we can vfld the value directly into the fpu */
-               fent = get_ia32_frame_ent(ld);
-               ptr  = get_irn_n(ld, 0);
-               offs = get_ia32_am_offs_int(ld);
-       } else {
-               res = new_rd_ia32_xStore(dbgi, irg, block, new_ptr, noreg, new_mem,
-                                        new_val);
-               set_ia32_frame_ent(res, fent);
-               set_ia32_use_frame(res);
-               set_ia32_ls_mode(res, lsmode);
-               set_ia32_op_type(res, ia32_AddrModeD);
-               mem = res;
-       }
+       SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
 
-       /* Load MEM -> x87 */
-       res = new_rd_ia32_vfld(dbgi, irg, block, new_ptr, noreg, new_mem, lsmode);
-       set_ia32_frame_ent(res, fent);
-       set_ia32_use_frame(res);
-       add_ia32_am_offs_int(res, offs);
-       set_ia32_op_type(res, ia32_AddrModeS);
-       res = new_rd_Proj(dbgi, irg, block, res, mode_vfp, pn_ia32_vfld_res);
+       return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
+}
 
-       return res;
+static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
+       (void) node;
+       panic("LLtoFloat NIY");
 }
 
 /**
@@ -4779,8 +4738,8 @@ static void register_transformers(void)
        GEN(ia32_l_Load);
        GEN(ia32_l_vfist);
        GEN(ia32_l_Store);
-       GEN(ia32_l_X87toSSE);
-       GEN(ia32_l_SSEtoX87);
+       GEN(ia32_l_LLtoFloat);
+       GEN(ia32_l_FloattoLL);
 
        GEN(Const);
        GEN(SymConst);