[liba] Correct __aeabi_llsr, __aeabi_llsl with tests

Change-Id: I710adab0ecd232f2e5bab08adbf10ef686c651c5
This commit is contained in:
Émilie Feral
2017-05-23 10:39:11 +02:00
parent 9dda07da0e
commit 3d1fc8e5d1
4 changed files with 58 additions and 5 deletions

View File

@@ -67,6 +67,7 @@ liba/src/external/openbsd/s_roundf.o: CFLAGS += -Os
endif
tests += $(addprefix liba/test/, \
aeabi.c \
ieee754.c \
stdint.c \
strlcpy.c \

View File

@@ -1,9 +1,14 @@
/* See the "Run-time ABI for the ARM Architecture", Section 4.2 */
typedef int uint32_t;
typedef unsigned int uint32_t;
long long __aeabi_llsl(long long value, int shift) {
uint32_t low = (uint32_t)value << shift;
uint32_t high = ((uint32_t)(value >> 32) << shift) | ((uint32_t)value >> (32 - shift));
uint32_t high = ((uint32_t)(value >> 32) << shift);
if (shift < 32) {
high |= ((uint32_t)value >> (32 - shift));
} else {
high |= ((uint32_t)value << (shift - 32));
}
return ((long long)high << 32) | low;
}

View File

@@ -1,9 +1,14 @@
/* See the "Run-time ABI for the ARM Architecture", Section 4.2 */
typedef int uint32_t;
typedef unsigned int uint32_t;
long long __aeabi_llsr(long long value, int shift) {
uint32_t low = ((uint32_t)value >> shift) | ((uint32_t)(value >> 32) << (32 - shift));
uint32_t high = (uint32_t)value >> shift;
uint32_t low = ((uint32_t)value >> shift);
if (shift < 32) {
low |= ((uint32_t)(value >> 32) << (32 - shift));
} else {
low |= ((uint32_t)(value >> 32) >> (shift - 32));
}
uint32_t high = (uint32_t)(value >> 32) >> shift;
return ((long long)high << 32) | low;
}

42
liba/test/aeabi.c Normal file
View File

@@ -0,0 +1,42 @@
#include <quiz.h>
#include <stdint.h>
#include <assert.h>
long long __aeabi_llsl(long long value, int shift);
long long __aeabi_llsr(long long value, int shift);
QUIZ_CASE(liba_llsl) {
assert(__aeabi_llsl((uint64_t)1, 1) == (uint64_t)0x2);
assert(__aeabi_llsl((uint64_t)1, 2) == (uint64_t)0x4);
assert(__aeabi_llsl((uint64_t)1, 10) == (uint64_t)0x400);
assert(__aeabi_llsl((uint64_t)1, 20) == (uint64_t)0x100000);
assert(__aeabi_llsl((uint64_t)1, 30) == (uint64_t)0x40000000);
assert(__aeabi_llsl((uint64_t)1, 31) == (uint64_t)0x80000000);
assert(__aeabi_llsl((uint64_t)1, 32) == (uint64_t)0x100000000);
assert(__aeabi_llsl((uint64_t)1, 33) == (uint64_t)0x200000000);
assert(__aeabi_llsl((uint64_t)1, 40) == (uint64_t)0x10000000000);
assert(__aeabi_llsl((uint64_t)1, 50) == (uint64_t)0x4000000000000);
assert(__aeabi_llsl((uint64_t)1, 60) == (uint64_t)0x1000000000000000);
assert(__aeabi_llsl((uint64_t)1, 61) == (uint64_t)0x2000000000000000);
assert(__aeabi_llsl((uint64_t)1, 62) == (uint64_t)0x4000000000000000);
assert(__aeabi_llsl((uint64_t)1, 63) == (uint64_t)0x8000000000000000);
assert(__aeabi_llsl((uint64_t)1, 64) == (uint64_t)0);
}
QUIZ_CASE(liba_llsr) {
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 1) == (uint64_t)0x4000000000000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 2) == (uint64_t)0x2000000000000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 10) == (uint64_t)0x20000000000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 20) == (uint64_t)0x80000000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 30) == (uint64_t)0x200000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 31) == (uint64_t)0x100000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 32) == (uint64_t)0x80000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 33) == (uint64_t)0x40000000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 40) == (uint64_t)0x800000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 50) == (uint64_t)0x2000);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 60) == (uint64_t)0x8);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 61) == (uint64_t)0x4);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 62) == (uint64_t)0x2);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 63) == (uint64_t)0x1);
assert(__aeabi_llsr((uint64_t)0x8000000000000000, 64) == (uint64_t)0);
}