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