baremetal: add baremetal platform
This commit is contained in:
@ -150,7 +150,7 @@ endif ()
|
||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
|
||||
set (THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
# find_package(Threads REQUIRED)
|
||||
|
||||
add_library (vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
set_target_properties (vmlib PROPERTIES OUTPUT_NAME iwasm)
|
||||
|
||||
206
core/shared/platform/baremetal/platform_init.c
Normal file
206
core/shared/platform/baremetal/platform_init.c
Normal file
@ -0,0 +1,206 @@
|
||||
#include "platform_api_vmcore.h"
|
||||
|
||||
// int
|
||||
// os_rwlock_init(korp_rwlock *rwlock)
|
||||
// {
|
||||
// if (!rwlock)
|
||||
// return -1;
|
||||
// rwlock->readers = 0;
|
||||
// rwlock->writer = false;
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// int
|
||||
// os_rwlock_destroy(korp_rwlock *rwlock)
|
||||
// {
|
||||
// if (!rwlock)
|
||||
// return -1;
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// int
|
||||
// os_rwlock_rdlock(korp_rwlock *rwlock)
|
||||
// {
|
||||
// if (!rwlock)
|
||||
// return -1;
|
||||
//
|
||||
// // Wait until no writer
|
||||
// while (__atomic_load_n(&rwlock->writer, __ATOMIC_ACQUIRE))
|
||||
// ;
|
||||
//
|
||||
// // Increment readers count
|
||||
// __atomic_fetch_add(&rwlock->readers, 1, __ATOMIC_ACQUIRE);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// int
|
||||
// os_rwlock_wrlock(korp_rwlock *rwlock)
|
||||
// {
|
||||
// if (!rwlock)
|
||||
// return -1;
|
||||
//
|
||||
// // Wait until no readers and no writer
|
||||
// while (__atomic_load_n(&rwlock->readers, __ATOMIC_ACQUIRE) > 0
|
||||
// || __atomic_test_and_set(&rwlock->writer, __ATOMIC_ACQUIRE))
|
||||
// ;
|
||||
//
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// int
|
||||
// os_rwlock_unlock(korp_rwlock *rwlock)
|
||||
// {
|
||||
// if (!rwlock)
|
||||
// return -1;
|
||||
//
|
||||
// if (__atomic_load_n(&rwlock->writer, __ATOMIC_ACQUIRE)) {
|
||||
// // Writer releasing
|
||||
// __atomic_clear(&rwlock->writer, __ATOMIC_RELEASE);
|
||||
// }
|
||||
// else {
|
||||
// // Reader releasing
|
||||
// __atomic_fetch_sub(&rwlock->readers, 1, __ATOMIC_RELEASE);
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
/****************************************************
|
||||
* Section 1 *
|
||||
* Interfaces required by the runtime *
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
* Initialize the platform internal resources if needed,
|
||||
* this function is called by wasm_runtime_init() and
|
||||
* wasm_runtime_full_init()
|
||||
*
|
||||
* @return 0 if success
|
||||
*/
|
||||
|
||||
int
|
||||
bh_platform_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bh_platform_destroy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
******** memory allocator APIs **********
|
||||
*/
|
||||
|
||||
void *
|
||||
os_malloc(unsigned size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
os_realloc(void *ptr, unsigned size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
os_free(void *ptr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: the above APIs can simply return NULL if wasm runtime
|
||||
* isn't initialized with Alloc_With_System_Allocator.
|
||||
* Refer to wasm_runtime_full_init().
|
||||
*/
|
||||
|
||||
int
|
||||
os_printf(const char *format, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
os_vprintf(const char *format, va_list ap)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get microseconds after boot.
|
||||
*/
|
||||
uint64
|
||||
os_time_get_boot_us(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get thread-specific CPU-time clock in microseconds
|
||||
*/
|
||||
uint64
|
||||
os_time_thread_cputime_us(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current thread id.
|
||||
* Implementation optional: Used by runtime for logging only.
|
||||
*/
|
||||
korp_tid
|
||||
os_self_thread(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current thread's stack boundary address, used for runtime
|
||||
* to check the native stack overflow. Return NULL if it is not
|
||||
* easy to implement, but may have potential issue.
|
||||
*/
|
||||
uint8 *
|
||||
os_thread_get_stack_boundary(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the MAP_JIT region write protection is enabled for this thread.
|
||||
* Pass true to make the region executable, false to make it writable.
|
||||
*/
|
||||
void
|
||||
os_thread_jit_write_protect_np(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
************** mutext APIs ***********
|
||||
* vmcore: Not required until pthread is supported by runtime
|
||||
* app-mgr: Must be implemented
|
||||
*/
|
||||
|
||||
int
|
||||
os_mutex_init(korp_mutex *mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_destroy(korp_mutex *mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_lock(korp_mutex *mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
517
core/shared/platform/baremetal/platform_internal.h
Normal file
517
core/shared/platform/baremetal/platform_internal.h
Normal file
@ -0,0 +1,517 @@
|
||||
#ifndef _PLATFORM_INTERNAL_H
|
||||
#define _PLATFORM_INTERNAL_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
// #include <assert.h>
|
||||
// #include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <pthread.h>
|
||||
// #include <signal.h>
|
||||
#include <semaphore.h>
|
||||
// #include <limits.h>
|
||||
#include <dirent.h>
|
||||
// #include <fcntl.h>
|
||||
// #include <unistd.h>
|
||||
// #include <poll.h>
|
||||
// #include <sched.h>
|
||||
// #include <errno.h>
|
||||
// #include <sys/types.h>
|
||||
// #include <sys/stat.h>
|
||||
// #include <sys/mman.h>
|
||||
// #include <sys/time.h>
|
||||
// #include <sys/timeb.h>
|
||||
// #include <sys/uio.h>
|
||||
// #include <sys/ioctl.h>
|
||||
// #include <sys/socket.h>
|
||||
// #include <sys/resource.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef BH_PLATFORM_BAREMETAL
|
||||
#define BH_PLATFORM_BAREMETAL
|
||||
#endif
|
||||
|
||||
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024)
|
||||
#define BH_THREAD_DEFAULT_PRIORITY 0
|
||||
|
||||
typedef pthread_t korp_tid;
|
||||
typedef pthread_mutex_t korp_mutex;
|
||||
typedef pthread_cond_t korp_cond;
|
||||
typedef pthread_t korp_thread;
|
||||
// typedef pthread_rwlock_t korp_rwlock;
|
||||
typedef sem_t korp_sem;
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t readers;
|
||||
volatile bool writer;
|
||||
} korp_rwlock;
|
||||
|
||||
// int
|
||||
// os_rwlock_init(korp_rwlock *rwlock);
|
||||
// int
|
||||
// os_rwlock_destroy(korp_rwlock *rwlock);
|
||||
// int
|
||||
// os_rwlock_rdlock(korp_rwlock *rwlock);
|
||||
// int
|
||||
// os_rwlock_wrlock(korp_rwlock *rwlock);
|
||||
// int
|
||||
// os_rwlock_unlock(korp_rwlock *rwlock);
|
||||
|
||||
typedef int os_file_handle;
|
||||
typedef DIR *os_dir_stream;
|
||||
typedef int os_raw_file_handle;
|
||||
|
||||
static inline os_file_handle
|
||||
os_get_invalid_handle(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
os_getpagesize()
|
||||
{
|
||||
// TODO: What pagesize?
|
||||
return 4096;
|
||||
}
|
||||
|
||||
// Memory
|
||||
|
||||
// https://git.musl-libc.org/cgit/musl/tree/src/string/memcpy.c
|
||||
|
||||
__attribute__((weak)) void *
|
||||
memcpy(void *restrict dest, const void *restrict src, size_t n)
|
||||
{
|
||||
unsigned char *d = dest;
|
||||
const unsigned char *s = src;
|
||||
|
||||
for (; n; n--)
|
||||
*d++ = *s++;
|
||||
return dest;
|
||||
}
|
||||
|
||||
// https://git.musl-libc.org/cgit/musl/tree/src/string/memmove.c
|
||||
|
||||
__attribute__((weak)) void *
|
||||
memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
|
||||
if (d == s)
|
||||
return d;
|
||||
if ((uintptr_t)s - (uintptr_t)d - n <= -2 * n)
|
||||
return memcpy(d, s, n);
|
||||
|
||||
if (d < s) {
|
||||
for (; n; n--)
|
||||
*d++ = *s++;
|
||||
}
|
||||
else {
|
||||
while (n)
|
||||
n--, d[n] = s[n];
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
// https://git.musl-libc.org/cgit/musl/tree/src/string/memset.c
|
||||
|
||||
__attribute__((weak)) void *
|
||||
memset(void *dest, int c, size_t n)
|
||||
{
|
||||
unsigned char *s = dest;
|
||||
size_t k;
|
||||
|
||||
/* Fill head and tail with minimal branching. Each
|
||||
* conditional ensures that all the subsequently used
|
||||
* offsets are well-defined and in the dest region. */
|
||||
|
||||
if (!n)
|
||||
return dest;
|
||||
s[0] = c;
|
||||
s[n - 1] = c;
|
||||
if (n <= 2)
|
||||
return dest;
|
||||
s[1] = c;
|
||||
s[2] = c;
|
||||
s[n - 2] = c;
|
||||
s[n - 3] = c;
|
||||
if (n <= 6)
|
||||
return dest;
|
||||
s[3] = c;
|
||||
s[n - 4] = c;
|
||||
if (n <= 8)
|
||||
return dest;
|
||||
|
||||
/* Advance pointer to align it at a 4-byte boundary,
|
||||
* and truncate n to a multiple of 4. The previous code
|
||||
* already took care of any head/tail that get cut off
|
||||
* by the alignment. */
|
||||
|
||||
k = -(uintptr_t)s & 3;
|
||||
s += k;
|
||||
n -= k;
|
||||
n &= -4;
|
||||
|
||||
for (; n; n--, s++)
|
||||
*s = c;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
// Strings
|
||||
|
||||
// https://github.com/zerovm/glibc/blob/master/string/strcmp.c
|
||||
|
||||
__attribute__((weak)) int
|
||||
strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 && (*s1 == *s2)) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
|
||||
}
|
||||
|
||||
// Math
|
||||
|
||||
// https://github.com/glitchub/arith64/blob/master/arith64.c
|
||||
|
||||
#define arith64_u64 unsigned long long int
|
||||
#define arith64_s64 signed long long int
|
||||
#define arith64_u32 unsigned int
|
||||
#define arith64_s32 int
|
||||
|
||||
typedef union {
|
||||
arith64_u64 u64;
|
||||
arith64_s64 s64;
|
||||
struct {
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
arith64_u32 hi;
|
||||
arith64_u32 lo;
|
||||
#else
|
||||
arith64_u32 lo;
|
||||
arith64_u32 hi;
|
||||
#endif
|
||||
} u32;
|
||||
struct {
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
arith64_s32 hi;
|
||||
arith64_s32 lo;
|
||||
#else
|
||||
arith64_s32 lo;
|
||||
arith64_s32 hi;
|
||||
#endif
|
||||
} s32;
|
||||
} arith64_word;
|
||||
|
||||
// extract hi and lo 32-bit words from 64-bit value
|
||||
#define arith64_hi(n) (arith64_word){ .u64 = n }.u32.hi
|
||||
#define arith64_lo(n) (arith64_word){ .u64 = n }.u32.lo
|
||||
|
||||
// Negate a if b is negative, via invert and increment.
|
||||
#define arith64_neg(a, b) \
|
||||
(((a) ^ ((((arith64_s64)(b)) >= 0) - 1)) + (((arith64_s64)(b)) < 0))
|
||||
#define arith64_abs(a) arith64_neg(a, a)
|
||||
|
||||
// Return the absolute value of a.
|
||||
// Note LLINT_MIN cannot be negated.
|
||||
__attribute__((weak)) arith64_s64
|
||||
__absvdi2(arith64_s64 a)
|
||||
{
|
||||
return arith64_abs(a);
|
||||
}
|
||||
|
||||
// Return the result of shifting a left by b bits.
|
||||
__attribute__((weak)) arith64_s64
|
||||
__ashldi3(arith64_s64 a, int b)
|
||||
{
|
||||
arith64_word w = { .s64 = a };
|
||||
|
||||
b &= 63;
|
||||
|
||||
if (b >= 32) {
|
||||
w.u32.hi = w.u32.lo << (b - 32);
|
||||
w.u32.lo = 0;
|
||||
}
|
||||
else if (b) {
|
||||
w.u32.hi = (w.u32.lo >> (32 - b)) | (w.u32.hi << b);
|
||||
w.u32.lo <<= b;
|
||||
}
|
||||
return w.s64;
|
||||
}
|
||||
|
||||
// Return the result of arithmetically shifting a right by b bits.
|
||||
__attribute__((weak)) arith64_s64
|
||||
__ashrdi3(arith64_s64 a, int b)
|
||||
{
|
||||
arith64_word w = { .s64 = a };
|
||||
|
||||
b &= 63;
|
||||
|
||||
if (b >= 32) {
|
||||
w.s32.lo = w.s32.hi >> (b - 32);
|
||||
w.s32.hi >>= 31; // 0xFFFFFFFF or 0
|
||||
}
|
||||
else if (b) {
|
||||
w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b);
|
||||
w.s32.hi >>= b;
|
||||
}
|
||||
return w.s64;
|
||||
}
|
||||
|
||||
// These functions return the number of leading 0-bits in a, starting at the
|
||||
// most significant bit position. If a is zero, the result is undefined.
|
||||
__attribute__((weak)) int
|
||||
__clzsi2(arith64_u32 a)
|
||||
{
|
||||
int b, n = 0;
|
||||
b = !(a & 0xffff0000) << 4;
|
||||
n += b;
|
||||
a <<= b;
|
||||
b = !(a & 0xff000000) << 3;
|
||||
n += b;
|
||||
a <<= b;
|
||||
b = !(a & 0xf0000000) << 2;
|
||||
n += b;
|
||||
a <<= b;
|
||||
b = !(a & 0xc0000000) << 1;
|
||||
n += b;
|
||||
a <<= b;
|
||||
return n + !(a & 0x80000000);
|
||||
}
|
||||
|
||||
__attribute__((weak)) int
|
||||
__clzdi2(arith64_u64 a)
|
||||
{
|
||||
int b, n = 0;
|
||||
b = !(a & 0xffffffff00000000ULL) << 5;
|
||||
n += b;
|
||||
a <<= b;
|
||||
b = !(a & 0xffff000000000000ULL) << 4;
|
||||
n += b;
|
||||
a <<= b;
|
||||
b = !(a & 0xff00000000000000ULL) << 3;
|
||||
n += b;
|
||||
a <<= b;
|
||||
b = !(a & 0xf000000000000000ULL) << 2;
|
||||
n += b;
|
||||
a <<= b;
|
||||
b = !(a & 0xc000000000000000ULL) << 1;
|
||||
n += b;
|
||||
a <<= b;
|
||||
return n + !(a & 0x8000000000000000ULL);
|
||||
}
|
||||
|
||||
// These functions return the number of trailing 0-bits in a, starting at the
|
||||
// least significant bit position. If a is zero, the result is undefined.
|
||||
__attribute__((weak)) int
|
||||
__ctzsi2(arith64_u32 a)
|
||||
{
|
||||
int b, n = 0;
|
||||
b = !(a & 0x0000ffff) << 4;
|
||||
n += b;
|
||||
a >>= b;
|
||||
b = !(a & 0x000000ff) << 3;
|
||||
n += b;
|
||||
a >>= b;
|
||||
b = !(a & 0x0000000f) << 2;
|
||||
n += b;
|
||||
a >>= b;
|
||||
b = !(a & 0x00000003) << 1;
|
||||
n += b;
|
||||
a >>= b;
|
||||
return n + !(a & 0x00000001);
|
||||
}
|
||||
|
||||
__attribute__((weak)) int
|
||||
__ctzdi2(arith64_u64 a)
|
||||
{
|
||||
int b, n = 0;
|
||||
b = !(a & 0x00000000ffffffffULL) << 5;
|
||||
n += b;
|
||||
a >>= b;
|
||||
b = !(a & 0x000000000000ffffULL) << 4;
|
||||
n += b;
|
||||
a >>= b;
|
||||
b = !(a & 0x00000000000000ffULL) << 3;
|
||||
n += b;
|
||||
a >>= b;
|
||||
b = !(a & 0x000000000000000fULL) << 2;
|
||||
n += b;
|
||||
a >>= b;
|
||||
b = !(a & 0x0000000000000003ULL) << 1;
|
||||
n += b;
|
||||
a >>= b;
|
||||
return n + !(a & 0x0000000000000001ULL);
|
||||
}
|
||||
|
||||
// Calculate both the quotient and remainder of the unsigned division of a by
|
||||
// b. The return value is the quotient, and the remainder is placed in variable
|
||||
// pointed to by c (if it's not NULL).
|
||||
__attribute__((weak)) arith64_u64
|
||||
__divmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c)
|
||||
{
|
||||
if (b > a) // divisor > numerator?
|
||||
{
|
||||
if (c)
|
||||
*c = a; // remainder = numerator
|
||||
return 0; // quotient = 0
|
||||
}
|
||||
if (!arith64_hi(b)) // divisor is 32-bit
|
||||
{
|
||||
if (b == 0) // divide by 0
|
||||
{
|
||||
volatile char x = 0;
|
||||
x = 1 / x; // force an exception
|
||||
}
|
||||
if (b == 1) // divide by 1
|
||||
{
|
||||
if (c)
|
||||
*c = 0; // remainder = 0
|
||||
return a; // quotient = numerator
|
||||
}
|
||||
if (!arith64_hi(a)) // numerator is also 32-bit
|
||||
{
|
||||
if (c) // use generic 32-bit operators
|
||||
*c = arith64_lo(a) % arith64_lo(b);
|
||||
return arith64_lo(a) / arith64_lo(b);
|
||||
}
|
||||
}
|
||||
|
||||
// let's do long division
|
||||
char bits = __clzdi2(b) - __clzdi2(a)
|
||||
+ 1; // number of bits to iterate (a and b are non-zero)
|
||||
arith64_u64 rem = a >> bits; // init remainder
|
||||
a <<= 64 - bits; // shift numerator to the high bit
|
||||
arith64_u64 wrap = 0; // start with wrap = 0
|
||||
while (bits-- > 0) // for each bit
|
||||
{
|
||||
rem = (rem << 1) | (a >> 63); // shift numerator MSB to remainder LSB
|
||||
a = (a << 1) | (wrap & 1); // shift out the numerator, shift in wrap
|
||||
wrap = ((arith64_s64)(b - rem - 1)
|
||||
>> 63); // wrap = (b > rem) ? 0 : 0xffffffffffffffff (via sign
|
||||
// extension)
|
||||
rem -= b & wrap; // if (wrap) rem -= b
|
||||
}
|
||||
if (c)
|
||||
*c = rem; // maybe set remainder
|
||||
return (a << 1) | (wrap & 1); // return the quotient
|
||||
}
|
||||
|
||||
// Return the quotient of the signed division of a by b.
|
||||
__attribute__((weak)) arith64_s64
|
||||
__divdi3(arith64_s64 a, arith64_s64 b)
|
||||
{
|
||||
arith64_u64 q = __divmoddi4(arith64_abs(a), arith64_abs(b), (void *)0);
|
||||
return arith64_neg(q, a ^ b); // negate q if a and b signs are different
|
||||
}
|
||||
|
||||
// Return the index of the least significant 1-bit in a, or the value zero if a
|
||||
// is zero. The least significant bit is index one.
|
||||
__attribute__((weak)) int
|
||||
__ffsdi2(arith64_u64 a)
|
||||
{
|
||||
return a ? __ctzdi2(a) + 1 : 0;
|
||||
}
|
||||
|
||||
// Return the result of logically shifting a right by b bits.
|
||||
__attribute__((weak)) arith64_u64
|
||||
__lshrdi3(arith64_u64 a, int b)
|
||||
{
|
||||
arith64_word w = { .u64 = a };
|
||||
|
||||
b &= 63;
|
||||
|
||||
if (b >= 32) {
|
||||
w.u32.lo = w.u32.hi >> (b - 32);
|
||||
w.u32.hi = 0;
|
||||
}
|
||||
else if (b) {
|
||||
w.u32.lo = (w.u32.hi << (32 - b)) | (w.u32.lo >> b);
|
||||
w.u32.hi >>= b;
|
||||
}
|
||||
return w.u64;
|
||||
}
|
||||
|
||||
// Return the remainder of the signed division of a by b.
|
||||
__attribute__((weak)) arith64_s64
|
||||
__moddi3(arith64_s64 a, arith64_s64 b)
|
||||
{
|
||||
arith64_u64 r;
|
||||
__divmoddi4(arith64_abs(a), arith64_abs(b), &r);
|
||||
return arith64_neg(r, a); // negate remainder if numerator is negative
|
||||
}
|
||||
|
||||
// Return the number of bits set in a.
|
||||
__attribute__((weak)) int
|
||||
__popcountsi2(arith64_u32 a)
|
||||
{
|
||||
// collect sums into two low bytes
|
||||
a = a - ((a >> 1) & 0x55555555);
|
||||
a = ((a >> 2) & 0x33333333) + (a & 0x33333333);
|
||||
a = (a + (a >> 4)) & 0x0F0F0F0F;
|
||||
a = (a + (a >> 16));
|
||||
// add the bytes, return bottom 6 bits
|
||||
return (a + (a >> 8)) & 63;
|
||||
}
|
||||
|
||||
// Return the number of bits set in a.
|
||||
__attribute__((weak)) int
|
||||
__popcountdi2(arith64_u64 a)
|
||||
{
|
||||
// collect sums into two low bytes
|
||||
a = a - ((a >> 1) & 0x5555555555555555ULL);
|
||||
a = ((a >> 2) & 0x3333333333333333ULL) + (a & 0x3333333333333333ULL);
|
||||
a = (a + (a >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
|
||||
a = (a + (a >> 32));
|
||||
a = (a + (a >> 16));
|
||||
// add the bytes, return bottom 7 bits
|
||||
return (a + (a >> 8)) & 127;
|
||||
}
|
||||
|
||||
// Return the quotient of the unsigned division of a by b.
|
||||
__attribute__((weak)) arith64_u64
|
||||
__udivdi3(arith64_u64 a, arith64_u64 b)
|
||||
{
|
||||
return __divmoddi4(a, b, (void *)0);
|
||||
}
|
||||
|
||||
// Return the remainder of the unsigned division of a by b.
|
||||
__attribute__((weak)) arith64_u64
|
||||
__umoddi3(arith64_u64 a, arith64_u64 b)
|
||||
{
|
||||
arith64_u64 r;
|
||||
__divmoddi4(a, b, &r);
|
||||
return r;
|
||||
}
|
||||
|
||||
__attribute__((weak)) arith64_u64
|
||||
__udivmoddi4(arith64_u64 a, arith64_u64 b, arith64_u64 *c)
|
||||
{
|
||||
// https://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html#index-_005f_005fudivmoddi4
|
||||
*c = __umoddi3(a, b);
|
||||
return __udivdi3(a, b);
|
||||
}
|
||||
|
||||
// Stack protection (?)
|
||||
|
||||
uint32_t
|
||||
__stack_chk_fail_local()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _PLATFORM_INTERNAL_H */
|
||||
12
core/shared/platform/baremetal/shared_platform.cmake
Normal file
12
core/shared/platform/baremetal/shared_platform.cmake
Normal file
@ -0,0 +1,12 @@
|
||||
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions(-DBH_PLATFORM_BAREMETAL)
|
||||
|
||||
include_directories(${PLATFORM_SHARED_DIR})
|
||||
include_directories(${PLATFORM_SHARED_DIR}/../include)
|
||||
|
||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||
|
||||
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/baremetal/*.h)
|
||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||
Reference in New Issue
Block a user