- add barcelona and generic32 targets
[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         unsigned flags;
1156
1157         if (mode_is_float(mode)) {
1158                 if (ia32_cg_config.use_sse2)
1159                         return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1160                                          match_commutative | match_am);
1161                 else
1162                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1163                                                    match_commutative | match_am);
1164         }
1165
1166         /* for the lower 32bit of the result it doesn't matter whether we use
1167          * signed or unsigned multiplication so we use IMul as it has fewer
1168          * constraints */
1169         flags = match_commutative | match_am | match_mode_neutral | match_immediate;
1170         if (ia32_cg_config.use_imul_mem_imm32)
1171                 flags |= match_am_and_immediates;
1172         return gen_binop(node, op1, op2, new_rd_ia32_IMul, flags);
1173 }
1174
1175 /**
1176  * Creates an ia32 Mulh.
1177  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1178  * this result while Mul returns the lower 32 bit.
1179  *
1180  * @return the created ia32 Mulh node
1181  */
1182 static ir_node *gen_Mulh(ir_node *node)
1183 {
1184         ir_node  *block     = get_nodes_block(node);
1185         ir_node  *new_block = be_transform_node(block);
1186         ir_graph *irg       = current_ir_graph;
1187         dbg_info *dbgi      = get_irn_dbg_info(node);
1188         ir_mode  *mode      = get_irn_mode(node);
1189         ir_node  *op1       = get_Mulh_left(node);
1190         ir_node  *op2       = get_Mulh_right(node);
1191         ir_node  *proj_res_high;
1192         ir_node  *new_node;
1193         ia32_address_mode_t  am;
1194         ia32_address_t      *addr = &am.addr;
1195
1196         assert(!mode_is_float(mode) && "Mulh with float not supported");
1197         assert(get_mode_size_bits(mode) == 32);
1198
1199         match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1200
1201         if (mode_is_signed(mode)) {
1202                 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1203                                                addr->index, addr->mem, am.new_op1,
1204                                                am.new_op2);
1205         } else {
1206                 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1207                                            addr->index, addr->mem, am.new_op1,
1208                                            am.new_op2);
1209         }
1210
1211         set_am_attributes(new_node, &am);
1212         /* we can't use source address mode anymore when using immediates */
1213         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1214                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1215         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1216
1217         assert(get_irn_mode(new_node) == mode_T);
1218
1219         fix_mem_proj(new_node, &am);
1220
1221         assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1222         proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1223                                mode_Iu, pn_ia32_IMul1OP_res_high);
1224
1225         return proj_res_high;
1226 }
1227
1228
1229
1230 /**
1231  * Creates an ia32 And.
1232  *
1233  * @return The created ia32 And node
1234  */
1235 static ir_node *gen_And(ir_node *node) {
1236         ir_node *op1 = get_And_left(node);
1237         ir_node *op2 = get_And_right(node);
1238         assert(! mode_is_float(get_irn_mode(node)));
1239
1240         /* is it a zero extension? */
1241         if (is_Const(op2)) {
1242                 tarval   *tv    = get_Const_tarval(op2);
1243                 long      v     = get_tarval_long(tv);
1244
1245                 if (v == 0xFF || v == 0xFFFF) {
1246                         dbg_info *dbgi   = get_irn_dbg_info(node);
1247                         ir_node  *block  = get_nodes_block(node);
1248                         ir_mode  *src_mode;
1249                         ir_node  *res;
1250
1251                         if(v == 0xFF) {
1252                                 src_mode = mode_Bu;
1253                         } else {
1254                                 assert(v == 0xFFFF);
1255                                 src_mode = mode_Hu;
1256                         }
1257                         res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1258
1259                         return res;
1260                 }
1261         }
1262
1263         return gen_binop(node, op1, op2, new_rd_ia32_And,
1264                          match_commutative | match_mode_neutral | match_am
1265                                          | match_immediate);
1266 }
1267
1268
1269
1270 /**
1271  * Creates an ia32 Or.
1272  *
1273  * @return The created ia32 Or node
1274  */
1275 static ir_node *gen_Or(ir_node *node) {
1276         ir_node *op1 = get_Or_left(node);
1277         ir_node *op2 = get_Or_right(node);
1278
1279         assert (! mode_is_float(get_irn_mode(node)));
1280         return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1281                         | match_mode_neutral | match_am | match_immediate);
1282 }
1283
1284
1285
1286 /**
1287  * Creates an ia32 Eor.
1288  *
1289  * @return The created ia32 Eor node
1290  */
1291 static ir_node *gen_Eor(ir_node *node) {
1292         ir_node *op1 = get_Eor_left(node);
1293         ir_node *op2 = get_Eor_right(node);
1294
1295         assert(! mode_is_float(get_irn_mode(node)));
1296         return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1297                         | match_mode_neutral | match_am | match_immediate);
1298 }
1299
1300
1301 /**
1302  * Creates an ia32 Sub.
1303  *
1304  * @return The created ia32 Sub node
1305  */
1306 static ir_node *gen_Sub(ir_node *node) {
1307         ir_node  *op1  = get_Sub_left(node);
1308         ir_node  *op2  = get_Sub_right(node);
1309         ir_mode  *mode = get_irn_mode(node);
1310
1311         if (mode_is_float(mode)) {
1312                 if (ia32_cg_config.use_sse2)
1313                         return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1314                 else
1315                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1316                                                    match_am);
1317         }
1318
1319         if(is_Const(op2)) {
1320                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1321                            node);
1322         }
1323
1324         return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1325                         | match_am | match_immediate);
1326 }
1327
1328 /**
1329  * Generates an ia32 DivMod with additional infrastructure for the
1330  * register allocator if needed.
1331  */
1332 static ir_node *create_Div(ir_node *node)
1333 {
1334         ir_graph *irg       = current_ir_graph;
1335         dbg_info *dbgi      = get_irn_dbg_info(node);
1336         ir_node  *block     = get_nodes_block(node);
1337         ir_node  *new_block = be_transform_node(block);
1338         ir_node  *mem;
1339         ir_node  *new_mem;
1340         ir_node  *op1;
1341         ir_node  *op2;
1342         ir_node  *new_node;
1343         ir_mode  *mode;
1344         ir_node  *sign_extension;
1345         ia32_address_mode_t  am;
1346         ia32_address_t      *addr = &am.addr;
1347
1348         /* the upper bits have random contents for smaller modes */
1349         switch (get_irn_opcode(node)) {
1350         case iro_Div:
1351                 op1     = get_Div_left(node);
1352                 op2     = get_Div_right(node);
1353                 mem     = get_Div_mem(node);
1354                 mode    = get_Div_resmode(node);
1355                 break;
1356         case iro_Mod:
1357                 op1     = get_Mod_left(node);
1358                 op2     = get_Mod_right(node);
1359                 mem     = get_Mod_mem(node);
1360                 mode    = get_Mod_resmode(node);
1361                 break;
1362         case iro_DivMod:
1363                 op1     = get_DivMod_left(node);
1364                 op2     = get_DivMod_right(node);
1365                 mem     = get_DivMod_mem(node);
1366                 mode    = get_DivMod_resmode(node);
1367                 break;
1368         default:
1369                 panic("invalid divmod node %+F", node);
1370         }
1371
1372         match_arguments(&am, block, op1, op2, NULL, match_am);
1373
1374         /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1375            is the memory of the consumed address. We can have only the second op as address
1376            in Div nodes, so check only op2. */
1377         if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1378                 new_mem = be_transform_node(mem);
1379                 if(!is_NoMem(addr->mem)) {
1380                         ir_node *in[2];
1381                         in[0] = new_mem;
1382                         in[1] = addr->mem;
1383                         new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1384                 }
1385         } else {
1386                 new_mem = addr->mem;
1387         }
1388
1389         if (mode_is_signed(mode)) {
1390                 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1391                 add_irn_dep(produceval, get_irg_frame(irg));
1392                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1393                                                   produceval);
1394
1395                 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1396                                             addr->index, new_mem, am.new_op1,
1397                                             sign_extension, am.new_op2);
1398         } else {
1399                 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1400                 add_irn_dep(sign_extension, get_irg_frame(irg));
1401
1402                 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1403                                            addr->index, new_mem, am.new_op1,
1404                                            sign_extension, am.new_op2);
1405         }
1406
1407         set_irn_pinned(new_node, get_irn_pinned(node));
1408
1409         set_am_attributes(new_node, &am);
1410         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1411
1412         new_node = fix_mem_proj(new_node, &am);
1413
1414         return new_node;
1415 }
1416
1417
1418 static ir_node *gen_Mod(ir_node *node) {
1419         return create_Div(node);
1420 }
1421
1422 static ir_node *gen_Div(ir_node *node) {
1423         return create_Div(node);
1424 }
1425
1426 static ir_node *gen_DivMod(ir_node *node) {
1427         return create_Div(node);
1428 }
1429
1430
1431
1432 /**
1433  * Creates an ia32 floating Div.
1434  *
1435  * @return The created ia32 xDiv node
1436  */
1437 static ir_node *gen_Quot(ir_node *node)
1438 {
1439         ir_node  *op1     = get_Quot_left(node);
1440         ir_node  *op2     = get_Quot_right(node);
1441
1442         if (ia32_cg_config.use_sse2) {
1443                 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1444         } else {
1445                 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1446         }
1447 }
1448
1449
1450 /**
1451  * Creates an ia32 Shl.
1452  *
1453  * @return The created ia32 Shl node
1454  */
1455 static ir_node *gen_Shl(ir_node *node) {
1456         ir_node *left  = get_Shl_left(node);
1457         ir_node *right = get_Shl_right(node);
1458
1459         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1460                                match_mode_neutral | match_immediate);
1461 }
1462
1463 /**
1464  * Creates an ia32 Shr.
1465  *
1466  * @return The created ia32 Shr node
1467  */
1468 static ir_node *gen_Shr(ir_node *node) {
1469         ir_node *left  = get_Shr_left(node);
1470         ir_node *right = get_Shr_right(node);
1471
1472         return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1473 }
1474
1475
1476
1477 /**
1478  * Creates an ia32 Sar.
1479  *
1480  * @return The created ia32 Shrs node
1481  */
1482 static ir_node *gen_Shrs(ir_node *node) {
1483         ir_node *left  = get_Shrs_left(node);
1484         ir_node *right = get_Shrs_right(node);
1485         ir_mode *mode  = get_irn_mode(node);
1486
1487         if(is_Const(right) && mode == mode_Is) {
1488                 tarval *tv = get_Const_tarval(right);
1489                 long val = get_tarval_long(tv);
1490                 if(val == 31) {
1491                         /* this is a sign extension */
1492                         ir_graph *irg    = current_ir_graph;
1493                         dbg_info *dbgi   = get_irn_dbg_info(node);
1494                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1495                         ir_node  *op     = left;
1496                         ir_node  *new_op = be_transform_node(op);
1497                         ir_node  *pval   = new_rd_ia32_ProduceVal(dbgi, irg, block);
1498                         add_irn_dep(pval, get_irg_frame(irg));
1499
1500                         return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1501                 }
1502         }
1503
1504         /* 8 or 16 bit sign extension? */
1505         if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1506                 ir_node *shl_left  = get_Shl_left(left);
1507                 ir_node *shl_right = get_Shl_right(left);
1508                 if(is_Const(shl_right)) {
1509                         tarval *tv1 = get_Const_tarval(right);
1510                         tarval *tv2 = get_Const_tarval(shl_right);
1511                         if(tv1 == tv2 && tarval_is_long(tv1)) {
1512                                 long val = get_tarval_long(tv1);
1513                                 if(val == 16 || val == 24) {
1514                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1515                                         ir_node  *block  = get_nodes_block(node);
1516                                         ir_mode  *src_mode;
1517                                         ir_node  *res;
1518
1519                                         if(val == 24) {
1520                                                 src_mode = mode_Bs;
1521                                         } else {
1522                                                 assert(val == 16);
1523                                                 src_mode = mode_Hs;
1524                                         }
1525                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1526                                                               shl_left, node);
1527
1528                                         return res;
1529                                 }
1530                         }
1531                 }
1532         }
1533
1534         return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1535 }
1536
1537
1538
1539 /**
1540  * Creates an ia32 RotL.
1541  *
1542  * @param op1   The first operator
1543  * @param op2   The second operator
1544  * @return The created ia32 RotL node
1545  */
1546 static ir_node *gen_RotL(ir_node *node, ir_node *op1, ir_node *op2) {
1547         return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1548 }
1549
1550
1551
1552 /**
1553  * Creates an ia32 RotR.
1554  * NOTE: There is no RotR with immediate because this would always be a RotL
1555  *       "imm-mode_size_bits" which can be pre-calculated.
1556  *
1557  * @param op1   The first operator
1558  * @param op2   The second operator
1559  * @return The created ia32 RotR node
1560  */
1561 static ir_node *gen_RotR(ir_node *node, ir_node *op1, ir_node *op2) {
1562         return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1563 }
1564
1565
1566
1567 /**
1568  * Creates an ia32 RotR or RotL (depending on the found pattern).
1569  *
1570  * @return The created ia32 RotL or RotR node
1571  */
1572 static ir_node *gen_Rot(ir_node *node) {
1573         ir_node *rotate = NULL;
1574         ir_node *op1    = get_Rot_left(node);
1575         ir_node *op2    = get_Rot_right(node);
1576
1577         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1578                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1579                  that means we can create a RotR instead of an Add and a RotL */
1580
1581         if (get_irn_op(op2) == op_Add) {
1582                 ir_node *add = op2;
1583                 ir_node *left = get_Add_left(add);
1584                 ir_node *right = get_Add_right(add);
1585                 if (is_Const(right)) {
1586                         tarval  *tv   = get_Const_tarval(right);
1587                         ir_mode *mode = get_irn_mode(node);
1588                         long     bits = get_mode_size_bits(mode);
1589
1590                         if (get_irn_op(left) == op_Minus &&
1591                                         tarval_is_long(tv)       &&
1592                                         get_tarval_long(tv) == bits &&
1593                                         bits                == 32)
1594                         {
1595                                 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1596                                 rotate = gen_RotR(node, op1, get_Minus_op(left));
1597                         }
1598                 }
1599         }
1600
1601         if (rotate == NULL) {
1602                 rotate = gen_RotL(node, op1, op2);
1603         }
1604
1605         return rotate;
1606 }
1607
1608
1609
1610 /**
1611  * Transforms a Minus node.
1612  *
1613  * @return The created ia32 Minus node
1614  */
1615 static ir_node *gen_Minus(ir_node *node)
1616 {
1617         ir_node   *op    = get_Minus_op(node);
1618         ir_node   *block = be_transform_node(get_nodes_block(node));
1619         ir_graph  *irg   = current_ir_graph;
1620         dbg_info  *dbgi  = get_irn_dbg_info(node);
1621         ir_mode   *mode  = get_irn_mode(node);
1622         ir_entity *ent;
1623         ir_node   *new_node;
1624         int        size;
1625
1626         if (mode_is_float(mode)) {
1627                 ir_node *new_op = be_transform_node(op);
1628                 if (ia32_cg_config.use_sse2) {
1629                         /* TODO: non-optimal... if we have many xXors, then we should
1630                          * rather create a load for the const and use that instead of
1631                          * several AM nodes... */
1632                         ir_node *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1633                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1634                         ir_node *nomem     = new_rd_NoMem(irg);
1635
1636                         new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1637                                                     nomem, new_op, noreg_xmm);
1638
1639                         size = get_mode_size_bits(mode);
1640                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1641
1642                         set_ia32_am_sc(new_node, ent);
1643                         set_ia32_op_type(new_node, ia32_AddrModeS);
1644                         set_ia32_ls_mode(new_node, mode);
1645                 } else {
1646                         new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1647                 }
1648         } else {
1649                 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1650         }
1651
1652         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1653
1654         return new_node;
1655 }
1656
1657 /**
1658  * Transforms a Not node.
1659  *
1660  * @return The created ia32 Not node
1661  */
1662 static ir_node *gen_Not(ir_node *node) {
1663         ir_node *op   = get_Not_op(node);
1664
1665         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1666         assert (! mode_is_float(get_irn_mode(node)));
1667
1668         return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1669 }
1670
1671
1672
1673 /**
1674  * Transforms an Abs node.
1675  *
1676  * @return The created ia32 Abs node
1677  */
1678 static ir_node *gen_Abs(ir_node *node)
1679 {
1680         ir_node   *block     = get_nodes_block(node);
1681         ir_node   *new_block = be_transform_node(block);
1682         ir_node   *op        = get_Abs_op(node);
1683         ir_graph  *irg       = current_ir_graph;
1684         dbg_info  *dbgi      = get_irn_dbg_info(node);
1685         ir_mode   *mode      = get_irn_mode(node);
1686         ir_node   *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1687         ir_node   *nomem     = new_NoMem();
1688         ir_node   *new_op;
1689         ir_node   *new_node;
1690         int        size;
1691         ir_entity *ent;
1692
1693         if (mode_is_float(mode)) {
1694                 new_op = be_transform_node(op);
1695
1696                 if (ia32_cg_config.use_sse2) {
1697                         ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1698                         new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1699                                                     nomem, new_op, noreg_fp);
1700
1701                         size = get_mode_size_bits(mode);
1702                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1703
1704                         set_ia32_am_sc(new_node, ent);
1705
1706                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1707
1708                         set_ia32_op_type(new_node, ia32_AddrModeS);
1709                         set_ia32_ls_mode(new_node, mode);
1710                 } else {
1711                         new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1712                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1713                 }
1714         } else {
1715                 ir_node *xor, *pval, *sign_extension;
1716
1717                 if (get_mode_size_bits(mode) == 32) {
1718                         new_op = be_transform_node(op);
1719                 } else {
1720                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1721                 }
1722
1723                 pval           = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1724                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1725                                                            new_op, pval);
1726
1727                 add_irn_dep(pval, get_irg_frame(irg));
1728                 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1729
1730                 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1731                                       nomem, new_op, sign_extension);
1732                 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1733
1734                 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1735                                            nomem, xor, sign_extension);
1736                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1737         }
1738
1739         return new_node;
1740 }
1741
1742 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1743 {
1744         ir_graph *irg = current_ir_graph;
1745         ir_node  *flags;
1746         ir_node  *new_op;
1747         ir_node  *noreg;
1748         ir_node  *nomem;
1749         ir_node  *new_block;
1750         dbg_info *dbgi;
1751
1752         /* we have a Cmp as input */
1753         if(is_Proj(node)) {
1754                 ir_node *pred = get_Proj_pred(node);
1755                 if(is_Cmp(pred)) {
1756                         flags    = be_transform_node(pred);
1757                         *pnc_out = get_Proj_proj(node);
1758                         return flags;
1759                 }
1760         }
1761
1762         /* a mode_b value, we have to compare it against 0 */
1763         dbgi      = get_irn_dbg_info(node);
1764         new_block = be_transform_node(get_nodes_block(node));
1765         new_op    = be_transform_node(node);
1766         noreg     = ia32_new_NoReg_gp(env_cg);
1767         nomem     = new_NoMem();
1768         flags     = new_rd_ia32_Test(dbgi, irg, new_block, noreg, noreg, nomem,
1769                                      new_op, new_op, 0, 0);
1770         *pnc_out  = pn_Cmp_Lg;
1771         return flags;
1772 }
1773
1774 /**
1775  * Transforms a Load.
1776  *
1777  * @return the created ia32 Load node
1778  */
1779 static ir_node *gen_Load(ir_node *node) {
1780         ir_node  *old_block = get_nodes_block(node);
1781         ir_node  *block   = be_transform_node(old_block);
1782         ir_node  *ptr     = get_Load_ptr(node);
1783         ir_node  *mem     = get_Load_mem(node);
1784         ir_node  *new_mem = be_transform_node(mem);
1785         ir_node  *base;
1786         ir_node  *index;
1787         ir_graph *irg     = current_ir_graph;
1788         dbg_info *dbgi    = get_irn_dbg_info(node);
1789         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
1790         ir_mode  *mode    = get_Load_mode(node);
1791         ir_mode  *res_mode;
1792         ir_node  *new_node;
1793         ia32_address_t addr;
1794
1795         /* construct load address */
1796         memset(&addr, 0, sizeof(addr));
1797         ia32_create_address_mode(&addr, ptr, /*force=*/0);
1798         base  = addr.base;
1799         index = addr.index;
1800
1801         if(base == NULL) {
1802                 base = noreg;
1803         } else {
1804                 base = be_transform_node(base);
1805         }
1806
1807         if(index == NULL) {
1808                 index = noreg;
1809         } else {
1810                 index = be_transform_node(index);
1811         }
1812
1813         if (mode_is_float(mode)) {
1814                 if (ia32_cg_config.use_sse2) {
1815                         new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1816                                                      mode);
1817                         res_mode = mode_xmm;
1818                 } else {
1819                         new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1820                                                     mode);
1821                         res_mode = mode_vfp;
1822                 }
1823         } else {
1824                 assert(mode != mode_b);
1825
1826                 /* create a conv node with address mode for smaller modes */
1827                 if(get_mode_size_bits(mode) < 32) {
1828                         new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1829                                                         new_mem, noreg, mode);
1830                 } else {
1831                         new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1832                 }
1833                 res_mode = mode_Iu;
1834         }
1835
1836         set_irn_pinned(new_node, get_irn_pinned(node));
1837         set_ia32_op_type(new_node, ia32_AddrModeS);
1838         set_ia32_ls_mode(new_node, mode);
1839         set_address(new_node, &addr);
1840
1841         if(get_irn_pinned(node) == op_pin_state_floats) {
1842                 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1843         }
1844
1845         /* make sure we are scheduled behind the initial IncSP/Barrier
1846          * to avoid spills being placed before it
1847          */
1848         if (block == get_irg_start_block(irg)) {
1849                 add_irn_dep(new_node, get_irg_frame(irg));
1850         }
1851
1852         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1853
1854         return new_node;
1855 }
1856
1857 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1858                        ir_node *ptr, ir_node *other)
1859 {
1860         ir_node *load;
1861
1862         if(!is_Proj(node))
1863                 return 0;
1864
1865         /* we only use address mode if we're the only user of the load */
1866         if(get_irn_n_edges(node) > 1)
1867                 return 0;
1868
1869         load = get_Proj_pred(node);
1870         if(!is_Load(load))
1871                 return 0;
1872         if(get_nodes_block(load) != block)
1873                 return 0;
1874
1875         /* Store should be attached to the load */
1876         if(!is_Proj(mem) || get_Proj_pred(mem) != load)
1877                 return 0;
1878         /* store should have the same pointer as the load */
1879         if(get_Load_ptr(load) != ptr)
1880                 return 0;
1881
1882         /* don't do AM if other node inputs depend on the load (via mem-proj) */
1883         if(other != NULL && get_nodes_block(other) == block
1884                         && heights_reachable_in_block(heights, other, load))
1885                 return 0;
1886
1887         return 1;
1888 }
1889
1890 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1891                               ir_node *mem, ir_node *ptr, ir_mode *mode,
1892                               construct_binop_dest_func *func,
1893                               construct_binop_dest_func *func8bit,
1894                                                           match_flags_t flags)
1895 {
1896         ir_node  *src_block = get_nodes_block(node);
1897         ir_node  *block;
1898         ir_node  *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1899         ir_graph *irg      = current_ir_graph;
1900         dbg_info *dbgi;
1901         ir_node  *new_node;
1902         ir_node  *new_op;
1903         int       commutative;
1904         ia32_address_mode_t  am;
1905         ia32_address_t      *addr = &am.addr;
1906         memset(&am, 0, sizeof(am));
1907
1908         assert(flags & match_dest_am);
1909         assert(flags & match_immediate); /* there is no destam node without... */
1910         commutative = (flags & match_commutative) != 0;
1911
1912         if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1913                 build_address(&am, op1);
1914                 new_op = create_immediate_or_transform(op2, 0);
1915         } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1916                 build_address(&am, op2);
1917                 new_op = create_immediate_or_transform(op1, 0);
1918         } else {
1919                 return NULL;
1920         }
1921
1922         if(addr->base == NULL)
1923                 addr->base = noreg_gp;
1924         if(addr->index == NULL)
1925                 addr->index = noreg_gp;
1926         if(addr->mem == NULL)
1927                 addr->mem = new_NoMem();
1928
1929         dbgi  = get_irn_dbg_info(node);
1930         block = be_transform_node(src_block);
1931         if(get_mode_size_bits(mode) == 8) {
1932                 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1933                                     addr->mem, new_op);
1934         } else {
1935                 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
1936                                 new_op);
1937         }
1938         set_address(new_node, addr);
1939         set_ia32_op_type(new_node, ia32_AddrModeD);
1940         set_ia32_ls_mode(new_node, mode);
1941         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1942
1943         return new_node;
1944 }
1945
1946 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
1947                              ir_node *ptr, ir_mode *mode,
1948                              construct_unop_dest_func *func)
1949 {
1950         ir_graph *irg      = current_ir_graph;
1951         ir_node *src_block = get_nodes_block(node);
1952         ir_node *block;
1953         dbg_info *dbgi;
1954         ir_node *new_node;
1955         ia32_address_mode_t  am;
1956         ia32_address_t *addr = &am.addr;
1957         memset(&am, 0, sizeof(am));
1958
1959         if(!use_dest_am(src_block, op, mem, ptr, NULL))
1960                 return NULL;
1961
1962         build_address(&am, op);
1963
1964         dbgi     = get_irn_dbg_info(node);
1965         block    = be_transform_node(src_block);
1966         new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
1967         set_address(new_node, addr);
1968         set_ia32_op_type(new_node, ia32_AddrModeD);
1969         set_ia32_ls_mode(new_node, mode);
1970         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1971
1972         return new_node;
1973 }
1974
1975 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
1976         ir_mode  *mode        = get_irn_mode(node);
1977         ir_node  *psi_true    = get_Psi_val(node, 0);
1978         ir_node  *psi_default = get_Psi_default(node);
1979         ir_graph *irg;
1980         ir_node  *cond;
1981         ir_node  *new_mem;
1982         dbg_info *dbgi;
1983         ir_node  *block;
1984         ir_node  *new_block;
1985         ir_node  *flags;
1986         ir_node  *new_node;
1987         int       negated;
1988         pn_Cmp    pnc;
1989         ia32_address_t addr;
1990
1991         if(get_mode_size_bits(mode) != 8)
1992                 return NULL;
1993
1994         if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
1995                 negated = 0;
1996         } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
1997                 negated = 1;
1998         } else {
1999                 return NULL;
2000         }
2001
2002         build_address_ptr(&addr, ptr, mem);
2003
2004         irg       = current_ir_graph;
2005         dbgi      = get_irn_dbg_info(node);
2006         block     = get_nodes_block(node);
2007         new_block = be_transform_node(block);
2008         cond      = get_Psi_cond(node, 0);
2009         flags     = get_flags_node(cond, &pnc);
2010         new_mem   = be_transform_node(mem);
2011         new_node  = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2012                                        addr.index, addr.mem, flags, pnc, negated);
2013         set_address(new_node, &addr);
2014         set_ia32_op_type(new_node, ia32_AddrModeD);
2015         set_ia32_ls_mode(new_node, mode);
2016         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2017
2018         return new_node;
2019 }
2020
2021 static ir_node *try_create_dest_am(ir_node *node) {
2022         ir_node  *val  = get_Store_value(node);
2023         ir_node  *mem  = get_Store_mem(node);
2024         ir_node  *ptr  = get_Store_ptr(node);
2025         ir_mode  *mode = get_irn_mode(val);
2026         unsigned  bits = get_mode_size_bits(mode);
2027         ir_node  *op1;
2028         ir_node  *op2;
2029         ir_node  *new_node;
2030
2031         /* handle only GP modes for now... */
2032         if(!mode_needs_gp_reg(mode))
2033                 return NULL;
2034
2035         while(1) {
2036                 /* store must be the only user of the val node */
2037                 if(get_irn_n_edges(val) > 1)
2038                         return NULL;
2039                 /* skip pointless convs */
2040                 if(is_Conv(val)) {
2041                         ir_node *conv_op   = get_Conv_op(val);
2042                         ir_mode *pred_mode = get_irn_mode(conv_op);
2043                         if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2044                                 val = conv_op;
2045                                 continue;
2046                         }
2047                 }
2048                 break;
2049         }
2050
2051         /* value must be in the same block */
2052         if(get_nodes_block(node) != get_nodes_block(val))
2053                 return NULL;
2054
2055         switch(get_irn_opcode(val)) {
2056         case iro_Add:
2057                 op1      = get_Add_left(val);
2058                 op2      = get_Add_right(val);
2059                 if(is_Const_1(op2)) {
2060                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2061                                                 new_rd_ia32_IncMem);
2062                         break;
2063                 } else if(is_Const_Minus_1(op2)) {
2064                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2065                                                 new_rd_ia32_DecMem);
2066                         break;
2067                 }
2068                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2069                                          new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2070                                          match_dest_am | match_commutative |
2071                                          match_immediate);
2072                 break;
2073         case iro_Sub:
2074                 op1      = get_Sub_left(val);
2075                 op2      = get_Sub_right(val);
2076                 if(is_Const(op2)) {
2077                         ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2078                                    "found\n");
2079                 }
2080                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2081                                          new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2082                                          match_dest_am | match_immediate |
2083                                          match_immediate);
2084                 break;
2085         case iro_And:
2086                 op1      = get_And_left(val);
2087                 op2      = get_And_right(val);
2088                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2089                                          new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2090                                          match_dest_am | match_commutative |
2091                                          match_immediate);
2092                 break;
2093         case iro_Or:
2094                 op1      = get_Or_left(val);
2095                 op2      = get_Or_right(val);
2096                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2097                                          new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2098                                          match_dest_am | match_commutative |
2099                                          match_immediate);
2100                 break;
2101         case iro_Eor:
2102                 op1      = get_Eor_left(val);
2103                 op2      = get_Eor_right(val);
2104                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2105                                          new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2106                                          match_dest_am | match_commutative |
2107                                          match_immediate);
2108                 break;
2109         case iro_Shl:
2110                 op1      = get_Shl_left(val);
2111                 op2      = get_Shl_right(val);
2112                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2113                                          new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2114                                          match_dest_am | match_immediate);
2115                 break;
2116         case iro_Shr:
2117                 op1      = get_Shr_left(val);
2118                 op2      = get_Shr_right(val);
2119                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2120                                          new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2121                                          match_dest_am | match_immediate);
2122                 break;
2123         case iro_Shrs:
2124                 op1      = get_Shrs_left(val);
2125                 op2      = get_Shrs_right(val);
2126                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2127                                          new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2128                                          match_dest_am | match_immediate);
2129                 break;
2130         case iro_Rot:
2131                 op1      = get_Rot_left(val);
2132                 op2      = get_Rot_right(val);
2133                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2134                                          new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2135                                          match_dest_am | match_immediate);
2136                 break;
2137         /* TODO: match ROR patterns... */
2138         case iro_Psi:
2139                 new_node = try_create_SetMem(val, ptr, mem);
2140                 break;
2141         case iro_Minus:
2142                 op1      = get_Minus_op(val);
2143                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2144                 break;
2145         case iro_Not:
2146                 /* should be lowered already */
2147                 assert(mode != mode_b);
2148                 op1      = get_Not_op(val);
2149                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2150                 break;
2151         default:
2152                 return NULL;
2153         }
2154
2155         if(new_node != NULL) {
2156                 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2157                                 get_irn_pinned(node) == op_pin_state_pinned) {
2158                         set_irn_pinned(new_node, op_pin_state_pinned);
2159                 }
2160         }
2161
2162         return new_node;
2163 }
2164
2165 static int is_float_to_int32_conv(const ir_node *node)
2166 {
2167         ir_mode  *mode = get_irn_mode(node);
2168         ir_node  *conv_op;
2169         ir_mode  *conv_mode;
2170
2171         if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2172                 return 0;
2173
2174         if(!is_Conv(node))
2175                 return 0;
2176         conv_op   = get_Conv_op(node);
2177         conv_mode = get_irn_mode(conv_op);
2178
2179         if(!mode_is_float(conv_mode))
2180                 return 0;
2181
2182         return 1;
2183 }
2184
2185 /**
2186  * Transforms a Store.
2187  *
2188  * @return the created ia32 Store node
2189  */
2190 static ir_node *gen_Store(ir_node *node)
2191 {
2192         ir_node  *block     = get_nodes_block(node);
2193         ir_node  *new_block = be_transform_node(block);
2194         ir_node  *ptr       = get_Store_ptr(node);
2195         ir_node  *val       = get_Store_value(node);
2196         ir_node  *mem       = get_Store_mem(node);
2197         ir_graph *irg       = current_ir_graph;
2198         dbg_info *dbgi      = get_irn_dbg_info(node);
2199         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2200         ir_mode  *mode      = get_irn_mode(val);
2201         ir_node  *new_val;
2202         ir_node  *new_node;
2203         ia32_address_t addr;
2204
2205         /* check for destination address mode */
2206         new_node = try_create_dest_am(node);
2207         if(new_node != NULL)
2208                 return new_node;
2209
2210         /* construct store address */
2211         memset(&addr, 0, sizeof(addr));
2212         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2213
2214         if(addr.base == NULL) {
2215                 addr.base = noreg;
2216         } else {
2217                 addr.base = be_transform_node(addr.base);
2218         }
2219
2220         if(addr.index == NULL) {
2221                 addr.index = noreg;
2222         } else {
2223                 addr.index = be_transform_node(addr.index);
2224         }
2225         addr.mem = be_transform_node(mem);
2226
2227         if (mode_is_float(mode)) {
2228                 /* convs (and strict-convs) before stores are unnecessary if the mode
2229                    is the same */
2230                 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2231                         val = get_Conv_op(val);
2232                 }
2233                 new_val = be_transform_node(val);
2234                 if (ia32_cg_config.use_sse2) {
2235                         new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2236                                                       addr.index, addr.mem, new_val);
2237                 } else {
2238                         new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2239                                                     addr.index, addr.mem, new_val, mode);
2240                 }
2241         } else if(is_float_to_int32_conv(val)) {
2242                 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2243                 val = get_Conv_op(val);
2244
2245                 /* convs (and strict-convs) before stores are unnecessary if the mode
2246                    is the same */
2247                 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2248                         val = get_Conv_op(val);
2249                 }
2250                 new_val = be_transform_node(val);
2251
2252                 new_node = new_rd_ia32_vfist(dbgi, irg, new_block, addr.base,
2253                                              addr.index, addr.mem, new_val, trunc_mode);
2254         } else {
2255                 new_val = create_immediate_or_transform(val, 0);
2256                 assert(mode != mode_b);
2257
2258                 if (get_mode_size_bits(mode) == 8) {
2259                         new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2260                                                          addr.index, addr.mem, new_val);
2261                 } else {
2262                         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2263                                                      addr.index, addr.mem, new_val);
2264                 }
2265         }
2266
2267         set_irn_pinned(new_node, get_irn_pinned(node));
2268         set_ia32_op_type(new_node, ia32_AddrModeD);
2269         set_ia32_ls_mode(new_node, mode);
2270
2271         set_address(new_node, &addr);
2272         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2273
2274         return new_node;
2275 }
2276
2277 static ir_node *create_Switch(ir_node *node)
2278 {
2279         ir_graph *irg        = current_ir_graph;
2280         dbg_info *dbgi       = get_irn_dbg_info(node);
2281         ir_node  *block      = be_transform_node(get_nodes_block(node));
2282         ir_node  *sel        = get_Cond_selector(node);
2283         ir_node  *new_sel    = be_transform_node(sel);
2284         int       switch_min = INT_MAX;
2285         int       switch_max = INT_MIN;
2286         long      default_pn = get_Cond_defaultProj(node);
2287         ir_node  *new_node;
2288         const ir_edge_t *edge;
2289
2290         assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2291
2292         /* determine the smallest switch case value */
2293         foreach_out_edge(node, edge) {
2294                 ir_node *proj = get_edge_src_irn(edge);
2295                 long     pn   = get_Proj_proj(proj);
2296                 if(pn == default_pn)
2297                         continue;
2298
2299                 if(pn < switch_min)
2300                         switch_min = pn;
2301                 if(pn > switch_max)
2302                         switch_max = pn;
2303         }
2304
2305         if((unsigned) (switch_max - switch_min) > 256000) {
2306                 panic("Size of switch %+F bigger than 256000", node);
2307         }
2308
2309         if (switch_min != 0) {
2310                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2311
2312                 /* if smallest switch case is not 0 we need an additional sub */
2313                 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2314                 add_ia32_am_offs_int(new_sel, -switch_min);
2315                 set_ia32_op_type(new_sel, ia32_AddrModeS);
2316
2317                 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2318         }
2319
2320         new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2321         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2322
2323         return new_node;
2324 }
2325
2326 static ir_node *gen_Cond(ir_node *node) {
2327         ir_node  *block     = get_nodes_block(node);
2328         ir_node  *new_block = be_transform_node(block);
2329         ir_graph *irg       = current_ir_graph;
2330         dbg_info *dbgi      = get_irn_dbg_info(node);
2331         ir_node  *sel       = get_Cond_selector(node);
2332         ir_mode  *sel_mode  = get_irn_mode(sel);
2333         ir_node  *flags     = NULL;
2334         ir_node  *new_node;
2335         pn_Cmp    pnc;
2336
2337         if (sel_mode != mode_b) {
2338                 return create_Switch(node);
2339         }
2340
2341         /* we get flags from a cmp */
2342         flags = get_flags_node(sel, &pnc);
2343
2344         new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2345         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2346
2347         return new_node;
2348 }
2349
2350
2351
2352 /**
2353  * Transforms a CopyB node.
2354  *
2355  * @return The transformed node.
2356  */
2357 static ir_node *gen_CopyB(ir_node *node) {
2358         ir_node  *block    = be_transform_node(get_nodes_block(node));
2359         ir_node  *src      = get_CopyB_src(node);
2360         ir_node  *new_src  = be_transform_node(src);
2361         ir_node  *dst      = get_CopyB_dst(node);
2362         ir_node  *new_dst  = be_transform_node(dst);
2363         ir_node  *mem      = get_CopyB_mem(node);
2364         ir_node  *new_mem  = be_transform_node(mem);
2365         ir_node  *res      = NULL;
2366         ir_graph *irg      = current_ir_graph;
2367         dbg_info *dbgi     = get_irn_dbg_info(node);
2368         int      size      = get_type_size_bytes(get_CopyB_type(node));
2369         int      rem;
2370
2371         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2372         /* then we need the size explicitly in ECX.                    */
2373         if (size >= 32 * 4) {
2374                 rem = size & 0x3; /* size % 4 */
2375                 size >>= 2;
2376
2377                 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2378                 add_irn_dep(res, get_irg_frame(irg));
2379
2380                 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2381         } else {
2382                 if(size == 0) {
2383                         ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2384                                    node);
2385                 }
2386                 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2387         }
2388
2389         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2390
2391         return res;
2392 }
2393
2394 static ir_node *gen_be_Copy(ir_node *node)
2395 {
2396         ir_node *new_node = be_duplicate_node(node);
2397         ir_mode *mode     = get_irn_mode(new_node);
2398
2399         if (mode_needs_gp_reg(mode)) {
2400                 set_irn_mode(new_node, mode_Iu);
2401         }
2402
2403         return new_node;
2404 }
2405
2406 static ir_node *create_Fucom(ir_node *node)
2407 {
2408         ir_graph *irg       = current_ir_graph;
2409         dbg_info *dbgi      = get_irn_dbg_info(node);
2410         ir_node  *block     = get_nodes_block(node);
2411         ir_node  *new_block = be_transform_node(block);
2412         ir_node  *left      = get_Cmp_left(node);
2413         ir_node  *new_left  = be_transform_node(left);
2414         ir_node  *right     = get_Cmp_right(node);
2415         ir_node  *new_right;
2416         ir_node  *new_node;
2417
2418         if(ia32_cg_config.use_fucomi) {
2419                 new_right = be_transform_node(right);
2420                 new_node  = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2421                                                 new_right, 0);
2422                 set_ia32_commutative(new_node);
2423                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2424         } else {
2425                 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2426                         new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2427                                                            0);
2428                 } else {
2429                         new_right = be_transform_node(right);
2430                         new_node  = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2431                                                                                                  new_right, 0);
2432                 }
2433
2434                 set_ia32_commutative(new_node);
2435
2436                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2437
2438                 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2439                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2440         }
2441
2442         return new_node;
2443 }
2444
2445 static ir_node *create_Ucomi(ir_node *node)
2446 {
2447         ir_graph *irg       = current_ir_graph;
2448         dbg_info *dbgi      = get_irn_dbg_info(node);
2449         ir_node  *src_block = get_nodes_block(node);
2450         ir_node  *new_block = be_transform_node(src_block);
2451         ir_node  *left      = get_Cmp_left(node);
2452         ir_node  *right     = get_Cmp_right(node);
2453         ir_node  *new_node;
2454         ia32_address_mode_t  am;
2455         ia32_address_t      *addr = &am.addr;
2456
2457         match_arguments(&am, src_block, left, right, NULL,
2458                         match_commutative | match_am);
2459
2460         new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2461                                      addr->mem, am.new_op1, am.new_op2,
2462                                      am.ins_permuted);
2463         set_am_attributes(new_node, &am);
2464
2465         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2466
2467         new_node = fix_mem_proj(new_node, &am);
2468
2469         return new_node;
2470 }
2471
2472 /**
2473  * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2474  * to fold an and into a test node
2475  */
2476 static int can_fold_test_and(ir_node *node)
2477 {
2478         const ir_edge_t *edge;
2479
2480         /** we can only have eq and lg projs */
2481         foreach_out_edge(node, edge) {
2482                 ir_node *proj = get_edge_src_irn(edge);
2483                 pn_Cmp   pnc  = get_Proj_proj(proj);
2484                 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2485                         return 0;
2486         }
2487
2488         return 1;
2489 }
2490
2491 static ir_node *gen_Cmp(ir_node *node)
2492 {
2493         ir_graph *irg       = current_ir_graph;
2494         dbg_info *dbgi      = get_irn_dbg_info(node);
2495         ir_node  *block     = get_nodes_block(node);
2496         ir_node  *new_block = be_transform_node(block);
2497         ir_node  *left      = get_Cmp_left(node);
2498         ir_node  *right     = get_Cmp_right(node);
2499         ir_mode  *cmp_mode  = get_irn_mode(left);
2500         ir_node  *new_node;
2501         ia32_address_mode_t  am;
2502         ia32_address_t      *addr = &am.addr;
2503         int                  cmp_unsigned;
2504
2505         if(mode_is_float(cmp_mode)) {
2506                 if (ia32_cg_config.use_sse2) {
2507                         return create_Ucomi(node);
2508                 } else {
2509                         return create_Fucom(node);
2510                 }
2511         }
2512
2513         assert(mode_needs_gp_reg(cmp_mode));
2514
2515         /* we prefer the Test instruction where possible except cases where
2516          * we can use SourceAM */
2517         cmp_unsigned = !mode_is_signed(cmp_mode);
2518         if (is_Const_0(right)) {
2519                 if (is_And(left) &&
2520                                 get_irn_n_edges(left) == 1 &&
2521                                 can_fold_test_and(node)) {
2522                         /* Test(and_left, and_right) */
2523                         ir_node *and_left  = get_And_left(left);
2524                         ir_node *and_right = get_And_right(left);
2525                         ir_mode *mode      = get_irn_mode(and_left);
2526
2527                         match_arguments(&am, block, and_left, and_right, NULL,
2528                                         match_commutative |
2529                                         match_am | match_8bit_am | match_16bit_am |
2530                                         match_am_and_immediates | match_immediate |
2531                                         match_8bit | match_16bit);
2532                         if (get_mode_size_bits(mode) == 8) {
2533                                 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2534                                                                 addr->index, addr->mem, am.new_op1,
2535                                                                 am.new_op2, am.ins_permuted,
2536                                                                 cmp_unsigned);
2537                         } else {
2538                                 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2539                                                             addr->index, addr->mem, am.new_op1,
2540                                                             am.new_op2, am.ins_permuted, cmp_unsigned);
2541                         }
2542                 } else {
2543                         match_arguments(&am, block, NULL, left, NULL,
2544                                         match_am | match_8bit_am | match_16bit_am |
2545                                         match_8bit | match_16bit);
2546                         if (am.op_type == ia32_AddrModeS) {
2547                                 /* Cmp(AM, 0) */
2548                                 ir_node *imm_zero = try_create_Immediate(right, 0);
2549                                 if (get_mode_size_bits(cmp_mode) == 8) {
2550                                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2551                                                                        addr->index, addr->mem, am.new_op2,
2552                                                                        imm_zero, am.ins_permuted,
2553                                                                        cmp_unsigned);
2554                                 } else {
2555                                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2556                                                                    addr->index, addr->mem, am.new_op2,
2557                                                                    imm_zero, am.ins_permuted, cmp_unsigned);
2558                                 }
2559                         } else {
2560                                 /* Test(left, left) */
2561                                 if (get_mode_size_bits(cmp_mode) == 8) {
2562                                         new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2563                                                                         addr->index, addr->mem, am.new_op2,
2564                                                                         am.new_op2, am.ins_permuted,
2565                                                                         cmp_unsigned);
2566                                 } else {
2567                                         new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2568                                                                     addr->index, addr->mem, am.new_op2,
2569                                                                     am.new_op2, am.ins_permuted,
2570                                                                     cmp_unsigned);
2571                                 }
2572                         }
2573                 }
2574         } else {
2575                 /* Cmp(left, right) */
2576                 match_arguments(&am, block, left, right, NULL,
2577                                 match_commutative | match_am | match_8bit_am |
2578                                 match_16bit_am | match_am_and_immediates |
2579                                 match_immediate | match_8bit | match_16bit);
2580                 if (get_mode_size_bits(cmp_mode) == 8) {
2581                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2582                                                        addr->index, addr->mem, am.new_op1,
2583                                                        am.new_op2, am.ins_permuted,
2584                                                        cmp_unsigned);
2585                 } else {
2586                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2587                                                    addr->index, addr->mem, am.new_op1,
2588                                                    am.new_op2, am.ins_permuted, cmp_unsigned);
2589                 }
2590         }
2591         set_am_attributes(new_node, &am);
2592         assert(cmp_mode != NULL);
2593         set_ia32_ls_mode(new_node, cmp_mode);
2594
2595         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2596
2597         new_node = fix_mem_proj(new_node, &am);
2598
2599         return new_node;
2600 }
2601
2602 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2603                             pn_Cmp pnc)
2604 {
2605         ir_graph            *irg           = current_ir_graph;
2606         dbg_info            *dbgi          = get_irn_dbg_info(node);
2607         ir_node             *block         = get_nodes_block(node);
2608         ir_node             *new_block     = be_transform_node(block);
2609         ir_node             *val_true      = get_Psi_val(node, 0);
2610         ir_node             *val_false     = get_Psi_default(node);
2611         ir_node             *new_node;
2612         match_flags_t        match_flags;
2613         ia32_address_mode_t  am;
2614         ia32_address_t      *addr;
2615
2616         assert(ia32_cg_config.use_cmov);
2617         assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2618
2619         addr = &am.addr;
2620
2621         match_flags = match_commutative | match_am | match_16bit_am |
2622                       match_mode_neutral;
2623
2624         match_arguments(&am, block, val_false, val_true, flags, match_flags);
2625
2626         new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2627                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2628                                     am.ins_permuted, pnc);
2629         set_am_attributes(new_node, &am);
2630
2631         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2632
2633         new_node = fix_mem_proj(new_node, &am);
2634
2635         return new_node;
2636 }
2637
2638
2639
2640 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2641                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2642                                  int ins_permuted)
2643 {
2644         ir_graph *irg   = current_ir_graph;
2645         ir_node  *noreg = ia32_new_NoReg_gp(env_cg);
2646         ir_node  *nomem = new_NoMem();
2647         ir_mode  *mode  = get_irn_mode(orig_node);
2648         ir_node  *new_node;
2649
2650         new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2651         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2652
2653         /* we might need to conv the result up */
2654         if(get_mode_size_bits(mode) > 8) {
2655                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2656                                                     nomem, new_node, mode_Bu);
2657                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2658         }
2659
2660         return new_node;
2661 }
2662
2663 /**
2664  * Transforms a Psi node into CMov.
2665  *
2666  * @return The transformed node.
2667  */
2668 static ir_node *gen_Psi(ir_node *node)
2669 {
2670         dbg_info *dbgi        = get_irn_dbg_info(node);
2671         ir_node  *block       = get_nodes_block(node);
2672         ir_node  *new_block   = be_transform_node(block);
2673         ir_node  *psi_true    = get_Psi_val(node, 0);
2674         ir_node  *psi_default = get_Psi_default(node);
2675         ir_node  *cond        = get_Psi_cond(node, 0);
2676         ir_node  *flags       = NULL;
2677         ir_node  *new_node;
2678         pn_Cmp    pnc;
2679
2680         assert(get_Psi_n_conds(node) == 1);
2681         assert(get_irn_mode(cond) == mode_b);
2682         assert(mode_needs_gp_reg(get_irn_mode(node)));
2683
2684         flags = get_flags_node(cond, &pnc);
2685
2686         if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2687                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 0);
2688         } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2689                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 1);
2690         } else {
2691                 new_node = create_CMov(node, cond, flags, pnc);
2692         }
2693         return new_node;
2694 }
2695
2696
2697 /**
2698  * Create a conversion from x87 state register to general purpose.
2699  */
2700 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
2701         ir_node         *block      = be_transform_node(get_nodes_block(node));
2702         ir_node         *op         = get_Conv_op(node);
2703         ir_node         *new_op     = be_transform_node(op);
2704         ia32_code_gen_t *cg         = env_cg;
2705         ir_graph        *irg        = current_ir_graph;
2706         dbg_info        *dbgi       = get_irn_dbg_info(node);
2707         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
2708         ir_node         *trunc_mode = ia32_new_Fpu_truncate(cg);
2709         ir_mode         *mode       = get_irn_mode(node);
2710         ir_node         *fist, *load;
2711
2712         /* do a fist */
2713         fist = new_rd_ia32_vfist(dbgi, irg, block, get_irg_frame(irg), noreg,
2714                                  new_NoMem(), new_op, trunc_mode);
2715
2716         set_irn_pinned(fist, op_pin_state_floats);
2717         set_ia32_use_frame(fist);
2718         set_ia32_op_type(fist, ia32_AddrModeD);
2719
2720         assert(get_mode_size_bits(mode) <= 32);
2721         /* exception we can only store signed 32 bit integers, so for unsigned
2722            we store a 64bit (signed) integer and load the lower bits */
2723         if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
2724                 set_ia32_ls_mode(fist, mode_Ls);
2725         } else {
2726                 set_ia32_ls_mode(fist, mode_Is);
2727         }
2728         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
2729
2730         /* do a Load */
2731         load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, fist);
2732
2733         set_irn_pinned(load, op_pin_state_floats);
2734         set_ia32_use_frame(load);
2735         set_ia32_op_type(load, ia32_AddrModeS);
2736         set_ia32_ls_mode(load, mode_Is);
2737         if(get_ia32_ls_mode(fist) == mode_Ls) {
2738                 ia32_attr_t *attr = get_ia32_attr(load);
2739                 attr->data.need_64bit_stackent = 1;
2740         } else {
2741                 ia32_attr_t *attr = get_ia32_attr(load);
2742                 attr->data.need_32bit_stackent = 1;
2743         }
2744         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
2745
2746         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
2747 }
2748
2749 /**
2750  * Creates a x87 strict Conv by placing a Sore and a Load
2751  */
2752 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
2753 {
2754         ir_node  *block    = get_nodes_block(node);
2755         ir_graph *irg      = current_ir_graph;
2756         dbg_info *dbgi     = get_irn_dbg_info(node);
2757         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
2758         ir_node  *nomem    = new_NoMem();
2759         ir_node  *frame    = get_irg_frame(irg);
2760         ir_node  *store, *load;
2761         ir_node  *new_node;
2762
2763         store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
2764                                  tgt_mode);
2765         set_ia32_use_frame(store);
2766         set_ia32_op_type(store, ia32_AddrModeD);
2767         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2768
2769         load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
2770                                 tgt_mode);
2771         set_ia32_use_frame(load);
2772         set_ia32_op_type(load, ia32_AddrModeS);
2773         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
2774
2775         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
2776         return new_node;
2777 }
2778
2779 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
2780 {
2781         ir_graph *irg         = current_ir_graph;
2782         ir_node  *start_block = get_irg_start_block(irg);
2783         ir_node  *immediate   = new_rd_ia32_Immediate(NULL, irg, start_block,
2784                                                       symconst, symconst_sign, val);
2785         arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
2786
2787         return immediate;
2788 }
2789
2790 /**
2791  * Create a conversion from general purpose to x87 register
2792  */
2793 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
2794         ir_node  *src_block = get_nodes_block(node);
2795         ir_node  *block     = be_transform_node(src_block);
2796         ir_graph *irg       = current_ir_graph;
2797         dbg_info *dbgi      = get_irn_dbg_info(node);
2798         ir_node  *op        = get_Conv_op(node);
2799         ir_node  *new_op    = NULL;
2800         ir_node  *noreg;
2801         ir_node  *nomem;
2802         ir_mode  *mode;
2803         ir_mode  *store_mode;
2804         ir_node  *fild;
2805         ir_node  *store;
2806         ir_node  *new_node;
2807         int       src_bits;
2808
2809         /* fild can use source AM if the operand is a signed 32bit integer */
2810         if (src_mode == mode_Is) {
2811                 ia32_address_mode_t am;
2812
2813                 match_arguments(&am, src_block, NULL, op, NULL,
2814                                 match_am | match_try_am);
2815                 if (am.op_type == ia32_AddrModeS) {
2816                         ia32_address_t *addr = &am.addr;
2817
2818                         fild     = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
2819                                                      addr->index, addr->mem);
2820                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
2821                                               pn_ia32_vfild_res);
2822
2823                         set_am_attributes(fild, &am);
2824                         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
2825
2826                         fix_mem_proj(fild, &am);
2827
2828                         return new_node;
2829                 }
2830         }
2831         if(new_op == NULL) {
2832                 new_op = be_transform_node(op);
2833         }
2834
2835         noreg  = ia32_new_NoReg_gp(env_cg);
2836         nomem  = new_NoMem();
2837         mode   = get_irn_mode(op);
2838
2839         /* first convert to 32 bit signed if necessary */
2840         src_bits = get_mode_size_bits(src_mode);
2841         if (src_bits == 8) {
2842                 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
2843                                                   new_op, src_mode);
2844                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
2845                 mode = mode_Is;
2846         } else if (src_bits < 32) {
2847                 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
2848                                               new_op, src_mode);
2849                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
2850                 mode = mode_Is;
2851         }
2852
2853         assert(get_mode_size_bits(mode) == 32);
2854
2855         /* do a store */
2856         store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
2857                                   new_op);
2858
2859         set_ia32_use_frame(store);
2860         set_ia32_op_type(store, ia32_AddrModeD);
2861         set_ia32_ls_mode(store, mode_Iu);
2862
2863         /* exception for 32bit unsigned, do a 64bit spill+load */
2864         if(!mode_is_signed(mode)) {
2865                 ir_node *in[2];
2866                 /* store a zero */
2867                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
2868
2869                 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
2870                                                         get_irg_frame(irg), noreg, nomem,
2871                                                         zero_const);
2872
2873                 set_ia32_use_frame(zero_store);
2874                 set_ia32_op_type(zero_store, ia32_AddrModeD);
2875                 add_ia32_am_offs_int(zero_store, 4);
2876                 set_ia32_ls_mode(zero_store, mode_Iu);
2877
2878                 in[0] = zero_store;
2879                 in[1] = store;
2880
2881                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
2882                 store_mode = mode_Ls;
2883         } else {
2884                 store_mode = mode_Is;
2885         }
2886
2887         /* do a fild */
2888         fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
2889
2890         set_ia32_use_frame(fild);
2891         set_ia32_op_type(fild, ia32_AddrModeS);
2892         set_ia32_ls_mode(fild, store_mode);
2893
2894         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
2895
2896         return new_node;
2897 }
2898
2899 /**
2900  * Create a conversion from one integer mode into another one
2901  */
2902 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
2903                                 dbg_info *dbgi, ir_node *block, ir_node *op,
2904                                 ir_node *node)
2905 {
2906         ir_graph *irg       = current_ir_graph;
2907         int       src_bits  = get_mode_size_bits(src_mode);
2908         int       tgt_bits  = get_mode_size_bits(tgt_mode);
2909         ir_node  *new_block = be_transform_node(block);
2910         ir_node  *new_node;
2911         ir_mode  *smaller_mode;
2912         int       smaller_bits;
2913         ia32_address_mode_t  am;
2914         ia32_address_t      *addr = &am.addr;
2915
2916         (void) node;
2917         if (src_bits < tgt_bits) {
2918                 smaller_mode = src_mode;
2919                 smaller_bits = src_bits;
2920         } else {
2921                 smaller_mode = tgt_mode;
2922                 smaller_bits = tgt_bits;
2923         }
2924
2925 #ifdef DEBUG_libfirm
2926         if(is_Const(op)) {
2927                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
2928                            op);
2929         }
2930 #endif
2931
2932         match_arguments(&am, block, NULL, op, NULL,
2933                         match_8bit | match_16bit |
2934                         match_am | match_8bit_am | match_16bit_am);
2935         if (smaller_bits == 8) {
2936                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
2937                                                     addr->index, addr->mem, am.new_op2,
2938                                                     smaller_mode);
2939         } else {
2940                 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
2941                                                 addr->index, addr->mem, am.new_op2,
2942                                                 smaller_mode);
2943         }
2944         set_am_attributes(new_node, &am);
2945         /* match_arguments assume that out-mode = in-mode, this isn't true here
2946          * so fix it */
2947         set_ia32_ls_mode(new_node, smaller_mode);
2948         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2949         new_node = fix_mem_proj(new_node, &am);
2950         return new_node;
2951 }
2952
2953 /**
2954  * Transforms a Conv node.
2955  *
2956  * @return The created ia32 Conv node
2957  */
2958 static ir_node *gen_Conv(ir_node *node) {
2959         ir_node  *block     = get_nodes_block(node);
2960         ir_node  *new_block = be_transform_node(block);
2961         ir_node  *op        = get_Conv_op(node);
2962         ir_node  *new_op    = NULL;
2963         ir_graph *irg       = current_ir_graph;
2964         dbg_info *dbgi      = get_irn_dbg_info(node);
2965         ir_mode  *src_mode  = get_irn_mode(op);
2966         ir_mode  *tgt_mode  = get_irn_mode(node);
2967         int       src_bits  = get_mode_size_bits(src_mode);
2968         int       tgt_bits  = get_mode_size_bits(tgt_mode);
2969         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2970         ir_node  *nomem     = new_rd_NoMem(irg);
2971         ir_node  *res       = NULL;
2972
2973         if (src_mode == mode_b) {
2974                 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
2975                 /* nothing to do, we already model bools as 0/1 ints */
2976                 return be_transform_node(op);
2977         }
2978
2979         if (src_mode == tgt_mode) {
2980                 if (get_Conv_strict(node)) {
2981                         if (ia32_cg_config.use_sse2) {
2982                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
2983                                 return be_transform_node(op);
2984                         }
2985                 } else {
2986                         /* this should be optimized already, but who knows... */
2987                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
2988                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
2989                         return be_transform_node(op);
2990                 }
2991         }
2992
2993         if (mode_is_float(src_mode)) {
2994                 new_op = be_transform_node(op);
2995                 /* we convert from float ... */
2996                 if (mode_is_float(tgt_mode)) {
2997                         if(src_mode == mode_E && tgt_mode == mode_D
2998                                         && !get_Conv_strict(node)) {
2999                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3000                                 return new_op;
3001                         }
3002
3003                         /* ... to float */
3004                         if (ia32_cg_config.use_sse2) {
3005                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3006                                 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3007                                                              nomem, new_op);
3008                                 set_ia32_ls_mode(res, tgt_mode);
3009                         } else {
3010                                 if(get_Conv_strict(node)) {
3011                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3012                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3013                                         return res;
3014                                 }
3015                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3016                                 return new_op;
3017                         }
3018                 } else {
3019                         /* ... to int */
3020                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3021                         if (ia32_cg_config.use_sse2) {
3022                                 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3023                                                             nomem, new_op);
3024                                 set_ia32_ls_mode(res, src_mode);
3025                         } else {
3026                                 return gen_x87_fp_to_gp(node);
3027                         }
3028                 }
3029         } else {
3030                 /* we convert from int ... */
3031                 if (mode_is_float(tgt_mode)) {
3032                         /* ... to float */
3033                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3034                         if (ia32_cg_config.use_sse2) {
3035                                 new_op = be_transform_node(op);
3036                                 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3037                                                             nomem, new_op);
3038                                 set_ia32_ls_mode(res, tgt_mode);
3039                         } else {
3040                                 res = gen_x87_gp_to_fp(node, src_mode);
3041                                 if(get_Conv_strict(node)) {
3042                                         res = gen_x87_strict_conv(tgt_mode, res);
3043                                         SET_IA32_ORIG_NODE(get_Proj_pred(res),
3044                                                            ia32_get_old_node_name(env_cg, node));
3045                                 }
3046                                 return res;
3047                         }
3048                 } else if(tgt_mode == mode_b) {
3049                         /* mode_b lowering already took care that we only have 0/1 values */
3050                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3051                             src_mode, tgt_mode));
3052                         return be_transform_node(op);
3053                 } else {
3054                         /* to int */
3055                         if (src_bits == tgt_bits) {
3056                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3057                                     src_mode, tgt_mode));
3058                                 return be_transform_node(op);
3059                         }
3060
3061                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3062                         return res;
3063                 }
3064         }
3065
3066         return res;
3067 }
3068
3069 static int check_immediate_constraint(long val, char immediate_constraint_type)
3070 {
3071         switch (immediate_constraint_type) {
3072         case 0:
3073                 return 1;
3074         case 'I':
3075                 return val >= 0 && val <= 32;
3076         case 'J':
3077                 return val >= 0 && val <= 63;
3078         case 'K':
3079                 return val >= -128 && val <= 127;
3080         case 'L':
3081                 return val == 0xff || val == 0xffff;
3082         case 'M':
3083                 return val >= 0 && val <= 3;
3084         case 'N':
3085                 return val >= 0 && val <= 255;
3086         case 'O':
3087                 return val >= 0 && val <= 127;
3088         default:
3089                 break;
3090         }
3091         panic("Invalid immediate constraint found");
3092         return 0;
3093 }
3094
3095 static ir_node *try_create_Immediate(ir_node *node,
3096                                      char immediate_constraint_type)
3097 {
3098         int          minus         = 0;
3099         tarval      *offset        = NULL;
3100         int          offset_sign   = 0;
3101         long         val = 0;
3102         ir_entity   *symconst_ent  = NULL;
3103         int          symconst_sign = 0;
3104         ir_mode     *mode;
3105         ir_node     *cnst          = NULL;
3106         ir_node     *symconst      = NULL;
3107         ir_node     *new_node;
3108
3109         mode = get_irn_mode(node);
3110         if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3111                 return NULL;
3112         }
3113
3114         if(is_Minus(node)) {
3115                 minus = 1;
3116                 node  = get_Minus_op(node);
3117         }
3118
3119         if(is_Const(node)) {
3120                 cnst        = node;
3121                 symconst    = NULL;
3122                 offset_sign = minus;
3123         } else if(is_SymConst(node)) {
3124                 cnst          = NULL;
3125                 symconst      = node;
3126                 symconst_sign = minus;
3127         } else if(is_Add(node)) {
3128                 ir_node *left  = get_Add_left(node);
3129                 ir_node *right = get_Add_right(node);
3130                 if(is_Const(left) && is_SymConst(right)) {
3131                         cnst          = left;
3132                         symconst      = right;
3133                         symconst_sign = minus;
3134                         offset_sign   = minus;
3135                 } else if(is_SymConst(left) && is_Const(right)) {
3136                         cnst          = right;
3137                         symconst      = left;
3138                         symconst_sign = minus;
3139                         offset_sign   = minus;
3140                 }
3141         } else if(is_Sub(node)) {
3142                 ir_node *left  = get_Sub_left(node);
3143                 ir_node *right = get_Sub_right(node);
3144                 if(is_Const(left) && is_SymConst(right)) {
3145                         cnst          = left;
3146                         symconst      = right;
3147                         symconst_sign = !minus;
3148                         offset_sign   = minus;
3149                 } else if(is_SymConst(left) && is_Const(right)) {
3150                         cnst          = right;
3151                         symconst      = left;
3152                         symconst_sign = minus;
3153                         offset_sign   = !minus;
3154                 }
3155         } else {
3156                 return NULL;
3157         }
3158
3159         if(cnst != NULL) {
3160                 offset = get_Const_tarval(cnst);
3161                 if(tarval_is_long(offset)) {
3162                         val = get_tarval_long(offset);
3163                 } else {
3164                         ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3165                                    "long?\n", cnst);
3166                         return NULL;
3167                 }
3168
3169                 if(!check_immediate_constraint(val, immediate_constraint_type))
3170                         return NULL;
3171         }
3172         if(symconst != NULL) {
3173                 if(immediate_constraint_type != 0) {
3174                         /* we need full 32bits for symconsts */
3175                         return NULL;
3176                 }
3177
3178                 /* unfortunately the assembler/linker doesn't support -symconst */
3179                 if(symconst_sign)
3180                         return NULL;
3181
3182                 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3183                         return NULL;
3184                 symconst_ent = get_SymConst_entity(symconst);
3185         }
3186         if(cnst == NULL && symconst == NULL)
3187                 return NULL;
3188
3189         if(offset_sign && offset != NULL) {
3190                 offset = tarval_neg(offset);
3191         }
3192
3193         new_node = create_Immediate(symconst_ent, symconst_sign, val);
3194
3195         return new_node;
3196 }
3197
3198 static ir_node *create_immediate_or_transform(ir_node *node,
3199                                               char immediate_constraint_type)
3200 {
3201         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3202         if (new_node == NULL) {
3203                 new_node = be_transform_node(node);
3204         }
3205         return new_node;
3206 }
3207
3208 static const arch_register_req_t no_register_req = {
3209         arch_register_req_type_none,
3210         NULL,                         /* regclass */
3211         NULL,                         /* limit bitset */
3212         0,                            /* same pos */
3213         0                             /* different pos */
3214 };
3215
3216 /**
3217  * An assembler constraint.
3218  */
3219 typedef struct constraint_t constraint_t;
3220 struct constraint_t {
3221         int                         is_in;
3222         int                         n_outs;
3223         const arch_register_req_t **out_reqs;
3224
3225         const arch_register_req_t  *req;
3226         unsigned                    immediate_possible;
3227         char                        immediate_type;
3228 };
3229
3230 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3231 {
3232         int                          immediate_possible = 0;
3233         char                         immediate_type     = 0;
3234         unsigned                     limited            = 0;
3235         const arch_register_class_t *cls                = NULL;
3236         ir_graph                    *irg = current_ir_graph;
3237         struct obstack              *obst = get_irg_obstack(irg);
3238         arch_register_req_t         *req;
3239         unsigned                    *limited_ptr = NULL;
3240         int                          p;
3241         int                          same_as = -1;
3242
3243         /* TODO: replace all the asserts with nice error messages */
3244
3245         if(*c == 0) {
3246                 /* a memory constraint: no need to do anything in backend about it
3247                  * (the dependencies are already respected by the memory edge of
3248                  * the node) */
3249                 constraint->req = &no_register_req;
3250                 return;
3251         }
3252
3253         while(*c != 0) {
3254                 switch(*c) {
3255                 case ' ':
3256                 case '\t':
3257                 case '\n':
3258                         break;
3259
3260                 case 'a':
3261                         assert(cls == NULL ||
3262                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3263                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3264                         limited |= 1 << REG_EAX;
3265                         break;
3266                 case 'b':
3267                         assert(cls == NULL ||
3268                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3269                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3270                         limited |= 1 << REG_EBX;
3271                         break;
3272                 case 'c':
3273                         assert(cls == NULL ||
3274                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3275                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3276                         limited |= 1 << REG_ECX;
3277                         break;
3278                 case 'd':
3279                         assert(cls == NULL ||
3280                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3281                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3282                         limited |= 1 << REG_EDX;
3283                         break;
3284                 case 'D':
3285                         assert(cls == NULL ||
3286                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3287                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3288                         limited |= 1 << REG_EDI;
3289                         break;
3290                 case 'S':
3291                         assert(cls == NULL ||
3292                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3293                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3294                         limited |= 1 << REG_ESI;
3295                         break;
3296                 case 'Q':
3297                 case 'q': /* q means lower part of the regs only, this makes no
3298                                    * difference to Q for us (we only assigne whole registers) */
3299                         assert(cls == NULL ||
3300                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3301                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3302                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3303                                    1 << REG_EDX;
3304                         break;
3305                 case 'A':
3306                         assert(cls == NULL ||
3307                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3308                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3309                         limited |= 1 << REG_EAX | 1 << REG_EDX;
3310                         break;
3311                 case 'l':
3312                         assert(cls == NULL ||
3313                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3314                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3315                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3316                                    1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3317                                    1 << REG_EBP;
3318                         break;
3319
3320                 case 'R':
3321                 case 'r':
3322                 case 'p':
3323                         assert(cls == NULL);
3324                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3325                         break;
3326
3327                 case 'f':
3328                 case 't':
3329                 case 'u':
3330                         /* TODO: mark values so the x87 simulator knows about t and u */
3331                         assert(cls == NULL);
3332                         cls = &ia32_reg_classes[CLASS_ia32_vfp];
3333                         break;
3334
3335                 case 'Y':
3336                 case 'x':
3337                         assert(cls == NULL);
3338                         /* TODO: check that sse2 is supported */
3339                         cls = &ia32_reg_classes[CLASS_ia32_xmm];
3340                         break;
3341
3342                 case 'I':
3343                 case 'J':
3344                 case 'K':
3345                 case 'L':
3346                 case 'M':
3347                 case 'N':
3348                 case 'O':
3349                         assert(!immediate_possible);
3350                         immediate_possible = 1;
3351                         immediate_type     = *c;
3352                         break;
3353                 case 'n':
3354                 case 'i':
3355                         assert(!immediate_possible);
3356                         immediate_possible = 1;
3357                         break;
3358
3359                 case 'g':
3360                         assert(!immediate_possible && cls == NULL);
3361                         immediate_possible = 1;
3362                         cls                = &ia32_reg_classes[CLASS_ia32_gp];
3363                         break;
3364
3365                 case '0':
3366                 case '1':
3367                 case '2':
3368                 case '3':
3369                 case '4':
3370                 case '5':
3371                 case '6':
3372                 case '7':
3373                 case '8':
3374                 case '9':
3375                         assert(constraint->is_in && "can only specify same constraint "
3376                                "on input");
3377
3378                         sscanf(c, "%d%n", &same_as, &p);
3379                         if(same_as >= 0) {
3380                                 c += p;
3381                                 continue;
3382                         }
3383                         break;
3384
3385                 case 'm':
3386                         /* memory constraint no need to do anything in backend about it
3387                          * (the dependencies are already respected by the memory edge of
3388                          * the node) */
3389                         constraint->req    = &no_register_req;
3390                         return;
3391
3392                 case 'E': /* no float consts yet */
3393                 case 'F': /* no float consts yet */
3394                 case 's': /* makes no sense on x86 */
3395                 case 'X': /* we can't support that in firm */
3396                 case 'o':
3397                 case 'V':
3398                 case '<': /* no autodecrement on x86 */
3399                 case '>': /* no autoincrement on x86 */
3400                 case 'C': /* sse constant not supported yet */
3401                 case 'G': /* 80387 constant not supported yet */
3402                 case 'y': /* we don't support mmx registers yet */
3403                 case 'Z': /* not available in 32 bit mode */
3404                 case 'e': /* not available in 32 bit mode */
3405                         panic("unsupported asm constraint '%c' found in (%+F)",
3406                               *c, current_ir_graph);
3407                         break;
3408                 default:
3409                         panic("unknown asm constraint '%c' found in (%+F)", *c,
3410                               current_ir_graph);
3411                         break;
3412                 }
3413                 ++c;
3414         }
3415
3416         if(same_as >= 0) {
3417                 const arch_register_req_t *other_constr;
3418
3419                 assert(cls == NULL && "same as and register constraint not supported");
3420                 assert(!immediate_possible && "same as and immediate constraint not "
3421                        "supported");
3422                 assert(same_as < constraint->n_outs && "wrong constraint number in "
3423                        "same_as constraint");
3424
3425                 other_constr         = constraint->out_reqs[same_as];
3426
3427                 req                  = obstack_alloc(obst, sizeof(req[0]));
3428                 req->cls             = other_constr->cls;
3429                 req->type            = arch_register_req_type_should_be_same;
3430                 req->limited         = NULL;
3431                 req->other_same      = 1U << pos;
3432                 req->other_different = 0;
3433
3434                 /* switch constraints. This is because in firm we have same_as
3435                  * constraints on the output constraints while in the gcc asm syntax
3436                  * they are specified on the input constraints */
3437                 constraint->req               = other_constr;
3438                 constraint->out_reqs[same_as] = req;
3439                 constraint->immediate_possible = 0;
3440                 return;
3441         }
3442
3443         if(immediate_possible && cls == NULL) {
3444                 cls = &ia32_reg_classes[CLASS_ia32_gp];
3445         }
3446         assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3447         assert(cls != NULL);
3448
3449         if(immediate_possible) {
3450                 assert(constraint->is_in
3451                        && "immediate make no sense for output constraints");
3452         }
3453         /* todo: check types (no float input on 'r' constrained in and such... */
3454
3455         if(limited != 0) {
3456                 req          = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3457                 limited_ptr  = (unsigned*) (req+1);
3458         } else {
3459                 req = obstack_alloc(obst, sizeof(req[0]));
3460         }
3461         memset(req, 0, sizeof(req[0]));
3462
3463         if(limited != 0) {
3464                 req->type    = arch_register_req_type_limited;
3465                 *limited_ptr = limited;
3466                 req->limited = limited_ptr;
3467         } else {
3468                 req->type    = arch_register_req_type_normal;
3469         }
3470         req->cls = cls;
3471
3472         constraint->req                = req;
3473         constraint->immediate_possible = immediate_possible;
3474         constraint->immediate_type     = immediate_type;
3475 }
3476
3477 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3478                           const char *clobber)
3479 {
3480         ir_graph                    *irg  = get_irn_irg(node);
3481         struct obstack              *obst = get_irg_obstack(irg);
3482         const arch_register_t       *reg  = NULL;
3483         int                          c;
3484         size_t                       r;
3485         arch_register_req_t         *req;
3486         const arch_register_class_t *cls;
3487         unsigned                    *limited;
3488
3489         (void) pos;
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         ir_node  *src_block  = get_nodes_block(node);
4272         ir_node  *block      = be_transform_node(src_block);
4273         ir_graph *irg        = current_ir_graph;
4274         dbg_info *dbgi       = get_irn_dbg_info(node);
4275         ir_node  *frame      = get_irg_frame(irg);
4276         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4277         ir_node  *nomem      = new_NoMem();
4278         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
4279         ir_node  *new_val    = be_transform_node(val);
4280         ir_node  *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4281
4282         ir_node  *fist;
4283
4284         /* do a fist */
4285         fist = new_rd_ia32_vfist(dbgi, irg, block, frame, noreg, nomem, new_val,
4286                                  trunc_mode);
4287         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4288         set_ia32_use_frame(fist);
4289         set_ia32_op_type(fist, ia32_AddrModeD);
4290         set_ia32_ls_mode(fist, mode_Ls);
4291
4292         return fist;
4293 }
4294
4295 /**
4296  * the BAD transformer.
4297  */
4298 static ir_node *bad_transform(ir_node *node) {
4299         panic("No transform function for %+F available.\n", node);
4300         return NULL;
4301 }
4302
4303 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4304         ir_graph *irg      = current_ir_graph;
4305         ir_node  *block    = be_transform_node(get_nodes_block(node));
4306         ir_node  *pred     = get_Proj_pred(node);
4307         ir_node  *new_pred = be_transform_node(pred);
4308         ir_node  *frame    = get_irg_frame(irg);
4309         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
4310         dbg_info *dbgi     = get_irn_dbg_info(node);
4311         long      pn       = get_Proj_proj(node);
4312         ir_node  *load;
4313         ir_node  *proj;
4314         ia32_attr_t *attr;
4315
4316         load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4317         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4318         set_ia32_use_frame(load);
4319         set_ia32_op_type(load, ia32_AddrModeS);
4320         set_ia32_ls_mode(load, mode_Iu);
4321         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4322          * 32 bit from it with this particular load */
4323         attr = get_ia32_attr(load);
4324         attr->data.need_64bit_stackent = 1;
4325
4326         if (pn == pn_ia32_l_FloattoLL_res_high) {
4327                 add_ia32_am_offs_int(load, 4);
4328         } else {
4329                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4330         }
4331
4332         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4333
4334         return proj;
4335 }
4336
4337 /**
4338  * Transform the Projs of an AddSP.
4339  */
4340 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4341         ir_node  *block    = be_transform_node(get_nodes_block(node));
4342         ir_node  *pred     = get_Proj_pred(node);
4343         ir_node  *new_pred = be_transform_node(pred);
4344         ir_graph *irg      = current_ir_graph;
4345         dbg_info *dbgi     = get_irn_dbg_info(node);
4346         long     proj      = get_Proj_proj(node);
4347
4348         if (proj == pn_be_AddSP_sp) {
4349                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4350                                            pn_ia32_SubSP_stack);
4351                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4352                 return res;
4353         } else if(proj == pn_be_AddSP_res) {
4354                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4355                                    pn_ia32_SubSP_addr);
4356         } else if (proj == pn_be_AddSP_M) {
4357                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4358         }
4359
4360         assert(0);
4361         return new_rd_Unknown(irg, get_irn_mode(node));
4362 }
4363
4364 /**
4365  * Transform the Projs of a SubSP.
4366  */
4367 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4368         ir_node  *block    = be_transform_node(get_nodes_block(node));
4369         ir_node  *pred     = get_Proj_pred(node);
4370         ir_node  *new_pred = be_transform_node(pred);
4371         ir_graph *irg      = current_ir_graph;
4372         dbg_info *dbgi     = get_irn_dbg_info(node);
4373         long     proj      = get_Proj_proj(node);
4374
4375         if (proj == pn_be_SubSP_sp) {
4376                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4377                                            pn_ia32_AddSP_stack);
4378                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4379                 return res;
4380         } else if (proj == pn_be_SubSP_M) {
4381                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4382         }
4383
4384         assert(0);
4385         return new_rd_Unknown(irg, get_irn_mode(node));
4386 }
4387
4388 /**
4389  * Transform and renumber the Projs from a Load.
4390  */
4391 static ir_node *gen_Proj_Load(ir_node *node) {
4392         ir_node  *new_pred;
4393         ir_node  *block    = be_transform_node(get_nodes_block(node));
4394         ir_node  *pred     = get_Proj_pred(node);
4395         ir_graph *irg      = current_ir_graph;
4396         dbg_info *dbgi     = get_irn_dbg_info(node);
4397         long     proj      = get_Proj_proj(node);
4398
4399
4400         /* loads might be part of source address mode matches, so we don't
4401            transform the ProjMs yet (with the exception of loads whose result is
4402            not used)
4403          */
4404         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4405                 ir_node *res;
4406
4407                 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4408                                                                                 nodes is 1 */
4409                 /* this is needed, because sometimes we have loops that are only
4410                    reachable through the ProjM */
4411                 be_enqueue_preds(node);
4412                 /* do it in 2 steps, to silence firm verifier */
4413                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4414                 set_Proj_proj(res, pn_ia32_Load_M);
4415                 return res;
4416         }
4417
4418         /* renumber the proj */
4419         new_pred = be_transform_node(pred);
4420         if (is_ia32_Load(new_pred)) {
4421                 switch (proj) {
4422                 case pn_Load_res:
4423                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4424                 case pn_Load_M:
4425                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4426                 case pn_Load_X_regular:
4427                         return new_rd_Jmp(dbgi, irg, block);
4428                 case pn_Load_X_except:
4429                         /* This Load might raise an exception. Mark it. */
4430                         set_ia32_exc_label(new_pred, 1);
4431                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4432                 default:
4433                         break;
4434                 }
4435         } else if (is_ia32_Conv_I2I(new_pred) ||
4436                    is_ia32_Conv_I2I8Bit(new_pred)) {
4437                 set_irn_mode(new_pred, mode_T);
4438                 if (proj == pn_Load_res) {
4439                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4440                 } else if (proj == pn_Load_M) {
4441                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4442                 }
4443         } else if (is_ia32_xLoad(new_pred)) {
4444                 switch (proj) {
4445                 case pn_Load_res:
4446                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4447                 case pn_Load_M:
4448                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4449                 case pn_Load_X_regular:
4450                         return new_rd_Jmp(dbgi, irg, block);
4451                 case pn_Load_X_except:
4452                         /* This Load might raise an exception. Mark it. */
4453                         set_ia32_exc_label(new_pred, 1);
4454                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4455                 default:
4456                         break;
4457                 }
4458         } else if (is_ia32_vfld(new_pred)) {
4459                 switch (proj) {
4460                 case pn_Load_res:
4461                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4462                 case pn_Load_M:
4463                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4464                 case pn_Load_X_regular:
4465                         return new_rd_Jmp(dbgi, irg, block);
4466                 case pn_Load_X_except:
4467                         /* This Load might raise an exception. Mark it. */
4468                         set_ia32_exc_label(new_pred, 1);
4469                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4470                 default:
4471                         break;
4472                 }
4473         } else {
4474                 /* can happen for ProJMs when source address mode happened for the
4475                    node */
4476
4477                 /* however it should not be the result proj, as that would mean the
4478                    load had multiple users and should not have been used for
4479                    SourceAM */
4480                 if (proj != pn_Load_M) {
4481                         panic("internal error: transformed node not a Load");
4482                 }
4483                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4484         }
4485
4486         assert(0);
4487         return new_rd_Unknown(irg, get_irn_mode(node));
4488 }
4489
4490 /**
4491  * Transform and renumber the Projs from a DivMod like instruction.
4492  */
4493 static ir_node *gen_Proj_DivMod(ir_node *node) {
4494         ir_node  *block    = be_transform_node(get_nodes_block(node));
4495         ir_node  *pred     = get_Proj_pred(node);
4496         ir_node  *new_pred = be_transform_node(pred);
4497         ir_graph *irg      = current_ir_graph;
4498         dbg_info *dbgi     = get_irn_dbg_info(node);
4499         ir_mode  *mode     = get_irn_mode(node);
4500         long     proj      = get_Proj_proj(node);
4501
4502         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4503
4504         switch (get_irn_opcode(pred)) {
4505         case iro_Div:
4506                 switch (proj) {
4507                 case pn_Div_M:
4508                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4509                 case pn_Div_res:
4510                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4511                 case pn_Div_X_regular:
4512                         return new_rd_Jmp(dbgi, irg, block);
4513                 case pn_Div_X_except:
4514                         set_ia32_exc_label(new_pred, 1);
4515                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4516                 default:
4517                         break;
4518                 }
4519                 break;
4520         case iro_Mod:
4521                 switch (proj) {
4522                 case pn_Mod_M:
4523                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4524                 case pn_Mod_res:
4525                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4526                 case pn_Mod_X_except:
4527                         set_ia32_exc_label(new_pred, 1);
4528                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4529                 default:
4530                         break;
4531                 }
4532                 break;
4533         case iro_DivMod:
4534                 switch (proj) {
4535                 case pn_DivMod_M:
4536                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4537                 case pn_DivMod_res_div:
4538                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4539                 case pn_DivMod_res_mod:
4540                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4541                 case pn_DivMod_X_regular:
4542                         return new_rd_Jmp(dbgi, irg, block);
4543                 case pn_DivMod_X_except:
4544                         set_ia32_exc_label(new_pred, 1);
4545                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4546                 default:
4547                         break;
4548                 }
4549                 break;
4550         default:
4551                 break;
4552         }
4553
4554         assert(0);
4555         return new_rd_Unknown(irg, mode);
4556 }
4557
4558 /**
4559  * Transform and renumber the Projs from a CopyB.
4560  */
4561 static ir_node *gen_Proj_CopyB(ir_node *node) {
4562         ir_node  *block    = be_transform_node(get_nodes_block(node));
4563         ir_node  *pred     = get_Proj_pred(node);
4564         ir_node  *new_pred = be_transform_node(pred);
4565         ir_graph *irg      = current_ir_graph;
4566         dbg_info *dbgi     = get_irn_dbg_info(node);
4567         ir_mode  *mode     = get_irn_mode(node);
4568         long     proj      = get_Proj_proj(node);
4569
4570         switch(proj) {
4571         case pn_CopyB_M_regular:
4572                 if (is_ia32_CopyB_i(new_pred)) {
4573                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4574                 } else if (is_ia32_CopyB(new_pred)) {
4575                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4576                 }
4577                 break;
4578         default:
4579                 break;
4580         }
4581
4582         assert(0);
4583         return new_rd_Unknown(irg, mode);
4584 }
4585
4586 /**
4587  * Transform and renumber the Projs from a Quot.
4588  */
4589 static ir_node *gen_Proj_Quot(ir_node *node) {
4590         ir_node  *block    = be_transform_node(get_nodes_block(node));
4591         ir_node  *pred     = get_Proj_pred(node);
4592         ir_node  *new_pred = be_transform_node(pred);
4593         ir_graph *irg      = current_ir_graph;
4594         dbg_info *dbgi     = get_irn_dbg_info(node);
4595         ir_mode  *mode     = get_irn_mode(node);
4596         long     proj      = get_Proj_proj(node);
4597
4598         switch(proj) {
4599         case pn_Quot_M:
4600                 if (is_ia32_xDiv(new_pred)) {
4601                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4602                 } else if (is_ia32_vfdiv(new_pred)) {
4603                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4604                 }
4605                 break;
4606         case pn_Quot_res:
4607                 if (is_ia32_xDiv(new_pred)) {
4608                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4609                 } else if (is_ia32_vfdiv(new_pred)) {
4610                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4611                 }
4612                 break;
4613         default:
4614                 break;
4615         }
4616
4617         assert(0);
4618         return new_rd_Unknown(irg, mode);
4619 }
4620
4621 /**
4622  * Transform the Thread Local Storage Proj.
4623  */
4624 static ir_node *gen_Proj_tls(ir_node *node) {
4625         ir_node  *block = be_transform_node(get_nodes_block(node));
4626         ir_graph *irg   = current_ir_graph;
4627         dbg_info *dbgi  = NULL;
4628         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4629
4630         return res;
4631 }
4632
4633 static ir_node *gen_be_Call(ir_node *node) {
4634         ir_node *res = be_duplicate_node(node);
4635         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4636
4637         return res;
4638 }
4639
4640 static ir_node *gen_be_IncSP(ir_node *node) {
4641         ir_node *res = be_duplicate_node(node);
4642         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4643
4644         return res;
4645 }
4646
4647 /**
4648  * Transform the Projs from a be_Call.
4649  */
4650 static ir_node *gen_Proj_be_Call(ir_node *node) {
4651         ir_node  *block       = be_transform_node(get_nodes_block(node));
4652         ir_node  *call        = get_Proj_pred(node);
4653         ir_node  *new_call    = be_transform_node(call);
4654         ir_graph *irg         = current_ir_graph;
4655         dbg_info *dbgi        = get_irn_dbg_info(node);
4656         ir_type  *method_type = be_Call_get_type(call);
4657         int       n_res       = get_method_n_ress(method_type);
4658         long      proj        = get_Proj_proj(node);
4659         ir_mode  *mode        = get_irn_mode(node);
4660         ir_node  *sse_load;
4661         const arch_register_class_t *cls;
4662
4663         /* The following is kinda tricky: If we're using SSE, then we have to
4664          * move the result value of the call in floating point registers to an
4665          * xmm register, we therefore construct a GetST0 -> xLoad sequence
4666          * after the call, we have to make sure to correctly make the
4667          * MemProj and the result Proj use these 2 nodes
4668          */
4669         if (proj == pn_be_Call_M_regular) {
4670                 // get new node for result, are we doing the sse load/store hack?
4671                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4672                 ir_node *call_res_new;
4673                 ir_node *call_res_pred = NULL;
4674
4675                 if (call_res != NULL) {
4676                         call_res_new  = be_transform_node(call_res);
4677                         call_res_pred = get_Proj_pred(call_res_new);
4678                 }
4679
4680                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4681                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4682                                            pn_be_Call_M_regular);
4683                 } else {
4684                         assert(is_ia32_xLoad(call_res_pred));
4685                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4686                                            pn_ia32_xLoad_M);
4687                 }
4688         }
4689         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4690                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4691                 ir_node *fstp;
4692                 ir_node *frame = get_irg_frame(irg);
4693                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4694                 //ir_node *p;
4695                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4696                 ir_node *call_res;
4697
4698                 /* in case there is no memory output: create one to serialize the copy
4699                    FPU -> SSE */
4700                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4701                                        pn_be_Call_M_regular);
4702                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4703                                        pn_be_Call_first_res);
4704
4705                 /* store st(0) onto stack */
4706                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4707                                         call_res, mode);
4708                 set_ia32_op_type(fstp, ia32_AddrModeD);
4709                 set_ia32_use_frame(fstp);
4710
4711                 /* load into SSE register */
4712                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4713                                              mode);
4714                 set_ia32_op_type(sse_load, ia32_AddrModeS);
4715                 set_ia32_use_frame(sse_load);
4716
4717                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4718                                        pn_ia32_xLoad_res);
4719
4720                 return sse_load;
4721         }
4722
4723         /* transform call modes */
4724         if (mode_is_data(mode)) {
4725                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4726                 mode = cls->mode;
4727         }
4728
4729         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4730 }
4731
4732 /**
4733  * Transform the Projs from a Cmp.
4734  */
4735 static ir_node *gen_Proj_Cmp(ir_node *node)
4736 {
4737         /* this probably means not all mode_b nodes were lowered... */
4738         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4739               node);
4740 }
4741
4742 /**
4743  * Transform and potentially renumber Proj nodes.
4744  */
4745 static ir_node *gen_Proj(ir_node *node) {
4746         ir_graph *irg  = current_ir_graph;
4747         dbg_info *dbgi = get_irn_dbg_info(node);
4748         ir_node  *pred = get_Proj_pred(node);
4749         long     proj  = get_Proj_proj(node);
4750
4751         if (is_Store(pred)) {
4752                 if (proj == pn_Store_M) {
4753                         return be_transform_node(pred);
4754                 } else {
4755                         assert(0);
4756                         return new_r_Bad(irg);
4757                 }
4758         } else if (is_Load(pred)) {
4759                 return gen_Proj_Load(node);
4760         } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
4761                 return gen_Proj_DivMod(node);
4762         } else if (is_CopyB(pred)) {
4763                 return gen_Proj_CopyB(node);
4764         } else if (is_Quot(pred)) {
4765                 return gen_Proj_Quot(node);
4766         } else if (be_is_SubSP(pred)) {
4767                 return gen_Proj_be_SubSP(node);
4768         } else if (be_is_AddSP(pred)) {
4769                 return gen_Proj_be_AddSP(node);
4770         } else if (be_is_Call(pred)) {
4771                 return gen_Proj_be_Call(node);
4772         } else if (is_Cmp(pred)) {
4773                 return gen_Proj_Cmp(node);
4774         } else if (get_irn_op(pred) == op_Start) {
4775                 if (proj == pn_Start_X_initial_exec) {
4776                         ir_node *block = get_nodes_block(pred);
4777                         ir_node *jump;
4778
4779                         /* we exchange the ProjX with a jump */
4780                         block = be_transform_node(block);
4781                         jump  = new_rd_Jmp(dbgi, irg, block);
4782                         return jump;
4783                 }
4784                 if (node == be_get_old_anchor(anchor_tls)) {
4785                         return gen_Proj_tls(node);
4786                 }
4787         } else if (is_ia32_l_FloattoLL(pred)) {
4788                 return gen_Proj_l_FloattoLL(node);
4789 #ifdef FIRM_EXT_GRS
4790         } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4791 #else
4792         } else {
4793 #endif
4794                 ir_node *new_pred = be_transform_node(pred);
4795                 ir_node *block    = be_transform_node(get_nodes_block(node));
4796                 ir_mode *mode     = get_irn_mode(node);
4797                 if (mode_needs_gp_reg(mode)) {
4798                         ir_node *new_proj = new_r_Proj(irg, block, new_pred, mode_Iu,
4799                                                        get_Proj_proj(node));
4800 #ifdef DEBUG_libfirm
4801                         new_proj->node_nr = node->node_nr;
4802 #endif
4803                         return new_proj;
4804                 }
4805         }
4806
4807         return be_duplicate_node(node);
4808 }
4809
4810 /**
4811  * Enters all transform functions into the generic pointer
4812  */
4813 static void register_transformers(void)
4814 {
4815         ir_op *op_Mulh;
4816
4817         /* first clear the generic function pointer for all ops */
4818         clear_irp_opcodes_generic_func();
4819
4820 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4821 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
4822
4823         GEN(Add);
4824         GEN(Sub);
4825         GEN(Mul);
4826         GEN(And);
4827         GEN(Or);
4828         GEN(Eor);
4829
4830         GEN(Shl);
4831         GEN(Shr);
4832         GEN(Shrs);
4833         GEN(Rot);
4834
4835         GEN(Quot);
4836
4837         GEN(Div);
4838         GEN(Mod);
4839         GEN(DivMod);
4840
4841         GEN(Minus);
4842         GEN(Conv);
4843         GEN(Abs);
4844         GEN(Not);
4845
4846         GEN(Load);
4847         GEN(Store);
4848         GEN(Cond);
4849
4850         GEN(Cmp);
4851         GEN(ASM);
4852         GEN(CopyB);
4853         BAD(Mux);
4854         GEN(Psi);
4855         GEN(Proj);
4856         GEN(Phi);
4857         GEN(IJmp);
4858
4859         /* transform ops from intrinsic lowering */
4860         GEN(ia32_l_Add);
4861         GEN(ia32_l_Adc);
4862         GEN(ia32_l_Mul);
4863         GEN(ia32_l_IMul);
4864         GEN(ia32_l_ShlDep);
4865         GEN(ia32_l_ShrDep);
4866         GEN(ia32_l_SarDep);
4867         GEN(ia32_l_ShlD);
4868         GEN(ia32_l_ShrD);
4869         GEN(ia32_l_Sub);
4870         GEN(ia32_l_Sbb);
4871         GEN(ia32_l_vfild);
4872         GEN(ia32_l_Load);
4873         GEN(ia32_l_vfist);
4874         GEN(ia32_l_Store);
4875         GEN(ia32_l_LLtoFloat);
4876         GEN(ia32_l_FloattoLL);
4877
4878         GEN(Const);
4879         GEN(SymConst);
4880         GEN(Unknown);
4881
4882         /* we should never see these nodes */
4883         BAD(Raise);
4884         BAD(Sel);
4885         BAD(InstOf);
4886         BAD(Cast);
4887         BAD(Free);
4888         BAD(Tuple);
4889         BAD(Id);
4890         //BAD(Bad);
4891         BAD(Confirm);
4892         BAD(Filter);
4893         BAD(CallBegin);
4894         BAD(EndReg);
4895         BAD(EndExcept);
4896
4897         /* handle generic backend nodes */
4898         GEN(be_FrameAddr);
4899         GEN(be_Call);
4900         GEN(be_IncSP);
4901         GEN(be_Return);
4902         GEN(be_AddSP);
4903         GEN(be_SubSP);
4904         GEN(be_Copy);
4905
4906         op_Mulh = get_op_Mulh();
4907         if (op_Mulh)
4908                 GEN(Mulh);
4909
4910 #undef GEN
4911 #undef BAD
4912 }
4913
4914 /**
4915  * Pre-transform all unknown and noreg nodes.
4916  */
4917 static void ia32_pretransform_node(void *arch_cg) {
4918         ia32_code_gen_t *cg = arch_cg;
4919
4920         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
4921         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4922         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4923         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
4924         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
4925         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
4926         get_fpcw();
4927 }
4928
4929 /**
4930  * Walker, checks if all ia32 nodes producing more than one result have
4931  * its Projs, other wise creates new projs and keep them using a be_Keep node.
4932  */
4933 static void add_missing_keep_walker(ir_node *node, void *data)
4934 {
4935         int              n_outs, i;
4936         unsigned         found_projs = 0;
4937         const ir_edge_t *edge;
4938         ir_mode         *mode = get_irn_mode(node);
4939         ir_node         *last_keep;
4940         (void) data;
4941         if(mode != mode_T)
4942                 return;
4943         if(!is_ia32_irn(node))
4944                 return;
4945
4946         n_outs = get_ia32_n_res(node);
4947         if(n_outs <= 0)
4948                 return;
4949         if(is_ia32_SwitchJmp(node))
4950                 return;
4951
4952         assert(n_outs < (int) sizeof(unsigned) * 8);
4953         foreach_out_edge(node, edge) {
4954                 ir_node *proj = get_edge_src_irn(edge);
4955                 int      pn   = get_Proj_proj(proj);
4956
4957                 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
4958                 found_projs |= 1 << pn;
4959         }
4960
4961
4962         /* are keeps missing? */
4963         last_keep = NULL;
4964         for(i = 0; i < n_outs; ++i) {
4965                 ir_node                     *block;
4966                 ir_node                     *in[1];
4967                 const arch_register_req_t   *req;
4968                 const arch_register_class_t *class;
4969
4970                 if(found_projs & (1 << i)) {
4971                         continue;
4972                 }
4973
4974                 req   = get_ia32_out_req(node, i);
4975                 class = req->cls;
4976                 if(class == NULL) {
4977                         continue;
4978                 }
4979                 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
4980                         continue;
4981                 }
4982
4983                 block = get_nodes_block(node);
4984                 in[0] = new_r_Proj(current_ir_graph, block, node,
4985                                    arch_register_class_mode(class), i);
4986                 if(last_keep != NULL) {
4987                         be_Keep_add_node(last_keep, class, in[0]);
4988                 } else {
4989                         last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
4990                         if(sched_is_scheduled(node)) {
4991                                 sched_add_after(node, last_keep);
4992                         }
4993                 }
4994         }
4995 }
4996
4997 /**
4998  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4999  * and keeps them.
5000  */
5001 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5002 {
5003         ir_graph *irg = be_get_birg_irg(cg->birg);
5004         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5005 }
5006
5007 /* do the transformation */
5008 void ia32_transform_graph(ia32_code_gen_t *cg) {
5009         int cse_last;
5010         ir_graph *irg = cg->irg;
5011
5012         register_transformers();
5013         env_cg       = cg;
5014         initial_fpcw = NULL;
5015
5016 BE_TIMER_PUSH(t_heights);
5017         heights      = heights_new(irg);
5018 BE_TIMER_POP(t_heights);
5019         ia32_calculate_non_address_mode_nodes(cg->birg);
5020
5021         /* the transform phase is not safe for CSE (yet) because several nodes get
5022          * attributes set after their creation */
5023         cse_last = get_opt_cse();
5024         set_opt_cse(0);
5025
5026         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5027
5028         set_opt_cse(cse_last);
5029
5030         ia32_free_non_address_mode_nodes();
5031         heights_free(heights);
5032         heights = NULL;
5033 }
5034
5035 void ia32_init_transform(void)
5036 {
5037         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
5038 }