fixes, use new blockscheduler
[libfirm] / ir / be / ia32 / bearch_ia32.c
1 /**
2  * This is the main ia32 firm backend driver.
3  * @author Christian Wuerdig
4  * $Id$
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #ifdef HAVE_MALLOC_H
12 #include <malloc.h>
13 #endif
14
15 #ifdef HAVE_ALLOCA_H
16 #include <alloca.h>
17 #endif
18
19 #ifdef WITH_LIBCORE
20 #include <libcore/lc_opts.h>
21 #include <libcore/lc_opts_enum.h>
22 #endif /* WITH_LIBCORE */
23
24 #include <math.h>
25
26 #include "pseudo_irg.h"
27 #include "irgwalk.h"
28 #include "irprog.h"
29 #include "irprintf.h"
30 #include "iredges_t.h"
31 #include "ircons.h"
32 #include "irgmod.h"
33 #include "irgopt.h"
34 #include "irbitset.h"
35 #include "pdeq.h"
36 #include "debug.h"
37
38 #include "../beabi.h"                 /* the general register allocator interface */
39 #include "../benode_t.h"
40 #include "../belower.h"
41 #include "../besched_t.h"
42 #include "../be.h"
43 #include "../be_t.h"
44 #include "../beirgmod.h"
45 #include "../be_dbgout.h"
46 #include "../beblocksched.h"
47 #include "bearch_ia32_t.h"
48
49 #include "ia32_new_nodes.h"           /* ia32 nodes interface */
50 #include "gen_ia32_regalloc_if.h"     /* the generated interface (register type and class defenitions) */
51 #include "ia32_gen_decls.h"           /* interface declaration emitter */
52 #include "ia32_transform.h"
53 #include "ia32_emitter.h"
54 #include "ia32_map_regs.h"
55 #include "ia32_optimize.h"
56 #include "ia32_x87.h"
57 #include "ia32_dbg_stat.h"
58 #include "ia32_finish.h"
59 #include "ia32_util.h"
60
61 #define DEBUG_MODULE "firm.be.ia32.isa"
62
63 /* TODO: ugly */
64 static set *cur_reg_set = NULL;
65
66 /* Creates the unique per irg GP NoReg node. */
67 ir_node *ia32_new_NoReg_gp(ia32_code_gen_t *cg) {
68         return be_abi_get_callee_save_irn(cg->birg->abi, &ia32_gp_regs[REG_GP_NOREG]);
69 }
70
71 /* Creates the unique per irg FP NoReg node. */
72 ir_node *ia32_new_NoReg_fp(ia32_code_gen_t *cg) {
73         return be_abi_get_callee_save_irn(cg->birg->abi,
74                 USE_SSE2(cg) ? &ia32_xmm_regs[REG_XMM_NOREG] : &ia32_vfp_regs[REG_VFP_NOREG]);
75 }
76
77 /**
78  * Returns gp_noreg or fp_noreg, depending in input requirements.
79  */
80 ir_node *ia32_get_admissible_noreg(ia32_code_gen_t *cg, ir_node *irn, int pos) {
81         arch_register_req_t       req;
82         const arch_register_req_t *p_req;
83
84         p_req = arch_get_register_req(cg->arch_env, &req, irn, pos);
85         assert(p_req && "Missing register requirements");
86         if (p_req->cls == &ia32_reg_classes[CLASS_ia32_gp])
87                 return ia32_new_NoReg_gp(cg);
88         else
89                 return ia32_new_NoReg_fp(cg);
90 }
91
92 /**************************************************
93  *                         _ _              _  __
94  *                        | | |            (_)/ _|
95  *  _ __ ___  __ _    __ _| | | ___   ___   _| |_
96  * | '__/ _ \/ _` |  / _` | | |/ _ \ / __| | |  _|
97  * | | |  __/ (_| | | (_| | | | (_) | (__  | | |
98  * |_|  \___|\__, |  \__,_|_|_|\___/ \___| |_|_|
99  *            __/ |
100  *           |___/
101  **************************************************/
102
103 /**
104  * Return register requirements for an ia32 node.
105  * If the node returns a tuple (mode_T) then the proj's
106  * will be asked for this information.
107  */
108 static const arch_register_req_t *ia32_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos) {
109         const ia32_irn_ops_t      *ops = self;
110         const ia32_register_req_t *irn_req;
111         long                       node_pos = pos == -1 ? 0 : pos;
112         ir_mode                   *mode     = is_Block(irn) ? NULL : get_irn_mode(irn);
113         FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
114
115         if (is_Block(irn) || mode == mode_M || mode == mode_X) {
116                 DBG((mod, LEVEL_1, "ignoring Block, mode_M, mode_X node %+F\n", irn));
117                 return NULL;
118         }
119
120         if (mode == mode_T && pos < 0) {
121                 DBG((mod, LEVEL_1, "ignoring request OUT requirements for node %+F\n", irn));
122                 return NULL;
123         }
124
125         DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
126
127         if (is_Proj(irn)) {
128                 if(pos >= 0) {
129                         DBG((mod, LEVEL_1, "ignoring request IN requirements for node %+F\n", irn));
130                         return NULL;
131                 }
132
133                 if (pos == -1) {
134                         node_pos = ia32_translate_proj_pos(irn);
135                 }
136                 else {
137                         node_pos = pos;
138                 }
139
140                 irn = skip_Proj(irn);
141
142                 DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
143         }
144
145         if (is_ia32_irn(irn)) {
146                 if (pos >= 0) {
147                         irn_req = get_ia32_in_req(irn, pos);
148                 }
149                 else {
150                         irn_req = get_ia32_out_req(irn, node_pos);
151                 }
152
153                 DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
154
155                 memcpy(req, &(irn_req->req), sizeof(*req));
156
157                 if (arch_register_req_is(&(irn_req->req), should_be_same)) {
158                         assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
159                         req->other_same = get_irn_n(irn, irn_req->same_pos);
160                 }
161
162                 if (arch_register_req_is(&(irn_req->req), should_be_different)) {
163                         assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
164                         req->other_different = get_irn_n(irn, irn_req->different_pos);
165                 }
166         }
167         else {
168                 /* treat Unknowns like Const with default requirements */
169                 if (is_Unknown(irn)) {
170                         DB((mod, LEVEL_1, "returning UKNWN reqs for %+F\n", irn));
171                         if (mode_is_float(mode)) {
172                                 if (USE_SSE2(ops->cg))
173                                         memcpy(req, &(ia32_default_req_ia32_xmm_xmm_UKNWN), sizeof(*req));
174                                 else
175                                         memcpy(req, &(ia32_default_req_ia32_vfp_vfp_UKNWN), sizeof(*req));
176                         }
177                         else if (mode_is_int(mode) || mode_is_reference(mode))
178                                 memcpy(req, &(ia32_default_req_ia32_gp_gp_UKNWN), sizeof(*req));
179                         else if (mode == mode_T || mode == mode_M) {
180                                 DBG((mod, LEVEL_1, "ignoring Unknown node %+F\n", irn));
181                                 return NULL;
182                         }
183                         else
184                                 assert(0 && "unsupported Unknown-Mode");
185                 }
186                 else {
187                         DB((mod, LEVEL_1, "returning NULL for %+F (not ia32)\n", irn));
188                         req = NULL;
189                 }
190         }
191
192         return req;
193 }
194
195 static void ia32_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
196         int                   pos = 0;
197         const ia32_irn_ops_t *ops = self;
198
199         if (get_irn_mode(irn) == mode_X) {
200                 return;
201         }
202
203         DBG((ops->cg->mod, LEVEL_1, "ia32 assigned register %s to node %+F\n", reg->name, irn));
204
205         if (is_Proj(irn)) {
206                 pos = ia32_translate_proj_pos(irn);
207                 irn = skip_Proj(irn);
208         }
209
210         if (is_ia32_irn(irn)) {
211                 const arch_register_t **slots;
212
213                 slots      = get_ia32_slots(irn);
214                 slots[pos] = reg;
215         }
216         else {
217                 ia32_set_firm_reg(irn, reg, cur_reg_set);
218         }
219 }
220
221 static const arch_register_t *ia32_get_irn_reg(const void *self, const ir_node *irn) {
222         int pos = 0;
223         const arch_register_t *reg = NULL;
224
225         if (is_Proj(irn)) {
226
227                 if (get_irn_mode(irn) == mode_X) {
228                         return NULL;
229                 }
230
231                 pos = ia32_translate_proj_pos(irn);
232                 irn = skip_Proj(irn);
233         }
234
235         if (is_ia32_irn(irn)) {
236                 const arch_register_t **slots;
237                 slots = get_ia32_slots(irn);
238                 reg   = slots[pos];
239         }
240         else {
241                 reg = ia32_get_firm_reg(irn, cur_reg_set);
242         }
243
244         return reg;
245 }
246
247 static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
248         arch_irn_class_t classification = arch_irn_class_normal;
249
250         irn = skip_Proj(irn);
251
252         if (is_cfop(irn))
253                 classification |= arch_irn_class_branch;
254
255         if (! is_ia32_irn(irn))
256                 return classification & ~arch_irn_class_normal;
257
258         if (is_ia32_Cnst(irn))
259                 classification |= arch_irn_class_const;
260
261         if (is_ia32_Ld(irn))
262                 classification |= arch_irn_class_load;
263
264         if (is_ia32_St(irn) || is_ia32_Store8Bit(irn))
265                 classification |= arch_irn_class_store;
266
267         if (is_ia32_got_reload(irn))
268                 classification |= arch_irn_class_reload;
269
270         return classification;
271 }
272
273 static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
274
275         if(is_Proj(irn)) {
276                 ir_node *pred = get_Proj_pred(irn);
277                 int ia32_op   = get_ia32_irn_opcode(pred);
278                 long proj     = get_Proj_proj(irn);
279                 if (iro_ia32_Push == ia32_op && proj == pn_ia32_Push_stack) {
280                         /* Push modifies always ESP, this cannot be changed */
281                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
282                 }
283                 if (iro_ia32_Pop == ia32_op && proj == pn_ia32_Pop_stack) {
284                         /* Pop modifies always ESP, this cannot be changed */
285                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
286                 }
287                 if (iro_ia32_AddSP == ia32_op && proj == pn_ia32_AddSP_stack) {
288                         /* AddSP modifies always ESP, this cannot be changed */
289                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
290                 }
291                 if (iro_ia32_SubSP == ia32_op && proj == pn_ia32_SubSP_stack) {
292                         /* SubSP modifies always ESP, this cannot be changed */
293                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
294                 }
295         }
296
297         irn = skip_Proj(irn);
298         if (is_ia32_irn(irn))
299                 return get_ia32_flags(irn);
300         else {
301                 if (is_Unknown(irn))
302                         return arch_irn_flags_ignore;
303                 return 0;
304         }
305 }
306
307 /**
308  * The IA32 ABI callback object.
309  */
310 typedef struct {
311         be_abi_call_flags_bits_t flags;  /**< The call flags. */
312         const arch_isa_t *isa;           /**< The ISA handle. */
313         const arch_env_t *aenv;          /**< The architecture environment. */
314         ir_graph *irg;                   /**< The associated graph. */
315 } ia32_abi_env_t;
316
317 static entity *ia32_get_frame_entity(const void *self, const ir_node *irn) {
318         return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL;
319 }
320
321 static void ia32_set_frame_entity(const void *self, ir_node *irn, entity *ent) {
322         set_ia32_frame_ent(irn, ent);
323 }
324
325 static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) {
326         char buf[64];
327         const ia32_irn_ops_t *ops = self;
328
329         if (get_ia32_frame_ent(irn)) {
330                 ia32_am_flavour_t am_flav = get_ia32_am_flavour(irn);
331
332                 if(is_ia32_Pop(irn)) {
333                         int omit_fp = be_abi_omit_fp(ops->cg->birg->abi);
334                         if (omit_fp) {
335                                 /* Pop nodes modify the stack pointer before calculating the destination
336                                  * address, so fix this here
337                                  */
338                                 bias -= 4;
339                         }
340                 }
341
342                 DBG((ops->cg->mod, LEVEL_1, "stack biased %+F with %d\n", irn, bias));
343
344                 snprintf(buf, sizeof(buf), "%d", bias);
345
346                 if (get_ia32_op_type(irn) == ia32_Normal) {
347                         set_ia32_cnst(irn, buf);
348                 } else {
349                         add_ia32_am_offs(irn, buf);
350                         am_flav |= ia32_O;
351                         set_ia32_am_flavour(irn, am_flav);
352                 }
353         }
354 }
355
356 static int ia32_get_sp_bias(const void *self, const ir_node *irn) {
357         if(is_Proj(irn)) {
358                 long proj = get_Proj_proj(irn);
359                 ir_node *pred = get_Proj_pred(irn);
360
361                 if (proj == pn_ia32_Push_stack && is_ia32_Push(pred))
362                         return 4;
363                 if (proj == pn_ia32_Pop_stack && is_ia32_Pop(pred))
364                         return -4;
365         }
366
367         return 0;
368 }
369
370 /**
371  * Put all registers which are saved by the prologue/epilogue in a set.
372  *
373  * @param self  The callback object.
374  * @param s     The result set.
375  */
376 static void ia32_abi_dont_save_regs(void *self, pset *s)
377 {
378         ia32_abi_env_t *env = self;
379         if(env->flags.try_omit_fp)
380                 pset_insert_ptr(s, env->isa->bp);
381 }
382
383 /**
384  * Generate the routine prologue.
385  *
386  * @param self    The callback object.
387  * @param mem     A pointer to the mem node. Update this if you define new memory.
388  * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
389  *
390  * @return        The register which shall be used as a stack frame base.
391  *
392  * All nodes which define registers in @p reg_map must keep @p reg_map current.
393  */
394 static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
395 {
396         ia32_abi_env_t *env = self;
397
398         if (! env->flags.try_omit_fp) {
399                 ir_node *bl      = get_irg_start_block(env->irg);
400                 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
401                 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
402                 ir_node *noreg = be_abi_reg_map_get(reg_map, &ia32_gp_regs[REG_GP_NOREG]);
403                 ir_node *push;
404
405                 /* push ebp */
406                 push    = new_rd_ia32_Push(NULL, env->irg, bl, noreg, noreg, curr_bp, curr_sp, *mem);
407                 curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
408                 *mem    = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
409
410                 /* the push must have SP out register */
411                 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
412                 set_ia32_flags(push, arch_irn_flags_ignore);
413
414                 /* move esp to ebp */
415                 curr_bp  = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
416                 be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
417                 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
418                 be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
419
420                 /* beware: the copy must be done before any other sp use */
421                 curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
422                 be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
423                 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
424                 be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
425
426                 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
427                 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
428
429                 return env->isa->bp;
430         }
431
432         return env->isa->sp;
433 }
434
435 /**
436  * Generate the routine epilogue.
437  * @param self    The callback object.
438  * @param bl      The block for the epilog
439  * @param mem     A pointer to the mem node. Update this if you define new memory.
440  * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
441  * @return        The register which shall be used as a stack frame base.
442  *
443  * All nodes which define registers in @p reg_map must keep @p reg_map current.
444  */
445 static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
446 {
447         ia32_abi_env_t *env     = self;
448         ir_node        *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
449         ir_node        *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
450
451         if (env->flags.try_omit_fp) {
452                 /* simply remove the stack frame here */
453                 curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK);
454                 add_irn_dep(curr_sp, *mem);
455         }
456         else {
457                 const ia32_isa_t *isa     = (ia32_isa_t *)env->isa;
458                 ir_mode          *mode_bp = env->isa->bp->reg_class->mode;
459
460                 /* gcc always emits a leave at the end of a routine */
461                 if (1 || ARCH_AMD(isa->opt_arch)) {
462                         ir_node *leave;
463
464                         /* leave */
465                         leave   = new_rd_ia32_Leave(NULL, env->irg, bl, curr_sp, curr_bp);
466                         set_ia32_flags(leave, arch_irn_flags_ignore);
467                         curr_bp = new_r_Proj(current_ir_graph, bl, leave, mode_bp, pn_ia32_Leave_frame);
468                         curr_sp = new_r_Proj(current_ir_graph, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
469                         *mem    = new_r_Proj(current_ir_graph, bl, leave, mode_M, pn_ia32_Leave_M);
470                 }
471                 else {
472                         ir_node *noreg = be_abi_reg_map_get(reg_map, &ia32_gp_regs[REG_GP_NOREG]);
473                         ir_node *pop;
474
475                         /* copy ebp to esp */
476                         curr_sp = be_new_SetSP(env->isa->sp, env->irg, bl, curr_sp, curr_bp, *mem);
477
478                         /* pop ebp */
479                         pop     = new_rd_ia32_Pop(NULL, env->irg, bl, noreg, noreg, curr_sp, *mem);
480                         set_ia32_flags(pop, arch_irn_flags_ignore);
481                         curr_bp = new_r_Proj(current_ir_graph, bl, pop, mode_bp, pn_ia32_Pop_res);
482                         curr_sp = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
483                         *mem    = new_r_Proj(current_ir_graph, bl, pop, mode_M, pn_ia32_Pop_M);
484                 }
485                 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
486                 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
487         }
488
489         be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
490         be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
491 }
492
493 /**
494  * Initialize the callback object.
495  * @param call The call object.
496  * @param aenv The architecture environment.
497  * @param irg  The graph with the method.
498  * @return     Some pointer. This pointer is passed to all other callback functions as self object.
499  */
500 static void *ia32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg)
501 {
502         ia32_abi_env_t *env    = xmalloc(sizeof(env[0]));
503         be_abi_call_flags_t fl = be_abi_call_get_flags(call);
504         env->flags = fl.bits;
505         env->irg   = irg;
506         env->aenv  = aenv;
507         env->isa   = aenv->isa;
508         return env;
509 }
510
511 /**
512  * Destroy the callback object.
513  * @param self The callback object.
514  */
515 static void ia32_abi_done(void *self) {
516         free(self);
517 }
518
519 /**
520  * Produces the type which sits between the stack args and the locals on the stack.
521  * it will contain the return address and space to store the old base pointer.
522  * @return The Firm type modeling the ABI between type.
523  */
524 static ir_type *ia32_abi_get_between_type(void *self)
525 {
526 #define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
527         static ir_type *omit_fp_between_type = NULL;
528         static ir_type *between_type         = NULL;
529
530         ia32_abi_env_t *env = self;
531
532         if ( !between_type) {
533                 entity *old_bp_ent;
534                 entity *ret_addr_ent;
535                 entity *omit_fp_ret_addr_ent;
536
537                 ir_type *old_bp_type   = new_type_primitive(IDENT("bp"), mode_P);
538                 ir_type *ret_addr_type = new_type_primitive(IDENT("return_addr"), mode_P);
539
540                 between_type           = new_type_struct(IDENT("ia32_between_type"));
541                 old_bp_ent             = new_entity(between_type, IDENT("old_bp"), old_bp_type);
542                 ret_addr_ent           = new_entity(between_type, IDENT("ret_addr"), ret_addr_type);
543
544                 set_entity_offset_bytes(old_bp_ent, 0);
545                 set_entity_offset_bytes(ret_addr_ent, get_type_size_bytes(old_bp_type));
546                 set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
547                 set_type_state(between_type, layout_fixed);
548
549                 omit_fp_between_type = new_type_struct(IDENT("ia32_between_type_omit_fp"));
550                 omit_fp_ret_addr_ent = new_entity(omit_fp_between_type, IDENT("ret_addr"), ret_addr_type);
551
552                 set_entity_offset_bytes(omit_fp_ret_addr_ent, 0);
553                 set_type_size_bytes(omit_fp_between_type, get_type_size_bytes(ret_addr_type));
554                 set_type_state(omit_fp_between_type, layout_fixed);
555         }
556
557         return env->flags.try_omit_fp ? omit_fp_between_type : between_type;
558 #undef IDENT
559 }
560
561 /**
562  * Get the estimated cycle count for @p irn.
563  *
564  * @param self The this pointer.
565  * @param irn  The node.
566  *
567  * @return     The estimated cycle count for this operation
568  */
569 static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
570 {
571         int cost;
572         ia32_op_type_t op_tp;
573         const ia32_irn_ops_t *ops = self;
574
575         if (is_Proj(irn))
576           return 0;
577
578         assert(is_ia32_irn(irn));
579
580         cost  = get_ia32_latency(irn);
581         op_tp = get_ia32_op_type(irn);
582
583         if (is_ia32_CopyB(irn)) {
584                 cost = 250;
585                 if (ARCH_INTEL(ops->cg->arch))
586                         cost += 150;
587         }
588         else if (is_ia32_CopyB_i(irn)) {
589                 int size = get_tarval_long(get_ia32_Immop_tarval(irn));
590                 cost     = 20 + (int)ceil((4/3) * size);
591                 if (ARCH_INTEL(ops->cg->arch))
592                         cost += 150;
593         }
594         /* in case of address mode operations add additional cycles */
595         else if (op_tp == ia32_AddrModeD || op_tp == ia32_AddrModeS) {
596                 /*
597                         In case of stack access add 5 cycles (we assume stack is in cache),
598                         other memory operations cost 20 cycles.
599                 */
600                 cost += is_ia32_use_frame(irn) ? 5 : 20;
601         }
602
603         return cost;
604 }
605
606 /**
607  * Returns the inverse operation if @p irn, recalculating the argument at position @p i.
608  *
609  * @param irn       The original operation
610  * @param i         Index of the argument we want the inverse operation to yield
611  * @param inverse   struct to be filled with the resulting inverse op
612  * @param obstack   The obstack to use for allocation of the returned nodes array
613  * @return          The inverse operation or NULL if operation invertible
614  */
615 static arch_inverse_t *ia32_get_inverse(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst) {
616         ir_graph *irg;
617         ir_mode  *mode;
618         ir_node  *block, *noreg, *nomem;
619         int      pnc;
620
621         /* we cannot invert non-ia32 irns */
622         if (! is_ia32_irn(irn))
623                 return NULL;
624
625         /* operand must always be a real operand (not base, index or mem) */
626         if (i != 2 && i != 3)
627                 return NULL;
628
629         /* we don't invert address mode operations */
630         if (get_ia32_op_type(irn) != ia32_Normal)
631                 return NULL;
632
633         irg   = get_irn_irg(irn);
634         block = get_nodes_block(irn);
635         mode  = get_ia32_res_mode(irn);
636         noreg = get_irn_n(irn, 0);
637         nomem = new_r_NoMem(irg);
638
639         /* initialize structure */
640         inverse->nodes = obstack_alloc(obst, 2 * sizeof(inverse->nodes[0]));
641         inverse->costs = 0;
642         inverse->n     = 2;
643
644         switch (get_ia32_irn_opcode(irn)) {
645                 case iro_ia32_Add:
646                         if (get_ia32_immop_type(irn) == ia32_ImmConst) {
647                                 /* we have an add with a const here */
648                                 /* invers == add with negated const */
649                                 inverse->nodes[0] = new_rd_ia32_Add(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
650                                 pnc               = pn_ia32_Add_res;
651                                 inverse->costs   += 1;
652                                 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
653                                 set_ia32_Immop_tarval(inverse->nodes[0], tarval_neg(get_ia32_Immop_tarval(irn)));
654                                 set_ia32_commutative(inverse->nodes[0]);
655                         }
656                         else if (get_ia32_immop_type(irn) == ia32_ImmSymConst) {
657                                 /* we have an add with a symconst here */
658                                 /* invers == sub with const */
659                                 inverse->nodes[0] = new_rd_ia32_Sub(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
660                                 pnc               = pn_ia32_Sub_res;
661                                 inverse->costs   += 2;
662                                 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
663                         }
664                         else {
665                                 /* normal add: inverse == sub */
666                                 ir_node *proj = ia32_get_res_proj(irn);
667                                 assert(proj);
668
669                                 inverse->nodes[0] = new_rd_ia32_Sub(NULL, irg, block, noreg, noreg, proj, get_irn_n(irn, i ^ 1), nomem);
670                                 pnc               = pn_ia32_Sub_res;
671                                 inverse->costs   += 2;
672                         }
673                         break;
674                 case iro_ia32_Sub:
675                         if (get_ia32_immop_type(irn) != ia32_ImmNone) {
676                                 /* we have a sub with a const/symconst here */
677                                 /* invers == add with this const */
678                                 inverse->nodes[0] = new_rd_ia32_Add(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
679                                 pnc               = pn_ia32_Add_res;
680                                 inverse->costs   += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
681                                 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
682                         }
683                         else {
684                                 /* normal sub */
685                                 ir_node *proj = ia32_get_res_proj(irn);
686                                 assert(proj);
687
688                                 if (i == 2) {
689                                         inverse->nodes[0] = new_rd_ia32_Add(NULL, irg, block, noreg, noreg, proj, get_irn_n(irn, 3), nomem);
690                                 }
691                                 else {
692                                         inverse->nodes[0] = new_rd_ia32_Sub(NULL, irg, block, noreg, noreg, get_irn_n(irn, 2), proj, nomem);
693                                 }
694                                 pnc             = pn_ia32_Sub_res;
695                                 inverse->costs += 1;
696                         }
697                         break;
698                 case iro_ia32_Eor:
699                         if (get_ia32_immop_type(irn) != ia32_ImmNone) {
700                                 /* xor with const: inverse = xor */
701                                 inverse->nodes[0] = new_rd_ia32_Eor(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
702                                 pnc               = pn_ia32_Eor_res;
703                                 inverse->costs   += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
704                                 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
705                         }
706                         else {
707                                 /* normal xor */
708                                 inverse->nodes[0] = new_rd_ia32_Eor(NULL, irg, block, noreg, noreg, (ir_node *)irn, get_irn_n(irn, i), nomem);
709                                 pnc               = pn_ia32_Eor_res;
710                                 inverse->costs   += 1;
711                         }
712                         break;
713                 case iro_ia32_Not: {
714                         ir_node *proj = ia32_get_res_proj(irn);
715                         assert(proj);
716
717                         inverse->nodes[0] = new_rd_ia32_Not(NULL, irg, block, noreg, noreg, proj, nomem);
718                         pnc = pn_ia32_Not_res;
719                         inverse->costs   += 1;
720                         break;
721                 }
722                 case iro_ia32_Minus: {
723                         ir_node *proj = ia32_get_res_proj(irn);
724                         assert(proj);
725
726                         inverse->nodes[0] = new_rd_ia32_Minus(NULL, irg, block, noreg, noreg, proj, nomem);
727                         pnc               = pn_ia32_Minus_res;
728                         inverse->costs   += 1;
729                         break;
730                 }
731                 default:
732                         /* inverse operation not supported */
733                         return NULL;
734         }
735
736         set_ia32_res_mode(inverse->nodes[0], mode);
737         inverse->nodes[1] = new_r_Proj(irg, block, inverse->nodes[0], mode, pnc);
738
739         return inverse;
740 }
741
742 /**
743  * Check if irn can load it's operand at position i from memory (source addressmode).
744  * @param self   Pointer to irn ops itself
745  * @param irn    The irn to be checked
746  * @param i      The operands position
747  * @return Non-Zero if operand can be loaded
748  */
749 static int ia32_possible_memory_operand(const void *self, const ir_node *irn, unsigned int i) {
750         if (! is_ia32_irn(irn)                            ||  /* must be an ia32 irn */
751                 get_irn_arity(irn) != 5                       ||  /* must be a binary operation */
752                 get_ia32_op_type(irn) != ia32_Normal          ||  /* must not already be a addressmode irn */
753                 ! (get_ia32_am_support(irn) & ia32_am_Source) ||  /* must be capable of source addressmode */
754                 (i != 2 && i != 3)                            ||  /* a "real" operand position must be requested */
755                 (i == 2 && ! is_ia32_commutative(irn))        ||  /* if first operand requested irn must be commutative */
756                 is_ia32_use_frame(irn))                           /* must not already use frame */
757                 return 0;
758
759         return 1;
760 }
761
762 static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node *spill, unsigned int i) {
763         const ia32_irn_ops_t *ops = self;
764         ia32_code_gen_t      *cg  = ops->cg;
765
766         assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
767
768         if (i == 2) {
769                 ir_node *tmp = get_irn_n(irn, 3);
770                 set_irn_n(irn, 3, get_irn_n(irn, 2));
771                 set_irn_n(irn, 2, tmp);
772         }
773
774         set_ia32_am_support(irn, ia32_am_Source);
775         set_ia32_op_type(irn, ia32_AddrModeS);
776         set_ia32_am_flavour(irn, ia32_B);
777         set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i)));
778         set_ia32_use_frame(irn);
779         set_ia32_got_reload(irn);
780
781         set_irn_n(irn, 0, get_irg_frame(get_irn_irg(irn)));
782         set_irn_n(irn, 4, spill);
783
784         /*
785                 Input at position one is index register, which is NoReg.
786                 We would need cg object to get a real noreg, but we cannot
787                 access it from here.
788          */
789         set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
790
791         //FIXME DBG_OPT_AM_S(reload, irn);
792 }
793
794 static const be_abi_callbacks_t ia32_abi_callbacks = {
795         ia32_abi_init,
796         ia32_abi_done,
797         ia32_abi_get_between_type,
798         ia32_abi_dont_save_regs,
799         ia32_abi_prologue,
800         ia32_abi_epilogue,
801 };
802
803 /* fill register allocator interface */
804
805 static const arch_irn_ops_if_t ia32_irn_ops_if = {
806         ia32_get_irn_reg_req,
807         ia32_set_irn_reg,
808         ia32_get_irn_reg,
809         ia32_classify,
810         ia32_get_flags,
811         ia32_get_frame_entity,
812         ia32_set_frame_entity,
813         ia32_set_frame_offset,
814         ia32_get_sp_bias,
815         ia32_get_inverse,
816         ia32_get_op_estimated_cost,
817         ia32_possible_memory_operand,
818         ia32_perform_memory_operand,
819 };
820
821 ia32_irn_ops_t ia32_irn_ops = {
822         &ia32_irn_ops_if,
823         NULL
824 };
825
826
827
828 /**************************************************
829  *                _                         _  __
830  *               | |                       (_)/ _|
831  *   ___ ___   __| | ___  __ _  ___ _ __    _| |_
832  *  / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \  | |  _|
833  * | (_| (_) | (_| |  __/ (_| |  __/ | | | | | |
834  *  \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
835  *                        __/ |
836  *                       |___/
837  **************************************************/
838
839 static void ia32_kill_convs(ia32_code_gen_t *cg) {
840         ir_node *irn;
841
842         /* BEWARE: the Projs are inserted in the set */
843         foreach_nodeset(cg->kill_conv, irn) {
844                 ir_node *in = get_irn_n(get_Proj_pred(irn), 2);
845                 edges_reroute(irn, in, cg->birg->irg);
846         }
847 }
848
849 /**
850  * Transform the Thread Local Store base.
851  */
852 static void transform_tls(ir_graph *irg) {
853         ir_node *irn = get_irg_tls(irg);
854
855         if (irn) {
856                 dbg_info *dbg = get_irn_dbg_info(irn);
857                 ir_node  *blk = get_nodes_block(irn);
858                 ir_node  *newn;
859                 newn = new_rd_ia32_LdTls(dbg, irg, blk, get_irn_mode(irn));
860
861                 exchange(irn, newn);
862         }
863 }
864
865 /**
866  * Transforms the standard firm graph into
867  * an ia32 firm graph
868  */
869 static void ia32_prepare_graph(void *self) {
870         ia32_code_gen_t *cg = self;
871         dom_front_info_t *dom;
872         DEBUG_ONLY(firm_dbg_module_t *old_mod = cg->mod;)
873
874         FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.transform");
875
876         /* 1st: transform constants and psi condition trees */
877         ia32_pre_transform_phase(cg);
878
879         /* 2nd: transform all remaining nodes */
880         ia32_register_transformers();
881         dom = be_compute_dominance_frontiers(cg->irg);
882
883         cg->kill_conv = new_nodeset(5);
884         transform_tls(cg->irg);
885         irg_walk_blkwise_graph(cg->irg, NULL, ia32_transform_node, cg);
886         ia32_kill_convs(cg);
887         del_nodeset(cg->kill_conv);
888
889         be_free_dominance_frontiers(dom);
890
891         if (cg->dump)
892                 be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
893
894         /* 3rd: optimize address mode */
895         FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.am");
896         ia32_optimize_addressmode(cg);
897
898         if (cg->dump)
899                 be_dump(cg->irg, "-am", dump_ir_block_graph_sched);
900
901         DEBUG_ONLY(cg->mod = old_mod;)
902 }
903
904 /**
905  * Dummy functions for hooks we don't need but which must be filled.
906  */
907 static void ia32_before_sched(void *self) {
908 }
909
910 static void remove_unused_nodes(ir_node *irn, bitset_t *already_visited) {
911         int i, arity;
912         ir_mode *mode;
913         ir_node *mem_proj = NULL;
914
915         if (is_Block(irn))
916                 return;
917
918         mode = get_irn_mode(irn);
919
920         /* check if we already saw this node or the node has more than one user */
921         if (bitset_contains_irn(already_visited, irn) || get_irn_n_edges(irn) > 1) {
922                 return;
923         };
924
925         /* mark irn visited */
926         bitset_add_irn(already_visited, irn);
927
928         /* non-Tuple nodes with one user: ok, return */
929         if (get_irn_n_edges(irn) >= 1 && mode != mode_T) {
930                 return;
931         }
932
933         /* tuple node has one user which is not the mem proj-> ok */
934         if (mode == mode_T && get_irn_n_edges(irn) == 1) {
935                 mem_proj = ia32_get_proj_for_mode(irn, mode_M);
936                 if (mem_proj == NULL) {
937                         return;
938                 }
939         }
940
941         arity = get_irn_arity(irn);
942         for (i = 0; i < arity; ++i) {
943                 ir_node *pred = get_irn_n(irn, i);
944
945                 /* do not follow memory edges or we will accidentally remove stores */
946                 if (get_irn_mode(pred) == mode_M) {
947                         if(mem_proj != NULL) {
948                                 edges_reroute(mem_proj, pred, get_irn_irg(mem_proj));
949                                 mem_proj = NULL;
950                         }
951                         continue;
952                 }
953
954                 set_irn_n(irn, i, new_Bad());
955
956                 /*
957                         The current node is about to be removed: if the predecessor
958                         has only this node as user, it need to be removed as well.
959                 */
960                 if (get_irn_n_edges(pred) <= 1)
961                         remove_unused_nodes(pred, already_visited);
962         }
963
964         // we need to set the presd to Bad again to also get the memory edges
965         arity = get_irn_arity(irn);
966         for (i = 0; i < arity; ++i) {
967                 set_irn_n(irn, i, new_Bad());
968         }
969
970         if (sched_is_scheduled(irn)) {
971                 sched_remove(irn);
972         }
973 }
974
975 static void remove_unused_loads_walker(ir_node *irn, void *env) {
976         bitset_t *already_visited = env;
977         if (is_ia32_Ld(irn) && ! bitset_contains_irn(already_visited, irn))
978                 remove_unused_nodes(irn, env);
979 }
980
981 /**
982  * Called before the register allocator.
983  * Calculate a block schedule here. We need it for the x87
984  * simulator and the emitter.
985  */
986 static void ia32_before_ra(void *self) {
987         ia32_code_gen_t *cg              = self;
988         bitset_t        *already_visited = bitset_irg_alloca(cg->irg);
989
990         /*
991                 Handle special case:
992                 There are sometimes unused loads, only pinned by memory.
993                 We need to remove those Loads and all other nodes which won't be used
994                 after removing the Load from schedule.
995         */
996         irg_walk_graph(cg->irg, NULL, remove_unused_loads_walker, already_visited);
997 }
998
999
1000 /**
1001  * Transforms a be node into a Load.
1002  */
1003 static void transform_to_Load(ia32_transform_env_t *env) {
1004         ir_node *irn         = env->irn;
1005         entity  *ent         = be_get_frame_entity(irn);
1006         ir_mode *mode        = env->mode;
1007         ir_node *noreg       = ia32_new_NoReg_gp(env->cg);
1008         ir_node *nomem       = new_rd_NoMem(env->irg);
1009         ir_node *sched_point = NULL;
1010         ir_node *ptr         = get_irn_n(irn, 0);
1011         ir_node *mem         = be_is_Reload(irn) ? get_irn_n(irn, 1) : nomem;
1012         ir_node *new_op, *proj;
1013         const arch_register_t *reg;
1014
1015         if (sched_is_scheduled(irn)) {
1016                 sched_point = sched_prev(irn);
1017         }
1018
1019         if (mode_is_float(mode)) {
1020                 if (USE_SSE2(env->cg))
1021                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
1022                 else
1023                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
1024         }
1025         else {
1026                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
1027         }
1028
1029         set_ia32_am_support(new_op, ia32_am_Source);
1030         set_ia32_op_type(new_op, ia32_AddrModeS);
1031         set_ia32_am_flavour(new_op, ia32_B);
1032         set_ia32_ls_mode(new_op, mode);
1033         set_ia32_frame_ent(new_op, ent);
1034         set_ia32_use_frame(new_op);
1035
1036         DBG_OPT_RELOAD2LD(irn, new_op);
1037
1038         proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_Load_res);
1039
1040         if (sched_point) {
1041                 sched_add_after(sched_point, new_op);
1042                 sched_add_after(new_op, proj);
1043
1044                 sched_remove(irn);
1045         }
1046
1047         /* copy the register from the old node to the new Load */
1048         reg = arch_get_irn_register(env->cg->arch_env, irn);
1049         arch_set_irn_register(env->cg->arch_env, new_op, reg);
1050
1051         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, irn));
1052
1053         exchange(irn, proj);
1054 }
1055
1056 /**
1057  * Transforms a be node into a Store.
1058  */
1059 static void transform_to_Store(ia32_transform_env_t *env) {
1060         ir_node *irn   = env->irn;
1061         entity  *ent   = be_get_frame_entity(irn);
1062         ir_mode *mode  = env->mode;
1063         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1064         ir_node *nomem = new_rd_NoMem(env->irg);
1065         ir_node *ptr   = get_irn_n(irn, 0);
1066         ir_node *val   = get_irn_n(irn, 1);
1067         ir_node *new_op, *proj;
1068         ir_node *sched_point = NULL;
1069
1070         if (sched_is_scheduled(irn)) {
1071                 sched_point = sched_prev(irn);
1072         }
1073
1074         if (mode_is_float(mode)) {
1075                 if (USE_SSE2(env->cg))
1076                         new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1077                 else
1078                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1079         }
1080         else if (get_mode_size_bits(mode) == 8) {
1081                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1082         }
1083         else {
1084                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1085         }
1086
1087         set_ia32_am_support(new_op, ia32_am_Dest);
1088         set_ia32_op_type(new_op, ia32_AddrModeD);
1089         set_ia32_am_flavour(new_op, ia32_B);
1090         set_ia32_ls_mode(new_op, mode);
1091         set_ia32_frame_ent(new_op, ent);
1092         set_ia32_use_frame(new_op);
1093
1094         DBG_OPT_SPILL2ST(irn, new_op);
1095
1096         proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode_M, pn_ia32_Store_M);
1097
1098         if (sched_point) {
1099                 sched_add_after(sched_point, new_op);
1100                 sched_remove(irn);
1101         }
1102
1103         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, irn));
1104
1105         exchange(irn, proj);
1106 }
1107
1108 static ir_node *create_push(ia32_transform_env_t *env, ir_node *schedpoint, ir_node *sp, ir_node *mem, entity *ent) {
1109         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1110         ir_node *frame = get_irg_frame(env->irg);
1111
1112         ir_node *push = new_rd_ia32_Push(env->dbg, env->irg, env->block, frame, noreg, noreg, sp, mem);
1113
1114         set_ia32_frame_ent(push, ent);
1115         set_ia32_use_frame(push);
1116         set_ia32_op_type(push, ia32_AddrModeS);
1117         set_ia32_am_flavour(push, ia32_B);
1118         set_ia32_ls_mode(push, mode_Is);
1119
1120         sched_add_before(schedpoint, push);
1121         return push;
1122 }
1123
1124 static ir_node *create_pop(ia32_transform_env_t *env, ir_node *schedpoint, ir_node *sp, entity *ent) {
1125         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1126         ir_node *frame = get_irg_frame(env->irg);
1127
1128         ir_node *pop = new_rd_ia32_Pop(env->dbg, env->irg, env->block, frame, noreg, sp, new_NoMem());
1129
1130         set_ia32_frame_ent(pop, ent);
1131         set_ia32_use_frame(pop);
1132         set_ia32_op_type(pop, ia32_AddrModeD);
1133         set_ia32_am_flavour(pop, ia32_B);
1134         set_ia32_ls_mode(pop, mode_Is);
1135
1136         sched_add_before(schedpoint, pop);
1137
1138         return pop;
1139 }
1140
1141 static ir_node* create_spproj(ia32_transform_env_t *env, ir_node *pred, int pos, ir_node *schedpoint) {
1142         ir_mode *spmode = mode_Iu;
1143         const arch_register_t *spreg = &ia32_gp_regs[REG_ESP];
1144         ir_node *sp;
1145
1146         sp = new_rd_Proj(env->dbg, env->irg, env->block, pred, spmode, pos);
1147         arch_set_irn_register(env->cg->arch_env, sp, spreg);
1148         sched_add_before(schedpoint, sp);
1149
1150         return sp;
1151 }
1152
1153 /**
1154  * Transform memperm, currently we do this the ugly way and produce
1155  * push/pop into/from memory cascades. This is possible without using
1156  * any registers.
1157  */
1158 static void transform_MemPerm(ia32_transform_env_t *env) {
1159         ir_node *node = env->irn;
1160         int i, arity;
1161         ir_node *sp = be_abi_get_ignore_irn(env->cg->birg->abi, &ia32_gp_regs[REG_ESP]);
1162         const ir_edge_t *edge;
1163         const ir_edge_t *next;
1164         ir_node **pops;
1165
1166         arity = be_get_MemPerm_entity_arity(node);
1167         pops = alloca(arity * sizeof(pops[0]));
1168
1169         // create pushs
1170         for(i = 0; i < arity; ++i) {
1171                 entity *ent = be_get_MemPerm_in_entity(node, i);
1172                 ir_type *enttype = get_entity_type(ent);
1173                 int entbits = get_type_size_bits(enttype);
1174                 ir_node *mem = get_irn_n(node, i + 1);
1175                 ir_node *push;
1176
1177                 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1178
1179                 push = create_push(env, node, sp, mem, ent);
1180                 sp = create_spproj(env, push, 0, node);
1181                 if(entbits == 64) {
1182                         // add another push after the first one
1183                         push = create_push(env, node, sp, mem, ent);
1184                         add_ia32_am_offs_int(push, 4);
1185                         sp = create_spproj(env, push, 0, node);
1186                 }
1187
1188                 set_irn_n(node, i, new_Bad());
1189         }
1190
1191         // create pops
1192         for(i = arity - 1; i >= 0; --i) {
1193                 entity *ent = be_get_MemPerm_out_entity(node, i);
1194                 ir_type *enttype = get_entity_type(ent);
1195                 int entbits = get_type_size_bits(enttype);
1196
1197                 ir_node *pop;
1198
1199                 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1200
1201                 pop = create_pop(env, node, sp, ent);
1202                 if(entbits == 64) {
1203                         // add another pop after the first one
1204                         sp = create_spproj(env, pop, 1, node);
1205                         pop = create_pop(env, node, sp, ent);
1206                         add_ia32_am_offs_int(pop, 4);
1207                 }
1208                 sp = create_spproj(env, pop, 1, node);
1209
1210                 pops[i] = pop;
1211         }
1212
1213         // exchange memprojs
1214         foreach_out_edge_safe(node, edge, next) {
1215                 ir_node *proj = get_edge_src_irn(edge);
1216                 int p = get_Proj_proj(proj);
1217
1218                 assert(p < arity);
1219
1220                 set_Proj_pred(proj, pops[p]);
1221                 set_Proj_proj(proj, 3);
1222         }
1223
1224         // remove memperm
1225         arity = get_irn_arity(node);
1226         for(i = 0; i < arity; ++i) {
1227                 set_irn_n(node, i, new_Bad());
1228         }
1229         sched_remove(node);
1230 }
1231
1232 /**
1233  * Fix the mode of Spill/Reload
1234  */
1235 static ir_mode *fix_spill_mode(ia32_code_gen_t *cg, ir_mode *mode)
1236 {
1237         if (mode_is_float(mode)) {
1238                 if (USE_SSE2(cg))
1239                         mode = mode_D;
1240                 else
1241                         mode = mode_E;
1242         }
1243         else
1244                 mode = mode_Is;
1245         return mode;
1246 }
1247
1248 /**
1249  * Block-Walker: Calls the transform functions Spill and Reload.
1250  */
1251 static void ia32_after_ra_walker(ir_node *block, void *env) {
1252         ir_node *node, *prev;
1253         ia32_code_gen_t *cg = env;
1254         ia32_transform_env_t tenv;
1255
1256         tenv.block = block;
1257         tenv.irg   = current_ir_graph;
1258         tenv.cg    = cg;
1259         DEBUG_ONLY(tenv.mod = cg->mod;)
1260
1261         /* beware: the schedule is changed here */
1262         for (node = sched_last(block); !sched_is_begin(node); node = prev) {
1263                 prev = sched_prev(node);
1264                 if (be_is_Reload(node)) {
1265                         /* we always reload the whole register  */
1266                         tenv.dbg  = get_irn_dbg_info(node);
1267                         tenv.irn  = node;
1268                         tenv.mode = fix_spill_mode(cg, get_irn_mode(node));
1269                         transform_to_Load(&tenv);
1270                 }
1271                 else if (be_is_Spill(node)) {
1272                         ir_node *spillval = get_irn_n(node, be_pos_Spill_val);
1273                         /* we always spill the whole register  */
1274                         tenv.dbg  = get_irn_dbg_info(node);
1275                         tenv.irn  = node;
1276                         tenv.mode = fix_spill_mode(cg, get_irn_mode(spillval));
1277                         transform_to_Store(&tenv);
1278                 }
1279                 else if(be_is_MemPerm(node)) {
1280                         tenv.dbg = get_irn_dbg_info(node);
1281                         tenv.irn = node;
1282                         transform_MemPerm(&tenv);
1283                 }
1284         }
1285 }
1286
1287 /**
1288  * We transform Spill and Reload here. This needs to be done before
1289  * stack biasing otherwise we would miss the corrected offset for these nodes.
1290  *
1291  * If x87 instruction should be emitted, run the x87 simulator and patch
1292  * the virtual instructions. This must obviously be done after register allocation.
1293  */
1294 static void ia32_after_ra(void *self) {
1295         ia32_code_gen_t *cg = self;
1296         ir_graph *irg = cg->irg;
1297
1298         irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, cg);
1299
1300         ia32_finish_irg(irg, cg);
1301 }
1302
1303 /**
1304  * Last touchups for the graph before emit
1305  */
1306 static void ia32_finish(void *self) {
1307         ia32_code_gen_t *cg = self;
1308         ir_graph        *irg = cg->irg;
1309
1310         //be_remove_empty_blocks(irg);
1311         cg->blk_sched = be_create_block_schedule(irg, cg->birg->execfreqs);
1312
1313         //cg->blk_sched = sched_create_block_schedule(cg->irg, cg->birg->execfreqs);
1314
1315         /* if we do x87 code generation, rewrite all the virtual instructions and registers */
1316         if (cg->used_fp == fp_x87 || cg->force_sim) {
1317                 x87_simulate_graph(cg->arch_env, irg, cg->blk_sched);
1318         }
1319
1320         ia32_peephole_optimization(irg, cg);
1321 }
1322
1323 /**
1324  * Emits the code, closes the output file and frees
1325  * the code generator interface.
1326  */
1327 static void ia32_codegen(void *self) {
1328         ia32_code_gen_t *cg = self;
1329         ir_graph        *irg = cg->irg;
1330
1331         ia32_gen_routine(cg->isa->out, irg, cg);
1332
1333         cur_reg_set = NULL;
1334
1335         /* remove it from the isa */
1336         cg->isa->cg = NULL;
1337
1338         /* de-allocate code generator */
1339         del_set(cg->reg_set);
1340         free(cg);
1341 }
1342
1343 static void *ia32_cg_init(const be_irg_t *birg);
1344
1345 static const arch_code_generator_if_t ia32_code_gen_if = {
1346         ia32_cg_init,
1347         NULL,                /* before abi introduce hook */
1348         ia32_prepare_graph,
1349         ia32_before_sched,   /* before scheduling hook */
1350         ia32_before_ra,      /* before register allocation hook */
1351         ia32_after_ra,       /* after register allocation hook */
1352         ia32_finish,         /* called before codegen */
1353         ia32_codegen         /* emit && done */
1354 };
1355
1356 /**
1357  * Initializes a IA32 code generator.
1358  */
1359 static void *ia32_cg_init(const be_irg_t *birg) {
1360         ia32_isa_t      *isa = (ia32_isa_t *)birg->main_env->arch_env->isa;
1361         ia32_code_gen_t *cg  = xcalloc(1, sizeof(*cg));
1362
1363         cg->impl      = &ia32_code_gen_if;
1364         cg->irg       = birg->irg;
1365         cg->reg_set   = new_set(ia32_cmp_irn_reg_assoc, 1024);
1366         cg->arch_env  = birg->main_env->arch_env;
1367         cg->isa       = isa;
1368         cg->birg      = birg;
1369         cg->blk_sched = NULL;
1370         cg->fp_to_gp  = NULL;
1371         cg->gp_to_fp  = NULL;
1372         cg->fp_kind   = isa->fp_kind;
1373         cg->used_fp   = fp_none;
1374         cg->dump      = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
1375
1376         FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.cg");
1377
1378         /* copy optimizations from isa for easier access */
1379         cg->opt      = isa->opt;
1380         cg->arch     = isa->arch;
1381         cg->opt_arch = isa->opt_arch;
1382
1383         /* enter it */
1384         isa->cg = cg;
1385
1386 #ifndef NDEBUG
1387         if (isa->name_obst_size) {
1388                 //printf("freed %d bytes from name obst\n", isa->name_obst_size);
1389                 isa->name_obst_size = 0;
1390                 obstack_free(isa->name_obst, NULL);
1391                 obstack_init(isa->name_obst);
1392         }
1393 #endif /* NDEBUG */
1394
1395         cur_reg_set = cg->reg_set;
1396
1397         ia32_irn_ops.cg = cg;
1398
1399         return (arch_code_generator_t *)cg;
1400 }
1401
1402
1403
1404 /*****************************************************************
1405  *  ____             _                  _   _____  _____
1406  * |  _ \           | |                | | |_   _|/ ____|  /\
1407  * | |_) | __ _  ___| | _____ _ __   __| |   | | | (___   /  \
1408  * |  _ < / _` |/ __| |/ / _ \ '_ \ / _` |   | |  \___ \ / /\ \
1409  * | |_) | (_| | (__|   <  __/ | | | (_| |  _| |_ ____) / ____ \
1410  * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/    \_\
1411  *
1412  *****************************************************************/
1413
1414 /**
1415  * Set output modes for GCC
1416  */
1417 static const tarval_mode_info mo_integer = {
1418         TVO_DECIMAL,
1419         NULL,
1420         NULL,
1421 };
1422
1423 /*
1424  * set the tarval output mode of all integer modes to decimal
1425  */
1426 static void set_tarval_output_modes(void)
1427 {
1428         int i;
1429
1430         for (i = get_irp_n_modes() - 1; i >= 0; --i) {
1431                 ir_mode *mode = get_irp_mode(i);
1432
1433                 if (mode_is_int(mode))
1434                         set_tarval_mode_output_option(mode, &mo_integer);
1435         }
1436 }
1437
1438
1439 /**
1440  * The template that generates a new ISA object.
1441  * Note that this template can be changed by command line
1442  * arguments.
1443  */
1444 static ia32_isa_t ia32_isa_template = {
1445         {
1446                 &ia32_isa_if,            /* isa interface implementation */
1447                 &ia32_gp_regs[REG_ESP],  /* stack pointer register */
1448                 &ia32_gp_regs[REG_EBP],  /* base pointer register */
1449                 -1,                      /* stack direction */
1450                 NULL,                    /* main environment */
1451         },
1452         NULL,                    /* 16bit register names */
1453         NULL,                    /* 8bit register names */
1454         NULL,                    /* types */
1455         NULL,                    /* tv_ents */
1456         (0                 |
1457         IA32_OPT_INCDEC    |     /* optimize add 1, sub 1 into inc/dec               default: on  */
1458         IA32_OPT_DOAM      |     /* optimize address mode                            default: on  */
1459         IA32_OPT_LEA       |     /* optimize for LEAs                                default: on  */
1460         IA32_OPT_PLACECNST |     /* place constants immediately before instructions, default: on  */
1461         IA32_OPT_IMMOPS    |     /* operations can use immediates,                   default: on  */
1462         IA32_OPT_EXTBB),         /* use extended basic block scheduling,             default: on  */
1463         arch_pentium_4,          /* instruction architecture */
1464         arch_pentium_4,          /* optimize for architecture */
1465         fp_sse2,                 /* use sse2 unit */
1466         NULL,                    /* current code generator */
1467         NULL,                    /* output file */
1468 #ifndef NDEBUG
1469         NULL,                    /* name obstack */
1470         0                        /* name obst size */
1471 #endif
1472 };
1473
1474 /**
1475  * Initializes the backend ISA.
1476  */
1477 static void *ia32_init(FILE *file_handle) {
1478         static int inited = 0;
1479         ia32_isa_t *isa;
1480
1481         if (inited)
1482                 return NULL;
1483
1484         set_tarval_output_modes();
1485
1486         isa = xmalloc(sizeof(*isa));
1487         memcpy(isa, &ia32_isa_template, sizeof(*isa));
1488
1489         ia32_register_init(isa);
1490         ia32_create_opcodes();
1491
1492         if ((ARCH_INTEL(isa->arch) && isa->arch < arch_pentium_4) ||
1493             (ARCH_AMD(isa->arch) && isa->arch < arch_athlon))
1494                 /* no SSE2 for these cpu's */
1495                 isa->fp_kind = fp_x87;
1496
1497         if (ARCH_INTEL(isa->opt_arch) && isa->opt_arch >= arch_pentium_4) {
1498                 /* Pentium 4 don't like inc and dec instructions */
1499                 isa->opt &= ~IA32_OPT_INCDEC;
1500         }
1501
1502         isa->regs_16bit = pmap_create();
1503         isa->regs_8bit  = pmap_create();
1504         isa->types      = pmap_create();
1505         isa->tv_ent     = pmap_create();
1506         isa->out        = file_handle;
1507
1508         ia32_build_16bit_reg_map(isa->regs_16bit);
1509         ia32_build_8bit_reg_map(isa->regs_8bit);
1510
1511         /* patch register names of x87 registers */
1512         if (USE_x87(isa)) {
1513                 ia32_st_regs[0].name = "st";
1514                 ia32_st_regs[1].name = "st(1)";
1515                 ia32_st_regs[2].name = "st(2)";
1516                 ia32_st_regs[3].name = "st(3)";
1517                 ia32_st_regs[4].name = "st(4)";
1518                 ia32_st_regs[5].name = "st(5)";
1519                 ia32_st_regs[6].name = "st(6)";
1520                 ia32_st_regs[7].name = "st(7)";
1521         }
1522
1523 #ifndef NDEBUG
1524         isa->name_obst = xmalloc(sizeof(*isa->name_obst));
1525         obstack_init(isa->name_obst);
1526         isa->name_obst_size = 0;
1527 #endif /* NDEBUG */
1528
1529         ia32_handle_intrinsics();
1530         ia32_switch_section(isa->out, NO_SECTION);
1531         fprintf(isa->out, "\t.intel_syntax\n");
1532
1533         /* needed for the debug support */
1534         ia32_switch_section(isa->out, SECTION_TEXT);
1535         fprintf(isa->out, ".Ltext0:\n");
1536
1537         inited = 1;
1538
1539         return isa;
1540 }
1541
1542
1543
1544 /**
1545  * Closes the output file and frees the ISA structure.
1546  */
1547 static void ia32_done(void *self) {
1548         ia32_isa_t *isa = self;
1549
1550         /* emit now all global declarations */
1551         ia32_gen_decls(isa->out, isa->arch_isa.main_env);
1552
1553         pmap_destroy(isa->regs_16bit);
1554         pmap_destroy(isa->regs_8bit);
1555         pmap_destroy(isa->tv_ent);
1556         pmap_destroy(isa->types);
1557
1558 #ifndef NDEBUG
1559         //printf("name obst size = %d bytes\n", isa->name_obst_size);
1560         obstack_free(isa->name_obst, NULL);
1561 #endif /* NDEBUG */
1562
1563         free(self);
1564 }
1565
1566
1567 /**
1568  * Return the number of register classes for this architecture.
1569  * We report always these:
1570  *  - the general purpose registers
1571  *  - the SSE floating point register set
1572  *  - the virtual floating point registers
1573  */
1574 static int ia32_get_n_reg_class(const void *self) {
1575         return 3;
1576 }
1577
1578 /**
1579  * Return the register class for index i.
1580  */
1581 static const arch_register_class_t *ia32_get_reg_class(const void *self, int i) {
1582         assert(i >= 0 && i < 3 && "Invalid ia32 register class requested.");
1583         if (i == 0)
1584                 return &ia32_reg_classes[CLASS_ia32_gp];
1585         else if (i == 1)
1586                 return &ia32_reg_classes[CLASS_ia32_xmm];
1587         else
1588                 return &ia32_reg_classes[CLASS_ia32_vfp];
1589 }
1590
1591 /**
1592  * Get the register class which shall be used to store a value of a given mode.
1593  * @param self The this pointer.
1594  * @param mode The mode in question.
1595  * @return A register class which can hold values of the given mode.
1596  */
1597 const arch_register_class_t *ia32_get_reg_class_for_mode(const void *self, const ir_mode *mode) {
1598         const ia32_isa_t *isa = self;
1599         if (mode_is_float(mode)) {
1600                 return USE_SSE2(isa) ? &ia32_reg_classes[CLASS_ia32_xmm] : &ia32_reg_classes[CLASS_ia32_vfp];
1601         }
1602         else
1603                 return &ia32_reg_classes[CLASS_ia32_gp];
1604 }
1605
1606 /**
1607  * Get the ABI restrictions for procedure calls.
1608  * @param self        The this pointer.
1609  * @param method_type The type of the method (procedure) in question.
1610  * @param abi         The abi object to be modified
1611  */
1612 static void ia32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) {
1613         const ia32_isa_t *isa = self;
1614         ir_type  *tp;
1615         ir_mode  *mode;
1616         unsigned  cc        = get_method_calling_convention(method_type);
1617         int       n         = get_method_n_params(method_type);
1618         int       biggest_n = -1;
1619         int       stack_idx = 0;
1620         int       i, ignore_1, ignore_2;
1621         ir_mode **modes;
1622         const arch_register_t *reg;
1623         be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi);
1624
1625         unsigned use_push = !IS_P6_ARCH(isa->opt_arch);
1626
1627         /* set abi flags for calls */
1628         call_flags.bits.left_to_right         = 0;  /* always last arg first on stack */
1629         call_flags.bits.store_args_sequential = use_push;
1630         /* call_flags.bits.try_omit_fp                 not changed: can handle both settings */
1631         call_flags.bits.fp_free               = 0;  /* the frame pointer is fixed in IA32 */
1632         call_flags.bits.call_has_imm          = 1;  /* IA32 calls can have immediate address */
1633
1634         /* set stack parameter passing style */
1635         be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
1636
1637         /* collect the mode for each type */
1638         modes = alloca(n * sizeof(modes[0]));
1639
1640         for (i = 0; i < n; i++) {
1641                 tp       = get_method_param_type(method_type, i);
1642                 modes[i] = get_type_mode(tp);
1643         }
1644
1645         /* set register parameters  */
1646         if (cc & cc_reg_param) {
1647                 /* determine the number of parameters passed via registers */
1648                 biggest_n = ia32_get_n_regparam_class(n, modes, &ignore_1, &ignore_2);
1649
1650                 /* loop over all parameters and set the register requirements */
1651                 for (i = 0; i <= biggest_n; i++) {
1652                         reg = ia32_get_RegParam_reg(n, modes, i, cc);
1653                         assert(reg && "kaputt");
1654                         be_abi_call_param_reg(abi, i, reg);
1655                 }
1656
1657                 stack_idx = i;
1658         }
1659
1660
1661         /* set stack parameters */
1662         for (i = stack_idx; i < n; i++) {
1663                 /* parameters on the stack are 32 bit aligned */
1664                 be_abi_call_param_stack(abi, i, 4, 0, 0);
1665         }
1666
1667
1668         /* set return registers */
1669         n = get_method_n_ress(method_type);
1670
1671         assert(n <= 2 && "more than two results not supported");
1672
1673         /* In case of 64bit returns, we will have two 32bit values */
1674         if (n == 2) {
1675                 tp   = get_method_res_type(method_type, 0);
1676                 mode = get_type_mode(tp);
1677
1678                 assert(!mode_is_float(mode) && "two FP results not supported");
1679
1680                 tp   = get_method_res_type(method_type, 1);
1681                 mode = get_type_mode(tp);
1682
1683                 assert(!mode_is_float(mode) && "mixed INT, FP results not supported");
1684
1685                 be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]);
1686                 be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]);
1687         }
1688         else if (n == 1) {
1689                 const arch_register_t *reg;
1690
1691                 tp   = get_method_res_type(method_type, 0);
1692                 assert(is_atomic_type(tp));
1693                 mode = get_type_mode(tp);
1694
1695                 reg = mode_is_float(mode) ? &ia32_vfp_regs[REG_VF0] : &ia32_gp_regs[REG_EAX];
1696
1697                 be_abi_call_res_reg(abi, 0, reg);
1698         }
1699 }
1700
1701
1702 static const void *ia32_get_irn_ops(const arch_irn_handler_t *self, const ir_node *irn) {
1703         return &ia32_irn_ops;
1704 }
1705
1706 const arch_irn_handler_t ia32_irn_handler = {
1707         ia32_get_irn_ops
1708 };
1709
1710 const arch_irn_handler_t *ia32_get_irn_handler(const void *self) {
1711         return &ia32_irn_handler;
1712 }
1713
1714 int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn) {
1715         return is_ia32_irn(irn) ? 1 : -1;
1716 }
1717
1718 /**
1719  * Initializes the code generator interface.
1720  */
1721 static const arch_code_generator_if_t *ia32_get_code_generator_if(void *self) {
1722         return &ia32_code_gen_if;
1723 }
1724
1725 /**
1726  * Returns the estimated execution time of an ia32 irn.
1727  */
1728 static sched_timestep_t ia32_sched_exectime(void *env, const ir_node *irn) {
1729         const arch_env_t *arch_env = env;
1730         return is_ia32_irn(irn) ? ia32_get_op_estimated_cost(arch_get_irn_ops(arch_env, irn), irn) : 1;
1731 }
1732
1733 list_sched_selector_t ia32_sched_selector;
1734
1735 /**
1736  * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
1737  */
1738 static const list_sched_selector_t *ia32_get_list_sched_selector(const void *self, list_sched_selector_t *selector) {
1739         memcpy(&ia32_sched_selector, selector, sizeof(ia32_sched_selector));
1740         ia32_sched_selector.exectime              = ia32_sched_exectime;
1741         ia32_sched_selector.to_appear_in_schedule = ia32_to_appear_in_schedule;
1742         return &ia32_sched_selector;
1743 }
1744
1745 /**
1746  * Returns the necessary byte alignment for storing a register of given class.
1747  */
1748 static int ia32_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) {
1749         ir_mode *mode = arch_register_class_mode(cls);
1750         int bytes     = get_mode_size_bytes(mode);
1751
1752         if (mode_is_float(mode) && bytes > 8)
1753                 return 16;
1754         return bytes;
1755 }
1756
1757 static ia32_intrinsic_env_t intrinsic_env = { NULL, NULL };
1758
1759 /**
1760  * Returns the libFirm configuration parameter for this backend.
1761  */
1762 static const backend_params *ia32_get_libfirm_params(void) {
1763         static const arch_dep_params_t ad = {
1764                 1, /* also use subs */
1765                 4, /* maximum shifts */
1766                 31, /* maximum shift amount */
1767
1768                 1, /* allow Mulhs */
1769                 1, /* allow Mulus */
1770                 32  /* Mulh allowed up to 32 bit */
1771         };
1772         static backend_params p = {
1773                 NULL,  /* no additional opcodes */
1774                 NULL,  /* will be set later */
1775                 1,     /* need dword lowering */
1776                 ia32_create_intrinsic_fkt,
1777                 &intrinsic_env,  /* context for ia32_create_intrinsic_fkt */
1778         };
1779
1780         p.dep_param = &ad;
1781         return &p;
1782 }
1783 #ifdef WITH_LIBCORE
1784
1785 /* instruction set architectures. */
1786 static const lc_opt_enum_int_items_t arch_items[] = {
1787         { "386",        arch_i386, },
1788         { "486",        arch_i486, },
1789         { "pentium",    arch_pentium, },
1790         { "586",        arch_pentium, },
1791         { "pentiumpro", arch_pentium_pro, },
1792         { "686",        arch_pentium_pro, },
1793         { "pentiummmx", arch_pentium_mmx, },
1794         { "pentium2",   arch_pentium_2, },
1795         { "p2",         arch_pentium_2, },
1796         { "pentium3",   arch_pentium_3, },
1797         { "p3",         arch_pentium_3, },
1798         { "pentium4",   arch_pentium_4, },
1799         { "p4",         arch_pentium_4, },
1800         { "pentiumm",   arch_pentium_m, },
1801         { "pm",         arch_pentium_m, },
1802         { "core",       arch_core, },
1803         { "k6",         arch_k6, },
1804         { "athlon",     arch_athlon, },
1805         { "athlon64",   arch_athlon_64, },
1806         { "opteron",    arch_opteron, },
1807         { NULL,         0 }
1808 };
1809
1810 static lc_opt_enum_int_var_t arch_var = {
1811         &ia32_isa_template.arch, arch_items
1812 };
1813
1814 static lc_opt_enum_int_var_t opt_arch_var = {
1815         &ia32_isa_template.opt_arch, arch_items
1816 };
1817
1818 static const lc_opt_enum_int_items_t fp_unit_items[] = {
1819         { "x87" ,    fp_x87 },
1820         { "sse2",    fp_sse2 },
1821         { NULL,      0 }
1822 };
1823
1824 static lc_opt_enum_int_var_t fp_unit_var = {
1825         &ia32_isa_template.fp_kind, fp_unit_items
1826 };
1827
1828 static const lc_opt_enum_int_items_t gas_items[] = {
1829         { "linux",   ASM_LINUX_GAS },
1830         { "mingw",   ASM_MINGW_GAS },
1831         { NULL,      0 }
1832 };
1833
1834 static lc_opt_enum_int_var_t gas_var = {
1835         (int *)&asm_flavour, gas_items
1836 };
1837
1838 static const lc_opt_table_entry_t ia32_options[] = {
1839         LC_OPT_ENT_ENUM_INT("arch",      "select the instruction architecture", &arch_var),
1840         LC_OPT_ENT_ENUM_INT("opt",       "optimize for instruction architecture", &opt_arch_var),
1841         LC_OPT_ENT_ENUM_INT("fpunit",    "select the floating point unit", &fp_unit_var),
1842         LC_OPT_ENT_NEGBIT("noaddrmode",  "do not use address mode", &ia32_isa_template.opt, IA32_OPT_DOAM),
1843         LC_OPT_ENT_NEGBIT("nolea",       "do not optimize for LEAs", &ia32_isa_template.opt, IA32_OPT_LEA),
1844         LC_OPT_ENT_NEGBIT("noplacecnst", "do not place constants", &ia32_isa_template.opt, IA32_OPT_PLACECNST),
1845         LC_OPT_ENT_NEGBIT("noimmop",     "no operations with immediates", &ia32_isa_template.opt, IA32_OPT_IMMOPS),
1846         LC_OPT_ENT_NEGBIT("noextbb",     "do not use extended basic block scheduling", &ia32_isa_template.opt, IA32_OPT_EXTBB),
1847         LC_OPT_ENT_ENUM_INT("gasmode",   "set the GAS compatibility mode", &gas_var),
1848         { NULL }
1849 };
1850
1851 /**
1852  * Register command line options for the ia32 backend.
1853  *
1854  * Options so far:
1855  *
1856  * ia32-arch=arch    create instruction for arch
1857  * ia32-opt=arch     optimize for run on arch
1858  * ia32-fpunit=unit  select floating point unit (x87 or SSE2)
1859  * ia32-incdec       optimize for inc/dec
1860  * ia32-noaddrmode   do not use address mode
1861  * ia32-nolea        do not optimize for LEAs
1862  * ia32-noplacecnst  do not place constants,
1863  * ia32-noimmop      no operations with immediates
1864  * ia32-noextbb      do not use extended basic block scheduling
1865  * ia32-gasmode      set the GAS compatibility mode
1866  */
1867 static void ia32_register_options(lc_opt_entry_t *ent)
1868 {
1869         lc_opt_entry_t *be_grp_ia32 = lc_opt_get_grp(ent, "ia32");
1870         lc_opt_add_table(be_grp_ia32, ia32_options);
1871 }
1872 #endif /* WITH_LIBCORE */
1873
1874 const arch_isa_if_t ia32_isa_if = {
1875         ia32_init,
1876         ia32_done,
1877         ia32_get_n_reg_class,
1878         ia32_get_reg_class,
1879         ia32_get_reg_class_for_mode,
1880         ia32_get_call_abi,
1881         ia32_get_irn_handler,
1882         ia32_get_code_generator_if,
1883         ia32_get_list_sched_selector,
1884         ia32_get_reg_class_alignment,
1885         ia32_get_libfirm_params,
1886 #ifdef WITH_LIBCORE
1887         ia32_register_options
1888 #endif
1889 };