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