Added beirgmod and benode
[libfirm] / ir / be / bearch_firm.c
1
2 /**
3  * ISA implementation for Firm IR nodes.
4  */
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8
9 #include "bitset.h"
10 #include "obst.h"
11
12 #include "bearch.h"
13
14 #include "irreflect.h"
15
16 #define N_REGS 64
17
18 static arch_register_t datab_regs[N_REGS];
19
20 static arch_register_class_t reg_classes[] = {
21   { "datab", N_REGS, datab_regs },
22 };
23
24 #define N_CLASSES \
25   (sizeof(reg_classes) / sizeof(reg_classes[0]))
26
27 #define CLS_DATAB 0
28
29 static void firm_init(void)
30 {
31   static struct obstack obst;
32   static int inited = 0;
33   int k;
34
35   if(inited)
36     return;
37
38   inited = 1;
39   obstack_init(&obst);
40
41   for(k = 0; k < N_CLASSES; ++k) {
42     const arch_register_class_t *cls = &reg_classes[k];
43     int i;
44
45     for(i = 0; i < cls->n_regs; ++i) {
46       int n;
47       char buf[8];
48       char *name;
49       arch_register_t *reg = (arch_register_t *) &cls->regs[i];
50
51       n = snprintf(buf, sizeof(buf), "r%d", i);
52       name = obstack_copy0(&obst, buf, n);
53
54       reg->name = name;
55       reg->reg_class = cls;
56       reg->index = i;
57       reg->type = 0;
58     }
59   }
60 }
61
62 static int firm_get_n_reg_class(void)
63 {
64   return N_CLASSES;
65 }
66
67 static const arch_register_class_t *firm_get_reg_class(int i)
68 {
69   assert(i >= 0 && i < N_CLASSES);
70   return &reg_classes[i];
71 }
72
73 static const arch_register_req_t firm_std_reg_req = {
74   arch_register_req_type_normal,
75   &reg_classes[CLS_DATAB],
76   { NULL }
77 };
78
79 static const rflct_arg_t *get_arg(const ir_node *irn, int pos)
80 {
81   int sig = rflct_get_signature(irn);
82   const rflct_arg_t *args =
83     rflct_get_args(get_irn_opcode(irn), sig, arch_pos_is_in(pos));
84   return &args[arch_pos_get_index(pos)];
85 }
86
87 static const arch_register_req_t *
88 firm_get_irn_reg_req(const arch_irn_ops_t *self,
89     arch_register_req_t *req, const ir_node *irn, int pos)
90 {
91   if(mode_is_datab(get_irn_mode(irn)))
92     memcpy(req, &firm_std_reg_req, sizeof(*req));
93   else
94     req = NULL;
95
96   return req;
97 }
98
99 static int firm_get_n_operands(const arch_irn_ops_t *self, const ir_node *irn, int in_out)
100 {
101   int sig = rflct_get_signature(irn);
102   return rflct_get_args_count(get_irn_opcode(irn), sig, in_out >= 0);
103 }
104
105 struct irn_reg_assoc {
106   const ir_node *irn;
107   int pos;
108   const arch_register_t *reg;
109 };
110
111 static int cmp_irn_reg_assoc(const void *a, const void *b, size_t len)
112 {
113   const struct irn_reg_assoc *x = a;
114   const struct irn_reg_assoc *y = b;
115
116   return !(x->irn == y->irn && x->pos == y->pos);
117 }
118
119 static struct irn_reg_assoc *get_irn_reg_assoc(const ir_node *irn, int pos)
120 {
121   static set *reg_set = NULL;
122   struct irn_reg_assoc templ;
123   unsigned int hash;
124
125   if(!reg_set)
126     reg_set = new_set(cmp_irn_reg_assoc, 1024);
127
128   templ.irn = irn;
129   templ.pos = pos;
130   templ.reg = NULL;
131   hash = HASH_PTR(irn) + 7 * pos;
132
133   return set_insert(reg_set, &templ, sizeof(templ), hash);
134 }
135
136 static void firm_set_irn_reg(const arch_irn_ops_t *self, ir_node *irn,
137     int pos, const arch_register_t *reg)
138 {
139   struct irn_reg_assoc *assoc = get_irn_reg_assoc(irn, pos);
140   assoc->reg = reg;
141 }
142
143 static const arch_register_t *firm_get_irn_reg(const arch_irn_ops_t *self,
144     const ir_node *irn, int pos)
145 {
146   struct irn_reg_assoc *assoc = get_irn_reg_assoc(irn, pos);
147   return assoc->reg;
148 }
149
150 static arch_irn_class_t firm_classify(const arch_irn_ops_t *self, const ir_node *irn)
151 {
152   return arch_irn_class_normal;
153 }
154
155 static const arch_irn_ops_t irn_ops = {
156   firm_get_irn_reg_req,
157   firm_get_n_operands,
158   firm_set_irn_reg,
159   firm_get_irn_reg,
160   firm_classify
161 };
162
163 const arch_isa_if_t firm_isa = {
164   firm_init,
165   firm_get_n_reg_class,
166   firm_get_reg_class
167 };
168
169 static const arch_irn_ops_t *firm_get_irn_ops(const arch_irn_handler_t *self,
170     const ir_node *irn)
171 {
172   return &irn_ops;
173 }
174
175 const arch_irn_handler_t firm_irn_handler = {
176   firm_get_irn_ops,
177 };