private static void FillBlock( ReadOnlySpan <byte> code, Block block, ulong limitAddress, ulong startAddress) { ulong address = block.Address; do { if (address + 7 >= limitAddress) { break; } // Ignore scheduling instructions, which are written every 32 bytes. if ((address & 0x1f) == 0) { address += 8; continue; } uint word0 = BinaryPrimitives.ReadUInt32LittleEndian(code.Slice((int)(startAddress + address))); uint word1 = BinaryPrimitives.ReadUInt32LittleEndian(code.Slice((int)(startAddress + address + 4))); ulong opAddress = address; address += 8; long opCode = word0 | (long)word1 << 32; (InstEmitter emitter, OpCodeTable.OpActivator opActivator) = OpCodeTable.GetEmitter(opCode); if (emitter == null) { // TODO: Warning, illegal encoding. block.OpCodes.Add(new OpCode(null, opAddress, opCode)); continue; } if (opActivator == null) { throw new ArgumentNullException(nameof(opActivator)); } OpCode op = (OpCode)opActivator(emitter, opAddress, opCode); block.OpCodes.Add(op); }while (!IsBranch(block.GetLastOp())); block.EndAddress = address; block.UpdatePushOps(); }
private static void FillBlock( IGpuAccessor gpuAccessor, Block block, ulong limitAddress, ulong startAddress) { ulong address = block.Address; do { if (address + 7 >= limitAddress) { break; } // Ignore scheduling instructions, which are written every 32 bytes. if ((address & 0x1f) == 0) { address += 8; continue; } ulong opAddress = address; address += 8; long opCode = gpuAccessor.MemoryRead <long>(startAddress + opAddress); (InstEmitter emitter, OpCodeTable.OpActivator opActivator) = OpCodeTable.GetEmitter(opCode); if (emitter == null) { // TODO: Warning, illegal encoding. block.OpCodes.Add(new OpCode(null, opAddress, opCode)); continue; } if (opActivator == null) { throw new ArgumentNullException(nameof(opActivator)); } OpCode op = (OpCode)opActivator(emitter, opAddress, opCode); block.OpCodes.Add(op); }while (!IsBranch(block.GetLastOp())); block.EndAddress = address; block.UpdatePushOps(); }
private static void FillBlock( IGalMemory memory, Block block, ulong limitAddress, ulong startAddress) { ulong address = block.Address; do { if (address >= limitAddress) { break; } //Ignore scheduling instructions, which are written every 32 bytes. if (((address - startAddress) & 0x1f) == 0) { address += 8; continue; } uint word0 = (uint)memory.ReadInt32((long)(address + 0)); uint word1 = (uint)memory.ReadInt32((long)(address + 4)); ulong opAddress = address; address += 8; long opCode = word0 | (long)word1 << 32; (InstEmitter emitter, Type opCodeType) = OpCodeTable.GetEmitter(opCode); if (emitter == null) { //TODO: Warning, illegal encoding. continue; } OpCode op = MakeOpCode(opCodeType, emitter, opAddress, opCode); block.OpCodes.Add(op); }while (!IsBranch(block.GetLastOp())); block.EndAddress = address; block.UpdateSsyOpCodes(); }
private static void FillBlock(ShaderConfig config, Block block, ulong limitAddress, ulong startAddress) { IGpuAccessor gpuAccessor = config.GpuAccessor; ulong address = block.Address; do { if (address + 7 >= limitAddress) { break; } // Ignore scheduling instructions, which are written every 32 bytes. if ((address & 0x1f) == 0) { address += 8; continue; } ulong opAddress = address; address += 8; long opCode = gpuAccessor.MemoryRead <long>(startAddress + opAddress); (InstEmitter emitter, OpCodeTable.MakeOp makeOp) = OpCodeTable.GetEmitter(opCode); if (emitter == null) { // TODO: Warning, illegal encoding. block.OpCodes.Add(new OpCode(null, opAddress, opCode)); continue; } if (makeOp == null) { throw new ArgumentNullException(nameof(makeOp)); } OpCode op = makeOp(emitter, opAddress, 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)) { config.SetUsedFeature(FeatureFlags.Bindless); } // Populate used attributes. if (op is IOpCodeAttribute opAttr) { SetUserAttributeUses(config, opAttr); } block.OpCodes.Add(op); }while (!IsControlFlowChange(block.GetLastOp())); block.EndAddress = address; block.UpdatePushOps(); }