From: Christian Würdig Date: Mon, 7 Nov 2005 12:47:13 +0000 (+0000) Subject: added generation of Mulh, Min, Max, Div and DivMod nodes X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=148d024d4fd12b8aca394ed1a69798d4a188ad77;p=libfirm added generation of Mulh, Min, Max, Div and DivMod nodes added assert for not yet implemented nodes --- diff --git a/ir/be/ia32/transform.c b/ir/be/ia32/transform.c index 533fc3850..a3563efce 100644 --- a/ir/be/ia32/transform.c +++ b/ir/be/ia32/transform.c @@ -12,10 +12,11 @@ #include "../firm2arch_nodes_attr.h" #include "../bearch_firm.h" +#include "../arch/archop.h" /* we need this for Min and Max nodes */ #include "transform.h" #include "new_nodes.h" - +extern ir_op *get_op_Mulh(void); /* determine if one operator is an Imm */ ir_node *get_immediate_op(ir_node *op1, ir_node *op2) { @@ -160,6 +161,39 @@ ir_node *gen_Mul(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node +/** + * Creates an ia32 Mulh with immediate. + * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of + * this result while Mul returns the lower 32 bit. + * + * @param dbg firm dbg + * @param block the block the new node should belong to + * @param expr_op operator + * @param mode node mode + * @return the created ia23 Mulh_i node + */ +ir_node *gen_imm_Mulh(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) { + return new_rd_ia32_Mulh_i(dbg, current_ir_graph, block, expr_op, mode); +} + +/** + * Creates an ia32 Mulh. + * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of + * this result while Mul returns the lower 32 bit. + * + * @param dbg firm node dbg + * @param block the block the new node should belong to + * @param op1 first operator + * @param op2 second operator + * @param mode node mode + * @return the created ia32 Mulh node + */ +ir_node *gen_Mulh(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) { + return new_rd_ia32_Mulh(dbg, current_ir_graph, block, op1, op2, mode); +} + + + /** * Creates an ia32 And with immediate. * @@ -247,6 +281,62 @@ ir_node *gen_Eor(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node +/** + * Creates an ia32 Max with immediate. + * + * @param dbg firm dbg + * @param block the block the new node should belong to + * @param expr_op operator + * @param mode node mode + * @return the created ia23 Max_i node + */ +ir_node *gen_imm_Max(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) { + return new_rd_ia32_Max_i(dbg, current_ir_graph, block, expr_op, mode); +} + +/** + * Creates an ia32 Max. + * + * @param dbg firm dbg + * @param block the block the new node should belong to + * @param expr_op operator + * @param mode node mode + * @return the created ia23 Max node + */ +ir_node *gen_Max(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) { + return new_rd_ia32_Max(dbg, current_ir_graph, block, op1, op2, mode); +} + + + +/** + * Creates an ia32 Min with immediate. + * + * @param dbg firm dbg + * @param block the block the new node should belong to + * @param expr_op operator + * @param mode node mode + * @return the created ia23 Min_i node + */ +ir_node *gen_imm_Min(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) { + return new_rd_ia32_Min_i(dbg, current_ir_graph, block, expr_op, mode); +} + +/** + * Creates an ia32 Min. + * + * @param dbg firm dbg + * @param block the block the new node should belong to + * @param expr_op operator + * @param mode node mode + * @return the created ia23 Min node + */ +ir_node *gen_Min(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) { + return new_rd_ia32_Min(dbg, current_ir_graph, block, op1, op2, mode); +} + + + /** * Creates an ia32 Cmp with immediate. * @@ -374,6 +464,64 @@ ir_node *gen_Mod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node +/** + * Creates an ia32 Div with immediate. + * + * @param dbg firm dbg + * @param block the block the new node should belong to + * @param expr_op operator + * @param mode node mode + * @return the created ia23 Div_i node + */ +ir_node *gen_imm_Div(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) { + return new_rd_ia32_Div_i(dbg, current_ir_graph, block, expr_op, mode); +} + +/** + * Creates an ia32 Div. + * + * @param dbg firm node dbg + * @param block the block the new node should belong to + * @param op1 first operator + * @param op2 second operator + * @param mode node mode + * @return the created ia32 Div node + */ +ir_node *gen_Div(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) { + return new_rd_ia32_Div(dbg, current_ir_graph, block, op1, op2, mode); +} + + + +/** + * Creates an ia32 DivMod with immediate. + * + * @param dbg firm dbg + * @param block the block the new node should belong to + * @param expr_op operator + * @param mode node mode + * @return the created ia23 DivMod_i node + */ +ir_node *gen_imm_DivMod(dbg_info *dbg, ir_node *block, ir_node *expr_op, ir_node *const_op, ir_mode *mode) { + return new_rd_ia32_DivMod_i(dbg, current_ir_graph, block, expr_op, mode); +} + +/** + * Creates an ia32 DivMod. + * + * @param dbg firm node dbg + * @param block the block the new node should belong to + * @param op1 first operator + * @param op2 second operator + * @param mode node mode + * @return the created ia32 DivMod node + */ +ir_node *gen_DivMod(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) { + return new_rd_ia32_DivMod(dbg, current_ir_graph, block, op1, op2, mode); +} + + + /** * Creates an ia32 Shl with immediate. * @@ -490,46 +638,9 @@ ir_node *gen_Rot(firm_dbg_module_t *mod, dbg_info *dbg, ir_node *block, ir_node -/** - * Transforms a Minus node. - * - * @param mod the debug module - * @param block the block the new node should belong to - * @param node the ir Minus node - * @param op operator - * @param mode node mode - * @return the created ia32 Minus node - */ -ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) { - if (is_ia32_Minus(op)) { - DBG((mod, LEVEL_1, "optimizing --(e) to e ...")); - return get_irn_n(op, 0); - } - else - return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode); -} - - - -/** - * Transforms a Conv node. - * - * @param mod the debug module - * @param block the block the new node should belong to - * @param node the ir Conv node - * @param op operator - * @param mode node mode - * @return the created ia32 Conv node - */ -ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) { - return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode); -} - - - /** * Transforms commutative operations (op_Add, op_Mul, op_And, op_Or, op_Eor, op_Cmp) - * and non-commutative operations with com == 0 (op_Sub, op_Mod, op_Shl, op_Shr, op_Shrs, op_Rot) + * and non-commutative operations with com == 0 (op_Sub, op_Mod, op_Div, op_DivMod, op_Shl, op_Shr, op_Shrs, op_Rot) * * @param mod the debug module * @param block the block node belongs to @@ -577,12 +688,24 @@ ir_node *gen_arith_Op(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_ GENOPI(Sub); GENOPI(Mod); + GENOPI(Div); + GENOPI(DivMod); GENOPI(Shl); GENOPI(Shr); GENOPI(Shrs); GENOPI(Rot); default: - assert("binop_i: THIS SHOULD NOT HAPPEN"); + if (get_irn_op(node) == get_op_Mulh()) { + asm_node = gen_imm_Mulh(dbg, block, expr_op, imm_op, mode); + } + else if (get_irn_op(node) == get_op_Max()) { + asm_node = gen_imm_Max(dbg, block, expr_op, imm_op, mode); + } + else if (get_irn_op(node) == get_op_Min()) { + asm_node = gen_imm_Min(dbg, block, expr_op, imm_op, mode); + } + else + assert("binop_i: THIS SHOULD NOT HAPPEN"); } set_Immop_attr(asm_node, imm_op); @@ -600,12 +723,24 @@ ir_node *gen_arith_Op(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_ GENOP(Sub); GENOP(Mod); + GENOP(Div); + GENOP(DivMod); GENOP(Shl); GENOP(Shr); GENOP(Shrs); GENOP(Rot); default: - assert("binop: THIS SHOULD NOT HAPPEN"); + if (get_irn_op(node) == get_op_Mulh()) { + asm_node = gen_Mulh(mod, dbg, block, op1, op2, mode); + } + else if (get_irn_op(node) == get_op_Max()) { + asm_node = gen_Max(mod, dbg, block, op1, op2, mode); + } + else if (get_irn_op(node) == get_op_Min()) { + asm_node = gen_Min(mod, dbg, block, op1, op2, mode); + } + else + assert("binop: THIS SHOULD NOT HAPPEN"); } } @@ -614,6 +749,75 @@ ir_node *gen_arith_Op(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_ +/** + * Transforms a Minus node. + * + * @param mod the debug module + * @param block the block the new node should belong to + * @param node the ir Minus node + * @param op operator + * @param mode node mode + * @return the created ia32 Minus node + */ +ir_node *gen_Minus(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) { + if (is_ia32_Minus(op)) { + DBG((mod, LEVEL_1, "optimizing --(e) to e ...")); + return get_irn_n(op, 0); + } + else + return new_rd_ia32_Minus(get_irn_dbg_info(node), current_ir_graph, block, op, mode); +} + + + +/** + * Transforms a Conv node. + * + * @param mod the debug module + * @param block the block the new node should belong to + * @param node the ir Conv node + * @param op operator + * @param mode node mode + * @return the created ia32 Conv node + */ +ir_node *gen_Conv(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) { + return new_rd_ia32_Conv(get_irn_dbg_info(node), current_ir_graph, block, op, mode); +} + + + +/** + * Transforms a Not node. + * + * @param mod the debug module + * @param block the block the new node should belong to + * @param node the ir Not node + * @param op operator + * @param mode node mode + * @return the created ia32 Not node + */ +ir_node *gen_Not(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) { + return new_rd_ia32_Not(get_irn_dbg_info(node), current_ir_graph, block, op, mode); +} + + + +/** + * Transforms an Abs node. + * + * @param mod the debug module + * @param block the block the new node should belong to + * @param node the ir Abs node + * @param op operator + * @param mode node mode + * @return the created ia32 Abs node + */ +ir_node *gen_Abs(firm_dbg_module_t *mod, ir_node *block, ir_node *node, ir_node *op, ir_mode *mode) { + return new_rd_ia32_Abs(get_irn_dbg_info(node), current_ir_graph, block, op, mode); +} + + + /** * Transforms a Load. * @@ -684,6 +888,7 @@ void transform_node(ir_node *node, void *env) { #define UNOP(a) case iro_##a: asm_node = gen_##a(mod, block, node, get_irn_n(node, 0), mode); break #define GEN(a) case iro_##a: asm_node = gen_##a(mod, block, node, mode); break #define IGN(a) case iro_##a: break +#define BAD(a) case iro_##a: goto bad DBG((mod, LEVEL_1, "transforming node %s (%ld) ... ", get_irn_opname(node), get_irn_node_nr(node))); @@ -697,22 +902,66 @@ void transform_node(ir_node *node, void *env) { BINOP_NCOM(Sub); BINOP_NCOM(Mod); + BINOP_NCOM(Div); + BINOP_NCOM(DivMod); BINOP_NCOM(Shl); BINOP_NCOM(Shr); BINOP_NCOM(Shrs); BINOP_NCOM(Rot); -// BINOP_ARITH_NCOM(DivMod); UNOP(Minus); UNOP(Conv); + UNOP(Abs); + UNOP(Not); GEN(Load); GEN(Store); GEN(Call); + IGN(Const); + IGN(SymConst); IGN(Block); IGN(Start); IGN(End); + IGN(NoMem); + IGN(Phi); + IGN(Cond); + IGN(Jmp); + IGN(IJmp); + IGN(Proj); + IGN(Break); + + BAD(Raise); + BAD(Sel); + BAD(InstOf); + BAD(Quot); + BAD(Cast); + BAD(Alloc); + BAD(Free); + BAD(Sync); + BAD(Tuple); + BAD(Id); + BAD(Bad); + BAD(Confirm); + BAD(Unknown); + BAD(Filter); + BAD(CallBegin); + BAD(EndReg); + BAD(EndExcept); + BAD(Mux); + BAD(CopyB); + + default: + if (get_irn_op(node) == get_op_Mulh() || + get_irn_op(node) == get_op_Max() || + get_irn_op(node) == get_op_Min()) + { + asm_node = gen_arith_Op(mod, block, node, get_irn_n(node, 0), get_irn_n(node, 1), mode, 1); + } + break; +bad: + fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node)); + assert(0); } if (asm_node) {