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 !; }
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)); } }
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, }); } }