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