backend_marked was a buggy/wrong concept, removed it
[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 static ir_node *gen_Jmp(TEMPLATE_transform_env_t *env)
285 {
286         return new_bd_TEMPLATE_Jmp(env->dbg, env->block);
287 }
288
289
290
291
292 /**
293  * Transforms the given firm node (and maybe some other related nodes)
294  * into one or more assembler nodes.
295  *
296  * @param node    the firm node
297  * @param env     the debug module
298  */
299 void TEMPLATE_transform_node(ir_node *node, void *env)
300 {
301         ir_opcode code             = get_irn_opcode(node);
302         ir_node *asm_node          = NULL;
303         TEMPLATE_transform_env_t tenv;
304         (void) env;
305
306         if (is_Block(node))
307                 return;
308
309         tenv.block    = get_nodes_block(node);
310         tenv.dbg      = get_irn_dbg_info(node);
311         tenv.irg      = current_ir_graph;
312         tenv.irn      = node;
313         tenv.mode     = get_irn_mode(node);
314
315 #define UNOP(a)        case iro_##a: asm_node = gen_##a(&tenv, get_##a##_op(node)); break
316 #define BINOP(a)       case iro_##a: asm_node = gen_##a(&tenv, get_##a##_left(node), get_##a##_right(node)); break
317 #define GEN(a)         case iro_##a: asm_node = gen_##a(&tenv); break
318 #define IGN(a)         case iro_##a: break
319 #define BAD(a)         case iro_##a: goto bad
320
321         DBG((dbg, LEVEL_1, "check %+F ... ", node));
322
323         switch (code) {
324                 BINOP(Add);
325                 BINOP(Mul);
326                 BINOP(And);
327                 BINOP(Or);
328                 BINOP(Eor);
329
330                 BINOP(Sub);
331                 BINOP(Shl);
332                 BINOP(Shr);
333                 BINOP(Quot);
334
335
336                 UNOP(Minus);
337                 UNOP(Not);
338
339                 GEN(Load);
340                 GEN(Store);
341                 GEN(Jmp);
342
343                 /* TODO: implement these nodes */
344                 IGN(Shrs);
345                 IGN(Div);
346                 IGN(Mod);
347                 IGN(DivMod);
348                 IGN(Const);
349                 IGN(SymConst);
350                 IGN(Conv);
351                 IGN(Abs);
352                 IGN(Cond);
353                 IGN(Mux);
354                 IGN(Mulh);
355                 IGN(CopyB);
356                 IGN(Unknown);
357                 IGN(Cmp);
358
359                 /* You probably don't need to handle the following nodes */
360
361                 IGN(Call);
362                 IGN(Proj);
363                 IGN(Alloc);
364
365                 IGN(Block);
366                 IGN(Start);
367                 IGN(End);
368                 IGN(NoMem);
369                 IGN(Phi);
370                 IGN(IJmp);
371                 IGN(Break);
372                 IGN(Sync);
373
374                 BAD(Raise);
375                 BAD(Sel);
376                 BAD(InstOf);
377                 BAD(Cast);
378                 BAD(Free);
379                 BAD(Tuple);
380                 BAD(Id);
381                 BAD(Bad);
382                 BAD(Confirm);
383                 BAD(Filter);
384                 BAD(CallBegin);
385                 BAD(EndReg);
386                 BAD(EndExcept);
387
388                 default:
389                         break;
390 bad:
391                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
392                 assert(0);
393         }
394
395         if (asm_node) {
396                 exchange(node, asm_node);
397                 DB((dbg, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
398         } else {
399                 DB((dbg, LEVEL_1, "ignored\n"));
400         }
401 }
402
403 void TEMPLATE_init_transform(void)
404 {
405         FIRM_DBG_REGISTER(dbg, "firm.be.TEMPLATE.transform");
406 }