2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief code selection (transform FIRM into TEMPLATE FIRM)
30 #include "irgraph_t.h"
40 #include "../benode_t.h"
41 #include "bearch_TEMPLATE_t.h"
43 #include "TEMPLATE_nodes_attr.h"
45 #include "TEMPLATE_transform.h"
46 #include "TEMPLATE_new_nodes.h"
47 #include "TEMPLATE_map_regs.h"
49 #include "gen_TEMPLATE_regalloc_if.h"
51 extern ir_op *get_op_Mulh(void);
55 /****************************************************************************************************
57 * | | | | / _| | | (_)
58 * _ __ ___ __| | ___ | |_ _ __ __ _ _ __ ___| |_ ___ _ __ _ __ ___ __ _| |_ _ ___ _ __
59 * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __| _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
60 * | | | | (_) | (_| | __/ | |_| | | (_| | | | \__ \ || (_) | | | | | | | | (_| | |_| | (_) | | | |
61 * |_| |_|\___/ \__,_|\___| \__|_| \__,_|_| |_|___/_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_|
63 ****************************************************************************************************/
66 * Creates an TEMPLATE Add.
68 * @param env The transformation environment
69 * @param op1 first operator
70 * @param op2 second operator
71 * @return the created TEMPLATE Add node
73 static ir_node *gen_Add(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
74 return new_rd_TEMPLATE_Add(env->dbg, env->irg, env->block, op1, op2, env->mode);
80 * Creates an TEMPLATE Mul.
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 Mul node
89 static ir_node *gen_Mul(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
90 if (mode_is_float(env->mode)) {
91 return new_rd_TEMPLATE_fMul(env->dbg, env->irg, env->block, op1, op2, env->mode);
94 return new_rd_TEMPLATE_Mul(env->dbg, env->irg, env->block, op1, op2, env->mode);
101 * Creates an TEMPLATE And.
103 * @param dbg firm node dbg
104 * @param block the block the new node should belong to
105 * @param op1 first operator
106 * @param op2 second operator
107 * @param mode node mode
108 * @return the created TEMPLATE And node
110 static ir_node *gen_And(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
111 return new_rd_TEMPLATE_And(env->dbg, env->irg, env->block, op1, op2, env->mode);
117 * Creates an TEMPLATE Or.
119 * @param dbg firm node dbg
120 * @param block the block the new node should belong to
121 * @param op1 first operator
122 * @param op2 second operator
123 * @param mode node mode
124 * @return the created TEMPLATE Or node
126 static ir_node *gen_Or(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
127 return new_rd_TEMPLATE_Or(env->dbg, env->irg, env->block, op1, op2, env->mode);
133 * Creates an TEMPLATE Eor.
135 * @param dbg firm node dbg
136 * @param block the block the new node should belong to
137 * @param op1 first operator
138 * @param op2 second operator
139 * @param mode node mode
140 * @return the created TEMPLATE Eor node
142 static ir_node *gen_Eor(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
143 return new_rd_TEMPLATE_Eor(env->dbg, env->irg, env->block, op1, op2, env->mode);
149 * Creates an TEMPLATE Sub.
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 Sub node
158 static ir_node *gen_Sub(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
159 if (mode_is_float(env->mode)) {
160 return new_rd_TEMPLATE_fSub(env->dbg, env->irg, env->block, op1, op2, env->mode);
163 return new_rd_TEMPLATE_Sub(env->dbg, env->irg, env->block, op1, op2, env->mode);
170 * Creates an TEMPLATE floating Div.
172 * @param dbg firm node dbg
173 * @param block the block the new node should belong to
174 * @param op1 first operator
175 * @param op2 second operator
176 * @param mode node mode
177 * @return the created TEMPLATE fDiv node
179 static ir_node *gen_Quot(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
180 return new_rd_TEMPLATE_fDiv(env->dbg, env->irg, env->block, op1, op2, env->mode);
186 * Creates an TEMPLATE Shl.
188 * @param dbg firm node dbg
189 * @param block the block the new node should belong to
190 * @param op1 first operator
191 * @param op2 second operator
192 * @param mode node mode
193 * @return the created TEMPLATE Shl node
195 static ir_node *gen_Shl(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
196 return new_rd_TEMPLATE_Shl(env->dbg, env->irg, env->block, op1, op2, env->mode);
202 * Creates an TEMPLATE Shr.
204 * @param dbg firm node dbg
205 * @param block the block the new node should belong to
206 * @param op1 first operator
207 * @param op2 second operator
208 * @param mode node mode
209 * @return the created TEMPLATE Shr node
211 static ir_node *gen_Shr(TEMPLATE_transform_env_t *env, ir_node *op1, ir_node *op2) {
212 return new_rd_TEMPLATE_Shr(env->dbg, env->irg, env->block, op1, op2, env->mode);
218 * Transforms a Minus node.
220 * @param mod the debug module
221 * @param block the block the new node should belong to
222 * @param node the ir Minus node
224 * @param mode node mode
225 * @return the created TEMPLATE Minus node
227 static ir_node *gen_Minus(TEMPLATE_transform_env_t *env, ir_node *op) {
228 if (mode_is_float(env->mode)) {
229 return new_rd_TEMPLATE_fMinus(env->dbg, env->irg, env->block, op, env->mode);
231 return new_rd_TEMPLATE_Minus(env->dbg, env->irg, env->block, op, env->mode);
237 * Transforms a Not node.
239 * @param mod the debug module
240 * @param block the block the new node should belong to
241 * @param node the ir Not node
243 * @param mode node mode
244 * @return the created TEMPLATE Not node
246 static ir_node *gen_Not(TEMPLATE_transform_env_t *env, ir_node *op) {
247 return new_rd_TEMPLATE_Not(env->dbg, env->irg, env->block, op, env->mode);
255 * @param mod the debug module
256 * @param block the block the new node should belong to
257 * @param node the ir Load node
258 * @param mode node mode
259 * @return the created TEMPLATE Load node
261 static ir_node *gen_Load(TEMPLATE_transform_env_t *env) {
262 ir_node *node = env->irn;
264 if (mode_is_float(env->mode)) {
265 return new_rd_TEMPLATE_fLoad(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
267 return new_rd_TEMPLATE_Load(env->dbg, env->irg, env->block, get_Load_ptr(node), get_Load_mem(node), env->mode);
273 * Transforms a Store.
275 * @param mod the debug module
276 * @param block the block the new node should belong to
277 * @param node the ir Store node
278 * @param mode node mode
279 * @return the created TEMPLATE Store node
281 static ir_node *gen_Store(TEMPLATE_transform_env_t *env) {
282 ir_node *node = env->irn;
284 if (mode_is_float(env->mode)) {
285 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);
287 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);
292 /*********************************************************
295 * _ __ ___ __ _ _ _ __ __| |_ __ ___ _____ _ __
296 * | '_ ` _ \ / _` | | '_ \ / _` | '__| \ \ / / _ \ '__|
297 * | | | | | | (_| | | | | | | (_| | | | |\ V / __/ |
298 * |_| |_| |_|\__,_|_|_| |_| \__,_|_| |_| \_/ \___|_|
300 *********************************************************/
305 * Transforms the given firm node (and maybe some other related nodes)
306 * into one or more assembler nodes.
308 * @param node the firm node
309 * @param env the debug module
311 void TEMPLATE_transform_node(ir_node *node, void *env) {
312 TEMPLATE_code_gen_t *cgenv = (TEMPLATE_code_gen_t *)env;
313 ir_opcode code = get_irn_opcode(node);
314 ir_node *asm_node = NULL;
315 TEMPLATE_transform_env_t tenv;
320 tenv.block = get_nodes_block(node);
321 tenv.dbg = get_irn_dbg_info(node);
322 tenv.irg = current_ir_graph;
325 tenv.mod = cgenv->mod;
327 tenv.mode = get_irn_mode(node);
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
335 DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
356 /* TODO: implement these nodes */
371 /* You probably don't need to handle the following nodes */
402 if (get_irn_op(node) == get_op_Max() ||
403 get_irn_op(node) == get_op_Min() ||
404 get_irn_op(node) == get_op_Mulh())
406 /* TODO: implement */
411 fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node));
416 exchange(node, asm_node);
417 DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
420 DB((tenv.mod, LEVEL_1, "ignored\n"));