Example #1
0
        private Expression Sbrc(Expression a, Expression b)
        {
            var imm = ((Constant)b).ToInt32();

            return(m.Eq0(m.And(a, m.Byte((byte)(1 << imm)))));
        }
Example #2
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                this.instr  = dasm.Current;
                this.iclass = instr.InstructionClass;
                var instrs = new List <RtlInstruction>();
                m = new RtlEmitter(instrs);
                switch (instr.Mnemonic)
                {
                default:
                    EmitUnitTest();
                    goto case Mnemonic.invalid;

                case Mnemonic.invalid: m.Invalid(); break;

                case Mnemonic.add: RewriteAdd(true); break;

                case Mnemonic.add_c: RewriteAdd_c(); break;

                case Mnemonic.add_l: RewriteAdd(false); break;

                case Mnemonic.addb: RewriteAddb(); break;

                case Mnemonic.addi: RewriteAddi(false); break;

                case Mnemonic.addi_tc: RewriteAddi(true); break;

                case Mnemonic.addib: RewriteAddb(); break;

                case Mnemonic.addil: RewriteAddi(false); break;

                case Mnemonic.and: RewriteLogical(m.And); break;

                case Mnemonic.andcm: RewriteLogical((a, b) => m.And(a, m.Comp(b))); break;

                case Mnemonic.b_l: RewriteBranch(); break;

                case Mnemonic.be: RewriteBe(); break;

                case Mnemonic.be_l: RewriteBe(); break;

                case Mnemonic.bv: RewriteBv(); break;

                case Mnemonic.cmpb: RewriteCmpb(0, 1); break;

                case Mnemonic.cmpib: RewriteCmpb(1, 0); break;

                case Mnemonic.@break: RewriteBreak(); break;

                case Mnemonic.depwi: RewriteDepwi(); break;

                case Mnemonic.diag: RewriteDiag(); break;

                case Mnemonic.extrw: RewriteExtrw(); break;

                case Mnemonic.fadd: RewriteFpArithmetic(m.FAdd); break;

                case Mnemonic.fcpy: RewriteFcpy(); break;

                case Mnemonic.fid: RewriteFid(); break;

                case Mnemonic.fldd: RewriteFld(PrimitiveType.Real64); break;

                case Mnemonic.fldw: RewriteFld(PrimitiveType.Real32); break;

                case Mnemonic.fmpy: RewriteFpArithmetic(m.FMul); break;

                case Mnemonic.fstd: RewriteFst(PrimitiveType.Real64); break;

                case Mnemonic.fstw: RewriteFst(PrimitiveType.Real32); break;

                case Mnemonic.fsub: RewriteFpArithmetic(m.FSub); break;

                case Mnemonic.ldb: RewriteLd(PrimitiveType.Byte); break;

                case Mnemonic.ldd: RewriteLd(PrimitiveType.Word64); break;

                case Mnemonic.ldh: RewriteLd(PrimitiveType.Word16); break;

                case Mnemonic.ldil: RewriteLdil(); break;

                case Mnemonic.ldo: RewriteLdo(); break;

                case Mnemonic.ldsid: RewriteLdsid(); break;

                case Mnemonic.ldw: RewriteLd(PrimitiveType.Word32); break;

                case Mnemonic.ldwa: RewriteLd(PrimitiveType.Word32); break;

                case Mnemonic.mfctl: RewriteMfctl(); break;

                case Mnemonic.mfctl_w: RewriteMfctl(); break;

                case Mnemonic.mtctl: RewriteMtctl(); break;

                case Mnemonic.mtsm: RewriteMtsm(); break;

                case Mnemonic.mtsp: RewriteMtsp(); break;

                case Mnemonic.or: RewriteOr(); break;

                case Mnemonic.rfi: RewriteRfi("__rfi"); break;

                case Mnemonic.rfi_r: RewriteRfi("__rfi_r"); break;

                case Mnemonic.shladd: RewriteShladd(); break;

                case Mnemonic.shrpd: RewriteShrp(PrimitiveType.Word64, PrimitiveType.Word128); break;

                case Mnemonic.shrpw: RewriteShrp(PrimitiveType.Word32, PrimitiveType.Word64); break;

                case Mnemonic.stb: RewriteSt(PrimitiveType.Byte); break;

                case Mnemonic.std: RewriteSt(PrimitiveType.Word64); break;

                case Mnemonic.stda: RewriteSt(PrimitiveType.Word64); break;

                case Mnemonic.sth: RewriteSt(PrimitiveType.Word16); break;

                case Mnemonic.stw: RewriteSt(PrimitiveType.Word32); break;

                case Mnemonic.sub: RewriteSub(); break;

                case Mnemonic.subi: RewriteSubi(); break;
                }
                yield return(new RtlInstructionCluster(instr.Address, instr.Length, instrs.ToArray())
                {
                    Class = iclass,
                });
            }
        }
Example #3
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                di = dasm.Current;
                var addr = di.Address;
                var len  = di.Length;
                rtlInstructions = new List <RtlInstruction>();
                rtlc            = RtlClass.Linear;
                m   = new RtlEmitter(rtlInstructions);
                orw = new OperandRewriter(arch, this.m, this.binder, di.dataWidth);
                switch (di.code)
                {
                default:
                    host.Warn(
                        di.Address,
                        "Rewriting M68k opcode '{0}' is not supported yet.",
                        di.code);
                    m.Invalid();
                    break;

                case Opcode.illegal: RewriteIllegal(); break;

                case Opcode.abcd: RewriteAbcd(); break;

                case Opcode.add: RewriteBinOp((s, d) => m.IAdd(d, s), FlagM.CVZNX); break;

                case Opcode.adda: RewriteBinOp((s, d) => m.IAdd(d, s)); break;

                case Opcode.addi: RewriteArithmetic((s, d) => m.IAdd(d, s)); break;

                case Opcode.addq: RewriteAddSubq((s, d) => m.IAdd(d, s)); break;

                case Opcode.addx: RewriteAddSubx(m.IAdd); break;

                case Opcode.and: RewriteLogical((s, d) => m.And(d, s)); break;

                case Opcode.andi: RewriteLogical((s, d) => m.And(d, s)); break;

                case Opcode.asl: RewriteArithmetic((s, d) => m.Shl(d, s)); break;

                case Opcode.asr: RewriteShift((s, d) => m.Sar(d, s)); break;

/*
 *
 * Mnemonic Condition Encoding Test
 * T* True 0000 1
 * F* False 0001 0
 * HI High 0010 C L Z
 * LS Low or Same 0011 C V Z
 * VC Overflow Clear 1000 V
 * VS Overflow Set 1001 V
 */
                case Opcode.bclr: RewriteBclrBset("__bclr"); break;

                case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break;

                case Opcode.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break;

                case Opcode.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Opcode.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.blt: RewriteBcc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break;

                case Opcode.bls: RewriteBcc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Opcode.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break;

                case Opcode.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break;

                case Opcode.bvc: RewriteBcc(ConditionCode.NO, FlagM.VF); break;

                case Opcode.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break;

                case Opcode.bchg: RewriteBchg(); break;

                case Opcode.bkpt: RewriteBkpt(); break;

                case Opcode.bra: RewriteBra(); break;

                case Opcode.bset: RewriteBclrBset("__bset"); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.btst: RewriteBtst(); break;

                case Opcode.callm: RewriteCallm(); break;

                case Opcode.cas: RewriteCas(); break;

                case Opcode.clr: RewriteClr(); break;

                case Opcode.chk: RewriteChk(); break;

                case Opcode.chk2: RewriteChk2(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmp2: RewriteCmp2(); break;

                case Opcode.cmpa: RewriteCmp(); break;

                case Opcode.cmpi: RewriteCmp(); break;

                case Opcode.cmpm: RewriteCmp(); break;

                case Opcode.dbcc: RewriteDbcc(ConditionCode.UGE, FlagM.CF); break;

                case Opcode.dbcs: RewriteDbcc(ConditionCode.ULT, FlagM.CF); break;

                case Opcode.dbeq: RewriteDbcc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.dbge: RewriteDbcc(ConditionCode.GE, FlagM.NF | FlagM.ZF); break;

                case Opcode.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.dbls: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break;

                case Opcode.dbhi: RewriteDbcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.dbpl: RewriteDbcc(ConditionCode.GT, FlagM.NF); break;

                case Opcode.dbne: RewriteDbcc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.dbt: RewriteDbcc(ConditionCode.ALWAYS, 0); break;

                case Opcode.dbra: RewriteDbcc(ConditionCode.None, 0); break;

                case Opcode.divs: RewriteDiv(m.SDiv, PrimitiveType.Int16); break;

                case Opcode.divsl: RewriteDiv(m.SDiv, PrimitiveType.Int32); break;

                case Opcode.divu: RewriteDiv(m.UDiv, PrimitiveType.UInt16); break;

                case Opcode.divul: RewriteDiv(m.UDiv, PrimitiveType.UInt32); break;

                case Opcode.eor: RewriteLogical((s, d) => m.Xor(d, s)); break;

                case Opcode.eori: RewriteLogical((s, d) => m.Xor(d, s)); break;

                case Opcode.exg: RewriteExg(); break;

                case Opcode.ext: RewriteExt(); break;

                case Opcode.extb: RewriteExtb(); break;

                case Opcode.fadd: RewriteFBinOp((s, d) => m.FAdd(d, s)); break;

                //$REVIEW: the following don't respect NaN, but NaN typically doesn't exist in HLLs.
                case Opcode.fbf: m.Nop(); break;

                case Opcode.fblt: RewriteFbcc(ConditionCode.LT); break;

                case Opcode.fbgl: RewriteFbcc(ConditionCode.NE); break;

                case Opcode.fbgt: RewriteFbcc(ConditionCode.GT); break;

                case Opcode.fbgle: RewriteFbcc(ConditionCode.NE); break;    //$BUG: should be !is_nan

                case Opcode.fbne: RewriteFbcc(ConditionCode.NE); break;

                case Opcode.fbnge: RewriteFbcc(ConditionCode.LT); break;

                case Opcode.fbngl: RewriteFbcc(ConditionCode.EQ); break;

                case Opcode.fbngle: RewriteFbcc(ConditionCode.EQ); break;   //$BUG: should be is_nan

                case Opcode.fbnlt: RewriteFbcc(ConditionCode.GE); break;

                case Opcode.fbnle: RewriteFbcc(ConditionCode.GT); break;

                case Opcode.fbogl: RewriteFbcc(ConditionCode.NE); break;

                case Opcode.fbole: RewriteFbcc(ConditionCode.LE); break;

                case Opcode.fbolt: RewriteFbcc(ConditionCode.LT); break;

                case Opcode.fbogt: RewriteFbcc(ConditionCode.GT); break;

                case Opcode.fbor: RewriteFbcc(ConditionCode.EQ); break;     //$REVIEW: is this correct?

                case Opcode.fbseq: RewriteFbcc(ConditionCode.EQ); break;

                case Opcode.fbsf: RewriteFbcc(ConditionCode.NEVER); break;

                case Opcode.fbsne: RewriteFbcc(ConditionCode.NE); break;

                case Opcode.fbst: RewriteFbcc(ConditionCode.ALWAYS); break;

                case Opcode.fbuge: RewriteFbcc(ConditionCode.GE); break;

                case Opcode.fbugt: RewriteFbcc(ConditionCode.GT); break;

                case Opcode.fbult: RewriteFbcc(ConditionCode.LT); break;

                case Opcode.fbun: RewriteFbcc(ConditionCode.IS_NAN); break;

                case Opcode.fcmp: RewriteFcmp(); break;

                case Opcode.fdiv: RewriteFBinOp((s, d) => m.FDiv(d, s)); break;

                case Opcode.fmove: RewriteFmove(); break;

                case Opcode.fmovecr: RewriteFmovecr(); break;

                case Opcode.fmovem: RewriteMovem(i => arch.GetRegister(i + Registers.fp0.Number)); break;

                case Opcode.fmul: RewriteFBinOp((s, d) => m.FMul(d, s)); break;

                case Opcode.fneg: RewriteFUnaryOp(m.Neg); break;

                case Opcode.fsub: RewriteFBinOp((s, d) => m.FSub(d, s)); break;

                case Opcode.ftan: RewriteFtan(); break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.jsr: RewriteJsr(); break;

                case Opcode.lea: RewriteLea(); break;

                case Opcode.link: RewriteLink(); break;

                case Opcode.lsl: RewriteShift((s, d) => m.Shl(d, s)); break;

                case Opcode.lsr: RewriteShift((s, d) => m.Shr(d, s)); break;

                case Opcode.move: RewriteMove(true); break;

                case Opcode.move16: RewriteMove16(); break;

                case Opcode.movea: RewriteMove(false); break;

                case Opcode.movep: RewriteMovep(); break;

                case Opcode.moveq: RewriteMoveq(); break;

                case Opcode.moves: RewriteMoves(); break;

                case Opcode.movem: RewriteMovem(arch.GetRegister); break;

                case Opcode.muls: RewriteMul((s, d) => m.SMul(d, s)); break;

                case Opcode.mulu: RewriteMul((s, d) => m.UMul(d, s)); break;

                case Opcode.nbcd: RewriteNbcd(); break;

                case Opcode.neg: RewriteUnary(s => m.Neg(s), AllConditions); break;

                case Opcode.negx: RewriteUnary(RewriteNegx, AllConditions); break;

                case Opcode.nop: m.Nop(); break;

                case Opcode.not: RewriteUnary(s => m.Comp(s), LogicalConditions); break;

                case Opcode.or: RewriteLogical((s, d) => m.Or(d, s)); break;

                case Opcode.ori: RewriteLogical((s, d) => m.Or(d, s)); break;

                case Opcode.pack: RewritePack(); break;

                case Opcode.pea: RewritePea(); break;

                case Opcode.pflushr: RewritePflushr(); break;

                case Opcode.ptest: RewritePtest(); break;

                case Opcode.rol: RewriteRotation(PseudoProcedure.Rol); break;

                case Opcode.ror: RewriteRotation(PseudoProcedure.Ror);  break;

                case Opcode.roxl: RewriteRotationX(PseudoProcedure.RolC);  break;

                case Opcode.roxr: RewriteRotationX(PseudoProcedure.RorC);  break;

                case Opcode.rte: RewriteRte(); break;

                case Opcode.rtm: RewriteRtm(); break;

                case Opcode.rts: RewriteRts(); break;

                case Opcode.sbcd: RewriteSbcd(); break;

                case Opcode.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break;

                case Opcode.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break;

                case Opcode.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Opcode.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.slt: RewriteScc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sls: RewriteScc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Opcode.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break;

                case Opcode.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break;

                case Opcode.svc: RewriteScc(ConditionCode.NO, FlagM.VF); break;

                case Opcode.svs: RewriteScc(ConditionCode.OV, FlagM.VF); break;

                case Opcode.st: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.True()); break;

                case Opcode.sf: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.False()); break;

                case Opcode.stop: RewriteStop(); break;

                case Opcode.sub: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Opcode.suba: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Opcode.subi: RewriteArithmetic((s, d) => m.ISub(d, s)); break;

                case Opcode.subq: RewriteAddSubq((s, d) => m.ISub(d, s)); break;

                case Opcode.subx: RewriteArithmetic((s, d) => m.ISub(m.ISub(d, s), binder.EnsureFlagGroup(Registers.ccr, (uint)FlagM.XF, "X", PrimitiveType.Bool))); break;

                case Opcode.swap: RewriteSwap(); break;

                case Opcode.trap: RewriteTrap(); break;

                case Opcode.trapeq: RewriteTrapCc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.trapf: RewriteTrapCc(ConditionCode.NEVER, 0); break;

                case Opcode.traphi: RewriteTrapCc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.trapls: RewriteTrapCc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Opcode.traplt: RewriteTrapCc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break;

                case Opcode.tas: RewriteTas(); break;

                case Opcode.tst: RewriteTst(); break;

                case Opcode.unlk: RewriteUnlk(); break;

                case Opcode.unpk: RewriteUnpk(); break;
                }
                yield return(new RtlInstructionCluster(
                                 addr,
                                 len,
                                 rtlInstructions.ToArray())
                {
                    Class = rtlc
                });
            }
            yield break;
        }
