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