public TreeNode(InstOp op, byte order) { Op = op; Uses = new List <TreeNodeUse>(); Type = TreeNodeType.Op; Order = order; }
public bool AddInstruction(InstOp op, string arg0, string arg1, string special = null, OpModifier opModifier = OpModifier.None) { _currentScope.Instructions.AddRecord(new InstEntry(op, arg0, arg1, opModifier)); Debug.PrintDbg($"{op} {arg0} {arg1} {opModifier}"); return(true); }
public Inst(InstOp Op = default, uint Out = default, uint Arg = default, slice <int> Rune = default) { this.Op = Op; this.Out = Out; this.Arg = Arg; this.Rune = Rune; }
public InstEntry(InstOp op, string arg0, string arg1, OpModifier opModifier = OpModifier.None) { Op = op; Arg0 = arg0; Arg1 = arg1; OpModifier = opModifier; }
public Instruction(InstOp op, int arg0, int arg1, int spcl0, int spcl1, OpModifier modifier) { Op = op; Arg0 = arg0; Arg1 = arg1; Spcl0 = spcl0; Spcl1 = spcl1; Modifier = modifier; }
public static @string String(this InstOp i) { if (uint(i) >= uint(len(instOpNames))) { return(""); } return(instOpNames[i]); }
public string FormatInstruction(InstOp opcode, int arg0, int arg1, int spcl1, int spcl2, InstOp mode) { var ret = ""; switch (opcode) { } return(ret); }
internal bool AddInstruction(InstOp op, int arg0, int arg1, int spcl0, int spcl1, OpModifier modifier) { if (_trackedRecord == null) { return(false); } _trackedRecord.AddInstruction(new Instruction( op, arg0, arg1, spcl0, spcl1, modifier)); return(true); }
//Expressions*********************************** public override object VisitSet_alt([NotNull] KCCParser.Set_altContext context) { string declType; string symbolId; string op = context.op_sum.Text; string index = context.index_anyvalue()?.GetText(); InstOp instOp = InstOp.NoOp; var dCtx = context.expression(); symbolId = context.accessor().GetText(); if (context.symbol_id() != null)//Contains a type, so is definition { declType = context.symbol_id().GetText(); _controller.DeclareVariable(symbolId, declType); } if (op != null) { switch (context.op_sum.Text) { case "=": instOp = InstOp.Set; break; case "+=": instOp = InstOp.SetAdd; break; case "-=": instOp = InstOp.SetSub; break; case "*=": instOp = InstOp.SetMult; break; case "/=": instOp = InstOp.SetDiv; break; case "%=": instOp = InstOp.SetModulo; break; case "&=": instOp = InstOp.SetAnd; break; case "^=": instOp = InstOp.SetOr; break; case "|=": instOp = InstOp.SetXor; break; } var value = (string)Visit(dCtx); OpModifier valueType = value == null ? OpModifier.FromLastTemp : OpModifier.None; _controller.AddInstruction(instOp, symbolId, value, index, valueType); } else { _controller.AddInstruction(InstOp.Set, symbolId, null, index, OpModifier.NullOrDefault); } return(null); }
public override object VisitL_or([NotNull] KCCParser.L_orContext context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.lg_or.Text) { case "||": op = InstOp.Or; break; case "!|": op = InstOp.Nor; break; case "|||": op = InstOp.Xor; break; case "!||": op = InstOp.XNor; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
//Math************************* public override object VisitMath1([NotNull] KCCParser.Math1Context context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.prod_op.Text) { case "*": op = InstOp.Mult; break; case "/": op = InstOp.Div; break; case "%": op = InstOp.Modulo; break; case "**": op = InstOp.Power; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
public override object VisitCompare1([NotNull] KCCParser.Compare1Context context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.gl_compare.Text) { case "<": op = InstOp.Lss; break; case "<=": op = InstOp.LssEqu; break; case ">": op = InstOp.Gtr; break; case ">=": op = InstOp.GtrEqu; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
private static TranslatorContext DecodeShader(ulong address, IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts) { ShaderConfig config; DecodedProgram program; ulong maxEndAddress = 0; if ((options.Flags & TranslationFlags.Compute) != 0) { config = new ShaderConfig(gpuAccessor, options, counts); program = Decoder.Decode(config, address); } else { config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, options, counts); program = Decoder.Decode(config, address + HeaderSize); } foreach (DecodedFunction function in program) { foreach (Block block in function.Blocks) { if (maxEndAddress < block.EndAddress) { maxEndAddress = block.EndAddress; } if (!config.UsedFeatures.HasFlag(FeatureFlags.Bindless)) { for (int index = 0; index < block.OpCodes.Count; index++) { InstOp op = block.OpCodes[index]; if (op.Props.HasFlag(InstProps.Tex)) { int tidB = (int)((op.RawOpCode >> 36) & 0x1fff); config.TextureHandlesForCache.Add(tidB); } } } } } config.SizeAdd((int)maxEndAddress + (options.Flags.HasFlag(TranslationFlags.Compute) ? 0 : HeaderSize)); return(new TranslatorContext(address, program, config)); }
public string FormatInstruction(InstOp opcode, string arg0, string arg1, string spcl1, string spcl2, OpModifier mode) { var ret = ""; switch (opcode) { case InstOp.Print: ret = $" leaq .LC{arg0}(%{AsmRef.GetInstructionPointer(BitCntr.B64)}), %{AsmRef.GetCounter(BitCntr.B64)}" + _nl + $" call printf"; break; case InstOp.Exit: ret = $" movl %{arg0}, %{AsmRef.GetDestination(BitCntr.B32)}" + _nl + " call exit"; break; } return(ret); }
//Comparators********************** public override object VisitShift([NotNull] KCCParser.ShiftContext context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.shift_op.Text) { case "<<": op = InstOp.ShL; break; case ">>": op = InstOp.ShR; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
private static void EmitOps(EmitterContext context, Block block) { for (int opIndex = 0; opIndex < block.OpCodes.Count; opIndex++) { InstOp op = block.OpCodes[opIndex]; if (context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode)) { string instName; if (op.Emitter != null) { instName = op.Name.ToString(); } else { instName = "???"; context.Config.GpuAccessor.Log($"Invalid instruction at 0x{op.Address:X6} (0x{op.RawOpCode:X16})."); } string dbgComment = $"0x{op.Address:X6}: 0x{op.RawOpCode:X16} {instName}"; context.Add(new CommentNode(dbgComment)); } 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; if (Decoder.IsPopBranch(op.Name)) { // 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. noPred = block.SyncTargets.Count <= 1; } else if (op.Name == InstName.Bra) { noPred = true; } if (!(opConditional.Pred == RegisterConsts.PredicateTrueIndex || noPred)) { Operand label; if (opIndex == block.OpCodes.Count - 1 && block.HasNext()) { label = context.GetLabel(block.Successors[0].Address); } else { label = Label(); predSkipLbl = label; } Operand pred = Register(opConditional.Pred, RegisterType.Predicate); if (opConditional.PredInv) { context.BranchIfTrue(label, pred); } else { context.BranchIfFalse(label, pred); } } context.CurrOp = op; op.Emitter?.Invoke(context); if (predSkipLbl != null) { context.MarkLabel(predSkipLbl); } } }
private static TreeNode[] BuildTree(Block[] blocks) { List <TreeNode> nodes = new List <TreeNode>(); Dictionary <ulong, TreeNode> labels = new Dictionary <ulong, TreeNode>(); TreeNodeUse[] predDefs = new TreeNodeUse[RegisterConsts.PredsCount]; TreeNodeUse[] gprDefs = new TreeNodeUse[RegisterConsts.GprsCount]; void DefPred(byte predIndex, int index, TreeNode node) { if (predIndex != RegisterConsts.PredicateTrueIndex) { predDefs[predIndex] = new TreeNodeUse(index, node); } } void DefGpr(byte regIndex, int index, TreeNode node) { if (regIndex != RegisterConsts.RegisterZeroIndex) { gprDefs[regIndex] = new TreeNodeUse(index, node); } } TreeNodeUse UsePred(byte predIndex, bool predInv) { if (predIndex != RegisterConsts.PredicateTrueIndex) { TreeNodeUse use = predDefs[predIndex]; if (use.Node != null) { nodes.Remove(use.Node); } else { use = new TreeNodeUse(-(predIndex + 2), null); } return(predInv ? use.Flip() : use); } return(new TreeNodeUse(-1, null)); } TreeNodeUse UseGpr(byte regIndex) { if (regIndex != RegisterConsts.RegisterZeroIndex) { TreeNodeUse use = gprDefs[regIndex]; if (use.Node != null) { nodes.Remove(use.Node); } else { use = new TreeNodeUse(-(regIndex + 2), null); } return(use); } return(new TreeNodeUse(-1, null)); } byte order = 0; for (int index = 0; index < blocks.Length; index++) { Block block = blocks[index]; if (block.Predecessors.Count > 1) { TreeNode label = new TreeNode(order++); nodes.Add(label); labels.Add(block.Address, label); } for (int opIndex = 0; opIndex < block.OpCodes.Count; opIndex++) { InstOp op = block.OpCodes[opIndex]; TreeNode node = new TreeNode(op, IsOrderDependant(op.Name) ? order : (byte)0); // Add uses. if (!op.Props.HasFlag(InstProps.NoPred)) { byte predIndex = (byte)((op.RawOpCode >> 16) & 7); bool predInv = (op.RawOpCode & 0x80000) != 0; node.Uses.Add(UsePred(predIndex, predInv)); } if (op.Props.HasFlag(InstProps.Ps)) { byte predIndex = (byte)((op.RawOpCode >> 39) & 7); bool predInv = (op.RawOpCode & 0x40000000000) != 0; node.Uses.Add(UsePred(predIndex, predInv)); } if (op.Props.HasFlag(InstProps.Ra)) { byte ra = (byte)(op.RawOpCode >> 8); node.Uses.Add(UseGpr(ra)); } if ((op.Props & (InstProps.Rb | InstProps.Rb2)) != 0) { byte rb = op.Props.HasFlag(InstProps.Rb2) ? (byte)op.RawOpCode : (byte)(op.RawOpCode >> 20); node.Uses.Add(UseGpr(rb)); } if (op.Props.HasFlag(InstProps.Rc)) { byte rc = (byte)(op.RawOpCode >> 39); node.Uses.Add(UseGpr(rc)); } if (op.Name == InstName.Bra && labels.TryGetValue(op.GetAbsoluteAddress(), out TreeNode label)) { node.Uses.Add(new TreeNodeUse(0, label)); } // Make definitions. int defIndex = 0; InstProps pdType = op.Props & InstProps.PdMask; if (pdType != 0) { int bit = pdType switch { InstProps.Pd => 3, InstProps.LPd => 48, InstProps.SPd => 30, InstProps.TPd => 51, InstProps.VPd => 45, _ => throw new InvalidOperationException($"Table has unknown predicate destination {pdType}.") }; byte predIndex = (byte)((op.RawOpCode >> bit) & 7); DefPred(predIndex, defIndex++, node); } if (op.Props.HasFlag(InstProps.Rd)) { byte rd = (byte)op.RawOpCode; DefGpr(rd, defIndex++, node); } nodes.Add(node); } } return(nodes.ToArray()); }
public int[] runes; // length==1 => exact match // otherwise a list of [lo,hi] pairs. hi is *inclusive*. // REVIEWERS: why not half-open intervals? public Inst(Inst.InstOp op) { this.op = (InstOp)op; }
public static bool isRuneOp(InstOp op) { return(InstOp.RUNE <= op && op <= InstOp.RUNE_ANY_NOT_NL); }