Example #4
0
 public HExpr And(HExpr a, HExpr b)
 {
     return(MapToHandle(m.And(GetExpression(a), GetExpression(b))));
 }
Example #5
0
 private Expression OpSrc(MachineOperand op)
 {
     switch (op)
     {
     case RegisterOperand reg:
         return binder.EnsureRegister(reg.Register);
     case FlagGroupOperand flg:
         return binder.EnsureFlagGroup(flg.FlagGroup);
     case ImmediateOperand imm:
         return imm.Value;
     case AddressOperand addr:
         return addr.Address;
     case MemoryOperand mem:
         Expression ea;
         if (mem.DirectAddress != null)
         {
             if (mem.Index != null)
             {
                 ea = m.IAdd(mem.DirectAddress, binder.EnsureRegister(mem.Index));
             }
             else if (mem.DirectAddress is Address addr)
             {
                 var alias = AliasedSpecialFunctionRegister(addr.ToUInt16());
                 if (alias != null)
                     return alias;
                 ea =  addr;
             }
             else
             {
                 ea = mem.DirectAddress;
             }
         }
         else if (mem.Register != null)
         {
             if (mem.Index != null)
             {
                 var idx = binder.EnsureRegister(mem.Index);
                 if (mem.Register == Registers.PC)
                 {
                     ea = m.IAdd(
                         instr.Address + instr.Length, idx);
                 }
                 else
                 {
                     ea = binder.EnsureIdentifier(mem.Register);
                     ea = m.IAdd(ea, idx);
                 }
             }
             else
             {
                 ea = binder.EnsureIdentifier(mem.Register);
             }
         }
         else
         {
             throw new NotImplementedException();
         }
         return m.Mem(mem.Width, ea);
     case BitOperand bit:
         Expression e = binder.EnsureRegister(bit.Register);
         if (bit.Bit > 0)
         {
             e = m.Shr(e, (byte)bit.Bit);
         }
         e = m.And(e, 1);
         if (bit.Negated)
         {
             e = m.Not(e);
         }
         return e;
     case SequenceOperand seq:
         return binder.EnsureSequence(seq.Sequence.DataType, seq.Sequence.Name, seq.Sequence.Elements);
     default:
         throw new NotImplementedException($"Not implemented {op.GetType().Name}.");
     }
 }
Example #6
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                var addr = dasm.Current.Address;
                var len  = dasm.Current.Length;
                rtlInstructions = new List <RtlInstruction>();
                rtlc            = RtlClass.Linear;
                m          = new RtlEmitter(rtlInstructions);
                this.instr = dasm.Current;
                switch (instr.Opcode)
                {
                default:
                    throw new AddressCorrelatedException(
                              instr.Address,
                              "Rewriting of Xtensa instruction '{0}' not implemented yet.",
                              instr.Opcode);

                case Opcodes.abs: RewritePseudoFn("abs"); break;

                case Opcodes.add:
                case Opcodes.add_n: RewriteBinOp(m.IAdd); break;

                case Opcodes.add_s: RewriteBinOp(m.FAdd); break;

                case Opcodes.addi: RewriteAddi(); break;

                case Opcodes.addi_n: RewriteAddi(); break;

                case Opcodes.addmi: RewriteBinOp(m.IAdd); break;

                case Opcodes.addx2: RewriteAddx(2); break;

                case Opcodes.addx4: RewriteAddx(4); break;

                case Opcodes.addx8: RewriteAddx(8); break;

                case Opcodes.and: RewriteBinOp(m.And); break;

                case Opcodes.andbc: RewriteBinOp((a, b) => m.And(a, m.Not(b))); break;

                case Opcodes.ball: RewriteBall(); break;

                case Opcodes.bany: RewriteBany(); break;

                case Opcodes.bbc:
                case Opcodes.bbci: RewriteBbx(m.Eq0); break;

                case Opcodes.bbs:
                case Opcodes.bbsi: RewriteBbx(m.Ne0); break;

                case Opcodes.beq:
                case Opcodes.beqi: RewriteBranch(m.Eq); break;

                case Opcodes.beqz:
                case Opcodes.beqz_n: RewriteBranchZ(m.Eq0); break;

                case Opcodes.bge:
                case Opcodes.bgei: RewriteBranch(m.Ge); break;

                case Opcodes.bgeu:
                case Opcodes.bgeui: RewriteBranch(m.Uge); break;

                case Opcodes.bgez: RewriteBranchZ(m.Ge0); break;

                case Opcodes.blt: RewriteBranch(m.Lt); break;

                case Opcodes.blti: RewriteBranch(m.Lt); break;

                case Opcodes.bltu:
                case Opcodes.bltui: RewriteBranch(m.Ult); break;

                case Opcodes.bltz: RewriteBranchZ(m.Lt0); break;

                case Opcodes.bnall: RewriteBnall(); break;

                case Opcodes.bne: RewriteBranch(m.Ne); break;

                case Opcodes.bnei: RewriteBranch(m.Ne); break;

                case Opcodes.bnez:
                case Opcodes.bnez_n: RewriteBranchZ(m.Ne0); break;

                case Opcodes.bnone: RewriteBnone(); break;

                case Opcodes.@break: RewriteBreak(); break;

                case Opcodes.call0:
                case Opcodes.callx0: RewriteCall0(); break;

                case Opcodes.extui: RewriteExtui(); break;

                case Opcodes.floor_s: RewritePseudoFn("__floor"); break;

                case Opcodes.isync: RewritePseudoProc("__isync"); break;

                case Opcodes.j:
                case Opcodes.jx: RewriteJ(); break;

                case Opcodes.ill: RewriteIll(); break;

                case Opcodes.l16si: RewriteLsi(PrimitiveType.Int16); break;

                case Opcodes.l16ui: RewriteLui(PrimitiveType.UInt16); break;

                case Opcodes.l32i: RewriteL32i(); break;

                case Opcodes.l32e: RewriteL32e(); break;

                case Opcodes.l32i_n: RewriteL32i(); break;

                case Opcodes.l32r: RewriteCopy(); break;

                case Opcodes.l8ui: RewriteLui(PrimitiveType.Byte); break;

                case Opcodes.ldpte: RewritePseudoProc("__ldpte"); break;

                case Opcodes.lsiu: RewriteLsiu(); break;

                case Opcodes.memw: RewriteNop(); break; /// memory sync barriers?

                case Opcodes.mov_n: RewriteCopy(); break;

                case Opcodes.movi: RewriteCopy(); break;

                case Opcodes.movi_n: RewriteMovi_n(); break;

                case Opcodes.moveqz:
                case Opcodes.moveqz_s: RewriteMovcc(m.Eq); break;

                case Opcodes.movltz: RewriteMovcc(m.Lt); break;

                case Opcodes.movgez: RewriteMovcc(m.Ge); break;

                case Opcodes.movnez: RewriteMovcc(m.Ne); break;

                case Opcodes.mul_s: RewriteBinOp(m.FMul); break;

                case Opcodes.mul16s: RewriteMul16(m.SMul, Domain.SignedInt); break;

                case Opcodes.mul16u: RewriteMul16(m.UMul, Domain.UnsignedInt); break;

                case Opcodes.mull: RewriteBinOp(m.IMul); break;

                case Opcodes.neg: RewriteUnaryOp(m.Neg); break;

                case Opcodes.nsa: RewritePseudoFn("__nsa"); break;

                case Opcodes.nsau: RewritePseudoFn("__nsau"); break;

                case Opcodes.or: RewriteOr(); break;

                case Opcodes.orbc: RewriteBinOp((a, b) => m.Or(a, m.Not(b))); break;

                case Opcodes.quos: RewriteBinOp(m.SDiv); break;

                case Opcodes.quou: RewriteBinOp(m.UDiv); break;

                case Opcodes.rems: RewriteBinOp(m.Mod); break;

                case Opcodes.remu: RewriteBinOp(m.Mod); break;

                case Opcodes.reserved: RewriteReserved(); break;

                case Opcodes.ret:
                case Opcodes.ret_n: RewriteRet(); break;

                case Opcodes.rfe: RewriteRet(); break;      //$REVIEW: emit some hint this is a return from exception?

                case Opcodes.rfi: RewriteRet(); break;      //$REVIEW: emit some hint this is a return from interrupt?

                case Opcodes.rsil: RewritePseudoFn("__rsil"); break;

                case Opcodes.rsr: RewriteCopy(); break;

                case Opcodes.s16i: RewriteSi(PrimitiveType.Word16); break;

                case Opcodes.s32e: RewriteS32e(); break;

                case Opcodes.s32i:
                case Opcodes.s32i_n: RewriteSi(PrimitiveType.Word32); break;

                case Opcodes.s32ri: RewriteSi(PrimitiveType.Word32); break; //$REVIEW: what about concurrency semantics

                case Opcodes.s8i: RewriteSi(PrimitiveType.Byte); break;

                case Opcodes.sll: RewriteShift(m.Shl); break;

                case Opcodes.slli: RewriteShiftI(m.Shl); break;

                case Opcodes.sra: RewriteShift(m.Sar); break;

                case Opcodes.srai: RewriteShiftI(m.Sar); break;

                case Opcodes.src: RewriteSrc(); break;

                case Opcodes.srl: RewriteShift(m.Sar); break;

                case Opcodes.srli: RewriteShiftI(m.Shr); break;

                case Opcodes.ssa8l: RewriteSsa8l(); break;

                case Opcodes.ssi: RewriteSi(PrimitiveType.Real32); break;

                case Opcodes.ssl: RewriteSsl(); break;

                case Opcodes.ssr:
                case Opcodes.ssai: RewriteSsa(); break;

                case Opcodes.sub: RewriteBinOp(m.ISub); break;

                case Opcodes.sub_s: RewriteBinOp(m.FSub); break;

                case Opcodes.subx2: RewriteSubx(2); break;

                case Opcodes.subx4: RewriteSubx(4); break;

                case Opcodes.subx8: RewriteSubx(8); break;

                case Opcodes.ueq_s: RewriteBinOp(m.Eq); break;

                case Opcodes.wsr: RewriteWsr(); break;

                case Opcodes.xor: RewriteBinOp(m.Xor); break;
                }
                yield return(new RtlInstructionCluster(addr, len, rtlInstructions.ToArray())
                {
                    Class = rtlc,
                });
            }
        }
