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