13 #include "../firm2arch_nodes_attr.h"
14 #include "../bearch_firm.h"
15 #include "transform.h"
16 #include "new_nodes.h"
18 /* determine if one operator is an Imm */
19 ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
21 return is_Imm(op1) ? op1 : (is_Imm(op2) ? op2 : NULL);
22 else return is_Imm(op2) ? op2 : NULL;
25 /* determine if one operator is not an Imm */
26 ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
27 return !is_Imm(op1) ? op1 : (!is_Imm(op2) ? op2 : NULL);
33 * Creates an ia32 Add with immediate.
36 * @param block the block the new node should belong to
37 * @param expr_op operator
38 * @param mode node mode
39 * @return the created ia23 Add_i node
41 ir_node *gen_imm_Add(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
42 return new_rd_ia32_Add_i(dbg, current_ir_graph, block, expr_op, mode);
46 * Creates an ia32 Add.
48 * @param dbg firm node dbg
49 * @param block the block the new node should belong to
50 * @param op1 first operator
51 * @param op2 second operator
52 * @param mode node mode
53 * @return the created ia32 Add node
55 ir_node *gen_Add(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
56 return new_rd_ia32_Add(dbg, current_ir_graph, block, op1, op2, mode);
62 * Creates an ia32 Mul with immediate.
65 * @param block the block the new node should belong to
66 * @param expr_op operator
67 * @param mode node mode
68 * @return the created ia23 Mul_i node
70 ir_node *gen_imm_Mul(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
71 return new_rd_ia32_Mul_i(dbg, current_ir_graph, block, expr_op, mode);
75 * Creates an ia32 Mul.
77 * @param dbg firm node dbg
78 * @param block the block the new node should belong to
79 * @param op1 first operator
80 * @param op2 second operator
81 * @param mode node mode
82 * @return the created ia32 Mul node
84 ir_node *gen_Mul(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
85 return new_rd_ia32_Mul(dbg, current_ir_graph, block, op1, op2, mode);
91 * Creates an ia32 And with immediate.
94 * @param block the block the new node should belong to
95 * @param expr_op operator
96 * @param mode node mode
97 * @return the created ia23 And_i node
99 ir_node *gen_imm_And(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
100 return new_rd_ia32_And_i(dbg, current_ir_graph, block, expr_op, mode);
104 * Creates an ia32 And.
106 * @param dbg firm node dbg
107 * @param block the block the new node should belong to
108 * @param op1 first operator
109 * @param op2 second operator
110 * @param mode node mode
111 * @return the created ia32 And node
113 ir_node *gen_And(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
114 return new_rd_ia32_And(dbg, current_ir_graph, block, op1, op2, mode);
120 * Creates an ia32 Or with immediate.
122 * @param dbg firm dbg
123 * @param block the block the new node should belong to
124 * @param expr_op operator
125 * @param mode node mode
126 * @return the created ia23 Or_i node
128 ir_node *gen_imm_Or(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
129 return new_rd_ia32_Or_i(dbg, current_ir_graph, block, expr_op, mode);
133 * Creates an ia32 Or.
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 ia32 Or node
142 ir_node *gen_Or(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
143 return new_rd_ia32_Or(dbg, current_ir_graph, block, op1, op2, mode);
149 * Creates an ia32 Eor with immediate.
151 * @param dbg firm dbg
152 * @param block the block the new node should belong to
153 * @param expr_op operator
154 * @param mode node mode
155 * @return the created ia23 Eor_i node
157 ir_node *gen_imm_Eor(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
158 return new_rd_ia32_Eor_i(dbg, current_ir_graph, block, expr_op, mode);
162 * Creates an ia32 Eor.
164 * @param dbg firm node dbg
165 * @param block the block the new node should belong to
166 * @param op1 first operator
167 * @param op2 second operator
168 * @param mode node mode
169 * @return the created ia32 Eor node
171 ir_node *gen_Eor(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
172 return new_rd_ia32_Eor(dbg, current_ir_graph, block, op1, op2, mode);
178 * Creates an ia32 Cmp with immediate.
180 * @param dbg firm dbg
181 * @param block the block the new node should belong to
182 * @param expr_op operator
183 * @param mode node mode
184 * @return the created ia23 Cmp_i node
186 ir_node *gen_imm_Cmp(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
187 return new_rd_ia32_Cmp_i(dbg, current_ir_graph, block, expr_op, mode);
191 * Creates an ia32 Cmp.
193 * @param dbg firm node dbg
194 * @param block the block the new node should belong to
195 * @param op1 first operator
196 * @param op2 second operator
197 * @param mode node mode
198 * @return the created ia32 Cmp node
200 ir_node *gen_Cmp(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
201 return new_rd_ia32_Cmp(dbg, current_ir_graph, block, op1, op2, mode);
207 * Creates an ia32 Sub with immediate.
209 * @param dbg firm dbg
210 * @param block the block the new node should belong to
211 * @param expr_op operator
212 * @param mode node mode
213 * @return the created ia23 Sub_i node
215 ir_node *gen_imm_Sub(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
216 return new_rd_ia32_Sub_i(dbg, current_ir_graph, block, expr_op, mode);
220 * Creates an ia32 Sub.
222 * @param dbg firm node dbg
223 * @param block the block the new node should belong to
224 * @param op1 first operator
225 * @param op2 second operator
226 * @param mode node mode
227 * @return the created ia32 Sub node
229 ir_node *gen_Sub(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
230 return new_rd_ia32_Sub(dbg, current_ir_graph, block, op1, op2, mode);
236 * Creates an ia32 Mod with immediate.
238 * @param dbg firm dbg
239 * @param block the block the new node should belong to
240 * @param expr_op operator
241 * @param mode node mode
242 * @return the created ia23 Mod_i node
244 ir_node *gen_imm_Mod(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
245 return new_rd_ia32_Mod_i(dbg, current_ir_graph, block, expr_op, mode);
249 * Creates an ia32 Mod.
251 * @param dbg firm node dbg
252 * @param block the block the new node should belong to
253 * @param op1 first operator
254 * @param op2 second operator
255 * @param mode node mode
256 * @return the created ia32 Mod node
258 ir_node *gen_Mod(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
259 return new_rd_ia32_Mod(dbg, current_ir_graph, block, op1, op2, mode);
265 * Creates an ia32 Shl with immediate.
267 * @param dbg firm dbg
268 * @param block the block the new node should belong to
269 * @param expr_op operator
270 * @param mode node mode
271 * @return the created ia23 Shl_i node
273 ir_node *gen_imm_Shl(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
274 return new_rd_ia32_Shl_i(dbg, current_ir_graph, block, expr_op, mode);
278 * Creates an ia32 Shl.
280 * @param dbg firm node dbg
281 * @param block the block the new node should belong to
282 * @param op1 first operator
283 * @param op2 second operator
284 * @param mode node mode
285 * @return the created ia32 Shl node
287 ir_node *gen_Shl(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
288 return new_rd_ia32_Shl(dbg, current_ir_graph, block, op1, op2, mode);
294 * Creates an ia32 Shr with immediate.
296 * @param dbg firm dbg
297 * @param block the block the new node should belong to
298 * @param expr_op operator
299 * @param mode node mode
300 * @return the created ia23 Shr_i node
302 ir_node *gen_imm_Shr(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
303 return new_rd_ia32_Shr_i(dbg, current_ir_graph, block, expr_op, mode);
307 * Creates an ia32 Shr.
309 * @param dbg firm node dbg
310 * @param block the block the new node should belong to
311 * @param op1 first operator
312 * @param op2 second operator
313 * @param mode node mode
314 * @return the created ia32 Shr node
316 ir_node *gen_Shr(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
317 return new_rd_ia32_Shr(dbg, current_ir_graph, block, op1, op2, mode);
323 * Creates an ia32 Shrs with immediate.
325 * @param dbg firm dbg
326 * @param block the block the new node should belong to
327 * @param expr_op operator
328 * @param mode node mode
329 * @return the created ia23 Shrs_i node
331 ir_node *gen_imm_Shrs(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
332 return new_rd_ia32_Shrs_i(dbg, current_ir_graph, block, expr_op, mode);
336 * Creates an ia32 Shrs.
338 * @param dbg firm node dbg
339 * @param block the block the new node should belong to
340 * @param op1 first operator
341 * @param op2 second operator
342 * @param mode node mode
343 * @return the created ia32 Shrs node
345 ir_node *gen_Shrs(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
346 return new_rd_ia32_Shrs(dbg, current_ir_graph, block, op1, op2, mode);
352 * Creates an ia32 Rot with immediate.
354 * @param dbg firm dbg
355 * @param block the block the new node should belong to
356 * @param expr_op operator
357 * @param mode node mode
358 * @return the created ia23 Rot_i node
360 ir_node *gen_imm_Rot(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
361 return new_rd_ia32_Rot_i(dbg, current_ir_graph, block, expr_op, mode);
365 * Creates an ia32 Rot.
367 * @param dbg firm node dbg
368 * @param block the block the new node should belong to
369 * @param op1 first operator
370 * @param op2 second operator
371 * @param mode node mode
372 * @return the created ia32 Rot node
374 ir_node *gen_Rot(dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
375 return new_rd_ia32_Rot(dbg, current_ir_graph, block, op1, op2, mode);
381 * Transforms a Conv node.
383 * @param mod the debug module
384 * @param block the block the new node should belong to
385 * @param node the ir Conv node
387 * @param mode node mode
388 * @return the created ia32 Conv node
390 ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
391 return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
397 * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor, op_Cmp)
398 * and non-commutative operations with com == 0 (op_Sub, op_Mod, op_Shl, op_Shr, op_Shrs, op_Rot)
400 * @param mod the debug module
401 * @param block the block node belongs to
402 * @param node the node to transform
403 * @param op1 first operator
404 * @param op2 second operator
405 * @param mode node mode
406 * @param com flag if op is commutative
407 * @return the created assembler node
409 ir_node *gen_arith_Op(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op1, ir_node *op2, ir_mode *mode, int com) {
410 dbg_info *dbg = get_irn_dbg_info(node);
411 ir_node *imm_op = NULL;
412 ir_node *expr_op = NULL;
413 ir_node *asm_node = NULL;
415 #define GENOP(a) case iro_##a: asm_node = gen_##a(dbg, block, op1, op2, mode); break
416 #define GENOPI(a) case iro_##a: asm_node = gen_imm_##a(dbg, block, expr_op, mode); break
419 imm_op = get_immediate_op(op1, op2);
421 imm_op = get_immediate_op(NULL, op2);
423 expr_op = get_expr_op(op1, op2);
425 /* TODO: Op(Imm, Imm) support */
426 if (is_Imm(op1) && is_Imm(op2)) {
427 DBG((mod, LEVEL_1, "found unexpected %s(Imm, Imm), creating binop ... ", get_irn_opname(node)));
431 DBG((mod, LEVEL_1, "(op1: %s -- op2: %s) ... ", get_irn_opname(op1), get_irn_opname(op2)));
434 imm_attr_t *attr_imm = (imm_attr_t *)get_irn_generic_attr(imm_op);
436 DBG((mod, LEVEL_1, "%s with imm ... ", get_irn_opname(node)));
438 /* make sure that Imm is a Const and no SymConst */
439 if (attr_imm->tp == imm_Const) {
440 switch(get_irn_opcode(node)) {
455 assert("binop_i: THIS SHOULD NOT HAPPEN");
458 /* make the Const an attribute */
459 asmop_attr *attr = (asmop_attr *)get_irn_generic_attr(asm_node);
460 attr->tv = attr_imm->data.tv;
461 } /* TODO: SymConst support */
467 DBG((mod, LEVEL_1, "%s as binop ... ", get_irn_opname(node)));
469 switch(get_irn_opcode(node)) {
484 assert("binop: THIS SHOULD NOT HAPPEN");
496 * @param mod the debug module
497 * @param block the block the new node should belong to
498 * @param node the ir Load node
499 * @param mode node mode
500 * @return the created ia32 Load node
502 ir_node *gen_Load(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
503 return new_rd_ia32_Load(get_irn_dbg_info(node), current_ir_graph, block, get_Load_mem(node), get_Load_ptr(node), mode);
509 * Transforms a Store.
511 * @param mod the debug module
512 * @param block the block the new node should belong to
513 * @param node the ir Store node
514 * @param mode node mode
515 * @return the created ia32 Store node
517 ir_node *gen_Store(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
518 return new_rd_ia32_Store(get_irn_dbg_info(node), current_ir_graph, block, get_Store_mem(node), get_Store_ptr(node), get_Store_value(node), mode);
524 * Transforms the given firm node (and maybe some other related nodes)
525 * into one or more assembler nodes.
527 * @param node the firm node
528 * @param env the debug module
530 void transform_node(ir_node *node, void *env) {
531 firm_dbg_module_t *mod = (firm_dbg_module_t *)env;
532 opcode code = get_irn_opcode(node);
533 ir_node *asm_node = NULL;
540 block = get_nodes_block(node);
541 mode = get_irn_mode(node);
543 #define BINOP_COM(a) case iro_##a: asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 1); break
544 #define BINOP_NCOM(a) case iro_##a: asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 0); break
545 #define UNOP(a) case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break
546 #define GEN(a) case iro_##a: asm_node = gen_##a(mod, block, node, mode); break
547 #define IGN(a) case iro_##a: break
549 DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node)));
565 // BINOP_ARITH_NCOM(DivMod);
573 exchange(node, asm_node);
574 DBG((mod, LEVEL_1, "created node %u\n", get_irn_node_nr(asm_node)));
577 DBG((mod, LEVEL_1, "ignored\n"));