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