111
|
1 /* { dg-do compile } */
|
131
|
2 /* { dg-require-effective-target bswap } */
|
111
|
3 /* { dg-require-effective-target stdint_types } */
|
|
4 /* { dg-options "-O2 -fdump-tree-bswap" } */
|
|
5 /* { dg-additional-options "-march=z900" { target s390*-*-* } } */
|
|
6
|
|
7 #include <stdint.h>
|
|
8
|
|
9 #define __const_swab32(x) ((uint32_t)( \
|
|
10 (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
|
|
11 (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
|
|
12 (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
|
|
13 (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
|
|
14
|
|
15 /* This byte swap implementation is used by the Linux kernel and the
|
|
16 GNU C library. */
|
|
17
|
|
18 uint32_t
|
|
19 swap32_a (uint32_t in)
|
|
20 {
|
|
21 return __const_swab32 (in);
|
|
22 }
|
|
23
|
|
24 /* The OpenSSH byte swap implementation. */
|
|
25 uint32_t
|
|
26 swap32_b (uint32_t in)
|
|
27 {
|
|
28 uint32_t a;
|
|
29
|
|
30 a = (in << 16) | (in >> 16);
|
|
31 a = ((a & 0x00ff00ff) << 8) | ((a & 0xff00ff00) >> 8);
|
|
32
|
|
33 return a;
|
|
34 }
|
|
35
|
|
36 /* This variant is currently used by libgcc. The difference is that
|
|
37 the bswap source and destination have a signed integer type which
|
|
38 requires a slightly higher search depth in order to dive through
|
|
39 the cast as well. */
|
|
40
|
|
41 typedef int SItype __attribute__ ((mode (SI)));
|
|
42
|
|
43 SItype
|
|
44 swap32_c (SItype u)
|
|
45 {
|
|
46 return ((((u) & 0xff000000) >> 24)
|
|
47 | (((u) & 0x00ff0000) >> 8)
|
|
48 | (((u) & 0x0000ff00) << 8)
|
|
49 | (((u) & 0x000000ff) << 24));
|
|
50 }
|
|
51
|
|
52 /* This variant comes from gcc.target/sh/pr53568-1.c. It requires to track
|
|
53 which bytes have an unpredictable value (eg. due to sign extension) to
|
|
54 make sure that the final expression have only well defined byte values. */
|
|
55
|
|
56 SItype
|
|
57 swap32_d (SItype in)
|
|
58 {
|
|
59 /* 1x swap.w
|
|
60 2x swap.b */
|
|
61 return (((in >> 0) & 0xFF) << 24)
|
|
62 | (((in >> 8) & 0xFF) << 16)
|
|
63 | (((in >> 16) & 0xFF) << 8)
|
|
64 | (((in >> 24) & 0xFF) << 0);
|
|
65 }
|
|
66
|
|
67 /* This variant is adapted from swap32_d above. It detects missing cast of
|
|
68 MARKER_BYTE_UNKNOWN to uint64_t for the CASE_CONVERT case for host
|
|
69 architecture where a left shift with too big an operand mask its high
|
|
70 bits. */
|
|
71
|
|
72 SItype
|
|
73 swap32_e (SItype in)
|
|
74 {
|
|
75 return (((in >> 0) & 0xFF) << 24)
|
|
76 | (((in >> 8) & 0xFF) << 16)
|
|
77 | (((((int64_t) in) & 0xFF0000FF0000) >> 16) << 8)
|
|
78 | (((in >> 24) & 0xFF) << 0);
|
|
79 }
|
|
80
|
|
81 /* This variant comes from PR63259. It compiles to a gimple sequence that ends
|
|
82 with a rotation instead of a bitwise OR. */
|
|
83
|
|
84 unsigned
|
|
85 swap32_f (unsigned in)
|
|
86 {
|
|
87 in = ((in & 0xff00ff00) >> 8) | ((in & 0x00ff00ff) << 8);
|
|
88 in = ((in & 0xffff0000) >> 16) | ((in & 0x0000ffff) << 16);
|
|
89 return in;
|
|
90 }
|
|
91
|
|
92 /* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 6 "bswap" } } */
|