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