more floating point immediate support
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 26 Jun 2007 22:03:28 +0000 (22:03 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 26 Jun 2007 22:03:28 +0000 (22:03 +0000)
[r14775]

ir/be/arm/arm_emitter.c
ir/be/arm/arm_new_nodes.c
ir/be/arm/arm_nodes_attr.h
ir/be/arm/arm_spec.pl
ir/be/arm/arm_transform.c
ir/be/arm/bearch_arm.c

index 397c97d..ebdeb81 100644 (file)
@@ -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 {
index 8b6a4ef..88c7abe 100644 (file)
@@ -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"
index 5b0a171..5b9564d 100644 (file)
@@ -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 {
index cd0b111..932f064 100644 (file)
@@ -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" ] },
index cb170a2..302e608 100644 (file)
@@ -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. */
 }
index 512e90d..4c5c6ca 100644 (file)
@@ -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 */