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