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