2021-12-31 13:53:01 +01:00
|
|
|
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
|
|
|
|
|
2022-01-12 19:56:09 +01:00
|
|
|
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
|
|
|
|
|
2021-12-31 13:53:01 +01:00
|
|
|
function bit.extract(n, field, width)
|
2022-01-12 00:07:14 +01:00
|
|
|
local w = width or 1
|
2022-01-12 19:56:09 +01:00
|
|
|
check_args(field, w)
|
2022-01-12 00:07:14 +01:00
|
|
|
local m = trim(n)
|
|
|
|
return m >> field & mask(w)
|
2021-12-31 13:53:01 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function bit.replace(n, v, field, width)
|
2022-01-12 00:07:14 +01:00
|
|
|
local w = width or 1
|
2022-01-12 19:56:09 +01:00
|
|
|
check_args(field, w)
|
2022-01-12 00:07:14 +01:00
|
|
|
local m = trim(n)
|
|
|
|
local x = v & mask(width);
|
|
|
|
return m & ~(mask(w) << field) | (x << field)
|
2021-12-31 13:53:01 +01:00
|
|
|
end
|
|
|
|
|
2022-01-12 00:07:14 +01:00
|
|
|
return bit
|