- const arch_env_t *arch_env = cg->arch_env;
- ir_graph *irg = current_ir_graph;
- ir_node *base;
- ir_node *index;
- const arch_register_t *base_reg;
- const arch_register_t *index_reg;
- const arch_register_t *out_reg;
- int scale;
- int has_immediates;
- ir_node *op1;
- ir_node *op2;
- dbg_info *dbgi;
- ir_node *block;
- ir_node *res;
- ir_node *noreg;
- ir_node *nomem;
-
- if(!is_ia32_Lea(node))
- return;
-
- base = get_irn_n(node, n_ia32_Lea_base);
- index = get_irn_n(node, n_ia32_Lea_index);
-
- if(is_noreg(cg, base)) {
- base = NULL;
- base_reg = NULL;
- } else {
- base_reg = arch_get_irn_register(arch_env, base);
- }
- if(is_noreg(cg, index)) {
- index = NULL;
- index_reg = NULL;
- } else {
- index_reg = arch_get_irn_register(arch_env, index);
- }
-
- if(base == NULL && index == NULL) {
- /* we shouldn't construct these in the first place... */
-#ifdef DEBUG_libfirm
- ir_fprintf(stderr, "Optimisation warning: found immediate only lea\n");
-#endif
- return;
- }
-
- out_reg = arch_get_irn_register(arch_env, node);
- scale = get_ia32_am_scale(node);
- assert(!is_ia32_need_stackent(node) || get_ia32_frame_ent(node) != NULL);
- /* check if we have immediates values (frame entities should already be
- * expressed in the offsets) */
- if(get_ia32_am_offs_int(node) != 0 || get_ia32_am_sc(node) != NULL) {
- has_immediates = 1;
- } else {
- has_immediates = 0;
- }
-
- /* we can transform leas where the out register is the same as either the
- * base or index register back to an Add or Shl */
- if(out_reg == base_reg) {
- if(index == NULL) {
-#ifdef DEBUG_libfirm
- if(!has_immediates) {
- ir_fprintf(stderr, "Optimisation warning: found lea which is "
- "just a copy\n");
- }
-#endif
- op1 = base;
- goto make_add_immediate;
- }
- if(scale == 0 && !has_immediates) {
- op1 = base;
- op2 = index;
- goto make_add;
- }
- /* can't create an add */
- return;
- } else if(out_reg == index_reg) {
- if(base == NULL) {
- if(has_immediates && scale == 0) {
- op1 = index;
- goto make_add_immediate;
- } else if(!has_immediates && scale > 0) {
- op1 = index;
- op2 = create_immediate_from_int(cg, scale);
- goto make_shl;
- } else if(!has_immediates) {
-#ifdef DEBUG_libfirm
- ir_fprintf(stderr, "Optimisation warning: found lea which is "
- "just a copy\n");
-#endif
- }
- } else if(scale == 0 && !has_immediates) {
- op1 = index;
- op2 = base;
- goto make_add;
- }
- /* can't create an add */
- return;
- } else {
- /* can't create an add */
- return;
- }