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