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