Skip to content

etnaviv: isa: Add an assembler with unit tests

Christian Gmeiner requested to merge austriancoder/mesa:etnaviv-pest into main

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 🦀 route and generate pest grammar rules, some Rust helper code based on isaspec.

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.

Edited by Christian Gmeiner

Merge request reports