From: Andreas Schösser Date: Fri, 9 Mar 2007 11:06:01 +0000 (+0000) Subject: Added possibility to include automatically generated simd nodes specification. Also... X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=4ca3ed8fab5193b7fd57a084808ecb7a5819db24;p=libfirm Added possibility to include automatically generated simd nodes specification. Also Added code to Spill and Reload sse registers. SSE registers have mode_DLu now, which represents a 128 bit unsigned value. --- diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 699df5cde..9275b297d 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -1201,6 +1201,10 @@ static void transform_to_Load(ia32_code_gen_t *cg, ir_node *node) { else new_op = new_rd_ia32_vfld(dbg, irg, block, ptr, noreg, mem); } + else if (get_mode_size_bits(spillmode) == 128) { + // Reload 128 bit sse registers + new_op = new_rd_ia32_xxLoad(dbg, irg, block, ptr, noreg, mem); + } else new_op = new_rd_ia32_Load(dbg, irg, block, ptr, noreg, mem); @@ -1258,6 +1262,10 @@ static void transform_to_Store(ia32_code_gen_t *cg, ir_node *node) { else store = new_rd_ia32_vfst(dbg, irg, block, ptr, noreg, val, nomem); } + else if (get_mode_size_bits(mode) == 128) { + // Spill 128 bit SSE registers + store = new_rd_ia32_xxStore(dbg, irg, block, ptr, noreg, val, nomem); + } else if (get_mode_size_bits(mode) == 8) { store = new_rd_ia32_Store8Bit(dbg, irg, block, ptr, noreg, val, nomem); } @@ -1770,6 +1778,7 @@ static void ia32_done(void *self) { * - the general purpose registers * - the SSE floating point register set * - the virtual floating point registers + * - the SSE vector register set */ static int ia32_get_n_reg_class(const void *self) { return 3; @@ -1779,13 +1788,17 @@ static int ia32_get_n_reg_class(const void *self) { * Return the register class for index i. */ static const arch_register_class_t *ia32_get_reg_class(const void *self, int i) { - assert(i >= 0 && i < 3 && "Invalid ia32 register class requested."); - if (i == 0) - return &ia32_reg_classes[CLASS_ia32_gp]; - else if (i == 1) - return &ia32_reg_classes[CLASS_ia32_xmm]; - else - return &ia32_reg_classes[CLASS_ia32_vfp]; + switch (i) { + case 0: + return &ia32_reg_classes[CLASS_ia32_gp]; + case 1: + return &ia32_reg_classes[CLASS_ia32_xmm]; + case 2: + return &ia32_reg_classes[CLASS_ia32_vfp]; + default: + assert(0 && "Invalid ia32 register class requested."); + return NULL; + } } /** diff --git a/ir/be/ia32/ia32_nodes_attr.h b/ir/be/ia32/ia32_nodes_attr.h index 19d520211..f5d1de534 100644 --- a/ir/be/ia32/ia32_nodes_attr.h +++ b/ir/be/ia32/ia32_nodes_attr.h @@ -25,9 +25,9 @@ typedef enum { } ia32_op_type_t; typedef enum { - ia32_ImmNone, - ia32_ImmConst, - ia32_ImmSymConst + ia32_ImmNone = 0, + ia32_ImmConst = 1, + ia32_ImmSymConst = 2 } ia32_immop_type_t; typedef enum { diff --git a/ir/be/ia32/ia32_simd_spec.pl b/ir/be/ia32/ia32_simd_spec.pl new file mode 100644 index 000000000..035634a1d --- /dev/null +++ b/ir/be/ia32/ia32_simd_spec.pl @@ -0,0 +1,8 @@ +# This file is generated! Do not edit, your changes will be lost! +# ___ _____ _____ _ _ +# / ___/ ___|| ____| __ _____ ___| |_ ___ _ __ _ __ ___ __| | ___ ___ +# \___ \___ \| _| \ \ / / _ \/ __| __/ _ \| '__| | '_ \ / _ \ / _` |/ _ \/ __| +# ___) |__) | |___ \ V / __/ (__| || (_) | | | | | | (_) | (_| | __/\__ \ +# |____/____/|_____| \_/ \___|\___|\__\___/|_| |_| |_|\___/ \__,_|\___||___/ + +$dummy=1; diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 2524a8911..c7b0ae191 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -126,9 +126,9 @@ $arch = "ia32"; { "name" => "xmm5", "type" => 1 }, { "name" => "xmm6", "type" => 1 }, { "name" => "xmm7", "type" => 1 }, - { "name" => "xmm_NOREG", "type" => 4 | 8 | 16 }, # we need a dummy register for NoReg nodes - { "name" => "xmm_UKNWN", "type" => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes - { "mode" => "mode_E" } + { "name" => "xmm_NOREG", "type" => 4 | 16 }, # we need a dummy register for NoReg nodes + { "name" => "xmm_UKNWN", "type" => 4 | 8 | 16}, # we need a dummy register for Unknown nodes + { "mode" => "mode_DLu" } ], "vfp" => [ { "name" => "vf0", "type" => 1 | 16 }, @@ -158,6 +158,7 @@ $arch = "ia32"; { "name" => "fpcw", "type" => 0 }, { "mode" => "mode_Hu" }, ], + ); # %reg_classes %cpu = ( @@ -1914,4 +1915,41 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) { "reg_req" => { }, }, + +# -------------------------------------------------------------------------------- # +# ____ ____ _____ _ _ # +# / ___/ ___|| ____| __ _____ ___| |_ ___ _ __ _ __ ___ __| | ___ ___ # +# \___ \___ \| _| \ \ / / _ \/ __| __/ _ \| '__| | '_ \ / _ \ / _` |/ _ \/ __| # +# ___) |__) | |___ \ V / __/ (__| || (_) | | | | | | (_) | (_| | __/\__ \ # +# |____/____/|_____| \_/ \___|\___|\__\___/|_| |_| |_|\___/ \__,_|\___||___/ # +# # +# -------------------------------------------------------------------------------- # + + +# Spilling and reloading of SSE registers, hardcoded, not generated # + +"xxLoad" => { + "op_flags" => "L|F", + "state" => "exc_pinned", + "comment" => "construct SSE Load: Load(ptr, mem) = LD ptr", + "reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm", "none" ] }, + "emit" => '. movdqu %D1, %AM', + "outs" => [ "res", "M" ], + "units" => [ "SSE" ], +}, + +"xxStore" => { + "op_flags" => "L|F", + "state" => "exc_pinned", + "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", + "reg_req" => { "in" => [ "gp", "gp", "xmm", "none" ] }, + "emit" => '. movdqu %binop', + "units" => [ "SSE" ], + "mode" => "mode_M", +}, + ); # end of %nodes + +# Include the generated SIMD node specification written by the SIMD optimization + +do "../ir/be/ia32/ia32_simd_spec.pl";