From: Matthias Braun Date: Thu, 19 Apr 2007 15:43:25 +0000 (+0000) Subject: use own mode for fpcw, fix constants for shift, xmm const assembler X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=7a3b3ea720315e8b4e17d537d2618159074d5139;p=libfirm use own mode for fpcw, fix constants for shift, xmm const assembler [r13422] --- diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index db7911677..2c24f2972 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -65,6 +65,8 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) /* TODO: ugly */ static set *cur_reg_set = NULL; +ir_mode *mode_fpcw = NULL; + typedef ir_node *(*create_const_node_func) (dbg_info *dbg, ir_graph *irg, ir_node *block); static INLINE ir_node *create_const(ia32_code_gen_t *cg, ir_node **place, @@ -1510,6 +1512,10 @@ static void *ia32_init(FILE *file_handle) { isa = xmalloc(sizeof(*isa)); memcpy(isa, &ia32_isa_template, sizeof(*isa)); + if(mode_fpcw == NULL) { + mode_fpcw = new_ir_mode("Fpcw", irms_int_number, 16, 0, irma_none, 0); + } + ia32_register_init(isa); ia32_create_opcodes(); ia32_register_copy_attr_func(); diff --git a/ir/be/ia32/bearch_ia32_t.h b/ir/be/ia32/bearch_ia32_t.h index 947eba143..e46d71132 100644 --- a/ir/be/ia32/bearch_ia32_t.h +++ b/ir/be/ia32/bearch_ia32_t.h @@ -151,6 +151,9 @@ typedef struct _ia32_intrinsic_env_t { ir_entity *d_ll_conv; /**< entity for converts d -> ll */ } ia32_intrinsic_env_t; +/** mode for the floating point control word */ +extern ir_mode *mode_fpcw; + /** * Returns the unique per irg GP NoReg node. */ diff --git a/ir/be/ia32/ia32_new_nodes.c b/ir/be/ia32/ia32_new_nodes.c index f9980872a..a6d4add6b 100644 --- a/ir/be/ia32/ia32_new_nodes.c +++ b/ir/be/ia32/ia32_new_nodes.c @@ -27,6 +27,7 @@ #include "../bearch_t.h" +#include "bearch_ia32_t.h" #include "ia32_nodes_attr.h" #include "ia32_new_nodes.h" #include "gen_ia32_regalloc_if.h" diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 05cdfc7e8..6c1cfc36d 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -160,7 +160,7 @@ $arch = "ia32"; ], fp_cw => [ # the floating point control word { name => "fpcw", type => 4 | 32}, - { mode => "mode_Hu" } + { mode => "mode_fpcw" } ], flags => [ { name => "eflags", type => 4 }, @@ -288,6 +288,7 @@ $default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);"; $mode_xmm = "mode_E"; $mode_gp = "mode_Iu"; +$mode_fpcw = "mode_fpcw"; $status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ]; $fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM", "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ]; @@ -568,9 +569,9 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) { } } else { if (get_ia32_op_type(node) == ia32_AddrModeD) { - . shldl $%C, %S4, %AM + . shldl %C, %S4, %AM } else { - . shldl $%C, %S4, %S3 + . shldl %C, %S4, %S3 } } ', @@ -623,9 +624,9 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) { } } else { if (get_ia32_op_type(node) == ia32_AddrModeD) { - . shrdl $%C, %S4, %AM + . shrdl %C, %S4, %AM } else { - . shrdl $%C, %S4, %S3 + . shrdl %C, %S4, %S3 } } ', @@ -871,7 +872,7 @@ ChangeCW => { irn_flags => "I", comment => "change floating point control word", reg_req => { out => [ "fp_cw" ] }, - mode => "mode_Hu", + mode => $mode_fpcw, latency => 3, units => [ "GP" ], modified_flags => $fpcw_flags @@ -884,7 +885,7 @@ FldCW => { reg_req => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] }, latency => 5, emit => ". fldcw %AM", - mode => "mode_Hu", + mode => $mode_fpcw, units => [ "GP" ], modified_flags => $fpcw_flags }, @@ -1178,7 +1179,7 @@ xConst => { irn_flags => "R", comment => "represents a SSE constant", reg_req => { out => [ "xmm" ] }, - emit => '. mov%XXM $%C, %D1', + emit => '. mov%XXM %C, %D1', latency => 2, units => [ "SSE" ], mode => "mode_E", diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 40c0cfdba..0d8a35b1e 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -108,6 +108,14 @@ static ir_node *transform_node(ia32_transform_env_t *env, ir_node *node); static void duplicate_deps(ia32_transform_env_t *env, ir_node *old_node, ir_node *new_node); +static INLINE int mode_needs_gp_reg(ir_mode *mode) +{ + if(mode == mode_fpcw) + return 0; + + return mode_is_int(mode) || mode_is_character(mode) || mode_is_reference(mode); +} + static INLINE void set_new_node(ir_node *old_node, ir_node *new_node) { set_irn_link(old_node, new_node); @@ -1812,7 +1820,7 @@ static ir_node *gen_Cond(ia32_transform_env_t *env, ir_node *node) { pnc = get_inversed_pnc(pnc); } - if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) { + if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_needs_gp_reg(get_irn_mode(expr))) { if (get_ia32_immop_type(cnst) == ia32_ImmConst && classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL) { @@ -2723,7 +2731,7 @@ static ir_node *gen_Unknown(ia32_transform_env_t *env, ir_node *node) { return ia32_new_Unknown_xmm(env->cg); else return ia32_new_Unknown_vfp(env->cg); - } else if (mode_is_int(mode) || mode_is_reference(mode)) { + } else if (mode_needs_gp_reg(mode)) { return ia32_new_Unknown_gp(env->cg); } else { assert(0 && "unsupported Unknown-Mode"); @@ -2743,7 +2751,7 @@ static ir_node *gen_Phi(ia32_transform_env_t *env, ir_node *node) { ir_node *phi; int i, arity; - if(mode_is_int(mode) || mode_is_reference(mode)) { + if(mode_needs_gp_reg(mode)) { // we shouldn't have any 64bit stuff around anymore assert(get_mode_size_bits(mode) <= 32); // all integer operations are on 32bit registers now @@ -3655,7 +3663,7 @@ static ir_node *gen_Proj(ia32_transform_env_t *env, ir_node *node) { ir_node *new_pred = transform_node(env, pred); ir_node *block = transform_node(env, get_nodes_block(node)); ir_mode *mode = get_irn_mode(node); - if (mode_is_signed(mode) || mode_is_reference(mode)) { + if (mode_needs_gp_reg(mode)) { return new_r_Proj(irg, block, new_pred, mode_Iu, get_Proj_proj(node)); } } diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index ac1d0d36f..8291626ae 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -1671,9 +1671,13 @@ static int sim_Copy(x87_state *state, ir_node *n) { } else { /* just a virtual copy */ x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx); + /* don't remove the node to keep the verifier quiet :), + the emitter won't emit any code for the node */ +#if 0 sched_remove(n); DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n))); exchange(n, get_unop_op(n)); +#endif } }