aboutsummaryrefslogtreecommitdiff
path: root/data/core/bit.lua
blob: e55fb9bfae6bb213f0ed467a9b0db2e5034adeeb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
local bit = {}

local LUA_NBITS = 32
local ALLONES = (~(((~0) << (LUA_NBITS - 1)) << 1))

local function trim(x)
	return (x & ALLONES)
end

local function mask(n)
	return (~((ALLONES << 1) << ((n) - 1)))
end

local function check_args(field, width)
	assert(field >= 0, "field cannot be negative")
	assert(width > 0, "width must be positive")
	assert(field + width < LUA_NBITS and field + width >= 0,
	       "trying to access non-existent bits")
end

function bit.extract(n, field, width)
	local w = width or 1
	check_args(field, w)
	local m = trim(n)
	return m >> field & mask(w)
end

function bit.replace(n, v, field, width)
	local w = width or 1
	check_args(field, w)
	local m = trim(n)
	local x = v & mask(width);
	return m & ~(mask(w) << field) | (x << field)
end

return bit