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