removed some unncessary nodes (Stackparam, return, etc.)
authorChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Fri, 3 Mar 2006 12:25:04 +0000 (12:25 +0000)
committerChristian Würdig <chriswue@ipd.info.uni-karlsruhe.de>
Fri, 3 Mar 2006 12:25:04 +0000 (12:25 +0000)
added CopyB and CMov (Mux) nodes

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

index 3e377a2..78b5043 100644 (file)
@@ -699,6 +699,59 @@ void emit_Proj(ir_node *irn, emit_env_t *env) {
        }
 }
 
        }
 }
 
+/**********************************
+ *   _____                  ____
+ *  / ____|                |  _ \
+ * | |     ___  _ __  _   _| |_) |
+ * | |    / _ \| '_ \| | | |  _ <
+ * | |___| (_) | |_) | |_| | |_) |
+ *  \_____\___/| .__/ \__, |____/
+ *             | |     __/ |
+ *             |_|    |___/
+ **********************************/
+
+static void emit_CopyB_prolog(FILE *F, int rem, int size) {
+       fprintf(F, "\t/* memcopy %d bytes*/\n", size);
+       fprintf(F, "\tcld\t\t\t\t/* copy direction forward*/\n");
+
+       switch(rem) {
+               case 1:
+                       fprintf(F, "\tmovsb\t\t\t\t/* memcopy remainder 1 */\n");
+                       break;
+               case 2:
+                       fprintf(F, "\tmovsw\t\t\t\t/* memcopy remainder 2 */\n");
+                       break;
+               case 3:
+                       fprintf(F, "\tmovsb\t\t\t\t/* memcopy remainder 3 */\n");
+                       fprintf(F, "\tmovsw\t\t\t\t/* memcopy remainder 3 */\n");
+                       break;
+       }
+}
+
+void emit_ia32_CopyB(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);
+       int     size = get_tarval_long(get_ia32_Immop_tarval(get_irn_n(irn, 2)));
+
+       emit_CopyB_prolog(F, rem, size);
+
+       fprintf(F, "\trep movsd\t\t\t\t/* memcopy */\n");
+}
+
+void emit_ia32_CopyB_i(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;
+
+       emit_CopyB_prolog(F, size & 0x3, size);
+
+       size >>= 2;
+       while (size--) {
+               fprintf(F, "\tmovsd\t\t\t\t/* memcopy unrolled */\n");
+       }
+}
+
 /********************
  *   _____      _ _
  *  / ____|    | | |
 /********************
  *   _____      _ _
  *  / ____|    | | |
@@ -748,6 +801,7 @@ void ia32_emit_node(ir_node *irn, void *env) {
 
        IA32_EMIT(Max);
        IA32_EMIT(Min);
 
        IA32_EMIT(Max);
        IA32_EMIT(Min);
+       IA32_EMIT(CMov);
 
        IA32_EMIT(And);
        IA32_EMIT(Or);
 
        IA32_EMIT(And);
        IA32_EMIT(Or);
@@ -770,6 +824,9 @@ void ia32_emit_node(ir_node *irn, void *env) {
        IA32_EMIT(Store);
        IA32_EMIT(Load);
 
        IA32_EMIT(Store);
        IA32_EMIT(Load);
 
+       IA32_EMIT(CopyB);
+       IA32_EMIT(CopyB_i);
+
        /* generated floating point emitter */
        IA32_EMIT(fConst);
 
        /* generated floating point emitter */
        IA32_EMIT(fConst);
 
index 353e617..04c4b08 100644 (file)
@@ -22,6 +22,8 @@ $arch = "ia32";
 #                    ...
 #                  ],
 #   "comment"   => "any comment for constructor",
 #                    ...
 #                  ],
 #   "comment"   => "any comment for constructor",
+#   "reg_req"   => { "in" => [ "reg_class|register" ], "out" => [ "reg_class|register|in_rX" ] },
+#   "cmp_attr"  => "c source code for comparing node attributes",
 #   "emit"      => "emit code with templates",
 #   "rd_constructor" => "c source code which constructs an ir_node"
 # },
 #   "emit"      => "emit code with templates",
 #   "rd_constructor" => "c source code which constructs an ir_node"
 # },
