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