- Eliminate the field masks.
- Segregate the encoding logic.
- Simplify and clarify the user code.
This is supposed to help updating downstream branches where we
have a more advanced version of the same facility.
Given a `S_SET_VGPR_MSB` instruction with `CurrentMode` and
`CurrentMask` where `CurrentMask` is a bit mask with 1 for every bit
position we set to 0 or 1 in `CurrentMode`.
We also have a new mode bitset `Mode` and a `Mask` with the bit position
we want set.
Currently we check if the difference between `Mode` and `CurrentMode`
(`Delta = Mode ^ CurrentMode`) overlaps with the bit positions we
previously set (`Delta & CurrentMask .== 0`). We then update
`CurrentMode` and `CurrentMask` accordingly.
However if bit positions differ in `Mode` and `CurrentMode` but we do
not care about these bit positions for our next instruction `(Delta &
Mask) & CurrentMask .== 0`) we can still update the previous
`S_SET_VGPR_MSB`, since we don't interfere with any of the bit positions
in `CurrentMask`
```mir
S_SET_VGPR_MSB 0x0002
$vgpr0 = V_MOV_B32_e32 $vgpr530 ; mode: 0b0000_0010 mask: 0b0000_0011
-> $vgpr1 = V_ADD_U32_e32 0x1234, $vgpr531 ; mode: 0b0000_1000 mask: 0b0000_1100
; src0 is imm so we don't care about it.
```
| | dst | src2 | src1 | src0 |
|---|---|---|---|---|
| CurrentMode | 00 | 00 | 00 | 10 |
| CurrentMask | 00 | 00 | 00 | 11 |
| Mode | 00 | 00 | 10 | 00 |
| Mask | 00 | 00 | 11 | 00 |
| Delta | 00 | 00 | 10 | 10 |
| Delta & CurrentMask | 00 | 00 | 00 | 10 |
| Delta & Mask & CurrentMask | 00 | 00 | 00 | 00 |
If we exit the loop at a non SALU state instruction we have to return
the next instruction because we will insert before the instruction we
return. The check before the loop already did this for cases we start on
a non SALU state instruction by returning `I`. This is now done
afterwards.
By convention a basic block shall start with MSBs zero. We also
need to know a previous mode in all cases as SWDEV-562450 asks
to record the old mode in the high bits of the mode.