c217a70e2810de25e9fb97592a87f174a5e0e0c9
[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) {
666                 if (!(flags & match_8bit_am))
667                         use_am = 0;
668                 /* we don't automatically add upconvs yet */
669                 assert((flags & match_mode_neutral) || (flags & match_8bit));
670         } else if (mode_bits == 16) {
671                 if (!(flags & match_16bit_am))
672                         use_am = 0;
673                 /* we don't automatically add upconvs yet */
674                 assert((flags & match_mode_neutral) || (flags & match_16bit));
675         }
676
677         /* we can simply skip downconvs for mode neutral nodes: the upper bits
678          * can be random for these operations */
679         if (flags & match_mode_neutral) {
680                 op2 = ia32_skip_downconv(op2);
681                 if (op1 != NULL) {
682                         op1 = ia32_skip_downconv(op1);
683                 }
684         }
685
686         /* match immediates. firm nodes are normalized: constants are always on the
687          * op2 input */
688         new_op2 = NULL;
689         if (!(flags & match_try_am) && use_immediate) {
690                 new_op2 = try_create_Immediate(op2, 0);
691         }
692
693         noreg_gp = ia32_new_NoReg_gp(env_cg);
694         if (new_op2 == NULL &&
695             use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
696                 build_address(am, op2, 0);
697                 new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
698                 if (mode_is_float(mode)) {
699                         new_op2 = ia32_new_NoReg_vfp(env_cg);
700                 } else {
701                         new_op2 = noreg_gp;
702                 }
703                 am->op_type = ia32_AddrModeS;
704         } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
705                        use_am &&
706                        ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
707                 ir_node *noreg;
708                 build_address(am, op1, 0);
709
710                 if (mode_is_float(mode)) {
711                         noreg = ia32_new_NoReg_vfp(env_cg);
712                 } else {
713                         noreg = noreg_gp;
714                 }
715
716                 if (new_op2 != NULL) {
717                         new_op1 = noreg;
718                 } else {
719                         new_op1 = be_transform_node(op2);
720                         new_op2 = noreg;
721                         am->ins_permuted = 1;
722                 }
723                 am->op_type = ia32_AddrModeS;
724         } else {
725                 am->op_type = ia32_Normal;
726
727                 if (flags & match_try_am) {
728                         am->new_op1 = NULL;
729                         am->new_op2 = NULL;
730                         return;
731                 }
732
733                 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
734                 if (new_op2 == NULL)
735                         new_op2 = be_transform_node(op2);
736                 am->ls_mode =
737                         (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
738         }
739         if (addr->base == NULL)
740                 addr->base = noreg_gp;
741         if (addr->index == NULL)
742                 addr->index = noreg_gp;
743         if (addr->mem == NULL)
744                 addr->mem = new_NoMem();
745
746         am->new_op1     = new_op1;
747         am->new_op2     = new_op2;
748         am->commutative = commutative;
749 }
750
751 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
752 {
753         ir_mode  *mode;
754         ir_node  *load;
755
756         if (am->mem_proj == NULL)
757                 return node;
758
759         /* we have to create a mode_T so the old MemProj can attach to us */
760         mode = get_irn_mode(node);
761         load = get_Proj_pred(am->mem_proj);
762
763         be_set_transformed_node(load, node);
764
765         if (mode != mode_T) {
766                 set_irn_mode(node, mode_T);
767                 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
768         } else {
769                 return node;
770         }
771 }
772
773 /**
774  * Construct a standard binary operation, set AM and immediate if required.
775  *
776  * @param node  The original node for which the binop is created
777  * @param op1   The first operand
778  * @param op2   The second operand
779  * @param func  The node constructor function
780  * @return The constructed ia32 node.
781  */
782 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
783                           construct_binop_func *func, match_flags_t flags)
784 {
785         dbg_info            *dbgi;
786         ir_node             *block, *new_block, *new_node;
787         ia32_address_mode_t  am;
788         ia32_address_t      *addr = &am.addr;
789
790         block = get_nodes_block(node);
791         match_arguments(&am, block, op1, op2, NULL, flags);
792
793         dbgi      = get_irn_dbg_info(node);
794         new_block = be_transform_node(block);
795         new_node  = func(dbgi, new_block, addr->base, addr->index, addr->mem,
796                         am.new_op1, am.new_op2);
797         set_am_attributes(new_node, &am);
798         /* we can't use source address mode anymore when using immediates */
799         if (!(flags & match_am_and_immediates) &&
800             (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
801                 set_ia32_am_support(new_node, ia32_am_none);
802         SET_IA32_ORIG_NODE(new_node, node);
803
804         new_node = fix_mem_proj(new_node, &am);
805
806         return new_node;
807 }
808
809 enum {
810         n_ia32_l_binop_left,
811         n_ia32_l_binop_right,
812         n_ia32_l_binop_eflags
813 };
814 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Adc_left,       n_Adc_left)
815 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Adc_right,      n_Adc_right)
816 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags,     n_Adc_eflags)
817 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Sbb_minuend,    n_Sbb_minuend)
818 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
819 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags,     n_Sbb_eflags)
820
821 /**
822  * Construct a binary operation which also consumes the eflags.
823  *
824  * @param node  The node to transform
825  * @param func  The node constructor function
826  * @param flags The match flags
827  * @return      The constructor ia32 node
828  */
829 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
830                                 match_flags_t flags)
831 {
832         ir_node             *src_block  = get_nodes_block(node);
833         ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
834         ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
835         ir_node             *eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
836         dbg_info            *dbgi;
837         ir_node             *block, *new_node, *new_eflags;
838         ia32_address_mode_t  am;
839         ia32_address_t      *addr       = &am.addr;
840
841         match_arguments(&am, src_block, op1, op2, eflags, flags);
842
843         dbgi       = get_irn_dbg_info(node);
844         block      = be_transform_node(src_block);
845         new_eflags = be_transform_node(eflags);
846         new_node   = func(dbgi, block, addr->base, addr->index, addr->mem,
847                         am.new_op1, am.new_op2, new_eflags);
848         set_am_attributes(new_node, &am);
849         /* we can't use source address mode anymore when using immediates */
850         if (!(flags & match_am_and_immediates) &&
851             (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
852                 set_ia32_am_support(new_node, ia32_am_none);
853         SET_IA32_ORIG_NODE(new_node, node);
854
855         new_node = fix_mem_proj(new_node, &am);
856
857         return new_node;
858 }
859
860 static ir_node *get_fpcw(void)
861 {
862         ir_node *fpcw;
863         if (initial_fpcw != NULL)
864                 return initial_fpcw;
865
866         fpcw         = be_abi_get_ignore_irn(env_cg->birg->abi,
867                                              &ia32_fp_cw_regs[REG_FPCW]);
868         initial_fpcw = be_transform_node(fpcw);
869
870         return initial_fpcw;
871 }
872
873 /**
874  * Construct a standard binary operation, set AM and immediate if required.
875  *
876  * @param op1   The first operand
877  * @param op2   The second operand
878  * @param func  The node constructor function
879  * @return The constructed ia32 node.
880  */
881 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
882                                     construct_binop_float_func *func)
883 {
884         ir_mode             *mode  = get_irn_mode(node);
885         dbg_info            *dbgi;
886         ir_node             *block, *new_block, *new_node;
887         ia32_address_mode_t  am;
888         ia32_address_t      *addr = &am.addr;
889         ia32_x87_attr_t     *attr;
890         /* All operations are considered commutative, because there are reverse
891          * variants */
892         match_flags_t        flags = match_commutative;
893
894         /* cannot use address mode with long double on x87 */
895         if (get_mode_size_bits(mode) <= 64)
896                 flags |= match_am;
897
898         block = get_nodes_block(node);
899         match_arguments(&am, block, op1, op2, NULL, flags);
900
901         dbgi      = get_irn_dbg_info(node);
902         new_block = be_transform_node(block);
903         new_node  = func(dbgi, new_block, addr->base, addr->index, addr->mem,
904                         am.new_op1, am.new_op2, get_fpcw());
905         set_am_attributes(new_node, &am);
906
907         attr = get_ia32_x87_attr(new_node);
908         attr->attr.data.ins_permuted = am.ins_permuted;
909
910         SET_IA32_ORIG_NODE(new_node, node);
911
912         new_node = fix_mem_proj(new_node, &am);
913
914         return new_node;
915 }
916
917 /**
918  * Construct a shift/rotate binary operation, sets AM and immediate if required.
919  *
920  * @param op1   The first operand
921  * @param op2   The second operand
922  * @param func  The node constructor function
923  * @return The constructed ia32 node.
924  */
925 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
926                                 construct_shift_func *func,
927                                 match_flags_t flags)
928 {
929         dbg_info *dbgi;
930         ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
931
932         assert(! mode_is_float(get_irn_mode(node)));
933         assert(flags & match_immediate);
934         assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
935
936         if (flags & match_mode_neutral) {
937                 op1     = ia32_skip_downconv(op1);
938                 new_op1 = be_transform_node(op1);
939         } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
940                 new_op1 = create_upconv(op1, node);
941         } else {
942                 new_op1 = be_transform_node(op1);
943         }
944
945         /* the shift amount can be any mode that is bigger than 5 bits, since all
946          * other bits are ignored anyway */
947         while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
948                 ir_node *const op = get_Conv_op(op2);
949                 if (mode_is_float(get_irn_mode(op)))
950                         break;
951                 op2 = op;
952                 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
953         }
954         new_op2 = create_immediate_or_transform(op2, 0);
955
956         dbgi      = get_irn_dbg_info(node);
957         block     = get_nodes_block(node);
958         new_block = be_transform_node(block);
959         new_node  = func(dbgi, new_block, new_op1, new_op2);
960         SET_IA32_ORIG_NODE(new_node, node);
961
962         /* lowered shift instruction may have a dependency operand, handle it here */
963         if (get_irn_arity(node) == 3) {
964                 /* we have a dependency */
965                 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
966                 add_irn_dep(new_node, new_dep);
967         }
968
969         return new_node;
970 }
971
972
973 /**
974  * Construct a standard unary operation, set AM and immediate if required.
975  *
976  * @param op    The operand
977  * @param func  The node constructor function
978  * @return The constructed ia32 node.
979  */
980 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
981                          match_flags_t flags)
982 {
983         dbg_info *dbgi;
984         ir_node  *block, *new_block, *new_op, *new_node;
985
986         assert(flags == 0 || flags == match_mode_neutral);
987         if (flags & match_mode_neutral) {
988                 op = ia32_skip_downconv(op);
989         }
990
991         new_op    = be_transform_node(op);
992         dbgi      = get_irn_dbg_info(node);
993         block     = get_nodes_block(node);
994         new_block = be_transform_node(block);
995         new_node  = func(dbgi, new_block, new_op);
996
997         SET_IA32_ORIG_NODE(new_node, node);
998
999         return new_node;
1000 }
1001
1002 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1003                                         ia32_address_t *addr)
1004 {
1005         ir_node *base, *index, *res;
1006
1007         base = addr->base;
1008         if (base == NULL) {
1009                 base = ia32_new_NoReg_gp(env_cg);
1010         } else {
1011                 base = be_transform_node(base);
1012         }
1013
1014         index = addr->index;
1015         if (index == NULL) {
1016                 index = ia32_new_NoReg_gp(env_cg);
1017         } else {
1018                 index = be_transform_node(index);
1019         }
1020
1021         res = new_bd_ia32_Lea(dbgi, block, base, index);
1022         set_address(res, addr);
1023
1024         return res;
1025 }
1026
1027 /**
1028  * Returns non-zero if a given address mode has a symbolic or
1029  * numerical offset != 0.
1030  */
1031 static int am_has_immediates(const ia32_address_t *addr)
1032 {
1033         return addr->offset != 0 || addr->symconst_ent != NULL
1034                 || addr->frame_entity || addr->use_frame;
1035 }
1036
1037 /**
1038  * Creates an ia32 Add.
1039  *
1040  * @return the created ia32 Add node
1041  */
1042 static ir_node *gen_Add(ir_node *node)
1043 {
1044         ir_mode  *mode = get_irn_mode(node);
1045         ir_node  *op1  = get_Add_left(node);
1046         ir_node  *op2  = get_Add_right(node);
1047         dbg_info *dbgi;
1048         ir_node  *block, *new_block, *new_node, *add_immediate_op;
1049         ia32_address_t       addr;
1050         ia32_address_mode_t  am;
1051
1052         if (mode_is_float(mode)) {
1053                 if (ia32_cg_config.use_sse2)
1054                         return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1055                                          match_commutative | match_am);
1056                 else
1057                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1058         }
1059
1060         ia32_mark_non_am(node);
1061
1062         op2 = ia32_skip_downconv(op2);
1063         op1 = ia32_skip_downconv(op1);
1064
1065         /**
1066          * Rules for an Add:
1067          *   0. Immediate Trees (example Add(Symconst, Const) -> Const)
1068          *   1. Add with immediate -> Lea
1069          *   2. Add with possible source address mode -> Add
1070          *   3. Otherwise -> Lea
1071          */
1072         memset(&addr, 0, sizeof(addr));
1073         ia32_create_address_mode(&addr, node, ia32_create_am_force);
1074         add_immediate_op = NULL;
1075
1076         dbgi      = get_irn_dbg_info(node);
1077         block     = get_nodes_block(node);
1078         new_block = be_transform_node(block);
1079
1080         /* a constant? */
1081         if (addr.base == NULL && addr.index == NULL) {
1082                 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1083                                              addr.symconst_sign, addr.offset);
1084                 be_dep_on_frame(new_node);
1085                 SET_IA32_ORIG_NODE(new_node, node);
1086                 return new_node;
1087         }
1088         /* add with immediate? */
1089         if (addr.index == NULL) {
1090                 add_immediate_op = addr.base;
1091         } else if (addr.base == NULL && addr.scale == 0) {
1092                 add_immediate_op = addr.index;
1093         }
1094
1095         if (add_immediate_op != NULL) {
1096                 if (!am_has_immediates(&addr)) {
1097 #ifdef DEBUG_libfirm
1098                         ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1099                                            node);
1100 #endif
1101                         return be_transform_node(add_immediate_op);
1102                 }
1103
1104                 new_node = create_lea_from_address(dbgi, new_block, &addr);
1105                 SET_IA32_ORIG_NODE(new_node, node);
1106                 return new_node;
1107         }
1108
1109         /* test if we can use source address mode */
1110         match_arguments(&am, block, op1, op2, NULL, match_commutative
1111                         | match_mode_neutral | match_am | match_immediate | match_try_am);
1112
1113         /* construct an Add with source address mode */
1114         if (am.op_type == ia32_AddrModeS) {
1115                 ia32_address_t *am_addr = &am.addr;
1116                 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1117                                          am_addr->index, am_addr->mem, am.new_op1,
1118                                          am.new_op2);
1119                 set_am_attributes(new_node, &am);
1120                 SET_IA32_ORIG_NODE(new_node, node);
1121
1122                 new_node = fix_mem_proj(new_node, &am);
1123
1124                 return new_node;
1125         }
1126
1127         /* otherwise construct a lea */
1128         new_node = create_lea_from_address(dbgi, new_block, &addr);
1129         SET_IA32_ORIG_NODE(new_node, node);
1130         return new_node;
1131 }
1132
1133 /**
1134  * Creates an ia32 Mul.
1135  *
1136  * @return the created ia32 Mul node
1137  */
1138 static ir_node *gen_Mul(ir_node *node)
1139 {
1140         ir_node *op1  = get_Mul_left(node);
1141         ir_node *op2  = get_Mul_right(node);
1142         ir_mode *mode = get_irn_mode(node);
1143
1144         if (mode_is_float(mode)) {
1145                 if (ia32_cg_config.use_sse2)
1146                         return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1147                                          match_commutative | match_am);
1148                 else
1149                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1150         }
1151         return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1152                          match_commutative | match_am | match_mode_neutral |
1153                          match_immediate | match_am_and_immediates);
1154 }
1155
1156 /**
1157  * Creates an ia32 Mulh.
1158  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1159  * this result while Mul returns the lower 32 bit.
1160  *
1161  * @return the created ia32 Mulh node
1162  */
1163 static ir_node *gen_Mulh(ir_node *node)
1164 {
1165         ir_node              *block     = get_nodes_block(node);
1166         ir_node              *new_block = be_transform_node(block);
1167         dbg_info             *dbgi      = get_irn_dbg_info(node);
1168         ir_node              *op1       = get_Mulh_left(node);
1169         ir_node              *op2       = get_Mulh_right(node);
1170         ir_mode              *mode      = get_irn_mode(node);
1171         ir_node              *new_node;
1172         ir_node              *proj_res_high;
1173
1174         if (mode_is_signed(mode)) {
1175                 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1176                 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1177                                     mode_Iu, pn_ia32_IMul1OP_res_high);
1178         } else {
1179                 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1180                 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1181                                     mode_Iu, pn_ia32_Mul_res_high);
1182         }
1183         return proj_res_high;
1184 }
1185
1186 /**
1187  * Creates an ia32 And.
1188  *
1189  * @return The created ia32 And node
1190  */
1191 static ir_node *gen_And(ir_node *node)
1192 {
1193         ir_node *op1 = get_And_left(node);
1194         ir_node *op2 = get_And_right(node);
1195         assert(! mode_is_float(get_irn_mode(node)));
1196
1197         /* is it a zero extension? */
1198         if (is_Const(op2)) {
1199                 tarval   *tv    = get_Const_tarval(op2);
1200                 long      v     = get_tarval_long(tv);
1201
1202                 if (v == 0xFF || v == 0xFFFF) {
1203                         dbg_info *dbgi   = get_irn_dbg_info(node);
1204                         ir_node  *block  = get_nodes_block(node);
1205                         ir_mode  *src_mode;
1206                         ir_node  *res;
1207
1208                         if (v == 0xFF) {
1209                                 src_mode = mode_Bu;
1210                         } else {
1211                                 assert(v == 0xFFFF);
1212                                 src_mode = mode_Hu;
1213                         }
1214                         res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1215
1216                         return res;
1217                 }
1218         }
1219         return gen_binop(node, op1, op2, new_bd_ia32_And,
1220                         match_commutative | match_mode_neutral | match_am | match_immediate);
1221 }
1222
1223
1224
1225 /**
1226  * Creates an ia32 Or.
1227  *
1228  * @return The created ia32 Or node
1229  */
1230 static ir_node *gen_Or(ir_node *node)
1231 {
1232         ir_node *op1 = get_Or_left(node);
1233         ir_node *op2 = get_Or_right(node);
1234
1235         assert (! mode_is_float(get_irn_mode(node)));
1236         return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1237                         | match_mode_neutral | match_am | match_immediate);
1238 }
1239
1240
1241
1242 /**
1243  * Creates an ia32 Eor.
1244  *
1245  * @return The created ia32 Eor node
1246  */
1247 static ir_node *gen_Eor(ir_node *node)
1248 {
1249         ir_node *op1 = get_Eor_left(node);
1250         ir_node *op2 = get_Eor_right(node);
1251
1252         assert(! mode_is_float(get_irn_mode(node)));
1253         return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1254                         | match_mode_neutral | match_am | match_immediate);
1255 }
1256
1257
1258 /**
1259  * Creates an ia32 Sub.
1260  *
1261  * @return The created ia32 Sub node
1262  */
1263 static ir_node *gen_Sub(ir_node *node)
1264 {
1265         ir_node  *op1  = get_Sub_left(node);
1266         ir_node  *op2  = get_Sub_right(node);
1267         ir_mode  *mode = get_irn_mode(node);
1268
1269         if (mode_is_float(mode)) {
1270                 if (ia32_cg_config.use_sse2)
1271                         return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1272                 else
1273                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1274         }
1275
1276         if (is_Const(op2)) {
1277                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1278                            node);
1279         }
1280
1281         return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1282                         | match_am | match_immediate);
1283 }
1284
1285 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1286                                  ir_node  *const src_val,
1287                                  ir_node  *const src_mem,
1288                                  ir_node  *const am_mem)
1289 {
1290         if (is_NoMem(am_mem)) {
1291                 return be_transform_node(src_mem);
1292         } else if (is_Proj(src_val) &&
1293                    is_Proj(src_mem) &&
1294                    get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1295                 /* avoid memory loop */
1296                 return am_mem;
1297         } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1298                 ir_node  *const ptr_pred = get_Proj_pred(src_val);
1299                 int       const arity    = get_Sync_n_preds(src_mem);
1300                 int             n        = 0;
1301                 ir_node **      ins;
1302                 int             i;
1303
1304                 NEW_ARR_A(ir_node*, ins, arity + 1);
1305
1306                 /* NOTE: This sometimes produces dead-code because the old sync in
1307                  * src_mem might not be used anymore, we should detect this case
1308                  * and kill the sync... */
1309                 for (i = arity - 1; i >= 0; --i) {
1310                         ir_node *const pred = get_Sync_pred(src_mem, i);
1311
1312                         /* avoid memory loop */
1313                         if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1314                                 continue;
1315
1316                         ins[n++] = be_transform_node(pred);
1317                 }
1318
1319                 ins[n++] = am_mem;
1320
1321                 return new_r_Sync(irg, block, n, ins);
1322         } else {
1323                 ir_node *ins[2];
1324
1325                 ins[0] = be_transform_node(src_mem);
1326                 ins[1] = am_mem;
1327                 return new_r_Sync(irg, block, 2, ins);
1328         }
1329 }
1330
1331 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1332                                  ir_node *val, const ir_node *orig)
1333 {
1334         ir_node *res;
1335
1336         (void)orig;
1337         if (ia32_cg_config.use_short_sex_eax) {
1338                 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1339                 be_dep_on_frame(pval);
1340                 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1341         } else {
1342                 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1343                 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1344         }
1345         SET_IA32_ORIG_NODE(res, orig);
1346         return res;
1347 }
1348
1349 /**
1350  * Generates an ia32 DivMod with additional infrastructure for the
1351  * register allocator if needed.
1352  */
1353 static ir_node *create_Div(ir_node *node)
1354 {
1355         dbg_info *dbgi      = get_irn_dbg_info(node);
1356         ir_node  *block     = get_nodes_block(node);
1357         ir_node  *new_block = be_transform_node(block);
1358         ir_node  *mem;
1359         ir_node  *new_mem;
1360         ir_node  *op1;
1361         ir_node  *op2;
1362         ir_node  *new_node;
1363         ir_mode  *mode;
1364         ir_node  *sign_extension;
1365         ia32_address_mode_t  am;
1366         ia32_address_t      *addr = &am.addr;
1367
1368         /* the upper bits have random contents for smaller modes */
1369         switch (get_irn_opcode(node)) {
1370         case iro_Div:
1371                 op1     = get_Div_left(node);
1372                 op2     = get_Div_right(node);
1373                 mem     = get_Div_mem(node);
1374                 mode    = get_Div_resmode(node);
1375                 break;
1376         case iro_Mod:
1377                 op1     = get_Mod_left(node);
1378                 op2     = get_Mod_right(node);
1379                 mem     = get_Mod_mem(node);
1380                 mode    = get_Mod_resmode(node);
1381                 break;
1382         case iro_DivMod:
1383                 op1     = get_DivMod_left(node);
1384                 op2     = get_DivMod_right(node);
1385                 mem     = get_DivMod_mem(node);
1386                 mode    = get_DivMod_resmode(node);
1387                 break;
1388         default:
1389                 panic("invalid divmod node %+F", node);
1390         }
1391
1392         match_arguments(&am, block, op1, op2, NULL, match_am);
1393
1394         /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1395            is the memory of the consumed address. We can have only the second op as address
1396            in Div nodes, so check only op2. */
1397         new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1398
1399         if (mode_is_signed(mode)) {
1400                 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1401                 new_node       = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1402                                 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1403         } else {
1404                 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1405                 be_dep_on_frame(sign_extension);
1406
1407                 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1408                                            addr->index, new_mem, am.new_op2,
1409                                            am.new_op1, sign_extension);
1410         }
1411
1412         set_irn_pinned(new_node, get_irn_pinned(node));
1413
1414         set_am_attributes(new_node, &am);
1415         SET_IA32_ORIG_NODE(new_node, node);
1416
1417         new_node = fix_mem_proj(new_node, &am);
1418
1419         return new_node;
1420 }
1421
1422
1423 static ir_node *gen_Mod(ir_node *node)
1424 {
1425         return create_Div(node);
1426 }
1427
1428 static ir_node *gen_Div(ir_node *node)
1429 {
1430         return create_Div(node);
1431 }
1432
1433 static ir_node *gen_DivMod(ir_node *node)
1434 {
1435         return create_Div(node);
1436 }
1437
1438
1439
1440 /**
1441  * Creates an ia32 floating Div.
1442  *
1443  * @return The created ia32 xDiv node
1444  */
1445 static ir_node *gen_Quot(ir_node *node)
1446 {
1447         ir_node *op1 = get_Quot_left(node);
1448         ir_node *op2 = get_Quot_right(node);
1449
1450         if (ia32_cg_config.use_sse2) {
1451                 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1452         } else {
1453                 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1454         }
1455 }
1456
1457
1458 /**
1459  * Creates an ia32 Shl.
1460  *
1461  * @return The created ia32 Shl node
1462  */
1463 static ir_node *gen_Shl(ir_node *node)
1464 {
1465         ir_node *left  = get_Shl_left(node);
1466         ir_node *right = get_Shl_right(node);
1467
1468         return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1469                                match_mode_neutral | match_immediate);
1470 }
1471
1472 /**
1473  * Creates an ia32 Shr.
1474  *
1475  * @return The created ia32 Shr node
1476  */
1477 static ir_node *gen_Shr(ir_node *node)
1478 {
1479         ir_node *left  = get_Shr_left(node);
1480         ir_node *right = get_Shr_right(node);
1481
1482         return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1483 }
1484
1485
1486
1487 /**
1488  * Creates an ia32 Sar.
1489  *
1490  * @return The created ia32 Shrs node
1491  */
1492 static ir_node *gen_Shrs(ir_node *node)
1493 {
1494         ir_node *left  = get_Shrs_left(node);
1495         ir_node *right = get_Shrs_right(node);
1496         ir_mode *mode  = get_irn_mode(node);
1497
1498         if (is_Const(right) && mode == mode_Is) {
1499                 tarval *tv = get_Const_tarval(right);
1500                 long val = get_tarval_long(tv);
1501                 if (val == 31) {
1502                         /* this is a sign extension */
1503                         dbg_info *dbgi   = get_irn_dbg_info(node);
1504                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1505                         ir_node  *new_op = be_transform_node(left);
1506
1507                         return create_sex_32_64(dbgi, block, new_op, node);
1508                 }
1509         }
1510
1511         /* 8 or 16 bit sign extension? */
1512         if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1513                 ir_node *shl_left  = get_Shl_left(left);
1514                 ir_node *shl_right = get_Shl_right(left);
1515                 if (is_Const(shl_right)) {
1516                         tarval *tv1 = get_Const_tarval(right);
1517                         tarval *tv2 = get_Const_tarval(shl_right);
1518                         if (tv1 == tv2 && tarval_is_long(tv1)) {
1519                                 long val = get_tarval_long(tv1);
1520                                 if (val == 16 || val == 24) {
1521                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1522                                         ir_node  *block  = get_nodes_block(node);
1523                                         ir_mode  *src_mode;
1524                                         ir_node  *res;
1525
1526                                         if (val == 24) {
1527                                                 src_mode = mode_Bs;
1528                                         } else {
1529                                                 assert(val == 16);
1530                                                 src_mode = mode_Hs;
1531                                         }
1532                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1533                                                               shl_left, node);
1534
1535                                         return res;
1536                                 }
1537                         }
1538                 }
1539         }
1540
1541         return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1542 }
1543
1544
1545
1546 /**
1547  * Creates an ia32 Rol.
1548  *
1549  * @param op1   The first operator
1550  * @param op2   The second operator
1551  * @return The created ia32 RotL node
1552  */
1553 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1554 {
1555         return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1556 }
1557
1558
1559
1560 /**
1561  * Creates an ia32 Ror.
1562  * NOTE: There is no RotR with immediate because this would always be a RotL
1563  *       "imm-mode_size_bits" which can be pre-calculated.
1564  *
1565  * @param op1   The first operator
1566  * @param op2   The second operator
1567  * @return The created ia32 RotR node
1568  */
1569 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1570 {
1571         return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1572 }
1573
1574
1575
1576 /**
1577  * Creates an ia32 RotR or RotL (depending on the found pattern).
1578  *
1579  * @return The created ia32 RotL or RotR node
1580  */
1581 static ir_node *gen_Rotl(ir_node *node)
1582 {
1583         ir_node *rotate = NULL;
1584         ir_node *op1    = get_Rotl_left(node);
1585         ir_node *op2    = get_Rotl_right(node);
1586
1587         /* Firm has only RotL, so we are looking for a right (op2)
1588                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1589                  that means we can create a RotR instead of an Add and a RotL */
1590
1591         if (is_Add(op2)) {
1592                 ir_node *add = op2;
1593                 ir_node *left = get_Add_left(add);
1594                 ir_node *right = get_Add_right(add);
1595                 if (is_Const(right)) {
1596                         tarval  *tv   = get_Const_tarval(right);
1597                         ir_mode *mode = get_irn_mode(node);
1598                         long     bits = get_mode_size_bits(mode);
1599
1600                         if (is_Minus(left) &&
1601                             tarval_is_long(tv)       &&
1602                             get_tarval_long(tv) == bits &&
1603                             bits                == 32)
1604                         {
1605                                 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1606                                 rotate = gen_Ror(node, op1, get_Minus_op(left));
1607                         }
1608                 }
1609         }
1610
1611         if (rotate == NULL) {
1612                 rotate = gen_Rol(node, op1, op2);
1613         }
1614
1615         return rotate;
1616 }
1617
1618
1619
1620 /**
1621  * Transforms a Minus node.
1622  *
1623  * @return The created ia32 Minus node
1624  */
1625 static ir_node *gen_Minus(ir_node *node)
1626 {
1627         ir_node   *op    = get_Minus_op(node);
1628         ir_node   *block = be_transform_node(get_nodes_block(node));
1629         dbg_info  *dbgi  = get_irn_dbg_info(node);
1630         ir_mode   *mode  = get_irn_mode(node);
1631         ir_entity *ent;
1632         ir_node   *new_node;
1633         int        size;
1634
1635         if (mode_is_float(mode)) {
1636                 ir_node *new_op = be_transform_node(op);
1637                 if (ia32_cg_config.use_sse2) {
1638                         /* TODO: non-optimal... if we have many xXors, then we should
1639                          * rather create a load for the const and use that instead of
1640                          * several AM nodes... */
1641                         ir_node *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1642                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1643                         ir_node *nomem     = new_NoMem();
1644
1645                         new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1646                                                     nomem, new_op, noreg_xmm);
1647
1648                         size = get_mode_size_bits(mode);
1649                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1650
1651                         set_ia32_am_sc(new_node, ent);
1652                         set_ia32_op_type(new_node, ia32_AddrModeS);
1653                         set_ia32_ls_mode(new_node, mode);
1654                 } else {
1655                         new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1656                 }
1657         } else {
1658                 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1659         }
1660
1661         SET_IA32_ORIG_NODE(new_node, node);
1662
1663         return new_node;
1664 }
1665
1666 /**
1667  * Transforms a Not node.
1668  *
1669  * @return The created ia32 Not node
1670  */
1671 static ir_node *gen_Not(ir_node *node)
1672 {
1673         ir_node *op   = get_Not_op(node);
1674
1675         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1676         assert (! mode_is_float(get_irn_mode(node)));
1677
1678         return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1679 }
1680
1681
1682
1683 /**
1684  * Transforms an Abs node.
1685  *
1686  * @return The created ia32 Abs node
1687  */
1688 static ir_node *gen_Abs(ir_node *node)
1689 {
1690         ir_node   *block     = get_nodes_block(node);
1691         ir_node   *new_block = be_transform_node(block);
1692         ir_node   *op        = get_Abs_op(node);
1693         dbg_info  *dbgi      = get_irn_dbg_info(node);
1694         ir_mode   *mode      = get_irn_mode(node);
1695         ir_node   *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1696         ir_node   *nomem     = new_NoMem();
1697         ir_node   *new_op;
1698         ir_node   *new_node;
1699         int        size;
1700         ir_entity *ent;
1701
1702         if (mode_is_float(mode)) {
1703                 new_op = be_transform_node(op);
1704
1705                 if (ia32_cg_config.use_sse2) {
1706                         ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1707                         new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1708                                                     nomem, new_op, noreg_fp);
1709
1710                         size = get_mode_size_bits(mode);
1711                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1712
1713                         set_ia32_am_sc(new_node, ent);
1714
1715                         SET_IA32_ORIG_NODE(new_node, node);
1716
1717                         set_ia32_op_type(new_node, ia32_AddrModeS);
1718                         set_ia32_ls_mode(new_node, mode);
1719                 } else {
1720                         new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1721                         SET_IA32_ORIG_NODE(new_node, node);
1722                 }
1723         } else {
1724                 ir_node *xor, *sign_extension;
1725
1726                 if (get_mode_size_bits(mode) == 32) {
1727                         new_op = be_transform_node(op);
1728                 } else {
1729                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1730                 }
1731
1732                 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1733
1734                 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1735                                       nomem, new_op, sign_extension);
1736                 SET_IA32_ORIG_NODE(xor, node);
1737
1738                 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1739                                            nomem, xor, sign_extension);
1740                 SET_IA32_ORIG_NODE(new_node, node);
1741         }
1742
1743         return new_node;
1744 }
1745
1746 /**
1747  * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1748  */
1749 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1750 {
1751         dbg_info *dbgi      = get_irn_dbg_info(cmp);
1752         ir_node  *block     = get_nodes_block(cmp);
1753         ir_node  *new_block = be_transform_node(block);
1754         ir_node  *op1       = be_transform_node(x);
1755         ir_node  *op2       = be_transform_node(n);
1756
1757         return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1758 }
1759
1760 /**
1761  * Transform a node returning a "flag" result.
1762  *
1763  * @param node     the node to transform
1764  * @param pnc_out  the compare mode to use
1765  */
1766 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1767 {
1768         ir_node  *flags;
1769         ir_node  *new_op;
1770         ir_node  *noreg;
1771         ir_node  *nomem;
1772         ir_node  *new_block;
1773         dbg_info *dbgi;
1774
1775         /* we have a Cmp as input */
1776         if (is_Proj(node)) {
1777                 ir_node *pred = get_Proj_pred(node);
1778                 if (is_Cmp(pred)) {
1779                         pn_Cmp pnc = get_Proj_proj(node);
1780                         if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1781                                 ir_node *l = get_Cmp_left(pred);
1782                                 ir_node *r = get_Cmp_right(pred);
1783                                 if (is_And(l)) {
1784                                         ir_node *la = get_And_left(l);
1785                                         ir_node *ra = get_And_right(l);
1786                                         if (is_Shl(la)) {
1787                                                 ir_node *c = get_Shl_left(la);
1788                                                 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1789                                                         /* (1 << n) & ra) */
1790                                                         ir_node *n = get_Shl_right(la);
1791                                                         flags    = gen_bt(pred, ra, n);
1792                                                         /* we must generate a Jc/Jnc jump */
1793                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1794                                                         if (r == la)
1795                                                                 pnc ^= pn_Cmp_Leg;
1796                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1797                                                         return flags;
1798                                                 }
1799                                         }
1800                                         if (is_Shl(ra)) {
1801                                                 ir_node *c = get_Shl_left(ra);
1802                                                 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1803                                                         /* la & (1 << n)) */
1804                                                         ir_node *n = get_Shl_right(ra);
1805                                                         flags    = gen_bt(pred, la, n);
1806                                                         /* we must generate a Jc/Jnc jump */
1807                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1808                                                         if (r == ra)
1809                                                                 pnc ^= pn_Cmp_Leg;
1810                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1811                                                         return flags;
1812                                                 }
1813                                         }
1814                                 }
1815                         }
1816                         flags    = be_transform_node(pred);
1817                         *pnc_out = pnc;
1818                         return flags;
1819                 }
1820         }
1821
1822         /* a mode_b value, we have to compare it against 0 */
1823         dbgi      = get_irn_dbg_info(node);
1824         new_block = be_transform_node(get_nodes_block(node));
1825         new_op    = be_transform_node(node);
1826         noreg     = ia32_new_NoReg_gp(env_cg);
1827         nomem     = new_NoMem();
1828         flags     = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1829                         new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1830         *pnc_out  = pn_Cmp_Lg;
1831         return flags;
1832 }
1833
1834 /**
1835  * Transforms a Load.
1836  *
1837  * @return the created ia32 Load node
1838  */
1839 static ir_node *gen_Load(ir_node *node)
1840 {
1841         ir_node  *old_block = get_nodes_block(node);
1842         ir_node  *block   = be_transform_node(old_block);
1843         ir_node  *ptr     = get_Load_ptr(node);
1844         ir_node  *mem     = get_Load_mem(node);
1845         ir_node  *new_mem = be_transform_node(mem);
1846         ir_node  *base;
1847         ir_node  *index;
1848         dbg_info *dbgi    = get_irn_dbg_info(node);
1849         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
1850         ir_mode  *mode    = get_Load_mode(node);
1851         ir_mode  *res_mode;
1852         ir_node  *new_node;
1853         ia32_address_t addr;
1854
1855         /* construct load address */
1856         memset(&addr, 0, sizeof(addr));
1857         ia32_create_address_mode(&addr, ptr, 0);
1858         base  = addr.base;
1859         index = addr.index;
1860
1861         if (base == NULL) {
1862                 base = noreg;
1863         } else {
1864                 base = be_transform_node(base);
1865         }
1866
1867         if (index == NULL) {
1868                 index = noreg;
1869         } else {
1870                 index = be_transform_node(index);
1871         }
1872
1873         if (mode_is_float(mode)) {
1874                 if (ia32_cg_config.use_sse2) {
1875                         new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1876                                                      mode);
1877                         res_mode = mode_xmm;
1878                 } else {
1879                         new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1880                                                     mode);
1881                         res_mode = mode_vfp;
1882                 }
1883         } else {
1884                 assert(mode != mode_b);
1885
1886                 /* create a conv node with address mode for smaller modes */
1887                 if (get_mode_size_bits(mode) < 32) {
1888                         new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1889                                                         new_mem, noreg, mode);
1890                 } else {
1891                         new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1892                 }
1893                 res_mode = mode_Iu;
1894         }
1895
1896         set_irn_pinned(new_node, get_irn_pinned(node));
1897         set_ia32_op_type(new_node, ia32_AddrModeS);
1898         set_ia32_ls_mode(new_node, mode);
1899         set_address(new_node, &addr);
1900
1901         if (get_irn_pinned(node) == op_pin_state_floats) {
1902                 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1903                                 && pn_ia32_vfld_res == pn_ia32_Load_res
1904                                 && pn_ia32_Load_res == pn_ia32_res);
1905                 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1906         }
1907
1908         SET_IA32_ORIG_NODE(new_node, node);
1909
1910         be_dep_on_frame(new_node);
1911         return new_node;
1912 }
1913
1914 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1915                        ir_node *ptr, ir_node *other)
1916 {
1917         ir_node *load;
1918
1919         if (!is_Proj(node))
1920                 return 0;
1921
1922         /* we only use address mode if we're the only user of the load */
1923         if (get_irn_n_edges(node) > 1)
1924                 return 0;
1925
1926         load = get_Proj_pred(node);
1927         if (!is_Load(load))
1928                 return 0;
1929         if (get_nodes_block(load) != block)
1930                 return 0;
1931
1932         /* store should have the same pointer as the load */
1933         if (get_Load_ptr(load) != ptr)
1934                 return 0;
1935
1936         /* don't do AM if other node inputs depend on the load (via mem-proj) */
1937         if (other != NULL                   &&
1938             get_nodes_block(other) == block &&
1939             heights_reachable_in_block(heights, other, load)) {
1940                 return 0;
1941         }
1942
1943         if (prevents_AM(block, load, mem))
1944                 return 0;
1945         /* Store should be attached to the load via mem */
1946         assert(heights_reachable_in_block(heights, mem, load));
1947
1948         return 1;
1949 }
1950
1951 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1952                               ir_node *mem, ir_node *ptr, ir_mode *mode,
1953                               construct_binop_dest_func *func,
1954                               construct_binop_dest_func *func8bit,
1955                                                           match_flags_t flags)
1956 {
1957         ir_node  *src_block = get_nodes_block(node);
1958         ir_node  *block;
1959         ir_node  *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1960         dbg_info *dbgi;
1961         ir_node  *new_mem;
1962         ir_node  *new_node;
1963         ir_node  *new_op;
1964         ir_node  *mem_proj;
1965         int       commutative;
1966         ia32_address_mode_t  am;
1967         ia32_address_t      *addr = &am.addr;
1968         memset(&am, 0, sizeof(am));
1969
1970         assert(flags & match_dest_am);
1971         assert(flags & match_immediate); /* there is no destam node without... */
1972         commutative = (flags & match_commutative) != 0;
1973
1974         if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1975                 build_address(&am, op1, ia32_create_am_double_use);
1976                 new_op = create_immediate_or_transform(op2, 0);
1977         } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1978                 build_address(&am, op2, ia32_create_am_double_use);
1979                 new_op = create_immediate_or_transform(op1, 0);
1980         } else {
1981                 return NULL;
1982         }
1983
1984         if (addr->base == NULL)
1985                 addr->base = noreg_gp;
1986         if (addr->index == NULL)
1987                 addr->index = noreg_gp;
1988         if (addr->mem == NULL)
1989                 addr->mem = new_NoMem();
1990
1991         dbgi    = get_irn_dbg_info(node);
1992         block   = be_transform_node(src_block);
1993         new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
1994
1995         if (get_mode_size_bits(mode) == 8) {
1996                 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
1997         } else {
1998                 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
1999         }
2000         set_address(new_node, addr);
2001         set_ia32_op_type(new_node, ia32_AddrModeD);
2002         set_ia32_ls_mode(new_node, mode);
2003         SET_IA32_ORIG_NODE(new_node, node);
2004
2005         be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2006         mem_proj = be_transform_node(am.mem_proj);
2007         be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2008
2009         return new_node;
2010 }
2011
2012 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2013                              ir_node *ptr, ir_mode *mode,
2014                              construct_unop_dest_func *func)
2015 {
2016         ir_node  *src_block = get_nodes_block(node);
2017         ir_node  *block;
2018         dbg_info *dbgi;
2019         ir_node  *new_mem;
2020         ir_node  *new_node;
2021         ir_node  *mem_proj;
2022         ia32_address_mode_t  am;
2023         ia32_address_t *addr = &am.addr;
2024
2025         if (!use_dest_am(src_block, op, mem, ptr, NULL))
2026                 return NULL;
2027
2028         memset(&am, 0, sizeof(am));
2029         build_address(&am, op, ia32_create_am_double_use);
2030
2031         dbgi     = get_irn_dbg_info(node);
2032         block    = be_transform_node(src_block);
2033         new_mem  = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2034         new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2035         set_address(new_node, addr);
2036         set_ia32_op_type(new_node, ia32_AddrModeD);
2037         set_ia32_ls_mode(new_node, mode);
2038         SET_IA32_ORIG_NODE(new_node, node);
2039
2040         be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2041         mem_proj = be_transform_node(am.mem_proj);
2042         be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2043
2044         return new_node;
2045 }
2046
2047 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2048 {
2049         ir_mode  *mode        = get_irn_mode(node);
2050         ir_node  *mux_true    = get_Mux_true(node);
2051         ir_node  *mux_false   = get_Mux_false(node);
2052         ir_node  *cond;
2053         ir_node  *new_mem;
2054         dbg_info *dbgi;
2055         ir_node  *block;
2056         ir_node  *new_block;
2057         ir_node  *flags;
2058         ir_node  *new_node;
2059         int       negated;
2060         pn_Cmp    pnc;
2061         ia32_address_t addr;
2062
2063         if (get_mode_size_bits(mode) != 8)
2064                 return NULL;
2065
2066         if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2067                 negated = 0;
2068         } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2069                 negated = 1;
2070         } else {
2071                 return NULL;
2072         }
2073
2074         build_address_ptr(&addr, ptr, mem);
2075
2076         dbgi      = get_irn_dbg_info(node);
2077         block     = get_nodes_block(node);
2078         new_block = be_transform_node(block);
2079         cond      = get_Mux_sel(node);
2080         flags     = get_flags_node(cond, &pnc);
2081         new_mem   = be_transform_node(mem);
2082         new_node  = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2083                                        addr.index, addr.mem, flags, pnc, negated);
2084         set_address(new_node, &addr);
2085         set_ia32_op_type(new_node, ia32_AddrModeD);
2086         set_ia32_ls_mode(new_node, mode);
2087         SET_IA32_ORIG_NODE(new_node, node);
2088
2089         return new_node;
2090 }
2091
2092 static ir_node *try_create_dest_am(ir_node *node)
2093 {
2094         ir_node  *val  = get_Store_value(node);
2095         ir_node  *mem  = get_Store_mem(node);
2096         ir_node  *ptr  = get_Store_ptr(node);
2097         ir_mode  *mode = get_irn_mode(val);
2098         unsigned  bits = get_mode_size_bits(mode);
2099         ir_node  *op1;
2100         ir_node  *op2;
2101         ir_node  *new_node;
2102
2103         /* handle only GP modes for now... */
2104         if (!ia32_mode_needs_gp_reg(mode))
2105                 return NULL;
2106
2107         for (;;) {
2108                 /* store must be the only user of the val node */
2109                 if (get_irn_n_edges(val) > 1)
2110                         return NULL;
2111                 /* skip pointless convs */
2112                 if (is_Conv(val)) {
2113                         ir_node *conv_op   = get_Conv_op(val);
2114                         ir_mode *pred_mode = get_irn_mode(conv_op);
2115                         if (!ia32_mode_needs_gp_reg(pred_mode))
2116                                 break;
2117                         if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2118                                 val = conv_op;
2119                                 continue;
2120                         }
2121                 }
2122                 break;
2123         }
2124
2125         /* value must be in the same block */
2126         if (get_nodes_block(node) != get_nodes_block(val))
2127                 return NULL;
2128
2129         switch (get_irn_opcode(val)) {
2130         case iro_Add:
2131                 op1      = get_Add_left(val);
2132                 op2      = get_Add_right(val);
2133                 if (ia32_cg_config.use_incdec) {
2134                         if (is_Const_1(op2)) {
2135                                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2136                                 break;
2137                         } else if (is_Const_Minus_1(op2)) {
2138                                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2139                                 break;
2140                         }
2141                 }
2142                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2143                                          new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2144                                          match_dest_am | match_commutative |
2145                                          match_immediate);
2146                 break;
2147         case iro_Sub:
2148                 op1      = get_Sub_left(val);
2149                 op2      = get_Sub_right(val);
2150                 if (is_Const(op2)) {
2151                         ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2152                 }
2153                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2154                                          new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2155                                          match_dest_am | match_immediate);
2156                 break;
2157         case iro_And:
2158                 op1      = get_And_left(val);
2159                 op2      = get_And_right(val);
2160                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2161                                          new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2162                                          match_dest_am | match_commutative |
2163                                          match_immediate);
2164                 break;
2165         case iro_Or:
2166                 op1      = get_Or_left(val);
2167                 op2      = get_Or_right(val);
2168                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2169                                          new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2170                                          match_dest_am | match_commutative |
2171                                          match_immediate);
2172                 break;
2173         case iro_Eor:
2174                 op1      = get_Eor_left(val);
2175                 op2      = get_Eor_right(val);
2176                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2177                                          new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2178                                          match_dest_am | match_commutative |
2179                                          match_immediate);
2180                 break;
2181         case iro_Shl:
2182                 op1      = get_Shl_left(val);
2183                 op2      = get_Shl_right(val);
2184                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2185                                          new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2186                                          match_dest_am | match_immediate);
2187                 break;
2188         case iro_Shr:
2189                 op1      = get_Shr_left(val);
2190                 op2      = get_Shr_right(val);
2191                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2192                                          new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2193                                          match_dest_am | match_immediate);
2194                 break;
2195         case iro_Shrs:
2196                 op1      = get_Shrs_left(val);
2197                 op2      = get_Shrs_right(val);
2198                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2199                                          new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2200                                          match_dest_am | match_immediate);
2201                 break;
2202         case iro_Rotl:
2203                 op1      = get_Rotl_left(val);
2204                 op2      = get_Rotl_right(val);
2205                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2206                                          new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2207                                          match_dest_am | match_immediate);
2208                 break;
2209         /* TODO: match ROR patterns... */
2210         case iro_Mux:
2211                 new_node = try_create_SetMem(val, ptr, mem);
2212                 break;
2213         case iro_Minus:
2214                 op1      = get_Minus_op(val);
2215                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2216                 break;
2217         case iro_Not:
2218                 /* should be lowered already */
2219                 assert(mode != mode_b);
2220                 op1      = get_Not_op(val);
2221                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2222                 break;
2223         default:
2224                 return NULL;
2225         }
2226
2227         if (new_node != NULL) {
2228                 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2229                                 get_irn_pinned(node) == op_pin_state_pinned) {
2230                         set_irn_pinned(new_node, op_pin_state_pinned);
2231                 }
2232         }
2233
2234         return new_node;
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 (mode != mode_Is && mode != mode_Hs)
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         if (is_ia32_Conv_I2I(transformed_node)
2649                         || is_ia32_Conv_I2I8Bit(transformed_node)) {
2650                 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2651                 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2652                         return false;
2653                 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2654                         return false;
2655
2656                 return true;
2657         }
2658
2659         if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2660                 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2661                 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2662                         const ia32_immediate_attr_t *attr
2663                                 = get_ia32_immediate_attr_const(right);
2664                         if (attr->symconst == 0
2665                                         && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2666                                 return true;
2667                         }
2668                 }
2669                 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2670         }
2671
2672         if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2673                 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2674                 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2675                         const ia32_immediate_attr_t *attr
2676                                 = get_ia32_immediate_attr_const(right);
2677                         if (attr->symconst == 0
2678                                         && (unsigned) attr->offset
2679                                         <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2680                                 return true;
2681                         }
2682                 }
2683                 /* TODO recurse? */
2684         }
2685
2686         /* TODO recurse on Or, Xor, ... if appropriate? */
2687
2688         if (is_ia32_Immediate(transformed_node)
2689                         || is_ia32_Const(transformed_node)) {
2690                 const ia32_immediate_attr_t *attr
2691                         = get_ia32_immediate_attr_const(transformed_node);
2692                 if (mode_is_signed(mode)) {
2693                         long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2694                         if (shifted == 0 || shifted == -1)
2695                                 return true;
2696                 } else {
2697                         unsigned long shifted = (unsigned long) attr->offset;
2698                         shifted >>= get_mode_size_bits(mode);
2699                         if (shifted == 0)
2700                                 return true;
2701                 }
2702         }
2703
2704         return false;
2705 }
2706
2707 /**
2708  * Generate code for a Cmp.
2709  */
2710 static ir_node *gen_Cmp(ir_node *node)
2711 {
2712         dbg_info *dbgi      = get_irn_dbg_info(node);
2713         ir_node  *block     = get_nodes_block(node);
2714         ir_node  *new_block = be_transform_node(block);
2715         ir_node  *left      = get_Cmp_left(node);
2716         ir_node  *right     = get_Cmp_right(node);
2717         ir_mode  *cmp_mode  = get_irn_mode(left);
2718         ir_node  *new_node;
2719         ia32_address_mode_t  am;
2720         ia32_address_t      *addr = &am.addr;
2721         int                  cmp_unsigned;
2722
2723         if (mode_is_float(cmp_mode)) {
2724                 if (ia32_cg_config.use_sse2) {
2725                         return create_Ucomi(node);
2726                 } else {
2727                         return create_Fucom(node);
2728                 }
2729         }
2730
2731         assert(ia32_mode_needs_gp_reg(cmp_mode));
2732
2733         /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2734         cmp_unsigned = !mode_is_signed(cmp_mode);
2735         if (is_Const_0(right)          &&
2736             is_And(left)               &&
2737             get_irn_n_edges(left) == 1 &&
2738             can_fold_test_and(node)) {
2739                 /* Test(and_left, and_right) */
2740                 ir_node *and_left  = get_And_left(left);
2741                 ir_node *and_right = get_And_right(left);
2742
2743                 /* matze: code here used mode instead of cmd_mode, I think it is always
2744                  * the same as cmp_mode, but I leave this here to see if this is really
2745                  * true...
2746                  */
2747                 assert(get_irn_mode(and_left) == cmp_mode);
2748
2749                 match_arguments(&am, block, and_left, and_right, NULL,
2750                                                                                 match_commutative |
2751                                                                                 match_am | match_8bit_am | match_16bit_am |
2752                                                                                 match_am_and_immediates | match_immediate |
2753                                                                                 match_8bit | match_16bit);
2754
2755                 /* use 32bit compare mode if possible since the opcode is smaller */
2756                 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2757                     upper_bits_clean(am.new_op2, cmp_mode)) {
2758                         cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2759                 }
2760
2761                 if (get_mode_size_bits(cmp_mode) == 8) {
2762                         new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2763                                         addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2764                                         cmp_unsigned);
2765                 } else {
2766                         new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2767                                         addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2768                 }
2769         } else {
2770                 /* Cmp(left, right) */
2771                 match_arguments(&am, block, left, right, NULL,
2772                                 match_commutative | match_am | match_8bit_am |
2773                                 match_16bit_am | match_am_and_immediates |
2774                                 match_immediate | match_8bit | match_16bit);
2775                 /* use 32bit compare mode if possible since the opcode is smaller */
2776                 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2777                     upper_bits_clean(am.new_op2, cmp_mode)) {
2778                         cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2779                 }
2780
2781                 if (get_mode_size_bits(cmp_mode) == 8) {
2782                         new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2783                                                        addr->index, addr->mem, am.new_op1,
2784                                                        am.new_op2, am.ins_permuted,
2785                                                        cmp_unsigned);
2786                 } else {
2787                         new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2788                                         addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2789                 }
2790         }
2791         set_am_attributes(new_node, &am);
2792         set_ia32_ls_mode(new_node, cmp_mode);
2793
2794         SET_IA32_ORIG_NODE(new_node, node);
2795
2796         new_node = fix_mem_proj(new_node, &am);
2797
2798         return new_node;
2799 }
2800
2801 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2802                             pn_Cmp pnc)
2803 {
2804         dbg_info            *dbgi          = get_irn_dbg_info(node);
2805         ir_node             *block         = get_nodes_block(node);
2806         ir_node             *new_block     = be_transform_node(block);
2807         ir_node             *val_true      = get_Mux_true(node);
2808         ir_node             *val_false     = get_Mux_false(node);
2809         ir_node             *new_node;
2810         match_flags_t        match_flags;
2811         ia32_address_mode_t  am;
2812         ia32_address_t      *addr;
2813
2814         assert(ia32_cg_config.use_cmov);
2815         assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2816
2817         addr = &am.addr;
2818
2819         match_flags = match_commutative | match_am | match_16bit_am |
2820                       match_mode_neutral;
2821
2822         match_arguments(&am, block, val_false, val_true, flags, match_flags);
2823
2824         new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2825                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2826                                     am.ins_permuted, pnc);
2827         set_am_attributes(new_node, &am);
2828
2829         SET_IA32_ORIG_NODE(new_node, node);
2830
2831         new_node = fix_mem_proj(new_node, &am);
2832
2833         return new_node;
2834 }
2835
2836 /**
2837  * Creates a ia32 Setcc instruction.
2838  */
2839 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2840                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2841                                  int ins_permuted)
2842 {
2843         ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2844         ir_node *nomem = new_NoMem();
2845         ir_mode *mode  = get_irn_mode(orig_node);
2846         ir_node *new_node;
2847
2848         new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2849         SET_IA32_ORIG_NODE(new_node, orig_node);
2850
2851         /* we might need to conv the result up */
2852         if (get_mode_size_bits(mode) > 8) {
2853                 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2854                                                     nomem, new_node, mode_Bu);
2855                 SET_IA32_ORIG_NODE(new_node, orig_node);
2856         }
2857
2858         return new_node;
2859 }
2860
2861 /**
2862  * Create instruction for an unsigned Difference or Zero.
2863  */
2864 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2865 {
2866         ir_graph *irg   = current_ir_graph;
2867         ir_mode  *mode  = get_irn_mode(psi);
2868         ir_node  *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2869         dbg_info *dbgi;
2870
2871         new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2872                 match_mode_neutral | match_am | match_immediate | match_two_users);
2873
2874         block = get_nodes_block(new_node);
2875
2876         if (is_Proj(new_node)) {
2877                 sub = get_Proj_pred(new_node);
2878                 assert(is_ia32_Sub(sub));
2879         } else {
2880                 sub = new_node;
2881                 set_irn_mode(sub, mode_T);
2882                 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2883         }
2884         eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2885
2886         dbgi   = get_irn_dbg_info(psi);
2887         noreg  = ia32_new_NoReg_gp(env_cg);
2888         tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2889         nomem  = new_NoMem();
2890         sbb    = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2891
2892         new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2893         set_ia32_commutative(new_node);
2894         return new_node;
2895 }
2896
2897 /**
2898  * Transforms a Mux node into CMov.
2899  *
2900  * @return The transformed node.
2901  */
2902 static ir_node *gen_Mux(ir_node *node)
2903 {
2904         dbg_info *dbgi        = get_irn_dbg_info(node);
2905         ir_node  *block       = get_nodes_block(node);
2906         ir_node  *new_block   = be_transform_node(block);
2907         ir_node  *mux_true    = get_Mux_true(node);
2908         ir_node  *mux_false   = get_Mux_false(node);
2909         ir_node  *cond        = get_Mux_sel(node);
2910         ir_mode  *mode        = get_irn_mode(node);
2911         pn_Cmp   pnc;
2912
2913         assert(get_irn_mode(cond) == mode_b);
2914
2915         /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2916         if (mode_is_float(mode)) {
2917                 ir_node  *cmp         = get_Proj_pred(cond);
2918                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2919                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2920                 pn_Cmp   pnc          = get_Proj_proj(cond);
2921
2922                 if (ia32_cg_config.use_sse2) {
2923                         if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2924                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2925                                         /* Mux(a <= b, a, b) => MIN */
2926                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2927                                          match_commutative | match_am | match_two_users);
2928                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2929                                         /* Mux(a <= b, b, a) => MAX */
2930                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2931                                          match_commutative | match_am | match_two_users);
2932                                 }
2933                         } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2934                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2935                                         /* Mux(a >= b, a, b) => MAX */
2936                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2937                                          match_commutative | match_am | match_two_users);
2938                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2939                                         /* Mux(a >= b, b, a) => MIN */
2940                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2941                                          match_commutative | match_am | match_two_users);
2942                                 }
2943                         }
2944                 }
2945                 panic("cannot transform floating point Mux");
2946
2947         } else {
2948                 ir_node *flags;
2949                 ir_node *new_node;
2950
2951                 assert(ia32_mode_needs_gp_reg(mode));
2952
2953                 if (is_Proj(cond)) {
2954                         ir_node *cmp = get_Proj_pred(cond);
2955                         if (is_Cmp(cmp)) {
2956                                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2957                                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2958                                 pn_Cmp   pnc          = get_Proj_proj(cond);
2959
2960                                 /* check for unsigned Doz first */
2961                                 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2962                                         is_Const_0(mux_false) && is_Sub(mux_true) &&
2963                                         get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2964                                         /* Mux(a >=u b, a - b, 0) unsigned Doz */
2965                                         return create_Doz(node, cmp_left, cmp_right);
2966                                 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2967                                         is_Const_0(mux_true) && is_Sub(mux_false) &&
2968                                         get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2969                                         /* Mux(a <=u b, 0, a - b) unsigned Doz */
2970                                         return create_Doz(node, cmp_left, cmp_right);
2971                                 }
2972                         }
2973                 }
2974
2975                 flags = get_flags_node(cond, &pnc);
2976
2977                 if (is_Const(mux_true) && is_Const(mux_false)) {
2978                         /* both are const, good */
2979                         if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2980                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2981                         } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2982                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2983                         } else {
2984                                 /* Not that simple. */
2985                                 goto need_cmov;
2986                         }
2987                 } else {
2988 need_cmov:
2989                         new_node = create_CMov(node, cond, flags, pnc);
2990                 }
2991                 return new_node;
2992         }
2993 }
2994
2995
2996 /**
2997  * Create a conversion from x87 state register to general purpose.
2998  */
2999 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3000 {
3001         ir_node         *block      = be_transform_node(get_nodes_block(node));
3002         ir_node         *op         = get_Conv_op(node);
3003         ir_node         *new_op     = be_transform_node(op);
3004         ia32_code_gen_t *cg         = env_cg;
3005         ir_graph        *irg        = current_ir_graph;
3006         dbg_info        *dbgi       = get_irn_dbg_info(node);
3007         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
3008         ir_mode         *mode       = get_irn_mode(node);
3009         ir_node         *fist, *load, *mem;
3010
3011         mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3012         set_irn_pinned(fist, op_pin_state_floats);
3013         set_ia32_use_frame(fist);
3014         set_ia32_op_type(fist, ia32_AddrModeD);
3015
3016         assert(get_mode_size_bits(mode) <= 32);
3017         /* exception we can only store signed 32 bit integers, so for unsigned
3018            we store a 64bit (signed) integer and load the lower bits */
3019         if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3020                 set_ia32_ls_mode(fist, mode_Ls);
3021         } else {
3022                 set_ia32_ls_mode(fist, mode_Is);
3023         }
3024         SET_IA32_ORIG_NODE(fist, node);
3025
3026         /* do a Load */
3027         load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3028
3029         set_irn_pinned(load, op_pin_state_floats);
3030         set_ia32_use_frame(load);
3031         set_ia32_op_type(load, ia32_AddrModeS);
3032         set_ia32_ls_mode(load, mode_Is);
3033         if (get_ia32_ls_mode(fist) == mode_Ls) {
3034                 ia32_attr_t *attr = get_ia32_attr(load);
3035                 attr->data.need_64bit_stackent = 1;
3036         } else {
3037                 ia32_attr_t *attr = get_ia32_attr(load);
3038                 attr->data.need_32bit_stackent = 1;
3039         }
3040         SET_IA32_ORIG_NODE(load, node);
3041
3042         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3043 }
3044
3045 /**
3046  * Creates a x87 strict Conv by placing a Store and a Load
3047  */
3048 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3049 {
3050         ir_node  *block    = get_nodes_block(node);
3051         ir_graph *irg      = current_ir_graph;
3052         dbg_info *dbgi     = get_irn_dbg_info(node);
3053         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3054         ir_node  *nomem    = new_NoMem();
3055         ir_node  *frame    = get_irg_frame(irg);
3056         ir_node  *store, *load;
3057         ir_node  *new_node;
3058
3059         store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3060         set_ia32_use_frame(store);
3061         set_ia32_op_type(store, ia32_AddrModeD);
3062         SET_IA32_ORIG_NODE(store, node);
3063
3064         load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3065         set_ia32_use_frame(load);
3066         set_ia32_op_type(load, ia32_AddrModeS);
3067         SET_IA32_ORIG_NODE(load, node);
3068
3069         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3070         return new_node;
3071 }
3072
3073 /**
3074  * Create a conversion from general purpose to x87 register
3075  */
3076 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3077 {
3078         ir_node  *src_block = get_nodes_block(node);
3079         ir_node  *block     = be_transform_node(src_block);
3080         ir_graph *irg       = current_ir_graph;
3081         dbg_info *dbgi      = get_irn_dbg_info(node);
3082         ir_node  *op        = get_Conv_op(node);
3083         ir_node  *new_op    = NULL;
3084         ir_node  *noreg;
3085         ir_node  *nomem;
3086         ir_mode  *mode;
3087         ir_mode  *store_mode;
3088         ir_node  *fild;
3089         ir_node  *store;
3090         ir_node  *new_node;
3091         int       src_bits;
3092
3093         /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3094         if (src_mode == mode_Is || src_mode == mode_Hs) {
3095                 ia32_address_mode_t am;
3096
3097                 match_arguments(&am, src_block, NULL, op, NULL,
3098                                 match_am | match_try_am | match_16bit | match_16bit_am);
3099                 if (am.op_type == ia32_AddrModeS) {
3100                         ia32_address_t *addr = &am.addr;
3101
3102                         fild     = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3103                                         addr->mem);
3104                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
3105                                               pn_ia32_vfild_res);
3106
3107                         set_am_attributes(fild, &am);
3108                         SET_IA32_ORIG_NODE(fild, node);
3109
3110                         fix_mem_proj(fild, &am);
3111
3112                         return new_node;
3113                 }
3114         }
3115         if (new_op == NULL) {
3116                 new_op = be_transform_node(op);
3117         }
3118
3119         noreg  = ia32_new_NoReg_gp(env_cg);
3120         nomem  = new_NoMem();
3121         mode   = get_irn_mode(op);
3122
3123         /* first convert to 32 bit signed if necessary */
3124         src_bits = get_mode_size_bits(src_mode);
3125         if (src_bits == 8) {
3126                 new_op = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg, noreg, nomem,
3127                                                   new_op, src_mode);
3128                 SET_IA32_ORIG_NODE(new_op, node);
3129                 mode = mode_Is;
3130         } else if (src_bits < 32) {
3131                 new_op = new_bd_ia32_Conv_I2I(dbgi, block, noreg, noreg, nomem,
3132                                               new_op, src_mode);
3133                 SET_IA32_ORIG_NODE(new_op, node);
3134                 mode = mode_Is;
3135         }
3136
3137         assert(get_mode_size_bits(mode) == 32);
3138
3139         /* do a store */
3140         store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3141                                   new_op);
3142
3143         set_ia32_use_frame(store);
3144         set_ia32_op_type(store, ia32_AddrModeD);
3145         set_ia32_ls_mode(store, mode_Iu);
3146
3147         /* exception for 32bit unsigned, do a 64bit spill+load */
3148         if (!mode_is_signed(mode)) {
3149                 ir_node *in[2];
3150                 /* store a zero */
3151                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3152
3153                 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3154                                 noreg, nomem, zero_const);
3155
3156                 set_ia32_use_frame(zero_store);
3157                 set_ia32_op_type(zero_store, ia32_AddrModeD);
3158                 add_ia32_am_offs_int(zero_store, 4);
3159                 set_ia32_ls_mode(zero_store, mode_Iu);
3160
3161                 in[0] = zero_store;
3162                 in[1] = store;
3163
3164                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
3165                 store_mode = mode_Ls;
3166         } else {
3167                 store_mode = mode_Is;
3168         }
3169
3170         /* do a fild */
3171         fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3172
3173         set_ia32_use_frame(fild);
3174         set_ia32_op_type(fild, ia32_AddrModeS);
3175         set_ia32_ls_mode(fild, store_mode);
3176
3177         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3178
3179         return new_node;
3180 }
3181
3182 /**
3183  * Create a conversion from one integer mode into another one
3184  */
3185 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3186                                 dbg_info *dbgi, ir_node *block, ir_node *op,
3187                                 ir_node *node)
3188 {
3189         int       src_bits  = get_mode_size_bits(src_mode);
3190         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3191         ir_node  *new_block = be_transform_node(block);
3192         ir_node  *new_node;
3193         ir_mode  *smaller_mode;
3194         int       smaller_bits;
3195         ia32_address_mode_t  am;
3196         ia32_address_t      *addr = &am.addr;
3197
3198         (void) node;
3199         if (src_bits < tgt_bits) {
3200                 smaller_mode = src_mode;
3201                 smaller_bits = src_bits;
3202         } else {
3203                 smaller_mode = tgt_mode;
3204                 smaller_bits = tgt_bits;
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_8bit | match_16bit |
3216                         match_am | match_8bit_am | match_16bit_am);
3217
3218         if (upper_bits_clean(am.new_op2, smaller_mode)) {
3219                 /* unnecessary conv. in theory it shouldn't have been AM */
3220                 assert(is_ia32_NoReg_GP(addr->base));
3221                 assert(is_ia32_NoReg_GP(addr->index));
3222                 assert(is_NoMem(addr->mem));
3223                 assert(am.addr.offset == 0);
3224                 assert(am.addr.symconst_ent == NULL);
3225                 return am.new_op2;
3226         }
3227
3228         if (smaller_bits == 8) {
3229                 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, addr->base,
3230                                                     addr->index, addr->mem, am.new_op2,
3231                                                     smaller_mode);
3232         } else {
3233                 new_node = new_bd_ia32_Conv_I2I(dbgi, new_block, addr->base,
3234                                                 addr->index, addr->mem, am.new_op2,
3235                                                 smaller_mode);
3236         }
3237         set_am_attributes(new_node, &am);
3238         /* match_arguments assume that out-mode = in-mode, this isn't true here
3239          * so fix it */
3240         set_ia32_ls_mode(new_node, smaller_mode);
3241         SET_IA32_ORIG_NODE(new_node, node);
3242         new_node = fix_mem_proj(new_node, &am);
3243         return new_node;
3244 }
3245
3246 /**
3247  * Transforms a Conv node.
3248  *
3249  * @return The created ia32 Conv node
3250  */
3251 static ir_node *gen_Conv(ir_node *node)
3252 {
3253         ir_node  *block     = get_nodes_block(node);
3254         ir_node  *new_block = be_transform_node(block);
3255         ir_node  *op        = get_Conv_op(node);
3256         ir_node  *new_op    = NULL;
3257         dbg_info *dbgi      = get_irn_dbg_info(node);
3258         ir_mode  *src_mode  = get_irn_mode(op);
3259         ir_mode  *tgt_mode  = get_irn_mode(node);
3260         int       src_bits  = get_mode_size_bits(src_mode);
3261         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3262         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
3263         ir_node  *nomem     = new_NoMem();
3264         ir_node  *res       = NULL;
3265
3266         if (src_mode == mode_b) {
3267                 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3268                 /* nothing to do, we already model bools as 0/1 ints */
3269                 return be_transform_node(op);
3270         }
3271
3272         if (src_mode == tgt_mode) {
3273                 if (get_Conv_strict(node)) {
3274                         if (ia32_cg_config.use_sse2) {
3275                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
3276                                 return be_transform_node(op);
3277                         }
3278                 } else {
3279                         /* this should be optimized already, but who knows... */
3280                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3281                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3282                         return be_transform_node(op);
3283                 }
3284         }
3285
3286         if (mode_is_float(src_mode)) {
3287                 new_op = be_transform_node(op);
3288                 /* we convert from float ... */
3289                 if (mode_is_float(tgt_mode)) {
3290                         if (src_mode == mode_E && tgt_mode == mode_D
3291                                         && !get_Conv_strict(node)) {
3292                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3293                                 return new_op;
3294                         }
3295
3296                         /* ... to float */
3297                         if (ia32_cg_config.use_sse2) {
3298                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3299                                 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3300                                                              nomem, new_op);
3301                                 set_ia32_ls_mode(res, tgt_mode);
3302                         } else {
3303                                 if (get_Conv_strict(node)) {
3304                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3305                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3306                                         return res;
3307                                 }
3308                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3309                                 return new_op;
3310                         }
3311                 } else {
3312                         /* ... to int */
3313                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3314                         if (ia32_cg_config.use_sse2) {
3315                                 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3316                                                             nomem, new_op);
3317                                 set_ia32_ls_mode(res, src_mode);
3318                         } else {
3319                                 return gen_x87_fp_to_gp(node);
3320                         }
3321                 }
3322         } else {
3323                 /* we convert from int ... */
3324                 if (mode_is_float(tgt_mode)) {
3325                         /* ... to float */
3326                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3327                         if (ia32_cg_config.use_sse2) {
3328                                 new_op = be_transform_node(op);
3329                                 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3330                                                             nomem, new_op);
3331                                 set_ia32_ls_mode(res, tgt_mode);
3332                         } else {
3333                                 res = gen_x87_gp_to_fp(node, src_mode);
3334                                 if (get_Conv_strict(node)) {
3335                                         /* The strict-Conv is only necessary, if the int mode has more bits
3336                                          * than the float mantissa */
3337                                         size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3338                                         size_t float_mantissa;
3339                                         /* FIXME There is no way to get the mantissa size of a mode */
3340                                         switch (get_mode_size_bits(tgt_mode)) {
3341                                                 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3342                                                 case 64: float_mantissa = 52 + 1; break;
3343                                                 case 80:
3344                                                 case 96: float_mantissa = 64;     break;
3345                                                 default: float_mantissa = 0;      break;
3346                                         }
3347                                         if (float_mantissa < int_mantissa) {
3348                                                 res = gen_x87_strict_conv(tgt_mode, res);
3349                                                 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3350                                         }
3351                                 }
3352                                 return res;
3353                         }
3354                 } else if (tgt_mode == mode_b) {
3355                         /* mode_b lowering already took care that we only have 0/1 values */
3356                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3357                             src_mode, tgt_mode));
3358                         return be_transform_node(op);
3359                 } else {
3360                         /* to int */
3361                         if (src_bits == tgt_bits) {
3362                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3363                                     src_mode, tgt_mode));
3364                                 return be_transform_node(op);
3365                         }
3366
3367                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3368                         return res;
3369                 }
3370         }
3371
3372         return res;
3373 }
3374
3375 static ir_node *create_immediate_or_transform(ir_node *node,
3376                                               char immediate_constraint_type)
3377 {
3378         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3379         if (new_node == NULL) {
3380                 new_node = be_transform_node(node);
3381         }
3382         return new_node;
3383 }
3384
3385 /**
3386  * Transforms a FrameAddr into an ia32 Add.
3387  */
3388 static ir_node *gen_be_FrameAddr(ir_node *node)
3389 {
3390         ir_node  *block  = be_transform_node(get_nodes_block(node));
3391         ir_node  *op     = be_get_FrameAddr_frame(node);
3392         ir_node  *new_op = be_transform_node(op);
3393         dbg_info *dbgi   = get_irn_dbg_info(node);
3394         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
3395         ir_node  *new_node;
3396
3397         new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3398         set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3399         set_ia32_use_frame(new_node);
3400
3401         SET_IA32_ORIG_NODE(new_node, node);
3402
3403         return new_node;
3404 }
3405
3406 /**
3407  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3408  */
3409 static ir_node *gen_be_Return(ir_node *node)
3410 {
3411         ir_graph  *irg     = current_ir_graph;
3412         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
3413         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
3414         ir_entity *ent     = get_irg_entity(irg);
3415         ir_type   *tp      = get_entity_type(ent);
3416         dbg_info  *dbgi;
3417         ir_node   *block;
3418         ir_type   *res_type;
3419         ir_mode   *mode;
3420         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
3421         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
3422         ir_node   *noreg;
3423         ir_node   **in;
3424         int       pn_ret_val, pn_ret_mem, arity, i;
3425
3426         assert(ret_val != NULL);
3427         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3428                 return be_duplicate_node(node);
3429         }
3430
3431         res_type = get_method_res_type(tp, 0);
3432
3433         if (! is_Primitive_type(res_type)) {
3434                 return be_duplicate_node(node);
3435         }
3436
3437         mode = get_type_mode(res_type);
3438         if (! mode_is_float(mode)) {
3439                 return be_duplicate_node(node);
3440         }
3441
3442         assert(get_method_n_ress(tp) == 1);
3443
3444         pn_ret_val = get_Proj_proj(ret_val);
3445         pn_ret_mem = get_Proj_proj(ret_mem);
3446
3447         /* get the Barrier */
3448         barrier = get_Proj_pred(ret_val);
3449
3450         /* get result input of the Barrier */
3451         ret_val     = get_irn_n(barrier, pn_ret_val);
3452         new_ret_val = be_transform_node(ret_val);
3453
3454         /* get memory input of the Barrier */
3455         ret_mem     = get_irn_n(barrier, pn_ret_mem);
3456         new_ret_mem = be_transform_node(ret_mem);
3457
3458         frame = get_irg_frame(irg);
3459
3460         dbgi  = get_irn_dbg_info(barrier);
3461         block = be_transform_node(get_nodes_block(barrier));
3462
3463         noreg = ia32_new_NoReg_gp(env_cg);
3464
3465         /* store xmm0 onto stack */
3466         sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3467                                              new_ret_mem, new_ret_val);
3468         set_ia32_ls_mode(sse_store, mode);
3469         set_ia32_op_type(sse_store, ia32_AddrModeD);
3470         set_ia32_use_frame(sse_store);
3471
3472         /* load into x87 register */
3473         fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3474         set_ia32_op_type(fld, ia32_AddrModeS);
3475         set_ia32_use_frame(fld);
3476
3477         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3478         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3479
3480         /* create a new barrier */
3481         arity = get_irn_arity(barrier);
3482         in    = ALLOCAN(ir_node*, arity);
3483         for (i = 0; i < arity; ++i) {
3484                 ir_node *new_in;
3485
3486                 if (i == pn_ret_val) {
3487                         new_in = fld;
3488                 } else if (i == pn_ret_mem) {
3489                         new_in = mproj;
3490                 } else {
3491                         ir_node *in = get_irn_n(barrier, i);
3492                         new_in = be_transform_node(in);
3493                 }
3494                 in[i] = new_in;
3495         }
3496
3497         new_barrier = new_ir_node(dbgi, irg, block,
3498                                   get_irn_op(barrier), get_irn_mode(barrier),
3499                                   arity, in);
3500         copy_node_attr(barrier, new_barrier);
3501         be_duplicate_deps(barrier, new_barrier);
3502         be_set_transformed_node(barrier, new_barrier);
3503
3504         /* transform normally */
3505         return be_duplicate_node(node);
3506 }
3507
3508 /**
3509  * Transform a be_AddSP into an ia32_SubSP.
3510  */
3511 static ir_node *gen_be_AddSP(ir_node *node)
3512 {
3513         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
3514         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3515
3516         return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3517                          match_am | match_immediate);
3518 }
3519
3520 /**
3521  * Transform a be_SubSP into an ia32_AddSP
3522  */
3523 static ir_node *gen_be_SubSP(ir_node *node)
3524 {
3525         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
3526         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3527
3528         return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3529                          match_am | match_immediate);
3530 }
3531
3532 /**
3533  * Change some phi modes
3534  */
3535 static ir_node *gen_Phi(ir_node *node)
3536 {
3537         ir_node  *block = be_transform_node(get_nodes_block(node));
3538         ir_graph *irg   = current_ir_graph;
3539         dbg_info *dbgi  = get_irn_dbg_info(node);
3540         ir_mode  *mode  = get_irn_mode(node);
3541         ir_node  *phi;
3542
3543         if (ia32_mode_needs_gp_reg(mode)) {
3544                 /* we shouldn't have any 64bit stuff around anymore */
3545                 assert(get_mode_size_bits(mode) <= 32);
3546                 /* all integer operations are on 32bit registers now */
3547                 mode = mode_Iu;
3548         } else if (mode_is_float(mode)) {
3549                 if (ia32_cg_config.use_sse2) {
3550                         mode = mode_xmm;
3551                 } else {
3552                         mode = mode_vfp;
3553                 }
3554         }
3555
3556         /* phi nodes allow loops, so we use the old arguments for now
3557          * and fix this later */
3558         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3559                           get_irn_in(node) + 1);
3560         copy_node_attr(node, phi);
3561         be_duplicate_deps(node, phi);
3562
3563         be_enqueue_preds(node);
3564
3565         return phi;
3566 }
3567
3568 /**
3569  * Transform IJmp
3570  */
3571 static ir_node *gen_IJmp(ir_node *node)
3572 {
3573         ir_node  *block     = get_nodes_block(node);
3574         ir_node  *new_block = be_transform_node(block);
3575         dbg_info *dbgi      = get_irn_dbg_info(node);
3576         ir_node  *op        = get_IJmp_target(node);
3577         ir_node  *new_node;
3578         ia32_address_mode_t  am;
3579         ia32_address_t      *addr = &am.addr;
3580
3581         assert(get_irn_mode(op) == mode_P);
3582
3583         match_arguments(&am, block, NULL, op, NULL,
3584                         match_am | match_8bit_am | match_16bit_am |
3585                         match_immediate | match_8bit | match_16bit);
3586
3587         new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3588                         addr->mem, am.new_op2);
3589         set_am_attributes(new_node, &am);
3590         SET_IA32_ORIG_NODE(new_node, node);
3591
3592         new_node = fix_mem_proj(new_node, &am);
3593
3594         return new_node;
3595 }
3596
3597 /**
3598  * Transform a Bound node.
3599  */
3600 static ir_node *gen_Bound(ir_node *node)
3601 {
3602         ir_node  *new_node;
3603         ir_node  *lower = get_Bound_lower(node);
3604         dbg_info *dbgi  = get_irn_dbg_info(node);
3605
3606         if (is_Const_0(lower)) {
3607                 /* typical case for Java */
3608                 ir_node  *sub, *res, *flags, *block;
3609                 ir_graph *irg  = current_ir_graph;
3610
3611                 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3612                         new_bd_ia32_Sub, match_mode_neutral     | match_am | match_immediate);
3613
3614                 block = get_nodes_block(res);
3615                 if (! is_Proj(res)) {
3616                         sub = res;
3617                         set_irn_mode(sub, mode_T);
3618                         res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3619                 } else {
3620                         sub = get_Proj_pred(res);
3621                 }
3622                 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3623                 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3624                 SET_IA32_ORIG_NODE(new_node, node);
3625         } else {
3626                 panic("generic Bound not supported in ia32 Backend");
3627         }
3628         return new_node;
3629 }
3630
3631
3632 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3633 {
3634         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
3635         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3636
3637         return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3638                                match_immediate | match_mode_neutral);
3639 }
3640
3641 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3642 {
3643         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
3644         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3645         return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3646                                match_immediate);
3647 }
3648
3649 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3650 {
3651         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
3652         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3653         return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3654                                match_immediate);
3655 }
3656
3657 static ir_node *gen_ia32_l_Add(ir_node *node)
3658 {
3659         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
3660         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
3661         ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3662                         match_commutative | match_am | match_immediate |
3663                         match_mode_neutral);
3664
3665         if (is_Proj(lowered)) {
3666                 lowered = get_Proj_pred(lowered);
3667         } else {
3668                 assert(is_ia32_Add(lowered));
3669                 set_irn_mode(lowered, mode_T);
3670         }
3671
3672         return lowered;
3673 }
3674
3675 static ir_node *gen_ia32_l_Adc(ir_node *node)
3676 {
3677         return gen_binop_flags(node, new_bd_ia32_Adc,
3678                         match_commutative | match_am | match_immediate |
3679                         match_mode_neutral);
3680 }
3681
3682 /**
3683  * Transforms a l_MulS into a "real" MulS node.
3684  *
3685  * @return the created ia32 Mul node
3686  */
3687 static ir_node *gen_ia32_l_Mul(ir_node *node)
3688 {
3689         ir_node *left  = get_binop_left(node);
3690         ir_node *right = get_binop_right(node);
3691
3692         return gen_binop(node, left, right, new_bd_ia32_Mul,
3693                          match_commutative | match_am | match_mode_neutral);
3694 }
3695
3696 /**
3697  * Transforms a l_IMulS into a "real" IMul1OPS node.
3698  *
3699  * @return the created ia32 IMul1OP node
3700  */
3701 static ir_node *gen_ia32_l_IMul(ir_node *node)
3702 {
3703         ir_node  *left  = get_binop_left(node);
3704         ir_node  *right = get_binop_right(node);
3705
3706         return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3707                          match_commutative | match_am | match_mode_neutral);
3708 }
3709
3710 static ir_node *gen_ia32_l_Sub(ir_node *node)
3711 {
3712         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
3713         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3714         ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3715                         match_am | match_immediate | match_mode_neutral);
3716
3717         if (is_Proj(lowered)) {
3718                 lowered = get_Proj_pred(lowered);
3719         } else {
3720                 assert(is_ia32_Sub(lowered));
3721                 set_irn_mode(lowered, mode_T);
3722         }
3723
3724         return lowered;
3725 }
3726
3727 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3728 {
3729         return gen_binop_flags(node, new_bd_ia32_Sbb,
3730                         match_am | match_immediate | match_mode_neutral);
3731 }
3732
3733 /**
3734  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3735  * op1 - target to be shifted
3736  * op2 - contains bits to be shifted into target
3737  * op3 - shift count
3738  * Only op3 can be an immediate.
3739  */
3740 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3741                                          ir_node *low, ir_node *count)
3742 {
3743         ir_node  *block     = get_nodes_block(node);
3744         ir_node  *new_block = be_transform_node(block);
3745         dbg_info *dbgi      = get_irn_dbg_info(node);
3746         ir_node  *new_high  = be_transform_node(high);
3747         ir_node  *new_low   = be_transform_node(low);
3748         ir_node  *new_count;
3749         ir_node  *new_node;
3750
3751         /* the shift amount can be any mode that is bigger than 5 bits, since all
3752          * other bits are ignored anyway */
3753         while (is_Conv(count)              &&
3754                get_irn_n_edges(count) == 1 &&
3755                mode_is_int(get_irn_mode(count))) {
3756                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3757                 count = get_Conv_op(count);
3758         }
3759         new_count = create_immediate_or_transform(count, 0);
3760
3761         if (is_ia32_l_ShlD(node)) {
3762                 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3763                                             new_count);
3764         } else {
3765                 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3766                                             new_count);
3767         }
3768         SET_IA32_ORIG_NODE(new_node, node);
3769
3770         return new_node;
3771 }
3772
3773 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3774 {
3775         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
3776         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
3777         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3778         return gen_lowered_64bit_shifts(node, high, low, count);
3779 }
3780
3781 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3782 {
3783         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
3784         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
3785         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3786         return gen_lowered_64bit_shifts(node, high, low, count);
3787 }
3788
3789 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3790 {
3791         ir_node  *src_block    = get_nodes_block(node);
3792         ir_node  *block        = be_transform_node(src_block);
3793         ir_graph *irg          = current_ir_graph;
3794         dbg_info *dbgi         = get_irn_dbg_info(node);
3795         ir_node  *frame        = get_irg_frame(irg);
3796         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
3797         ir_node  *nomem        = new_NoMem();
3798         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3799         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3800         ir_node  *new_val_low  = be_transform_node(val_low);
3801         ir_node  *new_val_high = be_transform_node(val_high);
3802         ir_node  *in[2];
3803         ir_node  *sync;
3804         ir_node  *fild;
3805         ir_node  *store_low;
3806         ir_node  *store_high;
3807
3808         if (!mode_is_signed(get_irn_mode(val_high))) {
3809                 panic("unsigned long long -> float not supported yet (%+F)", node);
3810         }
3811
3812         /* do a store */
3813         store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3814                                       new_val_low);
3815         store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3816                                        new_val_high);
3817         SET_IA32_ORIG_NODE(store_low,  node);
3818         SET_IA32_ORIG_NODE(store_high, node);
3819
3820         set_ia32_use_frame(store_low);
3821         set_ia32_use_frame(store_high);
3822         set_ia32_op_type(store_low, ia32_AddrModeD);
3823         set_ia32_op_type(store_high, ia32_AddrModeD);
3824         set_ia32_ls_mode(store_low, mode_Iu);
3825         set_ia32_ls_mode(store_high, mode_Is);
3826         add_ia32_am_offs_int(store_high, 4);
3827
3828         in[0] = store_low;
3829         in[1] = store_high;
3830         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
3831
3832         /* do a fild */
3833         fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3834
3835         set_ia32_use_frame(fild);
3836         set_ia32_op_type(fild, ia32_AddrModeS);
3837         set_ia32_ls_mode(fild, mode_Ls);
3838
3839         SET_IA32_ORIG_NODE(fild, node);
3840
3841         return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3842 }
3843
3844 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3845 {
3846         ir_node  *src_block  = get_nodes_block(node);
3847         ir_node  *block      = be_transform_node(src_block);
3848         ir_graph *irg        = current_ir_graph;
3849         dbg_info *dbgi       = get_irn_dbg_info(node);
3850         ir_node  *frame      = get_irg_frame(irg);
3851         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
3852         ir_node  *nomem      = new_NoMem();
3853         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
3854         ir_node  *new_val    = be_transform_node(val);
3855         ir_node  *fist, *mem;
3856
3857         mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3858         SET_IA32_ORIG_NODE(fist, node);
3859         set_ia32_use_frame(fist);
3860         set_ia32_op_type(fist, ia32_AddrModeD);
3861         set_ia32_ls_mode(fist, mode_Ls);
3862
3863         return mem;
3864 }
3865
3866 /**
3867  * the BAD transformer.
3868  */
3869 static ir_node *bad_transform(ir_node *node)
3870 {
3871         panic("No transform function for %+F available.", node);
3872         return NULL;
3873 }
3874
3875 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3876 {
3877         ir_graph *irg      = current_ir_graph;
3878         ir_node  *block    = be_transform_node(get_nodes_block(node));
3879         ir_node  *pred     = get_Proj_pred(node);
3880         ir_node  *new_pred = be_transform_node(pred);
3881         ir_node  *frame    = get_irg_frame(irg);
3882         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3883         dbg_info *dbgi     = get_irn_dbg_info(node);
3884         long      pn       = get_Proj_proj(node);
3885         ir_node  *load;
3886         ir_node  *proj;
3887         ia32_attr_t *attr;
3888
3889         load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3890         SET_IA32_ORIG_NODE(load, node);
3891         set_ia32_use_frame(load);
3892         set_ia32_op_type(load, ia32_AddrModeS);
3893         set_ia32_ls_mode(load, mode_Iu);
3894         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3895          * 32 bit from it with this particular load */
3896         attr = get_ia32_attr(load);
3897         attr->data.need_64bit_stackent = 1;
3898
3899         if (pn == pn_ia32_l_FloattoLL_res_high) {
3900                 add_ia32_am_offs_int(load, 4);
3901         } else {
3902                 assert(pn == pn_ia32_l_FloattoLL_res_low);
3903         }
3904
3905         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3906
3907         return proj;
3908 }
3909
3910 /**
3911  * Transform the Projs of an AddSP.
3912  */
3913 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3914 {
3915         ir_node  *block    = be_transform_node(get_nodes_block(node));
3916         ir_node  *pred     = get_Proj_pred(node);
3917         ir_node  *new_pred = be_transform_node(pred);
3918         ir_graph *irg      = current_ir_graph;
3919         dbg_info *dbgi     = get_irn_dbg_info(node);
3920         long     proj      = get_Proj_proj(node);
3921
3922         if (proj == pn_be_AddSP_sp) {
3923                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3924                                            pn_ia32_SubSP_stack);
3925                 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3926                 return res;
3927         } else if (proj == pn_be_AddSP_res) {
3928                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3929                                    pn_ia32_SubSP_addr);
3930         } else if (proj == pn_be_AddSP_M) {
3931                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3932         }
3933
3934         panic("No idea how to transform proj->AddSP");
3935 }
3936
3937 /**
3938  * Transform the Projs of a SubSP.
3939  */
3940 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3941 {
3942         ir_node  *block    = be_transform_node(get_nodes_block(node));
3943         ir_node  *pred     = get_Proj_pred(node);
3944         ir_node  *new_pred = be_transform_node(pred);
3945         ir_graph *irg      = current_ir_graph;
3946         dbg_info *dbgi     = get_irn_dbg_info(node);
3947         long     proj      = get_Proj_proj(node);
3948
3949         if (proj == pn_be_SubSP_sp) {
3950                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3951                                            pn_ia32_AddSP_stack);
3952                 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3953                 return res;
3954         } else if (proj == pn_be_SubSP_M) {
3955                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3956         }
3957
3958         panic("No idea how to transform proj->SubSP");
3959 }
3960
3961 /**
3962  * Transform and renumber the Projs from a Load.
3963  */
3964 static ir_node *gen_Proj_Load(ir_node *node)
3965 {
3966         ir_node  *new_pred;
3967         ir_node  *block    = be_transform_node(get_nodes_block(node));
3968         ir_node  *pred     = get_Proj_pred(node);
3969         ir_graph *irg      = current_ir_graph;
3970         dbg_info *dbgi     = get_irn_dbg_info(node);
3971         long     proj      = get_Proj_proj(node);
3972
3973         /* loads might be part of source address mode matches, so we don't
3974          * transform the ProjMs yet (with the exception of loads whose result is
3975          * not used)
3976          */
3977         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3978                 ir_node *res;
3979
3980                 /* this is needed, because sometimes we have loops that are only
3981                    reachable through the ProjM */
3982                 be_enqueue_preds(node);
3983                 /* do it in 2 steps, to silence firm verifier */
3984                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3985                 set_Proj_proj(res, pn_ia32_mem);
3986                 return res;
3987         }
3988
3989         /* renumber the proj */
3990         new_pred = be_transform_node(pred);
3991         if (is_ia32_Load(new_pred)) {
3992                 switch (proj) {
3993                 case pn_Load_res:
3994                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3995                 case pn_Load_M:
3996                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3997                 case pn_Load_X_regular:
3998                         return new_rd_Jmp(dbgi, irg, block);
3999                 case pn_Load_X_except:
4000                         /* This Load might raise an exception. Mark it. */
4001                         set_ia32_exc_label(new_pred, 1);
4002                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4003                 default:
4004                         break;
4005                 }
4006         } else if (is_ia32_Conv_I2I(new_pred) ||
4007                    is_ia32_Conv_I2I8Bit(new_pred)) {
4008                 set_irn_mode(new_pred, mode_T);
4009                 if (proj == pn_Load_res) {
4010                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4011                 } else if (proj == pn_Load_M) {
4012                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4013                 }
4014         } else if (is_ia32_xLoad(new_pred)) {
4015                 switch (proj) {
4016                 case pn_Load_res:
4017                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4018                 case pn_Load_M:
4019                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4020                 case pn_Load_X_regular:
4021                         return new_rd_Jmp(dbgi, irg, block);
4022                 case pn_Load_X_except:
4023                         /* This Load might raise an exception. Mark it. */
4024                         set_ia32_exc_label(new_pred, 1);
4025                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4026                 default:
4027                         break;
4028                 }
4029         } else if (is_ia32_vfld(new_pred)) {
4030                 switch (proj) {
4031                 case pn_Load_res:
4032                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4033                 case pn_Load_M:
4034                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4035                 case pn_Load_X_regular:
4036                         return new_rd_Jmp(dbgi, irg, block);
4037                 case pn_Load_X_except:
4038                         /* This Load might raise an exception. Mark it. */
4039                         set_ia32_exc_label(new_pred, 1);
4040                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4041                 default:
4042                         break;
4043                 }
4044         } else {
4045                 /* can happen for ProJMs when source address mode happened for the
4046                    node */
4047
4048                 /* however it should not be the result proj, as that would mean the
4049                    load had multiple users and should not have been used for
4050                    SourceAM */
4051                 if (proj != pn_Load_M) {
4052                         panic("internal error: transformed node not a Load");
4053                 }
4054                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4055         }
4056
4057         panic("No idea how to transform proj");
4058 }
4059
4060 /**
4061  * Transform and renumber the Projs from a DivMod like instruction.
4062  */
4063 static ir_node *gen_Proj_DivMod(ir_node *node)
4064 {
4065         ir_node  *block    = be_transform_node(get_nodes_block(node));
4066         ir_node  *pred     = get_Proj_pred(node);
4067         ir_node  *new_pred = be_transform_node(pred);
4068         ir_graph *irg      = current_ir_graph;
4069         dbg_info *dbgi     = get_irn_dbg_info(node);
4070         long     proj      = get_Proj_proj(node);
4071
4072         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4073
4074         switch (get_irn_opcode(pred)) {
4075         case iro_Div:
4076                 switch (proj) {
4077                 case pn_Div_M:
4078                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4079                 case pn_Div_res:
4080                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4081                 case pn_Div_X_regular:
4082                         return new_rd_Jmp(dbgi, irg, block);
4083                 case pn_Div_X_except:
4084                         set_ia32_exc_label(new_pred, 1);
4085                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4086                 default:
4087                         break;
4088                 }
4089                 break;
4090         case iro_Mod:
4091                 switch (proj) {
4092                 case pn_Mod_M:
4093                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4094                 case pn_Mod_res:
4095                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4096                 case pn_Mod_X_except:
4097                         set_ia32_exc_label(new_pred, 1);
4098                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4099                 default:
4100                         break;
4101                 }
4102                 break;
4103         case iro_DivMod:
4104                 switch (proj) {
4105                 case pn_DivMod_M:
4106                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4107                 case pn_DivMod_res_div:
4108                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4109                 case pn_DivMod_res_mod:
4110                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4111                 case pn_DivMod_X_regular:
4112                         return new_rd_Jmp(dbgi, irg, block);
4113                 case pn_DivMod_X_except:
4114                         set_ia32_exc_label(new_pred, 1);
4115                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4116                 default:
4117                         break;
4118                 }
4119                 break;
4120         default:
4121                 break;
4122         }
4123
4124         panic("No idea how to transform proj->DivMod");
4125 }
4126
4127 /**
4128  * Transform and renumber the Projs from a CopyB.
4129  */
4130 static ir_node *gen_Proj_CopyB(ir_node *node)
4131 {
4132         ir_node  *block    = be_transform_node(get_nodes_block(node));
4133         ir_node  *pred     = get_Proj_pred(node);
4134         ir_node  *new_pred = be_transform_node(pred);
4135         ir_graph *irg      = current_ir_graph;
4136         dbg_info *dbgi     = get_irn_dbg_info(node);
4137         long     proj      = get_Proj_proj(node);
4138
4139         switch (proj) {
4140         case pn_CopyB_M_regular:
4141                 if (is_ia32_CopyB_i(new_pred)) {
4142                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4143                 } else if (is_ia32_CopyB(new_pred)) {
4144                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4145                 }
4146                 break;
4147         default:
4148                 break;
4149         }
4150
4151         panic("No idea how to transform proj->CopyB");
4152 }
4153
4154 /**
4155  * Transform and renumber the Projs from a Quot.
4156  */
4157 static ir_node *gen_Proj_Quot(ir_node *node)
4158 {
4159         ir_node  *block    = be_transform_node(get_nodes_block(node));
4160         ir_node  *pred     = get_Proj_pred(node);
4161         ir_node  *new_pred = be_transform_node(pred);
4162         ir_graph *irg      = current_ir_graph;
4163         dbg_info *dbgi     = get_irn_dbg_info(node);
4164         long     proj      = get_Proj_proj(node);
4165
4166         switch (proj) {
4167         case pn_Quot_M:
4168                 if (is_ia32_xDiv(new_pred)) {
4169                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4170                 } else if (is_ia32_vfdiv(new_pred)) {
4171                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4172                 }
4173                 break;
4174         case pn_Quot_res:
4175                 if (is_ia32_xDiv(new_pred)) {
4176                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4177                 } else if (is_ia32_vfdiv(new_pred)) {
4178                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4179                 }
4180                 break;
4181         case pn_Quot_X_regular:
4182         case pn_Quot_X_except:
4183         default:
4184                 break;
4185         }
4186
4187         panic("No idea how to transform proj->Quot");
4188 }
4189
4190 static ir_node *gen_be_Call(ir_node *node)
4191 {
4192         dbg_info       *const dbgi      = get_irn_dbg_info(node);
4193         ir_graph       *const irg       = current_ir_graph;
4194         ir_node        *const src_block = get_nodes_block(node);
4195         ir_node        *const block     = be_transform_node(src_block);
4196         ir_node        *const src_mem   = get_irn_n(node, be_pos_Call_mem);
4197         ir_node        *const src_sp    = get_irn_n(node, be_pos_Call_sp);
4198         ir_node        *const sp        = be_transform_node(src_sp);
4199         ir_node        *const src_ptr   = get_irn_n(node, be_pos_Call_ptr);
4200         ir_node        *const noreg     = ia32_new_NoReg_gp(env_cg);
4201         ia32_address_mode_t   am;
4202         ia32_address_t *const addr      = &am.addr;
4203         ir_node        *      mem;
4204         ir_node        *      call;
4205         int                   i;
4206         ir_node        *      fpcw;
4207         ir_node        *      eax       = noreg;
4208         ir_node        *      ecx       = noreg;
4209         ir_node        *      edx       = noreg;
4210         unsigned        const pop       = be_Call_get_pop(node);
4211         ir_type        *const call_tp   = be_Call_get_type(node);
4212
4213         /* Run the x87 simulator if the call returns a float value */
4214         if (get_method_n_ress(call_tp) > 0) {
4215                 ir_type *const res_type = get_method_res_type(call_tp, 0);
4216                 ir_mode *const res_mode = get_type_mode(res_type);
4217
4218                 if (res_mode != NULL && mode_is_float(res_mode)) {
4219                         env_cg->do_x87_sim = 1;
4220                 }
4221         }
4222
4223         /* We do not want be_Call direct calls */
4224         assert(be_Call_get_entity(node) == NULL);
4225
4226         match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4227                         match_am | match_immediate);
4228
4229         i    = get_irn_arity(node) - 1;
4230         fpcw = be_transform_node(get_irn_n(node, i--));
4231         for (; i >= be_pos_Call_first_arg; --i) {
4232                 arch_register_req_t const *const req = arch_get_register_req(node, i);
4233                 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4234
4235                 assert(req->type == arch_register_req_type_limited);
4236                 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4237
4238                 switch (*req->limited) {
4239                         case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4240                         case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4241                         case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4242                         default: panic("Invalid GP register for register parameter");
4243                 }
4244         }
4245
4246         mem  = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4247         call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4248                                 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4249         set_am_attributes(call, &am);
4250         call = fix_mem_proj(call, &am);
4251
4252         if (get_irn_pinned(node) == op_pin_state_pinned)
4253                 set_irn_pinned(call, op_pin_state_pinned);
4254
4255         SET_IA32_ORIG_NODE(call, node);
4256         return call;
4257 }
4258
4259 static ir_node *gen_be_IncSP(ir_node *node)
4260 {
4261         ir_node *res = be_duplicate_node(node);
4262         arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4263
4264         return res;
4265 }
4266
4267 /**
4268  * Transform the Projs from a be_Call.
4269  */
4270 static ir_node *gen_Proj_be_Call(ir_node *node)
4271 {
4272         ir_node  *block       = be_transform_node(get_nodes_block(node));
4273         ir_node  *call        = get_Proj_pred(node);
4274         ir_node  *new_call    = be_transform_node(call);
4275         ir_graph *irg         = current_ir_graph;
4276         dbg_info *dbgi        = get_irn_dbg_info(node);
4277         ir_type  *method_type = be_Call_get_type(call);
4278         int       n_res       = get_method_n_ress(method_type);
4279         long      proj        = get_Proj_proj(node);
4280         ir_mode  *mode        = get_irn_mode(node);
4281         ir_node  *sse_load;
4282         ir_node  *res;
4283
4284         /* The following is kinda tricky: If we're using SSE, then we have to
4285          * move the result value of the call in floating point registers to an
4286          * xmm register, we therefore construct a GetST0 -> xLoad sequence
4287          * after the call, we have to make sure to correctly make the
4288          * MemProj and the result Proj use these 2 nodes
4289          */
4290         if (proj == pn_be_Call_M_regular) {
4291                 // get new node for result, are we doing the sse load/store hack?
4292                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4293                 ir_node *call_res_new;
4294                 ir_node *call_res_pred = NULL;
4295
4296                 if (call_res != NULL) {
4297                         call_res_new  = be_transform_node(call_res);
4298                         call_res_pred = get_Proj_pred(call_res_new);
4299                 }
4300
4301                 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4302                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4303                                            n_ia32_Call_mem);
4304                 } else {
4305                         assert(is_ia32_xLoad(call_res_pred));
4306                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4307                                            pn_ia32_xLoad_M);
4308                 }
4309         }
4310         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4311                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4312                 ir_node *fstp;
4313                 ir_node *frame = get_irg_frame(irg);
4314                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4315                 //ir_node *p;
4316                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4317                 ir_node *call_res;
4318
4319                 /* in case there is no memory output: create one to serialize the copy
4320                    FPU -> SSE */
4321                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4322                                        pn_be_Call_M_regular);
4323                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4324                                        pn_be_Call_first_res);
4325
4326                 /* store st(0) onto stack */
4327                 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4328                                         call_res, mode);
4329                 set_ia32_op_type(fstp, ia32_AddrModeD);
4330                 set_ia32_use_frame(fstp);
4331
4332                 /* load into SSE register */
4333                 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4334                 set_ia32_op_type(sse_load, ia32_AddrModeS);
4335                 set_ia32_use_frame(sse_load);
4336
4337                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4338                                        pn_ia32_xLoad_res);
4339
4340                 return sse_load;
4341         }
4342
4343         /* transform call modes */
4344         if (mode_is_data(mode)) {
4345                 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4346                 mode = cls->mode;
4347         }
4348
4349         /* Map from be_Call to ia32_Call proj number */
4350         if (proj == pn_be_Call_sp) {
4351                 proj = pn_ia32_Call_stack;
4352         } else if (proj == pn_be_Call_M_regular) {
4353                 proj = pn_ia32_Call_M;
4354         } else {
4355                 arch_register_req_t const *const req    = arch_get_register_req_out(node);
4356                 int                        const n_outs = arch_irn_get_n_outs(new_call);
4357                 int                              i;
4358
4359                 assert(proj      >= pn_be_Call_first_res);
4360                 assert(req->type & arch_register_req_type_limited);
4361
4362                 for (i = 0; i < n_outs; ++i) {
4363                         arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4364
4365                         if (!(new_req->type & arch_register_req_type_limited) ||
4366                             new_req->cls      != req->cls                     ||
4367                             *new_req->limited != *req->limited)
4368                                 continue;
4369
4370                         proj = i;
4371                         break;
4372                 }
4373                 assert(i < n_outs);
4374         }
4375
4376         res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4377
4378         /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4379         switch (proj) {
4380                 case pn_ia32_Call_stack:
4381                         arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4382                         break;
4383
4384                 case pn_ia32_Call_fpcw:
4385                         arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4386                         break;
4387         }
4388
4389         return res;
4390 }
4391
4392 /**
4393  * Transform the Projs from a Cmp.
4394  */
4395 static ir_node *gen_Proj_Cmp(ir_node *node)
4396 {
4397         /* this probably means not all mode_b nodes were lowered... */
4398         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4399               node);
4400 }
4401
4402 /**
4403  * Transform the Projs from a Bound.
4404  */
4405 static ir_node *gen_Proj_Bound(ir_node *node)
4406 {
4407         ir_node *new_node, *block;
4408         ir_node *pred = get_Proj_pred(node);
4409
4410         switch (get_Proj_proj(node)) {
4411         case pn_Bound_M:
4412                 return be_transform_node(get_Bound_mem(pred));
4413         case pn_Bound_X_regular:
4414                 new_node = be_transform_node(pred);
4415                 block    = get_nodes_block(new_node);
4416                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4417         case pn_Bound_X_except:
4418                 new_node = be_transform_node(pred);
4419                 block    = get_nodes_block(new_node);
4420                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4421         case pn_Bound_res:
4422                 return be_transform_node(get_Bound_index(pred));
4423         default:
4424                 panic("unsupported Proj from Bound");
4425         }
4426 }
4427
4428 static ir_node *gen_Proj_ASM(ir_node *node)
4429 {
4430         ir_node *pred;
4431         ir_node *new_pred;
4432         ir_node *block;
4433
4434         if (get_irn_mode(node) != mode_M)
4435                 return be_duplicate_node(node);
4436
4437         pred     = get_Proj_pred(node);
4438         new_pred = be_transform_node(pred);
4439         block    = get_nodes_block(new_pred);
4440         return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4441                         arch_irn_get_n_outs(new_pred) + 1);
4442 }
4443
4444 /**
4445  * Transform and potentially renumber Proj nodes.
4446  */
4447 static ir_node *gen_Proj(ir_node *node)
4448 {
4449         ir_node *pred = get_Proj_pred(node);
4450         long    proj;
4451
4452         switch (get_irn_opcode(pred)) {
4453         case iro_Store:
4454                 proj = get_Proj_proj(node);
4455                 if (proj == pn_Store_M) {
4456                         return be_transform_node(pred);
4457                 } else {
4458                         panic("No idea how to transform proj->Store");
4459                 }
4460         case iro_Load:
4461                 return gen_Proj_Load(node);
4462         case iro_ASM:
4463                 return gen_Proj_ASM(node);
4464         case iro_Div:
4465         case iro_Mod:
4466         case iro_DivMod:
4467                 return gen_Proj_DivMod(node);
4468         case iro_CopyB:
4469                 return gen_Proj_CopyB(node);
4470         case iro_Quot:
4471                 return gen_Proj_Quot(node);
4472         case beo_SubSP:
4473                 return gen_Proj_be_SubSP(node);
4474         case beo_AddSP:
4475                 return gen_Proj_be_AddSP(node);
4476         case beo_Call:
4477                 return gen_Proj_be_Call(node);
4478         case iro_Cmp:
4479                 return gen_Proj_Cmp(node);
4480         case iro_Bound:
4481                 return gen_Proj_Bound(node);
4482         case iro_Start:
4483                 proj = get_Proj_proj(node);
4484                 switch (proj) {
4485                         case pn_Start_X_initial_exec: {
4486                                 ir_node  *block     = get_nodes_block(pred);
4487                                 ir_node  *new_block = be_transform_node(block);
4488                                 dbg_info *dbgi      = get_irn_dbg_info(node);
4489                                 /* we exchange the ProjX with a jump */
4490                                 ir_node  *jump      = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4491
4492                                 return jump;
4493                         }
4494
4495                         case pn_Start_P_tls:
4496                                 return gen_Proj_tls(node);
4497                 }
4498                 break;
4499
4500         default:
4501                 if (is_ia32_l_FloattoLL(pred)) {
4502                         return gen_Proj_l_FloattoLL(node);
4503 #ifdef FIRM_EXT_GRS
4504                 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4505 #else
4506                 } else {
4507 #endif
4508                         ir_mode *mode = get_irn_mode(node);
4509                         if (ia32_mode_needs_gp_reg(mode)) {
4510                                 ir_node *new_pred = be_transform_node(pred);
4511                                 ir_node *block    = be_transform_node(get_nodes_block(node));
4512                                 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4513                                                                                            mode_Iu, get_Proj_proj(node));
4514 #ifdef DEBUG_libfirm
4515                                 new_proj->node_nr = node->node_nr;
4516 #endif
4517                                 return new_proj;
4518                         }
4519                 }
4520         }
4521         return be_duplicate_node(node);
4522 }
4523
4524 /**
4525  * Enters all transform functions into the generic pointer
4526  */
4527 static void register_transformers(void)
4528 {
4529         ir_op *op_Mulh;
4530
4531         /* first clear the generic function pointer for all ops */
4532         clear_irp_opcodes_generic_func();
4533
4534 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4535 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
4536
4537         GEN(Add);
4538         GEN(Sub);
4539         GEN(Mul);
4540         GEN(And);
4541         GEN(Or);
4542         GEN(Eor);
4543
4544         GEN(Shl);
4545         GEN(Shr);
4546         GEN(Shrs);
4547         GEN(Rotl);
4548
4549         GEN(Quot);
4550
4551         GEN(Div);
4552         GEN(Mod);
4553         GEN(DivMod);
4554
4555         GEN(Minus);
4556         GEN(Conv);
4557         GEN(Abs);
4558         GEN(Not);
4559
4560         GEN(Load);
4561         GEN(Store);
4562         GEN(Cond);
4563
4564         GEN(Cmp);
4565         GEN(ASM);
4566         GEN(CopyB);
4567         GEN(Mux);
4568         GEN(Proj);
4569         GEN(Phi);
4570         GEN(IJmp);
4571         GEN(Bound);
4572
4573         /* transform ops from intrinsic lowering */
4574         GEN(ia32_l_Add);
4575         GEN(ia32_l_Adc);
4576         GEN(ia32_l_Mul);
4577         GEN(ia32_l_IMul);
4578         GEN(ia32_l_ShlDep);
4579         GEN(ia32_l_ShrDep);
4580         GEN(ia32_l_SarDep);
4581         GEN(ia32_l_ShlD);
4582         GEN(ia32_l_ShrD);
4583         GEN(ia32_l_Sub);
4584         GEN(ia32_l_Sbb);
4585         GEN(ia32_l_LLtoFloat);
4586         GEN(ia32_l_FloattoLL);
4587
4588         GEN(Const);
4589         GEN(SymConst);
4590         GEN(Unknown);
4591
4592         /* we should never see these nodes */
4593         BAD(Raise);
4594         BAD(Sel);
4595         BAD(InstOf);
4596         BAD(Cast);
4597         BAD(Free);
4598         BAD(Tuple);
4599         BAD(Id);
4600         //BAD(Bad);
4601         BAD(Confirm);
4602         BAD(Filter);
4603         BAD(CallBegin);
4604         BAD(EndReg);
4605         BAD(EndExcept);
4606
4607         /* handle generic backend nodes */
4608         GEN(be_FrameAddr);
4609         GEN(be_Call);
4610         GEN(be_IncSP);
4611         GEN(be_Return);
4612         GEN(be_AddSP);
4613         GEN(be_SubSP);
4614         GEN(be_Copy);
4615
4616         op_Mulh = get_op_Mulh();
4617         if (op_Mulh)
4618                 GEN(Mulh);
4619
4620 #undef GEN
4621 #undef BAD
4622 }
4623
4624 /**
4625  * Pre-transform all unknown and noreg nodes.
4626  */
4627 static void ia32_pretransform_node(void)
4628 {
4629         ia32_code_gen_t *cg = env_cg;
4630
4631         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
4632         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4633         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4634         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
4635         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
4636         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
4637         get_fpcw();
4638 }
4639
4640 /**
4641  * Walker, checks if all ia32 nodes producing more than one result have their
4642  * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4643  */
4644 static void add_missing_keep_walker(ir_node *node, void *data)
4645 {
4646         int              n_outs, i;
4647         unsigned         found_projs = 0;
4648         const ir_edge_t *edge;
4649         ir_mode         *mode = get_irn_mode(node);
4650         ir_node         *last_keep;
4651         (void) data;
4652         if (mode != mode_T)
4653                 return;
4654         if (!is_ia32_irn(node))
4655                 return;
4656
4657         n_outs = arch_irn_get_n_outs(node);
4658         if (n_outs <= 0)
4659                 return;
4660         if (is_ia32_SwitchJmp(node))
4661                 return;
4662
4663         assert(n_outs < (int) sizeof(unsigned) * 8);
4664         foreach_out_edge(node, edge) {
4665                 ir_node *proj = get_edge_src_irn(edge);
4666                 int      pn;
4667
4668                 /* The node could be kept */
4669                 if (is_End(proj))
4670                         continue;
4671
4672                 if (get_irn_mode(proj) == mode_M)
4673                         continue;
4674
4675                 pn = get_Proj_proj(proj);
4676                 assert(pn < n_outs);
4677                 found_projs |= 1 << pn;
4678         }
4679
4680
4681         /* are keeps missing? */
4682         last_keep = NULL;
4683         for (i = 0; i < n_outs; ++i) {
4684                 ir_node                     *block;
4685                 ir_node                     *in[1];
4686                 const arch_register_req_t   *req;
4687                 const arch_register_class_t *cls;
4688
4689                 if (found_projs & (1 << i)) {
4690                         continue;
4691                 }
4692
4693                 req = get_ia32_out_req(node, i);
4694                 cls = req->cls;
4695                 if (cls == NULL) {
4696                         continue;
4697                 }
4698                 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4699                         continue;
4700                 }
4701
4702                 block = get_nodes_block(node);
4703                 in[0] = new_r_Proj(current_ir_graph, block, node,
4704                                    arch_register_class_mode(cls), i);
4705                 if (last_keep != NULL) {
4706                         be_Keep_add_node(last_keep, cls, in[0]);
4707                 } else {
4708                         last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4709                         if (sched_is_scheduled(node)) {
4710                                 sched_add_after(node, last_keep);
4711                         }
4712                 }
4713         }
4714 }
4715
4716 /**
4717  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4718  * and keeps them.
4719  */
4720 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4721 {
4722         ir_graph *irg = be_get_birg_irg(cg->birg);
4723         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4724 }
4725
4726 /* do the transformation */
4727 void ia32_transform_graph(ia32_code_gen_t *cg)
4728 {
4729         int cse_last;
4730
4731         register_transformers();
4732         env_cg       = cg;
4733         initial_fpcw = NULL;
4734
4735         BE_TIMER_PUSH(t_heights);
4736         heights      = heights_new(cg->irg);
4737         BE_TIMER_POP(t_heights);
4738         ia32_calculate_non_address_mode_nodes(cg->birg);
4739
4740         /* the transform phase is not safe for CSE (yet) because several nodes get
4741          * attributes set after their creation */
4742         cse_last = get_opt_cse();
4743         set_opt_cse(0);
4744
4745         be_transform_graph(cg->birg, ia32_pretransform_node);
4746
4747         set_opt_cse(cse_last);
4748
4749         ia32_free_non_address_mode_nodes();
4750         heights_free(heights);
4751         heights = NULL;
4752 }
4753
4754 void ia32_init_transform(void)
4755 {
4756         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
4757 }