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