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