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

added 8Bit Store work around

fixed several bugs
parent b9f9efa6
......@@ -101,7 +101,6 @@ static const arch_register_req_t *ia32_get_irn_reg_req(const void *self, arch_re
DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
if (is_Proj(irn)) {
if (pos == -1) {
node_pos = ia32_translate_proj_pos(irn);
......@@ -655,6 +654,7 @@ static void ia32_after_ra_walker(ir_node *node, void *env) {
transform_to_Load(&tenv);
}
else if (be_is_Spill(node)) {
tenv.mode = get_irn_mode(be_get_Spill_context(node));
transform_to_Store(&tenv);
}
}
......
......@@ -1280,6 +1280,61 @@ static void emit_be_Perm(const ir_node *irn, ia32_emit_env_t *emit_env) {
IA32_DO_EMIT(irn);
}
/**
* Emits code for an 8Bit Store.
*/
static void emit_ia32_Store8Bit(const ir_node *irn, ia32_emit_env_t *emit_env) {
FILE *F = emit_env->out;
char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
const arch_register_t *in1 = get_in_reg(irn, 2);
ir_mode *mode = get_ia32_ls_mode(irn);
/* In case an 8Bit SPill got transformed into an 8Bit Store, the */
/* register allocator had no chance to fulfill requirements. */
/* Check if we have a valid 8Bit register, otherwise emit a */
/* workaround. */
if (REGS_ARE_EQUAL(in1, &ia32_gp_regs[REG_EAX]) ||
REGS_ARE_EQUAL(in1, &ia32_gp_regs[REG_EBX]) ||
REGS_ARE_EQUAL(in1, &ia32_gp_regs[REG_ECX]) ||
REGS_ARE_EQUAL(in1, &ia32_gp_regs[REG_EDX]) ||
is_ia32_ImmConst(irn) ||
is_ia32_ImmSymConst(irn))
{
lc_esnprintf(ia32_get_arg_env(), cmd_buf, SNPRINTF_BUF_LEN, "mov %s", ia32_emit_binop(irn, emit_env));
lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F */", irn);
IA32_DO_EMIT(irn);
}
else {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* begin 8Bit Spill workaround %+F */", irn);
IA32_DO_EMIT(irn);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "push %%eax");
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* save %%eax */");
IA32_DO_EMIT(irn);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "mov %%eax, %%%s", arch_register_get_name(in1));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* copy 8Bit value into %%eax */");
IA32_DO_EMIT(irn);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "mov %s, %%al", ia32_emit_am(irn, emit_env));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* store 8Bit value */");
IA32_DO_EMIT(irn);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "pop %%eax", ia32_emit_am(irn, emit_env));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* restore %%eax */");
IA32_DO_EMIT(irn);
snprintf(cmd_buf, SNPRINTF_BUF_LEN, " ");
lc_esnprintf(ia32_get_arg_env(), cmnt_buf, SNPRINTF_BUF_LEN, "/* end of workaround %+F */", irn);
IA32_DO_EMIT(irn);
}
}
/***********************************************************************************
* _ __ _
* (_) / _| | |
......@@ -1319,6 +1374,7 @@ static void ia32_register_emitters(void) {
IA32_EMIT(Conv_FP2FP);
IA32_EMIT(Conv_I2I);
IA32_EMIT(Conv_I2I8Bit);
IA32_EMIT(Store8Bit);
/* benode emitter */
BE_EMIT(Call);
......
......@@ -186,8 +186,9 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
case dump_node_nodeattr_txt:
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
char *pref = is_ia32_ImmSymConst(n) ? "SymC" : "";
char *cnst = get_ia32_cnst(n);
fprintf(F, "[%s%s]", pref, get_ia32_cnst(n));
fprintf(F, "[%s%s]", pref, cnst ? cnst : "NONE");
}
if (! is_ia32_Lea(n)) {
......@@ -483,6 +484,7 @@ char *get_ia32_am_offs(const ir_node *node) {
memcpy(&res[1], obstack_base(attr->am_offs), size);
res[size + 1] = '\0';
}
return res;
}
......@@ -590,6 +592,8 @@ void set_ia32_sc(ir_node *node, ident *sc) {
*/
const char *get_ia32_cnst(const ir_node *node) {
ia32_attr_t *attr = get_ia32_attr(node);
if (! attr->cnst)
return NULL;
return get_id_str(attr->cnst);
}
......@@ -1093,7 +1097,7 @@ void alloc_ia32_reg_slots(ir_node *node, int num) {
ia32_attr_t *attr = get_ia32_attr(node);
if (num) {
attr->slots = NEW_ARR_D(arch_register_t *, get_irg_obstack(get_irn_irg(node)), num);
attr->slots = NEW_ARR_D(arch_register_t*, get_irg_obstack(get_irn_irg(node)), num);
memset(attr->slots, 0, sizeof(attr->slots[0]) * num);
}
else {
......@@ -1144,7 +1148,7 @@ static void ia32_copy_attr(const ir_node *old_node, ir_node *new_node) {
memcpy(attr_new, attr_old, sizeof(*attr_new));
/* copy the register slots */
attr_new->slots = NEW_ARR_D(arch_register_t *, get_irg_obstack(get_irn_irg(new_node)), n_res);
attr_new->slots = NEW_ARR_D(arch_register_t*, get_irg_obstack(get_irn_irg(new_node)), n_res);
memcpy((void *)attr_new->slots, (void *)attr_old->slots, sizeof(attr_new->slots[0]) * n_res);
}
......
......@@ -1631,11 +1631,11 @@ static ir_node *gen_StackParam(ia32_transform_env_t *env) {
entity *ent = be_get_frame_entity(node);
ir_mode *mode = env->mode;
/* If the StackParam has only one user -> */
/* put it in the Block where the user resides */
if (get_irn_n_edges(node) == 1) {
env->block = get_nodes_block(get_edge_src_irn(get_irn_out_edge_first(node)));
}
// /* If the StackParam has only one user -> */
// /* put it in the Block where the user resides */
// if (get_irn_n_edges(node) == 1) {
// env->block = get_nodes_block(get_edge_src_irn(get_irn_out_edge_first(node)));
// }
if (mode_is_float(mode)) {
if (USE_SSE2(env->cg))
......
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