Commit 747aab36 authored by Christian Würdig's avatar Christian Würdig
Browse files

removed some unncessary nodes (Stackparam, return, etc.)

added CopyB and CMov (Mux) nodes
parent daa56549
......@@ -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(CMov);
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(CopyB);
IA32_EMIT(CopyB_i);
/* generated floating point emitter */
IA32_EMIT(fConst);
......
......@@ -22,6 +22,8 @@ $arch = "ia32";
# ...
# ],
# "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"
# },
......@@ -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" => {
......@@ -387,27 +399,6 @@ $arch = "ia32";
"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) */'
},
"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
......@@ -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
......@@ -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(CopyB);
GEN(Mux);
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);
IGN(Sync);
BAD(Raise);
BAD(Sel);
BAD(InstOf);
BAD(Cast);
BAD(Free);
BAD(Sync);
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(Mux);
BAD(CopyB);
default:
if (get_irn_op(node) == get_op_Max()) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment