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