00e5e2872cb01e6f569f1d9a2caa78e8a975a0f8
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       This file implements the IR transformation from firm into
23  *              ia32-Firm.
24  * @author      Christian Wuerdig, Matthias Braun
25  * @version     $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <limits.h>
32
33 #include "irargs_t.h"
34 #include "irnode_t.h"
35 #include "irgraph_t.h"
36 #include "irmode_t.h"
37 #include "iropt_t.h"
38 #include "irop_t.h"
39 #include "irprog_t.h"
40 #include "iredges_t.h"
41 #include "irgmod.h"
42 #include "irvrfy.h"
43 #include "ircons.h"
44 #include "irgwalk.h"
45 #include "irprintf.h"
46 #include "debug.h"
47 #include "irdom.h"
48 #include "archop.h"
49 #include "error.h"
50 #include "height.h"
51
52 #include "../benode_t.h"
53 #include "../besched.h"
54 #include "../beabi.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
58
59 #include "bearch_ia32_t.h"
60 #include "ia32_nodes_attr.h"
61 #include "ia32_transform.h"
62 #include "ia32_new_nodes.h"
63 #include "ia32_map_regs.h"
64 #include "ia32_dbg_stat.h"
65 #include "ia32_optimize.h"
66 #include "ia32_util.h"
67 #include "ia32_address_mode.h"
68 #include "ia32_architecture.h"
69
70 #include "gen_ia32_regalloc_if.h"
71
72 #define SFP_SIGN   "0x80000000"
73 #define DFP_SIGN   "0x8000000000000000"
74 #define SFP_ABS    "0x7FFFFFFF"
75 #define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
76 #define DFP_INTMAX "9223372036854775807"
77
78 #define TP_SFP_SIGN "ia32_sfp_sign"
79 #define TP_DFP_SIGN "ia32_dfp_sign"
80 #define TP_SFP_ABS  "ia32_sfp_abs"
81 #define TP_DFP_ABS  "ia32_dfp_abs"
82 #define TP_INT_MAX  "ia32_int_max"
83
84 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
85 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
86 #define ENT_SFP_ABS  "IA32_SFP_ABS"
87 #define ENT_DFP_ABS  "IA32_DFP_ABS"
88 #define ENT_INT_MAX  "IA32_INT_MAX"
89
90 #define mode_vfp        (ia32_reg_classes[CLASS_ia32_vfp].mode)
91 #define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)
92
93 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
94
95 /** hold the current code generator during transformation */
96 static ia32_code_gen_t *env_cg       = NULL;
97 static ir_node         *initial_fpcw = NULL;
98 static heights_t       *heights      = NULL;
99
100 extern ir_op *get_op_Mulh(void);
101
102 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
103         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
104         ir_node *op1, ir_node *op2);
105
106 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
107         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
108         ir_node *op1, ir_node *op2, ir_node *flags);
109
110 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
111         ir_node *block, ir_node *op1, ir_node *op2);
112
113 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
114         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
115         ir_node *op);
116
117 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
118         ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
119
120 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
121         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
122         ir_node *op1, ir_node *op2, ir_node *fpcw);
123
124 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
125         ir_node *block, ir_node *op);
126
127 static ir_node *try_create_Immediate(ir_node *node,
128                                      char immediate_constraint_type);
129
130 static ir_node *create_immediate_or_transform(ir_node *node,
131                                               char immediate_constraint_type);
132
133 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
134                                 dbg_info *dbgi, ir_node *block,
135                                 ir_node *op, ir_node *orig_node);
136
137 /**
138  * Return true if a mode can be stored in the GP register set
139  */
140 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
141         if(mode == mode_fpcw)
142                 return 0;
143         if(get_mode_size_bits(mode) > 32)
144                 return 0;
145         return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
146 }
147
148 /**
149  * creates a unique ident by adding a number to a tag
150  *
151  * @param tag   the tag string, must contain a %d if a number
152  *              should be added
153  */
154 static ident *unique_id(const char *tag)
155 {
156         static unsigned id = 0;
157         char str[256];
158
159         snprintf(str, sizeof(str), tag, ++id);
160         return new_id_from_str(str);
161 }
162
163 /**
164  * Get a primitive type for a mode.
165  */
166 static ir_type *get_prim_type(pmap *types, ir_mode *mode)
167 {
168         pmap_entry *e = pmap_find(types, mode);
169         ir_type *res;
170
171         if (! e) {
172                 char buf[64];
173                 snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
174                 res = new_type_primitive(new_id_from_str(buf), mode);
175                 set_type_alignment_bytes(res, 16);
176                 pmap_insert(types, mode, res);
177         }
178         else
179                 res = e->value;
180         return res;
181 }
182
183 /**
184  * Get an atomic entity that is initialized with a tarval
185  */
186 static ir_entity *create_float_const_entity(ir_node *cnst)
187 {
188         ia32_isa_t *isa = env_cg->isa;
189         tarval *tv      = get_Const_tarval(cnst);
190         pmap_entry *e   = pmap_find(isa->tv_ent, tv);
191         ir_entity *res;
192         ir_graph *rem;
193
194         if (! e) {
195                 ir_mode *mode = get_irn_mode(cnst);
196                 ir_type *tp = get_Const_type(cnst);
197                 if (tp == firm_unknown_type)
198                         tp = get_prim_type(isa->types, mode);
199
200                 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
201
202                 set_entity_ld_ident(res, get_entity_ident(res));
203                 set_entity_visibility(res, visibility_local);
204                 set_entity_variability(res, variability_constant);
205                 set_entity_allocation(res, allocation_static);
206
207                  /* we create a new entity here: It's initialization must resist on the
208                     const code irg */
209                 rem = current_ir_graph;
210                 current_ir_graph = get_const_code_irg();
211                 set_atomic_ent_value(res, new_Const_type(tv, tp));
212                 current_ir_graph = rem;
213
214                 pmap_insert(isa->tv_ent, tv, res);
215         } else {
216                 res = e->value;
217         }
218
219         return res;
220 }
221
222 static int is_Const_0(ir_node *node) {
223         return is_Const(node) && is_Const_null(node);
224 }
225
226 static int is_Const_1(ir_node *node) {
227         return is_Const(node) && is_Const_one(node);
228 }
229
230 static int is_Const_Minus_1(ir_node *node) {
231         return is_Const(node) && is_Const_all_one(node);
232 }
233
234 /**
235  * returns true if constant can be created with a simple float command
236  */
237 static int is_simple_x87_Const(ir_node *node)
238 {
239         tarval *tv = get_Const_tarval(node);
240
241         if(tarval_is_null(tv) || tarval_is_one(tv))
242                 return 1;
243
244         /* TODO: match all the other float constants */
245         return 0;
246 }
247
248 /**
249  * Transforms a Const.
250  */
251 static ir_node *gen_Const(ir_node *node) {
252         ir_graph        *irg   = current_ir_graph;
253         ir_node         *old_block = get_nodes_block(node);
254         ir_node         *block = be_transform_node(old_block);
255         dbg_info        *dbgi  = get_irn_dbg_info(node);
256         ir_mode         *mode  = get_irn_mode(node);
257
258         if (mode_is_float(mode)) {
259                 ir_node   *res   = NULL;
260                 ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
261                 ir_node   *nomem = new_NoMem();
262                 ir_node   *load;
263                 ir_entity *floatent;
264
265                 if (ia32_cg_config.use_sse2) {
266                         if (is_Const_null(node)) {
267                                 load = new_rd_ia32_xZero(dbgi, irg, block);
268                                 set_ia32_ls_mode(load, mode);
269                                 res  = load;
270                         } else {
271                                 floatent = create_float_const_entity(node);
272
273                                 load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
274                                                                                          mode);
275                                 set_ia32_op_type(load, ia32_AddrModeS);
276                                 set_ia32_am_sc(load, floatent);
277                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
278                                 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
279                         }
280                 } else {
281                         if (is_Const_null(node)) {
282                                 load = new_rd_ia32_vfldz(dbgi, irg, block);
283                                 res  = load;
284                         } else if (is_Const_one(node)) {
285                                 load = new_rd_ia32_vfld1(dbgi, irg, block);
286                                 res  = load;
287                         } else {
288                                 floatent = create_float_const_entity(node);
289
290                                 load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
291                                 set_ia32_op_type(load, ia32_AddrModeS);
292                                 set_ia32_am_sc(load, floatent);
293                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
294                                 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
295                         }
296                         set_ia32_ls_mode(load, mode);
297                 }
298
299                 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
300
301                 /* Const Nodes before the initial IncSP are a bad idea, because
302                  * they could be spilled and we have no SP ready at that point yet.
303                  * So add a dependency to the initial frame pointer calculation to
304                  * avoid that situation.
305                  */
306                 if (get_irg_start_block(irg) == block) {
307                         add_irn_dep(load, get_irg_frame(irg));
308                 }
309
310                 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
311                 return res;
312         } else {
313                 ir_node *cnst;
314                 tarval  *tv = get_Const_tarval(node);
315                 long     val;
316
317                 tv = tarval_convert_to(tv, mode_Iu);
318
319                 if(tv == get_tarval_bad() || tv == get_tarval_undefined()
320                                 || tv == NULL) {
321                         panic("couldn't convert constant tarval (%+F)", node);
322                 }
323                 val = get_tarval_long(tv);
324
325                 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
326                 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
327
328                 /* see above */
329                 if (get_irg_start_block(irg) == block) {
330                         add_irn_dep(cnst, get_irg_frame(irg));
331                 }
332
333                 return cnst;
334         }
335 }
336
337 /**
338  * Transforms a SymConst.
339  */
340 static ir_node *gen_SymConst(ir_node *node) {
341         ir_graph *irg   = current_ir_graph;
342         ir_node  *old_block = get_nodes_block(node);
343         ir_node  *block = be_transform_node(old_block);
344         dbg_info *dbgi  = get_irn_dbg_info(node);
345         ir_mode  *mode  = get_irn_mode(node);
346         ir_node  *cnst;
347
348         if (mode_is_float(mode)) {
349                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
350                 ir_node *nomem = new_NoMem();
351
352                 if (ia32_cg_config.use_sse2)
353                         cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
354                 else
355                         cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
356                 set_ia32_am_sc(cnst, get_SymConst_entity(node));
357                 set_ia32_use_frame(cnst);
358         } else {
359                 ir_entity *entity;
360
361                 if(get_SymConst_kind(node) != symconst_addr_ent) {
362                         panic("backend only support symconst_addr_ent (at %+F)", node);
363                 }
364                 entity = get_SymConst_entity(node);
365                 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
366         }
367
368         /* Const Nodes before the initial IncSP are a bad idea, because
369          * they could be spilled and we have no SP ready at that point yet
370          */
371         if (get_irg_start_block(irg) == block) {
372                 add_irn_dep(cnst, get_irg_frame(irg));
373         }
374
375         SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
376
377         return cnst;
378 }
379
380 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
381 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
382         static const struct {
383                 const char *tp_name;
384                 const char *ent_name;
385                 const char *cnst_str;
386                 char mode;
387                 char align;
388         } names [ia32_known_const_max] = {
389                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN,   0, 16 },       /* ia32_SSIGN */
390                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN,   1, 16 },       /* ia32_DSIGN */
391                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS,    0, 16 },       /* ia32_SABS */
392                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS,    1, 16 },       /* ia32_DABS */
393                 { TP_INT_MAX,  ENT_INT_MAX,  DFP_INTMAX, 2, 4 }         /* ia32_INTMAX */
394         };
395         static ir_entity *ent_cache[ia32_known_const_max];
396
397         const char    *tp_name, *ent_name, *cnst_str;
398         ir_type       *tp;
399         ir_node       *cnst;
400         ir_graph      *rem;
401         ir_entity     *ent;
402         tarval        *tv;
403         ir_mode       *mode;
404
405         ent_name = names[kct].ent_name;
406         if (! ent_cache[kct]) {
407                 tp_name  = names[kct].tp_name;
408                 cnst_str = names[kct].cnst_str;
409
410                 switch (names[kct].mode) {
411                 case 0:  mode = mode_Iu; break;
412                 case 1:  mode = mode_Lu; break;
413                 default: mode = mode_F; break;
414                 }
415                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
416                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
417                 /* set the specified alignment */
418                 set_type_alignment_bytes(tp, names[kct].align);
419
420                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
421
422                 set_entity_ld_ident(ent, get_entity_ident(ent));
423                 set_entity_visibility(ent, visibility_local);
424                 set_entity_variability(ent, variability_constant);
425                 set_entity_allocation(ent, allocation_static);
426
427                 /* we create a new entity here: It's initialization must resist on the
428                     const code irg */
429                 rem = current_ir_graph;
430                 current_ir_graph = get_const_code_irg();
431                 cnst = new_Const(mode, tv);
432                 current_ir_graph = rem;
433
434                 set_atomic_ent_value(ent, cnst);
435
436                 /* cache the entry */
437                 ent_cache[kct] = ent;
438         }
439
440         return ent_cache[kct];
441 }
442
443 #ifndef NDEBUG
444 /**
445  * Prints the old node name on cg obst and returns a pointer to it.
446  */
447 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
448         ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
449
450         lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
451         obstack_1grow(isa->name_obst, 0);
452         return obstack_finish(isa->name_obst);
453 }
454 #endif /* NDEBUG */
455
456 /**
457  * return true if the node is a Proj(Load) and could be used in source address
458  * mode for another node. Will return only true if the @p other node is not
459  * dependent on the memory of the Load (for binary operations use the other
460  * input here, for unary operations use NULL).
461  */
462 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
463                                         ir_node *other, ir_node *other2)
464 {
465         ir_mode *mode = get_irn_mode(node);
466         ir_node *load;
467         long     pn;
468
469         /* float constants are always available */
470         if(is_Const(node) && mode_is_float(mode)) {
471                 if(!is_simple_x87_Const(node))
472                         return 0;
473                 if(get_irn_n_edges(node) > 1)
474                         return 0;
475                 return 1;
476         }
477
478         if(!is_Proj(node))
479                 return 0;
480         load = get_Proj_pred(node);
481         pn   = get_Proj_proj(node);
482         if(!is_Load(load) || pn != pn_Load_res)
483                 return 0;
484         if(get_nodes_block(load) != block)
485                 return 0;
486         /* we only use address mode if we're the only user of the load */
487         if(get_irn_n_edges(node) > 1)
488                 return 0;
489         /* in some edge cases with address mode we might reach the load normally
490          * and through some AM sequence, if it is already materialized then we
491          * can't create an AM node from it */
492         if(be_is_transformed(node))
493                 return 0;
494
495         /* don't do AM if other node inputs depend on the load (via mem-proj) */
496         if(other != NULL && get_nodes_block(other) == block
497                         && heights_reachable_in_block(heights, other, load))
498                 return 0;
499         if(other2 != NULL && get_nodes_block(other2) == block
500                         && heights_reachable_in_block(heights, other2, load))
501                 return 0;
502
503         return 1;
504 }
505
506 typedef struct ia32_address_mode_t ia32_address_mode_t;
507 struct ia32_address_mode_t {
508         ia32_address_t  addr;
509         ir_mode        *ls_mode;
510         ir_node        *mem_proj;
511         ia32_op_type_t  op_type;
512         ir_node        *new_op1;
513         ir_node        *new_op2;
514         op_pin_state    pinned;
515         unsigned        commutative  : 1;
516         unsigned        ins_permuted : 1;
517 };
518
519 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
520 {
521         ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
522
523         /* construct load address */
524         memset(addr, 0, sizeof(addr[0]));
525         ia32_create_address_mode(addr, ptr, /*force=*/0);
526
527         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
528         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
529         addr->mem   = be_transform_node(mem);
530 }
531
532 static void build_address(ia32_address_mode_t *am, ir_node *node)
533 {
534         ir_node        *noreg_gp = ia32_new_NoReg_gp(env_cg);
535         ia32_address_t *addr     = &am->addr;
536         ir_node        *load;
537         ir_node        *ptr;
538         ir_node        *mem;
539         ir_node        *new_mem;
540
541         if(is_Const(node)) {
542                 ir_entity *entity  = create_float_const_entity(node);
543                 addr->base         = noreg_gp;
544                 addr->index        = noreg_gp;
545                 addr->mem          = new_NoMem();
546                 addr->symconst_ent = entity;
547                 addr->use_frame    = 1;
548                 am->ls_mode        = get_irn_mode(node);
549                 am->pinned         = op_pin_state_floats;
550                 return;
551         }
552
553         load         = get_Proj_pred(node);
554         ptr          = get_Load_ptr(load);
555         mem          = get_Load_mem(load);
556         new_mem      = be_transform_node(mem);
557         am->pinned   = get_irn_pinned(load);
558         am->ls_mode  = get_Load_mode(load);
559         am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
560
561         /* construct load address */
562         ia32_create_address_mode(addr, ptr, /*force=*/0);
563
564         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
565         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
566         addr->mem   = new_mem;
567 }
568
569 static void set_address(ir_node *node, const ia32_address_t *addr)
570 {
571         set_ia32_am_scale(node, addr->scale);
572         set_ia32_am_sc(node, addr->symconst_ent);
573         set_ia32_am_offs_int(node, addr->offset);
574         if(addr->symconst_sign)
575                 set_ia32_am_sc_sign(node);
576         if(addr->use_frame)
577                 set_ia32_use_frame(node);
578         set_ia32_frame_ent(node, addr->frame_entity);
579 }
580
581 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
582 {
583         set_address(node, &am->addr);
584
585         set_ia32_op_type(node, am->op_type);
586         set_ia32_ls_mode(node, am->ls_mode);
587         if(am->pinned == op_pin_state_pinned && get_irn_pinned(node) != op_pin_state_pinned) {
588                 set_irn_pinned(node, am->pinned);
589         }
590         if(am->commutative)
591                 set_ia32_commutative(node);
592 }
593
594 /**
595  * Check, if a given node is a Down-Conv, ie. a integer Conv
596  * from a mode with a mode with more bits to a mode with lesser bits.
597  * Moreover, we return only true if the node has not more than 1 user.
598  *
599  * @param node   the node
600  * @return non-zero if node is a Down-Conv
601  */
602 static int is_downconv(const ir_node *node)
603 {
604         ir_mode *src_mode;
605         ir_mode *dest_mode;
606
607         if(!is_Conv(node))
608                 return 0;
609
610         /* we only want to skip the conv when we're the only user
611          * (not optimal but for now...)
612          */
613         if(get_irn_n_edges(node) > 1)
614                 return 0;
615
616         src_mode  = get_irn_mode(get_Conv_op(node));
617         dest_mode = get_irn_mode(node);
618         return mode_needs_gp_reg(src_mode)
619                 && mode_needs_gp_reg(dest_mode)
620                 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
621 }
622
623 /* Skip all Down-Conv's on a given node and return the resulting node. */
624 ir_node *ia32_skip_downconv(ir_node *node) {
625         while (is_downconv(node))
626                 node = get_Conv_op(node);
627
628         return node;
629 }
630
631 #if 0
632 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
633 {
634         ir_mode  *mode = get_irn_mode(node);
635         ir_node  *block;
636         ir_mode  *tgt_mode;
637         dbg_info *dbgi;
638
639         if(mode_is_signed(mode)) {
640                 tgt_mode = mode_Is;
641         } else {
642                 tgt_mode = mode_Iu;
643         }
644         block = get_nodes_block(node);
645         dbgi  = get_irn_dbg_info(node);
646
647         return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
648 }
649 #endif
650
651 /**
652  * matches operands of a node into ia32 addressing/operand modes. This covers
653  * usage of source address mode, immediates, operations with non 32-bit modes,
654  * ...
655  * The resulting data is filled into the @p am struct. block is the block
656  * of the node whose arguments are matched. op1, op2 are the first and second
657  * input that are matched (op1 may be NULL). other_op is another unrelated
658  * input that is not matched! but which is needed sometimes to check if AM
659  * for op1/op2 is legal.
660  * @p flags describes the supported modes of the operation in detail.
661  */
662 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
663                             ir_node *op1, ir_node *op2, ir_node *other_op,
664                             match_flags_t flags)
665 {
666         ia32_address_t *addr     = &am->addr;
667         ir_node        *noreg_gp = ia32_new_NoReg_gp(env_cg);
668         ir_node        *new_op1;
669         ir_node        *new_op2;
670         ir_mode        *mode = get_irn_mode(op2);
671         int             use_am;
672         unsigned        commutative;
673         int             use_am_and_immediates;
674         int             use_immediate;
675         int             mode_bits = get_mode_size_bits(mode);
676
677         memset(am, 0, sizeof(am[0]));
678
679         commutative           = (flags & match_commutative) != 0;
680         use_am_and_immediates = (flags & match_am_and_immediates) != 0;
681         use_am                = (flags & match_am) != 0;
682         use_immediate         = (flags & match_immediate) != 0;
683         assert(!use_am_and_immediates || use_immediate);
684
685         assert(op2 != NULL);
686         assert(!commutative || op1 != NULL);
687         assert(use_am || !(flags & match_8bit_am));
688         assert(use_am || !(flags & match_16bit_am));
689
690         if(mode_bits == 8) {
691                 if (! (flags & match_8bit_am))
692                         use_am = 0;
693                 /* we don't automatically add upconvs yet */
694                 assert((flags & match_mode_neutral) || (flags & match_8bit));
695         } else if(mode_bits == 16) {
696                 if(! (flags & match_16bit_am))
697                         use_am = 0;
698                 /* we don't automatically add upconvs yet */
699                 assert((flags & match_mode_neutral) || (flags & match_16bit));
700         }
701
702         /* we can simply skip downconvs for mode neutral nodes: the upper bits
703          * can be random for these operations */
704         if(flags & match_mode_neutral) {
705                 op2 = ia32_skip_downconv(op2);
706                 if(op1 != NULL) {
707                         op1 = ia32_skip_downconv(op1);
708                 }
709         }
710
711         /* match immediates. firm nodes are normalized: constants are always on the
712          * op2 input */
713         new_op2 = NULL;
714         if(! (flags & match_try_am) && use_immediate) {
715                 new_op2 = try_create_Immediate(op2, 0);
716         }
717
718         if(new_op2 == NULL
719            && use_am && ia32_use_source_address_mode(block, op2, op1, other_op)) {
720                 build_address(am, op2);
721                 new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
722                 if(mode_is_float(mode)) {
723                         new_op2 = ia32_new_NoReg_vfp(env_cg);
724                 } else {
725                         new_op2 = noreg_gp;
726                 }
727                 am->op_type = ia32_AddrModeS;
728         } else if(commutative && (new_op2 == NULL || use_am_and_immediates) &&
729                       use_am
730                       && ia32_use_source_address_mode(block, op1, op2, other_op)) {
731                 ir_node *noreg;
732                 build_address(am, op1);
733
734                 if(mode_is_float(mode)) {
735                         noreg = ia32_new_NoReg_vfp(env_cg);
736                 } else {
737                         noreg = noreg_gp;
738                 }
739
740                 if(new_op2 != NULL) {
741                         new_op1 = noreg;
742                 } else {
743                         new_op1 = be_transform_node(op2);
744                         new_op2 = noreg;
745                         am->ins_permuted = 1;
746                 }
747                 am->op_type = ia32_AddrModeS;
748         } else {
749                 if(flags & match_try_am) {
750                         am->new_op1 = NULL;
751                         am->new_op2 = NULL;
752                         am->op_type = ia32_Normal;
753                         return;
754                 }
755
756                 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
757                 if(new_op2 == NULL)
758                         new_op2 = be_transform_node(op2);
759                 am->op_type = ia32_Normal;
760                 am->ls_mode = get_irn_mode(op2);
761                 if(flags & match_mode_neutral)
762                         am->ls_mode = mode_Iu;
763         }
764         if(addr->base == NULL)
765                 addr->base = noreg_gp;
766         if(addr->index == NULL)
767                 addr->index = noreg_gp;
768         if(addr->mem == NULL)
769                 addr->mem = new_NoMem();
770
771         am->new_op1     = new_op1;
772         am->new_op2     = new_op2;
773         am->commutative = commutative;
774 }
775
776 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
777 {
778         ir_graph *irg = current_ir_graph;
779         ir_mode  *mode;
780         ir_node  *load;
781
782         if(am->mem_proj == NULL)
783                 return node;
784
785         /* we have to create a mode_T so the old MemProj can attach to us */
786         mode = get_irn_mode(node);
787         load = get_Proj_pred(am->mem_proj);
788
789         mark_irn_visited(load);
790         be_set_transformed_node(load, node);
791
792         if(mode != mode_T) {
793                 set_irn_mode(node, mode_T);
794                 return new_rd_Proj(NULL, irg, get_nodes_block(node), node, mode, pn_ia32_res);
795         } else {
796                 return node;
797         }
798 }
799
800 /**
801  * Construct a standard binary operation, set AM and immediate if required.
802  *
803  * @param op1   The first operand
804  * @param op2   The second operand
805  * @param func  The node constructor function
806  * @return The constructed ia32 node.
807  */
808 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
809                           construct_binop_func *func, match_flags_t flags)
810 {
811         ir_node  *block     = get_nodes_block(node);
812         ir_node  *new_block = be_transform_node(block);
813         ir_graph *irg       = current_ir_graph;
814         dbg_info *dbgi      = get_irn_dbg_info(node);
815         ir_node  *new_node;
816         ia32_address_mode_t  am;
817         ia32_address_t      *addr = &am.addr;
818
819         match_arguments(&am, block, op1, op2, NULL, flags);
820
821         new_node = func(dbgi, irg, new_block, addr->base, addr->index, addr->mem,
822                         am.new_op1, am.new_op2);
823         set_am_attributes(new_node, &am);
824         /* we can't use source address mode anymore when using immediates */
825         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
826                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
827         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
828
829         new_node = fix_mem_proj(new_node, &am);
830
831         return new_node;
832 }
833
834 enum {
835         n_ia32_l_binop_left,
836         n_ia32_l_binop_right,
837         n_ia32_l_binop_eflags
838 };
839 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Adc_left,   n_Adc_left)
840 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Adc_right,  n_Adc_right)
841 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
842 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Sbb_left,   n_Sbb_left)
843 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Sbb_right,  n_Sbb_right)
844 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
845
846 /**
847  * Construct a binary operation which also consumes the eflags.
848  *
849  * @param node  The node to transform
850  * @param func  The node constructor function
851  * @param flags The match flags
852  * @return      The constructor ia32 node
853  */
854 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
855                                 match_flags_t flags)
856 {
857         ir_node             *src_block  = get_nodes_block(node);
858         ir_node             *block      = be_transform_node(src_block);
859         ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
860         ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
861         ir_node             *eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
862         ir_node             *new_eflags = be_transform_node(eflags);
863         ir_graph            *irg        = current_ir_graph;
864         dbg_info            *dbgi       = get_irn_dbg_info(node);
865         ir_node             *new_node;
866         ia32_address_mode_t  am;
867         ia32_address_t      *addr       = &am.addr;
868
869         match_arguments(&am, src_block, op1, op2, NULL, flags);
870
871         new_node = func(dbgi, irg, block, addr->base, addr->index,
872                                    addr->mem, am.new_op1, am.new_op2, new_eflags);
873         set_am_attributes(new_node, &am);
874         /* we can't use source address mode anymore when using immediates */
875         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
876                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
877         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
878
879         new_node = fix_mem_proj(new_node, &am);
880
881         return new_node;
882 }
883
884 static ir_node *get_fpcw(void)
885 {
886         ir_node *fpcw;
887         if(initial_fpcw != NULL)
888                 return initial_fpcw;
889
890         fpcw         = be_abi_get_ignore_irn(env_cg->birg->abi,
891                                              &ia32_fp_cw_regs[REG_FPCW]);
892         initial_fpcw = be_transform_node(fpcw);
893
894         return initial_fpcw;
895 }
896
897 /**
898  * Construct a standard binary operation, set AM and immediate if required.
899  *
900  * @param op1   The first operand
901  * @param op2   The second operand
902  * @param func  The node constructor function
903  * @return The constructed ia32 node.
904  */
905 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
906                                     construct_binop_float_func *func,
907                                     match_flags_t flags)
908 {
909         ir_graph *irg       = current_ir_graph;
910         dbg_info *dbgi      = get_irn_dbg_info(node);
911         ir_node  *block     = get_nodes_block(node);
912         ir_node  *new_block = be_transform_node(block);
913         ir_mode  *mode      = get_irn_mode(node);
914         ir_node  *new_node;
915         ia32_address_mode_t  am;
916         ia32_address_t      *addr = &am.addr;
917
918         /* cannot use addresmode with long double on x87 */
919         if (get_mode_size_bits(mode) > 64)
920                 flags &= ~match_am;
921
922         match_arguments(&am, block, op1, op2, NULL, flags);
923
924         new_node = func(dbgi, irg, new_block, addr->base, addr->index, addr->mem,
925                         am.new_op1, am.new_op2, get_fpcw());
926         set_am_attributes(new_node, &am);
927
928         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
929
930         new_node = fix_mem_proj(new_node, &am);
931
932         return new_node;
933 }
934
935 /**
936  * Construct a shift/rotate binary operation, sets AM and immediate if required.
937  *
938  * @param op1   The first operand
939  * @param op2   The second operand
940  * @param func  The node constructor function
941  * @return The constructed ia32 node.
942  */
943 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
944                                 construct_shift_func *func,
945                                 match_flags_t flags)
946 {
947         dbg_info *dbgi      = get_irn_dbg_info(node);
948         ir_graph *irg       = current_ir_graph;
949         ir_node  *block     = get_nodes_block(node);
950         ir_node  *new_block = be_transform_node(block);
951         ir_mode  *mode      = get_irn_mode(node);
952         ir_node  *new_op1;
953         ir_node  *new_op2;
954         ir_node  *new_node;
955
956         assert(! mode_is_float(mode));
957         assert(flags & match_immediate);
958         assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
959
960         if(flags & match_mode_neutral) {
961                 op1 = ia32_skip_downconv(op1);
962         }
963         new_op1 = be_transform_node(op1);
964
965         /* the shift amount can be any mode that is bigger than 5 bits, since all
966          * other bits are ignored anyway */
967         while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
968                 op2 = get_Conv_op(op2);
969                 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
970         }
971         new_op2 = create_immediate_or_transform(op2, 0);
972
973         new_node = func(dbgi, irg, new_block, new_op1, new_op2);
974         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
975
976         /* lowered shift instruction may have a dependency operand, handle it here */
977         if (get_irn_arity(node) == 3) {
978                 /* we have a dependency */
979                 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
980                 add_irn_dep(new_node, new_dep);
981         }
982
983         return new_node;
984 }
985
986
987 /**
988  * Construct a standard unary operation, set AM and immediate if required.
989  *
990  * @param op    The operand
991  * @param func  The node constructor function
992  * @return The constructed ia32 node.
993  */
994 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
995                          match_flags_t flags)
996 {
997         ir_graph *irg       = current_ir_graph;
998         dbg_info *dbgi      = get_irn_dbg_info(node);
999         ir_node  *block     = get_nodes_block(node);
1000         ir_node  *new_block = be_transform_node(block);
1001         ir_node  *new_op;
1002         ir_node  *new_node;
1003
1004         assert(flags == 0 || flags == match_mode_neutral);
1005         if(flags & match_mode_neutral) {
1006                 op = ia32_skip_downconv(op);
1007         }
1008
1009         new_op   = be_transform_node(op);
1010         new_node = func(dbgi, irg, new_block, new_op);
1011
1012         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1013
1014         return new_node;
1015 }
1016
1017 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1018                                         ia32_address_t *addr)
1019 {
1020         ir_graph *irg   = current_ir_graph;
1021         ir_node  *base  = addr->base;
1022         ir_node  *index = addr->index;
1023         ir_node  *res;
1024
1025         if(base == NULL) {
1026                 base = ia32_new_NoReg_gp(env_cg);
1027         } else {
1028                 base = be_transform_node(base);
1029         }
1030
1031         if(index == NULL) {
1032                 index = ia32_new_NoReg_gp(env_cg);
1033         } else {
1034                 index = be_transform_node(index);
1035         }
1036
1037         res = new_rd_ia32_Lea(dbgi, irg, block, base, index);
1038         set_address(res, addr);
1039
1040         return res;
1041 }
1042
1043 static int am_has_immediates(const ia32_address_t *addr)
1044 {
1045         return addr->offset != 0 || addr->symconst_ent != NULL
1046                 || addr->frame_entity || addr->use_frame;
1047 }
1048
1049 /**
1050  * Creates an ia32 Add.
1051  *
1052  * @return the created ia32 Add node
1053  */
1054 static ir_node *gen_Add(ir_node *node) {
1055         ir_graph *irg       = current_ir_graph;
1056         dbg_info *dbgi      = get_irn_dbg_info(node);
1057         ir_node  *block     = get_nodes_block(node);
1058         ir_node  *new_block = be_transform_node(block);
1059         ir_node  *op1       = get_Add_left(node);
1060         ir_node  *op2       = get_Add_right(node);
1061         ir_mode  *mode      = get_irn_mode(node);
1062         ir_node  *new_node;
1063         ir_node  *add_immediate_op;
1064         ia32_address_t       addr;
1065         ia32_address_mode_t  am;
1066
1067         if (mode_is_float(mode)) {
1068                 if (ia32_cg_config.use_sse2)
1069                         return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1070                                          match_commutative | match_am);
1071                 else
1072                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1073                                                    match_commutative | match_am);
1074         }
1075
1076         ia32_mark_non_am(node);
1077
1078         op2 = ia32_skip_downconv(op2);
1079         op1 = ia32_skip_downconv(op1);
1080
1081         /**
1082          * Rules for an Add:
1083          *   0. Immediate Trees (example Add(Symconst, Const) -> Const)
1084          *   1. Add with immediate -> Lea
1085          *   2. Add with possible source address mode -> Add
1086          *   3. Otherwise -> Lea
1087          */
1088         memset(&addr, 0, sizeof(addr));
1089         ia32_create_address_mode(&addr, node, /*force=*/1);
1090         add_immediate_op = NULL;
1091         /* a constant? */
1092         if(addr.base == NULL && addr.index == NULL) {
1093                 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1094                                              addr.symconst_sign, addr.offset);
1095                 add_irn_dep(new_node, get_irg_frame(irg));
1096                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1097                 return new_node;
1098         }
1099         /* add with immediate? */
1100         if(addr.index == NULL) {
1101                 add_immediate_op = addr.base;
1102         } else if(addr.base == NULL && addr.scale == 0) {
1103                 add_immediate_op = addr.index;
1104         }
1105
1106         if(add_immediate_op != NULL) {
1107                 if(!am_has_immediates(&addr)) {
1108 #ifdef DEBUG_libfirm
1109                         ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1110                                            node);
1111 #endif
1112                         return be_transform_node(add_immediate_op);
1113                 }
1114
1115                 new_node = create_lea_from_address(dbgi, new_block, &addr);
1116                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1117                 return new_node;
1118         }
1119
1120         /* test if we can use source address mode */
1121         match_arguments(&am, block, op1, op2, NULL, match_commutative
1122                         | match_mode_neutral | match_am | match_immediate | match_try_am);
1123
1124         /* construct an Add with source address mode */
1125         if (am.op_type == ia32_AddrModeS) {
1126                 ia32_address_t *am_addr = &am.addr;
1127                 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1128                                          am_addr->index, am_addr->mem, am.new_op1,
1129                                          am.new_op2);
1130                 set_am_attributes(new_node, &am);
1131                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1132
1133                 new_node = fix_mem_proj(new_node, &am);
1134
1135                 return new_node;
1136         }
1137
1138         /* otherwise construct a lea */
1139         new_node = create_lea_from_address(dbgi, new_block, &addr);
1140         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1141         return new_node;
1142 }
1143
1144 /**
1145  * Creates an ia32 Mul.
1146  *
1147  * @return the created ia32 Mul node
1148  */
1149 static ir_node *gen_Mul(ir_node *node) {
1150         ir_node *op1  = get_Mul_left(node);
1151         ir_node *op2  = get_Mul_right(node);
1152         ir_mode *mode = get_irn_mode(node);
1153
1154         if (mode_is_float(mode)) {
1155                 if (ia32_cg_config.use_sse2)
1156                         return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1157                                          match_commutative | match_am);
1158                 else
1159                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1160                                                    match_commutative | match_am);
1161         }
1162
1163         /* for the lower 32bit of the result it doesn't matter whether we use
1164          * signed or unsigned multiplication so we use IMul as it has fewer
1165          * constraints */
1166         return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1167                          match_commutative | match_am | match_mode_neutral |
1168                          match_immediate | match_am_and_immediates);
1169 }
1170
1171 /**
1172  * Creates an ia32 Mulh.
1173  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1174  * this result while Mul returns the lower 32 bit.
1175  *
1176  * @return the created ia32 Mulh node
1177  */
1178 static ir_node *gen_Mulh(ir_node *node)
1179 {
1180         ir_node  *block     = get_nodes_block(node);
1181         ir_node  *new_block = be_transform_node(block);
1182         ir_graph *irg       = current_ir_graph;
1183         dbg_info *dbgi      = get_irn_dbg_info(node);
1184         ir_mode  *mode      = get_irn_mode(node);
1185         ir_node  *op1       = get_Mulh_left(node);
1186         ir_node  *op2       = get_Mulh_right(node);
1187         ir_node  *proj_res_high;
1188         ir_node  *new_node;
1189         ia32_address_mode_t  am;
1190         ia32_address_t      *addr = &am.addr;
1191
1192         assert(!mode_is_float(mode) && "Mulh with float not supported");
1193         assert(get_mode_size_bits(mode) == 32);
1194
1195         match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1196
1197         if (mode_is_signed(mode)) {
1198                 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1199                                                addr->index, addr->mem, am.new_op1,
1200                                                am.new_op2);
1201         } else {
1202                 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1203                                            addr->index, addr->mem, am.new_op1,
1204                                            am.new_op2);
1205         }
1206
1207         set_am_attributes(new_node, &am);
1208         /* we can't use source address mode anymore when using immediates */
1209         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1210                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1211         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1212
1213         assert(get_irn_mode(new_node) == mode_T);
1214
1215         fix_mem_proj(new_node, &am);
1216
1217         assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1218         proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1219                                mode_Iu, pn_ia32_IMul1OP_res_high);
1220
1221         return proj_res_high;
1222 }
1223
1224
1225
1226 /**
1227  * Creates an ia32 And.
1228  *
1229  * @return The created ia32 And node
1230  */
1231 static ir_node *gen_And(ir_node *node) {
1232         ir_node *op1 = get_And_left(node);
1233         ir_node *op2 = get_And_right(node);
1234         assert(! mode_is_float(get_irn_mode(node)));
1235
1236         /* is it a zero extension? */
1237         if (is_Const(op2)) {
1238                 tarval   *tv    = get_Const_tarval(op2);
1239                 long      v     = get_tarval_long(tv);
1240
1241                 if (v == 0xFF || v == 0xFFFF) {
1242                         dbg_info *dbgi   = get_irn_dbg_info(node);
1243                         ir_node  *block  = get_nodes_block(node);
1244                         ir_mode  *src_mode;
1245                         ir_node  *res;
1246
1247                         if(v == 0xFF) {
1248                                 src_mode = mode_Bu;
1249                         } else {
1250                                 assert(v == 0xFFFF);
1251                                 src_mode = mode_Hu;
1252                         }
1253                         res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1254
1255                         return res;
1256                 }
1257         }
1258
1259         return gen_binop(node, op1, op2, new_rd_ia32_And,
1260                          match_commutative | match_mode_neutral | match_am
1261                                          | match_immediate);
1262 }
1263
1264
1265
1266 /**
1267  * Creates an ia32 Or.
1268  *
1269  * @return The created ia32 Or node
1270  */
1271 static ir_node *gen_Or(ir_node *node) {
1272         ir_node *op1 = get_Or_left(node);
1273         ir_node *op2 = get_Or_right(node);
1274
1275         assert (! mode_is_float(get_irn_mode(node)));
1276         return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1277                         | match_mode_neutral | match_am | match_immediate);
1278 }
1279
1280
1281
1282 /**
1283  * Creates an ia32 Eor.
1284  *
1285  * @return The created ia32 Eor node
1286  */
1287 static ir_node *gen_Eor(ir_node *node) {
1288         ir_node *op1 = get_Eor_left(node);
1289         ir_node *op2 = get_Eor_right(node);
1290
1291         assert(! mode_is_float(get_irn_mode(node)));
1292         return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1293                         | match_mode_neutral | match_am | match_immediate);
1294 }
1295
1296
1297 /**
1298  * Creates an ia32 Sub.
1299  *
1300  * @return The created ia32 Sub node
1301  */
1302 static ir_node *gen_Sub(ir_node *node) {
1303         ir_node  *op1  = get_Sub_left(node);
1304         ir_node  *op2  = get_Sub_right(node);
1305         ir_mode  *mode = get_irn_mode(node);
1306
1307         if (mode_is_float(mode)) {
1308                 if (ia32_cg_config.use_sse2)
1309                         return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1310                 else
1311                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1312                                                    match_am);
1313         }
1314
1315         if(is_Const(op2)) {
1316                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1317                            node);
1318         }
1319
1320         return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1321                         | match_am | match_immediate);
1322 }
1323
1324 /**
1325  * Generates an ia32 DivMod with additional infrastructure for the
1326  * register allocator if needed.
1327  */
1328 static ir_node *create_Div(ir_node *node)
1329 {
1330         ir_graph *irg       = current_ir_graph;
1331         dbg_info *dbgi      = get_irn_dbg_info(node);
1332         ir_node  *block     = get_nodes_block(node);
1333         ir_node  *new_block = be_transform_node(block);
1334         ir_node  *mem;
1335         ir_node  *new_mem;
1336         ir_node  *op1;
1337         ir_node  *op2;
1338         ir_node  *new_node;
1339         ir_mode  *mode;
1340         ir_node  *sign_extension;
1341         int       has_exc;
1342         ia32_address_mode_t  am;
1343         ia32_address_t      *addr = &am.addr;
1344
1345         /* the upper bits have random contents for smaller modes */
1346         has_exc = 0;
1347         switch (get_irn_opcode(node)) {
1348         case iro_Div:
1349                 op1     = get_Div_left(node);
1350                 op2     = get_Div_right(node);
1351                 mem     = get_Div_mem(node);
1352                 mode    = get_Div_resmode(node);
1353                 has_exc = be_get_Proj_for_pn(node, pn_Div_X_except) != NULL;
1354                 break;
1355         case iro_Mod:
1356                 op1     = get_Mod_left(node);
1357                 op2     = get_Mod_right(node);
1358                 mem     = get_Mod_mem(node);
1359                 mode    = get_Mod_resmode(node);
1360                 has_exc = be_get_Proj_for_pn(node, pn_Mod_X_except) != NULL;
1361                 break;
1362         case iro_DivMod:
1363                 op1     = get_DivMod_left(node);
1364                 op2     = get_DivMod_right(node);
1365                 mem     = get_DivMod_mem(node);
1366                 mode    = get_DivMod_resmode(node);
1367                 has_exc = be_get_Proj_for_pn(node, pn_DivMod_X_except) != NULL;
1368                 break;
1369         default:
1370                 panic("invalid divmod node %+F", node);
1371         }
1372
1373         match_arguments(&am, block, op1, op2, NULL, match_am);
1374
1375         if(!is_NoMem(mem)) {
1376                 new_mem = be_transform_node(mem);
1377                 if(!is_NoMem(addr->mem)) {
1378                         ir_node *in[2];
1379                         in[0] = new_mem;
1380                         in[1] = addr->mem;
1381                         new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1382                 }
1383         } else {
1384                 new_mem = addr->mem;
1385         }
1386
1387         if (mode_is_signed(mode)) {
1388                 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1389                 add_irn_dep(produceval, get_irg_frame(irg));
1390                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1391                                                   produceval);
1392
1393                 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1394                                             addr->index, new_mem, am.new_op1,
1395                                             sign_extension, am.new_op2);
1396         } else {
1397                 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1398                 add_irn_dep(sign_extension, get_irg_frame(irg));
1399
1400                 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1401                                            addr->index, new_mem, am.new_op1,
1402                                            sign_extension, am.new_op2);
1403         }
1404
1405         set_ia32_exc_label(new_node, has_exc);
1406         set_irn_pinned(new_node, get_irn_pinned(node));
1407
1408         set_am_attributes(new_node, &am);
1409         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1410
1411         new_node = fix_mem_proj(new_node, &am);
1412
1413         return new_node;
1414 }
1415
1416
1417 static ir_node *gen_Mod(ir_node *node) {
1418         return create_Div(node);
1419 }
1420
1421 static ir_node *gen_Div(ir_node *node) {
1422         return create_Div(node);
1423 }
1424
1425 static ir_node *gen_DivMod(ir_node *node) {
1426         return create_Div(node);
1427 }
1428
1429
1430
1431 /**
1432  * Creates an ia32 floating Div.
1433  *
1434  * @return The created ia32 xDiv node
1435  */
1436 static ir_node *gen_Quot(ir_node *node)
1437 {
1438         ir_node  *op1     = get_Quot_left(node);
1439         ir_node  *op2     = get_Quot_right(node);
1440
1441         if (ia32_cg_config.use_sse2) {
1442                 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1443         } else {
1444                 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1445         }
1446 }
1447
1448
1449 /**
1450  * Creates an ia32 Shl.
1451  *
1452  * @return The created ia32 Shl node
1453  */
1454 static ir_node *gen_Shl(ir_node *node) {
1455         ir_node *left  = get_Shl_left(node);
1456         ir_node *right = get_Shl_right(node);
1457
1458         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1459                                match_mode_neutral | match_immediate);
1460 }
1461
1462 /**
1463  * Creates an ia32 Shr.
1464  *
1465  * @return The created ia32 Shr node
1466  */
1467 static ir_node *gen_Shr(ir_node *node) {
1468         ir_node *left  = get_Shr_left(node);
1469         ir_node *right = get_Shr_right(node);
1470
1471         return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1472 }
1473
1474
1475
1476 /**
1477  * Creates an ia32 Sar.
1478  *
1479  * @return The created ia32 Shrs node
1480  */
1481 static ir_node *gen_Shrs(ir_node *node) {
1482         ir_node *left  = get_Shrs_left(node);
1483         ir_node *right = get_Shrs_right(node);
1484         ir_mode *mode  = get_irn_mode(node);
1485
1486         if(is_Const(right) && mode == mode_Is) {
1487                 tarval *tv = get_Const_tarval(right);
1488                 long val = get_tarval_long(tv);
1489                 if(val == 31) {
1490                         /* this is a sign extension */
1491                         ir_graph *irg    = current_ir_graph;
1492                         dbg_info *dbgi   = get_irn_dbg_info(node);
1493                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1494                         ir_node  *op     = left;
1495                         ir_node  *new_op = be_transform_node(op);
1496                         ir_node  *pval   = new_rd_ia32_ProduceVal(dbgi, irg, block);
1497                         add_irn_dep(pval, get_irg_frame(irg));
1498
1499                         return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1500                 }
1501         }
1502
1503         /* 8 or 16 bit sign extension? */
1504         if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1505                 ir_node *shl_left  = get_Shl_left(left);
1506                 ir_node *shl_right = get_Shl_right(left);
1507                 if(is_Const(shl_right)) {
1508                         tarval *tv1 = get_Const_tarval(right);
1509                         tarval *tv2 = get_Const_tarval(shl_right);
1510                         if(tv1 == tv2 && tarval_is_long(tv1)) {
1511                                 long val = get_tarval_long(tv1);
1512                                 if(val == 16 || val == 24) {
1513                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1514                                         ir_node  *block  = get_nodes_block(node);
1515                                         ir_mode  *src_mode;
1516                                         ir_node  *res;
1517
1518                                         if(val == 24) {
1519                                                 src_mode = mode_Bs;
1520                                         } else {
1521                                                 assert(val == 16);
1522                                                 src_mode = mode_Hs;
1523                                         }
1524                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1525                                                               shl_left, node);
1526
1527                                         return res;
1528                                 }
1529                         }
1530                 }
1531         }
1532
1533         return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1534 }
1535
1536
1537
1538 /**
1539  * Creates an ia32 RotL.
1540  *
1541  * @param op1   The first operator
1542  * @param op2   The second operator
1543  * @return The created ia32 RotL node
1544  */
1545 static ir_node *gen_RotL(ir_node *node, ir_node *op1, ir_node *op2) {
1546         return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1547 }
1548
1549
1550
1551 /**
1552  * Creates an ia32 RotR.
1553  * NOTE: There is no RotR with immediate because this would always be a RotL
1554  *       "imm-mode_size_bits" which can be pre-calculated.
1555  *
1556  * @param op1   The first operator
1557  * @param op2   The second operator
1558  * @return The created ia32 RotR node
1559  */
1560 static ir_node *gen_RotR(ir_node *node, ir_node *op1, ir_node *op2) {
1561         return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1562 }
1563
1564
1565
1566 /**
1567  * Creates an ia32 RotR or RotL (depending on the found pattern).
1568  *
1569  * @return The created ia32 RotL or RotR node
1570  */
1571 static ir_node *gen_Rot(ir_node *node) {
1572         ir_node *rotate = NULL;
1573         ir_node *op1    = get_Rot_left(node);
1574         ir_node *op2    = get_Rot_right(node);
1575
1576         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1577                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1578                  that means we can create a RotR instead of an Add and a RotL */
1579
1580         if (get_irn_op(op2) == op_Add) {
1581                 ir_node *add = op2;
1582                 ir_node *left = get_Add_left(add);
1583                 ir_node *right = get_Add_right(add);
1584                 if (is_Const(right)) {
1585                         tarval  *tv   = get_Const_tarval(right);
1586                         ir_mode *mode = get_irn_mode(node);
1587                         long     bits = get_mode_size_bits(mode);
1588
1589                         if (get_irn_op(left) == op_Minus &&
1590                                         tarval_is_long(tv)       &&
1591                                         get_tarval_long(tv) == bits &&
1592                                         bits                == 32)
1593                         {
1594                                 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1595                                 rotate = gen_RotR(node, op1, get_Minus_op(left));
1596                         }
1597                 }
1598         }
1599
1600         if (rotate == NULL) {
1601                 rotate = gen_RotL(node, op1, op2);
1602         }
1603
1604         return rotate;
1605 }
1606
1607
1608
1609 /**
1610  * Transforms a Minus node.
1611  *
1612  * @return The created ia32 Minus node
1613  */
1614 static ir_node *gen_Minus(ir_node *node)
1615 {
1616         ir_node   *op    = get_Minus_op(node);
1617         ir_node   *block = be_transform_node(get_nodes_block(node));
1618         ir_graph  *irg   = current_ir_graph;
1619         dbg_info  *dbgi  = get_irn_dbg_info(node);
1620         ir_mode   *mode  = get_irn_mode(node);
1621         ir_entity *ent;
1622         ir_node   *new_node;
1623         int        size;
1624
1625         if (mode_is_float(mode)) {
1626                 ir_node *new_op = be_transform_node(op);
1627                 if (ia32_cg_config.use_sse2) {
1628                         /* TODO: non-optimal... if we have many xXors, then we should
1629                          * rather create a load for the const and use that instead of
1630                          * several AM nodes... */
1631                         ir_node *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1632                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1633                         ir_node *nomem     = new_rd_NoMem(irg);
1634
1635                         new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1636                                                     nomem, new_op, noreg_xmm);
1637
1638                         size = get_mode_size_bits(mode);
1639                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1640
1641                         set_ia32_am_sc(new_node, ent);
1642                         set_ia32_op_type(new_node, ia32_AddrModeS);
1643                         set_ia32_ls_mode(new_node, mode);
1644                 } else {
1645                         new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1646                 }
1647         } else {
1648                 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1649         }
1650
1651         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1652
1653         return new_node;
1654 }
1655
1656 /**
1657  * Transforms a Not node.
1658  *
1659  * @return The created ia32 Not node
1660  */
1661 static ir_node *gen_Not(ir_node *node) {
1662         ir_node *op   = get_Not_op(node);
1663
1664         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1665         assert (! mode_is_float(get_irn_mode(node)));
1666
1667         return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1668 }
1669
1670
1671
1672 /**
1673  * Transforms an Abs node.
1674  *
1675  * @return The created ia32 Abs node
1676  */
1677 static ir_node *gen_Abs(ir_node *node)
1678 {
1679         ir_node   *block     = get_nodes_block(node);
1680         ir_node   *new_block = be_transform_node(block);
1681         ir_node   *op        = get_Abs_op(node);
1682         ir_graph  *irg       = current_ir_graph;
1683         dbg_info  *dbgi      = get_irn_dbg_info(node);
1684         ir_mode   *mode      = get_irn_mode(node);
1685         ir_node   *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1686         ir_node   *nomem     = new_NoMem();
1687         ir_node   *new_op;
1688         ir_node   *new_node;
1689         int        size;
1690         ir_entity *ent;
1691
1692         if (mode_is_float(mode)) {
1693                 new_op = be_transform_node(op);
1694
1695                 if (ia32_cg_config.use_sse2) {
1696                         ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1697                         new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1698                                                     nomem, new_op, noreg_fp);
1699
1700                         size = get_mode_size_bits(mode);
1701                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1702
1703                         set_ia32_am_sc(new_node, ent);
1704
1705                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1706
1707                         set_ia32_op_type(new_node, ia32_AddrModeS);
1708                         set_ia32_ls_mode(new_node, mode);
1709                 } else {
1710                         new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1711                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1712                 }
1713         } else {
1714                 ir_node *xor, *pval, *sign_extension;
1715
1716                 if (get_mode_size_bits(mode) == 32) {
1717                         new_op = be_transform_node(op);
1718                 } else {
1719                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1720                 }
1721
1722                 pval           = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1723                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1724                                                            new_op, pval);
1725
1726                 add_irn_dep(pval, get_irg_frame(irg));
1727                 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1728
1729                 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1730                                       nomem, new_op, sign_extension);
1731                 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1732
1733                 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1734                                            nomem, xor, sign_extension);
1735                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1736         }
1737
1738         return new_node;
1739 }
1740
1741 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1742 {
1743         ir_graph *irg = current_ir_graph;
1744         ir_node  *flags;
1745         ir_node  *new_op;
1746         ir_node  *noreg;
1747         ir_node  *nomem;
1748         ir_node  *new_block;
1749         dbg_info *dbgi;
1750
1751         /* we have a Cmp as input */
1752         if(is_Proj(node)) {
1753                 ir_node *pred = get_Proj_pred(node);
1754                 if(is_Cmp(pred)) {
1755                         flags    = be_transform_node(pred);
1756                         *pnc_out = get_Proj_proj(node);
1757                         return flags;
1758                 }
1759         }
1760
1761         /* a mode_b value, we have to compare it against 0 */
1762         dbgi      = get_irn_dbg_info(node);
1763         new_block = be_transform_node(get_nodes_block(node));
1764         new_op    = be_transform_node(node);
1765         noreg     = ia32_new_NoReg_gp(env_cg);
1766         nomem     = new_NoMem();
1767         flags     = new_rd_ia32_Test(dbgi, irg, new_block, noreg, noreg, nomem,
1768                                      new_op, new_op, 0, 0);
1769         *pnc_out  = pn_Cmp_Lg;
1770         return flags;
1771 }
1772
1773 /**
1774  * Transforms a Load.
1775  *
1776  * @return the created ia32 Load node
1777  */
1778 static ir_node *gen_Load(ir_node *node) {
1779         ir_node  *old_block = get_nodes_block(node);
1780         ir_node  *block   = be_transform_node(old_block);
1781         ir_node  *ptr     = get_Load_ptr(node);
1782         ir_node  *mem     = get_Load_mem(node);
1783         ir_node  *new_mem = be_transform_node(mem);
1784         ir_node  *base;
1785         ir_node  *index;
1786         ir_graph *irg     = current_ir_graph;
1787         dbg_info *dbgi    = get_irn_dbg_info(node);
1788         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
1789         ir_mode  *mode    = get_Load_mode(node);
1790         ir_mode  *res_mode;
1791         ir_node  *new_node;
1792         ia32_address_t addr;
1793
1794         /* construct load address */
1795         memset(&addr, 0, sizeof(addr));
1796         ia32_create_address_mode(&addr, ptr, /*force=*/0);
1797         base  = addr.base;
1798         index = addr.index;
1799
1800         if(base == NULL) {
1801                 base = noreg;
1802         } else {
1803                 base = be_transform_node(base);
1804         }
1805
1806         if(index == NULL) {
1807                 index = noreg;
1808         } else {
1809                 index = be_transform_node(index);
1810         }
1811
1812         if (mode_is_float(mode)) {
1813                 if (ia32_cg_config.use_sse2) {
1814                         new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1815                                                      mode);
1816                         res_mode = mode_xmm;
1817                 } else {
1818                         new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1819                                                     mode);
1820                         res_mode = mode_vfp;
1821                 }
1822         } else {
1823                 assert(mode != mode_b);
1824
1825                 /* create a conv node with address mode for smaller modes */
1826                 if(get_mode_size_bits(mode) < 32) {
1827                         new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1828                                                         new_mem, noreg, mode);
1829                 } else {
1830                         new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1831                 }
1832                 res_mode = mode_Iu;
1833         }
1834
1835         set_irn_pinned(new_node, get_irn_pinned(node));
1836         set_ia32_op_type(new_node, ia32_AddrModeS);
1837         set_ia32_ls_mode(new_node, mode);
1838         set_address(new_node, &addr);
1839
1840         if(get_irn_pinned(node) == op_pin_state_floats) {
1841                 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1842         }
1843
1844         /* make sure we are scheduled behind the initial IncSP/Barrier
1845          * to avoid spills being placed before it
1846          */
1847         if (block == get_irg_start_block(irg)) {
1848                 add_irn_dep(new_node, get_irg_frame(irg));
1849         }
1850
1851         set_ia32_exc_label(new_node,
1852                            be_get_Proj_for_pn(node, pn_Load_X_except) != NULL);
1853         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1854
1855         return new_node;
1856 }
1857
1858 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1859                        ir_node *ptr, ir_node *other)
1860 {
1861         ir_node *load;
1862
1863         if(!is_Proj(node))
1864                 return 0;
1865
1866         /* we only use address mode if we're the only user of the load */
1867         if(get_irn_n_edges(node) > 1)
1868                 return 0;
1869
1870         load = get_Proj_pred(node);
1871         if(!is_Load(load))
1872                 return 0;
1873         if(get_nodes_block(load) != block)
1874                 return 0;
1875
1876         /* Store should be attached to the load */
1877         if(!is_Proj(mem) || get_Proj_pred(mem) != load)
1878                 return 0;
1879         /* store should have the same pointer as the load */
1880         if(get_Load_ptr(load) != ptr)
1881                 return 0;
1882
1883         /* don't do AM if other node inputs depend on the load (via mem-proj) */
1884         if(other != NULL && get_nodes_block(other) == block
1885                         && heights_reachable_in_block(heights, other, load))
1886                 return 0;
1887
1888         return 1;
1889 }
1890
1891 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1892                               ir_node *mem, ir_node *ptr, ir_mode *mode,
1893                               construct_binop_dest_func *func,
1894                               construct_binop_dest_func *func8bit,
1895                                                           match_flags_t flags)
1896 {
1897         ir_node  *src_block = get_nodes_block(node);
1898         ir_node  *block;
1899         ir_node  *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1900         ir_graph *irg      = current_ir_graph;
1901         dbg_info *dbgi;
1902         ir_node  *new_node;
1903         ir_node  *new_op;
1904         int       commutative;
1905         ia32_address_mode_t  am;
1906         ia32_address_t      *addr = &am.addr;
1907         memset(&am, 0, sizeof(am));
1908
1909         assert(flags & match_dest_am);
1910         assert(flags & match_immediate); /* there is no destam node without... */
1911         commutative = (flags & match_commutative) != 0;
1912
1913         if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1914                 build_address(&am, op1);
1915                 new_op = create_immediate_or_transform(op2, 0);
1916         } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1917                 build_address(&am, op2);
1918                 new_op = create_immediate_or_transform(op1, 0);
1919         } else {
1920                 return NULL;
1921         }
1922
1923         if(addr->base == NULL)
1924                 addr->base = noreg_gp;
1925         if(addr->index == NULL)
1926                 addr->index = noreg_gp;
1927         if(addr->mem == NULL)
1928                 addr->mem = new_NoMem();
1929
1930         dbgi  = get_irn_dbg_info(node);
1931         block = be_transform_node(src_block);
1932         if(get_mode_size_bits(mode) == 8) {
1933                 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1934                                     addr->mem, new_op);
1935         } else {
1936                 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
1937                                 new_op);
1938         }
1939         set_address(new_node, addr);
1940         set_ia32_op_type(new_node, ia32_AddrModeD);
1941         set_ia32_ls_mode(new_node, mode);
1942         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1943
1944         return new_node;
1945 }
1946
1947 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
1948                              ir_node *ptr, ir_mode *mode,
1949                              construct_unop_dest_func *func)
1950 {
1951         ir_graph *irg      = current_ir_graph;
1952         ir_node *src_block = get_nodes_block(node);
1953         ir_node *block;
1954         dbg_info *dbgi;
1955         ir_node *new_node;
1956         ia32_address_mode_t  am;
1957         ia32_address_t *addr = &am.addr;
1958         memset(&am, 0, sizeof(am));
1959
1960         if(!use_dest_am(src_block, op, mem, ptr, NULL))
1961                 return NULL;
1962
1963         build_address(&am, op);
1964
1965         dbgi     = get_irn_dbg_info(node);
1966         block    = be_transform_node(src_block);
1967         new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
1968         set_address(new_node, addr);
1969         set_ia32_op_type(new_node, ia32_AddrModeD);
1970         set_ia32_ls_mode(new_node, mode);
1971         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1972
1973         return new_node;
1974 }
1975
1976 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
1977         ir_mode  *mode        = get_irn_mode(node);
1978         ir_node  *psi_true    = get_Psi_val(node, 0);
1979         ir_node  *psi_default = get_Psi_default(node);
1980         ir_graph *irg;
1981         ir_node  *cond;
1982         ir_node  *new_mem;
1983         dbg_info *dbgi;
1984         ir_node  *block;
1985         ir_node  *new_block;
1986         ir_node  *flags;
1987         ir_node  *new_node;
1988         int       negated;
1989         pn_Cmp    pnc;
1990         ia32_address_t addr;
1991
1992         if(get_mode_size_bits(mode) != 8)
1993                 return NULL;
1994
1995         if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
1996                 negated = 0;
1997         } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
1998                 negated = 1;
1999         } else {
2000                 return NULL;
2001         }
2002
2003         build_address_ptr(&addr, ptr, mem);
2004
2005         irg       = current_ir_graph;
2006         dbgi      = get_irn_dbg_info(node);
2007         block     = get_nodes_block(node);
2008         new_block = be_transform_node(block);
2009         cond      = get_Psi_cond(node, 0);
2010         flags     = get_flags_node(cond, &pnc);
2011         new_mem   = be_transform_node(mem);
2012         new_node  = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2013                                        addr.index, addr.mem, flags, pnc, negated);
2014         set_address(new_node, &addr);
2015         set_ia32_op_type(new_node, ia32_AddrModeD);
2016         set_ia32_ls_mode(new_node, mode);
2017         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2018
2019         return new_node;
2020 }
2021
2022 static ir_node *try_create_dest_am(ir_node *node) {
2023         ir_node  *val  = get_Store_value(node);
2024         ir_node  *mem  = get_Store_mem(node);
2025         ir_node  *ptr  = get_Store_ptr(node);
2026         ir_mode  *mode = get_irn_mode(val);
2027         int       bits = get_mode_size_bits(mode);
2028         ir_node  *op1;
2029         ir_node  *op2;
2030         ir_node  *new_node;
2031
2032         /* handle only GP modes for now... */
2033         if(!mode_needs_gp_reg(mode))
2034                 return NULL;
2035
2036         while(1) {
2037                 /* store must be the only user of the val node */
2038                 if(get_irn_n_edges(val) > 1)
2039                         return NULL;
2040                 /* skip pointless convs */
2041                 if(is_Conv(val)) {
2042                         ir_node *conv_op   = get_Conv_op(val);
2043                         ir_mode *pred_mode = get_irn_mode(conv_op);
2044                         if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2045                                 val = conv_op;
2046                                 continue;
2047                         }
2048                 }
2049                 break;
2050         }
2051
2052         /* value must be in the same block */
2053         if(get_nodes_block(node) != get_nodes_block(val))
2054                 return NULL;
2055
2056         switch(get_irn_opcode(val)) {
2057         case iro_Add:
2058                 op1      = get_Add_left(val);
2059                 op2      = get_Add_right(val);
2060                 if(is_Const_1(op2)) {
2061                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2062                                                 new_rd_ia32_IncMem);
2063                         break;
2064                 } else if(is_Const_Minus_1(op2)) {
2065                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2066                                                 new_rd_ia32_DecMem);
2067                         break;
2068                 }
2069                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2070                                          new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2071                                          match_dest_am | match_commutative |
2072                                          match_immediate);
2073                 break;
2074         case iro_Sub:
2075                 op1      = get_Sub_left(val);
2076                 op2      = get_Sub_right(val);
2077                 if(is_Const(op2)) {
2078                         ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2079                                    "found\n");
2080                 }
2081                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2082                                          new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2083                                          match_dest_am | match_immediate |
2084                                          match_immediate);
2085                 break;
2086         case iro_And:
2087                 op1      = get_And_left(val);
2088                 op2      = get_And_right(val);
2089                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2090                                          new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2091                                          match_dest_am | match_commutative |
2092                                          match_immediate);
2093                 break;
2094         case iro_Or:
2095                 op1      = get_Or_left(val);
2096                 op2      = get_Or_right(val);
2097                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2098                                          new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2099                                          match_dest_am | match_commutative |
2100                                          match_immediate);
2101                 break;
2102         case iro_Eor:
2103                 op1      = get_Eor_left(val);
2104                 op2      = get_Eor_right(val);
2105                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2106                                          new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2107                                          match_dest_am | match_commutative |
2108                                          match_immediate);
2109                 break;
2110         case iro_Shl:
2111                 op1      = get_Shl_left(val);
2112                 op2      = get_Shl_right(val);
2113                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2114                                          new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2115                                          match_dest_am | match_immediate);
2116                 break;
2117         case iro_Shr:
2118                 op1      = get_Shr_left(val);
2119                 op2      = get_Shr_right(val);
2120                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2121                                          new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2122                                          match_dest_am | match_immediate);
2123                 break;
2124         case iro_Shrs:
2125                 op1      = get_Shrs_left(val);
2126                 op2      = get_Shrs_right(val);
2127                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2128                                          new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2129                                          match_dest_am | match_immediate);
2130                 break;
2131         case iro_Rot:
2132                 op1      = get_Rot_left(val);
2133                 op2      = get_Rot_right(val);
2134                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2135                                          new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2136                                          match_dest_am | match_immediate);
2137                 break;
2138         /* TODO: match ROR patterns... */
2139         case iro_Psi:
2140                 new_node = try_create_SetMem(val, ptr, mem);
2141                 break;
2142         case iro_Minus:
2143                 op1      = get_Minus_op(val);
2144                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2145                 break;
2146         case iro_Not:
2147                 /* should be lowered already */
2148                 assert(mode != mode_b);
2149                 op1      = get_Not_op(val);
2150                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2151                 break;
2152         default:
2153                 return NULL;
2154         }
2155
2156         if(new_node != NULL) {
2157                 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2158                                 get_irn_pinned(node) == op_pin_state_pinned) {
2159                         set_irn_pinned(new_node, op_pin_state_pinned);
2160                 }
2161         }
2162
2163         return new_node;
2164 }
2165
2166 static int is_float_to_int32_conv(const ir_node *node)
2167 {
2168         ir_mode  *mode = get_irn_mode(node);
2169         ir_node  *conv_op;
2170         ir_mode  *conv_mode;
2171
2172         if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2173                 return 0;
2174
2175         if(!is_Conv(node))
2176                 return 0;
2177         conv_op   = get_Conv_op(node);
2178         conv_mode = get_irn_mode(conv_op);
2179
2180         if(!mode_is_float(conv_mode))
2181                 return 0;
2182
2183         return 1;
2184 }
2185
2186 /**
2187  * Transforms a Store.
2188  *
2189  * @return the created ia32 Store node
2190  */
2191 static ir_node *gen_Store(ir_node *node)
2192 {
2193         ir_node  *block     = get_nodes_block(node);
2194         ir_node  *new_block = be_transform_node(block);
2195         ir_node  *ptr       = get_Store_ptr(node);
2196         ir_node  *val       = get_Store_value(node);
2197         ir_node  *mem       = get_Store_mem(node);
2198         ir_graph *irg       = current_ir_graph;
2199         dbg_info *dbgi      = get_irn_dbg_info(node);
2200         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2201         ir_mode  *mode      = get_irn_mode(val);
2202         ir_node  *new_val;
2203         ir_node  *new_node;
2204         ia32_address_t addr;
2205
2206         /* check for destination address mode */
2207         new_node = try_create_dest_am(node);
2208         if(new_node != NULL)
2209                 return new_node;
2210
2211         /* construct store address */
2212         memset(&addr, 0, sizeof(addr));
2213         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2214
2215         if(addr.base == NULL) {
2216                 addr.base = noreg;
2217         } else {
2218                 addr.base = be_transform_node(addr.base);
2219         }
2220
2221         if(addr.index == NULL) {
2222                 addr.index = noreg;
2223         } else {
2224                 addr.index = be_transform_node(addr.index);
2225         }
2226         addr.mem = be_transform_node(mem);
2227
2228         if (mode_is_float(mode)) {
2229                 /* convs (and strict-convs) before stores are unnecessary if the mode
2230                    is the same */
2231                 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2232                         val = get_Conv_op(val);
2233                 }
2234                 new_val = be_transform_node(val);
2235                 if (ia32_cg_config.use_sse2) {
2236                         new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2237                                                       addr.index, addr.mem, new_val);
2238                 } else {
2239                         new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2240                                                     addr.index, addr.mem, new_val, mode);
2241                 }
2242         } else if(is_float_to_int32_conv(val)) {
2243                 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2244                 val = get_Conv_op(val);
2245
2246                 /* convs (and strict-convs) before stores are unnecessary if the mode
2247                    is the same */
2248                 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2249                         val = get_Conv_op(val);
2250                 }
2251                 new_val = be_transform_node(val);
2252
2253                 new_node = new_rd_ia32_vfist(dbgi, irg, new_block, addr.base,
2254                                              addr.index, addr.mem, new_val, trunc_mode);
2255         } else {
2256                 new_val = create_immediate_or_transform(val, 0);
2257                 assert(mode != mode_b);
2258
2259                 if (get_mode_size_bits(mode) == 8) {
2260                         new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2261                                                          addr.index, addr.mem, new_val);
2262                 } else {
2263                         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2264                                                      addr.index, addr.mem, new_val);
2265                 }
2266         }
2267
2268         set_irn_pinned(new_node, get_irn_pinned(node));
2269         set_ia32_op_type(new_node, ia32_AddrModeD);
2270         set_ia32_ls_mode(new_node, mode);
2271
2272         set_ia32_exc_label(new_node,
2273                            be_get_Proj_for_pn(node, pn_Store_X_except) != NULL);
2274         set_address(new_node, &addr);
2275         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2276
2277         return new_node;
2278 }
2279
2280 static ir_node *create_Switch(ir_node *node)
2281 {
2282         ir_graph *irg       = current_ir_graph;
2283         dbg_info *dbgi      = get_irn_dbg_info(node);
2284         ir_node  *block     = be_transform_node(get_nodes_block(node));
2285         ir_node  *sel       = get_Cond_selector(node);
2286         ir_node  *new_sel   = be_transform_node(sel);
2287         int       switch_min = INT_MAX;
2288         ir_node  *new_node;
2289         const ir_edge_t *edge;
2290
2291         assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2292
2293         /* determine the smallest switch case value */
2294         foreach_out_edge(node, edge) {
2295                 ir_node *proj = get_edge_src_irn(edge);
2296                 int      pn   = get_Proj_proj(proj);
2297                 if(pn < switch_min)
2298                         switch_min = pn;
2299         }
2300
2301         if (switch_min != 0) {
2302                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2303
2304                 /* if smallest switch case is not 0 we need an additional sub */
2305                 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2306                 add_ia32_am_offs_int(new_sel, -switch_min);
2307                 set_ia32_op_type(new_sel, ia32_AddrModeS);
2308
2309                 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2310         }
2311
2312         new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel,
2313                                          get_Cond_defaultProj(node));
2314         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2315
2316         return new_node;
2317 }
2318
2319 static ir_node *gen_Cond(ir_node *node) {
2320         ir_node  *block     = get_nodes_block(node);
2321         ir_node  *new_block = be_transform_node(block);
2322         ir_graph *irg       = current_ir_graph;
2323         dbg_info *dbgi      = get_irn_dbg_info(node);
2324         ir_node  *sel       = get_Cond_selector(node);
2325         ir_mode  *sel_mode  = get_irn_mode(sel);
2326         ir_node  *flags     = NULL;
2327         ir_node  *new_node;
2328         pn_Cmp    pnc;
2329
2330         if (sel_mode != mode_b) {
2331                 return create_Switch(node);
2332         }
2333
2334         /* we get flags from a cmp */
2335         flags = get_flags_node(sel, &pnc);
2336
2337         new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2338         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2339
2340         return new_node;
2341 }
2342
2343
2344
2345 /**
2346  * Transforms a CopyB node.
2347  *
2348  * @return The transformed node.
2349  */
2350 static ir_node *gen_CopyB(ir_node *node) {
2351         ir_node  *block    = be_transform_node(get_nodes_block(node));
2352         ir_node  *src      = get_CopyB_src(node);
2353         ir_node  *new_src  = be_transform_node(src);
2354         ir_node  *dst      = get_CopyB_dst(node);
2355         ir_node  *new_dst  = be_transform_node(dst);
2356         ir_node  *mem      = get_CopyB_mem(node);
2357         ir_node  *new_mem  = be_transform_node(mem);
2358         ir_node  *res      = NULL;
2359         ir_graph *irg      = current_ir_graph;
2360         dbg_info *dbgi     = get_irn_dbg_info(node);
2361         int      size      = get_type_size_bytes(get_CopyB_type(node));
2362         int      rem;
2363
2364         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2365         /* then we need the size explicitly in ECX.                    */
2366         if (size >= 32 * 4) {
2367                 rem = size & 0x3; /* size % 4 */
2368                 size >>= 2;
2369
2370                 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2371                 add_irn_dep(res, get_irg_frame(irg));
2372
2373                 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2374         } else {
2375                 if(size == 0) {
2376                         ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2377                                    node);
2378                 }
2379                 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2380         }
2381
2382         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2383
2384         return res;
2385 }
2386
2387 static ir_node *gen_be_Copy(ir_node *node)
2388 {
2389         ir_node *new_node = be_duplicate_node(node);
2390         ir_mode *mode     = get_irn_mode(new_node);
2391
2392         if (mode_needs_gp_reg(mode)) {
2393                 set_irn_mode(new_node, mode_Iu);
2394         }
2395
2396         return new_node;
2397 }
2398
2399 static ir_node *create_Fucom(ir_node *node)
2400 {
2401         ir_graph *irg       = current_ir_graph;
2402         dbg_info *dbgi      = get_irn_dbg_info(node);
2403         ir_node  *block     = get_nodes_block(node);
2404         ir_node  *new_block = be_transform_node(block);
2405         ir_node  *left      = get_Cmp_left(node);
2406         ir_node  *new_left  = be_transform_node(left);
2407         ir_node  *right     = get_Cmp_right(node);
2408         ir_node  *new_right;
2409         ir_node  *new_node;
2410
2411         if(ia32_cg_config.use_fucomi) {
2412                 new_right = be_transform_node(right);
2413                 new_node  = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2414                                                 new_right, 0);
2415                 set_ia32_commutative(new_node);
2416                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2417         } else {
2418                 if(ia32_cg_config.use_ftst && is_Const_null(right)) {
2419                         new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2420                                                            0);
2421                 } else {
2422                         new_right = be_transform_node(right);
2423                         new_node  = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2424                                                                                                  new_right, 0);
2425                 }
2426
2427                 set_ia32_commutative(new_node);
2428
2429                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2430
2431                 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2432                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2433         }
2434
2435         return new_node;
2436 }
2437
2438 static ir_node *create_Ucomi(ir_node *node)
2439 {
2440         ir_graph *irg       = current_ir_graph;
2441         dbg_info *dbgi      = get_irn_dbg_info(node);
2442         ir_node  *src_block = get_nodes_block(node);
2443         ir_node  *new_block = be_transform_node(src_block);
2444         ir_node  *left      = get_Cmp_left(node);
2445         ir_node  *right     = get_Cmp_right(node);
2446         ir_node  *new_node;
2447         ia32_address_mode_t  am;
2448         ia32_address_t      *addr = &am.addr;
2449
2450         match_arguments(&am, src_block, left, right, NULL,
2451                         match_commutative | match_am);
2452
2453         new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2454                                      addr->mem, am.new_op1, am.new_op2,
2455                                      am.ins_permuted);
2456         set_am_attributes(new_node, &am);
2457
2458         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2459
2460         new_node = fix_mem_proj(new_node, &am);
2461
2462         return new_node;
2463 }
2464
2465 /**
2466  * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2467  * to fold an and into a test node
2468  */
2469 static int can_fold_test_and(ir_node *node)
2470 {
2471         const ir_edge_t *edge;
2472
2473         /** we can only have eq and lg projs */
2474         foreach_out_edge(node, edge) {
2475                 ir_node *proj = get_edge_src_irn(edge);
2476                 pn_Cmp   pnc  = get_Proj_proj(proj);
2477                 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2478                         return 0;
2479         }
2480
2481         return 1;
2482 }
2483
2484 static ir_node *gen_Cmp(ir_node *node)
2485 {
2486         ir_graph *irg       = current_ir_graph;
2487         dbg_info *dbgi      = get_irn_dbg_info(node);
2488         ir_node  *block     = get_nodes_block(node);
2489         ir_node  *new_block = be_transform_node(block);
2490         ir_node  *left      = get_Cmp_left(node);
2491         ir_node  *right     = get_Cmp_right(node);
2492         ir_mode  *cmp_mode  = get_irn_mode(left);
2493         ir_node  *new_node;
2494         ia32_address_mode_t  am;
2495         ia32_address_t      *addr = &am.addr;
2496         int                  cmp_unsigned;
2497
2498         if(mode_is_float(cmp_mode)) {
2499                 if (ia32_cg_config.use_sse2) {
2500                         return create_Ucomi(node);
2501                 } else {
2502                         return create_Fucom(node);
2503                 }
2504         }
2505
2506         assert(mode_needs_gp_reg(cmp_mode));
2507
2508         /* we prefer the Test instruction where possible except cases where
2509          * we can use SourceAM */
2510         cmp_unsigned = !mode_is_signed(cmp_mode);
2511         if (is_Const_0(right)) {
2512                 if (is_And(left) &&
2513                                 get_irn_n_edges(left) == 1 &&
2514                                 can_fold_test_and(node)) {
2515                         /* Test(and_left, and_right) */
2516                         ir_node *and_left  = get_And_left(left);
2517                         ir_node *and_right = get_And_right(left);
2518                         ir_mode *mode      = get_irn_mode(and_left);
2519
2520                         match_arguments(&am, block, and_left, and_right, NULL,
2521                                         match_commutative |
2522                                         match_am | match_8bit_am | match_16bit_am |
2523                                         match_am_and_immediates | match_immediate |
2524                                         match_8bit | match_16bit);
2525                         if (get_mode_size_bits(mode) == 8) {
2526                                 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2527                                                                 addr->index, addr->mem, am.new_op1,
2528                                                                 am.new_op2, am.ins_permuted,
2529                                                                 cmp_unsigned);
2530                         } else {
2531                                 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2532                                                             addr->index, addr->mem, am.new_op1,
2533                                                             am.new_op2, am.ins_permuted, cmp_unsigned);
2534                         }
2535                 } else {
2536                         match_arguments(&am, block, NULL, left, NULL,
2537                                         match_am | match_8bit_am | match_16bit_am |
2538                                         match_8bit | match_16bit);
2539                         if (am.op_type == ia32_AddrModeS) {
2540                                 /* Cmp(AM, 0) */
2541                                 ir_node *imm_zero = try_create_Immediate(right, 0);
2542                                 if (get_mode_size_bits(cmp_mode) == 8) {
2543                                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2544                                                                        addr->index, addr->mem, am.new_op2,
2545                                                                        imm_zero, am.ins_permuted,
2546                                                                        cmp_unsigned);
2547                                 } else {
2548                                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2549                                                                    addr->index, addr->mem, am.new_op2,
2550                                                                    imm_zero, am.ins_permuted, cmp_unsigned);
2551                                 }
2552                         } else {
2553                                 /* Test(left, left) */
2554                                 if (get_mode_size_bits(cmp_mode) == 8) {
2555                                         new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2556                                                                         addr->index, addr->mem, am.new_op2,
2557                                                                         am.new_op2, am.ins_permuted,
2558                                                                         cmp_unsigned);
2559                                 } else {
2560                                         new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2561                                                                     addr->index, addr->mem, am.new_op2,
2562                                                                     am.new_op2, am.ins_permuted,
2563                                                                     cmp_unsigned);
2564                                 }
2565                         }
2566                 }
2567         } else {
2568                 /* Cmp(left, right) */
2569                 match_arguments(&am, block, left, right, NULL,
2570                                 match_commutative | match_am | match_8bit_am |
2571                                 match_16bit_am | match_am_and_immediates |
2572                                 match_immediate | match_8bit | match_16bit);
2573                 if (get_mode_size_bits(cmp_mode) == 8) {
2574                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2575                                                        addr->index, addr->mem, am.new_op1,
2576                                                        am.new_op2, am.ins_permuted,
2577                                                        cmp_unsigned);
2578                 } else {
2579                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2580                                                    addr->index, addr->mem, am.new_op1,
2581                                                    am.new_op2, am.ins_permuted, cmp_unsigned);
2582                 }
2583         }
2584         set_am_attributes(new_node, &am);
2585         assert(cmp_mode != NULL);
2586         set_ia32_ls_mode(new_node, cmp_mode);
2587
2588         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2589
2590         new_node = fix_mem_proj(new_node, &am);
2591
2592         return new_node;
2593 }
2594
2595 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2596                             pn_Cmp pnc)
2597 {
2598         ir_graph            *irg           = current_ir_graph;
2599         dbg_info            *dbgi          = get_irn_dbg_info(node);
2600         ir_node             *block         = get_nodes_block(node);
2601         ir_node             *new_block     = be_transform_node(block);
2602         ir_node             *val_true      = get_Psi_val(node, 0);
2603         ir_node             *val_false     = get_Psi_default(node);
2604         ir_node             *new_node;
2605         match_flags_t        match_flags;
2606         ia32_address_mode_t  am;
2607         ia32_address_t      *addr;
2608
2609         assert(ia32_cg_config.use_cmov);
2610         assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2611
2612         addr = &am.addr;
2613
2614         match_flags = match_commutative | match_am | match_16bit_am |
2615                       match_mode_neutral;
2616
2617         match_arguments(&am, block, val_false, val_true, flags, match_flags);
2618
2619         new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2620                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2621                                     am.ins_permuted, pnc);
2622         set_am_attributes(new_node, &am);
2623
2624         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2625
2626         new_node = fix_mem_proj(new_node, &am);
2627
2628         return new_node;
2629 }
2630
2631
2632
2633 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2634                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2635                                  int ins_permuted)
2636 {
2637         ir_graph *irg   = current_ir_graph;
2638         ir_node  *noreg = ia32_new_NoReg_gp(env_cg);
2639         ir_node  *nomem = new_NoMem();
2640         ir_mode  *mode  = get_irn_mode(orig_node);
2641         ir_node  *new_node;
2642
2643         new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2644         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2645
2646         /* we might need to conv the result up */
2647         if(get_mode_size_bits(mode) > 8) {
2648                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2649                                                     nomem, new_node, mode_Bu);
2650                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2651         }
2652
2653         return new_node;
2654 }
2655
2656 /**
2657  * Transforms a Psi node into CMov.
2658  *
2659  * @return The transformed node.
2660  */
2661 static ir_node *gen_Psi(ir_node *node)
2662 {
2663         dbg_info *dbgi        = get_irn_dbg_info(node);
2664         ir_node  *block       = get_nodes_block(node);
2665         ir_node  *new_block   = be_transform_node(block);
2666         ir_node  *psi_true    = get_Psi_val(node, 0);
2667         ir_node  *psi_default = get_Psi_default(node);
2668         ir_node  *cond        = get_Psi_cond(node, 0);
2669         ir_node  *flags       = NULL;
2670         ir_node  *new_node;
2671         pn_Cmp    pnc;
2672
2673         assert(get_Psi_n_conds(node) == 1);
2674         assert(get_irn_mode(cond) == mode_b);
2675         assert(mode_needs_gp_reg(get_irn_mode(node)));
2676
2677         flags = get_flags_node(cond, &pnc);
2678
2679         if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2680                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 0);
2681         } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2682                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 1);
2683         } else {
2684                 new_node = create_CMov(node, cond, flags, pnc);
2685         }
2686         return new_node;
2687 }
2688
2689
2690 /**
2691  * Create a conversion from x87 state register to general purpose.
2692  */
2693 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
2694         ir_node         *block      = be_transform_node(get_nodes_block(node));
2695         ir_node         *op         = get_Conv_op(node);
2696         ir_node         *new_op     = be_transform_node(op);
2697         ia32_code_gen_t *cg         = env_cg;
2698         ir_graph        *irg        = current_ir_graph;
2699         dbg_info        *dbgi       = get_irn_dbg_info(node);
2700         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
2701         ir_node         *trunc_mode = ia32_new_Fpu_truncate(cg);
2702         ir_mode         *mode       = get_irn_mode(node);
2703         ir_node         *fist, *load;
2704
2705         /* do a fist */
2706         fist = new_rd_ia32_vfist(dbgi, irg, block, get_irg_frame(irg), noreg,
2707                                  new_NoMem(), new_op, trunc_mode);
2708
2709         set_irn_pinned(fist, op_pin_state_floats);
2710         set_ia32_use_frame(fist);
2711         set_ia32_op_type(fist, ia32_AddrModeD);
2712
2713         assert(get_mode_size_bits(mode) <= 32);
2714         /* exception we can only store signed 32 bit integers, so for unsigned
2715            we store a 64bit (signed) integer and load the lower bits */
2716         if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
2717                 set_ia32_ls_mode(fist, mode_Ls);
2718         } else {
2719                 set_ia32_ls_mode(fist, mode_Is);
2720         }
2721         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
2722
2723         /* do a Load */
2724         load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, fist);
2725
2726         set_irn_pinned(load, op_pin_state_floats);
2727         set_ia32_use_frame(load);
2728         set_ia32_op_type(load, ia32_AddrModeS);
2729         set_ia32_ls_mode(load, mode_Is);
2730         if(get_ia32_ls_mode(fist) == mode_Ls) {
2731                 ia32_attr_t *attr = get_ia32_attr(load);
2732                 attr->data.need_64bit_stackent = 1;
2733         } else {
2734                 ia32_attr_t *attr = get_ia32_attr(load);
2735                 attr->data.need_32bit_stackent = 1;
2736         }
2737         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
2738
2739         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
2740 }
2741
2742 /**
2743  * Creates a x87 strict Conv by placing a Sore and a Load
2744  */
2745 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
2746 {
2747         ir_node  *block    = get_nodes_block(node);
2748         ir_graph *irg      = current_ir_graph;
2749         dbg_info *dbgi     = get_irn_dbg_info(node);
2750         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
2751         ir_node  *nomem    = new_NoMem();
2752         ir_node  *frame    = get_irg_frame(irg);
2753         ir_node  *store, *load;
2754         ir_node  *new_node;
2755
2756         store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
2757                                  tgt_mode);
2758         set_ia32_use_frame(store);
2759         set_ia32_op_type(store, ia32_AddrModeD);
2760         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2761
2762         load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
2763                                 tgt_mode);
2764         set_ia32_use_frame(load);
2765         set_ia32_op_type(load, ia32_AddrModeS);
2766         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
2767
2768         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
2769         return new_node;
2770 }
2771
2772 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
2773 {
2774         ir_graph *irg         = current_ir_graph;
2775         ir_node  *start_block = get_irg_start_block(irg);
2776         ir_node  *immediate   = new_rd_ia32_Immediate(NULL, irg, start_block,
2777                                                       symconst, symconst_sign, val);
2778         arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
2779
2780         return immediate;
2781 }
2782
2783 /**
2784  * Create a conversion from general purpose to x87 register
2785  */
2786 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
2787         ir_node  *src_block = get_nodes_block(node);
2788         ir_node  *block     = be_transform_node(src_block);
2789         ir_graph *irg       = current_ir_graph;
2790         dbg_info *dbgi      = get_irn_dbg_info(node);
2791         ir_node  *op        = get_Conv_op(node);
2792         ir_node  *new_op    = NULL;
2793         ir_node  *noreg;
2794         ir_node  *nomem;
2795         ir_mode  *mode;
2796         ir_mode  *store_mode;
2797         ir_node  *fild;
2798         ir_node  *store;
2799         ir_node  *new_node;
2800         int       src_bits;
2801
2802         /* fild can use source AM if the operand is a signed 32bit integer */
2803         if (src_mode == mode_Is) {
2804                 ia32_address_mode_t am;
2805
2806                 match_arguments(&am, src_block, NULL, op, NULL,
2807                                 match_am | match_try_am);
2808                 if (am.op_type == ia32_AddrModeS) {
2809                         ia32_address_t *addr = &am.addr;
2810
2811                         fild     = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
2812                                                      addr->index, addr->mem);
2813                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
2814                                               pn_ia32_vfild_res);
2815
2816                         set_am_attributes(fild, &am);
2817                         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
2818
2819                         fix_mem_proj(fild, &am);
2820
2821                         return new_node;
2822                 }
2823         }
2824         if(new_op == NULL) {
2825                 new_op = be_transform_node(op);
2826         }
2827
2828         noreg  = ia32_new_NoReg_gp(env_cg);
2829         nomem  = new_NoMem();
2830         mode   = get_irn_mode(op);
2831
2832         /* first convert to 32 bit signed if necessary */
2833         src_bits = get_mode_size_bits(src_mode);
2834         if (src_bits == 8) {
2835                 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
2836                                                   new_op, src_mode);
2837                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
2838                 mode = mode_Is;
2839         } else if (src_bits < 32) {
2840                 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
2841                                               new_op, src_mode);
2842                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
2843                 mode = mode_Is;
2844         }
2845
2846         assert(get_mode_size_bits(mode) == 32);
2847
2848         /* do a store */
2849         store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
2850                                   new_op);
2851
2852         set_ia32_use_frame(store);
2853         set_ia32_op_type(store, ia32_AddrModeD);
2854         set_ia32_ls_mode(store, mode_Iu);
2855
2856         /* exception for 32bit unsigned, do a 64bit spill+load */
2857         if(!mode_is_signed(mode)) {
2858                 ir_node *in[2];
2859                 /* store a zero */
2860                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
2861
2862                 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
2863                                                         get_irg_frame(irg), noreg, nomem,
2864                                                         zero_const);
2865
2866                 set_ia32_use_frame(zero_store);
2867                 set_ia32_op_type(zero_store, ia32_AddrModeD);
2868                 add_ia32_am_offs_int(zero_store, 4);
2869                 set_ia32_ls_mode(zero_store, mode_Iu);
2870
2871                 in[0] = zero_store;
2872                 in[1] = store;
2873
2874                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
2875                 store_mode = mode_Ls;
2876         } else {
2877                 store_mode = mode_Is;
2878         }
2879
2880         /* do a fild */
2881         fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
2882
2883         set_ia32_use_frame(fild);
2884         set_ia32_op_type(fild, ia32_AddrModeS);
2885         set_ia32_ls_mode(fild, store_mode);
2886
2887         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
2888
2889         return new_node;
2890 }
2891
2892 /**
2893  * Create a conversion from one integer mode into another one
2894  */
2895 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
2896                                 dbg_info *dbgi, ir_node *block, ir_node *op,
2897                                 ir_node *node)
2898 {
2899         ir_graph *irg       = current_ir_graph;
2900         int       src_bits  = get_mode_size_bits(src_mode);
2901         int       tgt_bits  = get_mode_size_bits(tgt_mode);
2902         ir_node  *new_block = be_transform_node(block);
2903         ir_node  *new_node;
2904         ir_mode  *smaller_mode;
2905         int       smaller_bits;
2906         ia32_address_mode_t  am;
2907         ia32_address_t      *addr = &am.addr;
2908
2909         if (src_bits < tgt_bits) {
2910                 smaller_mode = src_mode;
2911                 smaller_bits = src_bits;
2912         } else {
2913                 smaller_mode = tgt_mode;
2914                 smaller_bits = tgt_bits;
2915         }
2916
2917 #ifdef DEBUG_libfirm
2918         if(is_Const(op)) {
2919                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
2920                            op);
2921         }
2922 #endif
2923
2924         match_arguments(&am, block, NULL, op, NULL,
2925                         match_8bit | match_16bit |
2926                         match_am | match_8bit_am | match_16bit_am);
2927         if (smaller_bits == 8) {
2928                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
2929                                                     addr->index, addr->mem, am.new_op2,
2930                                                     smaller_mode);
2931         } else {
2932                 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
2933                                                 addr->index, addr->mem, am.new_op2,
2934                                                 smaller_mode);
2935         }
2936         set_am_attributes(new_node, &am);
2937         /* match_arguments assume that out-mode = in-mode, this isn't true here
2938          * so fix it */
2939         set_ia32_ls_mode(new_node, smaller_mode);
2940         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2941         new_node = fix_mem_proj(new_node, &am);
2942         return new_node;
2943 }
2944
2945 /**
2946  * Transforms a Conv node.
2947  *
2948  * @return The created ia32 Conv node
2949  */
2950 static ir_node *gen_Conv(ir_node *node) {
2951         ir_node  *block     = get_nodes_block(node);
2952         ir_node  *new_block = be_transform_node(block);
2953         ir_node  *op        = get_Conv_op(node);
2954         ir_node  *new_op    = NULL;
2955         ir_graph *irg       = current_ir_graph;
2956         dbg_info *dbgi      = get_irn_dbg_info(node);
2957         ir_mode  *src_mode  = get_irn_mode(op);
2958         ir_mode  *tgt_mode  = get_irn_mode(node);
2959         int       src_bits  = get_mode_size_bits(src_mode);
2960         int       tgt_bits  = get_mode_size_bits(tgt_mode);
2961         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2962         ir_node  *nomem     = new_rd_NoMem(irg);
2963         ir_node  *res       = NULL;
2964
2965         if (src_mode == mode_b) {
2966                 assert(mode_is_int(tgt_mode));
2967                 /* nothing to do, we already model bools as 0/1 ints */
2968                 return be_transform_node(op);
2969         }
2970
2971         if (src_mode == tgt_mode) {
2972                 if (get_Conv_strict(node)) {
2973                         if (ia32_cg_config.use_sse2) {
2974                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
2975                                 return be_transform_node(op);
2976                         }
2977                 } else {
2978                         /* this should be optimized already, but who knows... */
2979                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
2980                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
2981                         return be_transform_node(op);
2982                 }
2983         }
2984
2985         if (mode_is_float(src_mode)) {
2986                 new_op = be_transform_node(op);
2987                 /* we convert from float ... */
2988                 if (mode_is_float(tgt_mode)) {
2989                         if(src_mode == mode_E && tgt_mode == mode_D
2990                                         && !get_Conv_strict(node)) {
2991                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
2992                                 return new_op;
2993                         }
2994
2995                         /* ... to float */
2996                         if (ia32_cg_config.use_sse2) {
2997                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
2998                                 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
2999                                                              nomem, new_op);
3000                                 set_ia32_ls_mode(res, tgt_mode);
3001                         } else {
3002                                 if(get_Conv_strict(node)) {
3003                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3004                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3005                                         return res;
3006                                 }
3007                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3008                                 return new_op;
3009                         }
3010                 } else {
3011                         /* ... to int */
3012                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3013                         if (ia32_cg_config.use_sse2) {
3014                                 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3015                                                             nomem, new_op);
3016                                 set_ia32_ls_mode(res, src_mode);
3017                         } else {
3018                                 return gen_x87_fp_to_gp(node);
3019                         }
3020                 }
3021         } else {
3022                 /* we convert from int ... */
3023                 if (mode_is_float(tgt_mode)) {
3024                         /* ... to float */
3025                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3026                         if (ia32_cg_config.use_sse2) {
3027                                 new_op = be_transform_node(op);
3028                                 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3029                                                             nomem, new_op);
3030                                 set_ia32_ls_mode(res, tgt_mode);
3031                         } else {
3032                                 res = gen_x87_gp_to_fp(node, src_mode);
3033                                 if(get_Conv_strict(node)) {
3034                                         res = gen_x87_strict_conv(tgt_mode, res);
3035                                         SET_IA32_ORIG_NODE(get_Proj_pred(res),
3036                                                            ia32_get_old_node_name(env_cg, node));
3037                                 }
3038                                 return res;
3039                         }
3040                 } else if(tgt_mode == mode_b) {
3041                         /* mode_b lowering already took care that we only have 0/1 values */
3042                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3043                             src_mode, tgt_mode));
3044                         return be_transform_node(op);
3045                 } else {
3046                         /* to int */
3047                         if (src_bits == tgt_bits) {
3048                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3049                                     src_mode, tgt_mode));
3050                                 return be_transform_node(op);
3051                         }
3052
3053                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3054                         return res;
3055                 }
3056         }
3057
3058         return res;
3059 }
3060
3061 static int check_immediate_constraint(long val, char immediate_constraint_type)
3062 {
3063         switch (immediate_constraint_type) {
3064         case 0:
3065                 return 1;
3066         case 'I':
3067                 return val >= 0 && val <= 32;
3068         case 'J':
3069                 return val >= 0 && val <= 63;
3070         case 'K':
3071                 return val >= -128 && val <= 127;
3072         case 'L':
3073                 return val == 0xff || val == 0xffff;
3074         case 'M':
3075                 return val >= 0 && val <= 3;
3076         case 'N':
3077                 return val >= 0 && val <= 255;
3078         case 'O':
3079                 return val >= 0 && val <= 127;
3080         default:
3081                 break;
3082         }
3083         panic("Invalid immediate constraint found");
3084         return 0;
3085 }
3086
3087 static ir_node *try_create_Immediate(ir_node *node,
3088                                      char immediate_constraint_type)
3089 {
3090         int          minus         = 0;
3091         tarval      *offset        = NULL;
3092         int          offset_sign   = 0;
3093         long         val = 0;
3094         ir_entity   *symconst_ent  = NULL;
3095         int          symconst_sign = 0;
3096         ir_mode     *mode;
3097         ir_node     *cnst          = NULL;
3098         ir_node     *symconst      = NULL;
3099         ir_node     *new_node;
3100
3101         mode = get_irn_mode(node);
3102         if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3103                 return NULL;
3104         }
3105
3106         if(is_Minus(node)) {
3107                 minus = 1;
3108                 node  = get_Minus_op(node);
3109         }
3110
3111         if(is_Const(node)) {
3112                 cnst        = node;
3113                 symconst    = NULL;
3114                 offset_sign = minus;
3115         } else if(is_SymConst(node)) {
3116                 cnst          = NULL;
3117                 symconst      = node;
3118                 symconst_sign = minus;
3119         } else if(is_Add(node)) {
3120                 ir_node *left  = get_Add_left(node);
3121                 ir_node *right = get_Add_right(node);
3122                 if(is_Const(left) && is_SymConst(right)) {
3123                         cnst          = left;
3124                         symconst      = right;
3125                         symconst_sign = minus;
3126                         offset_sign   = minus;
3127                 } else if(is_SymConst(left) && is_Const(right)) {
3128                         cnst          = right;
3129                         symconst      = left;
3130                         symconst_sign = minus;
3131                         offset_sign   = minus;
3132                 }
3133         } else if(is_Sub(node)) {
3134                 ir_node *left  = get_Sub_left(node);
3135                 ir_node *right = get_Sub_right(node);
3136                 if(is_Const(left) && is_SymConst(right)) {
3137                         cnst          = left;
3138                         symconst      = right;
3139                         symconst_sign = !minus;
3140                         offset_sign   = minus;
3141                 } else if(is_SymConst(left) && is_Const(right)) {
3142                         cnst          = right;
3143                         symconst      = left;
3144                         symconst_sign = minus;
3145                         offset_sign   = !minus;
3146                 }
3147         } else {
3148                 return NULL;
3149         }
3150
3151         if(cnst != NULL) {
3152                 offset = get_Const_tarval(cnst);
3153                 if(tarval_is_long(offset)) {
3154                         val = get_tarval_long(offset);
3155                 } else {
3156                         ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3157                                    "long?\n", cnst);
3158                         return NULL;
3159                 }
3160
3161                 if(!check_immediate_constraint(val, immediate_constraint_type))
3162                         return NULL;
3163         }
3164         if(symconst != NULL) {
3165                 if(immediate_constraint_type != 0) {
3166                         /* we need full 32bits for symconsts */
3167                         return NULL;
3168                 }
3169
3170                 /* unfortunately the assembler/linker doesn't support -symconst */
3171                 if(symconst_sign)
3172                         return NULL;
3173
3174                 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3175                         return NULL;
3176                 symconst_ent = get_SymConst_entity(symconst);
3177         }
3178         if(cnst == NULL && symconst == NULL)
3179                 return NULL;
3180
3181         if(offset_sign && offset != NULL) {
3182                 offset = tarval_neg(offset);
3183         }
3184
3185         new_node = create_Immediate(symconst_ent, symconst_sign, val);
3186
3187         return new_node;
3188 }
3189
3190 static ir_node *create_immediate_or_transform(ir_node *node,
3191                                               char immediate_constraint_type)
3192 {
3193         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3194         if (new_node == NULL) {
3195                 new_node = be_transform_node(node);
3196         }
3197         return new_node;
3198 }
3199
3200 static const arch_register_req_t no_register_req = {
3201         arch_register_req_type_none,
3202         NULL,                         /* regclass */
3203         NULL,                         /* limit bitset */
3204         0,                            /* same pos */
3205         0                             /* different pos */
3206 };
3207
3208 /**
3209  * An assembler constraint.
3210  */
3211 typedef struct constraint_t constraint_t;
3212 struct constraint_t {
3213         int                         is_in;
3214         int                         n_outs;
3215         const arch_register_req_t **out_reqs;
3216
3217         const arch_register_req_t  *req;
3218         unsigned                    immediate_possible;
3219         char                        immediate_type;
3220 };
3221
3222 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3223 {
3224         int                          immediate_possible = 0;
3225         char                         immediate_type     = 0;
3226         unsigned                     limited            = 0;
3227         const arch_register_class_t *cls                = NULL;
3228         ir_graph                    *irg = current_ir_graph;
3229         struct obstack              *obst = get_irg_obstack(irg);
3230         arch_register_req_t         *req;
3231         unsigned                    *limited_ptr = NULL;
3232         int                          p;
3233         int                          same_as = -1;
3234
3235         /* TODO: replace all the asserts with nice error messages */
3236
3237         if(*c == 0) {
3238                 /* a memory constraint: no need to do anything in backend about it
3239                  * (the dependencies are already respected by the memory edge of
3240                  * the node) */
3241                 constraint->req    = &no_register_req;
3242                 return;
3243         }
3244
3245         while(*c != 0) {
3246                 switch(*c) {
3247                 case ' ':
3248                 case '\t':
3249                 case '\n':
3250                         break;
3251
3252                 case 'a':
3253                         assert(cls == NULL ||
3254                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3255                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3256                         limited |= 1 << REG_EAX;
3257                         break;
3258                 case 'b':
3259                         assert(cls == NULL ||
3260                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3261                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3262                         limited |= 1 << REG_EBX;
3263                         break;
3264                 case 'c':
3265                         assert(cls == NULL ||
3266                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3267                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3268                         limited |= 1 << REG_ECX;
3269                         break;
3270                 case 'd':
3271                         assert(cls == NULL ||
3272                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3273                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3274                         limited |= 1 << REG_EDX;
3275                         break;
3276                 case 'D':
3277                         assert(cls == NULL ||
3278                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3279                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3280                         limited |= 1 << REG_EDI;
3281                         break;
3282                 case 'S':
3283                         assert(cls == NULL ||
3284                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3285                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3286                         limited |= 1 << REG_ESI;
3287                         break;
3288                 case 'Q':
3289                 case 'q': /* q means lower part of the regs only, this makes no
3290                                    * difference to Q for us (we only assigne whole registers) */
3291                         assert(cls == NULL ||
3292                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3293                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3294                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3295                                    1 << REG_EDX;
3296                         break;
3297                 case 'A':
3298                         assert(cls == NULL ||
3299                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3300                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3301                         limited |= 1 << REG_EAX | 1 << REG_EDX;
3302                         break;
3303                 case 'l':
3304                         assert(cls == NULL ||
3305                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3306                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3307                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3308                                    1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3309                                    1 << REG_EBP;
3310                         break;
3311
3312                 case 'R':
3313                 case 'r':
3314                 case 'p':
3315                         assert(cls == NULL);
3316                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3317                         break;
3318
3319                 case 'f':
3320                 case 't':
3321                 case 'u':
3322                         /* TODO: mark values so the x87 simulator knows about t and u */
3323                         assert(cls == NULL);
3324                         cls = &ia32_reg_classes[CLASS_ia32_vfp];
3325                         break;
3326
3327                 case 'Y':
3328                 case 'x':
3329                         assert(cls == NULL);
3330                         /* TODO: check that sse2 is supported */
3331                         cls = &ia32_reg_classes[CLASS_ia32_xmm];
3332                         break;
3333
3334                 case 'I':
3335                 case 'J':
3336                 case 'K':
3337                 case 'L':
3338                 case 'M':
3339                 case 'N':
3340                 case 'O':
3341                         assert(!immediate_possible);
3342                         immediate_possible = 1;
3343                         immediate_type     = *c;
3344                         break;
3345                 case 'n':
3346                 case 'i':
3347                         assert(!immediate_possible);
3348                         immediate_possible = 1;
3349                         break;
3350
3351                 case 'g':
3352                         assert(!immediate_possible && cls == NULL);
3353                         immediate_possible = 1;
3354                         cls                = &ia32_reg_classes[CLASS_ia32_gp];
3355                         break;
3356
3357                 case '0':
3358                 case '1':
3359                 case '2':
3360                 case '3':
3361                 case '4':
3362                 case '5':
3363                 case '6':
3364                 case '7':
3365                 case '8':
3366                 case '9':
3367                         assert(constraint->is_in && "can only specify same constraint "
3368                                "on input");
3369
3370                         sscanf(c, "%d%n", &same_as, &p);
3371                         if(same_as >= 0) {
3372                                 c += p;
3373                                 continue;
3374                         }
3375                         break;
3376
3377                 case 'm':
3378                         /* memory constraint no need to do anything in backend about it
3379                          * (the dependencies are already respected by the memory edge of
3380                          * the node) */
3381                         constraint->req    = &no_register_req;
3382                         return;
3383
3384                 case 'E': /* no float consts yet */
3385                 case 'F': /* no float consts yet */
3386                 case 's': /* makes no sense on x86 */
3387                 case 'X': /* we can't support that in firm */
3388                 case 'o':
3389                 case 'V':
3390                 case '<': /* no autodecrement on x86 */
3391                 case '>': /* no autoincrement on x86 */
3392                 case 'C': /* sse constant not supported yet */
3393                 case 'G': /* 80387 constant not supported yet */
3394                 case 'y': /* we don't support mmx registers yet */
3395                 case 'Z': /* not available in 32 bit mode */
3396                 case 'e': /* not available in 32 bit mode */
3397                         panic("unsupported asm constraint '%c' found in (%+F)",
3398                               *c, current_ir_graph);
3399                         break;
3400                 default:
3401                         panic("unknown asm constraint '%c' found in (%+F)", *c,
3402                               current_ir_graph);
3403                         break;
3404                 }
3405                 ++c;
3406         }
3407
3408         if(same_as >= 0) {
3409                 const arch_register_req_t *other_constr;
3410
3411                 assert(cls == NULL && "same as and register constraint not supported");
3412                 assert(!immediate_possible && "same as and immediate constraint not "
3413                        "supported");
3414                 assert(same_as < constraint->n_outs && "wrong constraint number in "
3415                        "same_as constraint");
3416
3417                 other_constr         = constraint->out_reqs[same_as];
3418
3419                 req                  = obstack_alloc(obst, sizeof(req[0]));
3420                 req->cls             = other_constr->cls;
3421                 req->type            = arch_register_req_type_should_be_same;
3422                 req->limited         = NULL;
3423                 req->other_same      = 1U << pos;
3424                 req->other_different = 0;
3425
3426                 /* switch constraints. This is because in firm we have same_as
3427                  * constraints on the output constraints while in the gcc asm syntax
3428                  * they are specified on the input constraints */
3429                 constraint->req               = other_constr;
3430                 constraint->out_reqs[same_as] = req;
3431                 constraint->immediate_possible = 0;
3432                 return;
3433         }
3434
3435         if(immediate_possible && cls == NULL) {
3436                 cls = &ia32_reg_classes[CLASS_ia32_gp];
3437         }
3438         assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3439         assert(cls != NULL);
3440
3441         if(immediate_possible) {
3442                 assert(constraint->is_in
3443                        && "immediate make no sense for output constraints");
3444         }
3445         /* todo: check types (no float input on 'r' constrained in and such... */
3446
3447         if(limited != 0) {
3448                 req          = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3449                 limited_ptr  = (unsigned*) (req+1);
3450         } else {
3451                 req = obstack_alloc(obst, sizeof(req[0]));
3452         }
3453         memset(req, 0, sizeof(req[0]));
3454
3455         if(limited != 0) {
3456                 req->type    = arch_register_req_type_limited;
3457                 *limited_ptr = limited;
3458                 req->limited = limited_ptr;
3459         } else {
3460                 req->type    = arch_register_req_type_normal;
3461         }
3462         req->cls = cls;
3463
3464         constraint->req                = req;
3465         constraint->immediate_possible = immediate_possible;
3466         constraint->immediate_type     = immediate_type;
3467 }
3468
3469 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3470                           const char *c)
3471 {
3472         (void) node;
3473         (void) pos;
3474         (void) constraint;
3475         (void) c;
3476         panic("Clobbers not supported yet");
3477 }
3478
3479 static int is_memory_op(const ir_asm_constraint *constraint)
3480 {
3481         ident      *id  = constraint->constraint;
3482         const char *str = get_id_str(id);
3483         const char *c;
3484
3485         for(c = str; *c != '\0'; ++c) {
3486                 if(*c == 'm')
3487                         return 1;
3488         }
3489
3490         return 0;
3491 }
3492
3493 /**
3494  * generates code for a ASM node
3495  */
3496 static ir_node *gen_ASM(ir_node *node)
3497 {
3498         int                         i, arity;
3499         ir_graph                   *irg       = current_ir_graph;
3500         ir_node                    *block     = get_nodes_block(node);
3501         ir_node                    *new_block = be_transform_node(block);
3502         dbg_info                   *dbgi      = get_irn_dbg_info(node);
3503         ir_node                   **in;
3504         ir_node                    *new_node;
3505         int                         out_arity;
3506         int                         n_out_constraints;
3507         int                         n_clobbers;
3508         const arch_register_req_t **out_reg_reqs;
3509         const arch_register_req_t **in_reg_reqs;
3510         ia32_asm_reg_t             *register_map;
3511         unsigned                    reg_map_size = 0;
3512         struct obstack             *obst;
3513         const ir_asm_constraint    *in_constraints;
3514         const ir_asm_constraint    *out_constraints;
3515         ident                     **clobbers;
3516         constraint_t                parsed_constraint;
3517
3518         arity = get_irn_arity(node);
3519         in    = alloca(arity * sizeof(in[0]));
3520         memset(in, 0, arity * sizeof(in[0]));
3521
3522         n_out_constraints = get_ASM_n_output_constraints(node);
3523         n_clobbers        = get_ASM_n_clobbers(node);
3524         out_arity         = n_out_constraints + n_clobbers;
3525
3526         in_constraints  = get_ASM_input_constraints(node);
3527         out_constraints = get_ASM_output_constraints(node);
3528         clobbers        = get_ASM_clobbers(node);
3529
3530         /* construct output constraints */
3531         obst         = get_irg_obstack(irg);
3532         out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3533         parsed_constraint.out_reqs = out_reg_reqs;
3534         parsed_constraint.n_outs   = n_out_constraints;
3535         parsed_constraint.is_in    = 0;
3536
3537         for(i = 0; i < out_arity; ++i) {
3538                 const char   *c;
3539
3540                 if(i < n_out_constraints) {
3541                         const ir_asm_constraint *constraint = &out_constraints[i];
3542                         c = get_id_str(constraint->constraint);
3543                         parse_asm_constraint(i, &parsed_constraint, c);
3544
3545                         if(constraint->pos > reg_map_size)
3546                                 reg_map_size = constraint->pos;
3547                 } else {
3548                         ident *glob_id = clobbers [i - n_out_constraints];
3549                         c = get_id_str(glob_id);
3550                         parse_clobber(node, i, &parsed_constraint, c);
3551                 }
3552
3553                 out_reg_reqs[i] = parsed_constraint.req;
3554         }
3555
3556         /* construct input constraints */
3557         in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
3558         parsed_constraint.is_in = 1;
3559         for(i = 0; i < arity; ++i) {
3560                 const ir_asm_constraint   *constraint = &in_constraints[i];
3561                 ident                     *constr_id  = constraint->constraint;
3562                 const char                *c          = get_id_str(constr_id);
3563
3564                 parse_asm_constraint(i, &parsed_constraint, c);
3565                 in_reg_reqs[i] = parsed_constraint.req;
3566
3567                 if(constraint->pos > reg_map_size)
3568                         reg_map_size = constraint->pos;
3569
3570                 if(parsed_constraint.immediate_possible) {
3571                         ir_node *pred      = get_irn_n(node, i);
3572                         char     imm_type  = parsed_constraint.immediate_type;
3573                         ir_node *immediate = try_create_Immediate(pred, imm_type);
3574
3575                         if(immediate != NULL) {
3576                                 in[i] = immediate;
3577                         }
3578                 }
3579         }
3580         reg_map_size++;
3581
3582         register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
3583         memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
3584
3585         for(i = 0; i < n_out_constraints; ++i) {
3586                 const ir_asm_constraint *constraint = &out_constraints[i];
3587                 unsigned                 pos        = constraint->pos;
3588
3589                 assert(pos < reg_map_size);
3590                 register_map[pos].use_input = 0;
3591                 register_map[pos].valid     = 1;
3592                 register_map[pos].memory    = is_memory_op(constraint);
3593                 register_map[pos].inout_pos = i;
3594                 register_map[pos].mode      = constraint->mode;
3595         }
3596
3597         /* transform inputs */
3598         for(i = 0; i < arity; ++i) {
3599                 const ir_asm_constraint *constraint = &in_constraints[i];
3600                 unsigned                 pos        = constraint->pos;
3601                 ir_node                 *pred       = get_irn_n(node, i);
3602                 ir_node                 *transformed;
3603
3604                 assert(pos < reg_map_size);
3605                 register_map[pos].use_input = 1;
3606                 register_map[pos].valid     = 1;
3607                 register_map[pos].memory    = is_memory_op(constraint);
3608                 register_map[pos].inout_pos = i;
3609                 register_map[pos].mode      = constraint->mode;
3610
3611                 if(in[i] != NULL)
3612                         continue;
3613
3614                 transformed = be_transform_node(pred);
3615                 in[i]       = transformed;
3616         }
3617
3618         new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
3619                                    get_ASM_text(node), register_map);
3620
3621         set_ia32_out_req_all(new_node, out_reg_reqs);
3622         set_ia32_in_req_all(new_node, in_reg_reqs);
3623
3624         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3625
3626         return new_node;
3627 }
3628
3629 /**
3630  * Transforms a FrameAddr into an ia32 Add.
3631  */
3632 static ir_node *gen_be_FrameAddr(ir_node *node) {
3633         ir_node  *block  = be_transform_node(get_nodes_block(node));
3634         ir_node  *op     = be_get_FrameAddr_frame(node);
3635         ir_node  *new_op = be_transform_node(op);
3636         ir_graph *irg    = current_ir_graph;
3637         dbg_info *dbgi   = get_irn_dbg_info(node);
3638         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
3639         ir_node  *new_node;
3640
3641         new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3642         set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3643         set_ia32_use_frame(new_node);
3644
3645         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3646
3647         return new_node;
3648 }
3649
3650 /**
3651  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3652  */
3653 static ir_node *gen_be_Return(ir_node *node) {
3654         ir_graph  *irg     = current_ir_graph;
3655         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
3656         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
3657         ir_entity *ent     = get_irg_entity(irg);
3658         ir_type   *tp      = get_entity_type(ent);
3659         dbg_info  *dbgi;
3660         ir_node   *block;
3661         ir_type   *res_type;
3662         ir_mode   *mode;
3663         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
3664         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
3665         ir_node   *noreg;
3666         ir_node   **in;
3667         int       pn_ret_val, pn_ret_mem, arity, i;
3668
3669         assert(ret_val != NULL);
3670         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3671                 return be_duplicate_node(node);
3672         }
3673
3674         res_type = get_method_res_type(tp, 0);
3675
3676         if (! is_Primitive_type(res_type)) {
3677                 return be_duplicate_node(node);
3678         }
3679
3680         mode = get_type_mode(res_type);
3681         if (! mode_is_float(mode)) {
3682                 return be_duplicate_node(node);
3683         }
3684
3685         assert(get_method_n_ress(tp) == 1);
3686
3687         pn_ret_val = get_Proj_proj(ret_val);
3688         pn_ret_mem = get_Proj_proj(ret_mem);
3689
3690         /* get the Barrier */
3691         barrier = get_Proj_pred(ret_val);
3692
3693         /* get result input of the Barrier */
3694         ret_val     = get_irn_n(barrier, pn_ret_val);
3695         new_ret_val = be_transform_node(ret_val);
3696
3697         /* get memory input of the Barrier */
3698         ret_mem     = get_irn_n(barrier, pn_ret_mem);
3699         new_ret_mem = be_transform_node(ret_mem);
3700
3701         frame = get_irg_frame(irg);
3702
3703         dbgi  = get_irn_dbg_info(barrier);
3704         block = be_transform_node(get_nodes_block(barrier));
3705
3706         noreg = ia32_new_NoReg_gp(env_cg);
3707
3708         /* store xmm0 onto stack */
3709         sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3710                                              new_ret_mem, new_ret_val);
3711         set_ia32_ls_mode(sse_store, mode);
3712         set_ia32_op_type(sse_store, ia32_AddrModeD);
3713         set_ia32_use_frame(sse_store);
3714
3715         /* load into x87 register */
3716         fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3717         set_ia32_op_type(fld, ia32_AddrModeS);
3718         set_ia32_use_frame(fld);
3719
3720         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3721         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3722
3723         /* create a new barrier */
3724         arity = get_irn_arity(barrier);
3725         in = alloca(arity * sizeof(in[0]));
3726         for (i = 0; i < arity; ++i) {
3727                 ir_node *new_in;
3728
3729                 if (i == pn_ret_val) {
3730                         new_in = fld;
3731                 } else if (i == pn_ret_mem) {
3732                         new_in = mproj;
3733                 } else {
3734                         ir_node *in = get_irn_n(barrier, i);
3735                         new_in = be_transform_node(in);
3736                 }
3737                 in[i] = new_in;
3738         }
3739
3740         new_barrier = new_ir_node(dbgi, irg, block,
3741                                   get_irn_op(barrier), get_irn_mode(barrier),
3742                                   arity, in);
3743         copy_node_attr(barrier, new_barrier);
3744         be_duplicate_deps(barrier, new_barrier);
3745         be_set_transformed_node(barrier, new_barrier);
3746         mark_irn_visited(barrier);
3747
3748         /* transform normally */
3749         return be_duplicate_node(node);
3750 }
3751
3752 /**
3753  * Transform a be_AddSP into an ia32_SubSP.
3754  */
3755 static ir_node *gen_be_AddSP(ir_node *node)
3756 {
3757         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
3758         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3759
3760         return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3761 }
3762
3763 /**
3764  * Transform a be_SubSP into an ia32_AddSP
3765  */
3766 static ir_node *gen_be_SubSP(ir_node *node)
3767 {
3768         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
3769         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3770
3771         return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3772 }
3773
3774 /**
3775  * This function just sets the register for the Unknown node
3776  * as this is not done during register allocation because Unknown
3777  * is an "ignore" node.
3778  */
3779 static ir_node *gen_Unknown(ir_node *node) {
3780         ir_mode *mode = get_irn_mode(node);
3781
3782         if (mode_is_float(mode)) {
3783                 if (ia32_cg_config.use_sse2) {
3784                         return ia32_new_Unknown_xmm(env_cg);
3785                 } else {
3786                         /* Unknown nodes are buggy in x87 sim, use zero for now... */
3787                         ir_graph *irg   = current_ir_graph;
3788                         dbg_info *dbgi  = get_irn_dbg_info(node);
3789                         ir_node  *block = get_irg_start_block(irg);
3790                         return new_rd_ia32_vfldz(dbgi, irg, block);
3791                 }
3792         } else if (mode_needs_gp_reg(mode)) {
3793                 return ia32_new_Unknown_gp(env_cg);
3794         } else {
3795                 panic("unsupported Unknown-Mode");
3796         }
3797         return NULL;
3798 }
3799
3800 /**
3801  * Change some phi modes
3802  */
3803 static ir_node *gen_Phi(ir_node *node) {
3804         ir_node  *block = be_transform_node(get_nodes_block(node));
3805         ir_graph *irg   = current_ir_graph;
3806         dbg_info *dbgi  = get_irn_dbg_info(node);
3807         ir_mode  *mode  = get_irn_mode(node);
3808         ir_node  *phi;
3809
3810         if(mode_needs_gp_reg(mode)) {
3811                 /* we shouldn't have any 64bit stuff around anymore */
3812                 assert(get_mode_size_bits(mode) <= 32);
3813                 /* all integer operations are on 32bit registers now */
3814                 mode = mode_Iu;
3815         } else if(mode_is_float(mode)) {
3816                 if (ia32_cg_config.use_sse2) {
3817                         mode = mode_xmm;
3818                 } else {
3819                         mode = mode_vfp;
3820                 }
3821         }
3822
3823         /* phi nodes allow loops, so we use the old arguments for now
3824          * and fix this later */
3825         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3826                           get_irn_in(node) + 1);
3827         copy_node_attr(node, phi);
3828         be_duplicate_deps(node, phi);
3829
3830         be_set_transformed_node(node, phi);
3831         be_enqueue_preds(node);
3832
3833         return phi;
3834 }
3835
3836 /**
3837  * Transform IJmp
3838  */
3839 static ir_node *gen_IJmp(ir_node *node)
3840 {
3841         ir_node  *block     = get_nodes_block(node);
3842         ir_node  *new_block = be_transform_node(block);
3843         ir_graph *irg       = current_ir_graph;
3844         dbg_info *dbgi      = get_irn_dbg_info(node);
3845         ir_node  *op        = get_IJmp_target(node);
3846         ir_node  *new_node;
3847         ia32_address_mode_t  am;
3848         ia32_address_t      *addr = &am.addr;
3849
3850         assert(get_irn_mode(op) == mode_P);
3851
3852         match_arguments(&am, block, NULL, op, NULL,
3853                         match_am | match_8bit_am | match_16bit_am |
3854                         match_immediate | match_8bit | match_16bit);
3855
3856         new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
3857                                     addr->mem, am.new_op2);
3858         set_am_attributes(new_node, &am);
3859         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3860
3861         new_node = fix_mem_proj(new_node, &am);
3862
3863         return new_node;
3864 }
3865
3866 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3867                                      ir_node *mem);
3868
3869 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3870                                       ir_node *val, ir_node *mem);
3871
3872 /**
3873  * Transforms a lowered Load into a "real" one.
3874  */
3875 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
3876 {
3877         ir_node  *block   = be_transform_node(get_nodes_block(node));
3878         ir_node  *ptr     = get_irn_n(node, 0);
3879         ir_node  *new_ptr = be_transform_node(ptr);
3880         ir_node  *mem     = get_irn_n(node, 1);
3881         ir_node  *new_mem = be_transform_node(mem);
3882         ir_graph *irg     = current_ir_graph;
3883         dbg_info *dbgi    = get_irn_dbg_info(node);
3884         ir_mode  *mode    = get_ia32_ls_mode(node);
3885         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
3886         ir_node  *new_op;
3887
3888         new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
3889
3890         set_ia32_op_type(new_op, ia32_AddrModeS);
3891         set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
3892         set_ia32_am_scale(new_op, get_ia32_am_scale(node));
3893         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
3894         if (is_ia32_am_sc_sign(node))
3895                 set_ia32_am_sc_sign(new_op);
3896         set_ia32_ls_mode(new_op, mode);
3897         if (is_ia32_use_frame(node)) {
3898                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3899                 set_ia32_use_frame(new_op);
3900         }
3901
3902         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3903
3904         return new_op;
3905 }
3906
3907 /**
3908  * Transforms a lowered Store into a "real" one.
3909  */
3910 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
3911 {
3912         ir_node  *block   = be_transform_node(get_nodes_block(node));
3913         ir_node  *ptr     = get_irn_n(node, 0);
3914         ir_node  *new_ptr = be_transform_node(ptr);
3915         ir_node  *val     = get_irn_n(node, 1);
3916         ir_node  *new_val = be_transform_node(val);
3917         ir_node  *mem     = get_irn_n(node, 2);
3918         ir_node  *new_mem = be_transform_node(mem);
3919         ir_graph *irg     = current_ir_graph;
3920         dbg_info *dbgi    = get_irn_dbg_info(node);
3921         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
3922         ir_mode  *mode    = get_ia32_ls_mode(node);
3923         ir_node  *new_op;
3924         long     am_offs;
3925
3926         new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
3927
3928         am_offs = get_ia32_am_offs_int(node);
3929         add_ia32_am_offs_int(new_op, am_offs);
3930
3931         set_ia32_op_type(new_op, ia32_AddrModeD);
3932         set_ia32_ls_mode(new_op, mode);
3933         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3934         set_ia32_use_frame(new_op);
3935
3936         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3937
3938         return new_op;
3939 }
3940
3941 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3942 {
3943         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
3944         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3945
3946         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3947                                match_immediate | match_mode_neutral);
3948 }
3949
3950 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3951 {
3952         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
3953         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3954         return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3955                                match_immediate);
3956 }
3957
3958 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3959 {
3960         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
3961         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3962         return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3963                                match_immediate);
3964 }
3965
3966 static ir_node *gen_ia32_l_Add(ir_node *node) {
3967         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
3968         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
3969         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3970                         match_commutative | match_am | match_immediate |
3971                         match_mode_neutral);
3972
3973         if(is_Proj(lowered)) {
3974                 lowered = get_Proj_pred(lowered);
3975         } else {
3976                 assert(is_ia32_Add(lowered));
3977                 set_irn_mode(lowered, mode_T);
3978         }
3979
3980         return lowered;
3981 }
3982
3983 static ir_node *gen_ia32_l_Adc(ir_node *node)
3984 {
3985         return gen_binop_flags(node, new_rd_ia32_Adc,
3986                         match_commutative | match_am | match_immediate |
3987                         match_mode_neutral);
3988 }
3989
3990 /**
3991  * Transforms an ia32_l_vfild into a "real" ia32_vfild node
3992  *
3993  * @param node   The node to transform
3994  * @return the created ia32 vfild node
3995  */
3996 static ir_node *gen_ia32_l_vfild(ir_node *node) {
3997         return gen_lowered_Load(node, new_rd_ia32_vfild);
3998 }
3999
4000 /**
4001  * Transforms an ia32_l_Load into a "real" ia32_Load node
4002  *
4003  * @param node   The node to transform
4004  * @return the created ia32 Load node
4005  */
4006 static ir_node *gen_ia32_l_Load(ir_node *node) {
4007         return gen_lowered_Load(node, new_rd_ia32_Load);
4008 }
4009
4010 /**
4011  * Transforms an ia32_l_Store into a "real" ia32_Store node
4012  *
4013  * @param node   The node to transform
4014  * @return the created ia32 Store node
4015  */
4016 static ir_node *gen_ia32_l_Store(ir_node *node) {
4017         return gen_lowered_Store(node, new_rd_ia32_Store);
4018 }
4019
4020 /**
4021  * Transforms a l_vfist into a "real" vfist node.
4022  *
4023  * @param node   The node to transform
4024  * @return the created ia32 vfist node
4025  */
4026 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4027         ir_node  *block      = be_transform_node(get_nodes_block(node));
4028         ir_node  *ptr        = get_irn_n(node, 0);
4029         ir_node  *new_ptr    = be_transform_node(ptr);
4030         ir_node  *val        = get_irn_n(node, 1);
4031         ir_node  *new_val    = be_transform_node(val);
4032         ir_node  *mem        = get_irn_n(node, 2);
4033         ir_node  *new_mem    = be_transform_node(mem);
4034         ir_graph *irg        = current_ir_graph;
4035         dbg_info *dbgi       = get_irn_dbg_info(node);
4036         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4037         ir_mode  *mode       = get_ia32_ls_mode(node);
4038         ir_node  *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4039         ir_node  *new_op;
4040         long     am_offs;
4041
4042         new_op = new_rd_ia32_vfist(dbgi, irg, block, new_ptr, noreg, new_mem,
4043                                    new_val, trunc_mode);
4044
4045         am_offs = get_ia32_am_offs_int(node);
4046         add_ia32_am_offs_int(new_op, am_offs);
4047
4048         set_ia32_op_type(new_op, ia32_AddrModeD);
4049         set_ia32_ls_mode(new_op, mode);
4050         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4051         set_ia32_use_frame(new_op);
4052
4053         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4054
4055         return new_op;
4056 }
4057
4058 /**
4059  * Transforms a l_MulS into a "real" MulS node.
4060  *
4061  * @return the created ia32 Mul node
4062  */
4063 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4064         ir_node *left  = get_binop_left(node);
4065         ir_node *right = get_binop_right(node);
4066
4067         return gen_binop(node, left, right, new_rd_ia32_Mul,
4068                          match_commutative | match_am | match_mode_neutral);
4069 }
4070
4071 /**
4072  * Transforms a l_IMulS into a "real" IMul1OPS node.
4073  *
4074  * @return the created ia32 IMul1OP node
4075  */
4076 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4077         ir_node  *left      = get_binop_left(node);
4078         ir_node  *right     = get_binop_right(node);
4079
4080         return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4081                          match_commutative | match_am | match_mode_neutral);
4082 }
4083
4084 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4085         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_left);
4086         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_right);
4087         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4088                         match_am | match_immediate | match_mode_neutral);
4089
4090         if(is_Proj(lowered)) {
4091                 lowered = get_Proj_pred(lowered);
4092         } else {
4093                 assert(is_ia32_Sub(lowered));
4094                 set_irn_mode(lowered, mode_T);
4095         }
4096
4097         return lowered;
4098 }
4099
4100 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4101         return gen_binop_flags(node, new_rd_ia32_Sbb,
4102                         match_am | match_immediate | match_mode_neutral);
4103 }
4104
4105 /**
4106  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4107  * op1 - target to be shifted
4108  * op2 - contains bits to be shifted into target
4109  * op3 - shift count
4110  * Only op3 can be an immediate.
4111  */
4112 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4113                                          ir_node *low, ir_node *count)
4114 {
4115         ir_node  *block     = get_nodes_block(node);
4116         ir_node  *new_block = be_transform_node(block);
4117         ir_graph *irg       = current_ir_graph;
4118         dbg_info *dbgi      = get_irn_dbg_info(node);
4119         ir_node  *new_high  = be_transform_node(high);
4120         ir_node  *new_low   = be_transform_node(low);
4121         ir_node  *new_count;
4122         ir_node  *new_node;
4123
4124         /* the shift amount can be any mode that is bigger than 5 bits, since all
4125          * other bits are ignored anyway */
4126         while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4127                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4128                 count = get_Conv_op(count);
4129         }
4130         new_count = create_immediate_or_transform(count, 0);
4131
4132         if (is_ia32_l_ShlD(node)) {
4133                 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4134                                             new_count);
4135         } else {
4136                 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4137                                             new_count);
4138         }
4139         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4140
4141         return new_node;
4142 }
4143
4144 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4145 {
4146         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
4147         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
4148         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4149         return gen_lowered_64bit_shifts(node, high, low, count);
4150 }
4151
4152 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4153 {
4154         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
4155         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
4156         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4157         return gen_lowered_64bit_shifts(node, high, low, count);
4158 }
4159
4160 /**
4161  * In case SSE Unit is used, the node is transformed into a vfst + xLoad.
4162  */
4163 static ir_node *gen_ia32_l_X87toSSE(ir_node *node) {
4164         ir_node         *block   = be_transform_node(get_nodes_block(node));
4165         ir_node         *val     = get_irn_n(node, 1);
4166         ir_node         *new_val = be_transform_node(val);
4167         ir_node         *res     = NULL;
4168         ir_graph        *irg     = current_ir_graph;
4169         dbg_info        *dbgi;
4170         ir_node         *noreg, *new_ptr, *new_mem;
4171         ir_node         *ptr, *mem;
4172
4173         if (ia32_cg_config.use_sse2) {
4174                 return new_val;
4175         }
4176
4177         mem     = get_irn_n(node, 2);
4178         new_mem = be_transform_node(mem);
4179         ptr     = get_irn_n(node, 0);
4180         new_ptr = be_transform_node(ptr);
4181         noreg   = ia32_new_NoReg_gp(env_cg);
4182         dbgi    = get_irn_dbg_info(node);
4183
4184         /* Store x87 -> MEM */
4185         res = new_rd_ia32_vfst(dbgi, irg, block, new_ptr, noreg, new_mem, new_val,
4186                                get_ia32_ls_mode(node));
4187         set_ia32_frame_ent(res, get_ia32_frame_ent(node));
4188         set_ia32_use_frame(res);
4189         set_ia32_ls_mode(res, get_ia32_ls_mode(node));
4190         set_ia32_op_type(res, ia32_AddrModeD);
4191
4192         /* Load MEM -> SSE */
4193         res = new_rd_ia32_xLoad(dbgi, irg, block, new_ptr, noreg, res,
4194                                 get_ia32_ls_mode(node));
4195         set_ia32_frame_ent(res, get_ia32_frame_ent(node));
4196         set_ia32_use_frame(res);
4197         set_ia32_op_type(res, ia32_AddrModeS);
4198         res = new_rd_Proj(dbgi, irg, block, res, mode_xmm, pn_ia32_xLoad_res);
4199
4200         return res;
4201 }
4202
4203 /**
4204  * In case SSE Unit is used, the node is transformed into a xStore + vfld.
4205  */
4206 static ir_node *gen_ia32_l_SSEtoX87(ir_node *node) {
4207         ir_node         *block   = be_transform_node(get_nodes_block(node));
4208         ir_node         *val     = get_irn_n(node, 1);
4209         ir_node         *new_val = be_transform_node(val);
4210         ir_graph        *irg     = current_ir_graph;
4211         ir_node         *res     = NULL;
4212         ir_entity       *fent    = get_ia32_frame_ent(node);
4213         ir_mode         *lsmode  = get_ia32_ls_mode(node);
4214         int             offs     = 0;
4215         ir_node         *noreg, *new_ptr, *new_mem;
4216         ir_node         *ptr, *mem;
4217         dbg_info        *dbgi;
4218
4219         if (! ia32_cg_config.use_sse2) {
4220                 /* SSE unit is not used -> skip this node. */
4221                 return new_val;
4222         }
4223
4224         ptr     = get_irn_n(node, 0);
4225         new_ptr = be_transform_node(ptr);
4226         mem     = get_irn_n(node, 2);
4227         new_mem = be_transform_node(mem);
4228         noreg   = ia32_new_NoReg_gp(env_cg);
4229         dbgi    = get_irn_dbg_info(node);
4230
4231         /* Store SSE -> MEM */
4232         if (is_ia32_xLoad(skip_Proj(new_val))) {
4233                 ir_node *ld = skip_Proj(new_val);
4234
4235                 /* we can vfld the value directly into the fpu */
4236                 fent = get_ia32_frame_ent(ld);
4237                 ptr  = get_irn_n(ld, 0);
4238                 offs = get_ia32_am_offs_int(ld);
4239         } else {
4240                 res = new_rd_ia32_xStore(dbgi, irg, block, new_ptr, noreg, new_mem,
4241                                          new_val);
4242                 set_ia32_frame_ent(res, fent);
4243                 set_ia32_use_frame(res);
4244                 set_ia32_ls_mode(res, lsmode);
4245                 set_ia32_op_type(res, ia32_AddrModeD);
4246                 mem = res;
4247         }
4248
4249         /* Load MEM -> x87 */
4250         res = new_rd_ia32_vfld(dbgi, irg, block, new_ptr, noreg, new_mem, lsmode);
4251         set_ia32_frame_ent(res, fent);
4252         set_ia32_use_frame(res);
4253         add_ia32_am_offs_int(res, offs);
4254         set_ia32_op_type(res, ia32_AddrModeS);
4255         res = new_rd_Proj(dbgi, irg, block, res, mode_vfp, pn_ia32_vfld_res);
4256
4257         return res;
4258 }
4259
4260 /**
4261  * the BAD transformer.
4262  */
4263 static ir_node *bad_transform(ir_node *node) {
4264         panic("No transform function for %+F available.\n", node);
4265         return NULL;
4266 }
4267
4268 /**
4269  * Transform the Projs of an AddSP.
4270  */
4271 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4272         ir_node  *block    = be_transform_node(get_nodes_block(node));
4273         ir_node  *pred     = get_Proj_pred(node);
4274         ir_node  *new_pred = be_transform_node(pred);
4275         ir_graph *irg      = current_ir_graph;
4276         dbg_info *dbgi     = get_irn_dbg_info(node);
4277         long     proj      = get_Proj_proj(node);
4278
4279         if (proj == pn_be_AddSP_sp) {
4280                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4281                                            pn_ia32_SubSP_stack);
4282                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4283                 return res;
4284         } else if(proj == pn_be_AddSP_res) {
4285                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4286                                    pn_ia32_SubSP_addr);
4287         } else if (proj == pn_be_AddSP_M) {
4288                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4289         }
4290
4291         assert(0);
4292         return new_rd_Unknown(irg, get_irn_mode(node));
4293 }
4294
4295 /**
4296  * Transform the Projs of a SubSP.
4297  */
4298 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4299         ir_node  *block    = be_transform_node(get_nodes_block(node));
4300         ir_node  *pred     = get_Proj_pred(node);
4301         ir_node  *new_pred = be_transform_node(pred);
4302         ir_graph *irg      = current_ir_graph;
4303         dbg_info *dbgi     = get_irn_dbg_info(node);
4304         long     proj      = get_Proj_proj(node);
4305
4306         if (proj == pn_be_SubSP_sp) {
4307                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4308                                            pn_ia32_AddSP_stack);
4309                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4310                 return res;
4311         } else if (proj == pn_be_SubSP_M) {
4312                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4313         }
4314
4315         assert(0);
4316         return new_rd_Unknown(irg, get_irn_mode(node));
4317 }
4318
4319 /**
4320  * Transform and renumber the Projs from a Load.
4321  */
4322 static ir_node *gen_Proj_Load(ir_node *node) {
4323         ir_node  *new_pred;
4324         ir_node  *block    = be_transform_node(get_nodes_block(node));
4325         ir_node  *pred     = get_Proj_pred(node);
4326         ir_graph *irg      = current_ir_graph;
4327         dbg_info *dbgi     = get_irn_dbg_info(node);
4328         long     proj      = get_Proj_proj(node);
4329
4330
4331         /* loads might be part of source address mode matches, so we don't
4332            transform the ProjMs yet (with the exception of loads whose result is
4333            not used)
4334          */
4335         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4336                 ir_node *res;
4337
4338                 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4339                                                                                 nodes is 1 */
4340                 /* this is needed, because sometimes we have loops that are only
4341                    reachable through the ProjM */
4342                 be_enqueue_preds(node);
4343                 /* do it in 2 steps, to silence firm verifier */
4344                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4345                 set_Proj_proj(res, pn_ia32_Load_M);
4346                 return res;
4347         }
4348
4349         /* renumber the proj */
4350         new_pred = be_transform_node(pred);
4351         if (is_ia32_Load(new_pred)) {
4352                 if (proj == pn_Load_res) {
4353                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4354                                            pn_ia32_Load_res);
4355                 } else if (proj == pn_Load_M) {
4356                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M,
4357                                            pn_ia32_Load_M);
4358                 }
4359         } else if(is_ia32_Conv_I2I(new_pred)
4360                         || is_ia32_Conv_I2I8Bit(new_pred)) {
4361                 set_irn_mode(new_pred, mode_T);
4362                 if (proj == pn_Load_res) {
4363                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4364                 } else if (proj == pn_Load_M) {
4365                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4366                 }
4367         } else if (is_ia32_xLoad(new_pred)) {
4368                 if (proj == pn_Load_res) {
4369                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm,
4370                                            pn_ia32_xLoad_res);
4371                 } else if (proj == pn_Load_M) {
4372                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M,
4373                                            pn_ia32_xLoad_M);
4374                 }
4375         } else if (is_ia32_vfld(new_pred)) {
4376                 if (proj == pn_Load_res) {
4377                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp,
4378                                            pn_ia32_vfld_res);
4379                 } else if (proj == pn_Load_M) {
4380                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M,
4381                                            pn_ia32_vfld_M);
4382                 }
4383         } else {
4384                 /* can happen for ProJMs when source address mode happened for the
4385                    node */
4386
4387                 /* however it should not be the result proj, as that would mean the
4388                    load had multiple users and should not have been used for
4389                    SourceAM */
4390                 if(proj != pn_Load_M) {
4391                         panic("internal error: transformed node not a Load");
4392                 }
4393                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4394         }
4395
4396         assert(0);
4397         return new_rd_Unknown(irg, get_irn_mode(node));
4398 }
4399
4400 /**
4401  * Transform and renumber the Projs from a DivMod like instruction.
4402  */
4403 static ir_node *gen_Proj_DivMod(ir_node *node) {
4404         ir_node  *block    = be_transform_node(get_nodes_block(node));
4405         ir_node  *pred     = get_Proj_pred(node);
4406         ir_node  *new_pred = be_transform_node(pred);
4407         ir_graph *irg      = current_ir_graph;
4408         dbg_info *dbgi     = get_irn_dbg_info(node);
4409         ir_mode  *mode     = get_irn_mode(node);
4410         long     proj      = get_Proj_proj(node);
4411
4412         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4413
4414         switch (get_irn_opcode(pred)) {
4415         case iro_Div:
4416                 switch (proj) {
4417                 case pn_Div_M:
4418                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4419                 case pn_Div_res:
4420                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4421                 default:
4422                         break;
4423                 }
4424                 break;
4425         case iro_Mod:
4426                 switch (proj) {
4427                 case pn_Mod_M:
4428                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4429                 case pn_Mod_res:
4430                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4431                 default:
4432                         break;
4433                 }
4434                 break;
4435         case iro_DivMod:
4436                 switch (proj) {
4437                 case pn_DivMod_M:
4438                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4439                 case pn_DivMod_res_div:
4440                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4441                 case pn_DivMod_res_mod:
4442                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4443                 default:
4444                         break;
4445                 }
4446                 break;
4447         default:
4448                 break;
4449         }
4450
4451         assert(0);
4452         return new_rd_Unknown(irg, mode);
4453 }
4454
4455 /**
4456  * Transform and renumber the Projs from a CopyB.
4457  */
4458 static ir_node *gen_Proj_CopyB(ir_node *node) {
4459         ir_node  *block    = be_transform_node(get_nodes_block(node));
4460         ir_node  *pred     = get_Proj_pred(node);
4461         ir_node  *new_pred = be_transform_node(pred);
4462         ir_graph *irg      = current_ir_graph;
4463         dbg_info *dbgi     = get_irn_dbg_info(node);
4464         ir_mode  *mode     = get_irn_mode(node);
4465         long     proj      = get_Proj_proj(node);
4466
4467         switch(proj) {
4468         case pn_CopyB_M_regular:
4469                 if (is_ia32_CopyB_i(new_pred)) {
4470                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4471                 } else if (is_ia32_CopyB(new_pred)) {
4472                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4473                 }
4474                 break;
4475         default:
4476                 break;
4477         }
4478
4479         assert(0);
4480         return new_rd_Unknown(irg, mode);
4481 }
4482
4483 /**
4484  * Transform and renumber the Projs from a Quot.
4485  */
4486 static ir_node *gen_Proj_Quot(ir_node *node) {
4487         ir_node  *block    = be_transform_node(get_nodes_block(node));
4488         ir_node  *pred     = get_Proj_pred(node);
4489         ir_node  *new_pred = be_transform_node(pred);
4490         ir_graph *irg      = current_ir_graph;
4491         dbg_info *dbgi     = get_irn_dbg_info(node);
4492         ir_mode  *mode     = get_irn_mode(node);
4493         long     proj      = get_Proj_proj(node);
4494
4495         switch(proj) {
4496         case pn_Quot_M:
4497                 if (is_ia32_xDiv(new_pred)) {
4498                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4499                 } else if (is_ia32_vfdiv(new_pred)) {
4500                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4501                 }
4502                 break;
4503         case pn_Quot_res:
4504                 if (is_ia32_xDiv(new_pred)) {
4505                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4506                 } else if (is_ia32_vfdiv(new_pred)) {
4507                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4508                 }
4509                 break;
4510         default:
4511                 break;
4512         }
4513
4514         assert(0);
4515         return new_rd_Unknown(irg, mode);
4516 }
4517
4518 /**
4519  * Transform the Thread Local Storage Proj.
4520  */
4521 static ir_node *gen_Proj_tls(ir_node *node) {
4522         ir_node  *block = be_transform_node(get_nodes_block(node));
4523         ir_graph *irg   = current_ir_graph;
4524         dbg_info *dbgi  = NULL;
4525         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4526
4527         return res;
4528 }
4529
4530 static ir_node *gen_be_Call(ir_node *node) {
4531         ir_node *res = be_duplicate_node(node);
4532         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4533
4534         return res;
4535 }
4536
4537 static ir_node *gen_be_IncSP(ir_node *node) {
4538         ir_node *res = be_duplicate_node(node);
4539         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4540
4541         return res;
4542 }
4543
4544 /**
4545  * Transform the Projs from a be_Call.
4546  */
4547 static ir_node *gen_Proj_be_Call(ir_node *node) {
4548         ir_node  *block       = be_transform_node(get_nodes_block(node));
4549         ir_node  *call        = get_Proj_pred(node);
4550         ir_node  *new_call    = be_transform_node(call);
4551         ir_graph *irg         = current_ir_graph;
4552         dbg_info *dbgi        = get_irn_dbg_info(node);
4553         ir_type  *method_type = be_Call_get_type(call);
4554         int       n_res       = get_method_n_ress(method_type);
4555         long      proj        = get_Proj_proj(node);
4556         ir_mode  *mode        = get_irn_mode(node);
4557         ir_node  *sse_load;
4558         const arch_register_class_t *cls;
4559
4560         /* The following is kinda tricky: If we're using SSE, then we have to
4561          * move the result value of the call in floating point registers to an
4562          * xmm register, we therefore construct a GetST0 -> xLoad sequence
4563          * after the call, we have to make sure to correctly make the
4564          * MemProj and the result Proj use these 2 nodes
4565          */
4566         if (proj == pn_be_Call_M_regular) {
4567                 // get new node for result, are we doing the sse load/store hack?
4568                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4569                 ir_node *call_res_new;
4570                 ir_node *call_res_pred = NULL;
4571
4572                 if (call_res != NULL) {
4573                         call_res_new  = be_transform_node(call_res);
4574                         call_res_pred = get_Proj_pred(call_res_new);
4575                 }
4576
4577                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4578                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4579                                            pn_be_Call_M_regular);
4580                 } else {
4581                         assert(is_ia32_xLoad(call_res_pred));
4582                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4583                                            pn_ia32_xLoad_M);
4584                 }
4585         }
4586         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4587                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4588                 ir_node *fstp;
4589                 ir_node *frame = get_irg_frame(irg);
4590                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4591                 //ir_node *p;
4592                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4593                 ir_node *call_res;
4594
4595                 /* in case there is no memory output: create one to serialize the copy
4596                    FPU -> SSE */
4597                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4598                                        pn_be_Call_M_regular);
4599                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4600                                        pn_be_Call_first_res);
4601
4602                 /* store st(0) onto stack */
4603                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4604                                         call_res, mode);
4605                 set_ia32_op_type(fstp, ia32_AddrModeD);
4606                 set_ia32_use_frame(fstp);
4607
4608                 /* load into SSE register */
4609                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4610                                              mode);
4611                 set_ia32_op_type(sse_load, ia32_AddrModeS);
4612                 set_ia32_use_frame(sse_load);
4613
4614                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4615                                        pn_ia32_xLoad_res);
4616
4617                 return sse_load;
4618         }
4619
4620         /* transform call modes */
4621         if (mode_is_data(mode)) {
4622                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4623                 mode = cls->mode;
4624         }
4625
4626         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4627 }
4628
4629 /**
4630  * Transform the Projs from a Cmp.
4631  */
4632 static ir_node *gen_Proj_Cmp(ir_node *node)
4633 {
4634         /* this probably means not all mode_b nodes were lowered... */
4635         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4636               node);
4637 }
4638
4639 /**
4640  * Transform and potentially renumber Proj nodes.
4641  */
4642 static ir_node *gen_Proj(ir_node *node) {
4643         ir_graph *irg  = current_ir_graph;
4644         dbg_info *dbgi = get_irn_dbg_info(node);
4645         ir_node  *pred = get_Proj_pred(node);
4646         long     proj  = get_Proj_proj(node);
4647
4648         if (is_Store(pred)) {
4649                 if (proj == pn_Store_M) {
4650                         return be_transform_node(pred);
4651                 } else {
4652                         assert(0);
4653                         return new_r_Bad(irg);
4654                 }
4655         } else if (is_Load(pred)) {
4656                 return gen_Proj_Load(node);
4657         } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
4658                 return gen_Proj_DivMod(node);
4659         } else if (is_CopyB(pred)) {
4660                 return gen_Proj_CopyB(node);
4661         } else if (is_Quot(pred)) {
4662                 return gen_Proj_Quot(node);
4663         } else if (be_is_SubSP(pred)) {
4664                 return gen_Proj_be_SubSP(node);
4665         } else if (be_is_AddSP(pred)) {
4666                 return gen_Proj_be_AddSP(node);
4667         } else if (be_is_Call(pred)) {
4668                 return gen_Proj_be_Call(node);
4669         } else if (is_Cmp(pred)) {
4670                 return gen_Proj_Cmp(node);
4671         } else if (get_irn_op(pred) == op_Start) {
4672                 if (proj == pn_Start_X_initial_exec) {
4673                         ir_node *block = get_nodes_block(pred);
4674                         ir_node *jump;
4675
4676                         /* we exchange the ProjX with a jump */
4677                         block = be_transform_node(block);
4678                         jump  = new_rd_Jmp(dbgi, irg, block);
4679                         return jump;
4680                 }
4681                 if (node == be_get_old_anchor(anchor_tls)) {
4682                         return gen_Proj_tls(node);
4683                 }
4684 #ifdef FIRM_EXT_GRS
4685         } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4686 #else
4687         } else {
4688 #endif
4689                 ir_node *new_pred = be_transform_node(pred);
4690                 ir_node *block    = be_transform_node(get_nodes_block(node));
4691                 ir_mode *mode     = get_irn_mode(node);
4692                 if (mode_needs_gp_reg(mode)) {
4693                         ir_node *new_proj = new_r_Proj(irg, block, new_pred, mode_Iu,
4694                                                        get_Proj_proj(node));
4695 #ifdef DEBUG_libfirm
4696                         new_proj->node_nr = node->node_nr;
4697 #endif
4698                         return new_proj;
4699                 }
4700         }
4701
4702         return be_duplicate_node(node);
4703 }
4704
4705 /**
4706  * Enters all transform functions into the generic pointer
4707  */
4708 static void register_transformers(void)
4709 {
4710         ir_op *op_Mulh;
4711
4712         /* first clear the generic function pointer for all ops */
4713         clear_irp_opcodes_generic_func();
4714
4715 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4716 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
4717
4718         GEN(Add);
4719         GEN(Sub);
4720         GEN(Mul);
4721         GEN(And);
4722         GEN(Or);
4723         GEN(Eor);
4724
4725         GEN(Shl);
4726         GEN(Shr);
4727         GEN(Shrs);
4728         GEN(Rot);
4729
4730         GEN(Quot);
4731
4732         GEN(Div);
4733         GEN(Mod);
4734         GEN(DivMod);
4735
4736         GEN(Minus);
4737         GEN(Conv);
4738         GEN(Abs);
4739         GEN(Not);
4740
4741         GEN(Load);
4742         GEN(Store);
4743         GEN(Cond);
4744
4745         GEN(Cmp);
4746         GEN(ASM);
4747         GEN(CopyB);
4748         BAD(Mux);
4749         GEN(Psi);
4750         GEN(Proj);
4751         GEN(Phi);
4752         GEN(IJmp);
4753
4754         /* transform ops from intrinsic lowering */
4755         GEN(ia32_l_Add);
4756         GEN(ia32_l_Adc);
4757         GEN(ia32_l_Mul);
4758         GEN(ia32_l_IMul);
4759         GEN(ia32_l_ShlDep);
4760         GEN(ia32_l_ShrDep);
4761         GEN(ia32_l_SarDep);
4762         GEN(ia32_l_ShlD);
4763         GEN(ia32_l_ShrD);
4764         GEN(ia32_l_Sub);
4765         GEN(ia32_l_Sbb);
4766         GEN(ia32_l_vfild);
4767         GEN(ia32_l_Load);
4768         GEN(ia32_l_vfist);
4769         GEN(ia32_l_Store);
4770         GEN(ia32_l_X87toSSE);
4771         GEN(ia32_l_SSEtoX87);
4772
4773         GEN(Const);
4774         GEN(SymConst);
4775         GEN(Unknown);
4776
4777         /* we should never see these nodes */
4778         BAD(Raise);
4779         BAD(Sel);
4780         BAD(InstOf);
4781         BAD(Cast);
4782         BAD(Free);
4783         BAD(Tuple);
4784         BAD(Id);
4785         //BAD(Bad);
4786         BAD(Confirm);
4787         BAD(Filter);
4788         BAD(CallBegin);
4789         BAD(EndReg);
4790         BAD(EndExcept);
4791
4792         /* handle generic backend nodes */
4793         GEN(be_FrameAddr);
4794         GEN(be_Call);
4795         GEN(be_IncSP);
4796         GEN(be_Return);
4797         GEN(be_AddSP);
4798         GEN(be_SubSP);
4799         GEN(be_Copy);
4800
4801         op_Mulh = get_op_Mulh();
4802         if (op_Mulh)
4803                 GEN(Mulh);
4804
4805 #undef GEN
4806 #undef BAD
4807 }
4808
4809 /**
4810  * Pre-transform all unknown and noreg nodes.
4811  */
4812 static void ia32_pretransform_node(void *arch_cg) {
4813         ia32_code_gen_t *cg = arch_cg;
4814
4815         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
4816         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4817         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4818         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
4819         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
4820         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
4821         get_fpcw();
4822 }
4823
4824 /**
4825  * Walker, checks if all ia32 nodes producing more than one result have
4826  * its Projs, other wise creates new projs and keep them using a be_Keep node.
4827  */
4828 static void add_missing_keep_walker(ir_node *node, void *data)
4829 {
4830         int              n_outs, i;
4831         unsigned         found_projs = 0;
4832         const ir_edge_t *edge;
4833         ir_mode         *mode = get_irn_mode(node);
4834         ir_node         *last_keep;
4835         (void) data;
4836         if(mode != mode_T)
4837                 return;
4838         if(!is_ia32_irn(node))
4839                 return;
4840
4841         n_outs = get_ia32_n_res(node);
4842         if(n_outs <= 0)
4843                 return;
4844         if(is_ia32_SwitchJmp(node))
4845                 return;
4846
4847         assert(n_outs < (int) sizeof(unsigned) * 8);
4848         foreach_out_edge(node, edge) {
4849                 ir_node *proj = get_edge_src_irn(edge);
4850                 int      pn   = get_Proj_proj(proj);
4851
4852                 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
4853                 found_projs |= 1 << pn;
4854         }
4855
4856
4857         /* are keeps missing? */
4858         last_keep = NULL;
4859         for(i = 0; i < n_outs; ++i) {
4860                 ir_node                     *block;
4861                 ir_node                     *in[1];
4862                 const arch_register_req_t   *req;
4863                 const arch_register_class_t *class;
4864
4865                 if(found_projs & (1 << i)) {
4866                         continue;
4867                 }
4868
4869                 req   = get_ia32_out_req(node, i);
4870                 class = req->cls;
4871                 if(class == NULL) {
4872                         continue;
4873                 }
4874                 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
4875                         continue;
4876                 }
4877
4878                 block = get_nodes_block(node);
4879                 in[0] = new_r_Proj(current_ir_graph, block, node,
4880                                    arch_register_class_mode(class), i);
4881                 if(last_keep != NULL) {
4882                         be_Keep_add_node(last_keep, class, in[0]);
4883                 } else {
4884                         last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
4885                         if(sched_is_scheduled(node)) {
4886                                 sched_add_after(node, last_keep);
4887                         }
4888                 }
4889         }
4890 }
4891
4892 /**
4893  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4894  * and keeps them.
4895  */
4896 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4897 {
4898         ir_graph *irg = be_get_birg_irg(cg->birg);
4899         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4900 }
4901
4902 /* do the transformation */
4903 void ia32_transform_graph(ia32_code_gen_t *cg) {
4904         int cse_last;
4905         ir_graph *irg = cg->irg;
4906
4907         register_transformers();
4908         env_cg       = cg;
4909         initial_fpcw = NULL;
4910
4911         heights      = heights_new(irg);
4912         ia32_calculate_non_address_mode_nodes(cg->birg);
4913
4914         /* the transform phase is not safe for CSE (yet) because several nodes get
4915          * attributes set after their creation */
4916         cse_last = get_opt_cse();
4917         set_opt_cse(0);
4918
4919         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4920
4921         set_opt_cse(cse_last);
4922
4923         ia32_free_non_address_mode_nodes();
4924         heights_free(heights);
4925         heights = NULL;
4926 }
4927
4928 void ia32_init_transform(void)
4929 {
4930         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
4931 }