removed is_Start macro, there exists a firm function now
[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 /* Creates the unique per irg GP NoReg node. */
66 ir_node *ia32_new_NoReg_gp(ia32_code_gen_t *cg) {
67         return be_abi_get_callee_save_irn(cg->birg->abi, &ia32_gp_regs[REG_GP_NOREG]);
68 }
69
70 /* Creates the unique per irg FP NoReg node. */
71 ir_node *ia32_new_NoReg_fp(ia32_code_gen_t *cg) {
72         return be_abi_get_callee_save_irn(cg->birg->abi,
73                 USE_SSE2(cg) ? &ia32_xmm_regs[REG_XMM_NOREG] : &ia32_vfp_regs[REG_VFP_NOREG]);
74 }
75
76 /**************************************************
77  *                         _ _              _  __
78  *                        | | |            (_)/ _|
79  *  _ __ ___  __ _    __ _| | | ___   ___   _| |_
80  * | '__/ _ \/ _` |  / _` | | |/ _ \ / __| | |  _|
81  * | | |  __/ (_| | | (_| | | | (_) | (__  | | |
82  * |_|  \___|\__, |  \__,_|_|_|\___/ \___| |_|_|
83  *            __/ |
84  *           |___/
85  **************************************************/
86
87 /**
88  * Return register requirements for an ia32 node.
89  * If the node returns a tuple (mode_T) then the proj's
90  * will be asked for this information.
91  */
92 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) {
93         const ia32_irn_ops_t      *ops = self;
94         const ia32_register_req_t *irn_req;
95         long                       node_pos = pos == -1 ? 0 : pos;
96         ir_mode                   *mode     = is_Block(irn) ? NULL : get_irn_mode(irn);
97         FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
98
99         if (is_Block(irn) || mode == mode_M || mode == mode_X) {
100                 DBG((mod, LEVEL_1, "ignoring Block, mode_M, mode_X node %+F\n", irn));
101                 return NULL;
102         }
103
104         if (mode == mode_T && pos < 0) {
105                 DBG((mod, LEVEL_1, "ignoring request OUT requirements for node %+F\n", irn));
106                 return NULL;
107         }
108
109         DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
110
111         if (is_Proj(irn)) {
112                 if(pos >= 0) {
113                         DBG((mod, LEVEL_1, "ignoring request IN requirements for node %+F\n", irn));
114                         return NULL;
115                 }
116
117                 if (pos == -1) {
118                         node_pos = ia32_translate_proj_pos(irn);
119                 }
120                 else {
121                         node_pos = pos;
122                 }
123
124                 irn = skip_Proj(irn);
125
126                 DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
127         }
128
129         if (is_ia32_irn(irn)) {
130                 if (pos >= 0) {
131                         irn_req = get_ia32_in_req(irn, pos);
132                 }
133                 else {
134                         irn_req = get_ia32_out_req(irn, node_pos);
135                 }
136
137                 DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
138
139                 memcpy(req, &(irn_req->req), sizeof(*req));
140
141                 if (arch_register_req_is(&(irn_req->req), should_be_same)) {
142                         assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
143                         req->other_same = get_irn_n(irn, irn_req->same_pos);
144                 }
145
146                 if (arch_register_req_is(&(irn_req->req), should_be_different)) {
147                         assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
148                         req->other_different = get_irn_n(irn, irn_req->different_pos);
149                 }
150         }
151         else {
152                 /* treat Unknowns like Const with default requirements */
153                 if (is_Unknown(irn)) {
154                         DB((mod, LEVEL_1, "returning UKNWN reqs for %+F\n", irn));
155                         if (mode_is_float(mode)) {
156                                 if (USE_SSE2(ops->cg))
157                                         memcpy(req, &(ia32_default_req_ia32_xmm_xmm_UKNWN), sizeof(*req));
158                                 else
159                                         memcpy(req, &(ia32_default_req_ia32_vfp_vfp_UKNWN), sizeof(*req));
160                         }
161                         else if (mode_is_int(mode) || mode_is_reference(mode))
162                                 memcpy(req, &(ia32_default_req_ia32_gp_gp_UKNWN), sizeof(*req));
163                         else if (mode == mode_T || mode == mode_M) {
164                                 DBG((mod, LEVEL_1, "ignoring Unknown node %+F\n", irn));
165                                 return NULL;
166                         }
167                         else
168                                 assert(0 && "unsupported Unknown-Mode");
169                 }
170                 else {
171                         DB((mod, LEVEL_1, "returning NULL for %+F (not ia32)\n", irn));
172                         req = NULL;
173                 }
174         }
175
176         return req;
177 }
178
179 static void ia32_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
180         int                   pos = 0;
181         const ia32_irn_ops_t *ops = self;
182
183         if (get_irn_mode(irn) == mode_X) {
184                 return;
185         }
186
187         DBG((ops->cg->mod, LEVEL_1, "ia32 assigned register %s to node %+F\n", reg->name, irn));
188
189         if (is_Proj(irn)) {
190                 pos = ia32_translate_proj_pos(irn);
191                 irn = skip_Proj(irn);
192         }
193
194         if (is_ia32_irn(irn)) {
195                 const arch_register_t **slots;
196
197                 slots      = get_ia32_slots(irn);
198                 slots[pos] = reg;
199         }
200         else {
201                 ia32_set_firm_reg(irn, reg, cur_reg_set);
202         }
203 }
204
205 static const arch_register_t *ia32_get_irn_reg(const void *self, const ir_node *irn) {
206         int pos = 0;
207         const arch_register_t *reg = NULL;
208
209         if (is_Proj(irn)) {
210
211                 if (get_irn_mode(irn) == mode_X) {
212                         return NULL;
213                 }
214
215                 pos = ia32_translate_proj_pos(irn);
216                 irn = skip_Proj(irn);
217         }
218
219         if (is_ia32_irn(irn)) {
220                 const arch_register_t **slots;
221                 slots = get_ia32_slots(irn);
222                 reg   = slots[pos];
223         }
224         else {
225                 reg = ia32_get_firm_reg(irn, cur_reg_set);
226         }
227
228         return reg;
229 }
230
231 static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
232         arch_irn_class_t classification = arch_irn_class_normal;
233
234         irn = skip_Proj(irn);
235
236         if (is_cfop(irn))
237                 classification |= arch_irn_class_branch;
238
239         if (! is_ia32_irn(irn))
240                 return classification & ~arch_irn_class_normal;
241
242         if (is_ia32_Cnst(irn))
243                 classification |= arch_irn_class_const;
244
245         if (is_ia32_Ld(irn))
246                 classification |= arch_irn_class_load;
247
248         if (is_ia32_St(irn) || is_ia32_Store8Bit(irn))
249                 classification |= arch_irn_class_store;
250
251         if (is_ia32_got_reload(irn))
252                 classification |= arch_irn_class_reload;
253
254         return classification;
255 }
256
257 static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
258
259         if(is_Proj(irn)) {
260                 ir_node *pred = get_Proj_pred(irn);
261                 int ia32_op   = get_ia32_irn_opcode(pred);
262                 long proj     = get_Proj_proj(irn);
263                 if (iro_ia32_Push == ia32_op && proj == pn_ia32_Push_stack) {
264                         /* Push modifies always ESP, this cannot be changed */
265                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
266                 }
267                 if (iro_ia32_Pop == ia32_op && proj == pn_ia32_Pop_stack) {
268                         /* Pop modifies always ESP, this cannot be changed */
269                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
270                 }
271                 if (iro_ia32_AddSP == ia32_op && proj == pn_ia32_AddSP_stack) {
272                         /* AddSP modifies always ESP, this cannot be changed */
273                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
274                 }
275                 if (iro_ia32_SubSP == ia32_op && proj == pn_ia32_SubSP_stack) {
276                         /* SubSP modifies always ESP, this cannot be changed */
277                         return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
278                 }
279         }
280
281         irn = skip_Proj(irn);
282         if (is_ia32_irn(irn))
283                 return get_ia32_flags(irn);
284         else {
285                 if (is_Unknown(irn))
286                         return arch_irn_flags_ignore;
287                 return 0;
288         }
289 }
290
291 /**
292  * The IA32 ABI callback object.
293  */
294 typedef struct {
295         be_abi_call_flags_bits_t flags;  /**< The call flags. */
296         const arch_isa_t *isa;           /**< The ISA handle. */
297         const arch_env_t *aenv;          /**< The architecture environment. */
298         ir_graph *irg;                   /**< The associated graph. */
299 } ia32_abi_env_t;
300
301 static entity *ia32_get_frame_entity(const void *self, const ir_node *irn) {
302         return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL;
303 }
304
305 static void ia32_set_frame_entity(const void *self, ir_node *irn, entity *ent) {
306         set_ia32_frame_ent(irn, ent);
307 }
308
309 static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) {
310         char buf[64];
311         const ia32_irn_ops_t *ops = self;
312
313         if (get_ia32_frame_ent(irn)) {
314                 ia32_am_flavour_t am_flav = get_ia32_am_flavour(irn);
315
316                 if(is_ia32_Pop(irn)) {
317                         int omit_fp = be_abi_omit_fp(ops->cg->birg->abi);
318                         if (omit_fp) {
319                                 /* Pop nodes modify the stack pointer before calculating the destination
320                                  * address, so fix this here
321                                  */
322                                 bias -= 4;
323                         }
324                 }
325
326                 DBG((ops->cg->mod, LEVEL_1, "stack biased %+F with %d\n", irn, bias));
327
328                 snprintf(buf, sizeof(buf), "%d", bias);
329
330                 if (get_ia32_op_type(irn) == ia32_Normal) {
331                         set_ia32_cnst(irn, buf);
332                 } else {
333                         add_ia32_am_offs(irn, buf);
334                         am_flav |= ia32_O;
335                         set_ia32_am_flavour(irn, am_flav);
336                 }
337         }
338 }
339
340 static int ia32_get_sp_bias(const void *self, const ir_node *irn) {
341         if(is_Proj(irn)) {
342                 long proj = get_Proj_proj(irn);
343                 ir_node *pred = get_Proj_pred(irn);
344
345                 if (proj == pn_ia32_Push_stack && is_ia32_Push(pred))
346                         return 4;
347                 if (proj == pn_ia32_Pop_stack && is_ia32_Pop(pred))
348                         return -4;
349         }
350
351         return 0;
352 }
353
354 /**
355  * Put all registers which are saved by the prologue/epilogue in a set.
356  *
357  * @param self  The callback object.
358  * @param s     The result set.
359  */
360 static void ia32_abi_dont_save_regs(void *self, pset *s)
361 {
362         ia32_abi_env_t *env = self;
363         if(env->flags.try_omit_fp)
364                 pset_insert_ptr(s, env->isa->bp);
365 }
366
367 /**
368  * Generate the routine prologue.
369  *
370  * @param self    The callback object.
371  * @param mem     A pointer to the mem node. Update this if you define new memory.
372  * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
373  *
374  * @return        The register which shall be used as a stack frame base.
375  *
376  * All nodes which define registers in @p reg_map must keep @p reg_map current.
377  */
378 static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
379 {
380         ia32_abi_env_t *env = self;
381
382         if (! env->flags.try_omit_fp) {
383                 ir_node *bl      = get_irg_start_block(env->irg);
384                 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
385                 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
386                 ir_node *noreg = be_abi_reg_map_get(reg_map, &ia32_gp_regs[REG_GP_NOREG]);
387                 ir_node *push;
388
389                 /* push ebp */
390                 push    = new_rd_ia32_Push(NULL, env->irg, bl, noreg, noreg, curr_bp, curr_sp, *mem);
391                 curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
392                 *mem    = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
393
394                 /* the push must have SP out register */
395                 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
396                 set_ia32_flags(push, arch_irn_flags_ignore);
397
398                 /* move esp to ebp */
399                 curr_bp  = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
400                 be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
401                 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
402                 be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
403
404                 /* beware: the copy must be done before any other sp use */
405                 curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
406                 be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
407                 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
408                 be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
409
410                 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
411                 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
412
413                 return env->isa->bp;
414         }
415
416         return env->isa->sp;
417 }
418
419 /**
420  * Generate the routine epilogue.
421  * @param self    The callback object.
422  * @param bl      The block for the epilog
423  * @param mem     A pointer to the mem node. Update this if you define new memory.
424  * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
425  * @return        The register which shall be used as a stack frame base.
426  *
427  * All nodes which define registers in @p reg_map must keep @p reg_map current.
428  */
429 static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
430 {
431         ia32_abi_env_t *env     = self;
432         ir_node        *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
433         ir_node        *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
434
435         if (env->flags.try_omit_fp) {
436                 /* simply remove the stack frame here */
437                 curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK);
438                 add_irn_dep(curr_sp, *mem);
439         }
440         else {
441                 const ia32_isa_t *isa     = (ia32_isa_t *)env->isa;
442                 ir_mode          *mode_bp = env->isa->bp->reg_class->mode;
443
444                 /* gcc always emits a leave at the end of a routine */
445                 if (1 || ARCH_AMD(isa->opt_arch)) {
446                         ir_node *leave;
447
448                         /* leave */
449                         leave   = new_rd_ia32_Leave(NULL, env->irg, bl, curr_sp, curr_bp);
450                         set_ia32_flags(leave, arch_irn_flags_ignore);
451                         curr_bp = new_r_Proj(current_ir_graph, bl, leave, mode_bp, pn_ia32_Leave_frame);
452                         curr_sp = new_r_Proj(current_ir_graph, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
453                         *mem    = new_r_Proj(current_ir_graph, bl, leave, mode_M, pn_ia32_Leave_M);
454                 }
455                 else {
456                         ir_node *noreg = be_abi_reg_map_get(reg_map, &ia32_gp_regs[REG_GP_NOREG]);
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, noreg, noreg, 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) {
1092         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1093         ir_node *frame = get_irg_frame(env->irg);
1094
1095         ir_node *push = new_rd_ia32_Push(env->dbg, env->irg, env->block, frame, noreg, noreg, sp, mem);
1096
1097         set_ia32_frame_ent(push, ent);
1098         set_ia32_use_frame(push);
1099         set_ia32_op_type(push, ia32_AddrModeS);
1100         set_ia32_am_flavour(push, ia32_B);
1101         set_ia32_ls_mode(push, mode_Is);
1102
1103         sched_add_before(schedpoint, push);
1104         return push;
1105 }
1106
1107 static ir_node *create_pop(ia32_transform_env_t *env, ir_node *schedpoint, ir_node *sp, entity *ent) {
1108         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1109         ir_node *frame = get_irg_frame(env->irg);
1110
1111         ir_node *pop = new_rd_ia32_Pop(env->dbg, env->irg, env->block, frame, noreg, sp, new_NoMem());
1112
1113         set_ia32_frame_ent(pop, ent);
1114         set_ia32_use_frame(pop);
1115         set_ia32_op_type(pop, ia32_AddrModeD);
1116         set_ia32_am_flavour(pop, ia32_B);
1117         set_ia32_ls_mode(pop, mode_Is);
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) {
1125         ir_mode *spmode = mode_Iu;
1126         const arch_register_t *spreg = &ia32_gp_regs[REG_ESP];
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 /**
1137  * Transform memperm, currently we do this the ugly way and produce
1138  * push/pop into/from memory cascades. This is possible without using
1139  * any registers.
1140  */
1141 static void transform_MemPerm(ia32_transform_env_t *env) {
1142         ir_node *node = env->irn;
1143         int i, arity;
1144         ir_node *sp = be_abi_get_ignore_irn(env->cg->birg->abi, &ia32_gp_regs[REG_ESP]);
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);
1163                 sp = create_spproj(env, push, 0, node);
1164                 if(entbits == 64) {
1165                         // add another push after the first one
1166                         push = create_push(env, node, sp, mem, ent);
1167                         add_ia32_am_offs_int(push, 4);
1168                         sp = create_spproj(env, push, 0, node);
1169                 }
1170
1171                 set_irn_n(node, i, new_Bad());
1172         }
1173
1174         // create pops
1175         for(i = arity - 1; i >= 0; --i) {
1176                 entity *ent = be_get_MemPerm_out_entity(node, i);
1177                 ir_type *enttype = get_entity_type(ent);
1178                 int entbits = get_type_size_bits(enttype);
1179
1180                 ir_node *pop;
1181
1182                 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1183
1184                 pop = create_pop(env, node, sp, ent);
1185                 if(entbits == 64) {
1186                         // add another pop after the first one
1187                         sp = create_spproj(env, pop, 1, node);
1188                         pop = create_pop(env, node, sp, ent);
1189                         add_ia32_am_offs_int(pop, 4);
1190                 }
1191                 sp = create_spproj(env, pop, 1, node);
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 };