summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/powerpc/direct-move.h
diff options
context:
space:
mode:
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-10 21:42:14 +0000
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-10 21:42:14 +0000
commitf88fbcb9038a17c788b10653842a99e1e3227d24 (patch)
tree13b6a456a0b24c6c9fe5357339f211def5e18338 /gcc/testsuite/gcc.target/powerpc/direct-move.h
parent47c1894f25362b5698b3fe00a631fc1efacb3a90 (diff)
downloadgcc-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.h183
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