Add start paused option
[lsnes.git] / src / lua / bit.cpp
blobcd33448f2241df4b79e90d76f2980e79e0d495d5
1 #include "lua/internal.hpp"
3 #define BITWISE_BITS 48
4 #define BITWISE_MASK ((1ULL << (BITWISE_BITS)) - 1)
6 namespace
8 uint64_t combine_none(uint64_t chain, uint64_t arg)
10 return (chain & ~arg) & BITWISE_MASK;
13 uint64_t combine_any(uint64_t chain, uint64_t arg)
15 return (chain | arg) & BITWISE_MASK;
18 uint64_t combine_all(uint64_t chain, uint64_t arg)
20 return (chain & arg) & BITWISE_MASK;
23 uint64_t combine_parity(uint64_t chain, uint64_t arg)
25 return (chain ^ arg) & BITWISE_MASK;
28 uint64_t shift_lrotate(uint64_t base, uint64_t amount, uint64_t bits)
30 uint64_t mask = ((1ULL << bits) - 1);
31 base &= mask;
32 base = (base << amount) | (base >> (bits - amount));
33 return base & mask & BITWISE_MASK;
36 uint64_t shift_rrotate(uint64_t base, uint64_t amount, uint64_t bits)
38 uint64_t mask = ((1ULL << bits) - 1);
39 base &= mask;
40 base = (base >> amount) | (base << (bits - amount));
41 return base & mask & BITWISE_MASK;
44 uint64_t shift_lshift(uint64_t base, uint64_t amount, uint64_t bits)
46 uint64_t mask = ((1ULL << bits) - 1);
47 base <<= amount;
48 return base & mask & BITWISE_MASK;
51 uint64_t shift_lrshift(uint64_t base, uint64_t amount, uint64_t bits)
53 uint64_t mask = ((1ULL << bits) - 1);
54 base &= mask;
55 base >>= amount;
56 return base & BITWISE_MASK;
59 uint64_t shift_arshift(uint64_t base, uint64_t amount, uint64_t bits)
61 uint64_t mask = ((1ULL << bits) - 1);
62 base &= mask;
63 bool negative = ((base >> (bits - 1)) != 0);
64 base >>= amount;
65 base |= ((negative ? BITWISE_MASK : 0) << (bits - amount));
66 return base & mask & BITWISE_MASK;
69 template<uint64_t (*combine)(uint64_t chain, uint64_t arg), uint64_t init>
70 class lua_symmetric_bitwise : public lua_function
72 public:
73 lua_symmetric_bitwise(const std::string& s) : lua_function(s) {};
74 int invoke(lua_State* L)
76 int stacksize = 0;
77 while(!lua_isnone(L, stacksize + 1))
78 stacksize++;
79 uint64_t ret = init;
80 for(int i = 0; i < stacksize; i++)
81 ret = combine(ret, get_numeric_argument<uint64_t>(L, i + 1, fname.c_str()));
82 lua_pushnumber(L, ret);
83 return 1;
87 template<uint64_t (*shift)(uint64_t base, uint64_t amount, uint64_t bits)>
88 class lua_shifter : public lua_function
90 public:
91 lua_shifter(const std::string& s) : lua_function(s) {};
92 int invoke(lua_State* L)
94 uint64_t base;
95 uint64_t amount = 1;
96 uint64_t bits = BITWISE_BITS;
97 base = get_numeric_argument<uint64_t>(L, 1, fname.c_str());
98 get_numeric_argument(L, 2, amount, fname.c_str());
99 get_numeric_argument(L, 3, bits, fname.c_str());
100 lua_pushnumber(L, shift(base, amount, bits));
101 return 1;
105 function_ptr_luafun lua_bextract("bit.extract", [](lua_State* LS, const std::string& fname) -> int {
106 uint64_t num = get_numeric_argument<uint64_t>(LS, 1, fname.c_str());
107 uint64_t ret = 0;
108 for(size_t i = 0;; i++) {
109 if(lua_isnumber(LS, i + 2)) {
110 uint8_t bit = get_numeric_argument<uint8_t>(LS, i + 2, fname.c_str());
111 ret |= (((num >> bit) & 1) << i);
112 } else if(lua_isboolean(LS, i + 2)) {
113 if(lua_toboolean(LS, i + 2))
114 ret |= (1ULL << i);
115 } else
116 break;
118 lua_pushnumber(LS, ret);
119 return 1;
122 function_ptr_luafun lua_bvalue("bit.value", [](lua_State* LS, const std::string& fname) -> int {
123 uint64_t ret = 0;
124 for(size_t i = 0;; i++) {
125 if(lua_isnumber(LS, i + 1)) {
126 uint8_t bit = get_numeric_argument<uint8_t>(LS, i + 1, fname.c_str());
127 ret |= (1ULL << bit);
128 } else if(lua_isnil(LS, i + 1)) {
129 } else
130 break;
132 lua_pushnumber(LS, ret);
133 return 1;
136 lua_symmetric_bitwise<combine_none, BITWISE_MASK> bit_none("bit.none");
137 lua_symmetric_bitwise<combine_none, BITWISE_MASK> bit_bnot("bit.bnot");
138 lua_symmetric_bitwise<combine_any, 0> bit_any("bit.any");
139 lua_symmetric_bitwise<combine_any, 0> bit_bor("bit.bor");
140 lua_symmetric_bitwise<combine_all, BITWISE_MASK> bit_all("bit.all");
141 lua_symmetric_bitwise<combine_all, BITWISE_MASK> bit_band("bit.band");
142 lua_symmetric_bitwise<combine_parity, 0> bit_parity("bit.parity");
143 lua_symmetric_bitwise<combine_parity, 0> bit_bxor("bit.bxor");
144 lua_shifter<shift_lrotate> bit_lrotate("bit.lrotate");
145 lua_shifter<shift_rrotate> bit_rrotate("bit.rrotate");
146 lua_shifter<shift_lshift> bit_lshift("bit.lshift");
147 lua_shifter<shift_arshift> bit_arshift("bit.arshift");
148 lua_shifter<shift_lrshift> bit_lrshift("bit.lrshift");