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