Evdev joystick plugin
[lsnes.git] / lua / bit.cpp
blob3db267f31e1ec90567c7436dc06008d4bd765057
1 #include "lua-int.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 lua_symmetric_bitwise<combine_none, BITWISE_MASK> bit_none("bit.none");
106 lua_symmetric_bitwise<combine_none, BITWISE_MASK> bit_bnot("bit.bnot");
107 lua_symmetric_bitwise<combine_any, 0> bit_any("bit.any");
108 lua_symmetric_bitwise<combine_any, 0> bit_bor("bit.bor");
109 lua_symmetric_bitwise<combine_all, BITWISE_MASK> bit_all("bit.all");
110 lua_symmetric_bitwise<combine_all, BITWISE_MASK> bit_band("bit.band");
111 lua_symmetric_bitwise<combine_parity, 0> bit_parity("bit.parity");
112 lua_symmetric_bitwise<combine_parity, 0> bit_bxor("bit.bxor");
113 lua_shifter<shift_lrotate> bit_lrotate("bit.lrotate");
114 lua_shifter<shift_rrotate> bit_rrotate("bit.rrotate");
115 lua_shifter<shift_lshift> bit_lshift("bit.lshift");
116 lua_shifter<shift_arshift> bit_arshift("bit.arshift");
117 lua_shifter<shift_lrshift> bit_lrshift("bit.lrshift");