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