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