Example #1
0
 public XtensaRewriter(XtensaArchitecture arch, EndianImageReader rdr, ProcessorState state, IStorageBinder binder, IRewriterHost host)
 {
     this.arch   = arch;
     this.rdr    = rdr;
     this.state  = state;
     this.binder = binder;
     this.host   = host;
     this.dasm   = new XtensaDisassembler(this.arch, rdr).GetEnumerator();
     this.instr  = null !;
     this.m      = null !;
 }
Example #2
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: RewriteIntrinsicFn("abs", true); 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: RewriteIntrinsicProc("__cust0"); break;

                case Mnemonic.cust1: RewriteIntrinsicProc("__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: RewriteIntrinsicProc("__dsync"); break;

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

                case Mnemonic.excw: RewriteIntrinsicProc("__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: RewriteIntrinsicFn("__floor", false); break;

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

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

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

                case Mnemonic.isync: RewriteIntrinsicProc("__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: RewriteIntrinsicProc("__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: RewriteIntrinsicFn("__nsa", false); break;

                case Mnemonic.nsau: RewriteIntrinsicFn("__nsau", false); 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: RewriteIntrinsicFn("__pitlb", false); break;

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

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

                case Mnemonic.rdtlb0: RewriteIntrinsicFn("__rdtlb0", false); break;

                case Mnemonic.rdtlb1: RewriteIntrinsicFn("__rdtlb1", false); 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: RewriteIntrinsicFn("__ritlb0", false); break;

                case Mnemonic.ritlb1: RewriteIntrinsicFn("__ritlb1", false); break;

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

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

                case Mnemonic.rsil: RewriteIntrinsicFn("__rsil", false); 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: RewriteIntrinsicFn("isunordered", true); break;

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

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

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

                case Mnemonic.witlb: RewriteIntrinsicProc("__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 #3
0
        public IEnumerator <RtlInstructionCluster> GetEnumerator()
        {
            while (dasm.MoveNext())
            {
                var addr = dasm.Current.Address;
                var len  = dasm.Current.Length;
                rtlInstructions = new List <RtlInstruction>();
                rtlc            = InstrClass.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.andb: 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,
                });
            }
        }