Example #7
0
 private Expression Bis(Expression a, Expression b)
 {
     return(m.And(a, m.Comp(b)));
 }
Example #8
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());
        }
Example #9
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                var addr            = dasm.Current.Address;
                var len             = dasm.Current.Length;
                var rtlInstructions = new List <RtlInstruction>();
                iclass     = InstrClass.Linear;
                m          = new RtlEmitter(rtlInstructions);
                this.instr = dasm.Current;
                switch (instr.Mnemonic)
                {
                default:
                    host.Error(instr.Address, $"Rewriting of Xtensa instruction '{instr}' not implemented yet.");
                    EmitUnitTest();
                    goto case Mnemonic.invalid;

                case Mnemonic.invalid:
                case Mnemonic.reserved:
                    iclass = InstrClass.Invalid; m.Invalid(); break;

                case Mnemonic.abs: RewritePseudoFn("abs"); break;

                case Mnemonic.add:
                case Mnemonic.add_n: RewriteBinOp(m.IAdd); break;

                case Mnemonic.add_s: RewriteBinOp(m.FAdd); break;

                case Mnemonic.addi: RewriteAddi(); break;

                case Mnemonic.addi_n: RewriteAddi(); break;

                case Mnemonic.addmi: RewriteBinOp(m.IAdd); break;

                case Mnemonic.addx2: RewriteAddx(2); break;

                case Mnemonic.addx4: RewriteAddx(4); break;

                case Mnemonic.addx8: RewriteAddx(8); break;

                case Mnemonic.all4: RewriteAll(4, m.And); break;

                case Mnemonic.all8: RewriteAll(8, m.And); break;

                case Mnemonic.and: RewriteBinOp(m.And); break;

                case Mnemonic.andb: RewriteBinOp(m.And); break;

                case Mnemonic.andbc: RewriteBinOp((a, b) => m.And(a, m.Not(b))); break;

                case Mnemonic.any4: RewriteAll(4, m.Or); break;

                case Mnemonic.any8: RewriteAll(8, m.Or); break;

                case Mnemonic.ball: RewriteBall(); break;

                case Mnemonic.bany: RewriteBany(); break;

                case Mnemonic.bbc:
                case Mnemonic.bbci: RewriteBbx(m.Eq0); break;

                case Mnemonic.bbs:
                case Mnemonic.bbsi: RewriteBbx(m.Ne0); break;

                case Mnemonic.beq:
                case Mnemonic.beqi: RewriteBranch(m.Eq); break;

                case Mnemonic.beqz:
                case Mnemonic.beqz_n: RewriteBranchZ(m.Eq0); break;

                case Mnemonic.bf: RewriteBranchZ(m.Not); break;

                case Mnemonic.bge:
                case Mnemonic.bgei: RewriteBranch(m.Ge); break;

                case Mnemonic.bgeu:
                case Mnemonic.bgeui: RewriteBranch(m.Uge); break;

                case Mnemonic.bgez: RewriteBranchZ(m.Ge0); break;

                case Mnemonic.blt: RewriteBranch(m.Lt); break;

                case Mnemonic.blti: RewriteBranch(m.Lt); break;

                case Mnemonic.bltu:
                case Mnemonic.bltui: RewriteBranch(m.Ult); break;

                case Mnemonic.bltz: RewriteBranchZ(m.Lt0); break;

                case Mnemonic.bnall: RewriteBnall(); break;

                case Mnemonic.bne: RewriteBranch(m.Ne); break;

                case Mnemonic.bnei: RewriteBranch(m.Ne); break;

                case Mnemonic.bnez:
                case Mnemonic.bnez_n: RewriteBranchZ(m.Ne0); break;

                case Mnemonic.bnone: RewriteBnone(); break;

                case Mnemonic.@break: RewriteBreak(); break;

                case Mnemonic.call0: RewriteCall0(); break;

                case Mnemonic.call4: RewriteCallW(4); break;

                case Mnemonic.call8: RewriteCallW(8); break;

                case Mnemonic.call12: RewriteCallW(12); break;

                case Mnemonic.callx0: RewriteCall0(); break;

                case Mnemonic.callx4: RewriteCallW(4); break;

                case Mnemonic.callx8: RewriteCallW(8); break;

                case Mnemonic.callx12: RewriteCallW(12); break;

                case Mnemonic.ceil_s: RewriteCvtFloatToIntegral("__ceil", PrimitiveType.Int32); break;

                case Mnemonic.clamps: RewriteClamps(); break;

                case Mnemonic.cust0: RewritePseudoProc("__cust0"); break;

                case Mnemonic.cust1: RewritePseudoProc("__cust1"); break;

                case Mnemonic.dhi: RewriteCacheFn("__dhi"); break;

                case Mnemonic.dhu: RewriteCacheFn("__dhu"); break;

                case Mnemonic.dhwb: RewriteCacheFn("__dhwb"); break;

                case Mnemonic.dhwbi: RewriteCacheFn("__dhwbi"); break;

                case Mnemonic.dii: RewriteCacheFn("__dii"); break;

                case Mnemonic.diu: RewriteCacheFn("__diu"); break;

                case Mnemonic.dpfr: RewriteCacheFn("__dpfr"); break;

                case Mnemonic.dpfro: RewriteCacheFn("__dpfro"); break;

                case Mnemonic.dpfw: RewriteCacheFn("__dpfw"); break;

                case Mnemonic.dpfwo: RewriteCacheFn("__dpfwo"); break;

                case Mnemonic.dsync: RewritePseudoProc("__dsync"); break;

                case Mnemonic.esync: RewritePseudoProc("__esync"); break;

                case Mnemonic.excw: RewritePseudoProc("__excw"); break;

                case Mnemonic.extui: RewriteExtui(); break;

                case Mnemonic.entry: RewriteEntry(); break;

                case Mnemonic.float_s: RewriteFloat_s(PrimitiveType.Int32); break;

                case Mnemonic.floor_s: RewritePseudoFn("__floor"); break;

                case Mnemonic.iii: RewriteCacheFn("__iii"); break;

                case Mnemonic.iitlb: RewritePseudoProc("__iitlb"); break;

                case Mnemonic.ipf: RewriteCacheFn("__ipf"); break;

                case Mnemonic.isync: RewritePseudoProc("__isync"); break;

                case Mnemonic.j:
                case Mnemonic.jx: RewriteJ(); break;

                case Mnemonic.ill: RewriteIll(); break;

                case Mnemonic.l16si: RewriteLsi(PrimitiveType.Int16); break;

                case Mnemonic.l16ui: RewriteLui(PrimitiveType.UInt16); break;

                case Mnemonic.l32ai: RewriteL32ai(); break;

                case Mnemonic.l32i: RewriteL32i(); break;

                case Mnemonic.l32e: RewriteL32e(); break;

                case Mnemonic.l32i_n: RewriteL32i(); break;

                case Mnemonic.l32r: RewriteCopy(); break;

                case Mnemonic.l8ui: RewriteLui(PrimitiveType.Byte); break;

                case Mnemonic.lddec: RewriteLddecinc(m.ISub); break;

                case Mnemonic.ldinc: RewriteLddecinc(m.IAdd); break;

                case Mnemonic.ldpte: RewritePseudoProc("__ldpte"); break;

                case Mnemonic.loop: RewriteLoop(); break;

                case Mnemonic.lsiu: RewriteLsiu(); break;

                case Mnemonic.madd_s: RewriteMaddSub(m.FAdd); break;

                case Mnemonic.memw: RewriteNop(); break; /// memory sync barriers?

                case Mnemonic.max: RewriteMax(); break;

                case Mnemonic.maxu: RewriteMaxu(); break;

                case Mnemonic.min: RewriteMin(); break;

                case Mnemonic.minu: RewriteMinu(); break;

                case Mnemonic.mov_n: RewriteCopy(); break;

                case Mnemonic.mov_s: RewriteCopy(); break;

                case Mnemonic.movf:
                case Mnemonic.movf_s: RewriteMovft(e => e); break;

                case Mnemonic.movi: RewriteCopy(); break;

                case Mnemonic.movi_n: RewriteMovi_n(); break;

                case Mnemonic.movsp: RewriteCopy(); break;

                case Mnemonic.moveqz:
                case Mnemonic.moveqz_s: RewriteMovcc(m.Eq); break;

                case Mnemonic.movltz:
                case Mnemonic.movltz_s: RewriteMovcc(m.Lt); break;

                case Mnemonic.movgez:
                case Mnemonic.movgez_s: RewriteMovcc(m.Ge); break;

                case Mnemonic.movnez:
                case Mnemonic.movnez_s: RewriteMovcc(m.Ne); break;

                case Mnemonic.movt:
                case Mnemonic.movt_s: RewriteMovft(m.Not); break;

                case Mnemonic.msub_s: RewriteMaddSub(m.FSub); break;

                case Mnemonic.mul_aa_hh: RewriteMul("__mul_hh", Int40); break;

                case Mnemonic.mul_aa_hl: RewriteMul("__mul_hl", Int40); break;

                case Mnemonic.mul_aa_lh: RewriteMul("__mul_lh", Int40); break;

                case Mnemonic.mul_aa_ll: RewriteMul("__mul_ll", Int40); break;

                case Mnemonic.mul_ad_hh: RewriteMul("__mul_hh", Int40); break;

                case Mnemonic.mul_ad_hl: RewriteMul("__mul_hl", Int40); break;

                case Mnemonic.mul_ad_lh: RewriteMul("__mul_lh", Int40); break;

                case Mnemonic.mul_ad_ll: RewriteMul("__mul_ll", Int40); break;

                case Mnemonic.mul_da_hh: RewriteMul("__mul_hh", Int40); break;

                case Mnemonic.mul_da_hl: RewriteMul("__mul_hl", Int40); break;

                case Mnemonic.mul_da_lh: RewriteMul("__mul_lh", Int40); break;

                case Mnemonic.mul_da_ll: RewriteMul("__mul_ll", Int40); break;

                case Mnemonic.mul_dd_hh: RewriteMul("__mul_hh", Int40); break;

                case Mnemonic.mul_dd_hl: RewriteMul("__mul_hl", Int40); break;

                case Mnemonic.mul_dd_lh: RewriteMul("__mul_lh", Int40); break;

                case Mnemonic.mul_dd_ll: RewriteMul("__mul_ll", Int40); break;

                case Mnemonic.mula_aa_hh: RewriteMula("__mul_hh", Int40); break;

                case Mnemonic.mula_aa_hl: RewriteMula("__mul_hl", Int40); break;

                case Mnemonic.mula_aa_lh: RewriteMula("__mul_lh", Int40); break;

                case Mnemonic.mula_aa_ll: RewriteMula("__mul_ll", Int40); break;

                case Mnemonic.mula_ad_hh: RewriteMula("__mul_hh", Int40); break;

                case Mnemonic.mula_ad_hl: RewriteMula("__mul_hl", Int40); break;

                case Mnemonic.mula_ad_lh: RewriteMula("__mul_lh", Int40); break;

                case Mnemonic.mula_ad_ll: RewriteMula("__mul_ll", Int40); break;

                case Mnemonic.mula_da_hh: RewriteMula("__mul_hh", Int40); break;

                case Mnemonic.mula_da_hh_lddec: RewriteMulaIncDec("__mul_hh", Int40, -4); break;

                case Mnemonic.mula_da_hh_ldinc: RewriteMulaIncDec("__mul_hh", Int40, 4); break;

                case Mnemonic.mula_da_hl: RewriteMula("__mul_hl", Int40); break;

                case Mnemonic.mula_da_hl_lddec: RewriteMulaIncDec("__mul_hl", Int40, -4); break;

                case Mnemonic.mula_da_hl_ldinc: RewriteMulaIncDec("__mul_hl", Int40, 4); break;

                case Mnemonic.mula_da_lh: RewriteMula("__mul_lh", Int40); break;

                case Mnemonic.mula_da_lh_lddec: RewriteMulaIncDec("__mul_lh", Int40, -4); break;

                case Mnemonic.mula_da_lh_ldinc: RewriteMulaIncDec("__mul_lh", Int40, 4); break;

                case Mnemonic.mula_da_ll: RewriteMula("__mul_ll", Int40); break;

                case Mnemonic.mula_da_ll_lddec: RewriteMulaIncDec("__mul_ll", Int40, -4); break;

                case Mnemonic.mula_da_ll_ldinc: RewriteMulaIncDec("__mul_ll", Int40, 4); break;

                case Mnemonic.mula_dd_hh: RewriteMula("__mul_hh", Int40); break;

                case Mnemonic.mula_dd_hh_lddec: RewriteMulaIncDec("__mul_hh", Int40, -4); break;

                case Mnemonic.mula_dd_hl: RewriteMula("__mul_hl", Int40); break;

                case Mnemonic.mula_dd_lh: RewriteMula("__mul_lh", Int40); break;

                case Mnemonic.mula_dd_ll: RewriteMula("__mul_ll", Int40); break;

                case Mnemonic.mula_dd_ll_lddec: RewriteMulaIncDec("__mul_ll", Int40, -4); break;

                case Mnemonic.muls_aa_hh: RewriteMuls("__mul_hh", Int40); break;

                case Mnemonic.muls_aa_hl: RewriteMuls("__mul_hl", Int40); break;

                case Mnemonic.muls_aa_lh: RewriteMuls("__mul_lh", Int40); break;

                case Mnemonic.muls_aa_ll: RewriteMuls("__mul_ll", Int40); break;

                case Mnemonic.muls_ad_hh: RewriteMuls("__mul_hh", Int40); break;

                case Mnemonic.muls_ad_hl: RewriteMuls("__mul_hl", Int40); break;

                case Mnemonic.muls_ad_lh: RewriteMuls("__mul_lh", Int40); break;

                case Mnemonic.muls_ad_ll: RewriteMuls("__mul_ll", Int40); break;

                case Mnemonic.muls_da_hh: RewriteMuls("__mul_hh", Int40); break;

                case Mnemonic.muls_da_hl: RewriteMuls("__mul_hl", Int40); break;

                case Mnemonic.muls_da_lh: RewriteMuls("__mul_lh", Int40); break;

                case Mnemonic.muls_da_ll: RewriteMuls("__mul_ll", Int40); break;

                case Mnemonic.muls_dd_hh: RewriteMuls("__mul_hh", Int40); break;

                case Mnemonic.muls_dd_hl: RewriteMuls("__mul_hl", Int40); break;

                case Mnemonic.muls_dd_lh: RewriteMuls("__mul_lh", Int40); break;

                case Mnemonic.muls_dd_ll: RewriteMuls("__mul_ll", Int40); break;

                case Mnemonic.mul_s: RewriteBinOp(m.FMul); break;

                case Mnemonic.mul16s: RewriteMul16(m.SMul, Domain.SignedInt); break;

                case Mnemonic.mul16u: RewriteMul16(m.UMul, Domain.UnsignedInt); break;

                case Mnemonic.mull: RewriteBinOp(m.IMul); break;

                case Mnemonic.mulsh: RewriteMulh("__mulsh", PrimitiveType.Int32); break;

                case Mnemonic.muluh: RewriteMulh("__muluh", PrimitiveType.UInt32); break;

                case Mnemonic.neg: RewriteUnaryOp(m.Neg); break;

                case Mnemonic.nsa: RewritePseudoFn("__nsa"); break;

                case Mnemonic.nsau: RewritePseudoFn("__nsau"); break;

                case Mnemonic.oeq_s: RewriteBinOp(m.FEq); break;    //$REVIEW: what to do about 'ordered' and 'unordered'

                case Mnemonic.ole_s: RewriteBinOp(m.FLe); break;    //$REVIEW: what to do about 'ordered' and 'unordered'

                case Mnemonic.olt_s: RewriteBinOp(m.FLt); break;    //$REVIEW: what to do about 'ordered' and 'unordered'

                case Mnemonic.or: RewriteOr(); break;

                case Mnemonic.orb: RewriteOr(); break;

                case Mnemonic.orbc: RewriteBinOp((a, b) => m.Or(a, m.Not(b))); break;

                case Mnemonic.pitlb: RewritePseudoFn("__pitlb"); break;

                case Mnemonic.quos: RewriteBinOp(m.SDiv); break;

                case Mnemonic.quou: RewriteBinOp(m.UDiv); break;

                case Mnemonic.rdtlb0: RewritePseudoFn("__rdtlb0"); break;

                case Mnemonic.rdtlb1: RewritePseudoFn("__rdtlb1"); break;

                case Mnemonic.rems: RewriteBinOp(m.Mod); break;

                case Mnemonic.remu: RewriteBinOp(m.Mod); break;

                case Mnemonic.ret:
                case Mnemonic.ret_n: RewriteRet(); break;

                case Mnemonic.rfe: RewriteRet(); break;      //$REVIEW: emit some hint this is a return from exception?

                case Mnemonic.rfi: RewriteRet(); break;      //$REVIEW: emit some hint this is a return from interrupt?

                case Mnemonic.ritlb0: RewritePseudoFn("__ritlb0"); break;

                case Mnemonic.ritlb1: RewritePseudoFn("__ritlb1"); break;

                case Mnemonic.rotw: RewritePseudoProc("__rotw"); break;

                case Mnemonic.round_s: RewriteCvtFloatToIntegral("__round", PrimitiveType.Int32); break;

                case Mnemonic.rsil: RewritePseudoFn("__rsil"); break;

                case Mnemonic.rer: RewriteRer(); break;

                case Mnemonic.rfr: RewriteCopy(); break;

                case Mnemonic.rsr: RewriteCopy(); break;

                case Mnemonic.rsync: RewriteRsync(); break;

                case Mnemonic.rur: RewriteCopy(); break;

                case Mnemonic.s16i: RewriteSi(PrimitiveType.Word16); break;

                case Mnemonic.s32c1i: RewriteS32c1i(); break;

                case Mnemonic.s32e: RewriteS32e(); break;

                case Mnemonic.s32i:
                case Mnemonic.s32i_n: RewriteSi(PrimitiveType.Word32); break;

                case Mnemonic.s32ri: RewriteSi(PrimitiveType.Word32); break; //$REVIEW: what about concurrency semantics

                case Mnemonic.s8i: RewriteSi(PrimitiveType.Byte); break;

                case Mnemonic.sext: RewriteSext(); break;

                case Mnemonic.sll: RewriteShift(m.Shl); break;

                case Mnemonic.slli: RewriteShiftI(m.Shl); break;

                case Mnemonic.sra: RewriteShift(m.Sar); break;

                case Mnemonic.srai: RewriteShiftI(m.Sar); break;

                case Mnemonic.src: RewriteSrc(); break;

                case Mnemonic.srl: RewriteShift(m.Sar); break;

                case Mnemonic.srli: RewriteShiftI(m.Shr); break;

                case Mnemonic.ssa8b: RewriteSsa8b(); break;

                case Mnemonic.ssa8l: RewriteSsa8l(); break;

                case Mnemonic.ssi: RewriteSi(PrimitiveType.Real32); break;

                case Mnemonic.ssl: RewriteSsl(); break;

                case Mnemonic.ssr:
                case Mnemonic.ssai: RewriteSsa(); break;

                case Mnemonic.sub: RewriteBinOp(m.ISub); break;

                case Mnemonic.sub_s: RewriteBinOp(m.FSub); break;

                case Mnemonic.subx2: RewriteSubx(2); break;

                case Mnemonic.subx4: RewriteSubx(4); break;

                case Mnemonic.subx8: RewriteSubx(8); break;

                case Mnemonic.syscall: RewriteSyscall(); break;

                case Mnemonic.trunc_s: RewriteCvtFloatToIntegral("__trunc", PrimitiveType.Int32); break;

                case Mnemonic.ueq_s: RewriteBinOp(m.Eq); break;     //$REVIEW: what to do about 'ordered' and 'unordered'

                case Mnemonic.ufloat_s: RewriteFloat_s(PrimitiveType.UInt32); break;

                case Mnemonic.ule_s: RewriteBinOp(m.FLe); break;    //$REVIEW: what to do about 'ordered' and 'unordered'

                case Mnemonic.ult_s: RewriteBinOp(m.FLt); break;    //$REVIEW: what to do about 'ordered' and 'unordered'

                case Mnemonic.umul_aa_hh: RewriteMul("__umul_hh", UInt40); break;

                case Mnemonic.umul_aa_hl: RewriteMul("__umul_hl", UInt40); break;

                case Mnemonic.umul_aa_lh: RewriteMul("__umul_lh", UInt40); break;

                case Mnemonic.umul_aa_ll: RewriteMul("__umul_ll", UInt40); break;

                case Mnemonic.un_s: RewritePseudoFn("isunordered"); break;

                case Mnemonic.utrunc_s: RewriteCvtFloatToIntegral("__utrunc", PrimitiveType.UInt32); break;

                case Mnemonic.waiti: RewritePseudoProc("__waiti"); break;

                case Mnemonic.wdtlb: RewritePseudoProc("__wdtlb"); break;

                case Mnemonic.witlb: RewritePseudoProc("__witlb"); break;

                case Mnemonic.wer: RewriteWer(); break;

                case Mnemonic.wsr: RewriteWsr(); break;

                case Mnemonic.wur: RewriteInverseCopy(); break;

                case Mnemonic.xor: RewriteBinOp(m.Xor); break;

                case Mnemonic.xorb: RewriteBinOp(m.Xor); break;

                case Mnemonic.xsr: RewriteXsr(); break;
                }
                CheckForLoopExit();
                yield return(m.MakeCluster(addr, len, iclass));
            }
        }
