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