Path: blob/master/thirdparty/pcre2/src/pcre2_jit_neon_inc.h
9898 views
/*************************************************1* Perl-Compatible Regular Expressions *2*************************************************/34/* PCRE is a library of functions to support regular expressions whose syntax5and semantics are as close as possible to those of the Perl 5 language.67Written by Philip Hazel8This module by Zoltan Herczeg and Sebastian Pop9Original API code Copyright (c) 1997-2012 University of Cambridge10New API code Copyright (c) 2016-2019 University of Cambridge1112-----------------------------------------------------------------------------13Redistribution and use in source and binary forms, with or without14modification, are permitted provided that the following conditions are met:1516* Redistributions of source code must retain the above copyright notice,17this list of conditions and the following disclaimer.1819* Redistributions in binary form must reproduce the above copyright20notice, this list of conditions and the following disclaimer in the21documentation and/or other materials provided with the distribution.2223* Neither the name of the University of Cambridge nor the names of its24contributors may be used to endorse or promote products derived from25this software without specific prior written permission.2627THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"28AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE29IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE30ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE31LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR32CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF33SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS34INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN35CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)36ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE37POSSIBILITY OF SUCH DAMAGE.38-----------------------------------------------------------------------------39*/4041# if defined(FFCS)42# if defined(FF_UTF)43# define FF_FUN ffcs_utf44# else45# define FF_FUN ffcs46# endif4748# elif defined(FFCS_2)49# if defined(FF_UTF)50# define FF_FUN ffcs_2_utf51# else52# define FF_FUN ffcs_253# endif5455# elif defined(FFCS_MASK)56# if defined(FF_UTF)57# define FF_FUN ffcs_mask_utf58# else59# define FF_FUN ffcs_mask60# endif6162# elif defined(FFCPS_0)63# if defined (FF_UTF)64# define FF_FUN ffcps_0_utf65# else66# define FF_FUN ffcps_067# endif6869# elif defined (FFCPS_1)70# if defined (FF_UTF)71# define FF_FUN ffcps_1_utf72# else73# define FF_FUN ffcps_174# endif7576# elif defined (FFCPS_DEFAULT)77# if defined (FF_UTF)78# define FF_FUN ffcps_default_utf79# else80# define FF_FUN ffcps_default81# endif82# endif8384#if (defined(__GNUC__) && defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__ ) \85|| (defined(__clang__) \86&& ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3)))87__attribute__((no_sanitize_address))88#endif89static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 **str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars)90#undef FF_FUN91{92quad_word qw;93int_char ic;9495SLJIT_UNUSED_ARG(offs1);96SLJIT_UNUSED_ARG(offs2);9798ic.x = chars;99100#if defined(FFCS)101sljit_u8 c1 = ic.c.c1;102vect_t vc1 = VDUPQ(c1);103104#elif defined(FFCS_2)105sljit_u8 c1 = ic.c.c1;106vect_t vc1 = VDUPQ(c1);107sljit_u8 c2 = ic.c.c2;108vect_t vc2 = VDUPQ(c2);109110#elif defined(FFCS_MASK)111sljit_u8 c1 = ic.c.c1;112vect_t vc1 = VDUPQ(c1);113sljit_u8 mask = ic.c.c2;114vect_t vmask = VDUPQ(mask);115#endif116117#if defined(FFCPS)118compare_type compare1_type = compare_match1;119compare_type compare2_type = compare_match1;120vect_t cmp1a, cmp1b, cmp2a, cmp2b;121const sljit_u32 diff = IN_UCHARS(offs1 - offs2);122PCRE2_UCHAR char1a = ic.c.c1;123PCRE2_UCHAR char2a = ic.c.c3;124125# ifdef FFCPS_CHAR1A2A126cmp1a = VDUPQ(char1a);127cmp2a = VDUPQ(char2a);128cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */129cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */130# else131PCRE2_UCHAR char1b = ic.c.c2;132PCRE2_UCHAR char2b = ic.c.c4;133if (char1a == char1b)134{135cmp1a = VDUPQ(char1a);136cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */137}138else139{140sljit_u32 bit1 = char1a ^ char1b;141if (is_powerof2(bit1))142{143compare1_type = compare_match1i;144cmp1a = VDUPQ(char1a | bit1);145cmp1b = VDUPQ(bit1);146}147else148{149compare1_type = compare_match2;150cmp1a = VDUPQ(char1a);151cmp1b = VDUPQ(char1b);152}153}154155if (char2a == char2b)156{157cmp2a = VDUPQ(char2a);158cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */159}160else161{162sljit_u32 bit2 = char2a ^ char2b;163if (is_powerof2(bit2))164{165compare2_type = compare_match1i;166cmp2a = VDUPQ(char2a | bit2);167cmp2b = VDUPQ(bit2);168}169else170{171compare2_type = compare_match2;172cmp2a = VDUPQ(char2a);173cmp2b = VDUPQ(char2b);174}175}176# endif177178*str_ptr += IN_UCHARS(offs1);179#endif180181#if PCRE2_CODE_UNIT_WIDTH != 8182vect_t char_mask = VDUPQ(0xff);183#endif184185#if defined(FF_UTF)186restart:;187#endif188189#if defined(FFCPS)190if (*str_ptr >= str_end)191return NULL;192sljit_u8 *p1 = *str_ptr - diff;193#endif194sljit_s32 align_offset = ((uint64_t)*str_ptr & 0xf);195*str_ptr = (sljit_u8 *) ((uint64_t)*str_ptr & ~0xf);196vect_t data = VLD1Q(*str_ptr);197#if PCRE2_CODE_UNIT_WIDTH != 8198data = VANDQ(data, char_mask);199#endif200201#if defined(FFCS)202vect_t eq = VCEQQ(data, vc1);203204#elif defined(FFCS_2)205vect_t eq1 = VCEQQ(data, vc1);206vect_t eq2 = VCEQQ(data, vc2);207vect_t eq = VORRQ(eq1, eq2);208209#elif defined(FFCS_MASK)210vect_t eq = VORRQ(data, vmask);211eq = VCEQQ(eq, vc1);212213#elif defined(FFCPS)214# if defined(FFCPS_DIFF1)215vect_t prev_data = data;216# endif217218vect_t data2;219if (p1 < *str_ptr)220{221data2 = VLD1Q(*str_ptr - diff);222#if PCRE2_CODE_UNIT_WIDTH != 8223data2 = VANDQ(data2, char_mask);224#endif225}226else227data2 = shift_left_n_lanes(data, offs1 - offs2);228229if (compare1_type == compare_match1)230data = VCEQQ(data, cmp1a);231else232data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);233234if (compare2_type == compare_match1)235data2 = VCEQQ(data2, cmp2a);236else237data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);238239vect_t eq = VANDQ(data, data2);240#endif241242VST1Q(qw.mem, eq);243/* Ignore matches before the first STR_PTR. */244if (align_offset < 8)245{246qw.dw[0] >>= align_offset * 8;247if (qw.dw[0])248{249*str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8;250goto match;251}252if (qw.dw[1])253{254*str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;255goto match;256}257}258else259{260qw.dw[1] >>= (align_offset - 8) * 8;261if (qw.dw[1])262{263*str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8;264goto match;265}266}267*str_ptr += 16;268269while (*str_ptr < str_end)270{271vect_t orig_data = VLD1Q(*str_ptr);272#if PCRE2_CODE_UNIT_WIDTH != 8273orig_data = VANDQ(orig_data, char_mask);274#endif275data = orig_data;276277#if defined(FFCS)278eq = VCEQQ(data, vc1);279280#elif defined(FFCS_2)281eq1 = VCEQQ(data, vc1);282eq2 = VCEQQ(data, vc2);283eq = VORRQ(eq1, eq2);284285#elif defined(FFCS_MASK)286eq = VORRQ(data, vmask);287eq = VCEQQ(eq, vc1);288#endif289290#if defined(FFCPS)291# if defined (FFCPS_DIFF1)292data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1);293# else294data2 = VLD1Q(*str_ptr - diff);295# if PCRE2_CODE_UNIT_WIDTH != 8296data2 = VANDQ(data2, char_mask);297# endif298# endif299300# ifdef FFCPS_CHAR1A2A301data = VCEQQ(data, cmp1a);302data2 = VCEQQ(data2, cmp2a);303# else304if (compare1_type == compare_match1)305data = VCEQQ(data, cmp1a);306else307data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);308if (compare2_type == compare_match1)309data2 = VCEQQ(data2, cmp2a);310else311data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);312# endif313314eq = VANDQ(data, data2);315#endif316317VST1Q(qw.mem, eq);318if (qw.dw[0])319*str_ptr += __builtin_ctzll(qw.dw[0]) / 8;320else if (qw.dw[1])321*str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;322else {323*str_ptr += 16;324#if defined (FFCPS_DIFF1)325prev_data = orig_data;326#endif327continue;328}329330match:;331if (*str_ptr >= str_end)332/* Failed match. */333return NULL;334335#if defined(FF_UTF)336if (utf_continue((PCRE2_SPTR)*str_ptr - offs1))337{338/* Not a match. */339*str_ptr += IN_UCHARS(1);340goto restart;341}342#endif343344/* Match. */345#if defined (FFCPS)346*str_ptr -= IN_UCHARS(offs1);347#endif348return *str_ptr;349}350351/* Failed match. */352return NULL;353}354355356