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