@@ -217,6 +219,16 @@ $arch = "ia32";
 '
 },
 
 '
 },
 
+"CMov" => {
+  "irn_flags" => "R",
+  "comment"   => "construct Mux: Mux(sel, a, b) == sel ? a : b",
+  "reg_req"   => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r2" ] },
+  "emit"      =>
+'. cmp %S1, 0\t\t\t/* compare Sel for CMov (%A2, %A3) */
+. cmovne %D1, %S3\t\t\t/* sel == true -> return %S3 */
+'
+},
+
 # not commutative operations
 
 "Sub" => {
 # not commutative operations
 
 "Sub" => {
@@ -387,27 +399,6 @@ $arch = "ia32";
   "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 << %C + %O, (%A1, %A2) */'
 },
 
-"StackParam" => {
-  "arity"    => 1,
-  "remat"    => 1,
-  "comment"  => "constructs a Stack Parameter to retrieve a parameter from Stack",
-  "reg_req"  => { "in" => [ "none" ], "out" => [ "gp" ] },
-  "cmp_attr" =>
-'
-  return (attr_a->pn_code != attr_b->pn_code);
-'
-},
-
-"StackArg" => {
-  "arity"    => 2,
-  "comment"  => "constructs a Stack Argument to pass an argument on Stack",
-  "reg_req"  => { "in" => [ "none", "gp" ], "out" => [ "none" ] },
-  "cmp_attr" =>
-'
-  return (attr_a->pn_code != attr_b->pn_code);
-'
-},
-
 #--------------------------------------------------------#
 #    __ _             _                     _            #
 #   / _| |           | |                   | |           #
 #--------------------------------------------------------#
 #    __ _             _                     _            #
 #   / _| |           | |                   | |           #
@@ -546,25 +537,20 @@ $arch = "ia32";
   "emit"     => '. movs%M %ia32_emit_am, %S3\t\t\t/* Store(%S3) -> (%A1) */'
 },
 
   "emit"     => '. movs%M %ia32_emit_am, %S3\t\t\t/* Store(%S3) -> (%A1) */'
 },
 
-"fStackParam" => {
-  "arity"    => 1,
-  "remat"    => 1,
-  "comment"  => "constructs a Stack Parameter to retrieve a SSE parameter from Stack",
-  "reg_req"  => { "in" => [ "none" ], "out" => [ "fp" ] },
-  "cmp_attr" =>
-'
-  return (attr_a->pn_code != attr_b->pn_code);
-'
+# 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" ] },
 },
 
 },
 
-"fStackArg" => {
-  "arity"    => 2,
-  "comment"  => "constructs a Stack Argument to pass an argument on Stack",
-  "reg_req"  => { "in" => [ "none", "fp" ], "out" => [ "none" ] },
-  "cmp_attr" =>
-'
-  return (attr_a->pn_code != attr_b->pn_code);
-'
+"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
@@ -584,31 +570,4 @@ $arch = "ia32";
 "
 },
 
 "
 },
 
-# Return
-
-"Return" => {
-  "op_flags" => "L|X",
-  "state"    => "pinned",
-  "arity"    => "variable",
-  "comment"  => "construct Return: Return(...)",
-  "args"     => [
-                  { "type" => "int",        "name" => "n" },
-                  { "type" => "ir_node **", "name" => "in" }
-                ],
-  "rd_constructor" =>
-"  if (!op_ia32_Return) assert(0);
-  return new_ir_node(db, irg, block, op_ia32_Return, mode_X, n, in);
-"
-},
-
-# M/Alloc
-
-"Alloca" => {
-  "op_flags" => "L|F",
-  "state"    => "pinned",
-  "arity"    => "2",
-  "comment"  => "construct Alloca: allocate memory on Stack",
-  "reg_req"  => { "in" => [ "gp" ], "out" => [ "gp" ] }
-},
-
 ); # end of %nodes
 ); # end of %nodes