Example #10
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                this.instr = dasm.Current;
                var cluster = new List <RtlInstruction>();
                m      = new RtlEmitter(cluster);
                iclass = instr.InstructionClass;
                switch (instr.Mnemonic)
                {
                default:
                    EmitUnitTest();
                    host.Warn(
                        instr.Address,
                        "AArch64 instruction {0} is not supported yet.",
                        instr);
                    goto case Mnemonic.Invalid;

                case Mnemonic.Invalid:
                    iclass = InstrClass.Invalid;
                    m.Invalid();
                    break;

                case Mnemonic.add: RewriteMaybeSimdBinary(m.IAdd, "__add_{0}"); break;

                case Mnemonic.adds: RewriteBinary(m.IAdd, this.NZCV); break;

                case Mnemonic.addv: RewriteAddv(); break;

                case Mnemonic.adr: RewriteUnary(n => n); break;

                case Mnemonic.asrv: RewriteBinary(m.Sar); break;

                case Mnemonic.bic: RewriteBinary((a, b) => m.And(a, m.Comp(b))); break;

                case Mnemonic.adrp: RewriteAdrp(); break;

                case Mnemonic.and: RewriteBinary(m.And); break;

                case Mnemonic.ands: RewriteBinary(m.And, this.NZ00); break;

                case Mnemonic.asr: RewriteBinary(m.Sar); break;

                case Mnemonic.b: RewriteB(); break;

                case Mnemonic.bfm: RewriteBfm(); break;

                case Mnemonic.bl: RewriteBl(); break;

                case Mnemonic.blr: RewriteBlr(); break;

                case Mnemonic.br: RewriteBr(); break;

                case Mnemonic.cbnz: RewriteCb(m.Ne0); break;

                case Mnemonic.cbz: RewriteCb(m.Eq0); break;

                case Mnemonic.ccmn: RewriteCcmn(); break;

                case Mnemonic.ccmp: RewriteCcmp(); break;

                case Mnemonic.clz: RewriteClz(); break;

                case Mnemonic.cmp: RewriteCmp(); break;

                case Mnemonic.cmeq: RewriteCmeq(); break;

                case Mnemonic.csel: RewriteCsel(); break;

                case Mnemonic.csinc: RewriteCsinc(); break;

                case Mnemonic.csinv: RewriteCsinv(); break;

                case Mnemonic.csneg: RewriteCsneg(); break;

                case Mnemonic.dsb: RewriteDsb(); break;

                case Mnemonic.dup: RewriteDup(); break;

                case Mnemonic.eor: RewriteBinary(m.Xor); break;

                case Mnemonic.fabs: RewriteFabs(); break;

                case Mnemonic.fadd: RewriteFadd(); break;

                case Mnemonic.fcmp: RewriteFcmp(); break;

                case Mnemonic.fcsel: RewriteFcsel(); break;

                case Mnemonic.fcvt: RewriteFcvt(); break;

                case Mnemonic.fcvtms: RewriteFcvtms(); break;

                case Mnemonic.fcvtps: RewriteFcvtps(); break;

                case Mnemonic.fcvtzs: RewriteFcvtzs(); break;

                case Mnemonic.fdiv: RewriteMaybeSimdBinary(m.FDiv, "__fdiv_{0}", Domain.Real); break;

                case Mnemonic.fmadd: RewriteIntrinsicFTernary("__fmaddf", "__fmadd"); break;

                case Mnemonic.fmsub: RewriteIntrinsicFTernary("__fmsubf", "__fmsub"); break;

                case Mnemonic.fmax: RewriteIntrinsicFBinary("fmaxf", "fmax"); break;

                case Mnemonic.fmin: RewriteIntrinsicFBinary("fminf", "fmin"); break;

                case Mnemonic.fmov: RewriteFmov(); break;

                case Mnemonic.fmul: RewriteFmul(); break;

                case Mnemonic.fneg: RewriteUnary(m.FNeg); break;

                case Mnemonic.fnmul: RewriteFnmul(); break;

                case Mnemonic.fsqrt: RewriteFsqrt(); break;

                case Mnemonic.fsub: RewriteMaybeSimdBinary(m.FSub, "__fsub_{0}", Domain.Real); break;

                case Mnemonic.isb: RewriteIsb(); break;

                case Mnemonic.ld1r: RewriteLdNr("__ld1r"); break;

                case Mnemonic.ld2: RewriteLdN("__ld2"); break;

                case Mnemonic.ld3: RewriteLdN("__ld3"); break;

                case Mnemonic.ld4: RewriteLdN("__ld4"); break;

                case Mnemonic.ldp: RewriteLoadStorePair(true); break;

                case Mnemonic.ldpsw: RewriteLoadStorePair(true, PrimitiveType.Int32, PrimitiveType.Int64); break;

                case Mnemonic.ldr: RewriteLdr(null); break;

                case Mnemonic.ldrb: RewriteLdr(PrimitiveType.Byte); break;

                case Mnemonic.ldrh: RewriteLdr(PrimitiveType.Word16); break;

                case Mnemonic.ldrsb: RewriteLdr(PrimitiveType.SByte); break;

                case Mnemonic.ldrsh: RewriteLdr(PrimitiveType.Int16); break;

                case Mnemonic.ldrsw: RewriteLdr(PrimitiveType.Int32); break;

                case Mnemonic.lslv: RewriteBinary(m.Shl); break;

                case Mnemonic.lsrv: RewriteBinary(m.Shr); break;

                case Mnemonic.ldur: RewriteLdr(null); break;

                case Mnemonic.ldurb: RewriteLdr(PrimitiveType.Byte); break;

                case Mnemonic.ldurh: RewriteLdr(PrimitiveType.Word16); break;

                case Mnemonic.ldursb: RewriteLdr(PrimitiveType.SByte); break;

                case Mnemonic.ldursh: RewriteLdr(PrimitiveType.Int16); break;

                case Mnemonic.ldursw: RewriteLdr(PrimitiveType.Int32); break;

                case Mnemonic.lsl: RewriteBinary(m.Shl); break;

                case Mnemonic.lsr: RewriteBinary(m.Shr); break;

                case Mnemonic.madd: RewriteMaddSub(m.IAdd); break;

                case Mnemonic.mneg: RewriteBinary((a, b) => m.Neg(m.IMul(a, b))); break;

                case Mnemonic.msub: RewriteMaddSub(m.ISub); break;

                case Mnemonic.mov: RewriteMov(); break;

                case Mnemonic.movi: RewriteMovi(); break;

                case Mnemonic.movk: RewriteMovk(); break;

                case Mnemonic.movn: RewriteMovn(); break;

                case Mnemonic.movz: RewriteMovz(); break;

                case Mnemonic.mrs: RewriteMrs(); break;

                case Mnemonic.msr: RewriteMsr(); break;

                case Mnemonic.mul: RewriteMaybeSimdBinary(m.IMul, "__mul_{0}"); break;

                case Mnemonic.mvn: RewriteUnary(m.Comp); break;

                case Mnemonic.nop: m.Nop(); break;

                case Mnemonic.not: RewriteMaybeSimdUnary(m.Comp, "__not_{0}"); break;

                case Mnemonic.orr: RewriteBinary(m.Or); break;

                case Mnemonic.orn: RewriteBinary((a, b) => m.Or(a, m.Comp(b))); break;

                case Mnemonic.prfm: RewritePrfm(); break;

                case Mnemonic.ret: RewriteRet(); break;

                case Mnemonic.rev16: RewriteRev16(); break;

                case Mnemonic.ror: RewriteRor(); break;

                case Mnemonic.rorv: RewriteRor(); break;

                case Mnemonic.sbfiz: RewriteSbfiz(); break;

                case Mnemonic.sbfm: RewriteUSbfm("__sbfm"); break;

                case Mnemonic.scvtf: RewriteScvtf(); break;

                case Mnemonic.sdiv: RewriteBinary(m.SDiv); break;

                case Mnemonic.shrn: RewriteShrn(); break;

                case Mnemonic.smaddl: RewriteMaddl(PrimitiveType.Int64, m.SMul); break;

                case Mnemonic.smax: RewriteSmax(); break;

                case Mnemonic.smaxv: RewriteSmaxv(); break;

                case Mnemonic.smc: RewriteSmc(); break;

                case Mnemonic.smull: RewriteMull(PrimitiveType.Int64, m.SMul); break;

                case Mnemonic.st1: RewriteStN("__st1"); break;

                case Mnemonic.st2: RewriteStN("__st2"); break;

                case Mnemonic.st3: RewriteStN("__st3"); break;

                case Mnemonic.st4: RewriteStN("__st4"); break;

                case Mnemonic.stlr: RewriteStlr(); break;

                case Mnemonic.stp: RewriteLoadStorePair(false); break;

                case Mnemonic.str: RewriteStr(null); break;

                case Mnemonic.strb: RewriteStr(PrimitiveType.Byte); break;

                case Mnemonic.strh: RewriteStr(PrimitiveType.Word16); break;

                case Mnemonic.stur: RewriteStr(null); break;

                case Mnemonic.sturb: RewriteStr(PrimitiveType.Byte); break;

                case Mnemonic.sturh: RewriteStr(PrimitiveType.Word16); break;

                case Mnemonic.sub: RewriteBinary(m.ISub); break;

                case Mnemonic.subs: RewriteBinary(m.ISub, NZCV); break;

                case Mnemonic.svc: RewriteSvc(); break;

                case Mnemonic.sxtb: RewriteUSxt(Domain.SignedInt, 8); break;

                case Mnemonic.sxth: RewriteUSxt(Domain.SignedInt, 16); break;

                case Mnemonic.sxtl: RewriteSimdUnary("__sxtl_{0}", Domain.SignedInt); break;

                case Mnemonic.sxtw: RewriteUSxt(Domain.SignedInt, 32); break;

                case Mnemonic.tbnz: RewriteTb(m.Ne0); break;

                case Mnemonic.tbz: RewriteTb(m.Eq0); break;

                case Mnemonic.test: RewriteTest(); break;

                case Mnemonic.uaddw: RewriteUaddw(); break;

                case Mnemonic.ubfm: RewriteUSbfm("__ubfm"); break;

                case Mnemonic.ucvtf: RewriteIcvt(Domain.UnsignedInt); break;

                case Mnemonic.udiv: RewriteBinary(m.UDiv); break;

                case Mnemonic.umaddl: RewriteMaddl(PrimitiveType.UInt64, m.UMul); break;

                case Mnemonic.umlal: RewriteUmlal(); break;

                case Mnemonic.umull: RewriteMull(PrimitiveType.UInt64, m.UMul); break;

                case Mnemonic.umulh: RewriteMulh(PrimitiveType.UInt64, m.UMul); break;

                case Mnemonic.uxtb: RewriteUSxt(Domain.UnsignedInt, 8); break;

                case Mnemonic.uxth: RewriteUSxt(Domain.UnsignedInt, 16); break;

                case Mnemonic.uxtl: RewriteSimdUnary("__uxtl_{0}", Domain.UnsignedInt); break;

                case Mnemonic.uxtw: RewriteUSxt(Domain.UnsignedInt, 32); break;

                case Mnemonic.xtn: RewriteSimdUnary("__xtn_{0}", Domain.None); break;
                }
                yield return(m.MakeCluster(instr.Address, instr.Length, iclass));
            }
        }
