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

fixed immediate operation handling

parent 4cdd9d65
......@@ -305,7 +305,13 @@ char *ia32_emit_binop(const ir_node *n, ia32_emit_env_t *env) {
}
break;
case ia32_AddrModeS:
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S, %s", n, ia32_emit_am(n, env));
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
assert(! PRODUCES_RESULT(n) && "Source AM with Const must not produce result");
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, "%4S, %s", n, ia32_emit_am(n, env));
}
break;
case ia32_AddrModeD:
if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n)) {
......@@ -421,7 +427,13 @@ char *ia32_emit_am(const ir_node *n, ia32_emit_env_t *env) {
}
if (am_flav & ia32_O) {
obstack_printf(obst, get_ia32_am_offs(n));
s = get_ia32_am_offs(n);
/* omit exlicit + if there was no base or index */
if (! had_output && s[0] == '+')
s++;
obstack_printf(obst, s);
}
obstack_printf(obst, "] ");
......
......@@ -483,6 +483,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;
}
......
......@@ -555,13 +555,20 @@ static int load_store_addr_is_equal(const ir_node *load, const ir_node *store,
int is_equal = (addr_b == get_irn_n(load, 0)) && (addr_i == get_irn_n(load, 1));
entity *lent = get_ia32_frame_ent(load);
entity *sent = get_ia32_frame_ent(store);
char *loffs = get_ia32_am_offs(load);
char *soffs = get_ia32_am_offs(store);
/* are both entities set and equal? */
is_equal = lent && sent && (lent == sent);
if (lent || sent)
is_equal = lent && sent && (lent == sent);
/* are the load and the store of the same mode? */
is_equal = get_ia32_ls_mode(load) == get_ia32_ls_mode(store);
/* are offsets set and equal */
if (loffs || soffs)
is_equal = loffs && soffs && strcmp(loffs, soffs) == 0;
return is_equal;
}
......
......@@ -1177,21 +1177,36 @@ static ir_node *gen_Abs(ia32_transform_env_t *env, ir_node *op) {
* @return the created ia32 Load node
*/
static ir_node *gen_Load(ia32_transform_env_t *env) {
ir_node *node = env->irn;
ir_node *noreg = ia32_new_NoReg_gp(env->cg);
ir_mode *mode = get_Load_mode(node);
ir_node *node = env->irn;
ir_node *noreg = ia32_new_NoReg_gp(env->cg);
ir_node *ptr = get_Load_ptr(node);
ir_mode *mode = get_Load_mode(node);
const char *offs = NULL;
ir_node *new_op;
ia32_am_flavour_t am_flav = ia32_B;
/* address might be a constant (symconst or absolute address) */
if (is_ia32_Const(ptr)) {
offs = get_ia32_cnst(ptr);
ptr = noreg;
}
if (mode_is_float(mode)) {
new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, get_Load_ptr(node), noreg, get_Load_mem(node), env->mode);
new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, get_Load_mem(node), env->mode);
}
else {
new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, get_Load_ptr(node), noreg, get_Load_mem(node), env->mode);
new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, get_Load_mem(node), env->mode);
}
/* base is an constant address */
if (offs) {
add_ia32_am_offs(new_op, offs);
am_flav = ia32_O;
}
set_ia32_am_support(new_op, ia32_am_Source);
set_ia32_op_type(new_op, ia32_AddrModeS);
set_ia32_am_flavour(new_op, ia32_B);
set_ia32_am_flavour(new_op, am_flav);
set_ia32_ls_mode(new_op, mode);
SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
......@@ -1211,20 +1226,40 @@ static ir_node *gen_Load(ia32_transform_env_t *env) {
* @return the created ia32 Store node
*/
static ir_node *gen_Store(ia32_transform_env_t *env) {
ir_node *node = env->irn;
ir_node *noreg = ia32_new_NoReg_gp(env->cg);
ir_node *val = get_Store_value(node);
ir_node *ptr = get_Store_ptr(node);
ir_node *mem = get_Store_mem(node);
ir_mode *mode = get_irn_mode(val);
ir_node *sval = val;
ir_node *node = env->irn;
ir_node *noreg = ia32_new_NoReg_gp(env->cg);
ir_node *val = get_Store_value(node);
ir_node *ptr = get_Store_ptr(node);
ir_node *mem = get_Store_mem(node);
ir_mode *mode = get_irn_mode(val);
ir_node *sval = val;
const char *offs = NULL;
ir_node *new_op;
ia32_am_flavour_t am_flav = ia32_B;
ia32_immop_type_t immop = ia32_ImmNone;
/* in case of storing a const (but not a symconst) -> make it an attribute */
if (is_ia32_Const(val)) {
if (is_ia32_Cnst(val)) {
switch (get_ia32_op_type(val)) {
case ia32_Const:
immop = ia32_ImmConst;
break;
case ia32_SymConst:
immop = ia32_ImmSymConst;
break;
default:
assert(0 && "unsupported Const type");
}
sval = noreg;
}
/* address might be a constant (symconst or absolute address) */
if (is_ia32_Const(ptr)) {
offs = get_ia32_cnst(ptr);
ptr = noreg;
}
if (mode_is_float(mode)) {
new_op = new_rd_ia32_fStore(env->dbg, env->irg, env->block, ptr, noreg, sval, mem, mode_T);
}
......@@ -1236,14 +1271,21 @@ static ir_node *gen_Store(ia32_transform_env_t *env) {
}
/* stored const is an attribute (saves a register) */
if (is_ia32_Const(val)) {
if (is_ia32_Cnst(val)) {
set_ia32_Immop_attr(new_op, val);
}
/* base is an constant address */
if (offs) {
add_ia32_am_offs(new_op, offs);
am_flav = ia32_O;
}
set_ia32_am_support(new_op, ia32_am_Dest);
set_ia32_op_type(new_op, ia32_AddrModeD);
set_ia32_am_flavour(new_op, ia32_B);
set_ia32_am_flavour(new_op, am_flav);
set_ia32_ls_mode(new_op, get_irn_mode(val));
set_ia32_immop_type(new_op, immop);
SET_IA32_ORIG_NODE(new_op, get_old_node_name(env));
......
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