fixed precedence constraint
[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  * Creates an TEMPLATE RotL.
197  *
198  * @param dbg       firm node dbg
199  * @param block     the block the new node should belong to
200  * @param op1       first operator
201  * @param op2       second operator
202  * @param mode      node mode
203  * @return the created TEMPLATE RotL node
204  */
205 static ir_node *gen_RotL(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
206         return new_rd_TEMPLATE_RotL(env->dbg, env->irg, env->block, op1, op2, env->mode);
207 }
208
209
210
211 /**
212  * Transforms a Minus node.
213  *
214  * @param mod     the debug module
215  * @param block   the block the new node should belong to
216  * @param node    the ir Minus node
217  * @param op      operator
218  * @param mode    node mode
219  * @return the created TEMPLATE Minus node
220  */
221 static ir_node *gen_Minus(TEMPLATE_transform_env_t *env, ir_node *op) {
222         if (mode_is_float(env->mode)) {
223                 return new_rd_TEMPLATE_fMinus(env->dbg, env->irg, env->block, op, env->mode);
224         }
225         return new_rd_TEMPLATE_Minus(env->dbg, env->irg, env->block, op, env->mode);
226 }
227
228
229
230 /**
231  * Transforms a Not node.
232  *
233  * @param mod     the debug module
234  * @param block   the block the new node should belong to
235  * @param node    the ir Not node
236  * @param op      operator
237  * @param mode    node mode
238  * @return the created TEMPLATE Not node
239  */
240 static ir_node *gen_Not(TEMPLATE_transform_env_t *env, ir_node *op) {
241         return new_rd_TEMPLATE_Not(env->dbg, env->irg, env->block, op, env->mode);
242 }
243
244
245
246 /**
247  * Transforms a Load.
248  *
249  * @param mod     the debug module
250  * @param block   the block the new node should belong to
251  * @param node    the ir Load node
252  * @param mode    node mode
253  * @return the created TEMPLATE Load node
254  */
255 static ir_node *gen_Load(TEMPLATE_transform_env_t *env) {
256         ir_node *node = env->irn;
257
258         if (mode_is_float(env->mode)) {
259                 return new_rd_TEMPLATE_fLoad(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
260         }
261         return new_rd_TEMPLATE_Load(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
262 }
263
264
265
266 /**
267  * Transforms a Store.
268  *
269  * @param mod     the debug module
270  * @param block   the block the new node should belong to
271  * @param node    the ir Store node
272  * @param mode    node mode
273  * @return the created TEMPLATE Store node
274  */
275 static ir_node *gen_Store(TEMPLATE_transform_env_t *env) {
276         ir_node *node = env->irn;
277
278         if (mode_is_float(env->mode)) {
279                 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);
280         }
281         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);
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         TEMPLATE_code_gen_t *cgenv = (TEMPLATE_code_gen_t *)env;
307         ir_opcode code             = get_irn_opcode(node);
308         ir_node *asm_node          = NULL;
309         TEMPLATE_transform_env_t tenv;
310
311         if (is_Block(node))
312                 return;
313
314         tenv.block    = get_nodes_block(node);
315         tenv.dbg      = get_irn_dbg_info(node);
316         tenv.irg      = current_ir_graph;
317         tenv.irn      = node;
318         tenv.mod      = cgenv->mod;
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((tenv.mod, 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(CopyB);
360                 IGN(Unknown);
361                 IGN(Cmp);
362
363                 /* You probably don't need to handle the following nodes */
364
365                 IGN(Call);
366                 IGN(Proj);
367                 IGN(Alloc);
368
369                 IGN(Block);
370                 IGN(Start);
371                 IGN(End);
372                 IGN(NoMem);
373                 IGN(Phi);
374                 IGN(IJmp);
375                 IGN(Jmp);
376                 IGN(Break);
377                 IGN(Sync);
378
379                 BAD(Raise);
380                 BAD(Sel);
381                 BAD(InstOf);
382                 BAD(Cast);
383                 BAD(Free);
384                 BAD(Tuple);
385                 BAD(Id);
386                 BAD(Bad);
387                 BAD(Confirm);
388                 BAD(Filter);
389                 BAD(CallBegin);
390                 BAD(EndReg);
391                 BAD(EndExcept);
392
393                 default:
394                         if (get_irn_op(node) == get_op_Max() ||
395                                 get_irn_op(node) == get_op_Min() ||
396                                 get_irn_op(node) == get_op_Mulh())
397                         {
398                                 /* TODO: implement */
399                                 /* ignore for now  */
400                         }
401                         break;
402 bad:
403                 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
404                 assert(0);
405         }
406
407         if (asm_node) {
408                 exchange(node, asm_node);
409                 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
410         }
411         else {
412                 DB((tenv.mod, LEVEL_1, "ignored\n"));
413         }
414 }