Example #11
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                di        = dasm.Current;
                ric       = new RtlInstructionCluster(di.Address, di.Length);
                ric.Class = RtlClass.Linear;
                emitter   = new RtlEmitter(ric.Instructions);
                orw       = new OperandRewriter(arch, this.emitter, this.frame, di.dataWidth);
                switch (di.code)
                {
                case Opcode.add: RewriteBinOp((s, d) => emitter.IAdd(d, s), FlagM.CVZNX); break;

                case Opcode.adda: RewriteBinOp((s, d) => emitter.IAdd(d, s)); break;

                case Opcode.addi: RewriteArithmetic((s, d) => emitter.IAdd(d, s)); break;

                case Opcode.addq: RewriteAddSubq((s, d) => emitter.IAdd(d, s)); break;

                case Opcode.addx: RewriteAddSubx(emitter.IAdd); break;

                case Opcode.and: RewriteLogical((s, d) => emitter.And(d, s)); break;

                case Opcode.andi: RewriteLogical((s, d) => emitter.And(d, s)); break;

                case Opcode.asl: RewriteArithmetic((s, d) => emitter.Shl(d, s)); break;

                case Opcode.asr: RewriteShift((s, d) => emitter.Sar(d, s)); break;

/*
 *
 * Mnemonic Condition Encoding Test
 * T* True 0000 1
 * F* False 0001 0
 * HI High 0010 C L Z
 * LS Low or Same 0011 C V Z
 * VC Overflow Clear 1000 V
 * VS Overflow Set 1001 V
 */
                case Opcode.bclr: RewriteBclrBset("__bclr"); break;

                case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break;

                case Opcode.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break;

                case Opcode.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Opcode.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.blt: RewriteBcc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break;

                case Opcode.bls: RewriteBcc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Opcode.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break;

                case Opcode.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break;

                case Opcode.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break;

                case Opcode.bchg: RewriteBchg(); break;

                case Opcode.bra: RewriteBra(); break;

                case Opcode.bset: RewriteBclrBset("__bset"); break;

                case Opcode.bsr: RewriteBsr(); break;

                case Opcode.btst: RewriteBtst(); break;

                case Opcode.clr: RewriteClr(); break;

                case Opcode.cmp: RewriteCmp(); break;

                case Opcode.cmpa: RewriteCmp(); break;

                case Opcode.cmpi: RewriteCmp(); break;

                case Opcode.cmpm: RewriteCmp(); break;

                case Opcode.dbeq: RewriteDbcc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.dbhi: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break;

                case Opcode.dbne: RewriteDbcc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.dbra: RewriteDbcc(ConditionCode.None, 0); break;

                case Opcode.divs: RewriteDiv(emitter.SDiv, PrimitiveType.Int16); break;

                case Opcode.divu: RewriteDiv(emitter.UDiv, PrimitiveType.UInt16); break;

                case Opcode.eor: RewriteLogical((s, d) => emitter.Xor(d, s)); break;

                case Opcode.eori: RewriteLogical((s, d) => emitter.Xor(d, s)); break;

                case Opcode.exg: RewriteExg(); break;

                case Opcode.ext: RewriteExt(); break;

                case Opcode.extb: RewriteExtb(); break;

                case Opcode.fadd: RewriteFBinOp((s, d) => emitter.FAdd(d, s)); break;

                //$REVIEW: the following don't respect NaN, but NaN typically doesn't exist in HLLs.
                case Opcode.fbnge: RewriteFbcc(ConditionCode.LT); break;

                case Opcode.fbnlt: RewriteFbcc(ConditionCode.GE); break;

                case Opcode.fbnle: RewriteFbcc(ConditionCode.GT); break;

                case Opcode.fcmp: RewriteFcmp(); break;

                case Opcode.fdiv: RewriteFBinOp((s, d) => emitter.FDiv(d, s)); break;

                case Opcode.fmove: RewriteFmove(); break;

                case Opcode.fmovecr: RewriteFmovecr(); break;

                case Opcode.fmovem: RewriteMovem(i => arch.GetRegister(i + Registers.fp0.Number)); break;

                case Opcode.fmul: RewriteFBinOp((s, d) => emitter.FMul(d, s)); break;

                case Opcode.fneg: RewriteFUnaryOp(emitter.Neg); break;

                case Opcode.fsub: RewriteFBinOp((s, d) => emitter.FSub(d, s)); break;

                case Opcode.illegal: if (!RewriteIllegal())
                    {
                        goto default;
                    }
                    break;

                case Opcode.jmp: RewriteJmp(); break;

                case Opcode.jsr: RewriteJsr(); break;

                case Opcode.lea: RewriteLea(); break;

                case Opcode.link: RewriteLink(); break;

                case Opcode.lsl: RewriteShift((s, d) => emitter.Shl(d, s)); break;

                case Opcode.lsr: RewriteShift((s, d) => emitter.Shr(d, s)); break;

                case Opcode.move: RewriteMove(true); break;

                case Opcode.movea: RewriteMove(false); break;

                case Opcode.moveq: RewriteMoveq(); break;

                case Opcode.movem: RewriteMovem(arch.GetRegister); break;

                case Opcode.muls: RewriteMul((s, d) => emitter.SMul(d, s)); break;

                case Opcode.mulu: RewriteMul((s, d) => emitter.UMul(d, s)); break;

                case Opcode.neg: RewriteUnary(s => emitter.Neg(s), AllConditions); break;

                case Opcode.negx: RewriteUnary(RewriteNegx, AllConditions); break;

                case Opcode.nop: emitter.Nop(); break;

                case Opcode.not: RewriteUnary(s => emitter.Comp(s), LogicalConditions); break;

                case Opcode.or: RewriteLogical((s, d) => emitter.Or(d, s)); break;

                case Opcode.ori: RewriteLogical((s, d) => emitter.Or(d, s)); break;

                case Opcode.pea: RewritePea(); break;

                case Opcode.rol: RewriteRotation(PseudoProcedure.Rol); break;

                case Opcode.ror: RewriteRotation(PseudoProcedure.Ror);  break;

                case Opcode.roxl: RewriteRotationX(PseudoProcedure.RolC);  break;

                case Opcode.roxr: RewriteRotationX(PseudoProcedure.RorC);  break;

                case Opcode.rts: RewriteRts(); break;

                case Opcode.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break;

                case Opcode.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break;

                case Opcode.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break;

                case Opcode.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break;

                case Opcode.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break;

                case Opcode.slt: RewriteScc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break;

                case Opcode.sls: RewriteScc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break;

                case Opcode.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break;

                case Opcode.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break;

                case Opcode.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break;

                case Opcode.st: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.True()); break;

                case Opcode.sf: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.False()); break;

                case Opcode.sub: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break;

                case Opcode.suba: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break;

                case Opcode.subi: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break;

                case Opcode.subq: RewriteAddSubq((s, d) => emitter.ISub(d, s)); break;

                case Opcode.subx: RewriteArithmetic((s, d) => emitter.ISub(emitter.ISub(d, s), frame.EnsureFlagGroup(Registers.ccr, (uint)FlagM.XF, "X", PrimitiveType.Bool))); break;

                case Opcode.swap: RewriteSwap(); break;

                case Opcode.tst: RewriteTst(); break;

                case Opcode.unlk: RewriteUnlk(); break;

                default:
                    throw new AddressCorrelatedException(
                              di.Address,
                              "Rewriting M68k opcode '{0}' is not supported yet.",
                              di.code);
                }
                yield return(ric);
            }
            yield break;
        }
