http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60369
Bug ID: 60369 Summary: [PATCH] [TIC6X] new compiler intrinsics Product: gcc Version: 4.8.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: wojtek.golf at interia dot pl Host: Linux wmigda-desktop 3.11.0-13-generic #20-Ubuntu SMP Wed Oct 23 17:26:33 UTC 2013 i686 i686 i686 GNU/Linux Target: tic6x-none-elf Build: 4.8.3 20140224 (prerelease) Texas Instruments TIC6X compiler suite offers a number of compiler intrinsics (see e.g. SPRU197u document) which are absent in gcc. This is a patch proposal which is supposed to amend that. The scope is rather limited as this would be my first contribution to gcc so I would like to treat this as a pilot to see if I got everything right. The intrinsics I would like to add with my patch are: _swap2 _swap4 _dmv _packlh2 _packhl2 _rotl 1. Legal Prerequisites I think this proposal is small enough not to require for a separate copyright disclaimer/assignment. 2. Coding Standards Applied. 3. Testing Patches I have prepared few testcases which check whether the instruction descriptions are correct and whether the expected assembler instruction is generated for each of the intrinsics. 4. Documentation Changes TIC6X intrinsics are not listed in gcc documentation, so no update is necessary. 5. Web Site Changes As above. 6. Submitting Patches A description of the problem/bug and how your patch addresses it. GCC is missing some of the compiler intrinsics available in the Texas Instruments TIC6X compiler suite. This patch attempts to extend the intrinsics set offered by gcc. Testcases I have created a total of 12 testcases and placed them inside the gcc/testsuite/gcc.target/tic6x folder. ChangeLog 2014-02-28 Wojciech Migda <wojtek.g...@interia.pl> * gcc/config/c6x/c6x.c: new intrinsics entries in enum c6x_builtins, c6x_init_builtins, bdesc_2arg, and bdesc_1arg. v2si_ftype_si_si definition. * gcc/config/c6x/c6x.md: new instruction definitions. * gcc/config/c6x/c6x_intrinsics.h: new intrinsics functions. * gcc/testsuite/gcc.target/tic6x/{dmv-O2-scan.c,dmv-O2-volatile-scan.c, packhl2-O2-scan.c,packhl2-O2-volatile-scan.c,packlh2-O2-scan.c, packlh2-O2-volatile-scan.c,rotl-O2-scan.c,rotl-O2-volatile-scan.c, swap2-O2-scan.c,swap2-O2-volatile-scan.c,swap4-O2-scan.c, swap4-O2-volatile-scan.c}: testcases for new intrinsics. Bootstrapping and testing Host: Linux wmigda-desktop 3.11.0-13-generic #20-Ubuntu SMP Wed Oct 23 17:26:33 UTC 2013 i686 i686 i686 GNU/Linux Target: tic6x-none-elf Results for the new testcases (run with make check-gcc RUNTESTFLAGS="CFLAGS_FOR_TARGET='$CFLAGS_FOR_TARGET --sysroot=${CXTOOLS}${TRIPLET}/sysroot' -v -v tic6x.exp") PASS: gcc.target/tic6x/dmv-O2-scan.c (test for excess errors) PASS: gcc.target/tic6x/dmv-O2-scan.c scan-assembler \\(exit\\) PASS: gcc.target/tic6x/dmv-O2-scan.c scan-assembler-not [\\t ]dmv[\\t ] PASS: gcc.target/tic6x/dmv-O2-volatile-scan.c (test for excess errors) PASS: gcc.target/tic6x/dmv-O2-volatile-scan.c scan-assembler dmv PASS: gcc.target/tic6x/dmv-O2-volatile-scan.c scan-assembler-not \\(_dmv\\) PASS: gcc.target/tic6x/packhl2-O2-scan.c (test for excess errors) PASS: gcc.target/tic6x/packhl2-O2-scan.c scan-assembler \\(exit\\) PASS: gcc.target/tic6x/packhl2-O2-scan.c scan-assembler-not [\\t ]packhl2[\\t ] PASS: gcc.target/tic6x/packhl2-O2-volatile-scan.c (test for excess errors) PASS: gcc.target/tic6x/packhl2-O2-volatile-scan.c scan-assembler packhl2 PASS: gcc.target/tic6x/packhl2-O2-volatile-scan.c scan-assembler-not \\(_packhl2\\) PASS: gcc.target/tic6x/packlh2-O2-scan.c (test for excess errors) PASS: gcc.target/tic6x/packlh2-O2-scan.c scan-assembler \\(exit\\) PASS: gcc.target/tic6x/packlh2-O2-scan.c scan-assembler-not [\\t ]packlh2[\\t ] PASS: gcc.target/tic6x/packlh2-O2-volatile-scan.c (test for excess errors) PASS: gcc.target/tic6x/packlh2-O2-volatile-scan.c scan-assembler packlh2 PASS: gcc.target/tic6x/packlh2-O2-volatile-scan.c scan-assembler-not \\(_packlh2\\) PASS: gcc.target/tic6x/rotl-O2-scan.c (test for excess errors) PASS: gcc.target/tic6x/rotl-O2-scan.c scan-assembler \\(exit\\) PASS: gcc.target/tic6x/rotl-O2-scan.c scan-assembler-not [\\t ]rotl[\\t ] PASS: gcc.target/tic6x/rotl-O2-volatile-scan.c (test for excess errors) PASS: gcc.target/tic6x/rotl-O2-volatile-scan.c scan-assembler rotl PASS: gcc.target/tic6x/rotl-O2-volatile-scan.c scan-assembler-not \\(_rotl\\) PASS: gcc.target/tic6x/swap2-O2-scan.c (test for excess errors) PASS: gcc.target/tic6x/swap2-O2-scan.c scan-assembler \\(exit\\) PASS: gcc.target/tic6x/swap2-O2-scan.c scan-assembler-not packlh2 PASS: gcc.target/tic6x/swap2-O2-scan.c scan-assembler-not _swap2 PASS: gcc.target/tic6x/swap2-O2-volatile-scan.c (test for excess errors) PASS: gcc.target/tic6x/swap2-O2-volatile-scan.c scan-assembler packlh2 PASS: gcc.target/tic6x/swap2-O2-volatile-scan.c scan-assembler-not \\(_swap2\\) PASS: gcc.target/tic6x/swap4-O2-scan.c (test for excess errors) PASS: gcc.target/tic6x/swap4-O2-scan.c scan-assembler \\(exit\\) PASS: gcc.target/tic6x/swap4-O2-scan.c scan-assembler-not [\\t ]swap4[\\t ] PASS: gcc.target/tic6x/swap4-O2-volatile-scan.c (test for excess errors) PASS: gcc.target/tic6x/swap4-O2-volatile-scan.c scan-assembler swap4 PASS: gcc.target/tic6x/swap4-O2-volatile-scan.c scan-assembler-not \\(_swap4\\) The patch itself diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index e0db8b12..2258c23 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -6364,6 +6364,12 @@ enum c6x_builtins C6X_BUILTIN_AVG2, C6X_BUILTIN_AVGU4, + C6X_BUILTIN_SWAP4, + C6X_BUILTIN_ROTL, + C6X_BUILTIN_PACKLH2, + C6X_BUILTIN_PACKHL2, + C6X_BUILTIN_DMV, + C6X_BUILTIN_MAX }; @@ -6412,6 +6418,9 @@ c6x_init_builtins (void) tree v2si_ftype_v2hi_v2hi = build_function_type_list (V2SI_type_node, V2HI_type_node, V2HI_type_node, NULL_TREE); + tree v2si_ftype_si_si + = build_function_type_list (V2SI_type_node, intSI_type_node, + intSI_type_node, NULL_TREE); def_builtin ("__builtin_c6x_sadd", int_ftype_int_int, C6X_BUILTIN_SADD); @@ -6462,8 +6471,17 @@ c6x_init_builtins (void) def_builtin ("__builtin_c6x_extru", int_ftype_int_int, C6X_BUILTIN_EXTRU); + def_builtin ("__builtin_c6x_abs", int_ftype_int, C6X_BUILTIN_ABS); def_builtin ("__builtin_c6x_abs2", v2hi_ftype_v2hi, C6X_BUILTIN_ABS2); + + def_builtin ("__builtin_c6x_swap4", v2hi_ftype_v2hi, C6X_BUILTIN_SWAP4); + def_builtin ("__builtin_c6x_rotl", int_ftype_int_int, C6X_BUILTIN_ROTL); + + def_builtin ("__builtin_c6x_packlh2", v2hi_ftype_v2hi_v2hi, C6X_BUILTIN_PACKLH2); + def_builtin ("__builtin_c6x_packhl2", v2hi_ftype_v2hi_v2hi, C6X_BUILTIN_PACKHL2); + + def_builtin ("__builtin_c6x_dmv", v2si_ftype_si_si, C6X_BUILTIN_DMV); } @@ -6501,13 +6519,21 @@ static const struct builtin_description bdesc_2arg[] = { CODE_FOR_clrr, "__builtin_c6x_clrr", C6X_BUILTIN_CLRR }, { CODE_FOR_extr, "__builtin_c6x_extr", C6X_BUILTIN_EXTR }, - { CODE_FOR_extru, "__builtin_c6x_extru", C6X_BUILTIN_EXTRU } + { CODE_FOR_extru, "__builtin_c6x_extru", C6X_BUILTIN_EXTRU }, + + { CODE_FOR_rotlsi3, "__builtin_c6x_rotl", C6X_BUILTIN_ROTL }, + + { CODE_FOR_packlh2v2hi, "__builtin_c6x_packlh2", C6X_BUILTIN_PACKLH2 }, + { CODE_FOR_packhl2v2hi, "__builtin_c6x_packhl2", C6X_BUILTIN_PACKHL2 }, + + { CODE_FOR_dmvv2si, "__builtin_c6x_dmv", C6X_BUILTIN_DMV } }; static const struct builtin_description bdesc_1arg[] = { { CODE_FOR_ssabssi2, "__builtin_c6x_abs", C6X_BUILTIN_ABS }, - { CODE_FOR_ssabsv2hi2, "__builtin_c6x_abs2", C6X_BUILTIN_ABS2 } + { CODE_FOR_ssabsv2hi2, "__builtin_c6x_abs2", C6X_BUILTIN_ABS2 }, + { CODE_FOR_bswapv2hi2, "__builtin_c6x_swap4", C6X_BUILTIN_SWAP4 } }; /* Errors in the source file can cause expand_expr to return const0_rtx diff --git a/gcc/config/c6x/c6x.md b/gcc/config/c6x/c6x.md index e1c6f9a..e655411 100644 --- a/gcc/config/c6x/c6x.md +++ b/gcc/config/c6x/c6x.md @@ -3136,5 +3136,41 @@ [(set_attr "units" "ls") (set_attr "cross" "n,n,y,y")]) +(define_insn "packlh2v2hi" + [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b") + (vec_concat:V2HI + (vec_select:HI (match_operand:V2HI 2 "register_operand" "a,b,?b,?a") (parallel [(const_int 1)])) + (vec_select:HI (match_operand:V2HI 1 "register_operand" "a,b,a,b") (parallel [(const_int 0)])) + ) + )] + "TARGET_INSNS_64" + "%|%.\\tpacklh2\\t%$\\t%1, %2, %0" + [(set_attr "units" "ls") + (set_attr "cross" "n,n,y,y")]) + +(define_insn "packhl2v2hi" + [(set (match_operand:V2HI 0 "register_operand" "=a,b,a,b") + (vec_concat:V2HI + (vec_select:HI (match_operand:V2HI 2 "register_operand" "a,b,?b,?a") (parallel [(const_int 0)])) + (vec_select:HI (match_operand:V2HI 1 "register_operand" "a,b,a,b") (parallel [(const_int 1)])) + ) + )] + "TARGET_INSNS_64" + "%|%.\\tpackhl2\\t%$\\t%1, %2, %0" + [(set_attr "units" "ls") + (set_attr "cross" "n,n,y,y")]) + +(define_insn "dmvv2si" + [(set (match_operand:V2SI 0 "register_operand" "=a,b,a,b") + (vec_concat:V2SI + (match_operand:SI 2 "register_operand" "a,b,?b,?a") + (match_operand:SI 1 "register_operand" "a,b,a,b") + ) + )] + "TARGET_INSNS_64PLUS" + "%|%.\\tdmv\\t%$\\t%1, %2, %0" + [(set_attr "units" "s") + (set_attr "cross" "n,n,y,y")]) + (include "c6x-mult.md") (include "sync.md") diff --git a/gcc/config/c6x/c6x_intrinsics.h b/gcc/config/c6x/c6x_intrinsics.h index d768046..bd027e2 100644 --- a/gcc/config/c6x/c6x_intrinsics.h +++ b/gcc/config/c6x/c6x_intrinsics.h @@ -186,6 +186,41 @@ _subc (int src1, int src2) return __builtin_c6x_subc (src1, src2); } +__extension__ static __inline unsigned __attribute__ ((__always_inline__)) +_swap4 (unsigned src) +{ + return (unsigned)__builtin_c6x_swap4 ((__v2hi)src); +} + +__extension__ static __inline unsigned __attribute__ ((__always_inline__)) +_swap2 (unsigned src) +{ + return (unsigned)__builtin_c6x_packlh2 ((__v2hi)src, (__v2hi)src); +} + +__extension__ static __inline unsigned __attribute__ ((__always_inline__)) +_rotl (unsigned src1, unsigned src2) +{ + return __builtin_c6x_rotl (src1, src2); +} + +__extension__ static __inline unsigned __attribute__ ((__always_inline__)) +_packlh2 (unsigned src1, unsigned src2) +{ + return (unsigned)__builtin_c6x_packlh2 ((__v2hi)src1, (__v2hi)src2); +} + +__extension__ static __inline unsigned __attribute__ ((__always_inline__)) +_packhl2 (unsigned src1, unsigned src2) +{ + return (unsigned)__builtin_c6x_packhl2 ((__v2hi)src1, (__v2hi)src2); +} + +__extension__ static __inline long long __attribute__ ((__always_inline__)) +_dmv (unsigned src1, unsigned src2) +{ + return (long long)__builtin_c6x_dmv (src1, src2); +} #ifdef __cplusplus } diff --git a/gcc/testsuite/gcc.target/tic6x/dmv-O2-scan.c b/gcc/testsuite/gcc.target/tic6x/dmv-O2-scan.c new file mode 100644 index 0000000..f9ae4ab --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/dmv-O2-scan.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x+" } */ +/* { dg-final { scan-assembler "\\(exit\\)" } } */ +/* { dg-final { scan-assembler-not "\[\\t \]dmv\[\\t \]" } } */ + +/* + * Check if the instruction definition is correct so that it will allow + * to evaluate and optimize away _dmv in the compile time. + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int main (void) +{ + unsigned src1 = 0x12345678; + unsigned src2 = 0x87654321; + long long ex = 0x1234567887654321LL; + + long long out = _dmv (src1, src2); + if (out != ex) + { + return 1; + } + else + { + exit (0); + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/dmv-O2-volatile-scan.c b/gcc/testsuite/gcc.target/tic6x/dmv-O2-volatile-scan.c new file mode 100644 index 0000000..dd13bd8 --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/dmv-O2-volatile-scan.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x+" } */ +/* { dg-final { scan-assembler "dmv" } } */ +/* { dg-final { scan-assembler-not "\\(_dmv\\)" } } */ + +/* + * Check if _dmv is resolved to the correct machine instruction + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +long long fn_dmv (unsigned src1, unsigned src2) +{ + return _dmv (src1, src2); +} + +int main (void) +{ + volatile unsigned src1 = 0x12345678; + volatile unsigned src2 = 0x87654321; + long long ex = 0x1234567887654321LL; + + long long out = fn_dmv (src1, src2); + if (out != ex) + { + exit (1); + } + else + { + return 0; + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/packhl2-O2-scan.c b/gcc/testsuite/gcc.target/tic6x/packhl2-O2-scan.c new file mode 100644 index 0000000..6bf17f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/packhl2-O2-scan.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "\\(exit\\)" } } */ +/* { dg-final { scan-assembler-not "\[\\t \]packhl2\[\\t \]" } } */ + +/* + * Check if the instruction definition is correct so that it will allow + * to evaluate and optimize away _packhl2 in the compile time. + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int main (void) +{ + int in1 = 0x12345678; + int in2 = 0x87654321; + int ex = 0x12344321; + + int out = _packhl2 (in1, in2); + if (out != ex) + { + return 1; + } + else + { + exit (0); + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/packhl2-O2-volatile-scan.c b/gcc/testsuite/gcc.target/tic6x/packhl2-O2-volatile-scan.c new file mode 100644 index 0000000..e3ca4da --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/packhl2-O2-volatile-scan.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "packhl2" } } */ +/* { dg-final { scan-assembler-not "\\(_packhl2\\)" } } */ + +/* + * Check if _packhl2 is resolved to the correct machine instruction + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +unsigned fn_packhl2 (unsigned x, unsigned y) +{ + return _packhl2 (x, y); +} + +int main (void) +{ + volatile int in1 = 0x12345678; + volatile int in2 = 0x87654321; + int ex = 0x12344321; + + int out = fn_packhl2 (in1, in2); + if (out != ex) + { + exit (1); + } + else + { + return 0; + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/packlh2-O2-scan.c b/gcc/testsuite/gcc.target/tic6x/packlh2-O2-scan.c new file mode 100644 index 0000000..343d428 --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/packlh2-O2-scan.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "\\(exit\\)" } } */ +/* { dg-final { scan-assembler-not "\[\\t \]packlh2\[\\t \]" } } */ + +/* + * Check if the instruction definition is correct so that it will allow + * to evaluate and optimize away _packlh2 in the compile time. + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int main (void) +{ + int in1 = 0x12345678; + int in2 = 0x87654321; + int ex = 0x56788765; + + int out = _packlh2 (in1, in2); + if (out != ex) + { + return 1; + } + else + { + exit (0); + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/packlh2-O2-volatile-scan.c b/gcc/testsuite/gcc.target/tic6x/packlh2-O2-volatile-scan.c new file mode 100644 index 0000000..af624cb --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/packlh2-O2-volatile-scan.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "packlh2" } } */ +/* { dg-final { scan-assembler-not "\\(_packlh2\\)" } } */ + +/* + * Check if _packlh2 is resolved to the correct machine instruction + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +unsigned fn_packlh2 (unsigned x, unsigned y) +{ + return _packlh2 (x, y); +} + +int main (void) +{ + volatile int in1 = 0x12345678; + volatile int in2 = 0x87654321; + int ex = 0x56788765; + + int out = fn_packlh2 (in1, in2); + if (out != ex) + { + exit (1); + } + else + { + return 0; + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/rotl-O2-scan.c b/gcc/testsuite/gcc.target/tic6x/rotl-O2-scan.c new file mode 100644 index 0000000..58147a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/rotl-O2-scan.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "\\(exit\\)" } } */ +/* { dg-final { scan-assembler-not "\[\\t \]rotl\[\\t \]" } } */ + +/* + * Check if the instruction definition is correct so that it will allow + * to evaluate and optimize away _rotl in the compile time. + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int main (void) +{ + int in = 0x12345678; + int nbit = 1; + int ex; + + ex = 0x2468ACF0; + int out = _rotl (in, nbit); + if (out != ex) + { + return 1; + } + else + { + exit (0); + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/rotl-O2-volatile-scan.c b/gcc/testsuite/gcc.target/tic6x/rotl-O2-volatile-scan.c new file mode 100644 index 0000000..a27921e --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/rotl-O2-volatile-scan.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "rotl" } } */ +/* { dg-final { scan-assembler-not "\\(_rotl\\)" } } */ + +/* + * Check if _rotl is resolved to the correct machine instruction + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int fn_rotl (int x, int nbit) +{ + return _rotl (x, nbit); +} + +int main (void) +{ + volatile int in = 0x12345678; + volatile int nbit = 1; + int ex; + + ex = 0x2468ACF0; + int out = fn_rotl (in, nbit); + if (out != ex) + { + exit (1); + } + else + { + return 0; + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/swap2-O2-scan.c b/gcc/testsuite/gcc.target/tic6x/swap2-O2-scan.c new file mode 100644 index 0000000..aceb266 --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/swap2-O2-scan.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "\\(exit\\)" } } */ +/* { dg-final { scan-assembler-not "packlh2" } } */ +/* { dg-final { scan-assembler-not "_swap2" } } */ + +/* + * Check if the instruction definition is correct so that it will allow + * to evaluate and optimize away _swap2 in the compile time. + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int main (void) +{ + int in = 0x12345678; + int ex = 0x56781234; + + int out = _swap2 (in); + if (out != ex) + { + return 1; + } + else + { + exit (0); + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/swap2-O2-volatile-scan.c b/gcc/testsuite/gcc.target/tic6x/swap2-O2-volatile-scan.c new file mode 100644 index 0000000..ada1a33 --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/swap2-O2-volatile-scan.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "packlh2" } } */ +/* { dg-final { scan-assembler-not "\\(_swap2\\)" } } */ + +/* + * Check if _swap2 is resolved to the correct machine instruction + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +unsigned fn_swap2 (unsigned x) +{ + return _swap2 (x); +} + +int main (void) +{ + volatile int in = 0x12345678; + int ex = 0x56781234; + + int out = fn_swap2 (in); + if (out != ex) + { + exit (1); + } + else + { + return 0; + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/swap4-O2-scan.c b/gcc/testsuite/gcc.target/tic6x/swap4-O2-scan.c new file mode 100644 index 0000000..0d8c30d --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/swap4-O2-scan.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "\\(exit\\)" } } */ +/* { dg-final { scan-assembler-not "\[\\t \]swap4\[\\t \]" } } */ + +/* + * Check if the instruction definition is correct so that it will allow + * to evaluate and optimize away _swap4 in the compile time. + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int main (void) +{ + int in = 0x12345678; + int ex = 0x34127856; + + int out = _swap4 (in); + if (out != ex) + { + return 1; + } + else + { + exit (0); + } +} diff --git a/gcc/testsuite/gcc.target/tic6x/swap4-O2-volatile-scan.c b/gcc/testsuite/gcc.target/tic6x/swap4-O2-volatile-scan.c new file mode 100644 index 0000000..862c940 --- /dev/null +++ b/gcc/testsuite/gcc.target/tic6x/swap4-O2-volatile-scan.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=c64x" } */ +/* { dg-final { scan-assembler "swap4" } } */ +/* { dg-final { scan-assembler-not "\\(_swap4\\)" } } */ + +/* + * Check if _swap4 is resolved to the correct machine instruction + */ + +#include <c6x_intrinsics.h> +#include <stdlib.h> + +int fn_swap4 (int x) +{ + return _swap4 (x); +} + +int main (void) +{ + volatile int in = 0x12345678; + int ex = 0x34127856; + + int out = fn_swap4 (in); + if (out != ex) + { + exit (1); + } + else + { + return 0; + } +}