ia32_Lea cannot use immediates, set the offset instead.
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /*
2  * Copyright (C) 1995-2011 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 "ircons.h"
42 #include "irgwalk.h"
43 #include "irprintf.h"
44 #include "debug.h"
45 #include "irdom.h"
46 #include "error.h"
47 #include "array_t.h"
48 #include "heights.h"
49
50 #include "../benode.h"
51 #include "../besched.h"
52 #include "../beabi.h"
53 #include "../beutil.h"
54 #include "../beirg.h"
55 #include "../betranshlp.h"
56 #include "../be_t.h"
57
58 #include "bearch_ia32_t.h"
59 #include "ia32_common_transform.h"
60 #include "ia32_nodes_attr.h"
61 #include "ia32_transform.h"
62 #include "ia32_new_nodes.h"
63 #include "ia32_dbg_stat.h"
64 #include "ia32_optimize.h"
65 #include "ia32_util.h"
66 #include "ia32_address_mode.h"
67 #include "ia32_architecture.h"
68
69 #include "gen_ia32_regalloc_if.h"
70
71 /* define this to construct SSE constants instead of load them */
72 #undef CONSTRUCT_SSE_CONST
73
74
75 #define SFP_SIGN   "0x80000000"
76 #define DFP_SIGN   "0x8000000000000000"
77 #define SFP_ABS    "0x7FFFFFFF"
78 #define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
79 #define DFP_INTMAX "9223372036854775807"
80 #define ULL_BIAS   "18446744073709551616"
81
82 #define ENT_SFP_SIGN "C_ia32_sfp_sign"
83 #define ENT_DFP_SIGN "C_ia32_dfp_sign"
84 #define ENT_SFP_ABS  "C_ia32_sfp_abs"
85 #define ENT_DFP_ABS  "C_ia32_dfp_abs"
86 #define ENT_ULL_BIAS "C_ia32_ull_bias"
87
88 #define mode_vfp    (ia32_reg_classes[CLASS_ia32_vfp].mode)
89 #define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)
90
91 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
92
93 static ir_node         *initial_fpcw = NULL;
94 int                     ia32_no_pic_adjust;
95
96 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
97         ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
98         ir_node *op2);
99
100 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
101         ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
102         ir_node *flags);
103
104 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
105         ir_node *op1, ir_node *op2);
106
107 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
108         ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
109
110 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
111         ir_node *base, ir_node *index, ir_node *mem);
112
113 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
114         ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
115         ir_node *fpcw);
116
117 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
118
119 static ir_node *create_immediate_or_transform(ir_node *node,
120                                               char immediate_constraint_type);
121
122 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
123                                 dbg_info *dbgi, ir_node *block,
124                                 ir_node *op, ir_node *orig_node);
125
126 /* its enough to have those once */
127 static ir_node *nomem, *noreg_GP;
128
129 /** a list to postprocess all calls */
130 static ir_node **call_list;
131 static ir_type **call_types;
132
133 /** Return non-zero is a node represents the 0 constant. */
134 static bool is_Const_0(ir_node *node)
135 {
136         return is_Const(node) && is_Const_null(node);
137 }
138
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node)
141 {
142         return is_Const(node) && is_Const_one(node);
143 }
144
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node)
147 {
148         return is_Const(node) && is_Const_all_one(node);
149 }
150
151 /**
152  * returns true if constant can be created with a simple float command
153  */
154 static bool is_simple_x87_Const(ir_node *node)
155 {
156         ir_tarval *tv = get_Const_tarval(node);
157         if (tarval_is_null(tv) || tarval_is_one(tv))
158                 return true;
159
160         /* TODO: match all the other float constants */
161         return false;
162 }
163
164 /**
165  * returns true if constant can be created with a simple float command
166  */
167 static bool is_simple_sse_Const(ir_node *node)
168 {
169         ir_tarval *tv   = get_Const_tarval(node);
170         ir_mode   *mode = get_tarval_mode(tv);
171
172         if (mode == mode_F)
173                 return true;
174
175         if (tarval_is_null(tv)
176 #ifdef CONSTRUCT_SSE_CONST
177             || tarval_is_one(tv)
178 #endif
179            )
180                 return true;
181 #ifdef CONSTRUCT_SSE_CONST
182         if (mode == mode_D) {
183                 unsigned val = get_tarval_sub_bits(tv, 0) |
184                         (get_tarval_sub_bits(tv, 1) << 8) |
185                         (get_tarval_sub_bits(tv, 2) << 16) |
186                         (get_tarval_sub_bits(tv, 3) << 24);
187                 if (val == 0)
188                         /* lower 32bit are zero, really a 32bit constant */
189                         return true;
190         }
191 #endif /* CONSTRUCT_SSE_CONST */
192         /* TODO: match all the other float constants */
193         return false;
194 }
195
196 /**
197  * return NoREG or pic_base in case of PIC.
198  * This is necessary as base address for newly created symbols
199  */
200 static ir_node *get_symconst_base(void)
201 {
202         ir_graph *irg = current_ir_graph;
203
204         if (be_get_irg_options(irg)->pic) {
205                 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
206                 return arch_env->impl->get_pic_base(irg);
207         }
208
209         return noreg_GP;
210 }
211
212 /**
213  * Transforms a Const.
214  */
215 static ir_node *gen_Const(ir_node *node)
216 {
217         ir_node  *old_block = get_nodes_block(node);
218         ir_node  *block     = be_transform_node(old_block);
219         dbg_info *dbgi      = get_irn_dbg_info(node);
220         ir_mode  *mode      = get_irn_mode(node);
221
222         assert(is_Const(node));
223
224         if (mode_is_float(mode)) {
225                 ir_node   *res   = NULL;
226                 ir_node   *load;
227                 ir_node   *base;
228                 ir_entity *floatent;
229
230                 if (ia32_cg_config.use_sse2) {
231                         ir_tarval *tv = get_Const_tarval(node);
232                         if (tarval_is_null(tv)) {
233                                 load = new_bd_ia32_xZero(dbgi, block);
234                                 set_ia32_ls_mode(load, mode);
235                                 res  = load;
236 #ifdef CONSTRUCT_SSE_CONST
237                         } else if (tarval_is_one(tv)) {
238                                 int     cnst  = mode == mode_F ? 26 : 55;
239                                 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
240                                 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
241                                 ir_node *pslld, *psrld;
242
243                                 load = new_bd_ia32_xAllOnes(dbgi, block);
244                                 set_ia32_ls_mode(load, mode);
245                                 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
246                                 set_ia32_ls_mode(pslld, mode);
247                                 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
248                                 set_ia32_ls_mode(psrld, mode);
249                                 res = psrld;
250 #endif /* CONSTRUCT_SSE_CONST */
251                         } else if (mode == mode_F) {
252                                 /* we can place any 32bit constant by using a movd gp, sse */
253                                 unsigned val = get_tarval_sub_bits(tv, 0) |
254                                                (get_tarval_sub_bits(tv, 1) << 8) |
255                                                (get_tarval_sub_bits(tv, 2) << 16) |
256                                                (get_tarval_sub_bits(tv, 3) << 24);
257                                 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
258                                 load = new_bd_ia32_xMovd(dbgi, block, cnst);
259                                 set_ia32_ls_mode(load, mode);
260                                 res = load;
261                         } else {
262 #ifdef CONSTRUCT_SSE_CONST
263                                 if (mode == mode_D) {
264                                         unsigned val = get_tarval_sub_bits(tv, 0) |
265                                                 (get_tarval_sub_bits(tv, 1) << 8) |
266                                                 (get_tarval_sub_bits(tv, 2) << 16) |
267                                                 (get_tarval_sub_bits(tv, 3) << 24);
268                                         if (val == 0) {
269                                                 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
270                                                 ir_node *cnst, *psllq;
271
272                                                 /* fine, lower 32bit are zero, produce 32bit value */
273                                                 val = get_tarval_sub_bits(tv, 4) |
274                                                         (get_tarval_sub_bits(tv, 5) << 8) |
275                                                         (get_tarval_sub_bits(tv, 6) << 16) |
276                                                         (get_tarval_sub_bits(tv, 7) << 24);
277                                                 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
278                                                 load = new_bd_ia32_xMovd(dbgi, block, cnst);
279                                                 set_ia32_ls_mode(load, mode);
280                                                 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
281                                                 set_ia32_ls_mode(psllq, mode);
282                                                 res = psllq;
283                                                 goto end;
284                                         }
285                                 }
286 #endif /* CONSTRUCT_SSE_CONST */
287                                 floatent = ia32_create_float_const_entity(node);
288
289                                 base     = get_symconst_base();
290                                 load     = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
291                                                              mode);
292                                 set_ia32_op_type(load, ia32_AddrModeS);
293                                 set_ia32_am_sc(load, floatent);
294                                 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
295                                 res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
296                         }
297                 } else {
298                         if (is_Const_null(node)) {
299                                 load = new_bd_ia32_vfldz(dbgi, block);
300                                 res  = load;
301                                 set_ia32_ls_mode(load, mode);
302                         } else if (is_Const_one(node)) {
303                                 load = new_bd_ia32_vfld1(dbgi, block);
304                                 res  = load;
305                                 set_ia32_ls_mode(load, mode);
306                         } else {
307                                 ir_mode *ls_mode;
308                                 ir_node *base;
309
310                                 floatent = ia32_create_float_const_entity(node);
311                                 /* create_float_const_ent is smart and sometimes creates
312                                    smaller entities */
313                                 ls_mode  = get_type_mode(get_entity_type(floatent));
314                                 base     = get_symconst_base();
315                                 load     = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
316                                                             ls_mode);
317                                 set_ia32_op_type(load, ia32_AddrModeS);
318                                 set_ia32_am_sc(load, floatent);
319                                 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
320                                 res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
321                         }
322                 }
323 #ifdef CONSTRUCT_SSE_CONST
324 end:
325 #endif /* CONSTRUCT_SSE_CONST */
326                 SET_IA32_ORIG_NODE(load, node);
327
328                 be_dep_on_frame(load);
329                 return res;
330         } else { /* non-float mode */
331                 ir_node   *cnst;
332                 ir_tarval *tv = get_Const_tarval(node);
333                 long       val;
334
335                 tv = tarval_convert_to(tv, mode_Iu);
336
337                 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
338                     tv == NULL) {
339                         panic("couldn't convert constant tarval (%+F)", node);
340                 }
341                 val = get_tarval_long(tv);
342
343                 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
344                 SET_IA32_ORIG_NODE(cnst, node);
345
346                 be_dep_on_frame(cnst);
347                 return cnst;
348         }
349 }
350
351 /**
352  * Transforms a SymConst.
353  */
354 static ir_node *gen_SymConst(ir_node *node)
355 {
356         ir_node  *old_block = get_nodes_block(node);
357         ir_node  *block = be_transform_node(old_block);
358         dbg_info *dbgi  = get_irn_dbg_info(node);
359         ir_mode  *mode  = get_irn_mode(node);
360         ir_node  *cnst;
361
362         if (mode_is_float(mode)) {
363                 if (ia32_cg_config.use_sse2)
364                         cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
365                 else
366                         cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
367                 set_ia32_am_sc(cnst, get_SymConst_entity(node));
368                 set_ia32_use_frame(cnst);
369         } else {
370                 ir_entity *entity;
371
372                 if (get_SymConst_kind(node) != symconst_addr_ent) {
373                         panic("backend only support symconst_addr_ent (at %+F)", node);
374                 }
375                 entity = get_SymConst_entity(node);
376                 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
377         }
378
379         SET_IA32_ORIG_NODE(cnst, node);
380
381         be_dep_on_frame(cnst);
382         return cnst;
383 }
384
385 /**
386  * Create a float type for the given mode and cache it.
387  *
388  * @param mode   the mode for the float type (might be integer mode for SSE2 types)
389  * @param align  alignment
390  */
391 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
392 {
393         ir_type *tp;
394
395         assert(align <= 16);
396
397         if (mode == mode_Iu) {
398                 static ir_type *int_Iu[16] = {NULL, };
399
400                 if (int_Iu[align] == NULL) {
401                         int_Iu[align] = tp = new_type_primitive(mode);
402                         /* set the specified alignment */
403                         set_type_alignment_bytes(tp, align);
404                 }
405                 return int_Iu[align];
406         } else if (mode == mode_Lu) {
407                 static ir_type *int_Lu[16] = {NULL, };
408
409                 if (int_Lu[align] == NULL) {
410                         int_Lu[align] = tp = new_type_primitive(mode);
411                         /* set the specified alignment */
412                         set_type_alignment_bytes(tp, align);
413                 }
414                 return int_Lu[align];
415         } else if (mode == mode_F) {
416                 static ir_type *float_F[16] = {NULL, };
417
418                 if (float_F[align] == NULL) {
419                         float_F[align] = tp = new_type_primitive(mode);
420                         /* set the specified alignment */
421                         set_type_alignment_bytes(tp, align);
422                 }
423                 return float_F[align];
424         } else if (mode == mode_D) {
425                 static ir_type *float_D[16] = {NULL, };
426
427                 if (float_D[align] == NULL) {
428                         float_D[align] = tp = new_type_primitive(mode);
429                         /* set the specified alignment */
430                         set_type_alignment_bytes(tp, align);
431                 }
432                 return float_D[align];
433         } else {
434                 static ir_type *float_E[16] = {NULL, };
435
436                 if (float_E[align] == NULL) {
437                         float_E[align] = tp = new_type_primitive(mode);
438                         /* set the specified alignment */
439                         set_type_alignment_bytes(tp, align);
440                 }
441                 return float_E[align];
442         }
443 }
444
445 /**
446  * Create a float[2] array type for the given atomic type.
447  *
448  * @param tp  the atomic type
449  */
450 static ir_type *ia32_create_float_array(ir_type *tp)
451 {
452         ir_mode  *mode = get_type_mode(tp);
453         unsigned align = get_type_alignment_bytes(tp);
454         ir_type  *arr;
455
456         assert(align <= 16);
457
458         if (mode == mode_F) {
459                 static ir_type *float_F[16] = {NULL, };
460
461                 if (float_F[align] != NULL)
462                         return float_F[align];
463                 arr = float_F[align] = new_type_array(1, tp);
464         } else if (mode == mode_D) {
465                 static ir_type *float_D[16] = {NULL, };
466
467                 if (float_D[align] != NULL)
468                         return float_D[align];
469                 arr = float_D[align] = new_type_array(1, tp);
470         } else {
471                 static ir_type *float_E[16] = {NULL, };
472
473                 if (float_E[align] != NULL)
474                         return float_E[align];
475                 arr = float_E[align] = new_type_array(1, tp);
476         }
477         set_type_alignment_bytes(arr, align);
478         set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
479         set_type_state(arr, layout_fixed);
480         return arr;
481 }
482
483 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
484 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
485 {
486         static const struct {
487                 const char *ent_name;
488                 const char *cnst_str;
489                 char mode;
490                 unsigned char align;
491         } names [ia32_known_const_max] = {
492                 { ENT_SFP_SIGN, SFP_SIGN,   0, 16 }, /* ia32_SSIGN */
493                 { ENT_DFP_SIGN, DFP_SIGN,   1, 16 }, /* ia32_DSIGN */
494                 { ENT_SFP_ABS,  SFP_ABS,    0, 16 }, /* ia32_SABS */
495                 { ENT_DFP_ABS,  DFP_ABS,    1, 16 }, /* ia32_DABS */
496                 { ENT_ULL_BIAS, ULL_BIAS,   2, 4 }   /* ia32_ULLBIAS */
497         };
498         static ir_entity *ent_cache[ia32_known_const_max];
499
500         const char *ent_name, *cnst_str;
501         ir_type    *tp;
502         ir_entity  *ent;
503         ir_tarval  *tv;
504         ir_mode    *mode;
505
506         ent_name = names[kct].ent_name;
507         if (! ent_cache[kct]) {
508                 cnst_str = names[kct].cnst_str;
509
510                 switch (names[kct].mode) {
511                 case 0:  mode = mode_Iu; break;
512                 case 1:  mode = mode_Lu; break;
513                 default: mode = mode_F;  break;
514                 }
515                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
516                 tp  = ia32_create_float_type(mode, names[kct].align);
517
518                 if (kct == ia32_ULLBIAS)
519                         tp = ia32_create_float_array(tp);
520                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
521
522                 set_entity_ld_ident(ent, get_entity_ident(ent));
523                 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
524                 set_entity_visibility(ent, ir_visibility_private);
525
526                 if (kct == ia32_ULLBIAS) {
527                         ir_initializer_t *initializer = create_initializer_compound(2);
528
529                         set_initializer_compound_value(initializer, 0,
530                                 create_initializer_tarval(get_mode_null(mode)));
531                         set_initializer_compound_value(initializer, 1,
532                                 create_initializer_tarval(tv));
533
534                         set_entity_initializer(ent, initializer);
535                 } else {
536                         set_entity_initializer(ent, create_initializer_tarval(tv));
537                 }
538
539                 /* cache the entry */
540                 ent_cache[kct] = ent;
541         }
542
543         return ent_cache[kct];
544 }
545
546 /**
547  * return true if the node is a Proj(Load) and could be used in source address
548  * mode for another node. Will return only true if the @p other node is not
549  * dependent on the memory of the Load (for binary operations use the other
550  * input here, for unary operations use NULL).
551  */
552 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
553                                         ir_node *other, ir_node *other2, match_flags_t flags)
554 {
555         ir_node *load;
556         long     pn;
557
558         /* float constants are always available */
559         if (is_Const(node)) {
560                 ir_mode *mode = get_irn_mode(node);
561                 if (mode_is_float(mode)) {
562                         if (ia32_cg_config.use_sse2) {
563                                 if (is_simple_sse_Const(node))
564                                         return 0;
565                         } else {
566                                 if (is_simple_x87_Const(node))
567                                         return 0;
568                         }
569                         if (get_irn_n_edges(node) > 1)
570                                 return 0;
571                         return 1;
572                 }
573         }
574
575         if (!is_Proj(node))
576                 return 0;
577         load = get_Proj_pred(node);
578         pn   = get_Proj_proj(node);
579         if (!is_Load(load) || pn != pn_Load_res)
580                 return 0;
581         if (get_nodes_block(load) != block)
582                 return 0;
583         /* we only use address mode if we're the only user of the load */
584         if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
585                 return 0;
586         /* in some edge cases with address mode we might reach the load normally
587          * and through some AM sequence, if it is already materialized then we
588          * can't create an AM node from it */
589         if (be_is_transformed(node))
590                 return 0;
591
592         /* don't do AM if other node inputs depend on the load (via mem-proj) */
593         if (other != NULL && ia32_prevents_AM(block, load, other))
594                 return 0;
595
596         if (other2 != NULL && ia32_prevents_AM(block, load, other2))
597                 return 0;
598
599         return 1;
600 }
601
602 typedef struct ia32_address_mode_t ia32_address_mode_t;
603 struct ia32_address_mode_t {
604         ia32_address_t  addr;
605         ir_mode        *ls_mode;
606         ir_node        *mem_proj;
607         ir_node        *am_node;
608         ia32_op_type_t  op_type;
609         ir_node        *new_op1;
610         ir_node        *new_op2;
611         op_pin_state    pinned;
612         unsigned        commutative  : 1;
613         unsigned        ins_permuted : 1;
614 };
615
616 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
617 {
618         /* construct load address */
619         memset(addr, 0, sizeof(addr[0]));
620         ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
621
622         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
623         addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
624         addr->mem   = be_transform_node(mem);
625 }
626
627 static void build_address(ia32_address_mode_t *am, ir_node *node,
628                           ia32_create_am_flags_t flags)
629 {
630         ia32_address_t *addr = &am->addr;
631         ir_node        *load;
632         ir_node        *ptr;
633         ir_node        *mem;
634         ir_node        *new_mem;
635
636         /* floating point immediates */
637         if (is_Const(node)) {
638                 ir_entity *entity  = ia32_create_float_const_entity(node);
639                 addr->base         = get_symconst_base();
640                 addr->index        = noreg_GP;
641                 addr->mem          = nomem;
642                 addr->symconst_ent = entity;
643                 addr->use_frame    = 1;
644                 am->ls_mode        = get_type_mode(get_entity_type(entity));
645                 am->pinned         = op_pin_state_floats;
646                 return;
647         }
648
649         load         = get_Proj_pred(node);
650         ptr          = get_Load_ptr(load);
651         mem          = get_Load_mem(load);
652         new_mem      = be_transform_node(mem);
653         am->pinned   = get_irn_pinned(load);
654         am->ls_mode  = get_Load_mode(load);
655         am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
656         am->am_node  = node;
657
658         /* construct load address */
659         ia32_create_address_mode(addr, ptr, flags);
660
661         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
662         addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
663         addr->mem   = new_mem;
664 }
665
666 static void set_address(ir_node *node, const ia32_address_t *addr)
667 {
668         set_ia32_am_scale(node, addr->scale);
669         set_ia32_am_sc(node, addr->symconst_ent);
670         set_ia32_am_offs_int(node, addr->offset);
671         if (addr->symconst_sign)
672                 set_ia32_am_sc_sign(node);
673         if (addr->use_frame)
674                 set_ia32_use_frame(node);
675         set_ia32_frame_ent(node, addr->frame_entity);
676 }
677
678 /**
679  * Apply attributes of a given address mode to a node.
680  */
681 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
682 {
683         set_address(node, &am->addr);
684
685         set_ia32_op_type(node, am->op_type);
686         set_ia32_ls_mode(node, am->ls_mode);
687         if (am->pinned == op_pin_state_pinned) {
688                 /* beware: some nodes are already pinned and did not allow to change the state */
689                 if (get_irn_pinned(node) != op_pin_state_pinned)
690                         set_irn_pinned(node, op_pin_state_pinned);
691         }
692         if (am->commutative)
693                 set_ia32_commutative(node);
694 }
695
696 /**
697  * Check, if a given node is a Down-Conv, ie. a integer Conv
698  * from a mode with a mode with more bits to a mode with lesser bits.
699  * Moreover, we return only true if the node has not more than 1 user.
700  *
701  * @param node   the node
702  * @return non-zero if node is a Down-Conv
703  */
704 static int is_downconv(const ir_node *node)
705 {
706         ir_mode *src_mode;
707         ir_mode *dest_mode;
708
709         if (!is_Conv(node))
710                 return 0;
711
712         /* we only want to skip the conv when we're the only user
713          * (because this test is used in the context of address-mode selection
714          *  and we don't want to use address mode for multiple users) */
715         if (get_irn_n_edges(node) > 1)
716                 return 0;
717
718         src_mode  = get_irn_mode(get_Conv_op(node));
719         dest_mode = get_irn_mode(node);
720         return
721                 ia32_mode_needs_gp_reg(src_mode)  &&
722                 ia32_mode_needs_gp_reg(dest_mode) &&
723                 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
724 }
725
726 /** Skip all Down-Conv's on a given node and return the resulting node. */
727 ir_node *ia32_skip_downconv(ir_node *node)
728 {
729         while (is_downconv(node))
730                 node = get_Conv_op(node);
731
732         return node;
733 }
734
735 static bool is_sameconv(ir_node *node)
736 {
737         ir_mode *src_mode;
738         ir_mode *dest_mode;
739
740         if (!is_Conv(node))
741                 return 0;
742
743         /* we only want to skip the conv when we're the only user
744          * (because this test is used in the context of address-mode selection
745          *  and we don't want to use address mode for multiple users) */
746         if (get_irn_n_edges(node) > 1)
747                 return 0;
748
749         src_mode  = get_irn_mode(get_Conv_op(node));
750         dest_mode = get_irn_mode(node);
751         return
752                 ia32_mode_needs_gp_reg(src_mode)  &&
753                 ia32_mode_needs_gp_reg(dest_mode) &&
754                 get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
755 }
756
757 /** Skip all signedness convs */
758 static ir_node *ia32_skip_sameconv(ir_node *node)
759 {
760         while (is_sameconv(node))
761                 node = get_Conv_op(node);
762
763         return node;
764 }
765
766 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
767 {
768         ir_mode  *mode = get_irn_mode(node);
769         ir_node  *block;
770         ir_mode  *tgt_mode;
771         dbg_info *dbgi;
772
773         if (mode_is_signed(mode)) {
774                 tgt_mode = mode_Is;
775         } else {
776                 tgt_mode = mode_Iu;
777         }
778         block = get_nodes_block(node);
779         dbgi  = get_irn_dbg_info(node);
780
781         return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
782 }
783
784 /**
785  * matches operands of a node into ia32 addressing/operand modes. This covers
786  * usage of source address mode, immediates, operations with non 32-bit modes,
787  * ...
788  * The resulting data is filled into the @p am struct. block is the block
789  * of the node whose arguments are matched. op1, op2 are the first and second
790  * input that are matched (op1 may be NULL). other_op is another unrelated
791  * input that is not matched! but which is needed sometimes to check if AM
792  * for op1/op2 is legal.
793  * @p flags describes the supported modes of the operation in detail.
794  */
795 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
796                             ir_node *op1, ir_node *op2, ir_node *other_op,
797                             match_flags_t flags)
798 {
799         ia32_address_t *addr      = &am->addr;
800         ir_mode        *mode      = get_irn_mode(op2);
801         int             mode_bits = get_mode_size_bits(mode);
802         ir_node        *new_op1, *new_op2;
803         int             use_am;
804         unsigned        commutative;
805         int             use_am_and_immediates;
806         int             use_immediate;
807
808         memset(am, 0, sizeof(am[0]));
809
810         commutative           = (flags & match_commutative) != 0;
811         use_am_and_immediates = (flags & match_am_and_immediates) != 0;
812         use_am                = (flags & match_am) != 0;
813         use_immediate         = (flags & match_immediate) != 0;
814         assert(!use_am_and_immediates || use_immediate);
815
816         assert(op2 != NULL);
817         assert(!commutative || op1 != NULL);
818         assert(use_am || !(flags & match_8bit_am));
819         assert(use_am || !(flags & match_16bit_am));
820
821         if ((mode_bits ==  8 && !(flags & match_8bit_am)) ||
822             (mode_bits == 16 && !(flags & match_16bit_am))) {
823                 use_am = 0;
824         }
825
826         /* we can simply skip downconvs for mode neutral nodes: the upper bits
827          * can be random for these operations */
828         if (flags & match_mode_neutral) {
829                 op2 = ia32_skip_downconv(op2);
830                 if (op1 != NULL) {
831                         op1 = ia32_skip_downconv(op1);
832                 }
833         } else {
834                 op2 = ia32_skip_sameconv(op2);
835                 if (op1 != NULL) {
836                         op1 = ia32_skip_sameconv(op1);
837                 }
838         }
839
840         /* match immediates. firm nodes are normalized: constants are always on the
841          * op2 input */
842         new_op2 = NULL;
843         if (!(flags & match_try_am) && use_immediate) {
844                 new_op2 = ia32_try_create_Immediate(op2, 0);
845         }
846
847         if (new_op2 == NULL &&
848             use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
849                 build_address(am, op2, ia32_create_am_normal);
850                 new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
851                 if (mode_is_float(mode)) {
852                         new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
853                 } else {
854                         new_op2 = noreg_GP;
855                 }
856                 am->op_type = ia32_AddrModeS;
857         } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
858                        use_am &&
859                        ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
860                 ir_node *noreg;
861                 build_address(am, op1, ia32_create_am_normal);
862
863                 if (mode_is_float(mode)) {
864                         noreg = ia32_new_NoReg_vfp(current_ir_graph);
865                 } else {
866                         noreg = noreg_GP;
867                 }
868
869                 if (new_op2 != NULL) {
870                         new_op1 = noreg;
871                 } else {
872                         new_op1 = be_transform_node(op2);
873                         new_op2 = noreg;
874                         am->ins_permuted = true;
875                 }
876                 am->op_type = ia32_AddrModeS;
877         } else {
878                 ir_mode *mode;
879                 am->op_type = ia32_Normal;
880
881                 if (flags & match_try_am) {
882                         am->new_op1 = NULL;
883                         am->new_op2 = NULL;
884                         return;
885                 }
886
887                 mode = get_irn_mode(op2);
888                 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
889                         new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
890                         if (new_op2 == NULL)
891                                 new_op2 = create_upconv(op2, NULL);
892                         am->ls_mode = mode_Iu;
893                 } else {
894                         new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
895                         if (new_op2 == NULL)
896                                 new_op2 = be_transform_node(op2);
897                         am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
898                 }
899         }
900         if (addr->base == NULL)
901                 addr->base = noreg_GP;
902         if (addr->index == NULL)
903                 addr->index = noreg_GP;
904         if (addr->mem == NULL)
905                 addr->mem = nomem;
906
907         am->new_op1     = new_op1;
908         am->new_op2     = new_op2;
909         am->commutative = commutative;
910 }
911
912 /**
913  * "Fixes" a node that uses address mode by turning it into mode_T
914  * and returning a pn_ia32_res Proj.
915  *
916  * @param node  the node
917  * @param am    its address mode
918  *
919  * @return a Proj(pn_ia32_res) if a memory address mode is used,
920  *         node else
921  */
922 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
923 {
924         ir_mode  *mode;
925         ir_node  *load;
926
927         if (am->mem_proj == NULL)
928                 return node;
929
930         /* we have to create a mode_T so the old MemProj can attach to us */
931         mode = get_irn_mode(node);
932         load = get_Proj_pred(am->mem_proj);
933
934         be_set_transformed_node(load, node);
935
936         if (mode != mode_T) {
937                 set_irn_mode(node, mode_T);
938                 return new_rd_Proj(NULL, node, mode, pn_ia32_res);
939         } else {
940                 return node;
941         }
942 }
943
944 /**
945  * Construct a standard binary operation, set AM and immediate if required.
946  *
947  * @param node  The original node for which the binop is created
948  * @param op1   The first operand
949  * @param op2   The second operand
950  * @param func  The node constructor function
951  * @return The constructed ia32 node.
952  */
953 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
954                           construct_binop_func *func, match_flags_t flags)
955 {
956         dbg_info            *dbgi;
957         ir_node             *block, *new_block, *new_node;
958         ia32_address_mode_t  am;
959         ia32_address_t      *addr = &am.addr;
960
961         block = get_nodes_block(node);
962         match_arguments(&am, block, op1, op2, NULL, flags);
963
964         dbgi      = get_irn_dbg_info(node);
965         new_block = be_transform_node(block);
966         new_node  = func(dbgi, new_block, addr->base, addr->index, addr->mem,
967                         am.new_op1, am.new_op2);
968         set_am_attributes(new_node, &am);
969         /* we can't use source address mode anymore when using immediates */
970         if (!(flags & match_am_and_immediates) &&
971             (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
972                 set_ia32_am_support(new_node, ia32_am_none);
973         SET_IA32_ORIG_NODE(new_node, node);
974
975         new_node = fix_mem_proj(new_node, &am);
976
977         return new_node;
978 }
979
980 /**
981  * Generic names for the inputs of an ia32 binary op.
982  */
983 enum {
984         n_ia32_l_binop_left,  /**< ia32 left input */
985         n_ia32_l_binop_right, /**< ia32 right input */
986         n_ia32_l_binop_eflags /**< ia32 eflags input */
987 };
988 COMPILETIME_ASSERT((int)n_ia32_l_binop_left   == (int)n_ia32_l_Adc_left,       n_Adc_left)
989 COMPILETIME_ASSERT((int)n_ia32_l_binop_right  == (int)n_ia32_l_Adc_right,      n_Adc_right)
990 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Adc_eflags,     n_Adc_eflags)
991 COMPILETIME_ASSERT((int)n_ia32_l_binop_left   == (int)n_ia32_l_Sbb_minuend,    n_Sbb_minuend)
992 COMPILETIME_ASSERT((int)n_ia32_l_binop_right  == (int)n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
993 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Sbb_eflags,     n_Sbb_eflags)
994
995 /**
996  * Construct a binary operation which also consumes the eflags.
997  *
998  * @param node  The node to transform
999  * @param func  The node constructor function
1000  * @param flags The match flags
1001  * @return      The constructor ia32 node
1002  */
1003 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
1004                                 match_flags_t flags)
1005 {
1006         ir_node             *src_block  = get_nodes_block(node);
1007         ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
1008         ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
1009         ir_node             *eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
1010         dbg_info            *dbgi;
1011         ir_node             *block, *new_node, *new_eflags;
1012         ia32_address_mode_t  am;
1013         ia32_address_t      *addr       = &am.addr;
1014
1015         match_arguments(&am, src_block, op1, op2, eflags, flags);
1016
1017         dbgi       = get_irn_dbg_info(node);
1018         block      = be_transform_node(src_block);
1019         new_eflags = be_transform_node(eflags);
1020         new_node   = func(dbgi, block, addr->base, addr->index, addr->mem,
1021                           am.new_op1, am.new_op2, new_eflags);
1022         set_am_attributes(new_node, &am);
1023         /* we can't use source address mode anymore when using immediates */
1024         if (!(flags & match_am_and_immediates) &&
1025             (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
1026                 set_ia32_am_support(new_node, ia32_am_none);
1027         SET_IA32_ORIG_NODE(new_node, node);
1028
1029         new_node = fix_mem_proj(new_node, &am);
1030
1031         return new_node;
1032 }
1033
1034 static ir_node *get_fpcw(void)
1035 {
1036         ir_node *fpcw;
1037         if (initial_fpcw != NULL)
1038                 return initial_fpcw;
1039
1040         fpcw         = be_abi_get_ignore_irn(be_get_irg_abi(current_ir_graph),
1041                                              &ia32_registers[REG_FPCW]);
1042         initial_fpcw = be_transform_node(fpcw);
1043
1044         return initial_fpcw;
1045 }
1046
1047 /**
1048  * Construct a standard binary operation, set AM and immediate if required.
1049  *
1050  * @param op1   The first operand
1051  * @param op2   The second operand
1052  * @param func  The node constructor function
1053  * @return The constructed ia32 node.
1054  */
1055 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1056                                     construct_binop_float_func *func)
1057 {
1058         ir_mode             *mode = get_irn_mode(node);
1059         dbg_info            *dbgi;
1060         ir_node             *block, *new_block, *new_node;
1061         ia32_address_mode_t  am;
1062         ia32_address_t      *addr = &am.addr;
1063         ia32_x87_attr_t     *attr;
1064         /* All operations are considered commutative, because there are reverse
1065          * variants */
1066         match_flags_t        flags = match_commutative;
1067
1068         /* happens for div nodes... */
1069         if (mode == mode_T) {
1070                 if (is_Div(node))
1071                         mode = get_Div_resmode(node);
1072                 else
1073                         panic("can't determine mode");
1074         }
1075
1076         /* cannot use address mode with long double on x87 */
1077         if (get_mode_size_bits(mode) <= 64)
1078                 flags |= match_am;
1079
1080         block = get_nodes_block(node);
1081         match_arguments(&am, block, op1, op2, NULL, flags);
1082
1083         dbgi      = get_irn_dbg_info(node);
1084         new_block = be_transform_node(block);
1085         new_node  = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1086                          am.new_op1, am.new_op2, get_fpcw());
1087         set_am_attributes(new_node, &am);
1088
1089         attr = get_ia32_x87_attr(new_node);
1090         attr->attr.data.ins_permuted = am.ins_permuted;
1091
1092         SET_IA32_ORIG_NODE(new_node, node);
1093
1094         new_node = fix_mem_proj(new_node, &am);
1095
1096         return new_node;
1097 }
1098
1099 /**
1100  * Construct a shift/rotate binary operation, sets AM and immediate if required.
1101  *
1102  * @param op1   The first operand
1103  * @param op2   The second operand
1104  * @param func  The node constructor function
1105  * @return The constructed ia32 node.
1106  */
1107 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1108                                 construct_shift_func *func,
1109                                 match_flags_t flags)
1110 {
1111         dbg_info *dbgi;
1112         ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
1113
1114         assert(! mode_is_float(get_irn_mode(node)));
1115         assert(flags & match_immediate);
1116         assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1117
1118         if (flags & match_mode_neutral) {
1119                 op1     = ia32_skip_downconv(op1);
1120                 new_op1 = be_transform_node(op1);
1121         } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1122                 new_op1 = create_upconv(op1, node);
1123         } else {
1124                 new_op1 = be_transform_node(op1);
1125         }
1126
1127         /* the shift amount can be any mode that is bigger than 5 bits, since all
1128          * other bits are ignored anyway */
1129         while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1130                 ir_node *const op = get_Conv_op(op2);
1131                 if (mode_is_float(get_irn_mode(op)))
1132                         break;
1133                 op2 = op;
1134                 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1135         }
1136         new_op2 = create_immediate_or_transform(op2, 0);
1137
1138         dbgi      = get_irn_dbg_info(node);
1139         block     = get_nodes_block(node);
1140         new_block = be_transform_node(block);
1141         new_node  = func(dbgi, new_block, new_op1, new_op2);
1142         SET_IA32_ORIG_NODE(new_node, node);
1143
1144         /* lowered shift instruction may have a dependency operand, handle it here */
1145         if (get_irn_arity(node) == 3) {
1146                 /* we have a dependency */
1147                 ir_node* dep = get_irn_n(node, 2);
1148                 if (get_irn_n_edges(dep) > 1) {
1149                         /* ... which has at least one user other than 'node' */
1150                         ir_node *new_dep = be_transform_node(dep);
1151                         add_irn_dep(new_node, new_dep);
1152                 }
1153         }
1154
1155         return new_node;
1156 }
1157
1158
1159 /**
1160  * Construct a standard unary operation, set AM and immediate if required.
1161  *
1162  * @param op    The operand
1163  * @param func  The node constructor function
1164  * @return The constructed ia32 node.
1165  */
1166 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1167                          match_flags_t flags)
1168 {
1169         dbg_info *dbgi;
1170         ir_node  *block, *new_block, *new_op, *new_node;
1171
1172         assert(flags == 0 || flags == match_mode_neutral);
1173         if (flags & match_mode_neutral) {
1174                 op = ia32_skip_downconv(op);
1175         }
1176
1177         new_op    = be_transform_node(op);
1178         dbgi      = get_irn_dbg_info(node);
1179         block     = get_nodes_block(node);
1180         new_block = be_transform_node(block);
1181         new_node  = func(dbgi, new_block, new_op);
1182
1183         SET_IA32_ORIG_NODE(new_node, node);
1184
1185         return new_node;
1186 }
1187
1188 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1189                                         ia32_address_t *addr)
1190 {
1191         ir_node *base, *index, *res;
1192
1193         base = addr->base;
1194         if (base == NULL) {
1195                 base = noreg_GP;
1196         } else {
1197                 base = be_transform_node(base);
1198         }
1199
1200         index = addr->index;
1201         if (index == NULL) {
1202                 index = noreg_GP;
1203         } else {
1204                 index = be_transform_node(index);
1205         }
1206
1207         res = new_bd_ia32_Lea(dbgi, block, base, index);
1208         set_address(res, addr);
1209
1210         return res;
1211 }
1212
1213 /**
1214  * Returns non-zero if a given address mode has a symbolic or
1215  * numerical offset != 0.
1216  */
1217 static int am_has_immediates(const ia32_address_t *addr)
1218 {
1219         return addr->offset != 0 || addr->symconst_ent != NULL
1220                 || addr->frame_entity || addr->use_frame;
1221 }
1222
1223 /**
1224  * Creates an ia32 Add.
1225  *
1226  * @return the created ia32 Add node
1227  */
1228 static ir_node *gen_Add(ir_node *node)
1229 {
1230         ir_mode  *mode = get_irn_mode(node);
1231         ir_node  *op1  = get_Add_left(node);
1232         ir_node  *op2  = get_Add_right(node);
1233         dbg_info *dbgi;
1234         ir_node  *block, *new_block, *new_node, *add_immediate_op;
1235         ia32_address_t       addr;
1236         ia32_address_mode_t  am;
1237
1238         if (mode_is_float(mode)) {
1239                 if (ia32_cg_config.use_sse2)
1240                         return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1241                                          match_commutative | match_am);
1242                 else
1243                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1244         }
1245
1246         ia32_mark_non_am(node);
1247
1248         op2 = ia32_skip_downconv(op2);
1249         op1 = ia32_skip_downconv(op1);
1250
1251         /**
1252          * Rules for an Add:
1253          *   0. Immediate Trees (example Add(Symconst, Const) -> Const)
1254          *   1. Add with immediate -> Lea
1255          *   2. Add with possible source address mode -> Add
1256          *   3. Otherwise -> Lea
1257          */
1258         memset(&addr, 0, sizeof(addr));
1259         ia32_create_address_mode(&addr, node, ia32_create_am_force);
1260         add_immediate_op = NULL;
1261
1262         dbgi      = get_irn_dbg_info(node);
1263         block     = get_nodes_block(node);
1264         new_block = be_transform_node(block);
1265
1266         /* a constant? */
1267         if (addr.base == NULL && addr.index == NULL) {
1268                 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1269                                              addr.symconst_sign, 0, addr.offset);
1270                 be_dep_on_frame(new_node);
1271                 SET_IA32_ORIG_NODE(new_node, node);
1272                 return new_node;
1273         }
1274         /* add with immediate? */
1275         if (addr.index == NULL) {
1276                 add_immediate_op = addr.base;
1277         } else if (addr.base == NULL && addr.scale == 0) {
1278                 add_immediate_op = addr.index;
1279         }
1280
1281         if (add_immediate_op != NULL) {
1282                 if (!am_has_immediates(&addr)) {
1283 #ifdef DEBUG_libfirm
1284                         ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1285                                            node);
1286 #endif
1287                         return be_transform_node(add_immediate_op);
1288                 }
1289
1290                 new_node = create_lea_from_address(dbgi, new_block, &addr);
1291                 SET_IA32_ORIG_NODE(new_node, node);
1292                 return new_node;
1293         }
1294
1295         /* test if we can use source address mode */
1296         match_arguments(&am, block, op1, op2, NULL, match_commutative
1297                         | match_mode_neutral | match_am | match_immediate | match_try_am);
1298
1299         /* construct an Add with source address mode */
1300         if (am.op_type == ia32_AddrModeS) {
1301                 ia32_address_t *am_addr = &am.addr;
1302                 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1303                                          am_addr->index, am_addr->mem, am.new_op1,
1304                                          am.new_op2);
1305                 set_am_attributes(new_node, &am);
1306                 SET_IA32_ORIG_NODE(new_node, node);
1307
1308                 new_node = fix_mem_proj(new_node, &am);
1309
1310                 return new_node;
1311         }
1312
1313         /* otherwise construct a lea */
1314         new_node = create_lea_from_address(dbgi, new_block, &addr);
1315         SET_IA32_ORIG_NODE(new_node, node);
1316         return new_node;
1317 }
1318
1319 /**
1320  * Creates an ia32 Mul.
1321  *
1322  * @return the created ia32 Mul node
1323  */
1324 static ir_node *gen_Mul(ir_node *node)
1325 {
1326         ir_node *op1  = get_Mul_left(node);
1327         ir_node *op2  = get_Mul_right(node);
1328         ir_mode *mode = get_irn_mode(node);
1329
1330         if (mode_is_float(mode)) {
1331                 if (ia32_cg_config.use_sse2)
1332                         return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1333                                          match_commutative | match_am);
1334                 else
1335                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1336         }
1337         return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1338                          match_commutative | match_am | match_mode_neutral |
1339                          match_immediate | match_am_and_immediates);
1340 }
1341
1342 /**
1343  * Creates an ia32 Mulh.
1344  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1345  * this result while Mul returns the lower 32 bit.
1346  *
1347  * @return the created ia32 Mulh node
1348  */
1349 static ir_node *gen_Mulh(ir_node *node)
1350 {
1351         dbg_info *dbgi      = get_irn_dbg_info(node);
1352         ir_node  *op1       = get_Mulh_left(node);
1353         ir_node  *op2       = get_Mulh_right(node);
1354         ir_mode  *mode      = get_irn_mode(node);
1355         ir_node  *new_node;
1356         ir_node  *proj_res_high;
1357
1358         if (get_mode_size_bits(mode) != 32) {
1359                 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1360         }
1361
1362         if (mode_is_signed(mode)) {
1363                 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1364                 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1365         } else {
1366                 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1367                 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1368         }
1369         return proj_res_high;
1370 }
1371
1372 /**
1373  * Creates an ia32 And.
1374  *
1375  * @return The created ia32 And node
1376  */
1377 static ir_node *gen_And(ir_node *node)
1378 {
1379         ir_node *op1 = get_And_left(node);
1380         ir_node *op2 = get_And_right(node);
1381         assert(! mode_is_float(get_irn_mode(node)));
1382
1383         /* is it a zero extension? */
1384         if (is_Const(op2)) {
1385                 ir_tarval *tv = get_Const_tarval(op2);
1386                 long       v  = get_tarval_long(tv);
1387
1388                 if (v == 0xFF || v == 0xFFFF) {
1389                         dbg_info *dbgi   = get_irn_dbg_info(node);
1390                         ir_node  *block  = get_nodes_block(node);
1391                         ir_mode  *src_mode;
1392                         ir_node  *res;
1393
1394                         if (v == 0xFF) {
1395                                 src_mode = mode_Bu;
1396                         } else {
1397                                 assert(v == 0xFFFF);
1398                                 src_mode = mode_Hu;
1399                         }
1400                         res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1401
1402                         return res;
1403                 }
1404         }
1405         return gen_binop(node, op1, op2, new_bd_ia32_And,
1406                         match_commutative | match_mode_neutral | match_am | match_immediate);
1407 }
1408
1409
1410
1411 /**
1412  * Creates an ia32 Or.
1413  *
1414  * @return The created ia32 Or node
1415  */
1416 static ir_node *gen_Or(ir_node *node)
1417 {
1418         ir_node *op1 = get_Or_left(node);
1419         ir_node *op2 = get_Or_right(node);
1420
1421         assert (! mode_is_float(get_irn_mode(node)));
1422         return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1423                         | match_mode_neutral | match_am | match_immediate);
1424 }
1425
1426
1427
1428 /**
1429  * Creates an ia32 Eor.
1430  *
1431  * @return The created ia32 Eor node
1432  */
1433 static ir_node *gen_Eor(ir_node *node)
1434 {
1435         ir_node *op1 = get_Eor_left(node);
1436         ir_node *op2 = get_Eor_right(node);
1437
1438         assert(! mode_is_float(get_irn_mode(node)));
1439         return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1440                         | match_mode_neutral | match_am | match_immediate);
1441 }
1442
1443
1444 /**
1445  * Creates an ia32 Sub.
1446  *
1447  * @return The created ia32 Sub node
1448  */
1449 static ir_node *gen_Sub(ir_node *node)
1450 {
1451         ir_node  *op1  = get_Sub_left(node);
1452         ir_node  *op2  = get_Sub_right(node);
1453         ir_mode  *mode = get_irn_mode(node);
1454
1455         if (mode_is_float(mode)) {
1456                 if (ia32_cg_config.use_sse2)
1457                         return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1458                 else
1459                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1460         }
1461
1462         if (is_Const(op2)) {
1463                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1464                            node);
1465         }
1466
1467         return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1468                         | match_am | match_immediate);
1469 }
1470
1471 static ir_node *transform_AM_mem(ir_node *const block,
1472                                  ir_node  *const src_val,
1473                                  ir_node  *const src_mem,
1474                                  ir_node  *const am_mem)
1475 {
1476         if (is_NoMem(am_mem)) {
1477                 return be_transform_node(src_mem);
1478         } else if (is_Proj(src_val) &&
1479                    is_Proj(src_mem) &&
1480                    get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1481                 /* avoid memory loop */
1482                 return am_mem;
1483         } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1484                 ir_node  *const ptr_pred = get_Proj_pred(src_val);
1485                 int       const arity    = get_Sync_n_preds(src_mem);
1486                 int             n        = 0;
1487                 ir_node **      ins;
1488                 int             i;
1489
1490                 NEW_ARR_A(ir_node*, ins, arity + 1);
1491
1492                 /* NOTE: This sometimes produces dead-code because the old sync in
1493                  * src_mem might not be used anymore, we should detect this case
1494                  * and kill the sync... */
1495                 for (i = arity - 1; i >= 0; --i) {
1496                         ir_node *const pred = get_Sync_pred(src_mem, i);
1497
1498                         /* avoid memory loop */
1499                         if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1500                                 continue;
1501
1502                         ins[n++] = be_transform_node(pred);
1503                 }
1504
1505                 if (n==1 && ins[0] == am_mem) {
1506                         return am_mem;
1507                         /* creating a new Sync and relying on CSE may fail,
1508                          * if am_mem is a ProjM, which does not yet verify. */
1509                 }
1510
1511                 ins[n++] = am_mem;
1512                 return new_r_Sync(block, n, ins);
1513         } else {
1514                 ir_node *ins[2];
1515
1516                 ins[0] = be_transform_node(src_mem);
1517                 ins[1] = am_mem;
1518                 return new_r_Sync(block, 2, ins);
1519         }
1520 }
1521
1522 /**
1523  * Create a 32bit to 64bit signed extension.
1524  *
1525  * @param dbgi   debug info
1526  * @param block  the block where node nodes should be placed
1527  * @param val    the value to extend
1528  * @param orig   the original node
1529  */
1530 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1531                                  ir_node *val, const ir_node *orig)
1532 {
1533         ir_node *res;
1534
1535         (void)orig;
1536         if (ia32_cg_config.use_short_sex_eax) {
1537                 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1538                 be_dep_on_frame(pval);
1539                 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1540         } else {
1541                 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1542                 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1543         }
1544         SET_IA32_ORIG_NODE(res, orig);
1545         return res;
1546 }
1547
1548 /**
1549  * Generates an ia32 Div with additional infrastructure for the
1550  * register allocator if needed.
1551  */
1552 static ir_node *create_Div(ir_node *node)
1553 {
1554         dbg_info *dbgi      = get_irn_dbg_info(node);
1555         ir_node  *block     = get_nodes_block(node);
1556         ir_node  *new_block = be_transform_node(block);
1557         ir_node  *mem;
1558         ir_node  *new_mem;
1559         ir_node  *op1;
1560         ir_node  *op2;
1561         ir_node  *new_node;
1562         ir_mode  *mode;
1563         ir_node  *sign_extension;
1564         ia32_address_mode_t  am;
1565         ia32_address_t      *addr = &am.addr;
1566
1567         /* the upper bits have random contents for smaller modes */
1568         switch (get_irn_opcode(node)) {
1569         case iro_Div:
1570                 op1     = get_Div_left(node);
1571                 op2     = get_Div_right(node);
1572                 mem     = get_Div_mem(node);
1573                 mode    = get_Div_resmode(node);
1574                 break;
1575         case iro_Mod:
1576                 op1     = get_Mod_left(node);
1577                 op2     = get_Mod_right(node);
1578                 mem     = get_Mod_mem(node);
1579                 mode    = get_Mod_resmode(node);
1580                 break;
1581         default:
1582                 panic("invalid divmod node %+F", node);
1583         }
1584
1585         match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1586
1587         /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1588            is the memory of the consumed address. We can have only the second op as address
1589            in Div nodes, so check only op2. */
1590         new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1591
1592         if (mode_is_signed(mode)) {
1593                 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1594                 new_node       = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1595                                 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1596         } else {
1597                 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1598                 be_dep_on_frame(sign_extension);
1599
1600                 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1601                                            addr->index, new_mem, am.new_op2,
1602                                            am.new_op1, sign_extension);
1603         }
1604
1605         set_irn_pinned(new_node, get_irn_pinned(node));
1606
1607         set_am_attributes(new_node, &am);
1608         SET_IA32_ORIG_NODE(new_node, node);
1609
1610         new_node = fix_mem_proj(new_node, &am);
1611
1612         return new_node;
1613 }
1614
1615 /**
1616  * Generates an ia32 Mod.
1617  */
1618 static ir_node *gen_Mod(ir_node *node)
1619 {
1620         return create_Div(node);
1621 }
1622
1623 /**
1624  * Generates an ia32 Div.
1625  */
1626 static ir_node *gen_Div(ir_node *node)
1627 {
1628         ir_mode *mode = get_Div_resmode(node);
1629         if (mode_is_float(mode)) {
1630                 ir_node *op1 = get_Div_left(node);
1631                 ir_node *op2 = get_Div_right(node);
1632
1633                 if (ia32_cg_config.use_sse2) {
1634                         return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1635                 } else {
1636                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1637                 }
1638         }
1639
1640         return create_Div(node);
1641 }
1642
1643 /**
1644  * Creates an ia32 Shl.
1645  *
1646  * @return The created ia32 Shl node
1647  */
1648 static ir_node *gen_Shl(ir_node *node)
1649 {
1650         ir_node *left  = get_Shl_left(node);
1651         ir_node *right = get_Shl_right(node);
1652
1653         return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1654                                match_mode_neutral | match_immediate);
1655 }
1656
1657 /**
1658  * Creates an ia32 Shr.
1659  *
1660  * @return The created ia32 Shr node
1661  */
1662 static ir_node *gen_Shr(ir_node *node)
1663 {
1664         ir_node *left  = get_Shr_left(node);
1665         ir_node *right = get_Shr_right(node);
1666
1667         return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1668 }
1669
1670
1671
1672 /**
1673  * Creates an ia32 Sar.
1674  *
1675  * @return The created ia32 Shrs node
1676  */
1677 static ir_node *gen_Shrs(ir_node *node)
1678 {
1679         ir_node *left  = get_Shrs_left(node);
1680         ir_node *right = get_Shrs_right(node);
1681
1682         if (is_Const(right)) {
1683                 ir_tarval *tv  = get_Const_tarval(right);
1684                 long       val = get_tarval_long(tv);
1685                 if (val == 31) {
1686                         /* this is a sign extension */
1687                         dbg_info *dbgi   = get_irn_dbg_info(node);
1688                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1689                         ir_node  *new_op = be_transform_node(left);
1690
1691                         return create_sex_32_64(dbgi, block, new_op, node);
1692                 }
1693         }
1694
1695         /* 8 or 16 bit sign extension? */
1696         if (is_Const(right) && is_Shl(left)) {
1697                 ir_node *shl_left  = get_Shl_left(left);
1698                 ir_node *shl_right = get_Shl_right(left);
1699                 if (is_Const(shl_right)) {
1700                         ir_tarval *tv1 = get_Const_tarval(right);
1701                         ir_tarval *tv2 = get_Const_tarval(shl_right);
1702                         if (tv1 == tv2 && tarval_is_long(tv1)) {
1703                                 long val = get_tarval_long(tv1);
1704                                 if (val == 16 || val == 24) {
1705                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1706                                         ir_node  *block  = get_nodes_block(node);
1707                                         ir_mode  *src_mode;
1708                                         ir_node  *res;
1709
1710                                         if (val == 24) {
1711                                                 src_mode = mode_Bs;
1712                                         } else {
1713                                                 assert(val == 16);
1714                                                 src_mode = mode_Hs;
1715                                         }
1716                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1717                                                               shl_left, node);
1718
1719                                         return res;
1720                                 }
1721                         }
1722                 }
1723         }
1724
1725         return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1726 }
1727
1728
1729
1730 /**
1731  * Creates an ia32 Rol.
1732  *
1733  * @param op1   The first operator
1734  * @param op2   The second operator
1735  * @return The created ia32 RotL node
1736  */
1737 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1738 {
1739         return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1740 }
1741
1742
1743
1744 /**
1745  * Creates an ia32 Ror.
1746  * NOTE: There is no RotR with immediate because this would always be a RotL
1747  *       "imm-mode_size_bits" which can be pre-calculated.
1748  *
1749  * @param op1   The first operator
1750  * @param op2   The second operator
1751  * @return The created ia32 RotR node
1752  */
1753 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1754 {
1755         return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1756 }
1757
1758
1759
1760 /**
1761  * Creates an ia32 RotR or RotL (depending on the found pattern).
1762  *
1763  * @return The created ia32 RotL or RotR node
1764  */
1765 static ir_node *gen_Rotl(ir_node *node)
1766 {
1767         ir_node *op1    = get_Rotl_left(node);
1768         ir_node *op2    = get_Rotl_right(node);
1769
1770         if (is_Minus(op2)) {
1771                 return gen_Ror(node, op1, get_Minus_op(op2));
1772         }
1773
1774         return gen_Rol(node, op1, op2);
1775 }
1776
1777
1778
1779 /**
1780  * Transforms a Minus node.
1781  *
1782  * @return The created ia32 Minus node
1783  */
1784 static ir_node *gen_Minus(ir_node *node)
1785 {
1786         ir_node   *op    = get_Minus_op(node);
1787         ir_node   *block = be_transform_node(get_nodes_block(node));
1788         dbg_info  *dbgi  = get_irn_dbg_info(node);
1789         ir_mode   *mode  = get_irn_mode(node);
1790         ir_entity *ent;
1791         ir_node   *new_node;
1792         int        size;
1793
1794         if (mode_is_float(mode)) {
1795                 ir_node *new_op = be_transform_node(op);
1796                 if (ia32_cg_config.use_sse2) {
1797                         /* TODO: non-optimal... if we have many xXors, then we should
1798                          * rather create a load for the const and use that instead of
1799                          * several AM nodes... */
1800                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1801
1802                         new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1803                                                     noreg_GP, nomem, new_op, noreg_xmm);
1804
1805                         size = get_mode_size_bits(mode);
1806                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1807
1808                         set_ia32_am_sc(new_node, ent);
1809                         set_ia32_op_type(new_node, ia32_AddrModeS);
1810                         set_ia32_ls_mode(new_node, mode);
1811                 } else {
1812                         new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1813                 }
1814         } else {
1815                 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1816         }
1817
1818         SET_IA32_ORIG_NODE(new_node, node);
1819
1820         return new_node;
1821 }
1822
1823 /**
1824  * Transforms a Not node.
1825  *
1826  * @return The created ia32 Not node
1827  */
1828 static ir_node *gen_Not(ir_node *node)
1829 {
1830         ir_node *op = get_Not_op(node);
1831
1832         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1833         assert (! mode_is_float(get_irn_mode(node)));
1834
1835         return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1836 }
1837
1838 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1839                            bool negate, ir_node *node)
1840 {
1841         ir_node   *new_block = be_transform_node(block);
1842         ir_mode   *mode      = get_irn_mode(op);
1843         ir_node   *new_op;
1844         ir_node   *new_node;
1845         int        size;
1846         ir_entity *ent;
1847
1848         if (mode_is_float(mode)) {
1849                 new_op = be_transform_node(op);
1850
1851                 if (ia32_cg_config.use_sse2) {
1852                         ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1853                         new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1854                                                     noreg_GP, nomem, new_op, noreg_fp);
1855
1856                         size = get_mode_size_bits(mode);
1857                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1858
1859                         set_ia32_am_sc(new_node, ent);
1860
1861                         SET_IA32_ORIG_NODE(new_node, node);
1862
1863                         set_ia32_op_type(new_node, ia32_AddrModeS);
1864                         set_ia32_ls_mode(new_node, mode);
1865
1866                         /* TODO, implement -Abs case */
1867                         assert(!negate);
1868                 } else {
1869                         new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1870                         SET_IA32_ORIG_NODE(new_node, node);
1871                         if (negate) {
1872                                 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1873                                 SET_IA32_ORIG_NODE(new_node, node);
1874                         }
1875                 }
1876         } else {
1877                 ir_node *xorn;
1878                 ir_node *sign_extension;
1879
1880                 if (get_mode_size_bits(mode) == 32) {
1881                         new_op = be_transform_node(op);
1882                 } else {
1883                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1884                 }
1885
1886                 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1887
1888                 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1889                                       nomem, new_op, sign_extension);
1890                 SET_IA32_ORIG_NODE(xorn, node);
1891
1892                 if (negate) {
1893                         new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1894                                                                            nomem, sign_extension, xorn);
1895                 } else {
1896                         new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1897                                                                            nomem, xorn, sign_extension);
1898                 }
1899                 SET_IA32_ORIG_NODE(new_node, node);
1900         }
1901
1902         return new_node;
1903 }
1904
1905 /**
1906  * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1907  */
1908 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1909 {
1910         dbg_info *dbgi      = get_irn_dbg_info(cmp);
1911         ir_node  *block     = get_nodes_block(cmp);
1912         ir_node  *new_block = be_transform_node(block);
1913         ir_node  *op1       = be_transform_node(x);
1914         ir_node  *op2       = be_transform_node(n);
1915
1916         return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1917 }
1918
1919 static ia32_condition_code_t pnc_to_condition_code(pn_Cmp pnc, ir_mode *mode)
1920 {
1921         if (mode_is_float(mode)) {
1922                 switch (pnc) {
1923                 case pn_Cmp_Eq:  return ia32_cc_float_equal;
1924                 case pn_Cmp_Lt:  return ia32_cc_float_below;
1925                 case pn_Cmp_Le:  return ia32_cc_float_below_equal;
1926                 case pn_Cmp_Gt:  return ia32_cc_float_above;
1927                 case pn_Cmp_Ge:  return ia32_cc_float_above_equal;
1928                 case pn_Cmp_Lg:  return ia32_cc_not_equal;
1929                 case pn_Cmp_Leg: return ia32_cc_not_parity;
1930                 case pn_Cmp_Uo:  return ia32_cc_parity;
1931                 case pn_Cmp_Ue:  return ia32_cc_equal;
1932                 case pn_Cmp_Ul:  return ia32_cc_float_unordered_below;
1933                 case pn_Cmp_Ule: return ia32_cc_float_unordered_below_equal;
1934                 case pn_Cmp_Ug:  return ia32_cc_float_unordered_above;
1935                 case pn_Cmp_Uge: return ia32_cc_float_unordered_above_equal;
1936                 case pn_Cmp_Ne:  return ia32_cc_float_not_equal;
1937                 case pn_Cmp_False:
1938                 case pn_Cmp_True:
1939                 case pn_Cmp_max:
1940                         /* should we introduce a jump always/jump never? */
1941                         break;
1942                 }
1943                 panic("Unexpected float pnc");
1944         } else if (mode_is_signed(mode)) {
1945                 switch (pnc) {
1946                 case pn_Cmp_Ue:
1947                 case pn_Cmp_Eq:  return ia32_cc_equal;
1948                 case pn_Cmp_Ul:
1949                 case pn_Cmp_Lt:  return ia32_cc_less;
1950                 case pn_Cmp_Ule:
1951                 case pn_Cmp_Le:  return ia32_cc_less_equal;
1952                 case pn_Cmp_Ug:
1953                 case pn_Cmp_Gt:  return ia32_cc_greater;
1954                 case pn_Cmp_Uge:
1955                 case pn_Cmp_Ge:  return ia32_cc_greater_equal;
1956                 case pn_Cmp_Lg:
1957                 case pn_Cmp_Ne:  return ia32_cc_not_equal;
1958                 case pn_Cmp_Leg:
1959                 case pn_Cmp_Uo:
1960                 case pn_Cmp_False:
1961                 case pn_Cmp_True:
1962                 case pn_Cmp_max:
1963                         /* introduce jump always/jump never? */
1964                         break;
1965                 }
1966                 panic("Unexpected pnc");
1967         } else {
1968                 switch (pnc) {
1969                 case pn_Cmp_Ue:
1970                 case pn_Cmp_Eq:  return ia32_cc_equal;
1971                 case pn_Cmp_Ul:
1972                 case pn_Cmp_Lt:  return ia32_cc_below;
1973                 case pn_Cmp_Ule:
1974                 case pn_Cmp_Le:  return ia32_cc_below_equal;
1975                 case pn_Cmp_Ug:
1976                 case pn_Cmp_Gt:  return ia32_cc_above;
1977                 case pn_Cmp_Uge:
1978                 case pn_Cmp_Ge:  return ia32_cc_above_equal;
1979                 case pn_Cmp_Lg:
1980                 case pn_Cmp_Ne:  return ia32_cc_not_equal;
1981                 case pn_Cmp_Leg:
1982                 case pn_Cmp_Uo:
1983                 case pn_Cmp_False:
1984                 case pn_Cmp_True:
1985                 case pn_Cmp_max:
1986                         /* introduce jump always/jump never? */
1987                         break;
1988                 }
1989                 panic("Unexpected pnc");
1990         }
1991 }
1992
1993 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
1994 {
1995         /* a mode_b value, we have to compare it against 0 */
1996         dbg_info *dbgi      = get_irn_dbg_info(node);
1997         ir_node  *new_block = be_transform_node(get_nodes_block(node));
1998         ir_node  *new_op    = be_transform_node(node);
1999         ir_node  *flags     = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
2000         *cc_out  = ia32_cc_not_equal;
2001         return flags;
2002 }
2003
2004 static ir_node *get_flags_node_cmp(ir_node *node, ia32_condition_code_t *cc_out)
2005 {
2006         /* must have a Proj(Cmp) as input */
2007         ir_node  *cmp  = get_Proj_pred(node);
2008         int       pnc  = get_Proj_pn_cmp(node);
2009         ir_node  *l    = get_Cmp_left(cmp);
2010         ir_mode  *mode = get_irn_mode(l);
2011         ir_node  *flags;
2012
2013         /* check for bit-test */
2014         if (ia32_cg_config.use_bt
2015                         && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq || pnc == pn_Cmp_Ne
2016                                 || pnc == pn_Cmp_Ue)) {
2017                 ir_node *l = get_Cmp_left(cmp);
2018                 ir_node *r = get_Cmp_right(cmp);
2019                 if (is_And(l)) {
2020                         ir_node *la = get_And_left(l);
2021                         ir_node *ra = get_And_right(l);
2022                         if (is_Shl(ra)) {
2023                                 ir_node *tmp = la;
2024                                 la = ra;
2025                                 ra = tmp;
2026                         }
2027                         if (is_Shl(la)) {
2028                                 ir_node *c = get_Shl_left(la);
2029                                 if (is_Const_1(c) && is_Const_0(r)) {
2030                                         /* (1 << n) & ra) */
2031                                         ir_node *n = get_Shl_right(la);
2032                                         flags    = gen_bt(cmp, ra, n);
2033                                         /* the bit is copied into the CF flag */
2034                                         if (pnc & pn_Cmp_Eq)
2035                                                 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2036                                         else
2037                                                 *cc_out = ia32_cc_below;       /* test for CF=1 */
2038                                         return flags;
2039                                 }
2040                         }
2041                 }
2042         }
2043
2044         /* just do a normal transformation of the Cmp */
2045         *cc_out = pnc_to_condition_code(pnc, mode);
2046         flags   = be_transform_node(cmp);
2047         return flags;
2048 }
2049
2050 /**
2051  * Transform a node returning a "flag" result.
2052  *
2053  * @param node    the node to transform
2054  * @param cc_out  the compare mode to use
2055  */
2056 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2057 {
2058         if (is_Proj(node) && is_Cmp(get_Proj_pred(node)))
2059                 return get_flags_node_cmp(node, cc_out);
2060         assert(get_irn_mode(node) == mode_b);
2061         return get_flags_mode_b(node, cc_out);
2062 }
2063
2064 /**
2065  * Transforms a Load.
2066  *
2067  * @return the created ia32 Load node
2068  */
2069 static ir_node *gen_Load(ir_node *node)
2070 {
2071         ir_node  *old_block = get_nodes_block(node);
2072         ir_node  *block   = be_transform_node(old_block);
2073         ir_node  *ptr     = get_Load_ptr(node);
2074         ir_node  *mem     = get_Load_mem(node);
2075         ir_node  *new_mem = be_transform_node(mem);
2076         ir_node  *base;
2077         ir_node  *index;
2078         dbg_info *dbgi    = get_irn_dbg_info(node);
2079         ir_mode  *mode    = get_Load_mode(node);
2080         ir_node  *new_node;
2081         ia32_address_t addr;
2082
2083         /* construct load address */
2084         memset(&addr, 0, sizeof(addr));
2085         ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2086         base  = addr.base;
2087         index = addr.index;
2088
2089         if (base == NULL) {
2090                 base = noreg_GP;
2091         } else {
2092                 base = be_transform_node(base);
2093         }
2094
2095         if (index == NULL) {
2096                 index = noreg_GP;
2097         } else {
2098                 index = be_transform_node(index);
2099         }
2100
2101         if (mode_is_float(mode)) {
2102                 if (ia32_cg_config.use_sse2) {
2103                         new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2104                                                      mode);
2105                 } else {
2106                         new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2107                                                     mode);
2108                 }
2109         } else {
2110                 assert(mode != mode_b);
2111
2112                 /* create a conv node with address mode for smaller modes */
2113                 if (get_mode_size_bits(mode) < 32) {
2114                         new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2115                                                         new_mem, noreg_GP, mode);
2116                 } else {
2117                         new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2118                 }
2119         }
2120
2121         set_irn_pinned(new_node, get_irn_pinned(node));
2122         set_ia32_op_type(new_node, ia32_AddrModeS);
2123         set_ia32_ls_mode(new_node, mode);
2124         set_address(new_node, &addr);
2125
2126         if (get_irn_pinned(node) == op_pin_state_floats) {
2127                 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2128                                 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2129                                 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2130                 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2131         }
2132
2133         SET_IA32_ORIG_NODE(new_node, node);
2134
2135         be_dep_on_frame(new_node);
2136         return new_node;
2137 }
2138
2139 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2140                        ir_node *ptr, ir_node *other)
2141 {
2142         ir_node *load;
2143
2144         if (!is_Proj(node))
2145                 return 0;
2146
2147         /* we only use address mode if we're the only user of the load */
2148         if (get_irn_n_edges(node) > 1)
2149                 return 0;
2150
2151         load = get_Proj_pred(node);
2152         if (!is_Load(load))
2153                 return 0;
2154         if (get_nodes_block(load) != block)
2155                 return 0;
2156
2157         /* store should have the same pointer as the load */
2158         if (get_Load_ptr(load) != ptr)
2159                 return 0;
2160
2161         /* don't do AM if other node inputs depend on the load (via mem-proj) */
2162         if (other != NULL                   &&
2163             get_nodes_block(other) == block &&
2164             heights_reachable_in_block(ia32_heights, other, load)) {
2165                 return 0;
2166         }
2167
2168         if (ia32_prevents_AM(block, load, mem))
2169                 return 0;
2170         /* Store should be attached to the load via mem */
2171         assert(heights_reachable_in_block(ia32_heights, mem, load));
2172
2173         return 1;
2174 }
2175
2176 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2177                               ir_node *mem, ir_node *ptr, ir_mode *mode,
2178                               construct_binop_dest_func *func,
2179                               construct_binop_dest_func *func8bit,
2180                                                           match_flags_t flags)
2181 {
2182         ir_node  *src_block = get_nodes_block(node);
2183         ir_node  *block;
2184         dbg_info *dbgi;
2185         ir_node  *new_mem;
2186         ir_node  *new_node;
2187         ir_node  *new_op;
2188         ir_node  *mem_proj;
2189         int       commutative;
2190         ia32_address_mode_t  am;
2191         ia32_address_t      *addr = &am.addr;
2192         memset(&am, 0, sizeof(am));
2193
2194         assert(flags & match_immediate); /* there is no destam node without... */
2195         commutative = (flags & match_commutative) != 0;
2196
2197         if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2198                 build_address(&am, op1, ia32_create_am_double_use);
2199                 new_op = create_immediate_or_transform(op2, 0);
2200         } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2201                 build_address(&am, op2, ia32_create_am_double_use);
2202                 new_op = create_immediate_or_transform(op1, 0);
2203         } else {
2204                 return NULL;
2205         }
2206
2207         if (addr->base == NULL)
2208                 addr->base = noreg_GP;
2209         if (addr->index == NULL)
2210                 addr->index = noreg_GP;
2211         if (addr->mem == NULL)
2212                 addr->mem = nomem;
2213
2214         dbgi    = get_irn_dbg_info(node);
2215         block   = be_transform_node(src_block);
2216         new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2217
2218         if (get_mode_size_bits(mode) == 8) {
2219                 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2220         } else {
2221                 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2222         }
2223         set_address(new_node, addr);
2224         set_ia32_op_type(new_node, ia32_AddrModeD);
2225         set_ia32_ls_mode(new_node, mode);
2226         SET_IA32_ORIG_NODE(new_node, node);
2227
2228         be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2229         mem_proj = be_transform_node(am.mem_proj);
2230         be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2231
2232         return new_node;
2233 }
2234
2235 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2236                              ir_node *ptr, ir_mode *mode,
2237                              construct_unop_dest_func *func)
2238 {
2239         ir_node  *src_block = get_nodes_block(node);
2240         ir_node  *block;
2241         dbg_info *dbgi;
2242         ir_node  *new_mem;
2243         ir_node  *new_node;
2244         ir_node  *mem_proj;
2245         ia32_address_mode_t  am;
2246         ia32_address_t *addr = &am.addr;
2247
2248         if (!use_dest_am(src_block, op, mem, ptr, NULL))
2249                 return NULL;
2250
2251         memset(&am, 0, sizeof(am));
2252         build_address(&am, op, ia32_create_am_double_use);
2253
2254         dbgi     = get_irn_dbg_info(node);
2255         block    = be_transform_node(src_block);
2256         new_mem  = transform_AM_mem(block, am.am_node, mem, addr->mem);
2257         new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2258         set_address(new_node, addr);
2259         set_ia32_op_type(new_node, ia32_AddrModeD);
2260         set_ia32_ls_mode(new_node, mode);
2261         SET_IA32_ORIG_NODE(new_node, node);
2262
2263         be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2264         mem_proj = be_transform_node(am.mem_proj);
2265         be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2266
2267         return new_node;
2268 }
2269
2270 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2271 {
2272         ir_mode              *mode      = get_irn_mode(node);
2273         ir_node              *mux_true  = get_Mux_true(node);
2274         ir_node              *mux_false = get_Mux_false(node);
2275         ir_node              *cond;
2276         dbg_info             *dbgi;
2277         ir_node              *block;
2278         ir_node              *new_block;
2279         ir_node              *flags;
2280         ir_node              *new_node;
2281         bool                  negated;
2282         ia32_condition_code_t cc;
2283         ia32_address_t        addr;
2284
2285         if (get_mode_size_bits(mode) != 8)
2286                 return NULL;
2287
2288         if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2289                 negated = false;
2290         } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2291                 negated = true;
2292         } else {
2293                 return NULL;
2294         }
2295
2296         cond  = get_Mux_sel(node);
2297         flags = get_flags_node(cond, &cc);
2298         /* we can't handle the float special cases with SetM */
2299         if (cc & ia32_cc_additional_float_cases)
2300                 return NULL;
2301         if (negated)
2302                 cc = ia32_negate_condition_code(cc);
2303
2304         build_address_ptr(&addr, ptr, mem);
2305
2306         dbgi      = get_irn_dbg_info(node);
2307         block     = get_nodes_block(node);
2308         new_block = be_transform_node(block);
2309         new_node  = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2310                                          addr.index, addr.mem, flags, cc);
2311         set_address(new_node, &addr);
2312         set_ia32_op_type(new_node, ia32_AddrModeD);
2313         set_ia32_ls_mode(new_node, mode);
2314         SET_IA32_ORIG_NODE(new_node, node);
2315
2316         return new_node;
2317 }
2318
2319 static ir_node *try_create_dest_am(ir_node *node)
2320 {
2321         ir_node  *val  = get_Store_value(node);
2322         ir_node  *mem  = get_Store_mem(node);
2323         ir_node  *ptr  = get_Store_ptr(node);
2324         ir_mode  *mode = get_irn_mode(val);
2325         unsigned  bits = get_mode_size_bits(mode);
2326         ir_node  *op1;
2327         ir_node  *op2;
2328         ir_node  *new_node;
2329
2330         /* handle only GP modes for now... */
2331         if (!ia32_mode_needs_gp_reg(mode))
2332                 return NULL;
2333
2334         for (;;) {
2335                 /* store must be the only user of the val node */
2336                 if (get_irn_n_edges(val) > 1)
2337                         return NULL;
2338                 /* skip pointless convs */
2339                 if (is_Conv(val)) {
2340                         ir_node *conv_op   = get_Conv_op(val);
2341                         ir_mode *pred_mode = get_irn_mode(conv_op);
2342                         if (!ia32_mode_needs_gp_reg(pred_mode))
2343                                 break;
2344                         if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2345                                 val = conv_op;
2346                                 continue;
2347                         }
2348                 }
2349                 break;
2350         }
2351
2352         /* value must be in the same block */
2353         if (get_nodes_block(node) != get_nodes_block(val))
2354                 return NULL;
2355
2356         switch (get_irn_opcode(val)) {
2357         case iro_Add:
2358                 op1      = get_Add_left(val);
2359                 op2      = get_Add_right(val);
2360                 if (ia32_cg_config.use_incdec) {
2361                         if (is_Const_1(op2)) {
2362                                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2363                                 break;
2364                         } else if (is_Const_Minus_1(op2)) {
2365                                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2366                                 break;
2367                         }
2368                 }
2369                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2370                                          new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2371                                          match_commutative | match_immediate);
2372                 break;
2373         case iro_Sub:
2374                 op1      = get_Sub_left(val);
2375                 op2      = get_Sub_right(val);
2376                 if (is_Const(op2)) {
2377                         ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2378                 }
2379                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2380                                          new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2381                                          match_immediate);
2382                 break;
2383         case iro_And:
2384                 op1      = get_And_left(val);
2385                 op2      = get_And_right(val);
2386                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2387                                          new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2388                                          match_commutative | match_immediate);
2389                 break;
2390         case iro_Or:
2391                 op1      = get_Or_left(val);
2392                 op2      = get_Or_right(val);
2393                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2394                                          new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2395                                          match_commutative | match_immediate);
2396                 break;
2397         case iro_Eor:
2398                 op1      = get_Eor_left(val);
2399                 op2      = get_Eor_right(val);
2400                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2401                                          new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2402                                          match_commutative | match_immediate);
2403                 break;
2404         case iro_Shl:
2405                 op1      = get_Shl_left(val);
2406                 op2      = get_Shl_right(val);
2407                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2408                                          new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2409                                          match_immediate);
2410                 break;
2411         case iro_Shr:
2412                 op1      = get_Shr_left(val);
2413                 op2      = get_Shr_right(val);
2414                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2415                                          new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2416                                          match_immediate);
2417                 break;
2418         case iro_Shrs:
2419                 op1      = get_Shrs_left(val);
2420                 op2      = get_Shrs_right(val);
2421                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2422                                          new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2423                                          match_immediate);
2424                 break;
2425         case iro_Rotl:
2426                 op1      = get_Rotl_left(val);
2427                 op2      = get_Rotl_right(val);
2428                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2429                                          new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2430                                          match_immediate);
2431                 break;
2432         /* TODO: match ROR patterns... */
2433         case iro_Mux:
2434                 new_node = try_create_SetMem(val, ptr, mem);
2435                 break;
2436
2437         case iro_Minus:
2438                 op1      = get_Minus_op(val);
2439                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2440                 break;
2441         case iro_Not:
2442                 /* should be lowered already */
2443                 assert(mode != mode_b);
2444                 op1      = get_Not_op(val);
2445                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2446                 break;
2447         default:
2448                 return NULL;
2449         }
2450
2451         if (new_node != NULL) {
2452                 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2453                                 get_irn_pinned(node) == op_pin_state_pinned) {
2454                         set_irn_pinned(new_node, op_pin_state_pinned);
2455                 }
2456         }
2457
2458         return new_node;
2459 }
2460
2461 static bool possible_int_mode_for_fp(ir_mode *mode)
2462 {
2463         unsigned size;
2464
2465         if (!mode_is_signed(mode))
2466                 return false;
2467         size = get_mode_size_bits(mode);
2468         if (size != 16 && size != 32)
2469                 return false;
2470         return true;
2471 }
2472
2473 static int is_float_to_int_conv(const ir_node *node)
2474 {
2475         ir_mode  *mode = get_irn_mode(node);
2476         ir_node  *conv_op;
2477         ir_mode  *conv_mode;
2478
2479         if (!possible_int_mode_for_fp(mode))
2480                 return 0;
2481
2482         if (!is_Conv(node))
2483                 return 0;
2484         conv_op   = get_Conv_op(node);
2485         conv_mode = get_irn_mode(conv_op);
2486
2487         if (!mode_is_float(conv_mode))
2488                 return 0;
2489
2490         return 1;
2491 }
2492
2493 /**
2494  * Transform a Store(floatConst) into a sequence of
2495  * integer stores.
2496  *
2497  * @return the created ia32 Store node
2498  */
2499 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2500 {
2501         ir_mode        *mode      = get_irn_mode(cns);
2502         unsigned        size      = get_mode_size_bytes(mode);
2503         ir_tarval      *tv        = get_Const_tarval(cns);
2504         ir_node        *block     = get_nodes_block(node);
2505         ir_node        *new_block = be_transform_node(block);
2506         ir_node        *ptr       = get_Store_ptr(node);
2507         ir_node        *mem       = get_Store_mem(node);
2508         dbg_info       *dbgi      = get_irn_dbg_info(node);
2509         int             ofs       = 0;
2510         int             i         = 0;
2511         ir_node        *ins[4];
2512         ia32_address_t  addr;
2513
2514         assert(size % 4 ==  0);
2515         assert(size     <= 16);
2516
2517         build_address_ptr(&addr, ptr, mem);
2518
2519         do {
2520                 unsigned val =
2521                          get_tarval_sub_bits(tv, ofs)            |
2522                         (get_tarval_sub_bits(tv, ofs + 1) <<  8) |
2523                         (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2524                         (get_tarval_sub_bits(tv, ofs + 3) << 24);
2525                 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2526
2527                 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2528                         addr.index, addr.mem, imm);
2529
2530                 set_irn_pinned(new_node, get_irn_pinned(node));
2531                 set_ia32_op_type(new_node, ia32_AddrModeD);
2532                 set_ia32_ls_mode(new_node, mode_Iu);
2533                 set_address(new_node, &addr);
2534                 SET_IA32_ORIG_NODE(new_node, node);
2535
2536                 assert(i < 4);
2537                 ins[i++] = new_node;
2538
2539                 size        -= 4;
2540                 ofs         += 4;
2541                 addr.offset += 4;
2542         } while (size != 0);
2543
2544         if (i > 1) {
2545                 return new_rd_Sync(dbgi, new_block, i, ins);
2546         } else {
2547                 return ins[0];
2548         }
2549 }
2550
2551 /**
2552  * Generate a vfist or vfisttp instruction.
2553  */
2554 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2555                           ir_node *mem,  ir_node *val, ir_node **fist)
2556 {
2557         ir_node *new_node;
2558
2559         if (ia32_cg_config.use_fisttp) {
2560                 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2561                 if other users exists */
2562                 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2563                 ir_node *value   = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2564                 be_new_Keep(block, 1, &value);
2565
2566                 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2567                 *fist    = vfisttp;
2568         } else {
2569                 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2570
2571                 /* do a fist */
2572                 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2573                 *fist    = new_node;
2574         }
2575         return new_node;
2576 }
2577 /**
2578  * Transforms a general (no special case) Store.
2579  *
2580  * @return the created ia32 Store node
2581  */
2582 static ir_node *gen_general_Store(ir_node *node)
2583 {
2584         ir_node  *val       = get_Store_value(node);
2585         ir_mode  *mode      = get_irn_mode(val);
2586         ir_node  *block     = get_nodes_block(node);
2587         ir_node  *new_block = be_transform_node(block);
2588         ir_node  *ptr       = get_Store_ptr(node);
2589         ir_node  *mem       = get_Store_mem(node);
2590         dbg_info *dbgi      = get_irn_dbg_info(node);
2591         ir_node  *new_val, *new_node, *store;
2592         ia32_address_t addr;
2593
2594         /* check for destination address mode */
2595         new_node = try_create_dest_am(node);
2596         if (new_node != NULL)
2597                 return new_node;
2598
2599         /* construct store address */
2600         memset(&addr, 0, sizeof(addr));
2601         ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2602
2603         if (addr.base == NULL) {
2604                 addr.base = noreg_GP;
2605         } else {
2606                 addr.base = be_transform_node(addr.base);
2607         }
2608
2609         if (addr.index == NULL) {
2610                 addr.index = noreg_GP;
2611         } else {
2612                 addr.index = be_transform_node(addr.index);
2613         }
2614         addr.mem = be_transform_node(mem);
2615
2616         if (mode_is_float(mode)) {
2617                 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2618                    is the same. */
2619                 while (is_Conv(val) && mode == get_irn_mode(val)) {
2620                         ir_node *op = get_Conv_op(val);
2621                         if (!mode_is_float(get_irn_mode(op)))
2622                                 break;
2623                         val = op;
2624                 }
2625                 new_val = be_transform_node(val);
2626                 if (ia32_cg_config.use_sse2) {
2627                         new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2628                                                       addr.index, addr.mem, new_val);
2629                 } else {
2630                         new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2631                                                     addr.index, addr.mem, new_val, mode);
2632                 }
2633                 store = new_node;
2634         } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2635                 val = get_Conv_op(val);
2636
2637                 /* TODO: is this optimisation still necessary at all (middleend)? */
2638                 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2639                 while (is_Conv(val)) {
2640                         ir_node *op = get_Conv_op(val);
2641                         if (!mode_is_float(get_irn_mode(op)))
2642                                 break;
2643                         if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2644                                 break;
2645                         val = op;
2646                 }
2647                 new_val  = be_transform_node(val);
2648                 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2649         } else {
2650                 new_val = create_immediate_or_transform(val, 0);
2651                 assert(mode != mode_b);
2652
2653                 if (get_mode_size_bits(mode) == 8) {
2654                         new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2655                                                          addr.index, addr.mem, new_val);
2656                 } else {
2657                         new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2658                                                      addr.index, addr.mem, new_val);
2659                 }
2660                 store = new_node;
2661         }
2662
2663         set_irn_pinned(store, get_irn_pinned(node));
2664         set_ia32_op_type(store, ia32_AddrModeD);
2665         set_ia32_ls_mode(store, mode);
2666
2667         set_address(store, &addr);
2668         SET_IA32_ORIG_NODE(store, node);
2669
2670         return new_node;
2671 }
2672
2673 /**
2674  * Transforms a Store.
2675  *
2676  * @return the created ia32 Store node
2677  */
2678 static ir_node *gen_Store(ir_node *node)
2679 {
2680         ir_node  *val  = get_Store_value(node);
2681         ir_mode  *mode = get_irn_mode(val);
2682
2683         if (mode_is_float(mode) && is_Const(val)) {
2684                 /* We can transform every floating const store
2685                    into a sequence of integer stores.
2686                    If the constant is already in a register,
2687                    it would be better to use it, but we don't
2688                    have this information here. */
2689                 return gen_float_const_Store(node, val);
2690         }
2691         return gen_general_Store(node);
2692 }
2693
2694 /**
2695  * Transforms a Switch.
2696  *
2697  * @return the created ia32 SwitchJmp node
2698  */
2699 static ir_node *create_Switch(ir_node *node)
2700 {
2701         dbg_info *dbgi       = get_irn_dbg_info(node);
2702         ir_node  *block      = be_transform_node(get_nodes_block(node));
2703         ir_node  *sel        = get_Cond_selector(node);
2704         ir_node  *new_sel    = be_transform_node(sel);
2705         long      switch_min = LONG_MAX;
2706         long      switch_max = LONG_MIN;
2707         long      default_pn = get_Cond_default_proj(node);
2708         ir_node  *new_node;
2709         const ir_edge_t *edge;
2710
2711         assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2712
2713         /* determine the smallest switch case value */
2714         foreach_out_edge(node, edge) {
2715                 ir_node *proj = get_edge_src_irn(edge);
2716                 long     pn   = get_Proj_proj(proj);
2717                 if (pn == default_pn)
2718                         continue;
2719
2720                 if (pn < switch_min)
2721                         switch_min = pn;
2722                 if (pn > switch_max)
2723                         switch_max = pn;
2724         }
2725
2726         if ((unsigned long) (switch_max - switch_min) > 128000) {
2727                 panic("Size of switch %+F bigger than 128000", node);
2728         }
2729
2730         if (switch_min != 0) {
2731                 /* if smallest switch case is not 0 we need an additional sub */
2732                 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2733                 add_ia32_am_offs_int(new_sel, -switch_min);
2734                 set_ia32_op_type(new_sel, ia32_AddrModeS);
2735
2736                 SET_IA32_ORIG_NODE(new_sel, node);
2737         }
2738
2739         new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2740         SET_IA32_ORIG_NODE(new_node, node);
2741
2742         return new_node;
2743 }
2744
2745 /**
2746  * Transform a Cond node.
2747  */
2748 static ir_node *gen_Cond(ir_node *node)
2749 {
2750         ir_node              *block     = get_nodes_block(node);
2751         ir_node              *new_block = be_transform_node(block);
2752         dbg_info             *dbgi      = get_irn_dbg_info(node);
2753         ir_node              *sel       = get_Cond_selector(node);
2754         ir_mode              *sel_mode  = get_irn_mode(sel);
2755         ir_node              *flags     = NULL;
2756         ir_node              *new_node;
2757         ia32_condition_code_t cc;
2758
2759         if (sel_mode != mode_b) {
2760                 return create_Switch(node);
2761         }
2762
2763         /* we get flags from a Cmp */
2764         flags = get_flags_node(sel, &cc);
2765
2766         new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2767         SET_IA32_ORIG_NODE(new_node, node);
2768
2769         return new_node;
2770 }
2771
2772 /**
2773  * Transform a be_Copy.
2774  */
2775 static ir_node *gen_be_Copy(ir_node *node)
2776 {
2777         ir_node *new_node = be_duplicate_node(node);
2778         ir_mode *mode     = get_irn_mode(new_node);
2779
2780         if (ia32_mode_needs_gp_reg(mode)) {
2781                 set_irn_mode(new_node, mode_Iu);
2782         }
2783
2784         return new_node;
2785 }
2786
2787 static ir_node *create_Fucom(ir_node *node)
2788 {
2789         dbg_info *dbgi      = get_irn_dbg_info(node);
2790         ir_node  *block     = get_nodes_block(node);
2791         ir_node  *new_block = be_transform_node(block);
2792         ir_node  *left      = get_Cmp_left(node);
2793         ir_node  *new_left  = be_transform_node(left);
2794         ir_node  *right     = get_Cmp_right(node);
2795         ir_node  *new_right;
2796         ir_node  *new_node;
2797
2798         if (ia32_cg_config.use_fucomi) {
2799                 new_right = be_transform_node(right);
2800                 new_node  = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2801                                                 new_right, 0);
2802                 set_ia32_commutative(new_node);
2803                 SET_IA32_ORIG_NODE(new_node, node);
2804         } else {
2805                 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2806                         new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2807                 } else {
2808                         new_right = be_transform_node(right);
2809                         new_node  = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2810                 }
2811
2812                 set_ia32_commutative(new_node);
2813
2814                 SET_IA32_ORIG_NODE(new_node, node);
2815
2816                 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2817                 SET_IA32_ORIG_NODE(new_node, node);
2818         }
2819
2820         return new_node;
2821 }
2822
2823 static ir_node *create_Ucomi(ir_node *node)
2824 {
2825         dbg_info *dbgi      = get_irn_dbg_info(node);
2826         ir_node  *src_block = get_nodes_block(node);
2827         ir_node  *new_block = be_transform_node(src_block);
2828         ir_node  *left      = get_Cmp_left(node);
2829         ir_node  *right     = get_Cmp_right(node);
2830         ir_node  *new_node;
2831         ia32_address_mode_t  am;
2832         ia32_address_t      *addr = &am.addr;
2833
2834         match_arguments(&am, src_block, left, right, NULL,
2835                         match_commutative | match_am);
2836
2837         new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2838                                      addr->mem, am.new_op1, am.new_op2,
2839                                      am.ins_permuted);
2840         set_am_attributes(new_node, &am);
2841
2842         SET_IA32_ORIG_NODE(new_node, node);
2843
2844         new_node = fix_mem_proj(new_node, &am);
2845
2846         return new_node;
2847 }
2848
2849 /**
2850  * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2851  * to fold an and into a test node
2852  */
2853 static bool can_fold_test_and(ir_node *node)
2854 {
2855         const ir_edge_t *edge;
2856
2857         /** we can only have eq and lg projs */
2858         foreach_out_edge(node, edge) {
2859                 ir_node *proj = get_edge_src_irn(edge);
2860                 pn_Cmp   pnc  = get_Proj_pn_cmp(proj);
2861                 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2862                         return false;
2863         }
2864
2865         return true;
2866 }
2867
2868 /**
2869  * returns true if it is assured, that the upper bits of a node are "clean"
2870  * which means for a 16 or 8 bit value, that the upper bits in the register
2871  * are 0 for unsigned and a copy of the last significant bit for signed
2872  * numbers.
2873  */
2874 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2875 {
2876         assert(ia32_mode_needs_gp_reg(mode));
2877         if (get_mode_size_bits(mode) >= 32)
2878                 return true;
2879
2880         if (is_Proj(transformed_node))
2881                 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2882
2883         switch (get_ia32_irn_opcode(transformed_node)) {
2884                 case iro_ia32_Conv_I2I:
2885                 case iro_ia32_Conv_I2I8Bit: {
2886                         ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2887                         if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2888                                 return false;
2889                         if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2890                                 return false;
2891
2892                         return true;
2893                 }
2894
2895                 case iro_ia32_Shr:
2896                         if (mode_is_signed(mode)) {
2897                                 return false; /* TODO handle signed modes */
2898                         } else {
2899                                 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2900                                 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2901                                         const ia32_immediate_attr_t *attr
2902                                                 = get_ia32_immediate_attr_const(right);
2903                                         if (attr->symconst == 0 &&
2904                                                         (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2905                                                 return true;
2906                                         }
2907                                 }
2908                                 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2909                         }
2910
2911                 case iro_ia32_Sar:
2912                         /* TODO too conservative if shift amount is constant */
2913                         return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2914
2915                 case iro_ia32_And:
2916                         if (!mode_is_signed(mode)) {
2917                                 return
2918                                         upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2919                                         upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left),  mode);
2920                         }
2921                         /* TODO if one is known to be zero extended, then || is sufficient */
2922                         /* FALLTHROUGH */
2923                 case iro_ia32_Or:
2924                 case iro_ia32_Xor:
2925                         return
2926                                 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2927                                 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left),  mode);
2928
2929                 case iro_ia32_Const:
2930                 case iro_ia32_Immediate: {
2931                         const ia32_immediate_attr_t *attr =
2932                                 get_ia32_immediate_attr_const(transformed_node);
2933                         if (mode_is_signed(mode)) {
2934                                 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2935                                 return shifted == 0 || shifted == -1;
2936                         } else {
2937                                 unsigned long shifted = (unsigned long)attr->offset;
2938                                 shifted >>= get_mode_size_bits(mode);
2939                                 return shifted == 0;
2940                         }
2941                 }
2942
2943                 default:
2944                         return false;
2945         }
2946 }
2947
2948 /**
2949  * Generate code for a Cmp.
2950  */
2951 static ir_node *gen_Cmp(ir_node *node)
2952 {
2953         dbg_info *dbgi      = get_irn_dbg_info(node);
2954         ir_node  *block     = get_nodes_block(node);
2955         ir_node  *new_block = be_transform_node(block);
2956         ir_node  *left      = get_Cmp_left(node);
2957         ir_node  *right     = get_Cmp_right(node);
2958         ir_mode  *cmp_mode  = get_irn_mode(left);
2959         ir_node  *new_node;
2960         ia32_address_mode_t  am;
2961         ia32_address_t      *addr = &am.addr;
2962
2963         if (mode_is_float(cmp_mode)) {
2964                 if (ia32_cg_config.use_sse2) {
2965                         return create_Ucomi(node);
2966                 } else {
2967                         return create_Fucom(node);
2968                 }
2969         }
2970
2971         assert(ia32_mode_needs_gp_reg(cmp_mode));
2972
2973         /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2974         if (is_Const_0(right)          &&
2975             is_And(left)               &&
2976             get_irn_n_edges(left) == 1 &&
2977             can_fold_test_and(node)) {
2978                 /* Test(and_left, and_right) */
2979                 ir_node *and_left  = get_And_left(left);
2980                 ir_node *and_right = get_And_right(left);
2981
2982                 /* matze: code here used mode instead of cmd_mode, I think it is always
2983                  * the same as cmp_mode, but I leave this here to see if this is really
2984                  * true...
2985                  */
2986                 assert(get_irn_mode(and_left) == cmp_mode);
2987
2988                 match_arguments(&am, block, and_left, and_right, NULL,
2989                                                                                 match_commutative |
2990                                                                                 match_am | match_8bit_am | match_16bit_am |
2991                                                                                 match_am_and_immediates | match_immediate);
2992
2993                 /* use 32bit compare mode if possible since the opcode is smaller */
2994                 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2995                     upper_bits_clean(am.new_op2, cmp_mode)) {
2996                         cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2997                 }
2998
2999                 if (get_mode_size_bits(cmp_mode) == 8) {
3000                         new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
3001                                         addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3002                 } else {
3003                         new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
3004                                         addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3005                 }
3006         } else {
3007                 /* Cmp(left, right) */
3008                 match_arguments(&am, block, left, right, NULL,
3009                                 match_commutative | match_am | match_8bit_am |
3010                                 match_16bit_am | match_am_and_immediates |
3011                                 match_immediate);
3012                 /* use 32bit compare mode if possible since the opcode is smaller */
3013                 if (upper_bits_clean(am.new_op1, cmp_mode) &&
3014                     upper_bits_clean(am.new_op2, cmp_mode)) {
3015                         cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
3016                 }
3017
3018                 if (get_mode_size_bits(cmp_mode) == 8) {
3019                         new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3020                                                        addr->index, addr->mem, am.new_op1,
3021                                                        am.new_op2, am.ins_permuted);
3022                 } else {
3023                         new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3024                                         addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3025                 }
3026         }
3027         set_am_attributes(new_node, &am);
3028         set_ia32_ls_mode(new_node, cmp_mode);
3029
3030         SET_IA32_ORIG_NODE(new_node, node);
3031
3032         new_node = fix_mem_proj(new_node, &am);
3033
3034         return new_node;
3035 }
3036
3037 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3038                             ia32_condition_code_t cc)
3039 {
3040         dbg_info            *dbgi          = get_irn_dbg_info(node);
3041         ir_node             *block         = get_nodes_block(node);
3042         ir_node             *new_block     = be_transform_node(block);
3043         ir_node             *val_true      = get_Mux_true(node);
3044         ir_node             *val_false     = get_Mux_false(node);
3045         ir_node             *new_node;
3046         ia32_address_mode_t  am;
3047         ia32_address_t      *addr;
3048
3049         assert(ia32_cg_config.use_cmov);
3050         assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3051
3052         addr = &am.addr;
3053
3054         match_arguments(&am, block, val_false, val_true, flags,
3055                         match_commutative | match_am | match_16bit_am | match_mode_neutral);
3056
3057         if (am.ins_permuted)
3058                 cc = ia32_invert_condition_code(cc);
3059
3060         new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3061                                       addr->mem, am.new_op1, am.new_op2, new_flags,
3062                                       cc);
3063         set_am_attributes(new_node, &am);
3064
3065         SET_IA32_ORIG_NODE(new_node, node);
3066
3067         new_node = fix_mem_proj(new_node, &am);
3068
3069         return new_node;
3070 }
3071
3072 /**
3073  * Creates a ia32 Setcc instruction.
3074  */
3075 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3076                                  ir_node *flags, ia32_condition_code_t cc,
3077                                  ir_node *orig_node)
3078 {
3079         ir_mode *mode  = get_irn_mode(orig_node);
3080         ir_node *new_node;
3081
3082         new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3083         SET_IA32_ORIG_NODE(new_node, orig_node);
3084
3085         /* we might need to conv the result up */
3086         if (get_mode_size_bits(mode) > 8) {
3087                 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3088                                                     nomem, new_node, mode_Bu);
3089                 SET_IA32_ORIG_NODE(new_node, orig_node);
3090         }
3091
3092         return new_node;
3093 }
3094
3095 /**
3096  * Create instruction for an unsigned Difference or Zero.
3097  */
3098 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3099 {
3100         ir_mode *mode  = get_irn_mode(psi);
3101         ir_node *new_node;
3102         ir_node *sub;
3103         ir_node *sbb;
3104         ir_node *notn;
3105         ir_node *eflags;
3106         ir_node *block;
3107
3108         dbg_info *dbgi;
3109
3110         new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3111                 match_mode_neutral | match_am | match_immediate | match_two_users);
3112
3113         block = get_nodes_block(new_node);
3114
3115         if (is_Proj(new_node)) {
3116                 sub = get_Proj_pred(new_node);
3117                 assert(is_ia32_Sub(sub));
3118         } else {
3119                 sub = new_node;
3120                 set_irn_mode(sub, mode_T);
3121                 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3122         }
3123         eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3124
3125         dbgi = get_irn_dbg_info(psi);
3126         sbb  = new_bd_ia32_Sbb0(dbgi, block, eflags);
3127         notn = new_bd_ia32_Not(dbgi, block, sbb);
3128
3129         new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3130         set_ia32_commutative(new_node);
3131         return new_node;
3132 }
3133
3134 /**
3135  * Create an const array of two float consts.
3136  *
3137  * @param c0        the first constant
3138  * @param c1        the second constant
3139  * @param new_mode  IN/OUT for the mode of the constants, if NULL
3140  *                  smallest possible mode will be used
3141  */
3142 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3143 {
3144         ir_entity        *ent;
3145         ir_mode          *mode = *new_mode;
3146         ir_type          *tp;
3147         ir_initializer_t *initializer;
3148         ir_tarval        *tv0 = get_Const_tarval(c0);
3149         ir_tarval        *tv1 = get_Const_tarval(c1);
3150
3151         if (mode == NULL) {
3152                 /* detect the best mode for the constants */
3153                 mode = get_tarval_mode(tv0);
3154
3155                 if (mode != mode_F) {
3156                         if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3157                             tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3158                                 mode = mode_F;
3159                                 tv0 = tarval_convert_to(tv0, mode);
3160                                 tv1 = tarval_convert_to(tv1, mode);
3161                         } else if (mode != mode_D) {
3162                                 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3163                                     tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3164                                         mode = mode_D;
3165                                         tv0 = tarval_convert_to(tv0, mode);
3166                                         tv1 = tarval_convert_to(tv1, mode);
3167                                 }
3168                         }
3169                 }
3170
3171         }
3172
3173         tp = ia32_create_float_type(mode, 4);
3174         tp = ia32_create_float_array(tp);
3175
3176         ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3177
3178         set_entity_ld_ident(ent, get_entity_ident(ent));
3179         set_entity_visibility(ent, ir_visibility_private);
3180         add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3181
3182         initializer = create_initializer_compound(2);
3183
3184         set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3185         set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3186
3187         set_entity_initializer(ent, initializer);
3188
3189         *new_mode = mode;
3190         return ent;
3191 }
3192
3193 /**
3194  * Possible transformations for creating a Setcc.
3195  */
3196 enum setcc_transform_insn {
3197         SETCC_TR_ADD,
3198         SETCC_TR_ADDxx,
3199         SETCC_TR_LEA,
3200         SETCC_TR_LEAxx,
3201         SETCC_TR_SHL,
3202         SETCC_TR_NEG,
3203         SETCC_TR_NOT,
3204         SETCC_TR_AND,
3205         SETCC_TR_SET,
3206         SETCC_TR_SBB,
3207 };
3208
3209 typedef struct setcc_transform {
3210         unsigned              num_steps;
3211         ia32_condition_code_t cc;
3212         struct {
3213                 enum setcc_transform_insn  transform;
3214                 long val;
3215                 int  scale;
3216         } steps[4];
3217 } setcc_transform_t;
3218
3219 /**
3220  * Setcc can only handle 0 and 1 result.
3221  * Find a transformation that creates 0 and 1 from
3222  * tv_t and tv_f.
3223  */
3224 static void find_const_transform(ia32_condition_code_t cc,
3225                                  ir_tarval *t, ir_tarval *f,
3226                                  setcc_transform_t *res)
3227 {
3228         unsigned step = 0;
3229
3230         res->num_steps = 0;
3231
3232         if (tarval_is_null(t)) {
3233                 ir_tarval *tmp = t;
3234                 t = f;
3235                 f = tmp;
3236                 cc = ia32_negate_condition_code(cc);
3237         } else if (tarval_cmp(t, f) == pn_Cmp_Lt) {
3238                 // now, t is the bigger one
3239                 ir_tarval *tmp = t;
3240                 t = f;
3241                 f = tmp;
3242                 cc = ia32_negate_condition_code(cc);
3243         }
3244         res->cc = cc;
3245
3246         if (! tarval_is_null(f)) {
3247                 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3248
3249                 t = t_sub;
3250                 res->steps[step].transform = SETCC_TR_ADD;
3251
3252                 if (t == tarval_bad)
3253                         panic("constant subtract failed");
3254                 if (! tarval_is_long(f))
3255                         panic("tarval is not long");
3256
3257                 res->steps[step].val = get_tarval_long(f);
3258                 ++step;
3259                 f = tarval_sub(f, f, NULL);
3260                 assert(tarval_is_null(f));
3261         }
3262
3263         if (tarval_is_one(t)) {
3264                 res->steps[step].transform = SETCC_TR_SET;
3265                 res->num_steps = ++step;
3266                 return;
3267         }
3268
3269         if (tarval_is_minus_one(t)) {
3270                 res->steps[step].transform = SETCC_TR_NEG;
3271                 ++step;
3272                 res->steps[step].transform = SETCC_TR_SET;
3273                 res->num_steps = ++step;
3274                 return;
3275         }
3276         if (tarval_is_long(t)) {
3277                 long v = get_tarval_long(t);
3278
3279                 res->steps[step].val = 0;
3280                 switch (v) {
3281                 case 9:
3282                         if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3283                                 --step;
3284                         res->steps[step].transform = SETCC_TR_LEAxx;
3285                         res->steps[step].scale     = 3; /* (a << 3) + a */
3286                         break;
3287                 case 8:
3288                         if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3289                                 --step;
3290                         res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3291                         res->steps[step].scale     = 3; /* (a << 3) */
3292                         break;
3293                 case 5:
3294                         if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3295                                 --step;
3296                         res->steps[step].transform = SETCC_TR_LEAxx;
3297                         res->steps[step].scale     = 2; /* (a << 2) + a */
3298                         break;
3299                 case 4:
3300                         if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3301                                 --step;
3302                         res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3303                         res->steps[step].scale     = 2; /* (a << 2) */
3304                         break;
3305                 case 3:
3306                         if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3307                                 --step;
3308                         res->steps[step].transform = SETCC_TR_LEAxx;
3309                         res->steps[step].scale     = 1; /* (a << 1) + a */
3310                         break;
3311                 case 2:
3312                         if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3313                                 --step;
3314                         res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3315                         res->steps[step].scale     = 1; /* (a << 1) */
3316                         break;
3317                 case 1:
3318                         res->num_steps = step;
3319                         return;
3320                 default:
3321                         if (! tarval_is_single_bit(t)) {
3322                                 res->steps[step].transform = SETCC_TR_AND;
3323                                 res->steps[step].val       = v;
3324                                 ++step;
3325                                 res->steps[step].transform = SETCC_TR_NEG;
3326                         } else {
3327                                 int v = get_tarval_lowest_bit(t);
3328                                 assert(v >= 0);
3329
3330                                 res->steps[step].transform = SETCC_TR_SHL;
3331                                 res->steps[step].scale     = v;
3332                         }
3333                 }
3334                 ++step;
3335                 res->steps[step].transform = SETCC_TR_SET;
3336                 res->num_steps = ++step;
3337                 return;
3338         }
3339         panic("tarval is not long");
3340 }
3341
3342 /**
3343  * Transforms a Mux node into some code sequence.
3344  *
3345  * @return The transformed node.
3346  */
3347 static ir_node *gen_Mux(ir_node *node)
3348 {
3349         dbg_info             *dbgi      = get_irn_dbg_info(node);
3350         ir_node              *block     = get_nodes_block(node);
3351         ir_node              *new_block = be_transform_node(block);
3352         ir_node              *mux_true  = get_Mux_true(node);
3353         ir_node              *mux_false = get_Mux_false(node);
3354         ir_node              *cond      = get_Mux_sel(node);
3355         ir_mode              *mode      = get_irn_mode(node);
3356         ir_node              *flags;
3357         ir_node              *new_node;
3358         int                   is_abs;
3359         ia32_condition_code_t cc;
3360
3361         assert(get_irn_mode(cond) == mode_b);
3362
3363         is_abs = be_mux_is_abs(cond, mux_true, mux_false);
3364         if (is_abs != 0) {
3365                 return create_abs(dbgi, block, be_get_abs_op(cond), is_abs < 0, node);
3366         }
3367
3368         /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3369         if (mode_is_float(mode)) {
3370                 ir_node  *cmp         = get_Proj_pred(cond);
3371                 ir_node  *cmp_left    = get_Cmp_left(cmp);
3372                 ir_node  *cmp_right   = get_Cmp_right(cmp);
3373                 int       pnc         = get_Proj_proj(cond);
3374
3375                 if (ia32_cg_config.use_sse2) {
3376                         if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3377                                 if (cmp_left == mux_true && cmp_right == mux_false) {
3378                                         /* Mux(a <= b, a, b) => MIN */
3379                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3380                                          match_commutative | match_am | match_two_users);
3381                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3382                                         /* Mux(a <= b, b, a) => MAX */
3383                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3384                                          match_commutative | match_am | match_two_users);
3385                                 }
3386                         } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3387                                 if (cmp_left == mux_true && cmp_right == mux_false) {
3388                                         /* Mux(a >= b, a, b) => MAX */
3389                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3390                                          match_commutative | match_am | match_two_users);
3391                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3392                                         /* Mux(a >= b, b, a) => MIN */
3393                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3394                                          match_commutative | match_am | match_two_users);
3395                                 }
3396                         }
3397                 }
3398
3399                 if (is_Const(mux_true) && is_Const(mux_false)) {
3400                         ia32_address_mode_t am;
3401                         ir_node             *load;
3402                         ir_mode             *new_mode;
3403                         unsigned            scale;
3404
3405                         flags    = get_flags_node(cond, &cc);
3406                         new_node = create_set_32bit(dbgi, new_block, flags, cc, node);
3407
3408                         if (ia32_cg_config.use_sse2) {
3409                                 /* cannot load from different mode on SSE */
3410                                 new_mode = mode;
3411                         } else {
3412                                 /* x87 can load any mode */
3413                                 new_mode = NULL;
3414                         }
3415
3416                         am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3417
3418                         switch (get_mode_size_bytes(new_mode)) {
3419                         case 4:
3420                                 scale = 2;
3421                                 break;
3422                         case 8:
3423                                 scale = 3;
3424                                 break;
3425                         case 10:
3426                                 /* use 2 * 5 */
3427                                 scale = 1;
3428                                 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3429                                 set_ia32_am_scale(new_node, 2);
3430                                 break;
3431                         case 12:
3432                                 /* use 4 * 3 */
3433                                 scale = 2;
3434                                 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3435                                 set_ia32_am_scale(new_node, 1);
3436                                 break;
3437                         case 16:
3438                                 /* arg, shift 16 NOT supported */
3439                                 scale = 3;
3440                                 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, new_node);
3441                                 break;
3442                         default:
3443                                 panic("Unsupported constant size");
3444                         }
3445
3446                         am.ls_mode            = new_mode;
3447                         am.addr.base          = get_symconst_base();
3448                         am.addr.index         = new_node;
3449                         am.addr.mem           = nomem;
3450                         am.addr.offset        = 0;
3451                         am.addr.scale         = scale;
3452                         am.addr.use_frame     = 0;
3453                         am.addr.frame_entity  = NULL;
3454                         am.addr.symconst_sign = 0;
3455                         am.mem_proj           = am.addr.mem;
3456                         am.op_type            = ia32_AddrModeS;
3457                         am.new_op1            = NULL;
3458                         am.new_op2            = NULL;
3459                         am.pinned             = op_pin_state_floats;
3460                         am.commutative        = 1;
3461                         am.ins_permuted       = false;
3462
3463                         if (ia32_cg_config.use_sse2)
3464                                 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3465                         else
3466                                 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3467                         set_am_attributes(load, &am);
3468
3469                         return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3470                 }
3471                 panic("cannot transform floating point Mux");
3472
3473         } else {
3474                 assert(ia32_mode_needs_gp_reg(mode));
3475
3476                 if (is_Proj(cond)) {
3477                         ir_node *cmp = get_Proj_pred(cond);
3478                         if (is_Cmp(cmp)) {
3479                                 ir_node  *cmp_left  = get_Cmp_left(cmp);
3480                                 ir_node  *cmp_right = get_Cmp_right(cmp);
3481                                 ir_node  *val_true  = mux_true;
3482                                 ir_node  *val_false = mux_false;
3483                                 int       pnc       = get_Proj_proj(cond);
3484
3485                                 if (is_Const(val_true) && is_Const_null(val_true)) {
3486                                         ir_node *tmp = val_false;
3487                                         val_false = val_true;
3488                                         val_true  = tmp;
3489                                         pnc       = get_negated_pnc(pnc, get_irn_mode(cmp_left));
3490                                 }
3491                                 if (is_Const_0(val_false) && is_Sub(val_true)) {
3492                                         if ((pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge)
3493                                                 && get_Sub_left(val_true) == cmp_left
3494                                                 && get_Sub_right(val_true) == cmp_right) {
3495                                                 return create_doz(node, cmp_left, cmp_right);
3496                                         }
3497                                         if ((pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le)
3498                                                 && get_Sub_left(val_true) == cmp_right
3499                                                 && get_Sub_right(val_true) == cmp_left) {
3500                                                 return create_doz(node, cmp_right, cmp_left);
3501                                         }
3502                                 }
3503                         }
3504                 }
3505
3506                 flags = get_flags_node(cond, &cc);
3507
3508                 if (is_Const(mux_true) && is_Const(mux_false)) {
3509                         /* both are const, good */
3510                         ir_tarval *tv_true  = get_Const_tarval(mux_true);
3511                         ir_tarval *tv_false = get_Const_tarval(mux_false);
3512                         setcc_transform_t res;
3513                         int step;
3514
3515                         find_const_transform(cc, tv_true, tv_false, &res);
3516                         new_node = node;
3517                         for (step = (int)res.num_steps - 1; step >= 0; --step) {
3518                                 ir_node *imm;
3519
3520                                 switch (res.steps[step].transform) {
3521                                 case SETCC_TR_ADD:
3522                                         imm = ia32_immediate_from_long(res.steps[step].val);
3523                                         new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3524                                         break;
3525                                 case SETCC_TR_ADDxx:
3526                                         new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3527                                         break;
3528                                 case SETCC_TR_LEA:
3529                                         new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3530                                         set_ia32_am_scale(new_node, res.steps[step].scale);
3531                                         set_ia32_am_offs_int(new_node, res.steps[step].val);
3532                                         break;
3533                                 case SETCC_TR_LEAxx:
3534                                         new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3535                                         set_ia32_am_scale(new_node, res.steps[step].scale);
3536                                         set_ia32_am_offs_int(new_node, res.steps[step].val);
3537                                         break;
3538                                 case SETCC_TR_SHL:
3539                                         imm = ia32_immediate_from_long(res.steps[step].scale);
3540                                         new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3541                                         break;
3542                                 case SETCC_TR_NEG:
3543                                         new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3544                                         break;
3545                                 case SETCC_TR_NOT:
3546                                         new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3547                                         break;
3548                                 case SETCC_TR_AND:
3549                                         imm = ia32_immediate_from_long(res.steps[step].val);
3550                                         new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3551                                         break;
3552                                 case SETCC_TR_SET:
3553                                         new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3554                                         break;
3555                                 case SETCC_TR_SBB:
3556                                         new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3557                                         break;
3558                                 default:
3559                                         panic("unknown setcc transform");
3560                                 }
3561                         }
3562                 } else {
3563                         new_node = create_CMov(node, cond, flags, cc);
3564                 }
3565                 return new_node;
3566         }
3567 }
3568
3569
3570 /**
3571  * Create a conversion from x87 state register to general purpose.
3572  */
3573 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3574 {
3575         ir_node         *block      = be_transform_node(get_nodes_block(node));
3576         ir_node         *op         = get_Conv_op(node);
3577         ir_node         *new_op     = be_transform_node(op);
3578         ir_graph        *irg        = current_ir_graph;
3579         dbg_info        *dbgi       = get_irn_dbg_info(node);
3580         ir_mode         *mode       = get_irn_mode(node);
3581         ir_node         *fist, *load, *mem;
3582
3583         mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3584         set_irn_pinned(fist, op_pin_state_floats);
3585         set_ia32_use_frame(fist);
3586         set_ia32_op_type(fist, ia32_AddrModeD);
3587
3588         assert(get_mode_size_bits(mode) <= 32);
3589         /* exception we can only store signed 32 bit integers, so for unsigned
3590            we store a 64bit (signed) integer and load the lower bits */
3591         if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3592                 set_ia32_ls_mode(fist, mode_Ls);
3593         } else {
3594                 set_ia32_ls_mode(fist, mode_Is);
3595         }
3596         SET_IA32_ORIG_NODE(fist, node);
3597
3598         /* do a Load */
3599         load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3600
3601         set_irn_pinned(load, op_pin_state_floats);
3602         set_ia32_use_frame(load);
3603         set_ia32_op_type(load, ia32_AddrModeS);
3604         set_ia32_ls_mode(load, mode_Is);
3605         if (get_ia32_ls_mode(fist) == mode_Ls) {
3606                 ia32_attr_t *attr = get_ia32_attr(load);
3607                 attr->data.need_64bit_stackent = 1;
3608         } else {
3609                 ia32_attr_t *attr = get_ia32_attr(load);
3610                 attr->data.need_32bit_stackent = 1;
3611         }
3612         SET_IA32_ORIG_NODE(load, node);
3613
3614         return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3615 }
3616
3617 /**
3618  * Creates a x87 strict Conv by placing a Store and a Load
3619  */
3620 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3621 {
3622         ir_node  *block    = get_nodes_block(node);
3623         ir_graph *irg      = get_Block_irg(block);
3624         dbg_info *dbgi     = get_irn_dbg_info(node);
3625         ir_node  *frame    = get_irg_frame(irg);
3626         ir_node  *store, *load;
3627         ir_node  *new_node;
3628
3629         store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3630         set_ia32_use_frame(store);
3631         set_ia32_op_type(store, ia32_AddrModeD);
3632         SET_IA32_ORIG_NODE(store, node);
3633
3634         load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3635         set_ia32_use_frame(load);
3636         set_ia32_op_type(load, ia32_AddrModeS);
3637         SET_IA32_ORIG_NODE(load, node);
3638
3639         new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3640         return new_node;
3641 }
3642
3643 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3644                 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3645 {
3646         ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3647
3648         func = get_mode_size_bits(mode) == 8 ?
3649                 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3650         return func(dbgi, block, base, index, mem, val, mode);
3651 }
3652
3653 /**
3654  * Create a conversion from general purpose to x87 register
3655  */
3656 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3657 {
3658         ir_node  *src_block = get_nodes_block(node);
3659         ir_node  *block     = be_transform_node(src_block);
3660         ir_graph *irg       = get_Block_irg(block);
3661         dbg_info *dbgi      = get_irn_dbg_info(node);
3662         ir_node  *op        = get_Conv_op(node);
3663         ir_node  *new_op    = NULL;
3664         ir_mode  *mode;
3665         ir_mode  *store_mode;
3666         ir_node  *fild;
3667         ir_node  *store;
3668         ir_node  *new_node;
3669
3670         /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3671         if (possible_int_mode_for_fp(src_mode)) {
3672                 ia32_address_mode_t am;
3673
3674                 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3675                 if (am.op_type == ia32_AddrModeS) {
3676                         ia32_address_t *addr = &am.addr;
3677
3678                         fild     = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3679                         new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3680
3681                         set_am_attributes(fild, &am);
3682                         SET_IA32_ORIG_NODE(fild, node);
3683
3684                         fix_mem_proj(fild, &am);
3685
3686                         return new_node;
3687                 }
3688         }
3689         if (new_op == NULL) {
3690                 new_op = be_transform_node(op);
3691         }
3692
3693         mode = get_irn_mode(op);
3694
3695         /* first convert to 32 bit signed if necessary */
3696         if (get_mode_size_bits(src_mode) < 32) {
3697                 if (!upper_bits_clean(new_op, src_mode)) {
3698                         new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3699                         SET_IA32_ORIG_NODE(new_op, node);
3700                 }
3701                 mode = mode_Is;
3702         }
3703
3704         assert(get_mode_size_bits(mode) == 32);
3705
3706         /* do a store */
3707         store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3708
3709         set_ia32_use_frame(store);
3710         set_ia32_op_type(store, ia32_AddrModeD);
3711         set_ia32_ls_mode(store, mode_Iu);
3712
3713         /* exception for 32bit unsigned, do a 64bit spill+load */
3714         if (!mode_is_signed(mode)) {
3715                 ir_node *in[2];
3716                 /* store a zero */
3717                 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3718
3719                 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3720                                                         noreg_GP, nomem, zero_const);
3721
3722                 set_ia32_use_frame(zero_store);
3723                 set_ia32_op_type(zero_store, ia32_AddrModeD);
3724                 add_ia32_am_offs_int(zero_store, 4);
3725                 set_ia32_ls_mode(zero_store, mode_Iu);
3726
3727                 in[0] = zero_store;
3728                 in[1] = store;
3729
3730                 store      = new_rd_Sync(dbgi, block, 2, in);
3731                 store_mode = mode_Ls;
3732         } else {
3733                 store_mode = mode_Is;
3734         }
3735
3736         /* do a fild */
3737         fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3738
3739         set_ia32_use_frame(fild);
3740         set_ia32_op_type(fild, ia32_AddrModeS);
3741         set_ia32_ls_mode(fild, store_mode);
3742
3743         new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3744
3745         return new_node;
3746 }
3747
3748 /**
3749  * Create a conversion from one integer mode into another one
3750  */
3751 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3752                                 dbg_info *dbgi, ir_node *block, ir_node *op,
3753                                 ir_node *node)
3754 {
3755         ir_node             *new_block = be_transform_node(block);
3756         ir_node             *new_node;
3757         ir_mode             *smaller_mode;
3758         ia32_address_mode_t  am;
3759         ia32_address_t      *addr = &am.addr;
3760
3761         (void) node;
3762         if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3763                 smaller_mode = src_mode;
3764         } else {
3765                 smaller_mode = tgt_mode;
3766         }
3767
3768 #ifdef DEBUG_libfirm
3769         if (is_Const(op)) {
3770                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3771                            op);
3772         }
3773 #endif
3774
3775         match_arguments(&am, block, NULL, op, NULL,
3776                         match_am | match_8bit_am | match_16bit_am);
3777
3778         if (upper_bits_clean(am.new_op2, smaller_mode)) {
3779                 /* unnecessary conv. in theory it shouldn't have been AM */
3780                 assert(is_ia32_NoReg_GP(addr->base));
3781                 assert(is_ia32_NoReg_GP(addr->index));
3782                 assert(is_NoMem(addr->mem));
3783                 assert(am.addr.offset == 0);
3784                 assert(am.addr.symconst_ent == NULL);
3785                 return am.new_op2;
3786         }
3787
3788         new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3789                         addr->mem, am.new_op2, smaller_mode);
3790         set_am_attributes(new_node, &am);
3791         /* match_arguments assume that out-mode = in-mode, this isn't true here
3792          * so fix it */
3793         set_ia32_ls_mode(new_node, smaller_mode);
3794         SET_IA32_ORIG_NODE(new_node, node);
3795         new_node = fix_mem_proj(new_node, &am);
3796         return new_node;
3797 }
3798
3799 /**
3800  * Transforms a Conv node.
3801  *
3802  * @return The created ia32 Conv node
3803  */
3804 static ir_node *gen_Conv(ir_node *node)
3805 {
3806         ir_node  *block     = get_nodes_block(node);
3807         ir_node  *new_block = be_transform_node(block);
3808         ir_node  *op        = get_Conv_op(node);
3809         ir_node  *new_op    = NULL;
3810         dbg_info *dbgi      = get_irn_dbg_info(node);
3811         ir_mode  *src_mode  = get_irn_mode(op);
3812         ir_mode  *tgt_mode  = get_irn_mode(node);
3813         int       src_bits  = get_mode_size_bits(src_mode);
3814         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3815         ir_node  *res       = NULL;
3816
3817         assert(!mode_is_int(src_mode) || src_bits <= 32);
3818         assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3819
3820         /* modeB -> X should already be lowered by the lower_mode_b pass */
3821         if (src_mode == mode_b) {
3822                 panic("ConvB not lowered %+F", node);
3823         }
3824
3825         if (src_mode == tgt_mode) {
3826                 if (get_Conv_strict(node)) {
3827                         if (ia32_cg_config.use_sse2) {
3828                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
3829                                 return be_transform_node(op);
3830                         }
3831                 } else {
3832                         /* this should be optimized already, but who knows... */
3833                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3834                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3835                         return be_transform_node(op);
3836                 }
3837         }
3838
3839         if (mode_is_float(src_mode)) {
3840                 new_op = be_transform_node(op);
3841                 /* we convert from float ... */
3842                 if (mode_is_float(tgt_mode)) {
3843                         /* ... to float */
3844                         if (ia32_cg_config.use_sse2) {
3845                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3846                                 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3847                                                              nomem, new_op);
3848                                 set_ia32_ls_mode(res, tgt_mode);
3849                         } else {
3850                                 if (get_Conv_strict(node)) {
3851                                         /* if fp_no_float_fold is not set then we assume that we
3852                                          * don't have any float operations in a non
3853                                          * mode_float_arithmetic mode and can skip strict upconvs */
3854                                         if (src_bits < tgt_bits) {
3855                                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3856                                                 return new_op;
3857                                         } else {
3858                                                 res = gen_x87_strict_conv(tgt_mode, new_op);
3859                                                 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3860                                                 return res;
3861                                         }
3862                                 }
3863                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3864                                 return new_op;
3865                         }
3866                 } else {
3867                         /* ... to int */
3868                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3869                         if (ia32_cg_config.use_sse2) {
3870                                 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3871                                                             nomem, new_op);
3872                                 set_ia32_ls_mode(res, src_mode);
3873                         } else {
3874                                 return gen_x87_fp_to_gp(node);
3875                         }
3876                 }
3877         } else {
3878                 /* we convert from int ... */
3879                 if (mode_is_float(tgt_mode)) {
3880                         /* ... to float */
3881                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3882                         if (ia32_cg_config.use_sse2) {
3883                                 new_op = be_transform_node(op);
3884                                 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3885                                                             nomem, new_op);
3886                                 set_ia32_ls_mode(res, tgt_mode);
3887                         } else {
3888                                 unsigned int_mantissa   = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3889                                 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3890                                 res = gen_x87_gp_to_fp(node, src_mode);
3891
3892                                 /* we need a strict-Conv, if the int mode has more bits than the
3893                                  * float mantissa */
3894                                 if (float_mantissa < int_mantissa) {
3895                                         res = gen_x87_strict_conv(tgt_mode, res);
3896                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3897                                 }
3898                                 return res;
3899                         }
3900                 } else if (tgt_mode == mode_b) {
3901                         /* mode_b lowering already took care that we only have 0/1 values */
3902                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3903                             src_mode, tgt_mode));
3904                         return be_transform_node(op);
3905                 } else {
3906                         /* to int */
3907                         if (src_bits == tgt_bits) {
3908                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3909                                     src_mode, tgt_mode));
3910                                 return be_transform_node(op);
3911                         }
3912
3913                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3914                         return res;
3915                 }
3916         }
3917
3918         return res;
3919 }
3920
3921 static ir_node *create_immediate_or_transform(ir_node *node,
3922                                               char immediate_constraint_type)
3923 {
3924         ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3925         if (new_node == NULL) {
3926                 new_node = be_transform_node(node);
3927         }
3928         return new_node;
3929 }
3930
3931 /**
3932  * Transforms a FrameAddr into an ia32 Add.
3933  */
3934 static ir_node *gen_be_FrameAddr(ir_node *node)
3935 {
3936         ir_node  *block  = be_transform_node(get_nodes_block(node));
3937         ir_node  *op     = be_get_FrameAddr_frame(node);
3938         ir_node  *new_op = be_transform_node(op);
3939         dbg_info *dbgi   = get_irn_dbg_info(node);
3940         ir_node  *new_node;
3941
3942         new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3943         set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3944         set_ia32_use_frame(new_node);
3945
3946         SET_IA32_ORIG_NODE(new_node, node);
3947
3948         return new_node;
3949 }
3950
3951 /**
3952  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3953  */
3954 static ir_node *gen_be_Return(ir_node *node)
3955 {
3956         ir_graph  *irg     = current_ir_graph;
3957         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
3958         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
3959         ir_entity *ent     = get_irg_entity(irg);
3960         ir_type   *tp      = get_entity_type(ent);
3961         dbg_info  *dbgi;
3962         ir_node   *block;
3963         ir_type   *res_type;
3964         ir_mode   *mode;
3965         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
3966         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
3967         ir_node   **in;
3968         int       pn_ret_val, pn_ret_mem, arity, i;
3969
3970         assert(ret_val != NULL);
3971         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3972                 return be_duplicate_node(node);
3973         }
3974
3975         res_type = get_method_res_type(tp, 0);
3976
3977         if (! is_Primitive_type(res_type)) {
3978                 return be_duplicate_node(node);
3979         }
3980
3981         mode = get_type_mode(res_type);
3982         if (! mode_is_float(mode)) {
3983                 return be_duplicate_node(node);
3984         }
3985
3986         assert(get_method_n_ress(tp) == 1);
3987
3988         pn_ret_val = get_Proj_proj(ret_val);
3989         pn_ret_mem = get_Proj_proj(ret_mem);
3990
3991         /* get the Barrier */
3992         barrier = get_Proj_pred(ret_val);
3993
3994         /* get result input of the Barrier */
3995         ret_val     = get_irn_n(barrier, pn_ret_val);
3996         new_ret_val = be_transform_node(ret_val);
3997
3998         /* get memory input of the Barrier */
3999         ret_mem     = get_irn_n(barrier, pn_ret_mem);
4000         new_ret_mem = be_transform_node(ret_mem);
4001
4002         frame = get_irg_frame(irg);
4003
4004         dbgi  = get_irn_dbg_info(barrier);
4005         block = be_transform_node(get_nodes_block(barrier));
4006
4007         /* store xmm0 onto stack */
4008         sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
4009                                              new_ret_mem, new_ret_val);
4010         set_ia32_ls_mode(sse_store, mode);
4011         set_ia32_op_type(sse_store, ia32_AddrModeD);
4012         set_ia32_use_frame(sse_store);
4013
4014         /* load into x87 register */
4015         fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4016         set_ia32_op_type(fld, ia32_AddrModeS);
4017         set_ia32_use_frame(fld);
4018
4019         mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
4020         fld   = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
4021
4022         /* create a new barrier */
4023         arity = get_irn_arity(barrier);
4024         in    = ALLOCAN(ir_node*, arity);
4025         for (i = 0; i < arity; ++i) {
4026                 ir_node *new_in;
4027
4028                 if (i == pn_ret_val) {
4029                         new_in = fld;
4030                 } else if (i == pn_ret_mem) {
4031                         new_in = mproj;
4032                 } else {
4033                         ir_node *in = get_irn_n(barrier, i);
4034                         new_in = be_transform_node(in);
4035                 }
4036                 in[i] = new_in;
4037         }
4038
4039         new_barrier = new_ir_node(dbgi, irg, block,
4040                                   get_irn_op(barrier), get_irn_mode(barrier),
4041                                   arity, in);
4042         copy_node_attr(irg, barrier, new_barrier);
4043         be_duplicate_deps(barrier, new_barrier);
4044         be_set_transformed_node(barrier, new_barrier);
4045
4046         /* transform normally */
4047         return be_duplicate_node(node);
4048 }
4049
4050 /**
4051  * Transform a be_AddSP into an ia32_SubSP.
4052  */
4053 static ir_node *gen_be_AddSP(ir_node *node)
4054 {
4055         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
4056         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4057
4058         return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4059                          match_am | match_immediate);
4060 }
4061
4062 /**
4063  * Transform a be_SubSP into an ia32_AddSP
4064  */
4065 static ir_node *gen_be_SubSP(ir_node *node)
4066 {
4067         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
4068         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4069
4070         return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4071                          match_am | match_immediate);
4072 }
4073
4074 /**
4075  * Change some phi modes
4076  */
4077 static ir_node *gen_Phi(ir_node *node)
4078 {
4079         const arch_register_req_t *req;
4080         ir_node  *block = be_transform_node(get_nodes_block(node));
4081         ir_graph *irg   = current_ir_graph;
4082         dbg_info *dbgi  = get_irn_dbg_info(node);
4083         ir_mode  *mode  = get_irn_mode(node);
4084         ir_node  *phi;
4085
4086         if (ia32_mode_needs_gp_reg(mode)) {
4087                 /* we shouldn't have any 64bit stuff around anymore */
4088                 assert(get_mode_size_bits(mode) <= 32);
4089                 /* all integer operations are on 32bit registers now */
4090                 mode = mode_Iu;
4091                 req  = ia32_reg_classes[CLASS_ia32_gp].class_req;
4092         } else if (mode_is_float(mode)) {
4093                 if (ia32_cg_config.use_sse2) {
4094                         mode = mode_xmm;
4095                         req  = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4096                 } else {
4097                         mode = mode_vfp;
4098                         req  = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4099                 }
4100         } else {
4101                 req = arch_no_register_req;
4102         }
4103
4104         /* phi nodes allow loops, so we use the old arguments for now
4105          * and fix this later */
4106         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4107                           get_irn_in(node) + 1);
4108         copy_node_attr(irg, node, phi);
4109         be_duplicate_deps(node, phi);
4110
4111         arch_set_out_register_req(phi, 0, req);
4112
4113         be_enqueue_preds(node);
4114
4115         return phi;
4116 }
4117
4118 static ir_node *gen_Jmp(ir_node *node)
4119 {
4120         ir_node  *block     = get_nodes_block(node);
4121         ir_node  *new_block = be_transform_node(block);
4122         dbg_info *dbgi      = get_irn_dbg_info(node);
4123         ir_node  *new_node;
4124
4125         new_node = new_bd_ia32_Jmp(dbgi, new_block);
4126         SET_IA32_ORIG_NODE(new_node, node);
4127
4128         return new_node;
4129 }
4130
4131 /**
4132  * Transform IJmp
4133  */
4134 static ir_node *gen_IJmp(ir_node *node)
4135 {
4136         ir_node  *block     = get_nodes_block(node);
4137         ir_node  *new_block = be_transform_node(block);
4138         dbg_info *dbgi      = get_irn_dbg_info(node);
4139         ir_node  *op        = get_IJmp_target(node);
4140         ir_node  *new_node;
4141         ia32_address_mode_t  am;
4142         ia32_address_t      *addr = &am.addr;
4143
4144         assert(get_irn_mode(op) == mode_P);
4145
4146         match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4147
4148         new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4149                         addr->mem, am.new_op2);
4150         set_am_attributes(new_node, &am);
4151         SET_IA32_ORIG_NODE(new_node, node);
4152
4153         new_node = fix_mem_proj(new_node, &am);
4154
4155         return new_node;
4156 }
4157
4158 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4159 {
4160         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
4161         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4162
4163         return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4164                                match_immediate | match_mode_neutral);
4165 }
4166
4167 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4168 {
4169         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
4170         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4171         return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4172                                match_immediate);
4173 }
4174
4175 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4176 {
4177         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
4178         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4179         return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4180                                match_immediate);
4181 }
4182
4183 static ir_node *gen_ia32_l_Add(ir_node *node)
4184 {
4185         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
4186         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
4187         ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4188                         match_commutative | match_am | match_immediate |
4189                         match_mode_neutral);
4190
4191         if (is_Proj(lowered)) {
4192                 lowered = get_Proj_pred(lowered);
4193         } else {
4194                 assert(is_ia32_Add(lowered));
4195                 set_irn_mode(lowered, mode_T);
4196         }
4197
4198         return lowered;
4199 }
4200
4201 static ir_node *gen_ia32_l_Adc(ir_node *node)
4202 {
4203         return gen_binop_flags(node, new_bd_ia32_Adc,
4204                         match_commutative | match_am | match_immediate |
4205                         match_mode_neutral);
4206 }
4207
4208 /**
4209  * Transforms a l_MulS into a "real" MulS node.
4210  *
4211  * @return the created ia32 Mul node
4212  */
4213 static ir_node *gen_ia32_l_Mul(ir_node *node)
4214 {
4215         ir_node *left  = get_binop_left(node);
4216         ir_node *right = get_binop_right(node);
4217
4218         return gen_binop(node, left, right, new_bd_ia32_Mul,
4219                          match_commutative | match_am | match_mode_neutral);
4220 }
4221
4222 /**
4223  * Transforms a l_IMulS into a "real" IMul1OPS node.
4224  *
4225  * @return the created ia32 IMul1OP node
4226  */
4227 static ir_node *gen_ia32_l_IMul(ir_node *node)
4228 {
4229         ir_node  *left  = get_binop_left(node);
4230         ir_node  *right = get_binop_right(node);
4231
4232         return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4233                          match_commutative | match_am | match_mode_neutral);
4234 }
4235
4236 static ir_node *gen_ia32_l_Sub(ir_node *node)
4237 {
4238         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
4239         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4240         ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4241                         match_am | match_immediate | match_mode_neutral);
4242
4243         if (is_Proj(lowered)) {
4244                 lowered = get_Proj_pred(lowered);
4245         } else {
4246                 assert(is_ia32_Sub(lowered));
4247                 set_irn_mode(lowered, mode_T);
4248         }
4249
4250         return lowered;
4251 }
4252
4253 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4254 {
4255         return gen_binop_flags(node, new_bd_ia32_Sbb,
4256                         match_am | match_immediate | match_mode_neutral);
4257 }
4258
4259 /**
4260  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4261  * op1 - target to be shifted
4262  * op2 - contains bits to be shifted into target
4263  * op3 - shift count
4264  * Only op3 can be an immediate.
4265  */
4266 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4267                                          ir_node *low, ir_node *count)
4268 {
4269         ir_node  *block     = get_nodes_block(node);
4270         ir_node  *new_block = be_transform_node(block);
4271         dbg_info *dbgi      = get_irn_dbg_info(node);
4272         ir_node  *new_high  = be_transform_node(high);
4273         ir_node  *new_low   = be_transform_node(low);
4274         ir_node  *new_count;
4275         ir_node  *new_node;
4276
4277         /* the shift amount can be any mode that is bigger than 5 bits, since all
4278          * other bits are ignored anyway */
4279         while (is_Conv(count)              &&
4280                get_irn_n_edges(count) == 1 &&
4281                mode_is_int(get_irn_mode(count))) {
4282                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4283                 count = get_Conv_op(count);
4284         }
4285         new_count = create_immediate_or_transform(count, 0);
4286
4287         if (is_ia32_l_ShlD(node)) {
4288                 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4289                                             new_count);
4290         } else {
4291                 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4292                                             new_count);
4293         }
4294         SET_IA32_ORIG_NODE(new_node, node);
4295
4296         return new_node;
4297 }
4298
4299 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4300 {
4301         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
4302         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
4303         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4304         return gen_lowered_64bit_shifts(node, high, low, count);
4305 }
4306
4307 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4308 {
4309         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
4310         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
4311         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4312         return gen_lowered_64bit_shifts(node, high, low, count);
4313 }
4314
4315 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4316 {
4317         ir_node  *src_block    = get_nodes_block(node);
4318         ir_node  *block        = be_transform_node(src_block);
4319         ir_graph *irg          = current_ir_graph;
4320         dbg_info *dbgi         = get_irn_dbg_info(node);
4321         ir_node  *frame        = get_irg_frame(irg);
4322         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4323         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4324         ir_node  *new_val_low  = be_transform_node(val_low);
4325         ir_node  *new_val_high = be_transform_node(val_high);
4326         ir_node  *in[2];
4327         ir_node  *sync, *fild, *res;
4328         ir_node  *store_low, *store_high;
4329
4330         if (ia32_cg_config.use_sse2) {
4331                 panic("ia32_l_LLtoFloat not implemented for SSE2");
4332         }
4333
4334         /* do a store */
4335         store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4336                                       new_val_low);
4337         store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4338                                        new_val_high);
4339         SET_IA32_ORIG_NODE(store_low,  node);
4340         SET_IA32_ORIG_NODE(store_high, node);
4341
4342         set_ia32_use_frame(store_low);
4343         set_ia32_use_frame(store_high);
4344         set_ia32_op_type(store_low, ia32_AddrModeD);
4345         set_ia32_op_type(store_high, ia32_AddrModeD);
4346         set_ia32_ls_mode(store_low, mode_Iu);
4347         set_ia32_ls_mode(store_high, mode_Is);
4348         add_ia32_am_offs_int(store_high, 4);
4349
4350         in[0] = store_low;
4351         in[1] = store_high;
4352         sync  = new_rd_Sync(dbgi, block, 2, in);
4353
4354         /* do a fild */
4355         fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4356
4357         set_ia32_use_frame(fild);
4358         set_ia32_op_type(fild, ia32_AddrModeS);
4359         set_ia32_ls_mode(fild, mode_Ls);
4360
4361         SET_IA32_ORIG_NODE(fild, node);
4362
4363         res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4364
4365         if (! mode_is_signed(get_irn_mode(val_high))) {
4366                 ia32_address_mode_t  am;
4367
4368                 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4369                 ir_node *fadd;
4370
4371                 am.addr.base          = get_symconst_base();
4372                 am.addr.index         = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4373                 am.addr.mem           = nomem;
4374                 am.addr.offset        = 0;
4375                 am.addr.scale         = 2;
4376                 am.addr.symconst_ent  = ia32_gen_fp_known_const(ia32_ULLBIAS);
4377                 am.addr.use_frame     = 0;
4378                 am.addr.frame_entity  = NULL;
4379                 am.addr.symconst_sign = 0;
4380                 am.ls_mode            = mode_F;
4381                 am.mem_proj           = nomem;
4382                 am.op_type            = ia32_AddrModeS;
4383                 am.new_op1            = res;
4384                 am.new_op2            = ia32_new_NoReg_vfp(current_ir_graph);
4385                 am.pinned             = op_pin_state_floats;
4386                 am.commutative        = 1;
4387                 am.ins_permuted       = false;
4388
4389                 fadd  = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4390                         am.new_op1, am.new_op2, get_fpcw());
4391                 set_am_attributes(fadd, &am);
4392
4393                 set_irn_mode(fadd, mode_T);
4394                 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4395         }
4396         return res;
4397 }
4398
4399 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4400 {
4401         ir_node  *src_block  = get_nodes_block(node);
4402         ir_node  *block      = be_transform_node(src_block);
4403         ir_graph *irg        = get_Block_irg(block);
4404         dbg_info *dbgi       = get_irn_dbg_info(node);
4405         ir_node  *frame      = get_irg_frame(irg);
4406         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
4407         ir_node  *new_val    = be_transform_node(val);
4408         ir_node  *fist, *mem;
4409
4410         mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4411         SET_IA32_ORIG_NODE(fist, node);
4412         set_ia32_use_frame(fist);
4413         set_ia32_op_type(fist, ia32_AddrModeD);
4414         set_ia32_ls_mode(fist, mode_Ls);
4415
4416         return mem;
4417 }
4418
4419 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4420 {
4421         ir_node  *block    = be_transform_node(get_nodes_block(node));
4422         ir_graph *irg      = get_Block_irg(block);
4423         ir_node  *pred     = get_Proj_pred(node);
4424         ir_node  *new_pred = be_transform_node(pred);
4425         ir_node  *frame    = get_irg_frame(irg);
4426         dbg_info *dbgi     = get_irn_dbg_info(node);
4427         long      pn       = get_Proj_proj(node);
4428         ir_node  *load;
4429         ir_node  *proj;
4430         ia32_attr_t *attr;
4431
4432         load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4433         SET_IA32_ORIG_NODE(load, node);
4434         set_ia32_use_frame(load);
4435         set_ia32_op_type(load, ia32_AddrModeS);
4436         set_ia32_ls_mode(load, mode_Iu);
4437         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4438          * 32 bit from it with this particular load */
4439         attr = get_ia32_attr(load);
4440         attr->data.need_64bit_stackent = 1;
4441
4442         if (pn == pn_ia32_l_FloattoLL_res_high) {
4443                 add_ia32_am_offs_int(load, 4);
4444         } else {
4445                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4446         }
4447
4448         proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4449
4450         return proj;
4451 }
4452
4453 /**
4454  * Transform the Projs of an AddSP.
4455  */
4456 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4457 {
4458         ir_node  *pred     = get_Proj_pred(node);
4459         ir_node  *new_pred = be_transform_node(pred);
4460         dbg_info *dbgi     = get_irn_dbg_info(node);
4461         long     proj      = get_Proj_proj(node);
4462
4463         if (proj == pn_be_AddSP_sp) {
4464                 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4465                                            pn_ia32_SubSP_stack);
4466                 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4467                 return res;
4468         } else if (proj == pn_be_AddSP_res) {
4469                 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4470                                    pn_ia32_SubSP_addr);
4471         } else if (proj == pn_be_AddSP_M) {
4472                 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4473         }
4474
4475         panic("No idea how to transform proj->AddSP");
4476 }
4477
4478 /**
4479  * Transform the Projs of a SubSP.
4480  */
4481 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4482 {
4483         ir_node  *pred     = get_Proj_pred(node);
4484         ir_node  *new_pred = be_transform_node(pred);
4485         dbg_info *dbgi     = get_irn_dbg_info(node);
4486         long     proj      = get_Proj_proj(node);
4487
4488         if (proj == pn_be_SubSP_sp) {
4489                 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4490                                            pn_ia32_AddSP_stack);
4491                 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4492                 return res;
4493         } else if (proj == pn_be_SubSP_M) {
4494                 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4495         }
4496
4497         panic("No idea how to transform proj->SubSP");
4498 }
4499
4500 /**
4501  * Transform and renumber the Projs from a Load.
4502  */
4503 static ir_node *gen_Proj_Load(ir_node *node)
4504 {
4505         ir_node  *new_pred;
4506         ir_node  *block    = be_transform_node(get_nodes_block(node));
4507         ir_node  *pred     = get_Proj_pred(node);
4508         dbg_info *dbgi     = get_irn_dbg_info(node);
4509         long     proj      = get_Proj_proj(node);
4510
4511         /* loads might be part of source address mode matches, so we don't
4512          * transform the ProjMs yet (with the exception of loads whose result is
4513          * not used)
4514          */
4515         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4516                 ir_node *res;
4517
4518                 /* this is needed, because sometimes we have loops that are only
4519                    reachable through the ProjM */
4520                 be_enqueue_preds(node);
4521                 /* do it in 2 steps, to silence firm verifier */
4522                 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4523                 set_Proj_proj(res, pn_ia32_mem);
4524                 return res;
4525         }
4526
4527         /* renumber the proj */
4528         new_pred = be_transform_node(pred);
4529         if (is_ia32_Load(new_pred)) {
4530                 switch (proj) {
4531                 case pn_Load_res:
4532                         return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4533                 case pn_Load_M:
4534                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4535                 case pn_Load_X_regular:
4536                         return new_rd_Jmp(dbgi, block);
4537                 case pn_Load_X_except:
4538                         /* This Load might raise an exception. Mark it. */
4539                         set_ia32_exc_label(new_pred, 1);
4540                         return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4541                 default:
4542                         break;
4543                 }
4544         } else if (is_ia32_Conv_I2I(new_pred) ||
4545                    is_ia32_Conv_I2I8Bit(new_pred)) {
4546                 set_irn_mode(new_pred, mode_T);
4547                 if (proj == pn_Load_res) {
4548                         return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4549                 } else if (proj == pn_Load_M) {
4550                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4551                 }
4552         } else if (is_ia32_xLoad(new_pred)) {
4553                 switch (proj) {
4554                 case pn_Load_res:
4555                         return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4556                 case pn_Load_M:
4557                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4558                 case pn_Load_X_regular:
4559                         return new_rd_Jmp(dbgi, block);
4560                 case pn_Load_X_except:
4561                         /* This Load might raise an exception. Mark it. */
4562                         set_ia32_exc_label(new_pred, 1);
4563                         return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4564                 default:
4565                         break;
4566                 }
4567         } else if (is_ia32_vfld(new_pred)) {
4568                 switch (proj) {
4569                 case pn_Load_res:
4570                         return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4571                 case pn_Load_M:
4572                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4573                 case pn_Load_X_regular:
4574                         return new_rd_Jmp(dbgi, block);
4575                 case pn_Load_X_except:
4576                         /* This Load might raise an exception. Mark it. */
4577                         set_ia32_exc_label(new_pred, 1);
4578                         return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4579                 default:
4580                         break;
4581                 }
4582         } else {
4583                 /* can happen for ProJMs when source address mode happened for the
4584                    node */
4585
4586                 /* however it should not be the result proj, as that would mean the
4587                    load had multiple users and should not have been used for
4588                    SourceAM */
4589                 if (proj != pn_Load_M) {
4590                         panic("internal error: transformed node not a Load");
4591                 }
4592                 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4593         }
4594
4595         panic("No idea how to transform proj");
4596 }
4597
4598 /**
4599  * Transform and renumber the Projs from a Div or Mod instruction.
4600  */
4601 static ir_node *gen_Proj_Div(ir_node *node)
4602 {
4603         ir_node  *block    = be_transform_node(get_nodes_block(node));
4604         ir_node  *pred     = get_Proj_pred(node);
4605         ir_node  *new_pred = be_transform_node(pred);
4606         dbg_info *dbgi     = get_irn_dbg_info(node);
4607         long     proj      = get_Proj_proj(node);
4608
4609         assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4610         assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4611
4612         switch (proj) {
4613         case pn_Div_M:
4614                 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4615                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4616                 } else if (is_ia32_xDiv(new_pred)) {
4617                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4618                 } else if (is_ia32_vfdiv(new_pred)) {
4619                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4620                 } else {
4621                         panic("Div transformed to unexpected thing %+F", new_pred);
4622                 }
4623         case pn_Div_res:
4624                 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4625                         return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4626                 } else if (is_ia32_xDiv(new_pred)) {
4627                         return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4628                 } else if (is_ia32_vfdiv(new_pred)) {
4629                         return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4630                 } else {
4631                         panic("Div transformed to unexpected thing %+F", new_pred);
4632                 }
4633         case pn_Div_X_regular:
4634                 return new_rd_Jmp(dbgi, block);
4635         case pn_Div_X_except:
4636                 set_ia32_exc_label(new_pred, 1);
4637                 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4638         default:
4639                 break;
4640         }
4641
4642         panic("No idea how to transform proj->Div");
4643 }
4644
4645 /**
4646  * Transform and renumber the Projs from a Div or Mod instruction.
4647  */
4648 static ir_node *gen_Proj_Mod(ir_node *node)
4649 {
4650         ir_node  *pred     = get_Proj_pred(node);
4651         ir_node  *new_pred = be_transform_node(pred);
4652         dbg_info *dbgi     = get_irn_dbg_info(node);
4653         long     proj      = get_Proj_proj(node);
4654
4655         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4656         assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4657         assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4658
4659         switch (proj) {
4660         case pn_Mod_M:
4661                 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4662         case pn_Mod_res:
4663                 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4664         case pn_Mod_X_except:
4665                 set_ia32_exc_label(new_pred, 1);
4666                 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4667         default:
4668                 break;
4669         }
4670         panic("No idea how to transform proj->Mod");
4671 }
4672
4673 /**
4674  * Transform and renumber the Projs from a CopyB.
4675  */
4676 static ir_node *gen_Proj_CopyB(ir_node *node)
4677 {
4678         ir_node  *pred     = get_Proj_pred(node);
4679         ir_node  *new_pred = be_transform_node(pred);
4680         dbg_info *dbgi     = get_irn_dbg_info(node);
4681         long     proj      = get_Proj_proj(node);
4682
4683         switch (proj) {
4684         case pn_CopyB_M:
4685                 if (is_ia32_CopyB_i(new_pred)) {
4686                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4687                 } else if (is_ia32_CopyB(new_pred)) {
4688                         return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4689                 }
4690                 break;
4691         default:
4692                 break;
4693         }
4694
4695         panic("No idea how to transform proj->CopyB");
4696 }
4697
4698 static ir_node *gen_be_Call(ir_node *node)
4699 {
4700         dbg_info       *const dbgi      = get_irn_dbg_info(node);
4701         ir_node        *const src_block = get_nodes_block(node);
4702         ir_node        *const block     = be_transform_node(src_block);
4703         ir_node        *const src_mem   = get_irn_n(node, be_pos_Call_mem);
4704         ir_node        *const src_sp    = get_irn_n(node, be_pos_Call_sp);
4705         ir_node        *const sp        = be_transform_node(src_sp);
4706         ir_node        *const src_ptr   = get_irn_n(node, be_pos_Call_ptr);
4707         ia32_address_mode_t   am;
4708         ia32_address_t *const addr      = &am.addr;
4709         ir_node        *      mem;
4710         ir_node        *      call;
4711         int                   i;
4712         ir_node        *      fpcw;
4713         ir_node        *      eax       = noreg_GP;
4714         ir_node        *      ecx       = noreg_GP;
4715         ir_node        *      edx       = noreg_GP;
4716         unsigned        const pop       = be_Call_get_pop(node);
4717         ir_type        *const call_tp   = be_Call_get_type(node);
4718         int                   old_no_pic_adjust;
4719
4720         /* Run the x87 simulator if the call returns a float value */
4721         if (get_method_n_ress(call_tp) > 0) {
4722                 ir_type *const res_type = get_method_res_type(call_tp, 0);
4723                 ir_mode *const res_mode = get_type_mode(res_type);
4724
4725                 if (res_mode != NULL && mode_is_float(res_mode)) {
4726                         ir_graph        *irg      = current_ir_graph;
4727                         ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4728                         irg_data->do_x87_sim = 1;
4729                 }
4730         }
4731
4732         /* We do not want be_Call direct calls */
4733         assert(be_Call_get_entity(node) == NULL);
4734
4735         /* special case for PIC trampoline calls */
4736         old_no_pic_adjust  = ia32_no_pic_adjust;
4737         ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4738
4739         match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4740                         match_am | match_immediate);
4741
4742         ia32_no_pic_adjust = old_no_pic_adjust;
4743
4744         i    = get_irn_arity(node) - 1;
4745         fpcw = be_transform_node(get_irn_n(node, i--));
4746         for (; i >= be_pos_Call_first_arg; --i) {
4747                 arch_register_req_t const *const req = arch_get_register_req(node, i);
4748                 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4749
4750                 assert(req->type == arch_register_req_type_limited);
4751                 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4752
4753                 switch (*req->limited) {
4754                         case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4755                         case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4756                         case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4757                         default: panic("Invalid GP register for register parameter");
4758                 }
4759         }
4760
4761         mem  = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4762         call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4763                                 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4764         set_am_attributes(call, &am);
4765         call = fix_mem_proj(call, &am);
4766
4767         if (get_irn_pinned(node) == op_pin_state_pinned)
4768                 set_irn_pinned(call, op_pin_state_pinned);
4769
4770         SET_IA32_ORIG_NODE(call, node);
4771
4772         if (ia32_cg_config.use_sse2) {
4773                 /* remember this call for post-processing */
4774                 ARR_APP1(ir_node *, call_list, call);
4775                 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4776         }
4777
4778         return call;
4779 }
4780
4781 /**
4782  * Transform Builtin trap
4783  */
4784 static ir_node *gen_trap(ir_node *node)
4785 {
4786         dbg_info *dbgi  = get_irn_dbg_info(node);
4787         ir_node *block  = be_transform_node(get_nodes_block(node));
4788         ir_node *mem    = be_transform_node(get_Builtin_mem(node));
4789
4790         return new_bd_ia32_UD2(dbgi, block, mem);
4791 }
4792
4793 /**
4794  * Transform Builtin debugbreak
4795  */
4796 static ir_node *gen_debugbreak(ir_node *node)
4797 {
4798         dbg_info *dbgi  = get_irn_dbg_info(node);
4799         ir_node *block  = be_transform_node(get_nodes_block(node));
4800         ir_node *mem    = be_transform_node(get_Builtin_mem(node));
4801
4802         return new_bd_ia32_Breakpoint(dbgi, block, mem);
4803 }
4804
4805 /**
4806  * Transform Builtin return_address
4807  */
4808 static ir_node *gen_return_address(ir_node *node)
4809 {
4810         ir_node   *param    = get_Builtin_param(node, 0);
4811         ir_node   *frame    = get_Builtin_param(node, 1);
4812         dbg_info  *dbgi     = get_irn_dbg_info(node);
4813         ir_tarval *tv       = get_Const_tarval(param);
4814         unsigned long value = get_tarval_long(tv);
4815
4816         ir_node *block  = be_transform_node(get_nodes_block(node));
4817         ir_node *ptr    = be_transform_node(frame);
4818         ir_node *load;
4819
4820         if (value > 0) {
4821                 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4822                 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4823                 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4824         }
4825
4826         /* load the return address from this frame */
4827         load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4828
4829         set_irn_pinned(load, get_irn_pinned(node));
4830         set_ia32_op_type(load, ia32_AddrModeS);
4831         set_ia32_ls_mode(load, mode_Iu);
4832
4833         set_ia32_am_offs_int(load, 0);
4834         set_ia32_use_frame(load);
4835         set_ia32_frame_ent(load, ia32_get_return_address_entity());
4836
4837         if (get_irn_pinned(node) == op_pin_state_floats) {
4838                 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4839                                 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4840                                 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4841                 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4842         }
4843
4844         SET_IA32_ORIG_NODE(load, node);
4845         return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4846 }
4847
4848 /**
4849  * Transform Builtin frame_address
4850  */
4851 static ir_node *gen_frame_address(ir_node *node)
4852 {
4853         ir_node   *param    = get_Builtin_param(node, 0);
4854         ir_node   *frame    = get_Builtin_param(node, 1);
4855         dbg_info  *dbgi     = get_irn_dbg_info(node);
4856         ir_tarval *tv       = get_Const_tarval(param);
4857         unsigned long value = get_tarval_long(tv);
4858
4859         ir_node *block  = be_transform_node(get_nodes_block(node));
4860         ir_node *ptr    = be_transform_node(frame);
4861         ir_node *load;
4862         ir_entity *ent;
4863
4864         if (value > 0) {
4865                 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4866                 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4867                 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4868         }
4869
4870         /* load the frame address from this frame */
4871         load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4872
4873         set_irn_pinned(load, get_irn_pinned(node));
4874         set_ia32_op_type(load, ia32_AddrModeS);
4875         set_ia32_ls_mode(load, mode_Iu);
4876
4877         ent = ia32_get_frame_address_entity();
4878         if (ent != NULL) {
4879                 set_ia32_am_offs_int(load, 0);
4880                 set_ia32_use_frame(load);
4881                 set_ia32_frame_ent(load, ent);
4882         } else {
4883                 /* will fail anyway, but gcc does this: */
4884                 set_ia32_am_offs_int(load, 0);
4885         }
4886
4887         if (get_irn_pinned(node) == op_pin_state_floats) {
4888                 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4889                                 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4890                                 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4891                 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4892         }
4893
4894         SET_IA32_ORIG_NODE(load, node);
4895         return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4896 }
4897
4898 /**
4899  * Transform Builtin frame_address
4900  */
4901 static ir_node *gen_prefetch(ir_node *node)
4902 {
4903         dbg_info       *dbgi;
4904         ir_node        *ptr, *block, *mem, *base, *index;
4905         ir_node        *param,  *new_node;
4906         long           rw, locality;
4907         ir_tarval      *tv;
4908         ia32_address_t addr;
4909
4910         if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4911                 /* no prefetch at all, route memory */
4912                 return be_transform_node(get_Builtin_mem(node));
4913         }
4914
4915         param = get_Builtin_param(node, 1);
4916         tv    = get_Const_tarval(param);
4917         rw    = get_tarval_long(tv);
4918
4919         /* construct load address */
4920         memset(&addr, 0, sizeof(addr));
4921         ptr = get_Builtin_param(node, 0);
4922         ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4923         base  = addr.base;
4924         index = addr.index;
4925
4926         if (base == NULL) {
4927                 base = noreg_GP;
4928         } else {
4929                 base = be_transform_node(base);
4930         }
4931
4932         if (index == NULL) {
4933                 index = noreg_GP;
4934         } else {
4935                 index = be_transform_node(index);
4936         }
4937
4938         dbgi     = get_irn_dbg_info(node);
4939         block    = be_transform_node(get_nodes_block(node));
4940         mem      = be_transform_node(get_Builtin_mem(node));
4941
4942         if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4943                 /* we have 3DNow!, this was already checked above */
4944                 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4945         } else if (ia32_cg_config.use_sse_prefetch) {
4946                 /* note: rw == 1 is IGNORED in that case */
4947                 param    = get_Builtin_param(node, 2);
4948                 tv       = get_Const_tarval(param);
4949                 locality = get_tarval_long(tv);
4950
4951                 /* SSE style prefetch */
4952                 switch (locality) {
4953                 case 0:
4954                         new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4955                         break;
4956                 case 1:
4957                         new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4958                         break;
4959                 case 2:
4960                         new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4961                         break;
4962                 default:
4963                         new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4964                         break;
4965                 }
4966         } else {
4967                 assert(ia32_cg_config.use_3dnow_prefetch);
4968                 /* 3DNow! style prefetch */
4969                 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4970         }
4971
4972         set_irn_pinned(new_node, get_irn_pinned(node));
4973         set_ia32_op_type(new_node, ia32_AddrModeS);
4974         set_ia32_ls_mode(new_node, mode_Bu);
4975         set_address(new_node, &addr);
4976
4977         SET_IA32_ORIG_NODE(new_node, node);
4978
4979         be_dep_on_frame(new_node);
4980         return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4981 }
4982
4983 /**
4984  * Transform bsf like node
4985  */
4986 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4987 {
4988         ir_node *param     = get_Builtin_param(node, 0);
4989         dbg_info *dbgi     = get_irn_dbg_info(node);
4990
4991         ir_node *block     = get_nodes_block(node);
4992         ir_node *new_block = be_transform_node(block);
4993
4994         ia32_address_mode_t  am;
4995         ia32_address_t      *addr = &am.addr;
4996         ir_node             *cnt;
4997
4998         match_arguments(&am, block, NULL, param, NULL, match_am);
4999
5000         cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5001         set_am_attributes(cnt, &am);
5002         set_ia32_ls_mode(cnt, get_irn_mode(param));
5003
5004         SET_IA32_ORIG_NODE(cnt, node);
5005         return fix_mem_proj(cnt, &am);
5006 }
5007
5008 /**
5009  * Transform builtin ffs.
5010  */
5011 static ir_node *gen_ffs(ir_node *node)
5012 {
5013         ir_node  *bsf   = gen_unop_AM(node, new_bd_ia32_Bsf);
5014         ir_node  *real  = skip_Proj(bsf);
5015         dbg_info *dbgi  = get_irn_dbg_info(real);
5016         ir_node  *block = get_nodes_block(real);
5017         ir_node  *flag, *set, *conv, *neg, *orn;
5018
5019         /* bsf x */
5020         if (get_irn_mode(real) != mode_T) {
5021                 set_irn_mode(real, mode_T);
5022                 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
5023         }
5024
5025         flag = new_r_Proj(real, mode_b, pn_ia32_flags);
5026
5027         /* sete */
5028         set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
5029         SET_IA32_ORIG_NODE(set, node);
5030
5031         /* conv to 32bit */
5032         conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5033         SET_IA32_ORIG_NODE(conv, node);
5034
5035         /* neg */
5036         neg = new_bd_ia32_Neg(dbgi, block, conv);
5037
5038         /* or */
5039         orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5040         set_ia32_commutative(orn);
5041
5042         /* add 1 */
5043         return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, orn, ia32_create_Immediate(NULL, 0, 1));
5044 }
5045
5046 /**
5047  * Transform builtin clz.
5048  */
5049 static ir_node *gen_clz(ir_node *node)
5050 {
5051         ir_node  *bsr   = gen_unop_AM(node, new_bd_ia32_Bsr);
5052         ir_node  *real  = skip_Proj(bsr);
5053         dbg_info *dbgi  = get_irn_dbg_info(real);
5054         ir_node  *block = get_nodes_block(real);
5055         ir_node  *imm   = ia32_create_Immediate(NULL, 0, 31);
5056
5057         return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5058 }
5059
5060 /**
5061  * Transform builtin ctz.
5062  */
5063 static ir_node *gen_ctz(ir_node *node)
5064 {
5065         return gen_unop_AM(node, new_bd_ia32_Bsf);
5066 }
5067
5068 /**
5069  * Transform builtin parity.
5070  */
5071 static ir_node *gen_parity(ir_node *node)
5072 {
5073         dbg_info *dbgi      = get_irn_dbg_info(node);
5074         ir_node  *block     = get_nodes_block(node);
5075         ir_node  *new_block = be_transform_node(block);
5076         ir_node  *param     = get_Builtin_param(node, 0);
5077         ir_node  *new_param = be_transform_node(param);
5078         ir_node  *new_node;
5079
5080         /* the x86 parity bit is stupid: it only looks at the lowest byte,
5081          * so we have to do complicated xoring first.
5082          * (we should also better lower this before the backend so we still have a
5083          * chance for CSE, constant folding and other goodies for some of these
5084          * operations)
5085          */
5086         ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5087         ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5088         ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5089                                        shr, new_param);
5090         ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5091         ir_node *flags;
5092
5093         set_irn_mode(xor2, mode_T);
5094         flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5095
5096         /* setp */
5097         new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5098         SET_IA32_ORIG_NODE(new_node, node);
5099
5100         /* conv to 32bit */
5101         new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5102                                             nomem, new_node, mode_Bu);
5103         SET_IA32_ORIG_NODE(new_node, node);
5104         return new_node;
5105 }
5106
5107 /**
5108  * Transform builtin popcount
5109  */
5110 static ir_node *gen_popcount(ir_node *node)
5111 {
5112         ir_node *param     = get_Builtin_param(node, 0);
5113         dbg_info *dbgi     = get_irn_dbg_info(node);
5114
5115         ir_node *block     = get_nodes_block(node);
5116         ir_node *new_block = be_transform_node(block);
5117
5118         ir_node *new_param;
5119         ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5120
5121         /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5122         if (ia32_cg_config.use_popcnt) {
5123                 ia32_address_mode_t am;
5124                 ia32_address_t      *addr = &am.addr;
5125                 ir_node             *cnt;
5126
5127                 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5128
5129                 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5130                 set_am_attributes(cnt, &am);
5131                 set_ia32_ls_mode(cnt, get_irn_mode(param));
5132
5133                 SET_IA32_ORIG_NODE(cnt, node);
5134                 return fix_mem_proj(cnt, &am);
5135         }
5136
5137         new_param = be_transform_node(param);
5138
5139         /* do the standard popcount algo */
5140         /* TODO: This is stupid, we should transform this before the backend,
5141          * to get CSE, localopts, etc. for the operations
5142          * TODO: This is also not the optimal algorithm (it is just the starting
5143          * example in hackers delight, they optimize it more on the following page)
5144          * But I'm too lazy to fix this now, as the code should get lowered before
5145          * the backend anyway.
5146          */
5147
5148         /* m1 = x & 0x55555555 */
5149         imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5150         m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5151
5152         /* s1 = x >> 1 */
5153         simm = ia32_create_Immediate(NULL, 0, 1);
5154         s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5155
5156         /* m2 = s1 & 0x55555555 */
5157         m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5158
5159         /* m3 = m1 + m2 */
5160         m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5161
5162         /* m4 = m3 & 0x33333333 */
5163         imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5164         m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5165
5166         /* s2 = m3 >> 2 */
5167         simm = ia32_create_Immediate(NULL, 0, 2);
5168         s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5169
5170         /* m5 = s2 & 0x33333333 */
5171         m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5172
5173         /* m6 = m4 + m5 */
5174         m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5175
5176         /* m7 = m6 & 0x0F0F0F0F */
5177         imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5178         m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5179
5180         /* s3 = m6 >> 4 */
5181         simm = ia32_create_Immediate(NULL, 0, 4);
5182         s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5183
5184         /* m8 = s3 & 0x0F0F0F0F */
5185         m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5186
5187         /* m9 = m7 + m8 */
5188         m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5189
5190         /* m10 = m9 & 0x00FF00FF */
5191         imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5192         m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5193
5194         /* s4 = m9 >> 8 */
5195         simm = ia32_create_Immediate(NULL, 0, 8);
5196         s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5197
5198         /* m11 = s4 & 0x00FF00FF */
5199         m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5200
5201         /* m12 = m10 + m11 */
5202         m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5203
5204         /* m13 = m12 & 0x0000FFFF */
5205         imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5206         m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5207
5208         /* s5 = m12 >> 16 */
5209         simm = ia32_create_Immediate(NULL, 0, 16);
5210         s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5211
5212         /* res = m13 + s5 */
5213         return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5214 }
5215
5216 /**
5217  * Transform builtin byte swap.
5218  */
5219 static ir_node *gen_bswap(ir_node *node)
5220 {
5221         ir_node *param     = be_transform_node(get_Builtin_param(node, 0));
5222         dbg_info *dbgi     = get_irn_dbg_info(node);
5223
5224         ir_node *block     = get_nodes_block(node);
5225         ir_node *new_block = be_transform_node(block);
5226         ir_mode *mode      = get_irn_mode(param);
5227         unsigned size      = get_mode_size_bits(mode);
5228         ir_node  *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5229
5230         switch (size) {
5231         case 32:
5232                 if (ia32_cg_config.use_i486) {
5233                         /* swap available */
5234                         return new_bd_ia32_Bswap(dbgi, new_block, param);
5235                 }
5236                 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5237                 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5238
5239                 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5240                 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5241
5242                 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5243
5244                 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5245                 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5246
5247                 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5248                 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5249
5250         case 16:
5251                 /* swap16 always available */
5252                 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5253
5254         default:
5255                 panic("Invalid bswap size (%d)", size);
5256         }
5257 }
5258
5259 /**
5260  * Transform builtin outport.
5261  */
5262 static ir_node *gen_outport(ir_node *node)
5263 {
5264         ir_node *port  = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5265         ir_node *oldv  = get_Builtin_param(node, 1);
5266         ir_mode *mode  = get_irn_mode(oldv);
5267         ir_node *value = be_transform_node(oldv);
5268         ir_node *block = be_transform_node(get_nodes_block(node));
5269         ir_node *mem   = be_transform_node(get_Builtin_mem(node));
5270         dbg_info *dbgi = get_irn_dbg_info(node);
5271
5272         ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5273         set_ia32_ls_mode(res, mode);
5274         return res;
5275 }
5276
5277 /**
5278  * Transform builtin inport.
5279  */
5280 static ir_node *gen_inport(ir_node *node)
5281 {
5282         ir_type *tp    = get_Builtin_type(node);
5283         ir_type *rstp  = get_method_res_type(tp, 0);
5284         ir_mode *mode  = get_type_mode(rstp);
5285         ir_node *port  = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5286         ir_node *block = be_transform_node(get_nodes_block(node));
5287         ir_node *mem   = be_transform_node(get_Builtin_mem(node));
5288         dbg_info *dbgi = get_irn_dbg_info(node);
5289
5290         ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5291         set_ia32_ls_mode(res, mode);
5292
5293         /* check for missing Result Proj */
5294         return res;
5295 }
5296
5297 /**
5298  * Transform a builtin inner trampoline
5299  */
5300 static ir_node *gen_inner_trampoline(ir_node *node)
5301 {
5302         ir_node  *ptr       = get_Builtin_param(node, 0);
5303         ir_node  *callee    = get_Builtin_param(node, 1);
5304         ir_node  *env       = be_transform_node(get_Builtin_param(node, 2));
5305         ir_node  *mem       = get_Builtin_mem(node);
5306         ir_node  *block     = get_nodes_block(node);
5307         ir_node  *new_block = be_transform_node(block);
5308         ir_node  *val;
5309         ir_node  *store;
5310         ir_node  *rel;
5311         ir_node  *trampoline;
5312         ir_node  *in[2];
5313         dbg_info *dbgi      = get_irn_dbg_info(node);
5314         ia32_address_t addr;
5315
5316         /* construct store address */
5317         memset(&addr, 0, sizeof(addr));
5318         ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5319
5320         if (addr.base == NULL) {
5321                 addr.base = noreg_GP;
5322         } else {
5323                 addr.base = be_transform_node(addr.base);
5324         }
5325
5326         if (addr.index == NULL) {
5327                 addr.index = noreg_GP;
5328         } else {
5329                 addr.index = be_transform_node(addr.index);
5330         }
5331         addr.mem = be_transform_node(mem);
5332
5333         /* mov  ecx, <env> */
5334         val   = ia32_create_Immediate(NULL, 0, 0xB9);
5335         store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5336                                       addr.index, addr.mem, val);
5337         set_irn_pinned(store, get_irn_pinned(node));
5338         set_ia32_op_type(store, ia32_AddrModeD);
5339         set_ia32_ls_mode(store, mode_Bu);
5340         set_address(store, &addr);
5341         addr.mem = store;
5342         addr.offset += 1;
5343
5344         store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5345                                   addr.index, addr.mem, env);
5346         set_irn_pinned(store, get_irn_pinned(node));
5347         set_ia32_op_type(store, ia32_AddrModeD);
5348         set_ia32_ls_mode(store, mode_Iu);
5349         set_address(store, &addr);
5350         addr.mem = store;
5351         addr.offset += 4;
5352
5353         /* jmp rel <callee> */
5354         val   = ia32_create_Immediate(NULL, 0, 0xE9);
5355         store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5356                                      addr.index, addr.mem, val);
5357         set_irn_pinned(store, get_irn_pinned(node));
5358         set_ia32_op_type(store, ia32_AddrModeD);
5359         set_ia32_ls_mode(store, mode_Bu);
5360         set_address(store, &addr);
5361         addr.mem = store;
5362         addr.offset += 1;
5363
5364         trampoline = be_transform_node(ptr);
5365
5366         /* the callee is typically an immediate */
5367         if (is_SymConst(callee)) {
5368                 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5369         } else {
5370                 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5371                 add_ia32_am_offs_int(rel, -10);
5372         }
5373         rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5374
5375         store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5376                                   addr.index, addr.mem, rel);
5377         set_irn_pinned(store, get_irn_pinned(node));
5378         set_ia32_op_type(store, ia32_AddrModeD);
5379         set_ia32_ls_mode(store, mode_Iu);
5380         set_address(store, &addr);
5381
5382         in[0] = store;
5383         in[1] = trampoline;
5384
5385         return new_r_Tuple(new_block, 2, in);
5386 }
5387
5388 /**
5389  * Transform Builtin node.
5390  */
5391 static ir_node *gen_Builtin(ir_node *node)
5392 {
5393         ir_builtin_kind kind = get_Builtin_kind(node);
5394
5395         switch (kind) {
5396         case ir_bk_trap:
5397                 return gen_trap(node);
5398         case ir_bk_debugbreak:
5399                 return gen_debugbreak(node);
5400         case ir_bk_return_address:
5401                 return gen_return_address(node);
5402         case ir_bk_frame_address:
5403                 return gen_frame_address(node);
5404         case ir_bk_prefetch:
5405                 return gen_prefetch(node);
5406         case ir_bk_ffs:
5407                 return gen_ffs(node);
5408         case ir_bk_clz:
5409                 return gen_clz(node);
5410         case ir_bk_ctz:
5411                 return gen_ctz(node);
5412         case ir_bk_parity:
5413                 return gen_parity(node);
5414         case ir_bk_popcount:
5415                 return gen_popcount(node);
5416         case ir_bk_bswap:
5417                 return gen_bswap(node);
5418         case ir_bk_outport:
5419                 return gen_outport(node);
5420         case ir_bk_inport:
5421                 return gen_inport(node);
5422         case ir_bk_inner_trampoline:
5423                 return gen_inner_trampoline(node);
5424         }
5425         panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5426 }
5427
5428 /**
5429  * Transform Proj(Builtin) node.
5430  */
5431 static ir_node *gen_Proj_Builtin(ir_node *proj)
5432 {
5433         ir_node         *node     = get_Proj_pred(proj);
5434         ir_node         *new_node = be_transform_node(node);
5435         ir_builtin_kind kind      = get_Builtin_kind(node);
5436
5437         switch (kind) {
5438         case ir_bk_return_address:
5439         case ir_bk_frame_address:
5440         case ir_bk_ffs:
5441         case ir_bk_clz:
5442         case ir_bk_ctz:
5443         case ir_bk_parity:
5444         case ir_bk_popcount:
5445         case ir_bk_bswap:
5446                 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5447                 return new_node;
5448         case ir_bk_trap:
5449         case ir_bk_debugbreak:
5450         case ir_bk_prefetch:
5451         case ir_bk_outport:
5452                 assert(get_Proj_proj(proj) == pn_Builtin_M);
5453                 return new_node;
5454         case ir_bk_inport:
5455                 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5456                         return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5457                 } else {
5458                         assert(get_Proj_proj(proj) == pn_Builtin_M);
5459                         return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5460                 }
5461         case ir_bk_inner_trampoline:
5462                 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5463                         return get_Tuple_pred(new_node, 1);
5464                 } else {
5465                         assert(get_Proj_proj(proj) == pn_Builtin_M);
5466                         return get_Tuple_pred(new_node, 0);
5467                 }
5468         }
5469         panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5470 }
5471
5472 static ir_node *gen_be_IncSP(ir_node *node)
5473 {
5474         ir_node *res = be_duplicate_node(node);
5475         arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5476
5477         return res;
5478 }
5479
5480 /**
5481  * Transform the Projs from a be_Call.
5482  */
5483 static ir_node *gen_Proj_be_Call(ir_node *node)
5484 {
5485         ir_node  *call        = get_Proj_pred(node);
5486         ir_node  *new_call    = be_transform_node(call);
5487         dbg_info *dbgi        = get_irn_dbg_info(node);
5488         long      proj        = get_Proj_proj(node);
5489         ir_mode  *mode        = get_irn_mode(node);
5490         ir_node  *res;
5491
5492         if (proj == pn_be_Call_M_regular) {
5493                 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5494         }
5495         /* transform call modes */
5496         if (mode_is_data(mode)) {
5497                 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5498                 mode = cls->mode;
5499         }
5500
5501         /* Map from be_Call to ia32_Call proj number */
5502         if (proj == pn_be_Call_sp) {
5503                 proj = pn_ia32_Call_stack;
5504         } else if (proj == pn_be_Call_M_regular) {
5505                 proj = pn_ia32_Call_M;
5506         } else {
5507                 arch_register_req_t const *const req    = arch_get_register_req_out(node);
5508                 int                        const n_outs = arch_irn_get_n_outs(new_call);
5509                 int                              i;
5510
5511                 assert(proj      >= pn_be_Call_first_res);
5512                 assert(req->type & arch_register_req_type_limited);
5513
5514                 for (i = 0; i < n_outs; ++i) {
5515                         arch_register_req_t const *const new_req
5516                                 = arch_get_out_register_req(new_call, i);
5517
5518                         if (!(new_req->type & arch_register_req_type_limited) ||
5519                             new_req->cls      != req->cls                     ||
5520                             *new_req->limited != *req->limited)
5521                                 continue;
5522
5523                         proj = i;
5524                         break;
5525                 }
5526                 assert(i < n_outs);
5527         }
5528
5529         res = new_rd_Proj(dbgi, new_call, mode, proj);
5530
5531         /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5532         switch (proj) {
5533                 case pn_ia32_Call_stack:
5534                         arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5535                         break;
5536
5537                 case pn_ia32_Call_fpcw:
5538                         arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5539                         break;
5540         }
5541
5542         return res;
5543 }
5544
5545 /**
5546  * Transform the Projs from a Cmp.
5547  */
5548 static ir_node *gen_Proj_Cmp(ir_node *node)
5549 {
5550         /* this probably means not all mode_b nodes were lowered... */
5551         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5552               node);
5553 }
5554
5555 static ir_node *gen_Proj_ASM(ir_node *node)
5556 {
5557         ir_mode *mode     = get_irn_mode(node);
5558         ir_node *pred     = get_Proj_pred(node);
5559         ir_node *new_pred = be_transform_node(pred);
5560         long     pos      = get_Proj_proj(node);
5561
5562         if (mode == mode_M) {
5563                 pos = arch_irn_get_n_outs(new_pred)-1;
5564         } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5565                 mode = mode_Iu;
5566         } else if (mode_is_float(mode)) {
5567                 mode = mode_E;
5568         } else {
5569                 panic("unexpected proj mode at ASM");
5570         }
5571
5572         return new_r_Proj(new_pred, mode, pos);
5573 }
5574
5575 /**
5576  * Transform and potentially renumber Proj nodes.
5577  */
5578 static ir_node *gen_Proj(ir_node *node)
5579 {
5580         ir_node *pred = get_Proj_pred(node);
5581         long    proj;
5582
5583         switch (get_irn_opcode(pred)) {
5584         case iro_Store:
5585                 proj = get_Proj_proj(node);
5586                 if (proj == pn_Store_M) {
5587                         return be_transform_node(pred);
5588                 } else {
5589                         panic("No idea how to transform proj->Store");
5590                 }
5591         case iro_Load:
5592                 return gen_Proj_Load(node);
5593         case iro_ASM:
5594                 return gen_Proj_ASM(node);
5595         case iro_Builtin:
5596                 return gen_Proj_Builtin(node);
5597         case iro_Div:
5598                 return gen_Proj_Div(node);
5599         case iro_Mod:
5600                 return gen_Proj_Mod(node);
5601         case iro_CopyB:
5602                 return gen_Proj_CopyB(node);
5603         case beo_SubSP:
5604                 return gen_Proj_be_SubSP(node);
5605         case beo_AddSP:
5606                 return gen_Proj_be_AddSP(node);
5607         case beo_Call:
5608                 return gen_Proj_be_Call(node);
5609         case iro_Cmp:
5610                 return gen_Proj_Cmp(node);
5611         case iro_Start:
5612                 proj = get_Proj_proj(node);
5613                 switch (proj) {
5614                         case pn_Start_X_initial_exec: {
5615                                 ir_node  *block     = get_nodes_block(pred);
5616                                 ir_node  *new_block = be_transform_node(block);
5617                                 dbg_info *dbgi      = get_irn_dbg_info(node);
5618                                 /* we exchange the ProjX with a jump */
5619                                 ir_node  *jump      = new_rd_Jmp(dbgi, new_block);
5620
5621                                 return jump;
5622                         }
5623
5624                         case pn_Start_P_tls:
5625                                 return ia32_gen_Proj_tls(node);
5626                 }
5627                 break;
5628
5629         default:
5630                 if (is_ia32_l_FloattoLL(pred)) {
5631                         return gen_Proj_l_FloattoLL(node);
5632 #ifdef FIRM_EXT_GRS
5633                 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5634 #else
5635                 } else {
5636 #endif
5637                         ir_mode *mode = get_irn_mode(node);
5638                         if (ia32_mode_needs_gp_reg(mode)) {
5639                                 ir_node *new_pred = be_transform_node(pred);
5640                                 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5641                                                                get_Proj_proj(node));
5642                                 new_proj->node_nr = node->node_nr;
5643                                 return new_proj;
5644                         }
5645                 }
5646         }
5647         return be_duplicate_node(node);
5648 }
5649
5650 /**
5651  * Enters all transform functions into the generic pointer
5652  */
5653 static void register_transformers(void)
5654 {
5655         /* first clear the generic function pointer for all ops */
5656         be_start_transform_setup();
5657
5658         be_set_transform_function(op_Add,              gen_Add);
5659         be_set_transform_function(op_And,              gen_And);
5660         be_set_transform_function(op_ASM,              ia32_gen_ASM);
5661         be_set_transform_function(op_be_AddSP,         gen_be_AddSP);
5662         be_set_transform_function(op_be_Call,          gen_be_Call);
5663         be_set_transform_function(op_be_Copy,          gen_be_Copy);
5664         be_set_transform_function(op_be_FrameAddr,     gen_be_FrameAddr);
5665         be_set_transform_function(op_be_IncSP,         gen_be_IncSP);
5666         be_set_transform_function(op_be_Return,        gen_be_Return);
5667         be_set_transform_function(op_be_SubSP,         gen_be_SubSP);
5668         be_set_transform_function(op_Builtin,          gen_Builtin);
5669         be_set_transform_function(op_Cmp,              gen_Cmp);
5670         be_set_transform_function(op_Cond,             gen_Cond);
5671         be_set_transform_function(op_Const,            gen_Const);
5672         be_set_transform_function(op_Conv,             gen_Conv);
5673         be_set_transform_function(op_CopyB,            ia32_gen_CopyB);
5674         be_set_transform_function(op_Div,              gen_Div);
5675         be_set_transform_function(op_Eor,              gen_Eor);
5676         be_set_transform_function(op_ia32_l_Adc,       gen_ia32_l_Adc);
5677         be_set_transform_function(op_ia32_l_Add,       gen_ia32_l_Add);
5678         be_set_transform_function(op_ia32_Leave,       be_duplicate_node);
5679         be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5680         be_set_transform_function(op_ia32_l_IMul,      gen_ia32_l_IMul);
5681         be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5682         be_set_transform_function(op_ia32_l_Mul,       gen_ia32_l_Mul);
5683         be_set_transform_function(op_ia32_l_SarDep,    gen_ia32_l_SarDep);
5684         be_set_transform_function(op_ia32_l_Sbb,       gen_ia32_l_Sbb);
5685         be_set_transform_function(op_ia32_l_ShlDep,    gen_ia32_l_ShlDep);
5686         be_set_transform_function(op_ia32_l_ShlD,      gen_ia32_l_ShlD);
5687         be_set_transform_function(op_ia32_l_ShrDep,    gen_ia32_l_ShrDep);
5688         be_set_transform_function(op_ia32_l_ShrD,      gen_ia32_l_ShrD);
5689         be_set_transform_function(op_ia32_l_Sub,       gen_ia32_l_Sub);
5690         be_set_transform_function(op_ia32_GetEIP,      be_duplicate_node);
5691         be_set_transform_function(op_ia32_Minus64Bit,  be_duplicate_node);
5692         be_set_transform_function(op_ia32_NoReg_GP,    be_duplicate_node);
5693         be_set_transform_function(op_ia32_NoReg_VFP,   be_duplicate_node);
5694         be_set_transform_function(op_ia32_NoReg_XMM,   be_duplicate_node);
5695         be_set_transform_function(op_ia32_PopEbp,      be_duplicate_node);
5696         be_set_transform_function(op_ia32_Push,        be_duplicate_node);
5697         be_set_transform_function(op_IJmp,             gen_IJmp);
5698         be_set_transform_function(op_Jmp,              gen_Jmp);
5699         be_set_transform_function(op_Load,             gen_Load);
5700         be_set_transform_function(op_Minus,            gen_Minus);
5701         be_set_transform_function(op_Mod,              gen_Mod);
5702         be_set_transform_function(op_Mul,              gen_Mul);
5703         be_set_transform_function(op_Mulh,             gen_Mulh);
5704         be_set_transform_function(op_Mux,              gen_Mux);
5705         be_set_transform_function(op_Not,              gen_Not);
5706         be_set_transform_function(op_Or,               gen_Or);
5707         be_set_transform_function(op_Phi,              gen_Phi);
5708         be_set_transform_function(op_Proj,             gen_Proj);
5709         be_set_transform_function(op_Rotl,             gen_Rotl);
5710         be_set_transform_function(op_Shl,              gen_Shl);
5711         be_set_transform_function(op_Shr,              gen_Shr);
5712         be_set_transform_function(op_Shrs,             gen_Shrs);
5713         be_set_transform_function(op_Store,            gen_Store);
5714         be_set_transform_function(op_Sub,              gen_Sub);
5715         be_set_transform_function(op_SymConst,         gen_SymConst);
5716         be_set_transform_function(op_Unknown,          ia32_gen_Unknown);
5717 }
5718
5719 /**
5720  * Pre-transform all unknown and noreg nodes.
5721  */
5722 static void ia32_pretransform_node(void)
5723 {
5724         ir_graph        *irg      = current_ir_graph;
5725         ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5726
5727         irg_data->noreg_gp  = be_pre_transform_node(irg_data->noreg_gp);
5728         irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5729         irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5730
5731         nomem    = get_irg_no_mem(irg);
5732         noreg_GP = ia32_new_NoReg_gp(irg);
5733
5734         get_fpcw();
5735 }
5736
5737 /**
5738  * Post-process all calls if we are in SSE mode.
5739  * The ABI requires that the results are in st0, copy them
5740  * to a xmm register.
5741  */
5742 static void postprocess_fp_call_results(void)
5743 {
5744         size_t i, n;
5745
5746         for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5747                 ir_node *call = call_list[i];
5748                 ir_type *mtp  = call_types[i];
5749                 int     j;
5750
5751                 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5752                         ir_type *res_tp = get_method_res_type(mtp, j);
5753                         ir_node *res, *new_res;
5754                         const ir_edge_t *edge, *next;
5755                         ir_mode *mode;
5756
5757                         if (! is_atomic_type(res_tp)) {
5758                                 /* no floating point return */
5759                                 continue;
5760                         }
5761                         mode = get_type_mode(res_tp);
5762                         if (! mode_is_float(mode)) {
5763                                 /* no floating point return */
5764                                 continue;
5765                         }
5766
5767                         res     = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5768                         new_res = NULL;
5769
5770                         /* now patch the users */
5771                         foreach_out_edge_safe(res, edge, next) {
5772                                 ir_node *succ = get_edge_src_irn(edge);
5773
5774                                 /* ignore Keeps */
5775                                 if (be_is_Keep(succ))
5776                                         continue;
5777
5778                                 if (is_ia32_xStore(succ)) {
5779                                         /* an xStore can be patched into an vfst */
5780                                         dbg_info *db    = get_irn_dbg_info(succ);
5781                                         ir_node  *block = get_nodes_block(succ);
5782                                         ir_node  *base  = get_irn_n(succ, n_ia32_xStore_base);
5783                                         ir_node  *index = get_irn_n(succ, n_ia32_xStore_index);
5784                                         ir_node  *mem   = get_irn_n(succ, n_ia32_xStore_mem);
5785                                         ir_node  *value = get_irn_n(succ, n_ia32_xStore_val);
5786                                         ir_mode  *mode  = get_ia32_ls_mode(succ);
5787
5788                                         ir_node  *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5789                                         set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5790                                         if (is_ia32_use_frame(succ))
5791                                                 set_ia32_use_frame(st);
5792                                         set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5793                                         set_irn_pinned(st, get_irn_pinned(succ));
5794                                         set_ia32_op_type(st, ia32_AddrModeD);
5795
5796                                         exchange(succ, st);
5797                                 } else {
5798                                         if (new_res == NULL) {
5799                                                 dbg_info *db       = get_irn_dbg_info(call);
5800                                                 ir_node  *block    = get_nodes_block(call);
5801                                                 ir_node  *frame    = get_irg_frame(current_ir_graph);
5802                                                 ir_node  *old_mem  = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5803                                                 ir_node  *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5804                                                 ir_node  *vfst, *xld, *new_mem;
5805
5806                                                 /* store st(0) on stack */
5807                                                 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5808                                                 set_ia32_op_type(vfst, ia32_AddrModeD);
5809                                                 set_ia32_use_frame(vfst);
5810
5811                                                 /* load into SSE register */
5812                                                 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5813                                                 set_ia32_op_type(xld, ia32_AddrModeS);
5814                                                 set_ia32_use_frame(xld);
5815
5816                                                 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5817                                                 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5818
5819                                                 if (old_mem != NULL) {
5820                                                         edges_reroute(old_mem, new_mem, current_ir_graph);
5821                                                         kill_node(old_mem);
5822                                                 }
5823                                         }
5824                                         set_irn_n(succ, get_edge_src_pos(edge), new_res);
5825                                 }
5826                         }
5827                 }
5828         }
5829 }
5830
5831 /* do the transformation */
5832 void ia32_transform_graph(ir_graph *irg)
5833 {
5834         int cse_last;
5835
5836         register_transformers();
5837         initial_fpcw       = NULL;
5838         ia32_no_pic_adjust = 0;
5839
5840         be_timer_push(T_HEIGHTS);
5841         ia32_heights = heights_new(irg);
5842         be_timer_pop(T_HEIGHTS);
5843         ia32_calculate_non_address_mode_nodes(irg);
5844
5845         /* the transform phase is not safe for CSE (yet) because several nodes get
5846          * attributes set after their creation */
5847         cse_last = get_opt_cse();
5848         set_opt_cse(0);
5849
5850         call_list  = NEW_ARR_F(ir_node *, 0);
5851         call_types = NEW_ARR_F(ir_type *, 0);
5852         be_transform_graph(irg, ia32_pretransform_node);
5853
5854         if (ia32_cg_config.use_sse2)
5855                 postprocess_fp_call_results();
5856         DEL_ARR_F(call_types);
5857         DEL_ARR_F(call_list);
5858
5859         set_opt_cse(cse_last);
5860
5861         ia32_free_non_address_mode_nodes();
5862         heights_free(ia32_heights);
5863         ia32_heights = NULL;
5864 }
5865
5866 void ia32_init_transform(void)
5867 {
5868         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
5869 }