diff options
author | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-10 21:42:14 +0000 |
---|---|---|
committer | meissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-10 21:42:14 +0000 |
commit | f88fbcb9038a17c788b10653842a99e1e3227d24 (patch) | |
tree | 13b6a456a0b24c6c9fe5357339f211def5e18338 /gcc/testsuite/gcc.target/powerpc/direct-move.h | |
parent | 47c1894f25362b5698b3fe00a631fc1efacb3a90 (diff) | |
download | gcc-f88fbcb9038a17c788b10653842a99e1e3227d24.tar.gz |
[gcc]
2013-06-10 Michael Meissner <meissner@linux.vnet.ibm.com>
Pat Haugen <pthaugen@us.ibm.com>
Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/vector.md (GPR move splitter): Do not split moves
of vectors in GPRS if they are direct moves or quad word load or
store moves.
* config/rs6000/rs6000-protos.h (rs6000_output_move_128bit): Add
declaration.
(direct_move_p): Likewise.
(quad_load_store_p): Likewise.
* config/rs6000/rs6000.c (enum rs6000_reg_type): Simplify register
classes into bins based on the physical register type.
(reg_class_to_reg_type): Likewise.
(IS_STD_REG_TYPE): Likewise.
(IS_FP_VECT_REG_TYPE): Likewise.
(reload_fpr_gpr): Arrays to determine what insn to use if we can
use direct move instructions.
(reload_gpr_vsx): Likewise.
(reload_vsx_gpr): Likewise.
(rs6000_init_hard_regno_mode_ok): Precalculate the register type
information that is a simplification of register classes. Also
precalculate direct move reload helpers.
(direct_move_p): New function to return true if the operation can
be done as a direct move instruciton.
(quad_load_store_p): New function to return true if the operation
is a quad memory operation.
(rs6000_legitimize_address): If quad memory, only allow register
indirect for TImode addresses.
(rs6000_legitimate_address_p): Likewise.
(enum reload_reg_type): Delete, replace with rs6000_reg_type.
(rs6000_reload_register_type): Likewise.
(register_to_reg_type): Return register type.
(rs6000_secondary_reload_simple_move): New helper function for
secondary reload and secondary memory needed to identify anything
that is a simple move, and does not need reloading.
(rs6000_secondary_reload_direct_move): New helper function for
secondary reload to identify cases that can be done with several
instructions via the direct move instructions.
(rs6000_secondary_reload_move): New helper function for secondary
reload to identify moves between register types that can be done.
(rs6000_secondary_reload): Add support for quad memory operations
and for direct move.
(rs6000_secondary_memory_needed): Likewise.
(rs6000_debug_secondary_memory_needed): Change argument names.
(rs6000_output_move_128bit): New function to return the move to
use for 128-bit moves, including knowing about the various
limitations of quad memory operations.
* config/rs6000/vsx.md (vsx_mov<mode>): Add support for quad
memory operations. call rs6000_output_move_128bit for the actual
instruciton(s) to generate.
(vsx_movti_64bit): Likewise.
* config/rs6000/rs6000.md (UNSPEC_P8V_FMRGOW): New unspec values.
(UNSPEC_P8V_MTVSRWZ): Likewise.
(UNSPEC_P8V_RELOAD_FROM_GPR): Likewise.
(UNSPEC_P8V_MTVSRD): Likewise.
(UNSPEC_P8V_XXPERMDI): Likewise.
(UNSPEC_P8V_RELOAD_FROM_VSX): Likewise.
(UNSPEC_FUSION_GPR): Likewise.
(FMOVE128_GPR): New iterator for direct move.
(f32_lv): New mode attribute for load/store of SFmode/SDmode
values.
(f32_sv): Likewise.
(f32_dm): Likewise.
(zero_extend<mode>di2_internal1): Add support for power8 32-bit
loads and direct move instructions.
(zero_extendsidi2_lfiwzx): Likewise.
(extendsidi2_lfiwax): Likewise.
(extendsidi2_nocell): Likewise.
(floatsi<mode>2_lfiwax): Likewise.
(lfiwax): Likewise.
(floatunssi<mode>2_lfiwzx): Likewise.
(lfiwzx): Likewise.
(fix_trunc<mode>_stfiwx): Likewise.
(fixuns_trunc<mode>_stfiwx): Likewise.
(mov<mode>_hardfloat, 32-bit floating point): Likewise.
(mov<move>_hardfloat64, 64-bit floating point): Likewise.
(parity<mode>2_cmpb): Set length/type attr.
(unnamed shift right patterns, mov<mode>_internal2): Change type attr
for 'mr.' to fast_compare.
(bpermd_<mode>): Change type attr to popcnt.
(p8_fmrgow_<mode>): New insns for power8 direct move support.
(p8_mtvsrwz_1): Likewise.
(p8_mtvsrwz_2): Likewise.
(reload_fpr_from_gpr<mode>): Likewise.
(p8_mtvsrd_1): Likewise.
(p8_mtvsrd_2): Likewise.
(p8_xxpermdi_<mode>): Likewise.
(reload_vsx_from_gpr<mode>): Likewise.
(reload_vsx_from_gprsf): Likewise.
(p8_mfvsrd_3_<mode>): LIkewise.
(reload_gpr_from_vsx<mode>): Likewise.
(reload_gpr_from_vsxsf): Likewise.
(p8_mfvsrd_4_disf): Likewise.
(multi-word GPR splits): Do not split direct moves or quad memory
operations.
[gcc/testsuite]
2013-06-10 Michael Meissner <meissner@linux.vnet.ibm.com>
Pat Haugen <pthaugen@us.ibm.com>
Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/direct-move-vint1.c: New tests for power8
direct move instructions.
* gcc.target/powerpc/direct-move-vint2.c: Likewise.
* gcc.target/powerpc/direct-move.h: Likewise.
* gcc.target/powerpc/direct-move-float1.c: Likewise.
* gcc.target/powerpc/direct-move-float2.c: Likewise.
* gcc.target/powerpc/direct-move-double1.c: Likewise.
* gcc.target/powerpc/direct-move-double2.c: Likewise.
* gcc.target/powerpc/direct-move-long1.c: Likewise.
* gcc.target/powerpc/direct-move-long2.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199918 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/gcc.target/powerpc/direct-move.h')
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/direct-move.h | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/powerpc/direct-move.h b/gcc/testsuite/gcc.target/powerpc/direct-move.h new file mode 100644 index 00000000000..4e84fd678bb --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/direct-move.h @@ -0,0 +1,183 @@ +/* Test functions for direct move support. */ + + +void __attribute__((__noinline__)) +copy (TYPE *a, TYPE *b) +{ + *b = *a; +} + +#ifndef NO_GPR +void __attribute__((__noinline__)) +load_gpr (TYPE *a, TYPE *b) +{ + TYPE c = *a; + __asm__ ("# gpr, reg = %0" : "+b" (c)); + *b = c; +} +#endif + +#ifndef NO_FPR +void __attribute__((__noinline__)) +load_fpr (TYPE *a, TYPE *b) +{ + TYPE c = *a; + __asm__ ("# fpr, reg = %0" : "+d" (c)); + *b = c; +} +#endif + +#ifndef NO_ALTIVEC +void __attribute__((__noinline__)) +load_altivec (TYPE *a, TYPE *b) +{ + TYPE c = *a; + __asm__ ("# altivec, reg = %0" : "+v" (c)); + *b = c; +} +#endif + +#ifndef NO_VSX +void __attribute__((__noinline__)) +load_vsx (TYPE *a, TYPE *b) +{ + TYPE c = *a; + __asm__ ("# vsx, reg = %x0" : "+wa" (c)); + *b = c; +} +#endif + +#ifndef NO_GPR_TO_VSX +void __attribute__((__noinline__)) +load_gpr_to_vsx (TYPE *a, TYPE *b) +{ + TYPE c = *a; + TYPE d; + __asm__ ("# gpr, reg = %0" : "+b" (c)); + d = c; + __asm__ ("# vsx, reg = %x0" : "+wa" (d)); + *b = d; +} +#endif + +#ifndef NO_VSX_TO_GPR +void __attribute__((__noinline__)) +load_vsx_to_gpr (TYPE *a, TYPE *b) +{ + TYPE c = *a; + TYPE d; + __asm__ ("# vsx, reg = %x0" : "+wa" (c)); + d = c; + __asm__ ("# gpr, reg = %0" : "+b" (d)); + *b = d; +} +#endif + +#ifdef DO_MAIN +typedef void (fn_type (TYPE *, TYPE *)); + +struct test_struct { + fn_type *func; + const char *name; +}; + +const struct test_struct test_functions[] = { + { copy, "copy" }, +#ifndef NO_GPR + { load_gpr, "load_gpr" }, +#endif +#ifndef NO_FPR + { load_fpr, "load_fpr" }, +#endif +#ifndef NO_ALTIVEC + { load_altivec, "load_altivec" }, +#endif +#ifndef NO_VSX + { load_vsx, "load_vsx" }, +#endif +#ifndef NO_GPR_TO_VSX + { load_gpr_to_vsx, "load_gpr_to_vsx" }, +#endif +#ifndef NO_VSX_TO_GPR + { load_vsx_to_gpr, "load_vsx_to_gpr" }, +#endif +}; + +/* Test a given value for each of the functions. */ +void __attribute__((__noinline__)) +test_value (TYPE a) +{ + size_t i; + + for (i = 0; i < sizeof (test_functions) / sizeof (test_functions[0]); i++) + { + TYPE b; + + test_functions[i].func (&a, &b); + if (memcmp ((void *)&a, (void *)&b, sizeof (TYPE)) != 0) + abort (); + } +} + +/* Main program. */ +int +main (void) +{ + size_t i; + long j; + union { + TYPE value; + unsigned char bytes[sizeof (TYPE)]; + } u; + +#if IS_INT + TYPE value = (TYPE)-5; + for (i = 0; i < 12; i++) + { + test_value (value); + value++; + } + + for (i = 0; i < 8*sizeof (TYPE); i++) + test_value (((TYPE)1) << i); + +#elif IS_UNS + TYPE value = (TYPE)0; + for (i = 0; i < 10; i++) + { + test_value (value); + test_value (~ value); + value++; + } + + for (i = 0; i < 8*sizeof (TYPE); i++) + test_value (((TYPE)1) << i); + +#elif IS_FLOAT + TYPE value = (TYPE)-5; + for (i = 0; i < 12; i++) + { + test_value (value); + value++; + } + + test_value ((TYPE)3.1415926535); + test_value ((TYPE)1.23456); + test_value ((TYPE)(-0.0)); + test_value ((TYPE)NAN); + test_value ((TYPE)+INFINITY); + test_value ((TYPE)-INFINITY); +#else + + for (j = 0; j < 10; j++) + { + for (i = 0; i < sizeof (TYPE); i++) + u.bytes[i] = (unsigned char) (random () >> 4); + + test_value (u.value); + } +#endif + + return 0; +} +#endif |