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(firm_dbg_module_t *mod, 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(firm_dbg_module_t *mod, 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(firm_dbg_module_t *mod, 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(firm_dbg_module_t *mod, 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(firm_dbg_module_t *mod, 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(firm_dbg_module_t *mod, 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(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
232 /* transform "Const -- Sub -- Expr" into "Minus -- (Expr -- Sub -- Const)" */
233 if (is_Imm(op1) && !is_Imm(op2)) {
234 imm_attr_t *attr_imm = (imm_attr_t *)get_irn_generic_attr(op1);
236 DBG((mod, LEVEL_1, "optimizing c-e into -(e-c) ... "));
238 /* make sure that Imm is a Const and no SymConst */
239 if (attr_imm->tp == imm_Const) {
240 sub = gen_imm_Sub(dbg, block, op2, mode);
242 /* make the Const an attribute */
243 asmop_attr *attr = (asmop_attr *)get_irn_generic_attr(sub);
244 attr->tv = attr_imm->data.tv;
250 sub = new_rd_ia32_Minus(dbg, current_ir_graph, block, sub, mode);
254 sub = new_rd_ia32_Sub(dbg, current_ir_graph, block, op1, op2, mode);
263 * Creates an ia32 Mod with immediate.
265 * @param dbg firm dbg
266 * @param block the block the new node should belong to
267 * @param expr_op operator
268 * @param mode node mode
269 * @return the created ia23 Mod_i node
271 ir_node *gen_imm_Mod(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
272 return new_rd_ia32_Mod_i(dbg, current_ir_graph, block, expr_op, mode);
276 * Creates an ia32 Mod.
278 * @param dbg firm node dbg
279 * @param block the block the new node should belong to
280 * @param op1 first operator
281 * @param op2 second operator
282 * @param mode node mode
283 * @return the created ia32 Mod node
285 ir_node *gen_Mod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
286 return new_rd_ia32_Mod(dbg, current_ir_graph, block, op1, op2, mode);
292 * Creates an ia32 Shl with immediate.
294 * @param dbg firm dbg
295 * @param block the block the new node should belong to
296 * @param expr_op operator
297 * @param mode node mode
298 * @return the created ia23 Shl_i node
300 ir_node *gen_imm_Shl(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
301 return new_rd_ia32_Shl_i(dbg, current_ir_graph, block, expr_op, mode);
305 * Creates an ia32 Shl.
307 * @param dbg firm node dbg
308 * @param block the block the new node should belong to
309 * @param op1 first operator
310 * @param op2 second operator
311 * @param mode node mode
312 * @return the created ia32 Shl node
314 ir_node *gen_Shl(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
315 return new_rd_ia32_Shl(dbg, current_ir_graph, block, op1, op2, mode);
321 * Creates an ia32 Shr with immediate.
323 * @param dbg firm dbg
324 * @param block the block the new node should belong to
325 * @param expr_op operator
326 * @param mode node mode
327 * @return the created ia23 Shr_i node
329 ir_node *gen_imm_Shr(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
330 return new_rd_ia32_Shr_i(dbg, current_ir_graph, block, expr_op, mode);
334 * Creates an ia32 Shr.
336 * @param dbg firm node dbg
337 * @param block the block the new node should belong to
338 * @param op1 first operator
339 * @param op2 second operator
340 * @param mode node mode
341 * @return the created ia32 Shr node
343 ir_node *gen_Shr(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
344 return new_rd_ia32_Shr(dbg, current_ir_graph, block, op1, op2, mode);
350 * Creates an ia32 Shrs with immediate.
352 * @param dbg firm dbg
353 * @param block the block the new node should belong to
354 * @param expr_op operator
355 * @param mode node mode
356 * @return the created ia23 Shrs_i node
358 ir_node *gen_imm_Shrs(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
359 return new_rd_ia32_Shrs_i(dbg, current_ir_graph, block, expr_op, mode);
363 * Creates an ia32 Shrs.
365 * @param dbg firm node dbg
366 * @param block the block the new node should belong to
367 * @param op1 first operator
368 * @param op2 second operator
369 * @param mode node mode
370 * @return the created ia32 Shrs node
372 ir_node *gen_Shrs(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
373 return new_rd_ia32_Shrs(dbg, current_ir_graph, block, op1, op2, mode);
379 * Creates an ia32 Rot with immediate.
381 * @param dbg firm dbg
382 * @param block the block the new node should belong to
383 * @param expr_op operator
384 * @param mode node mode
385 * @return the created ia23 Rot_i node
387 ir_node *gen_imm_Rot(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_mode *mode) {
388 return new_rd_ia32_Rot_i(dbg, current_ir_graph, block, expr_op, mode);
392 * Creates an ia32 Rot.
394 * @param dbg firm node dbg
395 * @param block the block the new node should belong to
396 * @param op1 first operator
397 * @param op2 second operator
398 * @param mode node mode
399 * @return the created ia32 Rot node
401 ir_node *gen_Rot(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) {
402 return new_rd_ia32_Rot(dbg, current_ir_graph, block, op1, op2, mode);
408 * Transforms a Minus node.
410 * @param mod the debug module
411 * @param block the block the new node should belong to
412 * @param node the ir Minus node
414 * @param mode node mode
415 * @return the created ia32 Minus node
417 ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
418 if (is_ia32_Minus(op)) {
419 DBG((mod, LEVEL_1, "optimizing --(e) to e ..."));
420 return get_irn_n(op, 0);
423 return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
429 * Transforms a Conv node.
431 * @param mod the debug module
432 * @param block the block the new node should belong to
433 * @param node the ir Conv node
435 * @param mode node mode
436 * @return the created ia32 Conv node
438 ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) {
439 return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode);
445 * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor, op_Cmp)
446 * and non-commutative operations with com == 0 (op_Sub, op_Mod, op_Shl, op_Shr, op_Shrs, op_Rot)
448 * @param mod the debug module
449 * @param block the block node belongs to
450 * @param node the node to transform
451 * @param op1 first operator
452 * @param op2 second operator
453 * @param mode node mode
454 * @param com flag if op is commutative
455 * @return the created assembler node
457 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) {
458 dbg_info *dbg = get_irn_dbg_info(node);
459 ir_node *imm_op = NULL;
460 ir_node *expr_op = NULL;
461 ir_node *asm_node = NULL;
463 #define GENOP(a) case iro_##a: asm_node = gen_##a(mod, dbg, block, op1, op2, mode); break
464 #define GENOPI(a) case iro_##a: asm_node = gen_imm_##a(dbg, block, expr_op, mode); break
467 imm_op = get_immediate_op(op1, op2);
469 imm_op = get_immediate_op(NULL, op2);
471 expr_op = get_expr_op(op1, op2);
473 /* TODO: Op(Imm, Imm) support */
474 if (is_Imm(op1) && is_Imm(op2)) {
475 DBG((mod, LEVEL_1, "found unexpected %s(Imm, Imm), creating binop ... ", get_irn_opname(node)));
479 DBG((mod, LEVEL_1, "(op1: %s -- op2: %s) ... ", get_irn_opname(op1), get_irn_opname(op2)));
482 imm_attr_t *attr_imm = (imm_attr_t *)get_irn_generic_attr(imm_op);
484 DBG((mod, LEVEL_1, "%s with imm ... ", get_irn_opname(node)));
486 /* make sure that Imm is a Const and no SymConst */
487 if (attr_imm->tp == imm_Const) {
488 switch(get_irn_opcode(node)) {
503 assert("binop_i: THIS SHOULD NOT HAPPEN");
506 /* make the Const an attribute */
507 asmop_attr *attr = (asmop_attr *)get_irn_generic_attr(asm_node);
508 attr->tv = attr_imm->data.tv;
509 } /* TODO: SymConst support */
515 DBG((mod, LEVEL_1, "%s as binop ... ", get_irn_opname(node)));
517 switch(get_irn_opcode(node)) {
532 assert("binop: THIS SHOULD NOT HAPPEN");
544 * @param mod the debug module
545 * @param block the block the new node should belong to
546 * @param node the ir Load node
547 * @param mode node mode
548 * @return the created ia32 Load node
550 ir_node *gen_Load(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
551 return new_rd_ia32_Load(get_irn_dbg_info(node), current_ir_graph, block, get_Load_mem(node), get_Load_ptr(node), mode);
557 * Transforms a Store.
559 * @param mod the debug module
560 * @param block the block the new node should belong to
561 * @param node the ir Store node
562 * @param mode node mode
563 * @return the created ia32 Store node
565 ir_node *gen_Store(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_mode *mode) {
566 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);
572 * Transforms the given firm node (and maybe some other related nodes)
573 * into one or more assembler nodes.
575 * @param node the firm node
576 * @param env the debug module
578 void transform_node(ir_node *node, void *env) {
579 firm_dbg_module_t *mod = (firm_dbg_module_t *)env;
580 opcode code = get_irn_opcode(node);
581 ir_node *asm_node = NULL;
588 block = get_nodes_block(node);
589 mode = get_irn_mode(node);
591 #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
592 #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
593 #define UNOP(a) case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break
594 #define GEN(a) case iro_##a: asm_node = gen_##a(mod, block, node, mode); break
595 #define IGN(a) case iro_##a: break
597 DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node)));
613 // BINOP_ARITH_NCOM(DivMod);
622 exchange(node, asm_node);
623 DBG((mod, LEVEL_1, "created node %u\n", get_irn_node_nr(asm_node)));
626 DBG((mod, LEVEL_1, "ignored\n"));