1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 // This file should only be compiled if you're on x86 or x86_64. Additionally,
6 // you'll need to compile this file with -msse2 if you're using gcc.
15 Convert_ascii_run(const char *&src
,
20 __m128i in
, out1
, out2
;
21 __m128d
*outp1
, *outp2
;
25 // align input to 16 bytes
26 while ((NS_PTR_TO_UINT32(src
) & 15) && len
> 0) {
29 *dst
++ = (char16_t
) *src
++;
33 zeroes
= _mm_setzero_si128();
35 offset
= NS_PTR_TO_UINT32(dst
) & 15;
37 // Note: all these inner loops have to break, not return; we need
38 // to let the single-char loop below catch any leftover
39 // byte-at-a-time ASCII chars, since this function must consume
40 // all available ASCII chars before it returns
44 in
= _mm_load_si128((__m128i
*) src
);
45 if (_mm_movemask_epi8(in
))
47 out1
= _mm_unpacklo_epi8(in
, zeroes
);
48 out2
= _mm_unpackhi_epi8(in
, zeroes
);
49 _mm_stream_si128((__m128i
*) dst
, out1
);
50 _mm_stream_si128((__m128i
*) (dst
+ 8), out2
);
55 } else if (offset
== 8) {
56 outp1
= (__m128d
*) &out1
;
57 outp2
= (__m128d
*) &out2
;
59 in
= _mm_load_si128((__m128i
*) src
);
60 if (_mm_movemask_epi8(in
))
62 out1
= _mm_unpacklo_epi8(in
, zeroes
);
63 out2
= _mm_unpackhi_epi8(in
, zeroes
);
64 _mm_storel_epi64((__m128i
*) dst
, out1
);
65 _mm_storel_epi64((__m128i
*) (dst
+ 8), out2
);
66 _mm_storeh_pd((double *) (dst
+ 4), *outp1
);
67 _mm_storeh_pd((double *) (dst
+ 12), *outp2
);
74 in
= _mm_load_si128((__m128i
*) src
);
75 if (_mm_movemask_epi8(in
))
77 out1
= _mm_unpacklo_epi8(in
, zeroes
);
78 out2
= _mm_unpackhi_epi8(in
, zeroes
);
79 _mm_storeu_si128((__m128i
*) dst
, out1
);
80 _mm_storeu_si128((__m128i
*) (dst
+ 8), out2
);
88 // finish off a byte at a time
90 while (len
-- > 0 && (*src
& 0x80U
) == 0) {
91 *dst
++ = (char16_t
) *src
++;
96 } // namespace mozilla