private void RewriteShd(Func <Expression, Expression, Expression> fnLeft, Func <Expression, Expression, Expression> fnRight) { rtlc = RtlClass.Linear; var sh = SrcOp(instr.op1); var dst = DstOp(instr.op2, sh, (d, s) => m.Conditional(d.DataType, m.Ge0(s), fnLeft(d, s), fnRight(d, s))); }
private void RewriteCmov() { var dst = Reg(instrCur.Operands[0]); var a = Reg0(instrCur.Operands[1]); var b = Reg0(instrCur.Operands[2]); var f = binder.EnsureFlagGroup(Registers.F); m.Assign(dst, m.Conditional(dst.DataType, f, a, b)); }
private void RewriteShd(Func <Expression, Expression, Expression> fnLeft, Func <Expression, Expression, Expression> fnRight) { var sh = SrcOp(instr.Operands[0]); var dst = DstOp(instr.Operands[1], sh, (d, s) => m.Conditional(d.DataType, m.Ge0(s), fnLeft(d, s), fnRight(d, s))); }
private Expression?RewriteApplication(ApplicationOperand app) { var ops = app.Operands.Select(o => OperandSrc(o) !).ToArray(); var dt = app.Width; switch (app.Mnemonic) { case Mnemonic.add: return(m.IAdd(ops[0], ops[1])); case Mnemonic.addasl: return(RewriteAddAsl(ops[0], ops[1], ops[2])); case Mnemonic.allocframe: RewriteAllocFrame(app.Operands[0]); return(null); case Mnemonic.and: return(m.And(ops[0], ops[1])); case Mnemonic.asl: return(m.Shl(ops[0], ops[1])); case Mnemonic.aslh: return(m.Shl(ops[0], 16)); case Mnemonic.asr: return(m.Sar(ops[0], ops[1])); case Mnemonic.asrh: return(m.Sar(ops[0], 16)); case Mnemonic.cmp__eq: return(m.Eq(ops[0], ops[1])); case Mnemonic.cmp__gt: return(m.Gt(ops[0], ops[1])); case Mnemonic.cmp__gtu: return(m.Ugt(ops[0], ops[1])); case Mnemonic.cmpb__eq: return(RewriteCmp(PrimitiveType.Byte, m.Eq, ops[0], ops[1])); case Mnemonic.cmpb__gt: return(RewriteCmp(PrimitiveType.Byte, m.Gt, ops[0], ops[1])); case Mnemonic.cmpb__gtu: return(RewriteCmp(PrimitiveType.Byte, m.Ugt, ops[0], ops[1])); case Mnemonic.cmph__eq: return(RewriteCmp(PrimitiveType.Word16, m.Eq, ops[0], ops[1])); case Mnemonic.cmph__gt: return(RewriteCmp(PrimitiveType.Word16, m.Gt, ops[0], ops[1])); case Mnemonic.cmph__gtu: return(RewriteCmp(PrimitiveType.Word16, m.Ugt, ops[0], ops[1])); case Mnemonic.dfcmp__eq: return(m.FEq(ops[0], ops[1])); case Mnemonic.dfcmp__ge: return(m.FGe(ops[0], ops[1])); case Mnemonic.dfcmp__uo: return(host.Intrinsic("isunordered", false, PrimitiveType.Bool, ops[0], ops[1])); case Mnemonic.combine: return(RewriteCombine(ops[0], ops[1])); case Mnemonic.convert_d2df: return(m.Convert(ops[0], PrimitiveType.Int64, PrimitiveType.Real64)); case Mnemonic.convert_df2sf: return(m.Convert(ops[0], PrimitiveType.Real64, PrimitiveType.Real32)); case Mnemonic.convert_sf2df: return(m.Convert(ops[0], PrimitiveType.Real32, PrimitiveType.Real64)); case Mnemonic.EQ: return(m.Eq(ops[0], ops[1])); case Mnemonic.extract: return(RewriteExtract(Domain.SignedInt, ops[0], app.Operands)); case Mnemonic.extractu: return(RewriteExtract(Domain.UnsignedInt, ops[0], app.Operands)); case Mnemonic.loop0: RewriteLoop(0, ops); return(null); case Mnemonic.loop1: RewriteLoop(1, ops); return(null); case Mnemonic.lsl: return(m.Shl(ops[0], ops[1])); case Mnemonic.lsr: return(m.Shr(ops[0], ops[1])); case Mnemonic.mpy: return(RewriteMpy(ops[0], ops[1])); case Mnemonic.mpyi: return(RewriteMpyi(ops[0], ops[1])); case Mnemonic.mpyu: return(RewriteMpyu(app.Width, ops[0], ops[1])); case Mnemonic.mux: return(m.Conditional(ops[1].DataType, ops[0], ops[1], ops[2])); case Mnemonic.NE: return(m.Ne(ops[0], ops[1])); case Mnemonic.neg: return(m.Neg(ops[0])); case Mnemonic.not: return(m.Not(ops[0])); case Mnemonic.or: return(m.Or(ops[0], ops[1])); case Mnemonic.sub: return(m.ISub(ops[0], ops[1])); case Mnemonic.sxtb: return(RewriteExt(ops[0], PrimitiveType.SByte, PrimitiveType.Int32)); case Mnemonic.sxth: return(RewriteExt(ops[0], PrimitiveType.Int16, PrimitiveType.Int32)); case Mnemonic.xor: return(m.Xor(ops[0], ops[1])); case Mnemonic.zxtb: return(RewriteExt(ops[0], PrimitiveType.Byte, PrimitiveType.UInt32)); case Mnemonic.zxth: return(RewriteExt(ops[0], PrimitiveType.UInt16, PrimitiveType.UInt32)); case Mnemonic.abs: dt = PrimitiveType.Int32; goto intrinsicFunc; case Mnemonic.max: dt = PrimitiveType.Int32; goto intrinsicFunc; case Mnemonic.maxu: dt = PrimitiveType.UInt32; goto intrinsicFunc; case Mnemonic.min: dt = PrimitiveType.Int32; goto intrinsicFunc; case Mnemonic.minu: dt = PrimitiveType.UInt32; goto intrinsicFunc; case Mnemonic.all8: case Mnemonic.any8: case Mnemonic.bitsclr: case Mnemonic.bitsplit: case Mnemonic.bitsset: case Mnemonic.ciad: case Mnemonic.cl0: case Mnemonic.cl1: case Mnemonic.clb: case Mnemonic.clrbit: case Mnemonic.crswap: case Mnemonic.cswi: case Mnemonic.ct0: case Mnemonic.dfclass: case Mnemonic.fastcorner9: case Mnemonic.insert: //$BUG: like DPB? case Mnemonic.memw_locked: case Mnemonic.setbit: case Mnemonic.start: case Mnemonic.stop: case Mnemonic.tlbw: case Mnemonic.tlbp: case Mnemonic.trap0: case Mnemonic.trap1: case Mnemonic.togglebit: case Mnemonic.tstbit: intrinsicFunc: return(RewriteIntrinsic(app.Mnemonic.ToString(), true, dt, ops)); case Mnemonic.dccleana: case Mnemonic.dccleaninva: case Mnemonic.dcfetch: case Mnemonic.dcinva: case Mnemonic.dczeroa: return(RewriteIntrinsic(app.Mnemonic.ToString(), true, VoidType.Instance, ops)); case Mnemonic.vavgh: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Word16, ops)); case Mnemonic.vcmpb__eq: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops)); case Mnemonic.vmux: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops)); case Mnemonic.vsplatb: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Byte, ops)); case Mnemonic.vsubh: return(RewriteVectorIntrinsic(app.Mnemonic, false, PrimitiveType.Int16, ops)); } throw new ArgumentException($"Hexagon rewriter for {app.Mnemonic} not implemented yet.", app.Mnemonic.ToString()); }