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