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