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