use new double wide register requirements; implement calling convention for sparc...
authorMatthias Braun <matze@braunis.de>
Thu, 29 Jul 2010 09:27:59 +0000 (09:27 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 29 Jul 2010 09:27:59 +0000 (09:27 +0000)
[r27846]

ir/be/bearch.h
ir/be/scripts/generate_new_opcodes.pl
ir/be/sparc/bearch_sparc.c
ir/be/sparc/sparc_cconv.c
ir/be/sparc/sparc_emitter.c
ir/be/sparc/sparc_emitter.h
ir/be/sparc/sparc_nodes_attr.h
ir/be/sparc/sparc_spec.pl
ir/be/sparc/sparc_transform.c

index 462ab08..7fb173a 100644 (file)
@@ -85,7 +85,7 @@ typedef enum arch_register_req_type_t {
        /** The register must be unequal from some other at the node. */
        arch_register_req_type_must_be_different = 1U << 3,
        /** The registernumber should be aligned (in case of multiregister values)*/
-       arch_register_req_type_must_be_aligned   = 1U << 4,
+       arch_register_req_type_aligned           = 1U << 4,
        /** ignore while allocating registers */
        arch_register_req_type_ignore            = 1U << 5,
        /** the output produces a new value for the stack pointer
index 9dc3948..2a16256 100755 (executable)
@@ -1263,6 +1263,7 @@ sub generate_requirements {
        my $idx   = shift;
        my $is_in = shift;
        my $class = "";
+       my $width = 1;
        my $result;
 
        my @req_type_mask;
@@ -1272,6 +1273,10 @@ sub generate_requirements {
                                push(@req_type_mask, "arch_register_req_type_ignore");
                        } elsif ($f eq "S") {
                                push(@req_type_mask, "arch_register_req_type_produces_sp");
+                       } elsif ($f eq "a") {
+                               push(@req_type_mask, "arch_register_req_type_aligned");
+                       } elsif ($f eq "2" or $f eq "4" or $f eq "8") {
+                               $width = int($f);
                        }
                }
        }
@@ -1300,7 +1305,7 @@ EOF
        NULL,        /* limit bitset */
        0,           /* same pos */
        0,           /* different pos */
-       1            /* width */
+       $width            /* width */
 };
 
 EOF
@@ -1336,7 +1341,7 @@ EOF
        ${limit_bitset},
        ${same_pos},        /* same pos */
        ${different_pos},       /* different pos */
-       1             /* width */
+       $width             /* width */
 };
 
 EOF
index 5e2e1a9..9067b9f 100644 (file)
@@ -263,11 +263,13 @@ static void sparc_collect_frame_entity_nodes(ir_node *node, void *data)
        attr   = get_sparc_load_store_attr_const(node);
        entity = attr->entity;
        mode   = attr->load_store_mode;
-       align  = get_mode_size_bytes(mode);
        if (entity != NULL)
                return;
        if (!attr->is_frame_entity)
                return;
+       if (arch_irn_get_flags(node) & sparc_arch_irn_flag_needs_64bit_spillslot)
+               mode = mode_Lu;
+       align  = get_mode_size_bytes(mode);
        be_node_needs_frame_entity(env, node, mode, align);
 }
 
index 4f83049..92c7297 100644 (file)
@@ -71,7 +71,6 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
                ir_mode            *mode       = get_type_mode(param_type);
                int                 bits       = get_mode_size_bits(mode);
                reg_or_stackslot_t *param      = &params[i];
-               param->type = param_type;
 
                if (regnum < n_param_regs) {
                        const arch_register_t *reg = param_regs[regnum++];
@@ -79,6 +78,7 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
                                reg = map_i_to_o_reg(reg);
                        param->reg0 = reg;
                } else {
+                       param->type   = param_type;
                        param->offset = stack_offset;
                        /* increase offset 4 bytes so everything is aligned */
                        stack_offset += bits > 32 ? bits/8 : 4;
index 4b751ae..96e55f1 100644 (file)
@@ -170,6 +170,21 @@ void sparc_emit_offset(const ir_node *node)
        }
 }
 
