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)
27 #include "irgraph_t.h"
37 #include "betranshlp.h"
38 #include "bearch_TEMPLATE_t.h"
40 #include "TEMPLATE_nodes_attr.h"
41 #include "TEMPLATE_transform.h"
42 #include "TEMPLATE_new_nodes.h"
44 #include "gen_TEMPLATE_regalloc_if.h"
46 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
48 typedef ir_node* (*new_binop_func)(dbg_info *dbgi, ir_node *block,
49 ir_node *left, ir_node *right);
51 static ir_mode *gp_regs_mode;
53 static ir_node *transform_binop(ir_node *node, new_binop_func new_func)
55 ir_node *block = get_nodes_block(node);
56 ir_node *new_block = be_transform_node(block);
57 dbg_info *dbgi = get_irn_dbg_info(node);
58 ir_node *left = get_binop_left(node);
59 ir_node *new_left = be_transform_node(left);
60 ir_node *right = get_binop_right(node);
61 ir_node *new_right = be_transform_node(right);
63 return new_func(dbgi, new_block, new_left, new_right);
66 static ir_node *gen_And(ir_node *node)
68 return transform_binop(node, new_bd_TEMPLATE_And);
71 static ir_node *gen_Or(ir_node *node)
73 return transform_binop(node, new_bd_TEMPLATE_Or);
76 static ir_node *gen_Eor(ir_node *node)
78 return transform_binop(node, new_bd_TEMPLATE_Xor);
81 static ir_node *gen_Div(ir_node *node)
83 ir_mode *mode = get_Div_resmode(node);
84 assert(mode_is_float(mode));
85 return transform_binop(node, new_bd_TEMPLATE_fDiv);
88 static ir_node *gen_Shl(ir_node *node)
90 ir_mode *mode = get_irn_mode(node);
91 if (get_mode_modulo_shift(mode) != 32)
92 panic("modulo shift!=32 not supported");
93 return transform_binop(node, new_bd_TEMPLATE_Shl);
96 static ir_node *gen_Shr(ir_node *node)
98 ir_mode *mode = get_irn_mode(node);
99 if (get_mode_modulo_shift(mode) != 32)
100 panic("modulo shift!=32 not supported");
101 return transform_binop(node, new_bd_TEMPLATE_Shr);
104 static ir_node *gen_Add(ir_node *node)
106 ir_mode *mode = get_irn_mode(node);
108 if (mode_is_float(mode)) {
109 return transform_binop(node, new_bd_TEMPLATE_fAdd);
111 return transform_binop(node, new_bd_TEMPLATE_Add);
114 static ir_node *gen_Sub(ir_node *node)
116 ir_mode *mode = get_irn_mode(node);
118 if (mode_is_float(mode)) {
119 return transform_binop(node, new_bd_TEMPLATE_fSub);
121 return transform_binop(node, new_bd_TEMPLATE_Sub);
124 static ir_node *gen_Mul(ir_node *node)
126 ir_mode *mode = get_irn_mode(node);
128 if (mode_is_float(mode)) {
129 return transform_binop(node, new_bd_TEMPLATE_fMul);
131 return transform_binop(node, new_bd_TEMPLATE_Mul);
135 typedef ir_node* (*new_unop_func)(dbg_info *dbgi, ir_node *block, ir_node *op);
137 static ir_node *transform_unop(ir_node *node, new_unop_func new_func)
139 ir_node *block = get_nodes_block(node);
140 ir_node *new_block = be_transform_node(block);
141 dbg_info *dbgi = get_irn_dbg_info(node);
142 ir_node *op = get_unop_op(node);
143 ir_node *new_op = be_transform_node(op);
145 return new_func(dbgi, new_block, new_op);
148 static ir_node *gen_Minus(ir_node *node)
150 ir_mode *mode = get_irn_mode(node);
152 if (mode_is_float(mode)) {
153 return transform_unop(node, new_bd_TEMPLATE_fMinus);
155 return transform_unop(node, new_bd_TEMPLATE_Minus);
158 static ir_node *gen_Not(ir_node *node)
160 return transform_unop(node, new_bd_TEMPLATE_Not);
163 static ir_node *gen_Const(ir_node *node)
165 ir_node *block = get_nodes_block(node);
166 ir_node *new_block = be_transform_node(block);
167 dbg_info *dbgi = get_irn_dbg_info(node);
168 ir_tarval *value = get_Const_tarval(node);
171 result = new_bd_TEMPLATE_Const(dbgi, new_block, value);
176 static ir_node *gen_Load(ir_node *node)
178 ir_node *block = get_nodes_block(node);
179 ir_node *new_block = be_transform_node(block);
180 dbg_info *dbgi = get_irn_dbg_info(node);
181 ir_node *ptr = get_Load_ptr(node);
182 ir_node *new_ptr = be_transform_node(ptr);
183 ir_node *mem = get_Load_mem(node);
184 ir_node *new_mem = be_transform_node(mem);
185 ir_mode *mode = get_irn_mode(node);
187 if (mode_is_float(mode)) {
188 return new_bd_TEMPLATE_fLoad(dbgi, new_block, new_ptr, new_mem, mode);
190 return new_bd_TEMPLATE_Load(dbgi, new_block, new_ptr, new_mem, mode);
193 static ir_node *gen_Store(ir_node *node)
195 ir_node *block = get_nodes_block(node);
196 ir_node *new_block = be_transform_node(block);
197 dbg_info *dbgi = get_irn_dbg_info(node);
198 ir_node *ptr = get_Store_ptr(node);
199 ir_node *new_ptr = be_transform_node(ptr);
200 ir_node *val = get_Store_value(node);
201 ir_node *new_val = be_transform_node(val);
202 ir_node *mem = get_Store_mem(node);
203 ir_node *new_mem = be_transform_node(mem);
204 ir_mode *mode = get_irn_mode(node);
206 if (mode_is_float(mode)) {
207 return new_bd_TEMPLATE_fStore(dbgi, new_block, new_ptr, new_val, new_mem, mode);
209 return new_bd_TEMPLATE_Store(dbgi, new_block, new_ptr, new_mem, new_val, mode);
212 static ir_node *gen_Jmp(ir_node *node)
214 ir_node *block = get_nodes_block(node);
215 ir_node *new_block = be_transform_node(block);
216 dbg_info *dbgi = get_irn_dbg_info(node);
218 return new_bd_TEMPLATE_Jmp(dbgi, new_block);
221 static ir_node *gen_Start(ir_node *node)
223 dbg_info *dbgi = get_irn_dbg_info(node);
224 ir_node *block = get_nodes_block(node);
225 ir_node *new_block = be_transform_node(block);
227 return new_bd_TEMPLATE_Start(dbgi, new_block);
230 static ir_node *gen_Return(ir_node *node)
232 dbg_info *dbgi = get_irn_dbg_info(node);
233 ir_node *block = get_nodes_block(node);
234 ir_node *new_block = be_transform_node(block);
235 ir_node *mem = get_Return_mem(node);
236 ir_node *new_mem = be_transform_node(mem);
237 ir_graph *irg = get_irn_irg(node);
238 ir_node *sp = get_irg_frame(irg);
240 return new_bd_TEMPLATE_Return(dbgi, new_block, sp, new_mem);
244 * returns true if mode should be stored in a general purpose register
246 static inline bool mode_needs_gp_reg(ir_mode *mode)
248 return mode_is_int(mode) || mode_is_reference(mode);
251 static ir_node *gen_Phi(ir_node *node)
253 ir_mode *mode = get_irn_mode(node);
254 const arch_register_req_t *req;
255 if (mode_needs_gp_reg(mode)) {
257 req = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].class_req;
259 req = arch_no_register_req;
262 return be_transform_phi(node, req);
265 static ir_node *gen_Proj_Start(ir_node *node)
267 dbg_info *dbgi = get_irn_dbg_info(node);
268 ir_node *block = get_nodes_block(node);
269 ir_node *new_block = be_transform_node(block);
270 ir_node *start = get_Proj_pred(node);
271 ir_node *new_start = be_transform_node(start);
272 long pn = get_Proj_proj(node);
274 switch ((pn_Start) pn) {
275 case pn_Start_X_initial_exec:
276 return new_bd_TEMPLATE_Jmp(dbgi, new_block);
278 return new_rd_Proj(dbgi, new_start, mode_M, pn_TEMPLATE_Start_M);
279 case pn_Start_T_args:
280 return new_r_Bad(get_irn_irg(block), mode_T);
281 case pn_Start_P_frame_base:
282 return new_rd_Proj(dbgi, new_start, gp_regs_mode, pn_TEMPLATE_Start_stack);
284 panic("unexpected Start proj %ld\n", pn);
287 static ir_node *gen_Proj(ir_node *node)
289 ir_node *pred = get_Proj_pred(node);
291 switch (get_irn_opcode(pred)) {
292 case iro_Start: return gen_Proj_Start(node);
294 panic("code selection can't handle Proj after %+F\n", pred);
298 static void TEMPLATE_register_transformers(void)
300 be_start_transform_setup();
302 be_set_transform_function(op_Add, gen_Add);
303 be_set_transform_function(op_And, gen_And);
304 be_set_transform_function(op_Const, gen_Const);
305 be_set_transform_function(op_Div, gen_Div);
306 be_set_transform_function(op_Eor, gen_Eor);
307 be_set_transform_function(op_Jmp, gen_Jmp);
308 be_set_transform_function(op_Load, gen_Load);
309 be_set_transform_function(op_Minus, gen_Minus);
310 be_set_transform_function(op_Mul, gen_Mul);
311 be_set_transform_function(op_Not, gen_Not);
312 be_set_transform_function(op_Or, gen_Or);
313 be_set_transform_function(op_Proj, gen_Proj);
314 be_set_transform_function(op_Phi, gen_Phi);
315 be_set_transform_function(op_Return, gen_Return);
316 be_set_transform_function(op_Shl, gen_Shl);
317 be_set_transform_function(op_Shr, gen_Shr);
318 be_set_transform_function(op_Start, gen_Start);
319 be_set_transform_function(op_Store, gen_Store);
320 be_set_transform_function(op_Sub, gen_Sub);
324 * Transform generic IR-nodes into TEMPLATE machine instructions
326 void TEMPLATE_transform_graph(ir_graph *irg)
328 gp_regs_mode = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].mode;
330 TEMPLATE_register_transformers();
331 be_transform_graph(irg, NULL);
334 void TEMPLATE_init_transform(void)
336 FIRM_DBG_REGISTER(dbg, "firm.be.TEMPLATE.transform");