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