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