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