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);
380 static void get_regparams_startbarrier(ir_graph *irg, ir_node **regparams, ir_node **startbarrier)
382 const ir_edge_t *edge;
383 ir_node *start_block = get_irg_start_block(irg);
386 *startbarrier = NULL;
387 foreach_out_edge(start_block, edge) {
388 ir_node *src = get_edge_src_irn(edge);
390 if(be_is_RegParams(src)) {
392 if(*startbarrier != NULL)
395 if(be_is_Barrier(src)) {
397 if(*regparams != NULL)
402 panic("Couldn't find regparams and startbarrier!");
405 static void add_fpu_edges(be_irg_t *birg)
407 ir_graph *irg = be_get_birg_irg(birg);
409 ir_node *startbarrier;
412 const arch_env_t *arch_env = birg->main_env->arch_env;
413 const arch_register_t *reg = &ia32_fp_cw_regs[REG_FPCW];
417 get_regparams_startbarrier(irg, ®params, &startbarrier);
419 fp_cw_reg = be_RegParams_append_out_reg(regparams, arch_env, reg);
421 fp_cw_reg = be_Barrier_append_node(startbarrier, fp_cw_reg);
422 pos = get_Proj_proj(fp_cw_reg);
423 be_set_constr_single_reg(startbarrier, BE_OUT_POS(pos), reg);
424 arch_set_irn_register(arch_env, fp_cw_reg, reg);
427 end_block = get_irg_end_block(irg);
428 arity = get_irn_arity(end_block);
429 for(i = 0; i < arity; ++i) {
431 ir_node *ret = get_irn_n(end_block, i);
432 ir_node *end_barrier = NULL;
433 ir_node *fp_cw_after_end_barrier;
434 if(!be_is_Return(ret))
437 /* search the barrier before the return */
438 arity2 = get_irn_arity(ret);
439 for(i2 = 0; i2 < arity2; i2++) {
440 ir_node *proj = get_irn_n(ret, i2);
445 end_barrier = get_Proj_pred(proj);
446 if(!be_is_Barrier(end_barrier))
450 assert(end_barrier != NULL);
452 /* add fp_cw to the barrier */
453 fp_cw_after_end_barrier = be_Barrier_append_node(end_barrier, fp_cw_reg);
454 pos = get_Proj_proj(fp_cw_after_end_barrier);
455 be_set_constr_single_reg(end_barrier, BE_OUT_POS(pos), reg);
456 arch_set_irn_register(arch_env, fp_cw_after_end_barrier, reg);
458 /* and append it to the return node */
459 be_Return_append_node(ret, fp_cw_after_end_barrier);
465 static unsigned count_callee_saves(ia32_code_gen_t *cg)
467 unsigned callee_saves = 0;
468 int c, num_reg_classes;
471 num_reg_classes = arch_isa_get_n_reg_class(isa);
472 for(c = 0; c < num_reg_classes; ++c) {
473 int r, num_registers;
474 arch_register_class_t *regclass = arch_isa_get_reg_class(isa, c);
476 num_registers = arch_register_class_n_regs(regclass);
477 for(r = 0; r < num_registers; ++r) {
478 arch_register_t *reg = arch_register_for_index(regclass, r);
479 if(arch_register_type_is(reg, callee_save))
487 static void create_callee_save_regprojs(ia32_code_gen_t *cg, ir_node *regparams)
489 int c, num_reg_classes;
493 num_reg_classes = arch_isa_get_n_reg_class(isa);
494 cg->initial_regs = obstack_alloc(cg->obst,
495 num_reg_classes * sizeof(cg->initial_regs[0]));
497 for(c = 0; c < num_reg_classes; ++c) {
498 int r, num_registers;
499 ir_node **initial_regclass;
500 arch_register_class_t *regclass = arch_isa_get_reg_class(isa, c);
502 num_registers = arch_register_class_n_regs(regclass);
503 initial_regclass = obstack_alloc(num_registers * sizeof(initial_regclass[0]));
504 for(r = 0; r < num_registers; ++r) {
506 arch_register_t *reg = arch_register_for_index(regclass, r);
507 if(!arch_register_type_is(reg, callee_save))
510 proj = new_r_Proj(irg, start_block, regparams, n);
511 be_set_constr_single_reg(regparams, n, reg);
512 arch_set_irn_register(cg->arch_env, proj, reg);
514 initial_regclass[r] = proj;
517 cg->initial_regs[c] = initial_regclass;
521 static void callee_saves_obstack_grow(ia32_code_gen_t *cg)
523 int c, num_reg_classes;
526 for(c = 0; c < num_reg_classes; ++c) {
527 int r, num_registers;
529 num_registers = arch_register_class_n_regs(regclass);
530 for(r = 0; r < num_registers; ++r) {
532 arch_register_t *reg = arch_register_for_index(regclass, r);
533 if(!arch_register_type_is(reg, callee_save))
536 proj = cg->initial_regs[c][r];
537 obstack_ptr_grow(cg->obst, proj);
542 static unsigned count_parameters_in_regs(ia32_code_gen_t *cg)
547 static void ia32_gen_prologue(ia32_code_gen_t *cg)
549 ir_graph *irg = cg->irg;
550 ir_node *start_block = get_irg_start_block(irg);
555 /* Create the regparams node */
556 n_regparams_out = count_callee_saves(cg) + count_parameters_in_regs(cg);
557 regparams = be_new_RegParams(irg, start_block, n_regparams_out);
559 create_callee_save_regprojs(cg, regparams);
561 /* Setup the stack */
563 ir_node *bl = get_irg_start_block(env->irg);
564 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
565 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
566 ir_node *noreg = ia32_new_NoReg_gp(cg);
570 push = new_rd_ia32_Push(NULL, env->irg, bl, noreg, noreg, curr_bp, curr_sp, *mem);
571 curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
572 *mem = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
574 /* the push must have SP out register */
575 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
576 set_ia32_flags(push, arch_irn_flags_ignore);
578 /* move esp to ebp */
579 curr_bp = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
580 be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
581 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
582 be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
584 /* beware: the copy must be done before any other sp use */
585 curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
586 be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
587 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
588 be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
590 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
591 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
594 sp = be_new_IncSP(sp, irg, start_block, initialsp, BE_STACK_FRAME_SIZE_EXPAND);
595 set_irg_frame(irg, sp);
598 static void ia32_gen_epilogue(ia32_code_gen_t *cg)
600 int n_callee_saves = count_callee_saves(cg);
601 int n_results_regs = 0;
604 ir_node *end_block = get_irg_end_block(irg);
607 /* We have to make sure that all reloads occur before the stack frame
608 gets destroyed, so we create a barrier for all callee-save and return
610 barrier_size = n_callee_saves + n_results_regs;
611 barrier = be_new_Barrier(irg, end_block, barrier_size,
613 /* simply remove the stack frame here */
614 curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK);
615 add_irn_dep(curr_sp, *mem);
620 * Generate the routine prologue.
622 * @param self The callback object.
623 * @param mem A pointer to the mem node. Update this if you define new memory.
624 * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
626 * @return The register which shall be used as a stack frame base.
628 * All nodes which define registers in @p reg_map must keep @p reg_map current.
630 static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
632 ia32_abi_env_t *env = self;
633 const ia32_isa_t *isa = (ia32_isa_t *)env->isa;
634 ia32_code_gen_t *cg = isa->cg;
636 if (! env->flags.try_omit_fp) {
637 ir_node *bl = get_irg_start_block(env->irg);
638 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
639 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
640 ir_node *noreg = ia32_new_NoReg_gp(cg);
644 push = new_rd_ia32_Push(NULL, env->irg, bl, noreg, noreg, curr_bp, curr_sp, *mem);
645 curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
646 *mem = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
648 /* the push must have SP out register */
649 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
650 set_ia32_flags(push, arch_irn_flags_ignore);
652 /* move esp to ebp */
653 curr_bp = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
654 be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
655 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
656 be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
658 /* beware: the copy must be done before any other sp use */
659 curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
660 be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
661 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
662 be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
664 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
665 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
674 * Generate the routine epilogue.
675 * @param self The callback object.
676 * @param bl The block for the epilog
677 * @param mem A pointer to the mem node. Update this if you define new memory.
678 * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
679 * @return The register which shall be used as a stack frame base.
681 * All nodes which define registers in @p reg_map must keep @p reg_map current.
683 static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
685 ia32_abi_env_t *env = self;
686 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
687 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
689 if (env->flags.try_omit_fp) {
690 /* simply remove the stack frame here */
691 curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK);
692 add_irn_dep(curr_sp, *mem);
694 const ia32_isa_t *isa = (ia32_isa_t *)env->isa;
695 ia32_code_gen_t *cg = isa->cg;
696 ir_mode *mode_bp = env->isa->bp->reg_class->mode;
698 /* gcc always emits a leave at the end of a routine */
699 if (1 || ARCH_AMD(isa->opt_arch)) {
703 leave = new_rd_ia32_Leave(NULL, env->irg, bl, curr_sp, curr_bp);
704 set_ia32_flags(leave, arch_irn_flags_ignore);
705 curr_bp = new_r_Proj(current_ir_graph, bl, leave, mode_bp, pn_ia32_Leave_frame);
706 curr_sp = new_r_Proj(current_ir_graph, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
708 ir_node *noreg = ia32_new_NoReg_gp(cg);
711 /* copy ebp to esp */
712 curr_sp = be_new_SetSP(env->isa->sp, env->irg, bl, curr_sp, curr_bp, *mem);
715 pop = new_rd_ia32_Pop(NULL, env->irg, bl, noreg, noreg, curr_sp, *mem);
716 set_ia32_flags(pop, arch_irn_flags_ignore);
717 curr_bp = new_r_Proj(current_ir_graph, bl, pop, mode_bp, pn_ia32_Pop_res);
718 curr_sp = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
720 *mem = new_r_Proj(current_ir_graph, bl, pop, mode_M, pn_ia32_Pop_M);
722 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
723 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
726 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
727 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
731 * Initialize the callback object.
732 * @param call The call object.
733 * @param aenv The architecture environment.
734 * @param irg The graph with the method.
735 * @return Some pointer. This pointer is passed to all other callback functions as self object.
737 static void *ia32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg)
739 ia32_abi_env_t *env = xmalloc(sizeof(env[0]));
740 be_abi_call_flags_t fl = be_abi_call_get_flags(call);
741 env->flags = fl.bits;
744 env->isa = aenv->isa;
749 * Destroy the callback object.
750 * @param self The callback object.
752 static void ia32_abi_done(void *self) {
757 * Produces the type which sits between the stack args and the locals on the stack.
758 * it will contain the return address and space to store the old base pointer.
759 * @return The Firm type modeling the ABI between type.
761 static ir_type *ia32_abi_get_between_type(void *self)
763 #define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
764 static ir_type *omit_fp_between_type = NULL;
765 static ir_type *between_type = NULL;
767 ia32_abi_env_t *env = self;
769 if (! between_type) {
770 ir_entity *old_bp_ent;
771 ir_entity *ret_addr_ent;
772 ir_entity *omit_fp_ret_addr_ent;
774 ir_type *old_bp_type = new_type_primitive(IDENT("bp"), mode_Iu);
775 ir_type *ret_addr_type = new_type_primitive(IDENT("return_addr"), mode_Iu);
777 between_type = new_type_struct(IDENT("ia32_between_type"));
778 old_bp_ent = new_entity(between_type, IDENT("old_bp"), old_bp_type);
779 ret_addr_ent = new_entity(between_type, IDENT("ret_addr"), ret_addr_type);
781 set_entity_offset(old_bp_ent, 0);
782 set_entity_offset(ret_addr_ent, get_type_size_bytes(old_bp_type));
783 set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
784 set_type_state(between_type, layout_fixed);
786 omit_fp_between_type = new_type_struct(IDENT("ia32_between_type_omit_fp"));
787 omit_fp_ret_addr_ent = new_entity(omit_fp_between_type, IDENT("ret_addr"), ret_addr_type);
789 set_entity_offset(omit_fp_ret_addr_ent, 0);
790 set_type_size_bytes(omit_fp_between_type, get_type_size_bytes(ret_addr_type));
791 set_type_state(omit_fp_between_type, layout_fixed);
794 return env->flags.try_omit_fp ? omit_fp_between_type : between_type;
799 * Get the estimated cycle count for @p irn.
801 * @param self The this pointer.
802 * @param irn The node.
804 * @return The estimated cycle count for this operation
806 static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
809 ia32_op_type_t op_tp;
810 const ia32_irn_ops_t *ops = self;
814 if (!is_ia32_irn(irn))
817 assert(is_ia32_irn(irn));
819 cost = get_ia32_latency(irn);
820 op_tp = get_ia32_op_type(irn);
822 if (is_ia32_CopyB(irn)) {
824 if (ARCH_INTEL(ops->cg->arch))
827 else if (is_ia32_CopyB_i(irn)) {
828 int size = get_tarval_long(get_ia32_Immop_tarval(irn));
829 cost = 20 + (int)ceil((4/3) * size);
830 if (ARCH_INTEL(ops->cg->arch))
833 /* in case of address mode operations add additional cycles */
834 else if (op_tp == ia32_AddrModeD || op_tp == ia32_AddrModeS) {
836 In case of stack access add 5 cycles (we assume stack is in cache),
837 other memory operations cost 20 cycles.
839 cost += is_ia32_use_frame(irn) ? 5 : 20;
846 * Returns the inverse operation if @p irn, recalculating the argument at position @p i.
848 * @param irn The original operation
849 * @param i Index of the argument we want the inverse operation to yield
850 * @param inverse struct to be filled with the resulting inverse op
851 * @param obstack The obstack to use for allocation of the returned nodes array
852 * @return The inverse operation or NULL if operation invertible
854 static arch_inverse_t *ia32_get_inverse(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst) {
858 ir_node *block, *noreg, *nomem;
861 /* we cannot invert non-ia32 irns */
862 if (! is_ia32_irn(irn))
865 /* operand must always be a real operand (not base, index or mem) */
866 if (i != 2 && i != 3)
869 /* we don't invert address mode operations */
870 if (get_ia32_op_type(irn) != ia32_Normal)
873 irg = get_irn_irg(irn);
874 block = get_nodes_block(irn);
875 mode = get_irn_mode(irn);
876 irn_mode = get_irn_mode(irn);
877 noreg = get_irn_n(irn, 0);
878 nomem = new_r_NoMem(irg);
879 dbg = get_irn_dbg_info(irn);
881 /* initialize structure */
882 inverse->nodes = obstack_alloc(obst, 2 * sizeof(inverse->nodes[0]));
886 switch (get_ia32_irn_opcode(irn)) {
888 if (get_ia32_immop_type(irn) == ia32_ImmConst) {
889 /* we have an add with a const here */
890 /* invers == add with negated const */
891 inverse->nodes[0] = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
893 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
894 set_ia32_Immop_tarval(inverse->nodes[0], tarval_neg(get_ia32_Immop_tarval(irn)));
895 set_ia32_commutative(inverse->nodes[0]);
897 else if (get_ia32_immop_type(irn) == ia32_ImmSymConst) {
898 /* we have an add with a symconst here */
899 /* invers == sub with const */
900 inverse->nodes[0] = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
902 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
905 /* normal add: inverse == sub */
906 inverse->nodes[0] = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, (ir_node*) irn, get_irn_n(irn, i ^ 1), nomem);
911 if (get_ia32_immop_type(irn) != ia32_ImmNone) {
912 /* we have a sub with a const/symconst here */
913 /* invers == add with this const */
914 inverse->nodes[0] = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
915 inverse->costs += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
916 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
921 inverse->nodes[0] = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, (ir_node*) irn, get_irn_n(irn, 3), nomem);
924 inverse->nodes[0] = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, get_irn_n(irn, 2), (ir_node*) irn, nomem);
930 if (get_ia32_immop_type(irn) != ia32_ImmNone) {
931 /* xor with const: inverse = xor */
932 inverse->nodes[0] = new_rd_ia32_Xor(dbg, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
933 inverse->costs += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
934 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
938 inverse->nodes[0] = new_rd_ia32_Xor(dbg, irg, block, noreg, noreg, (ir_node *) irn, get_irn_n(irn, i), nomem);
943 inverse->nodes[0] = new_rd_ia32_Not(dbg, irg, block, noreg, noreg, (ir_node*) irn, nomem);
948 inverse->nodes[0] = new_rd_ia32_Neg(dbg, irg, block, noreg, noreg, (ir_node*) irn, nomem);
953 /* inverse operation not supported */
960 static ir_mode *get_spill_mode_mode(const ir_mode *mode)
962 if(mode_is_float(mode))
969 * Get the mode that should be used for spilling value node
971 static ir_mode *get_spill_mode(const ir_node *node)
973 ir_mode *mode = get_irn_mode(node);
974 return get_spill_mode_mode(mode);
978 * Checks wether an addressmode reload for a node with mode mode is compatible
979 * with a spillslot of mode spill_mode
981 static int ia32_is_spillmode_compatible(const ir_mode *mode, const ir_mode *spillmode)
983 if(mode_is_float(mode)) {
984 return mode == spillmode;
991 * Check if irn can load it's operand at position i from memory (source addressmode).
992 * @param self Pointer to irn ops itself
993 * @param irn The irn to be checked
994 * @param i The operands position
995 * @return Non-Zero if operand can be loaded
997 static int ia32_possible_memory_operand(const void *self, const ir_node *irn, unsigned int i) {
998 ir_node *op = get_irn_n(irn, i);
999 const ir_mode *mode = get_irn_mode(op);
1000 const ir_mode *spillmode = get_spill_mode(op);
1002 if (! is_ia32_irn(irn) || /* must be an ia32 irn */
1003 get_irn_arity(irn) != 5 || /* must be a binary operation */
1004 get_ia32_op_type(irn) != ia32_Normal || /* must not already be a addressmode irn */
1005 ! (get_ia32_am_support(irn) & ia32_am_Source) || /* must be capable of source addressmode */
1006 ! ia32_is_spillmode_compatible(mode, spillmode) ||
1007 (i != 2 && i != 3) || /* a "real" operand position must be requested */
1008 (i == 2 && ! is_ia32_commutative(irn)) || /* if first operand requested irn must be commutative */
1009 is_ia32_use_frame(irn)) /* must not already use frame */
1015 static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node *spill, unsigned int i) {
1016 const ia32_irn_ops_t *ops = self;
1017 ia32_code_gen_t *cg = ops->cg;
1019 assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
1022 ir_node *tmp = get_irn_n(irn, 3);
1023 set_irn_n(irn, 3, get_irn_n(irn, 2));
1024 set_irn_n(irn, 2, tmp);
1027 set_ia32_am_support(irn, ia32_am_Source);
1028 set_ia32_op_type(irn, ia32_AddrModeS);
1029 set_ia32_am_flavour(irn, ia32_B);
1030 set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i)));
1031 set_ia32_use_frame(irn);
1032 set_ia32_need_stackent(irn);
1034 set_irn_n(irn, 0, get_irg_frame(get_irn_irg(irn)));
1035 set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
1036 set_irn_n(irn, 4, spill);
1038 //FIXME DBG_OPT_AM_S(reload, irn);
1041 static const be_abi_callbacks_t ia32_abi_callbacks = {
1044 ia32_abi_get_between_type,
1045 ia32_abi_dont_save_regs,
1050 /* fill register allocator interface */
1052 static const arch_irn_ops_if_t ia32_irn_ops_if = {
1053 ia32_get_irn_reg_req,
1058 ia32_get_frame_entity,
1059 ia32_set_frame_entity,
1060 ia32_set_frame_offset,
1063 ia32_get_op_estimated_cost,
1064 ia32_possible_memory_operand,
1065 ia32_perform_memory_operand,
1068 ia32_irn_ops_t ia32_irn_ops = {
1075 /**************************************************
1078 * ___ ___ __| | ___ __ _ ___ _ __ _| |_
1079 * / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \ | | _|
1080 * | (_| (_) | (_| | __/ (_| | __/ | | | | | |
1081 * \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
1084 **************************************************/
1087 * Transforms the standard firm graph into
1088 * an ia32 firm graph
1090 static void ia32_prepare_graph(void *self) {
1091 ia32_code_gen_t *cg = self;
1092 DEBUG_ONLY(firm_dbg_module_t *old_mod = cg->mod;)
1094 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.transform");
1096 /* transform psi condition trees */
1097 ia32_pre_transform_phase(cg);
1099 /* transform all remaining nodes */
1100 ia32_transform_graph(cg);
1101 add_fpu_edges(cg->birg);
1103 // Matze: disabled for now. Because after transformation start block has no
1104 // self-loop anymore so it might be merged with its successor block. This
1105 // will bring several nodes to the startblock which sometimes get scheduled
1106 // before the initial IncSP/Barrier
1107 //local_optimize_graph(cg->irg);
1110 be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
1112 /* optimize address mode */
1113 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.am");
1114 ia32_optimize_addressmode(cg);
1117 be_dump(cg->irg, "-am", dump_ir_block_graph_sched);
1119 /* do code placement, to optimize the position of constants */
1120 place_code(cg->irg);
1123 be_dump(cg->irg, "-place", dump_ir_block_graph_sched);
1125 DEBUG_ONLY(cg->mod = old_mod;)
1129 * Dummy functions for hooks we don't need but which must be filled.
1131 static void ia32_before_sched(void *self) {
1134 static void remove_unused_nodes(ir_node *irn, bitset_t *already_visited) {
1137 ir_node *mem_proj = NULL;
1142 mode = get_irn_mode(irn);
1144 /* check if we already saw this node or the node has more than one user */
1145 if (bitset_contains_irn(already_visited, irn) || get_irn_n_edges(irn) > 1) {
1149 /* mark irn visited */
1150 bitset_add_irn(already_visited, irn);
1152 /* non-Tuple nodes with one user: ok, return */
1153 if (get_irn_n_edges(irn) >= 1 && mode != mode_T) {
1157 /* tuple node has one user which is not the mem proj-> ok */
1158 if (mode == mode_T && get_irn_n_edges(irn) == 1) {
1159 mem_proj = ia32_get_proj_for_mode(irn, mode_M);
1160 if (mem_proj == NULL) {
1165 arity = get_irn_arity(irn);
1166 for (i = 0; i < arity; ++i) {
1167 ir_node *pred = get_irn_n(irn, i);
1169 /* do not follow memory edges or we will accidentally remove stores */
1170 if (get_irn_mode(pred) == mode_M) {
1171 if(mem_proj != NULL) {
1172 edges_reroute(mem_proj, pred, get_irn_irg(mem_proj));
1178 set_irn_n(irn, i, new_Bad());
1181 The current node is about to be removed: if the predecessor
1182 has only this node as user, it need to be removed as well.
1184 if (get_irn_n_edges(pred) <= 1)
1185 remove_unused_nodes(pred, already_visited);
1188 // we need to set the presd to Bad again to also get the memory edges
1189 arity = get_irn_arity(irn);
1190 for (i = 0; i < arity; ++i) {
1191 set_irn_n(irn, i, new_Bad());
1194 if (sched_is_scheduled(irn)) {
1199 static void remove_unused_loads_walker(ir_node *irn, void *env) {
1200 bitset_t *already_visited = env;
1201 if (is_ia32_Ld(irn) && ! bitset_contains_irn(already_visited, irn))
1202 remove_unused_nodes(irn, env);
1206 * Called before the register allocator.
1207 * Calculate a block schedule here. We need it for the x87
1208 * simulator and the emitter.
1210 static void ia32_before_ra(void *self) {
1211 ia32_code_gen_t *cg = self;
1212 bitset_t *already_visited = bitset_irg_alloca(cg->irg);
1215 Handle special case:
1216 There are sometimes unused loads, only pinned by memory.
1217 We need to remove those Loads and all other nodes which won't be used
1218 after removing the Load from schedule.
1220 irg_walk_graph(cg->irg, NULL, remove_unused_loads_walker, already_visited);
1225 * Transforms a be_Reload into a ia32 Load.
1227 static void transform_to_Load(ia32_code_gen_t *cg, ir_node *node) {
1228 ir_graph *irg = get_irn_irg(node);
1229 dbg_info *dbg = get_irn_dbg_info(node);
1230 ir_node *block = get_nodes_block(node);
1231 ir_entity *ent = be_get_frame_entity(node);
1232 ir_mode *mode = get_irn_mode(node);
1233 ir_mode *spillmode = get_spill_mode(node);
1234 ir_node *noreg = ia32_new_NoReg_gp(cg);
1235 ir_node *sched_point = NULL;
1236 ir_node *ptr = get_irg_frame(irg);
1237 ir_node *mem = get_irn_n(node, be_pos_Reload_mem);
1238 ir_node *new_op, *proj;
1239 const arch_register_t *reg;
1241 if (sched_is_scheduled(node)) {
1242 sched_point = sched_prev(node);
1245 if (mode_is_float(spillmode)) {
1247 new_op = new_rd_ia32_xLoad(dbg, irg, block, ptr, noreg, mem);
1249 new_op = new_rd_ia32_vfld(dbg, irg, block, ptr, noreg, mem);
1251 else if (get_mode_size_bits(spillmode) == 128) {
1252 // Reload 128 bit sse registers
1253 new_op = new_rd_ia32_xxLoad(dbg, irg, block, ptr, noreg, mem);
1256 new_op = new_rd_ia32_Load(dbg, irg, block, ptr, noreg, mem);
1258 set_ia32_am_support(new_op, ia32_am_Source);
1259 set_ia32_op_type(new_op, ia32_AddrModeS);
1260 set_ia32_am_flavour(new_op, ia32_B);
1261 set_ia32_ls_mode(new_op, spillmode);
1262 set_ia32_frame_ent(new_op, ent);
1263 set_ia32_use_frame(new_op);
1265 DBG_OPT_RELOAD2LD(node, new_op);
1267 proj = new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Load_res);
1270 sched_add_after(sched_point, new_op);
1271 sched_add_after(new_op, proj);
1276 /* copy the register from the old node to the new Load */
1277 reg = arch_get_irn_register(cg->arch_env, node);
1278 arch_set_irn_register(cg->arch_env, new_op, reg);
1280 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, node));
1282 exchange(node, proj);
1286 * Transforms a be_Spill node into a ia32 Store.
1288 static void transform_to_Store(ia32_code_gen_t *cg, ir_node *node) {
1289 ir_graph *irg = get_irn_irg(node);
1290 dbg_info *dbg = get_irn_dbg_info(node);
1291 ir_node *block = get_nodes_block(node);
1292 ir_entity *ent = be_get_frame_entity(node);
1293 const ir_node *spillval = get_irn_n(node, be_pos_Spill_val);
1294 ir_mode *mode = get_spill_mode(spillval);
1295 ir_node *noreg = ia32_new_NoReg_gp(cg);
1296 ir_node *nomem = new_rd_NoMem(irg);
1297 ir_node *ptr = get_irg_frame(irg);
1298 ir_node *val = get_irn_n(node, be_pos_Spill_val);
1300 ir_node *sched_point = NULL;
1302 if (sched_is_scheduled(node)) {
1303 sched_point = sched_prev(node);
1306 /* No need to spill unknown values... */
1307 if(is_ia32_Unknown_GP(val) ||
1308 is_ia32_Unknown_VFP(val) ||
1309 is_ia32_Unknown_XMM(val)) {
1314 exchange(node, store);
1318 if (mode_is_float(mode)) {
1320 store = new_rd_ia32_xStore(dbg, irg, block, ptr, noreg, val, nomem);
1322 store = new_rd_ia32_vfst(dbg, irg, block, ptr, noreg, val, nomem);
1324 else if (get_mode_size_bits(mode) == 128) {
1325 // Spill 128 bit SSE registers
1326 store = new_rd_ia32_xxStore(dbg, irg, block, ptr, noreg, val, nomem);
1328 else if (get_mode_size_bits(mode) == 8) {
1329 store = new_rd_ia32_Store8Bit(dbg, irg, block, ptr, noreg, val, nomem);
1332 store = new_rd_ia32_Store(dbg, irg, block, ptr, noreg, val, nomem);
1335 set_ia32_am_support(store, ia32_am_Dest);
1336 set_ia32_op_type(store, ia32_AddrModeD);
1337 set_ia32_am_flavour(store, ia32_B);
1338 set_ia32_ls_mode(store, mode);
1339 set_ia32_frame_ent(store, ent);
1340 set_ia32_use_frame(store);
1341 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(cg, node));
1342 DBG_OPT_SPILL2ST(node, store);
1345 sched_add_after(sched_point, store);
1349 exchange(node, store);
1352 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) {
1353 ir_graph *irg = get_irn_irg(node);
1354 dbg_info *dbg = get_irn_dbg_info(node);
1355 ir_node *block = get_nodes_block(node);
1356 ir_node *noreg = ia32_new_NoReg_gp(cg);
1357 ir_node *frame = get_irg_frame(irg);
1359 ir_node *push = new_rd_ia32_Push(dbg, irg, block, frame, noreg, noreg, sp, mem);
1361 set_ia32_frame_ent(push, ent);
1362 set_ia32_use_frame(push);
1363 set_ia32_op_type(push, ia32_AddrModeS);
1364 set_ia32_am_flavour(push, ia32_B);
1365 set_ia32_ls_mode(push, mode_Is);
1367 sched_add_before(schedpoint, push);
1371 static ir_node *create_pop(ia32_code_gen_t *cg, ir_node *node, ir_node *schedpoint, ir_node *sp, ir_entity *ent) {
1372 ir_graph *irg = get_irn_irg(node);
1373 dbg_info *dbg = get_irn_dbg_info(node);
1374 ir_node *block = get_nodes_block(node);
1375 ir_node *noreg = ia32_new_NoReg_gp(cg);
1376 ir_node *frame = get_irg_frame(irg);
1378 ir_node *pop = new_rd_ia32_Pop(dbg, irg, block, frame, noreg, sp, new_NoMem());
1380 set_ia32_frame_ent(pop, ent);
1381 set_ia32_use_frame(pop);
1382 set_ia32_op_type(pop, ia32_AddrModeD);
1383 set_ia32_am_flavour(pop, ia32_am_OB);
1384 set_ia32_ls_mode(pop, mode_Is);
1386 sched_add_before(schedpoint, pop);
1391 static ir_node* create_spproj(ia32_code_gen_t *cg, ir_node *node, ir_node *pred, int pos, ir_node *schedpoint) {
1392 ir_graph *irg = get_irn_irg(node);
1393 dbg_info *dbg = get_irn_dbg_info(node);
1394 ir_node *block = get_nodes_block(node);
1395 ir_mode *spmode = mode_Iu;
1396 const arch_register_t *spreg = &ia32_gp_regs[REG_ESP];
1399 sp = new_rd_Proj(dbg, irg, block, pred, spmode, pos);
1400 arch_set_irn_register(cg->arch_env, sp, spreg);
1401 sched_add_before(schedpoint, sp);
1407 * Transform memperm, currently we do this the ugly way and produce
1408 * push/pop into/from memory cascades. This is possible without using
1411 static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) {
1412 ir_graph *irg = get_irn_irg(node);
1413 ir_node *block = get_nodes_block(node);
1417 ir_node *sp = be_abi_get_ignore_irn(cg->birg->abi, &ia32_gp_regs[REG_ESP]);
1418 const ir_edge_t *edge;
1419 const ir_edge_t *next;
1422 arity = be_get_MemPerm_entity_arity(node);
1423 pops = alloca(arity * sizeof(pops[0]));
1426 for(i = 0; i < arity; ++i) {
1427 ir_entity *ent = be_get_MemPerm_in_entity(node, i);
1428 ir_type *enttype = get_entity_type(ent);
1429 int entbits = get_type_size_bits(enttype);
1430 ir_node *mem = get_irn_n(node, i + 1);
1433 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1435 push = create_push(cg, node, node, sp, mem, ent);
1436 sp = create_spproj(cg, node, push, pn_ia32_Push_stack, node);
1438 // add another push after the first one
1439 push = create_push(cg, node, node, sp, mem, ent);
1440 add_ia32_am_offs_int(push, 4);
1441 sp = create_spproj(cg, node, push, pn_ia32_Push_stack, node);
1444 set_irn_n(node, i, new_Bad());
1448 for(i = arity - 1; i >= 0; --i) {
1449 ir_entity *ent = be_get_MemPerm_out_entity(node, i);
1450 ir_type *enttype = get_entity_type(ent);
1451 int entbits = get_type_size_bits(enttype);
1455 assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
1457 pop = create_pop(cg, node, node, sp, ent);
1458 sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack, node);
1460 add_ia32_am_offs_int(pop, 4);
1462 // add another pop after the first one
1463 pop = create_pop(cg, node, node, sp, ent);
1464 sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack, node);
1471 keep = be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in);
1472 sched_add_before(node, keep);
1474 // exchange memprojs
1475 foreach_out_edge_safe(node, edge, next) {
1476 ir_node *proj = get_edge_src_irn(edge);
1477 int p = get_Proj_proj(proj);
1481 set_Proj_pred(proj, pops[p]);
1482 set_Proj_proj(proj, 3);
1486 arity = get_irn_arity(node);
1487 for(i = 0; i < arity; ++i) {
1488 set_irn_n(node, i, new_Bad());
1494 * Block-Walker: Calls the transform functions Spill and Reload.
1496 static void ia32_after_ra_walker(ir_node *block, void *env) {
1497 ir_node *node, *prev;
1498 ia32_code_gen_t *cg = env;
1500 /* beware: the schedule is changed here */
1501 for (node = sched_last(block); !sched_is_begin(node); node = prev) {
1502 prev = sched_prev(node);
1504 if (be_is_Reload(node)) {
1505 transform_to_Load(cg, node);
1506 } else if (be_is_Spill(node)) {
1507 transform_to_Store(cg, node);
1508 } else if(be_is_MemPerm(node)) {
1509 transform_MemPerm(cg, node);
1515 * Collects nodes that need frame entities assigned.
1517 static void ia32_collect_frame_entity_nodes(ir_node *node, void *data)
1519 be_fec_env_t *env = data;
1521 if (be_is_Reload(node) && be_get_frame_entity(node) == NULL) {
1522 const ir_mode *mode = get_spill_mode_mode(get_irn_mode(node));
1523 int align = get_mode_size_bytes(mode);
1524 be_node_needs_frame_entity(env, node, mode, align);
1525 } else if(is_ia32_irn(node) && get_ia32_frame_ent(node) == NULL
1526 && is_ia32_use_frame(node)) {
1527 if (is_ia32_need_stackent(node) || is_ia32_Load(node)) {
1528 const ir_mode *mode = get_ia32_ls_mode(node);
1529 int align = get_mode_size_bytes(mode);
1530 be_node_needs_frame_entity(env, node, mode, align);
1531 } else if (is_ia32_vfild(node) || is_ia32_xLoad(node)) {
1532 const ir_mode *mode = get_ia32_ls_mode(node);
1534 be_node_needs_frame_entity(env, node, mode, align);
1535 } else if (is_ia32_SetST0(node)) {
1536 const ir_mode *mode = get_ia32_ls_mode(node);
1538 be_node_needs_frame_entity(env, node, mode, align);
1541 if(!is_ia32_Store(node)
1542 && !is_ia32_xStore(node)
1543 && !is_ia32_xStoreSimple(node)
1544 && !is_ia32_vfist(node)
1545 && !is_ia32_GetST0(node)) {
1554 * We transform Spill and Reload here. This needs to be done before
1555 * stack biasing otherwise we would miss the corrected offset for these nodes.
1557 static void ia32_after_ra(void *self) {
1558 ia32_code_gen_t *cg = self;
1559 ir_graph *irg = cg->irg;
1560 be_fec_env_t *fec_env = be_new_frame_entity_coalescer(cg->birg);
1562 /* create and coalesce frame entities */
1563 irg_walk_graph(irg, NULL, ia32_collect_frame_entity_nodes, fec_env);
1564 be_assign_entities(fec_env);
1565 be_free_frame_entity_coalescer(fec_env);
1567 irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, cg);
1569 ia32_finish_irg(irg, cg);
1573 * Last touchups for the graph before emit: x87 simulation to replace the
1574 * virtual with real x87 instructions, creating a block schedule and peephole
1577 static void ia32_finish(void *self) {
1578 ia32_code_gen_t *cg = self;
1579 ir_graph *irg = cg->irg;
1581 /* if we do x87 code generation, rewrite all the virtual instructions and registers */
1582 if (cg->used_fp == fp_x87 || cg->force_sim) {
1583 x87_simulate_graph(cg->arch_env, cg->birg);
1586 /* create block schedule, this also removes empty blocks which might
1587 * produce critical edges */
1588 cg->blk_sched = be_create_block_schedule(irg, cg->birg->exec_freq);
1590 /* do peephole optimisations */
1591 ia32_peephole_optimization(irg, cg);
1595 * Emits the code, closes the output file and frees
1596 * the code generator interface.
1598 static void ia32_codegen(void *self) {
1599 ia32_code_gen_t *cg = self;
1600 ir_graph *irg = cg->irg;
1602 ia32_gen_routine(cg, irg);
1606 /* remove it from the isa */
1609 /* de-allocate code generator */
1610 del_set(cg->reg_set);
1614 static void *ia32_cg_init(be_irg_t *birg);
1616 static const arch_code_generator_if_t ia32_code_gen_if = {
1618 NULL, /* before abi introduce hook */
1621 ia32_before_sched, /* before scheduling hook */
1622 ia32_before_ra, /* before register allocation hook */
1623 ia32_after_ra, /* after register allocation hook */
1624 ia32_finish, /* called before codegen */
1625 ia32_codegen /* emit && done */
1629 * Initializes a IA32 code generator.
1631 static void *ia32_cg_init(be_irg_t *birg) {
1632 ia32_isa_t *isa = (ia32_isa_t *)birg->main_env->arch_env->isa;
1633 ia32_code_gen_t *cg = xcalloc(1, sizeof(*cg));
1635 cg->impl = &ia32_code_gen_if;
1636 cg->irg = birg->irg;
1637 cg->reg_set = new_set(ia32_cmp_irn_reg_assoc, 1024);
1638 cg->arch_env = birg->main_env->arch_env;
1641 cg->blk_sched = NULL;
1642 cg->fp_kind = isa->fp_kind;
1643 cg->used_fp = fp_none;
1644 cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
1646 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.cg");
1648 /* copy optimizations from isa for easier access */
1650 cg->arch = isa->arch;
1651 cg->opt_arch = isa->opt_arch;
1657 if (isa->name_obst) {
1658 obstack_free(isa->name_obst, NULL);
1659 obstack_init(isa->name_obst);
1663 cur_reg_set = cg->reg_set;
1665 ia32_irn_ops.cg = cg;
1667 return (arch_code_generator_t *)cg;
1672 /*****************************************************************
1673 * ____ _ _ _____ _____
1674 * | _ \ | | | | |_ _|/ ____| /\
1675 * | |_) | __ _ ___| | _____ _ __ __| | | | | (___ / \
1676 * | _ < / _` |/ __| |/ / _ \ '_ \ / _` | | | \___ \ / /\ \
1677 * | |_) | (_| | (__| < __/ | | | (_| | _| |_ ____) / ____ \
1678 * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/ \_\
1680 *****************************************************************/
1683 * Set output modes for GCC
1685 static const tarval_mode_info mo_integer = {
1692 * set the tarval output mode of all integer modes to decimal
1694 static void set_tarval_output_modes(void)
1698 for (i = get_irp_n_modes() - 1; i >= 0; --i) {
1699 ir_mode *mode = get_irp_mode(i);
1701 if (mode_is_int(mode))
1702 set_tarval_mode_output_option(mode, &mo_integer);
1706 const arch_isa_if_t ia32_isa_if;
1709 * The template that generates a new ISA object.
1710 * Note that this template can be changed by command line
1713 static ia32_isa_t ia32_isa_template = {
1715 &ia32_isa_if, /* isa interface implementation */
1716 &ia32_gp_regs[REG_ESP], /* stack pointer register */
1717 &ia32_gp_regs[REG_EBP], /* base pointer register */
1718 -1, /* stack direction */
1719 NULL, /* main environment */
1721 {}, /* emitter environment */
1722 NULL, /* 16bit register names */
1723 NULL, /* 8bit register names */
1727 IA32_OPT_INCDEC | /* optimize add 1, sub 1 into inc/dec default: on */
1728 IA32_OPT_DOAM | /* optimize address mode default: on */
1729 IA32_OPT_LEA | /* optimize for LEAs default: on */
1730 IA32_OPT_PLACECNST | /* place constants immediately before instructions, default: on */
1731 IA32_OPT_IMMOPS | /* operations can use immediates, default: on */
1732 IA32_OPT_PUSHARGS), /* create pushs for function argument passing, default: on */
1733 arch_pentium_4, /* instruction architecture */
1734 arch_pentium_4, /* optimize for architecture */
1735 fp_sse2, /* use sse2 unit */
1736 NULL, /* current code generator */
1738 NULL, /* name obstack */
1739 0 /* name obst size */
1744 * Initializes the backend ISA.
1746 static void *ia32_init(FILE *file_handle) {
1747 static int inited = 0;
1753 set_tarval_output_modes();
1755 isa = xmalloc(sizeof(*isa));
1756 memcpy(isa, &ia32_isa_template, sizeof(*isa));
1758 ia32_register_init(isa);
1759 ia32_create_opcodes();
1760 ia32_register_copy_attr_func();
1762 if ((ARCH_INTEL(isa->arch) && isa->arch < arch_pentium_4) ||
1763 (ARCH_AMD(isa->arch) && isa->arch < arch_athlon))
1764 /* no SSE2 for these cpu's */
1765 isa->fp_kind = fp_x87;
1767 if (ARCH_INTEL(isa->opt_arch) && isa->opt_arch >= arch_pentium_4) {
1768 /* Pentium 4 don't like inc and dec instructions */
1769 isa->opt &= ~IA32_OPT_INCDEC;
1772 be_emit_init_env(&isa->emit, file_handle);
1773 isa->regs_16bit = pmap_create();
1774 isa->regs_8bit = pmap_create();
1775 isa->types = pmap_create();
1776 isa->tv_ent = pmap_create();
1777 isa->cpu = ia32_init_machine_description();
1779 ia32_build_16bit_reg_map(isa->regs_16bit);
1780 ia32_build_8bit_reg_map(isa->regs_8bit);
1782 /* patch register names of x87 registers */
1783 ia32_st_regs[0].name = "st";
1784 ia32_st_regs[1].name = "st(1)";
1785 ia32_st_regs[2].name = "st(2)";
1786 ia32_st_regs[3].name = "st(3)";
1787 ia32_st_regs[4].name = "st(4)";
1788 ia32_st_regs[5].name = "st(5)";
1789 ia32_st_regs[6].name = "st(6)";
1790 ia32_st_regs[7].name = "st(7)";
1793 isa->name_obst = xmalloc(sizeof(*isa->name_obst));
1794 obstack_init(isa->name_obst);
1797 ia32_handle_intrinsics();
1799 /* needed for the debug support */
1800 be_gas_emit_switch_section(&isa->emit, GAS_SECTION_TEXT);
1801 be_emit_cstring(&isa->emit, ".Ltext0:\n");
1802 be_emit_write_line(&isa->emit);
1812 * Closes the output file and frees the ISA structure.
1814 static void ia32_done(void *self) {
1815 ia32_isa_t *isa = self;
1817 /* emit now all global declarations */
1818 be_gas_emit_decls(&isa->emit, isa->arch_isa.main_env);
1820 pmap_destroy(isa->regs_16bit);
1821 pmap_destroy(isa->regs_8bit);
1822 pmap_destroy(isa->tv_ent);
1823 pmap_destroy(isa->types);
1826 obstack_free(isa->name_obst, NULL);
1829 be_emit_destroy_env(&isa->emit);
1836 * Return the number of register classes for this architecture.
1837 * We report always these:
1838 * - the general purpose registers
1839 * - the SSE floating point register set
1840 * - the virtual floating point registers
1841 * - the SSE vector register set
1843 static int ia32_get_n_reg_class(const void *self) {
1848 * Return the register class for index i.
1850 static const arch_register_class_t *ia32_get_reg_class(const void *self, int i) {
1853 return &ia32_reg_classes[CLASS_ia32_gp];
1855 return &ia32_reg_classes[CLASS_ia32_xmm];
1857 return &ia32_reg_classes[CLASS_ia32_vfp];
1859 assert(0 && "Invalid ia32 register class requested.");
1865 * Get the register class which shall be used to store a value of a given mode.
1866 * @param self The this pointer.
1867 * @param mode The mode in question.
1868 * @return A register class which can hold values of the given mode.
1870 const arch_register_class_t *ia32_get_reg_class_for_mode(const void *self, const ir_mode *mode) {
1871 const ia32_isa_t *isa = self;
1872 if (mode_is_float(mode)) {
1873 return USE_SSE2(isa) ? &ia32_reg_classes[CLASS_ia32_xmm] : &ia32_reg_classes[CLASS_ia32_vfp];
1876 return &ia32_reg_classes[CLASS_ia32_gp];
1880 * Get the ABI restrictions for procedure calls.
1881 * @param self The this pointer.
1882 * @param method_type The type of the method (procedure) in question.
1883 * @param abi The abi object to be modified
1885 static void ia32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) {
1886 const ia32_isa_t *isa = self;
1889 unsigned cc = get_method_calling_convention(method_type);
1890 int n = get_method_n_params(method_type);
1893 int i, ignore_1, ignore_2;
1895 const arch_register_t *reg;
1896 be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi);
1898 unsigned use_push = !IS_P6_ARCH(isa->opt_arch);
1900 /* set abi flags for calls */
1901 call_flags.bits.left_to_right = 0; /* always last arg first on stack */
1902 call_flags.bits.store_args_sequential = use_push;
1903 /* call_flags.bits.try_omit_fp not changed: can handle both settings */
1904 call_flags.bits.fp_free = 0; /* the frame pointer is fixed in IA32 */
1905 call_flags.bits.call_has_imm = 1; /* IA32 calls can have immediate address */
1907 /* set stack parameter passing style */
1908 be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
1910 /* collect the mode for each type */
1911 modes = alloca(n * sizeof(modes[0]));
1913 for (i = 0; i < n; i++) {
1914 tp = get_method_param_type(method_type, i);
1915 modes[i] = get_type_mode(tp);
1918 /* set register parameters */
1919 if (cc & cc_reg_param) {
1920 /* determine the number of parameters passed via registers */
1921 biggest_n = ia32_get_n_regparam_class(n, modes, &ignore_1, &ignore_2);
1923 /* loop over all parameters and set the register requirements */
1924 for (i = 0; i <= biggest_n; i++) {
1925 reg = ia32_get_RegParam_reg(n, modes, i, cc);
1926 assert(reg && "kaputt");
1927 be_abi_call_param_reg(abi, i, reg);
1934 /* set stack parameters */
1935 for (i = stack_idx; i < n; i++) {
1936 /* parameters on the stack are 32 bit aligned */
1937 be_abi_call_param_stack(abi, i, 4, 0, 0);
1941 /* set return registers */
1942 n = get_method_n_ress(method_type);
1944 assert(n <= 2 && "more than two results not supported");
1946 /* In case of 64bit returns, we will have two 32bit values */
1948 tp = get_method_res_type(method_type, 0);
1949 mode = get_type_mode(tp);
1951 assert(!mode_is_float(mode) && "two FP results not supported");
1953 tp = get_method_res_type(method_type, 1);
1954 mode = get_type_mode(tp);
1956 assert(!mode_is_float(mode) && "mixed INT, FP results not supported");
1958 be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]);
1959 be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]);
1962 const arch_register_t *reg;
1964 tp = get_method_res_type(method_type, 0);
1965 assert(is_atomic_type(tp));
1966 mode = get_type_mode(tp);
1968 reg = mode_is_float(mode) ? &ia32_vfp_regs[REG_VF0] : &ia32_gp_regs[REG_EAX];
1970 be_abi_call_res_reg(abi, 0, reg);
1975 static const void *ia32_get_irn_ops(const arch_irn_handler_t *self, const ir_node *irn) {
1976 return &ia32_irn_ops;
1979 const arch_irn_handler_t ia32_irn_handler = {
1983 const arch_irn_handler_t *ia32_get_irn_handler(const void *self) {
1984 return &ia32_irn_handler;
1987 int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn) {
1988 return is_ia32_irn(irn) ? 1 : -1;
1992 * Initializes the code generator interface.
1994 static const arch_code_generator_if_t *ia32_get_code_generator_if(void *self) {
1995 return &ia32_code_gen_if;
1999 * Returns the estimated execution time of an ia32 irn.
2001 static sched_timestep_t ia32_sched_exectime(void *env, const ir_node *irn) {
2002 const arch_env_t *arch_env = env;
2003 return is_ia32_irn(irn) ? ia32_get_op_estimated_cost(arch_get_irn_ops(arch_env, irn), irn) : 1;
2006 list_sched_selector_t ia32_sched_selector;
2009 * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
2011 static const list_sched_selector_t *ia32_get_list_sched_selector(const void *self, list_sched_selector_t *selector) {
2012 memcpy(&ia32_sched_selector, selector, sizeof(ia32_sched_selector));
2013 ia32_sched_selector.exectime = ia32_sched_exectime;
2014 ia32_sched_selector.to_appear_in_schedule = ia32_to_appear_in_schedule;
2015 return &ia32_sched_selector;
2018 static const ilp_sched_selector_t *ia32_get_ilp_sched_selector(const void *self) {
2023 * Returns the necessary byte alignment for storing a register of given class.
2025 static int ia32_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) {
2026 ir_mode *mode = arch_register_class_mode(cls);
2027 int bytes = get_mode_size_bytes(mode);
2029 if (mode_is_float(mode) && bytes > 8)
2034 static const be_execution_unit_t ***ia32_get_allowed_execution_units(const void *self, const ir_node *irn) {
2035 static const be_execution_unit_t *_allowed_units_BRANCH[] = {
2036 &ia32_execution_units_BRANCH[IA32_EXECUNIT_TP_BRANCH_BRANCH1],
2037 &ia32_execution_units_BRANCH[IA32_EXECUNIT_TP_BRANCH_BRANCH2],
2040 static const be_execution_unit_t *_allowed_units_GP[] = {
2041 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EAX],
2042 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EBX],
2043 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_ECX],
2044 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EDX],
2045 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_ESI],
2046 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EDI],
2047 &ia32_execution_units_GP[IA32_EXECUNIT_TP_GP_GP_EBP],
2050 static const be_execution_unit_t *_allowed_units_DUMMY[] = {
2051 &be_machine_execution_units_DUMMY[0],
2054 static const be_execution_unit_t **_units_callret[] = {
2055 _allowed_units_BRANCH,
2058 static const be_execution_unit_t **_units_other[] = {
2062 static const be_execution_unit_t **_units_dummy[] = {
2063 _allowed_units_DUMMY,
2066 const be_execution_unit_t ***ret;
2068 if (is_ia32_irn(irn)) {
2069 ret = get_ia32_exec_units(irn);
2071 else if (is_be_node(irn)) {
2072 if (be_is_Call(irn) || be_is_Return(irn)) {
2073 ret = _units_callret;
2075 else if (be_is_Barrier(irn)) {
2090 * Return the abstract ia32 machine.
2092 static const be_machine_t *ia32_get_machine(const void *self) {
2093 const ia32_isa_t *isa = self;
2098 * Return irp irgs in the desired order.
2100 static ir_graph **ia32_get_irg_list(const void *self, ir_graph ***irg_list) {
2105 * Allows or disallows the creation of Psi nodes for the given Phi nodes.
2106 * @return 1 if allowed, 0 otherwise
2108 static int ia32_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j)
2110 ir_node *cmp, *cmp_a, *phi;
2113 /* we don't want long long an floating point Psi */
2114 #define IS_BAD_PSI_MODE(mode) (mode_is_float(mode) || get_mode_size_bits(mode) > 32)
2116 if (get_irn_mode(sel) != mode_b)
2119 cmp = get_Proj_pred(sel);
2120 cmp_a = get_Cmp_left(cmp);
2121 mode = get_irn_mode(cmp_a);
2123 if (IS_BAD_PSI_MODE(mode))
2126 /* check the Phi nodes */
2127 for (phi = phi_list; phi; phi = get_irn_link(phi)) {
2128 ir_node *pred_i = get_irn_n(phi, i);
2129 ir_node *pred_j = get_irn_n(phi, j);
2130 ir_mode *mode_i = get_irn_mode(pred_i);
2131 ir_mode *mode_j = get_irn_mode(pred_j);
2133 if (IS_BAD_PSI_MODE(mode_i) || IS_BAD_PSI_MODE(mode_j))
2137 #undef IS_BAD_PSI_MODE
2142 static ia32_intrinsic_env_t intrinsic_env = {
2143 NULL, /**< the irg, these entities belong to */
2144 NULL, /**< entity for first div operand (move into FPU) */
2145 NULL, /**< entity for second div operand (move into FPU) */
2146 NULL, /**< entity for converts ll -> d */
2147 NULL, /**< entity for converts d -> ll */
2151 * Returns the libFirm configuration parameter for this backend.
2153 static const backend_params *ia32_get_libfirm_params(void) {
2154 static const opt_if_conv_info_t ifconv = {
2155 4, /* maxdepth, doesn't matter for Psi-conversion */
2156 ia32_is_psi_allowed /* allows or disallows Psi creation for given selector */
2158 static const arch_dep_params_t ad = {
2159 1, /* also use subs */
2160 4, /* maximum shifts */
2161 31, /* maximum shift amount */
2163 1, /* allow Mulhs */
2164 1, /* allow Mulus */
2165 32 /* Mulh allowed up to 32 bit */
2167 static backend_params p = {
2168 NULL, /* no additional opcodes */
2169 NULL, /* will be set later */
2170 1, /* need dword lowering */
2171 ia32_create_intrinsic_fkt,
2172 &intrinsic_env, /* context for ia32_create_intrinsic_fkt */
2173 NULL, /* will be set later */
2177 p.if_conv_info = &ifconv;
2181 /* instruction set architectures. */
2182 static const lc_opt_enum_int_items_t arch_items[] = {
2183 { "386", arch_i386, },
2184 { "486", arch_i486, },
2185 { "pentium", arch_pentium, },
2186 { "586", arch_pentium, },
2187 { "pentiumpro", arch_pentium_pro, },
2188 { "686", arch_pentium_pro, },
2189 { "pentiummmx", arch_pentium_mmx, },
2190 { "pentium2", arch_pentium_2, },
2191 { "p2", arch_pentium_2, },
2192 { "pentium3", arch_pentium_3, },
2193 { "p3", arch_pentium_3, },
2194 { "pentium4", arch_pentium_4, },
2195 { "p4", arch_pentium_4, },
2196 { "pentiumm", arch_pentium_m, },
2197 { "pm", arch_pentium_m, },
2198 { "core", arch_core, },
2200 { "athlon", arch_athlon, },
2201 { "athlon64", arch_athlon_64, },
2202 { "opteron", arch_opteron, },
2206 static lc_opt_enum_int_var_t arch_var = {
2207 &ia32_isa_template.arch, arch_items
2210 static lc_opt_enum_int_var_t opt_arch_var = {
2211 &ia32_isa_template.opt_arch, arch_items
2214 static const lc_opt_enum_int_items_t fp_unit_items[] = {
2216 { "sse2", fp_sse2 },
2220 static lc_opt_enum_int_var_t fp_unit_var = {
2221 &ia32_isa_template.fp_kind, fp_unit_items
2224 static const lc_opt_enum_int_items_t gas_items[] = {
2225 { "normal", GAS_FLAVOUR_NORMAL },
2226 { "mingw", GAS_FLAVOUR_MINGW },
2230 static lc_opt_enum_int_var_t gas_var = {
2231 (int*) &be_gas_flavour, gas_items
2234 static const lc_opt_table_entry_t ia32_options[] = {
2235 LC_OPT_ENT_ENUM_INT("arch", "select the instruction architecture", &arch_var),
2236 LC_OPT_ENT_ENUM_INT("opt", "optimize for instruction architecture", &opt_arch_var),
2237 LC_OPT_ENT_ENUM_INT("fpunit", "select the floating point unit", &fp_unit_var),
2238 LC_OPT_ENT_NEGBIT("noaddrmode", "do not use address mode", &ia32_isa_template.opt, IA32_OPT_DOAM),
2239 LC_OPT_ENT_NEGBIT("nolea", "do not optimize for LEAs", &ia32_isa_template.opt, IA32_OPT_LEA),
2240 LC_OPT_ENT_NEGBIT("noplacecnst", "do not place constants", &ia32_isa_template.opt, IA32_OPT_PLACECNST),
2241 LC_OPT_ENT_NEGBIT("noimmop", "no operations with immediates", &ia32_isa_template.opt, IA32_OPT_IMMOPS),
2242 LC_OPT_ENT_NEGBIT("nopushargs", "do not create pushs for function arguments", &ia32_isa_template.opt, IA32_OPT_PUSHARGS),
2243 LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
2247 const arch_isa_if_t ia32_isa_if = {
2250 ia32_get_n_reg_class,
2252 ia32_get_reg_class_for_mode,
2254 ia32_get_irn_handler,
2255 ia32_get_code_generator_if,
2256 ia32_get_list_sched_selector,
2257 ia32_get_ilp_sched_selector,
2258 ia32_get_reg_class_alignment,
2259 ia32_get_libfirm_params,
2260 ia32_get_allowed_execution_units,
2265 void be_init_arch_ia32(void)
2267 lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
2268 lc_opt_entry_t *ia32_grp = lc_opt_get_grp(be_grp, "ia32");
2270 lc_opt_add_table(ia32_grp, ia32_options);
2271 be_register_isa_if("ia32", &ia32_isa_if);
2274 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ia32);