From a7109c767bdc014327b574012794156c92174495 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Tue, 12 Oct 2021 17:35:31 -0300
Subject: [PATCH] Rewrite shader decoding stage (#2698)

* Rewrite shader decoding stage

* Fix P2R constant buffer encoding

* Fix PSET/PSETP

* PR feedback

* Log unimplemented shader instructions

* Implement NOP

* Remove using

* PR feedback
---
 .../Shader/CachedGpuAccessor.cs               |   10 +-
 Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs    |   23 +-
 Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs    |    2 +-
 .../TextureDescriptorCapableGpuAccessor.cs    |    3 +-
 .../Glsl/Instructions/InstGenMemory.cs        |    2 +-
 Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs  |   16 -
 .../Decoders/BarrierLevel.cs                  |   10 -
 .../Decoders/BarrierMode.cs                   |   12 -
 .../Decoders/BitfieldExtensions.cs            |   10 -
 Ryujinx.Graphics.Shader/Decoders/Block.cs     |  147 +-
 .../Decoders/CbIndexMode.cs                   |   10 -
 Ryujinx.Graphics.Shader/Decoders/Condition.cs |   45 -
 .../Decoders/ConditionalOperation.cs          |   10 -
 Ryujinx.Graphics.Shader/Decoders/Decoder.cs   |  306 +-
 .../Decoders/DecoderHelper.cs                 |   74 -
 .../Decoders/FPHalfSwizzle.cs                 |   10 -
 .../Decoders/FPMultiplyScale.cs               |   13 -
 Ryujinx.Graphics.Shader/Decoders/FPType.cs    |   19 -
 Ryujinx.Graphics.Shader/Decoders/IOpCode.cs   |   16 -
 .../Decoders/IOpCodeAlu.cs                    |    9 -
 .../Decoders/IOpCodeAttribute.cs              |    9 -
 .../Decoders/IOpCodeCbuf.cs                   |    8 -
 .../Decoders/IOpCodeFArith.cs                 |   12 -
 .../Decoders/IOpCodeHfma.cs                   |   13 -
 .../Decoders/IOpCodeImm.cs                    |    7 -
 .../Decoders/IOpCodeImmF.cs                   |    7 -
 .../Decoders/IOpCodeLop.cs                    |   10 -
 .../Decoders/IOpCodePredicate39.cs            |    9 -
 Ryujinx.Graphics.Shader/Decoders/IOpCodeRa.cs |    7 -
 Ryujinx.Graphics.Shader/Decoders/IOpCodeRc.cs |    7 -
 Ryujinx.Graphics.Shader/Decoders/IOpCodeRd.cs |    7 -
 .../Decoders/IOpCodeReg.cs                    |    7 -
 .../Decoders/IOpCodeRegCbuf.cs                |    8 -
 .../Decoders/IOpCodeTexture.cs                |   23 -
 .../Decoders/IOpCodeTld4.cs                   |   11 -
 .../Decoders/ImageComponents.cs               |   10 -
 .../Decoders/ImageDimensions.cs               |   12 -
 .../Decoders/InstDecoders.cs                  | 5362 +++++++++++++++++
 Ryujinx.Graphics.Shader/Decoders/InstName.cs  |  188 +
 Ryujinx.Graphics.Shader/Decoders/InstOp.cs    |   27 +
 Ryujinx.Graphics.Shader/Decoders/InstProps.cs |   20 +
 Ryujinx.Graphics.Shader/Decoders/InstTable.cs |  388 ++
 .../Decoders/IntegerCondition.cs              |   18 -
 .../Decoders/IntegerHalfPart.cs               |    9 -
 .../Decoders/IntegerShift.cs                  |    9 -
 .../Decoders/IntegerSize.cs                   |   14 -
 .../Decoders/IntegerType.cs                   |   14 -
 .../Decoders/InterpolationMode.cs             |   10 -
 .../Decoders/LogicalOperation.cs              |   10 -
 .../Decoders/MufuOperation.cs                 |   15 -
 Ryujinx.Graphics.Shader/Decoders/OpCode.cs    |   32 -
 .../Decoders/OpCodeAl2p.cs                    |   24 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeAlu.cs |   36 -
 .../Decoders/OpCodeAluCbuf.cs                 |   18 -
 .../Decoders/OpCodeAluImm.cs                  |   16 -
 .../Decoders/OpCodeAluImm2x10.cs              |   16 -
 .../Decoders/OpCodeAluImm32.cs                |   20 -
 .../Decoders/OpCodeAluReg.cs                  |   16 -
 .../Decoders/OpCodeAluRegCbuf.cs              |   20 -
 .../Decoders/OpCodeAtom.cs                    |   28 -
 .../Decoders/OpCodeAttribute.cs               |   23 -
 .../Decoders/OpCodeBarrier.cs                 |   16 -
 .../Decoders/OpCodeBranch.cs                  |   25 -
 .../Decoders/OpCodeBranchIndir.cs             |   25 -
 .../Decoders/OpCodeBranchPop.cs               |   17 -
 .../Decoders/OpCodeConditional.cs             |   16 -
 .../Decoders/OpCodeDArithImm.cs               |   16 -
 .../Decoders/OpCodeExit.cs                    |   13 -
 .../Decoders/OpCodeFArith.cs                  |   26 -
 .../Decoders/OpCodeFArithCbuf.cs              |   18 -
 .../Decoders/OpCodeFArithImm.cs               |   16 -
 .../Decoders/OpCodeFArithImm32.cs             |   32 -
 .../Decoders/OpCodeFArithReg.cs               |   16 -
 .../Decoders/OpCodeFArithRegCbuf.cs           |   18 -
 .../Decoders/OpCodeFsetImm.cs                 |   16 -
 .../Decoders/OpCodeHfma.cs                    |   24 -
 .../Decoders/OpCodeHfmaCbuf.cs                |   32 -
 .../Decoders/OpCodeHfmaImm2x10.cs             |   28 -
 .../Decoders/OpCodeHfmaImm32.cs               |   27 -
 .../Decoders/OpCodeHfmaReg.cs                 |   31 -
 .../Decoders/OpCodeHfmaRegCbuf.cs             |   32 -
 .../Decoders/OpCodeHsetImm2x10.cs             |   16 -
 .../Decoders/OpCodeImage.cs                   |   47 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs |   28 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeLdc.cs |   30 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeLop.cs |   26 -
 .../Decoders/OpCodeLopCbuf.cs                 |   18 -
 .../Decoders/OpCodeLopImm.cs                  |   16 -
 .../Decoders/OpCodeLopImm32.cs                |   24 -
 .../Decoders/OpCodeLopReg.cs                  |   16 -
 .../Decoders/OpCodeMemory.cs                  |   30 -
 .../Decoders/OpCodeMemoryBarrier.cs           |   16 -
 .../Decoders/OpCodePset.cs                    |   28 -
 .../Decoders/OpCodePush.cs                    |   24 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeRed.cs |   34 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeSet.cs |   28 -
 .../Decoders/OpCodeSetCbuf.cs                 |   18 -
 .../Decoders/OpCodeSetImm.cs                  |   16 -
 .../Decoders/OpCodeSetReg.cs                  |   16 -
 .../Decoders/OpCodeShuffle.cs                 |   42 -
 .../Decoders/OpCodeSuatom.cs                  |   46 -
 .../Decoders/OpCodeSured.cs                   |   44 -
 .../Decoders/OpCodeTable.cs                   |  304 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeTex.cs |   16 -
 .../Decoders/OpCodeTexB.cs                    |   22 -
 .../Decoders/OpCodeTexs.cs                    |   13 -
 .../Decoders/OpCodeTexture.cs                 |   40 -
 .../Decoders/OpCodeTextureBase.cs             |   14 -
 .../Decoders/OpCodeTextureScalar.cs           |   60 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeTld.cs |   22 -
 .../Decoders/OpCodeTld4.cs                    |   24 -
 .../Decoders/OpCodeTld4B.cs                   |   24 -
 .../Decoders/OpCodeTld4s.cs                   |   26 -
 .../Decoders/OpCodeTlds.cs                    |   13 -
 Ryujinx.Graphics.Shader/Decoders/OpCodeTxd.cs |   20 -
 .../Decoders/OpCodeVideo.cs                   |  105 -
 .../Decoders/OpCodeVote.cs                    |   28 -
 .../Decoders/ReductionType.cs                 |   14 -
 .../Decoders/RoundingMode.cs                  |   10 -
 .../Decoders/ShuffleType.cs                   |   10 -
 .../Decoders/SystemRegister.cs                |   21 -
 .../Decoders/TexelLoadTarget.cs               |   15 -
 .../Decoders/TextureDimensions.cs             |   10 -
 .../Decoders/TextureGatherOffset.cs           |    9 -
 .../Decoders/TextureLodMode.cs                |   12 -
 .../Decoders/TextureProperty.cs               |   13 -
 .../Decoders/TextureTarget.cs                 |   20 -
 .../Decoders/VideoPostOp.cs                   |   14 -
 Ryujinx.Graphics.Shader/Decoders/VideoType.cs |   15 -
 Ryujinx.Graphics.Shader/Decoders/VoteOp.cs    |    9 -
 Ryujinx.Graphics.Shader/Decoders/XmadCMode.cs |   11 -
 Ryujinx.Graphics.Shader/IGpuAccessor.cs       |   11 +-
 .../Instructions/InstEmit.cs                  |  526 ++
 .../Instructions/InstEmitAlu.cs               |  984 ---
 .../Instructions/InstEmitAluHelper.cs         |   57 +-
 .../Instructions/InstEmitAttribute.cs         |  190 +
 .../Instructions/InstEmitBarrier.cs           |   44 +
 .../Instructions/InstEmitBitfield.cs          |  190 +
 .../Instructions/InstEmitConversion.cs        |  411 +-
 .../Instructions/InstEmitFArith.cs            |  547 --
 .../Instructions/InstEmitFloatArithmetic.cs   |  545 ++
 .../Instructions/InstEmitFloatComparison.cs   |  419 ++
 .../Instructions/InstEmitFloatMinMax.cs       |   70 +
 ...InstEmitFlow.cs => InstEmitFlowControl.cs} |  107 +-
 .../Instructions/InstEmitHelper.cs            |  267 +-
 .../Instructions/InstEmitIntegerArithmetic.cs |  656 ++
 .../Instructions/InstEmitIntegerComparison.cs |  327 +
 .../Instructions/InstEmitIntegerLogical.cs    |  167 +
 .../Instructions/InstEmitIntegerMinMax.cs     |   71 +
 .../Instructions/InstEmitMemory.cs            |  552 +-
 .../Instructions/InstEmitMove.cs              |  227 +-
 .../Instructions/InstEmitMultifunction.cs     |   85 +
 .../Instructions/InstEmitNop.cs               |   15 +
 .../Instructions/InstEmitPredicate.cs         |   54 +
 .../Instructions/InstEmitShift.cs             |  132 +
 .../Instructions/InstEmitSurface.cs           |  776 +++
 .../Instructions/InstEmitTexture.cs           | 1468 ++---
 .../Instructions/InstEmitVideoArithmetic.cs   |   18 +
 ...nstEmitVideo.cs => InstEmitVideoMinMax.cs} |   85 +-
 .../Instructions/InstEmitVote.cs              |   48 -
 .../Instructions/InstEmitWarp.cs              |   84 +
 .../Instructions/Lop3Expression.cs            |    9 +-
 .../Translation/ControlFlowGraph.cs           |   25 +
 .../Translation/Dominance.cs                  |    1 -
 .../Translation/EmitterContext.cs             |   11 +-
 .../Translation/ShaderHeader.cs               |   21 +-
 .../Translation/Translator.cs                 |   38 +-
 Ryujinx.ShaderTools/Program.cs                |    4 +-
 168 files changed, 12022 insertions(+), 6388 deletions(-)
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/CbIndexMode.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/Condition.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/ConditionalOperation.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/DecoderHelper.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/FPHalfSwizzle.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/FPMultiplyScale.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/FPType.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCode.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeAlu.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeFArith.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeHfma.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeImm.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeImmF.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeLop.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodePredicate39.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeRa.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeRc.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeRd.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeReg.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeRegCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/ImageDimensions.cs
 create mode 100644 Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
 create mode 100644 Ryujinx.Graphics.Shader/Decoders/InstName.cs
 create mode 100644 Ryujinx.Graphics.Shader/Decoders/InstOp.cs
 create mode 100644 Ryujinx.Graphics.Shader/Decoders/InstProps.cs
 create mode 100644 Ryujinx.Graphics.Shader/Decoders/InstTable.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IntegerCondition.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IntegerHalfPart.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IntegerShift.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IntegerSize.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/IntegerType.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/InterpolationMode.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/LogicalOperation.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/MufuOperation.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCode.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAlu.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAluCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm2x10.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm32.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAluReg.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAluRegCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeBranch.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeBranchIndir.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeBranchPop.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeConditional.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeDArithImm.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeExit.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeFArith.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeFArithCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm32.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeFArithReg.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeFArithRegCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeFsetImm.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeHfma.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm2x10.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm32.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaReg.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaRegCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeHsetImm2x10.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeImage.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeLdc.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeLop.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeLopCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm32.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeLopReg.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeMemory.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodePset.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodePush.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeRed.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeSet.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeSetCbuf.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeSetImm.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeSetReg.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeShuffle.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeSuatom.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeSured.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTex.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTexB.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTexs.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTextureBase.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTextureScalar.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTld.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTld4s.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTlds.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeTxd.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/OpCodeVote.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/ReductionType.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/RoundingMode.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/ShuffleType.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/TexelLoadTarget.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/TextureDimensions.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/TextureGatherOffset.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/TextureLodMode.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/TextureProperty.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/TextureTarget.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/VideoType.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/VoteOp.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Decoders/XmadCMode.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitBarrier.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitBitfield.cs
 delete mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitFloatComparison.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitFloatMinMax.cs
 rename Ryujinx.Graphics.Shader/Instructions/{InstEmitFlow.cs => InstEmitFlowControl.cs} (63%)
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerLogical.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerMinMax.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitMultifunction.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitNop.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitPredicate.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitShift.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitVideoArithmetic.cs
 rename Ryujinx.Graphics.Shader/Instructions/{InstEmitVideo.cs => InstEmitVideoMinMax.cs} (51%)
 delete mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs
 create mode 100644 Ryujinx.Graphics.Shader/Instructions/InstEmitWarp.cs

diff --git a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs
index 625b8bac15..3a52b2feb1 100644
--- a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs
@@ -60,14 +60,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
         }
 
         /// <summary>
-        /// Reads data from GPU memory.
+        /// Gets a span of the specified memory location, containing shader code.
         /// </summary>
-        /// <typeparam name="T">Type of the data to be read</typeparam>
         /// <param name="address">GPU virtual address of the data</param>
-        /// <returns>Data at the memory location</returns>
-        public override T MemoryRead<T>(ulong address)
+        /// <param name="minimumSize">Minimum size that the returned span may have</param>
+        /// <returns>Span of the memory location</returns>
+        public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
         {
-            return MemoryMarshal.Cast<byte, T>(_data.Span.Slice((int)address))[0];
+            return MemoryMarshal.Cast<byte, ulong>(_data.Span.Slice((int)address));
         }
 
         /// <summary>
diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
index 91746a9628..50e24b97db 100644
--- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
@@ -1,6 +1,8 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.GAL;
 using Ryujinx.Graphics.Shader;
+using System;
+using System.Runtime.InteropServices;
 
 namespace Ryujinx.Graphics.Gpu.Shader
 {
@@ -95,24 +97,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
         }
 
         /// <summary>
-        /// Reads data from GPU memory.
+        /// Gets a span of the specified memory location, containing shader code.
         /// </summary>
-        /// <typeparam name="T">Type of the data to be read</typeparam>
         /// <param name="address">GPU virtual address of the data</param>
-        /// <returns>Data at the memory location</returns>
-        public override T MemoryRead<T>(ulong address)
+        /// <param name="minimumSize">Minimum size that the returned span may have</param>
+        /// <returns>Span of the memory location</returns>
+        public override ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
         {
-            return _channel.MemoryManager.Read<T>(address);
-        }
-
-        /// <summary>
-        /// Checks if a given memory address is mapped.
-        /// </summary>
-        /// <param name="address">GPU virtual address to be checked</param>
-        /// <returns>True if the address is mapped, false otherwise</returns>
-        public bool MemoryMapped(ulong address)
-        {
-            return _channel.MemoryManager.IsMapped(address);
+            int size = Math.Max(minimumSize, 0x1000 - (int)(address & 0xfff));
+            return MemoryMarshal.Cast<byte, ulong>(_channel.MemoryManager.GetSpan(address, size));
         }
 
         /// <summary>
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index af6f9462cb..12b7c2f0d0 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
         /// <summary>
         /// Version of the codegen (to be changed when codegen or guest format change).
         /// </summary>
-        private const ulong ShaderCodeGenVersion = 2646;
+        private const ulong ShaderCodeGenVersion = 2697;
 
         // Progress reporting helpers
         private volatile int _shaderCount;
diff --git a/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs
index dfb67f358a..40353850fb 100644
--- a/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs
@@ -1,6 +1,7 @@
 using Ryujinx.Graphics.GAL;
 using Ryujinx.Graphics.Gpu.Image;
 using Ryujinx.Graphics.Shader;
+using System;
 
 namespace Ryujinx.Graphics.Gpu.Shader
 {
@@ -13,7 +14,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
             _context = context;
         }
 
-        public abstract T MemoryRead<T>(ulong address) where T : unmanaged;
+        public abstract ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize);
 
         public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot);
 
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
index 89215736bf..edaacd3e4e 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
@@ -176,7 +176,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
                 {
                     texCall = "int(" + texCall + ")";
                 }
-            } 
+            }
             else
             {
                 texCall += ")" + (texOp.Inst == Instruction.ImageLoad ? GetMask(texOp.Index) : "");
diff --git a/Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs b/Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs
deleted file mode 100644
index 1995519258..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/AtomicOp.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum AtomicOp
-    {
-        Add                = 0,
-        Minimum            = 1,
-        Maximum            = 2,
-        Increment          = 3,
-        Decrement          = 4,
-        BitwiseAnd         = 5,
-        BitwiseOr          = 6,
-        BitwiseExclusiveOr = 7,
-        Swap               = 8,
-        SafeAdd            = 10 // Only supported by ATOM.
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs b/Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs
deleted file mode 100644
index 95c71e0097..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/BarrierLevel.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum BarrierLevel
-    {
-        Cta = 0,
-        Gl  = 1,
-        Sys = 2,
-        Vc  = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs b/Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs
deleted file mode 100644
index a058cbbd71..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/BarrierMode.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum BarrierMode
-    {
-        ReductionPopCount = 2,
-        Scan              = 3,
-        ReductionAnd      = 0xa,
-        ReductionOr       = 0x12,
-        Sync              = 0x80,
-        Arrive            = 0x81
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/BitfieldExtensions.cs b/Ryujinx.Graphics.Shader/Decoders/BitfieldExtensions.cs
index d902fc863e..79e0a5c0e9 100644
--- a/Ryujinx.Graphics.Shader/Decoders/BitfieldExtensions.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/BitfieldExtensions.cs
@@ -11,15 +11,5 @@ namespace Ryujinx.Graphics.Shader.Decoders
         {
             return (value >> lsb) & (int)(uint.MaxValue >> (32 - length));
         }
-
-        public static bool Extract(this long value, int lsb)
-        {
-            return ((int)(value >> lsb) & 1) != 0;
-        }
-
-        public static int Extract(this long value, int lsb, int length)
-        {
-            return (int)(value >> lsb) & (int)(uint.MaxValue >> (32 - length));
-        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/Block.cs b/Ryujinx.Graphics.Shader/Decoders/Block.cs
index 69cb55b951..0b55c59ec5 100644
--- a/Ryujinx.Graphics.Shader/Decoders/Block.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/Block.cs
@@ -1,57 +1,56 @@
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
 using System;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace Ryujinx.Graphics.Shader.Decoders
 {
+    class PushOpInfo
+    {
+        public InstOp Op { get; }
+        public Dictionary<Block, Operand> Consumers;
+
+        public PushOpInfo(InstOp op)
+        {
+            Op = op;
+            Consumers = new Dictionary<Block, Operand>();
+        }
+    }
+
+    struct SyncTarget
+    {
+        public PushOpInfo PushOpInfo { get; }
+        public int PushOpId { get; }
+
+        public SyncTarget(PushOpInfo pushOpInfo, int pushOpId)
+        {
+            PushOpInfo = pushOpInfo;
+            PushOpId = pushOpId;
+        }
+    }
+
     class Block
     {
-        public ulong Address    { get; set; }
+        public ulong Address { get; set; }
         public ulong EndAddress { get; set; }
 
-        private Block _next;
-        private Block _branch;
+        public List<Block> Predecessors { get; }
+        public List<Block> Successors { get; }
 
-        public Block Next
-        {
-            get
-            {
-                return _next;
-            }
-            set
-            {
-                _next?.Predecessors.Remove(this);
-                value?.Predecessors.Add(this);
-                _next = value;
-            }
-        }
-
-        public Block Branch
-        {
-            get
-            {
-                return _branch;
-            }
-            set
-            {
-                _branch?.Predecessors.Remove(this);
-                value?.Predecessors.Add(this);
-                _branch = value;
-            }
-        }
-
-        public HashSet<Block> Predecessors { get; }
-
-        public List<OpCode>     OpCodes     { get; }
-        public List<OpCodePush> PushOpCodes { get; }
+        public List<InstOp> OpCodes { get; }
+        public List<PushOpInfo> PushOpCodes { get; }
+        public Dictionary<ulong, SyncTarget> SyncTargets { get; }
 
         public Block(ulong address)
         {
             Address = address;
 
-            Predecessors = new HashSet<Block>();
+            Predecessors = new List<Block>();
+            Successors = new List<Block>();
 
-            OpCodes     = new List<OpCode>();
-            PushOpCodes = new List<OpCodePush>();
+            OpCodes = new List<InstOp>();
+            PushOpCodes = new List<PushOpInfo>();
+            SyncTargets = new Dictionary<ulong, SyncTarget>();
         }
 
         public void Split(Block rightBlock)
@@ -64,36 +63,56 @@ namespace Ryujinx.Graphics.Shader.Decoders
             }
 
             int splitCount = OpCodes.Count - splitIndex;
-
             if (splitCount <= 0)
             {
                 throw new ArgumentException("Can't split at right block address.");
             }
 
             rightBlock.EndAddress = EndAddress;
-
-            rightBlock.Next   = Next;
-            rightBlock.Branch = Branch;
-
-            rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
-
-            rightBlock.UpdatePushOps();
+            rightBlock.Successors.AddRange(Successors);
+            rightBlock.Predecessors.Add(this);
 
             EndAddress = rightBlock.Address;
 
-            Next   = rightBlock;
-            Branch = null;
+            Successors.Clear();
+            Successors.Add(rightBlock);
+
+            // Move ops.
+            rightBlock.OpCodes.AddRange(OpCodes.GetRange(splitIndex, splitCount));
 
             OpCodes.RemoveRange(splitIndex, splitCount);
 
-            UpdatePushOps();
+            // Update push consumers that points to this block.
+            foreach (SyncTarget syncTarget in SyncTargets.Values)
+            {
+                PushOpInfo pushOpInfo = syncTarget.PushOpInfo;
+
+                Operand local = pushOpInfo.Consumers[this];
+                pushOpInfo.Consumers.Remove(this);
+                pushOpInfo.Consumers.Add(rightBlock, local);
+            }
+
+            rightBlock.SyncTargets.Union(SyncTargets);
+            SyncTargets.Clear();
+
+            // Move push ops.
+            for (int i = 0; i < PushOpCodes.Count; i++)
+            {
+                if (PushOpCodes[i].Op.Address >= rightBlock.Address)
+                {
+                    int count = PushOpCodes.Count - i;
+                    rightBlock.PushOpCodes.AddRange(PushOpCodes.Skip(i));
+                    PushOpCodes.RemoveRange(i, count);
+                    break;
+                }
+            }
         }
 
-        private static int BinarySearch(List<OpCode> opCodes, ulong address)
+        private static int BinarySearch(List<InstOp> opCodes, ulong address)
         {
-            int left   = 0;
+            int left = 0;
             int middle = 0;
-            int right  = opCodes.Count - 1;
+            int right = opCodes.Count - 1;
 
             while (left <= right)
             {
@@ -101,7 +120,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
 
                 middle = left + (size >> 1);
 
-                OpCode opCode = opCodes[middle];
+                InstOp opCode = opCodes[middle];
 
                 if (address == opCode.Address)
                 {
@@ -121,29 +140,25 @@ namespace Ryujinx.Graphics.Shader.Decoders
             return middle;
         }
 
-        public OpCode GetLastOp()
+        public InstOp GetLastOp()
         {
             if (OpCodes.Count != 0)
             {
                 return OpCodes[OpCodes.Count - 1];
             }
 
-            return null;
+            return default;
         }
 
-        public void UpdatePushOps()
+        public bool HasNext()
         {
-            PushOpCodes.Clear();
+            InstOp lastOp = GetLastOp();
+            return OpCodes.Count != 0 && !Decoder.IsUnconditionalBranch(ref lastOp);
+        }
 
-            for (int index = 0; index < OpCodes.Count; index++)
-            {
-                if (!(OpCodes[index] is OpCodePush op))
-                {
-                    continue;
-                }
-
-                PushOpCodes.Add(op);
-            }
+        public void AddPushOp(InstOp op)
+        {
+            PushOpCodes.Add(new PushOpInfo(op));
         }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/CbIndexMode.cs b/Ryujinx.Graphics.Shader/Decoders/CbIndexMode.cs
deleted file mode 100644
index 4c7a72b59e..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/CbIndexMode.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum CbIndexMode
-    {
-        Default = 0,
-        Il      = 1,
-        Is      = 2,
-        Isl     = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/Condition.cs b/Ryujinx.Graphics.Shader/Decoders/Condition.cs
deleted file mode 100644
index 10400f94ac..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/Condition.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum Condition
-    {
-        Less     = 1 << 0,
-        Equal    = 1 << 1,
-        Greater  = 1 << 2,
-        Nan      = 1 << 3,
-        Unsigned = 1 << 4,
-
-        Never = 0,
-
-        LessOrEqual    = Less    | Equal,
-        NotEqual       = Less    | Greater,
-        GreaterOrEqual = Greater | Equal,
-        Number         = Greater | Equal | Less,
-
-        LessUnordered           = Less           | Nan,
-        EqualUnordered          = Equal          | Nan,
-        LessOrEqualUnordered    = LessOrEqual    | Nan,
-        GreaterUnordered        = Greater        | Nan,
-        NotEqualUnordered       = NotEqual       | Nan,
-        GreaterOrEqualUnordered = GreaterOrEqual | Nan,
-
-        Always = 0xf,
-
-        Off          = Unsigned | Never,
-        Lower        = Unsigned | Less,
-        Sff          = Unsigned | Equal,
-        LowerOrSame  = Unsigned | LessOrEqual,
-        Higher       = Unsigned | Greater,
-        Sft          = Unsigned | NotEqual,
-        HigherOrSame = Unsigned | GreaterOrEqual,
-        Oft          = Unsigned | Always,
-
-        CsmTa  = 0x18,
-        CsmTr  = 0x19,
-        CsmMx  = 0x1a,
-        FcsmTa = 0x1b,
-        FcsmTr = 0x1c,
-        FcsmMx = 0x1d,
-        Rle    = 0x1e,
-        Rgt    = 0x1f
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/ConditionalOperation.cs b/Ryujinx.Graphics.Shader/Decoders/ConditionalOperation.cs
deleted file mode 100644
index 4fc31e842b..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/ConditionalOperation.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum ConditionalOperation
-    {
-        False   = 0,
-        True    = 1,
-        Zero    = 2,
-        NotZero = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
index c2901eab2c..656e9c44c8 100644
--- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
@@ -1,8 +1,8 @@
-using Ryujinx.Graphics.Shader.Instructions;
 using Ryujinx.Graphics.Shader.Translation;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Runtime.CompilerServices;
 
 using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
 
@@ -95,32 +95,33 @@ namespace Ryujinx.Graphics.Shader.Decoders
                         {
                             // We should have blocks for all possible branch targets,
                             // including those from SSY/PBK instructions.
-                            foreach (OpCodePush pushOp in currBlock.PushOpCodes)
+                            foreach (PushOpInfo pushOp in currBlock.PushOpCodes)
                             {
-                                GetBlock(pushOp.GetAbsoluteAddress());
+                                GetBlock(pushOp.Op.GetAbsoluteAddress());
                             }
 
                             // Set child blocks. "Branch" is the block the branch instruction
                             // points to (when taken), "Next" is the block at the next address,
                             // executed when the branch is not taken. For Unconditional Branches
                             // or end of program, Next is null.
-                            OpCode lastOp = currBlock.GetLastOp();
+                            InstOp lastOp = currBlock.GetLastOp();
 
-                            if (lastOp is OpCodeBranch opBr)
+                            if (lastOp.Name == InstName.Cal)
                             {
-                                if (lastOp.Emitter == InstEmit.Cal)
-                                {
-                                    EnqueueFunction(opBr.GetAbsoluteAddress());
-                                }
-                                else
-                                {
-                                    currBlock.Branch = GetBlock(opBr.GetAbsoluteAddress());
-                                }
+                                EnqueueFunction(lastOp.GetAbsoluteAddress());
+                            }
+                            else if (lastOp.Name == InstName.Bra)
+                            {
+                                Block succBlock = GetBlock(lastOp.GetAbsoluteAddress());
+                                currBlock.Successors.Add(succBlock);
+                                succBlock.Predecessors.Add(currBlock);
                             }
 
-                            if (!IsUnconditionalBranch(lastOp))
+                            if (!IsUnconditionalBranch(ref lastOp))
                             {
-                                currBlock.Next = GetBlock(currBlock.EndAddress);
+                                Block succBlock = GetBlock(currBlock.EndAddress);
+                                currBlock.Successors.Insert(0, succBlock);
+                                succBlock.Predecessors.Add(currBlock);
                             }
                         }
 
@@ -146,33 +147,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
                         }
                     }
 
-                    // Try to find target for BRX (indirect branch) instructions.
-                    hasNewTarget = false;
-
-                    foreach (Block block in blocks)
-                    {
-                        if (block.GetLastOp() is OpCodeBranchIndir opBrIndir && opBrIndir.PossibleTargets.Count == 0)
-                        {
-                            ulong baseOffset = opBrIndir.Address + 8 + (ulong)opBrIndir.Offset;
-
-                            // An indirect branch could go anywhere,
-                            // try to get the possible target offsets from the constant buffer.
-                            (int cbBaseOffset, int cbOffsetsCount) = FindBrxTargetRange(block, opBrIndir.Ra.Index);
-
-                            if (cbOffsetsCount != 0)
-                            {
-                                hasNewTarget = true;
-                            }
-
-                            for (int i = 0; i < cbOffsetsCount; i++)
-                            {
-                                uint targetOffset = config.GpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
-                                Block target = GetBlock(baseOffset + targetOffset);
-                                opBrIndir.PossibleTargets.Add(target);
-                                target.Predecessors.Add(block);
-                            }
-                        }
-                    }
+                    // Try to find targets for BRX (indirect branch) instructions.
+                    hasNewTarget = FindBrxTargets(config, blocks, GetBlock);
 
                     // If we discovered new branch targets from the BRX instruction,
                     // we need another round of decoding to decode the new blocks.
@@ -227,6 +203,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
             IGpuAccessor gpuAccessor = config.GpuAccessor;
 
             ulong address = block.Address;
+            int bufferOffset = 0;
+            ReadOnlySpan<ulong> buffer = ReadOnlySpan<ulong>.Empty;
+
+            InstOp op = default;
 
             do
             {
@@ -239,66 +219,75 @@ namespace Ryujinx.Graphics.Shader.Decoders
                 if ((address & 0x1f) == 0)
                 {
                     address += 8;
-
+                    bufferOffset++;
                     continue;
                 }
 
-                ulong opAddress = address;
-
-                address += 8;
-
-                long opCode = gpuAccessor.MemoryRead<long>(startAddress + opAddress);
-
-                (InstEmitter emitter, OpCodeTable.MakeOp makeOp) = OpCodeTable.GetEmitter(opCode);
-
-                if (emitter == null)
+                if (bufferOffset >= buffer.Length)
                 {
-                    // TODO: Warning, illegal encoding.
-
-                    block.OpCodes.Add(new OpCode(null, opAddress, opCode));
-
-                    continue;
+                    buffer = gpuAccessor.GetCode(startAddress + address, 8);
+                    bufferOffset = 0;
                 }
 
-                if (makeOp == null)
-                {
-                    throw new ArgumentNullException(nameof(makeOp));
-                }
+                ulong opCode = buffer[bufferOffset++];
 
-                OpCode op = makeOp(emitter, opAddress, opCode);
+                op = InstTable.GetOp(address, opCode);
 
-                // We check these patterns to figure out the presence of bindless access
-                if ((op is OpCodeImage image && image.IsBindless) ||
-                    (op is OpCodeTxd txd && txd.IsBindless) ||
-                    (op is OpCodeTld4B) ||
-                    (emitter == InstEmit.TexB) ||
-                    (emitter == InstEmit.TldB) ||
-                    (emitter == InstEmit.TmmlB) ||
-                    (emitter == InstEmit.TxqB))
+                if (op.Props.HasFlag(InstProps.TexB))
                 {
                     config.SetUsedFeature(FeatureFlags.Bindless);
                 }
 
-                // Populate used attributes.
-                if (op is IOpCodeAttribute opAttr)
+                if (op.Name == InstName.Ald || op.Name == InstName.Ast || op.Name == InstName.Ipa)
                 {
-                    SetUserAttributeUses(config, opAttr);
+                    SetUserAttributeUses(config, op.Name, opCode);
+                }
+                else if (op.Name == InstName.Ssy || op.Name == InstName.Pbk)
+                {
+                    block.AddPushOp(op);
                 }
 
                 block.OpCodes.Add(op);
+
+                address += 8;
             }
-            while (!IsControlFlowChange(block.GetLastOp()));
+            while (!op.Props.HasFlag(InstProps.Bra));
 
             block.EndAddress = address;
-
-            block.UpdatePushOps();
         }
 
-        private static void SetUserAttributeUses(ShaderConfig config, IOpCodeAttribute opAttr)
+        private static void SetUserAttributeUses(ShaderConfig config, InstName name, ulong opCode)
         {
-            if (opAttr.Indexed)
+            int offset;
+            int count = 1;
+            bool isStore = false;
+            bool indexed = false;
+
+            if (name == InstName.Ast)
             {
-                if (opAttr.Emitter == InstEmit.Ast)
+                InstAst opAst = new InstAst(opCode);
+                count = (int)opAst.AlSize + 1;
+                offset = opAst.Imm11;
+                indexed = opAst.Phys;
+                isStore = true;
+            }
+            else if (name == InstName.Ald)
+            {
+                InstAld opAld = new InstAld(opCode);
+                count = (int)opAld.AlSize + 1;
+                indexed = opAld.Phys;
+                offset = opAld.Imm11;
+            }
+            else /* if (name == InstName.Ipa) */
+            {
+                InstIpa opIpa = new InstIpa(opCode);
+                offset = opIpa.Imm10;
+                indexed = opIpa.Idx;
+            }
+
+            if (indexed)
+            {
+                if (isStore)
                 {
                     config.SetAllOutputUserAttributes();
                 }
@@ -309,14 +298,14 @@ namespace Ryujinx.Graphics.Shader.Decoders
             }
             else
             {
-                for (int elemIndex = 0; elemIndex < opAttr.Count; elemIndex++)
+                for (int elemIndex = 0; elemIndex < count; elemIndex++)
                 {
-                    int attr = opAttr.AttributeOffset + elemIndex * 4;
+                    int attr = offset + elemIndex * 4;
                     if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd)
                     {
                         int index = (attr - AttributeConsts.UserAttributeBase) / 16;
 
-                        if (opAttr.Emitter == InstEmit.Ast)
+                        if (isStore)
                         {
                             config.SetOutputUserAttribute(index);
                         }
@@ -329,27 +318,57 @@ namespace Ryujinx.Graphics.Shader.Decoders
             }
         }
 
-        private static bool IsUnconditionalBranch(OpCode opCode)
+        public static bool IsUnconditionalBranch(ref InstOp op)
         {
-            return IsUnconditional(opCode) && IsControlFlowChange(opCode);
+            return IsUnconditional(ref op) && op.Props.HasFlag(InstProps.Bra);
         }
 
-        private static bool IsUnconditional(OpCode opCode)
+        private static bool IsUnconditional(ref InstOp op)
         {
-            if (opCode is OpCodeExit op && op.Condition != Condition.Always)
+            InstConditional condOp = new InstConditional(op.RawOpCode);
+
+            if (op.Name == InstName.Exit && condOp.Ccc != Ccc.T)
             {
                 return false;
             }
 
-            return opCode.Predicate.Index == RegisterConsts.PredicateTrueIndex && !opCode.InvertPredicate;
+            return condOp.Pred == RegisterConsts.PredicateTrueIndex && !condOp.PredInv;
         }
 
-        private static bool IsControlFlowChange(OpCode opCode)
+        private static bool FindBrxTargets(ShaderConfig config, IEnumerable<Block> blocks, Func<ulong, Block> getBlock)
         {
-            return (opCode is OpCodeBranch opBranch && !opBranch.PushTarget) ||
-                    opCode is OpCodeBranchIndir                              ||
-                    opCode is OpCodeBranchPop                                ||
-                    opCode is OpCodeExit;
+            bool hasNewTarget = false;
+
+            foreach (Block block in blocks)
+            {
+                InstOp lastOp = block.GetLastOp();
+                bool hasNext = block.HasNext();
+
+                if (lastOp.Name == InstName.Brx && block.Successors.Count == (hasNext ? 1 : 0))
+                {
+                    InstBrx opBrx = new InstBrx(lastOp.RawOpCode);
+                    ulong baseOffset = lastOp.GetAbsoluteAddress();
+
+                    // An indirect branch could go anywhere,
+                    // try to get the possible target offsets from the constant buffer.
+                    (int cbBaseOffset, int cbOffsetsCount) = FindBrxTargetRange(block, opBrx.SrcA);
+
+                    if (cbOffsetsCount != 0)
+                    {
+                        hasNewTarget = true;
+                    }
+
+                    for (int i = 0; i < cbOffsetsCount; i++)
+                    {
+                        uint targetOffset = config.GpuAccessor.ConstantBuffer1Read(cbBaseOffset + i * 4);
+                        Block target = getBlock(baseOffset + targetOffset);
+                        target.Predecessors.Add(block);
+                        block.Successors.Add(target);
+                    }
+                }
+            }
+
+            return hasNewTarget;
         }
 
         private static (int, int) FindBrxTargetRange(Block block, int brxReg)
@@ -369,41 +388,51 @@ namespace Ryujinx.Graphics.Shader.Decoders
             HashSet<Block> visited = new HashSet<Block>();
 
             var ldcLocation = FindFirstRegWrite(visited, new BlockLocation(block, block.OpCodes.Count - 1), brxReg);
-            if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index] is not OpCodeLdc opLdc)
+            if (ldcLocation.Block == null || ldcLocation.Block.OpCodes[ldcLocation.Index].Name != InstName.Ldc)
             {
                 return (0, 0);
             }
 
-            if (opLdc.Slot != 1 || opLdc.IndexMode != CbIndexMode.Default)
+            GetOp<InstLdc>(ldcLocation, out var opLdc);
+
+            if (opLdc.CbufSlot != 1 || opLdc.AddressMode != 0)
             {
                 return (0, 0);
             }
 
-            var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.Ra.Index);
-            if (shlLocation.Block == null || shlLocation.Block.OpCodes[shlLocation.Index] is not OpCodeAluImm opShl)
+            var shlLocation = FindFirstRegWrite(visited, ldcLocation, opLdc.SrcA);
+            if (shlLocation.Block == null || !shlLocation.IsImmInst(InstName.Shl))
             {
                 return (0, 0);
             }
 
-            if (opShl.Emitter != InstEmit.Shl || opShl.Immediate != 2)
+            GetOp<InstShlI>(shlLocation, out var opShl);
+
+            if (opShl.Imm20 != 2)
             {
                 return (0, 0);
             }
 
-            var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.Ra.Index);
-            if (imnmxLocation.Block == null || imnmxLocation.Block.OpCodes[imnmxLocation.Index] is not OpCodeAluImm opImnmx)
+            var imnmxLocation = FindFirstRegWrite(visited, shlLocation, opShl.SrcA);
+            if (imnmxLocation.Block == null || !imnmxLocation.IsImmInst(InstName.Imnmx))
             {
                 return (0, 0);
             }
 
-            bool isImnmxS32 = opImnmx.RawOpCode.Extract(48);
+            GetOp<InstImnmxI>(imnmxLocation, out var opImnmx);
 
-            if (opImnmx.Emitter != InstEmit.Imnmx || isImnmxS32 || !opImnmx.Predicate39.IsPT || opImnmx.InvertP)
+            if (opImnmx.Signed || opImnmx.SrcPred != RegisterConsts.PredicateTrueIndex || opImnmx.SrcPredInv)
             {
                 return (0, 0);
             }
 
-            return (opLdc.Offset, opImnmx.Immediate + 1);
+            return (opLdc.CbufOffset, opImnmx.Imm20 + 1);
+        }
+
+        private static void GetOp<T>(BlockLocation location, out T op) where T : unmanaged
+        {
+            ulong rawOp = location.Block.OpCodes[location.Index].RawOpCode;
+            op = Unsafe.As<ulong, T>(ref rawOp);
         }
 
         private struct BlockLocation
@@ -416,6 +445,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
                 Block = block;
                 Index = index;
             }
+
+            public bool IsImmInst(InstName name)
+            {
+                InstOp op = Block.OpCodes[Index];
+                return op.Name == name && op.Props.HasFlag(InstProps.Ib);
+            }
         }
 
         private static BlockLocation FindFirstRegWrite(HashSet<Block> visited, BlockLocation location, int regIndex)
@@ -447,18 +482,20 @@ namespace Ryujinx.Graphics.Shader.Decoders
             return new BlockLocation(null, 0);
         }
 
-        private static bool WritesToRegister(OpCode opCode, int regIndex)
+        private static bool WritesToRegister(InstOp op, int regIndex)
         {
             // Predicate instruction only ever writes to predicate, so we shouldn't check those.
-            if (opCode.Emitter == InstEmit.Fsetp ||
-                opCode.Emitter == InstEmit.Hsetp2 ||
-                opCode.Emitter == InstEmit.Isetp ||
-                opCode.Emitter == InstEmit.R2p)
+            if ((op.Props & (InstProps.Rd | InstProps.Rd2)) == 0)
             {
                 return false;
             }
 
-            return opCode is IOpCodeRd opRd && opRd.Rd.Index == regIndex;
+            if (op.Props.HasFlag(InstProps.Rd2) && (byte)(op.RawOpCode >> 28) == regIndex)
+            {
+                return true;
+            }
+
+            return (byte)op.RawOpCode == regIndex;
         }
 
         private enum MergeType
@@ -527,14 +564,13 @@ namespace Ryujinx.Graphics.Shader.Decoders
 
         private static void PropagatePushOp(Dictionary<ulong, Block> blocks, Block currBlock, int pushOpIndex)
         {
-            OpCodePush pushOp = currBlock.PushOpCodes[pushOpIndex];
+            PushOpInfo pushOpInfo = currBlock.PushOpCodes[pushOpIndex];
+            InstOp pushOp = pushOpInfo.Op;
 
             Block target = blocks[pushOp.GetAbsoluteAddress()];
 
             Stack<PathBlockState> workQueue = new Stack<PathBlockState>();
-
             HashSet<Block> visited = new HashSet<Block>();
-
             Stack<(ulong, MergeType)> branchStack = new Stack<(ulong, MergeType)>();
 
             void Push(PathBlockState pbs)
@@ -574,42 +610,30 @@ namespace Ryujinx.Graphics.Shader.Decoders
                 }
 
                 int pushOpsCount = current.PushOpCodes.Count;
-
                 if (pushOpsCount != 0)
                 {
                     Push(new PathBlockState(branchStack.Count));
 
                     for (int index = pushOpIndex; index < pushOpsCount; index++)
                     {
-                        OpCodePush currentPushOp = current.PushOpCodes[index];
-                        MergeType pushMergeType = currentPushOp.Emitter == InstEmit.Ssy ? MergeType.Sync : MergeType.Brk;
+                        InstOp currentPushOp = current.PushOpCodes[index].Op;
+                        MergeType pushMergeType = currentPushOp.Name == InstName.Ssy ? MergeType.Sync : MergeType.Brk;
                         branchStack.Push((currentPushOp.GetAbsoluteAddress(), pushMergeType));
                     }
                 }
 
                 pushOpIndex = 0;
 
-                if (current.Next != null)
+                bool hasNext = current.HasNext();
+                if (hasNext)
                 {
-                    Push(new PathBlockState(current.Next));
+                    Push(new PathBlockState(current.Successors[0]));
                 }
 
-                if (current.Branch != null)
+                InstOp lastOp = current.GetLastOp();
+                if (lastOp.Name == InstName.Sync || lastOp.Name == InstName.Brk)
                 {
-                    Push(new PathBlockState(current.Branch));
-                }
-                else if (current.GetLastOp() is OpCodeBranchIndir brIndir)
-                {
-                    // By adding them in descending order (sorted by address), we process the blocks
-                    // in order (of ascending address), since we work with a LIFO.
-                    foreach (Block possibleTarget in brIndir.PossibleTargets.OrderByDescending(x => x.Address))
-                    {
-                        Push(new PathBlockState(possibleTarget));
-                    }
-                }
-                else if (current.GetLastOp() is OpCodeBranchPop op)
-                {
-                    MergeType popMergeType = op.Emitter == InstEmit.Sync ? MergeType.Sync : MergeType.Brk;
+                    MergeType popMergeType = lastOp.Name == InstName.Sync ? MergeType.Sync : MergeType.Brk;
 
                     bool found = true;
                     ulong targetAddress = 0UL;
@@ -641,20 +665,32 @@ namespace Ryujinx.Graphics.Shader.Decoders
                         {
                             // If the entire stack was consumed, then the current pop instruction
                             // just consumed the address from our push instruction.
-                            if (op.Targets.TryAdd(pushOp, op.Targets.Count))
+                            if (current.SyncTargets.TryAdd(pushOp.Address, new SyncTarget(pushOpInfo, current.SyncTargets.Count)))
                             {
-                                pushOp.PopOps.Add(op, Local());
+                                pushOpInfo.Consumers.Add(current, Local());
                                 target.Predecessors.Add(current);
+                                current.Successors.Add(target);
                             }
                         }
                         else
                         {
-                            // Push the block itself into the work "queue" (well, it's a stack)
-                            // for processing.
+                            // Push the block itself into the work queue for processing.
                             Push(new PathBlockState(blocks[targetAddress]));
                         }
                     }
                 }
+                else
+                {
+                    // By adding them in descending order (sorted by address), we process the blocks
+                    // in order (of ascending address), since we work with a LIFO.
+                    foreach (Block possibleTarget in current.Successors.OrderByDescending(x => x.Address))
+                    {
+                        if (!hasNext || possibleTarget != current.Successors[0])
+                        {
+                            Push(new PathBlockState(possibleTarget));
+                        }
+                    }
+                }
             }
         }
     }
diff --git a/Ryujinx.Graphics.Shader/Decoders/DecoderHelper.cs b/Ryujinx.Graphics.Shader/Decoders/DecoderHelper.cs
deleted file mode 100644
index 3585c35fa4..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/DecoderHelper.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    static class DecoderHelper
-    {
-        public static int DecodeS20Immediate(long opCode)
-        {
-            int imm = opCode.Extract(20, 19);
-
-            bool sign = opCode.Extract(56);
-
-            if (sign)
-            {
-                imm = (imm << 13) >> 13;
-            }
-
-            return imm;
-        }
-
-        public static int Decode2xF10Immediate(long opCode)
-        {
-            int immH0 = opCode.Extract(20, 9);
-            int immH1 = opCode.Extract(30, 9);
-
-            bool negateH0 = opCode.Extract(29);
-            bool negateH1 = opCode.Extract(56);
-
-            if (negateH0)
-            {
-                immH0 |= 1 << 9;
-            }
-
-            if (negateH1)
-            {
-                immH1 |= 1 << 9;
-            }
-
-            return immH1 << 22 | immH0 << 6;
-        }
-
-        public static float DecodeF20Immediate(long opCode)
-        {
-            int imm = opCode.Extract(20, 19);
-
-            bool negate = opCode.Extract(56);
-
-            imm <<= 12;
-
-            if (negate)
-            {
-                imm |= 1 << 31;
-            }
-
-            return BitConverter.Int32BitsToSingle(imm);
-        }
-
-        public static float DecodeD20Immediate(long opCode)
-        {
-            long imm = opCode.Extract(20, 19);
-
-            bool negate = opCode.Extract(56);
-
-            imm <<= 44;
-
-            if (negate)
-            {
-                imm |= 1L << 63;
-            }
-
-            return (float)BitConverter.Int64BitsToDouble(imm);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/FPHalfSwizzle.cs b/Ryujinx.Graphics.Shader/Decoders/FPHalfSwizzle.cs
deleted file mode 100644
index 3ddf17cfcc..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/FPHalfSwizzle.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum FPHalfSwizzle
-    {
-        FP16  = 0,
-        FP32  = 1,
-        DupH0 = 2,
-        DupH1 = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/FPMultiplyScale.cs b/Ryujinx.Graphics.Shader/Decoders/FPMultiplyScale.cs
deleted file mode 100644
index 398c0e66f7..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/FPMultiplyScale.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum FPMultiplyScale
-    {
-        None      = 0,
-        Divide2   = 1,
-        Divide4   = 2,
-        Divide8   = 3,
-        Multiply8 = 4,
-        Multiply4 = 5,
-        Multiply2 = 6
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/FPType.cs b/Ryujinx.Graphics.Shader/Decoders/FPType.cs
deleted file mode 100644
index b5af2c1d24..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/FPType.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum FPType
-    {
-        FP16 = 1,
-        FP32 = 2,
-        FP64 = 3
-    }
-
-    static class FPTypeExtensions
-    {
-        public static Instruction ToInstFPType(this FPType type)
-        {
-            return type == FPType.FP64 ? Instruction.FP64 : Instruction.FP32;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCode.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCode.cs
deleted file mode 100644
index dd6ad79a2e..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCode.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCode
-    {
-        InstEmitter Emitter { get; }
-
-        ulong Address   { get; }
-        long  RawOpCode { get; }
-
-        Register Predicate { get; }
-
-        bool InvertPredicate { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeAlu.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeAlu.cs
deleted file mode 100644
index 6d1382a8a3..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeAlu.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeAlu : IOpCodeRd, IOpCodeRa, IOpCodePredicate39
-    {
-        bool Extended    { get; }
-        bool SetCondCode { get; }
-        bool Saturate    { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
deleted file mode 100644
index 2b6835bea7..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeAttribute.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeAttribute : IOpCode
-    {
-        int AttributeOffset { get; }
-        int Count { get; }
-        bool Indexed { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeCbuf.cs
deleted file mode 100644
index 42a174514c..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeCbuf.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeCbuf : IOpCode
-    {
-        int Offset { get; }
-        int Slot   { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeFArith.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeFArith.cs
deleted file mode 100644
index 3d06eae0d0..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeFArith.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeFArith : IOpCodeAlu
-    {
-        RoundingMode RoundingMode { get; }
-
-        FPMultiplyScale Scale { get; }
-
-        bool FlushToZero { get; }
-        bool AbsoluteA   { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeHfma.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeHfma.cs
deleted file mode 100644
index 4638f66086..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeHfma.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeHfma : IOpCode
-    {
-        bool NegateB  { get; }
-        bool NegateC  { get; }
-        bool Saturate { get; }
-
-        FPHalfSwizzle SwizzleA { get; }
-        FPHalfSwizzle SwizzleB { get; }
-        FPHalfSwizzle SwizzleC { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeImm.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeImm.cs
deleted file mode 100644
index 9cfcd69b05..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeImm.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeImm : IOpCode
-    {
-        int Immediate { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeImmF.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeImmF.cs
deleted file mode 100644
index 629eff7973..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeImmF.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeImmF : IOpCode
-    {
-        float Immediate { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeLop.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeLop.cs
deleted file mode 100644
index 62c87bf435..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeLop.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeLop : IOpCodeAlu
-    {
-        LogicalOperation LogicalOp { get; }
-
-        bool InvertA { get; }
-        bool InvertB { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodePredicate39.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodePredicate39.cs
deleted file mode 100644
index 74e7aff134..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodePredicate39.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodePredicate39
-    {
-        Register Predicate39 { get; }
-
-        bool InvertP { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRa.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeRa.cs
deleted file mode 100644
index e5902110e5..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRa.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeRa : IOpCode
-    {
-        Register Ra { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRc.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeRc.cs
deleted file mode 100644
index bb806b95c9..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRc.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeRc : IOpCode
-    {
-        Register Rc { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRd.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeRd.cs
deleted file mode 100644
index 099c4061ab..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRd.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeRd : IOpCode
-    {
-        Register Rd { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeReg.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeReg.cs
deleted file mode 100644
index 3ed157e821..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeReg.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeReg : IOpCode
-    {
-        Register Rb { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRegCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeRegCbuf.cs
deleted file mode 100644
index 429f01bb7f..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeRegCbuf.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeRegCbuf : IOpCodeRc
-    {
-        int Offset { get; }
-        int Slot   { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs
deleted file mode 100644
index eb83544954..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeTexture.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeTexture : IOpCode
-    {
-        Register Rd { get; }
-        Register Ra { get; }
-        Register Rb { get; }
-
-        bool IsArray { get; }
-
-        TextureDimensions Dimensions { get; }
-
-        int ComponentMask { get; }
-
-        int HandleOffset { get; }
-
-        TextureLodMode LodMode { get; }
-
-        bool HasOffset       { get; }
-        bool HasDepthCompare { get; }
-        bool IsMultisample   { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs b/Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs
deleted file mode 100644
index 219d00cbf7..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IOpCodeTld4.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    interface IOpCodeTld4 : IOpCodeTexture
-    {
-        TextureGatherOffset Offset { get; }
-
-        int GatherCompIndex { get; }
-
-        bool Bindless { get; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs b/Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs
deleted file mode 100644
index 348a4768c9..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/ImageComponents.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum ImageComponents
-    {
-        Red   = 1 << 0,
-        Green = 1 << 1,
-        Blue  = 1 << 2,
-        Alpha = 1 << 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/ImageDimensions.cs b/Ryujinx.Graphics.Shader/Decoders/ImageDimensions.cs
deleted file mode 100644
index ecf41a82fc..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/ImageDimensions.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum ImageDimensions
-    {
-        Image1D,
-        ImageBuffer,
-        Image1DArray,
-        Image2D,
-        Image2DArray,
-        Image3D
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs b/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
new file mode 100644
index 0000000000..5e7c40f4bc
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
@@ -0,0 +1,5362 @@
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+    enum AlSize
+    {
+        _32 = 0,
+        _64 = 1,
+        _96 = 2,
+        _128 = 3,
+    }
+
+    enum AtomSize
+    {
+        U32 = 0,
+        S32 = 1,
+        U64 = 2,
+        F32FtzRn = 3,
+        F16x2FtzRn = 4,
+        S64 = 5,
+    }
+
+    enum AtomOp
+    {
+        Add = 0,
+        Min = 1,
+        Max = 2,
+        Inc = 3,
+        Dec = 4,
+        And = 5,
+        Or = 6,
+        Xor = 7,
+        Exch = 8,
+        Safeadd = 10,
+    }
+
+    enum AtomsSize
+    {
+        U32 = 0,
+        S32 = 1,
+        U64 = 2,
+        S64 = 3,
+    }
+
+    enum BarMode
+    {
+        Bar = 0,
+        Result = 1,
+        Warp = 2,
+    }
+
+    enum BarOp
+    {
+        Sync = 0,
+        Arv = 1,
+        Red = 2,
+        Scan = 3,
+        SyncAll = 4,
+    }
+
+    enum BarRedOp
+    {
+        Popc = 0,
+        And = 1,
+        Or = 2,
+    }
+
+    enum Bpt
+    {
+        DrainIllegal = 0,
+        Cal = 1,
+        Pause = 2,
+        Trap = 3,
+        Int = 4,
+        Drain = 5,
+    }
+
+    enum Ccc
+    {
+        F = 0,
+        Lt = 1,
+        Eq = 2,
+        Le = 3,
+        Gt = 4,
+        Ne = 5,
+        Ge = 6,
+        Num = 7,
+        Nan = 8,
+        Ltu = 9,
+        Equ = 10,
+        Leu = 11,
+        Gtu = 12,
+        Neu = 13,
+        Geu = 14,
+        T = 15,
+        Lo = 17,
+        Sff = 18,
+        Ls = 19,
+        Hi = 20,
+        Sft = 21,
+        Hs = 22,
+        Oft = 23,
+        CsmTa = 24,
+        CsmTr = 25,
+        CsmMx = 26,
+        FcsmTa = 27,
+        FcsmTr = 28,
+        FcsmMx = 29,
+        Rle = 30,
+        Rgt = 31,
+    }
+
+    enum CacheType
+    {
+        U = 1,
+        C = 2,
+        I = 3,
+        Crs = 4,
+    }
+
+    enum CctlOp
+    {
+        Pf1 = 1,
+        Pf1_5 = 2,
+        Pf2 = 3,
+        Wb = 4,
+        Iv = 5,
+        Ivall = 6,
+        Rs = 7,
+        Rslb = 9,
+    }
+
+    enum CctltOp
+    {
+        Ivth = 1,
+    }
+
+    enum BoolOp
+    {
+        And = 0,
+        Or = 1,
+        Xor = 2,
+    }
+
+    enum SReg
+    {
+        LaneId = 0,
+        Clock = 1,
+        VirtCfg = 2,
+        VirtId = 3,
+        Pm0 = 4,
+        Pm1 = 5,
+        Pm2 = 6,
+        Pm3 = 7,
+        Pm4 = 8,
+        Pm5 = 9,
+        Pm6 = 10,
+        Pm7 = 11,
+        OrderingTicket = 15,
+        PrimType = 16,
+        InvocationId = 17,
+        YDirection = 18,
+        ThreadKill = 19,
+        ShaderType = 20,
+        DirectCbeWriteAddressLow = 21,
+        DirectCbeWriteAddressHigh = 22,
+        DirectCbeWriteEnabled = 23,
+        MachineId0 = 24,
+        MachineId1 = 25,
+        MachineId2 = 26,
+        MachineId3 = 27,
+        Affinity = 28,
+        InvocationInfo = 29,
+        WScaleFactorXY = 30,
+        WScaleFactorZ = 31,
+        TId = 32,
+        TIdX = 33,
+        TIdY = 34,
+        TIdZ = 35,
+        CtaParam = 36,
+        CtaIdX = 37,
+        CtaIdY = 38,
+        CtaIdZ = 39,
+        Ntid = 40,
+        CirQueueIncrMinusOne = 41,
+        Nlatc = 42,
+        Swinlo = 48,
+        Swinsz = 49,
+        Smemsz = 50,
+        Smembanks = 51,
+        LWinLo = 52,
+        LWinSz = 53,
+        LMemLoSz = 54,
+        LMemHiOff = 55,
+        EqMask = 56,
+        LtMask = 57,
+        LeMask = 58,
+        GtMask = 59,
+        GeMask = 60,
+        RegAlloc = 61,
+        CtxAddr = 62,
+        GlobalErrorStatus = 64,
+        WarpErrorStatus = 66,
+        WarpErrorStatusClear = 67,
+        PmHi0 = 72,
+        PmHi1 = 73,
+        PmHi2 = 74,
+        PmHi3 = 75,
+        PmHi4 = 76,
+        PmHi5 = 77,
+        PmHi6 = 78,
+        PmHi7 = 79,
+        ClockLo = 80,
+        ClockHi = 81,
+        GlobalTimerLo = 82,
+        GlobalTimerHi = 83,
+        HwTaskId = 96,
+        CircularQueueEntryIndex = 97,
+        CircularQueueEntryAddressLow = 98,
+        CircularQueueEntryAddressHigh = 99,
+    }
+
+    enum RoundMode
+    {
+        Rn = 0,
+        Rm = 1,
+        Rp = 2,
+        Rz = 3,
+    }
+
+    enum FComp
+    {
+        F = 0,
+        Lt = 1,
+        Eq = 2,
+        Le = 3,
+        Gt = 4,
+        Ne = 5,
+        Ge = 6,
+        Num = 7,
+        Nan = 8,
+        Ltu = 9,
+        Equ = 10,
+        Leu = 11,
+        Gtu = 12,
+        Neu = 13,
+        Geu = 14,
+        T = 15,
+    }
+
+    enum IntegerRound
+    {
+        Pass = 1,
+        Round = 4,
+        Floor = 5,
+        Ceil = 6,
+        Trunc = 7,
+    }
+
+    enum IDstFmt
+    {
+        U16 = 1,
+        U32 = 2,
+        U64 = 3,
+        S16 = 5,
+        S32 = 6,
+        S64 = 7,
+    }
+
+    enum ISrcFmt
+    {
+        U8 = 0,
+        U16 = 1,
+        U32 = 2,
+        U64 = 3,
+        S8 = 4,
+        S16 = 5,
+        S32 = 6,
+        S64 = 7,
+    }
+
+    enum RoundMode2
+    {
+        Round = 0,
+        Floor = 1,
+        Ceil = 2,
+        Trunc = 3,
+    }
+
+    enum ChkModeF
+    {
+        Divide = 0,
+    }
+
+    enum Fmz
+    {
+        Ftz = 1,
+        Fmz = 2,
+    }
+
+    enum MultiplyScale
+    {
+        NoScale = 0,
+        D2 = 1,
+        D4 = 2,
+        D8 = 3,
+        M8 = 4,
+        M4 = 5,
+        M2 = 6,
+    }
+
+    enum OFmt
+    {
+        F16 = 0,
+        F32 = 1,
+        MrgH0 = 2,
+        MrgH1 = 3,
+    }
+
+    enum HalfSwizzle
+    {
+        F16 = 0,
+        F32 = 1,
+        H0H0 = 2,
+        H1H1 = 3,
+    }
+
+    enum ByteSel
+    {
+        B0 = 0,
+        B1 = 1,
+        B2 = 2,
+        B3 = 3,
+    }
+
+    enum DstFmt
+    {
+        F16 = 1,
+        F32 = 2,
+        F64 = 3,
+    }
+
+    enum AvgMode
+    {
+        NoNeg = 0,
+        NegB = 1,
+        NegA = 2,
+        PlusOne = 3,
+    }
+
+    enum Lrs
+    {
+        None = 0,
+        RightShift = 1,
+        LeftShift = 2,
+    }
+
+    enum HalfSelect
+    {
+        B32 = 0,
+        H0 = 1,
+        H1 = 2,
+    }
+
+    enum IComp
+    {
+        F = 0,
+        Lt = 1,
+        Eq = 2,
+        Le = 3,
+        Gt = 4,
+        Ne = 5,
+        Ge = 6,
+        T = 7,
+    }
+
+    enum XMode
+    {
+        Xlo = 1,
+        Xmed = 2,
+        Xhi = 3,
+    }
+
+    enum IpaOp
+    {
+        Pass = 0,
+        Multiply = 1,
+        Constant = 2,
+        Sc = 3,
+    }
+
+    enum IBase
+    {
+        Patch = 1,
+        Prim = 2,
+        Attr = 3,
+    }
+
+    enum CacheOp
+    {
+        Cg = 1,
+        Ci = 2,
+        Cv = 3,
+    }
+
+    enum LsSize
+    {
+        U8 = 0,
+        S8 = 1,
+        U16 = 2,
+        S16 = 3,
+        B32 = 4,
+        B64 = 5,
+        B128 = 6,
+        UB128 = 7,
+    }
+
+    enum LsSize2
+    {
+        U8 = 0,
+        S8 = 1,
+        U16 = 2,
+        S16 = 3,
+        B32 = 4,
+        B64 = 5,
+        B128 = 6,
+    }
+
+    enum AddressMode
+    {
+        Il = 1,
+        Is = 2,
+        Isl = 3,
+    }
+
+    enum CacheOp2
+    {
+        Lu = 1,
+        Ci = 2,
+        Cv = 3,
+    }
+
+    enum PredicateOp
+    {
+        F = 0,
+        T = 1,
+        Z = 2,
+        Nz = 3,
+    }
+
+    enum LogicOp
+    {
+        And = 0,
+        Or = 1,
+        Xor = 2,
+        PassB = 3,
+    }
+
+    enum Membar
+    {
+        Cta = 0,
+        Gl = 1,
+        Sys = 2,
+        Vc = 3,
+    }
+
+    enum Ivall
+    {
+        Ivalld = 1,
+        Ivallt = 2,
+        Ivalltd = 3,
+    }
+
+    enum MufuOp
+    {
+        Cos = 0,
+        Sin = 1,
+        Ex2 = 2,
+        Lg2 = 3,
+        Rcp = 4,
+        Rsq = 5,
+        Rcp64h = 6,
+        Rsq64h = 7,
+        Sqrt = 8,
+    }
+
+    enum OutType
+    {
+        Emit = 1,
+        Cut = 2,
+        EmitThenCut = 3,
+    }
+
+    enum PixMode
+    {
+        Covmask = 1,
+        Covered = 2,
+        Offset = 3,
+        CentroidOffset = 4,
+        MyIndex = 5,
+    }
+
+    enum PMode
+    {
+        F4e = 1,
+        B4e = 2,
+        Rc8 = 3,
+        Ecl = 4,
+        Ecr = 5,
+        Rc16 = 6,
+    }
+
+    enum RedOp
+    {
+        Add = 0,
+        Min = 1,
+        Max = 2,
+        Inc = 3,
+        Dec = 4,
+        And = 5,
+        Or = 6,
+        Xor = 7,
+    }
+
+    enum XModeShf
+    {
+        Hi = 1,
+        X = 2,
+        Xhi = 3,
+    }
+
+    enum MaxShift
+    {
+        U64 = 2,
+        S64 = 3,
+    }
+
+    enum ShflMode
+    {
+        Idx = 0,
+        Up = 1,
+        Down = 2,
+        Bfly = 3,
+    }
+
+    enum Clamp
+    {
+        Ign = 0,
+        Trap = 2,
+    }
+
+    enum SuatomSize
+    {
+        U32 = 0,
+        S32 = 1,
+        U64 = 2,
+        F32FtzRn = 3,
+        F16x2FtzRn = 4,
+        S64 = 5,
+        Sd32 = 6,
+        Sd64 = 7,
+    }
+
+    enum SuDim
+    {
+        _1d = 0,
+        _1dBuffer = 1,
+        _1dArray = 2,
+        _2d = 3,
+        _2dArray = 4,
+        _3d = 5,
+    }
+
+    enum SuatomOp
+    {
+        Add = 0,
+        Min = 1,
+        Max = 2,
+        Inc = 3,
+        Dec = 4,
+        And = 5,
+        Or = 6,
+        Xor = 7,
+        Exch = 8,
+    }
+
+    enum SuSize
+    {
+        U8 = 0,
+        S8 = 1,
+        U16 = 2,
+        S16 = 3,
+        B32 = 4,
+        B64 = 5,
+        B128 = 6,
+        UB128 = 7,
+    }
+
+    enum SuRgba
+    {
+        R = 1,
+        G = 2,
+        Rg = 3,
+        B = 4,
+        Rb = 5,
+        Gb = 6,
+        Rgb = 7,
+        A = 8,
+        Ra = 9,
+        Ga = 10,
+        Rga = 11,
+        Ba = 12,
+        Rba = 13,
+        Gba = 14,
+        Rgba = 15,
+    }
+
+    enum Lod
+    {
+        Lz = 1,
+        Lb = 2,
+        Ll = 3,
+        Lba = 6,
+        Lla = 7,
+    }
+
+    enum TexDim
+    {
+        _1d = 0,
+        Array1d = 1,
+        _2d = 2,
+        Array2d = 3,
+        _3d = 4,
+        Array3d = 5,
+        Cube = 6,
+        ArrayCube = 7,
+    }
+
+    enum TexsTarget
+    {
+        Texture1DLodZero = 0,
+        Texture2D = 1,
+        Texture2DLodZero = 2,
+        Texture2DLodLevel = 3,
+        Texture2DDepthCompare = 4,
+        Texture2DLodLevelDepthCompare = 5,
+        Texture2DLodZeroDepthCompare = 6,
+        Texture2DArray = 7,
+        Texture2DArrayLodZero = 8,
+        Texture2DArrayLodZeroDepthCompare = 9,
+        Texture3D = 10,
+        Texture3DLodZero = 11,
+        TextureCube = 12,
+        TextureCubeLodLevel = 13,
+    }
+
+    enum TldsTarget
+    {
+        Texture1DLodZero = 0x0,
+        Texture1DLodLevel = 0x1,
+        Texture2DLodZero = 0x2,
+        Texture2DLodZeroOffset = 0x4,
+        Texture2DLodLevel = 0x5,
+        Texture2DLodZeroMultisample = 0x6,
+        Texture3DLodZero = 0x7,
+        Texture2DArrayLodZero = 0x8,
+        Texture2DLodLevelOffset = 0xc
+    }
+
+    enum TexComp
+    {
+        R = 0,
+        G = 1,
+        B = 2,
+        A = 3,
+    }
+
+    enum TexOffset
+    {
+        None = 0,
+        Aoffi = 1,
+        Ptp = 2,
+    }
+
+    enum TexQuery
+    {
+        TexHeaderDimension = 1,
+        TexHeaderTextureType = 2,
+        TexHeaderSamplerPos = 5,
+        TexSamplerFilter = 16,
+        TexSamplerLod = 18,
+        TexSamplerWrap = 20,
+        TexSamplerBorderColor = 22,
+    }
+
+    enum VectorSelect
+    {
+        U8B0 = 0,
+        U8B1 = 1,
+        U8B2 = 2,
+        U8B3 = 3,
+        U16H0 = 4,
+        U16H1 = 5,
+        U32 = 6,
+        S8B0 = 8,
+        S8B1 = 9,
+        S8B2 = 10,
+        S8B3 = 11,
+        S16H0 = 12,
+        S16H1 = 13,
+        S32 = 14,
+    }
+
+    enum VideoOp
+    {
+        Mrg16h = 0,
+        Mrg16l = 1,
+        Mrg8b0 = 2,
+        Mrg8b2 = 3,
+        Acc = 4,
+        Min = 5,
+        Max = 6,
+    }
+
+    enum VideoRed
+    {
+        Acc = 1,
+    }
+
+    enum LaneMask4
+    {
+        Z = 1,
+        W = 2,
+        Zw = 3,
+        X = 4,
+        Xz = 5,
+        Xw = 6,
+        Xzw = 7,
+        Y = 8,
+        Yz = 9,
+        Yw = 10,
+        Yzw = 11,
+        Xy = 12,
+        Xyz = 13,
+        Xyw = 14,
+        Xyzw = 15,
+    }
+
+    enum ASelect4
+    {
+        _0000 = 0,
+        _1111 = 1,
+        _2222 = 2,
+        _3333 = 3,
+        _3210 = 4,
+        _5432 = 6,
+        _6543 = 7,
+        _3201 = 8,
+        _3012 = 9,
+        _0213 = 10,
+        _3120 = 11,
+        _1230 = 12,
+        _2310 = 13,
+    }
+
+    enum BSelect4
+    {
+        _4444 = 0,
+        _5555 = 1,
+        _6666 = 2,
+        _7777 = 3,
+        _7654 = 4,
+        _5432 = 6,
+        _4321 = 7,
+        _4567 = 8,
+        _6745 = 9,
+        _5476 = 10,
+    }
+
+    enum VideoScale
+    {
+        Shr7 = 1,
+        Shr15 = 2,
+    }
+
+    enum VoteMode
+    {
+        All = 0,
+        Any = 1,
+        Eq = 2,
+    }
+
+    enum XmadCop
+    {
+        Cfull = 0,
+        Clo = 1,
+        Chi = 2,
+        Csfu = 3,
+        Cbcc = 4,
+    }
+
+    enum XmadCop2
+    {
+        Cfull = 0,
+        Clo = 1,
+        Chi = 2,
+        Csfu = 3,
+    }
+
+    enum ImadspASelect
+    {
+        U32 = 0,
+        S32 = 1,
+        U24 = 2,
+        S24 = 3,
+        U16h0 = 4,
+        S16h0 = 5,
+        U16h1 = 6,
+        S16h1 = 7,
+    }
+
+    enum ImadspBSelect
+    {
+        U24 = 0,
+        S24 = 1,
+        U16h0 = 2,
+        S16h0 = 3,
+    }
+
+    struct InstConditional
+    {
+        private ulong _opcode;
+        public InstConditional(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+    }
+
+    struct InstAl2p
+    {
+        private ulong _opcode;
+        public InstAl2p(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public AlSize AlSize => (AlSize)((_opcode >> 47) & 0x3);
+        public bool Aio => (_opcode & 0x100000000) != 0;
+        public int Imm11 => (int)((_opcode >> 20) & 0x7FF);
+        public int DestPred => (int)((_opcode >> 44) & 0x7);
+    }
+
+    struct InstAld
+    {
+        private ulong _opcode;
+        public InstAld(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm11 => (int)((_opcode >> 20) & 0x7FF);
+        public bool P => (_opcode & 0x80000000) != 0;
+        public bool O => (_opcode & 0x100000000) != 0;
+        public AlSize AlSize => (AlSize)((_opcode >> 47) & 0x3);
+        public bool Phys => !P && Imm11 == 0 && SrcA != RegisterConsts.RegisterZeroIndex;
+    }
+
+    struct InstAst
+    {
+        private ulong _opcode;
+        public InstAst(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 0) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm11 => (int)((_opcode >> 20) & 0x7FF);
+        public bool P => (_opcode & 0x80000000) != 0;
+        public AlSize AlSize => (AlSize)((_opcode >> 47) & 0x3);
+        public bool Phys => !P && Imm11 == 0 && SrcA != RegisterConsts.RegisterZeroIndex;
+    }
+
+    struct InstAtom
+    {
+        private ulong _opcode;
+        public InstAtom(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm20 => (int)((_opcode >> 28) & 0xFFFFF);
+        public AtomSize Size => (AtomSize)((_opcode >> 49) & 0x7);
+        public AtomOp Op => (AtomOp)((_opcode >> 52) & 0xF);
+        public bool E => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstAtomCas
+    {
+        private ulong _opcode;
+        public InstAtomCas(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int BcRz => (int)((_opcode >> 50) & 0x3);
+        public bool E => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstAtoms
+    {
+        private ulong _opcode;
+        public InstAtoms(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm22 => (int)((_opcode >> 30) & 0x3FFFFF);
+        public AtomsSize AtomsSize => (AtomsSize)((_opcode >> 28) & 0x3);
+        public AtomOp AtomOp => (AtomOp)((_opcode >> 52) & 0xF);
+    }
+
+    struct InstAtomsCas
+    {
+        private ulong _opcode;
+        public InstAtomsCas(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int AtomsBcRz => (int)((_opcode >> 28) & 0x3);
+    }
+
+    struct InstB2r
+    {
+        private ulong _opcode;
+        public InstB2r(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int DestPred => (int)((_opcode >> 45) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public BarMode Mode => (BarMode)((_opcode >> 32) & 0x3);
+    }
+
+    struct InstBar
+    {
+        private ulong _opcode;
+        public InstBar(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm12 => (int)((_opcode >> 20) & 0xFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public BarOp BarOp => (BarOp)((_opcode >> 32) & 0x7);
+        public BarRedOp BarRedOp => (BarRedOp)((_opcode >> 35) & 0x3);
+        public bool AFixBar => (_opcode & 0x100000000000) != 0;
+        public bool BFixBar => (_opcode & 0x80000000000) != 0;
+    }
+
+    struct InstBfeR
+    {
+        private ulong _opcode;
+        public InstBfeR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public bool Brev => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstBfeI
+    {
+        private ulong _opcode;
+        public InstBfeI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public bool Brev => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstBfeC
+    {
+        private ulong _opcode;
+        public InstBfeC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public bool Brev => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstBfiR
+    {
+        private ulong _opcode;
+        public InstBfiR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstBfiI
+    {
+        private ulong _opcode;
+        public InstBfiI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstBfiC
+    {
+        private ulong _opcode;
+        public InstBfiC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstBfiRc
+    {
+        private ulong _opcode;
+        public InstBfiRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstBpt
+    {
+        private ulong _opcode;
+        public InstBpt(ulong opcode) => _opcode = opcode;
+        public int Imm20 => (int)((_opcode >> 20) & 0xFFFFF);
+        public Bpt Bpt => (Bpt)((_opcode >> 6) & 0x7);
+    }
+
+    struct InstBra
+    {
+        private ulong _opcode;
+        public InstBra(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Ca => (_opcode & 0x20) != 0;
+        public bool Lmt => (_opcode & 0x40) != 0;
+        public bool U => (_opcode & 0x80) != 0;
+    }
+
+    struct InstBrk
+    {
+        private ulong _opcode;
+        public InstBrk(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+    }
+
+    struct InstBrx
+    {
+        private ulong _opcode;
+        public InstBrx(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Ca => (_opcode & 0x20) != 0;
+        public bool Lmt => (_opcode & 0x40) != 0;
+    }
+
+    struct InstCal
+    {
+        private ulong _opcode;
+        public InstCal(ulong opcode) => _opcode = opcode;
+        public bool Ca => (_opcode & 0x20) != 0;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Inc => (_opcode & 0x40) != 0;
+    }
+
+    struct InstCctl
+    {
+        private ulong _opcode;
+        public InstCctl(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm30 => (int)((_opcode >> 22) & 0x3FFFFFFF);
+        public bool E => (_opcode & 0x10000000000000) != 0;
+        public CacheType Cache => (CacheType)((_opcode >> 4) & 0x7);
+        public CctlOp CctlOp => (CctlOp)((_opcode >> 0) & 0xF);
+    }
+
+    struct InstCctll
+    {
+        private ulong _opcode;
+        public InstCctll(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm22 => (int)((_opcode >> 22) & 0x3FFFFF);
+        public int Cache => (int)((_opcode >> 4) & 0x3);
+        public CctlOp CctlOp => (CctlOp)((_opcode >> 0) & 0xF);
+    }
+
+    struct InstCctlt
+    {
+        private ulong _opcode;
+        public InstCctlt(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int TsIdx13 => (int)((_opcode >> 36) & 0x1FFF);
+        public CctltOp CctltOp => (CctltOp)((_opcode >> 0) & 0x3);
+    }
+
+    struct InstCctltR
+    {
+        private ulong _opcode;
+        public InstCctltR(ulong opcode) => _opcode = opcode;
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public CctltOp CctltOp => (CctltOp)((_opcode >> 0) & 0x3);
+    }
+
+    struct InstContUnsup
+    {
+        private ulong _opcode;
+        public InstContUnsup(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+    }
+
+    struct InstCsetUnsup
+    {
+        private ulong _opcode;
+        public InstCsetUnsup(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 8) & 0x1F);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public bool BVal => (_opcode & 0x100000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+    }
+
+    struct InstCsetp
+    {
+        private ulong _opcode;
+        public InstCsetp(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 8) & 0x1F);
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+    }
+
+    struct InstCs2r
+    {
+        private ulong _opcode;
+        public InstCs2r(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public SReg SReg => (SReg)((_opcode >> 20) & 0xFF);
+    }
+
+    struct InstDaddR
+    {
+        private ulong _opcode;
+        public InstDaddR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstDaddI
+    {
+        private ulong _opcode;
+        public InstDaddI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstDaddC
+    {
+        private ulong _opcode;
+        public InstDaddC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstDepbar
+    {
+        private ulong _opcode;
+        public InstDepbar(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Le => (_opcode & 0x20000000) != 0;
+        public int Sbid => (int)((_opcode >> 26) & 0x7);
+        public int PendCnt => (int)((_opcode >> 20) & 0x3F);
+        public int Imm6 => (int)((_opcode >> 0) & 0x3F);
+    }
+
+    struct InstDfmaR
+    {
+        private ulong _opcode;
+        public InstDfmaR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 50) & 0x3);
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstDfmaI
+    {
+        private ulong _opcode;
+        public InstDfmaI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 50) & 0x3);
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstDfmaC
+    {
+        private ulong _opcode;
+        public InstDfmaC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 50) & 0x3);
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstDfmaRc
+    {
+        private ulong _opcode;
+        public InstDfmaRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 50) & 0x3);
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstDmnmxR
+    {
+        private ulong _opcode;
+        public InstDmnmxR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstDmnmxI
+    {
+        private ulong _opcode;
+        public InstDmnmxI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstDmnmxC
+    {
+        private ulong _opcode;
+        public InstDmnmxC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstDmulR
+    {
+        private ulong _opcode;
+        public InstDmulR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstDmulI
+    {
+        private ulong _opcode;
+        public InstDmulI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstDmulC
+    {
+        private ulong _opcode;
+        public InstDmulC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstDsetR
+    {
+        private ulong _opcode;
+        public InstDsetR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsA => (_opcode & 0x40000000000000) != 0;
+        public bool NegB => (_opcode & 0x20000000000000) != 0;
+        public bool BVal => (_opcode & 0x10000000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstDsetI
+    {
+        private ulong _opcode;
+        public InstDsetI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsA => (_opcode & 0x40000000000000) != 0;
+        public bool NegB => (_opcode & 0x20000000000000) != 0;
+        public bool BVal => (_opcode & 0x10000000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstDsetC
+    {
+        private ulong _opcode;
+        public InstDsetC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsA => (_opcode & 0x40000000000000) != 0;
+        public bool NegB => (_opcode & 0x20000000000000) != 0;
+        public bool BVal => (_opcode & 0x10000000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstDsetpR
+    {
+        private ulong _opcode;
+        public InstDsetpR(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool AbsA => (_opcode & 0x80) != 0;
+        public bool NegB => (_opcode & 0x40) != 0;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+    }
+
+    struct InstDsetpI
+    {
+        private ulong _opcode;
+        public InstDsetpI(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool AbsA => (_opcode & 0x80) != 0;
+        public bool NegB => (_opcode & 0x40) != 0;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+    }
+
+    struct InstDsetpC
+    {
+        private ulong _opcode;
+        public InstDsetpC(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool AbsA => (_opcode & 0x80) != 0;
+        public bool NegB => (_opcode & 0x40) != 0;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+    }
+
+    struct InstExit
+    {
+        private ulong _opcode;
+        public InstExit(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+        public bool KeepRefCnt => (_opcode & 0x20) != 0;
+    }
+
+    struct InstF2fR
+    {
+        private ulong _opcode;
+        public InstF2fR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public DstFmt DstFmt => (DstFmt)((_opcode >> 8) & 0x3);
+        public DstFmt SrcFmt => (DstFmt)((_opcode >> 10) & 0x3);
+        public IntegerRound RoundMode => (IntegerRound)((int)((_opcode >> 40) & 0x4) | (int)((_opcode >> 39) & 0x3));
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstF2fI
+    {
+        private ulong _opcode;
+        public InstF2fI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public DstFmt DstFmt => (DstFmt)((_opcode >> 8) & 0x3);
+        public DstFmt SrcFmt => (DstFmt)((_opcode >> 10) & 0x3);
+        public IntegerRound RoundMode => (IntegerRound)((int)((_opcode >> 40) & 0x4) | (int)((_opcode >> 39) & 0x3));
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstF2fC
+    {
+        private ulong _opcode;
+        public InstF2fC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public DstFmt DstFmt => (DstFmt)((_opcode >> 8) & 0x3);
+        public DstFmt SrcFmt => (DstFmt)((_opcode >> 10) & 0x3);
+        public IntegerRound RoundMode => (IntegerRound)((int)((_opcode >> 40) & 0x4) | (int)((_opcode >> 39) & 0x3));
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstF2iR
+    {
+        private ulong _opcode;
+        public InstF2iR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public DstFmt SrcFmt => (DstFmt)((_opcode >> 10) & 0x3);
+        public RoundMode2 RoundMode => (RoundMode2)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstF2iI
+    {
+        private ulong _opcode;
+        public InstF2iI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public DstFmt SrcFmt => (DstFmt)((_opcode >> 10) & 0x3);
+        public RoundMode2 RoundMode => (RoundMode2)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstF2iC
+    {
+        private ulong _opcode;
+        public InstF2iC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public DstFmt SrcFmt => (DstFmt)((_opcode >> 10) & 0x3);
+        public RoundMode2 RoundMode => (RoundMode2)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstFaddR
+    {
+        private ulong _opcode;
+        public InstFaddR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstFaddI
+    {
+        private ulong _opcode;
+        public InstFaddI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstFaddC
+    {
+        private ulong _opcode;
+        public InstFaddC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstFadd32i
+    {
+        private ulong _opcode;
+        public InstFadd32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool AbsB => (_opcode & 0x200000000000000) != 0;
+        public bool NegA => (_opcode & 0x100000000000000) != 0;
+        public bool Ftz => (_opcode & 0x80000000000000) != 0;
+        public bool AbsA => (_opcode & 0x40000000000000) != 0;
+        public bool NegB => (_opcode & 0x20000000000000) != 0;
+    }
+
+    struct InstFchkR
+    {
+        private ulong _opcode;
+        public InstFchkR(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ChkModeF ChkModeF => (ChkModeF)((_opcode >> 39) & 0x3F);
+    }
+
+    struct InstFchkI
+    {
+        private ulong _opcode;
+        public InstFchkI(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ChkModeF ChkModeF => (ChkModeF)((_opcode >> 39) & 0x3F);
+    }
+
+    struct InstFchkC
+    {
+        private ulong _opcode;
+        public InstFchkC(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ChkModeF ChkModeF => (ChkModeF)((_opcode >> 39) & 0x3F);
+    }
+
+    struct InstFcmpR
+    {
+        private ulong _opcode;
+        public InstFcmpR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public bool Ftz => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstFcmpI
+    {
+        private ulong _opcode;
+        public InstFcmpI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public bool Ftz => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstFcmpC
+    {
+        private ulong _opcode;
+        public InstFcmpC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public bool Ftz => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstFcmpRc
+    {
+        private ulong _opcode;
+        public InstFcmpRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public bool Ftz => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstFfmaR
+    {
+        private ulong _opcode;
+        public InstFfmaR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 51) & 0x3);
+        public Fmz Fmz => (Fmz)((_opcode >> 53) & 0x3);
+    }
+
+    struct InstFfmaI
+    {
+        private ulong _opcode;
+        public InstFfmaI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 51) & 0x3);
+        public Fmz Fmz => (Fmz)((_opcode >> 53) & 0x3);
+    }
+
+    struct InstFfmaC
+    {
+        private ulong _opcode;
+        public InstFfmaC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 51) & 0x3);
+        public Fmz Fmz => (Fmz)((_opcode >> 53) & 0x3);
+    }
+
+    struct InstFfmaRc
+    {
+        private ulong _opcode;
+        public InstFfmaRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 51) & 0x3);
+        public Fmz Fmz => (Fmz)((_opcode >> 53) & 0x3);
+    }
+
+    struct InstFfma32i
+    {
+        private ulong _opcode;
+        public InstFfma32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm32 => (int)(_opcode >> 20);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegC => (_opcode & 0x200000000000000) != 0;
+        public bool NegA => (_opcode & 0x100000000000000) != 0;
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 53) & 0x3);
+    }
+
+    struct InstFloR
+    {
+        private ulong _opcode;
+        public InstFloR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstFloI
+    {
+        private ulong _opcode;
+        public InstFloI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstFloC
+    {
+        private ulong _opcode;
+        public InstFloC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public bool Sh => (_opcode & 0x20000000000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstFmnmxR
+    {
+        private ulong _opcode;
+        public InstFmnmxR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstFmnmxI
+    {
+        private ulong _opcode;
+        public InstFmnmxI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstFmnmxC
+    {
+        private ulong _opcode;
+        public InstFmnmxC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstFmulR
+    {
+        private ulong _opcode;
+        public InstFmulR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public Fmz Fmz => (Fmz)((_opcode >> 44) & 0x3);
+        public MultiplyScale Scale => (MultiplyScale)((_opcode >> 41) & 0x7);
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstFmulI
+    {
+        private ulong _opcode;
+        public InstFmulI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public Fmz Fmz => (Fmz)((_opcode >> 44) & 0x3);
+        public MultiplyScale Scale => (MultiplyScale)((_opcode >> 41) & 0x7);
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstFmulC
+    {
+        private ulong _opcode;
+        public InstFmulC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public Fmz Fmz => (Fmz)((_opcode >> 44) & 0x3);
+        public MultiplyScale Scale => (MultiplyScale)((_opcode >> 41) & 0x7);
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstFmul32i
+    {
+        private ulong _opcode;
+        public InstFmul32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 53) & 0x3);
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+    }
+
+    struct InstFsetR
+    {
+        private ulong _opcode;
+        public InstFsetR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x20000000000000) != 0;
+        public bool AbsA => (_opcode & 0x40000000000000) != 0;
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x80000000000000) != 0;
+        public bool BVal => (_opcode & 0x10000000000000) != 0;
+    }
+
+    struct InstFsetC
+    {
+        private ulong _opcode;
+        public InstFsetC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x20000000000000) != 0;
+        public bool AbsA => (_opcode & 0x40000000000000) != 0;
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x80000000000000) != 0;
+        public bool BVal => (_opcode & 0x10000000000000) != 0;
+    }
+
+    struct InstFsetI
+    {
+        private ulong _opcode;
+        public InstFsetI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x20000000000000) != 0;
+        public bool AbsA => (_opcode & 0x40000000000000) != 0;
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x80000000000000) != 0;
+        public bool BVal => (_opcode & 0x10000000000000) != 0;
+    }
+
+    struct InstFsetpR
+    {
+        private ulong _opcode;
+        public InstFsetpR(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x40) != 0;
+        public bool AbsA => (_opcode & 0x80) != 0;
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstFsetpI
+    {
+        private ulong _opcode;
+        public InstFsetpI(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x40) != 0;
+        public bool AbsA => (_opcode & 0x80) != 0;
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstFsetpC
+    {
+        private ulong _opcode;
+        public InstFsetpC(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x40) != 0;
+        public bool AbsA => (_opcode & 0x80) != 0;
+        public bool AbsB => (_opcode & 0x100000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 48) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstFswzadd
+    {
+        private ulong _opcode;
+        public InstFswzadd(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Ftz => (_opcode & 0x100000000000) != 0;
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public bool Ndv => (_opcode & 0x4000000000) != 0;
+        public int PnWord => (int)((_opcode >> 28) & 0xFF);
+    }
+
+    struct InstGetcrsptr
+    {
+        private ulong _opcode;
+        public InstGetcrsptr(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+    }
+
+    struct InstGetlmembase
+    {
+        private ulong _opcode;
+        public InstGetlmembase(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+    }
+
+    struct InstHadd2R
+    {
+        private ulong _opcode;
+        public InstHadd2R(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle BSwizzle => (HalfSwizzle)((_opcode >> 28) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x80000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool AbsB => (_opcode & 0x40000000) != 0;
+        public bool Sat => (_opcode & 0x100000000) != 0;
+        public bool Ftz => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstHadd2I
+    {
+        private ulong _opcode;
+        public InstHadd2I(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
+        public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public bool Ftz => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstHadd2C
+    {
+        private ulong _opcode;
+        public InstHadd2C(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x100000000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool AbsB => (_opcode & 0x40000000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public bool Ftz => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstHadd232i
+    {
+        private ulong _opcode;
+        public InstHadd232i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm => (int)(_opcode >> 20);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 53) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x100000000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public bool Ftz => (_opcode & 0x80000000000000) != 0;
+    }
+
+    struct InstHfma2R
+    {
+        private ulong _opcode;
+        public InstHfma2R(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle BSwizzle => (HalfSwizzle)((_opcode >> 28) & 0x3);
+        public HalfSwizzle CSwizzle => (HalfSwizzle)((_opcode >> 35) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000) != 0;
+        public bool NegC => (_opcode & 0x40000000) != 0;
+        public bool Sat => (_opcode & 0x100000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 37) & 0x3);
+    }
+
+    struct InstHfma2I
+    {
+        private ulong _opcode;
+        public InstHfma2I(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
+        public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle CSwizzle => (HalfSwizzle)((_opcode >> 53) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegC => (_opcode & 0x8000000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 57) & 0x3);
+    }
+
+    struct InstHfma2C
+    {
+        private ulong _opcode;
+        public InstHfma2C(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle CSwizzle => (HalfSwizzle)((_opcode >> 53) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x100000000000000) != 0;
+        public bool NegC => (_opcode & 0x8000000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 57) & 0x3);
+    }
+
+    struct InstHfma2Rc
+    {
+        private ulong _opcode;
+        public InstHfma2Rc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle CSwizzle => (HalfSwizzle)((_opcode >> 53) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x100000000000000) != 0;
+        public bool NegC => (_opcode & 0x8000000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 57) & 0x3);
+    }
+
+    struct InstHfma232i
+    {
+        private ulong _opcode;
+        public InstHfma232i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm => (int)(_opcode >> 20);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegC => (_opcode & 0x8000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 57) & 0x3);
+    }
+
+    struct InstHmul2R
+    {
+        private ulong _opcode;
+        public InstHmul2R(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle BSwizzle => (HalfSwizzle)((_opcode >> 28) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool AbsB => (_opcode & 0x40000000) != 0;
+        public bool Sat => (_opcode & 0x100000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstHmul2I
+    {
+        private ulong _opcode;
+        public InstHmul2I(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
+        public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstHmul2C
+    {
+        private ulong _opcode;
+        public InstHmul2C(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public OFmt OFmt => (OFmt)((_opcode >> 49) & 0x3);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool AbsB => (_opcode & 0x40000000000000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstHmul232i
+    {
+        private ulong _opcode;
+        public InstHmul232i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm32 => (int)(_opcode >> 20);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 53) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Sat => (_opcode & 0x10000000000000) != 0;
+        public Fmz Fmz => (Fmz)((_opcode >> 55) & 0x3);
+    }
+
+    struct InstHset2R
+    {
+        private ulong _opcode;
+        public InstHset2R(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle BSwizzle => (HalfSwizzle)((_opcode >> 28) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool NegB => (_opcode & 0x80000000) != 0;
+        public bool AbsB => (_opcode & 0x40000000) != 0;
+        public bool Bval => (_opcode & 0x2000000000000) != 0;
+        public FComp Cmp => (FComp)((_opcode >> 35) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public bool Ftz => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstHset2I
+    {
+        private ulong _opcode;
+        public InstHset2I(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
+        public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool Bval => (_opcode & 0x20000000000000) != 0;
+        public FComp Cmp => (FComp)((_opcode >> 49) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public bool Ftz => (_opcode & 0x40000000000000) != 0;
+    }
+
+    struct InstHset2C
+    {
+        private ulong _opcode;
+        public InstHset2C(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool NegB => (_opcode & 0x100000000000000) != 0;
+        public bool Bval => (_opcode & 0x20000000000000) != 0;
+        public FComp Cmp => (FComp)((_opcode >> 49) & 0xF);
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public bool Ftz => (_opcode & 0x40000000000000) != 0;
+    }
+
+    struct InstHsetp2R
+    {
+        private ulong _opcode;
+        public InstHsetp2R(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x80000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool AbsB => (_opcode & 0x40000000) != 0;
+        public FComp FComp2 => (FComp)((_opcode >> 35) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x40) != 0;
+        public bool HAnd => (_opcode & 0x2000000000000) != 0;
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+        public HalfSwizzle BSwizzle => (HalfSwizzle)((_opcode >> 28) & 0x3);
+    }
+
+    struct InstHsetp2I
+    {
+        private ulong _opcode;
+        public InstHsetp2I(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int BimmH0 => (int)((_opcode >> 20) & 0x3FF);
+        public int BimmH1 => (int)((_opcode >> 47) & 0x200) | (int)((_opcode >> 30) & 0x1FF);
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 49) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x40) != 0;
+        public bool HAnd => (_opcode & 0x20000000000000) != 0;
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+    }
+
+    struct InstHsetp2C
+    {
+        private ulong _opcode;
+        public InstHsetp2C(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegA => (_opcode & 0x80000000000) != 0;
+        public bool NegB => (_opcode & 0x100000000000000) != 0;
+        public bool AbsA => (_opcode & 0x100000000000) != 0;
+        public bool AbsB => (_opcode & 0x40000000000000) != 0;
+        public FComp FComp => (FComp)((_opcode >> 49) & 0xF);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool Ftz => (_opcode & 0x40) != 0;
+        public bool HAnd => (_opcode & 0x20000000000000) != 0;
+        public HalfSwizzle ASwizzle => (HalfSwizzle)((_opcode >> 47) & 0x3);
+    }
+
+    struct InstI2fR
+    {
+        private ulong _opcode;
+        public InstI2fR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public ISrcFmt ISrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+        public DstFmt DstFmt => (DstFmt)((_opcode >> 8) & 0x3);
+    }
+
+    struct InstI2fI
+    {
+        private ulong _opcode;
+        public InstI2fI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public ISrcFmt ISrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+        public DstFmt DstFmt => (DstFmt)((_opcode >> 8) & 0x3);
+    }
+
+    struct InstI2fC
+    {
+        private ulong _opcode;
+        public InstI2fC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public RoundMode RoundMode => (RoundMode)((_opcode >> 39) & 0x3);
+        public ISrcFmt ISrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+        public DstFmt DstFmt => (DstFmt)((_opcode >> 8) & 0x3);
+    }
+
+    struct InstI2iR
+    {
+        private ulong _opcode;
+        public InstI2iR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+    }
+
+    struct InstI2iI
+    {
+        private ulong _opcode;
+        public InstI2iI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+    }
+
+    struct InstI2iC
+    {
+        private ulong _opcode;
+        public InstI2iC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+    }
+
+    struct InstIaddR
+    {
+        private ulong _opcode;
+        public InstIaddR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 48) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+    }
+
+    struct InstIaddI
+    {
+        private ulong _opcode;
+        public InstIaddI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 48) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+    }
+
+    struct InstIaddC
+    {
+        private ulong _opcode;
+        public InstIaddC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 48) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+    }
+
+    struct InstIadd32i
+    {
+        private ulong _opcode;
+        public InstIadd32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 55) & 0x3);
+        public bool Sat => (_opcode & 0x40000000000000) != 0;
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+        public bool X => (_opcode & 0x20000000000000) != 0;
+    }
+
+    struct InstIadd3R
+    {
+        private ulong _opcode;
+        public InstIadd3R(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x8000000000000) != 0;
+        public bool NegB => (_opcode & 0x4000000000000) != 0;
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool X => (_opcode & 0x1000000000000) != 0;
+        public Lrs Lrs => (Lrs)((_opcode >> 37) & 0x3);
+        public HalfSelect Apart => (HalfSelect)((_opcode >> 35) & 0x3);
+        public HalfSelect Bpart => (HalfSelect)((_opcode >> 33) & 0x3);
+        public HalfSelect Cpart => (HalfSelect)((_opcode >> 31) & 0x3);
+    }
+
+    struct InstIadd3I
+    {
+        private ulong _opcode;
+        public InstIadd3I(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x8000000000000) != 0;
+        public bool NegB => (_opcode & 0x4000000000000) != 0;
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool X => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstIadd3C
+    {
+        private ulong _opcode;
+        public InstIadd3C(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool NegA => (_opcode & 0x8000000000000) != 0;
+        public bool NegB => (_opcode & 0x4000000000000) != 0;
+        public bool NegC => (_opcode & 0x2000000000000) != 0;
+        public bool X => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstIcmpR
+    {
+        private ulong _opcode;
+        public InstIcmpR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstIcmpI
+    {
+        private ulong _opcode;
+        public InstIcmpI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstIcmpC
+    {
+        private ulong _opcode;
+        public InstIcmpC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstIcmpRc
+    {
+        private ulong _opcode;
+        public InstIcmpRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstIde
+    {
+        private ulong _opcode;
+        public InstIde(ulong opcode) => _opcode = opcode;
+        public int Imm16 => (int)((_opcode >> 20) & 0xFFFF);
+        public bool Di => (_opcode & 0x20) != 0;
+    }
+
+    struct InstIdpR
+    {
+        private ulong _opcode;
+        public InstIdpR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool IsHi => (_opcode & 0x4000000000000) != 0;
+        public bool SrcASign => (_opcode & 0x2000000000000) != 0;
+        public bool IsDp => (_opcode & 0x1000000000000) != 0;
+        public bool SrcBSign => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstIdpC
+    {
+        private ulong _opcode;
+        public InstIdpC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool IsHi => (_opcode & 0x4000000000000) != 0;
+        public bool SrcASign => (_opcode & 0x2000000000000) != 0;
+        public bool IsDp => (_opcode & 0x1000000000000) != 0;
+        public bool SrcBSign => (_opcode & 0x800000000000) != 0;
+    }
+
+    struct InstImadR
+    {
+        private ulong _opcode;
+        public InstImadR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Hilo => (_opcode & 0x40000000000000) != 0;
+        public bool BSigned => (_opcode & 0x20000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 51) & 0x3);
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool X => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstImadI
+    {
+        private ulong _opcode;
+        public InstImadI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Hilo => (_opcode & 0x40000000000000) != 0;
+        public bool BSigned => (_opcode & 0x20000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 51) & 0x3);
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool X => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstImadC
+    {
+        private ulong _opcode;
+        public InstImadC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Hilo => (_opcode & 0x40000000000000) != 0;
+        public bool BSigned => (_opcode & 0x20000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 51) & 0x3);
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool X => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstImadRc
+    {
+        private ulong _opcode;
+        public InstImadRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Hilo => (_opcode & 0x40000000000000) != 0;
+        public bool BSigned => (_opcode & 0x20000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 51) & 0x3);
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool X => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstImad32i
+    {
+        private ulong _opcode;
+        public InstImad32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool BSigned => (_opcode & 0x200000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 55) & 0x3);
+        public bool ASigned => (_opcode & 0x40000000000000) != 0;
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+        public bool Hilo => (_opcode & 0x20000000000000) != 0;
+    }
+
+    struct InstImadspR
+    {
+        private ulong _opcode;
+        public InstImadspR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ImadspASelect ASelect => (ImadspASelect)((_opcode >> 48) & 0x7);
+        public ImadspBSelect BSelect => (ImadspBSelect)((_opcode >> 53) & 0x3);
+        public ImadspASelect CSelect => (ImadspASelect)((int)((_opcode >> 50) & 0x6) | (int)((_opcode >> 48) & 0x1));
+    }
+
+    struct InstImadspI
+    {
+        private ulong _opcode;
+        public InstImadspI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ImadspASelect ASelect => (ImadspASelect)((_opcode >> 48) & 0x7);
+        public ImadspBSelect BSelect => (ImadspBSelect)((_opcode >> 53) & 0x3);
+        public ImadspASelect CSelect => (ImadspASelect)((int)((_opcode >> 50) & 0x6) | (int)((_opcode >> 48) & 0x1));
+    }
+
+    struct InstImadspC
+    {
+        private ulong _opcode;
+        public InstImadspC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ImadspASelect ASelect => (ImadspASelect)((_opcode >> 48) & 0x7);
+        public ImadspBSelect BSelect => (ImadspBSelect)((_opcode >> 53) & 0x3);
+        public ImadspASelect CSelect => (ImadspASelect)((int)((_opcode >> 50) & 0x6) | (int)((_opcode >> 48) & 0x1));
+    }
+
+    struct InstImadspRc
+    {
+        private ulong _opcode;
+        public InstImadspRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ImadspASelect ASelect => (ImadspASelect)((_opcode >> 48) & 0x7);
+        public ImadspBSelect BSelect => (ImadspBSelect)((_opcode >> 53) & 0x3);
+        public ImadspASelect CSelect => (ImadspASelect)((int)((_opcode >> 50) & 0x6) | (int)((_opcode >> 48) & 0x1));
+    }
+
+    struct InstImnmxR
+    {
+        private ulong _opcode;
+        public InstImnmxR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public XMode XMode => (XMode)((_opcode >> 43) & 0x3);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstImnmxI
+    {
+        private ulong _opcode;
+        public InstImnmxI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public XMode XMode => (XMode)((_opcode >> 43) & 0x3);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstImnmxC
+    {
+        private ulong _opcode;
+        public InstImnmxC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public XMode XMode => (XMode)((_opcode >> 43) & 0x3);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstImulR
+    {
+        private ulong _opcode;
+        public InstImulR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool ASigned => (_opcode & 0x10000000000) != 0;
+        public bool BSigned => (_opcode & 0x20000000000) != 0;
+        public bool Hilo => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstImulI
+    {
+        private ulong _opcode;
+        public InstImulI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool ASigned => (_opcode & 0x10000000000) != 0;
+        public bool BSigned => (_opcode & 0x20000000000) != 0;
+        public bool Hilo => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstImulC
+    {
+        private ulong _opcode;
+        public InstImulC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool ASigned => (_opcode & 0x10000000000) != 0;
+        public bool BSigned => (_opcode & 0x20000000000) != 0;
+        public bool Hilo => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstImul32i
+    {
+        private ulong _opcode;
+        public InstImul32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool ASigned => (_opcode & 0x40000000000000) != 0;
+        public bool BSigned => (_opcode & 0x80000000000000) != 0;
+        public bool Hilo => (_opcode & 0x20000000000000) != 0;
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+    }
+
+    struct InstIpa
+    {
+        private ulong _opcode;
+        public InstIpa(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IpaOp IpaOp => (IpaOp)((_opcode >> 54) & 0x3);
+        public int Msi => (int)((_opcode >> 52) & 0x3);
+        public bool Sat => (_opcode & 0x8000000000000) != 0;
+        public bool Idx => (_opcode & 0x4000000000) != 0;
+        public int Imm10 => (int)((_opcode >> 28) & 0x3FF);
+        public int SrcPred => (int)((_opcode >> 47) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstIsberd
+    {
+        private ulong _opcode;
+        public InstIsberd(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public AlSize AlSize => (AlSize)((_opcode >> 47) & 0x3);
+        public IBase IBase => (IBase)((_opcode >> 33) & 0x3);
+        public bool O => (_opcode & 0x100000000) != 0;
+        public bool P => (_opcode & 0x80000000) != 0;
+    }
+
+    struct InstIscaddR
+    {
+        private ulong _opcode;
+        public InstIscaddR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int Imm5 => (int)((_opcode >> 39) & 0x1F);
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 48) & 0x3);
+    }
+
+    struct InstIscaddI
+    {
+        private ulong _opcode;
+        public InstIscaddI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int Imm5 => (int)((_opcode >> 39) & 0x1F);
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 48) & 0x3);
+    }
+
+    struct InstIscaddC
+    {
+        private ulong _opcode;
+        public InstIscaddC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int Imm5 => (int)((_opcode >> 39) & 0x1F);
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 48) & 0x3);
+    }
+
+    struct InstIscadd32i
+    {
+        private ulong _opcode;
+        public InstIscadd32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+        public int Imm5 => (int)((_opcode >> 53) & 0x1F);
+    }
+
+    struct InstIsetR
+    {
+        private ulong _opcode;
+        public InstIsetR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public bool BVal => (_opcode & 0x100000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+    }
+
+    struct InstIsetI
+    {
+        private ulong _opcode;
+        public InstIsetI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public bool BVal => (_opcode & 0x100000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+    }
+
+    struct InstIsetC
+    {
+        private ulong _opcode;
+        public InstIsetC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public bool BVal => (_opcode & 0x100000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+    }
+
+    struct InstIsetpR
+    {
+        private ulong _opcode;
+        public InstIsetpR(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+    }
+
+    struct InstIsetpI
+    {
+        private ulong _opcode;
+        public InstIsetpI(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+    }
+
+    struct InstIsetpC
+    {
+        private ulong _opcode;
+        public InstIsetpC(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public IComp IComp => (IComp)((_opcode >> 49) & 0x7);
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public BoolOp Bop => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+    }
+
+    struct InstJcal
+    {
+        private ulong _opcode;
+        public InstJcal(ulong opcode) => _opcode = opcode;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool Ca => (_opcode & 0x20) != 0;
+        public bool Inc => (_opcode & 0x40) != 0;
+    }
+
+    struct InstJmp
+    {
+        private ulong _opcode;
+        public InstJmp(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+        public bool Ca => (_opcode & 0x20) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool Lmt => (_opcode & 0x40) != 0;
+        public bool U => (_opcode & 0x80) != 0;
+    }
+
+    struct InstJmx
+    {
+        private ulong _opcode;
+        public InstJmx(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+        public bool Ca => (_opcode & 0x20) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool Lmt => (_opcode & 0x40) != 0;
+    }
+
+    struct InstKil
+    {
+        private ulong _opcode;
+        public InstKil(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+    }
+
+    struct InstLd
+    {
+        private ulong _opcode;
+        public InstLd(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int SrcPred => (int)((_opcode >> 58) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 56) & 0x3);
+        public LsSize LsSize => (LsSize)((_opcode >> 53) & 0x7);
+        public bool E => (_opcode & 0x10000000000000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+    }
+
+    struct InstLdc
+    {
+        private ulong _opcode;
+        public InstLdc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public LsSize2 LsSize => (LsSize2)((_opcode >> 48) & 0x7);
+        public AddressMode AddressMode => (AddressMode)((_opcode >> 44) & 0x3);
+        public int CbufSlot => (int)((_opcode >> 36) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0xFFFF);
+    }
+
+    struct InstLdg
+    {
+        private ulong _opcode;
+        public InstLdg(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public LsSize LsSize => (LsSize)((_opcode >> 48) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 46) & 0x3);
+        public bool E => (_opcode & 0x200000000000) != 0;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+    }
+
+    struct InstLdl
+    {
+        private ulong _opcode;
+        public InstLdl(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public LsSize2 LsSize => (LsSize2)((_opcode >> 48) & 0x7);
+        public CacheOp2 CacheOp => (CacheOp2)((_opcode >> 44) & 0x3);
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+    }
+
+    struct InstLds
+    {
+        private ulong _opcode;
+        public InstLds(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public LsSize2 LsSize => (LsSize2)((_opcode >> 48) & 0x7);
+        public bool U => (_opcode & 0x100000000000) != 0;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+    }
+
+    struct InstLeaR
+    {
+        private ulong _opcode;
+        public InstLeaR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x400000000000) != 0;
+        public bool NegA => (_opcode & 0x200000000000) != 0;
+        public int ImmU5 => (int)((_opcode >> 39) & 0x1F);
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+    }
+
+    struct InstLeaI
+    {
+        private ulong _opcode;
+        public InstLeaI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x400000000000) != 0;
+        public bool NegA => (_opcode & 0x200000000000) != 0;
+        public int ImmU5 => (int)((_opcode >> 39) & 0x1F);
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+    }
+
+    struct InstLeaC
+    {
+        private ulong _opcode;
+        public InstLeaC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x400000000000) != 0;
+        public bool NegA => (_opcode & 0x200000000000) != 0;
+        public int ImmU5 => (int)((_opcode >> 39) & 0x1F);
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+    }
+
+    struct InstLeaHiR
+    {
+        private ulong _opcode;
+        public InstLeaHiR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x4000000000) != 0;
+        public bool NegA => (_opcode & 0x2000000000) != 0;
+        public int ImmU5 => (int)((_opcode >> 28) & 0x1F);
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+    }
+
+    struct InstLeaHiC
+    {
+        private ulong _opcode;
+        public InstLeaHiC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x200000000000000) != 0;
+        public bool NegA => (_opcode & 0x100000000000000) != 0;
+        public int ImmU5 => (int)((_opcode >> 51) & 0x1F);
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+    }
+
+    struct InstLepc
+    {
+        private ulong _opcode;
+        public InstLepc(ulong opcode) => _opcode = opcode;
+    }
+
+    struct InstLongjmp
+    {
+        private ulong _opcode;
+        public InstLongjmp(ulong opcode) => _opcode = opcode;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+    }
+
+    struct InstLopR
+    {
+        private ulong _opcode;
+        public InstLopR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+        public PredicateOp PredicateOp => (PredicateOp)((_opcode >> 44) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public LogicOp Lop => (LogicOp)((_opcode >> 41) & 0x3);
+        public bool NegA => (_opcode & 0x8000000000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstLopI
+    {
+        private ulong _opcode;
+        public InstLopI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+        public PredicateOp PredicateOp => (PredicateOp)((_opcode >> 44) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public LogicOp LogicOp => (LogicOp)((_opcode >> 41) & 0x3);
+        public bool NegA => (_opcode & 0x8000000000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstLopC
+    {
+        private ulong _opcode;
+        public InstLopC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+        public PredicateOp PredicateOp => (PredicateOp)((_opcode >> 44) & 0x3);
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public LogicOp LogicOp => (LogicOp)((_opcode >> 41) & 0x3);
+        public bool NegA => (_opcode & 0x8000000000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstLop3R
+    {
+        private ulong _opcode;
+        public InstLop3R(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+        public PredicateOp PredicateOp => (PredicateOp)((_opcode >> 36) & 0x3);
+        public bool X => (_opcode & 0x4000000000) != 0;
+        public int Imm => (int)((_opcode >> 28) & 0xFF);
+    }
+
+    struct InstLop3I
+    {
+        private ulong _opcode;
+        public InstLop3I(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x200000000000000) != 0;
+        public int Imm => (int)((_opcode >> 48) & 0xFF);
+    }
+
+    struct InstLop3C
+    {
+        private ulong _opcode;
+        public InstLop3C(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x100000000000000) != 0;
+        public int Imm => (int)((_opcode >> 48) & 0xFF);
+    }
+
+    struct InstLop32i
+    {
+        private ulong _opcode;
+        public InstLop32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x10000000000000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+        public bool X => (_opcode & 0x200000000000000) != 0;
+        public LogicOp LogicOp => (LogicOp)((_opcode >> 53) & 0x3);
+        public bool NegA => (_opcode & 0x80000000000000) != 0;
+        public bool NegB => (_opcode & 0x100000000000000) != 0;
+    }
+
+    struct InstMembar
+    {
+        private ulong _opcode;
+        public InstMembar(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Membar Membar => (Membar)((_opcode >> 8) & 0x3);
+        public Ivall Ivall => (Ivall)((_opcode >> 0) & 0x3);
+    }
+
+    struct InstMovR
+    {
+        private ulong _opcode;
+        public InstMovR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int QuadMask => (int)((_opcode >> 39) & 0xF);
+    }
+
+    struct InstMovI
+    {
+        private ulong _opcode;
+        public InstMovI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int QuadMask => (int)((_opcode >> 39) & 0xF);
+    }
+
+    struct InstMovC
+    {
+        private ulong _opcode;
+        public InstMovC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int QuadMask => (int)((_opcode >> 39) & 0xF);
+    }
+
+    struct InstMov32i
+    {
+        private ulong _opcode;
+        public InstMov32i(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm32 => (int)(_opcode >> 20);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int QuadMask => (int)((_opcode >> 12) & 0xF);
+    }
+
+    struct InstMufu
+    {
+        private ulong _opcode;
+        public InstMufu(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public MufuOp MufuOp => (MufuOp)((_opcode >> 20) & 0xF);
+        public bool AbsA => (_opcode & 0x400000000000) != 0;
+        public bool NegA => (_opcode & 0x1000000000000) != 0;
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstNop
+    {
+        private ulong _opcode;
+        public InstNop(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm16 => (int)((_opcode >> 20) & 0xFFFF);
+        public bool Trig => (_opcode & 0x2000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 8) & 0x1F);
+    }
+
+    struct InstOutR
+    {
+        private ulong _opcode;
+        public InstOutR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public OutType OutType => (OutType)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstOutI
+    {
+        private ulong _opcode;
+        public InstOutI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public OutType OutType => (OutType)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstOutC
+    {
+        private ulong _opcode;
+        public InstOutC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public OutType OutType => (OutType)((_opcode >> 39) & 0x3);
+    }
+
+    struct InstP2rR
+    {
+        private ulong _opcode;
+        public InstP2rR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public bool Ccpr => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstP2rI
+    {
+        private ulong _opcode;
+        public InstP2rI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public bool Ccpr => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstP2rC
+    {
+        private ulong _opcode;
+        public InstP2rC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public bool Ccpr => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstPbk
+    {
+        private ulong _opcode;
+        public InstPbk(ulong opcode) => _opcode = opcode;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Ca => (_opcode & 0x20) != 0;
+    }
+
+    struct InstPcnt
+    {
+        private ulong _opcode;
+        public InstPcnt(ulong opcode) => _opcode = opcode;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Ca => (_opcode & 0x20) != 0;
+    }
+
+    struct InstPexit
+    {
+        private ulong _opcode;
+        public InstPexit(ulong opcode) => _opcode = opcode;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+    }
+
+    struct InstPixld
+    {
+        private ulong _opcode;
+        public InstPixld(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int DestPred => (int)((_opcode >> 45) & 0x7);
+        public PixMode PixMode => (PixMode)((_opcode >> 31) & 0x7);
+        public int Imm8 => (int)((_opcode >> 20) & 0xFF);
+    }
+
+    struct InstPlongjmp
+    {
+        private ulong _opcode;
+        public InstPlongjmp(ulong opcode) => _opcode = opcode;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Ca => (_opcode & 0x20) != 0;
+    }
+
+    struct InstPopcR
+    {
+        private ulong _opcode;
+        public InstPopcR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstPopcI
+    {
+        private ulong _opcode;
+        public InstPopcI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstPopcC
+    {
+        private ulong _opcode;
+        public InstPopcC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool NegB => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstPret
+    {
+        private ulong _opcode;
+        public InstPret(ulong opcode) => _opcode = opcode;
+        public bool Ca => (_opcode & 0x20) != 0;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Inc => (_opcode & 0x40) != 0;
+    }
+
+    struct InstPrmtR
+    {
+        private ulong _opcode;
+        public InstPrmtR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public PMode PMode => (PMode)((_opcode >> 48) & 0xF);
+    }
+
+    struct InstPrmtI
+    {
+        private ulong _opcode;
+        public InstPrmtI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public PMode PMode => (PMode)((_opcode >> 48) & 0xF);
+    }
+
+    struct InstPrmtC
+    {
+        private ulong _opcode;
+        public InstPrmtC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public PMode PMode => (PMode)((_opcode >> 48) & 0xF);
+    }
+
+    struct InstPrmtRc
+    {
+        private ulong _opcode;
+        public InstPrmtRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public PMode PMode => (PMode)((_opcode >> 48) & 0xF);
+    }
+
+    struct InstPset
+    {
+        private ulong _opcode;
+        public InstPset(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int Src2Pred => (int)((_opcode >> 12) & 0x7);
+        public bool Src2PredInv => (_opcode & 0x8000) != 0;
+        public int Src1Pred => (int)((_opcode >> 29) & 0x7);
+        public bool Src1PredInv => (_opcode & 0x100000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp BoolOpAB => (BoolOp)((_opcode >> 24) & 0x3);
+        public BoolOp BoolOpC => (BoolOp)((_opcode >> 45) & 0x3);
+        public bool BVal => (_opcode & 0x100000000000) != 0;
+    }
+
+    struct InstPsetp
+    {
+        private ulong _opcode;
+        public InstPsetp(ulong opcode) => _opcode = opcode;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public int Src2Pred => (int)((_opcode >> 12) & 0x7);
+        public bool Src2PredInv => (_opcode & 0x8000) != 0;
+        public int Src1Pred => (int)((_opcode >> 29) & 0x7);
+        public bool Src1PredInv => (_opcode & 0x100000000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public BoolOp BoolOpAB => (BoolOp)((_opcode >> 24) & 0x3);
+        public BoolOp BoolOpC => (BoolOp)((_opcode >> 45) & 0x3);
+    }
+
+    struct InstR2b
+    {
+        private ulong _opcode;
+        public InstR2b(ulong opcode) => _opcode = opcode;
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public BarMode Mode => (BarMode)((_opcode >> 32) & 0x3);
+        public int Name => (int)((_opcode >> 28) & 0xF);
+    }
+
+    struct InstR2pR
+    {
+        private ulong _opcode;
+        public InstR2pR(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public bool Ccpr => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstR2pI
+    {
+        private ulong _opcode;
+        public InstR2pI(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public bool Ccpr => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstR2pC
+    {
+        private ulong _opcode;
+        public InstR2pC(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
+        public bool Ccpr => (_opcode & 0x10000000000) != 0;
+    }
+
+    struct InstRam
+    {
+        private ulong _opcode;
+        public InstRam(ulong opcode) => _opcode = opcode;
+    }
+
+    struct InstRed
+    {
+        private ulong _opcode;
+        public InstRed(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 0) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int Imm20 => (int)((_opcode >> 28) & 0xFFFFF);
+        public AtomSize RedSize => (AtomSize)((_opcode >> 20) & 0x7);
+        public RedOp RedOp => (RedOp)((_opcode >> 23) & 0x7);
+        public bool E => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstRet
+    {
+        private ulong _opcode;
+        public InstRet(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+    }
+
+    struct InstRroR
+    {
+        private ulong _opcode;
+        public InstRroR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool RroOp => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstRroI
+    {
+        private ulong _opcode;
+        public InstRroI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool RroOp => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstRroC
+    {
+        private ulong _opcode;
+        public InstRroC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool AbsB => (_opcode & 0x2000000000000) != 0;
+        public bool NegB => (_opcode & 0x200000000000) != 0;
+        public bool RroOp => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstRtt
+    {
+        private ulong _opcode;
+        public InstRtt(ulong opcode) => _opcode = opcode;
+    }
+
+    struct InstS2r
+    {
+        private ulong _opcode;
+        public InstS2r(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public SReg SReg => (SReg)((_opcode >> 20) & 0xFF);
+    }
+
+    struct InstSam
+    {
+        private ulong _opcode;
+        public InstSam(ulong opcode) => _opcode = opcode;
+    }
+
+    struct InstSelR
+    {
+        private ulong _opcode;
+        public InstSelR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstSelI
+    {
+        private ulong _opcode;
+        public InstSelI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstSelC
+    {
+        private ulong _opcode;
+        public InstSelC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+    }
+
+    struct InstSetcrsptr
+    {
+        private ulong _opcode;
+        public InstSetcrsptr(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+    }
+
+    struct InstSetlmembase
+    {
+        private ulong _opcode;
+        public InstSetlmembase(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+    }
+
+    struct InstShfLR
+    {
+        private ulong _opcode;
+        public InstShfLR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool M => (_opcode & 0x4000000000000) != 0;
+        public XModeShf XModeShf => (XModeShf)((_opcode >> 48) & 0x3);
+        public MaxShift MaxShift => (MaxShift)((_opcode >> 37) & 0x3);
+    }
+
+    struct InstShfRR
+    {
+        private ulong _opcode;
+        public InstShfRR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool M => (_opcode & 0x4000000000000) != 0;
+        public XModeShf XModeShf => (XModeShf)((_opcode >> 48) & 0x3);
+        public MaxShift MaxShift => (MaxShift)((_opcode >> 37) & 0x3);
+    }
+
+    struct InstShfLI
+    {
+        private ulong _opcode;
+        public InstShfLI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool M => (_opcode & 0x4000000000000) != 0;
+        public XModeShf XModeShf => (XModeShf)((_opcode >> 48) & 0x3);
+        public MaxShift MaxShift => (MaxShift)((_opcode >> 37) & 0x3);
+        public int Imm6 => (int)((_opcode >> 20) & 0x3F);
+    }
+
+    struct InstShfRI
+    {
+        private ulong _opcode;
+        public InstShfRI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool M => (_opcode & 0x4000000000000) != 0;
+        public XModeShf XModeShf => (XModeShf)((_opcode >> 48) & 0x3);
+        public MaxShift MaxShift => (MaxShift)((_opcode >> 37) & 0x3);
+        public int Imm6 => (int)((_opcode >> 20) & 0x3F);
+    }
+
+    struct InstShfl
+    {
+        private ulong _opcode;
+        public InstShfl(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int SrcBImm => (int)((_opcode >> 20) & 0x1F);
+        public int SrcCImm => (int)((_opcode >> 34) & 0x1FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public ShflMode ShflMode => (ShflMode)((_opcode >> 30) & 0x3);
+        public bool CFixShfl => (_opcode & 0x20000000) != 0;
+        public bool BFixShfl => (_opcode & 0x10000000) != 0;
+        public int DestPred => (int)((_opcode >> 48) & 0x7);
+    }
+
+    struct InstShlR
+    {
+        private ulong _opcode;
+        public InstShlR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public bool M => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstShlI
+    {
+        private ulong _opcode;
+        public InstShlI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public bool M => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstShlC
+    {
+        private ulong _opcode;
+        public InstShlC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x80000000000) != 0;
+        public bool M => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstShrR
+    {
+        private ulong _opcode;
+        public InstShrR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public XMode XMode => (XMode)((_opcode >> 43) & 0x3);
+        public bool Brev => (_opcode & 0x10000000000) != 0;
+        public bool M => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstShrI
+    {
+        private ulong _opcode;
+        public InstShrI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Imm20 => (int)((_opcode >> 37) & 0x80000) | (int)((_opcode >> 20) & 0x7FFFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public XMode XMode => (XMode)((_opcode >> 43) & 0x3);
+        public bool Brev => (_opcode & 0x10000000000) != 0;
+        public bool M => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstShrC
+    {
+        private ulong _opcode;
+        public InstShrC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Signed => (_opcode & 0x1000000000000) != 0;
+        public XMode XMode => (XMode)((_opcode >> 43) & 0x3);
+        public bool Brev => (_opcode & 0x10000000000) != 0;
+        public bool M => (_opcode & 0x8000000000) != 0;
+    }
+
+    struct InstSsy
+    {
+        private ulong _opcode;
+        public InstSsy(ulong opcode) => _opcode = opcode;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+        public bool Ca => (_opcode & 0x20) != 0;
+    }
+
+    struct InstSt
+    {
+        private ulong _opcode;
+        public InstSt(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int SrcPred => (int)((_opcode >> 58) & 0x7);
+        public CacheOp Cop => (CacheOp)((_opcode >> 56) & 0x3);
+        public LsSize LsSize => (LsSize)((_opcode >> 53) & 0x7);
+        public bool E => (_opcode & 0x10000000000000) != 0;
+        public int Imm32 => (int)(_opcode >> 20);
+    }
+
+    struct InstStg
+    {
+        private ulong _opcode;
+        public InstStg(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public LsSize2 LsSize => (LsSize2)((_opcode >> 48) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 46) & 0x3);
+        public bool E => (_opcode & 0x200000000000) != 0;
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+    }
+
+    struct InstStl
+    {
+        private ulong _opcode;
+        public InstStl(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public LsSize2 LsSize => (LsSize2)((_opcode >> 48) & 0x7);
+        public CacheOp2 CacheOp => (CacheOp2)((_opcode >> 44) & 0x3);
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+    }
+
+    struct InstStp
+    {
+        private ulong _opcode;
+        public InstStp(ulong opcode) => _opcode = opcode;
+        public bool Wait => (_opcode & 0x80000000) != 0;
+        public int Imm8 => (int)((_opcode >> 20) & 0xFF);
+    }
+
+    struct InstSts
+    {
+        private ulong _opcode;
+        public InstSts(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public LsSize2 LsSize => (LsSize2)((_opcode >> 48) & 0x7);
+        public int Imm24 => (int)((_opcode >> 20) & 0xFFFFFF);
+    }
+
+    struct InstSuatomB
+    {
+        private ulong _opcode;
+        public InstSuatomB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuatomSize Size => (SuatomSize)((_opcode >> 36) & 0x7);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public SuatomOp Op => (SuatomOp)((_opcode >> 29) & 0xF);
+        public bool Ba => (_opcode & 0x10000000) != 0;
+    }
+
+    struct InstSuatom
+    {
+        private ulong _opcode;
+        public InstSuatom(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public SuatomSize Size => (SuatomSize)((_opcode >> 51) & 0x7);
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public SuatomOp Op => (SuatomOp)((_opcode >> 29) & 0xF);
+        public bool Ba => (_opcode & 0x10000000) != 0;
+    }
+
+    struct InstSuatomB2
+    {
+        private ulong _opcode;
+        public InstSuatomB2(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuatomSize Size => (SuatomSize)((_opcode >> 36) & 0x7);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public SuatomOp Op => (SuatomOp)((_opcode >> 29) & 0xF);
+        public bool Ba => (_opcode & 0x10000000) != 0;
+    }
+
+    struct InstSuatomCasB
+    {
+        private ulong _opcode;
+        public InstSuatomCasB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuatomSize Size => (SuatomSize)((_opcode >> 36) & 0x7);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public int DestPred => (int)((_opcode >> 30) & 0x7);
+        public bool Ba => (_opcode & 0x10000000) != 0;
+    }
+
+    struct InstSuatomCas
+    {
+        private ulong _opcode;
+        public InstSuatomCas(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public SuatomSize Size => (SuatomSize)((_opcode >> 51) & 0x7);
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public int DestPred => (int)((_opcode >> 30) & 0x7);
+        public bool Ba => (_opcode & 0x10000000) != 0;
+    }
+
+    struct InstSuldDB
+    {
+        private ulong _opcode;
+        public InstSuldDB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public int DestPred2 => (int)((_opcode >> 30) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public bool Ba => (_opcode & 0x800000) != 0;
+        public SuSize Size => (SuSize)((_opcode >> 20) & 0x7);
+    }
+
+    struct InstSuldD
+    {
+        private ulong _opcode;
+        public InstSuldD(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public int DestPred2 => (int)((_opcode >> 30) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public bool Ba => (_opcode & 0x800000) != 0;
+        public SuSize Size => (SuSize)((_opcode >> 20) & 0x7);
+    }
+
+    struct InstSuldB
+    {
+        private ulong _opcode;
+        public InstSuldB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public int DestPred2 => (int)((_opcode >> 30) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public SuRgba Rgba => (SuRgba)((_opcode >> 20) & 0xF);
+    }
+
+    struct InstSuld
+    {
+        private ulong _opcode;
+        public InstSuld(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public int DestPred2 => (int)((_opcode >> 30) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public SuRgba Rgba => (SuRgba)((_opcode >> 20) & 0xF);
+    }
+
+    struct InstSuredB
+    {
+        private ulong _opcode;
+        public InstSuredB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public RedOp Op => (RedOp)((_opcode >> 24) & 0x7);
+        public bool Ba => (_opcode & 0x800000) != 0;
+        public SuatomSize Size => (SuatomSize)((_opcode >> 20) & 0x7);
+    }
+
+    struct InstSured
+    {
+        private ulong _opcode;
+        public InstSured(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public RedOp Op => (RedOp)((_opcode >> 24) & 0x7);
+        public bool Ba => (_opcode & 0x800000) != 0;
+        public SuatomSize Size => (SuatomSize)((_opcode >> 20) & 0x7);
+    }
+
+    struct InstSustDB
+    {
+        private ulong _opcode;
+        public InstSustDB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public bool Ba => (_opcode & 0x800000) != 0;
+        public SuSize Size => (SuSize)((_opcode >> 20) & 0x7);
+    }
+
+    struct InstSustD
+    {
+        private ulong _opcode;
+        public InstSustD(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public bool Ba => (_opcode & 0x800000) != 0;
+        public SuSize Size => (SuSize)((_opcode >> 20) & 0x7);
+    }
+
+    struct InstSustB
+    {
+        private ulong _opcode;
+        public InstSustB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public SuRgba Rgba => (SuRgba)((_opcode >> 20) & 0xF);
+    }
+
+    struct InstSust
+    {
+        private ulong _opcode;
+        public InstSust(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Clamp Clamp => (Clamp)((_opcode >> 49) & 0x3);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public SuDim Dim => (SuDim)((_opcode >> 33) & 0x7);
+        public CacheOp CacheOp => (CacheOp)((_opcode >> 24) & 0x3);
+        public SuRgba Rgba => (SuRgba)((_opcode >> 20) & 0xF);
+    }
+
+    struct InstSync
+    {
+        private ulong _opcode;
+        public InstSync(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public Ccc Ccc => (Ccc)((_opcode >> 0) & 0x1F);
+    }
+
+    struct InstTex
+    {
+        private ulong _opcode;
+        public InstTex(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Lc => (_opcode & 0x400000000000000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public Lod Lod => (Lod)((_opcode >> 55) & 0x7);
+        public bool Aoffi => (_opcode & 0x40000000000000) != 0;
+        public bool Dc => (_opcode & 0x4000000000000) != 0;
+        public bool Ndv => (_opcode & 0x800000000) != 0;
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+    }
+
+    struct InstTexB
+    {
+        private ulong _opcode;
+        public InstTexB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Lcb => (_opcode & 0x10000000000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public Lod Lodb => (Lod)((_opcode >> 37) & 0x7);
+        public bool Aoffib => (_opcode & 0x1000000000) != 0;
+        public bool Dc => (_opcode & 0x4000000000000) != 0;
+        public bool Ndv => (_opcode & 0x800000000) != 0;
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+    }
+
+    struct InstTexs
+    {
+        private ulong _opcode;
+        public InstTexs(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public TexsTarget Target => (TexsTarget)((_opcode >> 53) & 0xF);
+        public int WMask => (int)((_opcode >> 50) & 0x7);
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int Dest2 => (int)((_opcode >> 28) & 0xFF);
+    }
+
+    struct InstTld
+    {
+        private ulong _opcode;
+        public InstTld(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public bool Lod => (_opcode & 0x80000000000000) != 0;
+        public bool Toff => (_opcode & 0x800000000) != 0;
+        public bool Ms => (_opcode & 0x4000000000000) != 0;
+        public bool Cl => (_opcode & 0x40000000000000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+    }
+
+    struct InstTldB
+    {
+        private ulong _opcode;
+        public InstTldB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public bool Lod => (_opcode & 0x80000000000000) != 0;
+        public bool Toff => (_opcode & 0x800000000) != 0;
+        public bool Ms => (_opcode & 0x4000000000000) != 0;
+        public bool Cl => (_opcode & 0x40000000000000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+    }
+
+    struct InstTlds
+    {
+        private ulong _opcode;
+        public InstTlds(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public TldsTarget Target => (TldsTarget)((_opcode >> 53) & 0xF);
+        public int WMask => (int)((_opcode >> 50) & 0x7);
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int Dest2 => (int)((_opcode >> 28) & 0xFF);
+    }
+
+    struct InstTld4
+    {
+        private ulong _opcode;
+        public InstTld4(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Lc => (_opcode & 0x400000000000000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public TexComp TexComp => (TexComp)((_opcode >> 56) & 0x3);
+        public TexOffset Toff => (TexOffset)((_opcode >> 54) & 0x3);
+        public bool Dc => (_opcode & 0x4000000000000) != 0;
+        public bool Ndv => (_opcode & 0x800000000) != 0;
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+    }
+
+    struct InstTld4B
+    {
+        private ulong _opcode;
+        public InstTld4B(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Lc => (_opcode & 0x10000000000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public TexComp TexComp => (TexComp)((_opcode >> 38) & 0x3);
+        public TexOffset Toff => (TexOffset)((_opcode >> 36) & 0x3);
+        public bool Dc => (_opcode & 0x4000000000000) != 0;
+        public bool Ndv => (_opcode & 0x800000000) != 0;
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+    }
+
+    struct InstTld4s
+    {
+        private ulong _opcode;
+        public InstTld4s(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public TexComp TexComp => (TexComp)((_opcode >> 52) & 0x3);
+        public bool Aoffi => (_opcode & 0x8000000000000) != 0;
+        public bool Dc => (_opcode & 0x4000000000000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int Dest2 => (int)((_opcode >> 28) & 0xFF);
+    }
+
+    struct InstTmml
+    {
+        private ulong _opcode;
+        public InstTmml(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public bool Ndv => (_opcode & 0x800000000) != 0;
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+    }
+
+    struct InstTmmlB
+    {
+        private ulong _opcode;
+        public InstTmmlB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public bool Ndv => (_opcode & 0x800000000) != 0;
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+    }
+
+    struct InstTxa
+    {
+        private ulong _opcode;
+        public InstTxa(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public bool Ndv => (_opcode & 0x800000000) != 0;
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+    }
+
+    struct InstTxd
+    {
+        private ulong _opcode;
+        public InstTxd(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public bool Lc => (_opcode & 0x4000000000000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public bool Toff => (_opcode & 0x800000000) != 0;
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+    }
+
+    struct InstTxdB
+    {
+        private ulong _opcode;
+        public InstTxdB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int DestPred => (int)((_opcode >> 51) & 0x7);
+        public bool Lc => (_opcode & 0x4000000000000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public bool Toff => (_opcode & 0x800000000) != 0;
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public TexDim Dim => (TexDim)((_opcode >> 28) & 0x7);
+    }
+
+    struct InstTxq
+    {
+        private ulong _opcode;
+        public InstTxq(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int TidB => (int)((_opcode >> 36) & 0x1FFF);
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public TexQuery TexQuery => (TexQuery)((_opcode >> 22) & 0x3F);
+    }
+
+    struct InstTxqB
+    {
+        private ulong _opcode;
+        public InstTxqB(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool Nodep => (_opcode & 0x2000000000000) != 0;
+        public int WMask => (int)((_opcode >> 31) & 0xF);
+        public TexQuery TexQuery => (TexQuery)((_opcode >> 22) & 0x3F);
+    }
+
+    struct InstVabsdiff
+    {
+        private ulong _opcode;
+        public InstVabsdiff(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool DFormat => (_opcode & 0x40000000000000) != 0;
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((int)((_opcode >> 46) & 0x8) | (int)((_opcode >> 28) & 0x7));
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public VideoOp VideoOp => (VideoOp)((_opcode >> 51) & 0x7);
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstVabsdiff4
+    {
+        private ulong _opcode;
+        public InstVabsdiff4(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public VideoRed VRed => (VideoRed)((_opcode >> 53) & 0x3);
+        public LaneMask4 LaneMask4 => (LaneMask4)((int)((_opcode >> 49) & 0xC) | (int)((_opcode >> 36) & 0x3));
+        public bool Sat => (_opcode & 0x4000000000000) != 0;
+        public bool SrcBFmt => (_opcode & 0x2000000000000) != 0;
+        public bool SrcAFmt => (_opcode & 0x1000000000000) != 0;
+        public bool DFormat => (_opcode & 0x4000000000) != 0;
+        public ASelect4 Asel4 => (ASelect4)((_opcode >> 32) & 0xF);
+        public BSelect4 Bsel4 => (BSelect4)((_opcode >> 28) & 0xF);
+    }
+
+    struct InstVadd
+    {
+        private ulong _opcode;
+        public InstVadd(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 56) & 0x3);
+        public bool DFormat => (_opcode & 0x40000000000000) != 0;
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((int)((_opcode >> 46) & 0x8) | (int)((_opcode >> 28) & 0x7));
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public VideoOp VideoOp => (VideoOp)((_opcode >> 51) & 0x7);
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstVmad
+    {
+        private ulong _opcode;
+        public InstVmad(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((int)((_opcode >> 46) & 0x8) | (int)((_opcode >> 28) & 0x7));
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public AvgMode AvgMode => (AvgMode)((_opcode >> 53) & 0x3);
+        public VideoScale VideoScale => (VideoScale)((_opcode >> 51) & 0x3);
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstVmnmx
+    {
+        private ulong _opcode;
+        public InstVmnmx(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public int Imm16 => (int)((_opcode >> 20) & 0xFFFF);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool DFormat => (_opcode & 0x40000000000000) != 0;
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((int)((_opcode >> 46) & 0x8) | (int)((_opcode >> 28) & 0x7));
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public VideoOp VideoOp => (VideoOp)((_opcode >> 51) & 0x7);
+        public bool Mn => (_opcode & 0x100000000000000) != 0;
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstVote
+    {
+        private ulong _opcode;
+        public InstVote(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public VoteMode VoteMode => (VoteMode)((_opcode >> 48) & 0x3);
+        public int VpDest => (int)((_opcode >> 45) & 0x7);
+    }
+
+    struct InstVotevtg
+    {
+        private ulong _opcode;
+        public InstVotevtg(ulong opcode) => _opcode = opcode;
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public VoteMode VoteMode => (VoteMode)((_opcode >> 48) & 0x3);
+        public int Imm28 => (int)((_opcode >> 20) & 0xFFFFFFF);
+    }
+
+    struct InstVset
+    {
+        private ulong _opcode;
+        public InstVset(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public IComp VComp => (IComp)((_opcode >> 54) & 0x7);
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((int)((_opcode >> 46) & 0x8) | (int)((_opcode >> 28) & 0x7));
+        public VideoOp VideoOp => (VideoOp)((_opcode >> 51) & 0x7);
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstVsetp
+    {
+        private ulong _opcode;
+        public InstVsetp(ulong opcode) => _opcode = opcode;
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((int)((_opcode >> 46) & 0x8) | (int)((_opcode >> 28) & 0x7));
+        public IComp VComp => (IComp)((int)((_opcode >> 45) & 0x4) | (int)((_opcode >> 43) & 0x3));
+        public BoolOp BoolOp => (BoolOp)((_opcode >> 45) & 0x3);
+        public int SrcPred => (int)((_opcode >> 39) & 0x7);
+        public bool SrcPredInv => (_opcode & 0x40000000000) != 0;
+        public int DestPred => (int)((_opcode >> 3) & 0x7);
+        public int DestPredInv => (int)((_opcode >> 0) & 0x7);
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstVshl
+    {
+        private ulong _opcode;
+        public InstVshl(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Mv => (_opcode & 0x2000000000000) != 0;
+        public bool DFormat => (_opcode & 0x40000000000000) != 0;
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((_opcode >> 28) & 0x7);
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public VideoOp VideoOp => (VideoOp)((_opcode >> 51) & 0x7);
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstVshr
+    {
+        private ulong _opcode;
+        public InstVshr(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Mv => (_opcode & 0x2000000000000) != 0;
+        public bool DFormat => (_opcode & 0x40000000000000) != 0;
+        public VectorSelect ASelect => (VectorSelect)((int)((_opcode >> 45) & 0x8) | (int)((_opcode >> 36) & 0x7));
+        public VectorSelect BSelect => (VectorSelect)((_opcode >> 28) & 0x7);
+        public bool Sat => (_opcode & 0x80000000000000) != 0;
+        public VideoOp VideoOp => (VideoOp)((_opcode >> 51) & 0x7);
+        public bool BVideo => (_opcode & 0x4000000000000) != 0;
+    }
+
+    struct InstXmadR
+    {
+        private ulong _opcode;
+        public InstXmadR(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcB => (int)((_opcode >> 20) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool HiloA => (_opcode & 0x20000000000000) != 0;
+        public XmadCop XmadCop => (XmadCop)((_opcode >> 50) & 0x7);
+        public bool BSigned => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+        public bool X => (_opcode & 0x4000000000) != 0;
+        public bool Mrg => (_opcode & 0x2000000000) != 0;
+        public bool Psl => (_opcode & 0x1000000000) != 0;
+        public bool HiloB => (_opcode & 0x800000000) != 0;
+    }
+
+    struct InstXmadI
+    {
+        private ulong _opcode;
+        public InstXmadI(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public int Imm16 => (int)((_opcode >> 20) & 0xFFFF);
+        public bool HiloA => (_opcode & 0x20000000000000) != 0;
+        public XmadCop XmadCop => (XmadCop)((_opcode >> 50) & 0x7);
+        public bool BSigned => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+        public bool X => (_opcode & 0x4000000000) != 0;
+        public bool Mrg => (_opcode & 0x2000000000) != 0;
+        public bool Psl => (_opcode & 0x1000000000) != 0;
+    }
+
+    struct InstXmadC
+    {
+        private ulong _opcode;
+        public InstXmadC(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool Mrg => (_opcode & 0x100000000000000) != 0;
+        public bool Psl => (_opcode & 0x80000000000000) != 0;
+        public bool X => (_opcode & 0x40000000000000) != 0;
+        public bool HiloA => (_opcode & 0x20000000000000) != 0;
+        public bool HiloB => (_opcode & 0x10000000000000) != 0;
+        public XmadCop2 XmadCop => (XmadCop2)((_opcode >> 50) & 0x3);
+        public bool BSigned => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+    }
+
+    struct InstXmadRc
+    {
+        private ulong _opcode;
+        public InstXmadRc(ulong opcode) => _opcode = opcode;
+        public int Dest => (int)((_opcode >> 0) & 0xFF);
+        public int SrcA => (int)((_opcode >> 8) & 0xFF);
+        public int SrcC => (int)((_opcode >> 39) & 0xFF);
+        public int CbufSlot => (int)((_opcode >> 34) & 0x1F);
+        public int CbufOffset => (int)((_opcode >> 20) & 0x3FFF);
+        public int Pred => (int)((_opcode >> 16) & 0x7);
+        public bool PredInv => (_opcode & 0x80000) != 0;
+        public bool WriteCC => (_opcode & 0x800000000000) != 0;
+        public bool X => (_opcode & 0x40000000000000) != 0;
+        public bool HiloA => (_opcode & 0x20000000000000) != 0;
+        public bool HiloB => (_opcode & 0x10000000000000) != 0;
+        public XmadCop2 XmadCop => (XmadCop2)((_opcode >> 50) & 0x3);
+        public bool BSigned => (_opcode & 0x2000000000000) != 0;
+        public bool ASigned => (_opcode & 0x1000000000000) != 0;
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/InstName.cs b/Ryujinx.Graphics.Shader/Decoders/InstName.cs
new file mode 100644
index 0000000000..9c79b7a5cc
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/InstName.cs
@@ -0,0 +1,188 @@
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+    enum InstName : byte
+    {
+        Invalid = 0,
+
+        Al2p,
+        Ald,
+        Ast,
+        Atom,
+        AtomCas,
+        Atoms,
+        AtomsCas,
+        B2r,
+        Bar,
+        Bfe,
+        Bfi,
+        Bpt,
+        Bra,
+        Brk,
+        Brx,
+        Cal,
+        Cctl,
+        Cctll,
+        Cctlt,
+        Cont,
+        Cset,
+        Csetp,
+        Cs2r,
+        Dadd,
+        Depbar,
+        Dfma,
+        Dmnmx,
+        Dmul,
+        Dset,
+        Dsetp,
+        Exit,
+        F2f,
+        F2i,
+        Fadd,
+        Fadd32i,
+        Fchk,
+        Fcmp,
+        Ffma,
+        Ffma32i,
+        Flo,
+        Fmnmx,
+        Fmul,
+        Fmul32i,
+        Fset,
+        Fsetp,
+        Fswzadd,
+        Getcrsptr,
+        Getlmembase,
+        Hadd2,
+        Hadd232i,
+        Hfma2,
+        Hmul2,
+        Hmul232i,
+        Hset2,
+        Hsetp2,
+        I2f,
+        I2i,
+        Iadd,
+        Iadd32i,
+        Iadd3,
+        Icmp,
+        Ide,
+        Idp,
+        Imad,
+        Imad32i,
+        Imadsp,
+        Imnmx,
+        Imul,
+        Imul32i,
+        Ipa,
+        Isberd,
+        Iscadd,
+        Iscadd32i,
+        Iset,
+        Isetp,
+        Jcal,
+        Jmp,
+        Jmx,
+        Kil,
+        Ld,
+        Ldc,
+        Ldg,
+        Ldl,
+        Lds,
+        Lea,
+        LeaHi,
+        Lepc,
+        Longjmp,
+        Lop,
+        Lop3,
+        Lop32i,
+        Membar,
+        Mov,
+        Mov32i,
+        Mufu,
+        Nop,
+        Out,
+        P2r,
+        Pbk,
+        Pcnt,
+        Pexit,
+        Pixld,
+        Plongjmp,
+        Popc,
+        Pret,
+        Prmt,
+        Pset,
+        Psetp,
+        R2b,
+        R2p,
+        Ram,
+        Red,
+        Ret,
+        Rro,
+        Rtt,
+        S2r,
+        Sam,
+        Sel,
+        Setcrsptr,
+        Setlmembase,
+        Shf,
+        Shf_2,
+        Shf_3,
+        Shf_4,
+        Shfl,
+        Shl,
+        Shr,
+        Ssy,
+        St,
+        Stg,
+        Stl,
+        Stp,
+        Sts,
+        SuatomB,
+        Suatom,
+        SuatomB2,
+        SuatomCasB,
+        SuatomCas,
+        SuldDB,
+        SuldD,
+        SuldB,
+        Suld,
+        SuredB,
+        Sured,
+        SustDB,
+        SustD,
+        SustB,
+        Sust,
+        Sync,
+        Tex,
+        TexB,
+        Texs,
+        TexsF16,
+        Tld,
+        TldB,
+        Tlds,
+        TldsF16,
+        Tld4,
+        Tld4B,
+        Tld4s,
+        Tld4sF16,
+        Tmml,
+        TmmlB,
+        Txa,
+        Txd,
+        TxdB,
+        Txq,
+        TxqB,
+        Vabsdiff,
+        Vabsdiff4,
+        Vadd,
+        Vmad,
+        Vmnmx,
+        Vote,
+        Votevtg,
+        Vset,
+        Vsetp,
+        Vshl,
+        Vshr,
+        Xmad,
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/InstOp.cs b/Ryujinx.Graphics.Shader/Decoders/InstOp.cs
new file mode 100644
index 0000000000..39244e647f
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/InstOp.cs
@@ -0,0 +1,27 @@
+using Ryujinx.Graphics.Shader.Instructions;
+
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+    readonly struct InstOp
+    {
+        public readonly ulong Address;
+        public readonly ulong RawOpCode;
+        public readonly InstEmitter Emitter;
+        public readonly InstProps Props;
+        public readonly InstName Name;
+
+        public InstOp(ulong address, ulong rawOpCode, InstName name, InstEmitter emitter, InstProps props)
+        {
+            Address = address;
+            RawOpCode = rawOpCode;
+            Name = name;
+            Emitter = emitter;
+            Props = props;
+        }
+
+        public ulong GetAbsoluteAddress()
+        {
+            return (ulong)((long)Address + (((int)(RawOpCode >> 20) << 8) >> 8) + 8);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/InstProps.cs b/Ryujinx.Graphics.Shader/Decoders/InstProps.cs
new file mode 100644
index 0000000000..7d329a81e5
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/InstProps.cs
@@ -0,0 +1,20 @@
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+    enum InstProps : ushort
+    {
+        None = 0,
+        Rd = 1 << 0,
+        Rd2 = 1 << 1,
+        Ra = 1 << 2,
+        Rb = 1 << 3,
+        Ib = 1 << 4,
+        Rc = 1 << 5,
+        Pd = 1 << 6,
+        Pd2 = 1 << 7,
+        Pdn = 1 << 8,
+        Tex = 1 << 9,
+        TexB = 1 << 10,
+        Bra = 1 << 11,
+        NoPred = 1 << 12
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/InstTable.cs b/Ryujinx.Graphics.Shader/Decoders/InstTable.cs
new file mode 100644
index 0000000000..c971d64686
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Decoders/InstTable.cs
@@ -0,0 +1,388 @@
+using Ryujinx.Graphics.Shader.Instructions;
+
+namespace Ryujinx.Graphics.Shader.Decoders
+{
+    static class InstTable
+    {
+        private const int EncodingBits = 14;
+
+        private struct TableEntry
+        {
+            public InstName Name { get; }
+            public InstEmitter Emitter { get; }
+            public InstProps Props { get; }
+
+            public int XBits { get; }
+
+            public TableEntry(InstName name, InstEmitter emitter, InstProps props, int xBits)
+            {
+                Name = name;
+                Emitter = emitter;
+                Props = props;
+                XBits = xBits;
+            }
+        }
+
+        private static TableEntry[] _opCodes;
+
+        static InstTable()
+        {
+            _opCodes = new TableEntry[1 << EncodingBits];
+
+            #region Instructions
+            Add("1110111110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Al2p,        InstEmit.Al2p,        InstProps.Rd  | InstProps.Ra);
+            Add("1110111111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ald,         InstEmit.Ald,         InstProps.Rd  | InstProps.Ra);
+            Add("1110111111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ast,         InstEmit.Ast,         InstProps.Ra  | InstProps.Rc);
+            Add("11101101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Atom,        InstEmit.Atom,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("111011101111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.AtomCas,     InstEmit.AtomCas,     InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("11101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Atoms,       InstEmit.Atoms,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("111011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.AtomsCas,    InstEmit.AtomsCas,    InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("1111000010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.B2r,         InstEmit.B2r,         InstProps.Rd  | InstProps.Ra);
+            Add("1111000010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bar,         InstEmit.Bar,         InstProps.Ra);
+            Add("0101110000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfe,         InstEmit.BfeR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x00000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfe,         InstEmit.BfeI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfe,         InstEmit.BfeC,        InstProps.Rd  | InstProps.Ra);
+            Add("0101101111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi,         InstEmit.BfiR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011011x11110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi,         InstEmit.BfiI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("0100101111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi,         InstEmit.BfiC,        InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("0101001111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bfi,         InstEmit.BfiRc,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("111000111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bpt,         InstEmit.Bpt,         InstProps.NoPred);
+            Add("111000100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bra,         InstEmit.Bra,         InstProps.Bra);
+            Add("111000110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Brk,         InstEmit.Brk,         InstProps.Bra);
+            Add("111000100101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Brx,         InstEmit.Brx,         InstProps.Ra  | InstProps.Bra);
+            Add("111000100110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cal,         InstEmit.Cal,         InstProps.Bra | InstProps.NoPred);
+            Add("11101111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctl,        InstEmit.Cctl,        InstProps.Ra);
+            Add("1110111110000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctll,       InstEmit.Cctll,       InstProps.Ra);
+            Add("1110101111110xx0000000000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctlt,       InstEmit.Cctlt);
+            Add("1110101111101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cctlt,       InstEmit.Cctlt,       InstProps.Rc);
+            Add("111000110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cont,        InstEmit.Cont);
+            Add("0101000010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cset,        InstEmit.Cset,        InstProps.Rd);
+            Add("0101000010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Csetp,       InstEmit.Csetp,       InstProps.Pd  | InstProps.Pdn);
+            Add("0101000011001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Cs2r,        InstEmit.Cs2r,        InstProps.Rd);
+            Add("0101110001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dadd,        InstEmit.DaddR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x01110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dadd,        InstEmit.DaddI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dadd,        InstEmit.DaddC,       InstProps.Rd  | InstProps.Ra);
+            Add("1111000011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Depbar,      InstEmit.Depbar);
+            Add("010110110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma,        InstEmit.DfmaR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011011x0111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma,        InstEmit.DfmaI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010010110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma,        InstEmit.DfmaC,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dfma,        InstEmit.DfmaRc,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("0101110001010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx,       InstEmit.DmnmxR,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x01010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx,       InstEmit.DmnmxI,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110001010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmnmx,       InstEmit.DmnmxC,      InstProps.Rd  | InstProps.Ra);
+            Add("0101110010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmul,        InstEmit.DmulR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x10000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmul,        InstEmit.DmulI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dmul,        InstEmit.DmulC,       InstProps.Rd  | InstProps.Ra);
+            Add("010110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset,        InstEmit.DsetR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011001x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset,        InstEmit.DsetI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("010010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dset,        InstEmit.DsetC,       InstProps.Rd  | InstProps.Ra);
+            Add("010110111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp,       InstEmit.DsetpR,      InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Pdn);
+            Add("0011011x1000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp,       InstEmit.DsetpI,      InstProps.Ra  | InstProps.Ib  | InstProps.Pd  | InstProps.Pdn);
+            Add("010010111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Dsetp,       InstEmit.DsetpC,      InstProps.Ra  | InstProps.Pd  | InstProps.Pdn);
+            Add("111000110000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Exit,        InstEmit.Exit,        InstProps.Bra);
+            Add("0101110010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2f,         InstEmit.F2fR,        InstProps.Rd  | InstProps.Rb);
+            Add("0011100x10101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2f,         InstEmit.F2fI,        InstProps.Rd  | InstProps.Ib);
+            Add("0100110010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2f,         InstEmit.F2fC,        InstProps.Rd);
+            Add("0101110010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2i,         InstEmit.F2iR,        InstProps.Rd  | InstProps.Rb);
+            Add("0011100x10110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2i,         InstEmit.F2iI,        InstProps.Rd  | InstProps.Ib);
+            Add("0100110010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.F2i,         InstEmit.F2iC,        InstProps.Rd);
+            Add("0101110001011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd,        InstEmit.FaddR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x01011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd,        InstEmit.FaddI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110001011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd,        InstEmit.FaddC,       InstProps.Rd  | InstProps.Ra);
+            Add("000010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fadd32i,     InstEmit.Fadd32i,     InstProps.Rd  | InstProps.Ra);
+            Add("0101110010001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fchk,        InstEmit.FchkR,       InstProps.Ra  | InstProps.Rb  | InstProps.Pd);
+            Add("0011100x10001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fchk,        InstEmit.FchkI,       InstProps.Ra  | InstProps.Ib  | InstProps.Pd);
+            Add("0100110010001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fchk,        InstEmit.FchkC,       InstProps.Ra  | InstProps.Pd);
+            Add("010110111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp,        InstEmit.FcmpR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011011x1010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp,        InstEmit.FcmpI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010010111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp,        InstEmit.FcmpC,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fcmp,        InstEmit.FcmpRc,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma,        InstEmit.FfmaR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011001x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma,        InstEmit.FfmaI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma,        InstEmit.FfmaC,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma,        InstEmit.FfmaRc,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("000011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ffma32i,     InstEmit.Ffma32i,     InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("0101110000110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Flo,         InstEmit.FloR,        InstProps.Rd  | InstProps.Rb);
+            Add("0011100x00110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Flo,         InstEmit.FloI,        InstProps.Rd  | InstProps.Ib);
+            Add("0100110000110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Flo,         InstEmit.FloC,        InstProps.Rd);
+            Add("0101110001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx,       InstEmit.FmnmxR,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x01100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx,       InstEmit.FmnmxI,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmnmx,       InstEmit.FmnmxC,      InstProps.Rd  | InstProps.Ra);
+            Add("0101110001101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul,        InstEmit.FmulR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x01101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul,        InstEmit.FmulI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110001101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul,        InstEmit.FmulC,       InstProps.Rd  | InstProps.Ra);
+            Add("00011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fmul32i,     InstEmit.Fmul32i,     InstProps.Rd  | InstProps.Ra);
+            Add("01011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset,        InstEmit.FsetR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset,        InstEmit.FsetI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("01001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fset,        InstEmit.FsetC,       InstProps.Rd  | InstProps.Ra);
+            Add("010110111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp,       InstEmit.FsetpR,      InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Pdn);
+            Add("0011011x1011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp,       InstEmit.FsetpI,      InstProps.Ra  | InstProps.Ib  | InstProps.Pd  | InstProps.Pdn);
+            Add("010010111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fsetp,       InstEmit.FsetpC,      InstProps.Ra  | InstProps.Pd  | InstProps.Pdn);
+            Add("0101000011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Fswzadd,     InstEmit.Fswzadd,     InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("111000101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Getcrsptr,   InstEmit.Getcrsptr,   InstProps.Rd  | InstProps.NoPred);
+            Add("111000101101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Getlmembase, InstEmit.Getlmembase, InstProps.Rd  | InstProps.NoPred);
+            Add("0101110100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd2,       InstEmit.Hadd2R,      InstProps.Rd  | InstProps.Ra);
+            Add("0111101x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd2,       InstEmit.Hadd2I,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0111101x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd2,       InstEmit.Hadd2C,      InstProps.Rd  | InstProps.Ra);
+            Add("0010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hadd232i,    InstEmit.Hadd232i,    InstProps.Rd  | InstProps.Ra);
+            Add("0101110100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2,       InstEmit.Hfma2R,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("01110xxx0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2,       InstEmit.Hfma2I,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("01110xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2,       InstEmit.Hfma2C,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("01100xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hfma2,       InstEmit.Hfma2Rc,     InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("0101110100001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul2,       InstEmit.Hmul2R,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0111100x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul2,       InstEmit.Hmul2I,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0111100x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul2,       InstEmit.Hmul2C,      InstProps.Rd  | InstProps.Ra);
+            Add("0010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hmul232i,    InstEmit.Hmul232i,    InstProps.Rd  | InstProps.Ra);
+            Add("0101110100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2,       InstEmit.Hset2R,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0111110x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2,       InstEmit.Hset2I,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0111110x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hset2,       InstEmit.Hset2C,      InstProps.Rd  | InstProps.Ra);
+            Add("0101110100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2,      InstEmit.Hsetp2R,     InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Pdn);
+            Add("0111111x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2,      InstEmit.Hsetp2I,     InstProps.Ra  | InstProps.Ib  | InstProps.Pd  | InstProps.Pdn);
+            Add("0111111x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Hsetp2,      InstEmit.Hsetp2C,     InstProps.Ra  | InstProps.Pd  | InstProps.Pdn);
+            Add("0101110010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2f,         InstEmit.I2fR,        InstProps.Rd  | InstProps.Rb);
+            Add("0011100x10111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2f,         InstEmit.I2fI,        InstProps.Rd  | InstProps.Ib);
+            Add("0100110010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2f,         InstEmit.I2fC,        InstProps.Rd);
+            Add("0101110011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2i,         InstEmit.I2iR,        InstProps.Rd  | InstProps.Rb);
+            Add("0011100x11100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2i,         InstEmit.I2iI,        InstProps.Rd  | InstProps.Ib);
+            Add("0100110011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.I2i,         InstEmit.I2iC,        InstProps.Rd);
+            Add("0101110000010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd,        InstEmit.IaddR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x00010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd,        InstEmit.IaddI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110000010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd,        InstEmit.IaddC,       InstProps.Rd  | InstProps.Ra);
+            Add("0001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd32i,     InstEmit.Iadd32i,     InstProps.Rd  | InstProps.Ra);
+            Add("010111001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd3,       InstEmit.Iadd3R,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011100x1100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd3,       InstEmit.Iadd3I,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010011001100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iadd3,       InstEmit.Iadd3C,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010110110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp,        InstEmit.IcmpR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011011x0100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp,        InstEmit.IcmpI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010010110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp,        InstEmit.IcmpC,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Icmp,        InstEmit.IcmpRc,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("111000111001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ide,         InstEmit.Ide,         InstProps.NoPred);
+            Add("0101001111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Idp,         InstEmit.IdpR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0101001111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Idp,         InstEmit.IdpC,        InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010110100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad,        InstEmit.ImadR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011010x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad,        InstEmit.ImadI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad,        InstEmit.ImadC,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad,        InstEmit.ImadRc,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("000100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imad32i,     InstEmit.Imad32i,     InstProps.Rd  | InstProps.Ra);
+            Add("010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp,      InstEmit.ImadspR,     InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011010x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp,      InstEmit.ImadspI,     InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010010101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp,      InstEmit.ImadspC,     InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imadsp,      InstEmit.ImadspRc,    InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("0101110000100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx,       InstEmit.ImnmxR,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x00100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx,       InstEmit.ImnmxI,      InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110000100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imnmx,       InstEmit.ImnmxC,      InstProps.Rd  | InstProps.Ra);
+            Add("0101110000111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul,        InstEmit.ImulR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x00111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul,        InstEmit.ImulI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110000111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul,        InstEmit.ImulC,       InstProps.Rd  | InstProps.Ra);
+            Add("00011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Imul32i,     InstEmit.Imul32i,     InstProps.Rd  | InstProps.Ra);
+            Add("11100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ipa,         InstEmit.Ipa,         InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("1110111111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isberd,      InstEmit.Isberd,      InstProps.Rd  | InstProps.Ra);
+            Add("0101110000011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd,      InstEmit.IscaddR,     InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x00011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd,      InstEmit.IscaddI,     InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110000011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd,      InstEmit.IscaddC,     InstProps.Rd  | InstProps.Ra);
+            Add("000101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iscadd32i,   InstEmit.Iscadd32i,   InstProps.Rd  | InstProps.Ra);
+            Add("010110110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset,        InstEmit.IsetR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011011x0101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset,        InstEmit.IsetI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("010010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Iset,        InstEmit.IsetC,       InstProps.Rd  | InstProps.Ra);
+            Add("010110110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp,       InstEmit.IsetpR,      InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Pdn);
+            Add("0011011x0110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp,       InstEmit.IsetpI,      InstProps.Ra  | InstProps.Ib  | InstProps.Pd  | InstProps.Pdn);
+            Add("010010110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Isetp,       InstEmit.IsetpC,      InstProps.Ra  | InstProps.Pd  | InstProps.Pdn);
+            Add("111000100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Jcal,        InstEmit.Jcal,        InstProps.Bra);
+            Add("111000100001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Jmp,         InstEmit.Jmp,         InstProps.Ra  | InstProps.Bra);
+            Add("111000100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Jmx,         InstEmit.Jmx,         InstProps.Ra  | InstProps.Bra);
+            Add("111000110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Kil,         InstEmit.Kil,         InstProps.Bra);
+            Add("100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ld,          InstEmit.Ld,          InstProps.Rd  | InstProps.Ra);
+            Add("1110111110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ldc,         InstEmit.Ldc,         InstProps.Rd  | InstProps.Ra);
+            Add("1110111011010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ldg,         InstEmit.Ldg,         InstProps.Rd  | InstProps.Ra);
+            Add("1110111101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ldl,         InstEmit.Ldl,         InstProps.Rd  | InstProps.Ra);
+            Add("1110111101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lds,         InstEmit.Lds,         InstProps.Rd  | InstProps.Ra);
+            Add("0101101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea,         InstEmit.LeaR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd);
+            Add("0011011x11010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea,         InstEmit.LeaI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Pd);
+            Add("0100101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lea,         InstEmit.LeaC,        InstProps.Rd  | InstProps.Ra  | InstProps.Pd);
+            Add("0101101111011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.LeaHi,       InstEmit.LeaHiR,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc  | InstProps.Pd);
+            Add("000110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.LeaHi,       InstEmit.LeaHiC,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc  | InstProps.Pd);
+            Add("0101000011010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lepc,        InstEmit.Lepc);
+            Add("111000110001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Longjmp,     InstEmit.Longjmp,     InstProps.Bra);
+            Add("0101110001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop,         InstEmit.LopR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd);
+            Add("0011100x01000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop,         InstEmit.LopI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Pd);
+            Add("0100110001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop,         InstEmit.LopC,        InstProps.Rd  | InstProps.Ra  | InstProps.Pd);
+            Add("0101101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop3,        InstEmit.Lop3R,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc  | InstProps.Pd);
+            Add("001111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop3,        InstEmit.Lop3I,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("0000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop3,        InstEmit.Lop3C,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Lop32i,      InstEmit.Lop32i,      InstProps.Rd  | InstProps.Ra);
+            Add("1110111110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Membar,      InstEmit.Membar);
+            Add("0101110010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov,         InstEmit.MovR,        InstProps.Rd  | InstProps.Ra);
+            Add("0011100x10011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov,         InstEmit.MovI,        InstProps.Rd  | InstProps.Ib);
+            Add("0100110010011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov,         InstEmit.MovC,        InstProps.Rd);
+            Add("000000010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mov32i,      InstEmit.Mov32i,      InstProps.Rd);
+            Add("0101000010000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Mufu,        InstEmit.Mufu,        InstProps.Rd  | InstProps.Ra);
+            Add("0101000010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Nop,         InstEmit.Nop);
+            Add("1111101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Out,         InstEmit.OutR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("1111011x11100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Out,         InstEmit.OutI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("1110101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Out,         InstEmit.OutC,        InstProps.Rd  | InstProps.Ra);
+            Add("0101110011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.P2r,         InstEmit.P2rR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x11101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.P2r,         InstEmit.P2rI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.P2r,         InstEmit.P2rC,        InstProps.Rd  | InstProps.Ra);
+            Add("111000101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pbk,         InstEmit.Pbk,         InstProps.NoPred);
+            Add("111000101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pcnt,        InstEmit.Pcnt,        InstProps.NoPred);
+            Add("111000100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pexit,       InstEmit.Pexit);
+            Add("1110111111101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pixld,       InstEmit.Pixld,       InstProps.Rd  | InstProps.Ra);
+            Add("111000101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Plongjmp,    InstEmit.Plongjmp,    InstProps.Bra | InstProps.NoPred);
+            Add("0101110000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Popc,        InstEmit.PopcR,       InstProps.Rd  | InstProps.Rb);
+            Add("0011100x00001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Popc,        InstEmit.PopcI,       InstProps.Rd  | InstProps.Ib);
+            Add("0100110000001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Popc,        InstEmit.PopcC,       InstProps.Rd);
+            Add("111000100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pret,        InstEmit.Pret,        InstProps.NoPred);
+            Add("010110111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt,        InstEmit.PrmtR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011011x1100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt,        InstEmit.PrmtI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("010010111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt,        InstEmit.PrmtC,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Prmt,        InstEmit.PrmtRc,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("0101000010001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Pset,        InstEmit.Pset,        InstProps.Rd);
+            Add("0101000010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Psetp,       InstEmit.Psetp,       InstProps.Pd  | InstProps.Pdn);
+            Add("1111000011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2b,         InstEmit.R2b,         InstProps.Rb);
+            Add("0101110011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2p,         InstEmit.R2pR,        InstProps.Ra  | InstProps.Rb);
+            Add("0011100x11110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2p,         InstEmit.R2pI,        InstProps.Ra  | InstProps.Ib);
+            Add("0100110011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.R2p,         InstEmit.R2pC,        InstProps.Ra);
+            Add("111000111000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ram,         InstEmit.Ram,         InstProps.NoPred);
+            Add("1110101111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Red,         InstEmit.Red,         InstProps.Ra);
+            Add("111000110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ret,         InstEmit.Ret,         InstProps.Bra);
+            Add("0101110010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rro,         InstEmit.RroR,        InstProps.Rd  | InstProps.Rb);
+            Add("0011100x10010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rro,         InstEmit.RroI,        InstProps.Rd  | InstProps.Ib);
+            Add("0100110010010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rro,         InstEmit.RroC,        InstProps.Rd);
+            Add("111000110110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Rtt,         InstEmit.Rtt,         InstProps.NoPred);
+            Add("1111000011001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.S2r,         InstEmit.S2r,         InstProps.Rd);
+            Add("111000110111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sam,         InstEmit.Sam,         InstProps.NoPred);
+            Add("0101110010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel,         InstEmit.SelR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x10100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel,         InstEmit.SelI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sel,         InstEmit.SelC,        InstProps.Rd  | InstProps.Ra);
+            Add("111000101110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Setcrsptr,   InstEmit.Setcrsptr,   InstProps.Ra  | InstProps.NoPred);
+            Add("111000101111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Setlmembase, InstEmit.Setlmembase, InstProps.Ra  | InstProps.NoPred);
+            Add("0101101111111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf,         InstEmit.ShfLR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0101110011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf,         InstEmit.ShfRR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011011x11111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf,         InstEmit.ShfLI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("0011100x11111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shf,         InstEmit.ShfRI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("1110111100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shfl,        InstEmit.Shfl,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc  | InstProps.Pd);
+            Add("0101110001001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shl,         InstEmit.ShlR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x01001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shl,         InstEmit.ShlI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110001001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shl,         InstEmit.ShlC,        InstProps.Rd  | InstProps.Ra);
+            Add("0101110000101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shr,         InstEmit.ShrR,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("0011100x00101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shr,         InstEmit.ShrI,        InstProps.Rd  | InstProps.Ra  | InstProps.Ib);
+            Add("0100110000101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Shr,         InstEmit.ShrC,        InstProps.Rd  | InstProps.Ra);
+            Add("111000101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Ssy,         InstEmit.Ssy,         InstProps.NoPred);
+            Add("101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.St,          InstEmit.St,          InstProps.Rd  | InstProps.Ra);
+            Add("1110111011011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Stg,         InstEmit.Stg,         InstProps.Rd  | InstProps.Ra);
+            Add("1110111101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Stl,         InstEmit.Stl,         InstProps.Rd  | InstProps.Ra);
+            Add("1110111010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Stp,         InstEmit.Stp,         InstProps.NoPred);
+            Add("1110111101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sts,         InstEmit.Sts,         InstProps.Rd  | InstProps.Ra);
+            Add("1110101001110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomB,     InstEmit.SuatomB,     InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("11101010x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Suatom,      InstEmit.Suatom,      InstProps.Rd  | InstProps.Ra  | InstProps.Rb);
+            Add("1110101110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomB2,    InstEmit.SuatomB2,    InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("1110101011010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomCasB,  InstEmit.SuatomCasB,  InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc  | InstProps.Pd2);
+            Add("1110101x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuatomCas,   InstEmit.SuatomCas,   InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd2);
+            Add("111010110001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldDB,      InstEmit.SuldDB,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc  | InstProps.Pd2 | InstProps.TexB);
+            Add("1110101100011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldD,       InstEmit.SuldD,       InstProps.Rd  | InstProps.Ra  | InstProps.Pd2 | InstProps.Tex);
+            Add("11101011000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuldB,       InstEmit.SuldB,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc  | InstProps.Pd2 | InstProps.TexB);
+            Add("11101011000x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Suld,        InstEmit.Suld,        InstProps.Rd  | InstProps.Ra  | InstProps.Pd2 | InstProps.Tex);
+            Add("111010110101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SuredB,      InstEmit.SuredB,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("1110101101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sured,       InstEmit.Sured,       InstProps.Rd  | InstProps.Ra);
+            Add("111010110011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustDB,      InstEmit.SustDB,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc  | InstProps.TexB);
+            Add("1110101100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustD,       InstEmit.SustD,       InstProps.Rd  | InstProps.Ra  | InstProps.Tex);
+            Add("11101011001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.SustB,       InstEmit.SustB,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc  | InstProps.TexB);
+            Add("11101011001x1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sust,        InstEmit.Sust,        InstProps.Rd  | InstProps.Ra  | InstProps.Tex);
+            Add("1111000011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Sync,        InstEmit.Sync,        InstProps.Bra);
+            Add("11000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tex,         InstEmit.Tex,         InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Tex);
+            Add("1101111010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TexB,        InstEmit.TexB,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.TexB);
+            Add("1101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Texs,        InstEmit.Texs,        InstProps.Rd  | InstProps.Rd2 | InstProps.Ra  | InstProps.Rb  | InstProps.Tex);
+            Add("1101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TexsF16,     InstEmit.TexsF16,     InstProps.Rd  | InstProps.Rd2 | InstProps.Ra  | InstProps.Rb  | InstProps.Tex);
+            Add("11011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld,         InstEmit.Tld,         InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Tex);
+            Add("11011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TldB,        InstEmit.TldB,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.TexB);
+            Add("1101101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tlds,        InstEmit.Tlds,        InstProps.Rd  | InstProps.Rd2 | InstProps.Ra  | InstProps.Rb  | InstProps.Tex);
+            Add("1101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TldsF16,     InstEmit.TldsF16,     InstProps.Rd  | InstProps.Rd2 | InstProps.Ra  | InstProps.Rb  | InstProps.Tex);
+            Add("110010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4,        InstEmit.Tld4,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Tex);
+            Add("1101111011xxxxxxxxxxxxx0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4B,       InstEmit.Tld4B,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.TexB);
+            Add("1101111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4s,       InstEmit.Tld4s,       InstProps.Rd  | InstProps.Rd2 | InstProps.Ra  | InstProps.Rb  | InstProps.Tex);
+            Add("1101111110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tld4sF16,    InstEmit.Tld4sF16,    InstProps.Rd  | InstProps.Rd2 | InstProps.Ra  | InstProps.Rb  | InstProps.Tex);
+            Add("1101111101011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Tmml,        InstEmit.Tmml,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Tex);
+            Add("1101111101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TmmlB,       InstEmit.TmmlB,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.TexB);
+            Add("1101111101000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Txa,         InstEmit.Txa,         InstProps.Rd  | InstProps.Ra  | InstProps.Tex);
+            Add("110111100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Txd,         InstEmit.Txd,         InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Tex);
+            Add("1101111001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TxdB,        InstEmit.TxdB,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.TexB);
+            Add("1101111101001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Txq,         InstEmit.Txq,         InstProps.Rd  | InstProps.Ra  | InstProps.Tex);
+            Add("1101111101010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.TxqB,        InstEmit.TxqB,        InstProps.Rd  | InstProps.Ra  | InstProps.TexB);
+            Add("01010100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vabsdiff,    InstEmit.Vabsdiff,    InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("010100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vabsdiff4,   InstEmit.Vabsdiff4,   InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("001000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vadd,        InstEmit.Vadd,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("01011111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vmad,        InstEmit.Vmad,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vmnmx,       InstEmit.Vmnmx,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0101000011011xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vote,        InstEmit.Vote,        InstProps.Rd);
+            Add("0101000011100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Votevtg,     InstEmit.Votevtg);
+            Add("0100000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vset,        InstEmit.Vset,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0101000011110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vsetp,       InstEmit.Vsetp,       InstProps.Ra  | InstProps.Rb  | InstProps.Pd  | InstProps.Pdn);
+            Add("01010111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vshl,        InstEmit.Vshl,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("01010110xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Vshr,        InstEmit.Vshr,        InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0101101100xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad,        InstEmit.XmadR,       InstProps.Rd  | InstProps.Ra  | InstProps.Rb  | InstProps.Rc);
+            Add("0011011x00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad,        InstEmit.XmadI,       InstProps.Rd  | InstProps.Ra  | InstProps.Ib  | InstProps.Rc);
+            Add("0100111xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad,        InstEmit.XmadC,       InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            Add("010100010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Xmad,        InstEmit.XmadRc,      InstProps.Rd  | InstProps.Ra  | InstProps.Rc);
+            #endregion
+        }
+
+        private static void Add(string encoding, InstName name, InstEmitter emitter, InstProps props = InstProps.None)
+        {
+            encoding = encoding.Substring(0, EncodingBits);
+
+            int bit = encoding.Length - 1;
+            int value = 0;
+            int xMask = 0;
+            int xBits = 0;
+
+            int[] xPos = new int[encoding.Length];
+
+            for (int index = 0; index < encoding.Length; index++, bit--)
+            {
+                char chr = encoding[index];
+
+                if (chr == '1')
+                {
+                    value |= 1 << bit;
+                }
+                else if (chr == 'x')
+                {
+                    xMask |= 1 << bit;
+
+                    xPos[xBits++] = bit;
+                }
+            }
+
+            xMask = ~xMask;
+
+            TableEntry entry = new TableEntry(name, emitter, props, xBits);
+
+            for (int index = 0; index < (1 << xBits); index++)
+            {
+                value &= xMask;
+
+                for (int x = 0; x < xBits; x++)
+                {
+                    value |= ((index >> x) & 1) << xPos[x];
+                }
+
+                if (_opCodes[value].Emitter == null || _opCodes[value].XBits > xBits)
+                {
+                    _opCodes[value] = entry;
+                }
+            }
+        }
+
+        public static InstOp GetOp(ulong address, ulong opCode)
+        {
+            ref TableEntry entry = ref _opCodes[opCode >> (64 - EncodingBits)];
+
+            if (entry.Emitter != null)
+            {
+                return new InstOp(address, opCode, entry.Name, entry.Emitter, entry.Props);
+            }
+
+            return new InstOp(address, opCode, InstName.Invalid, null, InstProps.None);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IntegerCondition.cs b/Ryujinx.Graphics.Shader/Decoders/IntegerCondition.cs
deleted file mode 100644
index a1937c2f52..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IntegerCondition.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum IntegerCondition
-    {
-        Less    = 1 << 0,
-        Equal   = 1 << 1,
-        Greater = 1 << 2,
-
-        Never = 0,
-
-        LessOrEqual    = Less    | Equal,
-        NotEqual       = Less    | Greater,
-        GreaterOrEqual = Greater | Equal,
-        Number         = Greater | Equal | Less,
-
-        Always = 7
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IntegerHalfPart.cs b/Ryujinx.Graphics.Shader/Decoders/IntegerHalfPart.cs
deleted file mode 100644
index b779f44d4b..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IntegerHalfPart.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum IntegerHalfPart
-    {
-        B32 = 0,
-        H0  = 1,
-        H1  = 2
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IntegerShift.cs b/Ryujinx.Graphics.Shader/Decoders/IntegerShift.cs
deleted file mode 100644
index ce4d9f3bb6..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IntegerShift.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum IntegerShift
-    {
-        NoShift    = 0,
-        ShiftRight = 1,
-        ShiftLeft  = 2
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IntegerSize.cs b/Ryujinx.Graphics.Shader/Decoders/IntegerSize.cs
deleted file mode 100644
index d39c2a9091..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IntegerSize.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum IntegerSize
-    {
-        U8    = 0,
-        S8    = 1,
-        U16   = 2,
-        S16   = 3,
-        B32   = 4,
-        B64   = 5,
-        B128  = 6,
-        UB128 = 7
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/IntegerType.cs b/Ryujinx.Graphics.Shader/Decoders/IntegerType.cs
deleted file mode 100644
index 46734dbe4a..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/IntegerType.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum IntegerType
-    {
-        U8  = 0,
-        U16 = 1,
-        U32 = 2,
-        U64 = 3,
-        S8  = 4,
-        S16 = 5,
-        S32 = 6,
-        S64 = 7
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/InterpolationMode.cs b/Ryujinx.Graphics.Shader/Decoders/InterpolationMode.cs
deleted file mode 100644
index 98ee3b9703..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/InterpolationMode.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum InterpolationMode
-    {
-        Pass,
-        Default,
-        Constant,
-        Sc
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/LogicalOperation.cs b/Ryujinx.Graphics.Shader/Decoders/LogicalOperation.cs
deleted file mode 100644
index 5221442510..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/LogicalOperation.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum LogicalOperation
-    {
-        And         = 0,
-        Or          = 1,
-        ExclusiveOr = 2,
-        Passthrough = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/MufuOperation.cs b/Ryujinx.Graphics.Shader/Decoders/MufuOperation.cs
deleted file mode 100644
index 88bd1f5cea..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/MufuOperation.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum MufuOperation
-    {
-        Cosine                  = 0,
-        Sine                    = 1,
-        ExponentB2              = 2,
-        LogarithmB2             = 3,
-        Reciprocal              = 4,
-        ReciprocalSquareRoot    = 5,
-        Reciprocal64H           = 6,
-        ReciprocalSquareRoot64H = 7,
-        SquareRoot              = 8
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCode.cs b/Ryujinx.Graphics.Shader/Decoders/OpCode.cs
deleted file mode 100644
index 27e10f89f3..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCode.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCode
-    {
-        public InstEmitter Emitter { get; }
-
-        public ulong Address   { get; }
-        public long  RawOpCode { get; }
-
-        public Register Predicate { get; protected set; }
-
-        public bool InvertPredicate { get; protected set; }
-
-        // When inverted, the always true predicate == always false.
-        public bool NeverExecute => Predicate.Index == RegisterConsts.PredicateTrueIndex && InvertPredicate;
-
-        public static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCode(emitter, address, opCode);
-
-        public OpCode(InstEmitter emitter, ulong address, long opCode)
-        {
-            Emitter   = emitter;
-            Address   = address;
-            RawOpCode = opCode;
-
-            Predicate = new Register(opCode.Extract(16, 3), RegisterType.Predicate);
-
-            InvertPredicate = opCode.Extract(19);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs
deleted file mode 100644
index d924b39348..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAl2p.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAl2p : OpCode, IOpCodeRd, IOpCodeRa
-    {
-        public Register Rd          { get; }
-        public Register Ra          { get; }
-        public Register Predicate44 { get; }
-
-        public int Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAl2p(emitter, address, opCode);
-
-        public OpCodeAl2p(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd          = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra          = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Predicate44 = new Register(opCode.Extract(44, 3), RegisterType.Predicate);
-
-            Immediate = ((int)opCode << 1) >> 21;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAlu.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAlu.cs
deleted file mode 100644
index 035aa7301e..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAlu.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAlu : OpCode, IOpCodeAlu, IOpCodeRc
-    {
-        public Register Rd          { get; }
-        public Register Ra          { get; }
-        public Register Rc          { get; }
-        public Register Predicate39 { get; }
-
-        public int ByteSelection { get; }
-
-        public bool InvertP     { get; }
-        public bool Extended    { get; protected set; }
-        public bool SetCondCode { get; protected set; }
-        public bool Saturate    { get; protected set; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAlu(emitter, address, opCode);
-
-        public OpCodeAlu(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd          = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra          = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rc          = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-            Predicate39 = new Register(opCode.Extract(39, 3), RegisterType.Predicate);
-
-            ByteSelection = opCode.Extract(41, 2);
-
-            InvertP     = opCode.Extract(42);
-            Extended    = opCode.Extract(43);
-            SetCondCode = opCode.Extract(47);
-            Saturate    = opCode.Extract(50);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAluCbuf.cs
deleted file mode 100644
index 04ef64dff7..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluCbuf.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAluCbuf : OpCodeAlu, IOpCodeCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluCbuf(emitter, address, opCode);
-
-        public OpCodeAluCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm.cs
deleted file mode 100644
index 7faa0d8003..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAluImm : OpCodeAlu, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluImm(emitter, address, opCode);
-
-        public OpCodeAluImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.DecodeS20Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm2x10.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm2x10.cs
deleted file mode 100644
index b475c8a93a..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm2x10.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAluImm2x10 : OpCodeAlu, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluImm2x10(emitter, address, opCode);
-
-        public OpCodeAluImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.Decode2xF10Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm32.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm32.cs
deleted file mode 100644
index 26b27a3d86..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluImm32.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAluImm32 : OpCodeAlu, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluImm32(emitter, address, opCode);
-
-        public OpCodeAluImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = opCode.Extract(20, 32);
-
-            SetCondCode = opCode.Extract(52);
-            Extended    = opCode.Extract(53);
-            Saturate    = opCode.Extract(54);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluReg.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAluReg.cs
deleted file mode 100644
index fe61a51f1a..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluReg.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAluReg : OpCodeAlu, IOpCodeReg
-    {
-        public Register Rb { get; protected set; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluReg(emitter, address, opCode);
-
-        public OpCodeAluReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluRegCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAluRegCbuf.cs
deleted file mode 100644
index 628fb472bc..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAluRegCbuf.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAluRegCbuf : OpCodeAluReg, IOpCodeRegCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAluRegCbuf(emitter, address, opCode);
-
-        public OpCodeAluRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-
-            Rb = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs
deleted file mode 100644
index 006a91f3fa..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAtom.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAtom : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeReg
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-        public Register Rb { get; }
-
-        public bool Extended { get; }
-
-        public AtomicOp AtomicOp { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAtom(emitter, address, opCode);
-
-        public OpCodeAtom(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-
-            Extended = opCode.Extract(48);
-
-            AtomicOp = (AtomicOp)opCode.Extract(52, 4);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
deleted file mode 100644
index 0a24d4c8be..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeAttribute.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeAttribute : OpCodeAluReg, IOpCodeAttribute
-    {
-        public int  AttributeOffset { get; }
-        public bool Patch           { get; }
-        public int  Count           { get; }
-
-        public bool Phys => !Patch && AttributeOffset == 0 && !Ra.IsRZ;
-        public bool Indexed => Phys;
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeAttribute(emitter, address, opCode);
-
-        public OpCodeAttribute(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            AttributeOffset = opCode.Extract(20, 10);
-            Patch           = opCode.Extract(31);
-            Count           = opCode.Extract(47, 2) + 1;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs
deleted file mode 100644
index 7c82c68382..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeBarrier.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeBarrier : OpCode
-    {
-        public BarrierMode Mode { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBarrier(emitter, address, opCode);
-
-        public OpCodeBarrier(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Mode = (BarrierMode)((opCode >> 32) & 0x9b);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeBranch.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeBranch.cs
deleted file mode 100644
index 9ca437b370..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeBranch.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeBranch : OpCodeConditional
-    {
-        public int Offset { get; }
-
-        public bool PushTarget { get; protected set; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBranch(emitter, address, opCode);
-
-        public OpCodeBranch(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = ((int)(opCode >> 20) << 8) >> 8;
-
-            PushTarget = false;
-        }
-
-        public ulong GetAbsoluteAddress()
-        {
-            return (ulong)((long)Address + (long)Offset + 8);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeBranchIndir.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeBranchIndir.cs
deleted file mode 100644
index b3911d6a07..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeBranchIndir.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeBranchIndir : OpCode
-    {
-        public HashSet<Block> PossibleTargets { get; }
-
-        public Register Ra { get; }
-
-        public int Offset { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBranchIndir(emitter, address, opCode);
-
-        public OpCodeBranchIndir(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            PossibleTargets = new HashSet<Block>();
-
-            Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
-
-            Offset = ((int)(opCode >> 20) << 8) >> 8;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeBranchPop.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeBranchPop.cs
deleted file mode 100644
index 318048709e..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeBranchPop.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeBranchPop : OpCodeConditional
-    {
-        public Dictionary<OpCodePush, int> Targets { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeBranchPop(emitter, address, opCode);
-
-        public OpCodeBranchPop(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Targets = new Dictionary<OpCodePush, int>();
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeConditional.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeConditional.cs
deleted file mode 100644
index 219eec89d5..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeConditional.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeConditional : OpCode
-    {
-        public Condition Condition { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeConditional(emitter, address, opCode);
-
-        public OpCodeConditional(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Condition = (Condition)opCode.Extract(0, 5);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeDArithImm.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeDArithImm.cs
deleted file mode 100644
index f13bfc4760..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeDArithImm.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeDArithImm : OpCodeFArith, IOpCodeImmF
-    {
-        public float Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeDArithImm(emitter, address, opCode);
-
-        public OpCodeDArithImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.DecodeD20Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeExit.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeExit.cs
deleted file mode 100644
index f63d5d1166..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeExit.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeExit : OpCodeConditional
-    {
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeExit(emitter, address, opCode);
-
-        public OpCodeExit(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArith.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeFArith.cs
deleted file mode 100644
index d262f1578f..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArith.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeFArith : OpCodeAlu, IOpCodeFArith
-    {
-        public RoundingMode RoundingMode { get; }
-
-        public FPMultiplyScale Scale { get; }
-
-        public bool FlushToZero { get; }
-        public bool AbsoluteA   { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArith(emitter, address, opCode);
-
-        public OpCodeFArith(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            RoundingMode = (RoundingMode)opCode.Extract(39, 2);
-
-            Scale = (FPMultiplyScale)opCode.Extract(41, 3);
-
-            FlushToZero = opCode.Extract(44);
-            AbsoluteA   = opCode.Extract(46);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithCbuf.cs
deleted file mode 100644
index 1475f11b86..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithCbuf.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeFArithCbuf : OpCodeFArith, IOpCodeCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithCbuf(emitter, address, opCode);
-
-        public OpCodeFArithCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm.cs
deleted file mode 100644
index 91a6561be6..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeFArithImm : OpCodeFArith, IOpCodeImmF
-    {
-        public float Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithImm(emitter, address, opCode);
-
-        public OpCodeFArithImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.DecodeF20Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm32.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm32.cs
deleted file mode 100644
index 09d0a13d87..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithImm32.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-using System;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeFArithImm32 : OpCodeAlu, IOpCodeFArith, IOpCodeImmF
-    {
-        public RoundingMode RoundingMode => RoundingMode.ToNearest;
-
-        public FPMultiplyScale Scale => FPMultiplyScale.None;
-
-        public bool FlushToZero { get; }
-        public bool AbsoluteA   { get; }
-
-        public float Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithImm32(emitter, address, opCode);
-
-        public OpCodeFArithImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            int imm = opCode.Extract(20, 32);
-
-            Immediate = BitConverter.Int32BitsToSingle(imm);
-
-            SetCondCode = opCode.Extract(52);
-            AbsoluteA   = opCode.Extract(54);
-            FlushToZero = opCode.Extract(55);
-
-            Saturate = false;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithReg.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithReg.cs
deleted file mode 100644
index f4b64584d4..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithReg.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeFArithReg : OpCodeFArith, IOpCodeReg
-    {
-        public Register Rb { get; protected set; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithReg(emitter, address, opCode);
-
-        public OpCodeFArithReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithRegCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithRegCbuf.cs
deleted file mode 100644
index c1b5cca6aa..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeFArithRegCbuf.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeFArithRegCbuf : OpCodeFArith, IOpCodeRegCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFArithRegCbuf(emitter, address, opCode);
-
-        public OpCodeFArithRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeFsetImm.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeFsetImm.cs
deleted file mode 100644
index aa216db2e6..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeFsetImm.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeFsetImm : OpCodeSet, IOpCodeImmF
-    {
-        public float Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeFsetImm(emitter, address, opCode);
-
-        public OpCodeFsetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.DecodeF20Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfma.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeHfma.cs
deleted file mode 100644
index 9123cb9755..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfma.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeHfma : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeRc
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-        public Register Rc { get; protected set; }
-
-        public FPHalfSwizzle SwizzleA { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfma(emitter, address, opCode);
-
-        public OpCodeHfma(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-
-            SwizzleA = (FPHalfSwizzle)opCode.Extract(47, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaCbuf.cs
deleted file mode 100644
index d73223ab98..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaCbuf.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeHfmaCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public bool NegateB  { get; }
-        public bool NegateC  { get; }
-        public bool Saturate { get; }
-
-        public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP32;
-        public FPHalfSwizzle SwizzleC { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaCbuf(emitter, address, opCode);
-
-        public OpCodeHfmaCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-
-            NegateC  = opCode.Extract(51);
-            Saturate = opCode.Extract(52);
-
-            SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2);
-
-            NegateB = opCode.Extract(56);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm2x10.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm2x10.cs
deleted file mode 100644
index c847be0f1b..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm2x10.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeHfmaImm2x10 : OpCodeHfma, IOpCodeHfma, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public bool NegateB => false;
-        public bool NegateC  { get; }
-        public bool Saturate { get; }
-
-        public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16;
-        public FPHalfSwizzle SwizzleC { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaImm2x10(emitter, address, opCode);
-
-        public OpCodeHfmaImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.Decode2xF10Immediate(opCode);
-
-            NegateC  = opCode.Extract(51);
-            Saturate = opCode.Extract(52);
-
-            SwizzleC = (FPHalfSwizzle)opCode.Extract(53, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm32.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm32.cs
deleted file mode 100644
index 6d1ab265cb..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaImm32.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeHfmaImm32 : OpCodeHfma, IOpCodeHfma, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public bool NegateB => false;
-        public bool NegateC { get; }
-        public bool Saturate => false;
-
-        public FPHalfSwizzle SwizzleB => FPHalfSwizzle.FP16;
-        public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP16;
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaImm32(emitter, address, opCode);
-
-        public OpCodeHfmaImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = opCode.Extract(20, 32);
-
-            NegateC = opCode.Extract(52);
-
-            Rc = Rd;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaReg.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaReg.cs
deleted file mode 100644
index ebb1fec903..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaReg.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeHfmaReg : OpCodeHfma, IOpCodeHfma, IOpCodeReg
-    {
-        public Register Rb { get; }
-
-        public bool NegateB  { get; }
-        public bool NegateC  { get; }
-        public bool Saturate { get; }
-
-        public FPHalfSwizzle SwizzleB { get; }
-        public FPHalfSwizzle SwizzleC { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaReg(emitter, address, opCode);
-
-        public OpCodeHfmaReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-
-            SwizzleB = (FPHalfSwizzle)opCode.Extract(28, 2);
-
-            NegateC  = opCode.Extract(30);
-            NegateB  = opCode.Extract(31);
-            Saturate = opCode.Extract(32);
-
-            SwizzleC = (FPHalfSwizzle)opCode.Extract(35, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaRegCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaRegCbuf.cs
deleted file mode 100644
index dc5d2fe94e..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeHfmaRegCbuf.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeHfmaRegCbuf : OpCodeHfma, IOpCodeHfma, IOpCodeRegCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public bool NegateB  { get; }
-        public bool NegateC  { get; }
-        public bool Saturate { get; }
-
-        public FPHalfSwizzle SwizzleB { get; }
-        public FPHalfSwizzle SwizzleC => FPHalfSwizzle.FP32;
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHfmaRegCbuf(emitter, address, opCode);
-
-        public OpCodeHfmaRegCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-
-            NegateC  = opCode.Extract(51);
-            Saturate = opCode.Extract(52);
-
-            SwizzleB = (FPHalfSwizzle)opCode.Extract(53, 2);
-
-            NegateB = opCode.Extract(56);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeHsetImm2x10.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeHsetImm2x10.cs
deleted file mode 100644
index d5af5049ea..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeHsetImm2x10.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeHsetImm2x10 : OpCodeSet, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeHsetImm2x10(emitter, address, opCode);
-
-        public OpCodeHsetImm2x10(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.Decode2xF10Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeImage.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeImage.cs
deleted file mode 100644
index 36f0b16452..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeImage.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeImage : OpCodeTextureBase
-    {
-        public Register Ra { get; }
-        public Register Rb { get; }
-        public Register Rc { get; }
-
-        public ImageComponents Components { get; }
-        public IntegerSize     Size       { get; }
-
-        public bool ByteAddress { get; }
-
-        public ImageDimensions Dimensions { get; }
-
-        public bool UseComponents { get; }
-        public bool IsBindless    { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeImage(emitter, address, opCode);
-
-        public OpCodeImage(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Ra = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rb = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-
-            UseComponents = !opCode.Extract(52);
-
-            if (UseComponents)
-            {
-                Components = (ImageComponents)opCode.Extract(20, 4);
-            }
-            else
-            {
-                Size = (IntegerSize)opCode.Extract(20, 4);
-            }
-
-            ByteAddress = opCode.Extract(23);
-
-            Dimensions = (ImageDimensions)opCode.Extract(33, 3);
-
-            IsBindless = !opCode.Extract(51);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
deleted file mode 100644
index d38a1b3afb..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeIpa.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeIpa : OpCodeAluReg, IOpCodeAttribute
-    {
-        public int AttributeOffset { get; }
-        public int Count => 1;
-
-        public bool Idx { get; }
-        public bool Indexed => Idx;
-
-        public InterpolationMode Mode { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeIpa(emitter, address, opCode);
-
-        public OpCodeIpa(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            AttributeOffset = opCode.Extract(28, 10);
-
-            Idx = opCode.Extract(38);
-
-            Saturate = opCode.Extract(51);
-
-            Mode = (InterpolationMode)opCode.Extract(54, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeLdc.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeLdc.cs
deleted file mode 100644
index 28d34d5aa1..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeLdc.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeLdc : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeCbuf
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public CbIndexMode IndexMode { get; }
-        public IntegerSize Size { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLdc(emitter, address, opCode);
-
-        public OpCodeLdc(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
-
-            Offset = (opCode.Extract(20, 16) << 16) >> 16;
-            Slot   = opCode.Extract(36, 5);
-
-            IndexMode = (CbIndexMode)opCode.Extract(44, 2);
-            Size      = (IntegerSize)opCode.Extract(48, 3);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeLop.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeLop.cs
deleted file mode 100644
index c774523ba7..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeLop.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeLop : OpCodeAlu, IOpCodeLop
-    {
-        public bool InvertA { get; protected set; }
-        public bool InvertB { get; protected set; }
-
-        public LogicalOperation LogicalOp { get; }
-
-        public Register Predicate48 { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLop(emitter, address, opCode);
-
-        public OpCodeLop(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            InvertA = opCode.Extract(39);
-            InvertB = opCode.Extract(40);
-
-            LogicalOp = (LogicalOperation)opCode.Extract(41, 2);
-
-            Predicate48 = new Register(opCode.Extract(48, 3), RegisterType.Predicate);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeLopCbuf.cs
deleted file mode 100644
index 7a32382acc..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopCbuf.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeLopCbuf : OpCodeLop, IOpCodeCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopCbuf(emitter, address, opCode);
-
-        public OpCodeLopCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm.cs
deleted file mode 100644
index b2443688c2..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeLopImm : OpCodeLop, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopImm(emitter, address, opCode);
-
-        public OpCodeLopImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.DecodeS20Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm32.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm32.cs
deleted file mode 100644
index a751c2cd7a..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopImm32.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeLopImm32 : OpCodeAluImm32, IOpCodeLop, IOpCodeImm
-    {
-        public LogicalOperation LogicalOp { get; }
-
-        public bool InvertA { get; }
-        public bool InvertB { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopImm32(emitter, address, opCode);
-
-        public OpCodeLopImm32(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            LogicalOp = (LogicalOperation)opCode.Extract(53, 2);
-
-            InvertA = opCode.Extract(55);
-            InvertB = opCode.Extract(56);
-
-            Extended = opCode.Extract(57);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopReg.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeLopReg.cs
deleted file mode 100644
index d14e4920d4..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeLopReg.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeLopReg : OpCodeLop, IOpCodeReg
-    {
-        public Register Rb { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeLopReg(emitter, address, opCode);
-
-        public OpCodeLopReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeMemory.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeMemory.cs
deleted file mode 100644
index 65da3aedb3..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeMemory.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeMemory : OpCode, IOpCodeRd, IOpCodeRa
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-
-        public int Offset { get; }
-
-        public bool Extended { get; }
-
-        public IntegerSize Size { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeMemory(emitter, address, opCode);
-
-        public OpCodeMemory(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
-
-            Offset = (opCode.Extract(20, 24) << 8) >> 8;
-
-            Extended = opCode.Extract(45);
-
-            Size = (IntegerSize)opCode.Extract(48, 3);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs
deleted file mode 100644
index c086b460d6..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeMemoryBarrier.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeMemoryBarrier : OpCode
-    {
-        public BarrierLevel Level { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeMemoryBarrier(emitter, address, opCode);
-
-        public OpCodeMemoryBarrier(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Level = (BarrierLevel)opCode.Extract(8, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodePset.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodePset.cs
deleted file mode 100644
index 9d88b86398..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodePset.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodePset : OpCodeSet
-    {
-        public Register Predicate12  { get; }
-        public Register Predicate29  { get; }
-
-        public bool InvertA { get; }
-        public bool InvertB { get; }
-
-        public LogicalOperation LogicalOpAB { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodePset(emitter, address, opCode);
-
-        public OpCodePset(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Predicate12 = new Register(opCode.Extract(12, 3), RegisterType.Predicate);
-            Predicate29 = new Register(opCode.Extract(29, 3), RegisterType.Predicate);
-
-            InvertA = opCode.Extract(15);
-            InvertB = opCode.Extract(32);
-
-            LogicalOpAB = (LogicalOperation)opCode.Extract(24, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodePush.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodePush.cs
deleted file mode 100644
index 4f00a0697e..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodePush.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using System.Collections.Generic;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodePush : OpCodeBranch
-    {
-        public Dictionary<OpCodeBranchPop, Operand> PopOps { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodePush(emitter, address, opCode);
-
-        public OpCodePush(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            PopOps = new Dictionary<OpCodeBranchPop, Operand>();
-
-            Predicate = new Register(RegisterConsts.PredicateTrueIndex, RegisterType.Predicate);
-
-            InvertPredicate = false;
-
-            PushTarget = true;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeRed.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeRed.cs
deleted file mode 100644
index 98bf9939a7..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeRed.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeRed : OpCode, IOpCodeRd, IOpCodeRa
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-
-        public AtomicOp AtomicOp { get; }
-
-        public ReductionType Type { get; }
-
-        public int Offset { get; }
-
-        public bool Extended { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeRed(emitter, address, opCode);
-
-        public OpCodeRed(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
-
-            Type = (ReductionType)opCode.Extract(20, 3);
-
-            AtomicOp = (AtomicOp)opCode.Extract(23, 3);
-
-            Offset = (opCode.Extract(28, 20) << 12) >> 12;
-
-            Extended = opCode.Extract(48);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeSet.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeSet.cs
deleted file mode 100644
index 94ed0beeb2..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeSet.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeSet : OpCodeAlu
-    {
-        public Register Predicate0 { get; }
-        public Register Predicate3 { get; }
-
-        public bool NegateP { get; }
-
-        public LogicalOperation LogicalOp { get; }
-
-        public bool FlushToZero { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSet(emitter, address, opCode);
-
-        public OpCodeSet(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Predicate0 = new Register(opCode.Extract(0, 3), RegisterType.Predicate);
-            Predicate3 = new Register(opCode.Extract(3, 3), RegisterType.Predicate);
-
-            LogicalOp = (LogicalOperation)opCode.Extract(45, 2);
-
-            FlushToZero = opCode.Extract(47);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeSetCbuf.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeSetCbuf.cs
deleted file mode 100644
index 4e0eccf977..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeSetCbuf.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeSetCbuf : OpCodeSet, IOpCodeCbuf
-    {
-        public int Offset { get; }
-        public int Slot   { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSetCbuf(emitter, address, opCode);
-
-        public OpCodeSetCbuf(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Offset = opCode.Extract(20, 14);
-            Slot   = opCode.Extract(34, 5);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeSetImm.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeSetImm.cs
deleted file mode 100644
index 7c82c07c01..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeSetImm.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeSetImm : OpCodeSet, IOpCodeImm
-    {
-        public int Immediate { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSetImm(emitter, address, opCode);
-
-        public OpCodeSetImm(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Immediate = DecoderHelper.DecodeS20Immediate(opCode);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeSetReg.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeSetReg.cs
deleted file mode 100644
index 8ef0d7e498..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeSetReg.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeSetReg : OpCodeSet, IOpCodeReg
-    {
-        public Register Rb { get; protected set; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSetReg(emitter, address, opCode);
-
-        public OpCodeSetReg(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeShuffle.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeShuffle.cs
deleted file mode 100644
index f9f424332c..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeShuffle.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeShuffle : OpCode, IOpCodeRd, IOpCodeRa
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-        public Register Rb { get; }
-        public Register Rc { get; }
-
-        public int ImmediateB { get; }
-        public int ImmediateC { get; }
-
-        public bool IsBImmediate { get; }
-        public bool IsCImmediate { get; }
-
-        public ShuffleType ShuffleType { get; }
-
-        public Register Predicate48 { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeShuffle(emitter, address, opCode);
-
-        public OpCodeShuffle(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-            Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-
-            ImmediateB = opCode.Extract(20, 5);
-            ImmediateC = opCode.Extract(34, 13);
-
-            IsBImmediate = opCode.Extract(28);
-            IsCImmediate = opCode.Extract(29);
-
-            ShuffleType = (ShuffleType)opCode.Extract(30, 2);
-
-            Predicate48 = new Register(opCode.Extract(48, 3), RegisterType.Predicate);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeSuatom.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeSuatom.cs
deleted file mode 100644
index 7c807b369c..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeSuatom.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeSuatom : OpCodeTextureBase
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-        public Register Rb { get; }
-        public Register Rc { get; }
-
-        public ReductionType Type { get; }
-        public AtomicOp AtomicOp { get; }
-        public ImageDimensions Dimensions { get; }
-        public ClampMode ClampMode { get; }
-
-        public bool ByteAddress { get; }
-        public bool UseType { get; }
-        public bool IsBindless { get; }
-
-        public bool CompareAndSwap { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSuatom(emitter, address, opCode);
-
-        public OpCodeSuatom(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-            Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-
-            bool supportsBindless = opCode.Extract(54);
-
-            Type = (ReductionType)opCode.Extract(supportsBindless ? 36 : 51, 3);
-            ByteAddress = opCode.Extract(28);
-            AtomicOp = (AtomicOp)opCode.Extract(29, 4); // Only useful if CAS is not true.
-            Dimensions = (ImageDimensions)opCode.Extract(33, 3);
-            ClampMode = (ClampMode)opCode.Extract(49, 2);
-
-            IsBindless = supportsBindless && !opCode.Extract(51);
-            UseType = !supportsBindless || opCode.Extract(52);
-
-            CompareAndSwap = opCode.Extract(55);
-        }
-    }
-}
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeSured.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeSured.cs
deleted file mode 100644
index 57b8ec789c..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeSured.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum ClampMode
-    {
-        Ignore = 0,
-        Trap = 2
-    }
-
-    class OpCodeSured : OpCodeTextureBase
-    {
-        public Register Ra { get; }
-        public Register Rb { get; }
-        public Register Rc { get; }
-
-        public ReductionType Type { get; }
-        public AtomicOp AtomicOp { get; }
-        public ImageDimensions Dimensions { get; }
-        public ClampMode ClampMode { get; }
-
-        public bool UseType { get; }
-        public bool IsBindless { get; }
-        public bool ByteAddress { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeSured(emitter, address, opCode);
-
-        public OpCodeSured(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
-            Rb = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
-            Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-
-            Type = (ReductionType)opCode.Extract(20, 3);
-            ByteAddress = opCode.Extract(23);
-            AtomicOp = (AtomicOp)opCode.Extract(24, 3);
-            Dimensions = (ImageDimensions)opCode.Extract(33, 3);
-            ClampMode = (ClampMode)opCode.Extract(49, 2);
-
-            IsBindless = !opCode.Extract(51);
-            UseType = opCode.Extract(52);
-        }
-    }
-}
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
deleted file mode 100644
index df09d907bd..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ /dev/null
@@ -1,304 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-using System;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    static class OpCodeTable
-    {
-        public delegate OpCode MakeOp(InstEmitter emitter, ulong address, long opCode);
-
-        private const int EncodingBits = 14;
-
-        private class TableEntry
-        {
-            public InstEmitter Emitter { get; }
-
-            public MakeOp MakeOp { get; }
-
-            public int XBits { get; }
-
-            public TableEntry(InstEmitter emitter, MakeOp makeOp, int xBits)
-            {
-                Emitter = emitter;
-                MakeOp  = makeOp;
-                XBits   = xBits;
-            }
-        }
-
-        private static TableEntry[] _opCodes;
-
-        static OpCodeTable()
-        {
-            _opCodes = new TableEntry[1 << EncodingBits];
-
-#region Instructions
-            Set("1110111110100x", InstEmit.Al2p,    OpCodeAl2p.Create);
-            Set("1110111111011x", InstEmit.Ald,     OpCodeAttribute.Create);
-            Set("1110111111110x", InstEmit.Ast,     OpCodeAttribute.Create);
-            Set("11101101xxxxxx", InstEmit.Atom,    OpCodeAtom.Create);
-            Set("11101100xxxxxx", InstEmit.Atoms,   OpCodeAtom.Create);
-            Set("1111000010101x", InstEmit.Bar,     OpCodeBarrier.Create);
-            Set("0100110000000x", InstEmit.Bfe,     OpCodeAluCbuf.Create);
-            Set("0011100x00000x", InstEmit.Bfe,     OpCodeAluImm.Create);
-            Set("0101110000000x", InstEmit.Bfe,     OpCodeAluReg.Create);
-            Set("0100101111110x", InstEmit.Bfi,     OpCodeAluCbuf.Create);
-            Set("0011011x11110x", InstEmit.Bfi,     OpCodeAluImm.Create);
-            Set("0101001111110x", InstEmit.Bfi,     OpCodeAluRegCbuf.Create);
-            Set("0101101111110x", InstEmit.Bfi,     OpCodeAluReg.Create);
-            Set("111000100100xx", InstEmit.Bra,     OpCodeBranch.Create);
-            Set("111000110100xx", InstEmit.Brk,     OpCodeBranchPop.Create);
-            Set("111000100101xx", InstEmit.Brx,     OpCodeBranchIndir.Create);
-            Set("111000100110xx", InstEmit.Cal,     OpCodeBranch.Create);
-            Set("0101000010100x", InstEmit.Csetp,   OpCodePset.Create);
-            Set("0100110001110x", InstEmit.Dadd,    OpCodeFArithCbuf.Create);
-            Set("0011100x01110x", InstEmit.Dadd,    OpCodeDArithImm.Create);
-            Set("0101110001110x", InstEmit.Dadd,    OpCodeFArithReg.Create);
-            Set("1111000011110x", InstEmit.Depbar,  OpCode.Create);
-            Set("010010110111xx", InstEmit.Dfma,    OpCodeFArithCbuf.Create);
-            Set("0011011x0111xx", InstEmit.Dfma,    OpCodeDArithImm.Create);
-            Set("010100110111xx", InstEmit.Dfma,    OpCodeFArithRegCbuf.Create);
-            Set("010110110111xx", InstEmit.Dfma,    OpCodeFArithReg.Create);
-            Set("0100110010000x", InstEmit.Dmul,    OpCodeFArithCbuf.Create);
-            Set("0011100x10000x", InstEmit.Dmul,    OpCodeDArithImm.Create);
-            Set("0101110010000x", InstEmit.Dmul,    OpCodeFArithReg.Create);
-            Set("111000110000xx", InstEmit.Exit,    OpCodeExit.Create);
-            Set("0100110010101x", InstEmit.F2F,     OpCodeFArithCbuf.Create);
-            Set("0011100x10101x", InstEmit.F2F,     OpCodeFArithImm.Create);
-            Set("0101110010101x", InstEmit.F2F,     OpCodeFArithReg.Create);
-            Set("0100110010110x", InstEmit.F2I,     OpCodeFArithCbuf.Create);
-            Set("0011100x10110x", InstEmit.F2I,     OpCodeFArithImm.Create);
-            Set("0101110010110x", InstEmit.F2I,     OpCodeFArithReg.Create);
-            Set("0100110001011x", InstEmit.Fadd,    OpCodeFArithCbuf.Create);
-            Set("0011100x01011x", InstEmit.Fadd,    OpCodeFArithImm.Create);
-            Set("000010xxxxxxxx", InstEmit.Fadd,    OpCodeFArithImm32.Create);
-            Set("0101110001011x", InstEmit.Fadd,    OpCodeFArithReg.Create);
-            Set("010010111010xx", InstEmit.Fcmp,    OpCodeFArithCbuf.Create);
-            Set("0011011x1010xx", InstEmit.Fcmp,    OpCodeFArithImm.Create);
-            Set("010110111010xx", InstEmit.Fcmp,    OpCodeFArithReg.Create);
-            Set("010100111010xx", InstEmit.Fcmp,    OpCodeFArithRegCbuf.Create);
-            Set("010010011xxxxx", InstEmit.Ffma,    OpCodeFArithCbuf.Create);
-            Set("0011001x1xxxxx", InstEmit.Ffma,    OpCodeFArithImm.Create);
-            Set("000011xxxxxxxx", InstEmit.Ffma32i, OpCodeFArithImm32.Create);
-            Set("010100011xxxxx", InstEmit.Ffma,    OpCodeFArithRegCbuf.Create);
-            Set("010110011xxxxx", InstEmit.Ffma,    OpCodeFArithReg.Create);
-            Set("0100110000110x", InstEmit.Flo,     OpCodeAluCbuf.Create);
-            Set("0011100x00110x", InstEmit.Flo,     OpCodeAluImm.Create);
-            Set("0101110000110x", InstEmit.Flo,     OpCodeAluReg.Create);
-            Set("0100110001100x", InstEmit.Fmnmx,   OpCodeFArithCbuf.Create);
-            Set("0011100x01100x", InstEmit.Fmnmx,   OpCodeFArithImm.Create);
-            Set("0101110001100x", InstEmit.Fmnmx,   OpCodeFArithReg.Create);
-            Set("0100110001101x", InstEmit.Fmul,    OpCodeFArithCbuf.Create);
-            Set("0011100x01101x", InstEmit.Fmul,    OpCodeFArithImm.Create);
-            Set("00011110xxxxxx", InstEmit.Fmul,    OpCodeFArithImm32.Create);
-            Set("0101110001101x", InstEmit.Fmul,    OpCodeFArithReg.Create);
-            Set("0100100xxxxxxx", InstEmit.Fset,    OpCodeSetCbuf.Create);
-            Set("0011000xxxxxxx", InstEmit.Fset,    OpCodeFsetImm.Create);
-            Set("01011000xxxxxx", InstEmit.Fset,    OpCodeSetReg.Create);
-            Set("010010111011xx", InstEmit.Fsetp,   OpCodeSetCbuf.Create);
-            Set("0011011x1011xx", InstEmit.Fsetp,   OpCodeFsetImm.Create);
-            Set("010110111011xx", InstEmit.Fsetp,   OpCodeSetReg.Create);
-            Set("0101000011111x", InstEmit.Fswzadd, OpCodeAluReg.Create);
-            Set("0111101x1xxxxx", InstEmit.Hadd2,   OpCodeAluCbuf.Create);
-            Set("0111101x0xxxxx", InstEmit.Hadd2,   OpCodeAluImm2x10.Create);
-            Set("0010110xxxxxxx", InstEmit.Hadd2,   OpCodeAluImm32.Create);
-            Set("0101110100010x", InstEmit.Hadd2,   OpCodeAluReg.Create);
-            Set("01110xxx1xxxxx", InstEmit.Hfma2,   OpCodeHfmaCbuf.Create);
-            Set("01110xxx0xxxxx", InstEmit.Hfma2,   OpCodeHfmaImm2x10.Create);
-            Set("0010100xxxxxxx", InstEmit.Hfma2,   OpCodeHfmaImm32.Create);
-            Set("0101110100000x", InstEmit.Hfma2,   OpCodeHfmaReg.Create);
-            Set("01100xxx1xxxxx", InstEmit.Hfma2,   OpCodeHfmaRegCbuf.Create);
-            Set("0111100x1xxxxx", InstEmit.Hmul2,   OpCodeAluCbuf.Create);
-            Set("0111100x0xxxxx", InstEmit.Hmul2,   OpCodeAluImm2x10.Create);
-            Set("0010101xxxxxxx", InstEmit.Hmul2,   OpCodeAluImm32.Create);
-            Set("0101110100001x", InstEmit.Hmul2,   OpCodeAluReg.Create);
-            Set("0111110x1xxxxx", InstEmit.Hset2,   OpCodeSetCbuf.Create);
-            Set("0111110x0xxxxx", InstEmit.Hset2,   OpCodeHsetImm2x10.Create);
-            Set("0101110100011x", InstEmit.Hset2,   OpCodeSetReg.Create);
-            Set("0111111x1xxxxx", InstEmit.Hsetp2,  OpCodeSetCbuf.Create);
-            Set("0111111x0xxxxx", InstEmit.Hsetp2,  OpCodeHsetImm2x10.Create);
-            Set("0101110100100x", InstEmit.Hsetp2,  OpCodeSetReg.Create);
-            Set("0100110010111x", InstEmit.I2F,     OpCodeAluCbuf.Create);
-            Set("0011100x10111x", InstEmit.I2F,     OpCodeAluImm.Create);
-            Set("0101110010111x", InstEmit.I2F,     OpCodeAluReg.Create);
-            Set("0100110011100x", InstEmit.I2I,     OpCodeAluCbuf.Create);
-            Set("0011100x11100x", InstEmit.I2I,     OpCodeAluImm.Create);
-            Set("0101110011100x", InstEmit.I2I,     OpCodeAluReg.Create);
-            Set("0100110000010x", InstEmit.Iadd,    OpCodeAluCbuf.Create);
-            Set("0011100x00010x", InstEmit.Iadd,    OpCodeAluImm.Create);
-            Set("0001110x0xxxxx", InstEmit.Iadd,    OpCodeAluImm32.Create);
-            Set("0101110000010x", InstEmit.Iadd,    OpCodeAluReg.Create);
-            Set("010011001100xx", InstEmit.Iadd3,   OpCodeAluCbuf.Create);
-            Set("0011100x1100xx", InstEmit.Iadd3,   OpCodeAluImm.Create);
-            Set("010111001100xx", InstEmit.Iadd3,   OpCodeAluReg.Create);
-            Set("010010110100xx", InstEmit.Icmp,    OpCodeAluCbuf.Create);
-            Set("0011011x0100xx", InstEmit.Icmp,    OpCodeAluImm.Create);
-            Set("010110110100xx", InstEmit.Icmp,    OpCodeAluReg.Create);
-            Set("010100110100xx", InstEmit.Icmp,    OpCodeAluRegCbuf.Create);
-            Set("010010100xxxxx", InstEmit.Imad,    OpCodeAluCbuf.Create);
-            Set("0011010x0xxxxx", InstEmit.Imad,    OpCodeAluImm.Create);
-            Set("010110100xxxxx", InstEmit.Imad,    OpCodeAluReg.Create);
-            Set("010100100xxxxx", InstEmit.Imad,    OpCodeAluRegCbuf.Create);
-            Set("0100110000100x", InstEmit.Imnmx,   OpCodeAluCbuf.Create);
-            Set("0011100x00100x", InstEmit.Imnmx,   OpCodeAluImm.Create);
-            Set("0101110000100x", InstEmit.Imnmx,   OpCodeAluReg.Create);
-            Set("11100000xxxxxx", InstEmit.Ipa,     OpCodeIpa.Create);
-            Set("1110111111010x", InstEmit.Isberd,  OpCodeAlu.Create);
-            Set("0100110000011x", InstEmit.Iscadd,  OpCodeAluCbuf.Create);
-            Set("0011100x00011x", InstEmit.Iscadd,  OpCodeAluImm.Create);
-            Set("000101xxxxxxxx", InstEmit.Iscadd,  OpCodeAluImm32.Create);
-            Set("0101110000011x", InstEmit.Iscadd,  OpCodeAluReg.Create);
-            Set("010010110101xx", InstEmit.Iset,    OpCodeSetCbuf.Create);
-            Set("0011011x0101xx", InstEmit.Iset,    OpCodeSetImm.Create);
-            Set("010110110101xx", InstEmit.Iset,    OpCodeSetReg.Create);
-            Set("010010110110xx", InstEmit.Isetp,   OpCodeSetCbuf.Create);
-            Set("0011011x0110xx", InstEmit.Isetp,   OpCodeSetImm.Create);
-            Set("010110110110xx", InstEmit.Isetp,   OpCodeSetReg.Create);
-            Set("111000110011xx", InstEmit.Kil,     OpCodeExit.Create);
-            Set("1110111101000x", InstEmit.Ld,      OpCodeMemory.Create);
-            Set("1110111110010x", InstEmit.Ldc,     OpCodeLdc.Create);
-            Set("1110111011010x", InstEmit.Ldg,     OpCodeMemory.Create);
-            Set("1110111101001x", InstEmit.Lds,     OpCodeMemory.Create);
-            Set("010010111101xx", InstEmit.Lea,     OpCodeAluCbuf.Create);
-            Set("0011011x11010x", InstEmit.Lea,     OpCodeAluImm.Create);
-            Set("0101101111010x", InstEmit.Lea,     OpCodeAluReg.Create);
-            Set("000110xxxxxxxx", InstEmit.Lea_Hi,  OpCodeAluCbuf.Create);
-            Set("0101101111011x", InstEmit.Lea_Hi,  OpCodeAluReg.Create);
-            Set("0100110001000x", InstEmit.Lop,     OpCodeLopCbuf.Create);
-            Set("0011100001000x", InstEmit.Lop,     OpCodeLopImm.Create);
-            Set("000001xxxxxxxx", InstEmit.Lop,     OpCodeLopImm32.Create);
-            Set("0101110001000x", InstEmit.Lop,     OpCodeLopReg.Create);
-            Set("0000001xxxxxxx", InstEmit.Lop3,    OpCodeLopCbuf.Create);
-            Set("001111xxxxxxxx", InstEmit.Lop3,    OpCodeLopImm.Create);
-            Set("0101101111100x", InstEmit.Lop3,    OpCodeLopReg.Create);
-            Set("1110111110011x", InstEmit.Membar,  OpCodeMemoryBarrier.Create);
-            Set("0100110010011x", InstEmit.Mov,     OpCodeAluCbuf.Create);
-            Set("0011100x10011x", InstEmit.Mov,     OpCodeAluImm.Create);
-            Set("000000010000xx", InstEmit.Mov,     OpCodeAluImm32.Create);
-            Set("0101110010011x", InstEmit.Mov,     OpCodeAluReg.Create);
-            Set("0101000010000x", InstEmit.Mufu,    OpCodeFArith.Create);
-            Set("0101000010110x", InstEmit.Nop,     OpCode.Create);
-            Set("1111101111100x", InstEmit.Out,     OpCode.Create);
-            Set("111000101010xx", InstEmit.Pbk,     OpCodePush.Create);
-            Set("0100110000001x", InstEmit.Popc,    OpCodeAluCbuf.Create);
-            Set("0011100x00001x", InstEmit.Popc,    OpCodeAluImm.Create);
-            Set("0101110000001x", InstEmit.Popc,    OpCodeAluReg.Create);
-            Set("0101000010001x", InstEmit.Pset,    OpCodePset.Create);
-            Set("0101000010010x", InstEmit.Psetp,   OpCodePset.Create);
-            Set("0100110011110x", InstEmit.R2p,     OpCodeAluCbuf.Create);
-            Set("0011100x11110x", InstEmit.R2p,     OpCodeAluImm.Create);
-            Set("0101110011110x", InstEmit.R2p,     OpCodeAluReg.Create);
-            Set("1110101111111x", InstEmit.Red,     OpCodeRed.Create);
-            Set("111000110010xx", InstEmit.Ret,     OpCodeExit.Create);
-            Set("0100110010010x", InstEmit.Rro,     OpCodeFArithCbuf.Create);
-            Set("0011100x10010x", InstEmit.Rro,     OpCodeFArithImm.Create);
-            Set("0101110010010x", InstEmit.Rro,     OpCodeFArithReg.Create);
-            Set("1111000011001x", InstEmit.S2r,     OpCodeAlu.Create);
-            Set("0100110010100x", InstEmit.Sel,     OpCodeAluCbuf.Create);
-            Set("0011100x10100x", InstEmit.Sel,     OpCodeAluImm.Create);
-            Set("0101110010100x", InstEmit.Sel,     OpCodeAluReg.Create);
-            Set("1110111100010x", InstEmit.Shfl,    OpCodeShuffle.Create);
-            Set("0100110001001x", InstEmit.Shl,     OpCodeAluCbuf.Create);
-            Set("0011100x01001x", InstEmit.Shl,     OpCodeAluImm.Create);
-            Set("0101110001001x", InstEmit.Shl,     OpCodeAluReg.Create);
-            Set("0100110000101x", InstEmit.Shr,     OpCodeAluCbuf.Create);
-            Set("0011100x00101x", InstEmit.Shr,     OpCodeAluImm.Create);
-            Set("0101110000101x", InstEmit.Shr,     OpCodeAluReg.Create);
-            Set("111000101001xx", InstEmit.Ssy,     OpCodePush.Create);
-            Set("1110111101010x", InstEmit.St,      OpCodeMemory.Create);
-            Set("1110111011011x", InstEmit.Stg,     OpCodeMemory.Create);
-            Set("1110111101011x", InstEmit.Sts,     OpCodeMemory.Create);
-            Set("11101011000xxx", InstEmit.Suld,    OpCodeImage.Create);
-            Set("11101011001xxx", InstEmit.Sust,    OpCodeImage.Create);
-            Set("11101011010xxx", InstEmit.Sured,   OpCodeSured.Create);
-            Set("11101010110xxx", InstEmit.Suatom,  OpCodeSuatom.Create);
-            Set("1110101010xxxx", InstEmit.Suatom,  OpCodeSuatom.Create);
-            Set("11101010011xxx", InstEmit.Suatom,  OpCodeSuatom.Create);
-            Set("1110101000xxxx", InstEmit.Suatom,  OpCodeSuatom.Create);
-            Set("1111000011111x", InstEmit.Sync,    OpCodeBranchPop.Create);
-            Set("110000xxxx111x", InstEmit.Tex,     OpCodeTex.Create);
-            Set("1101111010111x", InstEmit.TexB,    OpCodeTexB.Create);
-            Set("1101x00xxxxxxx", InstEmit.Texs,    OpCodeTexs.Create);
-            Set("1101x01xxxxxxx", InstEmit.Texs,    OpCodeTlds.Create);
-            Set("11011111x0xxxx", InstEmit.Texs,    OpCodeTld4s.Create);
-            Set("11011100xx111x", InstEmit.Tld,     OpCodeTld.Create);
-            Set("11011101xx111x", InstEmit.TldB,    OpCodeTld.Create);
-            Set("110010xxxx111x", InstEmit.Tld4,    OpCodeTld4.Create);
-            Set("1101111011111x", InstEmit.Tld4,    OpCodeTld4B.Create);
-            Set("11011111011000", InstEmit.TmmlB,   OpCodeTexture.Create);
-            Set("11011111010110", InstEmit.Tmml,    OpCodeTexture.Create);
-            Set("110111100x1110", InstEmit.Txd,     OpCodeTxd.Create);
-            Set("1101111101001x", InstEmit.Txq,     OpCodeTex.Create);
-            Set("1101111101010x", InstEmit.TxqB,    OpCodeTex.Create);
-            Set("01011111xxxxxx", InstEmit.Vmad,    OpCodeVideo.Create);
-            Set("0011101xxxxxxx", InstEmit.Vmnmx,   OpCodeVideo.Create);
-            Set("0101000011011x", InstEmit.Vote,    OpCodeVote.Create);
-            Set("0100111xxxxxxx", InstEmit.Xmad,    OpCodeAluCbuf.Create);
-            Set("0011011x00xxxx", InstEmit.Xmad,    OpCodeAluImm.Create);
-            Set("010100010xxxxx", InstEmit.Xmad,    OpCodeAluRegCbuf.Create);
-            Set("0101101100xxxx", InstEmit.Xmad,    OpCodeAluReg.Create);
-#endregion
-        }
-
-        private static void Set(string encoding, InstEmitter emitter, MakeOp makeOp)
-        {
-            if (encoding.Length != EncodingBits)
-            {
-                throw new ArgumentException(nameof(encoding));
-            }
-
-            int bit   = encoding.Length - 1;
-            int value = 0;
-            int xMask = 0;
-            int xBits = 0;
-
-            int[] xPos = new int[encoding.Length];
-
-            for (int index = 0; index < encoding.Length; index++, bit--)
-            {
-                char chr = encoding[index];
-
-                if (chr == '1')
-                {
-                    value |= 1 << bit;
-                }
-                else if (chr == 'x')
-                {
-                    xMask |= 1 << bit;
-
-                    xPos[xBits++] = bit;
-                }
-            }
-
-            xMask = ~xMask;
-
-            TableEntry entry = new TableEntry(emitter, makeOp, xBits);
-
-            for (int index = 0; index < (1 << xBits); index++)
-            {
-                value &= xMask;
-
-                for (int x = 0; x < xBits; x++)
-                {
-                    value |= ((index >> x) & 1) << xPos[x];
-                }
-
-                if (_opCodes[value] == null || _opCodes[value].XBits > xBits)
-                {
-                    _opCodes[value] = entry;
-                }
-            }
-        }
-
-        public static (InstEmitter Emitter, MakeOp MakeOp) GetEmitter(long opCode)
-        {
-            TableEntry entry = _opCodes[(ulong)opCode >> (64 - EncodingBits)];
-
-            if (entry != null)
-            {
-                return (entry.Emitter, entry.MakeOp);
-            }
-
-            return (null, null);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTex.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTex.cs
deleted file mode 100644
index c0e4da0245..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTex.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTex : OpCodeTexture
-    {
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTex(emitter, address, opCode);
-
-        public OpCodeTex(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            HasDepthCompare = opCode.Extract(50);
-
-            HasOffset = opCode.Extract(54);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexB.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTexB.cs
deleted file mode 100644
index 33434ae197..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexB.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTexB : OpCodeTex
-    {
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTexB(emitter, address, opCode);
-
-        public OpCodeTexB(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            switch (opCode.Extract(37, 3))
-            {
-                case 0: LodMode = TextureLodMode.None;      break;
-                case 1: LodMode = TextureLodMode.LodZero;   break;
-                case 2: LodMode = TextureLodMode.LodBias;   break;
-                case 3: LodMode = TextureLodMode.LodLevel;  break;
-                case 6: LodMode = TextureLodMode.LodBiasA;  break;
-                case 7: LodMode = TextureLodMode.LodLevelA; break;
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexs.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTexs.cs
deleted file mode 100644
index ea3057c883..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexs.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTexs : OpCodeTextureScalar
-    {
-        public TextureTarget Target => (TextureTarget)RawType;
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTexs(emitter, address, opCode);
-
-        public OpCodeTexs(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs
deleted file mode 100644
index 55e66f41d5..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTexture.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTexture : OpCodeTextureBase, IOpCodeTexture
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-        public Register Rb { get; }
-
-        public bool IsArray { get; }
-
-        public TextureDimensions Dimensions { get; }
-
-        public int ComponentMask { get; }
-
-        public TextureLodMode LodMode { get; protected set; }
-
-        public bool HasOffset       { get; protected set; }
-        public bool HasDepthCompare { get; protected set; }
-        public bool IsMultisample   { get; protected set; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTexture(emitter, address, opCode);
-
-        public OpCodeTexture(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-
-            IsArray = opCode.Extract(28);
-
-            Dimensions = (TextureDimensions)opCode.Extract(29, 2);
-
-            ComponentMask = opCode.Extract(31, 4);
-
-            LodMode = (TextureLodMode)opCode.Extract(55, 3);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTextureBase.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTextureBase.cs
deleted file mode 100644
index 0da1ca7651..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTextureBase.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTextureBase : OpCode
-    {
-        public int HandleOffset { get; }
-
-        public OpCodeTextureBase(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            HandleOffset = opCode.Extract(36, 13);
-        }
-    }
-}
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTextureScalar.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTextureScalar.cs
deleted file mode 100644
index be33a6f0c9..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTextureScalar.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-// ReSharper disable InconsistentNaming
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTextureScalar : OpCodeTextureBase
-    {
-#region "Component mask LUT"
-        private const int ____ = 0x0;
-        private const int R___ = 0x1;
-        private const int _G__ = 0x2;
-        private const int RG__ = 0x3;
-        private const int __B_ = 0x4;
-        private const int RGB_ = 0x7;
-        private const int ___A = 0x8;
-        private const int R__A = 0x9;
-        private const int _G_A = 0xa;
-        private const int RG_A = 0xb;
-        private const int __BA = 0xc;
-        private const int R_BA = 0xd;
-        private const int _GBA = 0xe;
-        private const int RGBA = 0xf;
-
-        private static int[,] _maskLut = new int[,]
-        {
-            { R___, _G__, __B_, ___A, RG__, R__A, _G_A, __BA },
-            { RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ }
-        };
-#endregion
-
-        public Register Rd0 { get; }
-        public Register Ra  { get; }
-        public Register Rb  { get; }
-        public Register Rd1 { get; }
-
-        public int ComponentMask { get; protected set; }
-
-        protected int RawType;
-
-        public bool IsFp16 { get; protected set; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTextureScalar(emitter, address, opCode);
-
-        public OpCodeTextureScalar(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd0 = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra  = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rb  = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-            Rd1 = new Register(opCode.Extract(28, 8), RegisterType.Gpr);
-
-            int compSel = opCode.Extract(50, 3);
-
-            RawType = opCode.Extract(53, 4);
-
-            IsFp16 = !opCode.Extract(59);
-
-            ComponentMask = _maskLut[Rd1.IsRZ ? 0 : 1, compSel];
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld.cs
deleted file mode 100644
index 199cf23441..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTld : OpCodeTexture
-    {
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTld(emitter, address, opCode);
-
-        public OpCodeTld(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            HasOffset = opCode.Extract(35);
-
-            IsMultisample = opCode.Extract(50);
-
-            bool isLL = opCode.Extract(55);
-
-            LodMode = isLL
-                ? TextureLodMode.LodLevel
-                : TextureLodMode.LodZero;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs
deleted file mode 100644
index db6572addd..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTld4 : OpCodeTexture, IOpCodeTld4
-    {
-        public TextureGatherOffset Offset { get; }
-
-        public int GatherCompIndex { get; }
-
-        public bool Bindless => false;
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTld4(emitter, address, opCode);
-
-        public OpCodeTld4(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            HasDepthCompare = opCode.Extract(50);
-
-            Offset = (TextureGatherOffset)opCode.Extract(54, 2);
-
-            GatherCompIndex = opCode.Extract(56, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs
deleted file mode 100644
index a3988d00de..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4B.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTld4B : OpCodeTexture, IOpCodeTld4
-    {
-        public TextureGatherOffset Offset { get; }
-
-        public int GatherCompIndex { get; }
-
-        public bool Bindless => true;
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTld4B(emitter, address, opCode);
-
-        public OpCodeTld4B(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            HasDepthCompare = opCode.Extract(50);
-
-            Offset = (TextureGatherOffset)opCode.Extract(36, 2);
-
-            GatherCompIndex = opCode.Extract(38, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4s.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4s.cs
deleted file mode 100644
index 442d36da7d..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTld4s.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTld4s : OpCodeTextureScalar
-    {
-        public bool HasDepthCompare { get; }
-        public bool HasOffset       { get; }
-
-        public int GatherCompIndex { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTld4s(emitter, address, opCode);
-
-        public OpCodeTld4s(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            HasDepthCompare = opCode.Extract(50);
-            HasOffset       = opCode.Extract(51);
-
-            GatherCompIndex = opCode.Extract(52, 2);
-
-            IsFp16 = opCode.Extract(55);
-
-            ComponentMask = Rd1.IsRZ ? 3 : 0xf;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTlds.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTlds.cs
deleted file mode 100644
index 97b328c49b..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTlds.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTlds : OpCodeTextureScalar
-    {
-        public TexelLoadTarget Target => (TexelLoadTarget)RawType;
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTlds(emitter, address, opCode);
-
-        public OpCodeTlds(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTxd.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTxd.cs
deleted file mode 100644
index 63185a1b0c..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTxd.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeTxd : OpCodeTexture
-    {
-        public bool IsBindless { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeTxd(emitter, address, opCode);
-
-        public OpCodeTxd(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            HasOffset = opCode.Extract(35);
-
-            IsBindless = opCode.Extract(54);
-
-            LodMode = TextureLodMode.None;
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs
deleted file mode 100644
index 786b81dcfc..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeVideo.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeVideo : OpCode, IOpCodeRd, IOpCodeRa, IOpCodeRc
-    {
-        public Register Rd { get; }
-        public Register Ra { get; }
-        public Register Rb { get; }
-        public Register Rc { get; }
-
-        public int Immediate { get; }
-
-        public int RaSelection { get; }
-        public int RbSelection { get; }
-
-        public bool SetCondCode { get; }
-
-        public bool HasRb { get; }
-
-        public VideoType RaType { get; }
-        public VideoType RbType { get; }
-
-        public VideoPostOp PostOp { get; }
-
-        public bool DstSigned { get; }
-        public bool Saturate  { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeVideo(emitter, address, opCode);
-
-        public OpCodeVideo(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Ra = new Register(opCode.Extract(8,  8), RegisterType.Gpr);
-            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);
-            Rc = new Register(opCode.Extract(39, 8), RegisterType.Gpr);
-
-            RaSelection = opCode.Extract(36, 2);
-            RbSelection = opCode.Extract(28, 2);
-
-            RaType = opCode.Extract(37, 2) switch
-            {
-                2 => VideoType.U16,
-                3 => VideoType.U32,
-                _ => VideoType.U8
-            };
-
-            RbType = opCode.Extract(29, 2) switch
-            {
-                2 => VideoType.U16,
-                3 => VideoType.U32,
-                _ => VideoType.U8
-            };
-
-            if (opCode.Extract(48))
-            {
-                RaType |= VideoType.Signed;
-            }
-
-            if (!opCode.Extract(50))
-            {
-                // Immediate variant.
-                Immediate = opCode.Extract(16, 20);
-
-                RbType = opCode.Extract(49) ? VideoType.S16 : VideoType.U16;
-
-                if (RbType == VideoType.S16)
-                {
-                    Immediate = (Immediate << 12) >> 12;
-                }
-            }
-            else if (opCode.Extract(49))
-            {
-                RbType |= VideoType.Signed;
-            }
-
-            if (RaType == VideoType.U16)
-            {
-                RaSelection &= 1;
-            }
-            else if (RaType == VideoType.U32)
-            {
-                RaSelection = 0;
-            }
-
-            if (RbType == VideoType.U16)
-            {
-                RbSelection &= 1;
-            }
-            else if (RbType == VideoType.U32)
-            {
-                RbSelection = 0;
-            }
-
-            SetCondCode = opCode.Extract(47);
-
-            HasRb = opCode.Extract(50);
-
-            PostOp = (VideoPostOp)opCode.Extract(51, 3);
-
-            DstSigned = opCode.Extract(54);
-            Saturate  = opCode.Extract(55);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeVote.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeVote.cs
deleted file mode 100644
index 4fc988bcb2..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeVote.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Ryujinx.Graphics.Shader.Instructions;
-
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    class OpCodeVote : OpCode, IOpCodeRd, IOpCodePredicate39
-    {
-        public Register Rd          { get; }
-        public Register Predicate39 { get; }
-        public Register Predicate45 { get; }
-
-        public VoteOp VoteOp { get; }
-
-        public bool InvertP { get; }
-
-        public new static OpCode Create(InstEmitter emitter, ulong address, long opCode) => new OpCodeVote(emitter, address, opCode);
-
-        public OpCodeVote(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
-        {
-            Rd          = new Register(opCode.Extract(0,  8), RegisterType.Gpr);
-            Predicate39 = new Register(opCode.Extract(39, 3), RegisterType.Predicate);
-            Predicate45 = new Register(opCode.Extract(45, 3), RegisterType.Predicate);
-
-            InvertP = opCode.Extract(42);
-
-            VoteOp = (VoteOp)opCode.Extract(48, 2);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/ReductionType.cs b/Ryujinx.Graphics.Shader/Decoders/ReductionType.cs
deleted file mode 100644
index 90814c6975..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/ReductionType.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum ReductionType
-    {
-        U32         = 0,
-        S32         = 1,
-        U64         = 2,
-        FP32FtzRn   = 3,
-        FP16x2FtzRn = 4,
-        S64         = 5,
-        SD32        = 6,
-        SD64        = 7
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/RoundingMode.cs b/Ryujinx.Graphics.Shader/Decoders/RoundingMode.cs
deleted file mode 100644
index 13bb08dc82..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/RoundingMode.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum RoundingMode
-    {
-        ToNearest               = 0,
-        TowardsNegativeInfinity = 1,
-        TowardsPositiveInfinity = 2,
-        TowardsZero             = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/ShuffleType.cs b/Ryujinx.Graphics.Shader/Decoders/ShuffleType.cs
deleted file mode 100644
index 2892c8dd1c..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/ShuffleType.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum ShuffleType
-    {
-        Indexed   = 0,
-        Up        = 1,
-        Down      = 2,
-        Butterfly = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs b/Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs
deleted file mode 100644
index 9eaa7a280d..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/SystemRegister.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum SystemRegister
-    {
-        LaneId     = 0,
-        YDirection = 0x12,
-        ThreadKill = 0x13,
-        ThreadId   = 0x20,
-        ThreadIdX  = 0x21,
-        ThreadIdY  = 0x22,
-        ThreadIdZ  = 0x23,
-        CtaIdX     = 0x25,
-        CtaIdY     = 0x26,
-        CtaIdZ     = 0x27,
-        EqMask     = 0x38,
-        LtMask     = 0x39,
-        LeMask     = 0x3a,
-        GtMask     = 0x3b,
-        GeMask     = 0x3c
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/TexelLoadTarget.cs b/Ryujinx.Graphics.Shader/Decoders/TexelLoadTarget.cs
deleted file mode 100644
index e5a0c004b5..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/TexelLoadTarget.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum TexelLoadTarget
-    {
-        Texture1DLodZero            = 0x0,
-        Texture1DLodLevel           = 0x1,
-        Texture2DLodZero            = 0x2,
-        Texture2DLodZeroOffset      = 0x4,
-        Texture2DLodLevel           = 0x5,
-        Texture2DLodZeroMultisample = 0x6,
-        Texture3DLodZero            = 0x7,
-        Texture2DArrayLodZero       = 0x8,
-        Texture2DLodLevelOffset     = 0xc
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/TextureDimensions.cs b/Ryujinx.Graphics.Shader/Decoders/TextureDimensions.cs
deleted file mode 100644
index dbdf1927fb..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/TextureDimensions.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum TextureDimensions
-    {
-        Texture1D   = 0,
-        Texture2D   = 1,
-        Texture3D   = 2,
-        TextureCube = 3
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/TextureGatherOffset.cs b/Ryujinx.Graphics.Shader/Decoders/TextureGatherOffset.cs
deleted file mode 100644
index 4e9ade26a4..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/TextureGatherOffset.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum TextureGatherOffset
-    {
-        None    = 0,
-        Offset  = 1,
-        Offsets = 2
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/TextureLodMode.cs b/Ryujinx.Graphics.Shader/Decoders/TextureLodMode.cs
deleted file mode 100644
index 0cc6f71432..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/TextureLodMode.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum TextureLodMode
-    {
-        None      = 0,
-        LodZero   = 1,
-        LodBias   = 2,
-        LodLevel  = 3,
-        LodBiasA  = 4, //?
-        LodLevelA = 5  //?
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/TextureProperty.cs b/Ryujinx.Graphics.Shader/Decoders/TextureProperty.cs
deleted file mode 100644
index ea35b1d1cb..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/TextureProperty.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum TextureProperty
-    {
-        Dimensions  = 0x1,
-        Type        = 0x2,
-        SamplePos   = 0x5,
-        Filter      = 0xa,
-        Lod         = 0xc,
-        Wrap        = 0xe,
-        BorderColor = 0x10
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/TextureTarget.cs b/Ryujinx.Graphics.Shader/Decoders/TextureTarget.cs
deleted file mode 100644
index 181a0a0d62..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/TextureTarget.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum TextureTarget
-    {
-        Texture1DLodZero                  = 0x0,
-        Texture2D                         = 0x1,
-        Texture2DLodZero                  = 0x2,
-        Texture2DLodLevel                 = 0x3,
-        Texture2DDepthCompare             = 0x4,
-        Texture2DLodLevelDepthCompare     = 0x5,
-        Texture2DLodZeroDepthCompare      = 0x6,
-        Texture2DArray                    = 0x7,
-        Texture2DArrayLodZero             = 0x8,
-        Texture2DArrayLodZeroDepthCompare = 0x9,
-        Texture3D                         = 0xa,
-        Texture3DLodZero                  = 0xb,
-        TextureCube                       = 0xc,
-        TextureCubeLodLevel               = 0xd
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs b/Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs
deleted file mode 100644
index 6589178971..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/VideoPostOp.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum VideoPostOp
-    {
-        Mrg16h,
-        Mrg16l,
-        Mrg8b0,
-        Mrg8b2,
-        Acc,
-        Min,
-        Max,
-        Pass
-    }
-}
diff --git a/Ryujinx.Graphics.Shader/Decoders/VideoType.cs b/Ryujinx.Graphics.Shader/Decoders/VideoType.cs
deleted file mode 100644
index 7186e7c33b..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/VideoType.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum VideoType
-    {
-        U8  = 0,
-        U16 = 1,
-        U32 = 2,
-
-        Signed = 1 << 2,
-
-        S8  = Signed | U8,
-        S16 = Signed | U16,
-        S32 = Signed | U32
-    }
-}
diff --git a/Ryujinx.Graphics.Shader/Decoders/VoteOp.cs b/Ryujinx.Graphics.Shader/Decoders/VoteOp.cs
deleted file mode 100644
index 2fe937c8c4..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/VoteOp.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum VoteOp
-    {
-        All      = 0,
-        Any      = 1,
-        AllEqual = 2
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Decoders/XmadCMode.cs b/Ryujinx.Graphics.Shader/Decoders/XmadCMode.cs
deleted file mode 100644
index 949a2ef70a..0000000000
--- a/Ryujinx.Graphics.Shader/Decoders/XmadCMode.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Ryujinx.Graphics.Shader.Decoders
-{
-    enum XmadCMode
-    {
-        Cfull = 0,
-        Clo   = 1,
-        Chi   = 2,
-        Csfu  = 3,
-        Cbcc  = 4
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/Ryujinx.Graphics.Shader/IGpuAccessor.cs
index a74782c8aa..6af42cf273 100644
--- a/Ryujinx.Graphics.Shader/IGpuAccessor.cs
+++ b/Ryujinx.Graphics.Shader/IGpuAccessor.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.Graphics.Shader
+using System;
+
+namespace Ryujinx.Graphics.Shader
 {
     public interface IGpuAccessor
     {
@@ -12,12 +14,7 @@
             return 0;
         }
 
-        T MemoryRead<T>(ulong address) where T : unmanaged;
-
-        bool MemoryMapped(ulong address)
-        {
-            return true;
-        }
+        ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize);
 
         int QueryComputeLocalSizeX()
         {
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
new file mode 100644
index 0000000000..8214c9f4b3
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmit.cs
@@ -0,0 +1,526 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.Translation;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void AtomCas(EmitterContext context)
+        {
+            InstAtomCas op = context.GetOp<InstAtomCas>();
+
+            context.Config.GpuAccessor.Log("Shader instruction AtomCas is not implemented.");
+        }
+
+        public static void AtomsCas(EmitterContext context)
+        {
+            InstAtomsCas op = context.GetOp<InstAtomsCas>();
+
+            context.Config.GpuAccessor.Log("Shader instruction AtomsCas is not implemented.");
+        }
+
+        public static void B2r(EmitterContext context)
+        {
+            InstB2r op = context.GetOp<InstB2r>();
+
+            context.Config.GpuAccessor.Log("Shader instruction B2r is not implemented.");
+        }
+
+        public static void Bpt(EmitterContext context)
+        {
+            InstBpt op = context.GetOp<InstBpt>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Bpt is not implemented.");
+        }
+
+        public static void Cctl(EmitterContext context)
+        {
+            InstCctl op = context.GetOp<InstCctl>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Cctl is not implemented.");
+        }
+
+        public static void Cctll(EmitterContext context)
+        {
+            InstCctll op = context.GetOp<InstCctll>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Cctll is not implemented.");
+        }
+
+        public static void Cctlt(EmitterContext context)
+        {
+            InstCctlt op = context.GetOp<InstCctlt>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Cctlt is not implemented.");
+        }
+
+        public static void Cont(EmitterContext context)
+        {
+            InstContUnsup op = context.GetOp<InstContUnsup>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ContUnsup is not implemented.");
+        }
+
+        public static void Cset(EmitterContext context)
+        {
+            InstCsetUnsup op = context.GetOp<InstCsetUnsup>();
+
+            context.Config.GpuAccessor.Log("Shader instruction CsetUnsup is not implemented.");
+        }
+
+        public static void Cs2r(EmitterContext context)
+        {
+            InstCs2r op = context.GetOp<InstCs2r>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Cs2r is not implemented.");
+        }
+
+        public static void DmnmxR(EmitterContext context)
+        {
+            InstDmnmxR op = context.GetOp<InstDmnmxR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DmnmxR is not implemented.");
+        }
+
+        public static void DmnmxI(EmitterContext context)
+        {
+            InstDmnmxI op = context.GetOp<InstDmnmxI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DmnmxI is not implemented.");
+        }
+
+        public static void DmnmxC(EmitterContext context)
+        {
+            InstDmnmxC op = context.GetOp<InstDmnmxC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DmnmxC is not implemented.");
+        }
+
+        public static void DsetR(EmitterContext context)
+        {
+            InstDsetR op = context.GetOp<InstDsetR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DsetR is not implemented.");
+        }
+
+        public static void DsetI(EmitterContext context)
+        {
+            InstDsetI op = context.GetOp<InstDsetI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DsetI is not implemented.");
+        }
+
+        public static void DsetC(EmitterContext context)
+        {
+            InstDsetC op = context.GetOp<InstDsetC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DsetC is not implemented.");
+        }
+
+        public static void DsetpR(EmitterContext context)
+        {
+            InstDsetpR op = context.GetOp<InstDsetpR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DsetpR is not implemented.");
+        }
+
+        public static void DsetpI(EmitterContext context)
+        {
+            InstDsetpI op = context.GetOp<InstDsetpI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DsetpI is not implemented.");
+        }
+
+        public static void DsetpC(EmitterContext context)
+        {
+            InstDsetpC op = context.GetOp<InstDsetpC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction DsetpC is not implemented.");
+        }
+
+        public static void FchkR(EmitterContext context)
+        {
+            InstFchkR op = context.GetOp<InstFchkR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction FchkR is not implemented.");
+        }
+
+        public static void FchkI(EmitterContext context)
+        {
+            InstFchkI op = context.GetOp<InstFchkI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction FchkI is not implemented.");
+        }
+
+        public static void FchkC(EmitterContext context)
+        {
+            InstFchkC op = context.GetOp<InstFchkC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction FchkC is not implemented.");
+        }
+
+        public static void Getcrsptr(EmitterContext context)
+        {
+            InstGetcrsptr op = context.GetOp<InstGetcrsptr>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Getcrsptr is not implemented.");
+        }
+
+        public static void Getlmembase(EmitterContext context)
+        {
+            InstGetlmembase op = context.GetOp<InstGetlmembase>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Getlmembase is not implemented.");
+        }
+
+        public static void Ide(EmitterContext context)
+        {
+            InstIde op = context.GetOp<InstIde>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Ide is not implemented.");
+        }
+
+        public static void IdpR(EmitterContext context)
+        {
+            InstIdpR op = context.GetOp<InstIdpR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction IdpR is not implemented.");
+        }
+
+        public static void IdpC(EmitterContext context)
+        {
+            InstIdpC op = context.GetOp<InstIdpC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction IdpC is not implemented.");
+        }
+
+        public static void ImadspR(EmitterContext context)
+        {
+            InstImadspR op = context.GetOp<InstImadspR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ImadspR is not implemented.");
+        }
+
+        public static void ImadspI(EmitterContext context)
+        {
+            InstImadspI op = context.GetOp<InstImadspI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ImadspI is not implemented.");
+        }
+
+        public static void ImadspC(EmitterContext context)
+        {
+            InstImadspC op = context.GetOp<InstImadspC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ImadspC is not implemented.");
+        }
+
+        public static void ImadspRc(EmitterContext context)
+        {
+            InstImadspRc op = context.GetOp<InstImadspRc>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ImadspRc is not implemented.");
+        }
+
+        public static void ImulR(EmitterContext context)
+        {
+            InstImulR op = context.GetOp<InstImulR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ImulR is not implemented.");
+        }
+
+        public static void ImulI(EmitterContext context)
+        {
+            InstImulI op = context.GetOp<InstImulI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ImulI is not implemented.");
+        }
+
+        public static void ImulC(EmitterContext context)
+        {
+            InstImulC op = context.GetOp<InstImulC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ImulC is not implemented.");
+        }
+
+        public static void Imul32i(EmitterContext context)
+        {
+            InstImul32i op = context.GetOp<InstImul32i>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Imul32i is not implemented.");
+        }
+
+        public static void Jcal(EmitterContext context)
+        {
+            InstJcal op = context.GetOp<InstJcal>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Jcal is not implemented.");
+        }
+
+        public static void Jmp(EmitterContext context)
+        {
+            InstJmp op = context.GetOp<InstJmp>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Jmp is not implemented.");
+        }
+
+        public static void Jmx(EmitterContext context)
+        {
+            InstJmx op = context.GetOp<InstJmx>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Jmx is not implemented.");
+        }
+
+        public static void Ld(EmitterContext context)
+        {
+            InstLd op = context.GetOp<InstLd>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Ld is not implemented.");
+        }
+
+        public static void Lepc(EmitterContext context)
+        {
+            InstLepc op = context.GetOp<InstLepc>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Lepc is not implemented.");
+        }
+
+        public static void Longjmp(EmitterContext context)
+        {
+            InstLongjmp op = context.GetOp<InstLongjmp>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Longjmp is not implemented.");
+        }
+
+        public static void P2rR(EmitterContext context)
+        {
+            InstP2rR op = context.GetOp<InstP2rR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction P2rR is not implemented.");
+        }
+
+        public static void P2rI(EmitterContext context)
+        {
+            InstP2rI op = context.GetOp<InstP2rI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction P2rI is not implemented.");
+        }
+
+        public static void P2rC(EmitterContext context)
+        {
+            InstP2rC op = context.GetOp<InstP2rC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction P2rC is not implemented.");
+        }
+
+        public static void Pcnt(EmitterContext context)
+        {
+            InstPcnt op = context.GetOp<InstPcnt>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Pcnt is not implemented.");
+        }
+
+        public static void Pexit(EmitterContext context)
+        {
+            InstPexit op = context.GetOp<InstPexit>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Pexit is not implemented.");
+        }
+
+        public static void Pixld(EmitterContext context)
+        {
+            InstPixld op = context.GetOp<InstPixld>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Pixld is not implemented.");
+        }
+
+        public static void Plongjmp(EmitterContext context)
+        {
+            InstPlongjmp op = context.GetOp<InstPlongjmp>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Plongjmp is not implemented.");
+        }
+
+        public static void Pret(EmitterContext context)
+        {
+            InstPret op = context.GetOp<InstPret>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Pret is not implemented.");
+        }
+
+        public static void PrmtR(EmitterContext context)
+        {
+            InstPrmtR op = context.GetOp<InstPrmtR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction PrmtR is not implemented.");
+        }
+
+        public static void PrmtI(EmitterContext context)
+        {
+            InstPrmtI op = context.GetOp<InstPrmtI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction PrmtI is not implemented.");
+        }
+
+        public static void PrmtC(EmitterContext context)
+        {
+            InstPrmtC op = context.GetOp<InstPrmtC>();
+
+            context.Config.GpuAccessor.Log("Shader instruction PrmtC is not implemented.");
+        }
+
+        public static void PrmtRc(EmitterContext context)
+        {
+            InstPrmtRc op = context.GetOp<InstPrmtRc>();
+
+            context.Config.GpuAccessor.Log("Shader instruction PrmtRc is not implemented.");
+        }
+
+        public static void R2b(EmitterContext context)
+        {
+            InstR2b op = context.GetOp<InstR2b>();
+
+            context.Config.GpuAccessor.Log("Shader instruction R2b is not implemented.");
+        }
+
+        public static void Ram(EmitterContext context)
+        {
+            InstRam op = context.GetOp<InstRam>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Ram is not implemented.");
+        }
+
+        public static void Rtt(EmitterContext context)
+        {
+            InstRtt op = context.GetOp<InstRtt>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Rtt is not implemented.");
+        }
+
+        public static void Sam(EmitterContext context)
+        {
+            InstSam op = context.GetOp<InstSam>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Sam is not implemented.");
+        }
+
+        public static void Setcrsptr(EmitterContext context)
+        {
+            InstSetcrsptr op = context.GetOp<InstSetcrsptr>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Setcrsptr is not implemented.");
+        }
+
+        public static void Setlmembase(EmitterContext context)
+        {
+            InstSetlmembase op = context.GetOp<InstSetlmembase>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Setlmembase is not implemented.");
+        }
+
+        public static void ShfLR(EmitterContext context)
+        {
+            InstShfLR op = context.GetOp<InstShfLR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ShfLR is not implemented.");
+        }
+
+        public static void ShfRR(EmitterContext context)
+        {
+            InstShfRR op = context.GetOp<InstShfRR>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ShfRR is not implemented.");
+        }
+
+        public static void ShfLI(EmitterContext context)
+        {
+            InstShfLI op = context.GetOp<InstShfLI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ShfLI is not implemented.");
+        }
+
+        public static void ShfRI(EmitterContext context)
+        {
+            InstShfRI op = context.GetOp<InstShfRI>();
+
+            context.Config.GpuAccessor.Log("Shader instruction ShfRI is not implemented.");
+        }
+
+        public static void St(EmitterContext context)
+        {
+            InstSt op = context.GetOp<InstSt>();
+
+            context.Config.GpuAccessor.Log("Shader instruction St is not implemented.");
+        }
+
+        public static void Stp(EmitterContext context)
+        {
+            InstStp op = context.GetOp<InstStp>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Stp is not implemented.");
+        }
+
+        public static void Txa(EmitterContext context)
+        {
+            InstTxa op = context.GetOp<InstTxa>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Txa is not implemented.");
+        }
+
+        public static void Vabsdiff(EmitterContext context)
+        {
+            InstVabsdiff op = context.GetOp<InstVabsdiff>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Vabsdiff is not implemented.");
+        }
+
+        public static void Vabsdiff4(EmitterContext context)
+        {
+            InstVabsdiff4 op = context.GetOp<InstVabsdiff4>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Vabsdiff4 is not implemented.");
+        }
+
+        public static void Vadd(EmitterContext context)
+        {
+            InstVadd op = context.GetOp<InstVadd>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Vadd is not implemented.");
+        }
+
+        public static void Votevtg(EmitterContext context)
+        {
+            InstVotevtg op = context.GetOp<InstVotevtg>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Votevtg is not implemented.");
+        }
+
+        public static void Vset(EmitterContext context)
+        {
+            InstVset op = context.GetOp<InstVset>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Vset is not implemented.");
+        }
+
+        public static void Vsetp(EmitterContext context)
+        {
+            InstVsetp op = context.GetOp<InstVsetp>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Vsetp is not implemented.");
+        }
+
+        public static void Vshl(EmitterContext context)
+        {
+            InstVshl op = context.GetOp<InstVshl>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Vshl is not implemented.");
+        }
+
+        public static void Vshr(EmitterContext context)
+        {
+            InstVshr op = context.GetOp<InstVshr>();
+
+            context.Config.GpuAccessor.Log("Shader instruction Vshr is not implemented.");
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs
deleted file mode 100644
index 734d3aa73f..0000000000
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs
+++ /dev/null
@@ -1,984 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
-    static partial class InstEmit
-    {
-        public static void Bfe(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool isReverse = op.RawOpCode.Extract(40);
-            bool isSigned  = op.RawOpCode.Extract(48);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            if (isReverse)
-            {
-                srcA = context.BitfieldReverse(srcA);
-            }
-
-            Operand position = context.BitwiseAnd(srcB, Const(0xff));
-
-            Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
-
-            Operand res = isSigned
-                ? context.BitfieldExtractS32(srcA, position, size)
-                : context.BitfieldExtractU32(srcA, position, size);
-
-            context.Copy(GetDest(context), res);
-
-            // TODO: CC, X, corner cases
-        }
-
-        public static void Bfi(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-            Operand srcC = GetSrcC(context);
-
-            Operand position = context.BitwiseAnd(srcB, Const(0xff));
-
-            Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
-
-            Operand res = context.BitfieldInsert(srcC, srcA, position, size);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Csetp(EmitterContext context)
-        {
-            OpCodePset op = (OpCodePset)context.CurrOp;
-
-            // TODO: Implement that properly
-
-            Operand p0Res = Const(IrConsts.True);
-
-            Operand p1Res = context.BitwiseNot(p0Res);
-
-            Operand pred = GetPredicate39(context);
-
-            p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
-            p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
-            context.Copy(Register(op.Predicate3), p0Res);
-            context.Copy(Register(op.Predicate0), p1Res);
-        }
-
-        public static void Flo(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool invert     = op.RawOpCode.Extract(40);
-            bool countZeros = op.RawOpCode.Extract(41);
-            bool isSigned   = op.RawOpCode.Extract(48);
-
-            Operand srcB = context.BitwiseNot(GetSrcB(context), invert);
-
-            Operand res = isSigned
-                ? context.FindFirstSetS32(srcB)
-                : context.FindFirstSetU32(srcB);
-
-            if (countZeros)
-            {
-                res = context.BitwiseExclusiveOr(res, Const(31));
-            }
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Iadd(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool negateA = false, negateB = false;
-
-            if (!(op is OpCodeAluImm32))
-            {
-                negateB = op.RawOpCode.Extract(48);
-                negateA = op.RawOpCode.Extract(49);
-            }
-            else
-            {
-                // TODO: Other IADD32I variant without the negate.
-                negateA = op.RawOpCode.Extract(56);
-            }
-
-            Operand srcA = context.INegate(GetSrcA(context), negateA);
-            Operand srcB = context.INegate(GetSrcB(context), negateB);
-
-            Operand res = context.IAdd(srcA, srcB);
-
-            if (op.Extended)
-            {
-                res = context.IAdd(res, context.BitwiseAnd(GetCF(), Const(1)));
-            }
-
-            SetIaddFlags(context, res, srcA, srcB, op.SetCondCode, op.Extended);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Iadd3(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            IntegerHalfPart partC = (IntegerHalfPart)op.RawOpCode.Extract(31, 2);
-            IntegerHalfPart partB = (IntegerHalfPart)op.RawOpCode.Extract(33, 2);
-            IntegerHalfPart partA = (IntegerHalfPart)op.RawOpCode.Extract(35, 2);
-
-            IntegerShift mode = (IntegerShift)op.RawOpCode.Extract(37, 2);
-
-            bool negateC = op.RawOpCode.Extract(49);
-            bool negateB = op.RawOpCode.Extract(50);
-            bool negateA = op.RawOpCode.Extract(51);
-
-            Operand Extend(Operand src, IntegerHalfPart part)
-            {
-                if (!(op is OpCodeAluReg) || part == IntegerHalfPart.B32)
-                {
-                    return src;
-                }
-
-                if (part == IntegerHalfPart.H0)
-                {
-                    return context.BitwiseAnd(src, Const(0xffff));
-                }
-                else if (part == IntegerHalfPart.H1)
-                {
-                    return context.ShiftRightU32(src, Const(16));
-                }
-                else
-                {
-                    // TODO: Warning.
-                }
-
-                return src;
-            }
-
-            Operand srcA = context.INegate(Extend(GetSrcA(context), partA), negateA);
-            Operand srcB = context.INegate(Extend(GetSrcB(context), partB), negateB);
-            Operand srcC = context.INegate(Extend(GetSrcC(context), partC), negateC);
-
-            Operand res = context.IAdd(srcA, srcB);
-
-            if (op is OpCodeAluReg && mode != IntegerShift.NoShift)
-            {
-                if (mode == IntegerShift.ShiftLeft)
-                {
-                    res = context.ShiftLeft(res, Const(16));
-                }
-                else if (mode == IntegerShift.ShiftRight)
-                {
-                    res = context.ShiftRightU32(res, Const(16));
-                }
-                else
-                {
-                    // TODO: Warning.
-                }
-            }
-
-            res = context.IAdd(res, srcC);
-
-            context.Copy(GetDest(context), res);
-
-            // TODO: CC, X, corner cases
-        }
-
-        public static void Icmp(EmitterContext context)
-        {
-            OpCode op = context.CurrOp;
-
-            bool isSigned = op.RawOpCode.Extract(48);
-
-            IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-            Operand srcC = GetSrcC(context);
-
-            Operand cmpRes = GetIntComparison(context, cmpOp, srcC, Const(0), isSigned);
-
-            Operand res = context.ConditionalSelect(cmpRes, srcA, srcB);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Imad(EmitterContext context)
-        {
-            bool signedA = context.CurrOp.RawOpCode.Extract(48);
-            bool signedB = context.CurrOp.RawOpCode.Extract(53);
-            bool high    = context.CurrOp.RawOpCode.Extract(54);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-            Operand srcC = GetSrcC(context);
-
-            Operand res;
-
-            if (high)
-            {
-                if (signedA && signedB)
-                {
-                    res = context.MultiplyHighS32(srcA, srcB);
-                }
-                else
-                {
-                    res = context.MultiplyHighU32(srcA, srcB);
-
-                    if (signedA)
-                    {
-                        res = context.IAdd(res, context.IMultiply(srcB, context.ShiftRightS32(srcA, Const(31))));
-                    }
-                    else if (signedB)
-                    {
-                        res = context.IAdd(res, context.IMultiply(srcA, context.ShiftRightS32(srcB, Const(31))));
-                    }
-                }
-            }
-            else
-            {
-                res = context.IMultiply(srcA, srcB);
-            }
-
-            res = context.IAdd(res, srcC);
-
-            // TODO: CC, X, SAT, and more?
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Imnmx(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool isSignedInt = op.RawOpCode.Extract(48);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            Operand resMin = isSignedInt
-                ? context.IMinimumS32(srcA, srcB)
-                : context.IMinimumU32(srcA, srcB);
-
-            Operand resMax = isSignedInt
-                ? context.IMaximumS32(srcA, srcB)
-                : context.IMaximumU32(srcA, srcB);
-
-            Operand pred = GetPredicate39(context);
-            Operand res = context.ConditionalSelect(pred, resMin, resMax);
-
-            context.Copy(GetDest(context), res);
-
-            SetZnFlags(context, res, op.SetCondCode);
-
-            // TODO: X flags.
-        }
-
-        public static void Iscadd(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool negateA = false, negateB = false;
-
-            if (!(op is OpCodeAluImm32))
-            {
-                negateB = op.RawOpCode.Extract(48);
-                negateA = op.RawOpCode.Extract(49);
-            }
-
-            int shift = op is OpCodeAluImm32
-                ? op.RawOpCode.Extract(53, 5)
-                : op.RawOpCode.Extract(39, 5);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            srcA = context.ShiftLeft(srcA, Const(shift));
-
-            srcA = context.INegate(srcA, negateA);
-            srcB = context.INegate(srcB, negateB);
-
-            Operand res = context.IAdd(srcA, srcB);
-
-            SetIaddFlags(context, res, srcA, srcB, op.SetCondCode, false);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Iset(EmitterContext context)
-        {
-            OpCodeSet op = (OpCodeSet)context.CurrOp;
-
-            bool boolFloat = op.RawOpCode.Extract(44);
-            bool isSigned  = op.RawOpCode.Extract(48);
-
-            IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            Operand res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned, op.Extended);
-
-            Operand pred = GetPredicate39(context);
-
-            res = GetPredLogicalOp(context, op.LogicalOp, res, pred);
-
-            Operand dest = GetDest(context);
-
-            if (boolFloat)
-            {
-                res = context.ConditionalSelect(res, ConstF(1), Const(0));
-
-                context.Copy(dest, res);
-
-                SetFPZnFlags(context, res, op.SetCondCode);
-            }
-            else
-            {
-                context.Copy(dest, res);
-
-                SetZnFlags(context, res, op.SetCondCode, op.Extended);
-            }
-        }
-
-        public static void Isetp(EmitterContext context)
-        {
-            OpCodeSet op = (OpCodeSet)context.CurrOp;
-
-            bool isSigned = op.RawOpCode.Extract(48);
-
-            IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            Operand p0Res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned, op.Extended);
-
-            Operand p1Res = context.BitwiseNot(p0Res);
-
-            Operand pred = GetPredicate39(context);
-
-            p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
-            p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
-            context.Copy(Register(op.Predicate3), p0Res);
-            context.Copy(Register(op.Predicate0), p1Res);
-        }
-
-        public static void Lea(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool negateA = op.RawOpCode.Extract(45);
-
-            int shift = op.RawOpCode.Extract(39, 5);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            srcA = context.ShiftLeft(srcA, Const(shift));
-            srcA = context.INegate(srcA, negateA);
-
-            Operand res = context.IAdd(srcA, srcB);
-
-            context.Copy(GetDest(context), res);
-
-            // TODO: CC, X
-        }
-
-        public static void Lea_Hi(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool isReg = op is OpCodeAluReg;
-            bool negateA;
-            int shift;
-
-            if (isReg)
-            {
-                negateA = op.RawOpCode.Extract(37);
-                shift   = op.RawOpCode.Extract(28, 5);
-            }
-            else
-            {
-                negateA = op.RawOpCode.Extract(56);
-                shift   = op.RawOpCode.Extract(51, 5);
-            }
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-            Operand srcC = GetSrcC(context);
-
-            Operand aLow = context.ShiftLeft(srcA, Const(shift));
-            Operand aHigh = shift == 0 ? Const(0) : context.ShiftRightU32(srcA, Const(32 - shift));
-            aHigh = context.BitwiseOr(aHigh, context.ShiftLeft(srcC, Const(shift)));
-
-            if (negateA)
-            {
-                // Perform 64-bit negation by doing bitwise not of the value,
-                // then adding 1 and carrying over from low to high.
-                aLow = context.BitwiseNot(aLow);
-                aHigh = context.BitwiseNot(aHigh);
-
-                aLow = AddWithCarry(context, aLow, Const(1), out Operand aLowCOut);
-                aHigh = context.IAdd(aHigh, aLowCOut);
-            }
-
-            Operand res = context.IAdd(aHigh, srcB);
-
-            context.Copy(GetDest(context), res);
-
-            // TODO: CC, X
-        }
-
-        public static void Lop(EmitterContext context)
-        {
-            IOpCodeLop op = (IOpCodeLop)context.CurrOp;
-
-            Operand srcA = context.BitwiseNot(GetSrcA(context), op.InvertA);
-            Operand srcB = context.BitwiseNot(GetSrcB(context), op.InvertB);
-
-            Operand res = srcB;
-
-            switch (op.LogicalOp)
-            {
-                case LogicalOperation.And:         res = context.BitwiseAnd        (srcA, srcB); break;
-                case LogicalOperation.Or:          res = context.BitwiseOr         (srcA, srcB); break;
-                case LogicalOperation.ExclusiveOr: res = context.BitwiseExclusiveOr(srcA, srcB); break;
-            }
-
-            EmitLopPredWrite(context, op, res, (ConditionalOperation)context.CurrOp.RawOpCode.Extract(44, 2));
-
-            context.Copy(GetDest(context), res);
-
-            SetZnFlags(context, res, op.SetCondCode, op.Extended);
-        }
-
-        public static void Lop3(EmitterContext context)
-        {
-            IOpCodeLop op = (IOpCodeLop)context.CurrOp;
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-            Operand srcC = GetSrcC(context);
-
-            bool regVariant = op is OpCodeLopReg;
-
-            int truthTable = regVariant
-                ? op.RawOpCode.Extract(28, 8)
-                : op.RawOpCode.Extract(48, 8);
-
-            Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable);
-
-            if (regVariant)
-            {
-                EmitLopPredWrite(context, op, res, (ConditionalOperation)context.CurrOp.RawOpCode.Extract(36, 2));
-            }
-
-            context.Copy(GetDest(context), res);
-
-            SetZnFlags(context, res, op.SetCondCode, op.Extended);
-        }
-
-        public static void Popc(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool invert = op.RawOpCode.Extract(40);
-
-            Operand srcB = context.BitwiseNot(GetSrcB(context), invert);
-
-            Operand res = context.BitCount(srcB);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Pset(EmitterContext context)
-        {
-            OpCodePset op = (OpCodePset)context.CurrOp;
-
-            bool boolFloat = op.RawOpCode.Extract(44);
-
-            Operand srcA = context.BitwiseNot(Register(op.Predicate12), op.InvertA);
-            Operand srcB = context.BitwiseNot(Register(op.Predicate29), op.InvertB);
-            Operand srcC = context.BitwiseNot(Register(op.Predicate39), op.InvertP);
-
-            Operand res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB);
-
-            res = GetPredLogicalOp(context, op.LogicalOp, res, srcC);
-
-            Operand dest = GetDest(context);
-
-            if (boolFloat)
-            {
-                context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0)));
-            }
-            else
-            {
-                context.Copy(dest, res);
-            }
-        }
-
-        public static void Psetp(EmitterContext context)
-        {
-            OpCodePset op = (OpCodePset)context.CurrOp;
-
-            Operand srcA = context.BitwiseNot(Register(op.Predicate12), op.InvertA);
-            Operand srcB = context.BitwiseNot(Register(op.Predicate29), op.InvertB);
-
-            Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB);
-
-            Operand p1Res = context.BitwiseNot(p0Res);
-
-            Operand pred = GetPredicate39(context);
-
-            p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
-            p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
-            context.Copy(Register(op.Predicate3), p0Res);
-            context.Copy(Register(op.Predicate0), p1Res);
-        }
-
-        public static void Rro(EmitterContext context)
-        {
-            // This is the range reduction operator,
-            // we translate it as a simple move, as it
-            // should be always followed by a matching
-            // MUFU instruction.
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool negateB   = op.RawOpCode.Extract(45);
-            bool absoluteB = op.RawOpCode.Extract(49);
-
-            Operand srcB = GetSrcB(context);
-
-            srcB = context.FPAbsNeg(srcB, absoluteB, negateB);
-
-            context.Copy(GetDest(context), srcB);
-        }
-
-        public static void Shl(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool isMasked = op.RawOpCode.Extract(39);
-
-            Operand srcB = GetSrcB(context);
-
-            if (isMasked)
-            {
-                srcB = context.BitwiseAnd(srcB, Const(0x1f));
-            }
-
-            Operand res = context.ShiftLeft(GetSrcA(context), srcB);
-
-            if (!isMasked)
-            {
-                // Clamped shift value.
-                Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
-
-                res = context.ConditionalSelect(isLessThan32, res, Const(0));
-            }
-
-            // TODO: X, CC
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Shr(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool isMasked  = op.RawOpCode.Extract(39);
-            bool isReverse = op.RawOpCode.Extract(40);
-            bool isSigned  = op.RawOpCode.Extract(48);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            if (isReverse)
-            {
-                srcA = context.BitfieldReverse(srcA);
-            }
-
-            if (isMasked)
-            {
-                srcB = context.BitwiseAnd(srcB, Const(0x1f));
-            }
-
-            Operand res = isSigned
-                ? context.ShiftRightS32(srcA, srcB)
-                : context.ShiftRightU32(srcA, srcB);
-
-            if (!isMasked)
-            {
-                // Clamped shift value.
-                Operand resShiftBy32;
-
-                if (isSigned)
-                {
-                    resShiftBy32 = context.ShiftRightS32(srcA, Const(31));
-                }
-                else
-                {
-                    resShiftBy32 = Const(0);
-                }
-
-                Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
-
-                res = context.ConditionalSelect(isLessThan32, res, resShiftBy32);
-            }
-
-            // TODO: X, CC
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Xmad(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            bool signedA = context.CurrOp.RawOpCode.Extract(48);
-            bool signedB = context.CurrOp.RawOpCode.Extract(49);
-            bool highA   = context.CurrOp.RawOpCode.Extract(53);
-
-            bool isReg = (op is OpCodeAluReg) && !(op is OpCodeAluRegCbuf);
-            bool isImm = (op is OpCodeAluImm);
-
-            XmadCMode mode = isReg || isImm
-                ? (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 3)
-                : (XmadCMode)context.CurrOp.RawOpCode.Extract(50, 2);
-
-            bool highB = false;
-
-            if (isReg)
-            {
-                highB = context.CurrOp.RawOpCode.Extract(35);
-            }
-            else if (!isImm)
-            {
-                highB = context.CurrOp.RawOpCode.Extract(52);
-            }
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-            Operand srcC = GetSrcC(context);
-
-            // XMAD immediates are 16-bits unsigned integers.
-            if (srcB.Type == OperandType.Constant)
-            {
-                srcB = Const(srcB.Value & 0xffff);
-            }
-
-            Operand Extend16To32(Operand src, bool high, bool signed)
-            {
-                if (signed && high)
-                {
-                    return context.ShiftRightS32(src, Const(16));
-                }
-                else if (signed)
-                {
-                    return context.BitfieldExtractS32(src, Const(0), Const(16));
-                }
-                else if (high)
-                {
-                    return context.ShiftRightU32(src, Const(16));
-                }
-                else
-                {
-                    return context.BitwiseAnd(src, Const(0xffff));
-                }
-            }
-
-            srcA = Extend16To32(srcA, highA, signedA);
-            srcB = Extend16To32(srcB, highB, signedB);
-
-            bool productShiftLeft = false;
-            bool merge            = false;
-
-            if (op is OpCodeAluCbuf)
-            {
-                productShiftLeft = context.CurrOp.RawOpCode.Extract(55);
-                merge            = context.CurrOp.RawOpCode.Extract(56);
-            }
-            else if (!(op is OpCodeAluRegCbuf))
-            {
-                productShiftLeft = context.CurrOp.RawOpCode.Extract(36);
-                merge            = context.CurrOp.RawOpCode.Extract(37);
-            }
-
-            bool extended;
-
-            if ((op is OpCodeAluReg) || (op is OpCodeAluImm))
-            {
-                extended = context.CurrOp.RawOpCode.Extract(38);
-            }
-            else
-            {
-                extended = context.CurrOp.RawOpCode.Extract(54);
-            }
-
-            Operand res = context.IMultiply(srcA, srcB);
-
-            if (productShiftLeft)
-            {
-                res = context.ShiftLeft(res, Const(16));
-            }
-
-            switch (mode)
-            {
-                case XmadCMode.Cfull: break;
-
-                case XmadCMode.Clo: srcC = Extend16To32(srcC, high: false, signed: false); break;
-                case XmadCMode.Chi: srcC = Extend16To32(srcC, high: true,  signed: false); break;
-
-                case XmadCMode.Cbcc:
-                {
-                    srcC = context.IAdd(srcC, context.ShiftLeft(GetSrcB(context), Const(16)));
-
-                    break;
-                }
-
-                case XmadCMode.Csfu:
-                {
-                    Operand signAdjustA = context.ShiftLeft(context.ShiftRightU32(srcA, Const(31)), Const(16));
-                    Operand signAdjustB = context.ShiftLeft(context.ShiftRightU32(srcB, Const(31)), Const(16));
-
-                    srcC = context.ISubtract(srcC, context.IAdd(signAdjustA, signAdjustB));
-
-                    break;
-                }
-
-                default: /* TODO: Warning */ break;
-            }
-
-            Operand product = res;
-
-            if (extended)
-            {
-                // Add with carry.
-                res = context.IAdd(res, context.BitwiseAnd(GetCF(), Const(1)));
-            }
-            else
-            {
-                // Add (no carry in).
-                res = context.IAdd(res, srcC);
-            }
-
-            SetIaddFlags(context, res, product, srcC, op.SetCondCode, extended);
-
-            if (merge)
-            {
-                res = context.BitwiseAnd(res, Const(0xffff));
-                res = context.BitwiseOr(res, context.ShiftLeft(GetSrcB(context), Const(16)));
-            }
-
-            context.Copy(GetDest(context), res);
-        }
-
-        private static Operand GetIntComparison(
-            EmitterContext   context,
-            IntegerCondition cond,
-            Operand          srcA,
-            Operand          srcB,
-            bool             isSigned,
-            bool             extended)
-        {
-            return extended
-                ? GetIntComparisonExtended(context, cond, srcA, srcB, isSigned)
-                : GetIntComparison        (context, cond, srcA, srcB, isSigned);
-        }
-
-        private static Operand GetIntComparisonExtended(
-            EmitterContext   context,
-            IntegerCondition cond,
-            Operand          srcA,
-            Operand          srcB,
-            bool             isSigned)
-        {
-            Operand res;
-
-            if (cond == IntegerCondition.Always)
-            {
-                res = Const(IrConsts.True);
-            }
-            else if (cond == IntegerCondition.Never)
-            {
-                res = Const(IrConsts.False);
-            }
-            else
-            {
-                res = context.ISubtract(srcA, srcB);
-                res = context.IAdd(res, context.BitwiseNot(GetCF()));
-
-                switch (cond)
-                {
-                    case Decoders.IntegerCondition.Equal: // r = xh == yh && xl == yl
-                        res = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), GetZF());
-                        break;
-                    case Decoders.IntegerCondition.Less: // r = xh < yh || (xh == yh && xl < yl)
-                        Operand notC = context.BitwiseNot(GetCF());
-                        Operand prevLt = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), notC);
-                        res = isSigned
-                            ? context.BitwiseOr(context.ICompareLess(srcA, srcB), prevLt)
-                            : context.BitwiseOr(context.ICompareLessUnsigned(srcA, srcB), prevLt);
-                        break;
-                    case Decoders.IntegerCondition.LessOrEqual: // r = xh < yh || (xh == yh && xl <= yl)
-                        Operand zOrNotC = context.BitwiseOr(GetZF(), context.BitwiseNot(GetCF()));
-                        Operand prevLe = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), zOrNotC);
-                        res = isSigned
-                            ? context.BitwiseOr(context.ICompareLess(srcA, srcB), prevLe)
-                            : context.BitwiseOr(context.ICompareLessUnsigned(srcA, srcB), prevLe);
-                        break;
-                    case Decoders.IntegerCondition.Greater: // r = xh > yh || (xh == yh && xl > yl)
-                        Operand notZAndC = context.BitwiseAnd(context.BitwiseNot(GetZF()), GetCF());
-                        Operand prevGt = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), notZAndC);
-                        res = isSigned
-                            ? context.BitwiseOr(context.ICompareGreater(srcA, srcB), prevGt)
-                            : context.BitwiseOr(context.ICompareGreaterUnsigned(srcA, srcB), prevGt);
-                        break;
-                    case Decoders.IntegerCondition.GreaterOrEqual: // r = xh > yh || (xh == yh && xl >= yl)
-                        Operand prevGe = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), GetCF());
-                        res = isSigned
-                            ? context.BitwiseOr(context.ICompareGreater(srcA, srcB), prevGe)
-                            : context.BitwiseOr(context.ICompareGreaterUnsigned(srcA, srcB), prevGe);
-                        break;
-                    case Decoders.IntegerCondition.NotEqual: // r = xh != yh || xl != yl
-                        context.BitwiseOr(context.ICompareNotEqual(srcA, srcB), context.BitwiseNot(GetZF()));
-                        break;
-                    default:
-                        throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
-                }
-            }
-
-            return res;
-        }
-
-        private static Operand GetIntComparison(
-            EmitterContext   context,
-            IntegerCondition cond,
-            Operand          srcA,
-            Operand          srcB,
-            bool             isSigned)
-        {
-            Operand res;
-
-            if (cond == IntegerCondition.Always)
-            {
-                res = Const(IrConsts.True);
-            }
-            else if (cond == IntegerCondition.Never)
-            {
-                res = Const(IrConsts.False);
-            }
-            else
-            {
-                var inst = cond switch
-                {
-                    IntegerCondition.Less => Instruction.CompareLessU32,
-                    IntegerCondition.Equal => Instruction.CompareEqual,
-                    IntegerCondition.LessOrEqual => Instruction.CompareLessOrEqualU32,
-                    IntegerCondition.Greater => Instruction.CompareGreaterU32,
-                    IntegerCondition.NotEqual => Instruction.CompareNotEqual,
-                    IntegerCondition.GreaterOrEqual => Instruction.CompareGreaterOrEqualU32,
-                    _ => throw new InvalidOperationException($"Unexpected condition \"{cond}\".")
-                };
-
-                if (isSigned)
-                {
-                    switch (cond)
-                    {
-                        case IntegerCondition.Less:           inst = Instruction.CompareLess;           break;
-                        case IntegerCondition.LessOrEqual:    inst = Instruction.CompareLessOrEqual;    break;
-                        case IntegerCondition.Greater:        inst = Instruction.CompareGreater;        break;
-                        case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break;
-                    }
-                }
-
-                res = context.Add(inst, Local(), srcA, srcB);
-            }
-
-            return res;
-        }
-
-        private static void EmitLopPredWrite(EmitterContext context, IOpCodeLop op, Operand result, ConditionalOperation condOp)
-        {
-            if (op is OpCodeLop opLop && !opLop.Predicate48.IsPT)
-            {
-                Operand pRes;
-
-                if (condOp == ConditionalOperation.False)
-                {
-                    pRes = Const(IrConsts.False);
-                }
-                else if (condOp == ConditionalOperation.True)
-                {
-                    pRes = Const(IrConsts.True);
-                }
-                else if (condOp == ConditionalOperation.Zero)
-                {
-                    pRes = context.ICompareEqual(result, Const(0));
-                }
-                else /* if (opLop.CondOp == ConditionalOperation.NotZero) */
-                {
-                    pRes = context.ICompareNotEqual(result, Const(0));
-                }
-
-                context.Copy(Register(opLop.Predicate48), pRes);
-            }
-        }
-
-        private static void SetIaddFlags(
-            EmitterContext context,
-            Operand        res,
-            Operand        srcA,
-            Operand        srcB,
-            bool           setCC,
-            bool           extended)
-        {
-            if (!setCC)
-            {
-                return;
-            }
-
-            if (extended)
-            {
-                // C = (d == a && CIn) || d < a
-                Operand tempC0 = context.ICompareEqual       (res, srcA);
-                Operand tempC1 = context.ICompareLessUnsigned(res, srcA);
-
-                tempC0 = context.BitwiseAnd(tempC0, GetCF());
-
-                context.Copy(GetCF(), context.BitwiseOr(tempC0, tempC1));
-            }
-            else
-            {
-                // C = d < a
-                context.Copy(GetCF(), context.ICompareLessUnsigned(res, srcA));
-            }
-
-            // V = (d ^ a) & ~(a ^ b) < 0
-            Operand tempV0 = context.BitwiseExclusiveOr(res,  srcA);
-            Operand tempV1 = context.BitwiseExclusiveOr(srcA, srcB);
-
-            tempV1 = context.BitwiseNot(tempV1);
-
-            Operand tempV = context.BitwiseAnd(tempV0, tempV1);
-
-            context.Copy(GetVF(), context.ICompareLess(tempV, Const(0)));
-
-            SetZnFlags(context, res, setCC: true, extended: extended);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
index 7fe969a0eb..3dda53162f 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
@@ -10,50 +10,39 @@ namespace Ryujinx.Graphics.Shader.Instructions
 {
     static class InstEmitAluHelper
     {
-        public static long GetIntMin(IntegerType type)
+        public static long GetIntMin(IDstFmt type)
         {
-            switch (type)
+            return type switch
             {
-                case IntegerType.U8:  return byte.MinValue;
-                case IntegerType.S8:  return sbyte.MinValue;
-                case IntegerType.U16: return ushort.MinValue;
-                case IntegerType.S16: return short.MinValue;
-                case IntegerType.U32: return uint.MinValue;
-                case IntegerType.S32: return int.MinValue;
-            }
-
-            throw new ArgumentException($"The type \"{type}\" is not a supported int type.");
+                IDstFmt.U16 => ushort.MinValue,
+                IDstFmt.S16 => short.MinValue,
+                IDstFmt.U32 => uint.MinValue,
+                IDstFmt.S32 => int.MinValue,
+                _ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
+            };
         }
 
-        public static long GetIntMax(IntegerType type)
+        public static long GetIntMax(IDstFmt type)
         {
-            switch (type)
+            return type switch
             {
-                case IntegerType.U8:  return byte.MaxValue;
-                case IntegerType.S8:  return sbyte.MaxValue;
-                case IntegerType.U16: return ushort.MaxValue;
-                case IntegerType.S16: return short.MaxValue;
-                case IntegerType.U32: return uint.MaxValue;
-                case IntegerType.S32: return int.MaxValue;
-            }
-
-            throw new ArgumentException($"The type \"{type}\" is not a supported int type.");
+                IDstFmt.U16 => ushort.MaxValue,
+                IDstFmt.S16 => short.MaxValue,
+                IDstFmt.U32 => uint.MaxValue,
+                IDstFmt.S32 => int.MaxValue,
+                _ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
+            };
         }
 
-        public static Operand GetPredLogicalOp(
-            EmitterContext   context,
-            LogicalOperation logicalOp,
-            Operand          input,
-            Operand          pred)
+        public static Operand GetPredLogicalOp(EmitterContext context, BoolOp logicOp, Operand input, Operand pred)
         {
-            switch (logicalOp)
+            return logicOp switch
             {
-                case LogicalOperation.And:         return context.BitwiseAnd        (input, pred);
-                case LogicalOperation.Or:          return context.BitwiseOr         (input, pred);
-                case LogicalOperation.ExclusiveOr: return context.BitwiseExclusiveOr(input, pred);
-            }
-
-            return input;
+                BoolOp.And => context.BitwiseAnd(input, pred),
+                BoolOp.Or => context.BitwiseOr(input, pred),
+                BoolOp.Xor => context.BitwiseExclusiveOr(input, pred),
+                _ => input
+            };
         }
 
         public static void SetZnFlags(EmitterContext context, Operand dest, bool setCC, bool extended = false)
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs
new file mode 100644
index 0000000000..e865caf2a5
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs
@@ -0,0 +1,190 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void Al2p(EmitterContext context)
+        {
+            InstAl2p op = context.GetOp<InstAl2p>();
+
+            context.Copy(GetDest(op.Dest), context.IAdd(GetSrcReg(context, op.SrcA), Const(op.Imm11)));
+        }
+
+        public static void Ald(EmitterContext context)
+        {
+            InstAld op = context.GetOp<InstAld>();
+
+            Operand primVertex = context.Copy(GetSrcReg(context, op.SrcB));
+
+            for (int index = 0; index < (int)op.AlSize + 1; index++)
+            {
+                Register rd = new Register(op.Dest + index, RegisterType.Gpr);
+
+                if (rd.IsRZ)
+                {
+                    break;
+                }
+
+                if (op.Phys)
+                {
+                    Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase));
+                    Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
+
+                    context.Copy(Register(rd), context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, primVertex));
+
+                    context.Config.SetUsedFeature(FeatureFlags.IaIndexing);
+                }
+                else if (op.SrcB == RegisterConsts.RegisterZeroIndex)
+                {
+                    Operand src = Attribute(op.Imm11 + index * 4);
+
+                    context.FlagAttributeRead(src.Value);
+
+                    context.Copy(Register(rd), src);
+                }
+                else
+                {
+                    Operand src = Const(op.Imm11 + index * 4);
+
+                    context.FlagAttributeRead(src.Value);
+
+                    context.Copy(Register(rd), context.LoadAttribute(src, Const(0), primVertex));
+                }
+            }
+        }
+
+        public static void Ast(EmitterContext context)
+        {
+            InstAst op = context.GetOp<InstAst>();
+
+            for (int index = 0; index < (int)op.AlSize + 1; index++)
+            {
+                if (op.SrcB + index > RegisterConsts.RegisterZeroIndex)
+                {
+                    break;
+                }
+
+                Register rd = new Register(op.SrcB + index, RegisterType.Gpr);
+
+                if (op.Phys)
+                {
+                    Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase));
+                    Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
+
+                    context.StoreAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Register(rd));
+
+                    context.Config.SetUsedFeature(FeatureFlags.OaIndexing);
+                }
+                else
+                {
+                    Operand dest = Attribute(op.Imm11 + index * 4);
+
+                    context.FlagAttributeWritten(dest.Value);
+
+                    context.Copy(dest, Register(rd));
+                }
+            }
+        }
+
+        public static void Ipa(EmitterContext context)
+        {
+            InstIpa op = context.GetOp<InstIpa>();
+
+            context.FlagAttributeRead(op.Imm10);
+
+            Operand res;
+
+            if (op.Idx)
+            {
+                Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase));
+                Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
+
+                res = context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Const(0));
+                res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW));
+
+                context.Config.SetUsedFeature(FeatureFlags.IaIndexing);
+            }
+            else
+            {
+                res = Attribute(op.Imm10);
+
+                if (op.Imm10 >= AttributeConsts.UserAttributeBase && op.Imm10 < AttributeConsts.UserAttributeEnd)
+                {
+                    int index = (op.Imm10 - AttributeConsts.UserAttributeBase) >> 4;
+
+                    if (context.Config.ImapTypes[index].GetFirstUsedType() == PixelImap.Perspective)
+                    {
+                        res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW));
+                    }
+                }
+            }
+
+            if (op.IpaOp == IpaOp.Multiply)
+            {
+                Operand srcB = GetSrcReg(context, op.SrcB);
+
+                res = context.FPMultiply(res, srcB);
+            }
+
+            res = context.FPSaturate(res, op.Sat);
+
+            context.Copy(GetDest(op.Dest), res);
+        }
+
+        public static void Isberd(EmitterContext context)
+        {
+            InstIsberd op = context.GetOp<InstIsberd>();
+
+            // This instruction performs a load from ISBE memory,
+            // however it seems to be only used to get some vertex
+            // input data, so we instead propagate the offset so that
+            // it can be used on the attribute load.
+            context.Copy(GetDest(op.Dest), GetSrcReg(context, op.SrcA));
+        }
+
+        public static void OutR(EmitterContext context)
+        {
+            InstOutR op = context.GetOp<InstOutR>();
+
+            EmitOut(context, op.OutType.HasFlag(OutType.Emit), op.OutType.HasFlag(OutType.Cut));
+        }
+
+        public static void OutI(EmitterContext context)
+        {
+            InstOutI op = context.GetOp<InstOutI>();
+
+            EmitOut(context, op.OutType.HasFlag(OutType.Emit), op.OutType.HasFlag(OutType.Cut));
+        }
+
+        public static void OutC(EmitterContext context)
+        {
+            InstOutC op = context.GetOp<InstOutC>();
+
+            EmitOut(context, op.OutType.HasFlag(OutType.Emit), op.OutType.HasFlag(OutType.Cut));
+        }
+
+        private static void EmitOut(EmitterContext context, bool emit, bool cut)
+        {
+            if (!(emit || cut))
+            {
+                context.Config.GpuAccessor.Log("Invalid OUT encoding.");
+            }
+
+            if (emit)
+            {
+                context.EmitVertex();
+            }
+
+            if (cut)
+            {
+                context.EndPrimitive();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitBarrier.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitBarrier.cs
new file mode 100644
index 0000000000..f3114c6e40
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitBarrier.cs
@@ -0,0 +1,44 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.Translation;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void Bar(EmitterContext context)
+        {
+            InstBar op = context.GetOp<InstBar>();
+
+            // TODO: Support other modes.
+            if (op.BarOp == BarOp.Sync)
+            {
+                context.Barrier();
+            }
+            else
+            {
+                context.Config.GpuAccessor.Log($"Invalid barrier mode: {op.BarOp}.");
+            }
+        }
+
+        public static void Depbar(EmitterContext context)
+        {
+            InstDepbar op = context.GetOp<InstDepbar>();
+
+            // No operation.
+        }
+
+        public static void Membar(EmitterContext context)
+        {
+            InstMembar op = context.GetOp<InstMembar>();
+
+            if (op.Membar == Decoders.Membar.Cta)
+            {
+                context.GroupMemoryBarrier();
+            }
+            else
+            {
+                context.MemoryBarrier();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitBitfield.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitBitfield.cs
new file mode 100644
index 0000000000..7a141bbcf6
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitBitfield.cs
@@ -0,0 +1,190 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void BfeR(EmitterContext context)
+        {
+            InstBfeR op = context.GetOp<InstBfeR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
+        }
+
+        public static void BfeI(EmitterContext context)
+        {
+            InstBfeI op = context.GetOp<InstBfeI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
+        }
+
+        public static void BfeC(EmitterContext context)
+        {
+            InstBfeC op = context.GetOp<InstBfeC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
+        }
+
+        public static void BfiR(EmitterContext context)
+        {
+            InstBfiR op = context.GetOp<InstBfiR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitBfi(context, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void BfiI(EmitterContext context)
+        {
+            InstBfiI op = context.GetOp<InstBfiI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitBfi(context, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void BfiC(EmitterContext context)
+        {
+            InstBfiC op = context.GetOp<InstBfiC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitBfi(context, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void BfiRc(EmitterContext context)
+        {
+            InstBfiRc op = context.GetOp<InstBfiRc>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcC);
+            var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitBfi(context, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void FloR(EmitterContext context)
+        {
+            InstFloR op = context.GetOp<InstFloR>();
+
+            EmitFlo(context, GetSrcReg(context, op.SrcB), op.Dest, op.NegB, op.Sh, op.Signed);
+        }
+
+        public static void FloI(EmitterContext context)
+        {
+            InstFloI op = context.GetOp<InstFloI>();
+
+            EmitFlo(context, GetSrcImm(context, Imm20ToSInt(op.Imm20)), op.Dest, op.NegB, op.Sh, op.Signed);
+        }
+
+        public static void FloC(EmitterContext context)
+        {
+            InstFloC op = context.GetOp<InstFloC>();
+
+            EmitFlo(context, GetSrcCbuf(context, op.CbufSlot, op.CbufOffset), op.Dest, op.NegB, op.Sh, op.Signed);
+        }
+
+        public static void PopcR(EmitterContext context)
+        {
+            InstPopcR op = context.GetOp<InstPopcR>();
+
+            EmitPopc(context, GetSrcReg(context, op.SrcB), op.Dest, op.NegB);
+        }
+
+        public static void PopcI(EmitterContext context)
+        {
+            InstPopcI op = context.GetOp<InstPopcI>();
+
+            EmitPopc(context, GetSrcImm(context, Imm20ToSInt(op.Imm20)), op.Dest, op.NegB);
+        }
+
+        public static void PopcC(EmitterContext context)
+        {
+            InstPopcC op = context.GetOp<InstPopcC>();
+
+            EmitPopc(context, GetSrcCbuf(context, op.CbufSlot, op.CbufOffset), op.Dest, op.NegB);
+        }
+
+        private static void EmitBfe(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            int rd,
+            bool bitReverse,
+            bool isSigned)
+        {
+            if (bitReverse)
+            {
+                srcA = context.BitfieldReverse(srcA);
+            }
+
+            Operand position = context.BitwiseAnd(srcB, Const(0xff));
+
+            Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
+
+            Operand res = isSigned
+                ? context.BitfieldExtractS32(srcA, position, size)
+                : context.BitfieldExtractU32(srcA, position, size);
+
+            context.Copy(GetDest(rd), res);
+
+            // TODO: CC, X, corner cases.
+        }
+
+        private static void EmitBfi(EmitterContext context, Operand srcA, Operand srcB, Operand srcC, int rd)
+        {
+            Operand position = context.BitwiseAnd(srcB, Const(0xff));
+
+            Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
+
+            Operand res = context.BitfieldInsert(srcC, srcA, position, size);
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void EmitFlo(EmitterContext context, Operand src, int rd, bool invert, bool sh, bool isSigned)
+        {
+            Operand srcB = context.BitwiseNot(src, invert);
+
+            Operand res = isSigned
+                ? context.FindFirstSetS32(srcB)
+                : context.FindFirstSetU32(srcB);
+
+            if (sh)
+            {
+                res = context.BitwiseExclusiveOr(res, Const(31));
+            }
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void EmitPopc(EmitterContext context, Operand src, int rd, bool invert)
+        {
+            Operand srcB = context.BitwiseNot(src, invert);
+
+            Operand res = context.BitCount(srcB);
+
+            context.Copy(GetDest(rd), res);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
index c4c6c55bb9..43b07cc2bc 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
@@ -1,253 +1,400 @@
 using Ryujinx.Graphics.Shader.Decoders;
 using Ryujinx.Graphics.Shader.IntermediateRepresentation;
 using Ryujinx.Graphics.Shader.Translation;
+using System;
 
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
 using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
 using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
 
 namespace Ryujinx.Graphics.Shader.Instructions
 {
     static partial class InstEmit
     {
-        public static void F2F(EmitterContext context)
+        public static void F2fR(EmitterContext context)
         {
-            OpCodeFArith op = (OpCodeFArith)context.CurrOp;
+            InstF2fR op = context.GetOp<InstF2fR>();
 
-            FPType dstType = (FPType)op.RawOpCode.Extract(8,  2);
-            FPType srcType = (FPType)op.RawOpCode.Extract(10, 2);
+            var src = UnpackReg(context, op.SrcFmt, op.Sh, op.SrcB);
 
-            bool round     = op.RawOpCode.Extract(42);
-            bool negateB   = op.RawOpCode.Extract(45);
-            bool absoluteB = op.RawOpCode.Extract(49);
+            EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
+        }
 
-            Operand srcB = context.FPAbsNeg(GetSrcB(context, srcType), absoluteB, negateB, srcType.ToInstFPType());
+        public static void F2fI(EmitterContext context)
+        {
+            InstF2fI op = context.GetOp<InstF2fI>();
 
-            if (round && srcType == dstType)
+            var src = UnpackImm(context, op.SrcFmt, op.Sh, Imm20ToFloat(op.Imm20));
+
+            EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
+        }
+
+        public static void F2fC(EmitterContext context)
+        {
+            InstF2fC op = context.GetOp<InstF2fC>();
+
+            var src = UnpackCbuf(context, op.SrcFmt, op.Sh, op.CbufSlot, op.CbufOffset);
+
+            EmitF2F(context, op.SrcFmt, op.DstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB, op.Sat);
+        }
+
+        public static void F2iR(EmitterContext context)
+        {
+            InstF2iR op = context.GetOp<InstF2iR>();
+
+            var src = UnpackReg(context, op.SrcFmt, op.Sh, op.SrcB);
+
+            EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void F2iI(EmitterContext context)
+        {
+            InstF2iI op = context.GetOp<InstF2iI>();
+
+            var src = UnpackImm(context, op.SrcFmt, op.Sh, Imm20ToFloat(op.Imm20));
+
+            EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void F2iC(EmitterContext context)
+        {
+            InstF2iC op = context.GetOp<InstF2iC>();
+
+            var src = UnpackCbuf(context, op.SrcFmt, op.Sh, op.CbufSlot, op.CbufOffset);
+
+            EmitF2I(context, op.SrcFmt, op.IDstFmt, op.RoundMode, src, op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void I2fR(EmitterContext context)
+        {
+            InstI2fR op = context.GetOp<InstI2fR>();
+
+            var src = GetSrcReg(context, op.SrcB);
+
+            EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void I2fI(EmitterContext context)
+        {
+            InstI2fI op = context.GetOp<InstI2fI>();
+
+            var src = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void I2fC(EmitterContext context)
+        {
+            InstI2fC op = context.GetOp<InstI2fC>();
+
+            var src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitI2F(context, op.ISrcFmt, op.DstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void I2iR(EmitterContext context)
+        {
+            InstI2iR op = context.GetOp<InstI2iR>();
+
+            var src = GetSrcReg(context, op.SrcB);
+
+            EmitI2I(context, op.SrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat);
+        }
+
+        public static void I2iI(EmitterContext context)
+        {
+            InstI2iI op = context.GetOp<InstI2iI>();
+
+            var src = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitI2I(context, op.SrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat);
+        }
+
+        public static void I2iC(EmitterContext context)
+        {
+            InstI2iC op = context.GetOp<InstI2iC>();
+
+            var src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitI2I(context, op.SrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat);
+        }
+
+        private static void EmitF2F(
+            EmitterContext context,
+            DstFmt srcType,
+            DstFmt dstType,
+            IntegerRound roundingMode,
+            Operand src,
+            int rd,
+            bool absolute,
+            bool negate,
+            bool saturate)
+        {
+            Operand srcB = context.FPAbsNeg(src, absolute, negate, srcType.ToInstFPType());
+
+            if (srcType == dstType)
             {
-                switch (op.RoundingMode)
+                srcB = roundingMode switch
                 {
-                    case RoundingMode.ToNearest:
-                        srcB = context.FPRound(srcB, srcType.ToInstFPType());
-                        break;
-
-                    case RoundingMode.TowardsNegativeInfinity:
-                        srcB = context.FPFloor(srcB, srcType.ToInstFPType());
-                        break;
-
-                    case RoundingMode.TowardsPositiveInfinity:
-                        srcB = context.FPCeiling(srcB, srcType.ToInstFPType());
-                        break;
-
-                    case RoundingMode.TowardsZero:
-                        srcB = context.FPTruncate(srcB, srcType.ToInstFPType());
-                        break;
-                }
+                    IntegerRound.Round => context.FPRound(srcB, srcType.ToInstFPType()),
+                    IntegerRound.Floor => context.FPFloor(srcB, srcType.ToInstFPType()),
+                    IntegerRound.Ceil => context.FPCeiling(srcB, srcType.ToInstFPType()),
+                    IntegerRound.Trunc => context.FPTruncate(srcB, srcType.ToInstFPType()),
+                    _ => srcB
+                };
             }
 
             // We don't need to handle conversions between FP16 <-> FP32
             // since we do FP16 operations as FP32 directly.
             // FP16 <-> FP64 conversions are invalid.
-            if (srcType == FPType.FP32 && dstType == FPType.FP64)
+            if (srcType == DstFmt.F32 && dstType == DstFmt.F64)
             {
                 srcB = context.FP32ConvertToFP64(srcB);
             }
-            else if (srcType == FPType.FP64 && dstType == FPType.FP32)
+            else if (srcType == DstFmt.F64 && dstType == DstFmt.F32)
             {
                 srcB = context.FP64ConvertToFP32(srcB);
             }
 
-            srcB = context.FPSaturate(srcB, op.Saturate, dstType.ToInstFPType());
+            srcB = context.FPSaturate(srcB, saturate, dstType.ToInstFPType());
 
-            WriteFP(context, dstType, srcB);
+            WriteFP(context, dstType, srcB, rd);
 
             // TODO: CC.
         }
 
-        public static void F2I(EmitterContext context)
+        private static void EmitF2I(
+            EmitterContext context,
+            DstFmt srcType,
+            IDstFmt dstType,
+            RoundMode2 roundingMode,
+            Operand src,
+            int rd,
+            bool absolute,
+            bool negate)
         {
-            OpCodeFArith op = (OpCodeFArith)context.CurrOp;
-
-            IntegerType intType = (IntegerType)op.RawOpCode.Extract(8, 2);
-
-            if (intType == IntegerType.U64)
+            if (dstType == IDstFmt.U64)
             {
                 context.Config.GpuAccessor.Log("Unimplemented 64-bits F2I.");
-
                 return;
             }
 
-            bool isSmallInt = intType <= IntegerType.U16;
+            bool isSignedInt = dstType == IDstFmt.S16 || dstType == IDstFmt.S32 || dstType == IDstFmt.S64;
+            bool isSmallInt = dstType == IDstFmt.U16 || dstType == IDstFmt.S16;
 
-            FPType floatType = (FPType)op.RawOpCode.Extract(10, 2);
+            Operand srcB = context.FPAbsNeg(src, absolute, negate);
 
-            bool isSignedInt = op.RawOpCode.Extract(12);
-            bool negateB     = op.RawOpCode.Extract(45);
-            bool absoluteB   = op.RawOpCode.Extract(49);
-
-            if (isSignedInt)
+            srcB = roundingMode switch
             {
-                intType |= IntegerType.S8;
-            }
-
-            Operand srcB = context.FPAbsNeg(GetSrcB(context, floatType), absoluteB, negateB);
-
-            switch (op.RoundingMode)
-            {
-                case RoundingMode.ToNearest:
-                    srcB = context.FPRound(srcB);
-                    break;
-
-                case RoundingMode.TowardsNegativeInfinity:
-                    srcB = context.FPFloor(srcB);
-                    break;
-
-                case RoundingMode.TowardsPositiveInfinity:
-                    srcB = context.FPCeiling(srcB);
-                    break;
-
-                case RoundingMode.TowardsZero:
-                    srcB = context.FPTruncate(srcB);
-                    break;
-            }
+                RoundMode2.Round => context.FPRound(srcB),
+                RoundMode2.Floor => context.FPFloor(srcB),
+                RoundMode2.Ceil => context.FPCeiling(srcB),
+                RoundMode2.Trunc => context.FPTruncate(srcB),
+                _ => srcB
+            };
 
             if (!isSignedInt)
             {
-                // Negative float to uint cast is undefined, so we clamp
-                // the value before conversion.
+                // Negative float to uint cast is undefined, so we clamp the value before conversion.
                 srcB = context.FPMaximum(srcB, ConstF(0));
             }
 
-            srcB = isSignedInt
-                ? context.FPConvertToS32(srcB)
-                : context.FPConvertToU32(srcB);
+            srcB = isSignedInt ? context.FPConvertToS32(srcB) : context.FPConvertToU32(srcB);
 
             if (isSmallInt)
             {
-                int min = (int)GetIntMin(intType);
-                int max = (int)GetIntMax(intType);
+                int min = (int)GetIntMin(dstType);
+                int max = (int)GetIntMax(dstType);
 
                 srcB = isSignedInt
                     ? context.IClampS32(srcB, Const(min), Const(max))
                     : context.IClampU32(srcB, Const(min), Const(max));
             }
 
-            Operand dest = GetDest(context);
+            Operand dest = GetDest(rd);
 
             context.Copy(dest, srcB);
 
             // TODO: CC.
         }
 
-        public static void I2F(EmitterContext context)
+        private static void EmitI2F(
+            EmitterContext context,
+            ISrcFmt srcType,
+            DstFmt dstType,
+            Operand src,
+            ByteSel byteSelection,
+            int rd,
+            bool absolute,
+            bool negate)
         {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            FPType dstType = (FPType)op.RawOpCode.Extract(8, 2);
-
-            IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2);
+            bool isSignedInt =
+                srcType == ISrcFmt.S8 ||
+                srcType == ISrcFmt.S16 ||
+                srcType == ISrcFmt.S32 ||
+                srcType == ISrcFmt.S64;
+            bool isSmallInt =
+                srcType == ISrcFmt.U16 ||
+                srcType == ISrcFmt.S16 ||
+                srcType == ISrcFmt.U8 ||
+                srcType == ISrcFmt.S8;
 
             // TODO: Handle S/U64.
 
-            bool isSmallInt = srcType <= IntegerType.U16;
-
-            bool isSignedInt = op.RawOpCode.Extract(13);
-            bool negateB     = op.RawOpCode.Extract(45);
-            bool absoluteB   = op.RawOpCode.Extract(49);
-
-            Operand srcB = context.IAbsNeg(GetSrcB(context), absoluteB, negateB);
+            Operand srcB = context.IAbsNeg(src, absolute, negate);
 
             if (isSmallInt)
             {
-                int size = srcType == IntegerType.U16 ? 16 : 8;
+                int size = srcType == ISrcFmt.U16 || srcType == ISrcFmt.S16 ? 16 : 8;
 
                 srcB = isSignedInt
-                    ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size))
-                    : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size));
+                    ? context.BitfieldExtractS32(srcB, Const((int)byteSelection * 8), Const(size))
+                    : context.BitfieldExtractU32(srcB, Const((int)byteSelection * 8), Const(size));
             }
 
-            srcB = isSignedInt
-                ? context.IConvertS32ToFP(srcB)
-                : context.IConvertU32ToFP(srcB);
+            srcB = isSignedInt ? context.IConvertS32ToFP(srcB) : context.IConvertU32ToFP(srcB);
 
-            WriteFP(context, dstType, srcB);
+            WriteFP(context, dstType, srcB, rd);
 
             // TODO: CC.
         }
 
-        public static void I2I(EmitterContext context)
+        private static void EmitI2I(
+            EmitterContext context,
+            ISrcFmt srcType,
+            IDstFmt dstType,
+            Operand src,
+            ByteSel byteSelection,
+            int rd,
+            bool absolute,
+            bool negate,
+            bool saturate)
         {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            IntegerType dstType = (IntegerType)op.RawOpCode.Extract(8,  2);
-            IntegerType srcType = (IntegerType)op.RawOpCode.Extract(10, 2);
-
-            if (srcType == IntegerType.U64 || dstType == IntegerType.U64)
+            if (srcType == ISrcFmt.U64 || dstType == IDstFmt.U64)
             {
                 context.Config.GpuAccessor.Log("Invalid I2I encoding.");
-
                 return;
             }
 
-            bool srcIsSmallInt = srcType <= IntegerType.U16;
-
-            bool dstIsSignedInt = op.RawOpCode.Extract(12);
-            bool srcIsSignedInt = op.RawOpCode.Extract(13);
-            bool negateB        = op.RawOpCode.Extract(45);
-            bool absoluteB      = op.RawOpCode.Extract(49);
-
-            Operand srcB = GetSrcB(context);
+            bool srcIsSignedInt =
+                srcType == ISrcFmt.S8 ||
+                srcType == ISrcFmt.S16 ||
+                srcType == ISrcFmt.S32 ||
+                srcType == ISrcFmt.S64;
+            bool dstIsSignedInt =
+                dstType == IDstFmt.S16 ||
+                dstType == IDstFmt.S32 ||
+                dstType == IDstFmt.S64;
+            bool srcIsSmallInt =
+                srcType == ISrcFmt.U16 ||
+                srcType == ISrcFmt.S16 ||
+                srcType == ISrcFmt.U8 ||
+                srcType == ISrcFmt.S8;
 
             if (srcIsSmallInt)
             {
-                int size = srcType == IntegerType.U16 ? 16 : 8;
+                int size = srcType == ISrcFmt.U16 || srcType == ISrcFmt.S16 ? 16 : 8;
 
-                srcB = srcIsSignedInt
-                    ? context.BitfieldExtractS32(srcB, Const(op.ByteSelection * 8), Const(size))
-                    : context.BitfieldExtractU32(srcB, Const(op.ByteSelection * 8), Const(size));
+                src = srcIsSignedInt
+                    ? context.BitfieldExtractS32(src, Const((int)byteSelection * 8), Const(size))
+                    : context.BitfieldExtractU32(src, Const((int)byteSelection * 8), Const(size));
             }
 
-            srcB = context.IAbsNeg(srcB, absoluteB, negateB);
+            src = context.IAbsNeg(src, absolute, negate);
 
-            if (op.Saturate)
+            if (saturate)
             {
-                if (dstIsSignedInt)
-                {
-                    dstType |= IntegerType.S8;
-                }
-
                 int min = (int)GetIntMin(dstType);
                 int max = (int)GetIntMax(dstType);
 
-                srcB = dstIsSignedInt
-                    ? context.IClampS32(srcB, Const(min), Const(max))
-                    : context.IClampU32(srcB, Const(min), Const(max));
+                src = dstIsSignedInt
+                    ? context.IClampS32(src, Const(min), Const(max))
+                    : context.IClampU32(src, Const(min), Const(max));
             }
 
-            context.Copy(GetDest(context), srcB);
+            context.Copy(GetDest(rd), src);
 
             // TODO: CC.
         }
 
-        private static void WriteFP(EmitterContext context, FPType type, Operand srcB)
+        private static Operand UnpackReg(EmitterContext context, DstFmt floatType, bool h, int reg)
         {
-            Operand dest = GetDest(context);
+            if (floatType == DstFmt.F32)
+            {
+                return GetSrcReg(context, reg);
+            }
+            else if (floatType == DstFmt.F16)
+            {
+                return GetHalfUnpacked(context, GetSrcReg(context, reg), HalfSwizzle.F16)[h ? 1 : 0];
+            }
+            else if (floatType == DstFmt.F64)
+            {
+                return GetSrcReg(context, reg, isFP64: true);
+            }
 
-            if (type == FPType.FP32)
+            throw new ArgumentException($"Invalid floating point type \"{floatType}\".");
+        }
+
+        private static Operand UnpackCbuf(EmitterContext context, DstFmt floatType, bool h, int cbufSlot, int cbufOffset)
+        {
+            if (floatType == DstFmt.F32)
+            {
+                return GetSrcCbuf(context, cbufSlot, cbufOffset);
+            }
+            else if (floatType == DstFmt.F16)
+            {
+                return GetHalfUnpacked(context, GetSrcCbuf(context, cbufSlot, cbufOffset), HalfSwizzle.F16)[h ? 1 : 0];
+            }
+            else if (floatType == DstFmt.F64)
+            {
+                return GetSrcCbuf(context, cbufSlot, cbufOffset, isFP64: true);
+            }
+
+            throw new ArgumentException($"Invalid floating point type \"{floatType}\".");
+        }
+
+        private static Operand UnpackImm(EmitterContext context, DstFmt floatType, bool h, int imm)
+        {
+            if (floatType == DstFmt.F32)
+            {
+                return GetSrcImm(context, imm);
+            }
+            else if (floatType == DstFmt.F16)
+            {
+                return GetHalfUnpacked(context, GetSrcImm(context, imm), HalfSwizzle.F16)[h ? 1 : 0];
+            }
+            else if (floatType == DstFmt.F64)
+            {
+                return GetSrcImm(context, imm, isFP64: true);
+            }
+
+            throw new ArgumentException($"Invalid floating point type \"{floatType}\".");
+        }
+
+        private static void WriteFP(EmitterContext context, DstFmt type, Operand srcB, int rd)
+        {
+            Operand dest = GetDest(rd);
+
+            if (type == DstFmt.F32)
             {
                 context.Copy(dest, srcB);
             }
-            else if (type == FPType.FP16)
+            else if (type == DstFmt.F16)
             {
                 context.Copy(dest, context.PackHalf2x16(srcB, ConstF(0)));
             }
             else /* if (type == FPType.FP64) */
             {
-                Operand dest2 = GetDest2(context);
+                Operand dest2 = GetDest2(rd);
 
                 context.Copy(dest, context.UnpackDouble2x32Low(srcB));
                 context.Copy(dest2, context.UnpackDouble2x32High(srcB));
             }
         }
+
+        private static Instruction ToInstFPType(this DstFmt type)
+        {
+            return type == DstFmt.F64 ? Instruction.FP64 : Instruction.FP32;
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs
deleted file mode 100644
index 6dc4c09326..0000000000
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitFArith.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
-    static partial class InstEmit
-    {
-        public static void Dadd(EmitterContext context) => EmitFPAdd(context, Instruction.FP64);
-        public static void Dfma(EmitterContext context) => EmitFPFma(context, Instruction.FP64);
-        public static void Dmul(EmitterContext context) => EmitFPMultiply(context, Instruction.FP64);
-
-        public static void Fadd(EmitterContext context) => EmitFPAdd(context, Instruction.FP32);
-
-        public static void Fcmp(EmitterContext context)
-        {
-            OpCode op = context.CurrOp;
-
-            Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-            Operand srcC = GetSrcC(context);
-
-            Operand cmpRes = GetFPComparison(context, cmpOp, srcC, ConstF(0));
-
-            Operand res = context.ConditionalSelect(cmpRes, srcA, srcB);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Ffma(EmitterContext context) => EmitFPFma(context, Instruction.FP32);
-
-        public static void Ffma32i(EmitterContext context)
-        {
-            IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
-            bool saturate = op.RawOpCode.Extract(55);
-            bool negateA  = op.RawOpCode.Extract(56);
-            bool negateC  = op.RawOpCode.Extract(57);
-
-            Operand srcA = context.FPNegate(GetSrcA(context), negateA);
-            Operand srcC = context.FPNegate(GetDest(context), negateC);
-
-            Operand srcB = GetSrcB(context);
-
-            Operand dest = GetDest(context);
-
-            context.Copy(dest, context.FPSaturate(context.FPFusedMultiplyAdd(srcA, srcB, srcC), saturate));
-
-            SetFPZnFlags(context, dest, op.SetCondCode);
-        }
-
-        public static void Fmnmx(EmitterContext context)
-        {
-            IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
-            bool absoluteA = op.AbsoluteA;
-            bool negateB   = op.RawOpCode.Extract(45);
-            bool negateA   = op.RawOpCode.Extract(48);
-            bool absoluteB = op.RawOpCode.Extract(49);
-
-            Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA);
-            Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB);
-
-            Operand resMin = context.FPMinimum(srcA, srcB);
-            Operand resMax = context.FPMaximum(srcA, srcB);
-
-            Operand pred = GetPredicate39(context);
-
-            Operand dest = GetDest(context);
-
-            context.Copy(dest, context.ConditionalSelect(pred, resMin, resMax));
-
-            SetFPZnFlags(context, dest, op.SetCondCode);
-        }
-
-        public static void Fmul(EmitterContext context) => EmitFPMultiply(context, Instruction.FP32);
-
-        public static void Fset(EmitterContext context)
-        {
-            OpCodeSet op = (OpCodeSet)context.CurrOp;
-
-            Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4);
-
-            bool negateA   = op.RawOpCode.Extract(43);
-            bool absoluteB = op.RawOpCode.Extract(44);
-            bool boolFloat = op.RawOpCode.Extract(52);
-            bool negateB   = op.RawOpCode.Extract(53);
-            bool absoluteA = op.RawOpCode.Extract(54);
-
-            Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA);
-            Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB);
-
-            Operand res = GetFPComparison(context, cmpOp, srcA, srcB);
-
-            Operand pred = GetPredicate39(context);
-
-            res = GetPredLogicalOp(context, op.LogicalOp, res, pred);
-
-            Operand dest = GetDest(context);
-
-            if (boolFloat)
-            {
-                res = context.ConditionalSelect(res, ConstF(1), Const(0));
-
-                context.Copy(dest, res);
-
-                SetFPZnFlags(context, res, op.SetCondCode);
-            }
-            else
-            {
-                context.Copy(dest, res);
-
-                SetZnFlags(context, res, op.SetCondCode, op.Extended);
-            }
-
-            // TODO: X
-        }
-
-        public static void Fsetp(EmitterContext context)
-        {
-            OpCodeSet op = (OpCodeSet)context.CurrOp;
-
-            Condition cmpOp = (Condition)op.RawOpCode.Extract(48, 4);
-
-            bool negateB   = op.RawOpCode.Extract(6);
-            bool absoluteA = op.RawOpCode.Extract(7);
-            bool negateA   = op.RawOpCode.Extract(43);
-            bool absoluteB = op.RawOpCode.Extract(44);
-
-            Operand srcA = context.FPAbsNeg(GetSrcA(context), absoluteA, negateA);
-            Operand srcB = context.FPAbsNeg(GetSrcB(context), absoluteB, negateB);
-
-            Operand p0Res = GetFPComparison(context, cmpOp, srcA, srcB);
-
-            Operand p1Res = context.BitwiseNot(p0Res);
-
-            Operand pred = GetPredicate39(context);
-
-            p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
-            p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
-            context.Copy(Register(op.Predicate3), p0Res);
-            context.Copy(Register(op.Predicate0), p1Res);
-        }
-
-        public static void Fswzadd(EmitterContext context)
-        {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            int mask = op.RawOpCode.Extract(28, 8);
-
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
-
-            Operand dest = GetDest(context);
-
-            context.Copy(dest, context.FPSwizzleAdd(srcA, srcB, mask));
-
-            SetFPZnFlags(context, dest, op.SetCondCode);
-        }
-
-        public static void Hadd2(EmitterContext context)
-        {
-            Hadd2Hmul2Impl(context, isAdd: true);
-        }
-
-        public static void Hfma2(EmitterContext context)
-        {
-            IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
-            Operand[] srcA = GetHfmaSrcA(context);
-            Operand[] srcB = GetHfmaSrcB(context);
-            Operand[] srcC = GetHfmaSrcC(context);
-
-            Operand[] res = new Operand[2];
-
-            for (int index = 0; index < res.Length; index++)
-            {
-                res[index] = context.FPFusedMultiplyAdd(srcA[index], srcB[index], srcC[index]);
-
-                res[index] = context.FPSaturate(res[index], op.Saturate);
-            }
-
-            context.Copy(GetDest(context), GetHalfPacked(context, res));
-        }
-
-        public static void Hmul2(EmitterContext context)
-        {
-            Hadd2Hmul2Impl(context, isAdd: false);
-        }
-
-        private static void Hadd2Hmul2Impl(EmitterContext context, bool isAdd)
-        {
-            OpCode op = context.CurrOp;
-
-            bool saturate = op.RawOpCode.Extract(op is IOpCodeReg ? 32 : 52);
-
-            Operand[] srcA = GetHalfSrcA(context, isAdd);
-            Operand[] srcB = GetHalfSrcB(context, !isAdd);
-
-            Operand[] res = new Operand[2];
-
-            for (int index = 0; index < res.Length; index++)
-            {
-                if (isAdd)
-                {
-                    res[index] = context.FPAdd(srcA[index], srcB[index]);
-                }
-                else
-                {
-                    res[index] = context.FPMultiply(srcA[index], srcB[index]);
-                }
-
-                res[index] = context.FPSaturate(res[index], saturate);
-            }
-
-            context.Copy(GetDest(context), GetHalfPacked(context, res));
-        }
-
-        public static void Hset2(EmitterContext context)
-        {
-            OpCodeSet op = (OpCodeSet)context.CurrOp;
-
-            bool isRegVariant = op is IOpCodeReg;
-
-            bool boolFloat = isRegVariant
-                ? op.RawOpCode.Extract(49)
-                : op.RawOpCode.Extract(53);
-
-            Condition cmpOp = isRegVariant
-                ? (Condition)op.RawOpCode.Extract(35, 4)
-                : (Condition)op.RawOpCode.Extract(49, 4);
-
-            Operand[] srcA = GetHalfSrcA(context);
-            Operand[] srcB = GetHalfSrcB(context);
-
-            Operand[] res = new Operand[2];
-
-            res[0] = GetFPComparison(context, cmpOp, srcA[0], srcB[0]);
-            res[1] = GetFPComparison(context, cmpOp, srcA[1], srcB[1]);
-
-            Operand pred = GetPredicate39(context);
-
-            res[0] = GetPredLogicalOp(context, op.LogicalOp, res[0], pred);
-            res[1] = GetPredLogicalOp(context, op.LogicalOp, res[1], pred);
-
-            if (boolFloat)
-            {
-                res[0] = context.ConditionalSelect(res[0], ConstF(1), Const(0));
-                res[1] = context.ConditionalSelect(res[1], ConstF(1), Const(0));
-
-                context.Copy(GetDest(context), context.PackHalf2x16(res[0], res[1]));
-            }
-            else
-            {
-                Operand low  = context.BitwiseAnd(res[0], Const(0xffff));
-                Operand high = context.ShiftLeft (res[1], Const(16));
-
-                Operand packed = context.BitwiseOr(low, high);
-
-                context.Copy(GetDest(context), packed);
-            }
-        }
-
-        public static void Hsetp2(EmitterContext context)
-        {
-            OpCodeSet op = (OpCodeSet)context.CurrOp;
-
-            bool isRegVariant = op is IOpCodeReg;
-
-            bool hAnd = isRegVariant
-                ? op.RawOpCode.Extract(49)
-                : op.RawOpCode.Extract(53);
-
-            Condition cmpOp = isRegVariant
-                ? (Condition)op.RawOpCode.Extract(35, 4)
-                : (Condition)op.RawOpCode.Extract(49, 4);
-
-            Operand[] srcA = GetHalfSrcA(context);
-            Operand[] srcB = GetHalfSrcB(context);
-
-            Operand p0Res = GetFPComparison(context, cmpOp, srcA[0], srcB[0]);
-            Operand p1Res = GetFPComparison(context, cmpOp, srcA[1], srcB[1]);
-
-            if (hAnd)
-            {
-                p0Res = context.BitwiseAnd(p0Res, p1Res);
-                p1Res = context.BitwiseNot(p0Res);
-            }
-
-            Operand pred = GetPredicate39(context);
-
-            p0Res = GetPredLogicalOp(context, op.LogicalOp, p0Res, pred);
-            p1Res = GetPredLogicalOp(context, op.LogicalOp, p1Res, pred);
-
-            context.Copy(Register(op.Predicate3), p0Res);
-            context.Copy(Register(op.Predicate0), p1Res);
-        }
-
-        public static void Mufu(EmitterContext context)
-        {
-            IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
-            bool negateB = op.RawOpCode.Extract(48);
-
-            Operand res = context.FPAbsNeg(GetSrcA(context), op.AbsoluteA, negateB);
-
-            MufuOperation subOp = (MufuOperation)context.CurrOp.RawOpCode.Extract(20, 4);
-
-            switch (subOp)
-            {
-                case MufuOperation.Cosine:
-                    res = context.FPCosine(res);
-                    break;
-
-                case MufuOperation.Sine:
-                    res = context.FPSine(res);
-                    break;
-
-                case MufuOperation.ExponentB2:
-                    res = context.FPExponentB2(res);
-                    break;
-
-                case MufuOperation.LogarithmB2:
-                    res = context.FPLogarithmB2(res);
-                    break;
-
-                case MufuOperation.Reciprocal:
-                    res = context.FPReciprocal(res);
-                    break;
-
-                case MufuOperation.ReciprocalSquareRoot:
-                    res = context.FPReciprocalSquareRoot(res);
-                    break;
-
-                case MufuOperation.SquareRoot:
-                    res = context.FPSquareRoot(res);
-                    break;
-
-                default: /* TODO */ break;
-            }
-
-            context.Copy(GetDest(context), context.FPSaturate(res, op.Saturate));
-        }
-
-        private static void EmitFPAdd(EmitterContext context, Instruction fpType)
-        {
-            IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
-            bool isFP64 = fpType == Instruction.FP64;
-
-            bool absoluteA = op.AbsoluteA, absoluteB, negateA, negateB;
-
-            if (op is OpCodeFArithImm32)
-            {
-                negateB   = op.RawOpCode.Extract(53);
-                negateA   = op.RawOpCode.Extract(56);
-                absoluteB = op.RawOpCode.Extract(57);
-            }
-            else
-            {
-                negateB   = op.RawOpCode.Extract(45);
-                negateA   = op.RawOpCode.Extract(48);
-                absoluteB = op.RawOpCode.Extract(49);
-            }
-
-            Operand srcA = context.FPAbsNeg(GetSrcA(context, isFP64), absoluteA, negateA, fpType);
-            Operand srcB = context.FPAbsNeg(GetSrcB(context, isFP64), absoluteB, negateB, fpType);
-
-            Operand res = context.FPSaturate(context.FPAdd(srcA, srcB, fpType), op.Saturate, fpType);
-
-            SetDest(context, res, isFP64);
-
-            SetFPZnFlags(context, res, op.SetCondCode, fpType);
-        }
-
-        private static void EmitFPFma(EmitterContext context, Instruction fpType)
-        {
-            IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
-            bool isFP64 = fpType == Instruction.FP64;
-
-            bool negateB = op.RawOpCode.Extract(48);
-            bool negateC = op.RawOpCode.Extract(49);
-
-            Operand srcA = GetSrcA(context, isFP64);
-
-            Operand srcB = context.FPNegate(GetSrcB(context, isFP64), negateB, fpType);
-            Operand srcC = context.FPNegate(GetSrcC(context, isFP64), negateC, fpType);
-
-            Operand res = context.FPSaturate(context.FPFusedMultiplyAdd(srcA, srcB, srcC, fpType), op.Saturate, fpType);
-
-            SetDest(context, res, isFP64);
-
-            SetFPZnFlags(context, res, op.SetCondCode, fpType);
-        }
-
-        private static void EmitFPMultiply(EmitterContext context, Instruction fpType)
-        {
-            IOpCodeFArith op = (IOpCodeFArith)context.CurrOp;
-
-            bool isFP64 = fpType == Instruction.FP64;
-
-            bool isImm32 = op is OpCodeFArithImm32;
-
-            bool negateB = !isImm32 && op.RawOpCode.Extract(48);
-
-            Operand srcA = GetSrcA(context, isFP64);
-
-            Operand srcB = context.FPNegate(GetSrcB(context, isFP64), negateB, fpType);
-
-            if (op.Scale != FPMultiplyScale.None)
-            {
-                Operand scale = op.Scale switch
-                {
-                    FPMultiplyScale.Divide2 => ConstF(0.5f),
-                    FPMultiplyScale.Divide4 => ConstF(0.25f),
-                    FPMultiplyScale.Divide8 => ConstF(0.125f),
-                    FPMultiplyScale.Multiply2 => ConstF(2f),
-                    FPMultiplyScale.Multiply4 => ConstF(4f),
-                    FPMultiplyScale.Multiply8 => ConstF(8f),
-                    _ => ConstF(1) // Invalid, behave as if it had no scale.
-                };
-
-                if (scale.AsFloat() == 1)
-                {
-                    context.Config.GpuAccessor.Log($"Invalid FP multiply scale \"{op.Scale}\".");
-                }
-
-                if (isFP64)
-                {
-                    scale = context.FP32ConvertToFP64(scale);
-                }
-
-                srcA = context.FPMultiply(srcA, scale, fpType);
-            }
-
-            bool saturate = isImm32 ? op.RawOpCode.Extract(55) : op.Saturate;
-
-            Operand res = context.FPSaturate(context.FPMultiply(srcA, srcB, fpType), saturate, fpType);
-
-            SetDest(context, res, isFP64);
-
-            SetFPZnFlags(context, res, op.SetCondCode, fpType);
-        }
-
-        private static Operand GetFPComparison(
-            EmitterContext context,
-            Condition      cond,
-            Operand        srcA,
-            Operand        srcB)
-        {
-            Operand res;
-
-            if (cond == Condition.Always)
-            {
-                res = Const(IrConsts.True);
-            }
-            else if (cond == Condition.Never)
-            {
-                res = Const(IrConsts.False);
-            }
-            else if (cond == Condition.Nan || cond == Condition.Number)
-            {
-                res = context.BitwiseOr(context.IsNan(srcA), context.IsNan(srcB));
-
-                if (cond == Condition.Number)
-                {
-                    res = context.BitwiseNot(res);
-                }
-            }
-            else
-            {
-                Instruction inst;
-
-                switch (cond & ~Condition.Nan)
-                {
-                    case Condition.Less:           inst = Instruction.CompareLess;           break;
-                    case Condition.Equal:          inst = Instruction.CompareEqual;          break;
-                    case Condition.LessOrEqual:    inst = Instruction.CompareLessOrEqual;    break;
-                    case Condition.Greater:        inst = Instruction.CompareGreater;        break;
-                    case Condition.NotEqual:       inst = Instruction.CompareNotEqual;       break;
-                    case Condition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqual; break;
-
-                    default: throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
-                }
-
-                res = context.Add(inst | Instruction.FP32, Local(), srcA, srcB);
-
-                if ((cond & Condition.Nan) != 0)
-                {
-                    res = context.BitwiseOr(res, context.IsNan(srcA));
-                    res = context.BitwiseOr(res, context.IsNan(srcB));
-                }
-            }
-
-            return res;
-        }
-
-        private static Operand[] GetHfmaSrcA(EmitterContext context)
-        {
-            IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
-            return GetHalfUnpacked(context, GetSrcA(context), op.SwizzleA);
-        }
-
-        private static Operand[] GetHfmaSrcB(EmitterContext context)
-        {
-            IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
-            Operand[] operands = GetHalfUnpacked(context, GetSrcB(context), op.SwizzleB);
-
-            return FPAbsNeg(context, operands, false, op.NegateB);
-        }
-
-        private static Operand[] GetHfmaSrcC(EmitterContext context)
-        {
-            IOpCodeHfma op = (IOpCodeHfma)context.CurrOp;
-
-            Operand[] operands = GetHalfUnpacked(context, GetSrcC(context), op.SwizzleC);
-
-            return FPAbsNeg(context, operands, false, op.NegateC);
-        }
-
-        private static void SetDest(EmitterContext context, Operand value, bool isFP64)
-        {
-            if (isFP64)
-            {
-                IOpCodeRd op = (IOpCodeRd)context.CurrOp;
-
-                context.Copy(Register(op.Rd.Index, op.Rd.Type), context.UnpackDouble2x32Low(value));
-                context.Copy(Register(op.Rd.Index | 1, op.Rd.Type), context.UnpackDouble2x32High(value));
-            }
-            else
-            {
-                context.Copy(GetDest(context), value);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs
new file mode 100644
index 0000000000..2318f2b767
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatArithmetic.cs
@@ -0,0 +1,545 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void DaddR(EmitterContext context)
+        {
+            InstDaddR op = context.GetOp<InstDaddR>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
+
+            EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
+        }
+
+        public static void DaddI(EmitterContext context)
+        {
+            InstDaddI op = context.GetOp<InstDaddI>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
+
+            EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
+        }
+
+        public static void DaddC(EmitterContext context)
+        {
+            InstDaddC op = context.GetOp<InstDaddC>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
+
+            EmitFadd(context, Instruction.FP64, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
+        }
+
+        public static void DfmaR(EmitterContext context)
+        {
+            InstDfmaR op = context.GetOp<InstDfmaR>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
+            var srcC = GetSrcReg(context, op.SrcC, isFP64: true);
+
+            EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
+        }
+
+        public static void DfmaI(EmitterContext context)
+        {
+            InstDfmaI op = context.GetOp<InstDfmaI>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
+            var srcC = GetSrcReg(context, op.SrcC, isFP64: true);
+
+            EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
+        }
+
+        public static void DfmaC(EmitterContext context)
+        {
+            InstDfmaC op = context.GetOp<InstDfmaC>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
+            var srcC = GetSrcReg(context, op.SrcC, isFP64: true);
+
+            EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
+        }
+
+        public static void DfmaRc(EmitterContext context)
+        {
+            InstDfmaRc op = context.GetOp<InstDfmaRc>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcReg(context, op.SrcC, isFP64: true);
+            var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
+
+            EmitFfma(context, Instruction.FP64, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, false, op.WriteCC);
+        }
+
+        public static void DmulR(EmitterContext context)
+        {
+            InstDmulR op = context.GetOp<InstDmulR>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
+
+            EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
+        }
+
+        public static void DmulI(EmitterContext context)
+        {
+            InstDmulI op = context.GetOp<InstDmulI>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
+
+            EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
+        }
+
+        public static void DmulC(EmitterContext context)
+        {
+            InstDmulC op = context.GetOp<InstDmulC>();
+
+            var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
+
+            EmitFmul(context, Instruction.FP64, MultiplyScale.NoScale, srcA, srcB, op.Dest, op.NegA, false, op.WriteCC);
+        }
+
+        public static void FaddR(EmitterContext context)
+        {
+            InstFaddR op = context.GetOp<InstFaddR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
+        }
+
+        public static void FaddI(EmitterContext context)
+        {
+            InstFaddI op = context.GetOp<InstFaddI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
+
+            EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
+        }
+
+        public static void FaddC(EmitterContext context)
+        {
+            InstFaddC op = context.GetOp<InstFaddC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, op.Sat, op.WriteCC);
+        }
+
+        public static void Fadd32i(EmitterContext context)
+        {
+            InstFadd32i op = context.GetOp<InstFadd32i>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm32);
+
+            EmitFadd(context, Instruction.FP32, srcA, srcB, op.Dest, op.NegA, op.NegB, op.AbsA, op.AbsB, false, op.WriteCC);
+        }
+
+        public static void FfmaR(EmitterContext context)
+        {
+            InstFfmaR op = context.GetOp<InstFfmaR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
+        }
+
+        public static void FfmaI(EmitterContext context)
+        {
+            InstFfmaI op = context.GetOp<InstFfmaI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
+        }
+
+        public static void FfmaC(EmitterContext context)
+        {
+            InstFfmaC op = context.GetOp<InstFfmaC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
+        }
+
+        public static void FfmaRc(EmitterContext context)
+        {
+            InstFfmaRc op = context.GetOp<InstFfmaRc>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcC);
+            var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
+        }
+
+        public static void Ffma32i(EmitterContext context)
+        {
+            InstFfma32i op = context.GetOp<InstFfma32i>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm32);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitFfma(context, Instruction.FP32, srcA, srcB, srcC, op.Dest, op.NegA, op.NegC, op.Sat, op.WriteCC);
+        }
+
+        public static void FmulR(EmitterContext context)
+        {
+            InstFmulR op = context.GetOp<InstFmulR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
+        }
+
+        public static void FmulI(EmitterContext context)
+        {
+            InstFmulI op = context.GetOp<InstFmulI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
+
+            EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
+        }
+
+        public static void FmulC(EmitterContext context)
+        {
+            InstFmulC op = context.GetOp<InstFmulC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitFmul(context, Instruction.FP32, op.Scale, srcA, srcB, op.Dest, op.NegA, op.Sat, op.WriteCC);
+        }
+
+        public static void Fmul32i(EmitterContext context)
+        {
+            InstFmul32i op = context.GetOp<InstFmul32i>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm32);
+
+            EmitFmul(context, Instruction.FP32, MultiplyScale.NoScale, srcA, srcB, op.Dest, false, op.Sat, op.WriteCC);
+        }
+
+        public static void Hadd2R(EmitterContext context)
+        {
+            InstHadd2R op = context.GetOp<InstHadd2R>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
+
+            EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
+        }
+
+        public static void Hadd2I(EmitterContext context)
+        {
+            InstHadd2I op = context.GetOp<InstHadd2I>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
+
+            EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
+        }
+
+        public static void Hadd2C(EmitterContext context)
+        {
+            InstHadd2C op = context.GetOp<InstHadd2C>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, op.AbsB);
+
+            EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: true, op.Dest, op.Sat);
+        }
+
+        public static void Hadd232i(EmitterContext context)
+        {
+            InstHadd232i op = context.GetOp<InstHadd232i>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, false);
+            var srcB = GetHalfSrc(context, op.Imm);
+
+            EmitHadd2Hmul2(context, OFmt.F16, srcA, srcB, isAdd: true, op.Dest, op.Sat);
+        }
+
+        public static void Hfma2R(EmitterContext context)
+        {
+            InstHfma2R op = context.GetOp<InstHfma2R>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
+            var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegA, false);
+            var srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
+
+            EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
+        }
+
+        public static void Hfma2I(EmitterContext context)
+        {
+            InstHfma2I op = context.GetOp<InstHfma2I>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
+            var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
+            var srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
+
+            EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
+        }
+
+        public static void Hfma2C(EmitterContext context)
+        {
+            InstHfma2C op = context.GetOp<InstHfma2C>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
+            var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegA, false);
+            var srcC = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegC, false);
+
+            EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
+        }
+
+        public static void Hfma2Rc(EmitterContext context)
+        {
+            InstHfma2Rc op = context.GetOp<InstHfma2Rc>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
+            var srcB = GetHalfSrc(context, op.CSwizzle, op.SrcC, op.NegA, false);
+            var srcC = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegC, false);
+
+            EmitHfma2(context, op.OFmt, srcA, srcB, srcC, op.Dest, op.Sat);
+        }
+
+        public static void Hfma232iI(EmitterContext context)
+        {
+            InstHfma232i op = context.GetOp<InstHfma232i>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
+            var srcB = GetHalfSrc(context, op.Imm);
+            var srcC = GetHalfSrc(context, HalfSwizzle.F16, op.SrcC, op.NegC, false);
+
+            EmitHfma2(context, OFmt.F16, srcA, srcB, srcC, op.Dest, saturate: false);
+        }
+
+        public static void Hmul2R(EmitterContext context)
+        {
+            InstHmul2R op = context.GetOp<InstHmul2R>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegA, op.AbsB);
+
+            EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
+        }
+
+        public static void Hmul2I(EmitterContext context)
+        {
+            InstHmul2I op = context.GetOp<InstHmul2I>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
+
+            EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
+        }
+
+        public static void Hmul2C(EmitterContext context)
+        {
+            InstHmul2C op = context.GetOp<InstHmul2C>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, op.AbsA);
+            var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegA, op.AbsB);
+
+            EmitHadd2Hmul2(context, op.OFmt, srcA, srcB, isAdd: false, op.Dest, op.Sat);
+        }
+
+        public static void Hmul232i(EmitterContext context)
+        {
+            InstHmul232i op = context.GetOp<InstHmul232i>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, false, false);
+            var srcB = GetHalfSrc(context, op.Imm32);
+
+            EmitHadd2Hmul2(context, OFmt.F16, srcA, srcB, isAdd: false, op.Dest, op.Sat);
+        }
+
+        private static void EmitFadd(
+            EmitterContext context,
+            Instruction fpType,
+            Operand srcA,
+            Operand srcB,
+            int rd,
+            bool negateA,
+            bool negateB,
+            bool absoluteA,
+            bool absoluteB,
+            bool saturate,
+            bool writeCC)
+        {
+            bool isFP64 = fpType == Instruction.FP64;
+
+            srcA = context.FPAbsNeg(srcA, absoluteA, negateA, fpType);
+            srcB = context.FPAbsNeg(srcB, absoluteB, negateB, fpType);
+
+            Operand res = context.FPSaturate(context.FPAdd(srcA, srcB, fpType), saturate, fpType);
+
+            SetDest(context, res, rd, isFP64);
+
+            SetFPZnFlags(context, res, writeCC, fpType);
+        }
+
+        private static void EmitFfma(
+            EmitterContext context,
+            Instruction fpType,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            int rd,
+            bool negateB,
+            bool negateC,
+            bool saturate,
+            bool writeCC)
+        {
+            bool isFP64 = fpType == Instruction.FP64;
+
+            srcB = context.FPNegate(srcB, negateB, fpType);
+            srcC = context.FPNegate(srcC, negateC, fpType);
+
+            Operand res = context.FPSaturate(context.FPFusedMultiplyAdd(srcA, srcB, srcC, fpType), saturate, fpType);
+
+            SetDest(context, res, rd, isFP64);
+
+            SetFPZnFlags(context, res, writeCC, fpType);
+        }
+
+        private static void EmitFmul(
+            EmitterContext context,
+            Instruction fpType,
+            MultiplyScale scale,
+            Operand srcA,
+            Operand srcB,
+            int rd,
+            bool negateB,
+            bool saturate,
+            bool writeCC)
+        {
+            bool isFP64 = fpType == Instruction.FP64;
+
+            srcB = context.FPNegate(srcB, negateB, fpType);
+
+            if (scale != MultiplyScale.NoScale)
+            {
+                Operand scaleConst = scale switch
+                {
+                    MultiplyScale.D2 => ConstF(0.5f),
+                    MultiplyScale.D4 => ConstF(0.25f),
+                    MultiplyScale.D8 => ConstF(0.125f),
+                    MultiplyScale.M2 => ConstF(2f),
+                    MultiplyScale.M4 => ConstF(4f),
+                    MultiplyScale.M8 => ConstF(8f),
+                    _ => ConstF(1f) // Invalid, behave as if it had no scale.
+                };
+
+                if (scaleConst.AsFloat() == 1f)
+                {
+                    context.Config.GpuAccessor.Log($"Invalid FP multiply scale \"{scale}\".");
+                }
+
+                if (isFP64)
+                {
+                    scaleConst = context.FP32ConvertToFP64(scaleConst);
+                }
+
+                srcA = context.FPMultiply(srcA, scaleConst, fpType);
+            }
+
+            Operand res = context.FPSaturate(context.FPMultiply(srcA, srcB, fpType), saturate, fpType);
+
+            SetDest(context, res, rd, isFP64);
+
+            SetFPZnFlags(context, res, writeCC, fpType);
+        }
+
+        private static void EmitHadd2Hmul2(
+            EmitterContext context,
+            OFmt swizzle,
+            Operand[] srcA,
+            Operand[] srcB,
+            bool isAdd,
+            int rd,
+            bool saturate)
+        {
+            Operand[] res = new Operand[2];
+
+            for (int index = 0; index < res.Length; index++)
+            {
+                if (isAdd)
+                {
+                    res[index] = context.FPAdd(srcA[index], srcB[index]);
+                }
+                else
+                {
+                    res[index] = context.FPMultiply(srcA[index], srcB[index]);
+                }
+
+                res[index] = context.FPSaturate(res[index], saturate);
+            }
+
+            context.Copy(GetDest(rd), GetHalfPacked(context, swizzle, res, rd));
+        }
+
+        public static void EmitHfma2(
+            EmitterContext context,
+            OFmt swizzle,
+            Operand[] srcA,
+            Operand[] srcB,
+            Operand[] srcC,
+            int rd,
+            bool saturate)
+        {
+            Operand[] res = new Operand[2];
+
+            for (int index = 0; index < res.Length; index++)
+            {
+                res[index] = context.FPFusedMultiplyAdd(srcA[index], srcB[index], srcC[index]);
+                res[index] = context.FPSaturate(res[index], saturate);
+            }
+
+            context.Copy(GetDest(rd), GetHalfPacked(context, swizzle, res, rd));
+        }
+
+        private static void SetDest(EmitterContext context, Operand value, int rd, bool isFP64)
+        {
+            if (isFP64)
+            {
+                context.Copy(GetDest(rd), context.UnpackDouble2x32Low(value));
+                context.Copy(GetDest2(rd), context.UnpackDouble2x32High(value));
+            }
+            else
+            {
+                context.Copy(GetDest(rd), value);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatComparison.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatComparison.cs
new file mode 100644
index 0000000000..b7b5f9bac6
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatComparison.cs
@@ -0,0 +1,419 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+using System;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void FcmpR(EmitterContext context)
+        {
+            InstFcmpR op = context.GetOp<InstFcmpR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void FcmpI(EmitterContext context)
+        {
+            InstFcmpI op = context.GetOp<InstFcmpI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void FcmpC(EmitterContext context)
+        {
+            InstFcmpC op = context.GetOp<InstFcmpC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void FcmpRc(EmitterContext context)
+        {
+            InstFcmpRc op = context.GetOp<InstFcmpRc>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcC);
+            var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitFcmp(context, op.FComp, srcA, srcB, srcC, op.Dest);
+        }
+
+        public static void FsetR(EmitterContext context)
+        {
+            InstFsetR op = context.GetOp<InstFsetR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
+        }
+
+        public static void FsetC(EmitterContext context)
+        {
+            InstFsetC op = context.GetOp<InstFsetC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
+        }
+
+        public static void FsetI(EmitterContext context)
+        {
+            InstFsetI op = context.GetOp<InstFsetI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
+
+            EmitFset(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.BVal, op.WriteCC);
+        }
+
+        public static void FsetpR(EmitterContext context)
+        {
+            InstFsetpR op = context.GetOp<InstFsetpR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitFsetp(
+                context,
+                op.FComp,
+                op.Bop,
+                srcA,
+                srcB,
+                op.SrcPred,
+                op.SrcPredInv,
+                op.DestPred,
+                op.DestPredInv,
+                op.AbsA,
+                op.AbsB,
+                op.NegA,
+                op.NegB,
+                op.WriteCC);
+        }
+
+        public static void FsetpI(EmitterContext context)
+        {
+            InstFsetpI op = context.GetOp<InstFsetpI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
+
+            EmitFsetp(
+                context,
+                op.FComp,
+                op.Bop,
+                srcA,
+                srcB,
+                op.SrcPred,
+                op.SrcPredInv,
+                op.DestPred,
+                op.DestPredInv,
+                op.AbsA,
+                op.AbsB,
+                op.NegA,
+                op.NegB,
+                op.WriteCC);
+        }
+
+        public static void FsetpC(EmitterContext context)
+        {
+            InstFsetpC op = context.GetOp<InstFsetpC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitFsetp(
+                context,
+                op.FComp,
+                op.Bop,
+                srcA,
+                srcB,
+                op.SrcPred,
+                op.SrcPredInv,
+                op.DestPred,
+                op.DestPredInv,
+                op.AbsA,
+                op.AbsB,
+                op.NegA,
+                op.NegB,
+                op.WriteCC);
+        }
+
+        public static void Hset2R(EmitterContext context)
+        {
+            InstHset2R op = context.GetOp<InstHset2R>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
+
+            EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
+        }
+
+        public static void Hset2I(EmitterContext context)
+        {
+            InstHset2I op = context.GetOp<InstHset2I>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
+
+            EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
+        }
+
+        public static void Hset2C(EmitterContext context)
+        {
+            InstHset2C op = context.GetOp<InstHset2C>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, false);
+
+            EmitHset2(context, op.Cmp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.Bval);
+        }
+
+        public static void Hsetp2R(EmitterContext context)
+        {
+            InstHsetp2R op = context.GetOp<InstHsetp2R>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BSwizzle, op.SrcB, op.NegB, op.AbsB);
+
+            EmitHsetp2(context, op.FComp2, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
+        }
+
+        public static void Hsetp2I(EmitterContext context)
+        {
+            InstHsetp2I op = context.GetOp<InstHsetp2I>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, op.BimmH0, op.BimmH1);
+
+            EmitHsetp2(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
+        }
+
+        public static void Hsetp2C(EmitterContext context)
+        {
+            InstHsetp2C op = context.GetOp<InstHsetp2C>();
+
+            var srcA = GetHalfSrc(context, op.ASwizzle, op.SrcA, op.NegA, op.AbsA);
+            var srcB = GetHalfSrc(context, HalfSwizzle.F32, op.CbufSlot, op.CbufOffset, op.NegB, op.AbsB);
+
+            EmitHsetp2(context, op.FComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.HAnd);
+        }
+
+        private static void EmitFcmp(EmitterContext context, FComp cmpOp, Operand srcA, Operand srcB, Operand srcC, int rd)
+        {
+            Operand cmpRes = GetFPComparison(context, cmpOp, srcC, ConstF(0));
+
+            Operand res = context.ConditionalSelect(cmpRes, srcA, srcB);
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void EmitFset(
+            EmitterContext context,
+            FComp cmpOp,
+            BoolOp logicOp,
+            Operand srcA,
+            Operand srcB,
+            int srcPred,
+            bool srcPredInv,
+            int rd,
+            bool absoluteA,
+            bool absoluteB,
+            bool negateA,
+            bool negateB,
+            bool boolFloat,
+            bool writeCC)
+        {
+            srcA = context.FPAbsNeg(srcA, absoluteA, negateA);
+            srcB = context.FPAbsNeg(srcB, absoluteB, negateB);
+
+            Operand res = GetFPComparison(context, cmpOp, srcA, srcB);
+            Operand pred = GetPredicate(context, srcPred, srcPredInv);
+
+            res = GetPredLogicalOp(context, logicOp, res, pred);
+
+            Operand dest = GetDest(rd);
+
+            if (boolFloat)
+            {
+                res = context.ConditionalSelect(res, ConstF(1), Const(0));
+
+                context.Copy(dest, res);
+
+                SetFPZnFlags(context, res, writeCC);
+            }
+            else
+            {
+                context.Copy(dest, res);
+
+                SetZnFlags(context, res, writeCC, extended: false);
+            }
+        }
+
+        private static void EmitFsetp(
+            EmitterContext context,
+            FComp cmpOp,
+            BoolOp logicOp,
+            Operand srcA,
+            Operand srcB,
+            int srcPred,
+            bool srcPredInv,
+            int destPred,
+            int destPredInv,
+            bool absoluteA,
+            bool absoluteB,
+            bool negateA,
+            bool negateB,
+            bool writeCC)
+        {
+            srcA = context.FPAbsNeg(srcA, absoluteA, negateA);
+            srcB = context.FPAbsNeg(srcB, absoluteB, negateB);
+
+            Operand p0Res = GetFPComparison(context, cmpOp, srcA, srcB);
+            Operand p1Res = context.BitwiseNot(p0Res);
+            Operand pred = GetPredicate(context, srcPred, srcPredInv);
+
+            p0Res = GetPredLogicalOp(context, logicOp, p0Res, pred);
+            p1Res = GetPredLogicalOp(context, logicOp, p1Res, pred);
+
+            context.Copy(Register(destPred, RegisterType.Predicate), p0Res);
+            context.Copy(Register(destPredInv, RegisterType.Predicate), p1Res);
+        }
+
+        private static void EmitHset2(
+            EmitterContext context,
+            FComp cmpOp,
+            BoolOp logicOp,
+            Operand[] srcA,
+            Operand[] srcB,
+            int srcPred,
+            bool srcPredInv,
+            int rd,
+            bool boolFloat)
+        {
+            Operand[] res = new Operand[2];
+
+            res[0] = GetFPComparison(context, cmpOp, srcA[0], srcB[0]);
+            res[1] = GetFPComparison(context, cmpOp, srcA[1], srcB[1]);
+
+            Operand pred = GetPredicate(context, srcPred, srcPredInv);
+
+            res[0] = GetPredLogicalOp(context, logicOp, res[0], pred);
+            res[1] = GetPredLogicalOp(context, logicOp, res[1], pred);
+
+            if (boolFloat)
+            {
+                res[0] = context.ConditionalSelect(res[0], ConstF(1), Const(0));
+                res[1] = context.ConditionalSelect(res[1], ConstF(1), Const(0));
+
+                context.Copy(GetDest(rd), context.PackHalf2x16(res[0], res[1]));
+            }
+            else
+            {
+                Operand low  = context.BitwiseAnd(res[0], Const(0xffff));
+                Operand high = context.ShiftLeft (res[1], Const(16));
+
+                Operand packed = context.BitwiseOr(low, high);
+
+                context.Copy(GetDest(rd), packed);
+            }
+        }
+
+        private static void EmitHsetp2(
+            EmitterContext context,
+            FComp cmpOp,
+            BoolOp logicOp,
+            Operand[] srcA,
+            Operand[] srcB,
+            int srcPred,
+            bool srcPredInv,
+            int destPred,
+            int destPredInv,
+            bool hAnd)
+        {
+            Operand p0Res = GetFPComparison(context, cmpOp, srcA[0], srcB[0]);
+            Operand p1Res = GetFPComparison(context, cmpOp, srcA[1], srcB[1]);
+
+            if (hAnd)
+            {
+                p0Res = context.BitwiseAnd(p0Res, p1Res);
+                p1Res = context.BitwiseNot(p0Res);
+            }
+
+            Operand pred = GetPredicate(context, srcPred, srcPredInv);
+
+            p0Res = GetPredLogicalOp(context, logicOp, p0Res, pred);
+            p1Res = GetPredLogicalOp(context, logicOp, p1Res, pred);
+
+            context.Copy(Register(destPred, RegisterType.Predicate), p0Res);
+            context.Copy(Register(destPredInv, RegisterType.Predicate), p1Res);
+        }
+
+        private static Operand GetFPComparison(EmitterContext context, FComp cond, Operand srcA, Operand srcB)
+        {
+            Operand res;
+
+            if (cond == FComp.T)
+            {
+                res = Const(IrConsts.True);
+            }
+            else if (cond == FComp.F)
+            {
+                res = Const(IrConsts.False);
+            }
+            else if (cond == FComp.Nan || cond == FComp.Num)
+            {
+                res = context.BitwiseOr(context.IsNan(srcA), context.IsNan(srcB));
+
+                if (cond == FComp.Num)
+                {
+                    res = context.BitwiseNot(res);
+                }
+            }
+            else
+            {
+                Instruction inst;
+
+                switch (cond & ~FComp.Nan)
+                {
+                    case FComp.Lt: inst = Instruction.CompareLess; break;
+                    case FComp.Eq: inst = Instruction.CompareEqual; break;
+                    case FComp.Le: inst = Instruction.CompareLessOrEqual; break;
+                    case FComp.Gt: inst = Instruction.CompareGreater; break;
+                    case FComp.Ne: inst = Instruction.CompareNotEqual; break;
+                    case FComp.Ge: inst = Instruction.CompareGreaterOrEqual; break;
+
+                    default: throw new ArgumentException($"Unexpected condition \"{cond}\".");
+                }
+
+                res = context.Add(inst | Instruction.FP32, Local(), srcA, srcB);
+
+                if ((cond & FComp.Nan) != 0)
+                {
+                    res = context.BitwiseOr(res, context.IsNan(srcA));
+                    res = context.BitwiseOr(res, context.IsNan(srcB));
+                }
+            }
+
+            return res;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatMinMax.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatMinMax.cs
new file mode 100644
index 0000000000..3e91fc8a2e
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFloatMinMax.cs
@@ -0,0 +1,70 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void FmnmxR(EmitterContext context)
+        {
+            InstFmnmxR op = context.GetOp<InstFmnmxR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
+        }
+
+        public static void FmnmxI(EmitterContext context)
+        {
+            InstFmnmxI op = context.GetOp<InstFmnmxI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
+            var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
+        }
+
+        public static void FmnmxC(EmitterContext context)
+        {
+            InstFmnmxC op = context.GetOp<InstFmnmxC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
+        }
+
+        private static void EmitFmnmx(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            Operand srcPred,
+            int rd,
+            bool absoluteA,
+            bool absoluteB,
+            bool negateA,
+            bool negateB,
+            bool writeCC)
+        {
+            srcA = context.FPAbsNeg(srcA, absoluteA, negateA);
+            srcB = context.FPAbsNeg(srcB, absoluteB, negateB);
+
+            Operand resMin = context.FPMinimum(srcA, srcB);
+            Operand resMax = context.FPMaximum(srcA, srcB);
+
+            Operand dest = GetDest(rd);
+
+            context.Copy(dest, context.ConditionalSelect(srcPred, resMin, resMax));
+
+            SetFPZnFlags(context, dest, writeCC);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
similarity index 63%
rename from Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs
rename to Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
index 1f5bf35bc6..fce951ba68 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlowControl.cs
@@ -13,32 +13,38 @@ namespace Ryujinx.Graphics.Shader.Instructions
     {
         public static void Bra(EmitterContext context)
         {
-            EmitBranch(context, context.CurrBlock.Branch.Address);
+            InstBra op = context.GetOp<InstBra>();
+
+            EmitBranch(context, context.CurrBlock.Successors[^1].Address);
         }
 
         public static void Brk(EmitterContext context)
         {
+            InstBrk op = context.GetOp<InstBrk>();
+
             EmitBrkOrSync(context);
         }
 
         public static void Brx(EmitterContext context)
         {
-            OpCodeBranchIndir op = (OpCodeBranchIndir)context.CurrOp;
+            InstBrx op = context.GetOp<InstBrx>();
+            InstOp currOp = context.CurrOp;
+            int startIndex = context.CurrBlock.HasNext() ? 1 : 0;
 
-            if (op.PossibleTargets.Count == 0)
+            if (context.CurrBlock.Successors.Count <= startIndex)
             {
-                context.Config.GpuAccessor.Log($"Failed to find targets for BRX instruction at 0x{op.Address:X}.");
+                context.Config.GpuAccessor.Log($"Failed to find targets for BRX instruction at 0x{currOp.Address:X}.");
                 return;
             }
 
-            int offset = (int)op.Address + 8 + op.Offset;
+            int offset = (int)currOp.GetAbsoluteAddress();
 
-            Operand address = context.IAdd(Register(op.Ra), Const(offset));
+            Operand address = context.IAdd(Register(op.SrcA, RegisterType.Gpr), Const(offset));
 
             // Sorting the target addresses in descending order improves the code,
             // since it will always check the most distant targets first, then the
             // near ones. This can be easily transformed into if/else statements.
-            IOrderedEnumerable<Block> sortedTargets = op.PossibleTargets.OrderByDescending(x => x.Address);
+            var sortedTargets = context.CurrBlock.Successors.Skip(startIndex).OrderByDescending(x => x.Address);
 
             Block lastTarget = sortedTargets.LastOrDefault();
 
@@ -59,28 +65,24 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
         public static void Cal(EmitterContext context)
         {
-            OpCodeBranch op = (OpCodeBranch)context.CurrOp;
+            InstCal op = context.GetOp<InstCal>();
 
-            context.Call(context.GetFunctionId(op.GetAbsoluteAddress()), false);
-        }
-
-        public static void Depbar(EmitterContext context)
-        {
+            context.Call(context.GetFunctionId(context.CurrOp.GetAbsoluteAddress()), false);
         }
 
         public static void Exit(EmitterContext context)
         {
+            InstExit op = context.GetOp<InstExit>();
+
             if (context.IsNonMain)
             {
                 context.Config.GpuAccessor.Log("Invalid exit on non-main function.");
                 return;
             }
 
-            OpCodeExit op = (OpCodeExit)context.CurrOp;
-
             // TODO: Figure out how this is supposed to work in the
             // presence of other condition codes.
-            if (op.Condition == Condition.Always)
+            if (op.Ccc == Ccc.T)
             {
                 context.Return();
             }
@@ -88,20 +90,22 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
         public static void Kil(EmitterContext context)
         {
-            context.Discard();
-        }
+            InstKil op = context.GetOp<InstKil>();
 
-        public static void Nop(EmitterContext context)
-        {
+            context.Discard();
         }
 
         public static void Pbk(EmitterContext context)
         {
+            InstPbk op = context.GetOp<InstPbk>();
+
             EmitPbkOrSsy(context);
         }
 
         public static void Ret(EmitterContext context)
         {
+            InstRet op = context.GetOp<InstRet>();
+
             if (context.IsNonMain)
             {
                 context.Return();
@@ -114,63 +118,62 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
         public static void Ssy(EmitterContext context)
         {
+            InstSsy op = context.GetOp<InstSsy>();
+
             EmitPbkOrSsy(context);
         }
 
         public static void Sync(EmitterContext context)
         {
+            InstSync op = context.GetOp<InstSync>();
+
             EmitBrkOrSync(context);
         }
 
         private static void EmitPbkOrSsy(EmitterContext context)
         {
-            OpCodePush op = (OpCodePush)context.CurrOp;
+            var consumers = context.CurrBlock.PushOpCodes.First(x => x.Op.Address == context.CurrOp.Address).Consumers;
 
-            foreach (KeyValuePair<OpCodeBranchPop, Operand> kv in op.PopOps)
+            foreach (KeyValuePair<Block, Operand> kv in consumers)
             {
-                OpCodeBranchPop opSync = kv.Key;
-
+                Block consumerBlock = kv.Key;
                 Operand local = kv.Value;
 
-                int pushOpIndex = opSync.Targets[op];
+                int id = consumerBlock.SyncTargets[context.CurrOp.Address].PushOpId;
 
-                context.Copy(local, Const(pushOpIndex));
+                context.Copy(local, Const(id));
             }
         }
 
         private static void EmitBrkOrSync(EmitterContext context)
         {
-            OpCodeBranchPop op = (OpCodeBranchPop)context.CurrOp;
+            var targets = context.CurrBlock.SyncTargets;
 
-            if (op.Targets.Count == 1)
+            if (targets.Count == 1)
             {
                 // If we have only one target, then the SSY/PBK is basically
                 // a branch, we can produce better codegen for this case.
-                OpCodePush pushOp = op.Targets.Keys.First();
-
-                EmitBranch(context, pushOp.GetAbsoluteAddress());
+                EmitBranch(context, targets.Values.First().PushOpInfo.Op.GetAbsoluteAddress());
             }
             else
             {
                 // TODO: Support CC here aswell (condition).
-                foreach (KeyValuePair<OpCodePush, int> kv in op.Targets)
+                foreach (SyncTarget target in targets.Values)
                 {
-                    OpCodePush pushOp = kv.Key;
+                    PushOpInfo pushOpInfo = target.PushOpInfo;
 
-                    Operand label = context.GetLabel(pushOp.GetAbsoluteAddress());
+                    Operand label = context.GetLabel(pushOpInfo.Op.GetAbsoluteAddress());
+                    Operand local = pushOpInfo.Consumers[context.CurrBlock];
 
-                    Operand local = pushOp.PopOps[op];
-
-                    int pushOpIndex = kv.Value;
-
-                    context.BranchIfTrue(label, context.ICompareEqual(local, Const(pushOpIndex)));
+                    context.BranchIfTrue(label, context.ICompareEqual(local, Const(target.PushOpId)));
                 }
             }
         }
 
         private static void EmitBranch(EmitterContext context, ulong address)
         {
-            OpCode op = context.CurrOp;
+            InstOp op = context.CurrOp;
+            InstConditional opCond = new InstConditional(op.RawOpCode);
 
             // If we're branching to the next instruction, then the branch
             // is useless and we can ignore it.
@@ -181,17 +184,17 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             Operand label = context.GetLabel(address);
 
-            Operand pred = Register(op.Predicate);
+            Operand pred = Register(opCond.Pred, RegisterType.Predicate);
 
-            if (op is OpCodeConditional opCond && opCond.Condition != Condition.Always)
+            if (opCond.Ccc != Ccc.T)
             {
-                Operand cond = GetCondition(context, opCond.Condition);
+                Operand cond = GetCondition(context, opCond.Ccc);
 
-                if (op.Predicate.IsPT)
+                if (opCond.Pred == RegisterConsts.PredicateTrueIndex)
                 {
                     pred = cond;
                 }
-                else if (op.InvertPredicate)
+                else if (opCond.PredInv)
                 {
                     pred = context.BitwiseAnd(context.BitwiseNot(pred), cond);
                 }
@@ -202,11 +205,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
                 context.BranchIfTrue(label, pred);
             }
-            else if (op.Predicate.IsPT)
+            else if (opCond.Pred == RegisterConsts.PredicateTrueIndex)
             {
                 context.Branch(label);
             }
-            else if (op.InvertPredicate)
+            else if (opCond.PredInv)
             {
                 context.BranchIfFalse(label, pred);
             }
@@ -216,16 +219,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
             }
         }
 
-        private static Operand GetCondition(EmitterContext context, Condition cond)
+        private static Operand GetCondition(EmitterContext context, Ccc cond)
         {
             // TODO: More condition codes, figure out how they work.
             switch (cond)
             {
-                case Condition.Equal:
-                case Condition.EqualUnordered:
+                case Ccc.Eq:
+                case Ccc.Equ:
                     return GetZF();
-                case Condition.NotEqual:
-                case Condition.NotEqualUnordered:
+                case Ccc.Ne:
+                case Ccc.Neu:
                     return context.BitwiseNot(GetZF());
             }
 
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
index 5a351c73f8..9f5bbdf71d 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitHelper.cs
@@ -2,6 +2,7 @@ using Ryujinx.Graphics.Shader.Decoders;
 using Ryujinx.Graphics.Shader.IntermediateRepresentation;
 using Ryujinx.Graphics.Shader.Translation;
 using System;
+using System.Runtime.CompilerServices;
 
 using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
 
@@ -29,184 +30,101 @@ namespace Ryujinx.Graphics.Shader.Instructions
             return Register(3, RegisterType.Flag);
         }
 
-        public static Operand GetDest(EmitterContext context)
+        public static Operand GetDest(int rd)
         {
-            return Register(((IOpCodeRd)context.CurrOp).Rd);
+            return Register(rd, RegisterType.Gpr);
         }
 
-        public static Operand GetDest2(EmitterContext context)
+        public static Operand GetDest2(int rd)
         {
-            Register rd = ((IOpCodeRd)context.CurrOp).Rd;
-
-            return Register(rd.Index | 1, rd.Type);
+            return Register(rd | 1, RegisterType.Gpr);
         }
 
-        public static Operand GetSrcA(EmitterContext context, bool isFP64 = false)
-        {
-            IOpCodeRa op = (IOpCodeRa)context.CurrOp;
-
-            if (isFP64)
-            {
-                return context.PackDouble2x32(Register(op.Ra.Index, op.Ra.Type), Register(op.Ra.Index | 1, op.Ra.Type));
-            }
-            else
-            {
-                return Register(op.Ra);
-            }
-        }
-
-        public static Operand GetSrcB(EmitterContext context, FPType floatType)
-        {
-            if (floatType == FPType.FP32)
-            {
-                return GetSrcB(context);
-            }
-            else if (floatType == FPType.FP16)
-            {
-                int h = context.CurrOp.RawOpCode.Extract(41, 1);
-
-                return GetHalfUnpacked(context, GetSrcB(context), FPHalfSwizzle.FP16)[h];
-            }
-            else if (floatType == FPType.FP64)
-            {
-                return GetSrcB(context, true);
-            }
-
-            throw new ArgumentException($"Invalid floating point type \"{floatType}\".");
-        }
-
-        public static Operand GetSrcB(EmitterContext context, bool isFP64 = false)
+        public static Operand GetSrcCbuf(EmitterContext context, int cbufSlot, int cbufOffset, bool isFP64 = false)
         {
             if (isFP64)
             {
-                switch (context.CurrOp)
-                {
-                    case IOpCodeCbuf op:
-                        return context.PackDouble2x32(
-                            context.Config.CreateCbuf(op.Slot, op.Offset),
-                            context.Config.CreateCbuf(op.Slot, op.Offset + 1));
-
-                    case IOpCodeImmF op:
-                        return context.FP32ConvertToFP64(ConstF(op.Immediate));
-
-                    case IOpCodeReg op:
-                        return context.PackDouble2x32(Register(op.Rb.Index, op.Rb.Type), Register(op.Rb.Index | 1, op.Rb.Type));
-
-                    case IOpCodeRegCbuf op:
-                        return context.PackDouble2x32(Register(op.Rc.Index, op.Rc.Type), Register(op.Rc.Index | 1, op.Rc.Type));
-                }
+                return context.PackDouble2x32(
+                    context.Config.CreateCbuf(cbufSlot, cbufOffset),
+                    context.Config.CreateCbuf(cbufSlot, cbufOffset + 1));
             }
             else
             {
-                switch (context.CurrOp)
-                {
-                    case IOpCodeCbuf op:
-                        return context.Config.CreateCbuf(op.Slot, op.Offset);
-
-                    case IOpCodeImm op:
-                        return Const(op.Immediate);
-
-                    case IOpCodeImmF op:
-                        return ConstF(op.Immediate);
-
-                    case IOpCodeReg op:
-                        return Register(op.Rb);
-
-                    case IOpCodeRegCbuf op:
-                        return Register(op.Rc);
-                }
+                return context.Config.CreateCbuf(cbufSlot, cbufOffset);
             }
-
-            throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\".");
         }
 
-        public static Operand GetSrcC(EmitterContext context, bool isFP64 = false)
+        public static Operand GetSrcImm(EmitterContext context, int imm, bool isFP64 = false)
         {
             if (isFP64)
             {
-                switch (context.CurrOp)
-                {
-                    case IOpCodeRegCbuf op:
-                        return context.PackDouble2x32(
-                            context.Config.CreateCbuf(op.Slot, op.Offset),
-                            context.Config.CreateCbuf(op.Slot, op.Offset + 1));
-
-                    case IOpCodeRc op:
-                        return context.PackDouble2x32(Register(op.Rc.Index, op.Rc.Type), Register(op.Rc.Index | 1, op.Rc.Type));
-                }
+                return context.FP32ConvertToFP64(Const(imm));
             }
             else
             {
-                switch (context.CurrOp)
-                {
-                    case IOpCodeRegCbuf op:
-                        return context.Config.CreateCbuf(op.Slot, op.Offset);
-
-                    case IOpCodeRc op:
-                        return Register(op.Rc);
-                }
+                return Const(imm);
             }
-
-            throw new InvalidOperationException($"Unexpected opcode type \"{context.CurrOp.GetType().Name}\".");
         }
 
-        public static Operand[] GetHalfSrcA(EmitterContext context, bool isAdd = false)
+        public static Operand GetSrcReg(EmitterContext context, int reg, bool isFP64 = false)
         {
-            OpCode op = context.CurrOp;
-
-            bool absoluteA = false, negateA = false;
-
-            if (op is OpCodeAluImm32 && isAdd)
+            if (isFP64)
             {
-                negateA = op.RawOpCode.Extract(56);
+                return context.PackDouble2x32(Register(reg, RegisterType.Gpr), Register(reg | 1, RegisterType.Gpr));
             }
-            else if (isAdd || op is IOpCodeCbuf || op is IOpCodeImm)
+            else
             {
-                negateA   = op.RawOpCode.Extract(43);
-                absoluteA = op.RawOpCode.Extract(44);
+                return Register(reg, RegisterType.Gpr);
             }
-            else if (op is IOpCodeReg)
-            {
-                absoluteA = op.RawOpCode.Extract(44);
-            }
-
-            FPHalfSwizzle swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(47, 2);
-
-            Operand[] operands = GetHalfUnpacked(context, GetSrcA(context), swizzle);
-
-            return FPAbsNeg(context, operands, absoluteA, negateA);
         }
 
-        public static Operand[] GetHalfSrcB(EmitterContext context, bool isMul = false)
+        public static Operand[] GetHalfSrc(
+            EmitterContext context,
+            HalfSwizzle swizzle,
+            int ra,
+            bool negate,
+            bool absolute)
         {
-            OpCode op = context.CurrOp;
+            Operand[] operands = GetHalfUnpacked(context, GetSrcReg(context, ra), swizzle);
 
-            FPHalfSwizzle swizzle = FPHalfSwizzle.FP16;
+            return FPAbsNeg(context, operands, absolute, negate);
+        }
 
-            bool absoluteB = false, negateB = false;
+        public static Operand[] GetHalfSrc(
+            EmitterContext context,
+            HalfSwizzle swizzle,
+            int cbufSlot,
+            int cbufOffset,
+            bool negate,
+            bool absolute)
+        {
+            Operand[] operands = GetHalfUnpacked(context, GetSrcCbuf(context, cbufSlot, cbufOffset), swizzle);
 
-            if (op is IOpCodeReg)
+            return FPAbsNeg(context, operands, absolute, negate);
+        }
+
+        public static Operand[] GetHalfSrc(EmitterContext context, int immH0, int immH1)
+        {
+            ushort low = (ushort)(immH0 << 6);
+            ushort high = (ushort)(immH1 << 6);
+
+            return new Operand[]
             {
-                swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2);
+                ConstF((float)Unsafe.As<ushort, Half>(ref low)),
+                ConstF((float)Unsafe.As<ushort, Half>(ref high))
+            };
+        }
 
-                absoluteB = op.RawOpCode.Extract(30);
-                negateB   = op.RawOpCode.Extract(31);
-            }
-            else if (op is IOpCodeCbuf)
+        public static Operand[] GetHalfSrc(EmitterContext context, int imm32)
+        {
+            ushort low = (ushort)imm32;
+            ushort high = (ushort)(imm32 >> 16);
+
+            return new Operand[]
             {
-                swizzle = FPHalfSwizzle.FP32;
-
-                absoluteB = op.RawOpCode.Extract(54);
-
-                if (!isMul)
-                {
-                    negateB = op.RawOpCode.Extract(56);
-                }
-            }
-
-            Operand[] operands = GetHalfUnpacked(context, GetSrcB(context), swizzle);
-
-            return FPAbsNeg(context, operands, absoluteB, negateB);
+                ConstF((float)Unsafe.As<ushort, Half>(ref low)),
+                ConstF((float)Unsafe.As<ushort, Half>(ref high))
+            };
         }
 
         public static Operand[] FPAbsNeg(EmitterContext context, Operand[] operands, bool abs, bool neg)
@@ -219,27 +137,27 @@ namespace Ryujinx.Graphics.Shader.Instructions
             return operands;
         }
 
-        public static Operand[] GetHalfUnpacked(EmitterContext context, Operand src, FPHalfSwizzle swizzle)
+        public static Operand[] GetHalfUnpacked(EmitterContext context, Operand src, HalfSwizzle swizzle)
         {
             switch (swizzle)
             {
-                case FPHalfSwizzle.FP16:
+                case HalfSwizzle.F16:
                     return new Operand[]
                     {
                         context.UnpackHalf2x16Low (src),
                         context.UnpackHalf2x16High(src)
                     };
 
-                case FPHalfSwizzle.FP32: return new Operand[] { src, src };
+                case HalfSwizzle.F32: return new Operand[] { src, src };
 
-                case FPHalfSwizzle.DupH0:
+                case HalfSwizzle.H0H0:
                     return new Operand[]
                     {
                         context.UnpackHalf2x16Low(src),
                         context.UnpackHalf2x16Low(src)
                     };
 
-                case FPHalfSwizzle.DupH1:
+                case HalfSwizzle.H1H1:
                     return new Operand[]
                     {
                         context.UnpackHalf2x16High(src),
@@ -250,33 +168,24 @@ namespace Ryujinx.Graphics.Shader.Instructions
             throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
         }
 
-        public static Operand GetHalfPacked(EmitterContext context, Operand[] results)
+        public static Operand GetHalfPacked(EmitterContext context, OFmt swizzle, Operand[] results, int rd)
         {
-            OpCode op = context.CurrOp;
-
-            FPHalfSwizzle swizzle = FPHalfSwizzle.FP16;
-
-            if (!(op is OpCodeAluImm32))
-            {
-                swizzle = (FPHalfSwizzle)context.CurrOp.RawOpCode.Extract(49, 2);
-            }
-
             switch (swizzle)
             {
-                case FPHalfSwizzle.FP16: return context.PackHalf2x16(results[0], results[1]);
+                case OFmt.F16: return context.PackHalf2x16(results[0], results[1]);
 
-                case FPHalfSwizzle.FP32: return results[0];
+                case OFmt.F32: return results[0];
 
-                case FPHalfSwizzle.DupH0:
+                case OFmt.MrgH0:
                 {
-                    Operand h1 = GetHalfDest(context, isHigh: true);
+                    Operand h1 = GetHalfDest(context, rd, isHigh: true);
 
                     return context.PackHalf2x16(results[0], h1);
                 }
 
-                case FPHalfSwizzle.DupH1:
+                case OFmt.MrgH1:
                 {
-                    Operand h0 = GetHalfDest(context, isHigh: false);
+                    Operand h0 = GetHalfDest(context, rd, isHigh: false);
 
                     return context.PackHalf2x16(h0, results[1]);
                 }
@@ -285,25 +194,23 @@ namespace Ryujinx.Graphics.Shader.Instructions
             throw new ArgumentException($"Invalid swizzle \"{swizzle}\".");
         }
 
-        public static Operand GetHalfDest(EmitterContext context, bool isHigh)
+        public static Operand GetHalfDest(EmitterContext context, int rd, bool isHigh)
         {
             if (isHigh)
             {
-                return context.UnpackHalf2x16High(GetDest(context));
+                return context.UnpackHalf2x16High(GetDest(rd));
             }
             else
             {
-                return context.UnpackHalf2x16Low(GetDest(context));
+                return context.UnpackHalf2x16Low(GetDest(rd));
             }
         }
 
-        public static Operand GetPredicate39(EmitterContext context)
+        public static Operand GetPredicate(EmitterContext context, int pred, bool not)
         {
-            IOpCodePredicate39 op = (IOpCodePredicate39)context.CurrOp;
+            Operand local = Register(pred, RegisterType.Predicate);
 
-            Operand local = Register(op.Predicate39);
-
-            if (op.InvertP)
+            if (not)
             {
                 local = context.BitwiseNot(local);
             }
@@ -311,6 +218,26 @@ namespace Ryujinx.Graphics.Shader.Instructions
             return local;
         }
 
+        public static int Imm16ToSInt(int imm16)
+        {
+            return (short)imm16;
+        }
+
+        public static int Imm20ToFloat(int imm20)
+        {
+            return imm20 << 12;
+        }
+
+        public static int Imm20ToSInt(int imm20)
+        {
+            return (imm20 << 12) >> 12;
+        }
+
+        public static int Imm24ToSInt(int imm24)
+        {
+            return (imm24 << 8) >> 8;
+        }
+
         public static Operand SignExtendTo32(EmitterContext context, Operand src, int srcBits)
         {
             return context.BitfieldExtractS32(src, Const(0), Const(srcBits));
@@ -318,7 +245,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
         public static Operand ZeroExtendTo32(EmitterContext context, Operand src, int srcBits)
         {
-            int mask = (int)(0xffffffffu >> (32 - srcBits));
+            int mask = (int)(uint.MaxValue >> (32 - srcBits));
 
             return context.BitwiseAnd(src, Const(mask));
         }
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs
new file mode 100644
index 0000000000..ac8cca1b77
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerArithmetic.cs
@@ -0,0 +1,656 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void IaddR(EmitterContext context)
+        {
+            InstIaddR op = context.GetOp<InstIaddR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
+        }
+
+        public static void IaddI(EmitterContext context)
+        {
+            InstIaddI op = context.GetOp<InstIaddI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
+        }
+
+        public static void IaddC(EmitterContext context)
+        {
+            InstIaddC op = context.GetOp<InstIaddC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
+        }
+
+        public static void Iadd32i(EmitterContext context)
+        {
+            InstIadd32i op = context.GetOp<InstIadd32i>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm32);
+
+            EmitIadd(context, srcA, srcB, op.Dest, op.AvgMode, op.X, op.WriteCC);
+        }
+
+        public static void Iadd3R(EmitterContext context)
+        {
+            InstIadd3R op = context.GetOp<InstIadd3R>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitIadd3(context, op.Lrs, srcA, srcB, srcC, op.Apart, op.Bpart, op.Cpart, op.Dest, op.NegA, op.NegB, op.NegC);
+        }
+
+        public static void Iadd3I(EmitterContext context)
+        {
+            InstIadd3I op = context.GetOp<InstIadd3I>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC);
+        }
+
+        public static void Iadd3C(EmitterContext context)
+        {
+            InstIadd3C op = context.GetOp<InstIadd3C>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitIadd3(context, Lrs.None, srcA, srcB, srcC, HalfSelect.B32, HalfSelect.B32, HalfSelect.B32, op.Dest, op.NegA, op.NegB, op.NegC);
+        }
+
+        public static void ImadR(EmitterContext context)
+        {
+            InstImadR op = context.GetOp<InstImadR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
+        }
+
+        public static void ImadI(EmitterContext context)
+        {
+            InstImadI op = context.GetOp<InstImadI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
+        }
+
+        public static void ImadC(EmitterContext context)
+        {
+            InstImadC op = context.GetOp<InstImadC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
+        }
+
+        public static void ImadRc(EmitterContext context)
+        {
+            InstImadRc op = context.GetOp<InstImadRc>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcC);
+            var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
+        }
+
+        public static void Imad32i(EmitterContext context)
+        {
+            InstImad32i op = context.GetOp<InstImad32i>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm32);
+            var srcC = GetSrcReg(context, op.Dest);
+
+            EmitImad(context, srcA, srcB, srcC, op.Dest, op.AvgMode, op.ASigned, op.BSigned, op.Hilo);
+        }
+
+        public static void IscaddR(EmitterContext context)
+        {
+            InstIscaddR op = context.GetOp<InstIscaddR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
+        }
+
+        public static void IscaddI(EmitterContext context)
+        {
+            InstIscaddI op = context.GetOp<InstIscaddI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
+        }
+
+        public static void IscaddC(EmitterContext context)
+        {
+            InstIscaddC op = context.GetOp<InstIscaddC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, op.AvgMode, op.WriteCC);
+        }
+
+        public static void Iscadd32i(EmitterContext context)
+        {
+            InstIscadd32i op = context.GetOp<InstIscadd32i>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm32);
+
+            EmitIscadd(context, srcA, srcB, op.Dest, op.Imm5, AvgMode.NoNeg, op.WriteCC);
+        }
+
+        public static void LeaR(EmitterContext context)
+        {
+            InstLeaR op = context.GetOp<InstLeaR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
+        }
+
+        public static void LeaI(EmitterContext context)
+        {
+            InstLeaI op = context.GetOp<InstLeaI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
+        }
+
+        public static void LeaC(EmitterContext context)
+        {
+            InstLeaC op = context.GetOp<InstLeaC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitLea(context, srcA, srcB, op.Dest, op.NegA, op.ImmU5);
+        }
+
+        public static void LeaHiR(EmitterContext context)
+        {
+            InstLeaHiR op = context.GetOp<InstLeaHiR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5);
+        }
+
+        public static void LeaHiC(EmitterContext context)
+        {
+            InstLeaHiC op = context.GetOp<InstLeaHiC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitLeaHi(context, srcA, srcB, srcC, op.Dest, op.NegA, op.ImmU5);
+        }
+
+        public static void XmadR(EmitterContext context)
+        {
+            InstXmadR op = context.GetOp<InstXmadR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC);
+        }
+
+        public static void XmadI(EmitterContext context)
+        {
+            InstXmadI op = context.GetOp<InstXmadI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm16);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, false, op.Psl, op.Mrg, op.X, op.WriteCC);
+        }
+
+        public static void XmadC(EmitterContext context)
+        {
+            InstXmadC op = context.GetOp<InstXmadC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, op.Psl, op.Mrg, op.X, op.WriteCC);
+        }
+
+        public static void XmadRc(EmitterContext context)
+        {
+            InstXmadRc op = context.GetOp<InstXmadRc>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcC);
+            var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitXmad(context, op.XmadCop, srcA, srcB, srcC, op.Dest, op.ASigned, op.BSigned, op.HiloA, op.HiloB, false, false, op.X, op.WriteCC);
+        }
+
+        private static void EmitIadd(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            int rd,
+            AvgMode avgMode,
+            bool extended,
+            bool writeCC)
+        {
+            srcA = context.INegate(srcA, avgMode == AvgMode.NegA);
+            srcB = context.INegate(srcB, avgMode == AvgMode.NegB);
+
+            Operand res = context.IAdd(srcA, srcB);
+
+            if (extended)
+            {
+                res = context.IAdd(res, context.BitwiseAnd(GetCF(), Const(1)));
+            }
+
+            SetIaddFlags(context, res, srcA, srcB, writeCC, extended);
+
+            // TODO: SAT.
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void EmitIadd3(
+            EmitterContext context,
+            Lrs mode,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            HalfSelect partA,
+            HalfSelect partB,
+            HalfSelect partC,
+            int rd,
+            bool negateA,
+            bool negateB,
+            bool negateC)
+        {
+            Operand Extend(Operand src, HalfSelect part)
+            {
+                if (part == HalfSelect.B32)
+                {
+                    return src;
+                }
+
+                if (part == HalfSelect.H0)
+                {
+                    return context.BitwiseAnd(src, Const(0xffff));
+                }
+                else if (part == HalfSelect.H1)
+                {
+                    return context.ShiftRightU32(src, Const(16));
+                }
+                else
+                {
+                    context.Config.GpuAccessor.Log($"Iadd3 has invalid component selection {part}.");
+                }
+
+                return src;
+            }
+
+            srcA = context.INegate(Extend(srcA, partA), negateA);
+            srcB = context.INegate(Extend(srcB, partB), negateB);
+            srcC = context.INegate(Extend(srcC, partC), negateC);
+
+            Operand res = context.IAdd(srcA, srcB);
+
+            if (mode != Lrs.None)
+            {
+                if (mode == Lrs.LeftShift)
+                {
+                    res = context.ShiftLeft(res, Const(16));
+                }
+                else if (mode == Lrs.RightShift)
+                {
+                    res = context.ShiftRightU32(res, Const(16));
+                }
+                else
+                {
+                    // TODO: Warning.
+                }
+            }
+
+            res = context.IAdd(res, srcC);
+
+            context.Copy(GetDest(rd), res);
+
+            // TODO: CC, X, corner cases.
+        }
+
+        public static void EmitImad(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            int rd,
+            AvgMode avgMode,
+            bool signedA,
+            bool signedB,
+            bool high)
+        {
+            srcB = context.INegate(srcB, avgMode == AvgMode.NegA);
+            srcC = context.INegate(srcC, avgMode == AvgMode.NegB);
+
+            Operand res;
+
+            if (high)
+            {
+                if (signedA && signedB)
+                {
+                    res = context.MultiplyHighS32(srcA, srcB);
+                }
+                else
+                {
+                    res = context.MultiplyHighU32(srcA, srcB);
+
+                    if (signedA)
+                    {
+                        res = context.IAdd(res, context.IMultiply(srcB, context.ShiftRightS32(srcA, Const(31))));
+                    }
+                    else if (signedB)
+                    {
+                        res = context.IAdd(res, context.IMultiply(srcA, context.ShiftRightS32(srcB, Const(31))));
+                    }
+                }
+            }
+            else
+            {
+                res = context.IMultiply(srcA, srcB);
+            }
+
+            res = context.IAdd(res, srcC);
+
+            // TODO: CC, X, SAT, and more?
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void EmitIscadd(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            int rd,
+            int shift,
+            AvgMode avgMode,
+            bool writeCC)
+        {
+            srcA = context.ShiftLeft(srcA, Const(shift));
+
+            srcA = context.INegate(srcA, avgMode == AvgMode.NegA);
+            srcB = context.INegate(srcB, avgMode == AvgMode.NegB);
+
+            Operand res = context.IAdd(srcA, srcB);
+
+            SetIaddFlags(context, res, srcA, srcB, writeCC, false);
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        public static void EmitLea(EmitterContext context, Operand srcA, Operand srcB, int rd, bool negateA, int shift)
+        {
+            srcA = context.ShiftLeft(srcA, Const(shift));
+            srcA = context.INegate(srcA, negateA);
+
+            Operand res = context.IAdd(srcA, srcB);
+
+            context.Copy(GetDest(rd), res);
+
+            // TODO: CC, X.
+        }
+
+        private static void EmitLeaHi(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            int rd,
+            bool negateA,
+            int shift)
+        {
+            Operand aLow = context.ShiftLeft(srcA, Const(shift));
+            Operand aHigh = shift == 0 ? Const(0) : context.ShiftRightU32(srcA, Const(32 - shift));
+            aHigh = context.BitwiseOr(aHigh, context.ShiftLeft(srcC, Const(shift)));
+
+            if (negateA)
+            {
+                // Perform 64-bit negation by doing bitwise not of the value,
+                // then adding 1 and carrying over from low to high.
+                aLow = context.BitwiseNot(aLow);
+                aHigh = context.BitwiseNot(aHigh);
+
+                aLow = AddWithCarry(context, aLow, Const(1), out Operand aLowCOut);
+                aHigh = context.IAdd(aHigh, aLowCOut);
+            }
+
+            Operand res = context.IAdd(aHigh, srcB);
+
+            context.Copy(GetDest(rd), res);
+
+            // TODO: CC, X.
+        }
+
+        public static void EmitXmad(
+            EmitterContext context,
+            XmadCop2 mode,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            int rd,
+            bool signedA,
+            bool signedB,
+            bool highA,
+            bool highB,
+            bool productShiftLeft,
+            bool merge,
+            bool extended,
+            bool writeCC)
+        {
+            XmadCop modeConv;
+            switch (mode)
+            {
+                case XmadCop2.Cfull:
+                    modeConv = XmadCop.Cfull;
+                    break;
+                case XmadCop2.Clo:
+                    modeConv = XmadCop.Clo;
+                    break;
+                case XmadCop2.Chi:
+                    modeConv = XmadCop.Chi;
+                    break;
+                case XmadCop2.Csfu:
+                    modeConv = XmadCop.Csfu;
+                    break;
+                default:
+                    context.Config.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\".");
+                    return;
+            }
+
+            EmitXmad(context, modeConv, srcA, srcB, srcC, rd, signedA, signedB, highA, highB, productShiftLeft, merge, extended, writeCC);
+        }
+
+        public static void EmitXmad(
+            EmitterContext context,
+            XmadCop mode,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            int rd,
+            bool signedA,
+            bool signedB,
+            bool highA,
+            bool highB,
+            bool productShiftLeft,
+            bool merge,
+            bool extended,
+            bool writeCC)
+        {
+            var srcBUnmodified = srcB;
+
+            Operand Extend16To32(Operand src, bool high, bool signed)
+            {
+                if (signed && high)
+                {
+                    return context.ShiftRightS32(src, Const(16));
+                }
+                else if (signed)
+                {
+                    return context.BitfieldExtractS32(src, Const(0), Const(16));
+                }
+                else if (high)
+                {
+                    return context.ShiftRightU32(src, Const(16));
+                }
+                else
+                {
+                    return context.BitwiseAnd(src, Const(0xffff));
+                }
+            }
+
+            srcA = Extend16To32(srcA, highA, signedA);
+            srcB = Extend16To32(srcB, highB, signedB);
+
+            Operand res = context.IMultiply(srcA, srcB);
+
+            if (productShiftLeft)
+            {
+                res = context.ShiftLeft(res, Const(16));
+            }
+
+            switch (mode)
+            {
+                case XmadCop.Cfull:
+                    break;
+
+                case XmadCop.Clo:
+                    srcC = Extend16To32(srcC, high: false, signed: false);
+                    break;
+                case XmadCop.Chi:
+                    srcC = Extend16To32(srcC, high: true, signed: false);
+                    break;
+
+                case XmadCop.Cbcc:
+                    srcC = context.IAdd(srcC, context.ShiftLeft(srcBUnmodified, Const(16)));
+                    break;
+
+                case XmadCop.Csfu:
+                    Operand signAdjustA = context.ShiftLeft(context.ShiftRightU32(srcA, Const(31)), Const(16));
+                    Operand signAdjustB = context.ShiftLeft(context.ShiftRightU32(srcB, Const(31)), Const(16));
+
+                    srcC = context.ISubtract(srcC, context.IAdd(signAdjustA, signAdjustB));
+                    break;
+
+                default:
+                    context.Config.GpuAccessor.Log($"Invalid XMAD mode \"{mode}\".");
+                    return;
+            }
+
+            Operand product = res;
+
+            if (extended)
+            {
+                // Add with carry.
+                res = context.IAdd(res, context.BitwiseAnd(GetCF(), Const(1)));
+            }
+            else
+            {
+                // Add (no carry in).
+                res = context.IAdd(res, srcC);
+            }
+
+            SetIaddFlags(context, res, product, srcC, writeCC, extended);
+
+            if (merge)
+            {
+                res = context.BitwiseAnd(res, Const(0xffff));
+                res = context.BitwiseOr(res, context.ShiftLeft(srcBUnmodified, Const(16)));
+            }
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void SetIaddFlags(EmitterContext context, Operand res, Operand srcA, Operand srcB, bool setCC, bool extended)
+        {
+            if (!setCC)
+            {
+                return;
+            }
+
+            if (extended)
+            {
+                // C = (d == a && CIn) || d < a
+                Operand tempC0 = context.ICompareEqual(res, srcA);
+                Operand tempC1 = context.ICompareLessUnsigned(res, srcA);
+
+                tempC0 = context.BitwiseAnd(tempC0, GetCF());
+
+                context.Copy(GetCF(), context.BitwiseOr(tempC0, tempC1));
+            }
+            else
+            {
+                // C = d < a
+                context.Copy(GetCF(), context.ICompareLessUnsigned(res, srcA));
+            }
+
+            // V = (d ^ a) & ~(a ^ b) < 0
+            Operand tempV0 = context.BitwiseExclusiveOr(res, srcA);
+            Operand tempV1 = context.BitwiseExclusiveOr(srcA, srcB);
+
+            tempV1 = context.BitwiseNot(tempV1);
+
+            Operand tempV = context.BitwiseAnd(tempV0, tempV1);
+
+            context.Copy(GetVF(), context.ICompareLess(tempV, Const(0)));
+
+            SetZnFlags(context, res, setCC: true, extended: extended);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs
new file mode 100644
index 0000000000..ddd90f8e81
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerComparison.cs
@@ -0,0 +1,327 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+using System;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void Csetp(EmitterContext context)
+        {
+            InstCsetp op = context.GetOp<InstCsetp>();
+
+            // TODO: Implement that properly.
+
+            Operand p0Res = Const(IrConsts.True);
+            Operand p1Res = context.BitwiseNot(p0Res);
+            Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            p0Res = GetPredLogicalOp(context, op.Bop, p0Res, srcPred);
+            p1Res = GetPredLogicalOp(context, op.Bop, p1Res, srcPred);
+
+            context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res);
+            context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res);
+        }
+
+        public static void IcmpR(EmitterContext context)
+        {
+            InstIcmpR op = context.GetOp<InstIcmpR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
+        }
+
+        public static void IcmpI(EmitterContext context)
+        {
+            InstIcmpI op = context.GetOp<InstIcmpI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
+        }
+
+        public static void IcmpC(EmitterContext context)
+        {
+            InstIcmpC op = context.GetOp<InstIcmpC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
+        }
+
+        public static void IcmpRc(EmitterContext context)
+        {
+            InstIcmpRc op = context.GetOp<InstIcmpRc>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcC);
+            var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitIcmp(context, op.IComp, srcA, srcB, srcC, op.Dest, op.Signed);
+        }
+
+        public static void IsetR(EmitterContext context)
+        {
+            InstIsetR op = context.GetOp<InstIsetR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
+        }
+
+        public static void IsetI(EmitterContext context)
+        {
+            InstIsetI op = context.GetOp<InstIsetI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
+        }
+
+        public static void IsetC(EmitterContext context)
+        {
+            InstIsetC op = context.GetOp<InstIsetC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitIset(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.Dest, op.BVal, op.Signed, op.X, op.WriteCC);
+        }
+
+        public static void IsetpR(EmitterContext context)
+        {
+            InstIsetpR op = context.GetOp<InstIsetpR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
+        }
+
+        public static void IsetpI(EmitterContext context)
+        {
+            InstIsetpI op = context.GetOp<InstIsetpI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
+        }
+
+        public static void IsetpC(EmitterContext context)
+        {
+            InstIsetpC op = context.GetOp<InstIsetpC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitIsetp(context, op.IComp, op.Bop, srcA, srcB, op.SrcPred, op.SrcPredInv, op.DestPred, op.DestPredInv, op.Signed, op.X);
+        }
+
+        private static void EmitIcmp(
+            EmitterContext context,
+            IComp cmpOp,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            int rd,
+            bool isSigned)
+        {
+            Operand cmpRes = GetIntComparison(context, cmpOp, srcC, Const(0), isSigned);
+
+            Operand res = context.ConditionalSelect(cmpRes, srcA, srcB);
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void EmitIset(
+            EmitterContext context,
+            IComp cmpOp,
+            BoolOp logicOp,
+            Operand srcA,
+            Operand srcB,
+            int srcPred,
+            bool srcPredInv,
+            int rd,
+            bool boolFloat,
+            bool isSigned,
+            bool extended,
+            bool writeCC)
+        {
+            Operand res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned, extended);
+            Operand pred = GetPredicate(context, srcPred, srcPredInv);
+
+            res = GetPredLogicalOp(context, logicOp, res, pred);
+
+            Operand dest = GetDest(rd);
+
+            if (boolFloat)
+            {
+                res = context.ConditionalSelect(res, ConstF(1), Const(0));
+
+                context.Copy(dest, res);
+
+                SetFPZnFlags(context, res, writeCC);
+            }
+            else
+            {
+                context.Copy(dest, res);
+
+                SetZnFlags(context, res, writeCC, extended);
+            }
+        }
+
+        private static void EmitIsetp(
+            EmitterContext context,
+            IComp cmpOp,
+            BoolOp logicOp,
+            Operand srcA,
+            Operand srcB,
+            int srcPred,
+            bool srcPredInv,
+            int destPred,
+            int destPredInv,
+            bool isSigned,
+            bool extended)
+        {
+            Operand p0Res = GetIntComparison(context, cmpOp, srcA, srcB, isSigned, extended);
+            Operand p1Res = context.BitwiseNot(p0Res);
+            Operand pred = GetPredicate(context, srcPred, srcPredInv);
+
+            p0Res = GetPredLogicalOp(context, logicOp, p0Res, pred);
+            p1Res = GetPredLogicalOp(context, logicOp, p1Res, pred);
+
+            context.Copy(Register(destPred, RegisterType.Predicate), p0Res);
+            context.Copy(Register(destPredInv, RegisterType.Predicate), p1Res);
+        }
+
+        private static Operand GetIntComparison(
+            EmitterContext context,
+            IComp cond,
+            Operand srcA,
+            Operand srcB,
+            bool isSigned,
+            bool extended)
+        {
+            return extended
+                ? GetIntComparisonExtended(context, cond, srcA, srcB, isSigned)
+                : GetIntComparison(context, cond, srcA, srcB, isSigned);
+        }
+
+        private static Operand GetIntComparisonExtended(EmitterContext context, IComp cond, Operand srcA, Operand srcB, bool isSigned)
+        {
+            Operand res;
+
+            if (cond == IComp.T)
+            {
+                res = Const(IrConsts.True);
+            }
+            else if (cond == IComp.F)
+            {
+                res = Const(IrConsts.False);
+            }
+            else
+            {
+                res = context.ISubtract(srcA, srcB);
+                res = context.IAdd(res, context.BitwiseNot(GetCF()));
+
+                switch (cond)
+                {
+                    case IComp.Eq: // r = xh == yh && xl == yl
+                        res = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), GetZF());
+                        break;
+                    case IComp.Lt: // r = xh < yh || (xh == yh && xl < yl)
+                        Operand notC = context.BitwiseNot(GetCF());
+                        Operand prevLt = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), notC);
+                        res = isSigned
+                            ? context.BitwiseOr(context.ICompareLess(srcA, srcB), prevLt)
+                            : context.BitwiseOr(context.ICompareLessUnsigned(srcA, srcB), prevLt);
+                        break;
+                    case IComp.Le: // r = xh < yh || (xh == yh && xl <= yl)
+                        Operand zOrNotC = context.BitwiseOr(GetZF(), context.BitwiseNot(GetCF()));
+                        Operand prevLe = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), zOrNotC);
+                        res = isSigned
+                            ? context.BitwiseOr(context.ICompareLess(srcA, srcB), prevLe)
+                            : context.BitwiseOr(context.ICompareLessUnsigned(srcA, srcB), prevLe);
+                        break;
+                    case IComp.Gt: // r = xh > yh || (xh == yh && xl > yl)
+                        Operand notZAndC = context.BitwiseAnd(context.BitwiseNot(GetZF()), GetCF());
+                        Operand prevGt = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), notZAndC);
+                        res = isSigned
+                            ? context.BitwiseOr(context.ICompareGreater(srcA, srcB), prevGt)
+                            : context.BitwiseOr(context.ICompareGreaterUnsigned(srcA, srcB), prevGt);
+                        break;
+                    case IComp.Ge: // r = xh > yh || (xh == yh && xl >= yl)
+                        Operand prevGe = context.BitwiseAnd(context.ICompareEqual(srcA, srcB), GetCF());
+                        res = isSigned
+                            ? context.BitwiseOr(context.ICompareGreater(srcA, srcB), prevGe)
+                            : context.BitwiseOr(context.ICompareGreaterUnsigned(srcA, srcB), prevGe);
+                        break;
+                    case IComp.Ne: // r = xh != yh || xl != yl
+                        res = context.BitwiseOr(context.ICompareNotEqual(srcA, srcB), context.BitwiseNot(GetZF()));
+                        break;
+                    default:
+                        throw new ArgumentException($"Unexpected condition \"{cond}\".");
+                }
+            }
+
+            return res;
+        }
+
+        private static Operand GetIntComparison(EmitterContext context, IComp cond, Operand srcA, Operand srcB, bool isSigned)
+        {
+            Operand res;
+
+            if (cond == IComp.T)
+            {
+                res = Const(IrConsts.True);
+            }
+            else if (cond == IComp.F)
+            {
+                res = Const(IrConsts.False);
+            }
+            else
+            {
+                var inst = cond switch
+                {
+                    IComp.Lt => Instruction.CompareLessU32,
+                    IComp.Eq => Instruction.CompareEqual,
+                    IComp.Le => Instruction.CompareLessOrEqualU32,
+                    IComp.Gt => Instruction.CompareGreaterU32,
+                    IComp.Ne => Instruction.CompareNotEqual,
+                    IComp.Ge => Instruction.CompareGreaterOrEqualU32,
+                    _ => throw new InvalidOperationException($"Unexpected condition \"{cond}\".")
+                };
+
+                if (isSigned)
+                {
+                    switch (cond)
+                    {
+                        case IComp.Lt: inst = Instruction.CompareLess; break;
+                        case IComp.Le: inst = Instruction.CompareLessOrEqual; break;
+                        case IComp.Gt: inst = Instruction.CompareGreater; break;
+                        case IComp.Ge: inst = Instruction.CompareGreaterOrEqual; break;
+                    }
+                }
+
+                res = context.Add(inst, Local(), srcA, srcB);
+            }
+
+            return res;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerLogical.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerLogical.cs
new file mode 100644
index 0000000000..1f3f66ae48
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerLogical.cs
@@ -0,0 +1,167 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        private const int PT = RegisterConsts.PredicateTrueIndex;
+
+        public static void LopR(EmitterContext context)
+        {
+            InstLopR op = context.GetOp<InstLopR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitLop(context, op.Lop, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
+        }
+
+        public static void LopI(EmitterContext context)
+        {
+            InstLopI op = context.GetOp<InstLopI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
+        }
+
+        public static void LopC(EmitterContext context)
+        {
+            InstLopC op = context.GetOp<InstLopC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
+        }
+
+        public static void Lop32i(EmitterContext context)
+        {
+            InstLop32i op = context.GetOp<InstLop32i>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, op.Imm32);
+
+            EmitLop(context, op.LogicOp, PredicateOp.F, srcA, srcB, op.Dest, PT, op.NegA, op.NegB, op.X, op.WriteCC);
+        }
+
+        public static void Lop3R(EmitterContext context)
+        {
+            InstLop3R op = context.GetOp<InstLop3R>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitLop3(context, op.Imm, op.PredicateOp, srcA, srcB, srcC, op.Dest, op.DestPred, op.X, op.WriteCC);
+        }
+
+        public static void Lop3I(EmitterContext context)
+        {
+            InstLop3I op = context.GetOp<InstLop3I>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
+        }
+
+        public static void Lop3C(EmitterContext context)
+        {
+            InstLop3C op = context.GetOp<InstLop3C>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcC = GetSrcReg(context, op.SrcC);
+
+            EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
+        }
+
+        private static void EmitLop(
+            EmitterContext context,
+            LogicOp logicOp,
+            PredicateOp predOp,
+            Operand srcA,
+            Operand srcB,
+            int rd,
+            int destPred,
+            bool invertA,
+            bool invertB,
+            bool extended,
+            bool writeCC)
+        {
+            srcA = context.BitwiseNot(srcA, invertA);
+            srcB = context.BitwiseNot(srcB, invertB);
+
+            Operand res = logicOp switch
+            {
+                LogicOp.And => res = context.BitwiseAnd(srcA, srcB),
+                LogicOp.Or => res = context.BitwiseOr(srcA, srcB),
+                LogicOp.Xor => res = context.BitwiseExclusiveOr(srcA, srcB),
+                _ => srcB
+            };
+
+            EmitLopPredWrite(context, res, predOp, destPred);
+
+            context.Copy(GetDest(rd), res);
+
+            SetZnFlags(context, res, writeCC, extended);
+        }
+
+        private static void EmitLop3(
+            EmitterContext context,
+            int truthTable,
+            PredicateOp predOp,
+            Operand srcA,
+            Operand srcB,
+            Operand srcC,
+            int rd,
+            int destPred,
+            bool extended,
+            bool writeCC)
+        {
+            Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable);
+
+            EmitLopPredWrite(context, res, predOp, destPred);
+
+            context.Copy(GetDest(rd), res);
+
+            SetZnFlags(context, res, writeCC, extended);
+        }
+
+        private static void EmitLopPredWrite(EmitterContext context, Operand result, PredicateOp predOp, int pred)
+        {
+            if (pred != RegisterConsts.PredicateTrueIndex)
+            {
+                Operand pRes;
+
+                if (predOp == PredicateOp.F)
+                {
+                    pRes = Const(IrConsts.False);
+                }
+                else if (predOp == PredicateOp.T)
+                {
+                    pRes = Const(IrConsts.True);
+                }
+                else if (predOp == PredicateOp.Z)
+                {
+                    pRes = context.ICompareEqual(result, Const(0));
+                }
+                else /* if (predOp == Pop.Nz) */
+                {
+                    pRes = context.ICompareNotEqual(result, Const(0));
+                }
+
+                context.Copy(Register(pred, RegisterType.Predicate), pRes);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerMinMax.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerMinMax.cs
new file mode 100644
index 0000000000..73930ed1fa
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitIntegerMinMax.cs
@@ -0,0 +1,71 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void ImnmxR(EmitterContext context)
+        {
+            InstImnmxR op = context.GetOp<InstImnmxR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+            var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
+        }
+
+        public static void ImnmxI(EmitterContext context)
+        {
+            InstImnmxI op = context.GetOp<InstImnmxI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+            var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
+        }
+
+        public static void ImnmxC(EmitterContext context)
+        {
+            InstImnmxC op = context.GetOp<InstImnmxC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            EmitImnmx(context, srcA, srcB, srcPred, op.Dest, op.Signed, op.WriteCC);
+        }
+
+        private static void EmitImnmx(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            Operand srcPred,
+            int rd,
+            bool isSignedInt,
+            bool writeCC)
+        {
+            Operand resMin = isSignedInt
+                ? context.IMinimumS32(srcA, srcB)
+                : context.IMinimumU32(srcA, srcB);
+
+            Operand resMax = isSignedInt
+                ? context.IMaximumS32(srcA, srcB)
+                : context.IMaximumU32(srcA, srcB);
+
+            Operand res = context.ConditionalSelect(srcPred, resMin, resMax);
+
+            context.Copy(GetDest(rd), res);
+
+            SetZnFlags(context, res, writeCC);
+
+            // TODO: X flags.
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index 6744a9e897..78f41e8e4e 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -15,369 +15,160 @@ namespace Ryujinx.Graphics.Shader.Instructions
             Shared
         }
 
-        public static void Al2p(EmitterContext context)
-        {
-            OpCodeAl2p op = (OpCodeAl2p)context.CurrOp;
-
-            if (op.Rd.IsRZ)
-            {
-                return;
-            }
-
-            context.Copy(Register(op.Rd), context.IAdd(Register(op.Ra), Const(op.Immediate)));
-        }
-
-        public static void Ald(EmitterContext context)
-        {
-            OpCodeAttribute op = (OpCodeAttribute)context.CurrOp;
-
-            Operand primVertex = context.Copy(GetSrcC(context));
-
-            for (int index = 0; index < op.Count; index++)
-            {
-                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
-
-                if (rd.IsRZ)
-                {
-                    break;
-                }
-
-                if (op.Phys)
-                {
-                    Operand userAttrOffset = context.ISubtract(GetSrcA(context), Const(AttributeConsts.UserAttributeBase));
-                    Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
-
-                    context.Copy(Register(rd), context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, primVertex));
-
-                    context.Config.SetUsedFeature(FeatureFlags.IaIndexing);
-                }
-                else if (op.Rc.IsRZ)
-                {
-                    Operand src = Attribute(op.AttributeOffset + index * 4);
-
-                    context.FlagAttributeRead(src.Value);
-
-                    context.Copy(Register(rd), src);
-                }
-                else
-                {
-                    Operand src = Const(op.AttributeOffset + index * 4);
-
-                    context.FlagAttributeRead(src.Value);
-
-                    context.Copy(Register(rd), context.LoadAttribute(src, Const(0), primVertex));
-                }
-            }
-        }
-
-        public static void Ast(EmitterContext context)
-        {
-            OpCodeAttribute op = (OpCodeAttribute)context.CurrOp;
-
-            for (int index = 0; index < op.Count; index++)
-            {
-                if (op.Rd.Index + index > RegisterConsts.RegisterZeroIndex)
-                {
-                    break;
-                }
-
-                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
-
-                if (op.Phys)
-                {
-                    Operand userAttrOffset = context.ISubtract(GetSrcA(context), Const(AttributeConsts.UserAttributeBase));
-                    Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
-
-                    context.StoreAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Register(rd));
-
-                    context.Config.SetUsedFeature(FeatureFlags.OaIndexing);
-                }
-                else
-                {
-                    Operand dest = Attribute(op.AttributeOffset + index * 4);
-
-                    context.FlagAttributeWritten(dest.Value);
-
-                    context.Copy(dest, Register(rd));
-                }
-            }
-        }
-
         public static void Atom(EmitterContext context)
         {
-            OpCodeAtom op = (OpCodeAtom)context.CurrOp;
+            InstAtom op = context.GetOp<InstAtom>();
 
-            ReductionType type = (ReductionType)op.RawOpCode.Extract(49, 2);
+            int sOffset = (op.Imm20 << 12) >> 12;
 
-            int sOffset = (op.RawOpCode.Extract(28, 20) << 12) >> 12;
+            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, new Register(op.SrcA, RegisterType.Gpr), op.E, sOffset);
 
-            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, op.Ra, op.Extended, sOffset);
+            Operand value = GetSrcReg(context, op.SrcB);
 
-            Operand value = GetSrcB(context);
+            Operand res = EmitAtomicOp(context, Instruction.MrGlobal, op.Op, op.Size, addrLow, addrHigh, value);
 
-            Operand res = EmitAtomicOp(
-                context,
-                Instruction.MrGlobal,
-                op.AtomicOp,
-                type,
-                addrLow,
-                addrHigh,
-                value);
-
-            context.Copy(GetDest(context), res);
+            context.Copy(GetDest(op.Dest), res);
         }
 
         public static void Atoms(EmitterContext context)
         {
-            OpCodeAtom op = (OpCodeAtom)context.CurrOp;
+            InstAtoms op = context.GetOp<InstAtoms>();
 
-            ReductionType type = op.RawOpCode.Extract(28, 2) switch
-            {
-                0 => ReductionType.U32,
-                1 => ReductionType.S32,
-                2 => ReductionType.U64,
-                _ => ReductionType.S64
-            };
+            Operand offset = context.ShiftRightU32(GetSrcReg(context, op.SrcA), Const(2));
 
-            Operand offset = context.ShiftRightU32(GetSrcA(context), Const(2));
-
-            int sOffset = (op.RawOpCode.Extract(30, 22) << 10) >> 10;
+            int sOffset = (op.Imm22 << 10) >> 10;
 
             offset = context.IAdd(offset, Const(sOffset));
 
-            Operand value = GetSrcB(context);
+            Operand value = GetSrcReg(context, op.SrcB);
 
-            Operand res = EmitAtomicOp(
-                context,
-                Instruction.MrShared,
-                op.AtomicOp,
-                type,
-                offset,
-                Const(0),
-                value);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Bar(EmitterContext context)
-        {
-            OpCodeBarrier op = (OpCodeBarrier)context.CurrOp;
-
-            // TODO: Support other modes.
-            if (op.Mode == BarrierMode.Sync)
+            AtomSize size = op.AtomsSize switch
             {
-                context.Barrier();
-            }
-            else
-            {
-                context.Config.GpuAccessor.Log($"Invalid barrier mode: {op.Mode}.");
-            }
-        }
+                AtomsSize.S32 => AtomSize.S32,
+                AtomsSize.U64 => AtomSize.U64,
+                AtomsSize.S64 => AtomSize.S64,
+                _ => AtomSize.U32
+            };
 
-        public static void Ipa(EmitterContext context)
-        {
-            OpCodeIpa op = (OpCodeIpa)context.CurrOp;
+            Operand res = EmitAtomicOp(context, Instruction.MrShared, op.AtomOp, size, offset, Const(0), value);
 
-            context.FlagAttributeRead(op.AttributeOffset);
-
-            Operand res;
-
-            if (op.Idx)
-            {
-                Operand userAttrOffset = context.ISubtract(GetSrcA(context), Const(AttributeConsts.UserAttributeBase));
-                Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2));
-
-                res = context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Const(0));
-                res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW));
-
-                context.Config.SetUsedFeature(FeatureFlags.IaIndexing);
-            }
-            else
-            {
-                res = Attribute(op.AttributeOffset);
-
-                if (op.AttributeOffset >= AttributeConsts.UserAttributeBase &&
-                    op.AttributeOffset <  AttributeConsts.UserAttributeEnd)
-                {
-                    int index = (op.AttributeOffset - AttributeConsts.UserAttributeBase) >> 4;
-
-                    if (context.Config.ImapTypes[index].GetFirstUsedType() == PixelImap.Perspective)
-                    {
-                        res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW));
-                    }
-                }
-            }
-
-            if (op.Mode == InterpolationMode.Default)
-            {
-                Operand srcB = GetSrcB(context);
-
-                res = context.FPMultiply(res, srcB);
-            }
-
-            res = context.FPSaturate(res, op.Saturate);
-
-            context.Copy(GetDest(context), res);
-        }
-
-        public static void Isberd(EmitterContext context)
-        {
-            // This instruction performs a load from ISBE memory,
-            // however it seems to be only used to get some vertex
-            // input data, so we instead propagate the offset so that
-            // it can be used on the attribute load.
-            context.Copy(GetDest(context), GetSrcA(context));
-        }
-
-        public static void Ld(EmitterContext context)
-        {
-            EmitLoad(context, MemoryRegion.Local);
+            context.Copy(GetDest(op.Dest), res);
         }
 
         public static void Ldc(EmitterContext context)
         {
-            OpCodeLdc op = (OpCodeLdc)context.CurrOp;
+            InstLdc op = context.GetOp<InstLdc>();
 
-            if (op.Size > IntegerSize.B64)
+            if (op.LsSize > LsSize2.B64)
             {
-                context.Config.GpuAccessor.Log($"Invalid LDC size: {op.Size}.");
+                context.Config.GpuAccessor.Log($"Invalid LDC size: {op.LsSize}.");
+                return;
             }
 
-            bool isSmallInt = op.Size < IntegerSize.B32;
+            bool isSmallInt = op.LsSize < LsSize2.B32;
 
-            int count = op.Size == IntegerSize.B64 ? 2 : 1;
+            int count = op.LsSize == LsSize2.B64 ? 2 : 1;
 
-            Operand slot = Const(op.Slot);
-            Operand srcA = GetSrcA(context);
+            Operand slot = Const(op.CbufSlot);
+            Operand srcA = GetSrcReg(context, op.SrcA);
 
-            if (op.IndexMode == CbIndexMode.Is ||
-                op.IndexMode == CbIndexMode.Isl)
+            if (op.AddressMode == AddressMode.Is || op.AddressMode == AddressMode.Isl)
             {
                 slot = context.IAdd(slot, context.BitfieldExtractU32(srcA, Const(16), Const(16)));
                 srcA = context.BitwiseAnd(srcA, Const(0xffff));
             }
 
-            Operand addr = context.IAdd(srcA, Const(op.Offset));
-
+            Operand addr = context.IAdd(srcA, Const(Imm16ToSInt(op.CbufOffset)));
             Operand wordOffset = context.ShiftRightU32(addr, Const(2));
-
             Operand bitOffset = GetBitOffset(context, addr);
 
             for (int index = 0; index < count; index++)
             {
-                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
+                Register dest = new Register(op.Dest + index, RegisterType.Gpr);
 
-                if (rd.IsRZ)
+                if (dest.IsRZ)
                 {
                     break;
                 }
 
                 Operand offset = context.IAdd(wordOffset, Const(index));
-
                 Operand value = context.LoadConstant(slot, offset);
 
                 if (isSmallInt)
                 {
-                    value = ExtractSmallInt(context, op.Size, bitOffset, value);
+                    value = ExtractSmallInt(context, (LsSize)op.LsSize, bitOffset, value);
                 }
 
-                context.Copy(Register(rd), value);
+                context.Copy(Register(dest), value);
             }
         }
 
         public static void Ldg(EmitterContext context)
         {
-            EmitLoadGlobal(context);
+            InstLdg op = context.GetOp<InstLdg>();
+
+            EmitLdg(context, op.LsSize, op.SrcA, op.Dest, Imm24ToSInt(op.Imm24), op.E);
+        }
+
+        public static void Ldl(EmitterContext context)
+        {
+            InstLdl op = context.GetOp<InstLdl>();
+
+            EmitLoad(context, MemoryRegion.Local, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
         }
 
         public static void Lds(EmitterContext context)
         {
-            EmitLoad(context, MemoryRegion.Shared);
-        }
+            InstLds op = context.GetOp<InstLds>();
 
-        public static void Membar(EmitterContext context)
-        {
-            OpCodeMemoryBarrier op = (OpCodeMemoryBarrier)context.CurrOp;
-
-            if (op.Level == BarrierLevel.Cta)
-            {
-                context.GroupMemoryBarrier();
-            }
-            else
-            {
-                context.MemoryBarrier();
-            }
-        }
-
-        public static void Out(EmitterContext context)
-        {
-            OpCode op = context.CurrOp;
-
-            bool emit = op.RawOpCode.Extract(39);
-            bool cut  = op.RawOpCode.Extract(40);
-
-            if (!(emit || cut))
-            {
-                context.Config.GpuAccessor.Log("Invalid OUT encoding.");
-            }
-
-            if (emit)
-            {
-                context.EmitVertex();
-            }
-
-            if (cut)
-            {
-                context.EndPrimitive();
-            }
+            EmitLoad(context, MemoryRegion.Shared, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
         }
 
         public static void Red(EmitterContext context)
         {
-            OpCodeRed op = (OpCodeRed)context.CurrOp;
+            InstRed op = context.GetOp<InstRed>();
 
-            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, op.Ra, op.Extended, op.Offset);
+            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, new Register(op.SrcA, RegisterType.Gpr), op.E, op.Imm20);
 
-            EmitAtomicOp(
-                context,
-                Instruction.MrGlobal,
-                op.AtomicOp,
-                op.Type,
-                addrLow,
-                addrHigh,
-                GetDest(context));
-        }
-
-        public static void St(EmitterContext context)
-        {
-            EmitStore(context, MemoryRegion.Local);
+            EmitAtomicOp(context, Instruction.MrGlobal, (AtomOp)op.RedOp, op.RedSize, addrLow, addrHigh, GetDest(op.SrcB));
         }
 
         public static void Stg(EmitterContext context)
         {
-            EmitStoreGlobal(context);
+            InstStg op = context.GetOp<InstStg>();
+
+            EmitStg(context, op.LsSize, op.SrcA, op.Dest, Imm24ToSInt(op.Imm24), op.E);
+        }
+
+        public static void Stl(EmitterContext context)
+        {
+            InstStl op = context.GetOp<InstStl>();
+
+            EmitStore(context, MemoryRegion.Local, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
         }
 
         public static void Sts(EmitterContext context)
         {
-            EmitStore(context, MemoryRegion.Shared);
+            InstSts op = context.GetOp<InstSts>();
+
+            EmitStore(context, MemoryRegion.Shared, op.LsSize, GetSrcReg(context, op.SrcA), op.Dest, Imm24ToSInt(op.Imm24));
         }
 
         private static Operand EmitAtomicOp(
             EmitterContext context,
-            Instruction    mr,
-            AtomicOp       op,
-            ReductionType  type,
-            Operand        addrLow,
-            Operand        addrHigh,
-            Operand        value)
+            Instruction mr,
+            AtomOp op,
+            AtomSize type,
+            Operand addrLow,
+            Operand addrHigh,
+            Operand value)
         {
             Operand res = Const(0);
 
             switch (op)
             {
-                case AtomicOp.Add:
-                    if (type == ReductionType.S32 || type == ReductionType.U32)
+                case AtomOp.Add:
+                    if (type == AtomSize.S32 || type == AtomSize.U32)
                     {
                         res = context.AtomicAdd(mr, addrLow, addrHigh, value);
                     }
@@ -386,8 +177,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomicOp.BitwiseAnd:
-                    if (type == ReductionType.S32 || type == ReductionType.U32)
+                case AtomOp.And:
+                    if (type == AtomSize.S32 || type == AtomSize.U32)
                     {
                         res = context.AtomicAnd(mr, addrLow, addrHigh, value);
                     }
@@ -396,8 +187,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomicOp.BitwiseExclusiveOr:
-                    if (type == ReductionType.S32 || type == ReductionType.U32)
+                case AtomOp.Xor:
+                    if (type == AtomSize.S32 || type == AtomSize.U32)
                     {
                         res = context.AtomicXor(mr, addrLow, addrHigh, value);
                     }
@@ -406,8 +197,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomicOp.BitwiseOr:
-                    if (type == ReductionType.S32 || type == ReductionType.U32)
+                case AtomOp.Or:
+                    if (type == AtomSize.S32 || type == AtomSize.U32)
                     {
                         res = context.AtomicOr(mr, addrLow, addrHigh, value);
                     }
@@ -416,12 +207,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomicOp.Maximum:
-                    if (type == ReductionType.S32)
+                case AtomOp.Max:
+                    if (type == AtomSize.S32)
                     {
                         res = context.AtomicMaxS32(mr, addrLow, addrHigh, value);
                     }
-                    else if (type == ReductionType.U32)
+                    else if (type == AtomSize.U32)
                     {
                         res = context.AtomicMaxU32(mr, addrLow, addrHigh, value);
                     }
@@ -430,12 +221,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomicOp.Minimum:
-                    if (type == ReductionType.S32)
+                case AtomOp.Min:
+                    if (type == AtomSize.S32)
                     {
                         res = context.AtomicMinS32(mr, addrLow, addrHigh, value);
                     }
-                    else if (type == ReductionType.U32)
+                    else if (type == AtomSize.U32)
                     {
                         res = context.AtomicMinU32(mr, addrLow, addrHigh, value);
                     }
@@ -449,77 +240,82 @@ namespace Ryujinx.Graphics.Shader.Instructions
             return res;
         }
 
-        private static void EmitLoad(EmitterContext context, MemoryRegion region)
+        private static void EmitLoad(
+            EmitterContext context,
+            MemoryRegion region,
+            LsSize2 size,
+            Operand srcA,
+            int rd,
+            int offset)
         {
-            OpCodeMemory op = (OpCodeMemory)context.CurrOp;
-
-            if (op.Size > IntegerSize.B128)
+            if (size > LsSize2.B128)
             {
-                context.Config.GpuAccessor.Log($"Invalid load size: {op.Size}.");
+                context.Config.GpuAccessor.Log($"Invalid load size: {size}.");
+                return;
             }
 
-            bool isSmallInt = op.Size < IntegerSize.B32;
+            bool isSmallInt = size < LsSize2.B32;
 
             int count = 1;
 
-            switch (op.Size)
+            switch (size)
             {
-                case IntegerSize.B64:  count = 2; break;
-                case IntegerSize.B128: count = 4; break;
+                case LsSize2.B64: count = 2; break;
+                case LsSize2.B128: count = 4; break;
             }
 
-            Operand baseOffset = context.IAdd(GetSrcA(context), Const(op.Offset));
-
-            // Word offset = byte offset / 4 (one word = 4 bytes).
-            Operand wordOffset = context.ShiftRightU32(baseOffset, Const(2));
-
+            Operand baseOffset = context.IAdd(srcA, Const(offset));
+            Operand wordOffset = context.ShiftRightU32(baseOffset, Const(2)); // Word offset = byte offset / 4 (one word = 4 bytes).
             Operand bitOffset = GetBitOffset(context, baseOffset);
 
             for (int index = 0; index < count; index++)
             {
-                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
+                Register dest = new Register(rd + index, RegisterType.Gpr);
 
-                if (rd.IsRZ)
+                if (dest.IsRZ)
                 {
                     break;
                 }
 
-                Operand offset = context.IAdd(wordOffset, Const(index));
-
+                Operand elemOffset = context.IAdd(wordOffset, Const(index));
                 Operand value = null;
 
                 switch (region)
                 {
-                    case MemoryRegion.Local:  value = context.LoadLocal (offset); break;
-                    case MemoryRegion.Shared: value = context.LoadShared(offset); break;
+                    case MemoryRegion.Local: value = context.LoadLocal(elemOffset); break;
+                    case MemoryRegion.Shared: value = context.LoadShared(elemOffset); break;
                 }
 
                 if (isSmallInt)
                 {
-                    value = ExtractSmallInt(context, op.Size, bitOffset, value);
+                    value = ExtractSmallInt(context, (LsSize)size, bitOffset, value);
                 }
 
-                context.Copy(Register(rd), value);
+                context.Copy(Register(dest), value);
             }
         }
 
-        private static void EmitLoadGlobal(EmitterContext context)
+        private static void EmitLdg(
+            EmitterContext context,
+            LsSize size,
+            int ra,
+            int rd,
+            int offset,
+            bool extended)
         {
-            OpCodeMemory op = (OpCodeMemory)context.CurrOp;
+            bool isSmallInt = size < LsSize.B32;
 
-            bool isSmallInt = op.Size < IntegerSize.B32;
+            int count = GetVectorCount(size);
 
-            int count = GetVectorCount(op.Size);
-
-            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, op.Ra, op.Extended, op.Offset);
+            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, new Register(ra, RegisterType.Gpr), extended, offset);
 
             Operand bitOffset = GetBitOffset(context, addrLow);
 
             for (int index = 0; index < count; index++)
             {
-                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
+                Register dest = new Register(rd + index, RegisterType.Gpr);
 
-                if (rd.IsRZ)
+                if (dest.IsRZ)
                 {
                     break;
                 }
@@ -528,47 +324,47 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
                 if (isSmallInt)
                 {
-                    value = ExtractSmallInt(context, op.Size, bitOffset, value);
+                    value = ExtractSmallInt(context, size, bitOffset, value);
                 }
 
-                context.Copy(Register(rd), value);
+                context.Copy(Register(dest), value);
             }
         }
 
-        private static void EmitStore(EmitterContext context, MemoryRegion region)
+        private static void EmitStore(
+            EmitterContext context,
+            MemoryRegion region,
+            LsSize2 size,
+            Operand srcA,
+            int rd,
+            int offset)
         {
-            OpCodeMemory op = (OpCodeMemory)context.CurrOp;
-
-            if (op.Size > IntegerSize.B128)
+            if (size > LsSize2.B128)
             {
-                context.Config.GpuAccessor.Log($"Invalid store size: {op.Size}.");
+                context.Config.GpuAccessor.Log($"Invalid store size: {size}.");
+                return;
             }
 
-            bool isSmallInt = op.Size < IntegerSize.B32;
+            bool isSmallInt = size < LsSize2.B32;
 
             int count = 1;
 
-            switch (op.Size)
+            switch (size)
             {
-                case IntegerSize.B64:  count = 2; break;
-                case IntegerSize.B128: count = 4; break;
+                case LsSize2.B64: count = 2; break;
+                case LsSize2.B128: count = 4; break;
             }
 
-            Operand baseOffset = context.IAdd(GetSrcA(context), Const(op.Offset));
-
+            Operand baseOffset = context.IAdd(srcA, Const(offset));
             Operand wordOffset = context.ShiftRightU32(baseOffset, Const(2));
-
             Operand bitOffset = GetBitOffset(context, baseOffset);
 
             for (int index = 0; index < count; index++)
             {
-                bool isRz = op.Rd.IsRZ;
+                bool isRz = rd + index >= RegisterConsts.RegisterZeroIndex;
 
-                Register rd = new Register(isRz ? op.Rd.Index : op.Rd.Index + index, RegisterType.Gpr);
-
-                Operand value = Register(rd);
-
-                Operand offset = context.IAdd(wordOffset, Const(index));
+                Operand value = Register(isRz ? rd : rd + index, RegisterType.Gpr);
+                Operand elemOffset = context.IAdd(wordOffset, Const(index));
 
                 if (isSmallInt)
                 {
@@ -576,60 +372,68 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
                     switch (region)
                     {
-                        case MemoryRegion.Local:  word = context.LoadLocal (offset); break;
-                        case MemoryRegion.Shared: word = context.LoadShared(offset); break;
+                        case MemoryRegion.Local: word = context.LoadLocal(elemOffset); break;
+                        case MemoryRegion.Shared: word = context.LoadShared(elemOffset); break;
                     }
 
-                    value = InsertSmallInt(context, op.Size, bitOffset, word, value);
+                    value = InsertSmallInt(context, (LsSize)size, bitOffset, word, value);
                 }
 
                 switch (region)
                 {
-                    case MemoryRegion.Local:  context.StoreLocal (offset, value); break;
-                    case MemoryRegion.Shared: context.StoreShared(offset, value); break;
+                    case MemoryRegion.Local: context.StoreLocal(elemOffset, value); break;
+                    case MemoryRegion.Shared: context.StoreShared(elemOffset, value); break;
                 }
             }
         }
 
-        private static void EmitStoreGlobal(EmitterContext context)
+        private static void EmitStg(
+            EmitterContext context,
+            LsSize2 size,
+            int ra,
+            int rd,
+            int offset,
+            bool extended)
         {
-            OpCodeMemory op = (OpCodeMemory)context.CurrOp;
+            if (size > LsSize2.B128)
+            {
+                context.Config.GpuAccessor.Log($"Invalid store size: {size}.");
+                return;
+            }
 
-            bool isSmallInt = op.Size < IntegerSize.B32;
+            bool isSmallInt = size < LsSize2.B32;
 
-            int count = GetVectorCount(op.Size);
+            int count = GetVectorCount((LsSize)size);
 
-            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, op.Ra, op.Extended, op.Offset);
+            (Operand addrLow, Operand addrHigh) = Get40BitsAddress(context, new Register(ra, RegisterType.Gpr), extended, offset);
 
             Operand bitOffset = GetBitOffset(context, addrLow);
 
             for (int index = 0; index < count; index++)
             {
-                bool isRz = op.Rd.IsRZ;
+                bool isRz = rd + index >= RegisterConsts.RegisterZeroIndex;
 
-                Register rd = new Register(isRz ? op.Rd.Index : op.Rd.Index + index, RegisterType.Gpr);
-
-                Operand value = Register(rd);
+                Operand value = Register(isRz ? rd : rd + index, RegisterType.Gpr);
 
                 if (isSmallInt)
                 {
                     Operand word = context.LoadGlobal(addrLow, addrHigh);
 
-                    value = InsertSmallInt(context, op.Size, bitOffset, word, value);
+                    value = InsertSmallInt(context, (LsSize)size, bitOffset, word, value);
                 }
 
                 context.StoreGlobal(context.IAdd(addrLow, Const(index * 4)), addrHigh, value);
             }
         }
 
-        private static int GetVectorCount(IntegerSize size)
+        private static int GetVectorCount(LsSize size)
         {
             switch (size)
             {
-                case IntegerSize.B64:
+                case LsSize.B64:
                     return 2;
-                case IntegerSize.B128:
-                case IntegerSize.UB128:
+                case LsSize.B128:
+                case LsSize.UB128:
                     return 4;
             }
 
@@ -642,7 +446,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
             bool extended,
             int offset)
         {
-            Operand addrLow = GetSrcA(context);
+            Operand addrLow = Register(ra);
             Operand addrHigh;
 
             if (extended && !ra.IsRZ)
@@ -678,18 +482,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
         private static Operand ExtractSmallInt(
             EmitterContext context,
-            IntegerSize    size,
-            Operand        bitOffset,
-            Operand        value)
+            LsSize size,
+            Operand bitOffset,
+            Operand value)
         {
             value = context.ShiftRightU32(value, bitOffset);
 
             switch (size)
             {
-                case IntegerSize.U8:  value = ZeroExtendTo32(context, value, 8);  break;
-                case IntegerSize.U16: value = ZeroExtendTo32(context, value, 16); break;
-                case IntegerSize.S8:  value = SignExtendTo32(context, value, 8);  break;
-                case IntegerSize.S16: value = SignExtendTo32(context, value, 16); break;
+                case LsSize.U8: value = ZeroExtendTo32(context, value, 8); break;
+                case LsSize.U16: value = ZeroExtendTo32(context, value, 16); break;
+                case LsSize.S8: value = SignExtendTo32(context, value, 8); break;
+                case LsSize.S16: value = SignExtendTo32(context, value, 16); break;
             }
 
             return value;
@@ -697,21 +501,21 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
         private static Operand InsertSmallInt(
             EmitterContext context,
-            IntegerSize    size,
-            Operand        bitOffset,
-            Operand        word,
-            Operand        value)
+            LsSize size,
+            Operand bitOffset,
+            Operand word,
+            Operand value)
         {
             switch (size)
             {
-                case IntegerSize.U8:
-                case IntegerSize.S8:
+                case LsSize.U8:
+                case LsSize.S8:
                     value = context.BitwiseAnd(value, Const(0xff));
                     value = context.BitfieldInsert(word, value, bitOffset, Const(8));
                     break;
 
-                case IntegerSize.U16:
-                case IntegerSize.S16:
+                case LsSize.U16:
+                case LsSize.S16:
                     value = context.BitwiseAnd(value, Const(0xffff));
                     value = context.BitfieldInsert(word, value, bitOffset, Const(16));
                     break;
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
index 98a713fb97..245b22536a 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
@@ -9,67 +9,85 @@ namespace Ryujinx.Graphics.Shader.Instructions
 {
     static partial class InstEmit
     {
-        public static void Mov(EmitterContext context)
+        public static void MovR(EmitterContext context)
         {
-            context.Copy(GetDest(context), GetSrcB(context));
+            InstMovR op = context.GetOp<InstMovR>();
+
+            context.Copy(GetDest(op.Dest), GetSrcReg(context, op.SrcA));
         }
 
-        public static void R2p(EmitterContext context)
+        public static void MovI(EmitterContext context)
         {
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
+            InstMovI op = context.GetOp<InstMovI>();
 
-            bool isCC  = op.RawOpCode.Extract(40);
-            int  shift = op.RawOpCode.Extract(41, 2) * 8;
+            context.Copy(GetDest(op.Dest), GetSrcImm(context, op.Imm20));
+        }
 
-            Operand value = GetSrcA(context);
-            Operand mask  = GetSrcB(context);
+        public static void MovC(EmitterContext context)
+        {
+            InstMovC op = context.GetOp<InstMovC>();
 
-            Operand Test(Operand value, int bit)
-            {
-                return context.ICompareNotEqual(context.BitwiseAnd(value, Const(1 << bit)), Const(0));
-            }
+            context.Copy(GetDest(op.Dest), GetSrcCbuf(context, op.CbufSlot, op.CbufOffset));
+        }
 
-            if (isCC)
-            {
-                // TODO: Support Register to condition code flags copy.
-                context.Config.GpuAccessor.Log("R2P.CC not implemented.");
-            }
-            else
-            {
-                for (int bit = 0; bit < 7; bit++)
-                {
-                    Operand pred = Register(bit, RegisterType.Predicate);
+        public static void Mov32i(EmitterContext context)
+        {
+            InstMov32i op = context.GetOp<InstMov32i>();
 
-                    Operand res = context.ConditionalSelect(Test(mask, bit), Test(value, bit + shift), pred);
+            context.Copy(GetDest(op.Dest), GetSrcImm(context, op.Imm32));
+        }
 
-                    context.Copy(pred, res);
-                }
-            }
+        public static void R2pR(EmitterContext context)
+        {
+            InstR2pR op = context.GetOp<InstR2pR>();
+
+            Operand value = GetSrcReg(context, op.SrcA);
+            Operand mask = GetSrcReg(context, op.SrcB);
+
+            EmitR2p(context, value, mask, op.ByteSel, op.Ccpr);
+        }
+
+        public static void R2pI(EmitterContext context)
+        {
+            InstR2pI op = context.GetOp<InstR2pI>();
+
+            Operand value = GetSrcReg(context, op.SrcA);
+            Operand mask = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitR2p(context, value, mask, op.ByteSel, op.Ccpr);
+        }
+
+        public static void R2pC(EmitterContext context)
+        {
+            InstR2pC op = context.GetOp<InstR2pC>();
+
+            Operand value = GetSrcReg(context, op.SrcA);
+            Operand mask = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitR2p(context, value, mask, op.ByteSel, op.Ccpr);
         }
 
         public static void S2r(EmitterContext context)
         {
-            // TODO: Better impl.
-            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
-            SystemRegister sysReg = (SystemRegister)op.RawOpCode.Extract(20, 8);
+            InstS2r op = context.GetOp<InstS2r>();
 
             Operand src;
 
-            switch (sysReg)
+            switch (op.SReg)
             {
-                case SystemRegister.LaneId: src = Attribute(AttributeConsts.LaneId); break;
-
-                // TODO: Use value from Y direction GPU register.
-                case SystemRegister.YDirection: src = ConstF(1); break;
-
-                case SystemRegister.ThreadKill: src = context.Config.Stage == ShaderStage.Fragment
-                    ? Attribute(AttributeConsts.ThreadKill)
-                    : Const(0);
+                case SReg.LaneId:
+                    src = Attribute(AttributeConsts.LaneId);
                     break;
 
-                case SystemRegister.ThreadId:
-                {
+                case SReg.YDirection:
+                    src = ConstF(1); // TODO: Use value from Y direction GPU register.
+                    break;
+
+                case SReg.ThreadKill:
+                    src = context.Config.Stage == ShaderStage.Fragment ? Attribute(AttributeConsts.ThreadKill) : Const(0);
+                    break;
+
+                case SReg.TId:
                     Operand tidX = Attribute(AttributeConsts.ThreadIdX);
                     Operand tidY = Attribute(AttributeConsts.ThreadIdY);
                     Operand tidZ = Attribute(AttributeConsts.ThreadIdZ);
@@ -78,62 +96,115 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     tidZ = context.ShiftLeft(tidZ, Const(26));
 
                     src = context.BitwiseOr(tidX, context.BitwiseOr(tidY, tidZ));
-
                     break;
-                }
 
-                case SystemRegister.ThreadIdX: src = Attribute(AttributeConsts.ThreadIdX); break;
-                case SystemRegister.ThreadIdY: src = Attribute(AttributeConsts.ThreadIdY); break;
-                case SystemRegister.ThreadIdZ: src = Attribute(AttributeConsts.ThreadIdZ); break;
-                case SystemRegister.CtaIdX:    src = Attribute(AttributeConsts.CtaIdX);    break;
-                case SystemRegister.CtaIdY:    src = Attribute(AttributeConsts.CtaIdY);    break;
-                case SystemRegister.CtaIdZ:    src = Attribute(AttributeConsts.CtaIdZ);    break;
-                case SystemRegister.EqMask:    src = Attribute(AttributeConsts.EqMask);    break;
-                case SystemRegister.LtMask:    src = Attribute(AttributeConsts.LtMask);    break;
-                case SystemRegister.LeMask:    src = Attribute(AttributeConsts.LeMask);    break;
-                case SystemRegister.GtMask:    src = Attribute(AttributeConsts.GtMask);    break;
-                case SystemRegister.GeMask:    src = Attribute(AttributeConsts.GeMask);    break;
+                case SReg.TIdX:
+                    src = Attribute(AttributeConsts.ThreadIdX);
+                    break;
+                case SReg.TIdY:
+                    src = Attribute(AttributeConsts.ThreadIdY);
+                    break;
+                case SReg.TIdZ:
+                    src = Attribute(AttributeConsts.ThreadIdZ);
+                    break;
 
-                default: src = Const(0); break;
+                case SReg.CtaIdX:
+                    src = Attribute(AttributeConsts.CtaIdX);
+                    break;
+                case SReg.CtaIdY:
+                    src = Attribute(AttributeConsts.CtaIdY);
+                    break;
+                case SReg.CtaIdZ:
+                    src = Attribute(AttributeConsts.CtaIdZ);
+                    break;
+
+                case SReg.EqMask:
+                    src = Attribute(AttributeConsts.EqMask);
+                    break;
+                case SReg.LtMask:
+                    src = Attribute(AttributeConsts.LtMask);
+                    break;
+                case SReg.LeMask:
+                    src = Attribute(AttributeConsts.LeMask);
+                    break;
+                case SReg.GtMask:
+                    src = Attribute(AttributeConsts.GtMask);
+                    break;
+                case SReg.GeMask:
+                    src = Attribute(AttributeConsts.GeMask);
+                    break;
+
+                default:
+                    src = Const(0);
+                    break;
             }
 
-            context.Copy(GetDest(context), src);
+            context.Copy(GetDest(op.Dest), src);
         }
 
-        public static void Sel(EmitterContext context)
+        public static void SelR(EmitterContext context)
         {
-            Operand pred = GetPredicate39(context);
+            InstSelR op = context.GetOp<InstSelR>();
 
-            Operand srcA = GetSrcA(context);
-            Operand srcB = GetSrcB(context);
+            Operand srcA = GetSrcReg(context, op.SrcA);
+            Operand srcB = GetSrcReg(context, op.SrcB);
+            Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
 
-            Operand res = context.ConditionalSelect(pred, srcA, srcB);
-
-            context.Copy(GetDest(context), res);
+            EmitSel(context, srcA, srcB, srcPred, op.Dest);
         }
 
-        public static void Shfl(EmitterContext context)
+        public static void SelI(EmitterContext context)
         {
-            OpCodeShuffle op = (OpCodeShuffle)context.CurrOp;
+            InstSelI op = context.GetOp<InstSelI>();
 
-            Operand pred = Register(op.Predicate48);
+            Operand srcA = GetSrcReg(context, op.SrcA);
+            Operand srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+            Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
 
-            Operand srcA = GetSrcA(context);
+            EmitSel(context, srcA, srcB, srcPred, op.Dest);
+        }
 
-            Operand srcB = op.IsBImmediate ? Const(op.ImmediateB) : Register(op.Rb);
-            Operand srcC = op.IsCImmediate ? Const(op.ImmediateC) : Register(op.Rc);
+        public static void SelC(EmitterContext context)
+        {
+            InstSelC op = context.GetOp<InstSelC>();
 
-            (Operand res, Operand valid) = op.ShuffleType switch
+            Operand srcA = GetSrcReg(context, op.SrcA);
+            Operand srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+            Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            EmitSel(context, srcA, srcB, srcPred, op.Dest);
+        }
+
+        private static void EmitR2p(EmitterContext context, Operand value, Operand mask, ByteSel byteSel, bool ccpr)
+        {
+            Operand Test(Operand value, int bit)
             {
-                ShuffleType.Indexed   => context.Shuffle(srcA, srcB, srcC),
-                ShuffleType.Up        => context.ShuffleUp(srcA, srcB, srcC),
-                ShuffleType.Down      => context.ShuffleDown(srcA, srcB, srcC),
-                ShuffleType.Butterfly => context.ShuffleXor(srcA, srcB, srcC),
-                _                     => (null, null)
-            };
+                return context.ICompareNotEqual(context.BitwiseAnd(value, Const(1 << bit)), Const(0));
+            }
 
-            context.Copy(GetDest(context), res);
-            context.Copy(pred, valid);
+            if (ccpr)
+            {
+                // TODO: Support Register to condition code flags copy.
+                context.Config.GpuAccessor.Log("R2P.CC not implemented.");
+            }
+            else
+            {
+                int shift = (int)byteSel * 8;
+
+                for (int bit = 0; bit < RegisterConsts.PredsCount; bit++)
+                {
+                    Operand pred = Register(bit, RegisterType.Predicate);
+                    Operand res = context.ConditionalSelect(Test(mask, bit), Test(value, bit + shift), pred);
+                    context.Copy(pred, res);
+                }
+            }
+        }
+
+        private static void EmitSel(EmitterContext context, Operand srcA, Operand srcB, Operand srcPred, int rd)
+        {
+            Operand res = context.ConditionalSelect(srcPred, srcA, srcB);
+
+            context.Copy(GetDest(rd), res);
         }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMultifunction.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMultifunction.cs
new file mode 100644
index 0000000000..465024eb71
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMultifunction.cs
@@ -0,0 +1,85 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void RroR(EmitterContext context)
+        {
+            InstRroR op = context.GetOp<InstRroR>();
+
+            EmitRro(context, GetSrcReg(context, op.SrcB), op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void RroI(EmitterContext context)
+        {
+            InstRroI op = context.GetOp<InstRroI>();
+
+            EmitRro(context, GetSrcImm(context, Imm20ToFloat(op.Imm20)), op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void RroC(EmitterContext context)
+        {
+            InstRroC op = context.GetOp<InstRroC>();
+
+            EmitRro(context, GetSrcCbuf(context, op.CbufSlot, op.CbufOffset), op.Dest, op.AbsB, op.NegB);
+        }
+
+        public static void Mufu(EmitterContext context)
+        {
+            InstMufu op = context.GetOp<InstMufu>();
+
+            Operand res = context.FPAbsNeg(GetSrcReg(context, op.SrcA), op.AbsA, op.NegA);
+
+            switch (op.MufuOp)
+            {
+                case MufuOp.Cos:
+                    res = context.FPCosine(res);
+                    break;
+
+                case MufuOp.Sin:
+                    res = context.FPSine(res);
+                    break;
+
+                case MufuOp.Ex2:
+                    res = context.FPExponentB2(res);
+                    break;
+
+                case MufuOp.Lg2:
+                    res = context.FPLogarithmB2(res);
+                    break;
+
+                case MufuOp.Rcp:
+                    res = context.FPReciprocal(res);
+                    break;
+
+                case MufuOp.Rsq:
+                    res = context.FPReciprocalSquareRoot(res);
+                    break;
+
+                case MufuOp.Sqrt:
+                    res = context.FPSquareRoot(res);
+                    break;
+
+                default: /* TODO */ break;
+            }
+
+            context.Copy(GetDest(op.Dest), context.FPSaturate(res, op.Sat));
+        }
+
+        private static void EmitRro(EmitterContext context, Operand srcB, int rd, bool absB, bool negB)
+        {
+            // This is the range reduction operator,
+            // we translate it as a simple move, as it
+            // should be always followed by a matching
+            // MUFU instruction.
+            srcB = context.FPAbsNeg(srcB, absB, negB);
+
+            context.Copy(GetDest(rd), srcB);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitNop.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitNop.cs
new file mode 100644
index 0000000000..0114400712
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitNop.cs
@@ -0,0 +1,15 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.Translation;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void Nop(EmitterContext context)
+        {
+            InstNop op = context.GetOp<InstNop>();
+
+            // No operation.
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitPredicate.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitPredicate.cs
new file mode 100644
index 0000000000..d605661ffb
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitPredicate.cs
@@ -0,0 +1,54 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void Pset(EmitterContext context)
+        {
+            InstPset op = context.GetOp<InstPset>();
+
+            Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv);
+            Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv);
+            Operand srcC = context.BitwiseNot(Register(op.SrcPred, RegisterType.Predicate), op.SrcPredInv);
+
+            Operand res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB);
+            res = GetPredLogicalOp(context, op.BoolOpC, res, srcC);
+
+            Operand dest = GetDest(op.Dest);
+
+            if (op.BVal)
+            {
+                context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0)));
+            }
+            else
+            {
+                context.Copy(dest, res);
+            }
+        }
+
+        public static void Psetp(EmitterContext context)
+        {
+            InstPsetp op = context.GetOp<InstPsetp>();
+
+            Operand srcA = context.BitwiseNot(Register(op.Src2Pred, RegisterType.Predicate), op.Src2PredInv);
+            Operand srcB = context.BitwiseNot(Register(op.Src1Pred, RegisterType.Predicate), op.Src1PredInv);
+
+            Operand p0Res = GetPredLogicalOp(context, op.BoolOpAB, srcA, srcB);
+            Operand p1Res = context.BitwiseNot(p0Res);
+            Operand srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+
+            p0Res = GetPredLogicalOp(context, op.BoolOpC, p0Res, srcPred);
+            p1Res = GetPredLogicalOp(context, op.BoolOpC, p1Res, srcPred);
+
+            context.Copy(Register(op.DestPred, RegisterType.Predicate), p0Res);
+            context.Copy(Register(op.DestPredInv, RegisterType.Predicate), p1Res);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitShift.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitShift.cs
new file mode 100644
index 0000000000..ca053ab64a
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitShift.cs
@@ -0,0 +1,132 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void ShlR(EmitterContext context)
+        {
+            InstShlR op = context.GetOp<InstShlR>();
+
+            EmitShl(context, GetSrcReg(context, op.SrcA), GetSrcReg(context, op.SrcB), op.Dest, op.M);
+        }
+
+        public static void ShlI(EmitterContext context)
+        {
+            InstShlI op = context.GetOp<InstShlI>();
+
+            EmitShl(context, GetSrcReg(context, op.SrcA), GetSrcImm(context, Imm20ToSInt(op.Imm20)), op.Dest, op.M);
+        }
+
+        public static void ShlC(EmitterContext context)
+        {
+            InstShlC op = context.GetOp<InstShlC>();
+
+            EmitShl(context, GetSrcReg(context, op.SrcA), GetSrcCbuf(context, op.CbufSlot, op.CbufOffset), op.Dest, op.M);
+        }
+
+        public static void ShrR(EmitterContext context)
+        {
+            InstShrR op = context.GetOp<InstShrR>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcReg(context, op.SrcB);
+
+            EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
+        }
+
+        public static void ShrI(EmitterContext context)
+        {
+            InstShrI op = context.GetOp<InstShrI>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
+
+            EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
+        }
+
+        public static void ShrC(EmitterContext context)
+        {
+            InstShrC op = context.GetOp<InstShrC>();
+
+            var srcA = GetSrcReg(context, op.SrcA);
+            var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
+
+            EmitShr(context, srcA, srcB, op.Dest, op.M, op.Brev, op.Signed);
+        }
+
+        private static void EmitShl(EmitterContext context, Operand srcA, Operand srcB, int rd, bool mask)
+        {
+            if (mask)
+            {
+                srcB = context.BitwiseAnd(srcB, Const(0x1f));
+            }
+
+            Operand res = context.ShiftLeft(srcA, srcB);
+
+            if (!mask)
+            {
+                // Clamped shift value.
+                Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
+
+                res = context.ConditionalSelect(isLessThan32, res, Const(0));
+            }
+
+            // TODO: X, CC.
+
+            context.Copy(GetDest(rd), res);
+        }
+
+        private static void EmitShr(
+            EmitterContext context,
+            Operand srcA,
+            Operand srcB,
+            int rd,
+            bool mask,
+            bool bitReverse,
+            bool isSigned)
+        {
+            if (bitReverse)
+            {
+                srcA = context.BitfieldReverse(srcA);
+            }
+
+            if (mask)
+            {
+                srcB = context.BitwiseAnd(srcB, Const(0x1f));
+            }
+
+            Operand res = isSigned
+                ? context.ShiftRightS32(srcA, srcB)
+                : context.ShiftRightU32(srcA, srcB);
+
+            if (!mask)
+            {
+                // Clamped shift value.
+                Operand resShiftBy32;
+
+                if (isSigned)
+                {
+                    resShiftBy32 = context.ShiftRightS32(srcA, Const(31));
+                }
+                else
+                {
+                    resShiftBy32 = Const(0);
+                }
+
+                Operand isLessThan32 = context.ICompareLessUnsigned(srcB, Const(32));
+
+                res = context.ConditionalSelect(isLessThan32, res, resShiftBy32);
+            }
+
+            // TODO: X, CC.
+
+            context.Copy(GetDest(rd), res);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs
new file mode 100644
index 0000000000..a47d66500a
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs
@@ -0,0 +1,776 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+using System.Collections.Generic;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void SuatomB(EmitterContext context)
+        {
+            InstSuatomB op = context.GetOp<InstSuatomB>();
+
+            EmitSuatom(
+                context,
+                op.Dim,
+                op.Op,
+                op.Size,
+                0,
+                op.SrcA,
+                op.SrcB,
+                op.SrcC,
+                op.Dest,
+                op.Ba,
+                isBindless: true,
+                compareAndSwap: false);
+        }
+
+        public static void Suatom(EmitterContext context)
+        {
+            InstSuatom op = context.GetOp<InstSuatom>();
+
+            EmitSuatom(
+                context,
+                op.Dim,
+                op.Op,
+                op.Size,
+                op.TidB,
+                op.SrcA,
+                op.SrcB,
+                0,
+                op.Dest,
+                op.Ba,
+                isBindless: false,
+                compareAndSwap: false);
+        }
+
+        public static void SuatomB2(EmitterContext context)
+        {
+            InstSuatomB2 op = context.GetOp<InstSuatomB2>();
+
+            EmitSuatom(
+                context,
+                op.Dim,
+                op.Op,
+                op.Size,
+                0,
+                op.SrcA,
+                op.SrcB,
+                op.SrcC,
+                op.Dest,
+                op.Ba,
+                isBindless: true,
+                compareAndSwap: false);
+        }
+
+        public static void SuatomCasB(EmitterContext context)
+        {
+            InstSuatomCasB op = context.GetOp<InstSuatomCasB>();
+
+            EmitSuatom(
+                context,
+                op.Dim,
+                0,
+                op.Size,
+                0,
+                op.SrcA,
+                op.SrcB,
+                op.SrcC,
+                op.Dest,
+                op.Ba,
+                isBindless: true,
+                compareAndSwap: true);
+        }
+
+        public static void SuatomCas(EmitterContext context)
+        {
+            InstSuatomCas op = context.GetOp<InstSuatomCas>();
+
+            EmitSuatom(
+                context,
+                op.Dim,
+                0,
+                op.Size,
+                op.TidB,
+                op.SrcA,
+                op.SrcB,
+                0,
+                op.Dest,
+                op.Ba,
+                isBindless: false,
+                compareAndSwap: true);
+        }
+
+        public static void SuldDB(EmitterContext context)
+        {
+            InstSuldDB op = context.GetOp<InstSuldDB>();
+
+            EmitSuld(context, op.Dim, op.Size, 0, 0, op.SrcA, op.Dest, op.SrcC, useComponents: false, op.Ba, isBindless: true);
+        }
+
+        public static void SuldD(EmitterContext context)
+        {
+            InstSuldD op = context.GetOp<InstSuldD>();
+
+            EmitSuld(context, op.Dim, op.Size, op.TidB, 0, op.SrcA, op.Dest, 0, useComponents: false, op.Ba, isBindless: false);
+        }
+
+        public static void SuldB(EmitterContext context)
+        {
+            InstSuldB op = context.GetOp<InstSuldB>();
+
+            EmitSuld(context, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: true);
+        }
+
+        public static void Suld(EmitterContext context)
+        {
+            InstSuld op = context.GetOp<InstSuld>();
+
+            EmitSuld(context, op.Dim, 0, op.TidB, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: false);
+        }
+
+        public static void SuredB(EmitterContext context)
+        {
+            InstSuredB op = context.GetOp<InstSuredB>();
+
+            EmitSured(context, op.Dim, op.Op, op.Size, 0, op.SrcA, op.Dest, op.SrcC, op.Ba, isBindless: true);
+        }
+
+        public static void Sured(EmitterContext context)
+        {
+            InstSured op = context.GetOp<InstSured>();
+
+            EmitSured(context, op.Dim, op.Op, op.Size, op.TidB, op.SrcA, op.Dest, 0, op.Ba, isBindless: false);
+        }
+
+        public static void SustDB(EmitterContext context)
+        {
+            InstSustDB op = context.GetOp<InstSustDB>();
+
+            EmitSust(context, op.Dim, op.Size, 0, 0, op.SrcA, op.Dest, op.SrcC, useComponents: false, op.Ba, isBindless: true);
+        }
+
+        public static void SustD(EmitterContext context)
+        {
+            InstSustD op = context.GetOp<InstSustD>();
+
+            EmitSust(context, op.Dim, op.Size, op.TidB, 0, op.SrcA, op.Dest, 0, useComponents: false, op.Ba, isBindless: false);
+        }
+
+        public static void SustB(EmitterContext context)
+        {
+            InstSustB op = context.GetOp<InstSustB>();
+
+            EmitSust(context, op.Dim, 0, 0, op.Rgba, op.SrcA, op.Dest, op.SrcC, useComponents: true, false, isBindless: true);
+        }
+
+        public static void Sust(EmitterContext context)
+        {
+            InstSust op = context.GetOp<InstSust>();
+
+            EmitSust(context, op.Dim, 0, op.TidB, op.Rgba, op.SrcA, op.Dest, 0, useComponents: true, false, isBindless: false);
+        }
+
+        private static void EmitSuatom(
+            EmitterContext context,
+            SuDim dimensions,
+            SuatomOp atomicOp,
+            SuatomSize size,
+            int imm,
+            int srcA,
+            int srcB,
+            int srcC,
+            int dest,
+            bool byteAddress,
+            bool isBindless,
+            bool compareAndSwap)
+        {
+            SamplerType type = ConvertSamplerType(dimensions);
+
+            if (type == SamplerType.None)
+            {
+                context.Config.GpuAccessor.Log("Invalid image atomic sampler type.");
+                return;
+            }
+
+            Operand Ra()
+            {
+                if (srcA > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
+            }
+
+            Operand Rb()
+            {
+                if (srcB > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(srcB++, RegisterType.Gpr));
+            }
+
+            Operand GetDest()
+            {
+                if (dest > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return Register(dest++, RegisterType.Gpr);
+            }
+
+            List<Operand> sourcesList = new List<Operand>();
+
+            if (isBindless)
+            {
+                sourcesList.Add(context.Copy(GetSrcReg(context, srcC)));
+            }
+
+            int coordsCount = type.GetDimensions();
+
+            for (int index = 0; index < coordsCount; index++)
+            {
+                sourcesList.Add(Ra());
+            }
+
+            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
+            {
+                sourcesList.Add(Const(0));
+
+                type &= ~SamplerType.Mask;
+                type |= SamplerType.Texture2D;
+            }
+
+            if (type.HasFlag(SamplerType.Array))
+            {
+                sourcesList.Add(Ra());
+
+                type |= SamplerType.Array;
+            }
+
+            if (byteAddress)
+            {
+                int xIndex = isBindless ? 1 : 0;
+
+                sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(size)));
+            }
+
+            // TODO: FP and 64-bit formats.
+            TextureFormat format = !isBindless && (size == SuatomSize.Sd32 || size == SuatomSize.Sd64)
+                ? context.Config.GetTextureFormatAtomic(imm)
+                : GetTextureFormat(size);
+
+            if (compareAndSwap)
+            {
+                sourcesList.Add(Rb());
+            }
+
+            sourcesList.Add(Rb());
+
+            Operand[] sources = sourcesList.ToArray();
+
+            TextureFlags flags = compareAndSwap ? TextureFlags.CAS : GetAtomicOpFlags(atomicOp);
+
+            if (isBindless)
+            {
+                flags |= TextureFlags.Bindless;
+            }
+
+            TextureOperation operation = context.CreateTextureOperation(
+                Instruction.ImageAtomic,
+                type,
+                format,
+                flags,
+                imm,
+                0,
+                GetDest(),
+                sources);
+
+            context.Add(operation);
+        }
+
+        private static void EmitSuld(
+            EmitterContext context,
+            SuDim dimensions,
+            SuSize size,
+            int imm,
+            SuRgba componentMask,
+            int srcA,
+            int srcB,
+            int srcC,
+            bool useComponents,
+            bool byteAddress,
+            bool isBindless)
+        {
+            context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
+
+            SamplerType type = ConvertSamplerType(dimensions);
+
+            if (type == SamplerType.None)
+            {
+                context.Config.GpuAccessor.Log("Invalid image store sampler type.");
+                return;
+            }
+
+            Operand Ra()
+            {
+                if (srcA > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
+            }
+
+            List<Operand> sourcesList = new List<Operand>();
+
+            if (isBindless)
+            {
+                sourcesList.Add(context.Copy(Register(srcC, RegisterType.Gpr)));
+            }
+
+            int coordsCount = type.GetDimensions();
+
+            for (int index = 0; index < coordsCount; index++)
+            {
+                sourcesList.Add(Ra());
+            }
+
+            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
+            {
+                sourcesList.Add(Const(0));
+
+                type &= ~SamplerType.Mask;
+                type |= SamplerType.Texture2D;
+            }
+
+            if (type.HasFlag(SamplerType.Array))
+            {
+                sourcesList.Add(Ra());
+            }
+
+            Operand[] sources = sourcesList.ToArray();
+
+            int handle = imm;
+
+            TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
+
+            if (useComponents)
+            {
+                for (int compMask = (int)componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+                {
+                    if ((compMask & 1) == 0)
+                    {
+                        continue;
+                    }
+
+                    if (srcB == RegisterConsts.RegisterZeroIndex)
+                    {
+                        break;
+                    }
+
+                    Operand rd = Register(srcB++, RegisterType.Gpr);
+
+                    TextureOperation operation = context.CreateTextureOperation(
+                        Instruction.ImageLoad,
+                        type,
+                        flags,
+                        handle,
+                        compIndex,
+                        rd,
+                        sources);
+
+                    if (!isBindless)
+                    {
+                        operation.Format = context.Config.GetTextureFormat(handle);
+                    }
+
+                    context.Add(operation);
+                }
+            }
+            else
+            {
+                if (byteAddress)
+                {
+                    int xIndex = isBindless ? 1 : 0;
+
+                    sources[xIndex] = context.ShiftRightS32(sources[xIndex], Const(GetComponentSizeInBytesLog2(size)));
+                }
+
+                int components = GetComponents(size);
+
+                for (int compIndex = 0; compIndex < components; compIndex++)
+                {
+                    if (srcB == RegisterConsts.RegisterZeroIndex)
+                    {
+                        break;
+                    }
+
+                    Operand rd = Register(srcB++, RegisterType.Gpr);
+
+                    TextureOperation operation = context.CreateTextureOperation(
+                        Instruction.ImageLoad,
+                        type,
+                        GetTextureFormat(size),
+                        flags,
+                        handle,
+                        compIndex,
+                        rd,
+                        sources);
+
+                    context.Add(operation);
+
+                    switch (size)
+                    {
+                        case SuSize.U8: context.Copy(rd, ZeroExtendTo32(context, rd, 8)); break;
+                        case SuSize.U16: context.Copy(rd, ZeroExtendTo32(context, rd, 16)); break;
+                        case SuSize.S8: context.Copy(rd, SignExtendTo32(context, rd, 8)); break;
+                        case SuSize.S16: context.Copy(rd, SignExtendTo32(context, rd, 16)); break;
+                    }
+                }
+            }
+        }
+
+        private static void EmitSured(
+            EmitterContext context,
+            SuDim dimensions,
+            RedOp atomicOp,
+            SuatomSize size,
+            int imm,
+            int srcA,
+            int srcB,
+            int srcC,
+            bool byteAddress,
+            bool isBindless)
+        {
+            SamplerType type = ConvertSamplerType(dimensions);
+
+            if (type == SamplerType.None)
+            {
+                context.Config.GpuAccessor.Log("Invalid image reduction sampler type.");
+                return;
+            }
+
+            Operand Ra()
+            {
+                if (srcA > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
+            }
+
+            Operand Rb()
+            {
+                if (srcB > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(srcB++, RegisterType.Gpr));
+            }
+
+            List<Operand> sourcesList = new List<Operand>();
+
+            if (isBindless)
+            {
+                sourcesList.Add(context.Copy(GetSrcReg(context, srcC)));
+            }
+
+            int coordsCount = type.GetDimensions();
+
+            for (int index = 0; index < coordsCount; index++)
+            {
+                sourcesList.Add(Ra());
+            }
+
+            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
+            {
+                sourcesList.Add(Const(0));
+
+                type &= ~SamplerType.Mask;
+                type |= SamplerType.Texture2D;
+            }
+
+            if (type.HasFlag(SamplerType.Array))
+            {
+                sourcesList.Add(Ra());
+
+                type |= SamplerType.Array;
+            }
+
+            if (byteAddress)
+            {
+                int xIndex = isBindless ? 1 : 0;
+
+                sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(size)));
+            }
+
+            // TODO: FP and 64-bit formats.
+            TextureFormat format = !isBindless && (size == SuatomSize.Sd32 || size == SuatomSize.Sd64)
+                ? context.Config.GetTextureFormatAtomic(imm)
+                : GetTextureFormat(size);
+
+            sourcesList.Add(Rb());
+
+            Operand[] sources = sourcesList.ToArray();
+
+            TextureFlags flags = GetAtomicOpFlags((SuatomOp)atomicOp);
+
+            if (isBindless)
+            {
+                flags |= TextureFlags.Bindless;
+            }
+
+            TextureOperation operation = context.CreateTextureOperation(
+                Instruction.ImageAtomic,
+                type,
+                format,
+                flags,
+                imm,
+                0,
+                null,
+                sources);
+
+            context.Add(operation);
+        }
+
+        private static void EmitSust(
+            EmitterContext context,
+            SuDim dimensions,
+            SuSize size,
+            int imm,
+            SuRgba componentMask,
+            int srcA,
+            int srcB,
+            int srcC,
+            bool useComponents,
+            bool byteAddress,
+            bool isBindless)
+        {
+            SamplerType type = ConvertSamplerType(dimensions);
+
+            if (type == SamplerType.None)
+            {
+                context.Config.GpuAccessor.Log("Invalid image store sampler type.");
+                return;
+            }
+
+            Operand Ra()
+            {
+                if (srcA > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
+            }
+
+            Operand Rb()
+            {
+                if (srcB > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(srcB++, RegisterType.Gpr));
+            }
+
+            List<Operand> sourcesList = new List<Operand>();
+
+            if (isBindless)
+            {
+                sourcesList.Add(context.Copy(Register(srcC, RegisterType.Gpr)));
+            }
+
+            int coordsCount = type.GetDimensions();
+
+            for (int index = 0; index < coordsCount; index++)
+            {
+                sourcesList.Add(Ra());
+            }
+
+            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
+            {
+                sourcesList.Add(Const(0));
+
+                type &= ~SamplerType.Mask;
+                type |= SamplerType.Texture2D;
+            }
+
+            if (type.HasFlag(SamplerType.Array))
+            {
+                sourcesList.Add(Ra());
+            }
+
+            TextureFormat format = TextureFormat.Unknown;
+
+            if (useComponents)
+            {
+                for (int compMask = (int)componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+                {
+                    if ((compMask & 1) != 0)
+                    {
+                        sourcesList.Add(Rb());
+                    }
+                }
+
+                if (!isBindless)
+                {
+                    format = context.Config.GetTextureFormat(imm);
+                }
+            }
+            else
+            {
+                if (byteAddress)
+                {
+                    int xIndex = isBindless ? 1 : 0;
+
+                    sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(size)));
+                }
+
+                int components = GetComponents(size);
+
+                for (int compIndex = 0; compIndex < components; compIndex++)
+                {
+                    sourcesList.Add(Rb());
+                }
+
+                format = GetTextureFormat(size);
+            }
+
+            Operand[] sources = sourcesList.ToArray();
+
+            int handle = imm;
+
+            TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
+
+            TextureOperation operation = context.CreateTextureOperation(
+                Instruction.ImageStore,
+                type,
+                format,
+                flags,
+                handle,
+                0,
+                null,
+                sources);
+
+            context.Add(operation);
+        }
+
+        private static int GetComponentSizeInBytesLog2(SuatomSize size)
+        {
+            return size switch
+            {
+                SuatomSize.U32 => 2,
+                SuatomSize.S32 => 2,
+                SuatomSize.U64 => 3,
+                SuatomSize.F32FtzRn => 2,
+                SuatomSize.F16x2FtzRn => 2,
+                SuatomSize.S64 => 3,
+                SuatomSize.Sd32 => 2,
+                SuatomSize.Sd64 => 3,
+                _ => 2
+            };
+        }
+
+        private static TextureFormat GetTextureFormat(SuatomSize size)
+        {
+            return size switch
+            {
+                SuatomSize.U32 => TextureFormat.R32Uint,
+                SuatomSize.S32 => TextureFormat.R32Sint,
+                SuatomSize.U64 => TextureFormat.R32G32Uint,
+                SuatomSize.F32FtzRn => TextureFormat.R32Float,
+                SuatomSize.F16x2FtzRn => TextureFormat.R16G16Float,
+                SuatomSize.S64 => TextureFormat.R32G32Uint,
+                SuatomSize.Sd32 => TextureFormat.R32Uint,
+                SuatomSize.Sd64 => TextureFormat.R32G32Uint,
+                _ => TextureFormat.R32Uint
+            };
+        }
+
+        private static TextureFlags GetAtomicOpFlags(SuatomOp op)
+        {
+            return op switch
+            {
+                SuatomOp.Add => TextureFlags.Add,
+                SuatomOp.Min => TextureFlags.Minimum,
+                SuatomOp.Max => TextureFlags.Maximum,
+                SuatomOp.Inc => TextureFlags.Increment,
+                SuatomOp.Dec => TextureFlags.Decrement,
+                SuatomOp.And => TextureFlags.BitwiseAnd,
+                SuatomOp.Or => TextureFlags.BitwiseOr,
+                SuatomOp.Xor => TextureFlags.BitwiseXor,
+                SuatomOp.Exch => TextureFlags.Swap,
+                _ => TextureFlags.Add
+            };
+        }
+
+        private static int GetComponents(SuSize size)
+        {
+            return size switch
+            {
+                SuSize.B64 => 2,
+                SuSize.B128 => 4,
+                SuSize.UB128 => 4,
+                _ => 1
+            };
+        }
+
+        private static int GetComponentSizeInBytesLog2(SuSize size)
+        {
+            return size switch
+            {
+                SuSize.U8 => 0,
+                SuSize.S8 => 0,
+                SuSize.U16 => 1,
+                SuSize.S16 => 1,
+                SuSize.B32 => 2,
+                SuSize.B64 => 3,
+                SuSize.B128 => 4,
+                SuSize.UB128 => 4,
+                _ => 2
+            };
+        }
+
+        private static TextureFormat GetTextureFormat(SuSize size)
+        {
+            return size switch
+            {
+                SuSize.U8 => TextureFormat.R8Uint,
+                SuSize.S8 => TextureFormat.R8Sint,
+                SuSize.U16 => TextureFormat.R16Uint,
+                SuSize.S16 => TextureFormat.R16Sint,
+                SuSize.B32 => TextureFormat.R32Uint,
+                SuSize.B64 => TextureFormat.R32G32Uint,
+                SuSize.B128 => TextureFormat.R32G32B32A32Uint,
+                SuSize.UB128 => TextureFormat.R32G32B32A32Uint,
+                _ => TextureFormat.R32Uint
+            };
+        }
+
+        private static SamplerType ConvertSamplerType(SuDim target)
+        {
+            return target switch
+            {
+                SuDim._1d => SamplerType.Texture1D,
+                SuDim._1dBuffer => SamplerType.TextureBuffer,
+                SuDim._1dArray => SamplerType.Texture1D | SamplerType.Array,
+                SuDim._2d => SamplerType.Texture2D,
+                SuDim._2dArray => SamplerType.Texture2D | SamplerType.Array,
+                SuDim._3d => SamplerType.Texture3D,
+                _ => SamplerType.None
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index 88bafd7656..ba1fdf17bd 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -4,173 +4,181 @@ using Ryujinx.Graphics.Shader.Translation;
 using System;
 using System.Collections.Generic;
 
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
 using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
 
 namespace Ryujinx.Graphics.Shader.Instructions
 {
     static partial class InstEmit
     {
+        private static readonly int[,] _maskLut = new int[,]
+        {
+            { 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b1001, 0b1010, 0b1100 },
+            { 0b0111, 0b1011, 0b1101, 0b1110, 0b1111, 0b0000, 0b0000, 0b0000 }
+        };
+
         private const bool Sample1DAs2D = true;
 
-        public static void Suld(EmitterContext context)
+        private enum TexsType
         {
+            Texs,
+            Tlds,
+            Tld4s
+        }
+
+        public static void Tex(EmitterContext context)
+        {
+            InstTex op = context.GetOp<InstTex>();
+
+            EmitTex(context, TextureFlags.None, op.Dim, op.Lod, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, false, op.Dc, op.Aoffi);
+        }
+
+        public static void TexB(EmitterContext context)
+        {
+            InstTexB op = context.GetOp<InstTexB>();
+
+            EmitTex(context, TextureFlags.Bindless, op.Dim, op.Lodb, 0, op.WMask, op.SrcA, op.SrcB, op.Dest, false, op.Dc, op.Aoffib);
+        }
+
+        public static void Texs(EmitterContext context)
+        {
+            InstTexs op = context.GetOp<InstTexs>();
+
+            EmitTexs(context, TexsType.Texs, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Dest2, isF16: false);
+        }
+
+        public static void TexsF16(EmitterContext context)
+        {
+            InstTexs op = context.GetOp<InstTexs>();
+
+            EmitTexs(context, TexsType.Texs, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Dest2, isF16: true);
+        }
+
+        public static void Tld(EmitterContext context)
+        {
+            InstTld op = context.GetOp<InstTld>();
+
             context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
 
-            OpCodeImage op = (OpCodeImage)context.CurrOp;
+            var lod = op.Lod ? Lod.Ll : Lod.Lz;
 
-            SamplerType type = ConvertSamplerType(op.Dimensions);
-
-            if (type == SamplerType.None)
-            {
-                context.Config.GpuAccessor.Log("Invalid image store sampler type.");
-
-                return;
-            }
-
-            // Rb is Rd on the SULD instruction.
-            int rdIndex = op.Rb.Index;
-            int raIndex = op.Ra.Index;
-
-            Operand Ra()
-            {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
-            }
-
-            List<Operand> sourcesList = new List<Operand>();
-
-            if (op.IsBindless)
-            {
-                sourcesList.Add(context.Copy(Register(op.Rc)));
-            }
-
-            int coordsCount = type.GetDimensions();
-
-            for (int index = 0; index < coordsCount; index++)
-            {
-                sourcesList.Add(Ra());
-            }
-
-            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
-            {
-                sourcesList.Add(Const(0));
-
-                type &= ~SamplerType.Mask;
-                type |= SamplerType.Texture2D;
-            }
-
-            if (type.HasFlag(SamplerType.Array))
-            {
-                sourcesList.Add(Ra());
-
-                type |= SamplerType.Array;
-            }
-
-            Operand[] sources = sourcesList.ToArray();
-
-            int handle = !op.IsBindless ? op.HandleOffset : 0;
-
-            TextureFlags flags = op.IsBindless ? TextureFlags.Bindless : TextureFlags.None;
-
-            if (op.UseComponents)
-            {
-                int componentMask = (int)op.Components;
-
-                for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
-                {
-                    if ((compMask & 1) == 0)
-                    {
-                        continue;
-                    }
-
-                    if (rdIndex == RegisterConsts.RegisterZeroIndex)
-                    {
-                        break;
-                    }
-
-                    Operand rd = Register(rdIndex++, RegisterType.Gpr);
-
-                    TextureOperation operation = context.CreateTextureOperation(
-                        Instruction.ImageLoad,
-                        type,
-                        flags,
-                        handle,
-                        compIndex,
-                        rd,
-                        sources);
-
-                    if (!op.IsBindless)
-                    {
-                        operation.Format = context.Config.GetTextureFormat(handle);
-                    }
-
-                    context.Add(operation);
-                }
-            }
-            else
-            {
-                if (op.ByteAddress)
-                {
-                    int xIndex = op.IsBindless ? 1 : 0;
-
-                    sources[xIndex] = context.ShiftRightS32(sources[xIndex], Const(GetComponentSizeInBytesLog2(op.Size)));
-                }
-
-                int components = GetComponents(op.Size);
-
-                for (int compIndex = 0; compIndex < components; compIndex++)
-                {
-                    if (rdIndex == RegisterConsts.RegisterZeroIndex)
-                    {
-                        break;
-                    }
-
-                    Operand rd = Register(rdIndex++, RegisterType.Gpr);
-
-                    TextureOperation operation = context.CreateTextureOperation(
-                        Instruction.ImageLoad,
-                        type,
-                        GetTextureFormat(op.Size),
-                        flags,
-                        handle,
-                        compIndex,
-                        rd,
-                        sources);
-
-                    context.Add(operation);
-
-                    switch (op.Size)
-                    {
-                        case IntegerSize.U8:  context.Copy(rd, ZeroExtendTo32(context, rd, 8));  break;
-                        case IntegerSize.U16: context.Copy(rd, ZeroExtendTo32(context, rd, 16)); break;
-                        case IntegerSize.S8:  context.Copy(rd, SignExtendTo32(context, rd, 8));  break;
-                        case IntegerSize.S16: context.Copy(rd, SignExtendTo32(context, rd, 16)); break;
-                    }
-                }
-            }
+            EmitTex(context, TextureFlags.IntCoords, op.Dim, lod, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Ms, false, op.Toff);
         }
 
-        public static void Sust(EmitterContext context)
+        public static void TldB(EmitterContext context)
         {
-            OpCodeImage op = (OpCodeImage)context.CurrOp;
+            InstTldB op = context.GetOp<InstTldB>();
 
-            SamplerType type = ConvertSamplerType(op.Dimensions);
+            context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
 
-            if (type == SamplerType.None)
+            var flags = TextureFlags.IntCoords | TextureFlags.Bindless;
+            var lod = op.Lod ? Lod.Ll : Lod.Lz;
+
+            EmitTex(context, flags, op.Dim, lod, 0, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Ms, false, op.Toff);
+        }
+
+        public static void Tlds(EmitterContext context)
+        {
+            InstTlds op = context.GetOp<InstTlds>();
+
+            EmitTexs(context, TexsType.Tlds, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Dest2, isF16: false);
+        }
+
+        public static void TldsF16(EmitterContext context)
+        {
+            InstTlds op = context.GetOp<InstTlds>();
+
+            EmitTexs(context, TexsType.Tlds, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Dest2, isF16: true);
+        }
+
+        public static void Tld4(EmitterContext context)
+        {
+            InstTld4 op = context.GetOp<InstTld4>();
+
+            EmitTld4(context, op.Dim, op.TexComp, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Toff, op.Dc, isBindless: false);
+        }
+
+        public static void Tld4B(EmitterContext context)
+        {
+            InstTld4B op = context.GetOp<InstTld4B>();
+
+            EmitTld4(context, op.Dim, op.TexComp, 0, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Toff, op.Dc, isBindless: true);
+        }
+
+        public static void Tld4s(EmitterContext context)
+        {
+            InstTld4s op = context.GetOp<InstTld4s>();
+
+            EmitTexs(context, TexsType.Tld4s, op.TidB, 4, op.SrcA, op.SrcB, op.Dest, op.Dest2, isF16: false);
+        }
+
+        public static void Tld4sF16(EmitterContext context)
+        {
+            InstTld4s op = context.GetOp<InstTld4s>();
+
+            EmitTexs(context, TexsType.Tld4s, op.TidB, 4, op.SrcA, op.SrcB, op.Dest, op.Dest2, isF16: true);
+        }
+
+        public static void Tmml(EmitterContext context)
+        {
+            InstTmml op = context.GetOp<InstTmml>();
+
+            EmitTmml(context, op.Dim, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, isBindless: false);
+        }
+
+        public static void TmmlB(EmitterContext context)
+        {
+            InstTmmlB op = context.GetOp<InstTmmlB>();
+
+            EmitTmml(context, op.Dim, 0, op.WMask, op.SrcA, op.SrcB, op.Dest, isBindless: true);
+        }
+
+        public static void Txd(EmitterContext context)
+        {
+            InstTxd op = context.GetOp<InstTxd>();
+
+            EmitTxd(context, op.Dim, op.TidB, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Toff, isBindless: false);
+        }
+
+        public static void TxdB(EmitterContext context)
+        {
+            InstTxdB op = context.GetOp<InstTxdB>();
+
+            EmitTxd(context, op.Dim, 0, op.WMask, op.SrcA, op.SrcB, op.Dest, op.Toff, isBindless: true);
+        }
+
+        public static void Txq(EmitterContext context)
+        {
+            InstTxq op = context.GetOp<InstTxq>();
+
+            EmitTxq(context, op.TexQuery, op.TidB, op.WMask, op.SrcA, op.Dest, isBindless: false);
+        }
+
+        public static void TxqB(EmitterContext context)
+        {
+            InstTxqB op = context.GetOp<InstTxqB>();
+
+            EmitTxq(context, op.TexQuery, 0, op.WMask, op.SrcA, op.Dest, isBindless: true);
+        }
+
+        private static void EmitTex(
+            EmitterContext context,
+            TextureFlags flags,
+            TexDim dimensions,
+            Lod lodMode,
+            int imm,
+            int componentMask,
+            int raIndex,
+            int rbIndex,
+            int rdIndex,
+            bool isMultisample,
+            bool hasDepthCompare,
+            bool hasOffset)
+        {
+            if (rdIndex == RegisterConsts.RegisterZeroIndex)
             {
-                context.Config.GpuAccessor.Log("Invalid image store sampler type.");
-
                 return;
             }
 
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
             Operand Ra()
             {
                 if (raIndex > RegisterConsts.RegisterZeroIndex)
@@ -191,11 +199,36 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 return context.Copy(Register(rbIndex++, RegisterType.Gpr));
             }
 
+            SamplerType type = ConvertSamplerType(dimensions);
+
+            bool isArray = type.HasFlag(SamplerType.Array);
+            bool isBindless = flags.HasFlag(TextureFlags.Bindless);
+
+            Operand arrayIndex = isArray ? Ra() : null;
+
             List<Operand> sourcesList = new List<Operand>();
 
-            if (op.IsBindless)
+            if (isBindless)
             {
-                sourcesList.Add(context.Copy(Register(op.Rc)));
+                sourcesList.Add(Rb());
+            }
+
+            bool hasLod = lodMode > Lod.Lz;
+
+            if (type == SamplerType.Texture1D && (flags & ~TextureFlags.Bindless) == TextureFlags.IntCoords && !(
+                hasLod ||
+                hasDepthCompare ||
+                hasOffset ||
+                isArray ||
+                isMultisample))
+            {
+                // For bindless, we don't have any way to know the texture type,
+                // so we assume it's texture buffer when the sampler type is 1D, since that's more common.
+                bool isTypeBuffer = isBindless || context.Config.GpuAccessor.QuerySamplerType(imm) == SamplerType.TextureBuffer;
+                if (isTypeBuffer)
+                {
+                    type = SamplerType.TextureBuffer;
+                }
             }
 
             int coordsCount = type.GetDimensions();
@@ -205,229 +238,72 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 sourcesList.Add(Ra());
             }
 
-            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
-            {
-                sourcesList.Add(Const(0));
-
-                type &= ~SamplerType.Mask;
-                type |= SamplerType.Texture2D;
-            }
-
-            if (type.HasFlag(SamplerType.Array))
-            {
-                sourcesList.Add(Ra());
-
-                type |= SamplerType.Array;
-            }
-
-            TextureFormat format = TextureFormat.Unknown;
-
-            if (op.UseComponents)
-            {
-                int componentMask = (int)op.Components;
-
-                for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
-                {
-                    if ((compMask & 1) != 0)
-                    {
-                        sourcesList.Add(Rb());
-                    }
-                }
-
-                if (!op.IsBindless)
-                {
-                    format = context.Config.GetTextureFormat(op.HandleOffset);
-                }
-            }
-            else
-            {
-                if (op.ByteAddress)
-                {
-                    int xIndex = op.IsBindless ? 1 : 0;
-
-                    sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(op.Size)));
-                }
-
-                int components = GetComponents(op.Size);
-
-                for (int compIndex = 0; compIndex < components; compIndex++)
-                {
-                    sourcesList.Add(Rb());
-                }
-
-                format = GetTextureFormat(op.Size);
-            }
-
-            Operand[] sources = sourcesList.ToArray();
-
-            int handle = !op.IsBindless ? op.HandleOffset : 0;
-
-            TextureFlags flags = op.IsBindless ? TextureFlags.Bindless : TextureFlags.None;
-
-            TextureOperation operation = context.CreateTextureOperation(
-                Instruction.ImageStore,
-                type,
-                format,
-                flags,
-                handle,
-                0,
-                null,
-                sources);
-
-            context.Add(operation);
-        }
-
-        public static void Sured(EmitterContext context)
-        {
-            OpCodeSured op = (OpCodeSured)context.CurrOp;
-
-            SamplerType type = ConvertSamplerType(op.Dimensions);
-
-            if (type == SamplerType.None)
-            {
-                context.Config.GpuAccessor.Log("Invalid image reduction sampler type.");
-
-                return;
-            }
-
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
-            Operand Ra()
-            {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
-            }
-
-            Operand Rb()
-            {
-                if (rbIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
-            }
-
-            List<Operand> sourcesList = new List<Operand>();
-
-            if (op.IsBindless)
-            {
-                sourcesList.Add(context.Copy(Register(op.Rc)));
-            }
-
-            int coordsCount = type.GetDimensions();
-
-            for (int index = 0; index < coordsCount; index++)
-            {
-                sourcesList.Add(Ra());
-            }
+            bool is1DTo2D = false;
 
             if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
             {
-                sourcesList.Add(Const(0));
+                sourcesList.Add(ConstF(0));
 
-                type &= ~SamplerType.Mask;
-                type |= SamplerType.Texture2D;
+                type = SamplerType.Texture2D | (type & SamplerType.Array);
+                is1DTo2D = true;
             }
 
-            if (type.HasFlag(SamplerType.Array))
+            if (isArray)
             {
-                sourcesList.Add(Ra());
-
-                type |= SamplerType.Array;
+                sourcesList.Add(arrayIndex);
             }
 
-            TextureFormat format = TextureFormat.R32Sint;
+            Operand lodValue = hasLod ? Rb() : ConstF(0);
 
-            if (op.UseType)
+            Operand packedOffs = hasOffset ? Rb() : null;
+
+            if (hasDepthCompare)
             {
-                if (op.ByteAddress)
+                sourcesList.Add(Rb());
+
+                type |= SamplerType.Shadow;
+            }
+
+            if ((lodMode == Lod.Lz ||
+                 lodMode == Lod.Ll ||
+                 lodMode == Lod.Lla) && !isMultisample && type != SamplerType.TextureBuffer)
+            {
+                sourcesList.Add(lodValue);
+
+                flags |= TextureFlags.LodLevel;
+            }
+
+            if (hasOffset)
+            {
+                for (int index = 0; index < coordsCount; index++)
                 {
-                    int xIndex = op.IsBindless ? 1 : 0;
-
-                    sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(op.Type)));
+                    sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * 4), Const(4)));
                 }
 
-                // TODO: FP and 64-bit formats.
-                format = (op.Type == ReductionType.SD32 || op.Type == ReductionType.SD64) ?
-                    context.Config.GetTextureFormatAtomic(op.HandleOffset) :
-                    GetTextureFormat(op.Type);
-            }
-            else if (!op.IsBindless)
-            {
-                format = context.Config.GetTextureFormatAtomic(op.HandleOffset);
+                if (is1DTo2D)
+                {
+                    sourcesList.Add(Const(0));
+                }
+
+                flags |= TextureFlags.Offset;
             }
 
-            sourcesList.Add(Rb());
+            if (lodMode == Lod.Lb || lodMode == Lod.Lba)
+            {
+                sourcesList.Add(lodValue);
+
+                flags |= TextureFlags.LodBias;
+            }
+
+            if (isMultisample)
+            {
+                sourcesList.Add(Rb());
+
+                type |= SamplerType.Multisample;
+            }
 
             Operand[] sources = sourcesList.ToArray();
 
-            int handle = op.HandleOffset;
-
-            TextureFlags flags = GetAtomicOpFlags(op.AtomicOp);
-
-            if (op.IsBindless)
-            {
-                handle = 0;
-                flags |= TextureFlags.Bindless;
-            }
-
-            TextureOperation operation = context.CreateTextureOperation(
-                Instruction.ImageAtomic,
-                type,
-                format,
-                flags,
-                handle,
-                0,
-                null,
-                sources);
-
-            context.Add(operation);
-        }
-
-        public static void Suatom(EmitterContext context)
-        {
-            OpCodeSuatom op = (OpCodeSuatom)context.CurrOp;
-
-            SamplerType type = ConvertSamplerType(op.Dimensions);
-
-            if (type == SamplerType.None)
-            {
-                context.Config.GpuAccessor.Log("Invalid image atomic sampler type.");
-
-                return;
-            }
-
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
-            Operand Ra()
-            {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
-            }
-
-            Operand Rb()
-            {
-                if (rbIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
-            }
-
-            int rdIndex = op.Rd.Index;
-
             Operand GetDest()
             {
                 if (rdIndex > RegisterConsts.RegisterZeroIndex)
@@ -438,144 +314,64 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 return Register(rdIndex++, RegisterType.Gpr);
             }
 
-            List<Operand> sourcesList = new List<Operand>();
+            int handle = !isBindless ? imm : 0;
 
-            if (op.IsBindless)
+            for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
             {
-                sourcesList.Add(context.Copy(Register(op.Rc)));
-            }
-
-            int coordsCount = type.GetDimensions();
-
-            for (int index = 0; index < coordsCount; index++)
-            {
-                sourcesList.Add(Ra());
-            }
-
-            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
-            {
-                sourcesList.Add(Const(0));
-
-                type &= ~SamplerType.Mask;
-                type |= SamplerType.Texture2D;
-            }
-
-            if (type.HasFlag(SamplerType.Array))
-            {
-                sourcesList.Add(Ra());
-
-                type |= SamplerType.Array;
-            }
-
-            TextureFormat format = TextureFormat.R32Sint;
-
-            if (op.UseType)
-            {
-                if (op.ByteAddress)
+                if ((compMask & 1) != 0)
                 {
-                    int xIndex = op.IsBindless ? 1 : 0;
+                    Operand dest = GetDest();
 
-                    sourcesList[xIndex] = context.ShiftRightS32(sourcesList[xIndex], Const(GetComponentSizeInBytesLog2(op.Type)));
+                    TextureOperation operation = context.CreateTextureOperation(
+                        Instruction.TextureSample,
+                        type,
+                        flags,
+                        handle,
+                        compIndex,
+                        dest,
+                        sources);
+
+                    context.Add(operation);
                 }
-
-                // TODO: FP and 64-bit formats.
-                format = (op.Type == ReductionType.SD32 || op.Type == ReductionType.SD64) ?
-                    context.Config.GetTextureFormatAtomic(op.HandleOffset) :
-                    GetTextureFormat(op.Type);
             }
-            else if (!op.IsBindless)
-            {
-                format = context.Config.GetTextureFormatAtomic(op.HandleOffset);
-            }
-
-            if (op.CompareAndSwap)
-            {
-                sourcesList.Add(Rb());
-            }
-
-            sourcesList.Add(Rb());
-
-            Operand[] sources = sourcesList.ToArray();
-
-            int handle = op.HandleOffset;
-
-            TextureFlags flags = op.CompareAndSwap ? TextureFlags.CAS : GetAtomicOpFlags(op.AtomicOp);
-
-            if (op.IsBindless)
-            {
-                handle = 0;
-                flags |= TextureFlags.Bindless;
-            }
-
-            TextureOperation operation = context.CreateTextureOperation(
-                Instruction.ImageAtomic,
-                type,
-                format,
-                flags,
-                handle,
-                0,
-                GetDest(),
-                sources);
-
-            context.Add(operation);
         }
 
-        public static void Tex(EmitterContext context)
+        private static void EmitTexs(
+            EmitterContext context,
+            TexsType texsType,
+            int imm,
+            int writeMask,
+            int srcA,
+            int srcB,
+            int dest,
+            int dest2,
+            bool isF16)
         {
-            EmitTextureSample(context, TextureFlags.None);
-        }
-
-        public static void TexB(EmitterContext context)
-        {
-            EmitTextureSample(context, TextureFlags.Bindless);
-        }
-
-        public static void Tld(EmitterContext context)
-        {
-            context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
-
-            EmitTextureSample(context, TextureFlags.IntCoords);
-        }
-
-        public static void TldB(EmitterContext context)
-        {
-            context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
-
-            EmitTextureSample(context, TextureFlags.IntCoords | TextureFlags.Bindless);
-        }
-
-        public static void Texs(EmitterContext context)
-        {
-            OpCodeTextureScalar op = (OpCodeTextureScalar)context.CurrOp;
-
-            if (op.Rd0.IsRZ && op.Rd1.IsRZ)
+            if (dest == RegisterConsts.RegisterZeroIndex && dest2 == RegisterConsts.RegisterZeroIndex)
             {
                 return;
             }
 
             List<Operand> sourcesList = new List<Operand>();
 
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
             Operand Ra()
             {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcA > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
             }
 
             Operand Rb()
             {
-                if (rbIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcB > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcB++, RegisterType.Gpr));
             }
 
             void AddTextureOffset(int coordsCount, int stride, int size)
@@ -588,17 +384,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 }
             }
 
-            SamplerType  type;
+            SamplerType type;
             TextureFlags flags;
 
-            if (op is OpCodeTexs texsOp)
+            if (texsType == TexsType.Texs)
             {
+                var texsOp = context.GetOp<InstTexs>();
+
                 type = ConvertSamplerType(texsOp.Target);
 
                 if (type == SamplerType.None)
                 {
                     context.Config.GpuAccessor.Log("Invalid texture sampler type.");
-
                     return;
                 }
 
@@ -630,7 +427,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 {
                     switch (texsOp.Target)
                     {
-                        case TextureTarget.Texture1DLodZero:
+                        case TexsTarget.Texture1DLodZero:
                             sourcesList.Add(Ra());
 
                             if (Sample1DAs2D)
@@ -644,36 +441,36 @@ namespace Ryujinx.Graphics.Shader.Instructions
                             sourcesList.Add(ConstF(0));
                             break;
 
-                        case TextureTarget.Texture2D:
+                        case TexsTarget.Texture2D:
                             sourcesList.Add(Ra());
                             sourcesList.Add(Rb());
                             break;
 
-                        case TextureTarget.Texture2DLodZero:
+                        case TexsTarget.Texture2DLodZero:
                             sourcesList.Add(Ra());
                             sourcesList.Add(Rb());
                             sourcesList.Add(ConstF(0));
                             break;
 
-                        case TextureTarget.Texture2DLodLevel:
-                        case TextureTarget.Texture2DDepthCompare:
-                        case TextureTarget.Texture3D:
-                        case TextureTarget.TextureCube:
+                        case TexsTarget.Texture2DLodLevel:
+                        case TexsTarget.Texture2DDepthCompare:
+                        case TexsTarget.Texture3D:
+                        case TexsTarget.TextureCube:
                             sourcesList.Add(Ra());
                             sourcesList.Add(Ra());
                             sourcesList.Add(Rb());
                             break;
 
-                        case TextureTarget.Texture2DLodZeroDepthCompare:
-                        case TextureTarget.Texture3DLodZero:
+                        case TexsTarget.Texture2DLodZeroDepthCompare:
+                        case TexsTarget.Texture3DLodZero:
                             sourcesList.Add(Ra());
                             sourcesList.Add(Ra());
                             sourcesList.Add(Rb());
                             sourcesList.Add(ConstF(0));
                             break;
 
-                        case TextureTarget.Texture2DLodLevelDepthCompare:
-                        case TextureTarget.TextureCubeLodLevel:
+                        case TexsTarget.Texture2DLodLevelDepthCompare:
+                        case TexsTarget.TextureCubeLodLevel:
                             sourcesList.Add(Ra());
                             sourcesList.Add(Ra());
                             sourcesList.Add(Rb());
@@ -682,14 +479,15 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     }
                 }
             }
-            else if (op is OpCodeTlds tldsOp)
+            else if (texsType == TexsType.Tlds)
             {
+                var tldsOp = context.GetOp<InstTlds>();
+
                 type = ConvertSamplerType(tldsOp.Target);
 
                 if (type == SamplerType.None)
                 {
                     context.Config.GpuAccessor.Log("Invalid texel fetch sampler type.");
-
                     return;
                 }
 
@@ -697,15 +495,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
                 flags = ConvertTextureFlags(tldsOp.Target) | TextureFlags.IntCoords;
 
-                if (tldsOp.Target == TexelLoadTarget.Texture1DLodZero && context.Config.GpuAccessor.QuerySamplerType(tldsOp.HandleOffset) == SamplerType.TextureBuffer)
+                if (tldsOp.Target == TldsTarget.Texture1DLodZero &&
+                    context.Config.GpuAccessor.QuerySamplerType(tldsOp.TidB) == SamplerType.TextureBuffer)
                 {
-                    type   = SamplerType.TextureBuffer;
+                    type = SamplerType.TextureBuffer;
                     flags &= ~TextureFlags.LodLevel;
                 }
 
                 switch (tldsOp.Target)
                 {
-                    case TexelLoadTarget.Texture1DLodZero:
+                    case TldsTarget.Texture1DLodZero:
                         sourcesList.Add(Ra());
 
                         if (type != SamplerType.TextureBuffer)
@@ -722,7 +521,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         }
                         break;
 
-                    case TexelLoadTarget.Texture1DLodLevel:
+                    case TldsTarget.Texture1DLodLevel:
                         sourcesList.Add(Ra());
 
                         if (Sample1DAs2D)
@@ -736,34 +535,34 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         sourcesList.Add(Rb());
                         break;
 
-                    case TexelLoadTarget.Texture2DLodZero:
+                    case TldsTarget.Texture2DLodZero:
                         sourcesList.Add(Ra());
                         sourcesList.Add(Rb());
                         sourcesList.Add(Const(0));
                         break;
 
-                    case TexelLoadTarget.Texture2DLodZeroOffset:
+                    case TldsTarget.Texture2DLodZeroOffset:
                         sourcesList.Add(Ra());
                         sourcesList.Add(Ra());
                         sourcesList.Add(Const(0));
                         break;
 
-                    case TexelLoadTarget.Texture2DLodZeroMultisample:
-                    case TexelLoadTarget.Texture2DLodLevel:
-                    case TexelLoadTarget.Texture2DLodLevelOffset:
+                    case TldsTarget.Texture2DLodZeroMultisample:
+                    case TldsTarget.Texture2DLodLevel:
+                    case TldsTarget.Texture2DLodLevelOffset:
                         sourcesList.Add(Ra());
                         sourcesList.Add(Ra());
                         sourcesList.Add(Rb());
                         break;
 
-                    case TexelLoadTarget.Texture3DLodZero:
+                    case TldsTarget.Texture3DLodZero:
                         sourcesList.Add(Ra());
                         sourcesList.Add(Ra());
                         sourcesList.Add(Rb());
                         sourcesList.Add(Const(0));
                         break;
 
-                    case TexelLoadTarget.Texture2DArrayLodZero:
+                    case TldsTarget.Texture2DArrayLodZero:
                         sourcesList.Add(Rb());
                         sourcesList.Add(Rb());
                         sourcesList.Add(Ra());
@@ -776,9 +575,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     AddTextureOffset(type.GetDimensions(), 4, 4);
                 }
             }
-            else if (op is OpCodeTld4s tld4sOp)
+            else if (texsType == TexsType.Tld4s)
             {
-                if (!(tld4sOp.HasDepthCompare || tld4sOp.HasOffset))
+                var tld4sOp = context.GetOp<InstTld4s>();
+
+                if (!(tld4sOp.Dc || tld4sOp.Aoffi))
                 {
                     sourcesList.Add(Ra());
                     sourcesList.Add(Rb());
@@ -789,28 +590,28 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     sourcesList.Add(Ra());
                 }
 
-                type  = SamplerType.Texture2D;
+                type = SamplerType.Texture2D;
                 flags = TextureFlags.Gather;
 
-                if (tld4sOp.HasDepthCompare)
+                if (tld4sOp.Dc)
                 {
                     sourcesList.Add(Rb());
 
                     type |= SamplerType.Shadow;
                 }
 
-                if (tld4sOp.HasOffset)
+                if (tld4sOp.Aoffi)
                 {
                     AddTextureOffset(type.GetDimensions(), 8, 6);
 
                     flags |= TextureFlags.Offset;
                 }
 
-                sourcesList.Add(Const(tld4sOp.GatherCompIndex));
+                sourcesList.Add(Const((int)tld4sOp.TexComp));
             }
             else
             {
-                throw new InvalidOperationException($"Invalid opcode type \"{op.GetType().Name}\".");
+                throw new ArgumentException($"Invalid TEXS type \"{texsType}\".");
             }
 
             Operand[] sources = sourcesList.ToArray();
@@ -823,11 +624,11 @@ namespace Ryujinx.Graphics.Shader.Instructions
             Operand GetDest()
             {
                 int high = destIncrement >> 1;
-                int low  = destIncrement &  1;
+                int low = destIncrement & 1;
 
                 destIncrement++;
 
-                if (op.IsFp16)
+                if (isF16)
                 {
                     return high != 0
                         ? (rd1[low] = Local())
@@ -835,7 +636,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 }
                 else
                 {
-                    int rdIndex = high != 0 ? op.Rd1.Index : op.Rd0.Index;
+                    int rdIndex = high != 0 ? dest2 : dest;
 
                     if (rdIndex < RegisterConsts.RegisterZeroIndex)
                     {
@@ -846,74 +647,85 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 }
             }
 
-            int handle = op.HandleOffset;
+            int handle = imm;
+            int componentMask = _maskLut[dest2 == RegisterConsts.RegisterZeroIndex ? 0 : 1, writeMask];
 
-            for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+            for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
             {
                 if ((compMask & 1) != 0)
                 {
-                    Operand dest = GetDest();
-
                     TextureOperation operation = context.CreateTextureOperation(
                         Instruction.TextureSample,
                         type,
                         flags,
                         handle,
                         compIndex,
-                        dest,
+                        GetDest(),
                         sources);
 
                     context.Add(operation);
                 }
             }
 
-            if (op.IsFp16)
+            if (isF16)
             {
-                context.Copy(Register(op.Rd0), context.PackHalf2x16(rd0[0], rd0[1]));
-                context.Copy(Register(op.Rd1), context.PackHalf2x16(rd1[0], rd1[1]));
+                context.Copy(Register(dest, RegisterType.Gpr), context.PackHalf2x16(rd0[0], rd0[1]));
+                context.Copy(Register(dest2, RegisterType.Gpr), context.PackHalf2x16(rd1[0], rd1[1]));
             }
         }
 
-        public static void Tld4(EmitterContext context)
+        private static void EmitTld4(
+            EmitterContext context,
+            TexDim dimensions,
+            TexComp component,
+            int imm,
+            int componentMask,
+            int srcA,
+            int srcB,
+            int dest,
+            TexOffset offset,
+            bool hasDepthCompare,
+            bool isBindless)
         {
-            IOpCodeTld4 op = (IOpCodeTld4)context.CurrOp;
-
-            if (op.Rd.IsRZ)
+            if (dest == RegisterConsts.RegisterZeroIndex)
             {
                 return;
             }
 
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
             Operand Ra()
             {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcA > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
             }
 
             Operand Rb()
             {
-                if (rbIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcB > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcB++, RegisterType.Gpr));
             }
 
-            Operand arrayIndex = op.IsArray ? Ra() : null;
+            bool isArray =
+                dimensions == TexDim.Array1d ||
+                dimensions == TexDim.Array2d ||
+                dimensions == TexDim.Array3d ||
+                dimensions == TexDim.ArrayCube;
+
+            Operand arrayIndex = isArray ? Ra() : null;
 
             List<Operand> sourcesList = new List<Operand>();
 
-            SamplerType  type  = ConvertSamplerType(op.Dimensions);
+            SamplerType type = ConvertSamplerType(dimensions);
             TextureFlags flags = TextureFlags.Gather;
 
-            if (op.Bindless)
+            if (isBindless)
             {
                 sourcesList.Add(Rb());
 
@@ -927,37 +739,37 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 sourcesList.Add(Ra());
             }
 
-            bool is1DTo2D = Sample1DAs2D && type == SamplerType.Texture1D;
+            bool is1DTo2D = Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D;
 
             if (is1DTo2D)
             {
                 sourcesList.Add(ConstF(0));
 
-                type = SamplerType.Texture2D;
+                type = SamplerType.Texture2D | (type & SamplerType.Array);
             }
 
-            if (op.IsArray)
+            if (isArray)
             {
                 sourcesList.Add(arrayIndex);
-
-                type |= SamplerType.Array;
             }
 
             Operand[] packedOffs = new Operand[2];
 
-            packedOffs[0] = op.Offset != TextureGatherOffset.None    ? Rb() : null;
-            packedOffs[1] = op.Offset == TextureGatherOffset.Offsets ? Rb() : null;
+            bool hasAnyOffset = offset == TexOffset.Aoffi || offset == TexOffset.Ptp;
 
-            if (op.HasDepthCompare)
+            packedOffs[0] = hasAnyOffset ? Rb() : null;
+            packedOffs[1] = offset == TexOffset.Ptp ? Rb() : null;
+
+            if (hasDepthCompare)
             {
                 sourcesList.Add(Rb());
 
                 type |= SamplerType.Shadow;
             }
 
-            if (op.Offset != TextureGatherOffset.None)
+            if (hasAnyOffset)
             {
-                int offsetTexelsCount = op.Offset == TextureGatherOffset.Offsets ? 4 : 1;
+                int offsetTexelsCount = offset == TexOffset.Ptp ? 4 : 1;
 
                 for (int index = 0; index < coordsCount * offsetTexelsCount; index++)
                 {
@@ -974,42 +786,36 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     }
                 }
 
-                flags |= op.Offset == TextureGatherOffset.Offsets
-                    ? TextureFlags.Offsets
-                    : TextureFlags.Offset;
+                flags |= offset == TexOffset.Ptp ? TextureFlags.Offsets : TextureFlags.Offset;
             }
 
-            sourcesList.Add(Const(op.GatherCompIndex));
+            sourcesList.Add(Const((int)component));
 
             Operand[] sources = sourcesList.ToArray();
 
-            int rdIndex = op.Rd.Index;
-
             Operand GetDest()
             {
-                if (rdIndex > RegisterConsts.RegisterZeroIndex)
+                if (dest > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return Register(rdIndex++, RegisterType.Gpr);
+                return Register(dest++, RegisterType.Gpr);
             }
 
-            int handle = op.HandleOffset;
+            int handle = imm;
 
-            for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+            for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
             {
                 if ((compMask & 1) != 0)
                 {
-                    Operand dest = GetDest();
-
                     TextureOperation operation = context.CreateTextureOperation(
                         Instruction.TextureSample,
                         type,
                         flags,
                         handle,
                         compIndex,
-                        dest,
+                        GetDest(),
                         sources);
 
                     context.Add(operation);
@@ -1017,46 +823,39 @@ namespace Ryujinx.Graphics.Shader.Instructions
             }
         }
 
-        public static void TmmlB(EmitterContext context)
+        private static void EmitTmml(
+            EmitterContext context,
+            TexDim dimensions,
+            int imm,
+            int componentMask,
+            int srcA,
+            int srcB,
+            int dest,
+            bool isBindless)
         {
-            EmitTextureMipMapLevel(context, true);
-        }
-
-        public static void Tmml(EmitterContext context)
-        {
-            EmitTextureMipMapLevel(context, false);
-        }
-
-        private static void EmitTextureMipMapLevel(EmitterContext context, bool isBindless)
-        {
-            OpCodeTexture op = (OpCodeTexture)context.CurrOp;
-
-            if (op.Rd.IsRZ)
+            if (dest == RegisterConsts.RegisterZeroIndex)
             {
                 return;
             }
 
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
             Operand Ra()
             {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcA > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
             }
 
             Operand Rb()
             {
-                if (rbIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcB > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcB++, RegisterType.Gpr));
             }
 
             TextureFlags flags = TextureFlags.None;
@@ -1070,58 +869,58 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 flags |= TextureFlags.Bindless;
             }
 
-            SamplerType type = ConvertSamplerType(op.Dimensions);
+            SamplerType type = ConvertSamplerType(dimensions);
 
             int coordsCount = type.GetDimensions();
 
-            Operand arrayIndex = op.IsArray ? Ra() : null;
+            bool isArray =
+                dimensions == TexDim.Array1d ||
+                dimensions == TexDim.Array2d ||
+                dimensions == TexDim.Array3d ||
+                dimensions == TexDim.ArrayCube;
+
+            Operand arrayIndex = isArray ? Ra() : null;
 
             for (int index = 0; index < coordsCount; index++)
             {
                 sourcesList.Add(Ra());
             }
 
-            if (Sample1DAs2D && type == SamplerType.Texture1D)
+            if (Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D)
             {
                 sourcesList.Add(ConstF(0));
 
-                type = SamplerType.Texture2D;
+                type = SamplerType.Texture2D | (type & SamplerType.Array);
             }
 
-            if (op.IsArray)
+            if (isArray)
             {
                 sourcesList.Add(arrayIndex);
-
-                type |= SamplerType.Array;
             }
 
             Operand[] sources = sourcesList.ToArray();
 
-            int rdIndex = op.Rd.Index;
-
             Operand GetDest()
             {
-                if (rdIndex > RegisterConsts.RegisterZeroIndex)
+                if (dest > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return Register(rdIndex++, RegisterType.Gpr);
+                return Register(dest++, RegisterType.Gpr);
             }
 
-            int handle = !isBindless ? op.HandleOffset : 0;
+            int handle = imm;
 
-            for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+            for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
             {
                 if ((compMask & 1) != 0)
                 {
-                    Operand dest = GetDest();
-
                     // Components z and w aren't standard, we return 0 in this case and add a comment.
                     if (compIndex >= 2)
                     {
                         context.Add(new CommentNode("Unsupported component z or w found"));
-                        context.Copy(dest, Const(0));
+                        context.Copy(GetDest(), Const(0));
                     }
                     else
                     {
@@ -1142,56 +941,60 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
                         Operand fixedPointValue = context.FPConvertToS32(tempDest);
 
-                        context.Copy(dest, fixedPointValue);
+                        context.Copy(GetDest(), fixedPointValue);
                     }
                 }
             }
         }
 
-        public static void Txd(EmitterContext context)
+        private static void EmitTxd(
+            EmitterContext context,
+            TexDim dimensions,
+            int imm,
+            int componentMask,
+            int srcA,
+            int srcB,
+            int dest,
+            bool hasOffset,
+            bool isBindless)
         {
-            OpCodeTxd op = (OpCodeTxd)context.CurrOp;
-
-            if (op.Rd.IsRZ)
+            if (dest == RegisterConsts.RegisterZeroIndex)
             {
                 return;
             }
 
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
             Operand Ra()
             {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcA > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
             }
 
             Operand Rb()
             {
-                if (rbIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcB > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcB++, RegisterType.Gpr));
             }
 
             TextureFlags flags = TextureFlags.Derivatives;
 
             List<Operand> sourcesList = new List<Operand>();
 
-            if (op.IsBindless)
+            if (isBindless)
             {
                 sourcesList.Add(Ra());
 
                 flags |= TextureFlags.Bindless;
             }
 
-            SamplerType type = ConvertSamplerType(op.Dimensions);
+            SamplerType type = ConvertSamplerType(dimensions);
 
             int coordsCount = type.GetDimensions();
 
@@ -1200,22 +1003,26 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 sourcesList.Add(Ra());
             }
 
-            bool is1DTo2D = Sample1DAs2D && type == SamplerType.Texture1D;
+            bool is1DTo2D = Sample1DAs2D && (type & SamplerType.Mask) == SamplerType.Texture1D;
 
             if (is1DTo2D)
             {
                 sourcesList.Add(ConstF(0));
 
-                type = SamplerType.Texture2D;
+                type = SamplerType.Texture2D | (type & SamplerType.Array);
             }
 
             Operand packedParams = Ra();
 
-            if (op.IsArray)
+            bool isArray =
+                dimensions == TexDim.Array1d ||
+                dimensions == TexDim.Array2d ||
+                dimensions == TexDim.Array3d ||
+                dimensions == TexDim.ArrayCube;
+
+            if (isArray)
             {
                 sourcesList.Add(context.BitwiseAnd(packedParams, Const(0xffff)));
-
-                type |= SamplerType.Array;
             }
 
             // Derivatives (X and Y).
@@ -1229,7 +1036,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 }
             }
 
-            if (op.HasOffset)
+            if (hasOffset)
             {
                 for (int index = 0; index < coordsCount; index++)
                 {
@@ -1246,33 +1053,29 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             Operand[] sources = sourcesList.ToArray();
 
-            int rdIndex = op.Rd.Index;
-
             Operand GetDest()
             {
-                if (rdIndex > RegisterConsts.RegisterZeroIndex)
+                if (dest > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return Register(rdIndex++, RegisterType.Gpr);
+                return Register(dest++, RegisterType.Gpr);
             }
 
-            int handle = !op.IsBindless ? op.HandleOffset : 0;
+            int handle = imm;
 
-            for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+            for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
             {
                 if ((compMask & 1) != 0)
                 {
-                    Operand dest = GetDest();
-
                     TextureOperation operation = context.CreateTextureOperation(
                         Instruction.TextureSample,
                         type,
                         flags,
                         handle,
                         compIndex,
-                        dest,
+                        GetDest(),
                         sources);
 
                     context.Add(operation);
@@ -1280,49 +1083,39 @@ namespace Ryujinx.Graphics.Shader.Instructions
             }
         }
 
-        public static void Txq(EmitterContext context)
+        private static void EmitTxq(
+            EmitterContext context,
+            TexQuery query,
+            int imm,
+            int componentMask,
+            int srcA,
+            int dest,
+            bool isBindless)
         {
-            EmitTextureQuery(context, bindless: false);
-        }
-
-        public static void TxqB(EmitterContext context)
-        {
-            EmitTextureQuery(context, bindless: true);
-        }
-
-        private static void EmitTextureQuery(EmitterContext context, bool bindless)
-        {
-            OpCodeTex op = (OpCodeTex)context.CurrOp;
-
-            if (op.Rd.IsRZ)
+            if (dest == RegisterConsts.RegisterZeroIndex)
             {
                 return;
             }
 
             context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
 
-            TextureProperty property = (TextureProperty)op.RawOpCode.Extract(22, 6);
-
-            // TODO: Validate and use property.
+            // TODO: Validate and use query.
             Instruction inst = Instruction.TextureSize;
-
-            TextureFlags flags = bindless ? TextureFlags.Bindless : TextureFlags.None;
-
-            int raIndex = op.Ra.Index;
+            TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
 
             Operand Ra()
             {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
+                if (srcA > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
+                return context.Copy(Register(srcA++, RegisterType.Gpr));
             }
 
             List<Operand> sourcesList = new List<Operand>();
 
-            if (bindless)
+            if (isBindless)
             {
                 sourcesList.Add(Ra());
             }
@@ -1331,44 +1124,38 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             Operand[] sources = sourcesList.ToArray();
 
-            int rdIndex = op.Rd.Index;
-
             Operand GetDest()
             {
-                if (rdIndex > RegisterConsts.RegisterZeroIndex)
+                if (dest > RegisterConsts.RegisterZeroIndex)
                 {
                     return Const(0);
                 }
 
-                return Register(rdIndex++, RegisterType.Gpr);
+                return Register(dest++, RegisterType.Gpr);
             }
 
-            int handle = !bindless ? op.HandleOffset : 0;
-
             SamplerType type;
 
-            if (bindless)
+            if (isBindless)
             {
-                type = (op.ComponentMask & 4) != 0 ? SamplerType.Texture3D : SamplerType.Texture2D;
-            } 
+                type = (componentMask & 4) != 0 ? SamplerType.Texture3D : SamplerType.Texture2D;
+            }
             else
             {
-                type = context.Config.GpuAccessor.QuerySamplerType(handle);
+                type = context.Config.GpuAccessor.QuerySamplerType(imm);
             }
 
-            for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+            for (int compMask = componentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
             {
                 if ((compMask & 1) != 0)
                 {
-                    Operand dest = GetDest();
-
                     TextureOperation operation = context.CreateTextureOperation(
                         inst,
                         type,
                         flags,
-                        handle,
+                        imm,
                         compIndex,
-                        dest,
+                        GetDest(),
                         sources);
 
                     context.Add(operation);
@@ -1376,393 +1163,126 @@ namespace Ryujinx.Graphics.Shader.Instructions
             }
         }
 
-        private static void EmitTextureSample(EmitterContext context, TextureFlags flags)
-        {
-            OpCodeTexture op = (OpCodeTexture)context.CurrOp;
-
-            bool isBindless = (flags & TextureFlags.Bindless) != 0;
-
-            if (op.Rd.IsRZ)
-            {
-                return;
-            }
-
-            int raIndex = op.Ra.Index;
-            int rbIndex = op.Rb.Index;
-
-            Operand Ra()
-            {
-                if (raIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return context.Copy(Register(raIndex++, RegisterType.Gpr));
-            }
-
-            Operand Rb()
-            {
-                if (rbIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
-            }
-
-            Operand arrayIndex = op.IsArray ? Ra() : null;
-
-            List<Operand> sourcesList = new List<Operand>();
-
-            if (isBindless)
-            {
-                sourcesList.Add(Rb());
-            }
-
-            SamplerType type = ConvertSamplerType(op.Dimensions);
-
-            bool hasLod = op.LodMode > TextureLodMode.LodZero;
-
-            if (type == SamplerType.Texture1D && (flags & ~TextureFlags.Bindless) == TextureFlags.IntCoords && !(hasLod ||
-                op.HasDepthCompare ||
-                op.HasOffset ||
-                op.IsArray ||
-                op.IsMultisample))
-            {
-                // For bindless, we don't have any way to know the texture type,
-                // so we assume it's texture buffer when the sampler type is 1D, since that's more common.
-                bool isTypeBuffer = isBindless || context.Config.GpuAccessor.QuerySamplerType(op.HandleOffset) == SamplerType.TextureBuffer;
-
-                if (isTypeBuffer)
-                {
-                    type = SamplerType.TextureBuffer;
-                }
-            }
-
-            int coordsCount = type.GetDimensions();
-
-            for (int index = 0; index < coordsCount; index++)
-            {
-                sourcesList.Add(Ra());
-            }
-
-            if (Sample1DAs2D && type == SamplerType.Texture1D)
-            {
-                sourcesList.Add(ConstF(0));
-
-                type = SamplerType.Texture2D;
-            }
-
-            if (op.IsArray)
-            {
-                sourcesList.Add(arrayIndex);
-
-                type |= SamplerType.Array;
-            }
-
-            Operand lodValue = hasLod ? Rb() : ConstF(0);
-
-            Operand packedOffs = op.HasOffset ? Rb() : null;
-
-            if (op.HasDepthCompare)
-            {
-                sourcesList.Add(Rb());
-
-                type |= SamplerType.Shadow;
-            }
-
-            if ((op.LodMode == TextureLodMode.LodZero  ||
-                 op.LodMode == TextureLodMode.LodLevel ||
-                 op.LodMode == TextureLodMode.LodLevelA) && !op.IsMultisample && type != SamplerType.TextureBuffer)
-            {
-                sourcesList.Add(lodValue);
-
-                flags |= TextureFlags.LodLevel;
-            }
-
-            if (op.HasOffset)
-            {
-                for (int index = 0; index < coordsCount; index++)
-                {
-                    sourcesList.Add(context.BitfieldExtractS32(packedOffs, Const(index * 4), Const(4)));
-                }
-
-                flags |= TextureFlags.Offset;
-            }
-
-            if (op.LodMode == TextureLodMode.LodBias ||
-                op.LodMode == TextureLodMode.LodBiasA)
-            {
-                sourcesList.Add(lodValue);
-
-                flags |= TextureFlags.LodBias;
-            }
-
-            if (op.IsMultisample)
-            {
-                sourcesList.Add(Rb());
-
-                type |= SamplerType.Multisample;
-            }
-
-            Operand[] sources = sourcesList.ToArray();
-
-            int rdIndex = op.Rd.Index;
-
-            Operand GetDest()
-            {
-                if (rdIndex > RegisterConsts.RegisterZeroIndex)
-                {
-                    return Const(0);
-                }
-
-                return Register(rdIndex++, RegisterType.Gpr);
-            }
-
-            int handle = !isBindless ? op.HandleOffset : 0;
-
-            for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
-            {
-                if ((compMask & 1) != 0)
-                {
-                    Operand dest = GetDest();
-
-                    TextureOperation operation = context.CreateTextureOperation(
-                        Instruction.TextureSample,
-                        type,
-                        flags,
-                        handle,
-                        compIndex,
-                        dest,
-                        sources);
-
-                    context.Add(operation);
-                }
-            }
-        }
-
-        private static int GetComponents(IntegerSize size)
-        {
-            return size switch
-            {
-                IntegerSize.B64   => 2,
-                IntegerSize.B128  => 4,
-                IntegerSize.UB128 => 4,
-                _                 => 1
-            };
-        }
-
-        private static int GetComponentSizeInBytesLog2(IntegerSize size)
-        {
-            return size switch
-            {
-                IntegerSize.U8    => 0,
-                IntegerSize.S8    => 0,
-                IntegerSize.U16   => 1,
-                IntegerSize.S16   => 1,
-                IntegerSize.B32   => 2,
-                IntegerSize.B64   => 3,
-                IntegerSize.B128  => 4,
-                IntegerSize.UB128 => 4,
-                _                 => 2
-            };
-        }
-
-        private static TextureFormat GetTextureFormat(IntegerSize size)
-        {
-            return size switch
-            {
-                IntegerSize.U8    => TextureFormat.R8Uint,
-                IntegerSize.S8    => TextureFormat.R8Sint,
-                IntegerSize.U16   => TextureFormat.R16Uint,
-                IntegerSize.S16   => TextureFormat.R16Sint,
-                IntegerSize.B32   => TextureFormat.R32Uint,
-                IntegerSize.B64   => TextureFormat.R32G32Uint,
-                IntegerSize.B128  => TextureFormat.R32G32B32A32Uint,
-                IntegerSize.UB128 => TextureFormat.R32G32B32A32Uint,
-                _                 => TextureFormat.R32Uint
-            };
-        }
-
-        private static int GetComponentSizeInBytesLog2(ReductionType type)
-        {
-            return type switch
-            {
-                ReductionType.U32         => 2,
-                ReductionType.S32         => 2,
-                ReductionType.U64         => 3,
-                ReductionType.FP32FtzRn   => 2,
-                ReductionType.FP16x2FtzRn => 2,
-                ReductionType.S64         => 3,
-                ReductionType.SD32        => 2,
-                ReductionType.SD64        => 3,
-                _                         => 2
-            };
-        }
-
-        private static TextureFormat GetTextureFormat(ReductionType type)
-        {
-            return type switch
-            {
-                ReductionType.U32         => TextureFormat.R32Uint,
-                ReductionType.S32         => TextureFormat.R32Sint,
-                ReductionType.U64         => TextureFormat.R32G32Uint,
-                ReductionType.FP32FtzRn   => TextureFormat.R32Float,
-                ReductionType.FP16x2FtzRn => TextureFormat.R16G16Float,
-                ReductionType.S64         => TextureFormat.R32G32Uint,
-                ReductionType.SD32        => TextureFormat.R32Uint,
-                ReductionType.SD64        => TextureFormat.R32G32Uint,
-                _                         => TextureFormat.R32Uint
-            };
-        }
-
-        private static TextureFlags GetAtomicOpFlags(AtomicOp op)
-        {
-            return op switch
-            {
-                AtomicOp.Add                => TextureFlags.Add,
-                AtomicOp.Minimum            => TextureFlags.Minimum,
-                AtomicOp.Maximum            => TextureFlags.Maximum,
-                AtomicOp.Increment          => TextureFlags.Increment,
-                AtomicOp.Decrement          => TextureFlags.Decrement,
-                AtomicOp.BitwiseAnd         => TextureFlags.BitwiseAnd,
-                AtomicOp.BitwiseOr          => TextureFlags.BitwiseOr,
-                AtomicOp.BitwiseExclusiveOr => TextureFlags.BitwiseXor,
-                AtomicOp.Swap               => TextureFlags.Swap,
-                _                           => TextureFlags.Add
-            };
-        }
-
-        private static SamplerType ConvertSamplerType(ImageDimensions target)
-        {
-            return target switch
-            {
-                ImageDimensions.Image1D      => SamplerType.Texture1D,
-                ImageDimensions.ImageBuffer  => SamplerType.TextureBuffer,
-                ImageDimensions.Image1DArray => SamplerType.Texture1D | SamplerType.Array,
-                ImageDimensions.Image2D      => SamplerType.Texture2D,
-                ImageDimensions.Image2DArray => SamplerType.Texture2D | SamplerType.Array,
-                ImageDimensions.Image3D      => SamplerType.Texture3D,
-                _                            => SamplerType.None
-            };
-        }
-
-        private static SamplerType ConvertSamplerType(TextureDimensions dimensions)
+        private static SamplerType ConvertSamplerType(TexDim dimensions)
         {
             return dimensions switch
             {
-                TextureDimensions.Texture1D   => SamplerType.Texture1D,
-                TextureDimensions.Texture2D   => SamplerType.Texture2D,
-                TextureDimensions.Texture3D   => SamplerType.Texture3D,
-                TextureDimensions.TextureCube => SamplerType.TextureCube,
+                TexDim._1d => SamplerType.Texture1D,
+                TexDim.Array1d => SamplerType.Texture1D | SamplerType.Array,
+                TexDim._2d => SamplerType.Texture2D,
+                TexDim.Array2d => SamplerType.Texture2D | SamplerType.Array,
+                TexDim._3d => SamplerType.Texture3D,
+                TexDim.Array3d => SamplerType.Texture3D | SamplerType.Array,
+                TexDim.Cube => SamplerType.TextureCube,
+                TexDim.ArrayCube => SamplerType.TextureCube | SamplerType.Array,
                 _ => throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".")
             };
         }
 
-        private static SamplerType ConvertSamplerType(TextureTarget type)
+        private static SamplerType ConvertSamplerType(TexsTarget type)
         {
             switch (type)
             {
-                case TextureTarget.Texture1DLodZero:
+                case TexsTarget.Texture1DLodZero:
                     return SamplerType.Texture1D;
 
-                case TextureTarget.Texture2D:
-                case TextureTarget.Texture2DLodZero:
-                case TextureTarget.Texture2DLodLevel:
+                case TexsTarget.Texture2D:
+                case TexsTarget.Texture2DLodZero:
+                case TexsTarget.Texture2DLodLevel:
                     return SamplerType.Texture2D;
 
-                case TextureTarget.Texture2DDepthCompare:
-                case TextureTarget.Texture2DLodLevelDepthCompare:
-                case TextureTarget.Texture2DLodZeroDepthCompare:
+                case TexsTarget.Texture2DDepthCompare:
+                case TexsTarget.Texture2DLodLevelDepthCompare:
+                case TexsTarget.Texture2DLodZeroDepthCompare:
                     return SamplerType.Texture2D | SamplerType.Shadow;
 
-                case TextureTarget.Texture2DArray:
-                case TextureTarget.Texture2DArrayLodZero:
+                case TexsTarget.Texture2DArray:
+                case TexsTarget.Texture2DArrayLodZero:
                     return SamplerType.Texture2D | SamplerType.Array;
 
-                case TextureTarget.Texture2DArrayLodZeroDepthCompare:
+                case TexsTarget.Texture2DArrayLodZeroDepthCompare:
                     return SamplerType.Texture2D | SamplerType.Array | SamplerType.Shadow;
 
-                case TextureTarget.Texture3D:
-                case TextureTarget.Texture3DLodZero:
+                case TexsTarget.Texture3D:
+                case TexsTarget.Texture3DLodZero:
                     return SamplerType.Texture3D;
 
-                case TextureTarget.TextureCube:
-                case TextureTarget.TextureCubeLodLevel:
+                case TexsTarget.TextureCube:
+                case TexsTarget.TextureCubeLodLevel:
                     return SamplerType.TextureCube;
             }
 
             return SamplerType.None;
         }
 
-        private static SamplerType ConvertSamplerType(TexelLoadTarget type)
+        private static SamplerType ConvertSamplerType(TldsTarget type)
         {
             switch (type)
             {
-                case TexelLoadTarget.Texture1DLodZero:
-                case TexelLoadTarget.Texture1DLodLevel:
+                case TldsTarget.Texture1DLodZero:
+                case TldsTarget.Texture1DLodLevel:
                     return SamplerType.Texture1D;
 
-                case TexelLoadTarget.Texture2DLodZero:
-                case TexelLoadTarget.Texture2DLodZeroOffset:
-                case TexelLoadTarget.Texture2DLodLevel:
-                case TexelLoadTarget.Texture2DLodLevelOffset:
+                case TldsTarget.Texture2DLodZero:
+                case TldsTarget.Texture2DLodZeroOffset:
+                case TldsTarget.Texture2DLodLevel:
+                case TldsTarget.Texture2DLodLevelOffset:
                     return SamplerType.Texture2D;
 
-                case TexelLoadTarget.Texture2DLodZeroMultisample:
+                case TldsTarget.Texture2DLodZeroMultisample:
                     return SamplerType.Texture2D | SamplerType.Multisample;
 
-                case TexelLoadTarget.Texture3DLodZero:
+                case TldsTarget.Texture3DLodZero:
                     return SamplerType.Texture3D;
 
-                case TexelLoadTarget.Texture2DArrayLodZero:
+                case TldsTarget.Texture2DArrayLodZero:
                     return SamplerType.Texture2D | SamplerType.Array;
             }
 
             return SamplerType.None;
         }
 
-        private static TextureFlags ConvertTextureFlags(TextureTarget type)
+        private static TextureFlags ConvertTextureFlags(TexsTarget type)
         {
             switch (type)
             {
-                case TextureTarget.Texture1DLodZero:
-                case TextureTarget.Texture2DLodZero:
-                case TextureTarget.Texture2DLodLevel:
-                case TextureTarget.Texture2DLodLevelDepthCompare:
-                case TextureTarget.Texture2DLodZeroDepthCompare:
-                case TextureTarget.Texture2DArrayLodZero:
-                case TextureTarget.Texture2DArrayLodZeroDepthCompare:
-                case TextureTarget.Texture3DLodZero:
-                case TextureTarget.TextureCubeLodLevel:
+                case TexsTarget.Texture1DLodZero:
+                case TexsTarget.Texture2DLodZero:
+                case TexsTarget.Texture2DLodLevel:
+                case TexsTarget.Texture2DLodLevelDepthCompare:
+                case TexsTarget.Texture2DLodZeroDepthCompare:
+                case TexsTarget.Texture2DArrayLodZero:
+                case TexsTarget.Texture2DArrayLodZeroDepthCompare:
+                case TexsTarget.Texture3DLodZero:
+                case TexsTarget.TextureCubeLodLevel:
                     return TextureFlags.LodLevel;
 
-                case TextureTarget.Texture2D:
-                case TextureTarget.Texture2DDepthCompare:
-                case TextureTarget.Texture2DArray:
-                case TextureTarget.Texture3D:
-                case TextureTarget.TextureCube:
+                case TexsTarget.Texture2D:
+                case TexsTarget.Texture2DDepthCompare:
+                case TexsTarget.Texture2DArray:
+                case TexsTarget.Texture3D:
+                case TexsTarget.TextureCube:
                     return TextureFlags.None;
             }
 
             return TextureFlags.None;
         }
 
-        private static TextureFlags ConvertTextureFlags(TexelLoadTarget type)
+        private static TextureFlags ConvertTextureFlags(TldsTarget type)
         {
             switch (type)
             {
-                case TexelLoadTarget.Texture1DLodZero:
-                case TexelLoadTarget.Texture1DLodLevel:
-                case TexelLoadTarget.Texture2DLodZero:
-                case TexelLoadTarget.Texture2DLodLevel:
-                case TexelLoadTarget.Texture2DLodZeroMultisample:
-                case TexelLoadTarget.Texture3DLodZero:
-                case TexelLoadTarget.Texture2DArrayLodZero:
+                case TldsTarget.Texture1DLodZero:
+                case TldsTarget.Texture1DLodLevel:
+                case TldsTarget.Texture2DLodZero:
+                case TldsTarget.Texture2DLodLevel:
+                case TldsTarget.Texture2DLodZeroMultisample:
+                case TldsTarget.Texture3DLodZero:
+                case TldsTarget.Texture2DArrayLodZero:
                     return TextureFlags.LodLevel;
 
-                case TexelLoadTarget.Texture2DLodZeroOffset:
-                case TexelLoadTarget.Texture2DLodLevelOffset:
+                case TldsTarget.Texture2DLodZeroOffset:
+                case TldsTarget.Texture2DLodLevelOffset:
                     return TextureFlags.LodLevel | TextureFlags.Offset;
             }
 
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitVideoArithmetic.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitVideoArithmetic.cs
new file mode 100644
index 0000000000..43c0035a32
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitVideoArithmetic.cs
@@ -0,0 +1,18 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void Vmad(EmitterContext context)
+        {
+            InstVmad op = context.GetOp<InstVmad>();
+
+            // TODO: Implement properly.
+            context.Copy(GetDest(op.Dest), GetSrcReg(context, op.SrcC));
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitVideo.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitVideoMinMax.cs
similarity index 51%
rename from Ryujinx.Graphics.Shader/Instructions/InstEmitVideo.cs
rename to Ryujinx.Graphics.Shader/Instructions/InstEmitVideoMinMax.cs
index 7b3d9ca515..890b31d669 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitVideo.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitVideoMinMax.cs
@@ -9,47 +9,46 @@ namespace Ryujinx.Graphics.Shader.Instructions
 {
     static partial class InstEmit
     {
-        public static void Vmad(EmitterContext context)
-        {
-            // TODO: Implement properly.
-            context.Copy(GetDest(context), GetSrcC(context));
-        }
-
         public static void Vmnmx(EmitterContext context)
         {
-            OpCodeVideo op = (OpCodeVideo)context.CurrOp;
+            InstVmnmx op = context.GetOp<InstVmnmx>();
 
-            bool max = op.RawOpCode.Extract(56);
-
-            Operand srcA = Extend(context, GetSrcA(context), op.RaSelection, op.RaType);
-            Operand srcC = GetSrcC(context);
+            Operand srcA = Extend(context, GetSrcReg(context, op.SrcA), op.ASelect);
+            Operand srcC = GetSrcReg(context, op.SrcC);
 
             Operand srcB;
 
-            if (op.HasRb)
+            if (op.BVideo)
             {
-                srcB = Extend(context, Register(op.Rb), op.RbSelection, op.RbType);
+                srcB = Extend(context, GetSrcReg(context, op.SrcB), op.BSelect);
             }
             else
             {
-                srcB = Const(op.Immediate);
+                int imm = op.Imm16;
+
+                if ((op.BSelect & VectorSelect.S8B0) != 0)
+                {
+                    imm = (imm << 16) >> 16;
+                }
+
+                srcB = Const(imm);
             }
 
             Operand res;
 
             bool resSigned;
 
-            if ((op.RaType & VideoType.Signed) != (op.RbType & VideoType.Signed))
+            if ((op.ASelect & VectorSelect.S8B0) != (op.BSelect & VectorSelect.S8B0))
             {
                 // Signedness is different, but for max, result will always fit a U32,
                 // since one of the inputs can't be negative, and the result is the one
                 // with highest value. For min, it will always fit on a S32, since
                 // one of the input can't be greater than INT_MAX and we want the lowest value.
-                resSigned = !max;
+                resSigned = !op.Mn;
 
-                res = max ? context.IMaximumU32(srcA, srcB) : context.IMinimumS32(srcA, srcB);
+                res = op.Mn ? context.IMaximumU32(srcA, srcB) : context.IMinimumS32(srcA, srcB);
 
-                if ((op.RaType & VideoType.Signed) != 0)
+                if ((op.ASelect & VectorSelect.S8B0) != 0)
                 {
                     Operand isBGtIntMax = context.ICompareLess(srcB, Const(0));
 
@@ -65,9 +64,9 @@ namespace Ryujinx.Graphics.Shader.Instructions
             else
             {
                 // Ra and Rb have the same signedness, so doesn't matter which one we test.
-                resSigned = (op.RaType & VideoType.Signed) != 0;
+                resSigned = (op.ASelect & VectorSelect.S8B0) != 0;
 
-                if (max)
+                if (op.Mn)
                 {
                     res = resSigned
                         ? context.IMaximumS32(srcA, srcB)
@@ -81,54 +80,62 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 }
             }
 
-            if (op.Saturate)
+            if (op.Sat)
             {
-                if (op.DstSigned && !resSigned)
+                if (op.DFormat && !resSigned)
                 {
                     res = context.IMinimumU32(res, Const(int.MaxValue));
                 }
-                else if (!op.DstSigned && resSigned)
+                else if (!op.DFormat && resSigned)
                 {
                     res = context.IMaximumS32(res, Const(0));
                 }
             }
 
-            switch (op.PostOp)
+            switch (op.VideoOp)
             {
-                case VideoPostOp.Acc:
+                case VideoOp.Acc:
                     res = context.IAdd(res, srcC);
                     break;
-                case VideoPostOp.Max:
-                    res = op.DstSigned ? context.IMaximumS32(res, srcC) : context.IMaximumU32(res, srcC);
+                case VideoOp.Max:
+                    res = op.DFormat ? context.IMaximumS32(res, srcC) : context.IMaximumU32(res, srcC);
                     break;
-                case VideoPostOp.Min:
-                    res = op.DstSigned ? context.IMinimumS32(res, srcC) : context.IMinimumU32(res, srcC);
+                case VideoOp.Min:
+                    res = op.DFormat ? context.IMinimumS32(res, srcC) : context.IMinimumU32(res, srcC);
                     break;
-                case VideoPostOp.Mrg16h:
+                case VideoOp.Mrg16h:
                     res = context.BitfieldInsert(srcC, res, Const(16), Const(16));
                     break;
-                case VideoPostOp.Mrg16l:
+                case VideoOp.Mrg16l:
                     res = context.BitfieldInsert(srcC, res, Const(0), Const(16));
                     break;
-                case VideoPostOp.Mrg8b0:
+                case VideoOp.Mrg8b0:
                     res = context.BitfieldInsert(srcC, res, Const(0), Const(8));
                     break;
-                case VideoPostOp.Mrg8b2:
+                case VideoOp.Mrg8b2:
                     res = context.BitfieldInsert(srcC, res, Const(16), Const(8));
                     break;
             }
 
-            context.Copy(GetDest(context), res);
+            context.Copy(GetDest(op.Dest), res);
         }
 
-        private static Operand Extend(EmitterContext context, Operand src, int sel, VideoType type)
+        private static Operand Extend(EmitterContext context, Operand src, VectorSelect type)
         {
             return type switch
             {
-                VideoType.U8  => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(sel * 8)),  8),
-                VideoType.U16 => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(sel * 16)), 16),
-                VideoType.S8  => SignExtendTo32(context, context.ShiftRightU32(src, Const(sel * 8)),  8),
-                VideoType.S16 => SignExtendTo32(context, context.ShiftRightU32(src, Const(sel * 16)), 16),
+                VectorSelect.U8B0 => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(0)), 8),
+                VectorSelect.U8B1 => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(8)), 8),
+                VectorSelect.U8B2 => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(16)), 8),
+                VectorSelect.U8B3 => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(24)), 8),
+                VectorSelect.U16H0 => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(0)), 16),
+                VectorSelect.U16H1 => ZeroExtendTo32(context, context.ShiftRightU32(src, Const(16)), 16),
+                VectorSelect.S8B0 => SignExtendTo32(context, context.ShiftRightU32(src, Const(0)), 8),
+                VectorSelect.S8B1 => SignExtendTo32(context, context.ShiftRightU32(src, Const(8)), 8),
+                VectorSelect.S8B2 => SignExtendTo32(context, context.ShiftRightU32(src, Const(16)), 8),
+                VectorSelect.S8B3 => SignExtendTo32(context, context.ShiftRightU32(src, Const(24)), 8),
+                VectorSelect.S16H0 => SignExtendTo32(context, context.ShiftRightU32(src, Const(0)), 16),
+                VectorSelect.S16H1 => SignExtendTo32(context, context.ShiftRightU32(src, Const(16)), 16),
                 _ => src
             };
         }
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs
deleted file mode 100644
index 5c16770aba..0000000000
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using Ryujinx.Graphics.Shader.Decoders;
-using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using Ryujinx.Graphics.Shader.Translation;
-
-using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
-using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
-
-namespace Ryujinx.Graphics.Shader.Instructions
-{
-    static partial class InstEmit
-    {
-        public static void Vote(EmitterContext context)
-        {
-            OpCodeVote op = (OpCodeVote)context.CurrOp;
-
-            Operand pred = GetPredicate39(context);
-
-            Operand res = null;
-
-            switch (op.VoteOp)
-            {
-                case VoteOp.All:
-                    res = context.VoteAll(pred);
-                    break;
-                case VoteOp.Any:
-                    res = context.VoteAny(pred);
-                    break;
-                case VoteOp.AllEqual:
-                    res = context.VoteAllEqual(pred);
-                    break;
-            }
-
-            if (res != null)
-            {
-                context.Copy(Register(op.Predicate45), res);
-            }
-            else
-            {
-                context.Config.GpuAccessor.Log($"Invalid vote operation: {op.VoteOp}.");
-            }
-
-            if (!op.Rd.IsRZ)
-            {
-                context.Copy(Register(op.Rd), context.Ballot(pred));
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitWarp.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitWarp.cs
new file mode 100644
index 0000000000..3c8336139c
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitWarp.cs
@@ -0,0 +1,84 @@
+using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.Translation;
+
+using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
+using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
+
+namespace Ryujinx.Graphics.Shader.Instructions
+{
+    static partial class InstEmit
+    {
+        public static void Fswzadd(EmitterContext context)
+        {
+            InstFswzadd op = context.GetOp<InstFswzadd>();
+
+            Operand srcA = GetSrcReg(context, op.SrcA);
+            Operand srcB = GetSrcReg(context, op.SrcB);
+            Operand dest = GetDest(op.Dest);
+
+            context.Copy(dest, context.FPSwizzleAdd(srcA, srcB, op.PnWord));
+
+            InstEmitAluHelper.SetFPZnFlags(context, dest, op.WriteCC);
+        }
+
+        public static void Shfl(EmitterContext context)
+        {
+            InstShfl op = context.GetOp<InstShfl>();
+
+            Operand pred = Register(op.DestPred, RegisterType.Predicate);
+
+            Operand srcA = GetSrcReg(context, op.SrcA);
+
+            Operand srcB = op.BFixShfl ? Const(op.SrcBImm) : GetSrcReg(context, op.SrcB);
+            Operand srcC = op.CFixShfl ? Const(op.SrcCImm) : GetSrcReg(context, op.SrcC);
+
+            (Operand res, Operand valid) = op.ShflMode switch
+            {
+                ShflMode.Idx => context.Shuffle(srcA, srcB, srcC),
+                ShflMode.Up => context.ShuffleUp(srcA, srcB, srcC),
+                ShflMode.Down => context.ShuffleDown(srcA, srcB, srcC),
+                ShflMode.Bfly => context.ShuffleXor(srcA, srcB, srcC),
+                _ => (null, null)
+            };
+
+            context.Copy(GetDest(op.Dest), res);
+            context.Copy(pred, valid);
+        }
+
+        public static void Vote(EmitterContext context)
+        {
+            InstVote op = context.GetOp<InstVote>();
+
+            Operand pred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
+            Operand res = null;
+
+            switch (op.VoteMode)
+            {
+                case VoteMode.All:
+                    res = context.VoteAll(pred);
+                    break;
+                case VoteMode.Any:
+                    res = context.VoteAny(pred);
+                    break;
+                case VoteMode.Eq:
+                    res = context.VoteAllEqual(pred);
+                    break;
+            }
+
+            if (res != null)
+            {
+                context.Copy(Register(op.VpDest, RegisterType.Predicate), res);
+            }
+            else
+            {
+                context.Config.GpuAccessor.Log($"Invalid vote operation: {op.VoteMode}.");
+            }
+
+            if (op.Dest != RegisterConsts.RegisterZeroIndex)
+            {
+                context.Copy(GetDest(op.Dest), context.Ballot(pred));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs b/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs
index 67e2495742..76a520075f 100644
--- a/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs
@@ -7,12 +7,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 {
     static class Lop3Expression
     {
-        public static Operand GetFromTruthTable(
-            EmitterContext context,
-            Operand        srcA,
-            Operand        srcB,
-            Operand        srcC,
-            int            imm)
+        public static Operand GetFromTruthTable(EmitterContext context, Operand srcA, Operand srcB, Operand srcC, int imm)
         {
             Operand expr = null;
 
@@ -45,7 +40,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
             int map;
 
             // Encode into gray code.
-            map  = ((imm >> 0) & 1) << 0;
+            map = ((imm >> 0) & 1) << 0;
             map |= ((imm >> 1) & 1) << 4;
             map |= ((imm >> 2) & 1) << 1;
             map |= ((imm >> 3) & 1) << 5;
diff --git a/Ryujinx.Graphics.Shader/Translation/ControlFlowGraph.cs b/Ryujinx.Graphics.Shader/Translation/ControlFlowGraph.cs
index fb0535c811..65328fd7fb 100644
--- a/Ryujinx.Graphics.Shader/Translation/ControlFlowGraph.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ControlFlowGraph.cs
@@ -129,6 +129,31 @@ namespace Ryujinx.Graphics.Shader.Translation
                 }
             }
 
+            // Remove unreachable blocks.
+            bool hasUnreachable;
+
+            do
+            {
+                hasUnreachable = false;
+
+                for (int blkIndex = 1; blkIndex < blocks.Count; blkIndex++)
+                {
+                    BasicBlock block = blocks[blkIndex];
+
+                    if (block.Predecessors.Count == 0)
+                    {
+                        block.Next = null;
+                        block.Branch = null;
+                        blocks.RemoveAt(blkIndex--);
+                        hasUnreachable = true;
+                    }
+                    else
+                    {
+                        block.Index = blkIndex;
+                    }
+                }
+            } while (hasUnreachable);
+
             return new ControlFlowGraph(blocks.ToArray());
         }
 
diff --git a/Ryujinx.Graphics.Shader/Translation/Dominance.cs b/Ryujinx.Graphics.Shader/Translation/Dominance.cs
index da4a38da7b..09c2eb0fdc 100644
--- a/Ryujinx.Graphics.Shader/Translation/Dominance.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Dominance.cs
@@ -1,5 +1,4 @@
 using Ryujinx.Graphics.Shader.IntermediateRepresentation;
-using System.Collections.Generic;
 
 namespace Ryujinx.Graphics.Shader.Translation
 {
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
index c96b75a5a0..bdfd9626a2 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
@@ -1,6 +1,8 @@
 using Ryujinx.Graphics.Shader.Decoders;
 using Ryujinx.Graphics.Shader.IntermediateRepresentation;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
 
 using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
 
@@ -9,7 +11,7 @@ namespace Ryujinx.Graphics.Shader.Translation
     class EmitterContext
     {
         public Block  CurrBlock { get; set; }
-        public OpCode CurrOp    { get; set; }
+        public InstOp CurrOp    { get; set; }
 
         public ShaderConfig Config { get; }
 
@@ -30,6 +32,13 @@ namespace Ryujinx.Graphics.Shader.Translation
             _labels = new Dictionary<ulong, Operand>();
         }
 
+        public T GetOp<T>() where T : unmanaged
+        {
+            Debug.Assert(Unsafe.SizeOf<T>() == sizeof(ulong));
+            ulong op = CurrOp.RawOpCode;
+            return Unsafe.As<ulong, T>(ref op);
+        }
+
         public Operand Add(Instruction inst, Operand dest = null, params Operand[] sources)
         {
             Operation operation = new Operation(inst, dest, sources);
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs b/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs
index ff5932e15a..0ad172da88 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderHeader.cs
@@ -1,5 +1,6 @@
 using Ryujinx.Graphics.Shader.Decoders;
 using System;
+using System.Runtime.InteropServices;
 
 namespace Ryujinx.Graphics.Shader.Translation
 {
@@ -113,11 +114,13 @@ namespace Ryujinx.Graphics.Shader.Translation
 
         public ShaderHeader(IGpuAccessor gpuAccessor, ulong address)
         {
-            int commonWord0 = gpuAccessor.MemoryRead<int>(address + 0);
-            int commonWord1 = gpuAccessor.MemoryRead<int>(address + 4);
-            int commonWord2 = gpuAccessor.MemoryRead<int>(address + 8);
-            int commonWord3 = gpuAccessor.MemoryRead<int>(address + 12);
-            int commonWord4 = gpuAccessor.MemoryRead<int>(address + 16);
+            ReadOnlySpan<int> header = MemoryMarshal.Cast<ulong, int>(gpuAccessor.GetCode(address, 0x50));
+
+            int commonWord0 = header[0];
+            int commonWord1 = header[1];
+            int commonWord2 = header[2];
+            int commonWord3 = header[3];
+            int commonWord4 = header[4];
 
             SphType = commonWord0.Extract(0, 5);
             Version = commonWord0.Extract(5, 5);
@@ -164,9 +167,9 @@ namespace Ryujinx.Graphics.Shader.Translation
 
             ImapTypes = new ImapPixelType[32];
 
-            for (ulong i = 0; i < 32; i++)
+            for (int i = 0; i < 32; i++)
             {
-                byte imap = gpuAccessor.MemoryRead<byte>(address + 0x18 + i);
+                byte imap = (byte)(header[6 + (i >> 2)] >> ((i & 3) * 8));
 
                 ImapTypes[i] = new ImapPixelType(
                     (PixelImap)((imap >> 0) & 3),
@@ -175,8 +178,8 @@ namespace Ryujinx.Graphics.Shader.Translation
                     (PixelImap)((imap >> 6) & 3));
             }
 
-            int type2OmapTarget = gpuAccessor.MemoryRead<int>(address + 0x48);
-            int type2Omap       = gpuAccessor.MemoryRead<int>(address + 0x4c);
+            int type2OmapTarget = header[18];
+            int type2Omap       = header[19];
 
             OmapTargets = new OmapTarget[8];
 
diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs
index 1abf19d716..0a0ee4a715 100644
--- a/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -150,9 +150,12 @@ namespace Ryujinx.Graphics.Shader.Translation
                     {
                         for (int index = 0; index < block.OpCodes.Count; index++)
                         {
-                            if (block.OpCodes[index] is OpCodeTextureBase texture)
+                            InstOp op = block.OpCodes[index];
+
+                            if (op.Props.HasFlag(InstProps.Tex))
                             {
-                                config.TextureHandlesForCache.Add(texture.HandleOffset);
+                                int tidB = (int)((op.RawOpCode >> 36) & 0x1fff);
+                                config.TextureHandlesForCache.Add(tidB);
                             }
                         }
                     }
@@ -241,15 +244,15 @@ namespace Ryujinx.Graphics.Shader.Translation
         {
             for (int opIndex = 0; opIndex < block.OpCodes.Count; opIndex++)
             {
-                OpCode op = block.OpCodes[opIndex];
+                InstOp op = block.OpCodes[opIndex];
 
-                if ((context.Config.Options.Flags & TranslationFlags.DebugMode) != 0)
+                if (context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode))
                 {
                     string instName;
 
                     if (op.Emitter != null)
                     {
-                        instName = op.Emitter.Method.Name;
+                        instName = op.Name.ToString();
                     }
                     else
                     {
@@ -263,31 +266,36 @@ namespace Ryujinx.Graphics.Shader.Translation
                     context.Add(new CommentNode(dbgComment));
                 }
 
-                if (op.NeverExecute)
+                InstConditional opConditional = new InstConditional(op.RawOpCode);
+
+                bool noPred = op.Props.HasFlag(InstProps.NoPred);
+                if (!noPred && opConditional.Pred == RegisterConsts.PredicateTrueIndex && opConditional.PredInv)
                 {
                     continue;
                 }
 
                 Operand predSkipLbl = null;
 
-                bool skipPredicateCheck = op is OpCodeBranch opBranch && !opBranch.PushTarget;
-
-                if (op is OpCodeBranchPop opBranchPop)
+                if (op.Name == InstName.Sync || op.Name == InstName.Brk)
                 {
                     // If the instruction is a SYNC or BRK instruction with only one
                     // possible target address, then the instruction is basically
                     // just a simple branch, we can generate code similar to branch
                     // instructions, with the condition check on the branch itself.
-                    skipPredicateCheck = opBranchPop.Targets.Count < 2;
+                    noPred = block.SyncTargets.Count <= 1;
+                }
+                else if (op.Name == InstName.Bra)
+                {
+                    noPred = true;
                 }
 
-                if (!(op.Predicate.IsPT || skipPredicateCheck))
+                if (!(opConditional.Pred == RegisterConsts.PredicateTrueIndex || noPred))
                 {
                     Operand label;
 
-                    if (opIndex == block.OpCodes.Count - 1 && block.Next != null)
+                    if (opIndex == block.OpCodes.Count - 1 && block.HasNext())
                     {
-                        label = context.GetLabel(block.Next.Address);
+                        label = context.GetLabel(block.Successors[0].Address);
                     }
                     else
                     {
@@ -296,9 +304,9 @@ namespace Ryujinx.Graphics.Shader.Translation
                         predSkipLbl = label;
                     }
 
-                    Operand pred = Register(op.Predicate);
+                    Operand pred = Register(opConditional.Pred, RegisterType.Predicate);
 
-                    if (op.InvertPredicate)
+                    if (opConditional.PredInv)
                     {
                         context.BranchIfTrue(label, pred);
                     }
diff --git a/Ryujinx.ShaderTools/Program.cs b/Ryujinx.ShaderTools/Program.cs
index fba0b3ad88..43b9494e70 100644
--- a/Ryujinx.ShaderTools/Program.cs
+++ b/Ryujinx.ShaderTools/Program.cs
@@ -18,9 +18,9 @@ namespace Ryujinx.ShaderTools
                 _data = data;
             }
 
-            public T MemoryRead<T>(ulong address) where T : unmanaged
+            public ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
             {
-                return MemoryMarshal.Cast<byte, T>(new ReadOnlySpan<byte>(_data).Slice((int)address))[0];
+                return MemoryMarshal.Cast<byte, ulong>(new ReadOnlySpan<byte>(_data).Slice((int)address));
             }
         }