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