1 #include "lua/internal.hpp"
2 #include "library/minmax.hpp"
3 #include "library/int24.hpp"
4 #include "library/serialization.hpp"
6 #define BITWISE_BITS 48
7 #define BITWISE_MASK ((1ULL << (BITWISE_BITS)) - 1)
11 uint64_t combine_none(uint64_t chain
, uint64_t arg
)
13 return (chain
& ~arg
) & BITWISE_MASK
;
16 uint64_t combine_any(uint64_t chain
, uint64_t arg
)
18 return (chain
| arg
) & BITWISE_MASK
;
21 uint64_t combine_all(uint64_t chain
, uint64_t arg
)
23 return (chain
& arg
) & BITWISE_MASK
;
26 uint64_t combine_parity(uint64_t chain
, uint64_t arg
)
28 return (chain
^ arg
) & BITWISE_MASK
;
31 uint64_t shift_lrotate(uint64_t base
, uint64_t amount
, uint64_t bits
)
33 uint64_t mask
= ((1ULL << bits
) - 1);
35 base
= (base
<< amount
) | (base
>> (bits
- amount
));
36 return base
& mask
& BITWISE_MASK
;
39 uint64_t shift_rrotate(uint64_t base
, uint64_t amount
, uint64_t bits
)
41 uint64_t mask
= ((1ULL << bits
) - 1);
43 base
= (base
>> amount
) | (base
<< (bits
- amount
));
44 return base
& mask
& BITWISE_MASK
;
47 uint64_t shift_lshift(uint64_t base
, uint64_t amount
, uint64_t bits
)
49 uint64_t mask
= ((1ULL << bits
) - 1);
51 return base
& mask
& BITWISE_MASK
;
54 uint64_t shift_lrshift(uint64_t base
, uint64_t amount
, uint64_t bits
)
56 uint64_t mask
= ((1ULL << bits
) - 1);
59 return base
& BITWISE_MASK
;
62 uint64_t shift_arshift(uint64_t base
, uint64_t amount
, uint64_t bits
)
64 uint64_t mask
= ((1ULL << bits
) - 1);
66 bool negative
= ((base
>> (bits
- 1)) != 0);
68 base
|= ((negative
? BITWISE_MASK
: 0) << (bits
- amount
));
69 return base
& mask
& BITWISE_MASK
;
72 template<uint64_t (*combine
)(uint64_t chain
, uint64_t arg
), uint64_t init
>
73 int fold(lua::state
& L
, lua::parameters
& P
)
77 ret
= combine(ret
, P
.arg
<uint64_t>());
82 template<uint64_t (*sh
)(uint64_t base
, uint64_t amount
, uint64_t bits
)>
83 int shift(lua::state
& L
, lua::parameters
& P
)
85 auto base
= P
.arg
<uint64_t>();
86 auto amount
= P
.arg_opt
<uint64_t>(1);
87 auto bits
= P
.arg_opt
<uint64_t>(BITWISE_BITS
);
88 L
.pushnumber(sh(base
, amount
, bits
));
93 int bswap(lua::state
& L
, lua::parameters
& P
)
96 serialization::swap_endian(val
);
101 lua::fnptr2
lua_bextract(lua_func_bit
, "bit.extract", [](lua::state
& L
, lua::parameters
& P
)
103 uint64_t num
= P
.arg
<uint64_t>();
105 for(size_t i
= 0;; i
++) {
109 } else if(P
.is_number()) {
110 ret
|= (((num
>> P
.arg
<uint8_t>()) & 1) << i
);
118 lua::fnptr2
lua_bvalue(lua_func_bit
, "bit.value", [](lua::state
& L
, lua::parameters
& P
) -> int {
120 for(size_t i
= 0;; i
++) {
122 ret
|= (1ULL << P
.arg
<uint8_t>());
123 } else if(P
.is_nil()) {
131 lua::fnptr2
lua_testany(lua_func_bit
, "bit.test_any", [](lua::state
& L
, lua::parameters
& P
) -> int {
132 auto a
= P
.arg
<uint64_t>();
133 auto b
= P
.arg
<uint64_t>();
134 L
.pushboolean((a
& b
) != 0);
138 lua::fnptr2
lua_testall(lua_func_bit
, "bit.test_all", [](lua::state
& L
, lua::parameters
& P
) -> int {
139 auto a
= P
.arg
<uint64_t>();
140 auto b
= P
.arg
<uint64_t>();
141 L
.pushboolean((a
& b
) == b
);
145 int poptable
[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
147 int popcount(uint64_t x
)
150 for(unsigned i
= 0; i
< 16; i
++) {
151 c
+= poptable
[x
& 15];
157 lua::fnptr2
lua_popcount(lua_func_bit
, "bit.popcount", [](lua::state
& L
, lua::parameters
& P
) -> int {
158 auto a
= P
.arg
<uint64_t>();
159 L
.pushnumber(popcount(a
));
163 lua::fnptr2
lua_clshift(lua_func_bit
, "bit.clshift", [](lua::state
& L
, lua::parameters
& P
) -> int {
164 auto a
= P
.arg
<uint64_t>();
165 auto b
= P
.arg
<uint64_t>();
166 auto amount
= P
.arg_opt
<unsigned>(1);
167 auto bits
= P
.arg_opt
<unsigned>(BITWISE_BITS
);
168 uint64_t mask
= ((1ULL << bits
) - 1);
173 a
|= (b
>> (bits
- amount
));
181 lua::fnptr2
lua_crshift(lua_func_bit
, "bit.crshift", [](lua::state
& L
, lua::parameters
& P
) -> int {
182 auto a
= P
.arg
<uint64_t>();
183 auto b
= P
.arg
<uint64_t>();
184 auto amount
= P
.arg_opt
<unsigned>(1);
185 auto bits
= P
.arg_opt
<unsigned>(BITWISE_BITS
);
186 uint64_t mask
= ((1ULL << bits
) - 1);
190 b
|= (a
<< (bits
- amount
));
198 template<bool reverse
>
199 int flagdecode_core(lua::state
& L
, lua::parameters
& P
)
201 auto a
= P
.arg
<uint64_t>();
202 auto b
= P
.arg
<uint64_t>();
203 auto on
= P
.arg_opt
<std::string
>("");
204 auto off
= P
.arg_opt
<std::string
>("");
205 size_t onl
= on
.length();
206 size_t offl
= off
.length();
207 char onc
= onl
? on
[onl
- 1] : '*';
208 char offc
= offl
? off
[offl
- 1] : '-';
211 size_t bias
= min(b
, (uint64_t)64) - 1;
212 for(i
= 0; i
< 64 && i
< b
; i
++) {
213 char onc2
= (i
< onl
) ? on
[i
] : onc
;
214 char offc2
= (i
< offl
) ? off
[i
] : offc
;
215 buffer
[reverse
? (bias
- i
) : i
] = ((a
>> i
) & 1) ? onc2
: offc2
;
218 L
.pushstring(buffer
);
222 lua::fnptr2
lua_flagdecode(lua_func_bit
, "bit.flagdecode", flagdecode_core
<false>);
223 lua::fnptr2
lua_rflagdecode(lua_func_bit
, "bit.rflagdecode", flagdecode_core
<true>);
224 lua::fnptr2
bit_none(lua_func_bit
, "bit.none", fold
<combine_none
, BITWISE_MASK
>);
225 lua::fnptr2
bit_any(lua_func_bit
, "bit.any", fold
<combine_any
, 0>);
226 lua::fnptr2
bit_all(lua_func_bit
, "bit.all", fold
<combine_all
, BITWISE_MASK
>);
227 lua::fnptr2
bit_parity(lua_func_bit
, "bit.parity", fold
<combine_parity
, 0>);
228 lua::fnptr2
bit_lrotate(lua_func_bit
, "bit.lrotate", shift
<shift_lrotate
>);
229 lua::fnptr2
bit_rrotate(lua_func_bit
, "bit.rrotate", shift
<shift_rrotate
>);
230 lua::fnptr2
bit_lshift(lua_func_bit
, "bit.lshift", shift
<shift_lshift
>);
231 lua::fnptr2
bit_arshift(lua_func_bit
, "bit.arshift", shift
<shift_arshift
>);
232 lua::fnptr2
bit_lrshift(lua_func_bit
, "bit.lrshift", shift
<shift_lrshift
>);
233 lua::fnptr2
bit_swapword(lua_func_bit
, "bit.swapword", bswap
<uint16_t>);
234 lua::fnptr2
bit_swaphword(lua_func_bit
, "bit.swaphword", bswap
<ss_uint24_t
>);
235 lua::fnptr2
bit_swapdword(lua_func_bit
, "bit.swapdword", bswap
<uint32_t>);
236 lua::fnptr2
bit_swapqword(lua_func_bit
, "bit.swapqword", bswap
<uint64_t>);
237 lua::fnptr2
bit_swapsword(lua_func_bit
, "bit.swapsword", bswap
<int16_t>);
238 lua::fnptr2
bit_swapshword(lua_func_bit
, "bit.swapshword", bswap
<ss_int24_t
>);
239 lua::fnptr2
bit_swapsdword(lua_func_bit
, "bit.swapsdword", bswap
<int32_t>);
240 lua::fnptr2
bit_swapsqword(lua_func_bit
, "bit.swapsqword", bswap
<int64_t>);