public byte[] instructionData(ushort address) { byte data = read(address); if (!instMode.ContainsKey(data)) { return new byte[] { data } } ; InstTable mode = instMode[data]; if (instSize[mode.mode] == 1) { return new byte[] { data } } ; byte imm1 = read((ushort)(address + 1)); if (instSize[mode.mode] == 2) { return new byte[] { data, imm1 } } ; byte imm2 = read((ushort)(address + 2)); return(new byte[] { data, imm1, imm2 }); } } }
private static void FillBlock(ShaderConfig config, Block block, ulong limitAddress, ulong startAddress) { IGpuAccessor gpuAccessor = config.GpuAccessor; ulong address = block.Address; int bufferOffset = 0; ReadOnlySpan <ulong> buffer = ReadOnlySpan <ulong> .Empty; InstOp op = default; do { if (address + 7 >= limitAddress) { break; } // Ignore scheduling instructions, which are written every 32 bytes. if ((address & 0x1f) == 0) { address += 8; bufferOffset++; continue; } if (bufferOffset >= buffer.Length) { buffer = gpuAccessor.GetCode(startAddress + address, 8); bufferOffset = 0; } ulong opCode = buffer[bufferOffset++]; op = InstTable.GetOp(address, opCode); if (op.Props.HasFlag(InstProps.TexB)) { config.SetUsedFeature(FeatureFlags.Bindless); } if (op.Name == InstName.Ald || op.Name == InstName.Ast || op.Name == InstName.Ipa) { 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 (!op.Props.HasFlag(InstProps.Bra)); block.EndAddress = address; }
public string instructionAsm(ushort address) { byte data = read(address); byte imm1 = read((ushort)(address + 1)); byte imm2 = read((ushort)(address + 2)); if (!instMode.ContainsKey(data)) { return("---"); } InstTable mode = instMode[data]; return(String.Format(mode.name + instFormat[mode.mode], new object[] { (ushort)(address + 2 + (sbyte)imm1), imm1 | (imm2 << 8), imm1 })); }