2 * This is the main ia32 firm backend driver.
3 * @author Christian Wuerdig
18 #include <libcore/lc_opts.h>
19 #include <libcore/lc_opts_enum.h>
23 #include "pseudo_irg.h"
27 #include "iredges_t.h"
40 #include "../benode_t.h"
41 #include "../belower.h"
42 #include "../besched_t.h"
45 #include "../beirgmod.h"
46 #include "../be_dbgout.h"
47 #include "../beblocksched.h"
48 #include "../bemachine.h"
49 #include "../beilpsched.h"
50 #include "../bespillslots.h"
51 #include "../bemodule.h"
52 #include "../begnuas.h"
54 #include "bearch_ia32_t.h"
56 #include "ia32_new_nodes.h"
57 #include "gen_ia32_regalloc_if.h"
58 #include "gen_ia32_machine.h"
59 #include "ia32_transform.h"
60 #include "ia32_emitter.h"
61 #include "ia32_map_regs.h"
62 #include "ia32_optimize.h"
64 #include "ia32_dbg_stat.h"
65 #include "ia32_finish.h"
66 #include "ia32_util.h"
69 static set *cur_reg_set = NULL;
71 typedef ir_node *(*create_const_node_func) (dbg_info *dbg, ir_graph *irg, ir_node *block);
73 static INLINE ir_node *create_const(ia32_code_gen_t *cg, ir_node **place,
74 create_const_node_func func,
85 block = get_irg_start_block(cg->irg);
86 res = func(NULL, cg->irg, block);
87 arch_set_irn_register(cg->arch_env, res, reg);
90 /* keep the node so it isn't accidently removed when unused ... */
92 keep = be_new_Keep(arch_register_get_class(reg), cg->irg, block, 1, in);
94 /* schedule the node if we already have a scheduled program */
95 startnode = get_irg_start(cg->irg);
96 if(sched_is_scheduled(startnode)) {
97 sched_add_after(startnode, res);
98 sched_add_after(res, keep);
104 /* Creates the unique per irg GP NoReg node. */
105 ir_node *ia32_new_NoReg_gp(ia32_code_gen_t *cg) {
106 return create_const(cg, &cg->noreg_gp, new_rd_ia32_NoReg_GP,
107 &ia32_gp_regs[REG_GP_NOREG]);
110 ir_node *ia32_new_NoReg_vfp(ia32_code_gen_t *cg) {
111 return create_const(cg, &cg->noreg_vfp, new_rd_ia32_NoReg_VFP,
112 &ia32_vfp_regs[REG_VFP_NOREG]);
115 ir_node *ia32_new_NoReg_xmm(ia32_code_gen_t *cg) {
116 return create_const(cg, &cg->noreg_xmm, new_rd_ia32_NoReg_XMM,
117 &ia32_xmm_regs[REG_XMM_NOREG]);
120 /* Creates the unique per irg FP NoReg node. */
121 ir_node *ia32_new_NoReg_fp(ia32_code_gen_t *cg) {
122 return USE_SSE2(cg) ? ia32_new_NoReg_xmm(cg) : ia32_new_NoReg_vfp(cg);
125 ir_node *ia32_new_Unknown_gp(ia32_code_gen_t *cg) {
126 return create_const(cg, &cg->unknown_gp, new_rd_ia32_Unknown_GP,
127 &ia32_gp_regs[REG_GP_UKNWN]);
130 ir_node *ia32_new_Unknown_vfp(ia32_code_gen_t *cg) {
131 return create_const(cg, &cg->unknown_vfp, new_rd_ia32_Unknown_VFP,
132 &ia32_vfp_regs[REG_VFP_UKNWN]);
135 ir_node *ia32_new_Unknown_xmm(ia32_code_gen_t *cg) {
136 return create_const(cg, &cg->unknown_xmm, new_rd_ia32_Unknown_XMM,
137 &ia32_xmm_regs[REG_XMM_UKNWN]);
142 * Returns gp_noreg or fp_noreg, depending in input requirements.
144 ir_node *ia32_get_admissible_noreg(ia32_code_gen_t *cg, ir_node *irn, int pos) {
145 const arch_register_req_t *req;
147 req = arch_get_register_req(cg->arch_env, irn, pos);
148 assert(req != NULL && "Missing register requirements");
149 if (req->cls == &ia32_reg_classes[CLASS_ia32_gp])
150 return ia32_new_NoReg_gp(cg);
152 return ia32_new_NoReg_fp(cg);
155 /**************************************************
158 * _ __ ___ __ _ __ _| | | ___ ___ _| |_
159 * | '__/ _ \/ _` | / _` | | |/ _ \ / __| | | _|
160 * | | | __/ (_| | | (_| | | | (_) | (__ | | |
161 * |_| \___|\__, | \__,_|_|_|\___/ \___| |_|_|
164 **************************************************/
167 * Return register requirements for an ia32 node.
168 * If the node returns a tuple (mode_T) then the proj's
169 * will be asked for this information.
171 static const arch_register_req_t *ia32_get_irn_reg_req(const void *self,
174 long node_pos = pos == -1 ? 0 : pos;
175 ir_mode *mode = is_Block(node) ? NULL : get_irn_mode(node);
177 if (is_Block(node) || mode == mode_X) {
178 return arch_no_register_req;
181 if (mode == mode_T && pos < 0) {
182 return arch_no_register_req;
187 return arch_no_register_req;
190 return arch_no_register_req;
193 node_pos = (pos == -1) ? get_Proj_proj(node) : pos;
194 node = skip_Proj_const(node);
197 if (is_ia32_irn(node)) {
198 const arch_register_req_t *req;
200 req = get_ia32_in_req(node, pos);
202 req = get_ia32_out_req(node, node_pos);
209 /* unknowns should be transformed already */
210 assert(!is_Unknown(node));
212 return arch_no_register_req;
215 static void ia32_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
218 if (get_irn_mode(irn) == mode_X) {
223 pos = get_Proj_proj(irn);
224 irn = skip_Proj(irn);
227 if (is_ia32_irn(irn)) {
228 const arch_register_t **slots;
230 slots = get_ia32_slots(irn);
233 ia32_set_firm_reg(irn, reg, cur_reg_set);
237 static const arch_register_t *ia32_get_irn_reg(const void *self, const ir_node *irn) {
239 const arch_register_t *reg = NULL;
243 if (get_irn_mode(irn) == mode_X) {
247 pos = get_Proj_proj(irn);
248 irn = skip_Proj_const(irn);
251 if (is_ia32_irn(irn)) {
252 const arch_register_t **slots;
253 slots = get_ia32_slots(irn);
256 reg = ia32_get_firm_reg(irn, cur_reg_set);
262 static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
263 arch_irn_class_t classification = arch_irn_class_normal;
265 irn = skip_Proj_const(irn);
268 classification |= arch_irn_class_branch;
270 if (! is_ia32_irn(irn))
271 return classification & ~arch_irn_class_normal;
273 if (is_ia32_Cnst(irn))
274 classification |= arch_irn_class_const;
277 classification |= arch_irn_class_load;
279 if (is_ia32_St(irn) || is_ia32_Store8Bit(irn))
280 classification |= arch_irn_class_store;
282 if (is_ia32_need_stackent(irn))
283 classification |= arch_irn_class_reload;
285 return classification;
288 static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
289 arch_irn_flags_t flags = arch_irn_flags_none;
292 return arch_irn_flags_ignore;
294 if(is_Proj(irn) && mode_is_datab(get_irn_mode(irn))) {
295 ir_node *pred = get_Proj_pred(irn);
297 if(is_ia32_irn(pred)) {
298 flags = get_ia32_out_flags(pred, get_Proj_proj(irn));
304 if (is_ia32_irn(irn)) {
305 flags |= get_ia32_flags(irn);
312 * The IA32 ABI callback object.
315 be_abi_call_flags_bits_t flags; /**< The call flags. */
316 const arch_isa_t *isa; /**< The ISA handle. */
317 const arch_env_t *aenv; /**< The architecture environment. */
318 ir_graph *irg; /**< The associated graph. */
321 static ir_entity *ia32_get_frame_entity(const void *self, const ir_node *irn) {
322 return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL;
325 static void ia32_set_frame_entity(const void *self, ir_node *irn, ir_entity *ent) {
326 set_ia32_frame_ent(irn, ent);
329 static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) {
330 const ia32_irn_ops_t *ops = self;
332 if (get_ia32_frame_ent(irn)) {
333 ia32_am_flavour_t am_flav;
335 if (is_ia32_Pop(irn)) {
336 int omit_fp = be_abi_omit_fp(ops->cg->birg->abi);
338 /* Pop nodes modify the stack pointer before calculating the destination
339 * address, so fix this here
345 am_flav = get_ia32_am_flavour(irn);
347 set_ia32_am_flavour(irn, am_flav);
349 add_ia32_am_offs_int(irn, bias);
353 static int ia32_get_sp_bias(const void *self, const ir_node *irn) {
355 long proj = get_Proj_proj(irn);
356 ir_node *pred = get_Proj_pred(irn);
358 if (is_ia32_Push(pred) && proj == pn_ia32_Push_stack)
360 if (is_ia32_Pop(pred) && proj == pn_ia32_Pop_stack)
368 * Put all registers which are saved by the prologue/epilogue in a set.
370 * @param self The callback object.
371 * @param s The result set.
373 static void ia32_abi_dont_save_regs(void *self, pset *s)
375 ia32_abi_env_t *env = self;
376 if(env->flags.try_omit_fp)
377 pset_insert_ptr(s, env->isa->bp);
382 static void get_regparams_startbarrier(ir_graph *irg, ir_node **regparams, ir_node **startbarrier)
384 const ir_edge_t *edge;
385 ir_node *start_block = get_irg_start_block(irg);
388 *startbarrier = NULL;
389 foreach_out_edge(start_block, edge) {
390 ir_node *src = get_edge_src_irn(edge);
392 if(be_is_RegParams(src)) {
394 if(*startbarrier != NULL)
397 if(be_is_Barrier(src)) {
399 if(*regparams != NULL)
404 panic("Couldn't find regparams and startbarrier!");
407 static void add_fpu_edges(be_irg_t *birg)
409 ir_graph *irg = be_get_birg_irg(birg);
411 ir_node *startbarrier;
414 const arch_env_t *arch_env = birg->main_env->arch_env;
415 const arch_register_t *reg = &ia32_fp_cw_regs[REG_FPCW];
419 get_regparams_startbarrier(irg, ®params, &startbarrier);
421 fp_cw_reg = be_RegParams_append_out_reg(regparams, arch_env, reg);
423 fp_cw_reg = be_Barrier_append_node(startbarrier, fp_cw_reg);
424 pos = get_Proj_proj(fp_cw_reg);
425 be_set_constr_single_reg(startbarrier, BE_OUT_POS(pos), reg);
426 arch_set_irn_register(arch_env, fp_cw_reg, reg);
429 end_block = get_irg_end_block(irg);
430 arity = get_irn_arity(end_block);
431 for(i = 0; i < arity; ++i) {
433 ir_node *ret = get_irn_n(end_block, i);
434 ir_node *end_barrier = NULL;
435 ir_node *fp_cw_after_end_barrier;
436 if(!be_is_Return(ret))
439 /* search the barrier before the return */
440 arity2 = get_irn_arity(ret);
441 for(i2 = 0; i2 < arity2; i2++) {
442 ir_node *proj = get_irn_n(ret, i2);
447 end_barrier = get_Proj_pred(proj);
448 if(!be_is_Barrier(end_barrier))
452 assert(end_barrier != NULL);
454 /* add fp_cw to the barrier */
455 fp_cw_after_end_barrier = be_Barrier_append_node(end_barrier, fp_cw_reg);
456 pos = get_Proj_proj(fp_cw_after_end_barrier);
457 be_set_constr_single_reg(end_barrier, BE_OUT_POS(pos), reg);
458 arch_set_irn_register(arch_env, fp_cw_after_end_barrier, reg);
460 /* and append it to the return node */
461 be_Return_append_node(ret, fp_cw_after_end_barrier);
468 static unsigned count_callee_saves(ia32_code_gen_t *cg)
470 unsigned callee_saves = 0;
471 int c, num_reg_classes;
474 num_reg_classes = arch_isa_get_n_reg_class(isa);
475 for(c = 0; c < num_reg_classes; ++c) {
476 int r, num_registers;
477 arch_register_class_t *regclass = arch_isa_get_reg_class(isa, c);
479 num_registers = arch_register_class_n_regs(regclass);
480 for(r = 0; r < num_registers; ++r) {
481 arch_register_t *reg = arch_register_for_index(regclass, r);
482 if(arch_register_type_is(reg, callee_save))
490 static void create_callee_save_regprojs(ia32_code_gen_t *cg, ir_node *regparams)
492 int c, num_reg_classes;
496 num_reg_classes = arch_isa_get_n_reg_class(isa);
497 cg->initial_regs = obstack_alloc(cg->obst,
498 num_reg_classes * sizeof(cg->initial_regs[0]));
500 for(c = 0; c < num_reg_classes; ++c) {
501 int r, num_registers;
502 ir_node **initial_regclass;
503 arch_register_class_t *regclass = arch_isa_get_reg_class(isa, c);
505 num_registers = arch_register_class_n_regs(regclass);
506 initial_regclass = obstack_alloc(num_registers * sizeof(initial_regclass[0]));
507 for(r = 0; r < num_registers; ++r) {
509 arch_register_t *reg = arch_register_for_index(regclass, r);
510 if(!arch_register_type_is(reg, callee_save))
513 proj = new_r_Proj(irg, start_block, regparams, n);
514 be_set_constr_single_reg(regparams, n, reg);
515 arch_set_irn_register(cg->arch_env, proj, reg);
517 initial_regclass[r] = proj;
520 cg->initial_regs[c] = initial_regclass;
524 static void callee_saves_obstack_grow(ia32_code_gen_t *cg)
526 int c, num_reg_classes;
529 for(c = 0; c < num_reg_classes; ++c) {
530 int r, num_registers;
532 num_registers = arch_register_class_n_regs(regclass);
533 for(r = 0; r < num_registers; ++r) {
535 arch_register_t *reg = arch_register_for_index(regclass, r);
536 if(!arch_register_type_is(reg, callee_save))
539 proj = cg->initial_regs[c][r];
540 obstack_ptr_grow(cg->obst, proj);
545 static unsigned count_parameters_in_regs(ia32_code_gen_t *cg)
550 static void ia32_gen_prologue(ia32_code_gen_t *cg)
552 ir_graph *irg = cg->irg;
553 ir_node *start_block = get_irg_start_block(irg);
558 /* Create the regparams node */
559 n_regparams_out = count_callee_saves(cg) + count_parameters_in_regs(cg);
560 regparams = be_new_RegParams(irg, start_block, n_regparams_out);
562 create_callee_save_regprojs(cg, regparams);
564 /* Setup the stack */
566 ir_node *bl = get_irg_start_block(env->irg);
567 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
568 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
569 ir_node *noreg = ia32_new_NoReg_gp(cg);
573 push = new_rd_ia32_Push(NULL, env->irg, bl, noreg, noreg, curr_bp, curr_sp, *mem);
574 curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
575 *mem = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
577 /* the push must have SP out register */
578 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
579 set_ia32_flags(push, arch_irn_flags_ignore);
581 /* move esp to ebp */
582 curr_bp = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
583 be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
584 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
585 be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
587 /* beware: the copy must be done before any other sp use */
588 curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
589 be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
590 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
591 be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
593 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
594 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
597 sp = be_new_IncSP(sp, irg, start_block, initialsp, BE_STACK_FRAME_SIZE_EXPAND);
598 set_irg_frame(irg, sp);
601 static void ia32_gen_epilogue(ia32_code_gen_t *cg)
603 int n_callee_saves = count_callee_saves(cg);
604 int n_results_regs = 0;
607 ir_node *end_block = get_irg_end_block(irg);
610 /* We have to make sure that all reloads occur before the stack frame
611 gets destroyed, so we create a barrier for all callee-save and return
613 barrier_size = n_callee_saves + n_results_regs;
614 barrier = be_new_Barrier(irg, end_block, barrier_size,
616 /* simply remove the stack frame here */
617 curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK);
618 add_irn_dep(curr_sp, *mem);
623 * Generate the routine prologue.
625 * @param self The callback object.
626 * @param mem A pointer to the mem node. Update this if you define new memory.
627 * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
629 * @return The register which shall be used as a stack frame base.
631 * All nodes which define registers in @p reg_map must keep @p reg_map current.
633 static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
635 ia32_abi_env_t *env = self;
636 const ia32_isa_t *isa = (ia32_isa_t *)env->isa;
637 ia32_code_gen_t *cg = isa->cg;
639 if (! env->flags.try_omit_fp) {
640 ir_node *bl = get_irg_start_block(env->irg);
641 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
642 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
643 ir_node *noreg = ia32_new_NoReg_gp(cg);
647 push = new_rd_ia32_Push(NULL, env->irg, bl, noreg, noreg, curr_bp, curr_sp, *mem);
648 curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
649 *mem = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
651 /* the push must have SP out register */
652 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
653 set_ia32_flags(push, arch_irn_flags_ignore);
655 /* move esp to ebp */
656 curr_bp = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
657 be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
658 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
659 be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
661 /* beware: the copy must be done before any other sp use */
662 curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
663 be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
664 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
665 be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
667 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
668 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
677 * Generate the routine epilogue.
678 * @param self The callback object.
679 * @param bl The block for the epilog
680 * @param mem A pointer to the mem node. Update this if you define new memory.
681 * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
682 * @return The register which shall be used as a stack frame base.
684 * All nodes which define registers in @p reg_map must keep @p reg_map current.
686 static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
688 ia32_abi_env_t *env = self;
689 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
690 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
692 if (env->flags.try_omit_fp) {
693 /* simply remove the stack frame here */
694 curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK);
695 add_irn_dep(curr_sp, *mem);
697 const ia32_isa_t *isa = (ia32_isa_t *)env->isa;
698 ia32_code_gen_t *cg = isa->cg;
699 ir_mode *mode_bp = env->isa->bp->reg_class->mode;
701 /* gcc always emits a leave at the end of a routine */
702 if (1 || ARCH_AMD(isa->opt_arch)) {
706 leave = new_rd_ia32_Leave(NULL, env->irg, bl, curr_sp, curr_bp);
707 set_ia32_flags(leave, arch_irn_flags_ignore);
708 curr_bp = new_r_Proj(current_ir_graph, bl, leave, mode_bp, pn_ia32_Leave_frame);
709 curr_sp = new_r_Proj(current_ir_graph, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
711 ir_node *noreg = ia32_new_NoReg_gp(cg);
714 /* copy ebp to esp */
715 curr_sp = be_new_SetSP(env->isa->sp, env->irg, bl, curr_sp, curr_bp, *mem);
718 pop = new_rd_ia32_Pop(NULL, env->irg, bl, noreg, noreg, curr_sp, *mem);
719 set_ia32_flags(pop, arch_irn_flags_ignore);
720 curr_bp = new_r_Proj(current_ir_graph, bl, pop, mode_bp, pn_ia32_Pop_res);
721 curr_sp = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
723 *mem = new_r_Proj(current_ir_graph, bl, pop, mode_M, pn_ia32_Pop_M);
725 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
726 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
729 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
730 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
734 * Initialize the callback object.
735 * @param call The call object.
736 * @param aenv The architecture environment.
737 * @param irg The graph with the method.
738 * @return Some pointer. This pointer is passed to all other callback functions as self object.
740 static void *ia32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg)
742 ia32_abi_env_t *env = xmalloc(sizeof(env[0]));
743 be_abi_call_flags_t fl = be_abi_call_get_flags(call);
744 env->flags = fl.bits;
747 env->isa = aenv->isa;
752 * Destroy the callback object.
753 * @param self The callback object.
755 static void ia32_abi_done(void *self) {
760 * Produces the type which sits between the stack args and the locals on the stack.
761 * it will contain the return address and space to store the old base pointer.
762 * @return The Firm type modeling the ABI between type.
764 static ir_type *ia32_abi_get_between_type(void *self)
766 #define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
767 static ir_type *omit_fp_between_type = NULL;
768 static ir_type *between_type = NULL;
770 ia32_abi_env_t *env = self;
772 if (! between_type) {
773 ir_entity *old_bp_ent;
774 ir_entity *ret_addr_ent;
775 ir_entity *omit_fp_ret_addr_ent;
777 ir_type *old_bp_type = new_type_primitive(IDENT("bp"), mode_Iu);
778 ir_type *ret_addr_type = new_type_primitive(IDENT("return_addr"), mode_Iu);
780 between_type = new_type_struct(IDENT("ia32_between_type"));
781 old_bp_ent = new_entity(between_type, IDENT("old_bp"), old_bp_type);
782 ret_addr_ent = new_entity(between_type, IDENT("ret_addr"), ret_addr_type);
784 set_entity_offset(old_bp_ent, 0);
785 set_entity_offset(ret_addr_ent, get_type_size_bytes(old_bp_type));
786 set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
787 set_type_state(between_type, layout_fixed);
789 omit_fp_between_type = new_type_struct(IDENT("ia32_between_type_omit_fp"));
790 omit_fp_ret_addr_ent = new_entity(omit_fp_between_type, IDENT("ret_addr"), ret_addr_type);
792 set_entity_offset(omit_fp_ret_addr_ent, 0);
793 set_type_size_bytes(omit_fp_between_type, get_type_size_bytes(ret_addr_type));
794 set_type_state(omit_fp_between_type, layout_fixed);
797 return env->flags.try_omit_fp ? omit_fp_between_type : between_type;
802 * Get the estimated cycle count for @p irn.
804 * @param self The this pointer.
805 * @param irn The node.
807 * @return The estimated cycle count for this operation
809 static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
812 ia32_op_type_t op_tp;
813 const ia32_irn_ops_t *ops = self;
817 if (!is_ia32_irn(irn))
820 assert(is_ia32_irn(irn));
822 cost = get_ia32_latency(irn);
823 op_tp = get_ia32_op_type(irn);
825 if (is_ia32_CopyB(irn)) {
827 if (ARCH_INTEL(ops->cg->arch))
830 else if (is_ia32_CopyB_i(irn)) {
831 int size = get_tarval_long(get_ia32_Immop_tarval(irn));
832 cost = 20 + (int)ceil((4/3) * size);
833 if (ARCH_INTEL(ops->cg->arch))
836 /* in case of address mode operations add additional cycles */
837 else if (op_tp == ia32_AddrModeD || op_tp == ia32_AddrModeS) {
839 In case of stack access add 5 cycles (we assume stack is in cache),
840 other memory operations cost 20 cycles.
842 cost += is_ia32_use_frame(irn) ? 5 : 20;
849 * Returns the inverse operation if @p irn, recalculating the argument at position @p i.
851 * @param irn The original operation
852 * @param i Index of the argument we want the inverse operation to yield
853 * @param inverse struct to be filled with the resulting inverse op
854 * @param obstack The obstack to use for allocation of the returned nodes array
855 * @return The inverse operation or NULL if operation invertible
857 static arch_inverse_t *ia32_get_inverse(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst) {
861 ir_node *block, *noreg, *nomem;
864 /* we cannot invert non-ia32 irns */
865 if (! is_ia32_irn(irn))
868 /* operand must always be a real operand (not base, index or mem) */
869 if (i != 2 && i != 3)
872 /* we don't invert address mode operations */
873 if (get_ia32_op_type(irn) != ia32_Normal)
876 irg = get_irn_irg(irn);
877 block = get_nodes_block(irn);
878 mode = get_irn_mode(irn);
879 irn_mode = get_irn_mode(irn);
880 noreg = get_irn_n(irn, 0);
881 nomem = new_r_NoMem(irg);
882 dbg = get_irn_dbg_info(irn);
884 /* initialize structure */
885 inverse->nodes = obstack_alloc(obst, 2 * sizeof(inverse->nodes[0]));
889 switch (get_ia32_irn_opcode(irn)) {
891 if (get_ia32_immop_type(irn) == ia32_ImmConst) {
892 /* we have an add with a const here */
893 /* invers == add with negated const */
894 inverse->nodes[0] = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
896 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
897 set_ia32_Immop_tarval(inverse->nodes[0], tarval_neg(get_ia32_Immop_tarval(irn)));
898 set_ia32_commutative(inverse->nodes[0]);
900 else if (get_ia32_immop_type(irn) == ia32_ImmSymConst) {
901 /* we have an add with a symconst here */
902 /* invers == sub with const */
903 inverse->nodes[0] = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
905 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
908 /* normal add: inverse == sub */
909 inverse->nodes[0] = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, (ir_node*) irn, get_irn_n(irn, i ^ 1), nomem);
914 if (get_ia32_immop_type(irn) != ia32_ImmNone) {
915 /* we have a sub with a const/symconst here */
916 /* invers == add with this const */
917 inverse->nodes[0] = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
918 inverse->costs += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
919 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
924 inverse->nodes[0] = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, (ir_node*) irn, get_irn_n(irn, 3), nomem);
927 inverse->nodes[0] = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, get_irn_n(irn, 2), (ir_node*) irn, nomem);
933 if (get_ia32_immop_type(irn) != ia32_ImmNone) {
934 /* xor with const: inverse = xor */
935 inverse->nodes[0] = new_rd_ia32_Xor(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
936 inverse->costs += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
937 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
941 inverse->nodes[0] = new_rd_ia32_Xor(dbg, irg, block, noreg, noreg, (ir_node *) irn, get_irn_n(irn, i), nomem);
946 inverse->nodes[0] = new_rd_ia32_Not(dbg, irg, block, noreg, noreg, (ir_node*) irn, nomem);
951 inverse->nodes[0] = new_rd_ia32_Neg(dbg, irg, block, noreg, noreg, (ir_node*) irn, nomem);
956 /* inverse operation not supported */
963 static ir_mode *get_spill_mode_mode(const ir_mode *mode)
965 if(mode_is_float(mode))
972 * Get the mode that should be used for spilling value node
974 static ir_mode *get_spill_mode(const ir_node *node)
976 ir_mode *mode = get_irn_mode(node);
977 return get_spill_mode_mode(mode);
981 * Checks wether an addressmode reload for a node with mode mode is compatible
982 * with a spillslot of mode spill_mode
984 static int ia32_is_spillmode_compatible(const ir_mode *mode, const ir_mode *spillmode)
986 if(mode_is_float(mode)) {
987 return mode == spillmode;
994 * Check if irn can load it's operand at position i from memory (source addressmode).
995 * @param self Pointer to irn ops itself
996 * @param irn The irn to be checked
997 * @param i The operands position
998 * @return Non-Zero if operand can be loaded
1000 static int ia32_possible_memory_operand(const void *self, const ir_node *irn, unsigned int i) {
1001 ir_node *op = get_irn_n(irn, i);
1002 const ir_mode *mode = get_irn_mode(op);
1003 const ir_mode *spillmode = get_spill_mode(op);
1005 if (! is_ia32_irn(irn) || /* must be an ia32 irn */
1006 get_irn_arity(irn) != 5 || /* must be a binary operation */
1007 get_ia32_op_type(irn) != ia32_Normal || /* must not already be a addressmode irn */
1008 ! (get_ia32_am_support(irn) & ia32_am_Source) || /* must be capable of source addressmode */
1009 ! ia32_is_spillmode_compatible(mode, spillmode) ||
1010 (i != 2 && i != 3) || /* a "real" operand position must be requested */
1011 (i == 2 && ! is_ia32_commutative(irn)) || /* if first operand requested irn must be commutative */
1012 is_ia32_use_frame(irn)) /* must not already use frame */
1018 static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node *spill, unsigned int i) {
1019 const ia32_irn_ops_t *ops = self;
1020 ia32_code_gen_t *cg = ops->cg;
1022 assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
1025 ir_node *tmp = get_irn_n(irn, 3);
1026 set_irn_n(irn, 3, get_irn_n(irn, 2));
1027 set_irn_n(irn, 2, tmp);
1030 set_ia32_am_support(irn, ia32_am_Source);
1031 set_ia32_op_type(irn, ia32_AddrModeS);
1032 set_ia32_am_flavour(irn, ia32_B);
1033 set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i)));
1034 set_ia32_use_frame(irn);
1035 set_ia32_need_stackent(irn);
1037 set_irn_n(irn, 0, get_irg_frame(get_irn_irg(irn)));
1038 set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
1039 set_irn_n(irn, 4, spill);
1041 //FIXME DBG_OPT_AM_S(reload, irn);
1044 static const be_abi_callbacks_t ia32_abi_callbacks = {
1047 ia32_abi_get_between_type,
1048 ia32_abi_dont_save_regs,
1053 /* fill register allocator interface */
1055 static const arch_irn_ops_if_t ia32_irn_ops_if = {
1056 ia32_get_irn_reg_req,
1061 ia32_get_frame_entity,
1062 ia32_set_frame_entity,
1063 ia32_set_frame_offset,
1066 ia32_get_op_estimated_cost,
1067 ia32_possible_memory_operand,
1068 ia32_perform_memory_operand,
1071 ia32_irn_ops_t ia32_irn_ops = {
1078 /**************************************************
1081 * ___ ___ __| | ___ __ _ ___ _ __ _| |_
1082 * / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \ | | _|
1083 * | (_| (_) | (_| | __/ (_| | __/ | | | | | |
1084 * \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
1087 **************************************************/
1090 * Transforms the standard firm graph into
1091 * an ia32 firm graph
1093 static void ia32_prepare_graph(void *self) {
1094 ia32_code_gen_t *cg = self;
1095 DEBUG_ONLY(firm_dbg_module_t *old_mod = cg->mod;)
1097 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.transform");
1099 /* transform psi condition trees */
1100 ia32_pre_transform_phase(cg);
1102 /* transform all remaining nodes */
1103 ia32_transform_graph(cg);
1104 //add_fpu_edges(cg->birg);
1106 // Matze: disabled for now. Because after transformation start block has no
1107 // self-loop anymore so it might be merged with its successor block. This
1108 // will bring several nodes to the startblock which sometimes get scheduled
1109 // before the initial IncSP/Barrier
1110 //local_optimize_graph(cg->irg);
1113 be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
1115 /* optimize address mode */
1116 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.am");
1117 ia32_optimize_addressmode(cg);
1120 be_dump(cg->irg, "-am", dump_ir_block_graph_sched);
1122 /* do code placement, to optimize the position of constants */
1123 place_code(cg->irg);
1126 be_dump(cg->irg, "-place", dump_ir_block_graph_sched);
1128 DEBUG_ONLY(cg->mod = old_mod;)
1132 * Dummy functions for hooks we don't need but which must be filled.
1134 static void ia32_before_sched(void *self) {
1137 static void remove_unused_nodes(ir_node *irn, bitset_t *already_visited) {
1140 ir_node *mem_proj = NULL;
1145 mode = get_irn_mode(irn);
1147 /* check if we already saw this node or the node has more than one user */
1148 if (bitset_contains_irn(already_visited, irn) || get_irn_n_edges(irn) > 1) {
1152 /* mark irn visited */
1153 bitset_add_irn(already_visited, irn);
1155 /* non-Tuple nodes with one user: ok, return */
1156 if (get_irn_n_edges(irn) >= 1 && mode != mode_T) {
1160 /* tuple node has one user which is not the mem proj-> ok */
1161 if (mode == mode_T && get_irn_n_edges(irn) == 1) {
1162 mem_proj = ia32_get_proj_for_mode(irn, mode_M);
1163 if (mem_proj == NULL) {
1168 arity = get_irn_arity(irn);
1169 for (i = 0; i < arity; ++i) {
1170 ir_node *pred = get_irn_n(irn, i);
1172 /* do not follow memory edges or we will accidentally remove stores */
1173 if (get_irn_mode(pred) == mode_M) {
1174 if(mem_proj != NULL) {
1175 edges_reroute(mem_proj, pred, get_irn_irg(mem_proj));
1181 set_irn_n(irn, i, new_Bad());
1184 The current node is about to be removed: if the predecessor
1185 has only this node as user, it need to be removed as well.
1187 if (get_irn_n_edges(pred) <= 1)
1188 remove_unused_nodes(pred, already_visited);
1191 // we need to set the presd to Bad again to also get the memory edges
1192 arity = get_irn_arity(irn);
1193 for (i = 0; i < arity; ++i) {
1194 set_irn_n(irn, i, new_Bad());
1197 if (sched_is_scheduled(irn)) {
1202 static void remove_unused_loads_walker(ir_node *irn, void *env) {
1203 bitset_t *already_visited = env;
1204 if (is_ia32_Ld(irn) && ! bitset_contains_irn(already_visited, irn))
1205 remove_unused_nodes(irn, env);
1209 * Called before the register allocator.
1210 * Calculate a block schedule here. We need it for the x87
1211 * simulator and the emitter.
1213 static void ia32_before_ra(void *self) {
1214 ia32_code_gen_t *cg = self;
1215 bitset_t *already_visited = bitset_irg_alloca(cg->irg);
1218 Handle special case:
1219 There are sometimes unused loads, only pinned by memory.
1220 We need to remove those Loads and all other nodes which won't be used
1221 after removing the Load from schedule.
1223 irg_walk_graph(cg->irg, NULL, remove_unused_loads_walker, already_visited);
1228 * Transforms a be_Reload into a ia32 Load.
1230 static void transform_to_Load(ia32_code_gen_t *cg, ir_node *node) {
1231 ir_graph *irg = get_irn_irg(node);
1232 dbg_info *dbg = get_irn_dbg_info(node);
1233 ir_node *block = get_nodes_block(node);
1234 ir_entity *ent = be_get_frame_entity(node);
1235 ir_mode *mode = get_irn_mode(node);
1236 ir_mode *spillmode = get_spill_mode(node);
1237 ir_node *noreg = ia32_new_NoReg_gp(cg);
1238 ir_node *sched_point = NULL;
1239 ir_node *ptr = get_irg_frame(irg);
1240 ir_node *mem = get_irn_n(node, be_pos_Reload_mem);
1241 ir_node *new_op, *proj;
1242 const arch_register_t *reg;
1244 if (sched_is_scheduled(node)) {
1245 sched_point = sched_prev(node);
1248 if (mode_is_float(spillmode)) {
1250 new_op = new_rd_ia32_xLoad(dbg, irg, block, ptr, noreg, mem);
1252 new_op = new_rd_ia32_vfld(dbg, irg, block, ptr, noreg, mem);
1254 else if (get_mode_size_bits(spillmode) == 128) {
1255 // Reload 128 bit sse registers
1256 new_op = new_rd_ia32_xxLoad(dbg, irg, block, ptr, noreg, mem);
1259 new_op = new_rd_ia32_Load(dbg, irg, block, ptr, noreg, mem);
1261 set_ia32_am_support(new_op, ia32_am_Source);
1262 set_ia32_op_type(new_op, ia32_AddrModeS);
1263 set_ia32_am_flavour(new_op, ia32_B);
1264 set_ia32_ls_mode(new_op, spillmode);
1265 set_ia32_frame_ent(new_op, ent);
1266 set_ia32_use_frame(new_op);
1268 DBG_OPT_RELOAD2LD(node, new_op);
1270 proj = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Load_res);
1273 sched_add_after(sched_point, new_op);
1274 sched_add_after(new_op, proj);
1279 /* copy the register from the old node to the new Load */
1280 reg = arch_get_irn_register(cg->arch_env, node);
1281 arch_set_irn_register(cg->arch_env, new_op, reg);
1283 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1285 exchange(node, proj);
1289 * Transforms a be_Spill node into a ia32 Store.
1291 static void transform_to_Store(ia32_code_gen_t *cg, ir_node *node) {
1292 ir_graph *irg = get_irn_irg(node);
1293 dbg_info *dbg = get_irn_dbg_info(node);
1294 ir_node *block = get_nodes_block(node);
1295 ir_entity *ent = be_get_frame_entity(node);
1296 const ir_node *spillval = get_irn_n(node, be_pos_Spill_val);
1297 ir_mode *mode = get_spill_mode(spillval);
1298 ir_node *noreg = ia32_new_NoReg_gp(cg);
1299 ir_node *nomem = new_rd_NoMem(irg);
1300 ir_node *ptr = get_irg_frame(irg);
1301 ir_node *val = get_irn_n(node, be_pos_Spill_val);
1303 ir_node *sched_point = NULL;
1305 if (sched_is_scheduled(node)) {
1306 sched_point = sched_prev(node);
1309 /* No need to spill unknown values... */
1310 if(is_ia32_Unknown_GP(val) ||
1311 is_ia32_Unknown_VFP(val) ||
1312 is_ia32_Unknown_XMM(val)) {
1317 exchange(node, store);
1321 if (mode_is_float(mode)) {
1323 store = new_rd_ia32_xStore(dbg, irg, block, ptr, noreg, val, nomem);
1325 store = new_rd_ia32_vfst(dbg, irg, block, ptr, noreg, val, nomem);
1327 else if (get_mode_size_bits(mode) == 128) {
1328 // Spill 128 bit SSE registers
1329 store = new_rd_ia32_xxStore(dbg, irg, block, ptr, noreg, val, nomem);
1331 else if (get_mode_size_bits(mode) == 8) {
1332 store = new_rd_ia32_Store8Bit(dbg, irg, block, ptr, noreg, val, nomem);
1335 store = new_rd_ia32_Store(dbg, irg, block, ptr, noreg, val, nomem);
1338 set_ia32_am_support(store, ia32_am_Dest);
1339 set_ia32_op_type(store, ia32_AddrModeD);
1340 set_ia32_am_flavour(store, ia32_B);
1341 set_ia32_ls_mode(store, mode);
1342 set_ia32_frame_ent(store, ent);
1343 set_ia32_use_frame(store);
1344 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(cg, node));
1345 DBG_OPT_SPILL2ST(node, store);
1348 sched_add_after(sched_point, store);
1352 exchange(node, store);
1355 static ir_node *create_push(ia32_code_gen_t *cg, ir_node *node, ir_node *schedpoint, ir_node *sp, ir_node *mem, ir_entity *ent) {
1356 ir_graph *irg = get_irn_irg(node);
1357 dbg_info *dbg = get_irn_dbg_info(node);
1358 ir_node *block = get_nodes_block(node);
1359 ir_node *noreg = ia32_new_NoReg_gp(cg);
1360 ir_node *frame = get_irg_frame(irg);
1362 ir_node *push = new_rd_ia32_Push(dbg, irg, block, frame, noreg, noreg, sp, mem);
1364 set_ia32_frame_ent(push, ent);
1365 set_ia32_use_frame(push);
1366 set_ia32_op_type(push, ia32_AddrModeS);
1367 set_ia32_am_flavour(push, ia32_B);
1368 set_ia32_ls_mode(push, mode_Is);
1370 sched_add_before(schedpoint, push);
1374 static ir_node *create_pop(ia32_code_gen_t *cg, ir_node *node, ir_node *schedpoint, ir_node *sp, ir_entity *ent) {
1375 ir_graph *irg = get_irn_irg(node);
1376 dbg_info *dbg = get_irn_dbg_info(node);
1377 ir_node *block = get_nodes_block(node);
1378 ir_node *noreg = ia32_new_NoReg_gp(cg);
1379 ir_node *frame = get_irg_frame(irg);
1381 ir_node *pop = new_rd_ia32_Pop(dbg, irg, block, frame, noreg, sp, new_NoMem());
1383 set_ia32_frame_ent(pop, ent);
1384 set_ia32_use_frame(pop);
1385 set_ia32_op_type(pop, ia32_AddrModeD);
1386 set_ia32_am_flavour(pop, ia32_am_OB);
1387 set_ia32_ls_mode(pop, mode_Is);
1389 sched_add_before(schedpoint, pop);
1394 static ir_node* create_spproj(ia32_code_gen_t *cg, ir_node *node, ir_node *pred, int pos, ir_node *schedpoint) {
1395 ir_graph *irg = get_irn_irg(node);
1396 dbg_info *dbg = get_irn_dbg_info(node);
1397 ir_node *block = get_nodes_block(node);
1398 ir_mode *spmode = mode_Iu;
1399 const arch_register_t *spreg = &ia32_gp_regs[REG_ESP];
1402 sp = new_rd_Proj(dbg, irg, block, pred, spmode, pos);
1403 arch_set_irn_register(cg->arch_env, sp, spreg);
1404 sched_add_before(schedpoint, sp);
1410 * Transform memperm, currently we do this the ugly way and produce
1411 * push/pop into/from memory cascades. This is possible without using
1414 static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) {
1415 ir_graph *irg = get_irn_irg(node);
1416 ir_node *block = get_nodes_block(node);
1420 ir_node *sp = be_abi_get_ignore_irn(cg->birg->abi, &ia32_gp_regs[REG_ESP]);
1421 const ir_edge_t *edge;
1422 const ir_edge_t *next;
1425 arity = be_get_MemPerm_entity_arity(node);
1426 pops = alloca(arity * sizeof(pops[0]));
1429 for(i = 0; i < arity; ++i) {
1430 ir_entity *ent = be_get_MemPerm_in_entity(node, i);
1431 ir_type *enttype = get_entity_type(ent);
1432 int entbits = get_type_size_bits(enttype);
1433 ir_node *mem = get_irn_n(node, i + 1);
1436 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1438 push = create_push(cg, node, node, sp, mem, ent);
1439 sp = create_spproj(cg, node, push, pn_ia32_Push_stack, node);
1441 // add another push after the first one
1442 push = create_push(cg, node, node, sp, mem, ent);
1443 add_ia32_am_offs_int(push, 4);
1444 sp = create_spproj(cg, node, push, pn_ia32_Push_stack, node);
1447 set_irn_n(node, i, new_Bad());
1451 for(i = arity - 1; i >= 0; --i) {
1452 ir_entity *ent = be_get_MemPerm_out_entity(node, i);
1453 ir_type *enttype = get_entity_type(ent);
1454 int entbits = get_type_size_bits(enttype);
1458 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1460 pop = create_pop(cg, node, node, sp, ent);
1461 sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack, node);
1463 add_ia32_am_offs_int(pop, 4);
1465 // add another pop after the first one
1466 pop = create_pop(cg, node, node, sp, ent);
1467 sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack, node);
1474 keep = be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in);
1475 sched_add_before(node, keep);
1477 // exchange memprojs
1478 foreach_out_edge_safe(node, edge, next) {
1479 ir_node *proj = get_edge_src_irn(edge);
1480 int p = get_Proj_proj(proj);
1484 set_Proj_pred(proj, pops[p]);
1485 set_Proj_proj(proj, 3);
1489 arity = get_irn_arity(node);
1490 for(i = 0; i < arity; ++i) {
1491 set_irn_n(node, i, new_Bad());
1497 * Block-Walker: Calls the transform functions Spill and Reload.
1499 static void ia32_after_ra_walker(ir_node *block, void *env) {
1500 ir_node *node, *prev;
1501 ia32_code_gen_t *cg = env;
1503 /* beware: the schedule is changed here */
1504 for (node = sched_last(block); !sched_is_begin(node); node = prev) {
1505 prev = sched_prev(node);
1507 if (be_is_Reload(node)) {
1508 transform_to_Load(cg, node);
1509 } else if (be_is_Spill(node)) {
1510 transform_to_Store(cg, node);
1511 } else if(be_is_MemPerm(node)) {
1512 transform_MemPerm(cg, node);
1518 * Collects nodes that need frame entities assigned.
1520 static void ia32_collect_frame_entity_nodes(ir_node *node, void *data)
1522 be_fec_env_t *env = data;
1524 if (be_is_Reload(node) && be_get_frame_entity(node) == NULL) {
1525 const ir_mode *mode = get_spill_mode_mode(get_irn_mode(node));
1526 int align = get_mode_size_bytes(mode);
1527 be_node_needs_frame_entity(env, node, mode, align);
1528 } else if(is_ia32_irn(node) && get_ia32_frame_ent(node) == NULL
1529 && is_ia32_use_frame(node)) {
1530 if (is_ia32_need_stackent(node) || is_ia32_Load(node)) {
1531 const ir_mode *mode = get_ia32_ls_mode(node);
1532 int align = get_mode_size_bytes(mode);
1533 be_node_needs_frame_entity(env, node, mode, align);
1534 } else if (is_ia32_vfild(node) || is_ia32_xLoad(node)) {
1535 const ir_mode *mode = get_ia32_ls_mode(node);
1537 be_node_needs_frame_entity(env, node, mode, align);
1538 } else if (is_ia32_SetST0(node)) {
1539 const ir_mode *mode = get_ia32_ls_mode(node);
1541 be_node_needs_frame_entity(env, node, mode, align);
1544 if(!is_ia32_Store(node)
1545 && !is_ia32_xStore(node)
1546 && !is_ia32_xStoreSimple(node)
1547 && !is_ia32_vfist(node)
1548 && !is_ia32_GetST0(node)) {
1557 * We transform Spill and Reload here. This needs to be done before
1558 * stack biasing otherwise we would miss the corrected offset for these nodes.
1560 static void ia32_after_ra(void *self) {
1561 ia32_code_gen_t *cg = self;
1562 ir_graph *irg = cg->irg;
1563 be_fec_env_t *fec_env = be_new_frame_entity_coalescer(cg->birg);
1565 /* create and coalesce frame entities */
1566 irg_walk_graph(irg, NULL, ia32_collect_frame_entity_nodes, fec_env);
1567 be_assign_entities(fec_env);
1568 be_free_frame_entity_coalescer(fec_env);
1570 irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, cg);
1572 ia32_finish_irg(irg, cg);
1576 * Last touchups for the graph before emit: x87 simulation to replace the
1577 * virtual with real x87 instructions, creating a block schedule and peephole
1580 static void ia32_finish(void *self) {
1581 ia32_code_gen_t *cg = self;
1582 ir_graph *irg = cg->irg;
1584 /* if we do x87 code generation, rewrite all the virtual instructions and registers */
1585 if (cg->used_fp == fp_x87 || cg->force_sim) {
1586 x87_simulate_graph(cg->arch_env, cg->birg);
1589 /* create block schedule, this also removes empty blocks which might
1590 * produce critical edges */
1591 cg->blk_sched = be_create_block_schedule(irg, cg->birg->exec_freq);
1593 /* do peephole optimisations */
1594 ia32_peephole_optimization(irg, cg);
1598 * Emits the code, closes the output file and frees
1599 * the code generator interface.
1601 static void ia32_codegen(void *self) {
1602 ia32_code_gen_t *cg = self;
1603 ir_graph *irg = cg->irg;
1605 ia32_gen_routine(cg, irg);
1609 /* remove it from the isa */
1612 /* de-allocate code generator */
1613 del_set(cg->reg_set);
1617 static void *ia32_cg_init(be_irg_t *birg);
1619 static const arch_code_generator_if_t ia32_code_gen_if = {
1621 NULL, /* before abi introduce hook */
1624 ia32_before_sched, /* before scheduling hook */
1625 ia32_before_ra, /* before register allocation hook */
1626 ia32_after_ra, /* after register allocation hook */
1627 ia32_finish, /* called before codegen */
1628 ia32_codegen /* emit && done */
1632 * Initializes a IA32 code generator.
1634 static void *ia32_cg_init(be_irg_t *birg) {
1635 ia32_isa_t *isa = (ia32_isa_t *)birg->main_env->arch_env->isa;
1636 ia32_code_gen_t *cg = xcalloc(1, sizeof(*cg));
1638 cg->impl = &ia32_code_gen_if;
1639 cg->irg = birg->irg;
1640 cg->reg_set = new_set(ia32_cmp_irn_reg_assoc, 1024);
1641 cg->arch_env = birg->main_env->arch_env;
1644 cg->blk_sched = NULL;
1645 cg->fp_kind = isa->fp_kind;
1646 cg->used_fp = fp_none;
1647 cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
1649 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.cg");
1651 /* copy optimizations from isa for easier access */
1653 cg->arch = isa->arch;
1654 cg->opt_arch = isa->opt_arch;
1660 if (isa->name_obst) {
1661 obstack_free(isa->name_obst, NULL);
1662 obstack_init(isa->name_obst);
1666 cur_reg_set = cg->reg_set;
1668 ia32_irn_ops.cg = cg;
1670 return (arch_code_generator_t *)cg;
1675 /*****************************************************************
1676 * ____ _ _ _____ _____
1677 * | _ \ | | | | |_ _|/ ____| /\
1678 * | |_) | __ _ ___| | _____ _ __ __| | | | | (___ / \
1679 * | _ < / _` |/ __| |/ / _ \ '_ \ / _` | | | \___ \ / /\ \
1680 * | |_) | (_| | (__| < __/ | | | (_| | _| |_ ____) / ____ \
1681 * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/ \_\
1683 *****************************************************************/
1686 * Set output modes for GCC
1688 static const tarval_mode_info mo_integer = {
1695 * set the tarval output mode of all integer modes to decimal
1697 static void set_tarval_output_modes(void)
1701 for (i = get_irp_n_modes() - 1; i >= 0; --i) {
1702 ir_mode *mode = get_irp_mode(i);
1704 if (mode_is_int(mode))
1705 set_tarval_mode_output_option(mode, &mo_integer);
1709 const arch_isa_if_t ia32_isa_if;
1712 * The template that generates a new ISA object.
1713 * Note that this template can be changed by command line
1716 static ia32_isa_t ia32_isa_template = {
1718 &ia32_isa_if, /* isa interface implementation */
1719 &ia32_gp_regs[REG_ESP], /* stack pointer register */
1720 &ia32_gp_regs[REG_EBP], /* base pointer register */
1721 -1, /* stack direction */
1722 NULL, /* main environment */
1724 {}, /* emitter environment */
1725 NULL, /* 16bit register names */
1726 NULL, /* 8bit register names */
1730 IA32_OPT_INCDEC | /* optimize add 1, sub 1 into inc/dec default: on */
1731 IA32_OPT_DOAM | /* optimize address mode default: on */
1732 IA32_OPT_LEA | /* optimize for LEAs default: on */
1733 IA32_OPT_PLACECNST | /* place constants immediately before instructions, default: on */
1734 IA32_OPT_IMMOPS | /* operations can use immediates, default: on */
1735 IA32_OPT_PUSHARGS), /* create pushs for function argument passing, default: on */
1736 arch_pentium_4, /* instruction architecture */
1737 arch_pentium_4, /* optimize for architecture */
1738 fp_sse2, /* use sse2 unit */
1739 NULL, /* current code generator */
1741 NULL, /* name obstack */
1742 0 /* name obst size */
1747 * Initializes the backend ISA.
1749 static void *ia32_init(FILE *file_handle) {
1750 static int inited = 0;
1756 set_tarval_output_modes();
1758 isa = xmalloc(sizeof(*isa));
1759 memcpy(isa, &ia32_isa_template, sizeof(*isa));
1761 ia32_register_init(isa);
1762 ia32_create_opcodes();
1763 ia32_register_copy_attr_func();
1765 if ((ARCH_INTEL(isa->arch) && isa->arch < arch_pentium_4) ||
1766 (ARCH_AMD(isa->arch) && isa->arch < arch_athlon))
1767 /* no SSE2 for these cpu's */
1768 isa->fp_kind = fp_x87;
1770 if (ARCH_INTEL(isa->opt_arch) && isa->opt_arch >= arch_pentium_4) {
1771 /* Pentium 4 don't like inc and dec instructions */
1772 isa->opt &= ~IA32_OPT_INCDEC;
1775 be_emit_init_env(&isa->emit, file_handle);
1776 isa->regs_16bit = pmap_create();
1777 isa->regs_8bit = pmap_create();
1778 isa->types = pmap_create();
1779 isa->tv_ent = pmap_create();
1780 isa->cpu = ia32_init_machine_description();
1782 ia32_build_16bit_reg_map(isa->regs_16bit);
1783 ia32_build_8bit_reg_map(isa->regs_8bit);
1785 /* patch register names of x87 registers */
1786 ia32_st_regs[0].name = "st";
1787 ia32_st_regs[1].name = "st(1)";
1788 ia32_st_regs[2].name = "st(2)";
1789 ia32_st_regs[3].name = "st(3)";
1790 ia32_st_regs[4].name = "st(4)";
1791 ia32_st_regs[5].name = "st(5)";
1792 ia32_st_regs[6].name = "st(6)";
1793 ia32_st_regs[7].name = "st(7)";
1796 isa->name_obst = xmalloc(sizeof(*isa->name_obst));
1797 obstack_init(isa->name_obst);
1800 ia32_handle_intrinsics();
1802 /* needed for the debug support */
1803 be_gas_emit_switch_section(&isa->emit, GAS_SECTION_TEXT);
1804 be_emit_cstring(&isa->emit, ".Ltext0:\n");
1805 be_emit_write_line(&isa->emit);
1815 * Closes the output file and frees the ISA structure.
1817 static void ia32_done(void *self) {
1818 ia32_isa_t *isa = self;
1820 /* emit now all global declarations */
1821 be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env);
1823 pmap_destroy(isa->regs_16bit);
1824 pmap_destroy(isa->regs_8bit);
1825 pmap_destroy(isa->tv_ent);
1826 pmap_destroy(isa->types);
1829 obstack_free(isa->name_obst, NULL);
1832 be_emit_destroy_env(&isa->emit);
1839 * Return the number of register classes for this architecture.
1840 * We report always these:
1841 * - the general purpose registers
1842 * - the SSE floating point register set
1843 * - the virtual floating point registers
1844 * - the SSE vector register set
1846 static int ia32_get_n_reg_class(const void *self) {
1851 * Return the register class for index i.
1853 static const arch_register_class_t *ia32_get_reg_class(const void *self, int i) {
1856 return &ia32_reg_classes[CLASS_ia32_gp];
1858 return &ia32_reg_classes[CLASS_ia32_xmm];
1860 return &ia32_reg_classes[CLASS_ia32_vfp];
1862 return &ia32_reg_classes[CLASS_ia32_fp_cw];
1864 assert(0 && "Invalid ia32 register class requested.");
1870 * Get the register class which shall be used to store a value of a given mode.
1871 * @param self The this pointer.
1872 * @param mode The mode in question.
1873 * @return A register class which can hold values of the given mode.
1875 const arch_register_class_t *ia32_get_reg_class_for_mode(const void *self, const ir_mode *mode) {
1876 const ia32_isa_t *isa = self;
1877 if (mode_is_float(mode)) {
1878 return USE_SSE2(isa) ? &ia32_reg_classes[CLASS_ia32_xmm] : &ia32_reg_classes[CLASS_ia32_vfp];
1881 return &ia32_reg_classes[CLASS_ia32_gp];
1885 * Get the ABI restrictions for procedure calls.
1886 * @param self The this pointer.
1887 * @param method_type The type of the method (procedure) in question.
1888 * @param abi The abi object to be modified
1890 static void ia32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) {
1891 const ia32_isa_t *isa = self;
1894 unsigned cc = get_method_calling_convention(method_type);
1895 int n = get_method_n_params(method_type);
1898 int i, ignore_1, ignore_2;
1900 const arch_register_t *reg;
1901 be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi);
1903 unsigned use_push = !IS_P6_ARCH(isa->opt_arch);
1905 /* set abi flags for calls */
1906 call_flags.bits.left_to_right = 0; /* always last arg first on stack */
1907 call_flags.bits.store_args_sequential = use_push;
1908 /* call_flags.bits.try_omit_fp not changed: can handle both settings */
1909 call_flags.bits.fp_free = 0; /* the frame pointer is fixed in IA32 */
1910 call_flags.bits.call_has_imm = 1; /* IA32 calls can have immediate address */
1912 /* set stack parameter passing style */
1913 be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
1915 /* collect the mode for each type */
1916 modes = alloca(n * sizeof(modes[0]));
1918 for (i = 0; i < n; i++) {
1919 tp = get_method_param_type(method_type, i);
1920 modes[i] = get_type_mode(tp);
1923 /* set register parameters */
1924 if (cc & cc_reg_param) {
1925 /* determine the number of parameters passed via registers */
1926 biggest_n = ia32_get_n_regparam_class(n, modes, &ignore_1, &ignore_2);
1928 /* loop over all parameters and set the register requirements */
1929 for (i = 0; i <= biggest_n; i++) {
1930 reg = ia32_get_RegParam_reg(n, modes, i, cc);
1931 assert(reg && "kaputt");
1932 be_abi_call_param_reg(abi, i, reg);
1939 /* set stack parameters */
1940 for (i = stack_idx; i < n; i++) {
1941 /* parameters on the stack are 32 bit aligned */
1942 be_abi_call_param_stack(abi, i, 4, 0, 0);
1946 /* set return registers */
1947 n = get_method_n_ress(method_type);
1949 assert(n <= 2 && "more than two results not supported");
1951 /* In case of 64bit returns, we will have two 32bit values */
1953 tp = get_method_res_type(method_type, 0);
1954 mode = get_type_mode(tp);
1956 assert(!mode_is_float(mode) && "two FP results not supported");
1958 tp = get_method_res_type(method_type, 1);
1959 mode = get_type_mode(tp);
1961 assert(!mode_is_float(mode) && "mixed INT, FP results not supported");
1963 be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]);
1964 be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]);
1967 const arch_register_t *reg;
1969 tp = get_method_res_type(method_type, 0);
1970 assert(is_atomic_type(tp));
1971 mode = get_type_mode(tp);
1973 reg = mode_is_float(mode) ? &ia32_vfp_regs[REG_VF0] : &ia32_gp_regs[REG_EAX];
1975 be_abi_call_res_reg(abi, 0, reg);
1980 static const void *ia32_get_irn_ops(const arch_irn_handler_t *self, const ir_node *irn) {
1981 return &ia32_irn_ops;
1984 const arch_irn_handler_t ia32_irn_handler = {
1988 const arch_irn_handler_t *ia32_get_irn_handler(const void *self) {
1989 return &ia32_irn_handler;
1992 int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn) {
1993 return is_ia32_irn(irn) ? 1 : -1;
1997 * Initializes the code generator interface.
1999 static const arch_code_generator_if_t *ia32_get_code_generator_if(void *self) {
2000 return &ia32_code_gen_if;
2004 * Returns the estimated execution time of an ia32 irn.
2006 static sched_timestep_t ia32_sched_exectime(void *env, const ir_node *irn) {
2007 const arch_env_t *arch_env = env;
2008 return is_ia32_irn(irn) ? ia32_get_op_estimated_cost(arch_get_irn_ops(arch_env, irn), irn) : 1;
2011 list_sched_selector_t ia32_sched_selector;
2014 * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
2016 static const list_sched_selector_t *ia32_get_list_sched_selector(const void *self, list_sched_selector_t *selector) {
2017 memcpy(&ia32_sched_selector, selector, sizeof(ia32_sched_selector));
2018 ia32_sched_selector.exectime = ia32_sched_exectime;
2019 ia32_sched_selector.to_appear_in_schedule = ia32_to_appear_in_schedule;
2020 return &ia32_sched_selector;
2023 static const ilp_sched_selector_t *ia32_get_ilp_sched_selector(const void *self) {
2028 * Returns the necessary byte alignment for storing a register of given class.
2030 static int ia32_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) {
2031 ir_mode *mode = arch_register_class_mode(cls);
2032 int bytes = get_mode_size_bytes(mode);
2034 if (mode_is_float(mode) && bytes > 8)
2039 static const be_execution_unit_t ***ia32_get_allowed_execution_units(const void *self, const ir_node *irn) {
2040 static const be_execution_unit_t *_allowed_units_BRANCH[] = {
2041 &ia32_execution_units_BRANCH[IA32_EXECUNIT_TP_BRANCH_BRANCH1],
2042 &ia32_execution_units_BRANCH[IA32_EXECUNIT_TP_BRANCH_BRANCH2],
2045 static const be_execution_unit_t *_allowed_units_GP[] = {
2046 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EAX],
2047 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EBX],
2048 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_ECX],
2049 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EDX],
2050 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_ESI],
2051 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EDI],
2052 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EBP],
2055 static const be_execution_unit_t *_allowed_units_DUMMY[] = {
2056 &be_machine_execution_units_DUMMY[0],
2059 static const be_execution_unit_t **_units_callret[] = {
2060 _allowed_units_BRANCH,
2063 static const be_execution_unit_t **_units_other[] = {
2067 static const be_execution_unit_t **_units_dummy[] = {
2068 _allowed_units_DUMMY,
2071 const be_execution_unit_t ***ret;
2073 if (is_ia32_irn(irn)) {
2074 ret = get_ia32_exec_units(irn);
2076 else if (is_be_node(irn)) {
2077 if (be_is_Call(irn) || be_is_Return(irn)) {
2078 ret = _units_callret;
2080 else if (be_is_Barrier(irn)) {
2095 * Return the abstract ia32 machine.
2097 static const be_machine_t *ia32_get_machine(const void *self) {
2098 const ia32_isa_t *isa = self;
2103 * Return irp irgs in the desired order.
2105 static ir_graph **ia32_get_irg_list(const void *self, ir_graph ***irg_list) {
2110 * Allows or disallows the creation of Psi nodes for the given Phi nodes.
2111 * @return 1 if allowed, 0 otherwise
2113 static int ia32_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j)
2115 ir_node *cmp, *cmp_a, *phi;
2118 /* we don't want long long an floating point Psi */
2119 #define IS_BAD_PSI_MODE(mode) (mode_is_float(mode) || get_mode_size_bits(mode) > 32)
2121 if (get_irn_mode(sel) != mode_b)
2124 cmp = get_Proj_pred(sel);
2125 cmp_a = get_Cmp_left(cmp);
2126 mode = get_irn_mode(cmp_a);
2128 if (IS_BAD_PSI_MODE(mode))
2131 /* check the Phi nodes */
2132 for (phi = phi_list; phi; phi = get_irn_link(phi)) {
2133 ir_node *pred_i = get_irn_n(phi, i);
2134 ir_node *pred_j = get_irn_n(phi, j);
2135 ir_mode *mode_i = get_irn_mode(pred_i);
2136 ir_mode *mode_j = get_irn_mode(pred_j);
2138 if (IS_BAD_PSI_MODE(mode_i) || IS_BAD_PSI_MODE(mode_j))
2142 #undef IS_BAD_PSI_MODE
2147 static ia32_intrinsic_env_t intrinsic_env = {
2148 NULL, /**< the irg, these entities belong to */
2149 NULL, /**< entity for first div operand (move into FPU) */
2150 NULL, /**< entity for second div operand (move into FPU) */
2151 NULL, /**< entity for converts ll -> d */
2152 NULL, /**< entity for converts d -> ll */
2156 * Returns the libFirm configuration parameter for this backend.
2158 static const backend_params *ia32_get_libfirm_params(void) {
2159 static const opt_if_conv_info_t ifconv = {
2160 4, /* maxdepth, doesn't matter for Psi-conversion */
2161 ia32_is_psi_allowed /* allows or disallows Psi creation for given selector */
2163 static const arch_dep_params_t ad = {
2164 1, /* also use subs */
2165 4, /* maximum shifts */
2166 31, /* maximum shift amount */
2168 1, /* allow Mulhs */
2169 1, /* allow Mulus */
2170 32 /* Mulh allowed up to 32 bit */
2172 static backend_params p = {
2173 NULL, /* no additional opcodes */
2174 NULL, /* will be set later */
2175 1, /* need dword lowering */
2176 ia32_create_intrinsic_fkt,
2177 &intrinsic_env, /* context for ia32_create_intrinsic_fkt */
2178 NULL, /* will be set later */
2182 p.if_conv_info = &ifconv;
2186 /* instruction set architectures. */
2187 static const lc_opt_enum_int_items_t arch_items[] = {
2188 { "386", arch_i386, },
2189 { "486", arch_i486, },
2190 { "pentium", arch_pentium, },
2191 { "586", arch_pentium, },
2192 { "pentiumpro", arch_pentium_pro, },
2193 { "686", arch_pentium_pro, },
2194 { "pentiummmx", arch_pentium_mmx, },
2195 { "pentium2", arch_pentium_2, },
2196 { "p2", arch_pentium_2, },
2197 { "pentium3", arch_pentium_3, },
2198 { "p3", arch_pentium_3, },
2199 { "pentium4", arch_pentium_4, },
2200 { "p4", arch_pentium_4, },
2201 { "pentiumm", arch_pentium_m, },
2202 { "pm", arch_pentium_m, },
2203 { "core", arch_core, },
2205 { "athlon", arch_athlon, },
2206 { "athlon64", arch_athlon_64, },
2207 { "opteron", arch_opteron, },
2211 static lc_opt_enum_int_var_t arch_var = {
2212 &ia32_isa_template.arch, arch_items
2215 static lc_opt_enum_int_var_t opt_arch_var = {
2216 &ia32_isa_template.opt_arch, arch_items
2219 static const lc_opt_enum_int_items_t fp_unit_items[] = {
2221 { "sse2", fp_sse2 },
2225 static lc_opt_enum_int_var_t fp_unit_var = {
2226 &ia32_isa_template.fp_kind, fp_unit_items
2229 static const lc_opt_enum_int_items_t gas_items[] = {
2230 { "normal", GAS_FLAVOUR_NORMAL },
2231 { "mingw", GAS_FLAVOUR_MINGW },
2235 static lc_opt_enum_int_var_t gas_var = {
2236 (int*) &be_gas_flavour, gas_items
2239 static const lc_opt_table_entry_t ia32_options[] = {
2240 LC_OPT_ENT_ENUM_INT("arch", "select the instruction architecture", &arch_var),
2241 LC_OPT_ENT_ENUM_INT("opt", "optimize for instruction architecture", &opt_arch_var),
2242 LC_OPT_ENT_ENUM_INT("fpunit", "select the floating point unit", &fp_unit_var),
2243 LC_OPT_ENT_NEGBIT("noaddrmode", "do not use address mode", &ia32_isa_template.opt, IA32_OPT_DOAM),
2244 LC_OPT_ENT_NEGBIT("nolea", "do not optimize for LEAs", &ia32_isa_template.opt, IA32_OPT_LEA),
2245 LC_OPT_ENT_NEGBIT("noplacecnst", "do not place constants", &ia32_isa_template.opt, IA32_OPT_PLACECNST),
2246 LC_OPT_ENT_NEGBIT("noimmop", "no operations with immediates", &ia32_isa_template.opt, IA32_OPT_IMMOPS),
2247 LC_OPT_ENT_NEGBIT("nopushargs", "do not create pushs for function arguments", &ia32_isa_template.opt, IA32_OPT_PUSHARGS),
2248 LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
2252 const arch_isa_if_t ia32_isa_if = {
2255 ia32_get_n_reg_class,
2257 ia32_get_reg_class_for_mode,
2259 ia32_get_irn_handler,
2260 ia32_get_code_generator_if,
2261 ia32_get_list_sched_selector,
2262 ia32_get_ilp_sched_selector,
2263 ia32_get_reg_class_alignment,
2264 ia32_get_libfirm_params,
2265 ia32_get_allowed_execution_units,
2270 void be_init_arch_ia32(void)
2272 lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
2273 lc_opt_entry_t *ia32_grp = lc_opt_get_grp(be_grp, "ia32");
2275 lc_opt_add_table(ia32_grp, ia32_options);
2276 be_register_isa_if("ia32", &ia32_isa_if);
2279 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32);