# OpenVM Load/Store flags
OpenVM's [`LoadStoreCoreAir`](https://github.com/powdr-labs/openvm/blob/dcf8ee6c5d6fd61fb8ce32c9cb836ac39e4e4fa8/extensions/rv32im/circuit/src/loadstore/core.rs#L101-L249) has 4 flags. They have the following constraints:
- Each of them can be 0, 1, or 2 ([code](https://github.com/powdr-labs/openvm/blob/dcf8ee6c5d6fd61fb8ce32c9cb836ac39e4e4fa8/extensions/rv32im/circuit/src/loadstore/core.rs#L121))
- Their sum can be 1, or 2 ([code](https://github.com/powdr-labs/openvm/blob/dcf8ee6c5d6fd61fb8ce32c9cb836ac39e4e4fa8/extensions/rv32im/circuit/src/loadstore/core.rs#L124-L126))
This leaves 14 possible assignments. For each of these 14 cases, there is a degree-2 expression to select it, built [here](https://github.com/powdr-labs/openvm/blob/dcf8ee6c5d6fd61fb8ce32c9cb836ac39e4e4fa8/extensions/rv32im/circuit/src/loadstore/core.rs#L130-L140).
Each case is associated with a `(opcode, shift)` tuple, see [this code](https://github.com/powdr-labs/openvm/blob/dcf8ee6c5d6fd61fb8ce32c9cb836ac39e4e4fa8/extensions/rv32im/circuit/src/loadstore/core.rs#L319-L337)
```rust=
*flags = [F::ZERO; 4];
match (opcode, record.shift) {
(LOADW, 0) => flags[0] = F::TWO,
(LOADHU, 0) => flags[1] = F::TWO,
(LOADHU, 2) => flags[2] = F::TWO,
(LOADBU, 0) => flags[3] = F::TWO,
(LOADBU, 1) => flags[0] = F::ONE,
(LOADBU, 2) => flags[1] = F::ONE,
(LOADBU, 3) => flags[2] = F::ONE,
(STOREW, 0) => flags[3] = F::ONE,
(STOREH, 0) => (flags[0], flags[1]) = (F::ONE, F::ONE),
(STOREH, 2) => (flags[0], flags[2]) = (F::ONE, F::ONE),
(STOREB, 0) => (flags[0], flags[3]) = (F::ONE, F::ONE),
(STOREB, 1) => (flags[1], flags[2]) = (F::ONE, F::ONE),
(STOREB, 2) => (flags[1], flags[3]) = (F::ONE, F::ONE),
(STOREB, 3) => (flags[2], flags[3]) = (F::ONE, F::ONE),
_ => unreachable!(),
};
```
For operations on words, the shift can only be 0; for operations on half words, the shift can be 0 or 2; for operations on bytes, the shift can be 0, 1, 2, or 3. For each operation we have a load and store variant, which leaves us with 14 cases (also encoded in [this enum](https://github.com/powdr-labs/openvm/blob/dcf8ee6c5d6fd61fb8ce32c9cb836ac39e4e4fa8/extensions/rv32im/circuit/src/loadstore/core.rs#L22-L37)).
To spell out the possibilities:
- `(2, 0, 0, 0)`: `(LOADW, 0)`
- `(0, 2, 0, 0)`: `(LOADHU, 0)`
- `(0, 0, 2, 0)`: `(LOADHU, 2)`
- `(0, 0, 0, 2)`: `(LOADBU, 0)`
- `(1, 0, 0, 0)`: `(LOADBU, 1)`
- `(0, 1, 0, 0)`: `(LOADBU, 2)`
- `(0, 0, 1, 0)`: `(LOADBU, 3)`
- `(0, 0, 0, 1)`: `(STOREW, 0)`
- `(1, 1, 0, 0)`: `(STOREH, 0)`
- `(1, 0, 1, 0)`: `(STOREH, 2)`
- `(1, 0, 0, 1)`: `(STOREB, 0)`
- `(0, 1, 1, 0)`: `(STOREB, 1)`
- `(0, 1, 0, 1)`: `(STOREB, 2)`
- `(0, 0, 1, 1)`: `(STOREB, 3)`