private static void CollectBasicUsages(IList <BasicBlock> blocks, Dictionary <Register, RegisterUsage> usages) { foreach (var block in blocks) { foreach (var ins in block.Instructions) { var instructionInBlock = new InstructionInBlock(ins, block); for (int i = 0; i < ins.Registers.Count; ++i) { var reg = ins.Registers[i]; RegisterUsage u; if (!usages.TryGetValue(reg, out u)) { u = new RegisterUsage(reg); usages.Add(reg, u); } u.Blocks.Add(block); u.Add(instructionInBlock, i); } } } }
public String StringifyInstruction(RegisterUsage Usage, Stringify AsString, int Val) { switch (Usage) { case RegisterUsage.Stringify: return(AsString(this)); case RegisterUsage.Register: RegisterCase: return("R[" + Val + "]"); case RegisterUsage.Constant: ConstantCase: return(this.Constants.ByIdx(Val).GetString()); case RegisterUsage.ConstantRegister: if (Val < 0x100) { goto RegisterCase; } else { Val -= 0x100; goto ConstantCase; } case RegisterUsage.Numeric: return(Val.ToString()); default: break; } return(null); }
/// <summary> /// Will replace all read and write usages of 'replaced' with 'replacement', /// and nop resulting assigments to itself. /// </summary> public void ReplaceRegister(RegisterUsage replaced, RegisterUsage replacement) { if (replaced.Register.KeepWith != replacement.Register.KeepWith) { throw new ArgumentException("New register has different keep-with value"); } if (replaced.Register.KeepWith == RFlags.KeepWithPrev) { throw new ArgumentException("can not replace a keep with prev register"); } Register replR = replaced.Register, replR2 = null; RegisterUsage replaced2 = null, replacement2 = null; if (replaced.Register.KeepWith == RFlags.KeepWithNext) { replaced2 = GetBasicUsage(_body.GetNext(replaced.Register)); replacement2 = GetBasicUsage(_body.GetNext(replacement.Register)); replR2 = replaced2.Register; } foreach (var ins in replaced.Instructions) { var instr = ins.Instruction; var regs = instr.Registers; for (int i = 0; i < regs.Count; ++i) { if (regs[i] == replR) { regs[i] = replacement.Register; replacement.Add(ins, i); } else if (regs[i] == replR2) { Debug.Assert(replacement2 != null, "replacement2 != null"); regs[i] = replacement2.Register; replacement2.Add(ins, i); } } if (instr.Code.IsMove() && instr.Registers[0] == instr.Registers[1]) { ConvertToNop(ins); } } replaced.Clear(); _usages.Remove(replaced.Register); if (replaced2 != null) { replaced2.Clear(); _usages.Remove(replaced2.Register); } }
public void Add(SourceReg sr, RegisterUsage usage, int offset = 0) { if (sr.d != 0) { Add(sr.itype, PrefixFromType(sr.itype, sr.programType) + sr.n.ToString(), sr.n, RegisterUsage.Vector4); Add(sr.type, PrefixFromType(sr.type, sr.programType) + sr.o.ToString(), sr.o, RegisterUsage.Vector4Array); return; } Add(sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage); }
private void SetABCField(RegisterUsage Usage, TextBox Box, Stub.Stringify AsString, int Val) { Box.Text = "No Impl"; String Str = SelectedStub.StringifyInstruction(Usage, AsString, Val); if (Str != null) { Box.Text = " = " + Str; } }
public RegisterUsage GetBasicUsage(Register r) { RegisterUsage ret; if (_usages.TryGetValue(r, out ret)) { return(ret); } if (!_body.Registers.Contains(r)) { throw new InvalidOperationException(); } ret = new RegisterUsage(r); _usages.Add(r, ret); return(ret); }
public String DecompileInstruction(RegisterUsage Usage, Stringify AsString, int Val) { switch (Usage) { case RegisterUsage.Stringify: return(AsString(this)); case RegisterUsage.Register: RegisterCase: return("var_" + Val); case RegisterUsage.Constant: ConstantCase: Constant Const = this.Constants.ByIdx(Val); if (Const.Type == ConstantType.STRING) { return("\"" + Const.GetString() + "\""); } return(Const.GetString()); case RegisterUsage.ConstantRegister: if (Val < 0x100) { goto RegisterCase; } else { Val -= 0x100; goto ConstantCase; } case RegisterUsage.Numeric: return(Val.ToString()); default: break; } return(null); }
public void Add(RegType type, string name, int number, RegisterUsage usage) { foreach (var entry in mEntries) { if (entry.type == type && entry.name == name && entry.number == number) { if (entry.usage != usage) { throw new InvalidOperationException("Cannot use register in multiple ways yet (mat4/vec4)"); } return; } } { var entry = new Entry(); entry.type = type; entry.name = name; entry.number = number; entry.usage = usage; mEntries.Add(entry); } }
public static IEnumerable <Operation> DevirtualizeRegisters(IReadOnlyList <Operation> code) { var ru = new RegisterUsage(code); var replace = new Dictionary <int, Register.RegisterId>(); foreach (var id in ru.GetPrioritisedVirtualRegisters()) { var n = ru.CanNotReplace(id); var to = PrioritisedRegisters.First(r => !n.Contains(RegisterUsage.ToReg(r))); replace[id] = to; ru.Replace(id, RegisterUsage.ToReg(to)); } Operand Replace(Operand op) { return(op switch { StubRegister stubRegister => new Register(replace[stubRegister.Number], stubRegister.Size), Memory memory => new Memory(Replace(memory.Address), memory.Size), Shift shift => new Shift(Replace(shift.Register) as AnyRegister, shift.Shft), _ => op }); }
public void Add (RegType type, string name, int number, RegisterUsage usage) { foreach (var entry in mEntries) { if (entry.type == type && entry.name == name && entry.number == number) { if (entry.usage != usage) { throw new InvalidOperationException ("Cannot use register in multiple ways yet (mat4/vec4)"); } return; } } { var entry = new Entry (); entry.type = type; entry.name = name; entry.number = number; entry.usage = usage; mEntries.Add (entry); } }
public void Add(DestReg dr, RegisterUsage usage) { Add (dr.type, dr.ToGLSL(false), dr.n, usage); }
public void Add(SamplerReg sr, RegisterUsage usage) { Add (sr.type, sr.ToGLSL(), sr.n, usage); }
public void Add(SourceReg sr, RegisterUsage usage, int offset = 0) { Add (sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage); }
/// <summary> /// Will replace all read and write usages of 'replaced' with 'replacement', /// and nop resulting assigments to itself. /// </summary> public void ReplaceRegister(RegisterUsage replaced, RegisterUsage replacement) { if (replaced.Register.KeepWith != replacement.Register.KeepWith) throw new ArgumentException("New register has different keep-with value"); if (replaced.Register.KeepWith == RFlags.KeepWithPrev) throw new ArgumentException("can not replace a keep with prev register"); Register replR = replaced.Register, replR2 = null; RegisterUsage replaced2 = null, replacement2 = null; if (replaced.Register.KeepWith == RFlags.KeepWithNext) { replaced2 = GetBasicUsage(_body.GetNext(replaced.Register)); replacement2 = GetBasicUsage(_body.GetNext(replacement.Register)); replR2 = replaced2.Register; } foreach (var ins in replaced.Instructions) { var instr = ins.Instruction; var regs = instr.Registers; for (int i = 0; i < regs.Count; ++i) { if (regs[i] == replR) { regs[i] = replacement.Register; replacement.Add(ins, i); } else if (regs[i] == replR2) { Debug.Assert(replacement2 != null, "replacement2 != null"); regs[i] = replacement2.Register; replacement2.Add(ins, i); } } if (instr.Code.IsMove() && instr.Registers[0] == instr.Registers[1]) { ConvertToNop(ins); } } replaced.Clear(); _usages.Remove(replaced.Register); if (replaced2 != null) { replaced2.Clear(); _usages.Remove(replaced2.Register); } }
public void Add(DestReg dr, RegisterUsage usage) { Add(dr.type, dr.ToGLSL(false), dr.n, usage); }
public void Add(SourceReg sr, RegisterUsage usage, int offset = 0) { Add(sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage); }
public void Add(SourceReg sr, RegisterUsage usage, int offset = 0) { if (sr.d != 0) { Add (sr.type, PrefixFromType(sr.type, sr.programType) + sr.n.ToString(), sr.n, RegisterUsage.Vector4Array); return; } Add (sr.type, sr.ToGLSL(false, offset), sr.n + offset, usage); }
public void Add(SamplerReg sr, RegisterUsage usage) { Add(sr.type, sr.ToGLSL(), sr.n, usage); }
public RegisterUsage GetBasicUsage(Register r) { RegisterUsage ret; if (_usages.TryGetValue(r, out ret)) return ret; if(!_body.Registers.Contains(r)) throw new InvalidOperationException(); ret = new RegisterUsage(r); _usages.Add(r, ret); return ret; }
private static void CollectBasicUsages(IList<BasicBlock> blocks, Dictionary<Register, RegisterUsage> usages) { foreach (var block in blocks) { foreach (var ins in block.Instructions) { var instructionInBlock = new InstructionInBlock(ins, block); for (int i = 0; i < ins.Registers.Count; ++i) { var reg = ins.Registers[i]; RegisterUsage u; if (!usages.TryGetValue(reg, out u)) { u = new RegisterUsage(reg); usages.Add(reg, u); } u.Blocks.Add(block); u.Add(instructionInBlock, i); } } } }
public void Add(SourceReg sr, RegisterUsage usage) { Add (sr.type, sr.ToGLSL(false), sr.n, usage); }