Example #12
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                this.instr  = dasm.Current;
                this.iclass = this.instr.InstructionClass;
                var instrs = new List <RtlInstruction>();
                this.m = new RtlEmitter(instrs);
                switch (this.instr.Mnemonic)
                {
                default:
                    EmitUnitTest();
                    host.Warn(
                        dasm.Current.Address,
                        "AVR32 instruction '{0}' is not supported yet.",
                        instr.Mnemonic);
                    goto case Mnemonic.invalid;

                case Mnemonic.invalid: m.Invalid(); break;

                case Mnemonic.abs: RewriteAbs(); break;

                case Mnemonic.acall: RewriteAcall(); break;

                case Mnemonic.acr: RewriteAcr(); break;

                case Mnemonic.adc: RewriteAdc(); break;

                case Mnemonic.add: RewriteAdd(); break;

                case Mnemonic.andh: RewriteAndh(); break;

                case Mnemonic.andl: RewriteAndl(); break;

                case Mnemonic.and: RewriteLogical(m.And); break;

                case Mnemonic.andnot: RewriteLogical((a, b) => m.And(a, m.Comp(b))); break;

                case Mnemonic.asr: RewriteShift(m.Sar); break;

                case Mnemonic.bfexts: RewriteBfexts(); break;

                case Mnemonic.bfextu: RewriteBfextu(); break;

                case Mnemonic.bld: RewriteBld(); break;

                case Mnemonic.br: RewriteBranch(); break;

                case Mnemonic.bst: RewriteBst(); break;

                case Mnemonic.casts_b: RewriteCast(PrimitiveType.SByte, PrimitiveType.Int32); break;

                case Mnemonic.casts_h: RewriteCast(PrimitiveType.Int16, PrimitiveType.Int32); break;

                case Mnemonic.castu_b: RewriteCast(PrimitiveType.Byte, PrimitiveType.Word32); break;

                case Mnemonic.castu_h: RewriteCast(PrimitiveType.Word16, PrimitiveType.Word32); break;

                case Mnemonic.cbr: RewriteCbr(); break;

                case Mnemonic.com: RewriteCom(); break;

                case Mnemonic.clz: RewriteClz(); break;

                case Mnemonic.cp_b: RewriteCp_b(); break;

                case Mnemonic.cp_w: RewriteCp_w(); break;

                case Mnemonic.cpc: RewriteCpc(); break;

                case Mnemonic.divs: RewriteDiv(m.SDiv); break;

                case Mnemonic.divu: RewriteDiv(m.UDiv); break;

                case Mnemonic.eor: RewriteLogical(m.Xor); break;

                case Mnemonic.eorh: RewriteOrh(m.Xor); break;

                case Mnemonic.eorl: RewriteOrh(m.Xor); break;

                case Mnemonic.icall: RewriteCall(); break;

                case Mnemonic.ld_d: RewriteLd(PrimitiveType.Word64, PrimitiveType.Word64); break;

                case Mnemonic.ld_sb: RewriteLd(PrimitiveType.SByte, PrimitiveType.Int32); break;

                case Mnemonic.ld_sh: RewriteLd(PrimitiveType.Int16, PrimitiveType.Int32); break;

                case Mnemonic.ld_ub: RewriteLd(PrimitiveType.Byte, PrimitiveType.Word32); break;

                case Mnemonic.ld_uh: RewriteLd(PrimitiveType.Word16, PrimitiveType.Word32); break;

                case Mnemonic.ld_w: RewriteLd(PrimitiveType.Word32, PrimitiveType.Word32); break;

                case Mnemonic.lddpc: RewriteLddpc(); break;

                case Mnemonic.lddsp: RewriteLddsp(); break;

                case Mnemonic.ldm: RewriteLdm(); break;

                case Mnemonic.lsl: RewriteShift(m.Shl); break;

                case Mnemonic.lsr: RewriteShift(m.Shr); break;

                case Mnemonic.macs_d: RewriteMac_d(m.SMul); break;

                case Mnemonic.macu_d: RewriteMac_d(m.UMul); break;

                case Mnemonic.max: RewriteMax(); break;

                case Mnemonic.mcall: RewriteCall(); break;

                case Mnemonic.min: RewriteMin(); break;

                case Mnemonic.mov: RewriteMov(); break;

                case Mnemonic.movh: RewriteMovh(); break;

                case Mnemonic.mul: RewriteMul(); break;

                case Mnemonic.muls_d: RewriteMul_d(m.SMul); break;

                case Mnemonic.mulu_d: RewriteMul_d(m.UMul); break;

                case Mnemonic.mustr: RewriteMustr(); break;

                case Mnemonic.neg: RewriteNeg(); break;

                case Mnemonic.nop: m.Nop(); break;

                case Mnemonic.or: RewriteLogical(m.Or); break;

                case Mnemonic.orh: RewriteOrh(m.Or); break;

                case Mnemonic.orl: RewriteOrl(m.Or); break;

                case Mnemonic.popm: RewritePopm(); break;

                case Mnemonic.pushm: RewritePushm(); break;

                case Mnemonic.ret: RewriteRet(); break;

                case Mnemonic.rcall: RewriteCall(); break;

                case Mnemonic.rjmp: RewriteGoto(); break;

                case Mnemonic.rol: RewriteRol(); break;

                case Mnemonic.ror: RewriteRor(); break;

                case Mnemonic.rsub: RewriteRsub(); break;

                case Mnemonic.sats: RewriteSat("__sats", PrimitiveType.Int32); break;

                case Mnemonic.satu: RewriteSat("__satu", PrimitiveType.UInt32); break;

                case Mnemonic.satsub_w: RewriteSatsubW(); break;

                case Mnemonic.sbc: RewriteSbc(); break;

                case Mnemonic.sbr: RewriteSbr(); break;

                case Mnemonic.scr: RewriteScr(); break;

                case Mnemonic.sr: RewriteSr(); break;

                case Mnemonic.stm: RewriteStm(); break;

                case Mnemonic.st_b: RewriteSt(PrimitiveType.Byte); break;

                case Mnemonic.st_h: RewriteSt(PrimitiveType.Word16); break;

                case Mnemonic.st_w: RewriteSt(PrimitiveType.Word32); break;

                case Mnemonic.st_d: RewriteSt(PrimitiveType.Word64); break;

                case Mnemonic.stcond: RewriteStcond(); break;

                case Mnemonic.stdsp: RewriteStdsp(); break;

                case Mnemonic.sub: RewriteSub(); break;

                case Mnemonic.subf: RewriteSub(); break;

                case Mnemonic.tst: RewriteTst(); break;
                }
                yield return(m.MakeCluster(instr.Address, instr.Length, iclass));
            }
        }
Example #13
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);
        }
