diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-03-19 07:52:35 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-03-19 15:09:13 +0200 |
commit | a66eebf57c212363f9f430a4c8c9a4f3ddf57cfb (patch) | |
tree | 0c7e48ae2bed8f3dbba1b43eee786f045f4ee2cd /include/byte_order_generic.h | |
parent | 6960e9ed24dbdab587730cdceab1f29bcdd6d52a (diff) | |
download | mariadb-git-a66eebf57c212363f9f430a4c8c9a4f3ddf57cfb.tar.gz |
MDEV-21981 Replace arithmetic + with bitwise OR when possible
Several macros such as sint2korr() and uint4korr() are using the
arithmetic + operator while a bitwise or operator would suffice.
GCC 5 and clang 5 and later can detect patterns consisting of
bitwise or and shifts by multiples of 8 bits, such as those used
in the InnoDB function mach_read_from_4(). They actually translate
that verbose low-level code into high-level machine language
(i486 bswap instruction or fused into the Haswell movbe instruction).
We should do the same for MariaDB Server code that is outside InnoDB.
Note: The Microsoft C compiler is lacking this optimization.
There, we might consider using _byteswap_ushort(), _byteswap_ulong(),
_byteswap_uint64(). But, those would lead to unaligned reads, which are
bad for reasons stated in MDEV-20277. Besides, outside InnoDB,
most data is already being stored in the native little-endian format
of that compiler.
Diffstat (limited to 'include/byte_order_generic.h')
-rw-r--r-- | include/byte_order_generic.h | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/include/byte_order_generic.h b/include/byte_order_generic.h index 451202be3b6..8381941b9b9 100644 --- a/include/byte_order_generic.h +++ b/include/byte_order_generic.h @@ -1,4 +1,5 @@ /* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +18,7 @@ Endianness-independent definitions for architectures other than the x86 architecture. */ -#define sint2korr(A) (int16) (((int16) ((uchar) (A)[0])) +\ +#define sint2korr(A) (int16) (((int16) ((uchar) (A)[0])) |\ ((int16) ((int16) (A)[1]) << 8)) #define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \ (((uint32) 255L << 24) | \ @@ -27,38 +28,38 @@ (((uint32) (uchar) (A)[2]) << 16) |\ (((uint32) (uchar) (A)[1]) << 8) | \ ((uint32) (uchar) (A)[0]))) -#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) +\ - (((int32) ((uchar) (A)[1]) << 8)) +\ - (((int32) ((uchar) (A)[2]) << 16)) +\ +#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) |\ + (((int32) ((uchar) (A)[1]) << 8)) |\ + (((int32) ((uchar) (A)[2]) << 16)) |\ (((int32) ((int16) (A)[3]) << 24))) #define sint8korr(A) (longlong) uint8korr(A) -#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) +\ +#define uint2korr(A) (uint16) (((uint16) ((uchar) (A)[0])) |\ ((uint16) ((uchar) (A)[1]) << 8)) -#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\ - (((uint32) ((uchar) (A)[1])) << 8) +\ +#define uint3korr(A) (uint32) (((uint32) ((uchar) (A)[0])) |\ + (((uint32) ((uchar) (A)[1])) << 8) |\ (((uint32) ((uchar) (A)[2])) << 16)) -#define uint4korr(A) (uint32) (((uint32) ((uchar) (A)[0])) +\ - (((uint32) ((uchar) (A)[1])) << 8) +\ - (((uint32) ((uchar) (A)[2])) << 16) +\ +#define uint4korr(A) (uint32) (((uint32) ((uchar) (A)[0])) |\ + (((uint32) ((uchar) (A)[1])) << 8) |\ + (((uint32) ((uchar) (A)[2])) << 16) |\ (((uint32) ((uchar) (A)[3])) << 24)) -#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ - (((uint32) ((uchar) (A)[1])) << 8) +\ - (((uint32) ((uchar) (A)[2])) << 16) +\ - (((uint32) ((uchar) (A)[3])) << 24)) +\ +#define uint5korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) |\ + (((uint32) ((uchar) (A)[1])) << 8) |\ + (((uint32) ((uchar) (A)[2])) << 16) |\ + (((uint32) ((uchar) (A)[3])) << 24)) |\ (((ulonglong) ((uchar) (A)[4])) << 32)) -#define uint6korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) + \ - (((uint32) ((uchar) (A)[1])) << 8) + \ - (((uint32) ((uchar) (A)[2])) << 16) + \ - (((uint32) ((uchar) (A)[3])) << 24)) + \ - (((ulonglong) ((uchar) (A)[4])) << 32) + \ +#define uint6korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) | \ + (((uint32) ((uchar) (A)[1])) << 8) | \ + (((uint32) ((uchar) (A)[2])) << 16) | \ + (((uint32) ((uchar) (A)[3])) << 24)) | \ + (((ulonglong) ((uchar) (A)[4])) << 32) | \ (((ulonglong) ((uchar) (A)[5])) << 40)) -#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\ - (((uint32) ((uchar) (A)[1])) << 8) +\ - (((uint32) ((uchar) (A)[2])) << 16) +\ - (((uint32) ((uchar) (A)[3])) << 24)) +\ - (((ulonglong) (((uint32) ((uchar) (A)[4])) +\ - (((uint32) ((uchar) (A)[5])) << 8) +\ - (((uint32) ((uchar) (A)[6])) << 16) +\ +#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) |\ + (((uint32) ((uchar) (A)[1])) << 8) |\ + (((uint32) ((uchar) (A)[2])) << 16) |\ + (((uint32) ((uchar) (A)[3])) << 24)) |\ + (((ulonglong) (((uint32) ((uchar) (A)[4])) |\ + (((uint32) ((uchar) (A)[5])) << 8) |\ + (((uint32) ((uchar) (A)[6])) << 16) |\ (((uint32) ((uchar) (A)[7])) << 24))) <<\ 32)) #define int2store(T,A) do { uint def_temp= (uint) (A) ;\ |