From 2e16fb5a300446e1b4cc0d9daf7e271adde88922 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Tue, 26 Jun 2007 22:03:28 +0000 Subject: [PATCH] more floating point immediate support [r14775] --- ir/be/arm/arm_emitter.c | 15 ++-- ir/be/arm/arm_new_nodes.c | 1 - ir/be/arm/arm_nodes_attr.h | 10 ++- ir/be/arm/arm_spec.pl | 130 ++++++++++++++++++++++++++--- ir/be/arm/arm_transform.c | 165 ++++++++++++++++++++++++++++++------- ir/be/arm/bearch_arm.c | 2 +- 6 files changed, 265 insertions(+), 58 deletions(-) diff --git a/ir/be/arm/arm_emitter.c b/ir/be/arm/arm_emitter.c index 397c97d4f..ebdeb8171 100644 --- a/ir/be/arm/arm_emitter.c +++ b/ir/be/arm/arm_emitter.c @@ -213,21 +213,16 @@ void arm_emit_mode(arm_emit_env_t *env, const ir_node *node) { arm_emit_fpa_postfix(env->emit, mode); } - -/** - * Returns non-zero if a mode has a Immediate attribute. - */ -int is_immediate_node(const ir_node *irn) { - const arm_attr_t *attr = get_arm_attr_const(irn); - return ARM_GET_SHF_MOD(attr) == ARM_SHF_IMM; -} - /** * Emit a const or SymConst value. */ void arm_emit_immediate(arm_emit_env_t *env, const ir_node *node) { - if (is_immediate_node(node)) { + const arm_attr_t *attr = get_arm_attr_const(node); + + if (ARM_GET_SHF_MOD(attr) == ARM_SHF_IMM) { be_emit_irprintf(env->emit, "#0x%X", arm_decode_imm_w_shift(get_arm_value(node))); + } else if (ARM_GET_FPA_IMM(attr)) { + be_emit_irprintf(env->emit, "#0x%F", get_arm_value(node)); } else if (is_arm_SymConst(node)) be_emit_ident(env->emit, get_arm_symconst_id(node)); else { diff --git a/ir/be/arm/arm_new_nodes.c b/ir/be/arm/arm_new_nodes.c index 8b6a4efb4..88c7abe8b 100644 --- a/ir/be/arm/arm_new_nodes.c +++ b/ir/be/arm/arm_new_nodes.c @@ -47,7 +47,6 @@ #include "arm_nodes_attr.h" #include "arm_new_nodes.h" -#include "gen_arm_regalloc_if_t.h" #include "../beabi.h" #include "bearch_arm_t.h" diff --git a/ir/be/arm/arm_nodes_attr.h b/ir/be/arm/arm_nodes_attr.h index 5b0a17188..5b9564d35 100644 --- a/ir/be/arm/arm_nodes_attr.h +++ b/ir/be/arm/arm_nodes_attr.h @@ -52,6 +52,12 @@ typedef enum _arm_shift_modifier { /** set the shift modifier to flags */ #define ARM_SET_SHF_MOD(attr, mod) ((attr)->instr_fl = (((attr)->instr_fl & ~7) | (mod))) +/** fpa immediate bit */ +#define ARM_FPA_IMM (1 << 3) /**< fpa floating point immediate */ + +#define ARM_GET_FPA_IMM(attr) ((attr)->instr_fl & ARM_FPA_IMM) +#define ARM_SET_FPA_IMM(attr) ((attr)->instr_fl |= ARM_FPA_IMM) +#define ARM_CLR_FPA_IMM(attr) ((attr)->instr_fl &= ~ARM_FPA_IMM) /** * Possible ARM condition codes. @@ -76,10 +82,10 @@ typedef enum _arm_condition { } arm_condition; /** Get the condition code from flags */ -#define ARM_GET_COND(attr) (((attr)->instr_fl >> 3) & 15) +#define ARM_GET_COND(attr) (((attr)->instr_fl >> 4) & 15) /** Set the condition code to flags */ -#define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 << 3)) | ((code) << 3))) +#define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 << 4)) | ((code) << 4))) /** Generic ARM node attributes. */ typedef struct _arm_attr_t { diff --git a/ir/be/arm/arm_spec.pl b/ir/be/arm/arm_spec.pl index cd0b111a6..932f064a8 100644 --- a/ir/be/arm/arm_spec.pl +++ b/ir/be/arm/arm_spec.pl @@ -704,7 +704,7 @@ LoadStackM3 => { # commutative operations -fpaAdd => { +fpaAdf => { op_flags => "C", irn_flags => "R", comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", @@ -712,15 +712,39 @@ fpaAdd => { emit => '. adf%M %D0, %S0, %S1', }, -fpaMul => { +fpaAdf_i => { op_flags => "C", + irn_flags => "R", + comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", + attr => "tarval *tv", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. adf%M %D0, %S0, %C', +}, + +fpaMuf => { + op_flags => "C", + irn_flags => "R", comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b", reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, emit =>'. muf%M %D0, %S0, %S1', }, -fpaFMul => { +fpaMuf_i => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b", + attr => "tarval *tv", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. muf%M %D0, %S0, %C', +}, + +fpaFml => { op_flags => "C", + irn_flags => "R", comment => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b", reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, emit =>'. fml%M %D0, %S0, %S1', @@ -744,21 +768,41 @@ fpaMin => { # not commutative operations -fpaSub => { +fpaSuf => { irn_flags => "R", comment => "construct FPA Sub: Sub(a, b) = a - b", reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, emit => '. suf%M %D0, %S0, %S1' }, -fpaRsb => { +fpaSuf_i => { + irn_flags => "R", + comment => "construct FPA Sub: Sub(a, b) = a - b", + attr => "tarval *tv", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. suf%M %D0, %S0, %C' +}, + +fpaRsf => { irn_flags => "R", comment => "construct FPA reverse Sub: Sub(a, b) = b - a", reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, emit => '. rsf%M %D0, %S0, %S1' }, -fpaDiv => { +fpaRsf_i => { + irn_flags => "R", + comment => "construct FPA reverse Sub: Sub(a, b) = b - a", + attr => "tarval *tv", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. rsf%M %D0, %S0, %C' +}, + +fpaDvf => { comment => "construct FPA Div: Div(a, b) = a / b", attr => "ir_mode *op_mode", init_attr => "attr->op_mode = op_mode;", @@ -767,7 +811,17 @@ fpaDiv => { outs => [ "res", "M" ], }, -fpaRdv => { +fpaDvf_i => { + comment => "construct FPA Div: Div(a, b) = a / b", + attr => "ir_mode *op_mode, tarval *tv", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. dvf%M %D0, %S0, %C', + outs => [ "res", "M" ], +}, + +fpaRdf => { comment => "construct FPA reverse Div: Div(a, b) = b / a", attr => "ir_mode *op_mode", init_attr => "attr->op_mode = op_mode;", @@ -776,7 +830,17 @@ fpaRdv => { outs => [ "res", "M" ], }, -fpaFDiv => { +fpaRdf_i => { + comment => "construct FPA reverse Div: Div(a, b) = b / a", + attr => "ir_mode *op_mode, tarval *tv", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. rdf%M %D0, %S0, %S1', + outs => [ "res", "M" ], +}, + +fpaFdv => { comment => "construct FPA Fast Div: Div(a, b) = a / b", attr => "ir_mode *op_mode", init_attr => "attr->op_mode = op_mode;", @@ -785,7 +849,17 @@ fpaFDiv => { outs => [ "res", "M" ], }, -fpaFRdv => { +fpaFdv_i => { + comment => "construct FPA Fast Div: Div(a, b) = a / b", + attr => "ir_mode *op_mode, tarval *tv", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. fdv%M %D0, %S0, %C', + outs => [ "res", "M" ], +}, + +fpaFrd => { comment => "construct FPA Fast reverse Div: Div(a, b) = b / a", attr => "ir_mode *op_mode", init_attr => "attr->op_mode = op_mode;", @@ -794,20 +868,52 @@ fpaFRdv => { outs => [ "res", "M" ], }, -fpaMov => { +fpaFrd_i => { + comment => "construct FPA Fast reverse Div: Div(a, b) = b / a", + attr => "ir_mode *op_mode, tarval *tv", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. frd%M %D0, %S0, %C', + outs => [ "res", "M" ], +}, + +fpaMvf => { irn_flags => "R", comment => "construct FPA Move: b = a", reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, emit => '. mvf%M %S0, %D0', }, -fpaMnv => { +fpaMvf_i => { + irn_flags => "R", + comment => "represents a float constant", + attr => "tarval *tv", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;', + reg_req => { "out" => [ "fpa" ] }, + mode => "get_tarval_mode(tv)", + emit => '. mvf %D0, %C', + cmp_attr => 'return attr_a->value != attr_b->value;' +}, + +fpaMnf => { irn_flags => "R", comment => "construct FPA Move Negated: b = -a", reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, emit => '. mnf%M %S0, %D0', }, +fpaMnf_i => { + irn_flags => "R", + comment => "represents a float constant", + attr => "tarval *tv", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->value = tv;', + reg_req => { "out" => [ "fpa" ] }, + mode => "get_tarval_mode(tv)", + emit => '. mnf %D0, %C', + cmp_attr => 'return attr_a->value != attr_b->value;' +}, + fpaAbs => { irn_flags => "R", comment => "construct FPA Absolute value: fAbsd(a) = |a|", @@ -939,7 +1045,7 @@ fpaConst => { op_flags => "c", irn_flags => "R", comment => "construct a floating point constant", - attr => "tarval *tv, int is_imm", + attr => "tarval *tv", init_attr => "attr->value = tv;", mode => "get_tarval_mode(tv)", reg_req => { "out" => [ "fpa" ] }, diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index cb170a266..302e60856 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -279,7 +279,7 @@ static ir_node *gen_Conv(ir_node *node) { if (mode_is_float(src_mode)) { if (mode_is_float(dst_mode)) { /* from float to float */ - return new_rd_arm_fpaMov(dbg, irg, block, new_op, dst_mode); + return new_rd_arm_fpaMvf(dbg, irg, block, new_op, dst_mode); } else { /* from float to int */ @@ -377,9 +377,13 @@ static ir_node *gen_Add(ir_node *node) { if (mode_is_float(mode)) { env_cg->have_fp_insn = 1; - if (USE_FPA(env_cg->isa)) - return new_rd_arm_fpaAdd(dbg, irg, block, new_op1, new_op2, mode); - else if (USE_VFP(env_cg->isa)) { + if (USE_FPA(env_cg->isa)) { + if (is_arm_fpaMvf_i(new_op1)) + return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1)); + if (is_arm_fpaMvf_i(new_op2)) + return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2)); + return new_rd_arm_fpaAdf(dbg, irg, block, new_op1, new_op2, mode); + } else if (USE_VFP(env_cg->isa)) { assert(mode != mode_E && "IEEE Extended FP not supported"); panic("VFP not supported yet\n"); return NULL; @@ -448,8 +452,13 @@ static ir_node *gen_Mul(ir_node *node) { if (mode_is_float(mode)) { env_cg->have_fp_insn = 1; - if (USE_FPA(env_cg->isa)) - return new_rd_arm_fpaMul(dbg, irg, block, new_op1, new_op2, mode); + if (USE_FPA(env_cg->isa)) { + if (is_arm_Mov_i(new_op1)) + return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1)); + if (is_arm_Mov_i(new_op2)) + return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2)); + return new_rd_arm_fpaMuf(dbg, irg, block, new_op1, new_op2, mode); + } else if (USE_VFP(env_cg->isa)) { assert(mode != mode_E && "IEEE Extended FP not supported"); panic("VFP not supported yet\n"); @@ -483,9 +492,13 @@ static ir_node *gen_Quot(ir_node *node) { assert(mode != mode_E && "IEEE Extended FP not supported"); env_cg->have_fp_insn = 1; - if (USE_FPA(env_cg->isa)) - return new_rd_arm_fpaDiv(dbg, current_ir_graph, block, new_op1, new_op2, mode); - else if (USE_VFP(env_cg->isa)) { + if (USE_FPA(env_cg->isa)) { + if (is_arm_Mov_i(new_op1)) + return new_rd_arm_fpaRdf_i(dbg, current_ir_graph, block, new_op2, mode, get_arm_value(new_op1)); + if (is_arm_Mov_i(new_op2)) + return new_rd_arm_fpaDvf_i(dbg, current_ir_graph, block, new_op1, mode, get_arm_value(new_op2)); + return new_rd_arm_fpaDvf(dbg, current_ir_graph, block, new_op1, new_op2, mode); + } else if (USE_VFP(env_cg->isa)) { assert(mode != mode_E && "IEEE Extended FP not supported"); panic("VFP not supported yet\n"); } @@ -573,9 +586,13 @@ static ir_node *gen_Sub(ir_node *node) { if (mode_is_float(mode)) { env_cg->have_fp_insn = 1; - if (USE_FPA(env_cg->isa)) - return new_rd_arm_fpaSub(dbg, irg, block, new_op1, new_op2, mode); - else if (USE_VFP(env_cg->isa)) { + if (USE_FPA(env_cg->isa)) { + if (is_arm_Mov_i(new_op1)) + return new_rd_arm_fpaRsf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1)); + if (is_arm_Mov_i(new_op2)) + return new_rd_arm_fpaSuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2)); + return new_rd_arm_fpaSuf(dbg, irg, block, new_op1, new_op2, mode); + } else if (USE_VFP(env_cg->isa)) { assert(mode != mode_E && "IEEE Extended FP not supported"); panic("VFP not supported yet\n"); return NULL; @@ -738,7 +755,7 @@ static ir_node *gen_Minus(ir_node *node) { if (mode_is_float(mode)) { env_cg->have_fp_insn = 1; if (USE_FPA(env_cg->isa)) - return new_rd_arm_fpaMnv(dbg, current_ir_graph, block, op, mode); + return new_rd_arm_fpaMvf(dbg, current_ir_graph, block, op, mode); else if (USE_VFP(env_cg->isa)) { assert(mode != mode_E && "IEEE Extended FP not supported"); panic("VFP not supported yet\n"); @@ -969,10 +986,48 @@ static ident *get_sc_ident(ir_node *symc) { return NULL; } +enum fpa_immediates { + fpa_null = 0, + fpa_one, + fpa_two, + fpa_three, + fpa_four, + fpa_five, + fpa_ten, + fpa_half, + fpa_max +}; + +static tarval *fpa_imm[3][fpa_max]; + /** * Check, if a floating point tarval is an fpa immediate, i.e. + * one of 0, 1, 2, 3, 4, 5, 10, or 0.5. */ static int is_fpa_immediate(tarval *tv) { + ir_mode *mode = get_tarval_mode(tv); + int i, j, res = 1; + + switch (get_mode_size_bits(mode)) { + case 32: + i = 0; + break; + case 64: + i = 1; + break; + default: + i = 2; + } + + if (tarval_cmp(tv, get_tarval_null(mode)) & pn_Cmp_Lt) { + tv = tarval_neg(tv); + res = -1; + } + + for (j = 0; j < fpa_max; ++j) { + if (tv == fpa_imm[i][j]) + return res; + } return 0; } @@ -991,7 +1046,16 @@ static ir_node *gen_Const(ir_node *node) { env_cg->have_fp_insn = 1; if (USE_FPA(env_cg->isa)) { tarval *tv = get_Const_tarval(node); - node = new_rd_arm_fpaConst(dbg, irg, block, tv, is_fpa_immediate(tv)); + int imm = is_fpa_immediate(tv); + + if (imm) { + if (imm > 0) + node = new_rd_arm_fpaMvf_i(dbg, irg, block, tv); + else + node = new_rd_arm_fpaMnf_i(dbg, irg, block, tv); + } else { + node = new_rd_arm_fpaConst(dbg, irg, block, tv); + } /* ensure the const is schedules AFTER the barrier */ add_irn_dep(node, be_abi_get_start_barrier(env_cg->birg->abi)); return node; @@ -1318,25 +1382,25 @@ static ir_node *gen_Proj_Quot(ir_node *node) { switch (proj) { case pn_Quot_M: - if (is_arm_fpaDiv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaDiv_M); - } else if (is_arm_fpaRdv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaRdv_M); - } else if (is_arm_fpaFDiv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFDiv_M); - } else if (is_arm_fpaFRdv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFRdv_M); + if (is_arm_fpaDvf(new_pred) || is_arm_fpaDvf_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaDvf_M); + } else if (is_arm_fpaRdf(new_pred) || is_arm_fpaRdf_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaRdf_M); + } else if (is_arm_fpaFdv(new_pred) || is_arm_fpaFdv_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFdv_M); + } else if (is_arm_fpaFrd(new_pred) || is_arm_fpaFrd_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_arm_fpaFrd_M); } break; case pn_Quot_res: - if (is_arm_fpaDiv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaDiv_res); - } else if (is_arm_fpaFDiv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaRdv_res); - } else if (is_arm_fpaFDiv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFDiv_res); - } else if (is_arm_fpaFDiv(new_pred)) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFRdv_res); + if (is_arm_fpaDvf(new_pred) || is_arm_fpaDvf_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaDvf_res); + } else if (is_arm_fpaRdf(new_pred) || is_arm_fpaRdf_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaRdf_res); + } else if (is_arm_fpaFdv(new_pred) || is_arm_fpaFdv_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFdv_res); + } else if (is_arm_fpaFrd(new_pred) || is_arm_fpaFrd_i(new_pred)) { + return new_rd_Proj(dbgi, irg, block, new_pred, mode, pn_arm_fpaFrd_res); } break; default: @@ -1681,10 +1745,49 @@ static void arm_pretransform_node(void *arch_cg) { cg->unknown_fpa = be_pre_transform_node(cg->unknown_fpa); } +/** + * Initialize fpa Immediate support. + */ +static void arm_init_fpa_immediate(void) { + /* 0, 1, 2, 3, 4, 5, 10, or 0.5. */ + fpa_imm[0][fpa_null] = get_tarval_null(mode_F); + fpa_imm[0][fpa_one] = get_tarval_one(mode_F); + fpa_imm[0][fpa_two] = new_tarval_from_str("2", 1, mode_F); + fpa_imm[0][fpa_three] = new_tarval_from_str("3", 1, mode_F); + fpa_imm[0][fpa_four] = new_tarval_from_str("4", 1, mode_F); + fpa_imm[0][fpa_five] = new_tarval_from_str("5", 1, mode_F); + fpa_imm[0][fpa_ten] = new_tarval_from_str("10", 2, mode_F); + fpa_imm[0][fpa_half] = new_tarval_from_str("0.5", 3, mode_F); + + fpa_imm[1][fpa_null] = get_tarval_null(mode_D); + fpa_imm[1][fpa_one] = get_tarval_one(mode_D); + fpa_imm[1][fpa_two] = new_tarval_from_str("2", 1, mode_D); + fpa_imm[1][fpa_three] = new_tarval_from_str("3", 1, mode_D); + fpa_imm[1][fpa_four] = new_tarval_from_str("4", 1, mode_D); + fpa_imm[1][fpa_five] = new_tarval_from_str("5", 1, mode_D); + fpa_imm[1][fpa_ten] = new_tarval_from_str("10", 2, mode_D); + fpa_imm[1][fpa_half] = new_tarval_from_str("0.5", 3, mode_D); + + fpa_imm[2][fpa_null] = get_tarval_null(mode_E); + fpa_imm[2][fpa_one] = get_tarval_one(mode_E); + fpa_imm[2][fpa_two] = new_tarval_from_str("2", 1, mode_E); + fpa_imm[2][fpa_three] = new_tarval_from_str("3", 1, mode_E); + fpa_imm[2][fpa_four] = new_tarval_from_str("4", 1, mode_E); + fpa_imm[2][fpa_five] = new_tarval_from_str("5", 1, mode_E); + fpa_imm[2][fpa_ten] = new_tarval_from_str("10", 2, mode_E); + fpa_imm[2][fpa_half] = new_tarval_from_str("0.5", 3, mode_E); +} + /** * Transform a Firm graph into an ARM graph. */ void arm_transform_graph(arm_code_gen_t *cg) { + static int imm_initialized = 0; + + if (! imm_initialized) { + arm_init_fpa_immediate(); + imm_initialized = 1; + } arm_register_transformers(); env_cg = cg; be_transform_graph(cg->birg, arm_pretransform_node, cg); @@ -1692,6 +1795,4 @@ void arm_transform_graph(arm_code_gen_t *cg) { void arm_init_transform(void) { // FIRM_DBG_REGISTER(dbg, "firm.be.arm.transform"); - - /* 0, 1, 2, 3, 4, 5, 10, or 0.5. */ } diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index 512e90d9e..4c5c6caa1 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -1165,7 +1165,7 @@ static const backend_params *arm_get_libfirm_params(void) { static arch_dep_params_t ad = { 1, /* allow subs */ 1, /* Muls are fast enough on ARM but ... */ - 1, /* ... one shift would be possible better */ + 31, /* ... one shift would be possible better */ 0, /* SMUL is needed, only in Arch M*/ 0, /* UMUL is needed, only in Arch M */ 32, /* SMUL & UMUL available for 32 bit */ -- 2.20.1