Example #14
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                this.instr = dasm.Current;
                iclass     = instr.InstructionClass;
                try
                {
                    switch (instr.Mnemonic)
                    {
                    default:
                        EmitUnitTest();
                        host.Warn(
                            instr.Address,
                            "AArch64 instruction {0} is not supported yet.",
                            instr);
                        goto case Mnemonic.Invalid;

                    case Mnemonic.Invalid:
                        iclass = InstrClass.Invalid;
                        m.Invalid();
                        break;

                    case Mnemonic.abs: RewriteSimdUnary("__abs_{0}", Domain.SignedInt); break;

                    case Mnemonic.adc: RewriteAdcSbc(m.IAdd); break;

                    case Mnemonic.adcs: RewriteAdcSbc(m.IAdd, this.NZCV); break;

                    case Mnemonic.add: RewriteMaybeSimdBinary(m.IAdd, "__add_{0}"); break;

                    case Mnemonic.addhn: RewriteSimdBinary("__addhn_{0}", Domain.None); break;

                    case Mnemonic.addhn2: RewriteSimdBinary("__addhn2_{0}", Domain.None); break;

                    case Mnemonic.addp: RewriteSimdBinary("__addp_{0}", Domain.None); break;

                    case Mnemonic.adds: RewriteBinary(m.IAdd, this.NZCV); break;

                    case Mnemonic.addv: RewriteAddv(); break;

                    case Mnemonic.adr: RewriteUnary(n => n); break;

                    case Mnemonic.asrv: RewriteBinary(m.Sar); break;

                    case Mnemonic.adrp: RewriteAdrp(); break;

                    case Mnemonic.and: RewriteBinary(m.And); break;

                    case Mnemonic.ands: RewriteBinary(m.And, this.NZ00); break;

                    case Mnemonic.asr: RewriteBinary(m.Sar); break;

                    case Mnemonic.b: RewriteB(); break;

                    case Mnemonic.bfm: RewriteBfm(); break;

                    case Mnemonic.bic: RewriteLogical((a, b) => m.And(a, m.Comp(b))); break;

                    case Mnemonic.bics: RewriteBinary((a, b) => m.And(a, m.Comp(b)), NZ00); break;

                    case Mnemonic.bif: RewriteSimdBinary("__bif_{0}", Domain.None); break;

                    case Mnemonic.bit: RewriteSimdBinary("__bit_{0}", Domain.None); break;

                    case Mnemonic.bl: RewriteBl(); break;

                    case Mnemonic.blr: RewriteBlr(); break;

                    case Mnemonic.br: RewriteBr(); break;

                    case Mnemonic.brk: RewriteBrk(); break;

                    case Mnemonic.bsl: RewriteBsl(); break;

                    case Mnemonic.cbnz: RewriteCb(m.Ne0); break;

                    case Mnemonic.cbz: RewriteCb(m.Eq0); break;

                    case Mnemonic.ccmn: RewriteCcmn(); break;

                    case Mnemonic.ccmp: RewriteCcmp(); break;

                    case Mnemonic.cls: RewriteSimdUnary("__cls_{0}", Domain.None); break;

                    case Mnemonic.clz: RewriteClz(); break;

                    case Mnemonic.cmp: RewriteCmp(); break;

                    case Mnemonic.cmeq: RewriteCm("__cmeq_{0}", Domain.None); break;

                    case Mnemonic.cmge: RewriteCm("__cmge_{0}", Domain.SignedInt); break;

                    case Mnemonic.cmgt: RewriteCm("__cmgt_{0}", Domain.SignedInt); break;

                    case Mnemonic.cmhi: RewriteCm("__cmhi_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.cmhs: RewriteCm("__cmhs_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.cmle: RewriteCm("__cmle_{0}", Domain.SignedInt); break;

                    case Mnemonic.cmlt: RewriteCm("__cmlt_{0}", Domain.SignedInt); break;

                    case Mnemonic.cmtst: RewriteCm("__cmtst_{0}", Domain.None); break;

                    case Mnemonic.cnt: RewriteSimdUnary("__cnt_{0}", Domain.None); break;

                    case Mnemonic.csel: RewriteCsel(); break;

                    case Mnemonic.csinc: RewriteCsinc(); break;

                    case Mnemonic.csinv: RewriteCsinv(); break;

                    case Mnemonic.csneg: RewriteCsneg(); break;

                    case Mnemonic.dmb: RewriteDmb(); break;

                    case Mnemonic.dsb: RewriteDsb(); break;

                    case Mnemonic.dup: RewriteDup(); break;

                    case Mnemonic.eor: RewriteBinary(m.Xor); break;

                    case Mnemonic.eon: RewriteBinary((a, b) => m.Xor(a, m.Comp(b))); break;

                    case Mnemonic.eret: RewriteEret(); break;

                    case Mnemonic.ext: RewriteExt(); break;

                    case Mnemonic.extr: RewriteExtr(); break;

                    case Mnemonic.fabs: RewriteFabs(); break;

                    case Mnemonic.fadd: RewriteFadd(); break;

                    case Mnemonic.fcmp: RewriteFcmp(); break;

                    case Mnemonic.fcmpe: RewriteFcmp(); break;  //$REVIEW: this leaves out the 'e'xception part.

                    case Mnemonic.fcsel: RewriteFcsel(); break;

                    case Mnemonic.fcvt: RewriteFcvt(); break;

                    case Mnemonic.fcvtms: RewriteFcvtms(); break;

                    case Mnemonic.fcvtps: RewriteFcvtps(); break;

                    case Mnemonic.fcvtzs: RewriteFcvtzs(); break;

                    case Mnemonic.fdiv: RewriteMaybeSimdBinary(m.FDiv, "__fdiv_{0}", Domain.Real); break;

                    case Mnemonic.fmadd: RewriteIntrinsicFTernary("__fmaddf", "__fmadd"); break;

                    case Mnemonic.fmsub: RewriteIntrinsicFTernary("__fmsubf", "__fmsub"); break;

                    case Mnemonic.fmax: RewriteIntrinsicFBinary("fmaxf", "fmax"); break;

                    case Mnemonic.fmin: RewriteIntrinsicFBinary("fminf", "fmin"); break;

                    case Mnemonic.fmov: RewriteFmov(); break;

                    case Mnemonic.fmul: RewriteFmul(); break;

                    case Mnemonic.fneg: RewriteUnary(m.FNeg); break;

                    case Mnemonic.fnmul: RewriteFnmul(); break;

                    case Mnemonic.fsqrt: RewriteFsqrt(); break;

                    case Mnemonic.fsub: RewriteMaybeSimdBinary(m.FSub, "__fsub_{0}", Domain.Real); break;

                    case Mnemonic.hlt: RewriteHlt(); break;

                    case Mnemonic.isb: RewriteIsb(); break;

                    case Mnemonic.ld1: RewriteLdN("__ld1"); break;

                    case Mnemonic.ld1r: RewriteLdNr("__ld1r"); break;

                    case Mnemonic.ld2: RewriteLdN("__ld2"); break;

                    case Mnemonic.ld3: RewriteLdN("__ld3"); break;

                    case Mnemonic.ld4: RewriteLdN("__ld4"); break;

                    case Mnemonic.ldnp: RewriteLoadStorePair(true); break;

                    case Mnemonic.ldp: RewriteLoadStorePair(true); break;

                    case Mnemonic.ldarh: RewriteLoadAcquire("__load_acquire_{0}", PrimitiveType.Word16); break;

                    case Mnemonic.ldaxrh: RewriteLoadAcquire("__load_acquire_exclusive_{0}", PrimitiveType.Word16); break;

                    case Mnemonic.ldpsw: RewriteLoadStorePair(true, PrimitiveType.Int32, PrimitiveType.Int64); break;

                    case Mnemonic.ldr: RewriteLdr(null); break;

                    case Mnemonic.ldrb: RewriteLdr(PrimitiveType.Byte); break;

                    case Mnemonic.ldrh: RewriteLdr(PrimitiveType.Word16); break;

                    case Mnemonic.ldrsb: RewriteLdr(PrimitiveType.SByte); break;

                    case Mnemonic.ldrsh: RewriteLdr(PrimitiveType.Int16); break;

                    case Mnemonic.ldrsw: RewriteLdr(PrimitiveType.Int32, PrimitiveType.Int64); break;

                    case Mnemonic.ldxr: RewriteLdx(instr.Operands[0].Width); break;

                    case Mnemonic.lslv: RewriteBinary(m.Shl); break;

                    case Mnemonic.lsrv: RewriteBinary(m.Shr); break;

                    case Mnemonic.ldur: RewriteLdr(null); break;

                    case Mnemonic.ldurb: RewriteLdr(PrimitiveType.Byte); break;

                    case Mnemonic.ldurh: RewriteLdr(PrimitiveType.Word16); break;

                    case Mnemonic.ldursb: RewriteLdr(PrimitiveType.SByte); break;

                    case Mnemonic.ldursh: RewriteLdr(PrimitiveType.Int16); break;

                    case Mnemonic.ldursw: RewriteLdr(PrimitiveType.Int32); break;

                    case Mnemonic.lsl: RewriteBinary(m.Shl); break;

                    case Mnemonic.lsr: RewriteBinary(m.Shr); break;

                    case Mnemonic.madd: RewriteMaddSub(m.IAdd); break;

                    case Mnemonic.mla: RewriteSimdTrinary(Domain.None); break;

                    case Mnemonic.mls: RewriteSimdTrinary(Domain.None); break;

                    case Mnemonic.mneg: RewriteBinary((a, b) => m.Neg(m.IMul(a, b))); break;

                    case Mnemonic.mov: RewriteMov(); break;

                    case Mnemonic.movi: RewriteMovi(); break;

                    case Mnemonic.movk: RewriteMovk(); break;

                    case Mnemonic.movn: RewriteMovn(); break;

                    case Mnemonic.movz: RewriteMovz(); break;

                    case Mnemonic.mrs: RewriteMrs(); break;

                    case Mnemonic.msr: RewriteMsr(); break;

                    case Mnemonic.msub: RewriteMaddSub(m.ISub); break;

                    case Mnemonic.mul: RewriteMaybeSimdBinary(m.IMul, "__mul_{0}"); break;

                    case Mnemonic.mvn: RewriteUnary(m.Comp); break;

                    case Mnemonic.mvni: RewriteLogical((a, b) => ((BigConstant)b).Complement()); break;

                    case Mnemonic.neg: RewriteSimdUnary("__neg_{0}", Domain.SignedInt); break;

                    case Mnemonic.nop: m.Nop(); break;

                    case Mnemonic.not: RewriteMaybeSimdUnary(m.Comp, "__not_{0}"); break;

                    case Mnemonic.orr: RewriteLogical(m.Or); break;

                    case Mnemonic.orn: RewriteBinary((a, b) => m.Or(a, m.Comp(b))); break;

                    case Mnemonic.pmul: RewriteSimdBinary("__pmul_{0}", Domain.None); break;

                    case Mnemonic.pmull: RewriteSimdBinary("__pmull_{0}", Domain.None); break;

                    case Mnemonic.pmull2: RewriteSimdBinary("__pmull2_{0}", Domain.None); break;

                    case Mnemonic.prfm: RewritePrfm(); break;

                    case Mnemonic.raddhn: RewriteSimdBinary("__raddhn_{0}", Domain.None); break;

                    case Mnemonic.raddhn2: RewriteSimdBinary("__raddhn2_{0}", Domain.None); break;

                    case Mnemonic.rbit: RewriteRbit(); break;

                    case Mnemonic.ret: RewriteRet(); break;

                    case Mnemonic.rev: RewriteRev(); break;

                    case Mnemonic.rev16: RewriteRev16(); break;

                    case Mnemonic.rev32: RewriteRev32(); break;

                    case Mnemonic.rev64: RewriteSimdUnary("__rev64_{0}", Domain.None); break;

                    case Mnemonic.ror: RewriteRor(); break;

                    case Mnemonic.rorv: RewriteRor(); break;

                    case Mnemonic.rshrn: RewriteSimdBinary("__rshrn_{0}", Domain.None); break;

                    case Mnemonic.rshrn2: RewriteSimdBinary("__rshrn2_{0}", Domain.None); break;

                    case Mnemonic.rsubhn: RewriteSimdBinary("__rsubhn_{0}", Domain.None); break;

                    case Mnemonic.rsubhn2: RewriteSimdBinary("__rsubhn2_{0}", Domain.None); break;

                    case Mnemonic.saba: RewriteSimdBinary("__saba_{0}", Domain.None); break;

                    case Mnemonic.sabal: RewriteSimdBinary("__sabal_{0}", Domain.None); break;

                    case Mnemonic.sabal2: RewriteSimdBinary("__sabal2_{0}", Domain.None); break;

                    case Mnemonic.sabd: RewriteSimdBinary("__sabd_{0}", Domain.None); break;

                    case Mnemonic.sabdl: RewriteSimdBinary("__sabdl_{0}", Domain.None); break;

                    case Mnemonic.sabdl2: RewriteSimdBinary("__sabdl2_{0}", Domain.None); break;

                    case Mnemonic.sadalp: RewriteSimdBinary("__sadalp_{0}", Domain.SignedInt); break;

                    case Mnemonic.saddl: RewriteSimdBinary("__saddl_{0}", Domain.SignedInt); break;

                    case Mnemonic.saddl2: RewriteSimdBinary("__saddl2_{0}", Domain.SignedInt); break;

                    case Mnemonic.saddlp: RewriteSimdUnary("__saddlp_{0}", Domain.SignedInt); break;

                    case Mnemonic.saddlv: RewriteSimdUnary("__saddlv_{0}", Domain.SignedInt); break;

                    case Mnemonic.saddw: RewriteSimdBinary("__saddw_{0}", Domain.SignedInt); break;

                    case Mnemonic.saddw2: RewriteSimdBinary("__saddw2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sbc: RewriteAdcSbc(m.ISub); break;

                    case Mnemonic.sbcs: RewriteAdcSbc(m.ISub, NZCV); break;

                    case Mnemonic.sbfiz: RewriteSbfiz(); break;

                    case Mnemonic.sbfm: RewriteUSbfm("__sbfm"); break;

                    case Mnemonic.scvtf: RewriteIcvtf("s", Domain.SignedInt); break;

                    case Mnemonic.sdiv: RewriteBinary(m.SDiv); break;

                    case Mnemonic.shadd: RewriteSimdBinary("__shadd_{0}", Domain.SignedInt); break;

                    case Mnemonic.shl: RewriteSimdBinary("__shl_{0}", Domain.None); break;

                    case Mnemonic.shll: RewriteSimdBinary("__shll_{0}", Domain.None); break;

                    case Mnemonic.shll2: RewriteSimdBinary("__shll2_{0}", Domain.None); break;

                    case Mnemonic.shrn: RewriteShrn(); break;

                    case Mnemonic.shsub: RewriteSimdBinary("__shsub_{0}", Domain.SignedInt); break;

                    case Mnemonic.sli: RewriteSimdBinary("__sli_{0}", Domain.None); break;

                    case Mnemonic.smaddl: RewriteMaddl(PrimitiveType.Int64, m.SMul); break;

                    case Mnemonic.smax: RewriteSimdBinary("__smax_{0}", Domain.SignedInt); break;

                    case Mnemonic.smaxp: RewriteSimdBinary("__smaxp_{0}", Domain.SignedInt); break;

                    case Mnemonic.smaxv: RewriteSimdReduce("__smaxv_{0}", Domain.SignedInt); break;

                    case Mnemonic.smc: RewriteSmc(); break;

                    case Mnemonic.smin: RewriteSimdBinary("__smin_{0}", Domain.SignedInt); break;

                    case Mnemonic.sminp: RewriteSimdBinary("__sminp_{0}", Domain.SignedInt); break;

                    case Mnemonic.sminv: RewriteSimdUnary("__sminv_{0}", Domain.SignedInt); break;

                    case Mnemonic.smlal: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.smlal2: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.smlsl: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.smlsl2: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.smov: RewriteVectorElementToScalar(Domain.SignedInt); break;

                    case Mnemonic.smsubl: RewriteSmsubl(); break;

                    case Mnemonic.smull: RewriteMull(PrimitiveType.Int32, PrimitiveType.Int64, m.SMul); break;

                    case Mnemonic.smull2: RewriteSimdBinary("__smull2_{0}", Domain.SignedInt); break;

                    case Mnemonic.smulh: RewriteMulh(PrimitiveType.Int64, PrimitiveType.Int128, m.SMul); break;

                    case Mnemonic.sqabs: RewriteSimdUnary("__sqabs_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqadd: RewriteSimdBinary("__sqadd_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqdmulh: RewriteMaybeSimdBinary(Domain.SignedInt); break;

                    case Mnemonic.sqdmull: RewriteSimdBinary("__sqdmull_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqdmull2: RewriteSimdBinary("__sqdmull2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqdmlal: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.sqdmlal2: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.sqdmlsl: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.sqdmlsl2: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.sqneg: RewriteSimdUnary("__sqneg_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqrdmlah: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.sqrdmlsh: RewriteSimdTrinary(Domain.SignedInt); break;

                    case Mnemonic.sqrdmulh: RewriteSimdBinary("__sqrdmulh_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqrshl: RewriteSimdBinary("__sqrshl_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqrshrn: RewriteSimdBinary("__sqrshrn_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqrshrn2: RewriteSimdBinary("__sqrshrn2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqrshrun: RewriteSimdBinary("__sqrshrun_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqrshrun2: RewriteSimdBinary("__sqrshrun2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqshl: RewriteSimdBinary("__sqshl_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqshlu: RewriteSimdBinary("__sqshlu_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqshrn: RewriteSimdBinary("__sqshrn_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqshrn2: RewriteSimdBinary("__sqshrn2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqsub: RewriteSimdBinary("__sqsub_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqxtn: RewriteSimdUnary("__sqxtn_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqxtn2: RewriteSimdUnary("__sqxtn2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqxtun: RewriteSimdUnary("__sqxtun_{0}", Domain.SignedInt); break;

                    case Mnemonic.sqxtun2: RewriteSimdUnary("__sqxtun2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sri: RewriteSimdBinary("__sri_{0}", Domain.SignedInt); break;

                    case Mnemonic.srhadd: RewriteSimdBinary("__srhadd_{0}", Domain.SignedInt); break;

                    case Mnemonic.srshl: RewriteSimdBinary("__srshl_{0}", Domain.SignedInt); break;

                    case Mnemonic.srshr: RewriteSimdBinary("__srshr_{0}", Domain.SignedInt); break;

                    case Mnemonic.srsra: RewriteSimdBinary("__srsra_{0}", Domain.SignedInt); break;

                    case Mnemonic.sshl: RewriteSimdBinary("__sshl_{0}", Domain.SignedInt); break;

                    case Mnemonic.sshll: RewriteSimdBinary("__sshll_{0}", Domain.SignedInt); break;

                    case Mnemonic.sshll2: RewriteSimdBinary("__sshll2_{0}", Domain.SignedInt); break;

                    case Mnemonic.sshr: RewriteSimdWithScalar("__sshr_{0}", Domain.SignedInt); break;

                    case Mnemonic.ssra: RewriteSimdBinary("__ssra_{0}", Domain.SignedInt); break;

                    case Mnemonic.ssubl: RewriteSimdBinary("__ssubl_{0}", Domain.SignedInt); break;

                    case Mnemonic.ssubl2: RewriteSimdBinary("__ssubl2_{0}", Domain.SignedInt); break;

                    case Mnemonic.ssubw: RewriteSimdBinary("__ssubw_{0}", Domain.SignedInt); break;

                    case Mnemonic.ssubw2: RewriteSimdBinary("__ssubw2_{0}", Domain.SignedInt); break;

                    case Mnemonic.subhn: RewriteSimdBinary("__subhn_{0}", Domain.SignedInt); break;

                    case Mnemonic.subhn2: RewriteSimdBinary("__subhn2_{0}", Domain.SignedInt); break;

                    case Mnemonic.suqadd: RewriteSimdBinary("__suqadd_{0}", Domain.SignedInt); break;

                    case Mnemonic.st1: RewriteStN("__st1"); break;

                    case Mnemonic.st2: RewriteStN("__st2"); break;

                    case Mnemonic.st3: RewriteStN("__st3"); break;

                    case Mnemonic.st4: RewriteStN("__st4"); break;

                    case Mnemonic.stlr: RewriteStlr(instr.Operands[0].Width); break;

                    case Mnemonic.stlrh: RewriteStlr(PrimitiveType.Word16); break;

                    case Mnemonic.stp: RewriteLoadStorePair(false); break;

                    case Mnemonic.str: RewriteStr(null); break;

                    case Mnemonic.strb: RewriteStr(PrimitiveType.Byte); break;

                    case Mnemonic.strh: RewriteStr(PrimitiveType.Word16); break;

                    case Mnemonic.stur: RewriteStr(null); break;

                    case Mnemonic.sturb: RewriteStr(PrimitiveType.Byte); break;

                    case Mnemonic.sturh: RewriteStr(PrimitiveType.Word16); break;

                    case Mnemonic.stxr: RewriteStx(instr.Operands[1].Width); break;

                    case Mnemonic.stxrb: RewriteStx(PrimitiveType.Byte); break;

                    case Mnemonic.sub: RewriteBinary(m.ISub); break;

                    case Mnemonic.subs: RewriteBinary(m.ISub, NZCV); break;

                    case Mnemonic.svc: RewriteSvc(); break;

                    case Mnemonic.sxtb: RewriteUSxt(Domain.SignedInt, 8); break;

                    case Mnemonic.sxth: RewriteUSxt(Domain.SignedInt, 16); break;

                    case Mnemonic.sxtl: RewriteSimdUnary("__sxtl_{0}", Domain.SignedInt); break;

                    case Mnemonic.sxtw: RewriteUSxt(Domain.SignedInt, 32); break;

                    case Mnemonic.tbnz: RewriteTb(m.Ne0); break;

                    case Mnemonic.tbl: RewriteTbl(); break;

                    case Mnemonic.tbx: RewriteTbx(); break;

                    case Mnemonic.tbz: RewriteTb(m.Eq0); break;

                    case Mnemonic.test: RewriteTest(); break;

                    case Mnemonic.trn1: RewriteSimdBinary("__trn1_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.trn2: RewriteSimdBinary("__trn2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uaba: RewriteSimdBinary("__uaba_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uabal: RewriteSimdBinary("__uabal_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uabal2: RewriteSimdBinary("__uabal2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uabd: RewriteSimdBinary("__uabd_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uabdl: RewriteSimdBinary("__uabdl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uabdl2: RewriteSimdBinary("__uabdl2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uadalp: RewriteSimdBinary("__uadalp_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uaddl: RewriteSimdBinary("__uaddl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uaddl2: RewriteSimdBinary("__uaddl2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uaddlp: RewriteSimdBinary("__uaddlp_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uaddlv: RewriteSimdUnary("__uaddlv_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uaddw: RewriteUaddw(); break;

                    case Mnemonic.uaddw2: RewriteSimdBinary("__uaddw_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.ubfm: RewriteUSbfm("__ubfm"); break;

                    case Mnemonic.ucvtf: RewriteIcvtf("u", Domain.UnsignedInt); break;

                    case Mnemonic.udiv: RewriteBinary(m.UDiv); break;

                    case Mnemonic.uhadd: RewriteSimdBinary("__uhadd_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uhsub: RewriteSimdBinary("__uhsub_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.umaddl: RewriteMaddl(PrimitiveType.UInt64, m.UMul); break;

                    case Mnemonic.umax: RewriteSimdBinary("__umax_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.umaxp: RewriteSimdBinary("__umaxp_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.umaxv: RewriteSimdUnary("__umaxv_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.umin: RewriteSimdBinary("__umin_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uminp: RewriteSimdBinary("__uminp_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uminv: RewriteSimdUnary("__uminv_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.umlal: RewriteSimdTrinary(Domain.UnsignedInt); break;

                    case Mnemonic.umlal2: RewriteSimdTrinary(Domain.UnsignedInt); break;

                    case Mnemonic.umlsl: RewriteSimdTrinary(Domain.UnsignedInt); break;

                    case Mnemonic.umlsl2: RewriteSimdTrinary(Domain.UnsignedInt); break;

                    case Mnemonic.umov: RewriteVectorElementToScalar(Domain.UnsignedInt); break;

                    case Mnemonic.umulh: RewriteMulh(PrimitiveType.UInt64, m.UMul); break;

                    case Mnemonic.umull: RewriteMull(PrimitiveType.UInt32, PrimitiveType.UInt64, m.UMul); break;

                    case Mnemonic.umull2: RewriteSimdBinary("__umull2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqadd: RewriteSimdBinary("__uqadd_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqrshl: RewriteSimdBinary("__uqrshl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqrshrn: RewriteSimdBinary("__uqrshrn_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqrshrn2: RewriteSimdBinary("__uqrshrn2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqshl: RewriteSimdBinary("__uqshl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqshrn: RewriteSimdBinary("__uqshrn_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqshrn2: RewriteSimdBinary("__uqshrn2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqsub: RewriteSimdBinary("__uqsub_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqxtn: RewriteSimdUnary("__uqxtn_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uqxtn2: RewriteSimdUnary("__uqxtn2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.urecpe: RewriteSimdUnary("__urecpe_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.urhadd: RewriteSimdBinary("__urhadd_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.urshl: RewriteSimdBinary("__urshl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.urshr: RewriteSimdBinary("__urshr_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.ursqrte: RewriteSimdUnary("__ursqrte_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.ursra: RewriteSimdBinary("__ursra_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.ushl: RewriteMaybeSimdBinary(m.Shr, "__ushl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.ushll: RewriteMaybeSimdBinary(m.Shr, "__ushll_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.ushll2: RewriteMaybeSimdBinary(m.Shr, "__ushll2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.ushr: RewriteMaybeSimdBinary(m.Shr, "__ushr_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.usqadd: RewriteSimdBinary("__usqadd_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.usra: RewriteSimdBinary("__usra_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.usubl: RewriteSimdBinary("__usubl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.usubl2: RewriteSimdBinary("__usubl2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.usubw: RewriteSimdBinary("__usubw_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.usubw2: RewriteSimdBinary("__usubw2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uxtb: RewriteUSxt(Domain.UnsignedInt, 8); break;

                    case Mnemonic.uxth: RewriteUSxt(Domain.UnsignedInt, 16); break;

                    case Mnemonic.uxtl: RewriteSimdUnary("__uxtl_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uxtl2: RewriteSimdUnary("__uxtl2_{0}", Domain.UnsignedInt); break;

                    case Mnemonic.uxtw: RewriteUSxt(Domain.UnsignedInt, 32); break;

                    case Mnemonic.uzp1: RewriteSimdBinary("__uzp1_{0}", Domain.None); break;

                    case Mnemonic.uzp2: RewriteSimdBinary("__uzp2_{0}", Domain.None); break;

                    case Mnemonic.xtn: RewriteSimdUnary("__xtn_{0}", Domain.None); break;

                    case Mnemonic.xtn2: RewriteSimdUnary("__xtn2_{0}", Domain.None); break;

                    case Mnemonic.zip1: RewriteSimdBinary("__zip1_{0}", Domain.None); break;

                    case Mnemonic.zip2: RewriteSimdBinary("__zip2_{0}", Domain.None); break;
                    }
                } catch (Exception e)
                {
                    EmitUnitTest(e.Message);
                }
                yield return(m.MakeCluster(instr.Address, instr.Length, iclass));

                cluster.Clear();
            }
        }