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