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