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

fixed binop emitter for Source AM

added UKNWN register
set Unknown nodes to ignore and assign them the UKNWN register
parent 7b1a7841
......@@ -147,23 +147,23 @@ static const arch_register_req_t *ia32_get_irn_reg_req(const void *self, arch_re
}
}
else {
/* treat Phi like Const with default requirements */
if (is_Phi(irn)) {
DB((mod, LEVEL_1, "returning standard reqs for %+F\n", irn));
/* treat Unknowns like Const with default requirements */
if (is_Unknown(irn)) {
DB((mod, LEVEL_1, "returning UKNWN reqs for %+F\n", irn));
if (mode_is_float(mode)) {
if (USE_SSE2(ops->cg))
memcpy(req, &(ia32_default_req_ia32_xmm.req), sizeof(*req));
memcpy(req, &(ia32_default_req_ia32_xmm_xmm_UKNWN), sizeof(*req));
else
memcpy(req, &(ia32_default_req_ia32_vfp.req), sizeof(*req));
memcpy(req, &(ia32_default_req_ia32_vfp_vfp_UKNWN), sizeof(*req));
}
else if (mode_is_int(mode) || mode_is_reference(mode))
memcpy(req, &(ia32_default_req_ia32_gp.req), sizeof(*req));
memcpy(req, &(ia32_default_req_ia32_gp_gp_UKNWN), sizeof(*req));
else if (mode == mode_T || mode == mode_M) {
DBG((mod, LEVEL_1, "ignoring Phi node %+F\n", irn));
DBG((mod, LEVEL_1, "ignoring Unknown node %+F\n", irn));
return NULL;
}
else
assert(0 && "unsupported Phi-Mode");
assert(0 && "unsupported Unknown-Mode");
}
else {
DB((mod, LEVEL_1, "returning NULL for %+F (not ia32)\n", irn));
......@@ -241,6 +241,8 @@ static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
if (is_ia32_irn(irn))
return get_ia32_flags(irn);
else {
if (is_Unknown(irn))
return arch_irn_flags_ignore;
return 0;
}
}
......
......@@ -78,6 +78,17 @@ static const arch_register_t *get_in_reg(const ir_node *irn, int pos) {
reg = arch_get_irn_register(arch_env, op);
assert(reg && "no in register found");
/* in case of unknown: just return a register */
if (REGS_ARE_EQUAL(reg, &ia32_gp_regs[REG_GP_UKNWN]))
reg = &ia32_gp_regs[REG_EAX];
else if (REGS_ARE_EQUAL(reg, &ia32_xmm_regs[REG_XMM_UKNWN]))
reg = &ia32_xmm_regs[REG_XMM0];
else if (REGS_ARE_EQUAL(reg, &ia32_vfp_regs[REG_VFP_UKNWN]))
reg = &ia32_vfp_regs[REG_VF0];
else if (REGS_ARE_EQUAL(reg, &ia32_st_regs[REG_ST_UKNWN]))
reg = &ia32_st_regs[REG_ST0];
return reg;
}
......@@ -326,7 +337,12 @@ char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
snprintf(buf, SNPRINTF_BUF_LEN, "%s, %s", get_ia32_cnst(n), ia32_emit_am(n, env));
}
else {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %s", n, ia32_emit_am(n, env));
if (PRODUCES_RESULT(n)) {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %s", n, ia32_emit_am(n, env));
}
else {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S, %s", n, ia32_emit_am(n, env));
}
}
break;
case ia32_AddrModeD:
......@@ -1061,12 +1077,17 @@ static void emit_CopyB_prolog(FILE *F, int rem, int size) {
* Emit rep movsd instruction for memcopy.
*/
static void emit_ia32_CopyB(const ir_node *irn, ia32_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)));
FILE *F = emit_env->out;
tarval *tv = get_ia32_Immop_tarval(irn);
int rem = get_tarval_long(tv);
ir_node *size_node = get_irn_n(irn, 2);
int size;
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
/* beware: size_node could be a be_Copy to fulfill constraints for ecx */
size_node = be_is_Copy(size_node) ? be_get_Copy_op(size_node) : size_node;
size = get_tarval_long(get_ia32_Immop_tarval(size_node));
emit_CopyB_prolog(F, rem, size);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "rep movsd");
......
......@@ -176,8 +176,8 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
break;
case dump_node_nodeattr_txt:
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
char *pref = is_ia32_ImmSymConst(n) ? "SymC" : "";
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n) || is_ia32_Cnst(n)) {
char *pref = is_ia32_ImmSymConst(n) || (get_ia32_op_type(n) == ia32_SymConst) ? "SymC" : "";
const char *cnst = get_ia32_cnst(n);
fprintf(F, "[%s%s]", pref, cnst ? cnst : "NONE");
......
......@@ -103,7 +103,8 @@ $comment_string = "/*";
{ "name" => "edi", "type" => 2 },
{ "name" => "ebp", "type" => 2 },
{ "name" => "esp", "type" => 4 },
{ "name" => "gp_NOREG", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes
{ "name" => "gp_NOREG", "type" => 6 }, # we need a dummy register for NoReg nodes
{ "name" => "gp_UKNWN", "type" => 6 }, # we need a dummy register for Unknown nodes
{ "mode" => "mode_P" }
],
"xmm" => [
......@@ -115,7 +116,8 @@ $comment_string = "/*";
{ "name" => "xmm5", "type" => 1 },
{ "name" => "xmm6", "type" => 1 },
{ "name" => "xmm7", "type" => 1 },
{ "name" => "xmm_NOREG", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes
{ "name" => "xmm_NOREG", "type" => 6 }, # we need a dummy register for NoReg nodes
{ "name" => "xmm_UKNWN", "type" => 6 }, # we need a dummy register for Unknown nodes
{ "mode" => "mode_D" }
],
"vfp" => [
......@@ -127,7 +129,8 @@ $comment_string = "/*";
{ "name" => "vf5", "type" => 1 },
{ "name" => "vf6", "type" => 1 },
{ "name" => "vf7", "type" => 1 },
{ "name" => "vfp_NOREG", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes
{ "name" => "vfp_NOREG", "type" => 6 }, # we need a dummy register for NoReg nodes
{ "name" => "vfp_UKNWN", "type" => 6 }, # we need a dummy register for Unknown nodes
{ "mode" => "mode_E" }
],
"st" => [
......@@ -139,7 +142,8 @@ $comment_string = "/*";
{ "name" => "st5", "type" => 1 },
{ "name" => "st6", "type" => 1 },
{ "name" => "st7", "type" => 1 },
{ "name" => "st_NOREG", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes
{ "name" => "st_NOREG", "type" => 6 }, # we need a dummy register for NoReg nodes
{ "name" => "st_UKNWN", "type" => 6 }, # we need a dummy register for Unknown nodes
{ "mode" => "mode_E" }
]
); # %reg_classes
......
......@@ -1949,6 +1949,30 @@ static ir_node *gen_be_FrameStore(ia32_transform_env_t *env) {
return new_op;
}
/**
* This function just sets the register for the Unknown node
* as this is not done during register allocation because Unknown
* is an "ignore" node.
*/
static ir_node *gen_Unknown(ia32_transform_env_t *env) {
ir_mode *mode = env->mode;
ir_node *irn = env->irn;
if (mode_is_float(mode)) {
if (USE_SSE2(env->cg))
arch_set_irn_register(env->cg->arch_env, irn, &ia32_xmm_regs[REG_XMM_UKNWN]);
else
arch_set_irn_register(env->cg->arch_env, irn, &ia32_vfp_regs[REG_VFP_UKNWN]);
}
else if (mode_is_int(mode) || mode_is_reference(mode)) {
arch_set_irn_register(env->cg->arch_env, irn, &ia32_gp_regs[REG_GP_UKNWN]);
}
else {
assert(0 && "unsupported Unknown-Mode");
}
return NULL;
}
/*********************************************************
......@@ -2207,7 +2231,6 @@ void ia32_register_transformers(void) {
IGN(IJmp);
IGN(Break);
IGN(Cmp);
IGN(Unknown);
/* constant transformation happens earlier */
IGN(Const);
......@@ -2233,6 +2256,9 @@ void ia32_register_transformers(void) {
GEN(be_FrameStore);
GEN(be_StackParam);
/* set the register for all Unknown nodes */
GEN(Unknown);
op_Max = get_op_Max();
if (op_Max)
GEN(Max);
......
Markdown is supported
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