+typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
+ ir_node *mem);
+
+typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
+ ir_node *val, ir_node *mem);
+
+/**
+ * Transforms a lowered Load into a "real" one.
+ */
+static ir_node *gen_lowered_Load(ia32_transform_env_t *env, construct_load_func func, char fp_unit) {
+ ir_node *node = env->irn;
+ ir_node *noreg = ia32_new_NoReg_gp(env->cg);
+ ir_mode *mode = get_ia32_ls_mode(node);
+ ir_node *new_op;
+ char *am_offs;
+ ia32_am_flavour_t am_flav = ia32_B;
+
+ /*
+ Could be that we have SSE2 unit, but due to 64Bit Div/Conv
+ lowering we have x87 nodes, so we need to enforce simulation.
+ */
+ if (mode_is_float(mode)) {
+ FP_USED(env->cg);
+ if (fp_unit == fp_x87)
+ FORCE_x87(env->cg);
+ }
+
+ new_op = func(env->dbg, env->irg, env->block, get_irn_n(node, 0), noreg, get_irn_n(node, 1));
+ am_offs = get_ia32_am_offs(node);
+
+ if (am_offs) {
+ am_flav |= ia32_O;
+ add_ia32_am_offs(new_op, am_offs);
+ }
+
+ set_ia32_am_support(new_op, ia32_am_Source);
+ set_ia32_op_type(new_op, ia32_AddrModeS);
+ set_ia32_am_flavour(new_op, am_flav);
+ set_ia32_ls_mode(new_op, mode);
+ set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
+ set_ia32_use_frame(new_op);
+
+ SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
+
+ return new_op;
+}
+
+/**
+* Transforms a lowered Store into a "real" one.
+*/
+static ir_node *gen_lowered_Store(ia32_transform_env_t *env, construct_store_func func, char fp_unit) {
+ ir_node *node = env->irn;
+ ir_node *noreg = ia32_new_NoReg_gp(env->cg);
+ ir_mode *mode = get_ia32_ls_mode(node);
+ ir_node *new_op;
+ char *am_offs;
+ ia32_am_flavour_t am_flav = ia32_B;
+
+ /*
+ Could be that we have SSE2 unit, but due to 64Bit Div/Conv
+ lowering we have x87 nodes, so we need to enforce simulation.
+ */
+ if (mode_is_float(mode)) {
+ FP_USED(env->cg);
+ if (fp_unit == fp_x87)
+ FORCE_x87(env->cg);
+ }
+
+ new_op = func(env->dbg, env->irg, env->block, get_irn_n(node, 0), noreg, get_irn_n(node, 1), get_irn_n(node, 2));
+
+ if (am_offs = get_ia32_am_offs(node)) {
+ am_flav |= ia32_O;
+ add_ia32_am_offs(new_op, am_offs);
+ }
+
+ set_ia32_am_support(new_op, ia32_am_Dest);
+ set_ia32_op_type(new_op, ia32_AddrModeD);
+ set_ia32_am_flavour(new_op, am_flav);
+ set_ia32_ls_mode(new_op, mode);
+ set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
+ set_ia32_use_frame(new_op);
+
+ SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, node));
+
+ return new_op;
+}
+
+