sync with texlive
[luatex.git] / source / libs / luajit / lbitlib.c
blob5187bbff0dc4815d13d38ecb29bd52807e8f953b
1 /*
2 ** $Id: lbitlib.c,v 1.16 2011/06/20 16:35:23 roberto Exp $
3 ** Standard library for bitwise operations
4 ** See Copyright Notice in lua.h
5 */
7 #define lbitlib_c
8 #define LUA_LIB
10 #include "lua.h"
12 #include "lauxlib.h"
13 #include "lualib.h"
15 #include "lj_obj.h"
16 #include "lj_state.h"
18 /* http://lua-users.org/lists/lua-l/2011-01/msg01039.html */
19 typedef unsigned int lua_Unsigned;
20 #define LUA_UNSIGNED unsigned LUA_INT32
23 #if !defined(lua_unsigned2number)
24 /* on several machines, coercion from unsigned to double is slow,
25 so it may be worth to avoid */
26 #define lua_unsigned2number(u) \
27 (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)( unsigned int )(u))
28 #endif
30 #if !defined(lua_lock)
31 #define lua_lock(L) ((void) 0)
32 #define lua_unlock(L) ((void) 0)
33 #endif
36 LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
37 lua_Number n=0;
38 lua_lock(L);
39 /* printf("u=%d,%u,%x\n",u,u,u);
40 printf("INT_MAX=%d %u %x, (lua_Unsigned)INT_MAX=%d %u %x (unsigned int)INT_MAX=%d %u %x\n",
41 INT_MAX,INT_MAX,INT_MAX,
42 (lua_Unsigned)INT_MAX,(lua_Unsigned)INT_MAX,(lua_Unsigned)INT_MAX,
43 (unsigned int)INT_MAX,(unsigned int)INT_MAX,(unsigned int)INT_MAX);
44 printf("((u) <= (lua_Unsigned)INT_MAX) :%d\n",(((unsigned int)u) <= (lua_Unsigned)INT_MAX));
45 printf("(lua_Number)(int)(u) =%d,%u,%x\n",(lua_Number)(int)(u),(lua_Number)(int)(u),(lua_Number)(int)(u));
46 printf("(lua_Number)(u) =%f,%u,%x\n",(lua_Number)(u),(lua_Number)(u),(lua_Number)(u));
47 printf("u=%d,%u,%x\n",u,u,u);
49 /*printf("n=%d,%u,%x u=%d,%u,%x\n",n,n,n,u,u,u); */
50 n = lua_unsigned2number(u);
51 /* printf("n=%f \n",n);
52 printf("u=%d %u %x n=%d %u %x\n",u,u,u,n,n,n);
53 printf("n=%d %u %x\n",n,n,n);
54 printf("u=%d,%u,%x\n",u,u,u);
56 /* setintptrV(L->top, n);
57 incr_top(L);
58 setnumV(L->top, n);
60 setnumV(L->top, n);
61 if (LJ_UNLIKELY(tvisnan(L->top)))
62 setnanV(L->top); /* Canonicalize injected NaNs. */
63 incr_top(L);
64 /*setnvalue(L->top, n);
65 api_incr_top(L);
67 lua_unlock(L);
75 #define luaL_checkunsigned (lua_Unsigned) luaL_checkinteger
76 /*#define lua_pushunsigned lua_pushinteger*/
80 /* number of bits to consider in a number */
81 #if !defined(LUA_NBITS)
82 #define LUA_NBITS 32
83 #endif
86 #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
88 /* macro to trim extra bits */
89 #define trim(x) ((x) & ALLONES)
92 /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
93 #define mask(n) (~((ALLONES << 1) << ((n) - 1)))
96 typedef lua_Unsigned b_uint;
100 static b_uint andaux (lua_State *L) {
101 int i, n = lua_gettop(L);
102 b_uint r = ~(b_uint)0;
103 /* printf("1 r=%d,%u,%x\n",r,r,r);*/
104 for (i = 1; i <= n; i++)
105 r &= luaL_checkunsigned(L, i);
106 /* printf("2 r=%d,%u,%x\n",r,r,r);
107 printf("3 r=%d,%u,%x\n",trim(r),trim(r),trim(r));
109 return trim(r);
113 static int b_and (lua_State *L) {
114 b_uint r = andaux(L);
115 /* printf("4 r=%d,%u,%x\n",r,r,r);*/
116 lua_pushunsigned(L, r);
117 return 1;
121 static int b_test (lua_State *L) {
122 b_uint r = andaux(L);
123 lua_pushboolean(L, r != 0);
124 return 1;
128 static int b_or (lua_State *L) {
129 int i, n = lua_gettop(L);
130 b_uint r = 0;
131 for (i = 1; i <= n; i++)
132 r |= luaL_checkunsigned(L, i);
133 lua_pushunsigned(L, trim(r));
134 return 1;
138 static int b_xor (lua_State *L) {
139 int i, n = lua_gettop(L);
140 b_uint r = 0;
141 for (i = 1; i <= n; i++)
142 r ^= luaL_checkunsigned(L, i);
143 lua_pushunsigned(L, trim(r));
144 return 1;
148 static int b_not (lua_State *L) {
149 b_uint r = ~luaL_checkunsigned(L, 1);
150 lua_pushunsigned(L, trim(r));
151 return 1;
155 static int b_shift (lua_State *L, b_uint r, int i) {
156 if (i < 0) { /* shift right? */
157 i = -i;
158 r = trim(r);
159 if (i >= LUA_NBITS) r = 0;
160 else r >>= i;
162 else { /* shift left */
163 if (i >= LUA_NBITS) r = 0;
164 else r <<= i;
165 r = trim(r);
167 lua_pushunsigned(L, r);
168 return 1;
172 static int b_lshift (lua_State *L) {
173 return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
177 static int b_rshift (lua_State *L) {
178 return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
182 static int b_arshift (lua_State *L) {
183 b_uint r = luaL_checkunsigned(L, 1);
184 int i = luaL_checkint(L, 2);
185 if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
186 return b_shift(L, r, -i);
187 else { /* arithmetic shift for 'negative' number */
188 if (i >= LUA_NBITS) r = ALLONES;
189 else
190 r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
191 lua_pushunsigned(L, r);
192 return 1;
197 static int b_rot (lua_State *L, int i) {
198 b_uint r = luaL_checkunsigned(L, 1);
199 i &= (LUA_NBITS - 1); /* i = i % NBITS */
200 r = trim(r);
201 r = (r << i) | (r >> (LUA_NBITS - i));
202 lua_pushunsigned(L, trim(r));
203 return 1;
207 static int b_lrot (lua_State *L) {
208 return b_rot(L, luaL_checkint(L, 2));
212 static int b_rrot (lua_State *L) {
213 return b_rot(L, -luaL_checkint(L, 2));
218 ** get field and width arguments for field-manipulation functions,
219 ** checking whether they are valid
221 static int fieldargs (lua_State *L, int farg, int *width) {
222 int f = luaL_checkint(L, farg);
223 int w = luaL_optint(L, farg + 1, 1);
224 luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
225 luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
226 if (f + w > LUA_NBITS)
227 luaL_error(L, "trying to access non-existent bits");
228 *width = w;
229 return f;
233 static int b_extract (lua_State *L) {
234 int w;
235 b_uint r = luaL_checkunsigned(L, 1);
236 int f = fieldargs(L, 2, &w);
237 r = (r >> f) & mask(w);
238 lua_pushunsigned(L, r);
239 return 1;
243 static int b_replace (lua_State *L) {
244 int w;
245 b_uint r = luaL_checkunsigned(L, 1);
246 b_uint v = luaL_checkunsigned(L, 2);
247 int f = fieldargs(L, 3, &w);
248 int m = mask(w);
249 v &= m; /* erase bits outside given width */
250 r = (r & ~(m << f)) | (v << f);
251 lua_pushunsigned(L, r);
252 return 1;
256 static const luaL_Reg bitlib[] = {
257 {"arshift", b_arshift},
258 {"band", b_and},
259 {"bnot", b_not},
260 {"bor", b_or},
261 {"bxor", b_xor},
262 {"btest", b_test},
263 {"extract", b_extract},
264 {"lrotate", b_lrot},
265 {"lshift", b_lshift},
266 {"replace", b_replace},
267 {"rrotate", b_rrot},
268 {"rshift", b_rshift},
269 {NULL, NULL}
274 /* http://lua-users.org/lists/lua-l/2011-01/msg01039.html */
276 /*LUAMOD_API int luaopen_bit32 (lua_State *L) {*/
277 /* luaL_newlib(L, bitlib);*/
278 /* return 1;*/
279 /*} */
281 int luaopen_bit32 (lua_State *L) {
282 luaL_register(L, "bit32", bitlib);
283 return 1;