1405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* 2405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Copyright (c) 2010 MIPS Technologies, Inc. 3405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 4405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * All rights reserved. 5405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 6405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Redistribution and use in source and binary forms, with or without 7405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * modification, are permitted provided that the following conditions 8405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * are met: 9405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 10405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Redistributions of source code must retain the above copyright 11405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * notice, this list of conditions and the following disclaimer. 12405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Redistributions in binary form must reproduce the above copyright 13405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * notice, this list of conditions and the following disclaimer 14405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * in the documentation and/or other materials provided with 15405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * the distribution. 16405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * * Neither the name of MIPS Technologies Inc. nor the names of its 17405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * contributors may be used to endorse or promote products derived 18405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * from this software without specific prior written permission. 19405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 20405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham */ 32405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 33405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#ifndef __MIPS_STRING_OPS_H 34405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define __MIPS_STRING_OPS_H 35405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* This definition of the byte bitfields uses the 36405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham assumption that the layout of the bitfields is 37405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham equivalent to the layout in memory. Generally, 38405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham for the MIPS ABIs, this is true. If you compile 39405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham the strcmp.c file with -DSMOKE_TEST_NEW_STRCMP, 40405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham this assumption will be tested. 41405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 42405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham Also, regardless of char signedness, ANSI C dictates that 43405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham strcmp() treats each character as unsigned char. For 44405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham strlen and the like, signedness doesn't matter. 45405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 46405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham Also, this code assumes that there are 8-bits per 'char'. */ 47405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 48405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#if __mips64 49405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamtypedef struct bits 50405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham{ 51405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham unsigned B0:8, B1:8, B2:8, B3:8, B4:8, B5:8, B6:8, B7:8; 52405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham} bits_t; 53405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#else 54405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamtypedef struct bits 55405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham{ 56405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham unsigned B0:8, B1:8, B2:8, B3:8; 57405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham} bits_t; 58405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 59405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 60405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#ifndef _ULW 61405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* for MIPS GCC, there is no unaligned builtins - so this code forces 62405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham the compiler to treat the pointer access as unaligned. */ 63405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamstruct ulw 64405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham{ 65405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham unsigned b; 66405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham} __attribute__ ((packed)); 67405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 68405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define _ULW(__x) ((struct ulw *) ((char *)(&__x)))->b; 69405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 70405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 71405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* This union assumes that small structures can be in registers. If 72405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham not, then memory accesses will be done - not optimal, but ok. */ 73405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamtypedef union 74405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham{ 75405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham unsigned v; 76405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham bits_t b; 77405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham} bitfields_t; 78405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 79405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#ifndef detect_zero 80405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* __mips_dsp, __mips_dspr2, and __mips64 are predefined by 81405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham the compiler, based on command line options. */ 82405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#if (__mips_dsp || __mips_dspr2) && !__mips64 83405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define __mips_using_dsp 1 84405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 85405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* DSP 4-lane (8 unsigned bits per line) subtract and saturate 86405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Intrinsic operation. How this works: 87405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * Given a 4-byte string of "ABC\0", subtract this as 88405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * an unsigned integer from 0x01010101: 89405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 0x01010101 90405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * - 0x41424300 91405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * ----------- 92405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham ( 0xbfbebe01 <-- answer without saturation 93405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * 0x00000001 <-- answer with saturation 94405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * When this 4-lane vector is treated as an unsigned int value, 95405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * a non-zero answer indicates the presence of a zero in the 96405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham * original 4-byte argument. */ 97405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 98405b8029a6888f386adf3512113a33546141d1c8Raghu Gandhamtypedef signed char v4i8 __attribute__ ((vector_size (4))); 99405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 100405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define detect_zero(__x,__y,__01s,__80s)\ 101405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham ((unsigned) __builtin_mips_subu_s_qb((v4i8) __01s,(v4i8) __x)) 102405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 103405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* sets all 4 lanes to requested byte. */ 104405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define set_byte_lanes(__x) ((unsigned) __builtin_mips_repl_qb(__x)) 105405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 106405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* sets all 4 lanes to 0x01. */ 107405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define def_and_set_01(__x) unsigned __x = (unsigned) __builtin_mips_repl_qb(0x01) 108405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 109405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* sets all 4 lanes to 0x80. Not needed when subu_s.qb used. */ 110405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define def_and_set_80(__x) /* do nothing */ 111405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 112405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#else 113405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham /* this version, originally published in the 80's, uses 114405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham a reverse-carry-set like determination of the zero byte. 115405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham The steps are, for __x = 0x31ff0001: 116405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham __x - _01s = 0x30fdff00 117405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham ~__x = 0xce00fffe 118405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham ((__x - _01s) & ~__x) = 0x0000ff00 119405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham x & _80s = 0x00008000 <- byte 3 was zero 120405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham Some implementaions naively assume that characters are 121405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham always 7-bit unsigned ASCII. With that assumption, the 122405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham "& ~x" is usually discarded. Since character strings 123405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham are 8-bit, the and is needed to catch the case of 124405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham a false positive when the byte is 0x80. */ 125405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 126405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define detect_zero(__x,__y,_01s,_80s)\ 127405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham ((unsigned) (((__x) - _01s) & ~(__x)) & _80s) 128405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 129405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#if __mips64 130405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define def_and_set_80(__x) unsigned __x = 0x8080808080808080ul 131405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define def_and_set_01(__x) unsigned __x = 0x0101010101010101ul 132405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#else 133405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define def_and_set_80(__x) unsigned __x = 0x80808080ul 134405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define def_and_set_01(__x) unsigned __x = 0x01010101ul 135405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 136405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 137405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 138405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 139405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 140405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham/* dealing with 'void *' conversions without using extra variables. */ 141405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define get_byte(__x,__idx) (((unsigned char *) (__x))[__idx]) 142405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define set_byte(__x,__idx,__fill) ((unsigned char *) (__x))[__idx] = (__fill) 143405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define get_word(__x,__idx) (((unsigned *) (__x))[__idx]) 144405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define set_word(__x,__idx,__fill) ((unsigned *) (__x))[__idx] = (__fill) 145405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define inc_ptr_as(__type,__x,__inc) __x = (void *) (((__type) __x) + (__inc)) 146405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#define cvt_ptr_to(__type,__x) ((__type) (__x)) 147405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham 148405b8029a6888f386adf3512113a33546141d1c8Raghu Gandham#endif 149