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