1 #include "pseudo_irg.h"
7 #include "../bearch.h" /* the general register allocator interface */
9 #include "ia32_new_nodes.h" /* ia32 nodes interface */
10 #include "gen_ia32_regalloc_if.h" /* the generated interface (register type and class defenitions) */
11 #include "ia32_gen_decls.h" /* interface declaration emitter */
12 #include "ia32_transform.h"
14 /* define shorter names for classes and indicees */
16 #define N_GP_REGS N_ia32_general_purpose_REGS
17 #define N_FP_REGS N_ia32_floating_point_REGS
18 #define N_FLAG_REGS N_ia32_flag_register_REGS
20 #define CLS_GP CLASS_ia32_general_purpose
21 #define CLS_FP CLASS_ia32_floating_point
22 #define CLS_FLAG CLASS_ia32_flag_register
24 #define N_CLASSES (sizeof(ia32_reg_classes) / sizeof(ia32_reg_classes[0]))
26 extern arch_register_class_t ia32_reg_classes[3];
28 /* Implementation of the register allocator functions */
31 * Return register requirements for an ia32 node.
32 * If the node returns a tuple (mode_T) then the proj's
33 * will be asked for this information.
35 static const arch_register_req_t *ia32_get_irn_reg_req(const arch_irn_ops_t *self, arch_register_req_t *req, const ir_node *irn, int pos) {
36 const arch_register_req_t **irn_req;
40 else if (is_ia32_irn(irn)) {
41 if (get_irn_mode(irn) == mode_T) {
45 if (arch_pos_is_in(pos)) {
46 irn_req = get_ia32_in_req(irn);
49 irn_req = get_ia32_out_req(irn);
53 memcpy(req, irn_req[pos], sizeof(*req));
62 static int ia32_get_n_operands(const arch_irn_ops_t *self, const ir_node *irn, int in_out) {
64 return get_irn_arity(irn);
66 return get_ia32_n_res(irn);
69 static void ia32_set_irn_reg(const arch_irn_ops_t *self, ir_node *irn, int pos, const arch_register_t *reg) {
70 if (is_ia32_irn(irn)) {
71 const arch_register_t **slots;
73 slots = get_ia32_out_slots(irn);
78 static const arch_register_t *ia32_get_irn_reg(const arch_irn_ops_t *self, const ir_node *irn, int pos) {
79 if (is_ia32_irn(irn)) {
80 const arch_register_t **slots;
82 slots = get_ia32_out_slots(irn);
90 static arch_irn_class_t ia32_classify(const arch_irn_ops_t *self, const ir_node *irn) {
91 if (is_ia32_irn(irn)) {
92 if (is_ia32_Cmp(irn) || is_ia32_Cmp_i(irn)) // TODO: ia32_Jmp
93 return arch_irn_class_branch;
95 return arch_irn_class_normal;
101 static arch_irn_flags_t ia32_get_flags(const arch_irn_ops_t *self, const ir_node *irn) {
102 if (is_ia32_irn(irn))
103 return get_ia32_flags(irn);
108 /* fill register allocator interface */
110 static const arch_irn_ops_t ia32_irn_ops = {
111 ia32_get_irn_reg_req,
119 /* Implementation of the backend isa functions */
121 static void ia32_init(void) {
122 ia32_register_init();
123 ia32_create_opcodes();
126 static int ia32_get_n_reg_class(void) {
130 static const arch_register_class_t *ia32_get_reg_class(int i) {
131 assert(i >= 0 && i < N_CLASSES && "Invalid ia32 register class requested.");
132 return &ia32_reg_classes[i];
135 static const arch_irn_ops_t *ia32_get_irn_ops(const arch_irn_handler_t *self, const ir_node *irn) {
136 return &ia32_irn_ops;
139 static void ia32_prepare_graph(ir_graph *irg) {
140 firm_dbg_module_t *dbg = firm_dbg_register("be.transform.ia32");
141 if (! is_pseudo_ir_graph(irg))
142 irg_walk_blkwise_graph(irg, NULL, ia32_transform_node, dbg);
145 static void ia32_codegen(FILE *out) {
149 for (i = 0; i < get_irp_n_irgs(); ++i) {
150 ir_graph *irg = get_irp_irg(i);
151 if (! is_pseudo_ir_graph(irg)) {
152 ia32_finish_irg(irg);
153 ia32_gen_routine(out, irg);
159 const arch_irn_handler_t ia32_irn_handler = {
163 /* fill isa interface */
165 const arch_isa_if_t ia32_isa = {
167 ia32_get_n_reg_class,