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