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