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