+void sparc_emit_float_load_store_mode(const ir_node *node)
+{
+       const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
+       ir_mode *mode = attr->load_store_mode;
+       int      bits = get_mode_size_bits(mode);
+
+       assert(mode_is_float(mode));
+
+       switch (bits) {
+       case 32:  return;
+       case 64:  be_emit_char('d'); return;
+       case 128: be_emit_char('q'); return;
+       }
+       panic("invalid flaot load/store mode %+F", mode);
+}
 
 /**
  *  Emit load mode char
@@ -186,7 +201,7 @@ void sparc_emit_load_mode(const ir_node *node)
        } else if (bits == 8) {
                be_emit_string(is_signed ? "sb" : "ub");
        } else if (bits == 64) {
-               be_emit_string("d");
+               be_emit_char('d');
        } else {
                assert(bits == 32);
        }
@@ -206,7 +221,7 @@ void sparc_emit_store_mode(const ir_node *node)
        } else if (bits == 8) {
                be_emit_string("b");
        } else if (bits == 64) {
-               be_emit_string("d");
+               be_emit_char('d');
        } else {
                assert(bits == 32);
        }
index ece24c2..ea3f4c1 100644 (file)
@@ -42,6 +42,7 @@ void sparc_emit_dest_register(const ir_node *node, int pos);
 void sparc_emit_offset(const ir_node *node);
 void sparc_emit_load_mode(const ir_node *node);
 void sparc_emit_store_mode(const ir_node *node);
+void sparc_emit_float_load_store_mode(const ir_node *node);
 void sparc_emit_mode_sign_prefix(const ir_node *node);
 void sparc_emit_fp_mode_suffix(const ir_node *node);
 void sparc_emit_fp_conv_source(const ir_node *node);
index 8cb690f..d8342da 100644 (file)
@@ -43,8 +43,9 @@ struct sparc_attr_t
 };
 
 enum sparc_arch_irn_flags_t {
-       sparc_arch_irn_flag_modifies_flags    = arch_irn_flags_backend << 0,
-       sparc_arch_irn_flag_modifies_fp_flags = arch_irn_flags_backend << 1,
+       sparc_arch_irn_flag_modifies_flags        = arch_irn_flags_backend << 0,
+       sparc_arch_irn_flag_modifies_fp_flags     = arch_irn_flags_backend << 1,
+       sparc_arch_irn_flag_needs_64bit_spillslot = arch_irn_flags_backend << 2,
 };
 
 /**
index af68581..cde6877 100644 (file)
@@ -6,7 +6,9 @@ $arch = "sparc";
 $mode_gp      = "mode_Iu";
 $mode_flags   = "mode_Bu";
 $mode_fpflags = "mode_Bu";
-$mode_fp      = "mode_D";
+$mode_fp      = "mode_F";
+$mode_fp2     = "mode_D";
+$mode_fp4     = "mode_E"; # not correct, we need to register a new mode
 
 $normal      =  0; # no special type
 $caller_save =  1; # caller save (register must be saved by the caller of a function)
@@ -130,6 +132,7 @@ $state       = 32; # register represents a state
        IM  => "${arch}_emit_immediate(node);",
        LM  => "${arch}_emit_load_mode(node);",
        SM  => "${arch}_emit_store_mode(node);",
+       FLSM => "${arch}_emit_float_load_store_mode(node);",
        FPM  => "${arch}_emit_fp_mode_suffix(node);",
        FCONVS => "${arch}_emit_fp_conv_source(node);",
        FCONVD => "${arch}_emit_fp_conv_destination(node);",
@@ -211,6 +214,24 @@ my %binop_operand_constructors = (
        },
 );
 
+my %float_binop_constructors = (
+       s => {
+               reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
+               ins     => [ "left", "right" ],
+               mode    => $mode_fp,
+       },
+       d => {
+               reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fp:a|2" ] },
+               ins     => [ "left", "right" ],
+               mode    => $mode_fp2,
+       },
+       q => {
+               reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fp:a|4" ] },
+               ins     => [ "left", "right" ],
+               mode    => $mode_fp4,
+       }
+);
+
 %nodes = (
 
 Add => {
@@ -233,9 +254,16 @@ Sub => {
 Ld => {
        op_flags  => [ "labeled", "fragile" ],
        state     => "exc_pinned",
-       ins       => [ "ptr", "mem" ],
+       constructors => {
+               "" => {
+                       reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
+               },
+               d => {
+                       reg_req => { in => [ "gp", "none" ], out => [ "gp:a|2", "none" ] },
+               },
+       },
        outs      => [ "res", "M" ],
-       reg_req   => { in => [ "gp", "none" ], out => [ "gp", "none" ] },
+       ins       => [ "ptr", "mem" ],
        attr_type => "sparc_load_store_attr_t",
        attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
        emit      => '. ld%LM [%S1%O], %D1'
@@ -264,11 +292,18 @@ LoImm => {
 
 St => {
        op_flags  => [ "labeled", "fragile" ],
-       mode            => "mode_M",
+       mode      => "mode_M",
        state     => "exc_pinned",
+       constructors => {
+               "" => {
+                       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
+               },
+               d => {
+                       reg_req   => { in => [ "gp", "gp:a|2", "none" ], out => [ "none" ] },
+               },
+       },
        ins       => [ "ptr", "val", "mem" ],
        outs      => [ "M" ],
-       reg_req   => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
        attr_type => "sparc_load_store_attr_t",
        attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
        emit      => '. st%SM %S2, [%S1%O]'
@@ -522,7 +557,7 @@ fadd => {
        emit      => '. fadd%FPM %S1, %S2, %D1',
        attr_type => "sparc_fp_attr_t",
        attr      => "ir_mode *fp_mode",
-       mode      => $mode_fp,
+       constructors => \%float_binop_constructors,
 },
 
 fsub => {
@@ -531,7 +566,7 @@ fsub => {
        emit      => '. fsub%FPM %S1, %S2, %D1',
        attr_type => "sparc_fp_attr_t",
        attr      => "ir_mode *fp_mode",
-       mode      => $mode_fp,
+       constructors => \%float_binop_constructors,
 },
 
 fmul => {
@@ -541,7 +576,7 @@ fmul => {
        emit      =>'. fmul%FPM %S1, %S2, %D1',
        attr_type => "sparc_fp_attr_t",
        attr      => "ir_mode *fp_mode",
-       mode      => $mode_fp,
+       constructors => \%float_binop_constructors,
 },
 
 fdiv => {
@@ -551,6 +586,7 @@ fdiv => {
        attr_type => "sparc_fp_attr_t",
        attr      => "ir_mode *fp_mode",
        outs      => [ "res", "M" ],
+       constructors => \%float_binop_constructors,
 },
 
 fneg => {
@@ -568,13 +604,13 @@ fneg => {
        emit      => '. fabs%FPM %S1, %D1',
        attr_type => "sparc_fp_attr_t",
        attr      => "ir_mode *fp_mode",
-       mode      => $mode_fp,
+       constructors => \%float_binop_constructors,
 },
 
 fftof => {
        irn_flags => [ "rematerializable" ],
        reg_req   => { in => [ "fp" ], out => [ "fp" ] },
-       emit      => '. f%FCONVS.to%FCONVD %S1, %D1',
+       emit      => '. f%FCONVS%.to%FCONVD %S1, %D1',
        attr_type => "sparc_fp_conv_attr_t",
        attr      => "ir_mode *src_mode, ir_mode *dest_mode",
        mode      => $mode_fp,
@@ -606,7 +642,7 @@ Ldf => {
        reg_req   => { in => [ "gp", "none" ], out => [ "fp", "none" ] },
        attr_type => "sparc_load_store_attr_t",
        attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
-       emit      => '. ld [%S1%O], %D1'
+       emit      => '. ld%FLSM [%S1%O], %D1'
 },
 
 Stf => {
@@ -617,7 +653,7 @@ Stf => {
        reg_req   => { in => [ "gp", "fp", "none" ], out => [ "none" ] },
        attr_type => "sparc_load_store_attr_t",
        attr      => "ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity",
-       emit      => '. st %S2, [%S1%O]',
+       emit      => '. st%FLSM %S2, [%S1%O]',
        mode      => 'mode_M',
 },
 
index dad12fc..cb26847 100644 (file)
@@ -62,6 +62,8 @@ static const arch_register_t *fp_reg = &sparc_gp_regs[REG_FRAME_POINTER];
 static calling_convention_t  *cconv  = NULL;
 static ir_mode               *mode_gp;
 static ir_mode               *mode_fp;
+static ir_mode               *mode_fp2;
+//static ir_mode               *mode_fp4;
 static pmap                  *node_to_stack;
 
 static ir_node *gen_SymConst(ir_node *node);
@@ -208,8 +210,6 @@ static bool is_imm_encodeable(const ir_node *node)
 {
        long val;
 
-       //assert(mode_is_float_vector(get_irn_mode(node)));
-
        if (!is_Const(node))
                return false;
 
@@ -254,7 +254,9 @@ static ir_node *gen_helper_binop(ir_node *node, match_flags_t flags,
  * helper function for FP binop operations
  */
 static ir_node *gen_helper_binfpop(ir_node *node, ir_mode *mode,
-                                   new_binop_fp_func new_func)
+                                   new_binop_fp_func new_func_single,
+                                   new_binop_fp_func new_func_double,
+                                   new_binop_fp_func new_func_quad)
 {
        ir_node  *block   = be_transform_node(get_nodes_block(node));
        ir_node  *op1     = get_binop_left(node);
@@ -262,8 +264,19 @@ static ir_node *gen_helper_binfpop(ir_node *node, ir_mode *mode,
        ir_node  *op2     = get_binop_right(node);
        ir_node  *new_op2 = be_transform_node(op2);
        dbg_info *dbgi    = get_irn_dbg_info(node);
-
-       return new_func(dbgi, block, new_op1, new_op2, mode);
+       unsigned  bits    = get_mode_size_bits(mode);
+
+       switch (bits) {
+       case 32:
+               return new_func_single(dbgi, block, new_op1, new_op2, mode);
+       case 64:
+               return new_func_double(dbgi, block, new_op1, new_op2, mode);
+       case 128:
+               return new_func_quad(dbgi, block, new_op1, new_op2, mode);
+       default:
+               break;
+       }
+       panic("unsupported mode %+F for float op", mode);
 }
 
 /**
@@ -277,7 +290,8 @@ static ir_node *gen_Add(ir_node *node)
        ir_mode *mode = get_irn_mode(node);
 
        if (mode_is_float(mode)) {
-               return gen_helper_binfpop(node, mode, new_bd_sparc_fadd);
+               return gen_helper_binfpop(node, mode, new_bd_sparc_fadd_s,
+                                         new_bd_sparc_fadd_d, new_bd_sparc_fadd_q);
        }
 
        return gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_Add_reg, new_bd_sparc_Add_imm);
@@ -294,7 +308,8 @@ static ir_node *gen_Sub(ir_node *node)
        ir_mode *mode = get_irn_mode(node);
 
        if (mode_is_float(mode)) {
-               return gen_helper_binfpop(node, mode, new_bd_sparc_fsub);
+               return gen_helper_binfpop(node, mode, new_bd_sparc_fsub_s,
+                                         new_bd_sparc_fsub_d, new_bd_sparc_fsub_q);
        }
 
        return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Sub_reg, new_bd_sparc_Sub_imm);
@@ -366,7 +381,8 @@ static ir_node *gen_Mul(ir_node *node)
 {
        ir_mode *mode = get_irn_mode(node);
        if (mode_is_float(mode)) {
-               return gen_helper_binfpop(node, mode, new_bd_sparc_fmul);
+               return gen_helper_binfpop(node, mode, new_bd_sparc_fmul_s,
+                                         new_bd_sparc_fmul_d, new_bd_sparc_fmul_q);
        }
 
        assert(mode_is_data(mode));
@@ -422,7 +438,8 @@ static ir_node *gen_Quot(ir_node *node)
 {
        ir_mode *mode = get_Quot_resmode(node);
        assert(mode_is_float(mode));
-       return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv);
+       return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv_s,
+                                 new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q);
 }
 
 /**
@@ -442,8 +459,10 @@ static ir_node *gen_Abs(ir_node *node) {
 
        ir_node *mov, *sra, *xor, *sub, *new_op;
 
-       if (mode_is_float(mode))
-               panic("FP not supported yet");
+       if (mode_is_float(mode)) {
+               return gen_helper_binfpop(node, mode, new_bd_sparc_fabs_s,
+                                         new_bd_sparc_fdiv_d, new_bd_sparc_fdiv_q);
+       }
 
        new_op = be_transform_node(op);
 
@@ -1071,37 +1090,66 @@ static ir_node *gen_Return(ir_node *node)
 }
 
 static ir_node *bitcast_int_to_float(dbg_info *dbgi, ir_node *block,
-                                     ir_node *node)
+                                     ir_node *value0, ir_node *value1)
 {
        ir_graph *irg   = current_ir_graph;
-       ir_node  *stack = get_irg_frame(irg);
+       ir_node  *sp    = get_irg_frame(irg);
        ir_node  *nomem = new_NoMem();
-       ir_node  *st    = new_bd_sparc_St(dbgi, block, stack, node, nomem, mode_gp,
+       ir_node  *st    = new_bd_sparc_St(dbgi, block, sp, value0, nomem, mode_gp,
                                          NULL, 0, 0, true);
+       ir_mode  *mode;
        ir_node  *ldf;
+       ir_node  *mem;
        set_irn_pinned(st, op_pin_state_floats);
 
-       ldf = new_bd_sparc_Ldf(dbgi, block, stack, st, mode_fp, NULL, 0, 0, true);
+       if (value1 != NULL) {
+               ir_node *st1 = new_bd_sparc_St(dbgi, block, sp, value1, nomem, mode_gp,
+                                              NULL, 0, 4, true);
+               ir_node *in[2] = { st, st1 };
+               ir_node *sync  = new_r_Sync(block, 2, in);
+               set_irn_pinned(st1, op_pin_state_floats);
+               mem  = sync;
+               mode = mode_fp2;
+       } else {
+               mem  = st;
+               mode = mode_fp;
+       }
+
+       ldf = new_bd_sparc_Ldf(dbgi, block, sp, mem, mode, NULL, 0, 0, true);
        set_irn_pinned(ldf, op_pin_state_floats);
 
-       return new_Proj(ldf, mode_fp, pn_sparc_Ldf_res);
+       return new_Proj(ldf, mode, pn_sparc_Ldf_res);
 }
 
-static ir_node *bitcast_float_to_int(dbg_info *dbgi, ir_node *block,
-                                     ir_node *node)
+static void bitcast_float_to_int(dbg_info *dbgi, ir_node *block,
+                                 ir_node *node, ir_mode *float_mode,
+                                 ir_node **result)
 {
        ir_graph *irg   = current_ir_graph;
        ir_node  *stack = get_irg_frame(irg);
        ir_node  *nomem = new_NoMem();
-       ir_node  *stf   = new_bd_sparc_Stf(dbgi, block, stack, node, nomem, mode_fp,
-                                          NULL, 0, 0, true);
+       ir_node  *stf   = new_bd_sparc_Stf(dbgi, block, stack, node, nomem,
+                                          float_mode, NULL, 0, 0, true);
+       int       bits  = get_mode_size_bits(float_mode);
        ir_node  *ld;
        set_irn_pinned(stf, op_pin_state_floats);
 
        ld = new_bd_sparc_Ld(dbgi, block, stack, stf, mode_gp, NULL, 0, 0, true);
        set_irn_pinned(ld, op_pin_state_floats);
+       result[0] = new_Proj(ld, mode_gp, pn_sparc_Ld_res);
 
-       return new_Proj(ld, mode_fp, pn_sparc_Ld_res);
+       if (bits == 64) {
+               ir_node *ld2 = new_bd_sparc_Ld(dbgi, block, stack, stf, mode_gp,
+                                              NULL, 0, 4, true);
+               set_irn_pinned(ld, op_pin_state_floats);
+               result[1] = new_Proj(ld2, mode_gp, pn_sparc_Ld_res);
+
+               arch_irn_add_flags(ld, sparc_arch_irn_flag_needs_64bit_spillslot);
+               arch_irn_add_flags(ld2, sparc_arch_irn_flag_needs_64bit_spillslot);
+       } else {
+               assert(bits == 32);
+               result[1] = NULL;
+       }
 }
 
 static ir_node *gen_Call(ir_node *node)
@@ -1161,37 +1209,40 @@ static ir_node *gen_Call(ir_node *node)
        for (p = 0; p < n_params; ++p) {
                ir_node                  *value      = get_Call_param(node, p);
                ir_node                  *new_value  = be_transform_node(value);
-               ir_node                  *new_value1 = NULL;
                const reg_or_stackslot_t *param      = &cconv->parameters[p];
                ir_type                  *param_type = get_method_param_type(type, p);
                ir_mode                  *mode       = get_type_mode(param_type);
+               ir_node                  *new_values[2];
                ir_node                  *str;
 
                if (mode_is_float(mode) && param->reg0 != NULL) {
                        unsigned size_bits = get_mode_size_bits(mode);
-                       assert(size_bits == 32);
-                       new_value = bitcast_float_to_int(dbgi, new_block, new_value);
+                       assert(size_bits <= 64);
+                       bitcast_float_to_int(dbgi, new_block, new_value, mode, new_values);
+               } else {
+                       new_values[0] = new_value;
+                       new_values[1] = NULL;
                }
 
                /* put value into registers */
                if (param->reg0 != NULL) {
-                       in[in_arity]     = new_value;
+                       in[in_arity]     = new_values[0];
                        in_req[in_arity] = param->reg0->single_req;
                        ++in_arity;
-                       if (new_value1 == NULL)
+                       if (new_values[1] == NULL)
                                continue;
                }
                if (param->reg1 != NULL) {
-                       assert(new_value1 != NULL);
-                       in[in_arity]     = new_value1;
+                       assert(new_values[1] != NULL);
+                       in[in_arity]     = new_values[1];
                        in_req[in_arity] = param->reg1->single_req;
                        ++in_arity;
                        continue;
                }
 
                /* we need a store if we're here */
-               if (new_value1 != NULL) {
-                       new_value = new_value1;
+               if (new_values[1] != NULL) {
+                       new_value = new_values[1];
                        mode      = mode_gp;
                }
 
@@ -1471,8 +1522,21 @@ static ir_node *gen_Proj_Proj_Start(ir_node *node)
                ir_node               *value = be_prolog_get_reg_value(abihelper, reg);
 
                if (mode_is_float(mode)) {
+                       ir_node *value1 = NULL;
+
+                       if (param->reg1 != NULL) {
+                               value1 = be_prolog_get_reg_value(abihelper, param->reg1);
+                       } else if (param->entity != NULL) {
+                               ir_node *fp  = be_prolog_get_reg_value(abihelper, fp_reg);
+                               ir_node *mem = be_prolog_get_memory(abihelper);
+                               ir_node *ld  = new_bd_sparc_Ld(NULL, new_block, fp, mem,
+                                                              mode_gp, param->entity,
+                                                              0, 0, true);
+                               value1 = new_Proj(ld, mode_gp, pn_sparc_Ld_res);
+                       }
+
                        /* convert integer value to float */
-                       value = bitcast_int_to_float(NULL, new_block, value);
+                       value = bitcast_int_to_float(NULL, new_block, value, value1);
                }
                return value;
        } else {
@@ -1690,8 +1754,10 @@ void sparc_transform_graph(sparc_code_gen_t *cg)
 
        node_to_stack = pmap_create();
 
-       mode_gp = mode_Iu;
-       mode_fp = mode_F;
+       mode_gp  = mode_Iu;
+       mode_fp  = mode_F;
+       mode_fp2 = mode_D;
+       //mode_fp4 = ?
 
        abihelper = be_abihelper_prepare(irg);
        be_collect_stacknodes(abihelper);