mirror of
https://github.com/nodemcu/nodemcu-firmware.git
synced 2025-01-16 20:52:57 +08:00
526d21dab4
The PR removed the bulk of non-newlib headers from the NodeMCU source base. app/libc has now been cut down to the bare minimum overrides to shadow the corresponding functions in the SDK's libc. The old c_xyz.h headerfiles have been nuked in favour of the standard <xyz.h> headers, with a few exceptions over in sdk-overrides. Again, shipping a libc.a without headers is a terrible thing to do. We're still living on a prayer that libc was configured the same was as a default-configured xtensa gcc toolchain assumes it is. That part I cannot do anything about, unfortunately, but it's no worse than it has been before. This enables our source files to compile successfully using the standard header files, and use the typical malloc()/calloc()/realloc()/free(), the strwhatever()s and memwhatever()s. These end up, through macro and linker magic, mapped to the appropriate SDK or ROM functions.
139 lines
4.2 KiB
C
139 lines
4.2 KiB
C
/* Bitwise operations library */
|
|
/* (c) Reuben Thomas 2000-2008 */
|
|
/* See README for license */
|
|
|
|
// Modified by BogdanM for eLua
|
|
|
|
|
|
#include "module.h"
|
|
#include <limits.h>
|
|
|
|
#include "lauxlib.h"
|
|
|
|
/* FIXME: Assume size_t is an unsigned lua_Integer */
|
|
typedef size_t lua_UInteger;
|
|
#define LUA_UINTEGER_MAX SIZE_MAX
|
|
|
|
/* Define TOBIT to get a bit value */
|
|
#define TOBIT(L, n) \
|
|
(luaL_checkinteger((L), (n)))
|
|
|
|
/* Operations
|
|
|
|
The macros MONADIC and VARIADIC only deal with bitwise operations.
|
|
|
|
LOGICAL_SHIFT truncates its left-hand operand before shifting so
|
|
that any extra bits at the most-significant end are not shifted
|
|
into the result.
|
|
|
|
ARITHMETIC_SHIFT does not truncate its left-hand operand, so that
|
|
the sign bits are not removed and right shift work properly.
|
|
*/
|
|
|
|
#define MONADIC(name, op) \
|
|
static int bit_ ## name(lua_State *L) { \
|
|
lua_pushinteger(L, op TOBIT(L, 1)); \
|
|
return 1; \
|
|
}
|
|
|
|
#define VARIADIC(name, op) \
|
|
static int bit_ ## name(lua_State *L) { \
|
|
int n = lua_gettop(L), i; \
|
|
lua_Integer w = TOBIT(L, 1); \
|
|
for (i = 2; i <= n; i++) \
|
|
w op TOBIT(L, i); \
|
|
lua_pushinteger(L, w); \
|
|
return 1; \
|
|
}
|
|
|
|
#define LOGICAL_SHIFT(name, op) \
|
|
static int bit_ ## name(lua_State *L) { \
|
|
lua_pushinteger(L, (lua_UInteger)TOBIT(L, 1) op \
|
|
(unsigned)luaL_checknumber(L, 2)); \
|
|
return 1; \
|
|
}
|
|
|
|
#define ARITHMETIC_SHIFT(name, op) \
|
|
static int bit_ ## name(lua_State *L) { \
|
|
lua_pushinteger(L, (lua_Integer)TOBIT(L, 1) op \
|
|
(unsigned)luaL_checknumber(L, 2)); \
|
|
return 1; \
|
|
}
|
|
|
|
MONADIC(bnot, ~)
|
|
VARIADIC(band, &=)
|
|
VARIADIC(bor, |=)
|
|
VARIADIC(bxor, ^=)
|
|
ARITHMETIC_SHIFT(lshift, <<)
|
|
LOGICAL_SHIFT(rshift, >>)
|
|
ARITHMETIC_SHIFT(arshift, >>)
|
|
|
|
// Lua: res = bit( position )
|
|
static int bit_bit( lua_State* L )
|
|
{
|
|
lua_pushinteger( L, ( lua_Integer )( 1 << luaL_checkinteger( L, 1 ) ) );
|
|
return 1;
|
|
}
|
|
|
|
// Lua: res = isset( value, position )
|
|
static int bit_isset( lua_State* L )
|
|
{
|
|
lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
|
|
unsigned pos = ( unsigned )luaL_checkinteger( L, 2 );
|
|
|
|
lua_pushboolean( L, val & ( 1 << pos ) ? 1 : 0 );
|
|
return 1;
|
|
}
|
|
|
|
// Lua: res = isclear( value, position )
|
|
static int bit_isclear( lua_State* L )
|
|
{
|
|
lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
|
|
unsigned pos = ( unsigned )luaL_checkinteger( L, 2 );
|
|
|
|
lua_pushboolean( L, val & ( 1 << pos ) ? 0 : 1 );
|
|
return 1;
|
|
}
|
|
|
|
// Lua: res = set( value, pos1, pos2, ... )
|
|
static int bit_set( lua_State* L )
|
|
{
|
|
lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
|
|
unsigned total = lua_gettop( L ), i;
|
|
|
|
for( i = 2; i <= total; i ++ )
|
|
val |= 1 << ( unsigned )luaL_checkinteger( L, i );
|
|
lua_pushinteger( L, ( lua_Integer )val );
|
|
return 1;
|
|
}
|
|
|
|
// Lua: res = clear( value, pos1, pos2, ... )
|
|
static int bit_clear( lua_State* L )
|
|
{
|
|
lua_UInteger val = ( lua_UInteger )luaL_checkinteger( L, 1 );
|
|
unsigned total = lua_gettop( L ), i;
|
|
|
|
for( i = 2; i <= total; i ++ )
|
|
val &= ~( 1 << ( unsigned )luaL_checkinteger( L, i ) );
|
|
lua_pushinteger( L, ( lua_Integer )val );
|
|
return 1;
|
|
}
|
|
|
|
LROT_BEGIN(bit)
|
|
LROT_FUNCENTRY( bnot, bit_bnot )
|
|
LROT_FUNCENTRY( band, bit_band )
|
|
LROT_FUNCENTRY( bor, bit_bor )
|
|
LROT_FUNCENTRY( bxor, bit_bxor )
|
|
LROT_FUNCENTRY( lshift, bit_lshift )
|
|
LROT_FUNCENTRY( rshift, bit_rshift )
|
|
LROT_FUNCENTRY( arshift, bit_arshift )
|
|
LROT_FUNCENTRY( bit, bit_bit )
|
|
LROT_FUNCENTRY( set, bit_set )
|
|
LROT_FUNCENTRY( clear, bit_clear )
|
|
LROT_FUNCENTRY( isset, bit_isset )
|
|
LROT_FUNCENTRY( isclear, bit_isclear )
|
|
LROT_END( bit, NULL, 0 )
|
|
|
|
|
|
NODEMCU_MODULE(BIT, "bit", bit, NULL);
|