etnaviv: isa: Add an assembler with unit tests
What does this MR do and why?
This MR adds support for libetnaviv_parse
. It can be used to convert a textual representation of etnaviv asm into struct etna_inst
.
Instead of going the flex/bison route I have decided to go the
This MR does not make Rust a requirement for etnaviv.
In my opinion this has multiple benefits:
- using a parsing expression grammar
- nice error messages
Error parsing instruction: --> 1:25
|
1 | branch.eq void, t1.zzzz, u0.zzzz, 8
| ^---
|
= expected SrcVoid
- isaspec as source of truth
- lot of generated code -> changes in isaspec (reorder flags etc) do not need manual code edit
This is how the current generated etnaviv.pest file looks like:
/*
* Copyright © 2024 Igalia S.L.
* SPDX-License-Identifier: MIT
*/
WHITESPACE = _{ " " | "\t" }
COMMENT = _{ ";" ~ (!NEWLINE ~ ANY)* ~ NEWLINE? }
Dst_full = { ".hp" }
Sat = { ".sat" }
Skphp = { ".skpHp" }
Pmode = { ".pack" }
Denorm = { ".denorm" }
Local = { ".local" }
Amount = { ASCII_DIGIT* }
Left_shift = { ".ls" ~ Amount }
SrcVoid = { "void" }
DestVoid = { "void" }
Negate = { "-" }
Absolute = { "|" }
Cond = { Xor | True | Selmsb | Or | Nz | Not | Ne | Lz | Lt | Lez | Le | Gz | Gt | Gez | Ge | Eq | And }
Xor = { ".xor" }
True = { ".true" }
Selmsb = { ".selmsb" }
Or = { ".or" }
Nz = { ".nz" }
Not = { ".not" }
Ne = { ".ne" }
Lz = { ".lz" }
Lt = { ".lt" }
Lez = { ".lez" }
Le = { ".le" }
Gz = { ".gz" }
Gt = { ".gt" }
Gez = { ".gez" }
Ge = { ".ge" }
Eq = { ".eq" }
And = { ".and" }
Swiz = { Z | Y | X | W }
Z = { "z" }
Y = { "y" }
X = { "x" }
W = { "w" }
Type = { U8 | U32 | U16 | S8 | S32 | S16 | F32 | F16 }
U8 = { ".u8" }
U32 = { ".u32" }
U16 = { ".u16" }
S8 = { ".s8" }
S32 = { ".s32" }
S16 = { ".s16" }
F32 = { ".f32" }
F16 = { ".f16" }
RegGroup = { Uniform_0 | Uniform_1 | Th | Temp | Immed | Internal }
Uniform_0 = { "u" }
Uniform_1 = { "u" }
Th = { "th" }
Temp = { "t" }
Immed = { "immed" }
Internal = { "i" }
RegAddressingMode = { Direct | Az | Ay | Ax | Aw }
Direct = { "direct" }
Az = { "[a.z]" }
Ay = { "[a.y]" }
Ax = { "[a.x]" }
Aw = { "[a.w]" }
Rounding = { Unkown2 | Unkown | Rtz | Rtne }
Unkown2 = { ".unkown2" }
Unkown = { ".unkown" }
Rtz = { ".rtz" }
Rtne = { ".rtne" }
Wrmask = { Xyzw | Zy | Zx | Xyz_ | Xy_w | Xy__ | X_zw | X__w | X___ | _yzw | _y_w | _y__ | __zw | __z_ | ___w | ____ }
Xyzw = { "xyzw" }
Zy = { ".zy" }
Zx = { ".zx" }
Xyz_ = { ".xyz_" }
Xy_w = { ".xy_w" }
Xy__ = { ".xy__" }
X_zw = { ".x_zw" }
X__w = { ".x__w" }
X___ = { ".x___" }
_yzw = { "._yzw" }
_y_w = { "._y_w" }
_y__ = { "._y__" }
__zw = { ".__zw" }
__z_ = { ".__z_" }
___w = { ".___w" }
____ = { ".____" }
Thread = { T1 | T0 }
T1 = { ".t1" }
T0 = { ".t0" }
Immediate_Minus_Nan = @{ Negate ~ "nan" }
Immediate_float = @{ Negate? ~ ASCII_DIGIT* ~ "." ~ ASCII_DIGIT* }
Immediate_int = @{ Negate ~ ASCII_DIGIT* }
Immediate_uint = @{ ASCII_DIGIT* }
Immediate = _{ Immediate_Minus_Nan | Immediate_float | Immediate_int | Immediate_uint }
Register = { ASCII_DIGIT* }
DstRegister = ${ RegGroup ~ Register ~ RegAddressingMode? ~ Wrmask? }
DstMemAddr = ${ "mem" ~ Wrmask? }
SrcSwizzle = ${ "." ~ Swiz ~ Swiz ~ Swiz ~ Swiz }
SrcRegister = ${
( Negate? ~ Absolute ~ RegGroup ~ Register ~ RegAddressingMode? ~ SrcSwizzle? ~ Absolute |
Negate? ~ RegGroup ~ Register ~ RegAddressingMode? ~ SrcSwizzle? |
Immediate )
}
Dest = _{ DstRegister }
Src = _{ SrcRegister }
TexSrc = ${ "tex" ~ Register ~ SrcSwizzle }
Target = { ASCII_DIGIT* }
instructions = _{ OpcNop | OpcAdd | OpcMad | OpcMul | OpcDp3 | OpcDp4 | OpcDsx | OpcDsy | OpcMov | OpcMovar | OpcRcp | OpcRsq | OpcSelect | OpcSet | OpcExp | OpcLog | OpcFrc | OpcCall | OpcRet | OpcBranch | OpcTexkill | OpcTexld | OpcTexldb | OpcTexldd | OpcTexldl | OpcSqrt | OpcSin | OpcCos | OpcBranchAny | OpcFloor | OpcCeil | OpcSign | OpcBarrier | OpcI2i | OpcI2f | OpcF2i | OpcF2irnd | OpcCmp | OpcLoad | OpcStore | OpcIaddsat | OpcImullo0 | OpcImulhi0 | OpcIdiv0 | OpcImod | OpcImadlo0 | OpcImadlosat0 | OpcMovai | OpcIabs | OpcLeadzero | OpcLshift | OpcRshift | OpcRotate | OpcOr | OpcAnd | OpcXor | OpcNot | OpcBitExtract | OpcPopcount | OpcDiv | OpcAtomicAdd | OpcAtomicXchg | OpcAtomicCmpXchg | OpcAtomicMin | OpcAtomicMax | OpcAtomicOr | OpcAtomicAnd | OpcAtomicXor | OpcBitRev | OpcTexldlpcf | OpcDp2 | OpcNormDp2 | OpcNormDp3 | OpcNormDp4 }
OpcNop = { "nop" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcAdd = { "add" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcMad = { "mad" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcMul = { "mul" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcDp3 = { "dp3" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcDp4 = { "dp4" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcDsx = { "dsx" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcDsy = { "dsy" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcMov = { "mov" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcMovar = { "movar" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcRcp = { "rcp" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcRsq = { "rsq" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcSelect = { "select" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcSet = { "set" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcExp = { "exp" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcLog = { "log" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcFrc = { "frc" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcCall = { "call" ~ Cond? ~ Type? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Target }
OpcRet = { "ret" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcBranch = { "branch" ~ Cond? ~ Type? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Target }
OpcTexkill = { "texkill" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcTexld = { "texld" ~ Dest ~ "," ~ TexSrc ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcTexldb = { "texldb" ~ Dest ~ "," ~ TexSrc ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcTexldd = { "texldd" ~ Dest ~ "," ~ TexSrc ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcTexldl = { "texldl" ~ Dest ~ "," ~ TexSrc ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcSqrt = { "sqrt" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcSin = { "sin" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcCos = { "cos" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcBranchAny = { "branch_any" ~ Cond? ~ Type? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Target }
OpcFloor = { "floor" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcCeil = { "ceil" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcSign = { "sign" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcBarrier = { "barrier" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcI2i = { "i2i" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcI2f = { "i2f" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcF2i = { "f2i" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcF2irnd = { "f2irnd" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcCmp = { "cmp" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcLoad = { "load" ~ Cond? ~ Skphp? ~ Denorm? ~ Local? ~ Type? ~ Left_shift? ~ Pmode? ~ (Dest | DstMemAddr) ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcStore = { "store" ~ Cond? ~ Skphp? ~ Denorm? ~ Local? ~ Type? ~ Left_shift? ~ Pmode? ~ (Dest | DstMemAddr) ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcIaddsat = { "iaddsat" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcImullo0 = { "imullo0" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcImulhi0 = { "imulhi0" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcIdiv0 = { "idiv0" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcImod = { "imod" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcImadlo0 = { "imadlo0" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcImadlosat0 = { "imadlosat0" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcMovai = { "movai" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ DestVoid ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcIabs = { "iabs" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcLeadzero = { "leadzero" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcLshift = { "lshift" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcRshift = { "rshift" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcRotate = { "rotate" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcOr = { "or" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcAnd = { "and" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcXor = { "xor" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ Src }
OpcNot = { "not" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcBitExtract = { "bit_extract" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcPopcount = { "popcount" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ SrcVoid ~ "," ~ Src }
OpcDiv = { "div" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ SrcVoid ~ "," ~ Src ~ "," ~ Src }
OpcAtomicAdd = { "atomic_add" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcAtomicXchg = { "atomic_xchg" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcAtomicCmpXchg = { "atomic_cmp_xchg" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcAtomicMin = { "atomic_min" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcAtomicMax = { "atomic_max" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcAtomicOr = { "atomic_or" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcAtomicAnd = { "atomic_and" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcAtomicXor = { "atomic_xor" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcBitRev = { "bit_rev" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcTexldlpcf = { "texldlpcf" ~ Dest ~ "," ~ TexSrc ~ "," ~ Src ~ "," ~ Src ~ "," ~ Src }
OpcDp2 = { "dp2" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ Src ~ "," ~ SrcVoid }
OpcNormDp2 = { "norm_dp2" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcNormDp3 = { "norm_dp3" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
OpcNormDp4 = { "norm_dp4" ~ Dst_full? ~ Sat? ~ Cond? ~ Skphp? ~ Type? ~ Pmode? ~ Thread? ~ Rounding? ~ Dest ~ "," ~ Src ~ "," ~ SrcVoid ~ "," ~ SrcVoid }
instruction = _{ SOI ~ instructions ~ NEWLINE? ~ EOI }
This MR is not be perfect yet and I am happy about every feedback I can get.