1 /* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
2    Copyright (c) 2020, MariaDB Corporation.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
16 
17 /*
18   Optimized function-like macros for the x86 architecture (_WIN32 included).
19 */
20 
21 #define sint2korr(A)	(int16) (*((int16 *) (A)))
22 #define sint3korr(A)	((int32) ((((uchar) (A)[2]) & 128) ? \
23 				  (((uint32) 255L << 24) | \
24 				   (((uint32) (uchar) (A)[2]) << 16) |\
25 				   (((uint32) (uchar) (A)[1]) << 8) | \
26 				   ((uint32) (uchar) (A)[0])) : \
27 				  (((uint32) (uchar) (A)[2]) << 16) |\
28 				  (((uint32) (uchar) (A)[1]) << 8) | \
29 				  ((uint32) (uchar) (A)[0])))
30 #define sint4korr(A)	(int32)  (*((int32 *) (A)))
31 #define uint2korr(A)	(uint16) (*((uint16 *) (A)))
32 #define uint3korr(A)	(uint32) (((uint32) ((uchar) (A)[0])) |\
33 				  (((uint32) ((uchar) (A)[1])) << 8) |\
34 				  (((uint32) ((uchar) (A)[2])) << 16))
35 #define uint4korr(A)	(uint32) (*((uint32 *) (A)))
36 
37 
38 static inline ulonglong uint5korr(const void *p)
39 {
40   ulonglong a= *(uint32 *) p;
41   ulonglong b= *(4 + (uchar *) p);
42   return a | (b << 32);
43 }
44 static inline ulonglong uint6korr(const void *p)
45 {
46   ulonglong a= *(uint32 *) p;
47   ulonglong b= *(uint16 *) (4 + (char *) p);
48   return a | (b << 32);
49 }
50 
51 #define uint8korr(A)	(ulonglong) (*((ulonglong *) (A)))
52 #define sint8korr(A)	(longlong) (*((longlong *) (A)))
53 
54 #define int2store(T,A)	do { uchar *pT= (uchar*)(T);\
55                              *((uint16*)(pT))= (uint16) (A);\
56                         } while (0)
57 
58 #define int3store(T,A)  do { *(T)=  (uchar) ((A));\
59                             *(T+1)=(uchar) (((uint) (A) >> 8));\
60                             *(T+2)=(uchar) (((A) >> 16));\
61                         } while (0)
62 
63 #define int4store(T,A)	do { uchar *pT= (uchar*)(T);\
64                              *((uint32 *) (pT))= (uint32) (A); \
65                         } while (0)
66 
67 #define int5store(T,A)  do { uchar *pT= (uchar*)(T);\
68                              *((uint32 *) (pT))= (uint32) (A); \
69                              *((pT)+4)=(uchar) (((A) >> 32));\
70                         } while (0)
71 
72 #define int6store(T,A)  do { uchar *pT= (uchar*)(T);\
73                              *((uint32 *) (pT))= (uint32) (A); \
74                              *((uint16*)(pT+4))= (uint16) (A >> 32);\
75                         } while (0)
76 
77 #define int8store(T,A)	do { uchar *pT= (uchar*)(T);\
78                              *((ulonglong *) (pT))= (ulonglong) (A);\
79                         } while(0)
80 
81 #if defined(__GNUC__)
82 
83 #define HAVE_mi_uint5korr
84 #define HAVE_mi_uint6korr
85 #define HAVE_mi_uint7korr
86 #define HAVE_mi_uint78orr
87 
88 /* Read numbers stored in high-bytes-first order */
89 
90 static inline ulonglong mi_uint5korr(const void *p)
91 {
92   ulonglong a= *(uint32 *) p;
93   ulonglong b= *(4 + (uchar *) p);
94   ulonglong v= (a | (b << 32)) << 24;
95   asm ("bswapq %0" : "=r" (v) : "0" (v));
96   return v;
97 }
98 
99 static inline ulonglong mi_uint6korr(const void *p)
100 {
101   ulonglong a= *(uint32 *) p;
102   ulonglong b= *(uint16 *) (4 + (char *) p);
103   ulonglong v= (a | (b << 32)) << 16;
104   asm ("bswapq %0" : "=r" (v) : "0" (v));
105   return v;
106 }
107 
108 static inline ulonglong mi_uint7korr(const void *p)
109 {
110   ulonglong a= *(uint32 *) p;
111   ulonglong b= *(uint16 *) (4 + (char *) p);
112   ulonglong c= *(6 + (uchar *) p);
113   ulonglong v= (a | (b << 32) | (c << 48)) << 8;
114   asm ("bswapq %0" : "=r" (v) : "0" (v));
115   return v;
116 }
117 
118 static inline ulonglong mi_uint8korr(const void *p)
119 {
120   ulonglong v= *(ulonglong *) p;
121   asm ("bswapq %0" : "=r" (v) : "0" (v));
122   return v;
123 }
124 
125 #endif
126