LCOV - code coverage report
Current view: top level - xpcom/string - nsReadableUtilsSSE2.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 23 27 85.2 %
Date: 2017-07-14 16:53:18 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include <emmintrin.h>
       8             : 
       9             : #include "nsReadableUtilsImpl.h"
      10             : 
      11             : namespace mozilla {
      12             : namespace SSE2 {
      13             : 
      14             : static inline bool
      15       28780 : is_zero (__m128i x)
      16             : {
      17             :   return
      18       86340 :     _mm_movemask_epi8(_mm_cmpeq_epi8(x, _mm_setzero_si128())) == 0xffff;
      19             : }
      20             : 
      21             : int32_t
      22        4047 : FirstNonASCII(const char16_t* aBegin, const char16_t* aEnd)
      23             : {
      24        4047 :   const size_t kNumUnicharsPerVector = sizeof(__m128i) / sizeof(char16_t);
      25             :   typedef NonASCIIParameters<sizeof(size_t)> p;
      26        4047 :   const size_t kMask = p::mask();
      27        4047 :   const uintptr_t kXmmAlignMask = 0xf;
      28        4047 :   const uint16_t kShortMask = 0xff80;
      29        4047 :   const size_t kNumUnicharsPerWord = p::numUnicharsPerWord();
      30             : 
      31        4047 :   const char16_t* idx = aBegin;
      32             : 
      33             :   // Align ourselves to a 16-byte boundary as required by _mm_load_si128
      34       26743 :   for (; idx != aEnd && ((uintptr_t(idx) & kXmmAlignMask) != 0); idx++) {
      35       11348 :     if (!IsASCII(*idx)) {
      36           0 :       return idx - aBegin;
      37             :     }
      38             :   }
      39             : 
      40             :   // Check one XMM register (16 bytes) at a time.
      41        4047 :   const char16_t* vectWalkEnd = aligned(aEnd, kXmmAlignMask);
      42        4047 :   __m128i vectmask = _mm_set1_epi16(static_cast<int16_t>(kShortMask));
      43       61607 :   for (; idx != vectWalkEnd; idx += kNumUnicharsPerVector) {
      44       28780 :     const __m128i vect = *reinterpret_cast<const __m128i*>(idx);
      45       28780 :     if (!is_zero(_mm_and_si128(vect, vectmask))) {
      46           0 :       return idx - aBegin;
      47             :     }
      48             :   }
      49             : 
      50             :   // Check one word at a time.
      51        4047 :   const char16_t* wordWalkEnd = aligned(aEnd, p::alignMask());
      52        8791 :   for(; idx != wordWalkEnd; idx += kNumUnicharsPerWord) {
      53        2372 :     const size_t word = *reinterpret_cast<const size_t*>(idx);
      54        2372 :     if (word & kMask) {
      55           0 :       return idx - aBegin;
      56             :     }
      57             :   }
      58             : 
      59             :   // Take care of the remainder one character at a time.
      60       15493 :   for (; idx != aEnd; idx++) {
      61        5723 :     if (!IsASCII(*idx)) {
      62           0 :       return idx - aBegin;
      63             :     }
      64             :   }
      65             : 
      66        4047 :   return -1;
      67             : }
      68             : 
      69             : } // namespace SSE2
      70             : } // namespace mozilla

Generated by: LCOV version 1.13