7cef37af620efe89f448828d91d3f43317f255f0
[libfirm] / ir / be / ia32 / bearch_ia32.c
1 /**
2  * This is the main ia32 firm backend driver.
3  * @author Christian Wuerdig
4  * $Id$
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #ifdef HAVE_MALLOC_H
12 #include <malloc.h>
13 #endif
14
15 #ifdef HAVE_ALLOCA_H
16 #include <alloca.h>
17 #endif
18
19 #ifdef WITH_LIBCORE
20 #include <libcore/lc_opts.h>
21 #include <libcore/lc_opts_enum.h>
22 #endif /* WITH_LIBCORE */
23
24 #include <math.h>
25
26 #include "pseudo_irg.h"
27 #include "irgwalk.h"
28 #include "irprog.h"
29 #include "irprintf.h"
30 #include "iredges_t.h"
31 #include "ircons.h"
32 #include "irgmod.h"
33 #include "irgopt.h"
34 #include "irbitset.h"
35 #include "pdeq.h"
36 #include "debug.h"
37
38 #include "../beabi.h"                 /* the general register allocator interface */
39 #include "../benode_t.h"
40 #include "../belower.h"
41 #include "../besched_t.h"
42 #include "../be.h"
43 #include "../be_t.h"
44 #include "../beirgmod.h"
45 #include "../be_dbgout.h"
46 #include "bearch_ia32_t.h"
47
48 #include "ia32_new_nodes.h"           /* ia32 nodes interface */
49 #include "gen_ia32_regalloc_if.h"     /* the generated interface (register type and class defenitions) */
50 #include "ia32_gen_decls.h"           /* interface declaration emitter */
51 #include "ia32_transform.h"
52 #include "ia32_emitter.h"
53 #include "ia32_map_regs.h"
54 #include "ia32_optimize.h"
55 #include "ia32_x87.h"
56 #include "ia32_dbg_stat.h"
57 #include "ia32_finish.h"
58 #include "ia32_util.h"
59
60 #define DEBUG_MODULE "firm.be.ia32.isa"
61
62 /* TODO: ugly */
63 static set *cur_reg_set = NULL;
64
65 #undef is_Start
66 #define is_Start(irn) (get_irn_opcode(irn) == iro_Start)
67
68 /* Creates the unique per irg GP NoReg node. */
69 ir_node *ia32_new_NoReg_gp(ia32_code_gen_t *cg) {
70         return be_abi_get_callee_save_irn(cg->birg->abi, &ia32_gp_regs[REG_GP_NOREG]);
71 }
72
73 /* Creates the unique per irg FP NoReg node. */
74 ir_node *ia32_new_NoReg_fp(ia32_code_gen_t *cg) {
75         return be_abi_get_callee_save_irn(cg->birg->abi,
76                 USE_SSE2(cg) ? &ia32_xmm_regs[REG_XMM_NOREG] : &ia32_vfp_regs[REG_VFP_NOREG]);
77 }
78
79 /**************************************************
80  *                         _ _              _  __
81  *                        | | |            (_)/ _|
82  *  _ __ ___  __ _    __ _| | | ___   ___   _| |_
83  * | '__/ _ \/ _` |  / _` | | |/ _ \ / __| | |  _|
84  * | | |  __/ (_| | | (_| | | | (_) | (__  | | |
85  * |_|  \___|\__, |  \__,_|_|_|\___/ \___| |_|_|
86  *            __/ |
87  *           |___/
88  **************************************************/
89
90 static ir_node *my_skip_proj(const ir_node *n) {
91         while (is_Proj(n))
92                 n = get_Proj_pred(n);
93         return (ir_node *)n;
94 }
95
96
97 /**
98  * Return register requirements for an ia32 node.
99  * If the node returns a tuple (mode_T) then the proj's
100  * will be asked for this information.
101  */
102 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) {
103         const ia32_irn_ops_t      *ops = self;
104         const ia32_register_req_t *irn_req;
105         long                       node_pos = pos == -1 ? 0 : pos;
106         ir_mode                   *mode     = is_Block(irn) ? NULL : get_irn_mode(irn);
107         FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
108
109         if (is_Block(irn) || mode == mode_M || mode == mode_X) {
110                 DBG((mod, LEVEL_1, "ignoring Block, mode_M, mode_X node %+F\n", irn));
111                 return NULL;
112         }
113
114         if (mode == mode_T && pos < 0) {
115                 DBG((mod, LEVEL_1, "ignoring request OUT requirements for node %+F\n", irn));
116                 return NULL;
117         }
118
119         DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
120
121         if (is_Proj(irn)) {
122                 if (pos == -1) {
123                         node_pos = ia32_translate_proj_pos(irn);
124                 }
125                 else {
126                         node_pos = pos;
127                 }
128
129                 irn = my_skip_proj(irn);
130
131                 DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
132         }
133
134         if (is_ia32_irn(irn)) {
135                 if (pos >= 0) {
136                         irn_req = get_ia32_in_req(irn, pos);
137                 }
138                 else {
139                         irn_req = get_ia32_out_req(irn, node_pos);
140                 }
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 = ia32_translate_proj_pos(irn);
196                 irn = my_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 = ia32_translate_proj_pos(irn);
221                 irn = my_skip_proj(irn);
222         }
223
224         if (is_ia32_irn(irn)) {
225                 const arch_register_t **slots;
226                 slots = get_ia32_slots(irn);
227                 reg   = slots[pos];
228         }
229         else {
230                 reg = ia32_get_firm_reg(irn, cur_reg_set);
231         }
232
233         return reg;
234 }
235
236 static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
237         arch_irn_class_t classification = arch_irn_class_normal;
238
239         irn = my_skip_proj(irn);
240
241         if (is_cfop(irn))
242                 classification |= arch_irn_class_branch;
243
244         if (! is_ia32_irn(irn))
245                 return classification & ~arch_irn_class_normal;
246
247         if (is_ia32_Cnst(irn))
248                 classification |= arch_irn_class_const;
249
250         if (is_ia32_Ld(irn))
251                 classification |= arch_irn_class_load;
252
253         if (is_ia32_St(irn) || is_ia32_Store8Bit(irn))
254                 classification |= arch_irn_class_store;
255
256         if (is_ia32_got_reload(irn))
257                 classification |= arch_irn_class_reload;
258
259         return classification;
260 }
261
262 static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
263
264         if(is_Proj(irn)) {
265                 ir_node *pred = get_Proj_pred(irn);
266                 if(is_ia32_Push(pred) && get_Proj_proj(irn) == pn_ia32_Push_stack) {
267                         return arch_irn_flags_modify_sp;
268                 }
269                 if(is_ia32_Pop(pred) && get_Proj_proj(irn) == pn_ia32_Pop_stack) {
270                         return arch_irn_flags_modify_sp;
271                 }
272                 if(is_ia32_AddSP(pred) && get_Proj_proj(irn) == pn_ia32_AddSP_stack) {
273                         return arch_irn_flags_modify_sp;
274                 }
275         }
276
277         irn = my_skip_proj(irn);
278         if (is_ia32_irn(irn))
279                 return get_ia32_flags(irn);
280         else {
281                 if (is_Unknown(irn))
282                         return arch_irn_flags_ignore;
283                 return 0;
284         }
285 }
286
287 static entity *ia32_get_frame_entity(const void *self, const ir_node *irn) {
288         return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL;
289 }
290
291 static void ia32_set_frame_entity(const void *self, ir_node *irn, entity *ent) {
292         set_ia32_frame_ent(irn, ent);
293 }
294
295 static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) {
296         char buf[64];
297         const ia32_irn_ops_t *ops = self;
298
299         if (get_ia32_frame_ent(irn)) {
300                 ia32_am_flavour_t am_flav = get_ia32_am_flavour(irn);
301
302                 /* Pop nodes modify the stack pointer before calculating the destination
303                  * address, so fix this here
304                  */
305                 if(is_ia32_Pop(irn)) {
306                         bias -= 4;
307                 }
308
309                 DBG((ops->cg->mod, LEVEL_1, "stack biased %+F with %d\n", irn, bias));
310
311                 snprintf(buf, sizeof(buf), "%d", bias);
312
313                 if (get_ia32_op_type(irn) == ia32_Normal) {
314                         set_ia32_cnst(irn, buf);
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                 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, arity;
868         ir_mode *mode;
869         ir_node *mem_proj = NULL;
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 == NULL)
891                         return;
892         }
893
894         arity = get_irn_arity(irn);
895         for (i = 0; i < arity; ++i) {
896                 ir_node *pred = get_irn_n(irn, i);
897
898                 /* do not follow memory edges or we will accidentally remove stores */
899                 if (get_irn_mode(pred) == mode_M) {
900                         if(mem_proj != NULL) {
901                                 edges_reroute(mem_proj, pred, get_irn_irg(mem_proj));
902                                 mem_proj = NULL;
903                         }
904                         continue;
905                 }
906
907                 set_irn_n(irn, i, new_Bad());
908
909                 /*
910                         The current node is about to be removed: if the predecessor
911                         has only this node as user, it need to be removed as well.
912                 */
913                 if (get_irn_n_edges(pred) <= 1)
914                         remove_unused_nodes(pred, already_visited);
915         }
916
917         // we need to set the presd to Bad again to also get the memory edges
918         arity = get_irn_arity(irn);
919         for (i = 0; i < arity; ++i) {
920                 set_irn_n(irn, i, new_Bad());
921         }
922
923         if (sched_is_scheduled(irn)) {
924                 sched_remove(irn);
925         }
926 }
927
928 static void remove_unused_loads_walker(ir_node *irn, void *env) {
929         bitset_t *already_visited = env;
930         if (is_ia32_Ld(irn) && ! bitset_contains_irn(already_visited, irn))
931                 remove_unused_nodes(irn, env);
932 }
933
934 /**
935  * Called before the register allocator.
936  * Calculate a block schedule here. We need it for the x87
937  * simulator and the emitter.
938  */
939 static void ia32_before_ra(void *self) {
940         ia32_code_gen_t *cg              = self;
941         bitset_t        *already_visited = bitset_irg_alloca(cg->irg);
942
943         /*
944                 Handle special case:
945                 There are sometimes unused loads, only pinned by memory.
946                 We need to remove those Loads and all other nodes which won't be used
947                 after removing the Load from schedule.
948         */
949         irg_walk_graph(cg->irg, remove_unused_loads_walker, NULL, already_visited);
950 }
951
952
953 /**
954  * Transforms a be node into a Load.
955  */
956 static void transform_to_Load(ia32_transform_env_t *env) {
957         ir_node *irn         = env->irn;
958         entity  *ent         = be_get_frame_entity(irn);
959         ir_mode *mode        = env->mode;
960         ir_node *noreg       = ia32_new_NoReg_gp(env->cg);
961         ir_node *nomem       = new_rd_NoMem(env->irg);
962         ir_node *sched_point = NULL;
963         ir_node *ptr         = get_irn_n(irn, 0);
964         ir_node *mem         = be_is_Reload(irn) ? get_irn_n(irn, 1) : nomem;
965         ir_node *new_op, *proj;
966         const arch_register_t *reg;
967
968         if (sched_is_scheduled(irn)) {
969                 sched_point = sched_prev(irn);
970         }
971
972         if (mode_is_float(mode)) {
973                 if (USE_SSE2(env->cg))
974                         new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
975                 else
976                         new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
977         }
978         else {
979                 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
980         }
981
982         set_ia32_am_support(new_op, ia32_am_Source);
983         set_ia32_op_type(new_op, ia32_AddrModeS);
984         set_ia32_am_flavour(new_op, ia32_B);
985         set_ia32_ls_mode(new_op, mode);
986         set_ia32_frame_ent(new_op, ent);
987         set_ia32_use_frame(new_op);
988
989         DBG_OPT_RELOAD2LD(irn, new_op);
990
991         proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_Load_res);
992
993         if (sched_point) {
994                 sched_add_after(sched_point, new_op);
995                 sched_add_after(new_op, proj);
996
997                 sched_remove(irn);
998         }
999
1000         /* copy the register from the old node to the new Load */
1001         reg = arch_get_irn_register(env->cg->arch_env, irn);
1002         arch_set_irn_register(env->cg->arch_env, new_op, reg);
1003
1004         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, irn));
1005
1006         exchange(irn, proj);
1007 }
1008
1009 /**
1010  * Transforms a be node into a Store.
1011  */
1012 static void transform_to_Store(ia32_transform_env_t *env) {
1013         ir_node *irn   = env->irn;
1014         entity  *ent   = be_get_frame_entity(irn);
1015         ir_mode *mode  = env->mode;
1016         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1017         ir_node *nomem = new_rd_NoMem(env->irg);
1018         ir_node *ptr   = get_irn_n(irn, 0);
1019         ir_node *val   = get_irn_n(irn, 1);
1020         ir_node *new_op, *proj;
1021         ir_node *sched_point = NULL;
1022
1023         if (sched_is_scheduled(irn)) {
1024                 sched_point = sched_prev(irn);
1025         }
1026
1027         if (mode_is_float(mode)) {
1028                 if (USE_SSE2(env->cg))
1029                         new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1030                 else
1031                         new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1032         }
1033         else if (get_mode_size_bits(mode) == 8) {
1034                 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1035         }
1036         else {
1037                 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1038         }
1039
1040         set_ia32_am_support(new_op, ia32_am_Dest);
1041         set_ia32_op_type(new_op, ia32_AddrModeD);
1042         set_ia32_am_flavour(new_op, ia32_B);
1043         set_ia32_ls_mode(new_op, mode);
1044         set_ia32_frame_ent(new_op, ent);
1045         set_ia32_use_frame(new_op);
1046
1047         DBG_OPT_SPILL2ST(irn, new_op);
1048
1049         proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode_M, pn_ia32_Store_M);
1050
1051         if (sched_point) {
1052                 sched_add_after(sched_point, new_op);
1053                 sched_remove(irn);
1054         }
1055
1056         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, irn));
1057
1058         exchange(irn, proj);
1059 }
1060
1061 static ir_node *create_push(ia32_transform_env_t *env, ir_node *schedpoint, ir_node *sp, ir_node *mem, entity *ent, const char *offset) {
1062         ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1063
1064         ir_node *push = new_rd_ia32_Push(env->dbg, env->irg, env->block, sp, noreg, mem);
1065
1066         set_ia32_frame_ent(push, ent);
1067         set_ia32_use_frame(push);
1068         set_ia32_op_type(push, ia32_AddrModeS);
1069         set_ia32_am_flavour(push, ia32_B);
1070         set_ia32_ls_mode(push, mode_Is);
1071         if(offset != NULL)
1072                 add_ia32_am_offs(push, offset);
1073
1074         sched_add_before(schedpoint, push);
1075         return push;
1076 }
1077
1078 static ir_node *create_pop(ia32_transform_env_t *env, ir_node *schedpoint, ir_node *sp, entity *ent, const char *offset) {
1079         ir_node *pop = new_rd_ia32_Pop(env->dbg, env->irg, env->block, sp, new_NoMem());
1080
1081         set_ia32_frame_ent(pop, ent);
1082         set_ia32_use_frame(pop);
1083         set_ia32_op_type(pop, ia32_AddrModeD);
1084         set_ia32_am_flavour(pop, ia32_B);
1085         set_ia32_ls_mode(pop, mode_Is);
1086         if(offset != NULL)
1087                 add_ia32_am_offs(pop, offset);
1088
1089         sched_add_before(schedpoint, pop);
1090
1091         return pop;
1092 }
1093
1094 static ir_node* create_spproj(ia32_transform_env_t *env, ir_node *pred, int pos, ir_node *schedpoint, const ir_node *oldsp) {
1095         ir_mode *spmode = get_irn_mode(oldsp);
1096         const arch_register_t *spreg = arch_get_irn_register(env->cg->arch_env, oldsp);
1097         ir_node *sp;
1098
1099         sp = new_rd_Proj(env->dbg, env->irg, env->block, pred, spmode, pos);
1100         arch_set_irn_register(env->cg->arch_env, sp, spreg);
1101         sched_add_before(schedpoint, sp);
1102
1103         return sp;
1104 }
1105
1106 static void transform_MemPerm(ia32_transform_env_t *env) {
1107         /*
1108          * Transform memperm, currently we do this the ugly way and produce
1109          * push/pop into/from memory cascades. This is possible without using
1110          * any registers.
1111          */
1112         ir_node *node = env->irn;
1113         int i, arity;
1114         ir_node *sp = get_irn_n(node, 0);
1115         const ir_edge_t *edge;
1116         const ir_edge_t *next;
1117         ir_node **pops;
1118
1119         arity = be_get_MemPerm_entity_arity(node);
1120         pops = alloca(arity * sizeof(pops[0]));
1121
1122         // create pushs
1123         for(i = 0; i < arity; ++i) {
1124                 entity *ent = be_get_MemPerm_in_entity(node, i);
1125                 ir_type *enttype = get_entity_type(ent);
1126                 int entbits = get_type_size_bits(enttype);
1127                 ir_node *mem = get_irn_n(node, i + 1);
1128                 ir_node *push;
1129
1130                 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1131
1132                 push = create_push(env, node, sp, mem, ent, NULL);
1133                 sp = create_spproj(env, push, 0, node, sp);
1134                 if(entbits == 64) {
1135                         // add another push after the first one
1136                         push = create_push(env, node, sp, mem, ent, "4");
1137                         sp = create_spproj(env, push, 0, node, sp);
1138                 }
1139
1140                 set_irn_n(node, i, new_Bad());
1141         }
1142
1143         // create pops
1144         for(i = arity - 1; i >= 0; --i) {
1145                 entity *ent = be_get_MemPerm_out_entity(node, i);
1146                 ir_type *enttype = get_entity_type(ent);
1147                 int entbits = get_type_size_bits(enttype);
1148
1149                 ir_node *pop;
1150
1151                 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1152
1153                 pop = create_pop(env, node, sp, ent, NULL);
1154                 if(entbits == 64) {
1155                         // add another pop after the first one
1156                         sp = create_spproj(env, pop, 1, node, sp);
1157                         pop = create_pop(env, node, sp, ent, "4");
1158                 }
1159                 //if(i != 0) {
1160                         sp = create_spproj(env, pop, 1, node, sp);
1161                 //}
1162
1163                 pops[i] = pop;
1164         }
1165
1166         // exchange memprojs
1167         foreach_out_edge_safe(node, edge, next) {
1168                 ir_node *proj = get_edge_src_irn(edge);
1169                 int p = get_Proj_proj(proj);
1170
1171                 assert(p < arity);
1172
1173                 set_Proj_pred(proj, pops[p]);
1174                 set_Proj_proj(proj, 3);
1175         }
1176
1177         // remove memperm
1178         arity = get_irn_arity(node);
1179         for(i = 0; i < arity; ++i) {
1180                 set_irn_n(node, i, new_Bad());
1181         }
1182         sched_remove(node);
1183 }
1184
1185 /**
1186  * Fix the mode of Spill/Reload
1187  */
1188 static ir_mode *fix_spill_mode(ia32_code_gen_t *cg, ir_mode *mode)
1189 {
1190         if (mode_is_float(mode)) {
1191                 if (USE_SSE2(cg))
1192                         mode = mode_D;
1193                 else
1194                         mode = mode_E;
1195         }
1196         else
1197                 mode = mode_Is;
1198         return mode;
1199 }
1200
1201 /**
1202  * Block-Walker: Calls the transform functions Spill and Reload.
1203  */
1204 static void ia32_after_ra_walker(ir_node *block, void *env) {
1205         ir_node *node, *prev;
1206         ia32_code_gen_t *cg = env;
1207         ia32_transform_env_t tenv;
1208
1209         tenv.block = block;
1210         tenv.irg   = current_ir_graph;
1211         tenv.cg    = cg;
1212         DEBUG_ONLY(tenv.mod = cg->mod;)
1213
1214         /* beware: the schedule is changed here */
1215         for (node = sched_last(block); !sched_is_begin(node); node = prev) {
1216                 prev = sched_prev(node);
1217                 if (be_is_Reload(node)) {
1218                         /* we always reload 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(node));
1222                         transform_to_Load(&tenv);
1223                 }
1224                 else if (be_is_Spill(node)) {
1225                         ir_node *spillval = get_irn_n(node, be_pos_Spill_val);
1226                         /* we always spill the whole register  */
1227                         tenv.dbg  = get_irn_dbg_info(node);
1228                         tenv.irn  = node;
1229                         tenv.mode = fix_spill_mode(cg, get_irn_mode(spillval));
1230                         transform_to_Store(&tenv);
1231                 }
1232                 else if(be_is_MemPerm(node)) {
1233                         tenv.dbg = get_irn_dbg_info(node);
1234                         tenv.irn = node;
1235                         transform_MemPerm(&tenv);
1236                 }
1237         }
1238 }
1239
1240 /**
1241  * We transform Spill and Reload here. This needs to be done before
1242  * stack biasing otherwise we would miss the corrected offset for these nodes.
1243  *
1244  * If x87 instruction should be emitted, run the x87 simulator and patch
1245  * the virtual instructions. This must obviously be done after register allocation.
1246  */
1247 static void ia32_after_ra(void *self) {
1248         ia32_code_gen_t *cg = self;
1249         ir_graph *irg = cg->irg;
1250
1251         irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, cg);
1252
1253         ia32_finish_irg(irg, cg);
1254 }
1255
1256 /**
1257  * Last touchups for the graph before emit
1258  */
1259 static void ia32_finish(void *self) {
1260         ia32_code_gen_t *cg = self;
1261         ir_graph        *irg = cg->irg;
1262
1263         // Matze: disabled for now, as the irextbb algo sometimes returns extbb in
1264         // the wrong order if the graph has critical edges
1265         be_remove_empty_blocks(irg);
1266
1267         cg->blk_sched = sched_create_block_schedule(cg->irg, cg->birg->execfreqs);
1268
1269         /* if we do x87 code generation, rewrite all the virtual instructions and registers */
1270         if (cg->used_fp == fp_x87 || cg->force_sim) {
1271                 x87_simulate_graph(cg->arch_env, irg, cg->blk_sched);
1272         }
1273
1274         ia32_peephole_optimization(irg, cg);
1275 }
1276
1277 /**
1278  * Emits the code, closes the output file and frees
1279  * the code generator interface.
1280  */
1281 static void ia32_codegen(void *self) {
1282         ia32_code_gen_t *cg = self;
1283         ir_graph        *irg = cg->irg;
1284
1285         ia32_gen_routine(cg->isa->out, irg, cg);
1286
1287         cur_reg_set = NULL;
1288
1289         /* remove it from the isa */
1290         cg->isa->cg = NULL;
1291
1292         /* de-allocate code generator */
1293         del_set(cg->reg_set);
1294         free(cg);
1295 }
1296
1297 static void *ia32_cg_init(const be_irg_t *birg);
1298
1299 static const arch_code_generator_if_t ia32_code_gen_if = {
1300         ia32_cg_init,
1301         NULL,                /* before abi introduce hook */
1302         ia32_prepare_graph,
1303         ia32_before_sched,   /* before scheduling hook */
1304         ia32_before_ra,      /* before register allocation hook */
1305         ia32_after_ra,       /* after register allocation hook */
1306         ia32_finish,         /* called before codegen */
1307         ia32_codegen         /* emit && done */
1308 };
1309
1310 /**
1311  * Initializes a IA32 code generator.
1312  */
1313 static void *ia32_cg_init(const be_irg_t *birg) {
1314         ia32_isa_t      *isa = (ia32_isa_t *)birg->main_env->arch_env->isa;
1315         ia32_code_gen_t *cg  = xcalloc(1, sizeof(*cg));
1316
1317         cg->impl      = &ia32_code_gen_if;
1318         cg->irg       = birg->irg;
1319         cg->reg_set   = new_set(ia32_cmp_irn_reg_assoc, 1024);
1320         cg->arch_env  = birg->main_env->arch_env;
1321         cg->isa       = isa;
1322         cg->birg      = birg;
1323         cg->blk_sched = NULL;
1324         cg->fp_to_gp  = NULL;
1325         cg->gp_to_fp  = NULL;
1326         cg->fp_kind   = isa->fp_kind;
1327         cg->used_fp   = fp_none;
1328         cg->dump      = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
1329
1330         FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.cg");
1331
1332         /* copy optimizations from isa for easier access */
1333         cg->opt      = isa->opt;
1334         cg->arch     = isa->arch;
1335         cg->opt_arch = isa->opt_arch;
1336
1337         /* enter it */
1338         isa->cg = cg;
1339
1340 #ifndef NDEBUG
1341         if (isa->name_obst_size) {
1342                 //printf("freed %d bytes from name obst\n", isa->name_obst_size);
1343                 isa->name_obst_size = 0;
1344                 obstack_free(isa->name_obst, NULL);
1345                 obstack_init(isa->name_obst);
1346         }
1347 #endif /* NDEBUG */
1348
1349         cur_reg_set = cg->reg_set;
1350
1351         ia32_irn_ops.cg = cg;
1352
1353         return (arch_code_generator_t *)cg;
1354 }
1355
1356
1357
1358 /*****************************************************************
1359  *  ____             _                  _   _____  _____
1360  * |  _ \           | |                | | |_   _|/ ____|  /\
1361  * | |_) | __ _  ___| | _____ _ __   __| |   | | | (___   /  \
1362  * |  _ < / _` |/ __| |/ / _ \ '_ \ / _` |   | |  \___ \ / /\ \
1363  * | |_) | (_| | (__|   <  __/ | | | (_| |  _| |_ ____) / ____ \
1364  * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/    \_\
1365  *
1366  *****************************************************************/
1367
1368 /**
1369  * Set output modes for GCC
1370  */
1371 static const tarval_mode_info mo_integer = {
1372         TVO_DECIMAL,
1373         NULL,
1374         NULL,
1375 };
1376
1377 /*
1378  * set the tarval output mode of all integer modes to decimal
1379  */
1380 static void set_tarval_output_modes(void)
1381 {
1382         int i;
1383
1384         for (i = get_irp_n_modes() - 1; i >= 0; --i) {
1385                 ir_mode *mode = get_irp_mode(i);
1386
1387                 if (mode_is_int(mode))
1388                         set_tarval_mode_output_option(mode, &mo_integer);
1389         }
1390 }
1391
1392
1393 /**
1394  * The template that generates a new ISA object.
1395  * Note that this template can be changed by command line
1396  * arguments.
1397  */
1398 static ia32_isa_t ia32_isa_template = {
1399         {
1400                 &ia32_isa_if,            /* isa interface implementation */
1401                 &ia32_gp_regs[REG_ESP],  /* stack pointer register */
1402                 &ia32_gp_regs[REG_EBP],  /* base pointer register */
1403                 -1,                      /* stack direction */
1404                 NULL,                    /* main environment */
1405         },
1406         NULL,                    /* 16bit register names */
1407         NULL,                    /* 8bit register names */
1408         NULL,                    /* types */
1409         NULL,                    /* tv_ents */
1410         (0                 |
1411         IA32_OPT_INCDEC    |     /* optimize add 1, sub 1 into inc/dec               default: on  */
1412         IA32_OPT_DOAM      |     /* optimize address mode                            default: on  */
1413         IA32_OPT_LEA       |     /* optimize for LEAs                                default: on  */
1414         IA32_OPT_PLACECNST |     /* place constants immediately before instructions, default: on  */
1415         IA32_OPT_IMMOPS    |     /* operations can use immediates,                   default: on  */
1416         IA32_OPT_EXTBB),         /* use extended basic block scheduling,             default: on  */
1417         arch_pentium_4,          /* instruction architecture */
1418         arch_pentium_4,          /* optimize for architecture */
1419         fp_sse2,                 /* use sse2 unit */
1420         NULL,                    /* current code generator */
1421         NULL,                    /* output file */
1422 #ifndef NDEBUG
1423         NULL,                    /* name obstack */
1424         0                        /* name obst size */
1425 #endif
1426 };
1427
1428 /**
1429  * Initializes the backend ISA.
1430  */
1431 static void *ia32_init(FILE *file_handle) {
1432         static int inited = 0;
1433         ia32_isa_t *isa;
1434
1435         if (inited)
1436                 return NULL;
1437
1438         set_tarval_output_modes();
1439
1440         isa = xmalloc(sizeof(*isa));
1441         memcpy(isa, &ia32_isa_template, sizeof(*isa));
1442
1443         ia32_register_init(isa);
1444         ia32_create_opcodes();
1445
1446         if ((ARCH_INTEL(isa->arch) && isa->arch < arch_pentium_4) ||
1447             (ARCH_AMD(isa->arch) && isa->arch < arch_athlon))
1448                 /* no SSE2 for these cpu's */
1449                 isa->fp_kind = fp_x87;
1450
1451         if (ARCH_INTEL(isa->opt_arch) && isa->opt_arch >= arch_pentium_4) {
1452                 /* Pentium 4 don't like inc and dec instructions */
1453                 isa->opt &= ~IA32_OPT_INCDEC;
1454         }
1455
1456         isa->regs_16bit = pmap_create();
1457         isa->regs_8bit  = pmap_create();
1458         isa->types      = pmap_create();
1459         isa->tv_ent     = pmap_create();
1460         isa->out        = file_handle;
1461
1462         ia32_build_16bit_reg_map(isa->regs_16bit);
1463         ia32_build_8bit_reg_map(isa->regs_8bit);
1464
1465         /* patch register names of x87 registers */
1466         if (USE_x87(isa)) {
1467                 ia32_st_regs[0].name = "st";
1468                 ia32_st_regs[1].name = "st(1)";
1469                 ia32_st_regs[2].name = "st(2)";
1470                 ia32_st_regs[3].name = "st(3)";
1471                 ia32_st_regs[4].name = "st(4)";
1472                 ia32_st_regs[5].name = "st(5)";
1473                 ia32_st_regs[6].name = "st(6)";
1474                 ia32_st_regs[7].name = "st(7)";
1475         }
1476
1477 #ifndef NDEBUG
1478         isa->name_obst = xmalloc(sizeof(*isa->name_obst));
1479         obstack_init(isa->name_obst);
1480         isa->name_obst_size = 0;
1481 #endif /* NDEBUG */
1482
1483         ia32_handle_intrinsics();
1484         ia32_switch_section(isa->out, NO_SECTION);
1485         fprintf(isa->out, "\t.intel_syntax\n");
1486
1487         /* needed for the debug support */
1488         ia32_switch_section(isa->out, SECTION_TEXT);
1489         fprintf(isa->out, ".Ltext0:\n");
1490
1491         inited = 1;
1492
1493         return isa;
1494 }
1495
1496
1497
1498 /**
1499  * Closes the output file and frees the ISA structure.
1500  */
1501 static void ia32_done(void *self) {
1502         ia32_isa_t *isa = self;
1503
1504         /* emit now all global declarations */
1505         ia32_gen_decls(isa->out, isa->arch_isa.main_env);
1506
1507         pmap_destroy(isa->regs_16bit);
1508         pmap_destroy(isa->regs_8bit);
1509         pmap_destroy(isa->tv_ent);
1510         pmap_destroy(isa->types);
1511
1512 #ifndef NDEBUG
1513         //printf("name obst size = %d bytes\n", isa->name_obst_size);
1514         obstack_free(isa->name_obst, NULL);
1515 #endif /* NDEBUG */
1516
1517         free(self);
1518 }
1519
1520
1521 /**
1522  * Return the number of register classes for this architecture.
1523  * We report always these:
1524  *  - the general purpose registers
1525  *  - the SSE floating point register set
1526  *  - the virtual floating point registers
1527  */
1528 static int ia32_get_n_reg_class(const void *self) {
1529         return 3;
1530 }
1531
1532 /**
1533  * Return the register class for index i.
1534  */
1535 static const arch_register_class_t *ia32_get_reg_class(const void *self, int i) {
1536         assert(i >= 0 && i < 3 && "Invalid ia32 register class requested.");
1537         if (i == 0)
1538                 return &ia32_reg_classes[CLASS_ia32_gp];
1539         else if (i == 1)
1540                 return &ia32_reg_classes[CLASS_ia32_xmm];
1541         else
1542                 return &ia32_reg_classes[CLASS_ia32_vfp];
1543 }
1544
1545 /**
1546  * Get the register class which shall be used to store a value of a given mode.
1547  * @param self The this pointer.
1548  * @param mode The mode in question.
1549  * @return A register class which can hold values of the given mode.
1550  */
1551 const arch_register_class_t *ia32_get_reg_class_for_mode(const void *self, const ir_mode *mode) {
1552         const ia32_isa_t *isa = self;
1553         if (mode_is_float(mode)) {
1554                 return USE_SSE2(isa) ? &ia32_reg_classes[CLASS_ia32_xmm] : &ia32_reg_classes[CLASS_ia32_vfp];
1555         }
1556         else
1557                 return &ia32_reg_classes[CLASS_ia32_gp];
1558 }
1559
1560 /**
1561  * Get the ABI restrictions for procedure calls.
1562  * @param self        The this pointer.
1563  * @param method_type The type of the method (procedure) in question.
1564  * @param abi         The abi object to be modified
1565  */
1566 static void ia32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) {
1567         const ia32_isa_t *isa = self;
1568         ir_type  *tp;
1569         ir_mode  *mode;
1570         unsigned  cc        = get_method_calling_convention(method_type);
1571         int       n         = get_method_n_params(method_type);
1572         int       biggest_n = -1;
1573         int       stack_idx = 0;
1574         int       i, ignore_1, ignore_2;
1575         ir_mode **modes;
1576         const arch_register_t *reg;
1577         be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi);
1578
1579         unsigned use_push = !IS_P6_ARCH(isa->opt_arch);
1580
1581         /* set abi flags for calls */
1582         call_flags.bits.left_to_right         = 0;  /* always last arg first on stack */
1583         call_flags.bits.store_args_sequential = use_push;
1584         /* call_flags.bits.try_omit_fp                 not changed: can handle both settings */
1585         call_flags.bits.fp_free               = 0;  /* the frame pointer is fixed in IA32 */
1586         call_flags.bits.call_has_imm          = 1;  /* IA32 calls can have immediate address */
1587
1588         /* set stack parameter passing style */
1589         be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
1590
1591         /* collect the mode for each type */
1592         modes = alloca(n * sizeof(modes[0]));
1593
1594         for (i = 0; i < n; i++) {
1595                 tp       = get_method_param_type(method_type, i);
1596                 modes[i] = get_type_mode(tp);
1597         }
1598
1599         /* set register parameters  */
1600         if (cc & cc_reg_param) {
1601                 /* determine the number of parameters passed via registers */
1602                 biggest_n = ia32_get_n_regparam_class(n, modes, &ignore_1, &ignore_2);
1603
1604                 /* loop over all parameters and set the register requirements */
1605                 for (i = 0; i <= biggest_n; i++) {
1606                         reg = ia32_get_RegParam_reg(n, modes, i, cc);
1607                         assert(reg && "kaputt");
1608                         be_abi_call_param_reg(abi, i, reg);
1609                 }
1610
1611                 stack_idx = i;
1612         }
1613
1614
1615         /* set stack parameters */
1616         for (i = stack_idx; i < n; i++) {
1617                 be_abi_call_param_stack(abi, i, 1, 0, 0);
1618         }
1619
1620
1621         /* set return registers */
1622         n = get_method_n_ress(method_type);
1623
1624         assert(n <= 2 && "more than two results not supported");
1625
1626         /* In case of 64bit returns, we will have two 32bit values */
1627         if (n == 2) {
1628                 tp   = get_method_res_type(method_type, 0);
1629                 mode = get_type_mode(tp);
1630
1631                 assert(!mode_is_float(mode) && "two FP results not supported");
1632
1633                 tp   = get_method_res_type(method_type, 1);
1634                 mode = get_type_mode(tp);
1635
1636                 assert(!mode_is_float(mode) && "two FP results not supported");
1637
1638                 be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]);
1639                 be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]);
1640         }
1641         else if (n == 1) {
1642                 const arch_register_t *reg;
1643
1644                 tp   = get_method_res_type(method_type, 0);
1645                 assert(is_atomic_type(tp));
1646                 mode = get_type_mode(tp);
1647
1648                 reg = mode_is_float(mode) ?
1649                         (USE_SSE2(isa) ? &ia32_xmm_regs[REG_XMM0] : &ia32_vfp_regs[REG_VF0]) :
1650                         &ia32_gp_regs[REG_EAX];
1651
1652                 be_abi_call_res_reg(abi, 0, reg);
1653         }
1654 }
1655
1656
1657 static const void *ia32_get_irn_ops(const arch_irn_handler_t *self, const ir_node *irn) {
1658         return &ia32_irn_ops;
1659 }
1660
1661 const arch_irn_handler_t ia32_irn_handler = {
1662         ia32_get_irn_ops
1663 };
1664
1665 const arch_irn_handler_t *ia32_get_irn_handler(const void *self) {
1666         return &ia32_irn_handler;
1667 }
1668
1669 int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn) {
1670         return is_ia32_irn(irn) ? 1 : -1;
1671 }
1672
1673 /**
1674  * Initializes the code generator interface.
1675  */
1676 static const arch_code_generator_if_t *ia32_get_code_generator_if(void *self) {
1677         return &ia32_code_gen_if;
1678 }
1679
1680 /**
1681  * Returns the estimated execution time of an ia32 irn.
1682  */
1683 static sched_timestep_t ia32_sched_exectime(void *env, const ir_node *irn) {
1684         const arch_env_t *arch_env = env;
1685         return is_ia32_irn(irn) ? ia32_get_op_estimated_cost(arch_get_irn_ops(arch_env, irn), irn) : 1;
1686 }
1687
1688 list_sched_selector_t ia32_sched_selector;
1689
1690 /**
1691  * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
1692  */
1693 static const list_sched_selector_t *ia32_get_list_sched_selector(const void *self, list_sched_selector_t *selector) {
1694         memcpy(&ia32_sched_selector, selector, sizeof(ia32_sched_selector));
1695         ia32_sched_selector.exectime              = ia32_sched_exectime;
1696         ia32_sched_selector.to_appear_in_schedule = ia32_to_appear_in_schedule;
1697         return &ia32_sched_selector;
1698 }
1699
1700 /**
1701  * Returns the necessary byte alignment for storing a register of given class.
1702  */
1703 static int ia32_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) {
1704         ir_mode *mode = arch_register_class_mode(cls);
1705         int bytes     = get_mode_size_bytes(mode);
1706
1707         if (mode_is_float(mode) && bytes > 8)
1708                 return 16;
1709         return bytes;
1710 }
1711
1712 static ia32_intrinsic_env_t intrinsic_env = { NULL, NULL };
1713
1714 /**
1715  * Returns the libFirm configuration parameter for this backend.
1716  */
1717 static const backend_params *ia32_get_libfirm_params(void) {
1718         static const arch_dep_params_t ad = {
1719                 1, /* also use subs */
1720                 4, /* maximum shifts */
1721                 31, /* maximum shift amount */
1722
1723                 1, /* allow Mulhs */
1724                 1, /* allow Mulus */
1725                 32  /* Mulh allowed up to 32 bit */
1726         };
1727         static backend_params p = {
1728                 NULL,  /* no additional opcodes */
1729                 NULL,  /* will be set later */
1730                 1,     /* need dword lowering */
1731                 ia32_create_intrinsic_fkt,
1732                 &intrinsic_env,  /* context for ia32_create_intrinsic_fkt */
1733         };
1734
1735         p.dep_param = &ad;
1736         return &p;
1737 }
1738 #ifdef WITH_LIBCORE
1739
1740 /* instruction set architectures. */
1741 static const lc_opt_enum_int_items_t arch_items[] = {
1742         { "386",        arch_i386, },
1743         { "486",        arch_i486, },
1744         { "pentium",    arch_pentium, },
1745         { "586",        arch_pentium, },
1746         { "pentiumpro", arch_pentium_pro, },
1747         { "686",        arch_pentium_pro, },
1748         { "pentiummmx", arch_pentium_mmx, },
1749         { "pentium2",   arch_pentium_2, },
1750         { "p2",         arch_pentium_2, },
1751         { "pentium3",   arch_pentium_3, },
1752         { "p3",         arch_pentium_3, },
1753         { "pentium4",   arch_pentium_4, },
1754         { "p4",         arch_pentium_4, },
1755         { "pentiumm",   arch_pentium_m, },
1756         { "pm",         arch_pentium_m, },
1757         { "core",       arch_core, },
1758         { "k6",         arch_k6, },
1759         { "athlon",     arch_athlon, },
1760         { "athlon64",   arch_athlon_64, },
1761         { "opteron",    arch_opteron, },
1762         { NULL,         0 }
1763 };
1764
1765 static lc_opt_enum_int_var_t arch_var = {
1766         &ia32_isa_template.arch, arch_items
1767 };
1768
1769 static lc_opt_enum_int_var_t opt_arch_var = {
1770         &ia32_isa_template.opt_arch, arch_items
1771 };
1772
1773 static const lc_opt_enum_int_items_t fp_unit_items[] = {
1774         { "x87" ,    fp_x87 },
1775         { "sse2",    fp_sse2 },
1776         { NULL,      0 }
1777 };
1778
1779 static lc_opt_enum_int_var_t fp_unit_var = {
1780         &ia32_isa_template.fp_kind, fp_unit_items
1781 };
1782
1783 static const lc_opt_enum_int_items_t gas_items[] = {
1784         { "linux",   ASM_LINUX_GAS },
1785         { "mingw",   ASM_MINGW_GAS },
1786         { NULL,      0 }
1787 };
1788
1789 static lc_opt_enum_int_var_t gas_var = {
1790         (int *)&asm_flavour, gas_items
1791 };
1792
1793 static const lc_opt_table_entry_t ia32_options[] = {
1794         LC_OPT_ENT_ENUM_INT("arch",      "select the instruction architecture", &arch_var),
1795         LC_OPT_ENT_ENUM_INT("opt",       "optimize for instruction architecture", &opt_arch_var),
1796         LC_OPT_ENT_ENUM_INT("fpunit",    "select the floating point unit", &fp_unit_var),
1797         LC_OPT_ENT_NEGBIT("noaddrmode",  "do not use address mode", &ia32_isa_template.opt, IA32_OPT_DOAM),
1798         LC_OPT_ENT_NEGBIT("nolea",       "do not optimize for LEAs", &ia32_isa_template.opt, IA32_OPT_LEA),
1799         LC_OPT_ENT_NEGBIT("noplacecnst", "do not place constants", &ia32_isa_template.opt, IA32_OPT_PLACECNST),
1800         LC_OPT_ENT_NEGBIT("noimmop",     "no operations with immediates", &ia32_isa_template.opt, IA32_OPT_IMMOPS),
1801         LC_OPT_ENT_NEGBIT("noextbb",     "do not use extended basic block scheduling", &ia32_isa_template.opt, IA32_OPT_EXTBB),
1802         LC_OPT_ENT_ENUM_INT("gasmode",   "set the GAS compatibility mode", &gas_var),
1803         { NULL }
1804 };
1805
1806 /**
1807  * Register command line options for the ia32 backend.
1808  *
1809  * Options so far:
1810  *
1811  * ia32-arch=arch    create instruction for arch
1812  * ia32-opt=arch     optimize for run on arch
1813  * ia32-fpunit=unit  select floating point unit (x87 or SSE2)
1814  * ia32-incdec       optimize for inc/dec
1815  * ia32-noaddrmode   do not use address mode
1816  * ia32-nolea        do not optimize for LEAs
1817  * ia32-noplacecnst  do not place constants,
1818  * ia32-noimmop      no operations with immediates
1819  * ia32-noextbb      do not use extended basic block scheduling
1820  * ia32-gasmode      set the GAS compatibility mode
1821  */
1822 static void ia32_register_options(lc_opt_entry_t *ent)
1823 {
1824         lc_opt_entry_t *be_grp_ia32 = lc_opt_get_grp(ent, "ia32");
1825         lc_opt_add_table(be_grp_ia32, ia32_options);
1826 }
1827 #endif /* WITH_LIBCORE */
1828
1829 const arch_isa_if_t ia32_isa_if = {
1830         ia32_init,
1831         ia32_done,
1832         ia32_get_n_reg_class,
1833         ia32_get_reg_class,
1834         ia32_get_reg_class_for_mode,
1835         ia32_get_call_abi,
1836         ia32_get_irn_handler,
1837         ia32_get_code_generator_if,
1838         ia32_get_list_sched_selector,
1839         ia32_get_reg_class_alignment,
1840         ia32_get_libfirm_params,
1841 #ifdef WITH_LIBCORE
1842         ia32_register_options
1843 #endif
1844 };