Пример #1
0
        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);
        }
Пример #2
0
        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()
            });
Пример #3
0
        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());
        }
Пример #4
0
        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);
        }