From a5e1011f6b967b00491c503c59753625fc74cb61 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Fri, 8 Oct 2010 20:51:37 +0000 Subject: [PATCH] Experimental support for double word irarch. include/libfirm/irarch.h - give the mode to the eval function ir/be/ia32/bearch_ia32.c - the maximum allowed shift is 63 (for double-word shifts) on x86, not 31 ir/be/ia32/ia32_architecture.c ir/be/ia32/ia32_architecture.h - estimate the cost for 64bit operations ir/ir/irarch.c - pass the mode [r28081] --- include/libfirm/irarch.h | 3 ++- ir/be/ia32/bearch_ia32.c | 2 +- ir/be/ia32/ia32_architecture.c | 24 ++++++++++++++++++------ ir/be/ia32/ia32_architecture.h | 3 ++- ir/ir/irarch.c | 11 ++++++----- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/include/libfirm/irarch.h b/include/libfirm/irarch.h index d1657b153..c8b440021 100644 --- a/include/libfirm/irarch.h +++ b/include/libfirm/irarch.h @@ -47,11 +47,12 @@ typedef enum instr { * A Callback for evaluating the costs of an instruction. * * @param kind the instruction + * @param mode the mode of the instruction * @param tv for MUL instruction, the multiplication constant * * @return the costs of this instruction */ -typedef int (*evaluate_costs_func)(insn_kind kind, ir_tarval *tv); +typedef int (*evaluate_costs_func)(insn_kind kind, const ir_mode *mode, ir_tarval *tv); /** * A parameter structure that drives the machine dependent Firm diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 592fdb7b8..bfc1aa715 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -2123,7 +2123,7 @@ static const backend_params *ia32_get_libfirm_params(void) static const ir_settings_arch_dep_t ad = { 1, /* also use subs */ 4, /* maximum shifts */ - 31, /* maximum shift amount */ + 63, /* maximum shift amount */ ia32_evaluate_insn, /* evaluate the instruction sequence */ 1, /* allow Mulhs */ diff --git a/ir/be/ia32/ia32_architecture.c b/ir/be/ia32/ia32_architecture.c index 29bf850dd..1b0881603 100644 --- a/ir/be/ia32/ia32_architecture.c +++ b/ir/be/ia32/ia32_architecture.c @@ -438,13 +438,13 @@ static void set_arch_costs(void) } /* Evaluate the costs of an instruction. */ -int ia32_evaluate_insn(insn_kind kind, ir_tarval *tv) +int ia32_evaluate_insn(insn_kind kind, const ir_mode *mode, ir_tarval *tv) { int cost; switch (kind) { case MUL: - cost = arch_costs->cost_mul_start; + cost = arch_costs->cost_mul_start; if (arch_costs->cost_mul_bit > 0) { char *bitstr = get_tarval_bitpattern(tv); int i; @@ -456,14 +456,26 @@ int ia32_evaluate_insn(insn_kind kind, ir_tarval *tv) } free(bitstr); } - return cost; + if (get_mode_size_bits(mode) <= 32) + return cost; + /* 64bit mul supported, approx 4times of a 32bit mul*/ + return 4 * cost; case LEA: - return arch_costs->lea_cost; + /* lea is only supported for 32 bit */ + if (get_mode_size_bits(mode) <= 32) + return arch_costs->lea_cost; + return 0x10000; case ADD: case SUB: - return arch_costs->add_cost; + if (get_mode_size_bits(mode) <= 32) + return arch_costs->add_cost; + /* 64bit add/sub supported, double the cost */ + return 2 * arch_costs->add_cost; case SHIFT: - return arch_costs->const_shf_cost; + if (get_mode_size_bits(mode) <= 32) + return arch_costs->const_shf_cost; + /* 64bit shift supported, double the cost */ + return 2 * arch_costs->const_shf_cost; case ZERO: return arch_costs->add_cost; default: diff --git a/ir/be/ia32/ia32_architecture.h b/ir/be/ia32/ia32_architecture.h index ec5f4a05b..84c0938df 100644 --- a/ir/be/ia32/ia32_architecture.h +++ b/ir/be/ia32/ia32_architecture.h @@ -115,10 +115,11 @@ void ia32_setup_cg_config(void); * lowerer. * * @param kind the instruction + * @param mode the mode of the instruction * @param tv for MUL instruction, the multiplication constant * * @return the cost */ -int ia32_evaluate_insn(insn_kind kind, ir_tarval *tv); +int ia32_evaluate_insn(insn_kind kind, const ir_mode *mode, ir_tarval *tv); #endif diff --git a/ir/ir/irarch.c b/ir/ir/irarch.c index f51c9b40a..69cb96ff2 100644 --- a/ir/ir/irarch.c +++ b/ir/ir/irarch.c @@ -104,8 +104,9 @@ typedef struct mul_env { * Some kind of default evaluator. Return the cost of * instructions. */ -static int default_evaluate(insn_kind kind, ir_tarval *tv) +static int default_evaluate(insn_kind kind, const ir_mode *mode, ir_tarval *tv) { + (void) mode; (void) tv; if (kind == MUL) @@ -485,7 +486,7 @@ static int evaluate_insn(mul_env *env, instruction *inst) case ADD: costs = evaluate_insn(env, inst->in[0]); costs += evaluate_insn(env, inst->in[1]); - costs += env->evaluate(inst->kind, NULL); + costs += env->evaluate(inst->kind, env->mode, NULL); inst->costs = costs; return costs; case SHIFT: @@ -496,11 +497,11 @@ static int evaluate_insn(mul_env *env, instruction *inst) else --env->n_shift; costs = evaluate_insn(env, inst->in[0]); - costs += env->evaluate(inst->kind, NULL); + costs += env->evaluate(inst->kind, env->mode, NULL); inst->costs = costs; return costs; case ZERO: - inst->costs = costs = env->evaluate(inst->kind, NULL); + inst->costs = costs = env->evaluate(inst->kind, env->mode, NULL); return costs; case MUL: case ROOT: @@ -544,7 +545,7 @@ static ir_node *do_decomposition(ir_node *irn, ir_node *operand, ir_tarval *tv) inst = decompose_mul(&env, R, r, tv); /* the paper suggests 70% here */ - mul_costs = (env.evaluate(MUL, tv) * 7 + 5) / 10; + mul_costs = (env.evaluate(MUL, env.mode, tv) * 7 + 5) / 10; if (evaluate_insn(&env, inst) <= mul_costs && !env.fail) { env.op = operand; env.blk = get_nodes_block(irn); -- 2.20.1