private Expression RewriteCondition(Expression left, Expression right) { Expression e; switch (instr.Condition.Type) { case ConditionType.Tr: e = Constant.True(); break; case ConditionType.Never: e = Constant.False(); break; case ConditionType.Eq: case ConditionType.Eq64: e = m.Eq(left, right); break; case ConditionType.Ne: case ConditionType.Ne64: e = m.Ne(left, right); break; case ConditionType.Lt: e = m.Lt(left, right); break; case ConditionType.Le: e = m.Le(left, right); break; case ConditionType.Ge: case ConditionType.Ge64: e = m.Ge(left, right); break; case ConditionType.Gt: e = m.Gt(left, right); break; case ConditionType.Ult: e = m.Ult(left, right); break; case ConditionType.Ule: e = m.Ule(left, right); break; case ConditionType.Uge: case ConditionType.Uge64: e = m.Uge(left, right); break; case ConditionType.Ugt: e = m.Ugt(left, right); break; case ConditionType.Nuv: case ConditionType.Nuv64: e = m.Test(ConditionCode.OV, m.ISub(left, right)); break; case ConditionType.Nsv: //$TODO: need signed minus/unsigned minus. e = m.Test(ConditionCode.OV, m.ISub(left, right)); break; case ConditionType.Even: case ConditionType.Even64: e = m.Eq0(m.And(left, 1)); break; default: throw new NotImplementedException(instr.Condition.ToString()); } return(e); }
private Expression SignedCondition(int iop, Expression left, Expression right) { var mm = ((ImmediateOperand)instr.Operands[iop]).Value.ToInt32(); return(mm switch { 2 => m.Gt(left, right), 4 => m.Lt(left, right), 6 => m.Ne(left, right), 8 => m.Eq(left, right), 0xA => m.Ge(left, right), 0xC => m.Le(left, right), _ => Constant.False() });
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()); }
private Expression RewriteCondition(Expression left, Expression right) { Expression e; switch (instr.Condition.Type) { case ConditionType.Tr: e = Constant.True(); break; case ConditionType.Never: case ConditionType.Never64: e = Constant.False(); break; case ConditionType.Eq: case ConditionType.Eq64: e = m.Eq(left, right); break; case ConditionType.Ne: case ConditionType.Ne64: e = m.Ne(left, right); break; case ConditionType.Lt: case ConditionType.Lt64: e = m.Lt(left, right); break; case ConditionType.Le: case ConditionType.Le64: e = m.Le(left, right); break; case ConditionType.Ge: case ConditionType.Ge64: e = m.Ge(left, right); break; case ConditionType.Gt: case ConditionType.Gt64: e = m.Gt(left, right); break; case ConditionType.Ult: case ConditionType.Ult64: e = m.Ult(left, right); break; case ConditionType.Ule: case ConditionType.Ule64: e = m.Ule(left, right); break; case ConditionType.Uge: case ConditionType.Uge64: e = m.Uge(left, right); break; case ConditionType.Ugt: case ConditionType.Ugt64: e = m.Ugt(left, right); break; case ConditionType.Uv: case ConditionType.Uv64: e = m.Test(ConditionCode.NO, m.USub(left, right)); break; case ConditionType.Sv: case ConditionType.Sv64: e = m.Test(ConditionCode.NO, m.ISub(left, right)); break; case ConditionType.Nuv: case ConditionType.Nuv64: e = m.Test(ConditionCode.OV, m.USub(left, right)); break; case ConditionType.Nsv: case ConditionType.Nsv64: e = m.Test(ConditionCode.OV, m.ISub(left, right)); break; case ConditionType.Even: case ConditionType.Even64: e = m.Eq0(m.And(left, 1)); break; case ConditionType.Odd: case ConditionType.Odd64: e = m.Ne0(m.And(left, 1)); break; case ConditionType.Vnz: case ConditionType.Vnz64: e = m.And(m.Eq(left, right), m.Test(ConditionCode.NO, m.ISub(left, right))); break; case ConditionType.Znv: case ConditionType.Znv64: e = m.And(m.Ne(left, right), m.Test(ConditionCode.OV, m.ISub(left, right))); break; default: throw new NotImplementedException(instr.Condition.ToString()); } return(e); }