index f7ed24c..2db63ee 100644 (file)
@@ -1202,6 +1202,64 @@ static ir_node *gen_Cond(ia32_transform_env_t *env) {
 
 
 
 
 
 
+/**
+ * Transforms a CopyB node.
+ *
+ * @param env   The transformation environment
+ * @return The transformed node.
+ */
+static ir_node *gen_CopyB(ia32_transform_env_t *env) {
+       ir_node  *res   = NULL;
+       dbg_info *dbg   = env->dbg;
+       ir_graph *irg   = env->irg;
+       ir_mode  *mode  = env->mode;
+       ir_node  *block = env->block;
+       ir_node  *node  = env->irn;
+       ir_node  *src   = get_CopyB_src(node);
+       ir_node  *dst   = get_CopyB_dst(node);
+       ir_node  *mem   = get_CopyB_mem(node);
+       ir_node  *noreg = ia32_new_NoReg_gp(env->cg);
+       int       size  = get_type_size_bytes(get_CopyB_type(node));
+       int       rem;
+
+       /* If we have to copy more than 16 bytes, we use REP MOVSx and */
+       /* then we need the size explicitly in ECX.                    */
+       if (size >= 16) {
+               rem = size & 0x3; /* size % 4 */
+               size >>= 2;
+
+               res = new_rd_ia32_Const(dbg, irg, block, mode_Is);
+               set_ia32_op_type(res, ia32_Const);
+               set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
+
+               res = new_rd_ia32_CopyB(dbg, irg, block, dst, src, res, mem, mode);
+               set_ia32_Immop_tarval(res, new_tarval_from_long(rem, mode_Is));
+       }
+       else {
+               res = new_rd_ia32_CopyB_i(dbg, irg, block, dst, src, mem, mode);
+               set_ia32_Immop_tarval(res, new_tarval_from_long(size, mode_Is));
+       }
+
+       return res;
+}
+
+
+
+/**
+ * Transforms a Mux node into CMov.
+ *
+ * @param env   The transformation environment
+ * @return The transformed node.
+ */
+static ir_node *gen_Mux(ia32_transform_env_t *env) {
+       ir_node  *node  = env->irn;
+
+       return new_rd_ia32_CMov(env->dbg, env->irg, env->block,
+               get_Mux_sel(node), get_Mux_false(node), get_Mux_true(node), env->mode);
+}
+
+
+
 /*********************************************************
  *                  _             _      _
  *                 (_)           | |    (_)
 /*********************************************************
  *                  _             _      _
  *                 (_)           | |    (_)
@@ -1274,6 +1332,9 @@ void ia32_transform_node(ir_node *node, void *env) {
                GEN(Store);
                GEN(Cond);
 
                GEN(Store);
                GEN(Cond);
 
+               GEN(CopyB);
+               GEN(Mux);
+
                IGN(Call);
                IGN(Alloc);
 
                IGN(Call);
                IGN(Alloc);
 
@@ -1290,13 +1351,13 @@ void ia32_transform_node(ir_node *node, void *env) {
                /* constant transformation happens earlier */
                IGN(Const);
                IGN(SymConst);
                /* constant transformation happens earlier */
                IGN(Const);
                IGN(SymConst);
+               IGN(Sync);
 
                BAD(Raise);
                BAD(Sel);
                BAD(InstOf);
                BAD(Cast);
                BAD(Free);
 
                BAD(Raise);
                BAD(Sel);
                BAD(InstOf);
                BAD(Cast);
                BAD(Free);
-               BAD(Sync);
                BAD(Tuple);
                BAD(Id);
                BAD(Bad);
                BAD(Tuple);
                BAD(Id);
                BAD(Bad);
@@ -1305,8 +1366,6 @@ void ia32_transform_node(ir_node *node, void *env) {
                BAD(CallBegin);
                BAD(EndReg);
                BAD(EndExcept);
                BAD(CallBegin);
                BAD(EndReg);
                BAD(EndExcept);
-               BAD(Mux);
-               BAD(CopyB);
 
                default:
                        if (get_irn_op(node) == get_op_Max()) {
 
                default:
                        if (get_irn_op(node) == get_op_Max()) {