- Reworked backends to put out register_requirements into backend_info_t
[libfirm] / ir / be / TEMPLATE / TEMPLATE_transform.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   code selection (transform FIRM into TEMPLATE FIRM)
23  * @version $Id$
24  */
25 #include "config.h"
26
27 #include "irnode_t.h"
28 #include "irgraph_t.h"
29 #include "irmode_t.h"
30 #include "irgmod.h"
31 #include "iredges.h"
32 #include "irvrfy.h"
33 #include "ircons.h"
34 #include "iropt_t.h"
35 #include "debug.h"
36
37 #include "../benode.h"
38 #include "bearch_TEMPLATE_t.h"
39
40 #include "TEMPLATE_nodes_attr.h"
41 #include "TEMPLATE_transform.h"
42 #include "TEMPLATE_new_nodes.h"
43
44 #include "gen_TEMPLATE_regalloc_if.h"
45
46 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
47
48 /**
49  * Creates an TEMPLATE Add.
50  *
51  * @param env   The transformation environment
52  * @param op1   first operator
53  * @param op2   second operator
54  * @return the created TEMPLATE Add node
55  */
56 static ir_node *gen_Add(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
57 {
58         return new_bd_TEMPLATE_Add(env->dbg, env->block, op1, op2, env->mode);
59 }
60
61
62
63 /**
64  * Creates an TEMPLATE Mul.
65  *
66  * @param dbg       firm node dbg
67  * @param block     the block the new node should belong to
68  * @param op1       first operator
69  * @param op2       second operator
70  * @param mode      node mode
71  * @return the created TEMPLATE Mul node
72  */
73 static ir_node *gen_Mul(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
74 {
75         if (mode_is_float(env->mode)) {
76                 return new_bd_TEMPLATE_fMul(env->dbg, env->block, op1, op2, env->mode);
77         } else {
78                 return new_bd_TEMPLATE_Mul(env->dbg, env->block, op1, op2, env->mode);
79         }
80 }
81
82
83
84 /**
85  * Creates an TEMPLATE And.
86  *
87  * @param dbg       firm node dbg
88  * @param block     the block the new node should belong to
89  * @param op1       first operator
90  * @param op2       second operator
91  * @param mode      node mode
92  * @return the created TEMPLATE And node
93  */
94 static ir_node *gen_And(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
95 {
96         return new_bd_TEMPLATE_And(env->dbg, env->block, op1, op2, env->mode);
97 }
98
99
100
101 /**
102  * Creates an TEMPLATE Or.
103  *
104  * @param dbg       firm node dbg
105  * @param block     the block the new node should belong to
106  * @param op1       first operator
107  * @param op2       second operator
108  * @param mode      node mode
109  * @return the created TEMPLATE Or node
110  */
111 static ir_node *gen_Or(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
112 {
113         return new_bd_TEMPLATE_Or(env->dbg, env->block, op1, op2, env->mode);
114 }
115
116
117
118 /**
119  * Creates an TEMPLATE Eor.
120  *
121  * @param dbg       firm node dbg
122  * @param block     the block the new node should belong to
123  * @param op1       first operator
124  * @param op2       second operator
125  * @param mode      node mode
126  * @return the created TEMPLATE Eor node
127  */
128 static ir_node *gen_Eor(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
129 {
130         return new_bd_TEMPLATE_Eor(env->dbg, env->block, op1, op2, env->mode);
131 }
132
133
134
135 /**
136  * Creates an TEMPLATE Sub.
137  *
138  * @param dbg       firm node dbg
139  * @param block     the block the new node should belong to
140  * @param op1       first operator
141  * @param op2       second operator
142  * @param mode      node mode
143  * @return the created TEMPLATE Sub node
144  */
145 static ir_node *gen_Sub(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
146 {
147         if (mode_is_float(env->mode)) {
148                 return new_bd_TEMPLATE_fSub(env->dbg, env->block, op1, op2, env->mode);
149         } else {
150                 return new_bd_TEMPLATE_Sub(env->dbg, env->block, op1, op2, env->mode);
151         }
152 }
153
154
155
156 /**
157  * Creates an TEMPLATE floating Div.
158  *
159  * @param dbg       firm node dbg
160  * @param block     the block the new node should belong to
161  * @param op1       first operator
162  * @param op2       second operator
163  * @param mode      node mode
164  * @return the created TEMPLATE fDiv node
165  */
166 static ir_node *gen_Quot(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
167 {
168         return new_bd_TEMPLATE_fDiv(env->dbg, env->block, op1, op2, env->mode);
169 }
170
171
172
173 /**
174  * Creates an TEMPLATE Shl.
175  *
176  * @param dbg       firm node dbg
177  * @param block     the block the new node should belong to
178  * @param op1       first operator
179  * @param op2       second operator
180  * @param mode      node mode
181  * @return the created TEMPLATE Shl node
182  */
183 static ir_node *gen_Shl(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
184 {
185         return new_bd_TEMPLATE_Shl(env->dbg, env->block, op1, op2, env->mode);
186 }
187
188
189
190 /**
191  * Creates an TEMPLATE Shr.
192  *
193  * @param dbg       firm node dbg
194  * @param block     the block the new node should belong to
195  * @param op1       first operator
196  * @param op2       second operator
197  * @param mode      node mode
198  * @return the created TEMPLATE Shr node
199  */
200 static ir_node *gen_Shr(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2)
201 {
202         return new_bd_TEMPLATE_Shr(env->dbg, env->block, op1, op2, env->mode);
203 }
204
205
206
207 /**
208  * Transforms a Minus node.
209  *
210  * @param mod     the debug module
211  * @param block   the block the new node should belong to
212  * @param node    the ir Minus node
213  * @param op      operator
214  * @param mode    node mode
215  * @return the created TEMPLATE Minus node
216  */
217 static ir_node *gen_Minus(TEMPLATE_transform_env_t *env, ir_node *op)
218 {
219         if (mode_is_float(env->mode)) {
220                 return new_bd_TEMPLATE_fMinus(env->dbg, env->block, op, env->mode);
221         }
222         return new_bd_TEMPLATE_Minus(env->dbg, env->block, op, env->mode);
223 }
224
225
226
227 /**
228  * Transforms a Not node.
229  *
230  * @param mod     the debug module
231  * @param block   the block the new node should belong to
232  * @param node    the ir Not node
233  * @param op      operator
234  * @param mode    node mode
235  * @return the created TEMPLATE Not node
236  */
237 static ir_node *gen_Not(TEMPLATE_transform_env_t *env, ir_node *op)
238 {
239         return new_bd_TEMPLATE_Not(env->dbg, env->block, op, env->mode);
240 }
241
242
243
244 /**
245  * Transforms a Load.
246  *
247  * @param mod     the debug module
248  * @param block   the block the new node should belong to
249  * @param node    the ir Load node
250  * @param mode    node mode
251  * @return the created TEMPLATE Load node
252  */
253 static ir_node *gen_Load(TEMPLATE_transform_env_t *env)
254 {
255         ir_node *node = env->irn;
256
257         if (mode_is_float(env->mode)) {
258                 return new_bd_TEMPLATE_fLoad(env->dbg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
259         }
260         return new_bd_TEMPLATE_Load(env->dbg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
261 }
262
263
264
265 /**
266  * Transforms a Store.
267  *
268  * @param mod     the debug module
269  * @param block   the block the new node should belong to
270  * @param node    the ir Store node
271  * @param mode    node mode
272  * @return the created TEMPLATE Store node
273  */
274 static ir_node *gen_Store(TEMPLATE_transform_env_t *env)
275 {
276         ir_node *node = env->irn;
277
278         if (mode_is_float(env->mode)) {
279                 return new_bd_TEMPLATE_fStore(env->dbg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
280         }
281         return new_bd_TEMPLATE_Store(env->dbg, env->block, get_Store_ptr(node), get_Store_value(node), get_Store_mem(node), env->mode);
282 }
283
284
285
286 /*********************************************************
287  *                  _             _      _
288  *                 (_)           | |    (_)
289  *  _ __ ___   __ _ _ _ __     __| |_ __ ___   _____ _ __
290  * | '_ ` _ \ / _` | | '_ \   / _` | '__| \ \ / / _ \ '__|
291  * | | | | | | (_| | | | | | | (_| | |  | |\ V /  __/ |
292  * |_| |_| |_|\__,_|_|_| |_|  \__,_|_|  |_| \_/ \___|_|
293  *
294  *********************************************************/
295
296
297
298 /**
299  * Transforms the given firm node (and maybe some other related nodes)
300  * into one or more assembler nodes.
301  *
302  * @param node    the firm node
303  * @param env     the debug module
304  */
305 void TEMPLATE_transform_node(ir_node *node, void *env)
306 {
307         ir_opcode code             = get_irn_opcode(node);
308         ir_node *asm_node          = NULL;
309         TEMPLATE_transform_env_t tenv;
310         (void) env;
311
312         if (is_Block(node))
313                 return;
314
315         tenv.block    = get_nodes_block(node);
316         tenv.dbg      = get_irn_dbg_info(node);
317         tenv.irg      = current_ir_graph;
318         tenv.irn      = node;
319         tenv.mode     = get_irn_mode(node);
320
321 #define UNOP(a)        case iro_##a: asm_node = gen_##a(&tenv, get_##a##_op(node)); break
322 #define BINOP(a)       case iro_##a: asm_node = gen_##a(&tenv, get_##a##_left(node), get_##a##_right(node)); break
323 #define GEN(a)         case iro_##a: asm_node = gen_##a(&tenv); break
324 #define IGN(a)         case iro_##a: break
325 #define BAD(a)         case iro_##a: goto bad
326
327         DBG((dbg, LEVEL_1, "check %+F ... ", node));
328
329         switch (code) {
330                 BINOP(Add);
331                 BINOP(Mul);
332                 BINOP(And);
333                 BINOP(Or);
334                 BINOP(Eor);
335
336                 BINOP(Sub);
337                 BINOP(Shl);
338                 BINOP(Shr);
339                 BINOP(Quot);
340
341
342                 UNOP(Minus);
343                 UNOP(Not);
344
345                 GEN(Load);
346                 GEN(Store);
347
348                 /* TODO: implement these nodes */
349                 IGN(Shrs);
350                 IGN(Div);
351                 IGN(Mod);
352                 IGN(DivMod);
353                 IGN(Const);
354                 IGN(SymConst);
355                 IGN(Conv);
356                 IGN(Abs);
357                 IGN(Cond);
358                 IGN(Mux);
359                 IGN(Mulh);
360                 IGN(CopyB);
361                 IGN(Unknown);
362                 IGN(Cmp);
363
364                 /* You probably don't need to handle the following nodes */
365
366                 IGN(Call);
367                 IGN(Proj);
368                 IGN(Alloc);
369
370                 IGN(Block);
371                 IGN(Start);
372                 IGN(End);
373                 IGN(NoMem);
374                 IGN(Phi);
375                 IGN(IJmp);
376                 IGN(Jmp);
377                 IGN(Break);
378                 IGN(Sync);
379
380                 BAD(Raise);
381                 BAD(Sel);
382                 BAD(InstOf);
383                 BAD(Cast);
384                 BAD(Free);
385                 BAD(Tuple);
386                 BAD(Id);
387                 BAD(Bad);
388                 BAD(Confirm);
389                 BAD(Filter);
390                 BAD(CallBegin);
391                 BAD(EndReg);
392                 BAD(EndExcept);
393
394                 default:
395                         break;
396 bad:
397                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
398                 assert(0);
399         }
400
401         if (asm_node) {
402                 exchange(node, asm_node);
403                 DB((dbg, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
404         }
405         else {
406                 DB((dbg, LEVEL_1, "ignored\n"));
407         }
408 }
409
410 void TEMPLATE_init_transform(void)
411 {
412         FIRM_DBG_REGISTER(dbg, "firm.be.TEMPLATE.transform");
413 }