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