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