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