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