public Emitter op(ptxop ptxop) { // todo. we need more generic solution // btw: set, tex, atom, bar_red and video instructions are left uncovered // since they (as well as setp and bar_sync) have variable number of operands if (ptxop is setp) { var setp = (setp)ptxop; setp.p = def_local(typeof(bool)); setp.b = pop_expr(); setp.a = pop_expr(); setp.b.Type.agree(setp.a.Type).AssertTrue(); setp.type = setp.b.Type; push(setp.p); } else if (ptxop is bar_sync) { var bar_sync = (bar_sync)ptxop; bar_sync.a = pop_expr(); } else { var sample = ptxop.PtxopSigs().AssertFirst(); var fixup = sample.Destination != null ? 1 : 0; var argc = sample.Operands.Count - fixup; var args = argc.Times(_ => pop_expr()).Reverse().ToReadOnly(); // todo. not all instructions are as simple as the lines below assume // I mean: cvt, set, slct, suld_b, suld_p, sured_b, sured_p, sust_b, sust_p, tex and video var t = args.Fold(null as PtxType, (t_curr, a) => (t_curr ?? a.Type).AssertThat(t1 => t1.agree(a.Type))); var p_t = sample.Affixes.SingleOrDefault(p => p.Decl.PropertyType == typeof(PtxType)); if (p_t != null) { p_t.Decl.SetValue(ptxop, t, null); } if (sample.Destination != null) { var dest = def_local(t); ptxop.Operands[0] = dest; push(dest); } args.ForEach((arg, i) => ptxop.Operands[i + fixup] = arg); } _ptx.Add(ptxop); return(this); }
public PtxopSnippet(ptxop ptxop) { Ptxop = ptxop; }