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