Integer as Bit-Fields

Since bit-wise operators are defined on integer numbers, individual bits can also be accessed and manipulated via an indexing syntax.

If a bit is set (i.e. 1), the index access returns true. If a bit is not set (i.e. 0), the index access returns false.

There is nothing here that cannot be done via standard bit-manipulation (i.e. shifting and masking) operations. However, this is an extremely useful, and performant, short-hand since it usually replaces a sequence of multiple steps.

Indexing an integer as a bit-field is disabled via the no_index feature.

From Least-Significant Bit (LSB)

Bits in a bit-field are accessed with zero-based, non-negative integer indices:

integer [ index from 0 to 63 or 31 ]

integer [ index from 0 to 63 or 31 ] = new value ;

The maximum bit number that can be accessed is 63 (or 31 under only_i32).

From Most-Significant Bit (MSB)

A negative index accesses a bit in the bit-field counting from the end, or from the most-significant bit, with −1 being the highest bit.

integer [ index from −1 to −64 or −32 ]

integer [ index from −1 to −64 or −32 ] = new value ;

The maximum bit number that can be accessed is −64 (or −32 under only_i32).

Bit-Field Functions

The following standard functions (defined in the LogicPackage but excluded if using a raw Engine) operate on INT bit-fields:

FunctionParameter(s)Description
get_bitbit number, counting from MSB if < 0returns the state of a bit: true if 1, false if 0
set_bit1) bit number, counting from MSB if < 0
2) new state: true if 1, false if 0
sets the state of a bit
get_bits1) starting bit number, counting from MSB if < 0
2) number of bits to extract, none if < 1, to MSB if ≥ length
extracts a number of bits, shifted towards LSB
set_bits1) starting bit number, counting from MSB if < 0
2) number of bits to set, none if < 1, to MSB if ≥ length
3) new value
sets a number of bits from the new value
bits1) (optional) starting bit number, counting from MSB if < 0
2) (optional) number of bits to extract, none if < 1, to MSB if ≥ length
allows iteration over the bits of a bit-field

Example

// Assume the following bits fields in a single 16-bit word:
//
// +---------+-------+-----------------+------------+
// |   0-2   |   3   |      4-11       |    12-15   |
// +---------+-------+-----------------+------------+
// | Command | Flag  |    0-255 data   |   0 0 0 0  |
// +---------+-------+-----------------+------------+

let value = read_from_hw_register(42);

let command = value.get_bits(0, 3);         // Command = bits 0-2
let flag = value[3];                        // Flag = bit 3
let data = value.get_bits(4, 8);            // Data = bits 4-11
let reserved = value.get_bits(-4);          // Reserved = last 4 bits

if reserved != 0 {
    throw reserved;
}

switch command {
    0 => print(`Data = ${data}`),
    1 => value.set_bits(4, 8, data / 2),
    2 => value[3] = !flag,
    _ => print(`Unknown: ${command}`)
}