fix/improve proj generation
[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 bool check_immediate_constraint(long val, char immediate_constraint_type)
3501 {
3502         switch (immediate_constraint_type) {
3503         case 0:
3504         case 'i':
3505                 return true;
3506         case 'I':
3507                 return val >= 0 && val <= 32;
3508         case 'J':
3509                 return val >= 0 && val <= 63;
3510         case 'K':
3511                 return val >= -128 && val <= 127;
3512         case 'L':
3513                 return val == 0xff || val == 0xffff;
3514         case 'M':
3515                 return val >= 0 && val <= 3;
3516         case 'N':
3517                 return val >= 0 && val <= 255;
3518         case 'O':
3519                 return val >= 0 && val <= 127;
3520         default:
3521                 break;
3522         }
3523         panic("Invalid immediate constraint found");
3524         return false;
3525 }
3526
3527 static ir_node *try_create_Immediate(ir_node *node,
3528                                      char immediate_constraint_type)
3529 {
3530         int          minus         = 0;
3531         tarval      *offset        = NULL;
3532         int          offset_sign   = 0;
3533         long         val = 0;
3534         ir_entity   *symconst_ent  = NULL;
3535         int          symconst_sign = 0;
3536         ir_mode     *mode;
3537         ir_node     *cnst          = NULL;
3538         ir_node     *symconst      = NULL;
3539         ir_node     *new_node;
3540
3541         mode = get_irn_mode(node);
3542         if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3543                 return NULL;
3544         }
3545
3546         if(is_Minus(node)) {
3547                 minus = 1;
3548                 node  = get_Minus_op(node);
3549         }
3550
3551         if(is_Const(node)) {
3552                 cnst        = node;
3553                 symconst    = NULL;
3554                 offset_sign = minus;
3555         } else if(is_SymConst(node)) {
3556                 cnst          = NULL;
3557                 symconst      = node;
3558                 symconst_sign = minus;
3559         } else if(is_Add(node)) {
3560                 ir_node *left  = get_Add_left(node);
3561                 ir_node *right = get_Add_right(node);
3562                 if(is_Const(left) && is_SymConst(right)) {
3563                         cnst          = left;
3564                         symconst      = right;
3565                         symconst_sign = minus;
3566                         offset_sign   = minus;
3567                 } else if(is_SymConst(left) && is_Const(right)) {
3568                         cnst          = right;
3569                         symconst      = left;
3570                         symconst_sign = minus;
3571                         offset_sign   = minus;
3572                 }
3573         } else if(is_Sub(node)) {
3574                 ir_node *left  = get_Sub_left(node);
3575                 ir_node *right = get_Sub_right(node);
3576                 if(is_Const(left) && is_SymConst(right)) {
3577                         cnst          = left;
3578                         symconst      = right;
3579                         symconst_sign = !minus;
3580                         offset_sign   = minus;
3581                 } else if(is_SymConst(left) && is_Const(right)) {
3582                         cnst          = right;
3583                         symconst      = left;
3584                         symconst_sign = minus;
3585                         offset_sign   = !minus;
3586                 }
3587         } else {
3588                 return NULL;
3589         }
3590
3591         if(cnst != NULL) {
3592                 offset = get_Const_tarval(cnst);
3593                 if(tarval_is_long(offset)) {
3594                         val = get_tarval_long(offset);
3595                 } else {
3596                         ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3597                                    "long?\n", cnst);
3598                         return NULL;
3599                 }
3600
3601                 if(!check_immediate_constraint(val, immediate_constraint_type))
3602                         return NULL;
3603         }
3604         if(symconst != NULL) {
3605                 if(immediate_constraint_type != 0) {
3606                         /* we need full 32bits for symconsts */
3607                         return NULL;
3608                 }
3609
3610                 /* unfortunately the assembler/linker doesn't support -symconst */
3611                 if(symconst_sign)
3612                         return NULL;
3613
3614                 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3615                         return NULL;
3616                 symconst_ent = get_SymConst_entity(symconst);
3617         }
3618         if(cnst == NULL && symconst == NULL)
3619                 return NULL;
3620
3621         if(offset_sign && offset != NULL) {
3622                 offset = tarval_neg(offset);
3623         }
3624
3625         new_node = create_Immediate(symconst_ent, symconst_sign, val);
3626
3627         return new_node;
3628 }
3629
3630 static ir_node *create_immediate_or_transform(ir_node *node,
3631                                               char immediate_constraint_type)
3632 {
3633         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3634         if (new_node == NULL) {
3635                 new_node = be_transform_node(node);
3636         }
3637         return new_node;
3638 }
3639
3640
3641
3642 void parse_asm_constraints(constraint_t *constraint, const char *c,
3643                            bool is_output)
3644 {
3645         asm_constraint_flags_t       flags              = 0;
3646         char                         immediate_type     = '\0';
3647         unsigned                     limited            = 0;
3648         const arch_register_class_t *cls                = NULL;
3649         bool                         memory_possible       = false;
3650         bool                         all_registers_allowed = false;
3651         int                          p;
3652         int                          same_as = -1;
3653
3654         memset(constraint, 0, sizeof(constraint[0]));
3655         constraint->same_as = -1;
3656
3657         if(*c == 0) {
3658                 /* a memory constraint: no need to do anything in backend about it
3659                  * (the dependencies are already respected by the memory edge of
3660                  * the node) */
3661                 return;
3662         }
3663
3664         /* TODO: improve error messages with node and source info. (As users can
3665          * easily hit these) */
3666         while(*c != 0) {
3667                 switch(*c) {
3668                 case ' ':
3669                 case '\t':
3670                 case '\n':
3671                         break;
3672
3673                 case '=':
3674                         flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
3675                                 | ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ;
3676                         break;
3677
3678                 case '+':
3679                         flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
3680                                 | ASM_CONSTRAINT_FLAG_MODIFIER_READ;
3681                         break;
3682
3683                 case '*':
3684                         ++c;
3685                         break;
3686                 case '#':
3687                         while(*c != 0 && *c != ',')
3688                                 ++c;
3689                         break;
3690
3691                 case 'a':
3692                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3693                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3694                         limited |= 1 << REG_EAX;
3695                         break;
3696                 case 'b':
3697                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3698                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3699                         limited |= 1 << REG_EBX;
3700                         break;
3701                 case 'c':
3702                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3703                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3704                         limited |= 1 << REG_ECX;
3705                         break;
3706                 case 'd':
3707                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3708                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3709                         limited |= 1 << REG_EDX;
3710                         break;
3711                 case 'D':
3712                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3713                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3714                         limited |= 1 << REG_EDI;
3715                         break;
3716                 case 'S':
3717                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3718                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3719                         limited |= 1 << REG_ESI;
3720                         break;
3721                 case 'Q':
3722                 case 'q':
3723                         /* q means lower part of the regs only, this makes no
3724                          * difference to Q for us (we only assign whole registers) */
3725                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3726                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3727                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3728                                    1 << REG_EDX;
3729                         break;
3730                 case 'A':
3731                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3732                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3733                         limited |= 1 << REG_EAX | 1 << REG_EDX;
3734                         break;
3735                 case 'l':
3736                         assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3737                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3738                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3739                                    1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3740                                    1 << REG_EBP;
3741                         break;
3742
3743                 case 'R':
3744                 case 'r':
3745                 case 'p':
3746                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3747                                 panic("multiple register classes not supported");
3748                         cls                   = &ia32_reg_classes[CLASS_ia32_gp];
3749                         all_registers_allowed = true;
3750                         break;
3751
3752                 case 'f':
3753                 case 't':
3754                 case 'u':
3755                         /* TODO: mark values so the x87 simulator knows about t and u */
3756                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_vfp])
3757                                 panic("multiple register classes not supported");
3758                         cls                   = &ia32_reg_classes[CLASS_ia32_vfp];
3759                         all_registers_allowed = true;
3760                         break;
3761
3762                 case 'Y':
3763                 case 'x':
3764                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_xmm])
3765                                 panic("multiple register classes not supproted");
3766                         cls                   = &ia32_reg_classes[CLASS_ia32_xmm];
3767                         all_registers_allowed = true;
3768                         break;
3769
3770                 case 'I':
3771                 case 'J':
3772                 case 'K':
3773                 case 'L':
3774                 case 'M':
3775                 case 'N':
3776                 case 'O':
3777                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3778                                 panic("multiple register classes not supported");
3779                         if (immediate_type != '\0')
3780                                 panic("multiple immediate types not supported");
3781                         cls            = &ia32_reg_classes[CLASS_ia32_gp];
3782                         immediate_type = *c;
3783                         break;
3784                 case 'n':
3785                 case 'i':
3786                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3787                                 panic("multiple register classes not supported");
3788                         if (immediate_type != '\0')
3789                                 panic("multiple immediate types not supported");
3790                         cls            = &ia32_reg_classes[CLASS_ia32_gp];
3791                         immediate_type = 'i';
3792                         break;
3793
3794                 case 'X':
3795                 case 'g':
3796                         if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3797                                 panic("multiple register classes not supported");
3798                         if (immediate_type != '\0')
3799                                 panic("multiple immediate types not supported");
3800                         immediate_type        = 'i';
3801                         cls                   = &ia32_reg_classes[CLASS_ia32_gp];
3802                         all_registers_allowed = true;
3803                         memory_possible       = true;
3804                         break;
3805
3806                 case '0':
3807                 case '1':
3808                 case '2':
3809                 case '3':
3810                 case '4':
3811                 case '5':
3812                 case '6':
3813                 case '7':
3814                 case '8':
3815                 case '9':
3816                         if (is_output)
3817                                 panic("can only specify same constraint on input");
3818
3819                         sscanf(c, "%d%n", &same_as, &p);
3820                         if(same_as >= 0) {
3821                                 c += p;
3822                                 continue;
3823                         }
3824                         break;
3825
3826                 case 'm':
3827                 case 'o':
3828                 case 'V':
3829                         /* memory constraint no need to do anything in backend about it
3830                          * (the dependencies are already respected by the memory edge of
3831                          * the node) */
3832                         memory_possible = true;
3833                         break;
3834
3835                 case 'E': /* no float consts yet */
3836                 case 'F': /* no float consts yet */
3837                 case 's': /* makes no sense on x86 */
3838                 case '<': /* no autodecrement on x86 */
3839                 case '>': /* no autoincrement on x86 */
3840                 case 'C': /* sse constant not supported yet */
3841                 case 'G': /* 80387 constant not supported yet */
3842                 case 'y': /* we don't support mmx registers yet */
3843                 case 'Z': /* not available in 32 bit mode */
3844                 case 'e': /* not available in 32 bit mode */
3845                         panic("unsupported asm constraint '%c' found in (%+F)",
3846                               *c, current_ir_graph);
3847                         break;
3848                 default:
3849                         panic("unknown asm constraint '%c' found in (%+F)", *c,
3850                               current_ir_graph);
3851                         break;
3852                 }
3853                 ++c;
3854         }
3855
3856         if(same_as >= 0) {
3857                 if (cls != NULL)
3858                         panic("same as and register constraint not supported");
3859                 if (immediate_type != '\0')
3860                         panic("same as and immediate constraint not supported");
3861         }
3862
3863         if (cls == NULL && same_as < 0) {
3864                 if (!memory_possible)
3865                         panic("no constraint specified for assembler input");
3866         }
3867
3868         constraint->same_as               = same_as;
3869         constraint->cls                   = cls;
3870         constraint->allowed_registers     = limited;
3871         constraint->all_registers_allowed = all_registers_allowed;
3872         constraint->memory_possible       = memory_possible;
3873         constraint->immediate_type        = immediate_type;
3874 }
3875
3876 const arch_register_req_t *make_register_req(const constraint_t *constraint,
3877                 int n_outs, const arch_register_req_t **out_reqs, int pos)
3878 {
3879         struct obstack      *obst    = get_irg_obstack(current_ir_graph);
3880         int                  same_as = constraint->same_as;
3881         arch_register_req_t *req;
3882
3883         if (same_as >= 0) {
3884                 const arch_register_req_t *other_constr;
3885
3886                 if (same_as >= n_outs)
3887                         panic("invalid output number in same_as constraint");
3888
3889                 other_constr         = out_reqs[same_as];
3890
3891                 req                  = obstack_alloc(obst, sizeof(req[0]));
3892                 req->cls             = other_constr->cls;
3893                 req->type            = arch_register_req_type_should_be_same;
3894                 req->limited         = NULL;
3895                 req->other_same      = 1U << pos;
3896                 req->other_different = 0;
3897
3898                 /* switch constraints. This is because in firm we have same_as
3899                  * constraints on the output constraints while in the gcc asm syntax
3900                  * they are specified on the input constraints */
3901                 out_reqs[same_as] = req;
3902                 return other_constr;
3903         }
3904
3905         /* pure memory ops */
3906         if (constraint->cls == NULL) {
3907                 return &no_register_req;
3908         }
3909
3910         if (constraint->allowed_registers != 0
3911                         && !constraint->all_registers_allowed) {
3912                 unsigned *limited_ptr;
3913
3914                 req         = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3915                 memset(req, 0, sizeof(req[0]));
3916                 limited_ptr = (unsigned*) (req+1);
3917
3918                 req->type    = arch_register_req_type_limited;
3919                 *limited_ptr = constraint->allowed_registers;
3920                 req->limited = limited_ptr;
3921         } else {
3922                 req       = obstack_alloc(obst, sizeof(req[0]));
3923                 memset(req, 0, sizeof(req[0]));
3924                 req->type = arch_register_req_type_normal;
3925         }
3926         req->cls = constraint->cls;
3927
3928         return req;
3929 }
3930
3931 const arch_register_t *ia32_get_clobber_register(const char *clobber)
3932 {
3933         const arch_register_t       *reg = NULL;
3934         int                          c;
3935         size_t                       r;
3936         const arch_register_class_t *cls;
3937
3938         /* TODO: construct a hashmap instead of doing linear search for clobber
3939          * register */
3940         for(c = 0; c < N_CLASSES; ++c) {
3941                 cls = & ia32_reg_classes[c];
3942                 for(r = 0; r < cls->n_regs; ++r) {
3943                         const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3944                         if(strcmp(temp_reg->name, clobber) == 0
3945                                         || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3946                                 reg = temp_reg;
3947                                 break;
3948                         }
3949                 }
3950                 if(reg != NULL)
3951                         break;
3952         }
3953
3954         return reg;
3955 }
3956
3957 const arch_register_req_t *parse_clobber(const char *clobber)
3958 {
3959         struct obstack        *obst = get_irg_obstack(current_ir_graph);
3960         const arch_register_t *reg  = ia32_get_clobber_register(clobber);
3961         arch_register_req_t   *req;
3962         unsigned              *limited;
3963
3964         if(reg == NULL) {
3965                 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3966         }
3967
3968         assert(reg->index < 32);
3969
3970         limited  = obstack_alloc(obst, sizeof(limited[0]));
3971         *limited = 1 << reg->index;
3972
3973         req          = obstack_alloc(obst, sizeof(req[0]));
3974         memset(req, 0, sizeof(req[0]));
3975         req->type    = arch_register_req_type_limited;
3976         req->cls     = arch_register_get_class(reg);
3977         req->limited = limited;
3978
3979         return req;
3980 }
3981
3982 /**
3983  * generates code for a ASM node
3984  */
3985 static ir_node *gen_ASM(ir_node *node)
3986 {
3987         ir_graph                   *irg       = current_ir_graph;
3988         ir_node                    *block     = get_nodes_block(node);
3989         ir_node                    *new_block = be_transform_node(block);
3990         dbg_info                   *dbgi      = get_irn_dbg_info(node);
3991         int                         i, arity;
3992         int                         out_idx;
3993         ir_node                   **in;
3994         ir_node                    *new_node;
3995         int                         out_arity;
3996         int                         n_out_constraints;
3997         int                         n_clobbers;
3998         const arch_register_req_t **out_reg_reqs;
3999         const arch_register_req_t **in_reg_reqs;
4000         ia32_asm_reg_t             *register_map;
4001         unsigned                    reg_map_size = 0;
4002         struct obstack             *obst;
4003         const ir_asm_constraint    *in_constraints;
4004         const ir_asm_constraint    *out_constraints;
4005         ident                     **clobbers;
4006         bool                        clobbers_flags = false;
4007
4008         /* workaround for lots of buggy code out there as most people think volatile
4009          * asm is enough for everything and forget the flags (linux kernel, etc.)
4010          */
4011         if (get_irn_pinned(node) == op_pin_state_pinned) {
4012                 clobbers_flags = true;
4013         }
4014
4015         arity = get_irn_arity(node);
4016         in    = alloca(arity * sizeof(in[0]));
4017         memset(in, 0, arity * sizeof(in[0]));
4018
4019         clobbers   = get_ASM_clobbers(node);
4020         n_clobbers = 0;
4021         for(i = 0; i < get_ASM_n_clobbers(node); ++i) {
4022                 const char *c = get_id_str(clobbers[i]);
4023                 if (strcmp(c, "memory") == 0)
4024                         continue;
4025                 if (strcmp(c, "cc") == 0) {
4026                         clobbers_flags = true;
4027                         continue;
4028                 }
4029                 n_clobbers++;
4030         }
4031         n_out_constraints = get_ASM_n_output_constraints(node);
4032         out_arity         = n_out_constraints + n_clobbers;
4033
4034         in_constraints  = get_ASM_input_constraints(node);
4035         out_constraints = get_ASM_output_constraints(node);
4036
4037         /* determine size of register_map */
4038         for(out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
4039                 const ir_asm_constraint *constraint = &out_constraints[out_idx];
4040                 if (constraint->pos > reg_map_size)
4041                         reg_map_size = constraint->pos;
4042         }
4043         for(i = 0; i < arity; ++i) {
4044                 const ir_asm_constraint   *constraint = &in_constraints[i];
4045                 if(constraint->pos > reg_map_size)
4046                         reg_map_size = constraint->pos;
4047         }
4048         ++reg_map_size;
4049
4050         obst         = get_irg_obstack(irg);
4051         register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
4052         memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
4053
4054         /* construct output constraints */
4055         out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
4056
4057         for(out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
4058                 const ir_asm_constraint   *constraint = &out_constraints[out_idx];
4059                 const char                *c       = get_id_str(constraint->constraint);
4060                 unsigned                   pos        = constraint->pos;
4061                 constraint_t               parsed_constraint;
4062                 const arch_register_req_t *req;
4063
4064                 parse_asm_constraints(&parsed_constraint, c, true);
4065                 req = make_register_req(&parsed_constraint, n_out_constraints,
4066                                         out_reg_reqs, out_idx);
4067                 out_reg_reqs[out_idx] = req;
4068
4069                 register_map[pos].use_input = false;
4070                 register_map[pos].valid     = true;
4071                 register_map[pos].memory    = false;
4072                 register_map[pos].inout_pos = out_idx;
4073                 register_map[pos].mode      = constraint->mode;
4074         }
4075
4076         /* inputs + input constraints */
4077         in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
4078         for(i = 0; i < arity; ++i) {
4079                 ir_node                   *pred         = get_irn_n(node, i);
4080                 const ir_asm_constraint   *constraint   = &in_constraints[i];
4081                 ident                     *constr_id    = constraint->constraint;
4082                 const char                *c            = get_id_str(constr_id);
4083                 unsigned                   pos          = constraint->pos;
4084                 bool                       is_memory_op = false;
4085                 ir_node                   *input        = NULL;
4086                 constraint_t               parsed_constraint;
4087                 const arch_register_req_t *req;
4088
4089                 parse_asm_constraints(&parsed_constraint, c, false);
4090                 req = make_register_req(&parsed_constraint, n_out_constraints,
4091                                         out_reg_reqs, i);
4092                 in_reg_reqs[i] = req;
4093
4094                 if (parsed_constraint.immediate_type != '\0') {
4095                         char imm_type = parsed_constraint.immediate_type;
4096                         input = try_create_Immediate(pred, imm_type);
4097                 }
4098
4099                 if (input == NULL) {
4100                         ir_node *pred = get_irn_n(node, i);
4101                         input         = be_transform_node(pred);
4102
4103                         if (parsed_constraint.cls == NULL
4104                                         && parsed_constraint.same_as < 0) {
4105                                 is_memory_op = true;
4106                         } else if(parsed_constraint.memory_possible) {
4107                                 /* TODO: match Load or Load/Store if memory possible is set */
4108                         }
4109                 }
4110                 in[i] = input;
4111
4112                 register_map[pos].use_input = true;
4113                 register_map[pos].valid     = true;
4114                 register_map[pos].memory    = is_memory_op;
4115                 register_map[pos].inout_pos = i;
4116                 register_map[pos].mode      = constraint->mode;
4117         }
4118
4119         /* parse clobbers */
4120         for(i = 0; i < get_ASM_n_clobbers(node); ++i) {
4121                 const char                *c = get_id_str(clobbers[i]);
4122                 const arch_register_req_t *req;
4123
4124                 if (strcmp(c, "memory") == 0 || strcmp(c, "cc") == 0)
4125                         continue;
4126
4127                 req = parse_clobber(c);
4128                 out_reg_reqs[out_idx] = req;
4129                 ++out_idx;
4130         }
4131
4132         new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4133                                    get_ASM_text(node), register_map);
4134
4135         set_ia32_out_req_all(new_node, out_reg_reqs);
4136         set_ia32_in_req_all(new_node, in_reg_reqs);
4137
4138         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4139
4140         return new_node;
4141 }
4142
4143 /**
4144  * Transforms a FrameAddr into an ia32 Add.
4145  */
4146 static ir_node *gen_be_FrameAddr(ir_node *node) {
4147         ir_node  *block  = be_transform_node(get_nodes_block(node));
4148         ir_node  *op     = be_get_FrameAddr_frame(node);
4149         ir_node  *new_op = be_transform_node(op);
4150         ir_graph *irg    = current_ir_graph;
4151         dbg_info *dbgi   = get_irn_dbg_info(node);
4152         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
4153         ir_node  *new_node;
4154
4155         new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4156         set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4157         set_ia32_use_frame(new_node);
4158
4159         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4160
4161         return new_node;
4162 }
4163
4164 /**
4165  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4166  */
4167 static ir_node *gen_be_Return(ir_node *node) {
4168         ir_graph  *irg     = current_ir_graph;
4169         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
4170         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
4171         ir_entity *ent     = get_irg_entity(irg);
4172         ir_type   *tp      = get_entity_type(ent);
4173         dbg_info  *dbgi;
4174         ir_node   *block;
4175         ir_type   *res_type;
4176         ir_mode   *mode;
4177         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
4178         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
4179         ir_node   *noreg;
4180         ir_node   **in;
4181         int       pn_ret_val, pn_ret_mem, arity, i;
4182
4183         assert(ret_val != NULL);
4184         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4185                 return be_duplicate_node(node);
4186         }
4187
4188         res_type = get_method_res_type(tp, 0);
4189
4190         if (! is_Primitive_type(res_type)) {
4191                 return be_duplicate_node(node);
4192         }
4193
4194         mode = get_type_mode(res_type);
4195         if (! mode_is_float(mode)) {
4196                 return be_duplicate_node(node);
4197         }
4198
4199         assert(get_method_n_ress(tp) == 1);
4200
4201         pn_ret_val = get_Proj_proj(ret_val);
4202         pn_ret_mem = get_Proj_proj(ret_mem);
4203
4204         /* get the Barrier */
4205         barrier = get_Proj_pred(ret_val);
4206
4207         /* get result input of the Barrier */
4208         ret_val     = get_irn_n(barrier, pn_ret_val);
4209         new_ret_val = be_transform_node(ret_val);
4210
4211         /* get memory input of the Barrier */
4212         ret_mem     = get_irn_n(barrier, pn_ret_mem);
4213         new_ret_mem = be_transform_node(ret_mem);
4214
4215         frame = get_irg_frame(irg);
4216
4217         dbgi  = get_irn_dbg_info(barrier);
4218         block = be_transform_node(get_nodes_block(barrier));
4219
4220         noreg = ia32_new_NoReg_gp(env_cg);
4221
4222         /* store xmm0 onto stack */
4223         sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4224                                              new_ret_mem, new_ret_val);
4225         set_ia32_ls_mode(sse_store, mode);
4226         set_ia32_op_type(sse_store, ia32_AddrModeD);
4227         set_ia32_use_frame(sse_store);
4228
4229         /* load into x87 register */
4230         fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4231         set_ia32_op_type(fld, ia32_AddrModeS);
4232         set_ia32_use_frame(fld);
4233
4234         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4235         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4236
4237         /* create a new barrier */
4238         arity = get_irn_arity(barrier);
4239         in = alloca(arity * sizeof(in[0]));
4240         for (i = 0; i < arity; ++i) {
4241                 ir_node *new_in;
4242
4243                 if (i == pn_ret_val) {
4244                         new_in = fld;
4245                 } else if (i == pn_ret_mem) {
4246                         new_in = mproj;
4247                 } else {
4248                         ir_node *in = get_irn_n(barrier, i);
4249                         new_in = be_transform_node(in);
4250                 }
4251                 in[i] = new_in;
4252         }
4253
4254         new_barrier = new_ir_node(dbgi, irg, block,
4255                                   get_irn_op(barrier), get_irn_mode(barrier),
4256                                   arity, in);
4257         copy_node_attr(barrier, new_barrier);
4258         be_duplicate_deps(barrier, new_barrier);
4259         be_set_transformed_node(barrier, new_barrier);
4260         mark_irn_visited(barrier);
4261
4262         /* transform normally */
4263         return be_duplicate_node(node);
4264 }
4265
4266 /**
4267  * Transform a be_AddSP into an ia32_SubSP.
4268  */
4269 static ir_node *gen_be_AddSP(ir_node *node)
4270 {
4271         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
4272         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4273
4274         return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4275 }
4276
4277 /**
4278  * Transform a be_SubSP into an ia32_AddSP
4279  */
4280 static ir_node *gen_be_SubSP(ir_node *node)
4281 {
4282         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
4283         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4284
4285         return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4286 }
4287
4288 /**
4289  * This function just sets the register for the Unknown node
4290  * as this is not done during register allocation because Unknown
4291  * is an "ignore" node.
4292  */
4293 static ir_node *gen_Unknown(ir_node *node) {
4294         ir_mode *mode = get_irn_mode(node);
4295
4296         if (mode_is_float(mode)) {
4297                 if (ia32_cg_config.use_sse2) {
4298                         return ia32_new_Unknown_xmm(env_cg);
4299                 } else {
4300                         /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4301                         ir_graph *irg   = current_ir_graph;
4302                         dbg_info *dbgi  = get_irn_dbg_info(node);
4303                         ir_node  *block = get_irg_start_block(irg);
4304                         ir_node  *ret   = new_rd_ia32_vfldz(dbgi, irg, block);
4305
4306                         /* Const Nodes before the initial IncSP are a bad idea, because
4307                          * they could be spilled and we have no SP ready at that point yet.
4308                          * So add a dependency to the initial frame pointer calculation to
4309                          * avoid that situation.
4310                          */
4311                         add_irn_dep(ret, get_irg_frame(irg));
4312                         return ret;
4313                 }
4314         } else if (ia32_mode_needs_gp_reg(mode)) {
4315                 return ia32_new_Unknown_gp(env_cg);
4316         } else {
4317                 panic("unsupported Unknown-Mode");
4318         }
4319         return NULL;
4320 }
4321
4322 /**
4323  * Change some phi modes
4324  */
4325 static ir_node *gen_Phi(ir_node *node) {
4326         ir_node  *block = be_transform_node(get_nodes_block(node));
4327         ir_graph *irg   = current_ir_graph;
4328         dbg_info *dbgi  = get_irn_dbg_info(node);
4329         ir_mode  *mode  = get_irn_mode(node);
4330         ir_node  *phi;
4331
4332         if(ia32_mode_needs_gp_reg(mode)) {
4333                 /* we shouldn't have any 64bit stuff around anymore */
4334                 assert(get_mode_size_bits(mode) <= 32);
4335                 /* all integer operations are on 32bit registers now */
4336                 mode = mode_Iu;
4337         } else if(mode_is_float(mode)) {
4338                 if (ia32_cg_config.use_sse2) {
4339                         mode = mode_xmm;
4340                 } else {
4341                         mode = mode_vfp;
4342                 }
4343         }
4344
4345         /* phi nodes allow loops, so we use the old arguments for now
4346          * and fix this later */
4347         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4348                           get_irn_in(node) + 1);
4349         copy_node_attr(node, phi);
4350         be_duplicate_deps(node, phi);
4351
4352         be_set_transformed_node(node, phi);
4353         be_enqueue_preds(node);
4354
4355         return phi;
4356 }
4357
4358 /**
4359  * Transform IJmp
4360  */
4361 static ir_node *gen_IJmp(ir_node *node)
4362 {
4363         ir_node  *block     = get_nodes_block(node);
4364         ir_node  *new_block = be_transform_node(block);
4365         dbg_info *dbgi      = get_irn_dbg_info(node);
4366         ir_node  *op        = get_IJmp_target(node);
4367         ir_node  *new_node;
4368         ia32_address_mode_t  am;
4369         ia32_address_t      *addr = &am.addr;
4370
4371         assert(get_irn_mode(op) == mode_P);
4372
4373         match_arguments(&am, block, NULL, op, NULL,
4374                         match_am | match_8bit_am | match_16bit_am |
4375                         match_immediate | match_8bit | match_16bit);
4376
4377         new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
4378                                     addr->base, addr->index, addr->mem,
4379                                     am.new_op2);
4380         set_am_attributes(new_node, &am);
4381         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4382
4383         new_node = fix_mem_proj(new_node, &am);
4384
4385         return new_node;
4386 }
4387
4388 /**
4389  * Transform a Bound node.
4390  */
4391 static ir_node *gen_Bound(ir_node *node)
4392 {
4393         ir_node  *new_node;
4394         ir_node  *lower = get_Bound_lower(node);
4395         dbg_info *dbgi  = get_irn_dbg_info(node);
4396
4397         if (is_Const_0(lower)) {
4398                 /* typical case for Java */
4399                 ir_node  *sub, *res, *flags, *block;
4400                 ir_graph *irg  = current_ir_graph;
4401
4402                 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
4403                         new_rd_ia32_Sub, match_mode_neutral     | match_am | match_immediate);
4404
4405                 block = get_nodes_block(res);
4406                 if (! is_Proj(res)) {
4407                         sub = res;
4408                         set_irn_mode(sub, mode_T);
4409                         res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
4410                 } else {
4411                         sub = get_Proj_pred(res);
4412                 }
4413                 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
4414                 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
4415                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4416         } else {
4417                 panic("generic Bound not supported in ia32 Backend");
4418         }
4419         return new_node;
4420 }
4421
4422
4423 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4424                                      ir_node *mem);
4425
4426 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4427                                       ir_node *val, ir_node *mem);
4428
4429 /**
4430  * Transforms a lowered Load into a "real" one.
4431  */
4432 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4433 {
4434         ir_node  *block   = be_transform_node(get_nodes_block(node));
4435         ir_node  *ptr     = get_irn_n(node, 0);
4436         ir_node  *new_ptr = be_transform_node(ptr);
4437         ir_node  *mem     = get_irn_n(node, 1);
4438         ir_node  *new_mem = be_transform_node(mem);
4439         ir_graph *irg     = current_ir_graph;
4440         dbg_info *dbgi    = get_irn_dbg_info(node);
4441         ir_mode  *mode    = get_ia32_ls_mode(node);
4442         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4443         ir_node  *new_op;
4444
4445         new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4446
4447         set_ia32_op_type(new_op, ia32_AddrModeS);
4448         set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4449         set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4450         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4451         if (is_ia32_am_sc_sign(node))
4452                 set_ia32_am_sc_sign(new_op);
4453         set_ia32_ls_mode(new_op, mode);
4454         if (is_ia32_use_frame(node)) {
4455                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4456                 set_ia32_use_frame(new_op);
4457         }
4458
4459         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4460
4461         return new_op;
4462 }
4463
4464 /**
4465  * Transforms a lowered Store into a "real" one.
4466  */
4467 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4468 {
4469         ir_node  *block   = be_transform_node(get_nodes_block(node));
4470         ir_node  *ptr     = get_irn_n(node, 0);
4471         ir_node  *new_ptr = be_transform_node(ptr);
4472         ir_node  *val     = get_irn_n(node, 1);
4473         ir_node  *new_val = be_transform_node(val);
4474         ir_node  *mem     = get_irn_n(node, 2);
4475         ir_node  *new_mem = be_transform_node(mem);
4476         ir_graph *irg     = current_ir_graph;
4477         dbg_info *dbgi    = get_irn_dbg_info(node);
4478         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4479         ir_mode  *mode    = get_ia32_ls_mode(node);
4480         ir_node  *new_op;
4481         long     am_offs;
4482
4483         new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4484
4485         am_offs = get_ia32_am_offs_int(node);
4486         add_ia32_am_offs_int(new_op, am_offs);
4487
4488         set_ia32_op_type(new_op, ia32_AddrModeD);
4489         set_ia32_ls_mode(new_op, mode);
4490         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4491         set_ia32_use_frame(new_op);
4492
4493         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4494
4495         return new_op;
4496 }
4497
4498 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4499 {
4500         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
4501         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4502
4503         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4504                                match_immediate | match_mode_neutral);
4505 }
4506
4507 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4508 {
4509         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
4510         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4511         return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4512                                match_immediate);
4513 }
4514
4515 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4516 {
4517         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
4518         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4519         return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4520                                match_immediate);
4521 }
4522
4523 static ir_node *gen_ia32_l_Add(ir_node *node) {
4524         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
4525         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
4526         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4527                         match_commutative | match_am | match_immediate |
4528                         match_mode_neutral);
4529
4530         if(is_Proj(lowered)) {
4531                 lowered = get_Proj_pred(lowered);
4532         } else {
4533                 assert(is_ia32_Add(lowered));
4534                 set_irn_mode(lowered, mode_T);
4535         }
4536
4537         return lowered;
4538 }
4539
4540 static ir_node *gen_ia32_l_Adc(ir_node *node)
4541 {
4542         return gen_binop_flags(node, new_rd_ia32_Adc,
4543                         match_commutative | match_am | match_immediate |
4544                         match_mode_neutral);
4545 }
4546
4547 /**
4548  * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4549  *
4550  * @param node   The node to transform
4551  * @return the created ia32 vfild node
4552  */
4553 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4554         return gen_lowered_Load(node, new_rd_ia32_vfild);
4555 }
4556
4557 /**
4558  * Transforms an ia32_l_Load into a "real" ia32_Load node
4559  *
4560  * @param node   The node to transform
4561  * @return the created ia32 Load node
4562  */
4563 static ir_node *gen_ia32_l_Load(ir_node *node) {
4564         return gen_lowered_Load(node, new_rd_ia32_Load);
4565 }
4566
4567 /**
4568  * Transforms an ia32_l_Store into a "real" ia32_Store node
4569  *
4570  * @param node   The node to transform
4571  * @return the created ia32 Store node
4572  */
4573 static ir_node *gen_ia32_l_Store(ir_node *node) {
4574         return gen_lowered_Store(node, new_rd_ia32_Store);
4575 }
4576
4577 /**
4578  * Transforms a l_vfist into a "real" vfist node.
4579  *
4580  * @param node   The node to transform
4581  * @return the created ia32 vfist node
4582  */
4583 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4584         ir_node  *block      = be_transform_node(get_nodes_block(node));
4585         ir_node  *ptr        = get_irn_n(node, 0);
4586         ir_node  *new_ptr    = be_transform_node(ptr);
4587         ir_node  *val        = get_irn_n(node, 1);
4588         ir_node  *new_val    = be_transform_node(val);
4589         ir_node  *mem        = get_irn_n(node, 2);
4590         ir_node  *new_mem    = be_transform_node(mem);
4591         ir_graph *irg        = current_ir_graph;
4592         dbg_info *dbgi       = get_irn_dbg_info(node);
4593         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4594         ir_mode  *mode       = get_ia32_ls_mode(node);
4595         ir_node  *memres, *fist;
4596         long     am_offs;
4597
4598         memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4599         am_offs = get_ia32_am_offs_int(node);
4600         add_ia32_am_offs_int(fist, am_offs);
4601
4602         set_ia32_op_type(fist, ia32_AddrModeD);
4603         set_ia32_ls_mode(fist, mode);
4604         set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4605         set_ia32_use_frame(fist);
4606
4607         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4608
4609         return memres;
4610 }
4611
4612 /**
4613  * Transforms a l_MulS into a "real" MulS node.
4614  *
4615  * @return the created ia32 Mul node
4616  */
4617 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4618         ir_node *left  = get_binop_left(node);
4619         ir_node *right = get_binop_right(node);
4620
4621         return gen_binop(node, left, right, new_rd_ia32_Mul,
4622                          match_commutative | match_am | match_mode_neutral);
4623 }
4624
4625 /**
4626  * Transforms a l_IMulS into a "real" IMul1OPS node.
4627  *
4628  * @return the created ia32 IMul1OP node
4629  */
4630 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4631         ir_node  *left  = get_binop_left(node);
4632         ir_node  *right = get_binop_right(node);
4633
4634         return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4635                          match_commutative | match_am | match_mode_neutral);
4636 }
4637
4638 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4639         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
4640         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4641         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4642                         match_am | match_immediate | match_mode_neutral);
4643
4644         if(is_Proj(lowered)) {
4645                 lowered = get_Proj_pred(lowered);
4646         } else {
4647                 assert(is_ia32_Sub(lowered));
4648                 set_irn_mode(lowered, mode_T);
4649         }
4650
4651         return lowered;
4652 }
4653
4654 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4655         return gen_binop_flags(node, new_rd_ia32_Sbb,
4656                         match_am | match_immediate | match_mode_neutral);
4657 }
4658
4659 /**
4660  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4661  * op1 - target to be shifted
4662  * op2 - contains bits to be shifted into target
4663  * op3 - shift count
4664  * Only op3 can be an immediate.
4665  */
4666 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4667                                          ir_node *low, ir_node *count)
4668 {
4669         ir_node  *block     = get_nodes_block(node);
4670         ir_node  *new_block = be_transform_node(block);
4671         ir_graph *irg       = current_ir_graph;
4672         dbg_info *dbgi      = get_irn_dbg_info(node);
4673         ir_node  *new_high  = be_transform_node(high);
4674         ir_node  *new_low   = be_transform_node(low);
4675         ir_node  *new_count;
4676         ir_node  *new_node;
4677
4678         /* the shift amount can be any mode that is bigger than 5 bits, since all
4679          * other bits are ignored anyway */
4680         while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4681                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4682                 count = get_Conv_op(count);
4683         }
4684         new_count = create_immediate_or_transform(count, 0);
4685
4686         if (is_ia32_l_ShlD(node)) {
4687                 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4688                                             new_count);
4689         } else {
4690                 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4691                                             new_count);
4692         }
4693         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4694
4695         return new_node;
4696 }
4697
4698 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4699 {
4700         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
4701         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
4702         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4703         return gen_lowered_64bit_shifts(node, high, low, count);
4704 }
4705
4706 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4707 {
4708         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
4709         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
4710         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4711         return gen_lowered_64bit_shifts(node, high, low, count);
4712 }
4713
4714 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4715         ir_node  *src_block    = get_nodes_block(node);
4716         ir_node  *block        = be_transform_node(src_block);
4717         ir_graph *irg          = current_ir_graph;
4718         dbg_info *dbgi         = get_irn_dbg_info(node);
4719         ir_node  *frame        = get_irg_frame(irg);
4720         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
4721         ir_node  *nomem        = new_NoMem();
4722         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4723         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4724         ir_node  *new_val_low  = be_transform_node(val_low);
4725         ir_node  *new_val_high = be_transform_node(val_high);
4726         ir_node  *in[2];
4727         ir_node  *sync;
4728         ir_node  *fild;
4729         ir_node  *store_low;
4730         ir_node  *store_high;
4731
4732         if(!mode_is_signed(get_irn_mode(val_high))) {
4733                 panic("unsigned long long -> float not supported yet (%+F)", node);
4734         }
4735
4736         /* do a store */
4737         store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4738                                       new_val_low);
4739         store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4740                                        new_val_high);
4741         SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4742         SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4743
4744         set_ia32_use_frame(store_low);
4745         set_ia32_use_frame(store_high);
4746         set_ia32_op_type(store_low, ia32_AddrModeD);
4747         set_ia32_op_type(store_high, ia32_AddrModeD);
4748         set_ia32_ls_mode(store_low, mode_Iu);
4749         set_ia32_ls_mode(store_high, mode_Is);
4750         add_ia32_am_offs_int(store_high, 4);
4751
4752         in[0] = store_low;
4753         in[1] = store_high;
4754         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
4755
4756         /* do a fild */
4757         fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4758
4759         set_ia32_use_frame(fild);
4760         set_ia32_op_type(fild, ia32_AddrModeS);
4761         set_ia32_ls_mode(fild, mode_Ls);
4762
4763         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4764
4765         return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4766 }
4767
4768 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4769         ir_node  *src_block  = get_nodes_block(node);
4770         ir_node  *block      = be_transform_node(src_block);
4771         ir_graph *irg        = current_ir_graph;
4772         dbg_info *dbgi       = get_irn_dbg_info(node);
4773         ir_node  *frame      = get_irg_frame(irg);
4774         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4775         ir_node  *nomem      = new_NoMem();
4776         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
4777         ir_node  *new_val    = be_transform_node(val);
4778         ir_node  *fist, *mem;
4779
4780         mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4781         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4782         set_ia32_use_frame(fist);
4783         set_ia32_op_type(fist, ia32_AddrModeD);
4784         set_ia32_ls_mode(fist, mode_Ls);
4785
4786         return mem;
4787 }
4788
4789 /**
4790  * the BAD transformer.
4791  */
4792 static ir_node *bad_transform(ir_node *node) {
4793         panic("No transform function for %+F available.\n", node);
4794         return NULL;
4795 }
4796
4797 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4798         ir_graph *irg      = current_ir_graph;
4799         ir_node  *block    = be_transform_node(get_nodes_block(node));
4800         ir_node  *pred     = get_Proj_pred(node);
4801         ir_node  *new_pred = be_transform_node(pred);
4802         ir_node  *frame    = get_irg_frame(irg);
4803         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
4804         dbg_info *dbgi     = get_irn_dbg_info(node);
4805         long      pn       = get_Proj_proj(node);
4806         ir_node  *load;
4807         ir_node  *proj;
4808         ia32_attr_t *attr;
4809
4810         load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4811         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4812         set_ia32_use_frame(load);
4813         set_ia32_op_type(load, ia32_AddrModeS);
4814         set_ia32_ls_mode(load, mode_Iu);
4815         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4816          * 32 bit from it with this particular load */
4817         attr = get_ia32_attr(load);
4818         attr->data.need_64bit_stackent = 1;
4819
4820         if (pn == pn_ia32_l_FloattoLL_res_high) {
4821                 add_ia32_am_offs_int(load, 4);
4822         } else {
4823                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4824         }
4825
4826         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4827
4828         return proj;
4829 }
4830
4831 /**
4832  * Transform the Projs of an AddSP.
4833  */
4834 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4835         ir_node  *block    = be_transform_node(get_nodes_block(node));
4836         ir_node  *pred     = get_Proj_pred(node);
4837         ir_node  *new_pred = be_transform_node(pred);
4838         ir_graph *irg      = current_ir_graph;
4839         dbg_info *dbgi     = get_irn_dbg_info(node);
4840         long     proj      = get_Proj_proj(node);
4841
4842         if (proj == pn_be_AddSP_sp) {
4843                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4844                                            pn_ia32_SubSP_stack);
4845                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4846                 return res;
4847         } else if(proj == pn_be_AddSP_res) {
4848                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4849                                    pn_ia32_SubSP_addr);
4850         } else if (proj == pn_be_AddSP_M) {
4851                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4852         }
4853
4854         assert(0);
4855         return new_rd_Unknown(irg, get_irn_mode(node));
4856 }
4857
4858 /**
4859  * Transform the Projs of a SubSP.
4860  */
4861 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4862         ir_node  *block    = be_transform_node(get_nodes_block(node));
4863         ir_node  *pred     = get_Proj_pred(node);
4864         ir_node  *new_pred = be_transform_node(pred);
4865         ir_graph *irg      = current_ir_graph;
4866         dbg_info *dbgi     = get_irn_dbg_info(node);
4867         long     proj      = get_Proj_proj(node);
4868
4869         if (proj == pn_be_SubSP_sp) {
4870                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4871                                            pn_ia32_AddSP_stack);
4872                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4873                 return res;
4874         } else if (proj == pn_be_SubSP_M) {
4875                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4876         }
4877
4878         assert(0);
4879         return new_rd_Unknown(irg, get_irn_mode(node));
4880 }
4881
4882 /**
4883  * Transform and renumber the Projs from a Load.
4884  */
4885 static ir_node *gen_Proj_Load(ir_node *node) {
4886         ir_node  *new_pred;
4887         ir_node  *block    = be_transform_node(get_nodes_block(node));
4888         ir_node  *pred     = get_Proj_pred(node);
4889         ir_graph *irg      = current_ir_graph;
4890         dbg_info *dbgi     = get_irn_dbg_info(node);
4891         long     proj      = get_Proj_proj(node);
4892
4893         /* loads might be part of source address mode matches, so we don't
4894          * transform the ProjMs yet (with the exception of loads whose result is
4895          * not used)
4896          */
4897         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4898                 ir_node *res;
4899
4900                 /* this is needed, because sometimes we have loops that are only
4901                    reachable through the ProjM */
4902                 be_enqueue_preds(node);
4903                 /* do it in 2 steps, to silence firm verifier */
4904                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4905                 set_Proj_proj(res, pn_ia32_mem);
4906                 return res;
4907         }
4908
4909         /* renumber the proj */
4910         new_pred = be_transform_node(pred);
4911         if (is_ia32_Load(new_pred)) {
4912                 switch (proj) {
4913                 case pn_Load_res:
4914                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4915                 case pn_Load_M:
4916                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4917                 case pn_Load_X_regular:
4918                         return new_rd_Jmp(dbgi, irg, block);
4919                 case pn_Load_X_except:
4920                         /* This Load might raise an exception. Mark it. */
4921                         set_ia32_exc_label(new_pred, 1);
4922                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4923                 default:
4924                         break;
4925                 }
4926         } else if (is_ia32_Conv_I2I(new_pred) ||
4927                    is_ia32_Conv_I2I8Bit(new_pred)) {
4928                 set_irn_mode(new_pred, mode_T);
4929                 if (proj == pn_Load_res) {
4930                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4931                 } else if (proj == pn_Load_M) {
4932                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4933                 }
4934         } else if (is_ia32_xLoad(new_pred)) {
4935                 switch (proj) {
4936                 case pn_Load_res:
4937                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4938                 case pn_Load_M:
4939                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4940                 case pn_Load_X_regular:
4941                         return new_rd_Jmp(dbgi, irg, block);
4942                 case pn_Load_X_except:
4943                         /* This Load might raise an exception. Mark it. */
4944                         set_ia32_exc_label(new_pred, 1);
4945                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4946                 default:
4947                         break;
4948                 }
4949         } else if (is_ia32_vfld(new_pred)) {
4950                 switch (proj) {
4951                 case pn_Load_res:
4952                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4953                 case pn_Load_M:
4954                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4955                 case pn_Load_X_regular:
4956                         return new_rd_Jmp(dbgi, irg, block);
4957                 case pn_Load_X_except:
4958                         /* This Load might raise an exception. Mark it. */
4959                         set_ia32_exc_label(new_pred, 1);
4960                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4961                 default:
4962                         break;
4963                 }
4964         } else {
4965                 /* can happen for ProJMs when source address mode happened for the
4966                    node */
4967
4968                 /* however it should not be the result proj, as that would mean the
4969                    load had multiple users and should not have been used for
4970                    SourceAM */
4971                 if (proj != pn_Load_M) {
4972                         panic("internal error: transformed node not a Load");
4973                 }
4974                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4975         }
4976
4977         assert(0);
4978         return new_rd_Unknown(irg, get_irn_mode(node));
4979 }
4980
4981 /**
4982  * Transform and renumber the Projs from a DivMod like instruction.
4983  */
4984 static ir_node *gen_Proj_DivMod(ir_node *node) {
4985         ir_node  *block    = be_transform_node(get_nodes_block(node));
4986         ir_node  *pred     = get_Proj_pred(node);
4987         ir_node  *new_pred = be_transform_node(pred);
4988         ir_graph *irg      = current_ir_graph;
4989         dbg_info *dbgi     = get_irn_dbg_info(node);
4990         ir_mode  *mode     = get_irn_mode(node);
4991         long     proj      = get_Proj_proj(node);
4992
4993         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4994
4995         switch (get_irn_opcode(pred)) {
4996         case iro_Div:
4997                 switch (proj) {
4998                 case pn_Div_M:
4999                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5000                 case pn_Div_res:
5001                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
5002                 case pn_Div_X_regular:
5003                         return new_rd_Jmp(dbgi, irg, block);
5004                 case pn_Div_X_except:
5005                         set_ia32_exc_label(new_pred, 1);
5006                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5007                 default:
5008                         break;
5009                 }
5010                 break;
5011         case iro_Mod:
5012                 switch (proj) {
5013                 case pn_Mod_M:
5014                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5015                 case pn_Mod_res:
5016                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
5017                 case pn_Mod_X_except:
5018                         set_ia32_exc_label(new_pred, 1);
5019                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5020                 default:
5021                         break;
5022                 }
5023                 break;
5024         case iro_DivMod:
5025                 switch (proj) {
5026                 case pn_DivMod_M:
5027                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5028                 case pn_DivMod_res_div:
5029                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
5030                 case pn_DivMod_res_mod:
5031                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
5032                 case pn_DivMod_X_regular:
5033                         return new_rd_Jmp(dbgi, irg, block);
5034                 case pn_DivMod_X_except:
5035                         set_ia32_exc_label(new_pred, 1);
5036                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5037                 default:
5038                         break;
5039                 }
5040                 break;
5041         default:
5042                 break;
5043         }
5044
5045         assert(0);
5046         return new_rd_Unknown(irg, mode);
5047 }
5048
5049 /**
5050  * Transform and renumber the Projs from a CopyB.
5051  */
5052 static ir_node *gen_Proj_CopyB(ir_node *node) {
5053         ir_node  *block    = be_transform_node(get_nodes_block(node));
5054         ir_node  *pred     = get_Proj_pred(node);
5055         ir_node  *new_pred = be_transform_node(pred);
5056         ir_graph *irg      = current_ir_graph;
5057         dbg_info *dbgi     = get_irn_dbg_info(node);
5058         ir_mode  *mode     = get_irn_mode(node);
5059         long     proj      = get_Proj_proj(node);
5060
5061         switch(proj) {
5062         case pn_CopyB_M_regular:
5063                 if (is_ia32_CopyB_i(new_pred)) {
5064                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
5065                 } else if (is_ia32_CopyB(new_pred)) {
5066                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
5067                 }
5068                 break;
5069         default:
5070                 break;
5071         }
5072
5073         assert(0);
5074         return new_rd_Unknown(irg, mode);
5075 }
5076
5077 /**
5078  * Transform and renumber the Projs from a Quot.
5079  */
5080 static ir_node *gen_Proj_Quot(ir_node *node) {
5081         ir_node  *block    = be_transform_node(get_nodes_block(node));
5082         ir_node  *pred     = get_Proj_pred(node);
5083         ir_node  *new_pred = be_transform_node(pred);
5084         ir_graph *irg      = current_ir_graph;
5085         dbg_info *dbgi     = get_irn_dbg_info(node);
5086         ir_mode  *mode     = get_irn_mode(node);
5087         long     proj      = get_Proj_proj(node);
5088
5089         switch(proj) {
5090         case pn_Quot_M:
5091                 if (is_ia32_xDiv(new_pred)) {
5092                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
5093                 } else if (is_ia32_vfdiv(new_pred)) {
5094                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5095                 }
5096                 break;
5097         case pn_Quot_res:
5098                 if (is_ia32_xDiv(new_pred)) {
5099                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5100                 } else if (is_ia32_vfdiv(new_pred)) {
5101                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5102                 }
5103                 break;
5104         case pn_Quot_X_regular:
5105         case pn_Quot_X_except:
5106         default:
5107                 break;
5108         }
5109
5110         assert(0);
5111         return new_rd_Unknown(irg, mode);
5112 }
5113
5114 /**
5115  * Transform the Thread Local Storage Proj.
5116  */
5117 static ir_node *gen_Proj_tls(ir_node *node) {
5118         ir_node  *block = be_transform_node(get_nodes_block(node));
5119         ir_graph *irg   = current_ir_graph;
5120         dbg_info *dbgi  = NULL;
5121         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5122
5123         return res;
5124 }
5125
5126 static ir_node *gen_be_Call(ir_node *node) {
5127         ir_node *res = be_duplicate_node(node);
5128         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5129
5130         return res;
5131 }
5132
5133 static ir_node *gen_be_IncSP(ir_node *node) {
5134         ir_node *res = be_duplicate_node(node);
5135         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5136
5137         return res;
5138 }
5139
5140 /**
5141  * Transform the Projs from a be_Call.
5142  */
5143 static ir_node *gen_Proj_be_Call(ir_node *node) {
5144         ir_node  *block       = be_transform_node(get_nodes_block(node));
5145         ir_node  *call        = get_Proj_pred(node);
5146         ir_node  *new_call    = be_transform_node(call);
5147         ir_graph *irg         = current_ir_graph;
5148         dbg_info *dbgi        = get_irn_dbg_info(node);
5149         ir_type  *method_type = be_Call_get_type(call);
5150         int       n_res       = get_method_n_ress(method_type);
5151         long      proj        = get_Proj_proj(node);
5152         ir_mode  *mode        = get_irn_mode(node);
5153         ir_node  *sse_load;
5154         const arch_register_class_t *cls;
5155
5156         /* The following is kinda tricky: If we're using SSE, then we have to
5157          * move the result value of the call in floating point registers to an
5158          * xmm register, we therefore construct a GetST0 -> xLoad sequence
5159          * after the call, we have to make sure to correctly make the
5160          * MemProj and the result Proj use these 2 nodes
5161          */
5162         if (proj == pn_be_Call_M_regular) {
5163                 // get new node for result, are we doing the sse load/store hack?
5164                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5165                 ir_node *call_res_new;
5166                 ir_node *call_res_pred = NULL;
5167
5168                 if (call_res != NULL) {
5169                         call_res_new  = be_transform_node(call_res);
5170                         call_res_pred = get_Proj_pred(call_res_new);
5171                 }
5172
5173                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5174                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5175                                            pn_be_Call_M_regular);
5176                 } else {
5177                         assert(is_ia32_xLoad(call_res_pred));
5178                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5179                                            pn_ia32_xLoad_M);
5180                 }
5181         }
5182         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5183                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5184                 ir_node *fstp;
5185                 ir_node *frame = get_irg_frame(irg);
5186                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5187                 //ir_node *p;
5188                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5189                 ir_node *call_res;
5190
5191                 /* in case there is no memory output: create one to serialize the copy
5192                    FPU -> SSE */
5193                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5194                                        pn_be_Call_M_regular);
5195                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5196                                        pn_be_Call_first_res);
5197
5198                 /* store st(0) onto stack */
5199                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5200                                         call_res, mode);
5201                 set_ia32_op_type(fstp, ia32_AddrModeD);
5202                 set_ia32_use_frame(fstp);
5203
5204                 /* load into SSE register */
5205                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5206                                              mode);
5207                 set_ia32_op_type(sse_load, ia32_AddrModeS);
5208                 set_ia32_use_frame(sse_load);
5209
5210                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5211                                        pn_ia32_xLoad_res);
5212
5213                 return sse_load;
5214         }
5215
5216         /* transform call modes */
5217         if (mode_is_data(mode)) {
5218                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5219                 mode = cls->mode;
5220         }
5221
5222         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5223 }
5224
5225 /**
5226  * Transform the Projs from a Cmp.
5227  */
5228 static ir_node *gen_Proj_Cmp(ir_node *node)
5229 {
5230         /* this probably means not all mode_b nodes were lowered... */
5231         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5232               node);
5233 }
5234
5235 /**
5236  * Transform the Projs from a Bound.
5237  */
5238 static ir_node *gen_Proj_Bound(ir_node *node)
5239 {
5240         ir_node *new_node, *block;
5241         ir_node *pred = get_Proj_pred(node);
5242
5243         switch (get_Proj_proj(node)) {
5244         case pn_Bound_M:
5245                 return be_transform_node(get_Bound_mem(pred));
5246         case pn_Bound_X_regular:
5247                 new_node = be_transform_node(pred);
5248                 block    = get_nodes_block(new_node);
5249                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
5250         case pn_Bound_X_except:
5251                 new_node = be_transform_node(pred);
5252                 block    = get_nodes_block(new_node);
5253                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
5254         case pn_Bound_res:
5255                 return be_transform_node(get_Bound_index(pred));
5256         default:
5257                 panic("unsupported Proj from Bound");
5258         }
5259 }
5260
5261 static ir_node *gen_Proj_ASM(ir_node *node)
5262 {
5263         ir_node *pred;
5264         ir_node *new_pred;
5265         ir_node *block;
5266
5267         if (get_irn_mode(node) != mode_M)
5268                 return be_duplicate_node(node);
5269
5270         pred     = get_Proj_pred(node);
5271         new_pred = be_transform_node(pred);
5272         block    = get_nodes_block(new_pred);
5273         return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
5274                         get_ia32_n_res(new_pred) + 1);
5275 }
5276
5277 /**
5278  * Transform and potentially renumber Proj nodes.
5279  */
5280 static ir_node *gen_Proj(ir_node *node) {
5281         ir_node *pred = get_Proj_pred(node);
5282         long    proj;
5283
5284         switch (get_irn_opcode(pred)) {
5285         case iro_Store:
5286                 proj = get_Proj_proj(node);
5287                 if (proj == pn_Store_M) {
5288                         return be_transform_node(pred);
5289                 } else {
5290                         assert(0);
5291                         return new_r_Bad(current_ir_graph);
5292                 }
5293         case iro_Load:
5294                 return gen_Proj_Load(node);
5295         case iro_ASM:
5296                 return gen_Proj_ASM(node);
5297         case iro_Div:
5298         case iro_Mod:
5299         case iro_DivMod:
5300                 return gen_Proj_DivMod(node);
5301         case iro_CopyB:
5302                 return gen_Proj_CopyB(node);
5303         case iro_Quot:
5304                 return gen_Proj_Quot(node);
5305         case beo_SubSP:
5306                 return gen_Proj_be_SubSP(node);
5307         case beo_AddSP:
5308                 return gen_Proj_be_AddSP(node);
5309         case beo_Call:
5310                 return gen_Proj_be_Call(node);
5311         case iro_Cmp:
5312                 return gen_Proj_Cmp(node);
5313         case iro_Bound:
5314                 return gen_Proj_Bound(node);
5315         case iro_Start:
5316                 proj = get_Proj_proj(node);
5317                 if (proj == pn_Start_X_initial_exec) {
5318                         ir_node *block = get_nodes_block(pred);
5319                         dbg_info *dbgi = get_irn_dbg_info(node);
5320                         ir_node *jump;
5321
5322                         /* we exchange the ProjX with a jump */
5323                         block = be_transform_node(block);
5324                         jump  = new_rd_Jmp(dbgi, current_ir_graph, block);
5325                         return jump;
5326                 }
5327                 if (node == be_get_old_anchor(anchor_tls)) {
5328                         return gen_Proj_tls(node);
5329                 }
5330                 break;
5331
5332         default:
5333                 if (is_ia32_l_FloattoLL(pred)) {
5334                         return gen_Proj_l_FloattoLL(node);
5335 #ifdef FIRM_EXT_GRS
5336                 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5337 #else
5338                 } else {
5339 #endif
5340                         ir_mode *mode = get_irn_mode(node);
5341                         if (ia32_mode_needs_gp_reg(mode)) {
5342                                 ir_node *new_pred = be_transform_node(pred);
5343                                 ir_node *block    = be_transform_node(get_nodes_block(node));
5344                                 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5345                                                                                            mode_Iu, get_Proj_proj(node));
5346 #ifdef DEBUG_libfirm
5347                                 new_proj->node_nr = node->node_nr;
5348 #endif
5349                                 return new_proj;
5350                         }
5351                 }
5352         }
5353         return be_duplicate_node(node);
5354 }
5355
5356 /**
5357  * Enters all transform functions into the generic pointer
5358  */
5359 static void register_transformers(void)
5360 {
5361         ir_op *op_Mulh;
5362
5363         /* first clear the generic function pointer for all ops */
5364         clear_irp_opcodes_generic_func();
5365
5366 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5367 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
5368
5369         GEN(Add);
5370         GEN(Sub);
5371         GEN(Mul);
5372         GEN(And);
5373         GEN(Or);
5374         GEN(Eor);
5375
5376         GEN(Shl);
5377         GEN(Shr);
5378         GEN(Shrs);
5379         GEN(Rotl);
5380
5381         GEN(Quot);
5382
5383         GEN(Div);
5384         GEN(Mod);
5385         GEN(DivMod);
5386
5387         GEN(Minus);
5388         GEN(Conv);
5389         GEN(Abs);
5390         GEN(Not);
5391
5392         GEN(Load);
5393         GEN(Store);
5394         GEN(Cond);
5395
5396         GEN(Cmp);
5397         GEN(ASM);
5398         GEN(CopyB);
5399         BAD(Mux);
5400         GEN(Psi);
5401         GEN(Proj);
5402         GEN(Phi);
5403         GEN(IJmp);
5404         GEN(Bound);
5405
5406         /* transform ops from intrinsic lowering */
5407         GEN(ia32_l_Add);
5408         GEN(ia32_l_Adc);
5409         GEN(ia32_l_Mul);
5410         GEN(ia32_l_IMul);
5411         GEN(ia32_l_ShlDep);
5412         GEN(ia32_l_ShrDep);
5413         GEN(ia32_l_SarDep);
5414         GEN(ia32_l_ShlD);
5415         GEN(ia32_l_ShrD);
5416         GEN(ia32_l_Sub);
5417         GEN(ia32_l_Sbb);
5418         GEN(ia32_l_vfild);
5419         GEN(ia32_l_Load);
5420         GEN(ia32_l_vfist);
5421         GEN(ia32_l_Store);
5422         GEN(ia32_l_LLtoFloat);
5423         GEN(ia32_l_FloattoLL);
5424
5425         GEN(Const);
5426         GEN(SymConst);
5427         GEN(Unknown);
5428
5429         /* we should never see these nodes */
5430         BAD(Raise);
5431         BAD(Sel);
5432         BAD(InstOf);
5433         BAD(Cast);
5434         BAD(Free);
5435         BAD(Tuple);
5436         BAD(Id);
5437         //BAD(Bad);
5438         BAD(Confirm);
5439         BAD(Filter);
5440         BAD(CallBegin);
5441         BAD(EndReg);
5442         BAD(EndExcept);
5443
5444         /* handle generic backend nodes */
5445         GEN(be_FrameAddr);
5446         GEN(be_Call);
5447         GEN(be_IncSP);
5448         GEN(be_Return);
5449         GEN(be_AddSP);
5450         GEN(be_SubSP);
5451         GEN(be_Copy);
5452
5453         op_Mulh = get_op_Mulh();
5454         if (op_Mulh)
5455                 GEN(Mulh);
5456
5457 #undef GEN
5458 #undef BAD
5459 }
5460
5461 /**
5462  * Pre-transform all unknown and noreg nodes.
5463  */
5464 static void ia32_pretransform_node(void *arch_cg) {
5465         ia32_code_gen_t *cg = arch_cg;
5466
5467         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
5468         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5469         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5470         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
5471         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
5472         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
5473         get_fpcw();
5474 }
5475
5476 /**
5477  * Walker, checks if all ia32 nodes producing more than one result have
5478  * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
5479  */
5480 static void add_missing_keep_walker(ir_node *node, void *data)
5481 {
5482         int              n_outs, i;
5483         unsigned         found_projs = 0;
5484         const ir_edge_t *edge;
5485         ir_mode         *mode = get_irn_mode(node);
5486         ir_node         *last_keep;
5487         (void) data;
5488         if(mode != mode_T)
5489                 return;
5490         if(!is_ia32_irn(node))
5491                 return;
5492
5493         n_outs = get_ia32_n_res(node);
5494         if(n_outs <= 0)
5495                 return;
5496         if(is_ia32_SwitchJmp(node))
5497                 return;
5498
5499         assert(n_outs < (int) sizeof(unsigned) * 8);
5500         foreach_out_edge(node, edge) {
5501                 ir_node *proj = get_edge_src_irn(edge);
5502                 int      pn   = get_Proj_proj(proj);
5503
5504                 if (get_irn_mode(proj) == mode_M)
5505                         continue;
5506
5507                 assert(pn < n_outs);
5508                 found_projs |= 1 << pn;
5509         }
5510
5511
5512         /* are keeps missing? */
5513         last_keep = NULL;
5514         for(i = 0; i < n_outs; ++i) {
5515                 ir_node                     *block;
5516                 ir_node                     *in[1];
5517                 const arch_register_req_t   *req;
5518                 const arch_register_class_t *cls;
5519
5520                 if(found_projs & (1 << i)) {
5521                         continue;
5522                 }
5523
5524                 req = get_ia32_out_req(node, i);
5525                 cls = req->cls;
5526                 if(cls == NULL) {
5527                         continue;
5528                 }
5529                 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5530                         continue;
5531                 }
5532
5533                 block = get_nodes_block(node);
5534                 in[0] = new_r_Proj(current_ir_graph, block, node,
5535                                    arch_register_class_mode(cls), i);
5536                 if(last_keep != NULL) {
5537                         be_Keep_add_node(last_keep, cls, in[0]);
5538                 } else {
5539                         last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
5540                         if(sched_is_scheduled(node)) {
5541                                 sched_add_after(node, last_keep);
5542                         }
5543                 }
5544         }
5545 }
5546
5547 /**
5548  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5549  * and keeps them.
5550  */
5551 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5552 {
5553         ir_graph *irg = be_get_birg_irg(cg->birg);
5554         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5555 }
5556
5557 /* do the transformation */
5558 void ia32_transform_graph(ia32_code_gen_t *cg) {
5559         int cse_last;
5560         ir_graph *irg = cg->irg;
5561
5562         register_transformers();
5563         env_cg       = cg;
5564         initial_fpcw = NULL;
5565
5566         BE_TIMER_PUSH(t_heights);
5567         heights      = heights_new(irg);
5568         BE_TIMER_POP(t_heights);
5569         ia32_calculate_non_address_mode_nodes(cg->birg);
5570
5571         /* the transform phase is not safe for CSE (yet) because several nodes get
5572          * attributes set after their creation */
5573         cse_last = get_opt_cse();
5574         set_opt_cse(0);
5575
5576         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5577
5578         set_opt_cse(cse_last);
5579
5580         ia32_free_non_address_mode_nodes();
5581         heights_free(heights);
5582         heights = NULL;
5583 }
5584
5585 void ia32_init_transform(void)
5586 {
5587         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
5588 }