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