initial checkin for TEMPLATE backend
[libfirm] / ir / be / TEMPLATE / TEMPLATE_new_nodes.c
1 /**
2  * This file implements the creation of the achitecture specific firm opcodes
3  * and the coresponding node constructors for the TEMPLATE assembler irg.
4  * $Id$
5  */
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #include <stdlib.h>
11
12 #include "irprog_t.h"
13 #include "irgraph_t.h"
14 #include "irnode_t.h"
15 #include "irmode_t.h"
16 #include "ircons_t.h"
17 #include "iropt_t.h"
18 #include "irop.h"
19 #include "firm_common_t.h"
20 #include "irvrfy_t.h"
21
22 #include "../bearch.h"
23
24 #include "TEMPLATE_nodes_attr.h"
25 #include "TEMPLATE_new_nodes.h"
26 #include "gen_TEMPLATE_regalloc_if.h"
27
28
29
30 /***********************************************************************************
31  *      _                                   _       _             __
32  *     | |                                 (_)     | |           / _|
33  *   __| |_   _ _ __ ___  _ __   ___ _ __   _ _ __ | |_ ___ _ __| |_ __ _  ___ ___
34  *  / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__|  _/ _` |/ __/ _ \
35  * | (_| | |_| | | | | | | |_) |  __/ |    | | | | | ||  __/ |  | || (_| | (_|  __/
36  *  \__,_|\__,_|_| |_| |_| .__/ \___|_|    |_|_| |_|\__\___|_|  |_| \__,_|\___\___|
37  *                       | |
38  *                       |_|
39  ***********************************************************************************/
40
41 /**
42  * Dumper interface for dumping TEMPLATE nodes in vcg.
43  * @param n        the node to dump
44  * @param F        the output file
45  * @param reason   indicates which kind of information should be dumped
46  * @return 0 on success or != 0 on failure
47  */
48 static int dump_node_TEMPLATE(ir_node *n, FILE *F, dump_reason_t reason) {
49         const char    *name, *p;
50         ir_mode       *mode = NULL;
51         int            bad  = 0;
52         int            i;
53         TEMPLATE_attr_t *attr;
54         const TEMPLATE_register_req_t **reqs;
55         const arch_register_t         **slots;
56
57         switch (reason) {
58                 case dump_node_opcode_txt:
59                         name = get_irn_opname(n);
60                         fprintf(F, "%s", name);
61                         break;
62
63                 case dump_node_mode_txt:
64                         mode = get_irn_mode(n);
65
66                         if (mode == mode_BB || mode == mode_ANY || mode == mode_BAD || mode == mode_T) {
67                                 mode = NULL;
68                         }
69
70                         if (mode) {
71                                 fprintf(F, "[%s]", get_mode_name(mode));
72                         }
73                         break;
74
75                 case dump_node_nodeattr_txt:
76
77                         /* TODO: Dump node specific attributes which should */
78                         /* visible in node name (e.g. const or the like).   */
79
80                         break;
81
82                 case dump_node_info_txt:
83                         attr = get_TEMPLATE_attr(n);
84
85                         /* dump IN requirements */
86                         if (get_irn_arity(n) > 0) {
87                                 reqs = get_TEMPLATE_in_req_all(n);
88
89                                 if (reqs) {
90                                         for (i = 0; i < get_irn_arity(n); i++) {
91                                                 if (reqs[i]->req.type != arch_register_req_type_none) {
92                                                         fprintf(F, "in req #%d = [%s]\n", i, reqs[i]->req.cls->name);
93                                                 }
94                                                 else {
95                                                         fprintf(F, "in req #%d = n/a\n", i);
96                                                 }
97                                         }
98
99                                         fprintf(F, "\n");
100                                 }
101                                 else {
102                                         fprintf(F, "in req = N/A\n");
103                                 }
104                         }
105
106                         /* dump OUT requirements */
107                         if (attr->n_res > 0) {
108                                 reqs = get_TEMPLATE_out_req_all(n);
109
110                                 if (reqs) {
111                                         for (i = 0; i < attr->n_res; i++) {
112                                                 if (reqs[i]->req.type != arch_register_req_type_none) {
113                                                         fprintf(F, "out req #%d = [%s]\n", i, reqs[i]->req.cls->name);
114                                                 }
115                                                 else {
116                                                         fprintf(F, "out req #%d = n/a\n", i);
117                                                 }
118                                         }
119                                 }
120                                 else {
121                                         fprintf(F, "out req = N/A\n");
122                                 }
123                         }
124
125                         /* dump assigned registers */
126                         slots = get_TEMPLATE_slots(n);
127                         if (slots && attr->n_res > 0) {
128                                 for (i = 0; i < attr->n_res; i++) {
129                                         if (slots[i]) {
130                                                 fprintf(F, "reg #%d = %s\n", i, slots[i]->name);
131                                         }
132                                         else {
133                                                 fprintf(F, "reg #%d = n/a\n", i);
134                                         }
135                                 }
136                         }
137
138                         break;
139         }
140
141         return bad;
142 }
143
144
145
146 /***************************************************************************************************
147  *        _   _                   _       __        _                    _   _               _
148  *       | | | |                 | |     / /       | |                  | | | |             | |
149  *   __ _| |_| |_ _ __   ___  ___| |_   / /_ _  ___| |_   _ __ ___   ___| |_| |__   ___   __| |___
150  *  / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
151  * | (_| | |_| |_| |    \__ \  __/ |_ / / (_| |  __/ |_  | | | | | |  __/ |_| | | | (_) | (_| \__ \
152  *  \__,_|\__|\__|_|    |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
153  *                                        __/ |
154  *                                       |___/
155  ***************************************************************************************************/
156
157 /**
158  * Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast.
159  * Firm was made by people hating const :-(
160  */
161 TEMPLATE_attr_t *get_TEMPLATE_attr(const ir_node *node) {
162         assert(is_TEMPLATE_irn(node) && "need TEMPLATE node to get attributes");
163         return (TEMPLATE_attr_t *)get_irn_generic_attr((ir_node *)node);
164 }
165
166 /**
167  * Returns the argument register requirements of a TEMPLATE node.
168  */
169 const TEMPLATE_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node) {
170         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
171         return attr->in_req;
172 }
173
174 /**
175  * Returns the result register requirements of an TEMPLATE node.
176  */
177 const TEMPLATE_register_req_t **get_TEMPLATE_out_req_all(const ir_node *node) {
178         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
179         return attr->out_req;
180 }
181
182 /**
183  * Returns the argument register requirement at position pos of an TEMPLATE node.
184  */
185 const TEMPLATE_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos) {
186         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
187         return attr->in_req[pos];
188 }
189
190 /**
191  * Returns the result register requirement at position pos of an TEMPLATE node.
192  */
193 const TEMPLATE_register_req_t *get_TEMPLATE_out_req(const ir_node *node, int pos) {
194         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
195         return attr->out_req[pos];
196 }
197
198 /**
199  * Sets the OUT register requirements at position pos.
200  */
201 void set_TEMPLATE_req_out(ir_node *node, const TEMPLATE_register_req_t *req, int pos) {
202         TEMPLATE_attr_t *attr   = get_TEMPLATE_attr(node);
203         attr->out_req[pos] = req;
204 }
205
206 /**
207  * Sets the IN register requirements at position pos.
208  */
209 void set_TEMPLATE_req_in(ir_node *node, const TEMPLATE_register_req_t *req, int pos) {
210         TEMPLATE_attr_t *attr  = get_TEMPLATE_attr(node);
211         attr->in_req[pos] = req;
212 }
213
214 /**
215  * Returns the register flag of an TEMPLATE node.
216  */
217 arch_irn_flags_t get_TEMPLATE_flags(const ir_node *node) {
218         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
219         return attr->flags;
220 }
221
222 /**
223  * Sets the register flag of an TEMPLATE node.
224  */
225 void set_TEMPLATE_flags(const ir_node *node, arch_irn_flags_t flags) {
226         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
227         attr->flags      = flags;
228 }
229
230 /**
231  * Returns the result register slots of an TEMPLATE node.
232  */
233 const arch_register_t **get_TEMPLATE_slots(const ir_node *node) {
234         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
235         return attr->slots;
236 }
237
238 /**
239  * Returns the name of the OUT register at position pos.
240  */
241 const char *get_TEMPLATE_out_reg_name(const ir_node *node, int pos) {
242         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
243
244         assert(is_TEMPLATE_irn(node) && "Not an TEMPLATE node.");
245         assert(pos < attr->n_res && "Invalid OUT position.");
246         assert(attr->slots[pos]  && "No register assigned");
247
248         return arch_register_get_name(attr->slots[pos]);
249 }
250
251 /**
252  * Returns the index of the OUT register at position pos within its register class.
253  */
254 int get_TEMPLATE_out_regnr(const ir_node *node, int pos) {
255         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
256
257         assert(is_TEMPLATE_irn(node) && "Not an TEMPLATE node.");
258         assert(pos < attr->n_res && "Invalid OUT position.");
259         assert(attr->slots[pos]  && "No register assigned");
260
261         return arch_register_get_index(attr->slots[pos]);
262 }
263
264 /**
265  * Returns the OUT register at position pos.
266  */
267 const arch_register_t *get_TEMPLATE_out_reg(const ir_node *node, int pos) {
268         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
269
270         assert(is_TEMPLATE_irn(node) && "Not an TEMPLATE node.");
271         assert(pos < attr->n_res && "Invalid OUT position.");
272         assert(attr->slots[pos]  && "No register assigned");
273
274         return attr->slots[pos];
275 }
276
277 /**
278  * Sets the number of results.
279  */
280 void set_TEMPLATE_n_res(ir_node *node, int n_res) {
281         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
282         attr->n_res      = n_res;
283 }
284
285 /**
286  * Returns the number of results.
287  */
288 int get_TEMPLATE_n_res(const ir_node *node) {
289         TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
290         return attr->n_res;
291 }
292
293
294
295 /***************************************************************************************
296  *                  _                            _                   _
297  *                 | |                          | |                 | |
298  *  _ __   ___   __| | ___    ___ ___  _ __  ___| |_ _ __ _   _  ___| |_ ___  _ __ ___
299  * | '_ \ / _ \ / _` |/ _ \  / __/ _ \| '_ \/ __| __| '__| | | |/ __| __/ _ \| '__/ __|
300  * | | | | (_) | (_| |  __/ | (_| (_) | | | \__ \ |_| |  | |_| | (__| || (_) | |  \__ \
301  * |_| |_|\___/ \__,_|\___|  \___\___/|_| |_|___/\__|_|   \__,_|\___|\__\___/|_|  |___/
302  *
303  ***************************************************************************************/
304
305 /* Include the generated constructor functions */
306 #include "gen_TEMPLATE_new_nodes.c.inl"