reduce code size
[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
1391         return gen_binop(node, op1, op2, new_rd_ia32_And,
1392                          match_commutative | match_mode_neutral | match_am
1393                                          | match_immediate);
1394 }
1395
1396
1397
1398 /**
1399  * Creates an ia32 Or.
1400  *
1401  * @return The created ia32 Or node
1402  */
1403 static ir_node *gen_Or(ir_node *node) {
1404         ir_node *op1 = get_Or_left(node);
1405         ir_node *op2 = get_Or_right(node);
1406
1407         assert (! mode_is_float(get_irn_mode(node)));
1408         return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1409                         | match_mode_neutral | match_am | match_immediate);
1410 }
1411
1412
1413
1414 /**
1415  * Creates an ia32 Eor.
1416  *
1417  * @return The created ia32 Eor node
1418  */
1419 static ir_node *gen_Eor(ir_node *node) {
1420         ir_node *op1 = get_Eor_left(node);
1421         ir_node *op2 = get_Eor_right(node);
1422
1423         assert(! mode_is_float(get_irn_mode(node)));
1424         return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1425                         | match_mode_neutral | match_am | match_immediate);
1426 }
1427
1428
1429 /**
1430  * Creates an ia32 Sub.
1431  *
1432  * @return The created ia32 Sub node
1433  */
1434 static ir_node *gen_Sub(ir_node *node) {
1435         ir_node  *op1  = get_Sub_left(node);
1436         ir_node  *op2  = get_Sub_right(node);
1437         ir_mode  *mode = get_irn_mode(node);
1438
1439         if (mode_is_float(mode)) {
1440                 if (ia32_cg_config.use_sse2)
1441                         return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1442                 else
1443                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1444                                                    match_am);
1445         }
1446
1447         if (is_Const(op2)) {
1448                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1449                            node);
1450         }
1451
1452         return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1453                         | match_am | match_immediate);
1454 }
1455
1456 /**
1457  * Generates an ia32 DivMod with additional infrastructure for the
1458  * register allocator if needed.
1459  */
1460 static ir_node *create_Div(ir_node *node)
1461 {
1462         ir_graph *irg       = current_ir_graph;
1463         dbg_info *dbgi      = get_irn_dbg_info(node);
1464         ir_node  *block     = get_nodes_block(node);
1465         ir_node  *new_block = be_transform_node(block);
1466         ir_node  *mem;
1467         ir_node  *new_mem;
1468         ir_node  *op1;
1469         ir_node  *op2;
1470         ir_node  *new_node;
1471         ir_mode  *mode;
1472         ir_node  *sign_extension;
1473         ia32_address_mode_t  am;
1474         ia32_address_t      *addr = &am.addr;
1475
1476         /* the upper bits have random contents for smaller modes */
1477         switch (get_irn_opcode(node)) {
1478         case iro_Div:
1479                 op1     = get_Div_left(node);
1480                 op2     = get_Div_right(node);
1481                 mem     = get_Div_mem(node);
1482                 mode    = get_Div_resmode(node);
1483                 break;
1484         case iro_Mod:
1485                 op1     = get_Mod_left(node);
1486                 op2     = get_Mod_right(node);
1487                 mem     = get_Mod_mem(node);
1488                 mode    = get_Mod_resmode(node);
1489                 break;
1490         case iro_DivMod:
1491                 op1     = get_DivMod_left(node);
1492                 op2     = get_DivMod_right(node);
1493                 mem     = get_DivMod_mem(node);
1494                 mode    = get_DivMod_resmode(node);
1495                 break;
1496         default:
1497                 panic("invalid divmod node %+F", node);
1498         }
1499
1500         match_arguments(&am, block, op1, op2, NULL, match_am);
1501
1502         /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1503            is the memory of the consumed address. We can have only the second op as address
1504            in Div nodes, so check only op2. */
1505         if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1506                 new_mem = be_transform_node(mem);
1507                 if(!is_NoMem(addr->mem)) {
1508                         ir_node *in[2];
1509                         in[0] = new_mem;
1510                         in[1] = addr->mem;
1511                         new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1512                 }
1513         } else {
1514                 new_mem = addr->mem;
1515         }
1516
1517         if (mode_is_signed(mode)) {
1518                 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1519                 add_irn_dep(produceval, get_irg_frame(irg));
1520                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1521                                                   produceval);
1522         } else {
1523                 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1524                 add_irn_dep(sign_extension, get_irg_frame(irg));
1525
1526         }
1527         new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1528                 addr->index, new_mem, am.new_op2,
1529                 am.new_op1, sign_extension);
1530         set_irn_pinned(new_node, get_irn_pinned(node));
1531
1532         set_am_attributes(new_node, &am);
1533         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1534
1535         new_node = fix_mem_proj(new_node, &am);
1536
1537         return new_node;
1538 }
1539
1540
1541 static ir_node *gen_Mod(ir_node *node) {
1542         return create_Div(node);
1543 }
1544
1545 static ir_node *gen_Div(ir_node *node) {
1546         return create_Div(node);
1547 }
1548
1549 static ir_node *gen_DivMod(ir_node *node) {
1550         return create_Div(node);
1551 }
1552
1553
1554
1555 /**
1556  * Creates an ia32 floating Div.
1557  *
1558  * @return The created ia32 xDiv node
1559  */
1560 static ir_node *gen_Quot(ir_node *node)
1561 {
1562         ir_node *op1 = get_Quot_left(node);
1563         ir_node *op2 = get_Quot_right(node);
1564
1565         if (ia32_cg_config.use_sse2) {
1566                 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1567         } else {
1568                 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1569         }
1570 }
1571
1572
1573 /**
1574  * Creates an ia32 Shl.
1575  *
1576  * @return The created ia32 Shl node
1577  */
1578 static ir_node *gen_Shl(ir_node *node) {
1579         ir_node *left  = get_Shl_left(node);
1580         ir_node *right = get_Shl_right(node);
1581
1582         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1583                                match_mode_neutral | match_immediate);
1584 }
1585
1586 /**
1587  * Creates an ia32 Shr.
1588  *
1589  * @return The created ia32 Shr node
1590  */
1591 static ir_node *gen_Shr(ir_node *node) {
1592         ir_node *left  = get_Shr_left(node);
1593         ir_node *right = get_Shr_right(node);
1594
1595         return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1596 }
1597
1598
1599
1600 /**
1601  * Creates an ia32 Sar.
1602  *
1603  * @return The created ia32 Shrs node
1604  */
1605 static ir_node *gen_Shrs(ir_node *node) {
1606         ir_node *left  = get_Shrs_left(node);
1607         ir_node *right = get_Shrs_right(node);
1608         ir_mode *mode  = get_irn_mode(node);
1609
1610         if(is_Const(right) && mode == mode_Is) {
1611                 tarval *tv = get_Const_tarval(right);
1612                 long val = get_tarval_long(tv);
1613                 if(val == 31) {
1614                         /* this is a sign extension */
1615                         ir_graph *irg    = current_ir_graph;
1616                         dbg_info *dbgi   = get_irn_dbg_info(node);
1617                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1618                         ir_node  *op     = left;
1619                         ir_node  *new_op = be_transform_node(op);
1620                         ir_node  *pval   = new_rd_ia32_ProduceVal(dbgi, irg, block);
1621                         add_irn_dep(pval, get_irg_frame(irg));
1622
1623                         return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1624                 }
1625         }
1626
1627         /* 8 or 16 bit sign extension? */
1628         if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1629                 ir_node *shl_left  = get_Shl_left(left);
1630                 ir_node *shl_right = get_Shl_right(left);
1631                 if(is_Const(shl_right)) {
1632                         tarval *tv1 = get_Const_tarval(right);
1633                         tarval *tv2 = get_Const_tarval(shl_right);
1634                         if(tv1 == tv2 && tarval_is_long(tv1)) {
1635                                 long val = get_tarval_long(tv1);
1636                                 if(val == 16 || val == 24) {
1637                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1638                                         ir_node  *block  = get_nodes_block(node);
1639                                         ir_mode  *src_mode;
1640                                         ir_node  *res;
1641
1642                                         if(val == 24) {
1643                                                 src_mode = mode_Bs;
1644                                         } else {
1645                                                 assert(val == 16);
1646                                                 src_mode = mode_Hs;
1647                                         }
1648                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1649                                                               shl_left, node);
1650
1651                                         return res;
1652                                 }
1653                         }
1654                 }
1655         }
1656
1657         return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1658 }
1659
1660
1661
1662 /**
1663  * Creates an ia32 RotL.
1664  *
1665  * @param op1   The first operator
1666  * @param op2   The second operator
1667  * @return The created ia32 RotL node
1668  */
1669 static ir_node *gen_RotL(ir_node *node, ir_node *op1, ir_node *op2) {
1670         return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1671 }
1672
1673
1674
1675 /**
1676  * Creates an ia32 RotR.
1677  * NOTE: There is no RotR with immediate because this would always be a RotL
1678  *       "imm-mode_size_bits" which can be pre-calculated.
1679  *
1680  * @param op1   The first operator
1681  * @param op2   The second operator
1682  * @return The created ia32 RotR node
1683  */
1684 static ir_node *gen_RotR(ir_node *node, ir_node *op1, ir_node *op2) {
1685         return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1686 }
1687
1688
1689
1690 /**
1691  * Creates an ia32 RotR or RotL (depending on the found pattern).
1692  *
1693  * @return The created ia32 RotL or RotR node
1694  */
1695 static ir_node *gen_Rot(ir_node *node) {
1696         ir_node *rotate = NULL;
1697         ir_node *op1    = get_Rot_left(node);
1698         ir_node *op2    = get_Rot_right(node);
1699
1700         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1701                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1702                  that means we can create a RotR instead of an Add and a RotL */
1703
1704         if (get_irn_op(op2) == op_Add) {
1705                 ir_node *add = op2;
1706                 ir_node *left = get_Add_left(add);
1707                 ir_node *right = get_Add_right(add);
1708                 if (is_Const(right)) {
1709                         tarval  *tv   = get_Const_tarval(right);
1710                         ir_mode *mode = get_irn_mode(node);
1711                         long     bits = get_mode_size_bits(mode);
1712
1713                         if (get_irn_op(left) == op_Minus &&
1714                                         tarval_is_long(tv)       &&
1715                                         get_tarval_long(tv) == bits &&
1716                                         bits                == 32)
1717                         {
1718                                 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1719                                 rotate = gen_RotR(node, op1, get_Minus_op(left));
1720                         }
1721                 }
1722         }
1723
1724         if (rotate == NULL) {
1725                 rotate = gen_RotL(node, op1, op2);
1726         }
1727
1728         return rotate;
1729 }
1730
1731
1732
1733 /**
1734  * Transforms a Minus node.
1735  *
1736  * @return The created ia32 Minus node
1737  */
1738 static ir_node *gen_Minus(ir_node *node)
1739 {
1740         ir_node   *op    = get_Minus_op(node);
1741         ir_node   *block = be_transform_node(get_nodes_block(node));
1742         ir_graph  *irg   = current_ir_graph;
1743         dbg_info  *dbgi  = get_irn_dbg_info(node);
1744         ir_mode   *mode  = get_irn_mode(node);
1745         ir_entity *ent;
1746         ir_node   *new_node;
1747         int        size;
1748
1749         if (mode_is_float(mode)) {
1750                 ir_node *new_op = be_transform_node(op);
1751                 if (ia32_cg_config.use_sse2) {
1752                         /* TODO: non-optimal... if we have many xXors, then we should
1753                          * rather create a load for the const and use that instead of
1754                          * several AM nodes... */
1755                         ir_node *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1756                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1757                         ir_node *nomem     = new_rd_NoMem(irg);
1758
1759                         new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1760                                                     nomem, new_op, noreg_xmm);
1761
1762                         size = get_mode_size_bits(mode);
1763                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1764
1765                         set_ia32_am_sc(new_node, ent);
1766                         set_ia32_op_type(new_node, ia32_AddrModeS);
1767                         set_ia32_ls_mode(new_node, mode);
1768                 } else {
1769                         new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1770                 }
1771         } else {
1772                 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1773         }
1774
1775         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1776
1777         return new_node;
1778 }
1779
1780 /**
1781  * Transforms a Not node.
1782  *
1783  * @return The created ia32 Not node
1784  */
1785 static ir_node *gen_Not(ir_node *node) {
1786         ir_node *op   = get_Not_op(node);
1787
1788         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1789         assert (! mode_is_float(get_irn_mode(node)));
1790
1791         return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1792 }
1793
1794
1795
1796 /**
1797  * Transforms an Abs node.
1798  *
1799  * @return The created ia32 Abs node
1800  */
1801 static ir_node *gen_Abs(ir_node *node)
1802 {
1803         ir_node   *block     = get_nodes_block(node);
1804         ir_node   *new_block = be_transform_node(block);
1805         ir_node   *op        = get_Abs_op(node);
1806         ir_graph  *irg       = current_ir_graph;
1807         dbg_info  *dbgi      = get_irn_dbg_info(node);
1808         ir_mode   *mode      = get_irn_mode(node);
1809         ir_node   *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1810         ir_node   *nomem     = new_NoMem();
1811         ir_node   *new_op;
1812         ir_node   *new_node;
1813         int        size;
1814         ir_entity *ent;
1815
1816         if (mode_is_float(mode)) {
1817                 new_op = be_transform_node(op);
1818
1819                 if (ia32_cg_config.use_sse2) {
1820                         ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1821                         new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1822                                                     nomem, new_op, noreg_fp);
1823
1824                         size = get_mode_size_bits(mode);
1825                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1826
1827                         set_ia32_am_sc(new_node, ent);
1828
1829                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1830
1831                         set_ia32_op_type(new_node, ia32_AddrModeS);
1832                         set_ia32_ls_mode(new_node, mode);
1833                 } else {
1834                         new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1835                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1836                 }
1837         } else {
1838                 ir_node *xor, *pval, *sign_extension;
1839
1840                 if (get_mode_size_bits(mode) == 32) {
1841                         new_op = be_transform_node(op);
1842                 } else {
1843                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1844                 }
1845
1846                 pval           = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1847                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1848                                                            new_op, pval);
1849
1850                 add_irn_dep(pval, get_irg_frame(irg));
1851                 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1852
1853                 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1854                                       nomem, new_op, sign_extension);
1855                 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1856
1857                 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1858                                            nomem, xor, sign_extension);
1859                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1860         }
1861
1862         return new_node;
1863 }
1864
1865 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1866 {
1867         ir_graph *irg = current_ir_graph;
1868         ir_node  *flags;
1869         ir_node  *new_op;
1870         ir_node  *noreg;
1871         ir_node  *nomem;
1872         ir_node  *new_block;
1873         dbg_info *dbgi;
1874
1875         /* we have a Cmp as input */
1876         if(is_Proj(node)) {
1877                 ir_node *pred = get_Proj_pred(node);
1878                 if(is_Cmp(pred)) {
1879                         flags    = be_transform_node(pred);
1880                         *pnc_out = get_Proj_proj(node);
1881                         return flags;
1882                 }
1883         }
1884
1885         /* a mode_b value, we have to compare it against 0 */
1886         dbgi      = get_irn_dbg_info(node);
1887         new_block = be_transform_node(get_nodes_block(node));
1888         new_op    = be_transform_node(node);
1889         noreg     = ia32_new_NoReg_gp(env_cg);
1890         nomem     = new_NoMem();
1891         flags     = new_rd_ia32_Test(dbgi, irg, new_block, noreg, noreg, nomem,
1892                                      new_op, new_op, 0, 0);
1893         *pnc_out  = pn_Cmp_Lg;
1894         return flags;
1895 }
1896
1897 /**
1898  * Transforms a Load.
1899  *
1900  * @return the created ia32 Load node
1901  */
1902 static ir_node *gen_Load(ir_node *node) {
1903         ir_node  *old_block = get_nodes_block(node);
1904         ir_node  *block   = be_transform_node(old_block);
1905         ir_node  *ptr     = get_Load_ptr(node);
1906         ir_node  *mem     = get_Load_mem(node);
1907         ir_node  *new_mem = be_transform_node(mem);
1908         ir_node  *base;
1909         ir_node  *index;
1910         ir_graph *irg     = current_ir_graph;
1911         dbg_info *dbgi    = get_irn_dbg_info(node);
1912         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
1913         ir_mode  *mode    = get_Load_mode(node);
1914         ir_mode  *res_mode;
1915         ir_node  *new_node;
1916         ia32_address_t addr;
1917
1918         /* construct load address */
1919         memset(&addr, 0, sizeof(addr));
1920         ia32_create_address_mode(&addr, ptr, /*force=*/0);
1921         base  = addr.base;
1922         index = addr.index;
1923
1924         if(base == NULL) {
1925                 base = noreg;
1926         } else {
1927                 base = be_transform_node(base);
1928         }
1929
1930         if(index == NULL) {
1931                 index = noreg;
1932         } else {
1933                 index = be_transform_node(index);
1934         }
1935
1936         if (mode_is_float(mode)) {
1937                 if (ia32_cg_config.use_sse2) {
1938                         new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1939                                                      mode);
1940                         res_mode = mode_xmm;
1941                 } else {
1942                         new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1943                                                     mode);
1944                         res_mode = mode_vfp;
1945                 }
1946         } else {
1947                 assert(mode != mode_b);
1948
1949                 /* create a conv node with address mode for smaller modes */
1950                 if(get_mode_size_bits(mode) < 32) {
1951                         new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1952                                                         new_mem, noreg, mode);
1953                 } else {
1954                         new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1955                 }
1956                 res_mode = mode_Iu;
1957         }
1958
1959         set_irn_pinned(new_node, get_irn_pinned(node));
1960         set_ia32_op_type(new_node, ia32_AddrModeS);
1961         set_ia32_ls_mode(new_node, mode);
1962         set_address(new_node, &addr);
1963
1964         if(get_irn_pinned(node) == op_pin_state_floats) {
1965                 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1966         }
1967
1968         /* make sure we are scheduled behind the initial IncSP/Barrier
1969          * to avoid spills being placed before it
1970          */
1971         if (block == get_irg_start_block(irg)) {
1972                 add_irn_dep(new_node, get_irg_frame(irg));
1973         }
1974
1975         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1976
1977         return new_node;
1978 }
1979
1980 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1981                        ir_node *ptr, ir_node *other)
1982 {
1983         ir_node *load;
1984
1985         if(!is_Proj(node))
1986                 return 0;
1987
1988         /* we only use address mode if we're the only user of the load */
1989         if(get_irn_n_edges(node) > 1)
1990                 return 0;
1991
1992         load = get_Proj_pred(node);
1993         if(!is_Load(load))
1994                 return 0;
1995         if(get_nodes_block(load) != block)
1996                 return 0;
1997
1998         /* Store should be attached to the load */
1999         if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2000                 return 0;
2001         /* store should have the same pointer as the load */
2002         if(get_Load_ptr(load) != ptr)
2003                 return 0;
2004
2005         /* don't do AM if other node inputs depend on the load (via mem-proj) */
2006         if(other != NULL && get_nodes_block(other) == block
2007                         && heights_reachable_in_block(heights, other, load))
2008                 return 0;
2009
2010         return 1;
2011 }
2012
2013 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2014                               ir_node *mem, ir_node *ptr, ir_mode *mode,
2015                               construct_binop_dest_func *func,
2016                               construct_binop_dest_func *func8bit,
2017                                                           match_flags_t flags)
2018 {
2019         ir_node  *src_block = get_nodes_block(node);
2020         ir_node  *block;
2021         ir_node  *noreg_gp  = ia32_new_NoReg_gp(env_cg);
2022         ir_graph *irg      = current_ir_graph;
2023         dbg_info *dbgi;
2024         ir_node  *new_node;
2025         ir_node  *new_op;
2026         int       commutative;
2027         ia32_address_mode_t  am;
2028         ia32_address_t      *addr = &am.addr;
2029         memset(&am, 0, sizeof(am));
2030
2031         assert(flags & match_dest_am);
2032         assert(flags & match_immediate); /* there is no destam node without... */
2033         commutative = (flags & match_commutative) != 0;
2034
2035         if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2036                 build_address(&am, op1);
2037                 new_op = create_immediate_or_transform(op2, 0);
2038         } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2039                 build_address(&am, op2);
2040                 new_op = create_immediate_or_transform(op1, 0);
2041         } else {
2042                 return NULL;
2043         }
2044
2045         if(addr->base == NULL)
2046                 addr->base = noreg_gp;
2047         if(addr->index == NULL)
2048                 addr->index = noreg_gp;
2049         if(addr->mem == NULL)
2050                 addr->mem = new_NoMem();
2051
2052         dbgi  = get_irn_dbg_info(node);
2053         block = be_transform_node(src_block);
2054         if(get_mode_size_bits(mode) == 8) {
2055                 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2056                                     addr->mem, new_op);
2057         } else {
2058                 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2059                                 new_op);
2060         }
2061         set_address(new_node, addr);
2062         set_ia32_op_type(new_node, ia32_AddrModeD);
2063         set_ia32_ls_mode(new_node, mode);
2064         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2065
2066         return new_node;
2067 }
2068
2069 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2070                              ir_node *ptr, ir_mode *mode,
2071                              construct_unop_dest_func *func)
2072 {
2073         ir_graph *irg      = current_ir_graph;
2074         ir_node *src_block = get_nodes_block(node);
2075         ir_node *block;
2076         dbg_info *dbgi;
2077         ir_node *new_node;
2078         ia32_address_mode_t  am;
2079         ia32_address_t *addr = &am.addr;
2080         memset(&am, 0, sizeof(am));
2081
2082         if(!use_dest_am(src_block, op, mem, ptr, NULL))
2083                 return NULL;
2084
2085         build_address(&am, op);
2086
2087         dbgi     = get_irn_dbg_info(node);
2088         block    = be_transform_node(src_block);
2089         new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2090         set_address(new_node, addr);
2091         set_ia32_op_type(new_node, ia32_AddrModeD);
2092         set_ia32_ls_mode(new_node, mode);
2093         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2094
2095         return new_node;
2096 }
2097
2098 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2099         ir_mode  *mode        = get_irn_mode(node);
2100         ir_node  *psi_true    = get_Psi_val(node, 0);
2101         ir_node  *psi_default = get_Psi_default(node);
2102         ir_graph *irg;
2103         ir_node  *cond;
2104         ir_node  *new_mem;
2105         dbg_info *dbgi;
2106         ir_node  *block;
2107         ir_node  *new_block;
2108         ir_node  *flags;
2109         ir_node  *new_node;
2110         int       negated;
2111         pn_Cmp    pnc;
2112         ia32_address_t addr;
2113
2114         if(get_mode_size_bits(mode) != 8)
2115                 return NULL;
2116
2117         if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2118                 negated = 0;
2119         } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2120                 negated = 1;
2121         } else {
2122                 return NULL;
2123         }
2124
2125         build_address_ptr(&addr, ptr, mem);
2126
2127         irg       = current_ir_graph;
2128         dbgi      = get_irn_dbg_info(node);
2129         block     = get_nodes_block(node);
2130         new_block = be_transform_node(block);
2131         cond      = get_Psi_cond(node, 0);
2132         flags     = get_flags_node(cond, &pnc);
2133         new_mem   = be_transform_node(mem);
2134         new_node  = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2135                                        addr.index, addr.mem, flags, pnc, negated);
2136         set_address(new_node, &addr);
2137         set_ia32_op_type(new_node, ia32_AddrModeD);
2138         set_ia32_ls_mode(new_node, mode);
2139         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2140
2141         return new_node;
2142 }
2143
2144 static ir_node *try_create_dest_am(ir_node *node) {
2145         ir_node  *val  = get_Store_value(node);
2146         ir_node  *mem  = get_Store_mem(node);
2147         ir_node  *ptr  = get_Store_ptr(node);
2148         ir_mode  *mode = get_irn_mode(val);
2149         unsigned  bits = get_mode_size_bits(mode);
2150         ir_node  *op1;
2151         ir_node  *op2;
2152         ir_node  *new_node;
2153
2154         /* handle only GP modes for now... */
2155         if(!mode_needs_gp_reg(mode))
2156                 return NULL;
2157
2158         while(1) {
2159                 /* store must be the only user of the val node */
2160                 if(get_irn_n_edges(val) > 1)
2161                         return NULL;
2162                 /* skip pointless convs */
2163                 if(is_Conv(val)) {
2164                         ir_node *conv_op   = get_Conv_op(val);
2165                         ir_mode *pred_mode = get_irn_mode(conv_op);
2166                         if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2167                                 val = conv_op;
2168                                 continue;
2169                         }
2170                 }
2171                 break;
2172         }
2173
2174         /* value must be in the same block */
2175         if(get_nodes_block(node) != get_nodes_block(val))
2176                 return NULL;
2177
2178         switch(get_irn_opcode(val)) {
2179         case iro_Add:
2180                 op1      = get_Add_left(val);
2181                 op2      = get_Add_right(val);
2182                 if(is_Const_1(op2)) {
2183                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2184                                                 new_rd_ia32_IncMem);
2185                         break;
2186                 } else if(is_Const_Minus_1(op2)) {
2187                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2188                                                 new_rd_ia32_DecMem);
2189                         break;
2190                 }
2191                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2192                                          new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2193                                          match_dest_am | match_commutative |
2194                                          match_immediate);
2195                 break;
2196         case iro_Sub:
2197                 op1      = get_Sub_left(val);
2198                 op2      = get_Sub_right(val);
2199                 if(is_Const(op2)) {
2200                         ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2201                                    "found\n");
2202                 }
2203                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2204                                          new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2205                                          match_dest_am | match_immediate |
2206                                          match_immediate);
2207                 break;
2208         case iro_And:
2209                 op1      = get_And_left(val);
2210                 op2      = get_And_right(val);
2211                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2212                                          new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2213                                          match_dest_am | match_commutative |
2214                                          match_immediate);
2215                 break;
2216         case iro_Or:
2217                 op1      = get_Or_left(val);
2218                 op2      = get_Or_right(val);
2219                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2220                                          new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2221                                          match_dest_am | match_commutative |
2222                                          match_immediate);
2223                 break;
2224         case iro_Eor:
2225                 op1      = get_Eor_left(val);
2226                 op2      = get_Eor_right(val);
2227                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2228                                          new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2229                                          match_dest_am | match_commutative |
2230                                          match_immediate);
2231                 break;
2232         case iro_Shl:
2233                 op1      = get_Shl_left(val);
2234                 op2      = get_Shl_right(val);
2235                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2236                                          new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2237                                          match_dest_am | match_immediate);
2238                 break;
2239         case iro_Shr:
2240                 op1      = get_Shr_left(val);
2241                 op2      = get_Shr_right(val);
2242                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2243                                          new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2244                                          match_dest_am | match_immediate);
2245                 break;
2246         case iro_Shrs:
2247                 op1      = get_Shrs_left(val);
2248                 op2      = get_Shrs_right(val);
2249                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2250                                          new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2251                                          match_dest_am | match_immediate);
2252                 break;
2253         case iro_Rot:
2254                 op1      = get_Rot_left(val);
2255                 op2      = get_Rot_right(val);
2256                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2257                                          new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2258                                          match_dest_am | match_immediate);
2259                 break;
2260         /* TODO: match ROR patterns... */
2261         case iro_Psi:
2262                 new_node = try_create_SetMem(val, ptr, mem);
2263                 break;
2264         case iro_Minus:
2265                 op1      = get_Minus_op(val);
2266                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2267                 break;
2268         case iro_Not:
2269                 /* should be lowered already */
2270                 assert(mode != mode_b);
2271                 op1      = get_Not_op(val);
2272                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2273                 break;
2274         default:
2275                 return NULL;
2276         }
2277
2278         if(new_node != NULL) {
2279                 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2280                                 get_irn_pinned(node) == op_pin_state_pinned) {
2281                         set_irn_pinned(new_node, op_pin_state_pinned);
2282                 }
2283         }
2284
2285         return new_node;
2286 }
2287
2288 static int is_float_to_int32_conv(const ir_node *node)
2289 {
2290         ir_mode  *mode = get_irn_mode(node);
2291         ir_node  *conv_op;
2292         ir_mode  *conv_mode;
2293
2294         if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2295                 return 0;
2296
2297         if(!is_Conv(node))
2298                 return 0;
2299         conv_op   = get_Conv_op(node);
2300         conv_mode = get_irn_mode(conv_op);
2301
2302         if(!mode_is_float(conv_mode))
2303                 return 0;
2304
2305         return 1;
2306 }
2307
2308 /**
2309  * Transform a Store(floatConst).
2310  *
2311  * @return the created ia32 Store node
2312  */
2313 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2314         ir_mode  *mode      = get_irn_mode(cns);
2315         int      size       = get_mode_size_bits(mode);
2316         tarval   *tv        = get_Const_tarval(cns);
2317         ir_node  *block     = get_nodes_block(node);
2318         ir_node  *new_block = be_transform_node(block);
2319         ir_node  *ptr       = get_Store_ptr(node);
2320         ir_node  *mem       = get_Store_mem(node);
2321         ir_graph *irg       = current_ir_graph;
2322         dbg_info *dbgi      = get_irn_dbg_info(node);
2323         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2324         int      ofs        = 4;
2325         ir_node  *new_node;
2326         ia32_address_t addr;
2327
2328         unsigned val = get_tarval_sub_bits(tv, 0) |
2329                 (get_tarval_sub_bits(tv, 1) << 8) |
2330                 (get_tarval_sub_bits(tv, 2) << 16) |
2331                 (get_tarval_sub_bits(tv, 3) << 24);
2332         ir_node *imm = create_Immediate(NULL, 0, val);
2333
2334         /* construct store address */
2335         memset(&addr, 0, sizeof(addr));
2336         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2337
2338         if (addr.base == NULL) {
2339                 addr.base = noreg;
2340         } else {
2341                 addr.base = be_transform_node(addr.base);
2342         }
2343
2344         if (addr.index == NULL) {
2345                 addr.index = noreg;
2346         } else {
2347                 addr.index = be_transform_node(addr.index);
2348         }
2349         addr.mem = be_transform_node(mem);
2350
2351         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2352                 addr.index, addr.mem, imm);
2353
2354         set_irn_pinned(new_node, get_irn_pinned(node));
2355         set_ia32_op_type(new_node, ia32_AddrModeD);
2356         set_ia32_ls_mode(new_node, mode_Iu);
2357
2358         set_address(new_node, &addr);
2359
2360         /** add more stores if needed */
2361         while (size > 32) {
2362                 unsigned val = get_tarval_sub_bits(tv, ofs) |
2363                         (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2364                         (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2365                         (get_tarval_sub_bits(tv, ofs + 3) << 24);
2366                 ir_node *imm = create_Immediate(NULL, 0, val);
2367
2368                 addr.offset += 4;
2369                 addr.mem = new_node;
2370
2371                 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2372                         addr.index, addr.mem, imm);
2373
2374                 set_irn_pinned(new_node, get_irn_pinned(node));
2375                 set_ia32_op_type(new_node, ia32_AddrModeD);
2376                 set_ia32_ls_mode(new_node, mode_Iu);
2377
2378                 set_address(new_node, &addr);
2379                 size -= 32;
2380                 ofs  += 4;
2381         }
2382
2383         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2384         return new_node;
2385 }
2386
2387 /**
2388  * Transforms a normal Store.
2389  *
2390  * @return the created ia32 Store node
2391  */
2392 static ir_node *gen_normal_Store(ir_node *node)
2393 {
2394         ir_node  *val       = get_Store_value(node);
2395         ir_mode  *mode      = get_irn_mode(val);
2396         ir_node  *block     = get_nodes_block(node);
2397         ir_node  *new_block = be_transform_node(block);
2398         ir_node  *ptr       = get_Store_ptr(node);
2399         ir_node  *mem       = get_Store_mem(node);
2400         ir_graph *irg       = current_ir_graph;
2401         dbg_info *dbgi      = get_irn_dbg_info(node);
2402         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2403         ir_node  *new_val;
2404         ir_node  *new_node;
2405         ia32_address_t addr;
2406
2407         /* check for destination address mode */
2408         new_node = try_create_dest_am(node);
2409         if (new_node != NULL)
2410                 return new_node;
2411
2412         /* construct store address */
2413         memset(&addr, 0, sizeof(addr));
2414         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2415
2416         if (addr.base == NULL) {
2417                 addr.base = noreg;
2418         } else {
2419                 addr.base = be_transform_node(addr.base);
2420         }
2421
2422         if (addr.index == NULL) {
2423                 addr.index = noreg;
2424         } else {
2425                 addr.index = be_transform_node(addr.index);
2426         }
2427         addr.mem = be_transform_node(mem);
2428
2429         if (mode_is_float(mode)) {
2430                 /* convs (and strict-convs) before stores are unnecessary if the mode
2431                    is the same */
2432                 while (is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2433                         val = get_Conv_op(val);
2434                 }
2435                 new_val = be_transform_node(val);
2436                 if (ia32_cg_config.use_sse2) {
2437                         new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2438                                                       addr.index, addr.mem, new_val);
2439                 } else {
2440                         new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2441                                                     addr.index, addr.mem, new_val, mode);
2442                 }
2443         } else if (is_float_to_int32_conv(val)) {
2444                 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2445                 val = get_Conv_op(val);
2446
2447                 /* convs (and strict-convs) before stores are unnecessary if the mode
2448                    is the same */
2449                 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2450                         val = get_Conv_op(val);
2451                 }
2452                 new_val = be_transform_node(val);
2453
2454                 new_node = new_rd_ia32_vfist(dbgi, irg, new_block, addr.base,
2455                                              addr.index, addr.mem, new_val, trunc_mode);
2456         } else {
2457                 new_val = create_immediate_or_transform(val, 0);
2458                 assert(mode != mode_b);
2459
2460                 if (get_mode_size_bits(mode) == 8) {
2461                         new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2462                                                          addr.index, addr.mem, new_val);
2463                 } else {
2464                         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2465                                                      addr.index, addr.mem, new_val);
2466                 }
2467         }
2468
2469         set_irn_pinned(new_node, get_irn_pinned(node));
2470         set_ia32_op_type(new_node, ia32_AddrModeD);
2471         set_ia32_ls_mode(new_node, mode);
2472
2473         set_address(new_node, &addr);
2474         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2475
2476         return new_node;
2477 }
2478
2479 /**
2480  * Transforms a Store.
2481  *
2482  * @return the created ia32 Store node
2483  */
2484 static ir_node *gen_Store(ir_node *node)
2485 {
2486         ir_node  *val  = get_Store_value(node);
2487         ir_mode  *mode = get_irn_mode(val);
2488
2489         if (mode_is_float(mode) && is_Const(val)) {
2490                 int transform = 1;
2491
2492                 /* we are storing a floating point constant */
2493                 if (ia32_cg_config.use_sse2) {
2494                         transform = !is_simple_sse_Const(val);
2495                 } else {
2496                         transform = !is_simple_x87_Const(val);
2497                 }
2498                 if (transform)
2499                         return gen_float_const_Store(node, val);
2500         }
2501         return gen_normal_Store(node);
2502 }
2503
2504 /**
2505  * Transforms a Switch.
2506  *
2507  * @return the created ia32 SwitchJmp node
2508  */
2509 static ir_node *create_Switch(ir_node *node)
2510 {
2511         ir_graph *irg        = current_ir_graph;
2512         dbg_info *dbgi       = get_irn_dbg_info(node);
2513         ir_node  *block      = be_transform_node(get_nodes_block(node));
2514         ir_node  *sel        = get_Cond_selector(node);
2515         ir_node  *new_sel    = be_transform_node(sel);
2516         int       switch_min = INT_MAX;
2517         int       switch_max = INT_MIN;
2518         long      default_pn = get_Cond_defaultProj(node);
2519         ir_node  *new_node;
2520         const ir_edge_t *edge;
2521
2522         assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2523
2524         /* determine the smallest switch case value */
2525         foreach_out_edge(node, edge) {
2526                 ir_node *proj = get_edge_src_irn(edge);
2527                 long     pn   = get_Proj_proj(proj);
2528                 if(pn == default_pn)
2529                         continue;
2530
2531                 if(pn < switch_min)
2532                         switch_min = pn;
2533                 if(pn > switch_max)
2534                         switch_max = pn;
2535         }
2536
2537         if((unsigned) (switch_max - switch_min) > 256000) {
2538                 panic("Size of switch %+F bigger than 256000", node);
2539         }
2540
2541         if (switch_min != 0) {
2542                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2543
2544                 /* if smallest switch case is not 0 we need an additional sub */
2545                 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2546                 add_ia32_am_offs_int(new_sel, -switch_min);
2547                 set_ia32_op_type(new_sel, ia32_AddrModeS);
2548
2549                 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2550         }
2551
2552         new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2553         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2554
2555         return new_node;
2556 }
2557
2558 /**
2559  * Transform a Cond node.
2560  */
2561 static ir_node *gen_Cond(ir_node *node) {
2562         ir_node  *block     = get_nodes_block(node);
2563         ir_node  *new_block = be_transform_node(block);
2564         ir_graph *irg       = current_ir_graph;
2565         dbg_info *dbgi      = get_irn_dbg_info(node);
2566         ir_node  *sel       = get_Cond_selector(node);
2567         ir_mode  *sel_mode  = get_irn_mode(sel);
2568         ir_node  *flags     = NULL;
2569         ir_node  *new_node;
2570         pn_Cmp    pnc;
2571
2572         if (sel_mode != mode_b) {
2573                 return create_Switch(node);
2574         }
2575
2576         /* we get flags from a cmp */
2577         flags = get_flags_node(sel, &pnc);
2578
2579         new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2580         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2581
2582         return new_node;
2583 }
2584
2585 /**
2586  * Transforms a CopyB node.
2587  *
2588  * @return The transformed node.
2589  */
2590 static ir_node *gen_CopyB(ir_node *node) {
2591         ir_node  *block    = be_transform_node(get_nodes_block(node));
2592         ir_node  *src      = get_CopyB_src(node);
2593         ir_node  *new_src  = be_transform_node(src);
2594         ir_node  *dst      = get_CopyB_dst(node);
2595         ir_node  *new_dst  = be_transform_node(dst);
2596         ir_node  *mem      = get_CopyB_mem(node);
2597         ir_node  *new_mem  = be_transform_node(mem);
2598         ir_node  *res      = NULL;
2599         ir_graph *irg      = current_ir_graph;
2600         dbg_info *dbgi     = get_irn_dbg_info(node);
2601         int      size      = get_type_size_bytes(get_CopyB_type(node));
2602         int      rem;
2603
2604         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2605         /* then we need the size explicitly in ECX.                    */
2606         if (size >= 32 * 4) {
2607                 rem = size & 0x3; /* size % 4 */
2608                 size >>= 2;
2609
2610                 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2611                 add_irn_dep(res, get_irg_frame(irg));
2612
2613                 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2614         } else {
2615                 if(size == 0) {
2616                         ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2617                                    node);
2618                 }
2619                 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2620         }
2621
2622         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2623
2624         return res;
2625 }
2626
2627 static ir_node *gen_be_Copy(ir_node *node)
2628 {
2629         ir_node *new_node = be_duplicate_node(node);
2630         ir_mode *mode     = get_irn_mode(new_node);
2631
2632         if (mode_needs_gp_reg(mode)) {
2633                 set_irn_mode(new_node, mode_Iu);
2634         }
2635
2636         return new_node;
2637 }
2638
2639 static ir_node *create_Fucom(ir_node *node)
2640 {
2641         ir_graph *irg       = current_ir_graph;
2642         dbg_info *dbgi      = get_irn_dbg_info(node);
2643         ir_node  *block     = get_nodes_block(node);
2644         ir_node  *new_block = be_transform_node(block);
2645         ir_node  *left      = get_Cmp_left(node);
2646         ir_node  *new_left  = be_transform_node(left);
2647         ir_node  *right     = get_Cmp_right(node);
2648         ir_node  *new_right;
2649         ir_node  *new_node;
2650
2651         if(ia32_cg_config.use_fucomi) {
2652                 new_right = be_transform_node(right);
2653                 new_node  = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2654                                                 new_right, 0);
2655                 set_ia32_commutative(new_node);
2656                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2657         } else {
2658                 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2659                         new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2660                                                            0);
2661                 } else {
2662                         new_right = be_transform_node(right);
2663                         new_node  = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2664                                                                                                  new_right, 0);
2665                 }
2666
2667                 set_ia32_commutative(new_node);
2668
2669                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2670
2671                 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2672                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2673         }
2674
2675         return new_node;
2676 }
2677
2678 static ir_node *create_Ucomi(ir_node *node)
2679 {
2680         ir_graph *irg       = current_ir_graph;
2681         dbg_info *dbgi      = get_irn_dbg_info(node);
2682         ir_node  *src_block = get_nodes_block(node);
2683         ir_node  *new_block = be_transform_node(src_block);
2684         ir_node  *left      = get_Cmp_left(node);
2685         ir_node  *right     = get_Cmp_right(node);
2686         ir_node  *new_node;
2687         ia32_address_mode_t  am;
2688         ia32_address_t      *addr = &am.addr;
2689
2690         match_arguments(&am, src_block, left, right, NULL,
2691                         match_commutative | match_am);
2692
2693         new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2694                                      addr->mem, am.new_op1, am.new_op2,
2695                                      am.ins_permuted);
2696         set_am_attributes(new_node, &am);
2697
2698         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2699
2700         new_node = fix_mem_proj(new_node, &am);
2701
2702         return new_node;
2703 }
2704
2705 /**
2706  * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2707  * to fold an and into a test node
2708  */
2709 static int can_fold_test_and(ir_node *node)
2710 {
2711         const ir_edge_t *edge;
2712
2713         /** we can only have eq and lg projs */
2714         foreach_out_edge(node, edge) {
2715                 ir_node *proj = get_edge_src_irn(edge);
2716                 pn_Cmp   pnc  = get_Proj_proj(proj);
2717                 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2718                         return 0;
2719         }
2720
2721         return 1;
2722 }
2723
2724 static ir_node *gen_Cmp(ir_node *node)
2725 {
2726         ir_graph *irg       = current_ir_graph;
2727         dbg_info *dbgi      = get_irn_dbg_info(node);
2728         ir_node  *block     = get_nodes_block(node);
2729         ir_node  *new_block = be_transform_node(block);
2730         ir_node  *left      = get_Cmp_left(node);
2731         ir_node  *right     = get_Cmp_right(node);
2732         ir_mode  *cmp_mode  = get_irn_mode(left);
2733         ir_node  *new_node;
2734         ia32_address_mode_t  am;
2735         ia32_address_t      *addr = &am.addr;
2736         int                  cmp_unsigned;
2737
2738         if(mode_is_float(cmp_mode)) {
2739                 if (ia32_cg_config.use_sse2) {
2740                         return create_Ucomi(node);
2741                 } else {
2742                         return create_Fucom(node);
2743                 }
2744         }
2745
2746         assert(mode_needs_gp_reg(cmp_mode));
2747
2748         /* we prefer the Test instruction where possible except cases where
2749          * we can use SourceAM */
2750         cmp_unsigned = !mode_is_signed(cmp_mode);
2751         if (is_Const_0(right)) {
2752                 if (is_And(left) &&
2753                                 get_irn_n_edges(left) == 1 &&
2754                                 can_fold_test_and(node)) {
2755                         /* Test(and_left, and_right) */
2756                         ir_node *and_left  = get_And_left(left);
2757                         ir_node *and_right = get_And_right(left);
2758                         ir_mode *mode      = get_irn_mode(and_left);
2759
2760                         match_arguments(&am, block, and_left, and_right, NULL,
2761                                         match_commutative |
2762                                         match_am | match_8bit_am | match_16bit_am |
2763                                         match_am_and_immediates | match_immediate |
2764                                         match_8bit | match_16bit);
2765                         if (get_mode_size_bits(mode) == 8) {
2766                                 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2767                                                                 addr->index, addr->mem, am.new_op1,
2768                                                                 am.new_op2, am.ins_permuted,
2769                                                                 cmp_unsigned);
2770                         } else {
2771                                 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2772                                                             addr->index, addr->mem, am.new_op1,
2773                                                             am.new_op2, am.ins_permuted, cmp_unsigned);
2774                         }
2775                 } else {
2776                         match_arguments(&am, block, NULL, left, NULL,
2777                                         match_am | match_8bit_am | match_16bit_am |
2778                                         match_8bit | match_16bit);
2779                         if (am.op_type == ia32_AddrModeS) {
2780                                 /* Cmp(AM, 0) */
2781                                 ir_node *imm_zero = try_create_Immediate(right, 0);
2782                                 if (get_mode_size_bits(cmp_mode) == 8) {
2783                                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2784                                                                        addr->index, addr->mem, am.new_op2,
2785                                                                        imm_zero, am.ins_permuted,
2786                                                                        cmp_unsigned);
2787                                 } else {
2788                                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2789                                                                    addr->index, addr->mem, am.new_op2,
2790                                                                    imm_zero, am.ins_permuted, cmp_unsigned);
2791                                 }
2792                         } else {
2793                                 /* Test(left, left) */
2794                                 if (get_mode_size_bits(cmp_mode) == 8) {
2795                                         new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2796                                                                         addr->index, addr->mem, am.new_op2,
2797                                                                         am.new_op2, am.ins_permuted,
2798                                                                         cmp_unsigned);
2799                                 } else {
2800                                         new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2801                                                                     addr->index, addr->mem, am.new_op2,
2802                                                                     am.new_op2, am.ins_permuted,
2803                                                                     cmp_unsigned);
2804                                 }
2805                         }
2806                 }
2807         } else {
2808                 /* Cmp(left, right) */
2809                 match_arguments(&am, block, left, right, NULL,
2810                                 match_commutative | match_am | match_8bit_am |
2811                                 match_16bit_am | match_am_and_immediates |
2812                                 match_immediate | match_8bit | match_16bit);
2813                 if (get_mode_size_bits(cmp_mode) == 8) {
2814                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2815                                                        addr->index, addr->mem, am.new_op1,
2816                                                        am.new_op2, am.ins_permuted,
2817                                                        cmp_unsigned);
2818                 } else {
2819                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2820                                                    addr->index, addr->mem, am.new_op1,
2821                                                    am.new_op2, am.ins_permuted, cmp_unsigned);
2822                 }
2823         }
2824         set_am_attributes(new_node, &am);
2825         assert(cmp_mode != NULL);
2826         set_ia32_ls_mode(new_node, cmp_mode);
2827
2828         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2829
2830         new_node = fix_mem_proj(new_node, &am);
2831
2832         return new_node;
2833 }
2834
2835 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2836                             pn_Cmp pnc)
2837 {
2838         ir_graph            *irg           = current_ir_graph;
2839         dbg_info            *dbgi          = get_irn_dbg_info(node);
2840         ir_node             *block         = get_nodes_block(node);
2841         ir_node             *new_block     = be_transform_node(block);
2842         ir_node             *val_true      = get_Psi_val(node, 0);
2843         ir_node             *val_false     = get_Psi_default(node);
2844         ir_node             *new_node;
2845         match_flags_t        match_flags;
2846         ia32_address_mode_t  am;
2847         ia32_address_t      *addr;
2848
2849         assert(ia32_cg_config.use_cmov);
2850         assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2851
2852         addr = &am.addr;
2853
2854         match_flags = match_commutative | match_am | match_16bit_am |
2855                       match_mode_neutral;
2856
2857         match_arguments(&am, block, val_false, val_true, flags, match_flags);
2858
2859         new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2860                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2861                                     am.ins_permuted, pnc);
2862         set_am_attributes(new_node, &am);
2863
2864         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2865
2866         new_node = fix_mem_proj(new_node, &am);
2867
2868         return new_node;
2869 }
2870
2871
2872
2873 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2874                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2875                                  int ins_permuted)
2876 {
2877         ir_graph *irg   = current_ir_graph;
2878         ir_node  *noreg = ia32_new_NoReg_gp(env_cg);
2879         ir_node  *nomem = new_NoMem();
2880         ir_mode  *mode  = get_irn_mode(orig_node);
2881         ir_node  *new_node;
2882
2883         new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2884         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2885
2886         /* we might need to conv the result up */
2887         if(get_mode_size_bits(mode) > 8) {
2888                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2889                                                     nomem, new_node, mode_Bu);
2890                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2891         }
2892
2893         return new_node;
2894 }
2895
2896 /**
2897  * Transforms a Psi node into CMov.
2898  *
2899  * @return The transformed node.
2900  */
2901 static ir_node *gen_Psi(ir_node *node)
2902 {
2903         dbg_info *dbgi        = get_irn_dbg_info(node);
2904         ir_node  *block       = get_nodes_block(node);
2905         ir_node  *new_block   = be_transform_node(block);
2906         ir_node  *psi_true    = get_Psi_val(node, 0);
2907         ir_node  *psi_default = get_Psi_default(node);
2908         ir_node  *cond        = get_Psi_cond(node, 0);
2909         ir_node  *flags       = NULL;
2910         ir_node  *new_node;
2911         pn_Cmp    pnc;
2912
2913         assert(get_Psi_n_conds(node) == 1);
2914         assert(get_irn_mode(cond) == mode_b);
2915         assert(mode_needs_gp_reg(get_irn_mode(node)));
2916
2917         flags = get_flags_node(cond, &pnc);
2918
2919         if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2920                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 0);
2921         } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2922                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 1);
2923         } else {
2924                 new_node = create_CMov(node, cond, flags, pnc);
2925         }
2926         return new_node;
2927 }
2928
2929
2930 /**
2931  * Create a conversion from x87 state register to general purpose.
2932  */
2933 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
2934         ir_node         *block      = be_transform_node(get_nodes_block(node));
2935         ir_node         *op         = get_Conv_op(node);
2936         ir_node         *new_op     = be_transform_node(op);
2937         ia32_code_gen_t *cg         = env_cg;
2938         ir_graph        *irg        = current_ir_graph;
2939         dbg_info        *dbgi       = get_irn_dbg_info(node);
2940         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
2941         ir_node         *trunc_mode = ia32_new_Fpu_truncate(cg);
2942         ir_mode         *mode       = get_irn_mode(node);
2943         ir_node         *fist, *load;
2944
2945         /* do a fist */
2946         fist = new_rd_ia32_vfist(dbgi, irg, block, get_irg_frame(irg), noreg,
2947                                  new_NoMem(), new_op, trunc_mode);
2948
2949         set_irn_pinned(fist, op_pin_state_floats);
2950         set_ia32_use_frame(fist);
2951         set_ia32_op_type(fist, ia32_AddrModeD);
2952
2953         assert(get_mode_size_bits(mode) <= 32);
2954         /* exception we can only store signed 32 bit integers, so for unsigned
2955            we store a 64bit (signed) integer and load the lower bits */
2956         if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
2957                 set_ia32_ls_mode(fist, mode_Ls);
2958         } else {
2959                 set_ia32_ls_mode(fist, mode_Is);
2960         }
2961         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
2962
2963         /* do a Load */
2964         load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, fist);
2965
2966         set_irn_pinned(load, op_pin_state_floats);
2967         set_ia32_use_frame(load);
2968         set_ia32_op_type(load, ia32_AddrModeS);
2969         set_ia32_ls_mode(load, mode_Is);
2970         if(get_ia32_ls_mode(fist) == mode_Ls) {
2971                 ia32_attr_t *attr = get_ia32_attr(load);
2972                 attr->data.need_64bit_stackent = 1;
2973         } else {
2974                 ia32_attr_t *attr = get_ia32_attr(load);
2975                 attr->data.need_32bit_stackent = 1;
2976         }
2977         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
2978
2979         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
2980 }
2981
2982 /**
2983  * Creates a x87 strict Conv by placing a Sore and a Load
2984  */
2985 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
2986 {
2987         ir_node  *block    = get_nodes_block(node);
2988         ir_graph *irg      = current_ir_graph;
2989         dbg_info *dbgi     = get_irn_dbg_info(node);
2990         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
2991         ir_node  *nomem    = new_NoMem();
2992         ir_node  *frame    = get_irg_frame(irg);
2993         ir_node  *store, *load;
2994         ir_node  *new_node;
2995
2996         store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
2997                                  tgt_mode);
2998         set_ia32_use_frame(store);
2999         set_ia32_op_type(store, ia32_AddrModeD);
3000         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3001
3002         load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3003                                 tgt_mode);
3004         set_ia32_use_frame(load);
3005         set_ia32_op_type(load, ia32_AddrModeS);
3006         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3007
3008         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3009         return new_node;
3010 }
3011
3012 /**
3013  * Create a conversion from general purpose to x87 register
3014  */
3015 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3016         ir_node  *src_block = get_nodes_block(node);
3017         ir_node  *block     = be_transform_node(src_block);
3018         ir_graph *irg       = current_ir_graph;
3019         dbg_info *dbgi      = get_irn_dbg_info(node);
3020         ir_node  *op        = get_Conv_op(node);
3021         ir_node  *new_op    = NULL;
3022         ir_node  *noreg;
3023         ir_node  *nomem;
3024         ir_mode  *mode;
3025         ir_mode  *store_mode;
3026         ir_node  *fild;
3027         ir_node  *store;
3028         ir_node  *new_node;
3029         int       src_bits;
3030
3031         /* fild can use source AM if the operand is a signed 32bit integer */
3032         if (src_mode == mode_Is) {
3033                 ia32_address_mode_t am;
3034
3035                 match_arguments(&am, src_block, NULL, op, NULL,
3036                                 match_am | match_try_am);
3037                 if (am.op_type == ia32_AddrModeS) {
3038                         ia32_address_t *addr = &am.addr;
3039
3040                         fild     = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3041                                                      addr->index, addr->mem);
3042                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
3043                                               pn_ia32_vfild_res);
3044
3045                         set_am_attributes(fild, &am);
3046                         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3047
3048                         fix_mem_proj(fild, &am);
3049
3050                         return new_node;
3051                 }
3052         }
3053         if(new_op == NULL) {
3054                 new_op = be_transform_node(op);
3055         }
3056
3057         noreg  = ia32_new_NoReg_gp(env_cg);
3058         nomem  = new_NoMem();
3059         mode   = get_irn_mode(op);
3060
3061         /* first convert to 32 bit signed if necessary */
3062         src_bits = get_mode_size_bits(src_mode);
3063         if (src_bits == 8) {
3064                 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3065                                                   new_op, src_mode);
3066                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3067                 mode = mode_Is;
3068         } else if (src_bits < 32) {
3069                 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3070                                               new_op, src_mode);
3071                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3072                 mode = mode_Is;
3073         }
3074
3075         assert(get_mode_size_bits(mode) == 32);
3076
3077         /* do a store */
3078         store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3079                                   new_op);
3080
3081         set_ia32_use_frame(store);
3082         set_ia32_op_type(store, ia32_AddrModeD);
3083         set_ia32_ls_mode(store, mode_Iu);
3084
3085         /* exception for 32bit unsigned, do a 64bit spill+load */
3086         if(!mode_is_signed(mode)) {
3087                 ir_node *in[2];
3088                 /* store a zero */
3089                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3090
3091                 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3092                                                         get_irg_frame(irg), noreg, nomem,
3093                                                         zero_const);
3094
3095                 set_ia32_use_frame(zero_store);
3096                 set_ia32_op_type(zero_store, ia32_AddrModeD);
3097                 add_ia32_am_offs_int(zero_store, 4);
3098                 set_ia32_ls_mode(zero_store, mode_Iu);
3099
3100                 in[0] = zero_store;
3101                 in[1] = store;
3102
3103                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
3104                 store_mode = mode_Ls;
3105         } else {
3106                 store_mode = mode_Is;
3107         }
3108
3109         /* do a fild */
3110         fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3111
3112         set_ia32_use_frame(fild);
3113         set_ia32_op_type(fild, ia32_AddrModeS);
3114         set_ia32_ls_mode(fild, store_mode);
3115
3116         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3117
3118         return new_node;
3119 }
3120
3121 /**
3122  * Create a conversion from one integer mode into another one
3123  */
3124 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3125                                 dbg_info *dbgi, ir_node *block, ir_node *op,
3126                                 ir_node *node)
3127 {
3128         ir_graph *irg       = current_ir_graph;
3129         int       src_bits  = get_mode_size_bits(src_mode);
3130         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3131         ir_node  *new_block = be_transform_node(block);
3132         ir_node  *new_node;
3133         ir_mode  *smaller_mode;
3134         int       smaller_bits;
3135         ia32_address_mode_t  am;
3136         ia32_address_t      *addr = &am.addr;
3137
3138         (void) node;
3139         if (src_bits < tgt_bits) {
3140                 smaller_mode = src_mode;
3141                 smaller_bits = src_bits;
3142         } else {
3143                 smaller_mode = tgt_mode;
3144                 smaller_bits = tgt_bits;
3145         }
3146
3147 #ifdef DEBUG_libfirm
3148         if(is_Const(op)) {
3149                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3150                            op);
3151         }
3152 #endif
3153
3154         match_arguments(&am, block, NULL, op, NULL,
3155                         match_8bit | match_16bit |
3156                         match_am | match_8bit_am | match_16bit_am);
3157         if (smaller_bits == 8) {
3158                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3159                                                     addr->index, addr->mem, am.new_op2,
3160                                                     smaller_mode);
3161         } else {
3162                 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3163                                                 addr->index, addr->mem, am.new_op2,
3164                                                 smaller_mode);
3165         }
3166         set_am_attributes(new_node, &am);
3167         /* match_arguments assume that out-mode = in-mode, this isn't true here
3168          * so fix it */
3169         set_ia32_ls_mode(new_node, smaller_mode);
3170         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3171         new_node = fix_mem_proj(new_node, &am);
3172         return new_node;
3173 }
3174
3175 /**
3176  * Transforms a Conv node.
3177  *
3178  * @return The created ia32 Conv node
3179  */
3180 static ir_node *gen_Conv(ir_node *node) {
3181         ir_node  *block     = get_nodes_block(node);
3182         ir_node  *new_block = be_transform_node(block);
3183         ir_node  *op        = get_Conv_op(node);
3184         ir_node  *new_op    = NULL;
3185         ir_graph *irg       = current_ir_graph;
3186         dbg_info *dbgi      = get_irn_dbg_info(node);
3187         ir_mode  *src_mode  = get_irn_mode(op);
3188         ir_mode  *tgt_mode  = get_irn_mode(node);
3189         int       src_bits  = get_mode_size_bits(src_mode);
3190         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3191         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
3192         ir_node  *nomem     = new_rd_NoMem(irg);
3193         ir_node  *res       = NULL;
3194
3195         if (src_mode == mode_b) {
3196                 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3197                 /* nothing to do, we already model bools as 0/1 ints */
3198                 return be_transform_node(op);
3199         }
3200
3201         if (src_mode == tgt_mode) {
3202                 if (get_Conv_strict(node)) {
3203                         if (ia32_cg_config.use_sse2) {
3204                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
3205                                 return be_transform_node(op);
3206                         }
3207                 } else {
3208                         /* this should be optimized already, but who knows... */
3209                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3210                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3211                         return be_transform_node(op);
3212                 }
3213         }
3214
3215         if (mode_is_float(src_mode)) {
3216                 new_op = be_transform_node(op);
3217                 /* we convert from float ... */
3218                 if (mode_is_float(tgt_mode)) {
3219                         if(src_mode == mode_E && tgt_mode == mode_D
3220                                         && !get_Conv_strict(node)) {
3221                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3222                                 return new_op;
3223                         }
3224
3225                         /* ... to float */
3226                         if (ia32_cg_config.use_sse2) {
3227                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3228                                 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3229                                                              nomem, new_op);
3230                                 set_ia32_ls_mode(res, tgt_mode);
3231                         } else {
3232                                 if(get_Conv_strict(node)) {
3233                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3234                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3235                                         return res;
3236                                 }
3237                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3238                                 return new_op;
3239                         }
3240                 } else {
3241                         /* ... to int */
3242                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3243                         if (ia32_cg_config.use_sse2) {
3244                                 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3245                                                             nomem, new_op);
3246                                 set_ia32_ls_mode(res, src_mode);
3247                         } else {
3248                                 return gen_x87_fp_to_gp(node);
3249                         }
3250                 }
3251         } else {
3252                 /* we convert from int ... */
3253                 if (mode_is_float(tgt_mode)) {
3254                         /* ... to float */
3255                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3256                         if (ia32_cg_config.use_sse2) {
3257                                 new_op = be_transform_node(op);
3258                                 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3259                                                             nomem, new_op);
3260                                 set_ia32_ls_mode(res, tgt_mode);
3261                         } else {
3262                                 res = gen_x87_gp_to_fp(node, src_mode);
3263                                 if(get_Conv_strict(node)) {
3264                                         res = gen_x87_strict_conv(tgt_mode, res);
3265                                         SET_IA32_ORIG_NODE(get_Proj_pred(res),
3266                                                            ia32_get_old_node_name(env_cg, node));
3267                                 }
3268                                 return res;
3269                         }
3270                 } else if(tgt_mode == mode_b) {
3271                         /* mode_b lowering already took care that we only have 0/1 values */
3272                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3273                             src_mode, tgt_mode));
3274                         return be_transform_node(op);
3275                 } else {
3276                         /* to int */
3277                         if (src_bits == tgt_bits) {
3278                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3279                                     src_mode, tgt_mode));
3280                                 return be_transform_node(op);
3281                         }
3282
3283                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3284                         return res;
3285                 }
3286         }
3287
3288         return res;
3289 }
3290
3291 static int check_immediate_constraint(long val, char immediate_constraint_type)
3292 {
3293         switch (immediate_constraint_type) {
3294         case 0:
3295                 return 1;
3296         case 'I':
3297                 return val >= 0 && val <= 32;
3298         case 'J':
3299                 return val >= 0 && val <= 63;
3300         case 'K':
3301                 return val >= -128 && val <= 127;
3302         case 'L':
3303                 return val == 0xff || val == 0xffff;
3304         case 'M':
3305                 return val >= 0 && val <= 3;
3306         case 'N':
3307                 return val >= 0 && val <= 255;
3308         case 'O':
3309                 return val >= 0 && val <= 127;
3310         default:
3311                 break;
3312         }
3313         panic("Invalid immediate constraint found");
3314         return 0;
3315 }
3316
3317 static ir_node *try_create_Immediate(ir_node *node,
3318                                      char immediate_constraint_type)
3319 {
3320         int          minus         = 0;
3321         tarval      *offset        = NULL;
3322         int          offset_sign   = 0;
3323         long         val = 0;
3324         ir_entity   *symconst_ent  = NULL;
3325         int          symconst_sign = 0;
3326         ir_mode     *mode;
3327         ir_node     *cnst          = NULL;
3328         ir_node     *symconst      = NULL;
3329         ir_node     *new_node;
3330
3331         mode = get_irn_mode(node);
3332         if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3333                 return NULL;
3334         }
3335
3336         if(is_Minus(node)) {
3337                 minus = 1;
3338                 node  = get_Minus_op(node);
3339         }
3340
3341         if(is_Const(node)) {
3342                 cnst        = node;
3343                 symconst    = NULL;
3344                 offset_sign = minus;
3345         } else if(is_SymConst(node)) {
3346                 cnst          = NULL;
3347                 symconst      = node;
3348                 symconst_sign = minus;
3349         } else if(is_Add(node)) {
3350                 ir_node *left  = get_Add_left(node);
3351                 ir_node *right = get_Add_right(node);
3352                 if(is_Const(left) && is_SymConst(right)) {
3353                         cnst          = left;
3354                         symconst      = right;
3355                         symconst_sign = minus;
3356                         offset_sign   = minus;
3357                 } else if(is_SymConst(left) && is_Const(right)) {
3358                         cnst          = right;
3359                         symconst      = left;
3360                         symconst_sign = minus;
3361                         offset_sign   = minus;
3362                 }
3363         } else if(is_Sub(node)) {
3364                 ir_node *left  = get_Sub_left(node);
3365                 ir_node *right = get_Sub_right(node);
3366                 if(is_Const(left) && is_SymConst(right)) {
3367                         cnst          = left;
3368                         symconst      = right;
3369                         symconst_sign = !minus;
3370                         offset_sign   = minus;
3371                 } else if(is_SymConst(left) && is_Const(right)) {
3372                         cnst          = right;
3373                         symconst      = left;
3374                         symconst_sign = minus;
3375                         offset_sign   = !minus;
3376                 }
3377         } else {
3378                 return NULL;
3379         }
3380
3381         if(cnst != NULL) {
3382                 offset = get_Const_tarval(cnst);
3383                 if(tarval_is_long(offset)) {
3384                         val = get_tarval_long(offset);
3385                 } else {
3386                         ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3387                                    "long?\n", cnst);
3388                         return NULL;
3389                 }
3390
3391                 if(!check_immediate_constraint(val, immediate_constraint_type))
3392                         return NULL;
3393         }
3394         if(symconst != NULL) {
3395                 if(immediate_constraint_type != 0) {
3396                         /* we need full 32bits for symconsts */
3397                         return NULL;
3398                 }
3399
3400                 /* unfortunately the assembler/linker doesn't support -symconst */
3401                 if(symconst_sign)
3402                         return NULL;
3403
3404                 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3405                         return NULL;
3406                 symconst_ent = get_SymConst_entity(symconst);
3407         }
3408         if(cnst == NULL && symconst == NULL)
3409                 return NULL;
3410
3411         if(offset_sign && offset != NULL) {
3412                 offset = tarval_neg(offset);
3413         }
3414
3415         new_node = create_Immediate(symconst_ent, symconst_sign, val);
3416
3417         return new_node;
3418 }
3419
3420 static ir_node *create_immediate_or_transform(ir_node *node,
3421                                               char immediate_constraint_type)
3422 {
3423         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3424         if (new_node == NULL) {
3425                 new_node = be_transform_node(node);
3426         }
3427         return new_node;
3428 }
3429
3430 static const arch_register_req_t no_register_req = {
3431         arch_register_req_type_none,
3432         NULL,                         /* regclass */
3433         NULL,                         /* limit bitset */
3434         0,                            /* same pos */
3435         0                             /* different pos */
3436 };
3437
3438 /**
3439  * An assembler constraint.
3440  */
3441 typedef struct constraint_t constraint_t;
3442 struct constraint_t {
3443         int                         is_in;
3444         int                         n_outs;
3445         const arch_register_req_t **out_reqs;
3446
3447         const arch_register_req_t  *req;
3448         unsigned                    immediate_possible;
3449         char                        immediate_type;
3450 };
3451
3452 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3453 {
3454         int                          immediate_possible = 0;
3455         char                         immediate_type     = 0;
3456         unsigned                     limited            = 0;
3457         const arch_register_class_t *cls                = NULL;
3458         ir_graph                    *irg = current_ir_graph;
3459         struct obstack              *obst = get_irg_obstack(irg);
3460         arch_register_req_t         *req;
3461         unsigned                    *limited_ptr = NULL;
3462         int                          p;
3463         int                          same_as = -1;
3464
3465         /* TODO: replace all the asserts with nice error messages */
3466
3467         if(*c == 0) {
3468                 /* a memory constraint: no need to do anything in backend about it
3469                  * (the dependencies are already respected by the memory edge of
3470                  * the node) */
3471                 constraint->req = &no_register_req;
3472                 return;
3473         }
3474
3475         while(*c != 0) {
3476                 switch(*c) {
3477                 case ' ':
3478                 case '\t':
3479                 case '\n':
3480                         break;
3481
3482                 case 'a':
3483                         assert(cls == NULL ||
3484                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3485                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3486                         limited |= 1 << REG_EAX;
3487                         break;
3488                 case 'b':
3489                         assert(cls == NULL ||
3490                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3491                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3492                         limited |= 1 << REG_EBX;
3493                         break;
3494                 case 'c':
3495                         assert(cls == NULL ||
3496                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3497                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3498                         limited |= 1 << REG_ECX;
3499                         break;
3500                 case 'd':
3501                         assert(cls == NULL ||
3502                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3503                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3504                         limited |= 1 << REG_EDX;
3505                         break;
3506                 case 'D':
3507                         assert(cls == NULL ||
3508                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3509                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3510                         limited |= 1 << REG_EDI;
3511                         break;
3512                 case 'S':
3513                         assert(cls == NULL ||
3514                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3515                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3516                         limited |= 1 << REG_ESI;
3517                         break;
3518                 case 'Q':
3519                 case 'q': /* q means lower part of the regs only, this makes no
3520                                    * difference to Q for us (we only assigne whole registers) */
3521                         assert(cls == NULL ||
3522                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3523                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3524                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3525                                    1 << REG_EDX;
3526                         break;
3527                 case 'A':
3528                         assert(cls == NULL ||
3529                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3530                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3531                         limited |= 1 << REG_EAX | 1 << REG_EDX;
3532                         break;
3533                 case 'l':
3534                         assert(cls == NULL ||
3535                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3536                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3537                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3538                                    1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3539                                    1 << REG_EBP;
3540                         break;
3541
3542                 case 'R':
3543                 case 'r':
3544                 case 'p':
3545                         assert(cls == NULL);
3546                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3547                         break;
3548
3549                 case 'f':
3550                 case 't':
3551                 case 'u':
3552                         /* TODO: mark values so the x87 simulator knows about t and u */
3553                         assert(cls == NULL);
3554                         cls = &ia32_reg_classes[CLASS_ia32_vfp];
3555                         break;
3556
3557                 case 'Y':
3558                 case 'x':
3559                         assert(cls == NULL);
3560                         /* TODO: check that sse2 is supported */
3561                         cls = &ia32_reg_classes[CLASS_ia32_xmm];
3562                         break;
3563
3564                 case 'I':
3565                 case 'J':
3566                 case 'K':
3567                 case 'L':
3568                 case 'M':
3569                 case 'N':
3570                 case 'O':
3571                         assert(!immediate_possible);
3572                         immediate_possible = 1;
3573                         immediate_type     = *c;
3574                         break;
3575                 case 'n':
3576                 case 'i':
3577                         assert(!immediate_possible);
3578                         immediate_possible = 1;
3579                         break;
3580
3581                 case 'g':
3582                         assert(!immediate_possible && cls == NULL);
3583                         immediate_possible = 1;
3584                         cls                = &ia32_reg_classes[CLASS_ia32_gp];
3585                         break;
3586
3587                 case '0':
3588                 case '1':
3589                 case '2':
3590                 case '3':
3591                 case '4':
3592                 case '5':
3593                 case '6':
3594                 case '7':
3595                 case '8':
3596                 case '9':
3597                         assert(constraint->is_in && "can only specify same constraint "
3598                                "on input");
3599
3600                         sscanf(c, "%d%n", &same_as, &p);
3601                         if(same_as >= 0) {
3602                                 c += p;
3603                                 continue;
3604                         }
3605                         break;
3606
3607                 case 'm':
3608                         /* memory constraint no need to do anything in backend about it
3609                          * (the dependencies are already respected by the memory edge of
3610                          * the node) */
3611                         constraint->req    = &no_register_req;
3612                         return;
3613
3614                 case 'E': /* no float consts yet */
3615                 case 'F': /* no float consts yet */
3616                 case 's': /* makes no sense on x86 */
3617                 case 'X': /* we can't support that in firm */
3618                 case 'o':
3619                 case 'V':
3620                 case '<': /* no autodecrement on x86 */
3621                 case '>': /* no autoincrement on x86 */
3622                 case 'C': /* sse constant not supported yet */
3623                 case 'G': /* 80387 constant not supported yet */
3624                 case 'y': /* we don't support mmx registers yet */
3625                 case 'Z': /* not available in 32 bit mode */
3626                 case 'e': /* not available in 32 bit mode */
3627                         panic("unsupported asm constraint '%c' found in (%+F)",
3628                               *c, current_ir_graph);
3629                         break;
3630                 default:
3631                         panic("unknown asm constraint '%c' found in (%+F)", *c,
3632                               current_ir_graph);
3633                         break;
3634                 }
3635                 ++c;
3636         }
3637
3638         if(same_as >= 0) {
3639                 const arch_register_req_t *other_constr;
3640
3641                 assert(cls == NULL && "same as and register constraint not supported");
3642                 assert(!immediate_possible && "same as and immediate constraint not "
3643                        "supported");
3644                 assert(same_as < constraint->n_outs && "wrong constraint number in "
3645                        "same_as constraint");
3646
3647                 other_constr         = constraint->out_reqs[same_as];
3648
3649                 req                  = obstack_alloc(obst, sizeof(req[0]));
3650                 req->cls             = other_constr->cls;
3651                 req->type            = arch_register_req_type_should_be_same;
3652                 req->limited         = NULL;
3653                 req->other_same      = 1U << pos;
3654                 req->other_different = 0;
3655
3656                 /* switch constraints. This is because in firm we have same_as
3657                  * constraints on the output constraints while in the gcc asm syntax
3658                  * they are specified on the input constraints */
3659                 constraint->req               = other_constr;
3660                 constraint->out_reqs[same_as] = req;
3661                 constraint->immediate_possible = 0;
3662                 return;
3663         }
3664
3665         if(immediate_possible && cls == NULL) {
3666                 cls = &ia32_reg_classes[CLASS_ia32_gp];
3667         }
3668         assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3669         assert(cls != NULL);
3670
3671         if(immediate_possible) {
3672                 assert(constraint->is_in
3673                        && "immediate make no sense for output constraints");
3674         }
3675         /* todo: check types (no float input on 'r' constrained in and such... */
3676
3677         if(limited != 0) {
3678                 req          = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3679                 limited_ptr  = (unsigned*) (req+1);
3680         } else {
3681                 req = obstack_alloc(obst, sizeof(req[0]));
3682         }
3683         memset(req, 0, sizeof(req[0]));
3684
3685         if(limited != 0) {
3686                 req->type    = arch_register_req_type_limited;
3687                 *limited_ptr = limited;
3688                 req->limited = limited_ptr;
3689         } else {
3690                 req->type    = arch_register_req_type_normal;
3691         }
3692         req->cls = cls;
3693
3694         constraint->req                = req;
3695         constraint->immediate_possible = immediate_possible;
3696         constraint->immediate_type     = immediate_type;
3697 }
3698
3699 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3700                           const char *clobber)
3701 {
3702         ir_graph                    *irg  = get_irn_irg(node);
3703         struct obstack              *obst = get_irg_obstack(irg);
3704         const arch_register_t       *reg  = NULL;
3705         int                          c;
3706         size_t                       r;
3707         arch_register_req_t         *req;
3708         const arch_register_class_t *cls;
3709         unsigned                    *limited;
3710
3711         (void) pos;
3712
3713         /* TODO: construct a hashmap instead of doing linear search for clobber
3714          * register */
3715         for(c = 0; c < N_CLASSES; ++c) {
3716                 cls = & ia32_reg_classes[c];
3717                 for(r = 0; r < cls->n_regs; ++r) {
3718                         const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3719                         if(strcmp(temp_reg->name, clobber) == 0
3720                                         || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3721                                 reg = temp_reg;
3722                                 break;
3723                         }
3724                 }
3725                 if(reg != NULL)
3726                         break;
3727         }
3728         if(reg == NULL) {
3729                 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3730                 return;
3731         }
3732
3733         assert(reg->index < 32);
3734
3735         limited  = obstack_alloc(obst, sizeof(limited[0]));
3736         *limited = 1 << reg->index;
3737
3738         req          = obstack_alloc(obst, sizeof(req[0]));
3739         memset(req, 0, sizeof(req[0]));
3740         req->type    = arch_register_req_type_limited;
3741         req->cls     = cls;
3742         req->limited = limited;
3743
3744         constraint->req                = req;
3745         constraint->immediate_possible = 0;
3746         constraint->immediate_type     = 0;
3747 }
3748
3749 static int is_memory_op(const ir_asm_constraint *constraint)
3750 {
3751         ident      *id  = constraint->constraint;
3752         const char *str = get_id_str(id);
3753         const char *c;
3754
3755         for(c = str; *c != '\0'; ++c) {
3756                 if(*c == 'm')
3757                         return 1;
3758         }
3759
3760         return 0;
3761 }
3762
3763 /**
3764  * generates code for a ASM node
3765  */
3766 static ir_node *gen_ASM(ir_node *node)
3767 {
3768         int                         i, arity;
3769         ir_graph                   *irg       = current_ir_graph;
3770         ir_node                    *block     = get_nodes_block(node);
3771         ir_node                    *new_block = be_transform_node(block);
3772         dbg_info                   *dbgi      = get_irn_dbg_info(node);
3773         ir_node                   **in;
3774         ir_node                    *new_node;
3775         int                         out_arity;
3776         int                         n_out_constraints;
3777         int                         n_clobbers;
3778         const arch_register_req_t **out_reg_reqs;
3779         const arch_register_req_t **in_reg_reqs;
3780         ia32_asm_reg_t             *register_map;
3781         unsigned                    reg_map_size = 0;
3782         struct obstack             *obst;
3783         const ir_asm_constraint    *in_constraints;
3784         const ir_asm_constraint    *out_constraints;
3785         ident                     **clobbers;
3786         constraint_t                parsed_constraint;
3787
3788         arity = get_irn_arity(node);
3789         in    = alloca(arity * sizeof(in[0]));
3790         memset(in, 0, arity * sizeof(in[0]));
3791
3792         n_out_constraints = get_ASM_n_output_constraints(node);
3793         n_clobbers        = get_ASM_n_clobbers(node);
3794         out_arity         = n_out_constraints + n_clobbers;
3795         /* hack to keep space for mem proj */
3796         if(n_clobbers > 0)
3797                 out_arity += 1;
3798
3799         in_constraints  = get_ASM_input_constraints(node);
3800         out_constraints = get_ASM_output_constraints(node);
3801         clobbers        = get_ASM_clobbers(node);
3802
3803         /* construct output constraints */
3804         obst         = get_irg_obstack(irg);
3805         out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3806         parsed_constraint.out_reqs = out_reg_reqs;
3807         parsed_constraint.n_outs   = n_out_constraints;
3808         parsed_constraint.is_in    = 0;
3809
3810         for(i = 0; i < out_arity; ++i) {
3811                 const char   *c;
3812
3813                 if(i < n_out_constraints) {
3814                         const ir_asm_constraint *constraint = &out_constraints[i];
3815                         c = get_id_str(constraint->constraint);
3816                         parse_asm_constraint(i, &parsed_constraint, c);
3817
3818                         if(constraint->pos > reg_map_size)
3819                                 reg_map_size = constraint->pos;
3820
3821                         out_reg_reqs[i] = parsed_constraint.req;
3822                 } else if(i < out_arity - 1) {
3823                         ident *glob_id = clobbers [i - n_out_constraints];
3824                         assert(glob_id != NULL);
3825                         c = get_id_str(glob_id);
3826                         parse_clobber(node, i, &parsed_constraint, c);
3827
3828                         out_reg_reqs[i+1] = parsed_constraint.req;
3829                 }
3830         }
3831         if(n_clobbers > 1)
3832                 out_reg_reqs[n_out_constraints] = &no_register_req;
3833
3834         /* construct input constraints */
3835         in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
3836         parsed_constraint.is_in = 1;
3837         for(i = 0; i < arity; ++i) {
3838                 const ir_asm_constraint   *constraint = &in_constraints[i];
3839                 ident                     *constr_id  = constraint->constraint;
3840                 const char                *c          = get_id_str(constr_id);
3841
3842                 parse_asm_constraint(i, &parsed_constraint, c);
3843                 in_reg_reqs[i] = parsed_constraint.req;
3844
3845                 if(constraint->pos > reg_map_size)
3846                         reg_map_size = constraint->pos;
3847
3848                 if(parsed_constraint.immediate_possible) {
3849                         ir_node *pred      = get_irn_n(node, i);
3850                         char     imm_type  = parsed_constraint.immediate_type;
3851                         ir_node *immediate = try_create_Immediate(pred, imm_type);
3852
3853                         if(immediate != NULL) {
3854                                 in[i] = immediate;
3855                         }
3856                 }
3857         }
3858         reg_map_size++;
3859
3860         register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
3861         memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
3862
3863         for(i = 0; i < n_out_constraints; ++i) {
3864                 const ir_asm_constraint *constraint = &out_constraints[i];
3865                 unsigned                 pos        = constraint->pos;
3866
3867                 assert(pos < reg_map_size);
3868                 register_map[pos].use_input = 0;
3869                 register_map[pos].valid     = 1;
3870                 register_map[pos].memory    = is_memory_op(constraint);
3871                 register_map[pos].inout_pos = i;
3872                 register_map[pos].mode      = constraint->mode;
3873         }
3874
3875         /* transform inputs */
3876         for(i = 0; i < arity; ++i) {
3877                 const ir_asm_constraint *constraint = &in_constraints[i];
3878                 unsigned                 pos        = constraint->pos;
3879                 ir_node                 *pred       = get_irn_n(node, i);
3880                 ir_node                 *transformed;
3881
3882                 assert(pos < reg_map_size);
3883                 register_map[pos].use_input = 1;
3884                 register_map[pos].valid     = 1;
3885                 register_map[pos].memory    = is_memory_op(constraint);
3886                 register_map[pos].inout_pos = i;
3887                 register_map[pos].mode      = constraint->mode;
3888
3889                 if(in[i] != NULL)
3890                         continue;
3891
3892                 transformed = be_transform_node(pred);
3893                 in[i]       = transformed;
3894         }
3895
3896         new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
3897                                    get_ASM_text(node), register_map);
3898
3899         set_ia32_out_req_all(new_node, out_reg_reqs);
3900         set_ia32_in_req_all(new_node, in_reg_reqs);
3901
3902         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3903
3904         return new_node;
3905 }
3906
3907 /**
3908  * Transforms a FrameAddr into an ia32 Add.
3909  */
3910 static ir_node *gen_be_FrameAddr(ir_node *node) {
3911         ir_node  *block  = be_transform_node(get_nodes_block(node));
3912         ir_node  *op     = be_get_FrameAddr_frame(node);
3913         ir_node  *new_op = be_transform_node(op);
3914         ir_graph *irg    = current_ir_graph;
3915         dbg_info *dbgi   = get_irn_dbg_info(node);
3916         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
3917         ir_node  *new_node;
3918
3919         new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3920         set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3921         set_ia32_use_frame(new_node);
3922
3923         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3924
3925         return new_node;
3926 }
3927
3928 /**
3929  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3930  */
3931 static ir_node *gen_be_Return(ir_node *node) {
3932         ir_graph  *irg     = current_ir_graph;
3933         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
3934         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
3935         ir_entity *ent     = get_irg_entity(irg);
3936         ir_type   *tp      = get_entity_type(ent);
3937         dbg_info  *dbgi;
3938         ir_node   *block;
3939         ir_type   *res_type;
3940         ir_mode   *mode;
3941         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
3942         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
3943         ir_node   *noreg;
3944         ir_node   **in;
3945         int       pn_ret_val, pn_ret_mem, arity, i;
3946
3947         assert(ret_val != NULL);
3948         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3949                 return be_duplicate_node(node);
3950         }
3951
3952         res_type = get_method_res_type(tp, 0);
3953
3954         if (! is_Primitive_type(res_type)) {
3955                 return be_duplicate_node(node);
3956         }
3957
3958         mode = get_type_mode(res_type);
3959         if (! mode_is_float(mode)) {
3960                 return be_duplicate_node(node);
3961         }
3962
3963         assert(get_method_n_ress(tp) == 1);
3964
3965         pn_ret_val = get_Proj_proj(ret_val);
3966         pn_ret_mem = get_Proj_proj(ret_mem);
3967
3968         /* get the Barrier */
3969         barrier = get_Proj_pred(ret_val);
3970
3971         /* get result input of the Barrier */
3972         ret_val     = get_irn_n(barrier, pn_ret_val);
3973         new_ret_val = be_transform_node(ret_val);
3974
3975         /* get memory input of the Barrier */
3976         ret_mem     = get_irn_n(barrier, pn_ret_mem);
3977         new_ret_mem = be_transform_node(ret_mem);
3978
3979         frame = get_irg_frame(irg);
3980
3981         dbgi  = get_irn_dbg_info(barrier);
3982         block = be_transform_node(get_nodes_block(barrier));
3983
3984         noreg = ia32_new_NoReg_gp(env_cg);
3985
3986         /* store xmm0 onto stack */
3987         sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3988                                              new_ret_mem, new_ret_val);
3989         set_ia32_ls_mode(sse_store, mode);
3990         set_ia32_op_type(sse_store, ia32_AddrModeD);
3991         set_ia32_use_frame(sse_store);
3992
3993         /* load into x87 register */
3994         fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3995         set_ia32_op_type(fld, ia32_AddrModeS);
3996         set_ia32_use_frame(fld);
3997
3998         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3999         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4000
4001         /* create a new barrier */
4002         arity = get_irn_arity(barrier);
4003         in = alloca(arity * sizeof(in[0]));
4004         for (i = 0; i < arity; ++i) {
4005                 ir_node *new_in;
4006
4007                 if (i == pn_ret_val) {
4008                         new_in = fld;
4009                 } else if (i == pn_ret_mem) {
4010                         new_in = mproj;
4011                 } else {
4012                         ir_node *in = get_irn_n(barrier, i);
4013                         new_in = be_transform_node(in);
4014                 }
4015                 in[i] = new_in;
4016         }
4017
4018         new_barrier = new_ir_node(dbgi, irg, block,
4019                                   get_irn_op(barrier), get_irn_mode(barrier),
4020                                   arity, in);
4021         copy_node_attr(barrier, new_barrier);
4022         be_duplicate_deps(barrier, new_barrier);
4023         be_set_transformed_node(barrier, new_barrier);
4024         mark_irn_visited(barrier);
4025
4026         /* transform normally */
4027         return be_duplicate_node(node);
4028 }
4029
4030 /**
4031  * Transform a be_AddSP into an ia32_SubSP.
4032  */
4033 static ir_node *gen_be_AddSP(ir_node *node)
4034 {
4035         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
4036         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4037
4038         return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4039 }
4040
4041 /**
4042  * Transform a be_SubSP into an ia32_AddSP
4043  */
4044 static ir_node *gen_be_SubSP(ir_node *node)
4045 {
4046         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
4047         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4048
4049         return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4050 }
4051
4052 /**
4053  * This function just sets the register for the Unknown node
4054  * as this is not done during register allocation because Unknown
4055  * is an "ignore" node.
4056  */
4057 static ir_node *gen_Unknown(ir_node *node) {
4058         ir_mode *mode = get_irn_mode(node);
4059
4060         if (mode_is_float(mode)) {
4061                 if (ia32_cg_config.use_sse2) {
4062                         return ia32_new_Unknown_xmm(env_cg);
4063                 } else {
4064                         /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4065                         ir_graph *irg   = current_ir_graph;
4066                         dbg_info *dbgi  = get_irn_dbg_info(node);
4067                         ir_node  *block = get_irg_start_block(irg);
4068                         ir_node  *ret   = new_rd_ia32_vfldz(dbgi, irg, block);
4069
4070                         /* Const Nodes before the initial IncSP are a bad idea, because
4071                          * they could be spilled and we have no SP ready at that point yet.
4072                          * So add a dependency to the initial frame pointer calculation to
4073                          * avoid that situation.
4074                          */
4075                         add_irn_dep(ret, get_irg_frame(irg));
4076                         return ret;
4077                 }
4078         } else if (mode_needs_gp_reg(mode)) {
4079                 return ia32_new_Unknown_gp(env_cg);
4080         } else {
4081                 panic("unsupported Unknown-Mode");
4082         }
4083         return NULL;
4084 }
4085
4086 /**
4087  * Change some phi modes
4088  */
4089 static ir_node *gen_Phi(ir_node *node) {
4090         ir_node  *block = be_transform_node(get_nodes_block(node));
4091         ir_graph *irg   = current_ir_graph;
4092         dbg_info *dbgi  = get_irn_dbg_info(node);
4093         ir_mode  *mode  = get_irn_mode(node);
4094         ir_node  *phi;
4095
4096         if(mode_needs_gp_reg(mode)) {
4097                 /* we shouldn't have any 64bit stuff around anymore */
4098                 assert(get_mode_size_bits(mode) <= 32);
4099                 /* all integer operations are on 32bit registers now */
4100                 mode = mode_Iu;
4101         } else if(mode_is_float(mode)) {
4102                 if (ia32_cg_config.use_sse2) {
4103                         mode = mode_xmm;
4104                 } else {
4105                         mode = mode_vfp;
4106                 }
4107         }
4108
4109         /* phi nodes allow loops, so we use the old arguments for now
4110          * and fix this later */
4111         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4112                           get_irn_in(node) + 1);
4113         copy_node_attr(node, phi);
4114         be_duplicate_deps(node, phi);
4115
4116         be_set_transformed_node(node, phi);
4117         be_enqueue_preds(node);
4118
4119         return phi;
4120 }
4121
4122 /**
4123  * Transform IJmp
4124  */
4125 static ir_node *gen_IJmp(ir_node *node)
4126 {
4127         ir_node  *block     = get_nodes_block(node);
4128         ir_node  *new_block = be_transform_node(block);
4129         ir_graph *irg       = current_ir_graph;
4130         dbg_info *dbgi      = get_irn_dbg_info(node);
4131         ir_node  *op        = get_IJmp_target(node);
4132         ir_node  *new_node;
4133         ia32_address_mode_t  am;
4134         ia32_address_t      *addr = &am.addr;
4135
4136         assert(get_irn_mode(op) == mode_P);
4137
4138         match_arguments(&am, block, NULL, op, NULL,
4139                         match_am | match_8bit_am | match_16bit_am |
4140                         match_immediate | match_8bit | match_16bit);
4141
4142         new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4143                                     addr->mem, am.new_op2);
4144         set_am_attributes(new_node, &am);
4145         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4146
4147         new_node = fix_mem_proj(new_node, &am);
4148
4149         return new_node;
4150 }
4151
4152 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4153                                      ir_node *mem);
4154
4155 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4156                                       ir_node *val, ir_node *mem);
4157
4158 /**
4159  * Transforms a lowered Load into a "real" one.
4160  */
4161 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4162 {
4163         ir_node  *block   = be_transform_node(get_nodes_block(node));
4164         ir_node  *ptr     = get_irn_n(node, 0);
4165         ir_node  *new_ptr = be_transform_node(ptr);
4166         ir_node  *mem     = get_irn_n(node, 1);
4167         ir_node  *new_mem = be_transform_node(mem);
4168         ir_graph *irg     = current_ir_graph;
4169         dbg_info *dbgi    = get_irn_dbg_info(node);
4170         ir_mode  *mode    = get_ia32_ls_mode(node);
4171         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4172         ir_node  *new_op;
4173
4174         new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4175
4176         set_ia32_op_type(new_op, ia32_AddrModeS);
4177         set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4178         set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4179         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4180         if (is_ia32_am_sc_sign(node))
4181                 set_ia32_am_sc_sign(new_op);
4182         set_ia32_ls_mode(new_op, mode);
4183         if (is_ia32_use_frame(node)) {
4184                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4185                 set_ia32_use_frame(new_op);
4186         }
4187
4188         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4189
4190         return new_op;
4191 }
4192
4193 /**
4194  * Transforms a lowered Store into a "real" one.
4195  */
4196 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4197 {
4198         ir_node  *block   = be_transform_node(get_nodes_block(node));
4199         ir_node  *ptr     = get_irn_n(node, 0);
4200         ir_node  *new_ptr = be_transform_node(ptr);
4201         ir_node  *val     = get_irn_n(node, 1);
4202         ir_node  *new_val = be_transform_node(val);
4203         ir_node  *mem     = get_irn_n(node, 2);
4204         ir_node  *new_mem = be_transform_node(mem);
4205         ir_graph *irg     = current_ir_graph;
4206         dbg_info *dbgi    = get_irn_dbg_info(node);
4207         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4208         ir_mode  *mode    = get_ia32_ls_mode(node);
4209         ir_node  *new_op;
4210         long     am_offs;
4211
4212         new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4213
4214         am_offs = get_ia32_am_offs_int(node);
4215         add_ia32_am_offs_int(new_op, am_offs);
4216
4217         set_ia32_op_type(new_op, ia32_AddrModeD);
4218         set_ia32_ls_mode(new_op, mode);
4219         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4220         set_ia32_use_frame(new_op);
4221
4222         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4223
4224         return new_op;
4225 }
4226
4227 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4228 {
4229         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
4230         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4231
4232         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4233                                match_immediate | match_mode_neutral);
4234 }
4235
4236 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4237 {
4238         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
4239         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4240         return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4241                                match_immediate);
4242 }
4243
4244 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4245 {
4246         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
4247         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4248         return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4249                                match_immediate);
4250 }
4251
4252 static ir_node *gen_ia32_l_Add(ir_node *node) {
4253         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
4254         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
4255         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4256                         match_commutative | match_am | match_immediate |
4257                         match_mode_neutral);
4258
4259         if(is_Proj(lowered)) {
4260                 lowered = get_Proj_pred(lowered);
4261         } else {
4262                 assert(is_ia32_Add(lowered));
4263                 set_irn_mode(lowered, mode_T);
4264         }
4265
4266         return lowered;
4267 }
4268
4269 static ir_node *gen_ia32_l_Adc(ir_node *node)
4270 {
4271         return gen_binop_flags(node, new_rd_ia32_Adc,
4272                         match_commutative | match_am | match_immediate |
4273                         match_mode_neutral);
4274 }
4275
4276 /**
4277  * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4278  *
4279  * @param node   The node to transform
4280  * @return the created ia32 vfild node
4281  */
4282 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4283         return gen_lowered_Load(node, new_rd_ia32_vfild);
4284 }
4285
4286 /**
4287  * Transforms an ia32_l_Load into a "real" ia32_Load node
4288  *
4289  * @param node   The node to transform
4290  * @return the created ia32 Load node
4291  */
4292 static ir_node *gen_ia32_l_Load(ir_node *node) {
4293         return gen_lowered_Load(node, new_rd_ia32_Load);
4294 }
4295
4296 /**
4297  * Transforms an ia32_l_Store into a "real" ia32_Store node
4298  *
4299  * @param node   The node to transform
4300  * @return the created ia32 Store node
4301  */
4302 static ir_node *gen_ia32_l_Store(ir_node *node) {
4303         return gen_lowered_Store(node, new_rd_ia32_Store);
4304 }
4305
4306 /**
4307  * Transforms a l_vfist into a "real" vfist node.
4308  *
4309  * @param node   The node to transform
4310  * @return the created ia32 vfist node
4311  */
4312 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4313         ir_node  *block      = be_transform_node(get_nodes_block(node));
4314         ir_node  *ptr        = get_irn_n(node, 0);
4315         ir_node  *new_ptr    = be_transform_node(ptr);
4316         ir_node  *val        = get_irn_n(node, 1);
4317         ir_node  *new_val    = be_transform_node(val);
4318         ir_node  *mem        = get_irn_n(node, 2);
4319         ir_node  *new_mem    = be_transform_node(mem);
4320         ir_graph *irg        = current_ir_graph;
4321         dbg_info *dbgi       = get_irn_dbg_info(node);
4322         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4323         ir_mode  *mode       = get_ia32_ls_mode(node);
4324         ir_node  *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4325         ir_node  *new_op;
4326         long     am_offs;
4327
4328         new_op = new_rd_ia32_vfist(dbgi, irg, block, new_ptr, noreg, new_mem,
4329                                    new_val, trunc_mode);
4330
4331         am_offs = get_ia32_am_offs_int(node);
4332         add_ia32_am_offs_int(new_op, am_offs);
4333
4334         set_ia32_op_type(new_op, ia32_AddrModeD);
4335         set_ia32_ls_mode(new_op, mode);
4336         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4337         set_ia32_use_frame(new_op);
4338
4339         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4340
4341         return new_op;
4342 }
4343
4344 /**
4345  * Transforms a l_MulS into a "real" MulS node.
4346  *
4347  * @return the created ia32 Mul node
4348  */
4349 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4350         ir_node *left  = get_binop_left(node);
4351         ir_node *right = get_binop_right(node);
4352
4353         return gen_binop(node, left, right, new_rd_ia32_Mul,
4354                          match_commutative | match_am | match_mode_neutral);
4355 }
4356
4357 /**
4358  * Transforms a l_IMulS into a "real" IMul1OPS node.
4359  *
4360  * @return the created ia32 IMul1OP node
4361  */
4362 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4363         ir_node  *left  = get_binop_left(node);
4364         ir_node  *right = get_binop_right(node);
4365
4366         return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4367                          match_commutative | match_am | match_mode_neutral);
4368 }
4369
4370 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4371         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
4372         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4373         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4374                         match_am | match_immediate | match_mode_neutral);
4375
4376         if(is_Proj(lowered)) {
4377                 lowered = get_Proj_pred(lowered);
4378         } else {
4379                 assert(is_ia32_Sub(lowered));
4380                 set_irn_mode(lowered, mode_T);
4381         }
4382
4383         return lowered;
4384 }
4385
4386 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4387         return gen_binop_flags(node, new_rd_ia32_Sbb,
4388                         match_am | match_immediate | match_mode_neutral);
4389 }
4390
4391 /**
4392  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4393  * op1 - target to be shifted
4394  * op2 - contains bits to be shifted into target
4395  * op3 - shift count
4396  * Only op3 can be an immediate.
4397  */
4398 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4399                                          ir_node *low, ir_node *count)
4400 {
4401         ir_node  *block     = get_nodes_block(node);
4402         ir_node  *new_block = be_transform_node(block);
4403         ir_graph *irg       = current_ir_graph;
4404         dbg_info *dbgi      = get_irn_dbg_info(node);
4405         ir_node  *new_high  = be_transform_node(high);
4406         ir_node  *new_low   = be_transform_node(low);
4407         ir_node  *new_count;
4408         ir_node  *new_node;
4409
4410         /* the shift amount can be any mode that is bigger than 5 bits, since all
4411          * other bits are ignored anyway */
4412         while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4413                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4414                 count = get_Conv_op(count);
4415         }
4416         new_count = create_immediate_or_transform(count, 0);
4417
4418         if (is_ia32_l_ShlD(node)) {
4419                 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4420                                             new_count);
4421         } else {
4422                 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4423                                             new_count);
4424         }
4425         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4426
4427         return new_node;
4428 }
4429
4430 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4431 {
4432         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
4433         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
4434         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4435         return gen_lowered_64bit_shifts(node, high, low, count);
4436 }
4437
4438 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4439 {
4440         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
4441         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
4442         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4443         return gen_lowered_64bit_shifts(node, high, low, count);
4444 }
4445
4446 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4447         ir_node  *src_block    = get_nodes_block(node);
4448         ir_node  *block        = be_transform_node(src_block);
4449         ir_graph *irg          = current_ir_graph;
4450         dbg_info *dbgi         = get_irn_dbg_info(node);
4451         ir_node  *frame        = get_irg_frame(irg);
4452         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
4453         ir_node  *nomem        = new_NoMem();
4454         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4455         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4456         ir_node  *new_val_low  = be_transform_node(val_low);
4457         ir_node  *new_val_high = be_transform_node(val_high);
4458         ir_node  *in[2];
4459         ir_node  *sync;
4460         ir_node  *fild;
4461         ir_node  *store_low;
4462         ir_node  *store_high;
4463
4464         if(!mode_is_signed(get_irn_mode(val_high))) {
4465                 panic("unsigned long long -> float not supported yet (%+F)", node);
4466         }
4467
4468         /* do a store */
4469         store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4470                                       new_val_low);
4471         store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4472                                        new_val_high);
4473         SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4474         SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4475
4476         set_ia32_use_frame(store_low);
4477         set_ia32_use_frame(store_high);
4478         set_ia32_op_type(store_low, ia32_AddrModeD);
4479         set_ia32_op_type(store_high, ia32_AddrModeD);
4480         set_ia32_ls_mode(store_low, mode_Iu);
4481         set_ia32_ls_mode(store_high, mode_Is);
4482         add_ia32_am_offs_int(store_high, 4);
4483
4484         in[0] = store_low;
4485         in[1] = store_high;
4486         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
4487
4488         /* do a fild */
4489         fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4490
4491         set_ia32_use_frame(fild);
4492         set_ia32_op_type(fild, ia32_AddrModeS);
4493         set_ia32_ls_mode(fild, mode_Ls);
4494
4495         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4496
4497         return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4498 }
4499
4500 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4501         ir_node  *src_block  = get_nodes_block(node);
4502         ir_node  *block      = be_transform_node(src_block);
4503         ir_graph *irg        = current_ir_graph;
4504         dbg_info *dbgi       = get_irn_dbg_info(node);
4505         ir_node  *frame      = get_irg_frame(irg);
4506         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4507         ir_node  *nomem      = new_NoMem();
4508         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
4509         ir_node  *new_val    = be_transform_node(val);
4510         ir_node  *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4511
4512         ir_node  *fist;
4513
4514         /* do a fist */
4515         fist = new_rd_ia32_vfist(dbgi, irg, block, frame, noreg, nomem, new_val,
4516                                  trunc_mode);
4517         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4518         set_ia32_use_frame(fist);
4519         set_ia32_op_type(fist, ia32_AddrModeD);
4520         set_ia32_ls_mode(fist, mode_Ls);
4521
4522         return fist;
4523 }
4524
4525 /**
4526  * the BAD transformer.
4527  */
4528 static ir_node *bad_transform(ir_node *node) {
4529         panic("No transform function for %+F available.\n", node);
4530         return NULL;
4531 }
4532
4533 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4534         ir_graph *irg      = current_ir_graph;
4535         ir_node  *block    = be_transform_node(get_nodes_block(node));
4536         ir_node  *pred     = get_Proj_pred(node);
4537         ir_node  *new_pred = be_transform_node(pred);
4538         ir_node  *frame    = get_irg_frame(irg);
4539         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
4540         dbg_info *dbgi     = get_irn_dbg_info(node);
4541         long      pn       = get_Proj_proj(node);
4542         ir_node  *load;
4543         ir_node  *proj;
4544         ia32_attr_t *attr;
4545
4546         load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4547         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4548         set_ia32_use_frame(load);
4549         set_ia32_op_type(load, ia32_AddrModeS);
4550         set_ia32_ls_mode(load, mode_Iu);
4551         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4552          * 32 bit from it with this particular load */
4553         attr = get_ia32_attr(load);
4554         attr->data.need_64bit_stackent = 1;
4555
4556         if (pn == pn_ia32_l_FloattoLL_res_high) {
4557                 add_ia32_am_offs_int(load, 4);
4558         } else {
4559                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4560         }
4561
4562         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4563
4564         return proj;
4565 }
4566
4567 /**
4568  * Transform the Projs of an AddSP.
4569  */
4570 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4571         ir_node  *block    = be_transform_node(get_nodes_block(node));
4572         ir_node  *pred     = get_Proj_pred(node);
4573         ir_node  *new_pred = be_transform_node(pred);
4574         ir_graph *irg      = current_ir_graph;
4575         dbg_info *dbgi     = get_irn_dbg_info(node);
4576         long     proj      = get_Proj_proj(node);
4577
4578         if (proj == pn_be_AddSP_sp) {
4579                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4580                                            pn_ia32_SubSP_stack);
4581                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4582                 return res;
4583         } else if(proj == pn_be_AddSP_res) {
4584                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4585                                    pn_ia32_SubSP_addr);
4586         } else if (proj == pn_be_AddSP_M) {
4587                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4588         }
4589
4590         assert(0);
4591         return new_rd_Unknown(irg, get_irn_mode(node));
4592 }
4593
4594 /**
4595  * Transform the Projs of a SubSP.
4596  */
4597 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4598         ir_node  *block    = be_transform_node(get_nodes_block(node));
4599         ir_node  *pred     = get_Proj_pred(node);
4600         ir_node  *new_pred = be_transform_node(pred);
4601         ir_graph *irg      = current_ir_graph;
4602         dbg_info *dbgi     = get_irn_dbg_info(node);
4603         long     proj      = get_Proj_proj(node);
4604
4605         if (proj == pn_be_SubSP_sp) {
4606                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4607                                            pn_ia32_AddSP_stack);
4608                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4609                 return res;
4610         } else if (proj == pn_be_SubSP_M) {
4611                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4612         }
4613
4614         assert(0);
4615         return new_rd_Unknown(irg, get_irn_mode(node));
4616 }
4617
4618 /**
4619  * Transform and renumber the Projs from a Load.
4620  */
4621 static ir_node *gen_Proj_Load(ir_node *node) {
4622         ir_node  *new_pred;
4623         ir_node  *block    = be_transform_node(get_nodes_block(node));
4624         ir_node  *pred     = get_Proj_pred(node);
4625         ir_graph *irg      = current_ir_graph;
4626         dbg_info *dbgi     = get_irn_dbg_info(node);
4627         long     proj      = get_Proj_proj(node);
4628
4629
4630         /* loads might be part of source address mode matches, so we don't
4631            transform the ProjMs yet (with the exception of loads whose result is
4632            not used)
4633          */
4634         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4635                 ir_node *res;
4636
4637                 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4638                                                                                 nodes is 1 */
4639                 /* this is needed, because sometimes we have loops that are only
4640                    reachable through the ProjM */
4641                 be_enqueue_preds(node);
4642                 /* do it in 2 steps, to silence firm verifier */
4643                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4644                 set_Proj_proj(res, pn_ia32_Load_M);
4645                 return res;
4646         }
4647
4648         /* renumber the proj */
4649         new_pred = be_transform_node(pred);
4650         if (is_ia32_Load(new_pred)) {
4651                 switch (proj) {
4652                 case pn_Load_res:
4653                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4654                 case pn_Load_M:
4655                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4656                 case pn_Load_X_regular:
4657                         return new_rd_Jmp(dbgi, irg, block);
4658                 case pn_Load_X_except:
4659                         /* This Load might raise an exception. Mark it. */
4660                         set_ia32_exc_label(new_pred, 1);
4661                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4662                 default:
4663                         break;
4664                 }
4665         } else if (is_ia32_Conv_I2I(new_pred) ||
4666                    is_ia32_Conv_I2I8Bit(new_pred)) {
4667                 set_irn_mode(new_pred, mode_T);
4668                 if (proj == pn_Load_res) {
4669                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4670                 } else if (proj == pn_Load_M) {
4671                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4672                 }
4673         } else if (is_ia32_xLoad(new_pred)) {
4674                 switch (proj) {
4675                 case pn_Load_res:
4676                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4677                 case pn_Load_M:
4678                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4679                 case pn_Load_X_regular:
4680                         return new_rd_Jmp(dbgi, irg, block);
4681                 case pn_Load_X_except:
4682                         /* This Load might raise an exception. Mark it. */
4683                         set_ia32_exc_label(new_pred, 1);
4684                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4685                 default:
4686                         break;
4687                 }
4688         } else if (is_ia32_vfld(new_pred)) {
4689                 switch (proj) {
4690                 case pn_Load_res:
4691                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4692                 case pn_Load_M:
4693                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4694                 case pn_Load_X_regular:
4695                         return new_rd_Jmp(dbgi, irg, block);
4696                 case pn_Load_X_except:
4697                         /* This Load might raise an exception. Mark it. */
4698                         set_ia32_exc_label(new_pred, 1);
4699                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4700                 default:
4701                         break;
4702                 }
4703         } else {
4704                 /* can happen for ProJMs when source address mode happened for the
4705                    node */
4706
4707                 /* however it should not be the result proj, as that would mean the
4708                    load had multiple users and should not have been used for
4709                    SourceAM */
4710                 if (proj != pn_Load_M) {
4711                         panic("internal error: transformed node not a Load");
4712                 }
4713                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4714         }
4715
4716         assert(0);
4717         return new_rd_Unknown(irg, get_irn_mode(node));
4718 }
4719
4720 /**
4721  * Transform and renumber the Projs from a DivMod like instruction.
4722  */
4723 static ir_node *gen_Proj_DivMod(ir_node *node) {
4724         ir_node  *block    = be_transform_node(get_nodes_block(node));
4725         ir_node  *pred     = get_Proj_pred(node);
4726         ir_node  *new_pred = be_transform_node(pred);
4727         ir_graph *irg      = current_ir_graph;
4728         dbg_info *dbgi     = get_irn_dbg_info(node);
4729         ir_mode  *mode     = get_irn_mode(node);
4730         long     proj      = get_Proj_proj(node);
4731
4732         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4733
4734         switch (get_irn_opcode(pred)) {
4735         case iro_Div:
4736                 switch (proj) {
4737                 case pn_Div_M:
4738                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4739                 case pn_Div_res:
4740                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4741                 case pn_Div_X_regular:
4742                         return new_rd_Jmp(dbgi, irg, block);
4743                 case pn_Div_X_except:
4744                         set_ia32_exc_label(new_pred, 1);
4745                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4746                 default:
4747                         break;
4748                 }
4749                 break;
4750         case iro_Mod:
4751                 switch (proj) {
4752                 case pn_Mod_M:
4753                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4754                 case pn_Mod_res:
4755                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4756                 case pn_Mod_X_except:
4757                         set_ia32_exc_label(new_pred, 1);
4758                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4759                 default:
4760                         break;
4761                 }
4762                 break;
4763         case iro_DivMod:
4764                 switch (proj) {
4765                 case pn_DivMod_M:
4766                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4767                 case pn_DivMod_res_div:
4768                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4769                 case pn_DivMod_res_mod:
4770                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4771                 case pn_DivMod_X_regular:
4772                         return new_rd_Jmp(dbgi, irg, block);
4773                 case pn_DivMod_X_except:
4774                         set_ia32_exc_label(new_pred, 1);
4775                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4776                 default:
4777                         break;
4778                 }
4779                 break;
4780         default:
4781                 break;
4782         }
4783
4784         assert(0);
4785         return new_rd_Unknown(irg, mode);
4786 }
4787
4788 /**
4789  * Transform and renumber the Projs from a CopyB.
4790  */
4791 static ir_node *gen_Proj_CopyB(ir_node *node) {
4792         ir_node  *block    = be_transform_node(get_nodes_block(node));
4793         ir_node  *pred     = get_Proj_pred(node);
4794         ir_node  *new_pred = be_transform_node(pred);
4795         ir_graph *irg      = current_ir_graph;
4796         dbg_info *dbgi     = get_irn_dbg_info(node);
4797         ir_mode  *mode     = get_irn_mode(node);
4798         long     proj      = get_Proj_proj(node);
4799
4800         switch(proj) {
4801         case pn_CopyB_M_regular:
4802                 if (is_ia32_CopyB_i(new_pred)) {
4803                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4804                 } else if (is_ia32_CopyB(new_pred)) {
4805                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4806                 }
4807                 break;
4808         default:
4809                 break;
4810         }
4811
4812         assert(0);
4813         return new_rd_Unknown(irg, mode);
4814 }
4815
4816 /**
4817  * Transform and renumber the Projs from a Quot.
4818  */
4819 static ir_node *gen_Proj_Quot(ir_node *node) {
4820         ir_node  *block    = be_transform_node(get_nodes_block(node));
4821         ir_node  *pred     = get_Proj_pred(node);
4822         ir_node  *new_pred = be_transform_node(pred);
4823         ir_graph *irg      = current_ir_graph;
4824         dbg_info *dbgi     = get_irn_dbg_info(node);
4825         ir_mode  *mode     = get_irn_mode(node);
4826         long     proj      = get_Proj_proj(node);
4827
4828         switch(proj) {
4829         case pn_Quot_M:
4830                 if (is_ia32_xDiv(new_pred)) {
4831                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4832                 } else if (is_ia32_vfdiv(new_pred)) {
4833                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4834                 }
4835                 break;
4836         case pn_Quot_res:
4837                 if (is_ia32_xDiv(new_pred)) {
4838                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4839                 } else if (is_ia32_vfdiv(new_pred)) {
4840                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4841                 }
4842                 break;
4843         case pn_Quot_X_regular:
4844         case pn_Quot_X_except:
4845         default:
4846                 break;
4847         }
4848
4849         assert(0);
4850         return new_rd_Unknown(irg, mode);
4851 }
4852
4853 /**
4854  * Transform the Thread Local Storage Proj.
4855  */
4856 static ir_node *gen_Proj_tls(ir_node *node) {
4857         ir_node  *block = be_transform_node(get_nodes_block(node));
4858         ir_graph *irg   = current_ir_graph;
4859         dbg_info *dbgi  = NULL;
4860         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4861
4862         return res;
4863 }
4864
4865 static ir_node *gen_be_Call(ir_node *node) {
4866         ir_node *res = be_duplicate_node(node);
4867         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4868
4869         return res;
4870 }
4871
4872 static ir_node *gen_be_IncSP(ir_node *node) {
4873         ir_node *res = be_duplicate_node(node);
4874         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4875
4876         return res;
4877 }
4878
4879 /**
4880  * Transform the Projs from a be_Call.
4881  */
4882 static ir_node *gen_Proj_be_Call(ir_node *node) {
4883         ir_node  *block       = be_transform_node(get_nodes_block(node));
4884         ir_node  *call        = get_Proj_pred(node);
4885         ir_node  *new_call    = be_transform_node(call);
4886         ir_graph *irg         = current_ir_graph;
4887         dbg_info *dbgi        = get_irn_dbg_info(node);
4888         ir_type  *method_type = be_Call_get_type(call);
4889         int       n_res       = get_method_n_ress(method_type);
4890         long      proj        = get_Proj_proj(node);
4891         ir_mode  *mode        = get_irn_mode(node);
4892         ir_node  *sse_load;
4893         const arch_register_class_t *cls;
4894
4895         /* The following is kinda tricky: If we're using SSE, then we have to
4896          * move the result value of the call in floating point registers to an
4897          * xmm register, we therefore construct a GetST0 -> xLoad sequence
4898          * after the call, we have to make sure to correctly make the
4899          * MemProj and the result Proj use these 2 nodes
4900          */
4901         if (proj == pn_be_Call_M_regular) {
4902                 // get new node for result, are we doing the sse load/store hack?
4903                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4904                 ir_node *call_res_new;
4905                 ir_node *call_res_pred = NULL;
4906
4907                 if (call_res != NULL) {
4908                         call_res_new  = be_transform_node(call_res);
4909                         call_res_pred = get_Proj_pred(call_res_new);
4910                 }
4911
4912                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4913                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4914                                            pn_be_Call_M_regular);
4915                 } else {
4916                         assert(is_ia32_xLoad(call_res_pred));
4917                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4918                                            pn_ia32_xLoad_M);
4919                 }
4920         }
4921         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4922                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4923                 ir_node *fstp;
4924                 ir_node *frame = get_irg_frame(irg);
4925                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4926                 //ir_node *p;
4927                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4928                 ir_node *call_res;
4929
4930                 /* in case there is no memory output: create one to serialize the copy
4931                    FPU -> SSE */
4932                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4933                                        pn_be_Call_M_regular);
4934                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4935                                        pn_be_Call_first_res);
4936
4937                 /* store st(0) onto stack */
4938                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4939                                         call_res, mode);
4940                 set_ia32_op_type(fstp, ia32_AddrModeD);
4941                 set_ia32_use_frame(fstp);
4942
4943                 /* load into SSE register */
4944                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4945                                              mode);
4946                 set_ia32_op_type(sse_load, ia32_AddrModeS);
4947                 set_ia32_use_frame(sse_load);
4948
4949                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4950                                        pn_ia32_xLoad_res);
4951
4952                 return sse_load;
4953         }
4954
4955         /* transform call modes */
4956         if (mode_is_data(mode)) {
4957                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4958                 mode = cls->mode;
4959         }
4960
4961         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4962 }
4963
4964 /**
4965  * Transform the Projs from a Cmp.
4966  */
4967 static ir_node *gen_Proj_Cmp(ir_node *node)
4968 {
4969         /* this probably means not all mode_b nodes were lowered... */
4970         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4971               node);
4972 }
4973
4974 /**
4975  * Transform and potentially renumber Proj nodes.
4976  */
4977 static ir_node *gen_Proj(ir_node *node) {
4978         ir_node  *pred = get_Proj_pred(node);
4979         if (is_Store(pred)) {
4980                 long proj = get_Proj_proj(node);
4981                 if (proj == pn_Store_M) {
4982                         return be_transform_node(pred);
4983                 } else {
4984                         assert(0);
4985                         return new_r_Bad(current_ir_graph);
4986                 }
4987         } else if (is_Load(pred)) {
4988                 return gen_Proj_Load(node);
4989         } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
4990                 return gen_Proj_DivMod(node);
4991         } else if (is_CopyB(pred)) {
4992                 return gen_Proj_CopyB(node);
4993         } else if (is_Quot(pred)) {
4994                 return gen_Proj_Quot(node);
4995         } else if (be_is_SubSP(pred)) {
4996                 return gen_Proj_be_SubSP(node);
4997         } else if (be_is_AddSP(pred)) {
4998                 return gen_Proj_be_AddSP(node);
4999         } else if (be_is_Call(pred)) {
5000                 return gen_Proj_be_Call(node);
5001         } else if (is_Cmp(pred)) {
5002                 return gen_Proj_Cmp(node);
5003         } else if (get_irn_op(pred) == op_Start) {
5004                 long proj = get_Proj_proj(node);
5005                 if (proj == pn_Start_X_initial_exec) {
5006                         ir_node *block = get_nodes_block(pred);
5007                         dbg_info *dbgi = get_irn_dbg_info(node);
5008                         ir_node *jump;
5009
5010                         /* we exchange the ProjX with a jump */
5011                         block = be_transform_node(block);
5012                         jump  = new_rd_Jmp(dbgi, current_ir_graph, block);
5013                         return jump;
5014                 }
5015                 if (node == be_get_old_anchor(anchor_tls)) {
5016                         return gen_Proj_tls(node);
5017                 }
5018         } else if (is_ia32_l_FloattoLL(pred)) {
5019                 return gen_Proj_l_FloattoLL(node);
5020 #ifdef FIRM_EXT_GRS
5021         } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5022 #else
5023         } else {
5024 #endif
5025                 ir_mode *mode = get_irn_mode(node);
5026                 if (mode_needs_gp_reg(mode)) {
5027                         ir_node *new_pred = be_transform_node(pred);
5028                         ir_node *block    = be_transform_node(get_nodes_block(node));
5029                         ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5030                                                        mode_Iu, get_Proj_proj(node));
5031 #ifdef DEBUG_libfirm
5032                         new_proj->node_nr = node->node_nr;
5033 #endif
5034                         return new_proj;
5035                 }
5036         }
5037
5038         return be_duplicate_node(node);
5039 }
5040
5041 /**
5042  * Enters all transform functions into the generic pointer
5043  */
5044 static void register_transformers(void)
5045 {
5046         ir_op *op_Mulh;
5047
5048         /* first clear the generic function pointer for all ops */
5049         clear_irp_opcodes_generic_func();
5050
5051 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5052 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
5053
5054         GEN(Add);
5055         GEN(Sub);
5056         GEN(Mul);
5057         GEN(And);
5058         GEN(Or);
5059         GEN(Eor);
5060
5061         GEN(Shl);
5062         GEN(Shr);
5063         GEN(Shrs);
5064         GEN(Rot);
5065
5066         GEN(Quot);
5067
5068         GEN(Div);
5069         GEN(Mod);
5070         GEN(DivMod);
5071
5072         GEN(Minus);
5073         GEN(Conv);
5074         GEN(Abs);
5075         GEN(Not);
5076
5077         GEN(Load);
5078         GEN(Store);
5079         GEN(Cond);
5080
5081         GEN(Cmp);
5082         GEN(ASM);
5083         GEN(CopyB);
5084         BAD(Mux);
5085         GEN(Psi);
5086         GEN(Proj);
5087         GEN(Phi);
5088         GEN(IJmp);
5089
5090         /* transform ops from intrinsic lowering */
5091         GEN(ia32_l_Add);
5092         GEN(ia32_l_Adc);
5093         GEN(ia32_l_Mul);
5094         GEN(ia32_l_IMul);
5095         GEN(ia32_l_ShlDep);
5096         GEN(ia32_l_ShrDep);
5097         GEN(ia32_l_SarDep);
5098         GEN(ia32_l_ShlD);
5099         GEN(ia32_l_ShrD);
5100         GEN(ia32_l_Sub);
5101         GEN(ia32_l_Sbb);
5102         GEN(ia32_l_vfild);
5103         GEN(ia32_l_Load);
5104         GEN(ia32_l_vfist);
5105         GEN(ia32_l_Store);
5106         GEN(ia32_l_LLtoFloat);
5107         GEN(ia32_l_FloattoLL);
5108
5109         GEN(Const);
5110         GEN(SymConst);
5111         GEN(Unknown);
5112
5113         /* we should never see these nodes */
5114         BAD(Raise);
5115         BAD(Sel);
5116         BAD(InstOf);
5117         BAD(Cast);
5118         BAD(Free);
5119         BAD(Tuple);
5120         BAD(Id);
5121         //BAD(Bad);
5122         BAD(Confirm);
5123         BAD(Filter);
5124         BAD(CallBegin);
5125         BAD(EndReg);
5126         BAD(EndExcept);
5127
5128         /* handle generic backend nodes */
5129         GEN(be_FrameAddr);
5130         GEN(be_Call);
5131         GEN(be_IncSP);
5132         GEN(be_Return);
5133         GEN(be_AddSP);
5134         GEN(be_SubSP);
5135         GEN(be_Copy);
5136
5137         op_Mulh = get_op_Mulh();
5138         if (op_Mulh)
5139                 GEN(Mulh);
5140
5141 #undef GEN
5142 #undef BAD
5143 }
5144
5145 /**
5146  * Pre-transform all unknown and noreg nodes.
5147  */
5148 static void ia32_pretransform_node(void *arch_cg) {
5149         ia32_code_gen_t *cg = arch_cg;
5150
5151         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
5152         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5153         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5154         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
5155         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
5156         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
5157         get_fpcw();
5158 }
5159
5160 /**
5161  * Walker, checks if all ia32 nodes producing more than one result have
5162  * its Projs, other wise creates new projs and keep them using a be_Keep node.
5163  */
5164 static void add_missing_keep_walker(ir_node *node, void *data)
5165 {
5166         int              n_outs, i;
5167         unsigned         found_projs = 0;
5168         const ir_edge_t *edge;
5169         ir_mode         *mode = get_irn_mode(node);
5170         ir_node         *last_keep;
5171         (void) data;
5172         if(mode != mode_T)
5173                 return;
5174         if(!is_ia32_irn(node))
5175                 return;
5176
5177         n_outs = get_ia32_n_res(node);
5178         if(n_outs <= 0)
5179                 return;
5180         if(is_ia32_SwitchJmp(node))
5181                 return;
5182
5183         assert(n_outs < (int) sizeof(unsigned) * 8);
5184         foreach_out_edge(node, edge) {
5185                 ir_node *proj = get_edge_src_irn(edge);
5186                 int      pn   = get_Proj_proj(proj);
5187
5188                 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5189                 found_projs |= 1 << pn;
5190         }
5191
5192
5193         /* are keeps missing? */
5194         last_keep = NULL;
5195         for(i = 0; i < n_outs; ++i) {
5196                 ir_node                     *block;
5197                 ir_node                     *in[1];
5198                 const arch_register_req_t   *req;
5199                 const arch_register_class_t *class;
5200
5201                 if(found_projs & (1 << i)) {
5202                         continue;
5203                 }
5204
5205                 req   = get_ia32_out_req(node, i);
5206                 class = req->cls;
5207                 if(class == NULL) {
5208                         continue;
5209                 }
5210                 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
5211                         continue;
5212                 }
5213
5214                 block = get_nodes_block(node);
5215                 in[0] = new_r_Proj(current_ir_graph, block, node,
5216                                    arch_register_class_mode(class), i);
5217                 if(last_keep != NULL) {
5218                         be_Keep_add_node(last_keep, class, in[0]);
5219                 } else {
5220                         last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
5221                         if(sched_is_scheduled(node)) {
5222                                 sched_add_after(node, last_keep);
5223                         }
5224                 }
5225         }
5226 }
5227
5228 /**
5229  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5230  * and keeps them.
5231  */
5232 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5233 {
5234         ir_graph *irg = be_get_birg_irg(cg->birg);
5235         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5236 }
5237
5238 /* do the transformation */
5239 void ia32_transform_graph(ia32_code_gen_t *cg) {
5240         int cse_last;
5241         ir_graph *irg = cg->irg;
5242
5243         register_transformers();
5244         env_cg       = cg;
5245         initial_fpcw = NULL;
5246
5247 BE_TIMER_PUSH(t_heights);
5248         heights      = heights_new(irg);
5249 BE_TIMER_POP(t_heights);
5250         ia32_calculate_non_address_mode_nodes(cg->birg);
5251
5252         /* the transform phase is not safe for CSE (yet) because several nodes get
5253          * attributes set after their creation */
5254         cse_last = get_opt_cse();
5255         set_opt_cse(0);
5256
5257         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5258
5259         set_opt_cse(cse_last);
5260
5261         ia32_free_non_address_mode_nodes();
5262         heights_free(heights);
5263         heights = NULL;
5264 }
5265
5266 void ia32_init_transform(void)
5267 {
5268         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
5269 }