1 /*
2  * Copyright (c) 2010 MIPS Technologies, Inc.
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  *      * Redistributions of source code must retain the above copyright
11  *        notice, this list of conditions and the following disclaimer.
12  *      * Redistributions in binary form must reproduce the above copyright
13  *        notice, this list of conditions and the following disclaimer
14  *        in the documentation and/or other materials provided with
15  *        the distribution.
16  *      * Neither the name of MIPS Technologies Inc. nor the names of its
17  *        contributors may be used to endorse or promote products derived
18  *        from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef __MIPS_STRING_OPS_H
34 #define __MIPS_STRING_OPS_H
35     /* This definition of the byte bitfields uses the
36        assumption that the layout of the bitfields is
37        equivalent to the layout in memory.  Generally,
38        for the MIPS ABIs, this is true. If you compile
39        the strcmp.c file with -DSMOKE_TEST_NEW_STRCMP,
40        this assumption will be tested.
41 
42        Also, regardless of char signedness, ANSI C dictates that
43        strcmp() treats each character as unsigned char.  For
44        strlen and the like, signedness doesn't matter.
45 
46        Also, this code assumes that there are 8-bits per 'char'.  */
47 
48 #if __mips64
49 typedef struct bits
50 {
51   unsigned B0:8, B1:8, B2:8, B3:8, B4:8, B5:8, B6:8, B7:8;
52 } bits_t;
53 #else
54 typedef struct bits
55 {
56   unsigned B0:8, B1:8, B2:8, B3:8;
57 } bits_t;
58 #endif
59 
60 #ifndef _ULW
61     /* for MIPS GCC, there is no unaligned builtins - so this code forces
62        the compiler to treat the pointer access as unaligned.  */
63 struct ulw
64 {
65   unsigned b;
66 } __attribute__ ((packed));
67 
68 #define _ULW(__x) ((struct ulw *) ((char *)(&__x)))->b;
69 #endif
70 
71 /* This union assumes that small structures can be in registers.  If
72    not, then memory accesses will be done - not optimal, but ok.  */
73 typedef union
74 {
75   unsigned v;
76   bits_t b;
77 } bitfields_t;
78 
79 #ifndef detect_zero
80 /* __mips_dsp, __mips_dspr2, and __mips64 are predefined by
81    the compiler, based on command line options.  */
82 #if (__mips_dsp || __mips_dspr2) && !__mips64
83 #define __mips_using_dsp 1
84 
85 /* DSP 4-lane (8 unsigned bits per line) subtract and saturate
86  * Intrinsic operation. How this works:
87  *     Given a 4-byte string of "ABC\0", subtract this as
88  *     an unsigned integer from 0x01010101:
89  *	   0x01010101
90  *       - 0x41424300
91  *        -----------
92  (         0xbfbebe01 <-- answer without saturation
93  *	   0x00000001 <-- answer with saturation
94  * When this 4-lane vector is treated as an unsigned int value,
95  * a non-zero answer indicates the presence of a zero in the
96  * original 4-byte argument.  */
97 
98 typedef signed char v4i8 __attribute__ ((vector_size (4)));
99 
100 #define detect_zero(__x,__y,__01s,__80s)\
101        ((unsigned) __builtin_mips_subu_s_qb((v4i8) __01s,(v4i8) __x))
102 
103     /* sets all 4 lanes to requested byte.  */
104 #define set_byte_lanes(__x) ((unsigned) __builtin_mips_repl_qb(__x))
105 
106     /* sets all 4 lanes to 0x01.  */
107 #define def_and_set_01(__x) unsigned __x = (unsigned) __builtin_mips_repl_qb(0x01)
108 
109     /* sets all 4 lanes to 0x80. Not needed when subu_s.qb used. */
110 #define def_and_set_80(__x) /* do nothing */
111 
112 #else
113     /* this version, originally published in the 80's, uses
114        a reverse-carry-set like determination of the zero byte.
115        The steps are, for __x = 0x31ff0001:
116        __x - _01s = 0x30fdff00
117        ~__x = 0xce00fffe
118        ((__x - _01s) & ~__x) = 0x0000ff00
119        x & _80s = 0x00008000 <- byte 3 was zero
120        Some implementaions naively assume that characters are
121        always 7-bit unsigned ASCII. With that assumption, the
122        "& ~x" is usually discarded. Since character strings
123        are 8-bit, the and is needed to catch the case of
124        a false positive when the byte is 0x80. */
125 
126 #define detect_zero(__x,__y,_01s,_80s)\
127 	((unsigned) (((__x) - _01s) & ~(__x)) & _80s)
128 
129 #if __mips64
130 #define def_and_set_80(__x) unsigned __x =  0x8080808080808080ul
131 #define def_and_set_01(__x)  unsigned __x = 0x0101010101010101ul
132 #else
133 #define def_and_set_80(__x) unsigned __x = 0x80808080ul
134 #define def_and_set_01(__x) unsigned __x = 0x01010101ul
135 #endif
136 
137 #endif
138 #endif
139 
140 /* dealing with 'void *' conversions without using extra variables. */
141 #define get_byte(__x,__idx) (((unsigned char *) (__x))[__idx])
142 #define set_byte(__x,__idx,__fill) ((unsigned char *) (__x))[__idx] = (__fill)
143 #define get_word(__x,__idx) (((unsigned *) (__x))[__idx])
144 #define set_word(__x,__idx,__fill) ((unsigned *) (__x))[__idx] = (__fill)
145 #define inc_ptr_as(__type,__x,__inc) __x = (void *) (((__type) __x) + (__inc))
146 #define cvt_ptr_to(__type,__x) ((__type) (__x))
147 
148 #endif
149