2 * This is the main ia32 firm backend driver.
3 * @author Christian Wuerdig
20 #include <libcore/lc_opts.h>
21 #include <libcore/lc_opts_enum.h>
22 #endif /* WITH_LIBCORE */
24 #include "pseudo_irg.h"
28 #include "iredges_t.h"
36 #include "../beabi.h" /* the general register allocator interface */
37 #include "../benode_t.h"
38 #include "../belower.h"
39 #include "../besched_t.h"
41 #include "bearch_ia32_t.h"
43 #include "ia32_new_nodes.h" /* ia32 nodes interface */
44 #include "gen_ia32_regalloc_if.h" /* the generated interface (register type and class defenitions) */
45 #include "ia32_gen_decls.h" /* interface declaration emitter */
46 #include "ia32_transform.h"
47 #include "ia32_emitter.h"
48 #include "ia32_map_regs.h"
49 #include "ia32_optimize.h"
51 #include "ia32_dbg_stat.h"
53 #define DEBUG_MODULE "firm.be.ia32.isa"
56 static set *cur_reg_set = NULL;
59 #define is_Start(irn) (get_irn_opcode(irn) == iro_Start)
61 /* Creates the unique per irg GP NoReg node. */
62 ir_node *ia32_new_NoReg_gp(ia32_code_gen_t *cg) {
63 return be_abi_get_callee_save_irn(cg->birg->abi, &ia32_gp_regs[REG_GP_NOREG]);
66 /* Creates the unique per irg FP NoReg node. */
67 ir_node *ia32_new_NoReg_fp(ia32_code_gen_t *cg) {
68 return be_abi_get_callee_save_irn(cg->birg->abi,
69 USE_SSE2(cg) ? &ia32_xmm_regs[REG_XMM_NOREG] : &ia32_vfp_regs[REG_VFP_NOREG]);
72 /* returns the first Proj with given mode from mode_T node */
73 static ir_node *get_proj_for_mode(ir_node *node, ir_mode *mode) {
74 const ir_edge_t *edge;
76 assert(get_irn_mode(node) == mode_T && "Need mode_T node.");
78 foreach_out_edge(node, edge) {
79 ir_node *proj = get_edge_src_irn(edge);
80 if (get_irn_mode(proj) == mode)
87 /**************************************************
90 * _ __ ___ __ _ __ _| | | ___ ___ _| |_
91 * | '__/ _ \/ _` | / _` | | |/ _ \ / __| | | _|
92 * | | | __/ (_| | | (_| | | | (_) | (__ | | |
93 * |_| \___|\__, | \__,_|_|_|\___/ \___| |_|_|
96 **************************************************/
98 static ir_node *my_skip_proj(const ir_node *n) {
100 n = get_Proj_pred(n);
106 * Return register requirements for an ia32 node.
107 * If the node returns a tuple (mode_T) then the proj's
108 * will be asked for this information.
110 static const arch_register_req_t *ia32_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos) {
111 const ia32_irn_ops_t *ops = self;
112 const ia32_register_req_t *irn_req;
113 long node_pos = pos == -1 ? 0 : pos;
114 ir_mode *mode = is_Block(irn) ? NULL : get_irn_mode(irn);
115 FIRM_DBG_REGISTER(firm_dbg_module_t *mod, DEBUG_MODULE);
117 if (is_Block(irn) || mode == mode_M || mode == mode_X) {
118 DBG((mod, LEVEL_1, "ignoring Block, mode_M, mode_X node %+F\n", irn));
122 if (mode == mode_T && pos < 0) {
123 DBG((mod, LEVEL_1, "ignoring request OUT requirements for node %+F\n", irn));
127 DBG((mod, LEVEL_1, "get requirements at pos %d for %+F ... ", pos, irn));
131 node_pos = ia32_translate_proj_pos(irn);
137 irn = my_skip_proj(irn);
139 DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
142 if (is_ia32_irn(irn)) {
144 irn_req = get_ia32_in_req(irn, pos);
147 irn_req = get_ia32_out_req(irn, node_pos);
150 DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
152 memcpy(req, &(irn_req->req), sizeof(*req));
154 if (arch_register_req_is(&(irn_req->req), should_be_same)) {
155 assert(irn_req->same_pos >= 0 && "should be same constraint for in -> out NYI");
156 req->other_same = get_irn_n(irn, irn_req->same_pos);
159 if (arch_register_req_is(&(irn_req->req), should_be_different)) {
160 assert(irn_req->different_pos >= 0 && "should be different constraint for in -> out NYI");
161 req->other_different = get_irn_n(irn, irn_req->different_pos);
165 /* treat Unknowns like Const with default requirements */
166 if (is_Unknown(irn)) {
167 DB((mod, LEVEL_1, "returning UKNWN reqs for %+F\n", irn));
168 if (mode_is_float(mode)) {
169 if (USE_SSE2(ops->cg))
170 memcpy(req, &(ia32_default_req_ia32_xmm_xmm_UKNWN), sizeof(*req));
172 memcpy(req, &(ia32_default_req_ia32_vfp_vfp_UKNWN), sizeof(*req));
174 else if (mode_is_int(mode) || mode_is_reference(mode))
175 memcpy(req, &(ia32_default_req_ia32_gp_gp_UKNWN), sizeof(*req));
176 else if (mode == mode_T || mode == mode_M) {
177 DBG((mod, LEVEL_1, "ignoring Unknown node %+F\n", irn));
181 assert(0 && "unsupported Unknown-Mode");
184 DB((mod, LEVEL_1, "returning NULL for %+F (not ia32)\n", irn));
192 static void ia32_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg) {
194 const ia32_irn_ops_t *ops = self;
196 if (get_irn_mode(irn) == mode_X) {
200 DBG((ops->cg->mod, LEVEL_1, "ia32 assigned register %s to node %+F\n", reg->name, irn));
203 pos = ia32_translate_proj_pos(irn);
204 irn = my_skip_proj(irn);
207 if (is_ia32_irn(irn)) {
208 const arch_register_t **slots;
210 slots = get_ia32_slots(irn);
214 ia32_set_firm_reg(irn, reg, cur_reg_set);
218 static const arch_register_t *ia32_get_irn_reg(const void *self, const ir_node *irn) {
220 const arch_register_t *reg = NULL;
224 if (get_irn_mode(irn) == mode_X) {
228 pos = ia32_translate_proj_pos(irn);
229 irn = my_skip_proj(irn);
232 if (is_ia32_irn(irn)) {
233 const arch_register_t **slots;
234 slots = get_ia32_slots(irn);
238 reg = ia32_get_firm_reg(irn, cur_reg_set);
244 static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
245 irn = my_skip_proj(irn);
247 return arch_irn_class_branch;
248 else if (is_ia32_Cnst(irn))
249 return arch_irn_class_const;
250 else if (is_ia32_Ld(irn))
251 return arch_irn_class_load;
252 else if (is_ia32_St(irn) || is_ia32_Store8Bit(irn))
253 return arch_irn_class_store;
254 else if (is_ia32_irn(irn))
255 return arch_irn_class_normal;
260 static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
261 irn = my_skip_proj(irn);
262 if (is_ia32_irn(irn))
263 return get_ia32_flags(irn);
266 return arch_irn_flags_ignore;
271 static entity *ia32_get_frame_entity(const void *self, const ir_node *irn) {
272 return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL;
275 static void ia32_set_stack_bias(const void *self, ir_node *irn, int bias) {
277 const ia32_irn_ops_t *ops = self;
279 if (get_ia32_frame_ent(irn)) {
280 ia32_am_flavour_t am_flav = get_ia32_am_flavour(irn);
282 DBG((ops->cg->mod, LEVEL_1, "stack biased %+F with %d\n", irn, bias));
283 snprintf(buf, sizeof(buf), "%d", bias);
285 if (get_ia32_op_type(irn) == ia32_Normal) {
286 set_ia32_cnst(irn, buf);
289 add_ia32_am_offs(irn, buf);
291 set_ia32_am_flavour(irn, am_flav);
297 be_abi_call_flags_bits_t flags;
298 const arch_isa_t *isa;
299 const arch_env_t *aenv;
303 static void *ia32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg)
305 ia32_abi_env_t *env = xmalloc(sizeof(env[0]));
306 be_abi_call_flags_t fl = be_abi_call_get_flags(call);
307 env->flags = fl.bits;
310 env->isa = aenv->isa;
315 * Put all registers which are saved by the prologue/epilogue in a set.
317 * @param self The callback object.
318 * @param s The result set.
320 static void ia32_abi_dont_save_regs(void *self, pset *s)
322 ia32_abi_env_t *env = self;
323 if(env->flags.try_omit_fp)
324 pset_insert_ptr(s, env->isa->bp);
328 * Generate the routine prologue.
330 * @param self The callback object.
331 * @param mem A pointer to the mem node. Update this if you define new memory.
332 * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
334 * @return The register which shall be used as a stack frame base.
336 * All nodes which define registers in @p reg_map must keep @p reg_map current.
338 static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map)
340 ia32_abi_env_t *env = self;
342 if (!env->flags.try_omit_fp) {
343 int reg_size = get_mode_size_bytes(env->isa->bp->reg_class->mode);
344 ir_node *bl = get_irg_start_block(env->irg);
345 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
346 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
350 push = new_rd_ia32_Push(NULL, env->irg, bl, curr_sp, curr_bp, *mem);
351 curr_sp = new_r_Proj(env->irg, bl, push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
352 *mem = new_r_Proj(env->irg, bl, push, mode_M, pn_ia32_Push_M);
354 /* the push must have SP out register */
355 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
356 set_ia32_flags(push, arch_irn_flags_ignore);
358 /* move esp to ebp */
359 curr_bp = be_new_Copy(env->isa->bp->reg_class, env->irg, bl, curr_sp);
360 be_set_constr_single_reg(curr_bp, BE_OUT_POS(0), env->isa->bp);
361 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
362 be_node_set_flags(curr_bp, BE_OUT_POS(0), arch_irn_flags_ignore);
364 /* beware: the copy must be done before any other sp use */
365 curr_sp = be_new_CopyKeep_single(env->isa->sp->reg_class, env->irg, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
366 be_set_constr_single_reg(curr_sp, BE_OUT_POS(0), env->isa->sp);
367 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
368 be_node_set_flags(curr_sp, BE_OUT_POS(0), arch_irn_flags_ignore);
370 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
371 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
380 * Generate the routine epilogue.
381 * @param self The callback object.
382 * @param bl The block for the epilog
383 * @param mem A pointer to the mem node. Update this if you define new memory.
384 * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
385 * @return The register which shall be used as a stack frame base.
387 * All nodes which define registers in @p reg_map must keep @p reg_map current.
389 static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
391 ia32_abi_env_t *env = self;
392 ir_node *curr_sp = be_abi_reg_map_get(reg_map, env->isa->sp);
393 ir_node *curr_bp = be_abi_reg_map_get(reg_map, env->isa->bp);
395 if (env->flags.try_omit_fp) {
396 /* simply remove the stack frame here */
397 curr_sp = be_new_IncSP(env->isa->sp, env->irg, bl, curr_sp, *mem, BE_STACK_FRAME_SIZE, be_stack_dir_shrink);
400 const ia32_isa_t *isa = (ia32_isa_t *)env->isa;
401 ir_mode *mode_bp = env->isa->bp->reg_class->mode;
402 int reg_size = get_mode_size_bytes(env->isa->bp->reg_class->mode);
404 /* gcc always emits a leave at the end of a routine */
405 if (1 || ARCH_AMD(isa->opt_arch)) {
409 leave = new_rd_ia32_Leave(NULL, env->irg, bl, curr_sp, *mem);
410 set_ia32_flags(leave, arch_irn_flags_ignore);
411 curr_bp = new_r_Proj(current_ir_graph, bl, leave, mode_bp, pn_ia32_Leave_frame);
412 curr_sp = new_r_Proj(current_ir_graph, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
413 *mem = new_r_Proj(current_ir_graph, bl, leave, mode_M, pn_ia32_Leave_M);
418 /* copy ebp to esp */
419 curr_sp = be_new_SetSP(env->isa->sp, env->irg, bl, curr_sp, curr_bp, *mem);
422 pop = new_rd_ia32_Pop(NULL, env->irg, bl, curr_sp, *mem);
423 set_ia32_flags(pop, arch_irn_flags_ignore);
424 curr_bp = new_r_Proj(current_ir_graph, bl, pop, mode_bp, pn_ia32_Pop_res);
425 curr_sp = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
426 *mem = new_r_Proj(current_ir_graph, bl, pop, mode_M, pn_ia32_Pop_M);
428 arch_set_irn_register(env->aenv, curr_sp, env->isa->sp);
429 arch_set_irn_register(env->aenv, curr_bp, env->isa->bp);
432 be_abi_reg_map_set(reg_map, env->isa->sp, curr_sp);
433 be_abi_reg_map_set(reg_map, env->isa->bp, curr_bp);
437 * Produces the type which sits between the stack args and the locals on the stack.
438 * it will contain the return address and space to store the old base pointer.
439 * @return The Firm type modeling the ABI between type.
441 static ir_type *ia32_abi_get_between_type(void *self)
443 #define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
444 static ir_type *omit_fp_between_type = NULL;
445 static ir_type *between_type = NULL;
447 ia32_abi_env_t *env = self;
451 entity *ret_addr_ent;
452 entity *omit_fp_ret_addr_ent;
454 ir_type *old_bp_type = new_type_primitive(IDENT("bp"), mode_P);
455 ir_type *ret_addr_type = new_type_primitive(IDENT("return_addr"), mode_P);
457 between_type = new_type_struct(IDENT("ia32_between_type"));
458 old_bp_ent = new_entity(between_type, IDENT("old_bp"), old_bp_type);
459 ret_addr_ent = new_entity(between_type, IDENT("ret_addr"), ret_addr_type);
461 set_entity_offset_bytes(old_bp_ent, 0);
462 set_entity_offset_bytes(ret_addr_ent, get_type_size_bytes(old_bp_type));
463 set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
464 set_type_state(between_type, layout_fixed);
466 omit_fp_between_type = new_type_struct(IDENT("ia32_between_type_omit_fp"));
467 omit_fp_ret_addr_ent = new_entity(omit_fp_between_type, IDENT("ret_addr"), ret_addr_type);
469 set_entity_offset_bytes(omit_fp_ret_addr_ent, 0);
470 set_type_size_bytes(omit_fp_between_type, get_type_size_bytes(ret_addr_type));
471 set_type_state(omit_fp_between_type, layout_fixed);
474 return env->flags.try_omit_fp ? omit_fp_between_type : between_type;
479 * Get the estimated cycle count for @p irn.
481 * @param self The this pointer.
482 * @param irn The node.
484 * @return The estimated cycle count for this operation
486 static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
489 switch (get_ia32_irn_opcode(irn)) {
491 case iro_ia32_DivMod:
496 case iro_ia32_l_Load:
503 case iro_ia32_xStore:
504 case iro_ia32_l_Store:
506 case iro_ia32_Store8Bit:
514 case iro_ia32_l_MulS:
527 * Returns the inverse operation if @p irn, recalculating the argument at position @p i.
529 * @param irn The original operation
530 * @param i Index of the argument we want the inverse operation to yield
531 * @param inverse struct to be filled with the resulting inverse op
532 * @param obstack The obstack to use for allocation of the returned nodes array
533 * @return The inverse operation or NULL if operation invertible
535 static arch_inverse_t *ia32_get_inverse(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst) {
538 ir_node *block, *noreg, *nomem;
541 /* we cannot invert non-ia32 irns */
542 if (! is_ia32_irn(irn))
545 /* operand must always be a real operand (not base, index or mem) */
546 if (i != 2 && i != 3)
549 /* we don't invert address mode operations */
550 if (get_ia32_op_type(irn) != ia32_Normal)
553 irg = get_irn_irg(irn);
554 block = get_nodes_block(irn);
555 mode = get_ia32_res_mode(irn);
556 noreg = get_irn_n(irn, 0);
557 nomem = new_r_NoMem(irg);
559 /* initialize structure */
560 inverse->nodes = obstack_alloc(obst, 2 * sizeof(inverse->nodes[0]));
564 switch (get_ia32_irn_opcode(irn)) {
566 if (get_ia32_immop_type(irn) == ia32_ImmConst) {
567 /* we have an add with a const here */
568 /* invers == add with negated const */
569 inverse->nodes[0] = new_rd_ia32_Add(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
570 pnc = pn_ia32_Add_res;
572 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
573 set_ia32_Immop_tarval(inverse->nodes[0], tarval_neg(get_ia32_Immop_tarval(irn)));
574 set_ia32_commutative(inverse->nodes[0]);
576 else if (get_ia32_immop_type(irn) == ia32_ImmSymConst) {
577 /* we have an add with a symconst here */
578 /* invers == sub with const */
579 inverse->nodes[0] = new_rd_ia32_Sub(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
580 pnc = pn_ia32_Sub_res;
582 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
585 /* normal add: inverse == sub */
586 ir_node *proj = get_irn_out_edge_first(irn)->src;
587 assert(proj && is_Proj(proj));
589 inverse->nodes[0] = new_rd_ia32_Sub(NULL, irg, block, noreg, noreg, proj, get_irn_n(irn, i ^ 1), nomem);
590 pnc = pn_ia32_Sub_res;
595 if (get_ia32_immop_type(irn) != ia32_ImmNone) {
596 /* we have a sub with a const/symconst here */
597 /* invers == add with this const */
598 inverse->nodes[0] = new_rd_ia32_Add(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
599 pnc = pn_ia32_Add_res;
600 inverse->costs += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
601 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
605 ir_node *proj = get_irn_out_edge_first(irn)->src;
606 assert(proj && is_Proj(proj));
609 inverse->nodes[0] = new_rd_ia32_Add(NULL, irg, block, noreg, noreg, proj, get_irn_n(irn, 3), nomem);
612 inverse->nodes[0] = new_rd_ia32_Sub(NULL, irg, block, noreg, noreg, get_irn_n(irn, 2), proj, nomem);
614 pnc = pn_ia32_Sub_res;
619 if (get_ia32_immop_type(irn) != ia32_ImmNone) {
620 /* xor with const: inverse = xor */
621 inverse->nodes[0] = new_rd_ia32_Eor(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), noreg, nomem);
622 pnc = pn_ia32_Eor_res;
623 inverse->costs += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
624 copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
628 inverse->nodes[0] = new_rd_ia32_Eor(NULL, irg, block, noreg, noreg, (ir_node *)irn, get_irn_n(irn, i), nomem);
629 pnc = pn_ia32_Eor_res;
634 inverse->nodes[0] = new_rd_ia32_Not(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), nomem);
635 pnc = pn_ia32_Not_res;
639 inverse->nodes[0] = new_rd_ia32_Minus(NULL, irg, block, noreg, noreg, get_irn_n(irn, i), nomem);
640 pnc = pn_ia32_Minus_res;
644 /* inverse operation not supported */
648 set_ia32_res_mode(inverse->nodes[0], mode);
649 inverse->nodes[1] = new_r_Proj(irg, block, inverse->nodes[0], mode, pnc);
654 static const be_abi_callbacks_t ia32_abi_callbacks = {
657 ia32_abi_get_between_type,
658 ia32_abi_dont_save_regs,
663 /* fill register allocator interface */
665 static const arch_irn_ops_if_t ia32_irn_ops_if = {
666 ia32_get_irn_reg_req,
671 ia32_get_frame_entity,
674 ia32_get_op_estimated_cost
677 ia32_irn_ops_t ia32_irn_ops = {
684 /**************************************************
687 * ___ ___ __| | ___ __ _ ___ _ __ _| |_
688 * / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \ | | _|
689 * | (_| (_) | (_| | __/ (_| | __/ | | | | | |
690 * \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
693 **************************************************/
696 * Transforms the standard firm graph into
699 static void ia32_prepare_graph(void *self) {
700 ia32_code_gen_t *cg = self;
701 dom_front_info_t *dom;
702 DEBUG_ONLY(firm_dbg_module_t *old_mod = cg->mod;)
704 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.transform");
706 /* 1st: transform constants and psi condition trees */
707 irg_walk_blkwise_graph(cg->irg, ia32_place_consts_set_modes, ia32_transform_psi_cond_tree, cg);
709 /* 2nd: transform all remaining nodes */
710 ia32_register_transformers();
711 dom = be_compute_dominance_frontiers(cg->irg);
712 irg_walk_blkwise_graph(cg->irg, NULL, ia32_transform_node, cg);
713 be_free_dominance_frontiers(dom);
716 be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
718 /* 3rd: optimize address mode */
719 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.am");
720 ia32_optimize_addressmode(cg);
723 be_dump(cg->irg, "-am", dump_ir_block_graph_sched);
725 DEBUG_ONLY(cg->mod = old_mod;)
728 static INLINE int need_constraint_copy(ir_node *irn) {
730 ! is_ia32_Lea(irn) && \
731 ! is_ia32_Conv_I2I(irn) && \
732 ! is_ia32_Conv_I2I8Bit(irn) && \
733 ! is_ia32_CmpCMov(irn) && \
734 ! is_ia32_CmpSet(irn);
738 * Insert copies for all ia32 nodes where the should_be_same requirement
740 * Transform Sub into Neg -- Add if IN2 == OUT
742 static void ia32_finish_node(ir_node *irn, void *env) {
743 ia32_code_gen_t *cg = env;
744 const ia32_register_req_t **reqs;
745 const arch_register_t *out_reg, *in_reg, *in2_reg;
747 ir_node *copy, *in_node, *block, *in2_node;
748 ia32_op_type_t op_tp;
750 if (is_ia32_irn(irn)) {
751 /* AM Dest nodes don't produce any values */
752 op_tp = get_ia32_op_type(irn);
753 if (op_tp == ia32_AddrModeD)
756 reqs = get_ia32_out_req_all(irn);
757 n_res = get_ia32_n_res(irn);
758 block = get_nodes_block(irn);
760 /* check all OUT requirements, if there is a should_be_same */
761 if ((op_tp == ia32_Normal || op_tp == ia32_AddrModeS) && need_constraint_copy(irn))
763 for (i = 0; i < n_res; i++) {
764 if (arch_register_req_is(&(reqs[i]->req), should_be_same)) {
765 /* get in and out register */
766 out_reg = get_ia32_out_reg(irn, i);
767 in_node = get_irn_n(irn, reqs[i]->same_pos);
768 in_reg = arch_get_irn_register(cg->arch_env, in_node);
770 /* don't copy ignore nodes */
771 if (arch_irn_is(cg->arch_env, in_node, ignore) && is_Proj(in_node))
774 /* check if in and out register are equal */
775 if (! REGS_ARE_EQUAL(out_reg, in_reg)) {
776 /* in case of a commutative op: just exchange the in's */
777 /* beware: the current op could be everything, so test for ia32 */
778 /* commutativity first before getting the second in */
779 if (is_ia32_commutative(irn)) {
780 in2_node = get_irn_n(irn, reqs[i]->same_pos ^ 1);
781 in2_reg = arch_get_irn_register(cg->arch_env, in2_node);
783 if (REGS_ARE_EQUAL(out_reg, in2_reg)) {
784 set_irn_n(irn, reqs[i]->same_pos, in2_node);
785 set_irn_n(irn, reqs[i]->same_pos ^ 1, in_node);
792 DBG((cg->mod, LEVEL_1, "inserting copy for %+F in_pos %d\n", irn, reqs[i]->same_pos));
793 /* create copy from in register */
794 copy = be_new_Copy(arch_register_get_class(in_reg), cg->irg, block, in_node);
796 DBG_OPT_2ADDRCPY(copy);
798 /* destination is the out register */
799 arch_set_irn_register(cg->arch_env, copy, out_reg);
801 /* insert copy before the node into the schedule */
802 sched_add_before(irn, copy);
805 set_irn_n(irn, reqs[i]->same_pos, copy);
812 /* If we have a CondJmp/CmpSet/xCmpSet with immediate, we need to */
813 /* check if it's the right operand, otherwise we have */
814 /* to change it, as CMP doesn't support immediate as */
816 if ((is_ia32_CondJmp(irn) || is_ia32_CmpSet(irn) || is_ia32_xCmpSet(irn)) &&
817 (is_ia32_ImmConst(irn) || is_ia32_ImmSymConst(irn)) &&
818 op_tp == ia32_AddrModeS)
820 set_ia32_op_type(irn, ia32_AddrModeD);
821 set_ia32_pncode(irn, get_inversed_pnc(get_ia32_pncode(irn)));
824 /* check if there is a sub which need to be transformed */
825 ia32_transform_sub_to_neg_add(irn, cg);
827 /* transform a LEA into an Add if possible */
828 ia32_transform_lea_to_add(irn, cg);
832 /* check for peephole optimization */
833 ia32_peephole_optimization(irn, cg);
836 static void ia32_finish_irg_walker(ir_node *block, void *env) {
839 for (irn = sched_first(block); ! sched_is_end(irn); irn = next) {
840 next = sched_next(irn);
841 ia32_finish_node(irn, env);
845 static void ia32_push_on_queue_walker(ir_node *block, void *env) {
847 waitq_put(wq, block);
852 * Add Copy nodes for not fulfilled should_be_equal constraints
854 static void ia32_finish_irg(ir_graph *irg, ia32_code_gen_t *cg) {
855 waitq *wq = new_waitq();
857 /* Push the blocks on the waitq because ia32_finish_irg_walker starts more walks ... */
858 irg_block_walk_graph(irg, NULL, ia32_push_on_queue_walker, wq);
860 while (! waitq_empty(wq)) {
861 ir_node *block = waitq_get(wq);
862 ia32_finish_irg_walker(block, cg);
870 * Dummy functions for hooks we don't need but which must be filled.
872 static void ia32_before_sched(void *self) {
875 static void remove_unused_nodes(ir_node *irn, bitset_t *already_visited) {
883 mode = get_irn_mode(irn);
885 /* check if we already saw this node or the node has more than one user */
886 if (bitset_contains_irn(already_visited, irn) || get_irn_n_edges(irn) > 1)
889 /* mark irn visited */
890 bitset_add_irn(already_visited, irn);
892 /* non-Tuple nodes with one user: ok, return */
893 if (get_irn_n_edges(irn) >= 1 && mode != mode_T)
896 /* tuple node has one user which is not the mem proj-> ok */
897 if (mode == mode_T && get_irn_n_edges(irn) == 1) {
898 mem_proj = get_proj_for_mode(irn, mode_M);
903 for (i = get_irn_arity(irn) - 1; i >= 0; i--) {
904 ir_node *pred = get_irn_n(irn, i);
906 /* do not follow memory edges or we will accidentally remove stores */
907 if (is_Proj(pred) && get_irn_mode(pred) == mode_M)
910 set_irn_n(irn, i, new_Bad());
913 The current node is about to be removed: if the predecessor
914 has only this node as user, it need to be removed as well.
916 if (get_irn_n_edges(pred) <= 1)
917 remove_unused_nodes(pred, already_visited);
920 if (sched_is_scheduled(irn))
924 static void remove_unused_loads_walker(ir_node *irn, void *env) {
925 bitset_t *already_visited = env;
926 if (is_ia32_Ld(irn) && ! bitset_contains_irn(already_visited, irn))
927 remove_unused_nodes(irn, env);
931 * Called before the register allocator.
932 * Calculate a block schedule here. We need it for the x87
933 * simulator and the emitter.
935 static void ia32_before_ra(void *self) {
936 ia32_code_gen_t *cg = self;
937 bitset_t *already_visited = bitset_irg_malloc(cg->irg);
939 cg->blk_sched = sched_create_block_schedule(cg->irg);
943 There are sometimes unused loads, only pinned by memory.
944 We need to remove those Loads and all other nodes which won't be used
945 after removing the Load from schedule.
947 irg_walk_graph(cg->irg, remove_unused_loads_walker, NULL, already_visited);
948 bitset_free(already_visited);
953 * Transforms a be node into a Load.
955 static void transform_to_Load(ia32_transform_env_t *env) {
956 ir_node *irn = env->irn;
957 entity *ent = be_get_frame_entity(irn);
958 ir_mode *mode = env->mode;
959 ir_node *noreg = ia32_new_NoReg_gp(env->cg);
960 ir_node *nomem = new_rd_NoMem(env->irg);
961 ir_node *sched_point = NULL;
962 ir_node *ptr = get_irn_n(irn, 0);
963 ir_node *mem = be_is_Reload(irn) ? get_irn_n(irn, 1) : nomem;
964 ir_node *new_op, *proj;
965 const arch_register_t *reg;
967 if (sched_is_scheduled(irn)) {
968 sched_point = sched_prev(irn);
971 if (mode_is_float(mode)) {
972 if (USE_SSE2(env->cg))
973 new_op = new_rd_ia32_xLoad(env->dbg, env->irg, env->block, ptr, noreg, mem);
975 new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
978 new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
981 set_ia32_am_support(new_op, ia32_am_Source);
982 set_ia32_op_type(new_op, ia32_AddrModeS);
983 set_ia32_am_flavour(new_op, ia32_B);
984 set_ia32_ls_mode(new_op, mode);
985 set_ia32_frame_ent(new_op, ent);
986 set_ia32_use_frame(new_op);
988 DBG_OPT_RELOAD2LD(irn, new_op);
990 proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_Load_res);
993 sched_add_after(sched_point, new_op);
994 sched_add_after(new_op, proj);
999 /* copy the register from the old node to the new Load */
1000 reg = arch_get_irn_register(env->cg->arch_env, irn);
1001 arch_set_irn_register(env->cg->arch_env, new_op, reg);
1003 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, irn));
1005 exchange(irn, proj);
1009 * Transforms a be node into a Store.
1011 static void transform_to_Store(ia32_transform_env_t *env) {
1012 ir_node *irn = env->irn;
1013 entity *ent = be_get_frame_entity(irn);
1014 ir_mode *mode = env->mode;
1015 ir_node *noreg = ia32_new_NoReg_gp(env->cg);
1016 ir_node *nomem = new_rd_NoMem(env->irg);
1017 ir_node *ptr = get_irn_n(irn, 0);
1018 ir_node *val = get_irn_n(irn, 1);
1019 ir_node *new_op, *proj;
1020 ir_node *sched_point = NULL;
1022 if (sched_is_scheduled(irn)) {
1023 sched_point = sched_prev(irn);
1026 if (mode_is_float(mode)) {
1027 if (USE_SSE2(env->cg))
1028 new_op = new_rd_ia32_xStore(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1030 new_op = new_rd_ia32_vfst(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1032 else if (get_mode_size_bits(mode) == 8) {
1033 new_op = new_rd_ia32_Store8Bit(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1036 new_op = new_rd_ia32_Store(env->dbg, env->irg, env->block, ptr, noreg, val, nomem);
1039 set_ia32_am_support(new_op, ia32_am_Dest);
1040 set_ia32_op_type(new_op, ia32_AddrModeD);
1041 set_ia32_am_flavour(new_op, ia32_B);
1042 set_ia32_ls_mode(new_op, mode);
1043 set_ia32_frame_ent(new_op, ent);
1044 set_ia32_use_frame(new_op);
1046 DBG_OPT_SPILL2ST(irn, new_op);
1048 proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode_M, pn_ia32_Store_M);
1051 sched_add_after(sched_point, new_op);
1055 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, irn));
1057 exchange(irn, proj);
1061 * Fix the mode of Spill/Reload
1063 static ir_mode *fix_spill_mode(ia32_code_gen_t *cg, ir_mode *mode)
1065 if (mode_is_float(mode)) {
1077 * Block-Walker: Calls the transform functions Spill and Reload.
1079 static void ia32_after_ra_walker(ir_node *block, void *env) {
1080 ir_node *node, *prev;
1081 ia32_code_gen_t *cg = env;
1082 ia32_transform_env_t tenv;
1085 tenv.irg = current_ir_graph;
1087 DEBUG_ONLY(tenv.mod = cg->mod;)
1089 /* beware: the schedule is changed here */
1090 for (node = sched_last(block); !sched_is_begin(node); node = prev) {
1091 prev = sched_prev(node);
1092 if (be_is_Reload(node)) {
1093 /* we always reload the whole register */
1094 tenv.dbg = get_irn_dbg_info(node);
1096 tenv.mode = fix_spill_mode(cg, get_irn_mode(node));
1097 transform_to_Load(&tenv);
1099 else if (be_is_Spill(node)) {
1100 /* we always spill the whole register */
1101 tenv.dbg = get_irn_dbg_info(node);
1103 tenv.mode = fix_spill_mode(cg, get_irn_mode(be_get_Spill_context(node)));
1104 transform_to_Store(&tenv);
1110 * We transform Spill and Reload here. This needs to be done before
1111 * stack biasing otherwise we would miss the corrected offset for these nodes.
1113 * If x87 instruction should be emitted, run the x87 simulator and patch
1114 * the virtual instructions. This must obviously be done after register allocation.
1116 static void ia32_after_ra(void *self) {
1117 ia32_code_gen_t *cg = self;
1118 irg_block_walk_graph(cg->irg, NULL, ia32_after_ra_walker, self);
1120 /* if we do x87 code generation, rewrite all the virtual instructions and registers */
1121 if (cg->used_fp == fp_x87 || cg->force_sim) {
1122 x87_simulate_graph(cg->arch_env, cg->irg, cg->blk_sched);
1128 * Emits the code, closes the output file and frees
1129 * the code generator interface.
1131 static void ia32_codegen(void *self) {
1132 ia32_code_gen_t *cg = self;
1133 ir_graph *irg = cg->irg;
1135 ia32_finish_irg(irg, cg);
1137 be_dump(irg, "-finished", dump_ir_block_graph_sched);
1138 ia32_gen_routine(cg->isa->out, irg, cg);
1142 /* remove it from the isa */
1145 /* de-allocate code generator */
1146 del_set(cg->reg_set);
1151 static void *ia32_cg_init(const be_irg_t *birg);
1153 static const arch_code_generator_if_t ia32_code_gen_if = {
1155 NULL, /* before abi introduce hook */
1157 ia32_before_sched, /* before scheduling hook */
1158 ia32_before_ra, /* before register allocation hook */
1159 ia32_after_ra, /* after register allocation hook */
1160 ia32_codegen /* emit && done */
1164 * Initializes a IA32 code generator.
1166 static void *ia32_cg_init(const be_irg_t *birg) {
1167 ia32_isa_t *isa = (ia32_isa_t *)birg->main_env->arch_env->isa;
1168 ia32_code_gen_t *cg = xcalloc(1, sizeof(*cg));
1170 cg->impl = &ia32_code_gen_if;
1171 cg->irg = birg->irg;
1172 cg->reg_set = new_set(ia32_cmp_irn_reg_assoc, 1024);
1173 cg->arch_env = birg->main_env->arch_env;
1176 cg->blk_sched = NULL;
1177 cg->fp_to_gp = NULL;
1178 cg->gp_to_fp = NULL;
1179 cg->fp_kind = isa->fp_kind;
1180 cg->used_fp = fp_none;
1181 cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
1183 FIRM_DBG_REGISTER(cg->mod, "firm.be.ia32.cg");
1185 /* copy optimizations from isa for easier access */
1192 if (isa->name_obst_size) {
1193 //printf("freed %d bytes from name obst\n", isa->name_obst_size);
1194 isa->name_obst_size = 0;
1195 obstack_free(isa->name_obst, NULL);
1196 obstack_init(isa->name_obst);
1200 cur_reg_set = cg->reg_set;
1202 ia32_irn_ops.cg = cg;
1204 return (arch_code_generator_t *)cg;
1209 /*****************************************************************
1210 * ____ _ _ _____ _____
1211 * | _ \ | | | | |_ _|/ ____| /\
1212 * | |_) | __ _ ___| | _____ _ __ __| | | | | (___ / \
1213 * | _ < / _` |/ __| |/ / _ \ '_ \ / _` | | | \___ \ / /\ \
1214 * | |_) | (_| | (__| < __/ | | | (_| | _| |_ ____) / ____ \
1215 * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/ \_\
1217 *****************************************************************/
1220 * The template that generates a new ISA object.
1221 * Note that this template can be changed by command line
1224 static ia32_isa_t ia32_isa_template = {
1226 &ia32_isa_if, /* isa interface implementation */
1227 &ia32_gp_regs[REG_ESP], /* stack pointer register */
1228 &ia32_gp_regs[REG_EBP], /* base pointer register */
1229 -1, /* stack direction */
1231 NULL, /* 16bit register names */
1232 NULL, /* 8bit register names */
1236 IA32_OPT_INCDEC | /* optimize add 1, sub 1 into inc/dec default: on */
1237 IA32_OPT_DOAM | /* optimize address mode default: on */
1238 IA32_OPT_LEA | /* optimize for LEAs default: on */
1239 IA32_OPT_PLACECNST | /* place constants immediately before instructions, default: on */
1240 IA32_OPT_IMMOPS | /* operations can use immediates, default: on */
1241 IA32_OPT_EXTBB), /* use extended basic block scheduling, default: on */
1242 arch_pentium_4, /* instruction architecture */
1243 arch_pentium_4, /* optimize for architecture */
1244 fp_sse2, /* use sse2 unit */
1245 NULL, /* current code generator */
1247 NULL, /* name obstack */
1248 0 /* name obst size */
1253 * Initializes the backend ISA.
1255 static void *ia32_init(FILE *file_handle) {
1256 static int inited = 0;
1262 isa = xmalloc(sizeof(*isa));
1263 memcpy(isa, &ia32_isa_template, sizeof(*isa));
1265 ia32_register_init(isa);
1266 ia32_create_opcodes();
1268 if ((ARCH_INTEL(isa->arch) && isa->arch < arch_pentium_4) ||
1269 (ARCH_AMD(isa->arch) && isa->arch < arch_athlon))
1270 /* no SSE2 for these cpu's */
1271 isa->fp_kind = fp_x87;
1273 if (ARCH_INTEL(isa->opt_arch) && isa->opt_arch >= arch_pentium_4) {
1274 /* Pentium 4 don't like inc and dec instructions */
1275 isa->opt &= ~IA32_OPT_INCDEC;
1278 isa->regs_16bit = pmap_create();
1279 isa->regs_8bit = pmap_create();
1280 isa->types = pmap_create();
1281 isa->tv_ent = pmap_create();
1282 isa->out = file_handle;
1284 ia32_build_16bit_reg_map(isa->regs_16bit);
1285 ia32_build_8bit_reg_map(isa->regs_8bit);
1287 /* patch register names of x87 registers */
1289 ia32_st_regs[0].name = "st";
1290 ia32_st_regs[1].name = "st(1)";
1291 ia32_st_regs[2].name = "st(2)";
1292 ia32_st_regs[3].name = "st(3)";
1293 ia32_st_regs[4].name = "st(4)";
1294 ia32_st_regs[5].name = "st(5)";
1295 ia32_st_regs[6].name = "st(6)";
1296 ia32_st_regs[7].name = "st(7)";
1300 isa->name_obst = xmalloc(sizeof(*isa->name_obst));
1301 obstack_init(isa->name_obst);
1302 isa->name_obst_size = 0;
1305 ia32_handle_intrinsics();
1306 ia32_switch_section(NULL, NO_SECTION);
1307 fprintf(isa->out, "\t.intel_syntax\n");
1317 * Closes the output file and frees the ISA structure.
1319 static void ia32_done(void *self) {
1320 ia32_isa_t *isa = self;
1322 /* emit now all global declarations */
1323 ia32_gen_decls(isa->out);
1325 pmap_destroy(isa->regs_16bit);
1326 pmap_destroy(isa->regs_8bit);
1327 pmap_destroy(isa->tv_ent);
1328 pmap_destroy(isa->types);
1331 //printf("name obst size = %d bytes\n", isa->name_obst_size);
1332 obstack_free(isa->name_obst, NULL);
1340 * Return the number of register classes for this architecture.
1341 * We report always these:
1342 * - the general purpose registers
1343 * - the SSE floating point register set
1344 * - the virtual floating point registers
1346 static int ia32_get_n_reg_class(const void *self) {
1351 * Return the register class for index i.
1353 static const arch_register_class_t *ia32_get_reg_class(const void *self, int i) {
1354 const ia32_isa_t *isa = self;
1355 assert(i >= 0 && i < 3 && "Invalid ia32 register class requested.");
1357 return &ia32_reg_classes[CLASS_ia32_gp];
1359 return &ia32_reg_classes[CLASS_ia32_xmm];
1361 return &ia32_reg_classes[CLASS_ia32_vfp];
1365 * Get the register class which shall be used to store a value of a given mode.
1366 * @param self The this pointer.
1367 * @param mode The mode in question.
1368 * @return A register class which can hold values of the given mode.
1370 const arch_register_class_t *ia32_get_reg_class_for_mode(const void *self, const ir_mode *mode) {
1371 const ia32_isa_t *isa = self;
1372 if (mode_is_float(mode)) {
1373 return USE_SSE2(isa) ? &ia32_reg_classes[CLASS_ia32_xmm] : &ia32_reg_classes[CLASS_ia32_vfp];
1376 return &ia32_reg_classes[CLASS_ia32_gp];
1380 * Get the ABI restrictions for procedure calls.
1381 * @param self The this pointer.
1382 * @param method_type The type of the method (procedure) in question.
1383 * @param abi The abi object to be modified
1385 static void ia32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi) {
1386 const ia32_isa_t *isa = self;
1389 unsigned cc = get_method_calling_convention(method_type);
1390 int n = get_method_n_params(method_type);
1393 int i, ignore_1, ignore_2;
1395 const arch_register_t *reg;
1396 be_abi_call_flags_t call_flags = be_abi_call_get_flags(abi);
1398 unsigned use_push = !IS_P6_ARCH(isa->opt_arch);
1400 /* set abi flags for calls */
1401 call_flags.bits.left_to_right = 0; /* always last arg first on stack */
1402 call_flags.bits.store_args_sequential = use_push;
1403 /* call_flags.bits.try_omit_fp not changed: can handle both settings */
1404 call_flags.bits.fp_free = 0; /* the frame pointer is fixed in IA32 */
1405 call_flags.bits.call_has_imm = 1; /* IA32 calls can have immediate address */
1407 /* set stack parameter passing style */
1408 be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
1410 /* collect the mode for each type */
1411 modes = alloca(n * sizeof(modes[0]));
1413 for (i = 0; i < n; i++) {
1414 tp = get_method_param_type(method_type, i);
1415 modes[i] = get_type_mode(tp);
1418 /* set register parameters */
1419 if (cc & cc_reg_param) {
1420 /* determine the number of parameters passed via registers */
1421 biggest_n = ia32_get_n_regparam_class(n, modes, &ignore_1, &ignore_2);
1423 /* loop over all parameters and set the register requirements */
1424 for (i = 0; i <= biggest_n; i++) {
1425 reg = ia32_get_RegParam_reg(n, modes, i, cc);
1426 assert(reg && "kaputt");
1427 be_abi_call_param_reg(abi, i, reg);
1434 /* set stack parameters */
1435 for (i = stack_idx; i < n; i++) {
1436 be_abi_call_param_stack(abi, i, 1, 0, 0);
1440 /* set return registers */
1441 n = get_method_n_ress(method_type);
1443 assert(n <= 2 && "more than two results not supported");
1445 /* In case of 64bit returns, we will have two 32bit values */
1447 tp = get_method_res_type(method_type, 0);
1448 mode = get_type_mode(tp);
1450 assert(!mode_is_float(mode) && "two FP results not supported");
1452 tp = get_method_res_type(method_type, 1);
1453 mode = get_type_mode(tp);
1455 assert(!mode_is_float(mode) && "two FP results not supported");
1457 be_abi_call_res_reg(abi, 0, &ia32_gp_regs[REG_EAX]);
1458 be_abi_call_res_reg(abi, 1, &ia32_gp_regs[REG_EDX]);
1461 const arch_register_t *reg;
1463 tp = get_method_res_type(method_type, 0);
1464 assert(is_atomic_type(tp));
1465 mode = get_type_mode(tp);
1467 reg = mode_is_float(mode) ?
1468 (USE_SSE2(isa) ? &ia32_xmm_regs[REG_XMM0] : &ia32_vfp_regs[REG_VF0]) :
1469 &ia32_gp_regs[REG_EAX];
1471 be_abi_call_res_reg(abi, 0, reg);
1476 static const void *ia32_get_irn_ops(const arch_irn_handler_t *self, const ir_node *irn) {
1477 return &ia32_irn_ops;
1480 const arch_irn_handler_t ia32_irn_handler = {
1484 const arch_irn_handler_t *ia32_get_irn_handler(const void *self) {
1485 return &ia32_irn_handler;
1488 int ia32_to_appear_in_schedule(void *block_env, const ir_node *irn) {
1489 return is_ia32_irn(irn) ? 1 : -1;
1493 * Initializes the code generator interface.
1495 static const arch_code_generator_if_t *ia32_get_code_generator_if(void *self) {
1496 return &ia32_code_gen_if;
1499 list_sched_selector_t ia32_sched_selector;
1502 * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
1504 static const list_sched_selector_t *ia32_get_list_sched_selector(const void *self) {
1505 // memcpy(&ia32_sched_selector, reg_pressure_selector, sizeof(list_sched_selector_t));
1506 memcpy(&ia32_sched_selector, trivial_selector, sizeof(list_sched_selector_t));
1507 ia32_sched_selector.to_appear_in_schedule = ia32_to_appear_in_schedule;
1508 return &ia32_sched_selector;
1512 * Returns the necessary byte alignment for storing a register of given class.
1514 static int ia32_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) {
1515 ir_mode *mode = arch_register_class_mode(cls);
1516 int bytes = get_mode_size_bytes(mode);
1518 if (mode_is_float(mode) && bytes > 8)
1523 static ia32_intrinsic_env_t intrinsic_env = { NULL, NULL };
1526 * Returns the libFirm configuration parameter for this backend.
1528 static const backend_params *ia32_get_libfirm_params(void) {
1529 static const arch_dep_params_t ad = {
1530 1, /* also use subs */
1531 4, /* maximum shifts */
1532 31, /* maximum shift amount */
1534 1, /* allow Mulhs */
1535 1, /* allow Mulus */
1536 32 /* Mulh allowed up to 32 bit */
1538 static backend_params p = {
1539 NULL, /* no additional opcodes */
1540 NULL, /* will be set later */
1541 1, /* need dword lowering */
1542 ia32_create_intrinsic_fkt,
1543 &intrinsic_env, /* context for ia32_create_intrinsic_fkt */
1551 /* instruction set architectures. */
1552 static const lc_opt_enum_int_items_t arch_items[] = {
1553 { "386", arch_i386, },
1554 { "486", arch_i486, },
1555 { "pentium", arch_pentium, },
1556 { "586", arch_pentium, },
1557 { "pentiumpro", arch_pentium_pro, },
1558 { "686", arch_pentium_pro, },
1559 { "pentiummmx", arch_pentium_mmx, },
1560 { "pentium2", arch_pentium_2, },
1561 { "p2", arch_pentium_2, },
1562 { "pentium3", arch_pentium_3, },
1563 { "p3", arch_pentium_3, },
1564 { "pentium4", arch_pentium_4, },
1565 { "p4", arch_pentium_4, },
1566 { "pentiumm", arch_pentium_m, },
1567 { "pm", arch_pentium_m, },
1568 { "core", arch_core, },
1570 { "athlon", arch_athlon, },
1571 { "athlon64", arch_athlon_64, },
1572 { "opteron", arch_opteron, },
1576 static lc_opt_enum_int_var_t arch_var = {
1577 &ia32_isa_template.arch, arch_items
1580 static lc_opt_enum_int_var_t opt_arch_var = {
1581 &ia32_isa_template.opt_arch, arch_items
1584 static const lc_opt_enum_int_items_t fp_unit_items[] = {
1586 { "sse2", fp_sse2 },
1590 static lc_opt_enum_int_var_t fp_unit_var = {
1591 &ia32_isa_template.fp_kind, fp_unit_items
1594 static const lc_opt_enum_int_items_t gas_items[] = {
1595 { "linux", ASM_LINUX_GAS },
1596 { "mingw", ASM_MINGW_GAS },
1600 static lc_opt_enum_int_var_t gas_var = {
1601 (int *)&asm_flavour, gas_items
1604 static const lc_opt_table_entry_t ia32_options[] = {
1605 LC_OPT_ENT_ENUM_INT("arch", "select the instruction architecture", &arch_var),
1606 LC_OPT_ENT_ENUM_INT("opt", "optimize for instruction architecture", &opt_arch_var),
1607 LC_OPT_ENT_ENUM_INT("fpunit", "select the floating point unit", &fp_unit_var),
1608 LC_OPT_ENT_NEGBIT("noaddrmode", "do not use address mode", &ia32_isa_template.opt, IA32_OPT_DOAM),
1609 LC_OPT_ENT_NEGBIT("nolea", "do not optimize for LEAs", &ia32_isa_template.opt, IA32_OPT_LEA),
1610 LC_OPT_ENT_NEGBIT("noplacecnst", "do not place constants", &ia32_isa_template.opt, IA32_OPT_PLACECNST),
1611 LC_OPT_ENT_NEGBIT("noimmop", "no operations with immediates", &ia32_isa_template.opt, IA32_OPT_IMMOPS),
1612 LC_OPT_ENT_NEGBIT("noextbb", "do not use extended basic block scheduling", &ia32_isa_template.opt, IA32_OPT_EXTBB),
1613 LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
1618 * Register command line options for the ia32 backend.
1622 * ia32-arch=arch create instruction for arch
1623 * ia32-opt=arch optimize for run on arch
1624 * ia32-fpunit=unit select floating point unit (x87 or SSE2)
1625 * ia32-incdec optimize for inc/dec
1626 * ia32-noaddrmode do not use address mode
1627 * ia32-nolea do not optimize for LEAs
1628 * ia32-noplacecnst do not place constants,
1629 * ia32-noimmop no operations with immediates
1630 * ia32-noextbb do not use extended basic block scheduling
1631 * ia32-gasmode set the GAS compatibility mode
1633 static void ia32_register_options(lc_opt_entry_t *ent)
1635 lc_opt_entry_t *be_grp_ia32 = lc_opt_get_grp(ent, "ia32");
1636 lc_opt_add_table(be_grp_ia32, ia32_options);
1638 #endif /* WITH_LIBCORE */
1640 const arch_isa_if_t ia32_isa_if = {
1643 ia32_get_n_reg_class,
1645 ia32_get_reg_class_for_mode,
1647 ia32_get_irn_handler,
1648 ia32_get_code_generator_if,
1649 ia32_get_list_sched_selector,
1650 ia32_get_reg_class_alignment,
1651 ia32_get_libfirm_params,
1653 ia32_register_options