Files
Upsilon/liba/src/aeabi-rt/llsl.c
Émilie Feral 3f0328f5b5 Add assertions for dangerous bit shift that could trigger undefined
behaviour

Change-Id: I051ed229d407eafcae1ea4b5fc745176a751e036
2017-12-01 11:53:55 +01:00

22 lines
760 B
C

/* See the "Run-time ABI for the ARM Architecture", Section 4.2 */
#include <assert.h>
typedef unsigned int uint32_t;
long long __aeabi_llsl(long long value, int shift) {
uint32_t low = (uint32_t)value << shift;
/* "Shift behavior is undefined if the right operand is negative, or greater
* than or equal to the length in bits of the promoted left operand" according
* to C++ spec. However, arm compiler fill the vacated bits with 0 */
assert(shift < 32 || low == 0);
uint32_t high = ((uint32_t)(value >> 32) << shift);
// Same comment
assert(shift < 32 || high == 0);
if (shift < 32) {
high |= ((uint32_t)value >> (32 - shift));
} else {
high |= ((uint32_t)value << (shift - 32));
}
return ((long long)high << 32) | low;
}