2 * Copyright (C) 1995-2008 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)
28 #include "irgraph_t.h"
37 #include "../benode.h"
38 #include "../betranshlp.h"
39 #include "bearch_TEMPLATE_t.h"
41 #include "TEMPLATE_nodes_attr.h"
42 #include "TEMPLATE_transform.h"
43 #include "TEMPLATE_new_nodes.h"
45 #include "gen_TEMPLATE_regalloc_if.h"
47 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
49 typedef ir_node* (*new_binop_func)(dbg_info *dbgi, ir_node *block,
50 ir_node *left, ir_node *right);
52 static ir_node *transform_binop(ir_node *node, new_binop_func new_func)
54 ir_node *block = get_nodes_block(node);
55 ir_node *new_block = be_transform_node(block);
56 dbg_info *dbgi = get_irn_dbg_info(node);
57 ir_node *left = get_binop_left(node);
58 ir_node *new_left = be_transform_node(left);
59 ir_node *right = get_binop_right(node);
60 ir_node *new_right = be_transform_node(right);
62 return new_func(dbgi, new_block, new_left, new_right);
65 static ir_node *gen_And(ir_node *node)
67 return transform_binop(node, new_bd_TEMPLATE_And);
70 static ir_node *gen_Or(ir_node *node)
72 return transform_binop(node, new_bd_TEMPLATE_Or);
75 static ir_node *gen_Eor(ir_node *node)
77 return transform_binop(node, new_bd_TEMPLATE_Xor);
80 static ir_node *gen_Div(ir_node *node)
82 ir_mode *mode = get_Div_resmode(node);
83 assert(mode_is_float(mode));
84 return transform_binop(node, new_bd_TEMPLATE_fDiv);
87 static ir_node *gen_Shl(ir_node *node)
89 ir_mode *mode = get_irn_mode(node);
90 if (get_mode_modulo_shift(mode) != 32)
91 panic("modulo shift!=32 not supported by TEMPLATE backend");
92 return transform_binop(node, new_bd_TEMPLATE_Shl);
95 static ir_node *gen_Shr(ir_node *node)
97 ir_mode *mode = get_irn_mode(node);
98 if (get_mode_modulo_shift(mode) != 32)
99 panic("modulo shift!=32 not supported by TEMPLATE backend");
100 return transform_binop(node, new_bd_TEMPLATE_Shr);
103 static ir_node *gen_Add(ir_node *node)
105 ir_mode *mode = get_irn_mode(node);
107 if (mode_is_float(mode)) {
108 return transform_binop(node, new_bd_TEMPLATE_fAdd);
110 return transform_binop(node, new_bd_TEMPLATE_Add);
113 static ir_node *gen_Sub(ir_node *node)
115 ir_mode *mode = get_irn_mode(node);
117 if (mode_is_float(mode)) {
118 return transform_binop(node, new_bd_TEMPLATE_fSub);
120 return transform_binop(node, new_bd_TEMPLATE_Sub);
123 static ir_node *gen_Mul(ir_node *node)
125 ir_mode *mode = get_irn_mode(node);
127 if (mode_is_float(mode)) {
128 return transform_binop(node, new_bd_TEMPLATE_fMul);
130 return transform_binop(node, new_bd_TEMPLATE_Mul);
134 typedef ir_node* (*new_unop_func)(dbg_info *dbgi, ir_node *block, ir_node *op);
136 static ir_node *transform_unop(ir_node *node, new_unop_func new_func)
138 ir_node *block = get_nodes_block(node);
139 ir_node *new_block = be_transform_node(block);
140 dbg_info *dbgi = get_irn_dbg_info(node);
141 ir_node *op = get_unop_op(node);
142 ir_node *new_op = be_transform_node(op);
144 return new_func(dbgi, new_block, new_op);
147 static ir_node *gen_Minus(ir_node *node)
149 ir_mode *mode = get_irn_mode(node);
151 if (mode_is_float(mode)) {
152 return transform_unop(node, new_bd_TEMPLATE_fMinus);
154 return transform_unop(node, new_bd_TEMPLATE_Minus);
157 static ir_node *gen_Not(ir_node *node)
159 return transform_unop(node, new_bd_TEMPLATE_Not);
162 static ir_node *gen_Const(ir_node *node)
164 ir_node *block = get_nodes_block(node);
165 ir_node *new_block = be_transform_node(block);
166 dbg_info *dbgi = get_irn_dbg_info(node);
167 ir_tarval *value = get_Const_tarval(node);
170 result = new_bd_TEMPLATE_Const(dbgi, new_block, value);
175 static ir_node *gen_Load(ir_node *node)
177 ir_node *block = get_nodes_block(node);
178 ir_node *new_block = be_transform_node(block);
179 dbg_info *dbgi = get_irn_dbg_info(node);
180 ir_node *ptr = get_Load_ptr(node);
181 ir_node *new_ptr = be_transform_node(ptr);
182 ir_node *mem = get_Load_mem(node);
183 ir_node *new_mem = be_transform_node(mem);
184 ir_mode *mode = get_irn_mode(node);
186 if (mode_is_float(mode)) {
187 return new_bd_TEMPLATE_fLoad(dbgi, new_block, new_ptr, new_mem, mode);
189 return new_bd_TEMPLATE_Load(dbgi, new_block, new_ptr, new_mem, mode);
192 static ir_node *gen_Store(ir_node *node)
194 ir_node *block = get_nodes_block(node);
195 ir_node *new_block = be_transform_node(block);
196 dbg_info *dbgi = get_irn_dbg_info(node);
197 ir_node *ptr = get_Store_ptr(node);
198 ir_node *new_ptr = be_transform_node(ptr);
199 ir_node *val = get_Store_value(node);
200 ir_node *new_val = be_transform_node(val);
201 ir_node *mem = get_Store_mem(node);
202 ir_node *new_mem = be_transform_node(mem);
203 ir_mode *mode = get_irn_mode(node);
205 if (mode_is_float(mode)) {
206 return new_bd_TEMPLATE_fStore(dbgi, new_block, new_ptr, new_val, new_mem, mode);
208 return new_bd_TEMPLATE_Store(dbgi, new_block, new_ptr, new_mem, new_val, mode);
211 static ir_node *gen_Jmp(ir_node *node)
213 ir_node *block = get_nodes_block(node);
214 ir_node *new_block = be_transform_node(block);
215 dbg_info *dbgi = get_irn_dbg_info(node);
217 return new_bd_TEMPLATE_Jmp(dbgi, new_block);
221 * returns true if mode should be stored in a general purpose register
223 static inline bool mode_needs_gp_reg(ir_mode *mode)
225 return mode_is_int(mode) || mode_is_reference(mode);
228 static ir_node *gen_Phi(ir_node *node)
230 const arch_register_req_t *req;
231 ir_node *block = get_nodes_block(node);
232 ir_node *new_block = be_transform_node(block);
233 dbg_info *dbgi = get_irn_dbg_info(node);
234 ir_mode *mode = get_irn_mode(node);
235 ir_graph *irg = get_irn_irg(node);
238 if (mode_needs_gp_reg(mode)) {
240 req = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].class_req;
242 req = arch_no_register_req;
245 phi = new_ir_node(dbgi, irg, new_block, op_Phi, mode, get_irn_arity(node),
247 copy_node_attr(irg, node, phi);
248 be_duplicate_deps(node, phi);
250 arch_set_irn_register_req_out(phi, 0, req);
251 be_enqueue_preds(node);
255 static void TEMPLATE_register_transformers(void)
257 be_start_transform_setup();
259 be_set_transform_function(op_Add, gen_Add);
260 be_set_transform_function(op_And, gen_And);
261 be_set_transform_function(op_Const, gen_Const);
262 be_set_transform_function(op_Div, gen_Div);
263 be_set_transform_function(op_Eor, gen_Eor);
264 be_set_transform_function(op_Jmp, gen_Jmp);
265 be_set_transform_function(op_Load, gen_Load);
266 be_set_transform_function(op_Minus, gen_Minus);
267 be_set_transform_function(op_Mul, gen_Mul);
268 be_set_transform_function(op_Not, gen_Not);
269 be_set_transform_function(op_Or, gen_Or);
270 be_set_transform_function(op_Phi, gen_Phi);
271 be_set_transform_function(op_Shl, gen_Shl);
272 be_set_transform_function(op_Shr, gen_Shr);
273 be_set_transform_function(op_Store, gen_Store);
274 be_set_transform_function(op_Sub, gen_Sub);
278 * Transform generic IR-nodes into TEMPLATE machine instructions
280 void TEMPLATE_transform_graph(ir_graph *irg)
282 TEMPLATE_register_transformers();
283 be_transform_graph(irg, NULL);
286 void TEMPLATE_init_transform(void)
288 FIRM_DBG_REGISTER(dbg, "firm.be.TEMPLATE.transform");