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