#include "iredges_t.h"
#include "ircons.h"
#include "irgmod.h"
+#include "irgopt.h"
#include "bitset.h"
#include "debug.h"
irg_walk_blkwise_graph(cg->irg, ia32_place_consts_set_modes, ia32_transform_node, cg);
dump_ir_block_graph_sched(cg->irg, "-transformed");
+ edges_deactivate(cg->irg);
+ dead_node_elimination(cg->irg);
+ edges_activate(cg->irg);
+
cg->mod = old_mod;
if (cg->opt.doam) {
tenv.mode = get_irn_mode(node);
tenv.cg = cg;
- if (be_is_StackParam(node) || be_is_Reload(node)) {
+ /* be_is_StackParam(node) || */
+ if (be_is_Reload(node)) {
transform_to_Load(&tenv);
}
else if (be_is_Spill(node)) {
long nr = get_Proj_proj(proj);
if (is_ia32_Ld(pred)) {
- if (nr == pn_Load_res)
+ if (nr == pn_Load_res || nr == 0)
return 0;
assert(0 && "unsupported Proj(Load) number");
}
#include "../be_t.h"
#include "../beabi.h"
+#include "../benode_t.h"
+#include "../besched_t.h"
#include "ia32_new_nodes.h"
#include "bearch_ia32_t.h"
}
/**
- * Returns the Proj with number 0 connected to irn.
+ * Returns the first Proj with mode != mode_M connected to irn.
*/
static ir_node *get_res_proj(const ir_node *irn) {
const ir_edge_t *edge;
assert(is_Proj(src) && "Proj expected");
- if (get_Proj_proj(src) == 0)
+ if (get_irn_mode(src) != mode_M)
return src;
}
return 0;
}
-static int is_addr_candidate(const ir_node *block, const ir_node *irn) {
-}
/**
* Checks if irn is a candidate for address calculation or address mode.
* return 1 if irn is a candidate for AC or AM, 0 otherwise
*/
static int is_candidate(const ir_node *block, const ir_node *irn, int check_addr) {
- ir_node *load_proj;
+ ir_node *in;
int n, is_cand = check_addr;
- if (pred_is_specific_nodeblock(block, get_irn_n(irn, 2), is_ia32_Load)) {
- load_proj = get_irn_n(irn, 2);
- n = ia32_get_irn_n_edges(load_proj);
+ in = get_irn_n(irn, 2);
+
+ if (pred_is_specific_nodeblock(block, in, is_ia32_Ld) || be_is_StackParam(in)) {
+ n = ia32_get_irn_n_edges(in);
is_cand = check_addr ? (n == 1 ? 0 : is_cand) : (n == 1 ? 1 : is_cand);
}
- if (pred_is_specific_nodeblock(block, get_irn_n(irn, 3), is_ia32_Load)) {
- load_proj = get_irn_n(irn, 3);
- n = ia32_get_irn_n_edges(load_proj);
+ in = get_irn_n(irn, 3);
+
+ if (pred_is_specific_nodeblock(block, in, is_ia32_Ld) || be_is_StackParam(in)) {
+ n = ia32_get_irn_n_edges(in);
is_cand = check_addr ? (n == 1 ? 0 : is_cand) : (n == 1 ? 1 : is_cand);
}
- is_cand = get_ia32_frame_ent(irn) ? (check_addr ? 1 : 0) : (check_addr ? 0 : 1);
+ is_cand = get_ia32_frame_ent(irn) ? (check_addr ? 1 : 0) : is_cand;
return is_cand;
}
entity *sent = get_ia32_frame_ent(store);
/* are both entities set and equal? */
- is_equal = (lent && sent && (lent == sent)) ? 1 : is_equal;
+ 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);
return is_equal;
}
+
+
/**
* Folds Add or Sub to LEA if possible
*/
left = get_irn_n(irn, 2);
right = get_irn_n(irn, 3);
- base = left;
- index = noreg;
- offs = NULL;
- scale = 0;
- am_flav = 0;
-
/* "normalize" arguments in case of add with two operands */
if (isadd && ! be_is_NoReg(babi, right)) {
/* put LEA == ia32_am_O as right operand */
}
}
+ base = left;
+ index = noreg;
+ offs = NULL;
+ scale = 0;
+ am_flav = 0;
+
/* check if operand is either const */
if (get_ia32_cnst(irn)) {
DBG((mod, LEVEL_1, "\tfound op with imm"));
/* a new LEA. */
/* If the LEA contains already a frame_entity then we also */
/* create a new one otherwise we would loose it. */
- if (isadd && ((!be_is_NoReg(babi, index) && (am_flav & ia32_am_I)) || get_ia32_frame_ent(left))) {
+ if ((isadd && ((!be_is_NoReg(babi, index) && (am_flav & ia32_am_I))) || get_ia32_frame_ent(left))) {
DBG((mod, LEVEL_1, "\tleave old LEA, creating new one\n"));
}
else {
"comment" => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
- "emit" => '. lea %D1, %ia32_emit_am\t\t/* %D1 = %S1 + %S2 << scale + %O, (%A1, %A2) */'
+ "emit" => '. lea %D1, %ia32_emit_am\t\t/* LEA(%A1, %A2) */'
},
#--------------------------------------------------------#
*
********************************************/
+static ir_node *gen_StackParam(ia32_transform_env_t *env) {
+ ir_node *new_op = NULL;
+ ir_node *node = env->irn;
+ ir_node *noreg = ia32_new_NoReg_gp(env->cg);
+ ir_node *mem = new_rd_NoMem(env->irg);
+ ir_node *ptr = get_irn_n(node, 0);
+ entity *ent = be_get_frame_entity(node);
+ ir_mode *mode = env->mode;
+
+ if (mode_is_float(mode)) {
+ new_op = new_rd_ia32_fLoad(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
+ }
+ else {
+ new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem, mode_T);
+ }
+
+ set_ia32_frame_ent(new_op, ent);
+ set_ia32_use_frame(new_op);
+
+ 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_ls_mode(new_op, mode);
+
+#ifndef NDEBUG
+ set_ia32_orig_node(new_op, get_old_node_name(env));
+#endif /* NDEBUG */
+
+ return new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, 0);
+}
+
/**
* Transforms a FrameAddr into an ia32 Add.
*/
}
set_ia32_frame_ent(new_op, ent);
+ set_ia32_use_frame(new_op);
set_ia32_am_support(new_op, ia32_am_Source);
set_ia32_op_type(new_op, ia32_AddrModeS);
else {
new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, mem, mode_T);
}
+
set_ia32_frame_ent(new_op, ent);
+ set_ia32_use_frame(new_op);
set_ia32_am_support(new_op, ia32_am_Dest);
set_ia32_op_type(new_op, ia32_AddrModeD);
BE_GEN(FrameAddr);
BE_GEN(FrameLoad);
BE_GEN(FrameStore);
+ BE_GEN(StackParam);
break;
bad:
fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));