public void Rewrite(AvrInstruction instr) { this.instr = instr; this.rtlInstructions = new List <RtlInstruction>(); this.iclass = instr.InstructionClass; this.m = new RtlEmitter(rtlInstructions); switch (instr.Mnemonic) { case Mnemonic.adc: RewriteAdcSbc(m.IAdd); break; case Mnemonic.add: RewriteBinOp(m.IAdd, CmpFlags); break; case Mnemonic.adiw: RewriteAddSubIW(m.IAdd); break; case Mnemonic.and: RewriteBinOp(m.And, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break; case Mnemonic.andi: RewriteBinOp(m.And, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break; case Mnemonic.asr: RewriteAsr(); break; case Mnemonic.brcc: RewriteBranch(ConditionCode.UGE, FlagM.CF); break; case Mnemonic.brcs: RewriteBranch(ConditionCode.ULT, FlagM.CF); break; case Mnemonic.breq: RewriteBranch(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.brge: RewriteBranch(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Mnemonic.brid: RewriteBranch(FlagM.IF, false); break; case Mnemonic.brne: RewriteBranch(ConditionCode.NE, FlagM.ZF); break; case Mnemonic.brpl: RewriteBranch(ConditionCode.GE, FlagM.NF); break; case Mnemonic.call: RewriteCall(); break; case Mnemonic.cli: RewriteCli(); break; case Mnemonic.com: RewriteUnary(m.Comp, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF, FlagM.CF); break; case Mnemonic.cp: RewriteCp(); break; case Mnemonic.cpi: RewriteCp(); break; case Mnemonic.cpc: RewriteCpc(); break; case Mnemonic.cpse: SkipIf(m.Eq); break; case Mnemonic.dec: RewriteIncDec(m.ISub); break; case Mnemonic.des: RewriteDes(); break; case Mnemonic.eor: RewriteBinOp(m.Xor, LogicalFlags, FlagM.VF); break; case Mnemonic.icall: RewriteIcall(); break; case Mnemonic.@in: RewriteIn(); break; case Mnemonic.inc: RewriteIncDec(m.IAdd); break; case Mnemonic.ijmp: RewriteIjmp(); break; case Mnemonic.jmp: RewriteJmp(); break; case Mnemonic.ld: RewriteLd(); break; case Mnemonic.ldd: RewriteLd(); break; case Mnemonic.ldi: RewriteLdi(); break; case Mnemonic.lds: RewriteLds(); break; case Mnemonic.lpm: RewriteLpm(); break; case Mnemonic.lsr: RewriteLsr(); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.movw: RewriteMovw(); break; case Mnemonic.muls: RewriteMuls(); break; case Mnemonic.neg: RewriteUnary(m.Neg, CmpFlags); break; case Mnemonic.@out: RewriteOut(); break; case Mnemonic.or: RewriteBinOp(m.Or, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break; case Mnemonic.ori: RewriteBinOp(m.Or, FlagM.SF | FlagM.NF | FlagM.ZF, FlagM.VF); break; case Mnemonic.pop: RewritePop(); break; case Mnemonic.push: RewritePush(); break; case Mnemonic.rcall: RewriteCall(); break; case Mnemonic.ror: RewriteRor(); break; case Mnemonic.ret: RewriteRet(); break; case Mnemonic.reti: RewriteRet(); break; //$TODO: more to indicate interrupt return? case Mnemonic.rjmp: RewriteJmp(); break; case Mnemonic.sbc: RewriteAdcSbc(m.ISub); break; case Mnemonic.sbci: RewriteAdcSbc(m.ISub); break; case Mnemonic.sbis: RewriteSbis(); return; // We've already added ourself to clusters. case Mnemonic.sbiw: RewriteAddSubIW(m.ISub); break; case Mnemonic.sbrc: SkipIf(Sbrc); break; case Mnemonic.sbrs: SkipIf(Sbrs); break; case Mnemonic.sec: RewriteSetBit(FlagM.CF, true); break; case Mnemonic.sei: RewriteSei(); break; case Mnemonic.st: RewriteSt(); break; case Mnemonic.std: RewriteSt(); break; case Mnemonic.sts: RewriteSts(); break; case Mnemonic.sub: RewriteBinOp(m.ISub, CmpFlags); break; case Mnemonic.subi: RewriteBinOp(m.ISub, CmpFlags); break; case Mnemonic.swap: RewriteSwap(); break; default: host.Error(instr.Address, string.Format("AVR8 instruction '{0}' is not supported yet.", instr.Mnemonic)); EmitUnitTest(); m.Invalid(); break; } clusters.Add(m.MakeCluster(instr.Address, instr.Length, iclass)); }
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)); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.rtlc = InstrClass.Linear; var instrs = new List <RtlInstruction>(); this.m = new RtlEmitter(instrs); switch (instr.Opcode) { default: host.Error( dasm.Current.Address, string.Format( "SuperH instruction {0} not supported yet.", dasm.Current.Opcode)); EmitUnitTest(); goto case Mnemonic.invalid; case Mnemonic.invalid: Invalid(); break; case Mnemonic.add: RewriteBinOp(m.IAdd, n => (sbyte)n); break; case Mnemonic.addc: RewriteAddcSubc(m.IAdd); break; case Mnemonic.addv: RewriteAddv(m.IAdd); break; case Mnemonic.and: RewriteBinOp(m.And, n => (byte)n); break; case Mnemonic.and_b: RewriteBinOp(m.And, n => (byte)n); break; case Mnemonic.bf: RewriteBranch(false, false); break; case Mnemonic.bf_s: RewriteBranch(false, true); break; case Mnemonic.bra: RewriteGoto(); break; case Mnemonic.braf: RewriteBraf(); break; case Mnemonic.brk: RewriteBrk(); break; case Mnemonic.bsr: RewriteBsr(); break; case Mnemonic.bsrf: RewriteBsrf(); break; case Mnemonic.bt: RewriteBranch(true, false); break; case Mnemonic.bt_s: RewriteBranch(true, true); break; case Mnemonic.clrmac: RewriteClr(Registers.mac); break; case Mnemonic.clrs: RewriteClrtSet(Registers.S, Constant.False()); break; case Mnemonic.clrt: RewriteClrtSet(Registers.T, Constant.False()); break; case Mnemonic.cmp_eq: RewriteCmp(m.Eq); break; case Mnemonic.cmp_ge: RewriteCmp(m.Ge); break; case Mnemonic.cmp_gt: RewriteCmp(m.Gt); break; case Mnemonic.cmp_hs: RewriteCmp(m.Uge); break; case Mnemonic.cmp_hi: RewriteCmp(m.Ugt); break; case Mnemonic.cmp_pl: RewriteCmp0(m.Gt0); break; case Mnemonic.cmp_pz: RewriteCmp0(m.Ge0); break; case Mnemonic.cmp_str: RewriteCmpStr(); break; case Mnemonic.div0s: RewriteDiv0s(); break; case Mnemonic.div0u: RewriteDiv0u(); break; case Mnemonic.div1: RewriteDiv1(); break; case Mnemonic.dmuls_l: RewriteDmul(m.SMul); break; case Mnemonic.dmulu_l: RewriteDmul(m.UMul); break; case Mnemonic.dt: RewriteDt(); break; case Mnemonic.exts_b: RewriteExt(PrimitiveType.SByte); break; case Mnemonic.exts_w: RewriteExt(PrimitiveType.Int16); break; case Mnemonic.extu_b: RewriteExt(PrimitiveType.Byte); break; case Mnemonic.extu_w: RewriteExt(PrimitiveType.UInt16); break; case Mnemonic.fabs: RewriteFabs(); break; case Mnemonic.fadd: RewriteBinOp(m.FAdd, null); break; case Mnemonic.fcmp_eq: RewriteCmp(m.FEq); break; case Mnemonic.fcmp_gt: RewriteCmp(m.FGt); break; case Mnemonic.fcnvds: RewriteUnary(d => m.Cast(PrimitiveType.Real32, d)); break; case Mnemonic.fcnvsd: RewriteUnary(d => m.Cast(PrimitiveType.Real64, d)); break; case Mnemonic.fdiv: RewriteBinOp(m.FDiv, null); break; case Mnemonic.fldi0: RewriteFldi(0.0F); break; case Mnemonic.fldi1: RewriteFldi(1.0F); break; case Mnemonic.flds: RewriteMov(); break; case Mnemonic.fmac: RewriteFmac(); break; case Mnemonic.fmov_d: RewriteMov(); break; case Mnemonic.fmov_s: RewriteMov(); break; case Mnemonic.jmp: RewriteJmp(); break; case Mnemonic.jsr: RewriteJsr(); break; case Mnemonic.lds: RewriteMov(); break; case Mnemonic.lds_l: RewriteMov(); break; case Mnemonic.mac_l: RewriteMac(PrimitiveType.Int64); break; case Mnemonic.mac_w: RewriteMac(PrimitiveType.Int32); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.mova: RewriteMova(); break; case Mnemonic.mov_b: RewriteMov(); break; case Mnemonic.mov_w: RewriteMov(); break; case Mnemonic.mov_l: RewriteMov(); break; case Mnemonic.movt: RewriteMovt(); break; case Mnemonic.mul_l: RewriteMul_l(); break; case Mnemonic.muls_w: RewriteMul_w(PrimitiveType.Int16, m.SMul); break; case Mnemonic.mulu_w: RewriteMul_w(PrimitiveType.UInt16, m.UMul); break; case Mnemonic.neg: RewriteUnary(m.Neg); break; case Mnemonic.negc: RewriteNegc(); break; case Mnemonic.not: RewriteUnary(m.Comp); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.ocbi: RewriteOcbi(); break; case Mnemonic.or: RewriteBinOp(m.Or, u => (byte)u); break; case Mnemonic.rotcl: RewriteRotc(PseudoProcedure.RolC); break; case Mnemonic.rotcr: RewriteRotc(PseudoProcedure.RorC); break; case Mnemonic.rotl: RewriteRot(PseudoProcedure.Rol); break; case Mnemonic.rotr: RewriteRot(PseudoProcedure.Ror); break; case Mnemonic.rts: RewriteRts(); break; case Mnemonic.sett: RewriteClrtSet(Registers.T, Constant.True()); break; case Mnemonic.shad: RewriteShd(m.Shl, m.Sar); break; case Mnemonic.shar: RewriteShift(m.Sar, 1); break; case Mnemonic.shld: RewriteShd(m.Shl, m.Shr); break; case Mnemonic.shll: RewriteShift(m.Shl, 1); break; case Mnemonic.shll2: RewriteShift(m.Shl, 2); break; case Mnemonic.shll8: RewriteShift(m.Shl, 8); break; case Mnemonic.shll16: RewriteShift(m.Shl, 16); break; case Mnemonic.shlr: RewriteShift(m.Shr, 1); break; case Mnemonic.shlr2: RewriteShift(m.Shr, 2); break; case Mnemonic.shlr8: RewriteShift(m.Shr, 8); break; case Mnemonic.shlr16: RewriteShift(m.Shr, 16); break; case Mnemonic.stc: RewriteMov(); break; case Mnemonic.sts: RewriteMov(); break; case Mnemonic.sts_l: RewriteMov(); break; case Mnemonic.sub: RewriteBinOp(m.ISub, null); break; case Mnemonic.subc: RewriteAddcSubc(m.ISub); break; case Mnemonic.swap_w: RewriteSwapW(); break; case Mnemonic.tst: RewriteTst(); break; case Mnemonic.xor: RewriteBinOp(m.Xor, n => (byte)n); break; case Mnemonic.xtrct: RewriteXtrct(); break; } var rtlc = new RtlInstructionCluster(instr.Address, instr.Length, instrs.ToArray()) { Class = this.rtlc, }; yield return(rtlc); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.iclass = InstrClass.Linear; var rtls = new List <RtlInstruction>(); this.m = new RtlEmitter(rtls); switch (instr.Mnemonic) { default: host.Error(instr.Address, "Rewriting TMS7000 instruction '{0}' is not supported yet.", instr); iclass = InstrClass.Invalid; break; case Mnemonic.adc: RewriteAdcSbb(m.IAdd); break; case Mnemonic.add: RewriteArithmetic(m.IAdd); break; case Mnemonic.and: RewriteLogical(m.And); break; case Mnemonic.andp: RewriteLogical(m.And); break; case Mnemonic.btjo: RewriteBtj(a => a); break; case Mnemonic.btjop: RewriteBtj(a => a); break; case Mnemonic.btjz: RewriteBtj(m.Comp); break; case Mnemonic.btjzp: RewriteBtj(m.Comp); break; case Mnemonic.br: RewriteBr(); break; case Mnemonic.call: RewriteCall(); break; case Mnemonic.clr: RewriteClr(); break; case Mnemonic.tsta: RewriteTst(arch.a); break; case Mnemonic.dac: RewriteDacDsb("__dac"); break; case Mnemonic.dec: RewriteIncDec(m.ISub); break; case Mnemonic.decd: RewriteIncdDecd(m.ISub); break; case Mnemonic.dint: RewriteDint(); break; case Mnemonic.djnz: RewriteDjnz(); break; case Mnemonic.dsb: RewriteDacDsb("__dsb"); break; case Mnemonic.eint: RewriteEint(); break; case Mnemonic.idle: RewriteIdle(); break; case Mnemonic.inc: RewriteIncDec(m.IAdd); break; case Mnemonic.inv: RewriteInv(); break; case Mnemonic.jmp: RewriteJmp(); break; case Mnemonic.jeq: RewriteJcc(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.jge: RewriteJcc(ConditionCode.GE, FlagM.NZ); break; case Mnemonic.jgt: RewriteJcc(ConditionCode.GT, FlagM.NZ); break; case Mnemonic.jhs: RewriteJcc(ConditionCode.UGE, FlagM.CF); break; case Mnemonic.jl: RewriteJcc(ConditionCode.ULT, FlagM.CF); break; case Mnemonic.jne: RewriteJcc(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.lda: RewriteLda(); break; case Mnemonic.ldsp: RewriteLdsp(); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.movd: RewriteMovd(); break; case Mnemonic.movp: RewriteMov(); break; case Mnemonic.mpy: RewriteMpy(); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.or: RewriteLogical(m.Or); break; case Mnemonic.orp: RewriteLogical(m.Or); break; case Mnemonic.pop: RewritePop(); break; case Mnemonic.push: RewritePush(); break; case Mnemonic.reti: RewriteReti(); break; case Mnemonic.rets: RewriteRets(); break; case Mnemonic.rl: RewriteRotate(IntrinsicProcedure.Rol); break; case Mnemonic.rlc: RewriteRotateC(IntrinsicProcedure.RolC); break; case Mnemonic.rr: RewriteRotate(IntrinsicProcedure.Ror); break; case Mnemonic.rrc: RewriteRotateC(IntrinsicProcedure.RorC); break; case Mnemonic.sbb: RewriteAdcSbb(m.ISub); break; case Mnemonic.setc: RewriteSetc(); break; case Mnemonic.sta: RewriteSta(); break; case Mnemonic.stsp: RewriteStsp(); break; case Mnemonic.sub: RewriteArithmetic(m.ISub); break; case Mnemonic.trap_0: RewriteTrap(0); break; case Mnemonic.trap_1: RewriteTrap(1); break; case Mnemonic.trap_2: RewriteTrap(2); break; case Mnemonic.trap_3: RewriteTrap(3); break; case Mnemonic.trap_4: RewriteTrap(4); break; case Mnemonic.trap_5: RewriteTrap(5); break; case Mnemonic.trap_6: RewriteTrap(6); break; case Mnemonic.trap_7: RewriteTrap(7); break; case Mnemonic.trap_8: RewriteTrap(8); break; case Mnemonic.trap_9: RewriteTrap(9); break; case Mnemonic.trap_10: RewriteTrap(10); break; case Mnemonic.trap_11: RewriteTrap(11); break; case Mnemonic.trap_12: RewriteTrap(12); break; case Mnemonic.trap_13: RewriteTrap(13); break; case Mnemonic.trap_14: RewriteTrap(14); break; case Mnemonic.trap_15: RewriteTrap(15); break; case Mnemonic.trap_16: RewriteTrap(16); break; case Mnemonic.trap_17: RewriteTrap(17); break; case Mnemonic.trap_18: RewriteTrap(18); break; case Mnemonic.trap_19: RewriteTrap(19); break; case Mnemonic.trap_20: RewriteTrap(20); break; case Mnemonic.trap_21: RewriteTrap(21); break; case Mnemonic.trap_22: RewriteTrap(22); break; case Mnemonic.trap_23: RewriteTrap(23); break; case Mnemonic.tstb: RewriteTst(arch.b); break; case Mnemonic.xchb: RewriteXchb(); break; case Mnemonic.xor: RewriteLogical(m.Xor); break; case Mnemonic.xorp: RewriteLogical(m.Xor); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { var instr = dasm.Current; var rtlInstructions = new List <RtlInstruction>(); this.iclass = instr.InstructionClass; this.m = new RtlEmitter(rtlInstructions); switch (instr.Mnemonic) { default: host.Error( instr.Address, string.Format("MIPS instruction '{0}' is not supported yet.", instr)); EmitUnitTest(instr); goto case Mnemonic.illegal; case Mnemonic.illegal: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.add: case Mnemonic.addi: case Mnemonic.addiu: case Mnemonic.addu: RewriteAdd(instr, PrimitiveType.Word32); break; case Mnemonic.add_s: RewriteFpuBinopS(instr, m.FAdd); break; case Mnemonic.add_d: RewriteFpuBinopD(instr, m.FAdd); break; case Mnemonic.and: case Mnemonic.andi: RewriteAnd(instr); break; case Mnemonic.bc1f: RewriteBranchConditional1(instr, false); break; case Mnemonic.bc1t: RewriteBranchConditional1(instr, true); break; case Mnemonic.beq: RewriteBranch(instr, m.Eq, false); break; case Mnemonic.beql: RewriteBranchLikely(instr, m.Eq); break; case Mnemonic.bgez: RewriteBranch0(instr, m.Ge, false); break; case Mnemonic.bgezl: RewriteBranch0(instr, m.Ge, true); break; case Mnemonic.bgezal: RewriteBgezal(instr); break; case Mnemonic.bgezall: RewriteBranch0(instr, m.Ge, true); break; case Mnemonic.bgtz: RewriteBranch0(instr, m.Gt, false); break; case Mnemonic.bgtzl: RewriteBranch0(instr, m.Gt, true); break; case Mnemonic.blez: RewriteBranch0(instr, m.Le, false); break; case Mnemonic.blezl: RewriteBranch0(instr, m.Le, true); break; case Mnemonic.bltz: RewriteBranch0(instr, m.Lt, false); break; case Mnemonic.bltzl: RewriteBranch0(instr, m.Lt, true); break; case Mnemonic.bltzal: RewriteBranch0(instr, m.Lt, true); break; case Mnemonic.bltzall: RewriteBranch0(instr, m.Lt, true); break; case Mnemonic.bne: RewriteBranch(instr, m.Ne, false); break; case Mnemonic.bnel: RewriteBranchLikely(instr, m.Ne); break; case Mnemonic.@break: RewriteBreak(instr); break; case Mnemonic.c_le_d: RewriteFpuCmpD(instr, Operator.Fle); break; case Mnemonic.c_le_s: RewriteFpuCmpD(instr, Operator.Fle); break; case Mnemonic.c_lt_d: RewriteFpuCmpD(instr, Operator.Flt); break; case Mnemonic.c_lt_s: RewriteFpuCmpD(instr, Operator.Flt); break; case Mnemonic.c_eq_d: RewriteFpuCmpD(instr, Operator.Feq); break; case Mnemonic.c_eq_s: RewriteFpuCmpD(instr, Operator.Feq); break; case Mnemonic.cache: RewriteCache(instr); break; case Mnemonic.cfc1: RewriteCfc1(instr); break; case Mnemonic.ctc1: RewriteCtc1(instr); break; case Mnemonic.clo: RewriteClo(instr); break; case Mnemonic.clz: RewriteClz(instr); break; case Mnemonic.cvt_d_l: RewriteCvtToD(instr, PrimitiveType.Int32); break; case Mnemonic.cvt_s_d: RewriteCvtFromD(instr, PrimitiveType.Real32); break; case Mnemonic.cvt_w_d: RewriteCvtFromD(instr, PrimitiveType.Int32); break; case Mnemonic.dadd: case Mnemonic.daddi: RewriteAdd(instr, PrimitiveType.Word64); break; case Mnemonic.daddiu: case Mnemonic.daddu: RewriteAdd(instr, PrimitiveType.Word64); break; case Mnemonic.ddiv: RewriteDiv(instr, m.SDiv); break; case Mnemonic.ddivu: RewriteDiv(instr, m.UDiv); break; case Mnemonic.div: RewriteDiv(instr, m.SDiv); break; case Mnemonic.divu: RewriteDiv(instr, m.UDiv); break; case Mnemonic.div_d: RewriteFpuBinopD(instr, m.FDiv); break; case Mnemonic.dmfc0: RewriteMfc0(instr); break; case Mnemonic.dmfc1: RewriteMfc1(instr); break; case Mnemonic.dmtc0: RewriteMtc0(instr); break; case Mnemonic.dmtc1: RewriteMtc1(instr); break; case Mnemonic.dmult: RewriteMul(instr, m.SMul, PrimitiveType.Int128); break; case Mnemonic.dmultu: RewriteMul(instr, m.UMul, PrimitiveType.UInt128); break; case Mnemonic.dsll: RewriteSll(instr); break; case Mnemonic.dsll32: RewriteDshift32(instr, m.Shl); break; case Mnemonic.dsllv: RewriteSrl(instr); break; case Mnemonic.dsra: RewriteSra(instr); break; case Mnemonic.dsra32: RewriteDshift32(instr, m.Sar); break; case Mnemonic.dsrav: RewriteSra(instr); break; case Mnemonic.dsrl: RewriteSrl(instr); break; case Mnemonic.dsrl32: RewriteDshift32(instr, m.Shr); break; case Mnemonic.dsrlv: RewriteSrl(instr); break; case Mnemonic.dsub: case Mnemonic.dsubu: RewriteSub(instr, PrimitiveType.Word64); break; case Mnemonic.eret: RewriteEret(instr); break; case Mnemonic.j: RewriteJump(instr); break; case Mnemonic.jal: RewriteJal(instr); break; case Mnemonic.jalr: RewriteJalr(instr); break; case Mnemonic.jr: RewriteJr(instr); break; case Mnemonic.lb: RewriteLoad(instr, PrimitiveType.SByte); break; case Mnemonic.lbu: RewriteLoad(instr, PrimitiveType.Byte); break; case Mnemonic.ld: RewriteLoad(instr, PrimitiveType.Word64); break; case Mnemonic.ldl: RewriteLdl(instr); break; case Mnemonic.ldr: RewriteLdr(instr); break; case Mnemonic.ldc1: RewriteLcpr1(instr); break; case Mnemonic.ldc2: RewriteLdc2(instr); break; case Mnemonic.ldxc1: RewriteLcpr1(instr); break; case Mnemonic.luxc1: RewriteLcpr1(instr); break; case Mnemonic.lwxc1: RewriteLcpr1(instr); break; case Mnemonic.lh: RewriteLoad(instr, PrimitiveType.Int16); break; case Mnemonic.lhxs: RewriteLoadIndexed(instr, PrimitiveType.Int16, PrimitiveType.Int32, 2); break; case Mnemonic.lhu: RewriteLoad(instr, PrimitiveType.UInt16); break; case Mnemonic.lhuxs: RewriteLoadIndexed(instr, PrimitiveType.Word16, PrimitiveType.Word32, 2); break; case Mnemonic.ll: RewriteLoadLinked32(instr); break; case Mnemonic.lld: RewriteLoadLinked64(instr); break; case Mnemonic.lui: RewriteLui(instr); break; case Mnemonic.lw: RewriteLoad(instr, PrimitiveType.Word32, PrimitiveType.Int32); break; case Mnemonic.lwc1: RewriteLcpr1(instr); break; case Mnemonic.lwc2: RewriteLdc2(instr); break; case Mnemonic.lwl: RewriteLwl(instr); break; case Mnemonic.lwr: RewriteLwr(instr); break; case Mnemonic.lwu: RewriteLoad(instr, PrimitiveType.UInt32); break; case Mnemonic.madd: RewriteMac_int(instr, m.IAdd); break; case Mnemonic.madd_s: RewriteMac_real(instr, PrimitiveType.Real32, m.FAdd); break; case Mnemonic.madd_ps: RewriteMac_vec(instr, PrimitiveType.Real32, m.FAdd); break; case Mnemonic.mfc0: RewriteMfc0(instr); break; case Mnemonic.mfc1: RewriteMfc1(instr); break; case Mnemonic.mfhi: RewriteMf(instr, arch.hi); break; case Mnemonic.mflo: RewriteMf(instr, arch.lo); break; case Mnemonic.mtc0: RewriteMtc0(instr); break; case Mnemonic.mthi: RewriteMt(instr, arch.hi); break; case Mnemonic.mtlo: RewriteMt(instr, arch.lo); break; case Mnemonic.movf: RewriteMovft(instr, false); break; case Mnemonic.movn: RewriteMovCc(instr, m.Ne0); break; case Mnemonic.movt: RewriteMovft(instr, true); break; case Mnemonic.movz: RewriteMovCc(instr, m.Eq0); break; case Mnemonic.mov_d: RewriteCopy(instr); break; case Mnemonic.mov_s: RewriteCopy(instr); break; case Mnemonic.msub: RewriteMac_int(instr, m.ISub); break; case Mnemonic.msub_s: RewriteMac_real(instr, PrimitiveType.Real32, m.FSub); break; case Mnemonic.mtc1: RewriteMtc1(instr); break; case Mnemonic.mul: RewriteMul(instr, m.SMul, PrimitiveType.Int32); break; case Mnemonic.mult: RewriteMul(instr, m.SMul, PrimitiveType.Int64); break; case Mnemonic.multu: RewriteMul(instr, m.UMul, PrimitiveType.UInt64); break; case Mnemonic.mul_s: RewriteMul(instr, m.FMul, PrimitiveType.Real32); break; case Mnemonic.mul_d: RewriteMulD(instr); break; case Mnemonic.nmadd_d: RewriteNmac_real(instr, PrimitiveType.Real64, m.FAdd); break; case Mnemonic.nmadd_s: RewriteNmac_real(instr, PrimitiveType.Real32, m.FAdd); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.nor: RewriteNor(instr); break; case Mnemonic.nmsub_d: RewriteNmac_real(instr, PrimitiveType.Real64, m.FSub); break; case Mnemonic.nmsub_s: RewriteNmac_real(instr, PrimitiveType.Real32, m.FSub); break; case Mnemonic.nmsub_ps: RewriteNmac_vec(instr, PrimitiveType.Real32, m.FSub); break; case Mnemonic.or: case Mnemonic.ori: RewriteOr(instr); break; case Mnemonic.pref: case Mnemonic.prefx: RewritePrefx(instr); break; case Mnemonic.sb: RewriteStore(instr); break; case Mnemonic.sc: RewriteStoreConditional32(instr); break; case Mnemonic.scd: RewriteStoreConditional64(instr); break; case Mnemonic.sd: RewriteStore(instr); break; case Mnemonic.sdc1: RewriteStore(instr); break; case Mnemonic.sdc2: RewriteSdc2(instr); break; case Mnemonic.sdl: RewriteSdl(instr); break; case Mnemonic.sdr: RewriteSdr(instr); break; case Mnemonic.seb: RewriteSignExtend(instr, PrimitiveType.Byte); break; case Mnemonic.seh: RewriteSignExtend(instr, PrimitiveType.Word16); break; case Mnemonic.seqi: RewriteScc(instr, m.Eq); break; case Mnemonic.sh: RewriteStore(instr); break; case Mnemonic.sll: case Mnemonic.sllv: RewriteSll(instr); break; case Mnemonic.slt: RewriteScc(instr, m.Lt); break; case Mnemonic.slti: RewriteScc(instr, m.Lt); break; case Mnemonic.sltiu: RewriteScc(instr, m.Ult); break; case Mnemonic.sltu: RewriteScc(instr, m.Ult); break; case Mnemonic.sra: case Mnemonic.srav: RewriteSra(instr); break; case Mnemonic.srl: case Mnemonic.srlv: RewriteSrl(instr); break; case Mnemonic.sub: case Mnemonic.subu: RewriteSub(instr, PrimitiveType.Word32); break; case Mnemonic.sub_d: RewriteFpuBinopD(instr, m.FSub); break; case Mnemonic.sw: case Mnemonic.swc1: RewriteStore(instr); break; case Mnemonic.swc2: RewriteSdc2(instr); break; case Mnemonic.swl: RewriteSwl(instr); break; case Mnemonic.swr: RewriteSwr(instr); break; case Mnemonic.swxc1: RewriteStore(instr); break; case Mnemonic.sync: RewriteSync(instr); break; case Mnemonic.syscall: RewriteSyscall(instr); break; case Mnemonic.teq: RewriteTrap(instr, m.Eq); break; case Mnemonic.teqi: RewriteTrap(instr, m.Eq); break; case Mnemonic.tge: RewriteTrap(instr, m.Ge); break; case Mnemonic.tgeu: RewriteTrap(instr, m.Uge); break; case Mnemonic.tgei: RewriteTrapi(instr, m.Ge); break; case Mnemonic.tgeiu: RewriteTrapi(instr, m.Uge); break; case Mnemonic.tlbp: RewriteTlbp(instr); break; case Mnemonic.tlbr: RewriteTlbr(instr); break; case Mnemonic.tlbwi: RewriteTlbwi(instr); break; case Mnemonic.tlbwr: RewriteTlbwr(instr); break; case Mnemonic.tlt: RewriteTrap(instr, m.Lt); break; case Mnemonic.tlti: RewriteTrapi(instr, m.Lt); break; case Mnemonic.tltiu: RewriteTrapi(instr, m.Ult); break; case Mnemonic.tltu: RewriteTrap(instr, m.Ult); break; case Mnemonic.tne: RewriteTrap(instr, m.Ne); break; case Mnemonic.tnei: RewriteTrapi(instr, m.Ne); break; case Mnemonic.trunc_l_d: RewriteTrunc(instr, "trunc", PrimitiveType.Real64, PrimitiveType.Int64); break; case Mnemonic.wait: RewriteWait(instr); break; case Mnemonic.xor: case Mnemonic.xori: RewriteXor(instr); break; // Nano instructions case Mnemonic.addiupc: RewriteAddiupc(instr); break; case Mnemonic.aluipc: RewriteAluipc(instr); break; case Mnemonic.balc: RewriteBalc(instr); break; case Mnemonic.bbeqzc: RewriteBb(instr, e => e); break; case Mnemonic.bbnezc: RewriteBb(instr, m.Not); break; case Mnemonic.bc: RewriteJump(instr); break; case Mnemonic.beqc: RewriteBranch(instr, m.Eq, false); break; case Mnemonic.beqic: RewriteBranchImm(instr, m.Eq, false); break; case Mnemonic.beqzc: RewriteBranch0(instr, m.Eq, false); break; case Mnemonic.bgec: RewriteBranch(instr, m.Ge, false); break; case Mnemonic.bgeic: RewriteBranchImm(instr, m.Ge, false); break; case Mnemonic.bgeiuc: RewriteBranchImm(instr, m.Uge, false); break; case Mnemonic.bgeuc: RewriteBranch(instr, m.Uge, false); break; case Mnemonic.bltc: RewriteBranch(instr, m.Lt, false); break; case Mnemonic.bltic: RewriteBranchImm(instr, m.Lt, false); break; case Mnemonic.bltiuc: RewriteBranchImm(instr, m.Ult, false); break; case Mnemonic.bltuc: RewriteBranch(instr, m.Ult, false); break; case Mnemonic.bnec: RewriteBranch(instr, m.Ne, false); break; case Mnemonic.bneiuc: RewriteBranchImm(instr, m.Ne, false); break; case Mnemonic.bnezc: RewriteBranch0(instr, m.Ne, false); break; case Mnemonic.ext: RewriteExt(instr); break; case Mnemonic.ins: RewriteIns(instr); break; case Mnemonic.jalrc: RewriteJalr(instr); break; case Mnemonic.jrc: RewriteJr(instr); break; case Mnemonic.lbux: RewriteLx(instr, PrimitiveType.Byte, 1); break; case Mnemonic.lwx: RewriteLx(instr, PrimitiveType.Word32, 1); break; case Mnemonic.lwpc: RewriteLwpc(instr); break; case Mnemonic.li: RewriteMove(instr); break; case Mnemonic.lsa: RewriteLsa(instr); break; case Mnemonic.lwm: RewriteLwm(instr); break; case Mnemonic.lwxs: RewriteLwxs(instr); break; case Mnemonic.mod: RewriteMod(instr, m.Mod); break; case Mnemonic.modu: RewriteMod(instr, m.Mod); break; //$TODO: unsigned modulus. case Mnemonic.move: RewriteMove(instr); break; case Mnemonic.move_balc: RewriteMoveBalc(instr); break; case Mnemonic.movep: RewriteMovep(instr); break; case Mnemonic.muh: RewriteMuh(instr, PrimitiveType.Int64, m.SMul); break; case Mnemonic.muhu: RewriteMuh(instr, PrimitiveType.UInt64, m.UMul); break; case Mnemonic.not: RewriteNot(instr); break; case Mnemonic.rdhwr: RewriteReadHardwareRegister(instr); break; case Mnemonic.restore: RewriteRestore(instr, false); break; case Mnemonic.restore_jrc: RewriteRestore(instr, true); break; case Mnemonic.rotx: RewriteRotx(instr); break; case Mnemonic.save: RewriteSave(instr); break; case Mnemonic.sigrie: RewriteSigrie(instr); break; case Mnemonic.swm: RewriteSwm(instr); break; case Mnemonic.swpc: RewriteSwpc(instr); break; case Mnemonic.sbx: RewriteSxs(instr, PrimitiveType.Byte, 1); break; case Mnemonic.shxs: RewriteSxs(instr, PrimitiveType.Word16, 2); break; case Mnemonic.swx: RewriteSxs(instr, PrimitiveType.Word32, 1); break; case Mnemonic.swxs: RewriteSxs(instr, PrimitiveType.Word32, 4); break; case Mnemonic.ualwm: RewriteLwm(instr); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); } }
public ScanResults ScanImage(ScanResults sr) { // At this point, we have some entries in the image map // that are data, and unscanned ranges in betweeen. We // have hopefully a bunch of procedure addresses to // break up the unscanned ranges. var ranges = FindUnscannedRanges(); var stopwatch = new Stopwatch(); var dasm = new ShingledScanner(program, host, storageBinder, sr, eventListener); bool unscanned = false; foreach (var range in ranges) { unscanned = true; try { dasm.ScanRange(range.Item1, range.Item2, range.Item3, range.Item3.ToLinear() - range.Item2.ToLinear()); } catch (AddressCorrelatedException aex) { host.Error(aex.Address, aex.Message); } } if (!unscanned) { // No unscanned blocks were found. return(null); } // Remove blocks that fall off the end of the segment // or into data. Probe(sr); dasm.Dump("After shingle scan graph built"); var deadNodes = dasm.RemoveBadInstructionsFromGraph(); dasm.BuildIcfg(deadNodes); Probe(sr); sr.Dump("After shingle scan"); // On processors with variable length instructions, // there may be many blocks that partially overlap the // "real" blocks that would actually have been executed // by the processor. Starting with known "roots", try to // remove as many invalid blocks as possible. var hsc = new HeuristicProcedureScanner( program, sr, program.SegmentMap.IsValidAddress, host); RemoveInvalidBlocks(sr); Probe(sr); hsc.ResolveBlockConflicts(sr.KnownProcedures.Concat(sr.DirectlyCalledAddresses.Keys)); Probe(sr); sr.Dump("After block conflict resolution"); var pd = new ProcedureDetector(program, sr, this.eventListener); var procs = pd.DetectProcedures(); sr.Procedures = procs; return(sr); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var addr = this.instr.Address; this.rtlInstructions = new List <RtlInstruction>(); this.rtlc = RtlClass.Linear; this.m = new RtlEmitter(rtlInstructions); switch (dasm.Current.Opcode) { default: host.Error( instr.Address, string.Format("PowerPC instruction '{0}' is not supported yet.", instr)); goto case Opcode.illegal; case Opcode.illegal: rtlc = RtlClass.Invalid; m.Invalid(); break; case Opcode.addi: RewriteAddi(); break; case Opcode.addc: RewriteAddc(); break; case Opcode.addic: RewriteAddic(); break; case Opcode.addis: RewriteAddis(); break; case Opcode.add: RewriteAdd(); break; case Opcode.adde: RewriteAdde(); break; case Opcode.addme: RewriteAddme(); break; case Opcode.addze: RewriteAddze(); break; case Opcode.and: RewriteAnd(false); break; case Opcode.andc: RewriteAndc(); break; case Opcode.andi: RewriteAnd(false); break; case Opcode.andis: RewriteAndis(); break; case Opcode.b: RewriteB(); break; case Opcode.bc: RewriteBc(false); break; case Opcode.bcctr: RewriteBcctr(false); break; case Opcode.bctrl: RewriteBcctr(true); break; case Opcode.bdnz: RewriteCtrBranch(false, false, m.Ne, false); break; case Opcode.bdnzf: RewriteCtrBranch(false, false, m.Ne, false); break; case Opcode.bdnzl: RewriteCtrBranch(true, false, m.Ne, false); break; case Opcode.bdnzt: RewriteCtrBranch(false, false, m.Ne, true); break; case Opcode.bdz: RewriteCtrBranch(false, false, m.Eq, false); break; case Opcode.bdzf: RewriteCtrBranch(false, false, m.Eq, false); break; case Opcode.bdzl: RewriteCtrBranch(true, false, m.Eq, false); break; case Opcode.beq: RewriteBranch(false, false, ConditionCode.EQ); break; case Opcode.beql: RewriteBranch(true, false, ConditionCode.EQ); break; case Opcode.beqlr: RewriteBranch(false, true, ConditionCode.EQ); break; case Opcode.beqlrl: RewriteBranch(true, true, ConditionCode.EQ); break; case Opcode.bge: RewriteBranch(false, false, ConditionCode.GE); break; case Opcode.bgel: RewriteBranch(true, false, ConditionCode.GE); break; case Opcode.bgt: RewriteBranch(false, false, ConditionCode.GT); break; case Opcode.bgtl: RewriteBranch(true, false, ConditionCode.GT); break; case Opcode.bgtlr: RewriteBranch(false, true, ConditionCode.GT); break; case Opcode.bl: RewriteBl(); break; case Opcode.blr: RewriteBlr(); break; case Opcode.ble: RewriteBranch(false, false, ConditionCode.LE); break; case Opcode.blel: RewriteBranch(true, false, ConditionCode.LE); break; case Opcode.blelr: RewriteBranch(false, true, ConditionCode.LE); break; case Opcode.blelrl: RewriteBranch(true, true, ConditionCode.LE); break; case Opcode.blt: RewriteBranch(false, false, ConditionCode.LT); break; case Opcode.bltl: RewriteBranch(true, false, ConditionCode.LT); break; case Opcode.bne: RewriteBranch(false, false, ConditionCode.NE); break; case Opcode.bnel: RewriteBranch(true, false, ConditionCode.NE); break; case Opcode.bnelr: RewriteBranch(false, true, ConditionCode.NE); break; case Opcode.bns: RewriteBranch(false, false, ConditionCode.NO); break; case Opcode.bnsl: RewriteBranch(true, false, ConditionCode.NO); break; case Opcode.bso: RewriteBranch(false, false, ConditionCode.OV); break; case Opcode.bsol: RewriteBranch(true, false, ConditionCode.OV); break; case Opcode.cmp: RewriteCmp(); break; case Opcode.cmpi: RewriteCmpi(); break; case Opcode.cmpl: RewriteCmpl(); break; case Opcode.cmpli: RewriteCmpli(); break; case Opcode.cmplw: RewriteCmplw(); break; case Opcode.cmplwi: RewriteCmplwi(); break; case Opcode.cmpwi: RewriteCmpwi(); break; case Opcode.cntlzd: RewriteCntlz("__cntlzd", PrimitiveType.Word64); break; case Opcode.cntlzw: RewriteCntlz("__cntlzw", PrimitiveType.Word32); break; case Opcode.creqv: RewriteCreqv(); break; case Opcode.cror: RewriteCror(); break; case Opcode.crnor: RewriteCrnor(); break; case Opcode.crxor: RewriteCrxor(); break; case Opcode.dcbt: RewriteDcbt(); break; case Opcode.divw: RewriteDivw(); break; case Opcode.divwu: RewriteDivwu(); break; case Opcode.extsb: RewriteExts(PrimitiveType.SByte); break; case Opcode.extsh: RewriteExts(PrimitiveType.Int16); break; case Opcode.extsw: RewriteExts(PrimitiveType.Int32); break; case Opcode.fadd: RewriteFadd(); break; case Opcode.fadds: RewriteFadd(); break; case Opcode.fcfid: RewriteFcfid(); break; case Opcode.fctiwz: RewriteFctiwz(); break; case Opcode.fcmpu: RewriteFcmpu(); break; case Opcode.fdiv: RewriteFdiv(); break; case Opcode.fdivs: RewriteFdiv(); break; case Opcode.fmr: RewriteFmr(); break; case Opcode.fmadd: RewriteFmadd(); break; case Opcode.fmadds: RewriteFmadd(); break; case Opcode.fmsubs: RewriteFmsub(); break; case Opcode.fmul: RewriteFmul(); break; case Opcode.fmuls: RewriteFmul(); break; case Opcode.fneg: RewriteFneg(); break; case Opcode.frsp: RewriteFrsp(); break; case Opcode.fsub: RewriteFsub(); break; case Opcode.fsubs: RewriteFsub(); break; case Opcode.isync: RewriteIsync(); break; case Opcode.lbz: RewriteLz(PrimitiveType.Byte); break; case Opcode.lbzx: RewriteLzx(PrimitiveType.Byte); break; case Opcode.lbzu: RewriteLzu(PrimitiveType.Byte); break; case Opcode.lbzux: RewriteLzux(PrimitiveType.Byte); break; case Opcode.ld: RewriteLz(PrimitiveType.Word64); break; case Opcode.ldu: RewriteLzu(PrimitiveType.Word64); break; case Opcode.lfd: RewriteLfd(); break; case Opcode.lfs: RewriteLfs(); break; case Opcode.lfsx: RewriteLzx(PrimitiveType.Real32); break; case Opcode.lha: RewriteLha(); break; case Opcode.lhax: RewriteLhax(); break; case Opcode.lhau: RewriteLhau(); break; case Opcode.lhaux: RewriteLhaux(); break; case Opcode.lhz: RewriteLz(PrimitiveType.Word16); break; case Opcode.lhzu: RewriteLzu(PrimitiveType.Word16); break; case Opcode.lhzx: RewriteLzx(PrimitiveType.Word16); break; case Opcode.lmw: RewriteLmw(); break; case Opcode.lvewx: RewriteLvewx(); break; case Opcode.lvlx: RewriteLvlx(); break; case Opcode.lvsl: RewriteLvsl(); break; case Opcode.lvx: RewriteLzx(PrimitiveType.Word128); break; case Opcode.lwbrx: RewriteLwbrx(); break; case Opcode.lwz: RewriteLz(PrimitiveType.Word32); break; case Opcode.lwzu: RewriteLzu(PrimitiveType.Word32); break; case Opcode.lwzx: RewriteLzx(PrimitiveType.Word32); break; case Opcode.mcrf: RewriteMcrf(); break; case Opcode.mfcr: RewriteMfcr(); break; case Opcode.mfctr: RewriteMfctr(); break; case Opcode.mftb: RewriteMftb(); break; case Opcode.mffs: RewriteMffs(); break; case Opcode.mflr: RewriteMflr(); break; case Opcode.mfmsr: RewriteMfmsr(); break; case Opcode.mfspr: RewriteMfspr(); break; case Opcode.mtcrf: RewriteMtcrf(); break; case Opcode.mtctr: RewriteMtctr(); break; case Opcode.mtfsf: RewriteMtfsf(); break; case Opcode.mtmsr: RewriteMtmsr(); break; case Opcode.mtspr: RewriteMtspr(); break; case Opcode.mtlr: RewriteMtlr(); break; case Opcode.mulhw: RewriteMulhw(); break; case Opcode.mulhwu: RewriteMulhwu(); break; case Opcode.mulli: RewriteMull(); break; case Opcode.mulld: RewriteMull(); break; case Opcode.mullw: RewriteMull(); break; case Opcode.neg: RewriteNeg(); break; case Opcode.nand: RewriteAnd(true); break; case Opcode.nor: RewriteOr(true); break; case Opcode.or: RewriteOr(false); break; case Opcode.orc: RewriteOrc(false); break; case Opcode.ori: RewriteOr(false); break; case Opcode.oris: RewriteOris(); break; case Opcode.rfi: RewriteRfi(); break; case Opcode.rldicl: RewriteRldicl(); break; case Opcode.rlwinm: RewriteRlwinm(); break; case Opcode.rlwimi: RewriteRlwimi(); break; case Opcode.rlwnm: RewriteRlwnm(); break; case Opcode.sc: RewriteSc(); break; case Opcode.sld: RewriteSl(PrimitiveType.Word64); break; case Opcode.slw: RewriteSl(PrimitiveType.Word32); break; case Opcode.sradi: RewriteSra(); break; case Opcode.sraw: RewriteSra(); break; case Opcode.srawi: RewriteSra(); break; case Opcode.srw: RewriteSrw(); break; case Opcode.stb: RewriteSt(PrimitiveType.Byte); break; case Opcode.stbu: RewriteStu(PrimitiveType.Byte); break; case Opcode.stbux: RewriteStux(PrimitiveType.Byte); break; case Opcode.stbx: RewriteStx(PrimitiveType.Byte); break; case Opcode.std: RewriteSt(PrimitiveType.Word64); break; case Opcode.stdu: RewriteStu(PrimitiveType.Word64); break; case Opcode.stdx: RewriteStx(PrimitiveType.Word64); break; case Opcode.stfd: RewriteSt(PrimitiveType.Real64); break; case Opcode.stfiwx: RewriteStx(PrimitiveType.Int32); break; case Opcode.stfs: RewriteSt(PrimitiveType.Real32); break; case Opcode.sth: RewriteSt(PrimitiveType.Word16); break; case Opcode.sthu: RewriteStu(PrimitiveType.Word16); break; case Opcode.sthx: RewriteStx(PrimitiveType.Word16); break; case Opcode.stmw: RewriteStmw(); break; case Opcode.stvewx: RewriteStvewx(); break; case Opcode.stvx: RewriteStx(PrimitiveType.Word128); break; case Opcode.stw: RewriteSt(PrimitiveType.Word32); break; case Opcode.stwbrx: RewriteStwbrx(); break; case Opcode.stwu: RewriteStu(PrimitiveType.Word32); break; case Opcode.stwux: RewriteStux(PrimitiveType.Word32); break; case Opcode.stwx: RewriteStx(PrimitiveType.Word32); break; case Opcode.subf: RewriteSubf(); break; case Opcode.subfc: RewriteSubfc(); break; case Opcode.subfe: RewriteSubfe(); break; case Opcode.subfic: RewriteSubfic(); break; case Opcode.subfze: RewriteSubfze(); break; case Opcode.sync: RewriteSync(); break; case Opcode.tw: RewriteTw(); break; case Opcode.vaddfp: RewriteVaddfp(); break; case Opcode.vadduwm: RewriteVadduwm(); break; case Opcode.vand: RewriteAnd(false); break; case Opcode.vandc: RewriteAndc(); break; case Opcode.vcfsx: RewriteVct("__vcfsx", PrimitiveType.Real32); break; case Opcode.vcmpgtfp: RewriteVcmpfp("__vcmpgtfp"); break; case Opcode.vcmpgtuw: RewriteVcmpuw("__vcmpgtuw"); break; case Opcode.vcmpeqfp: RewriteVcmpfp("__vcmpeqfp"); break; case Opcode.vcmpequw: RewriteVcmpfp("__vcmpequw"); break; case Opcode.vctsxs: RewriteVct("__vctsxs", PrimitiveType.Int32); break; case Opcode.vmaddfp: RewriteVmaddfp(); break; case Opcode.vmrghw: RewriteVmrghw(); break; case Opcode.vmrglw: RewriteVmrglw(); break; case Opcode.vnmsubfp: RewriteVnmsubfp(); break; case Opcode.vperm: RewriteVperm(); break; case Opcode.vrefp: RewriteVrefp(); break; case Opcode.vrsqrtefp: RewriteVrsqrtefp(); break; case Opcode.vsel: RewriteVsel(); break; case Opcode.vsldoi: RewriteVsldoi(); break; case Opcode.vslw: RewriteVslw(); break; case Opcode.vspltisw: RewriteVspltisw(); break; case Opcode.vspltw: RewriteVspltw(); break; case Opcode.vsubfp: RewriteVsubfp(); break; case Opcode.vxor: RewriteXor(); break; case Opcode.xor: RewriteXor(); break; case Opcode.xori: RewriteXor(); break; case Opcode.xoris: RewriteXoris(); break; } yield return(new RtlInstructionCluster(addr, 4, this.rtlInstructions.ToArray()) { Class = rtlc }); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var addr = this.instr.Address; this.rtlInstructions = new List <RtlInstruction>(); this.rtlc = instr.InstructionClass; this.m = new RtlEmitter(rtlInstructions); switch (dasm.Current.Mnemonic) { default: host.Error( instr.Address, string.Format("PowerPC instruction '{0}' is not supported yet.", instr)); EmitUnitTest(); goto case Mnemonic.illegal; case Mnemonic.illegal: rtlc = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.addi: RewriteAddi(); break; case Mnemonic.addc: RewriteAddc(); break; case Mnemonic.addic: RewriteAddic(); break; case Mnemonic.addis: RewriteAddis(); break; case Mnemonic.add: RewriteAdd(); break; case Mnemonic.adde: RewriteAdde(); break; case Mnemonic.addme: RewriteAddme(); break; case Mnemonic.addze: RewriteAddze(); break; case Mnemonic.and: RewriteAnd(false); break; case Mnemonic.andc: RewriteAndc(); break; case Mnemonic.andi: RewriteAnd(false); break; case Mnemonic.andis: RewriteAndis(); break; case Mnemonic.b: RewriteB(); break; case Mnemonic.bc: RewriteBc(false); break; case Mnemonic.bcctr: RewriteBcctr(false); break; case Mnemonic.bctrl: RewriteBcctr(true); break; case Mnemonic.bcdadd: RewriteBcdadd(); break; case Mnemonic.bdnz: RewriteCtrBranch(false, false, m.Ne, false); break; case Mnemonic.bdnzf: RewriteCtrBranch(false, false, m.Ne, false); break; case Mnemonic.bdnzl: RewriteCtrBranch(true, false, m.Ne, false); break; case Mnemonic.bdnzt: RewriteCtrBranch(false, false, m.Ne, true); break; case Mnemonic.bdnztl: RewriteCtrBranch(true, false, m.Ne, true); break; case Mnemonic.bdz: RewriteCtrBranch(false, false, m.Eq, false); break; case Mnemonic.bdzf: RewriteCtrBranch(false, false, m.Eq, false); break; case Mnemonic.bdzfl: RewriteCtrBranch(true, false, m.Eq, false); break; case Mnemonic.bdzt: RewriteCtrBranch(false, false, m.Eq, true); break; case Mnemonic.bdztl: RewriteCtrBranch(true, false, m.Eq, true); break; case Mnemonic.bdzl: RewriteCtrBranch(true, false, m.Eq, false); break; case Mnemonic.beq: RewriteBranch(false, false, ConditionCode.EQ); break; case Mnemonic.beql: RewriteBranch(true, false, ConditionCode.EQ); break; case Mnemonic.beqlr: RewriteBranch(false, true, ConditionCode.EQ); break; case Mnemonic.beqlrl: RewriteBranch(true, true, ConditionCode.EQ); break; case Mnemonic.bge: RewriteBranch(false, false, ConditionCode.GE); break; case Mnemonic.bgel: RewriteBranch(true, false, ConditionCode.GE); break; case Mnemonic.bgelr: RewriteBranch(false, true, ConditionCode.GE); break; case Mnemonic.bgt: RewriteBranch(false, false, ConditionCode.GT); break; case Mnemonic.bgtl: RewriteBranch(true, false, ConditionCode.GT); break; case Mnemonic.bgtlr: RewriteBranch(false, true, ConditionCode.GT); break; case Mnemonic.bl: RewriteBl(); break; case Mnemonic.blr: RewriteBlr(); break; case Mnemonic.bltlr: RewriteBranch(false, true, ConditionCode.LT); break; case Mnemonic.ble: RewriteBranch(false, false, ConditionCode.LE); break; case Mnemonic.blel: RewriteBranch(true, false, ConditionCode.LE); break; case Mnemonic.blelr: RewriteBranch(false, true, ConditionCode.LE); break; case Mnemonic.blelrl: RewriteBranch(true, true, ConditionCode.LE); break; case Mnemonic.blt: RewriteBranch(false, false, ConditionCode.LT); break; case Mnemonic.bltl: RewriteBranch(true, false, ConditionCode.LT); break; case Mnemonic.bne: RewriteBranch(false, false, ConditionCode.NE); break; case Mnemonic.bnel: RewriteBranch(true, false, ConditionCode.NE); break; case Mnemonic.bnelr: RewriteBranch(false, true, ConditionCode.NE); break; case Mnemonic.bns: RewriteBranch(false, false, ConditionCode.NO); break; case Mnemonic.bnsl: RewriteBranch(true, false, ConditionCode.NO); break; case Mnemonic.bso: RewriteBranch(false, false, ConditionCode.OV); break; case Mnemonic.bsol: RewriteBranch(true, false, ConditionCode.OV); break; case Mnemonic.cmp: RewriteCmp(); break; case Mnemonic.cmpi: RewriteCmpi(); break; case Mnemonic.cmpl: RewriteCmpl(); break; case Mnemonic.cmpli: RewriteCmpli(); break; case Mnemonic.cmplw: RewriteCmplw(); break; case Mnemonic.cmplwi: RewriteCmplwi(); break; case Mnemonic.cmpwi: RewriteCmpwi(); break; case Mnemonic.cntlzd: RewriteCntlz("__cntlzd", PrimitiveType.Word64); break; case Mnemonic.cntlzw: RewriteCntlz("__cntlzw", PrimitiveType.Word32); break; case Mnemonic.creqv: RewriteCreqv(); break; case Mnemonic.cror: RewriteCror(); break; case Mnemonic.crnor: RewriteCrnor(); break; case Mnemonic.crxor: RewriteCrxor(); break; case Mnemonic.dcbf: RewriteDcbf(); break; case Mnemonic.dcbi: RewriteDcbi(); break; case Mnemonic.dcbst: RewriteDcbst(); break; case Mnemonic.dcbt: RewriteDcbt(); break; case Mnemonic.dcbtst: RewriteDcbtst(); break; case Mnemonic.dcbz: RewriteDcbz(); break; case Mnemonic.divd: RewriteDivd(m.SDiv); break; case Mnemonic.divdu: RewriteDivd(m.UDiv); break; case Mnemonic.divw: RewriteDivw(); break; case Mnemonic.divwu: RewriteDivwu(); break; case Mnemonic.eieio: RewriteEieio(); break; case Mnemonic.evmhesmfaaw: RewriteVectorPairOp("__evmhesmfaaw", PrimitiveType.Word32); break; case Mnemonic.evmhessfaaw: RewriteVectorPairOp("__evmhessfaaw", PrimitiveType.Word32); break; case Mnemonic.eqv: RewriteXor(true); break; case Mnemonic.extsb: RewriteExts(PrimitiveType.SByte); break; case Mnemonic.extsh: RewriteExts(PrimitiveType.Int16); break; case Mnemonic.extsw: RewriteExts(PrimitiveType.Int32); break; case Mnemonic.fabs: RewriteFabs(); break; case Mnemonic.fadd: RewriteFadd(); break; case Mnemonic.fadds: RewriteFadd(); break; case Mnemonic.fcfid: RewriteFcfid(); break; case Mnemonic.fctid: RewriteFctid(); break; case Mnemonic.fctidz: RewriteFctidz(); break; case Mnemonic.fctiwz: RewriteFctiwz(); break; case Mnemonic.fcmpo: RewriteFcmpo(); break; case Mnemonic.fcmpu: RewriteFcmpu(); break; case Mnemonic.fdiv: RewriteFdiv(); break; case Mnemonic.fdivs: RewriteFdiv(); break; case Mnemonic.fmr: RewriteFmr(); break; case Mnemonic.fmadd: RewriteFmadd(PrimitiveType.Real64, m.FAdd, false); break; case Mnemonic.fmadds: RewriteFmadd(PrimitiveType.Real32, m.FAdd, false); break; case Mnemonic.fmsub: RewriteFmadd(PrimitiveType.Real64, m.FSub, false); break; case Mnemonic.fmsubs: RewriteFmadd(PrimitiveType.Real32, m.FSub, false); break; case Mnemonic.fnmadd: RewriteFmadd(PrimitiveType.Real64, m.FAdd, true); break; case Mnemonic.fnmadds: RewriteFmadd(PrimitiveType.Real32, m.FAdd, true); break; case Mnemonic.fnmsub: RewriteFmadd(PrimitiveType.Real64, m.FSub, true); break; case Mnemonic.fnmsubs: RewriteFmadd(PrimitiveType.Real32, m.FSub, true); break; case Mnemonic.fmul: RewriteFmul(); break; case Mnemonic.fmuls: RewriteFmul(); break; case Mnemonic.fneg: RewriteFneg(); break; case Mnemonic.frsp: RewriteFrsp(); break; case Mnemonic.frsqrte: RewriteFrsqrte(); break; case Mnemonic.fsel: RewriteFsel(); break; case Mnemonic.fsqrt: RewriteFsqrt(); break; case Mnemonic.fsub: RewriteFsub(); break; case Mnemonic.fsubs: RewriteFsub(); break; case Mnemonic.icbi: RewriteIcbi(); break; case Mnemonic.isync: RewriteIsync(); break; case Mnemonic.lbz: RewriteLz(PrimitiveType.Byte, arch.WordWidth); break; case Mnemonic.lbzx: RewriteLzx(PrimitiveType.Byte, arch.WordWidth); break; case Mnemonic.lbzu: RewriteLzu(PrimitiveType.Byte, arch.WordWidth); break; case Mnemonic.lbzux: RewriteLzux(PrimitiveType.Byte, arch.WordWidth); break; case Mnemonic.ld: RewriteLz(PrimitiveType.Word64, arch.WordWidth); break; case Mnemonic.ldarx: RewriteLarx("__ldarx", PrimitiveType.Word64); break; case Mnemonic.ldu: RewriteLzu(PrimitiveType.Word64, arch.WordWidth); break; case Mnemonic.ldx: RewriteLzx(PrimitiveType.Word64, arch.WordWidth); break; case Mnemonic.lfd: RewriteLfd(); break; case Mnemonic.lfdu: RewriteLzu(PrimitiveType.Real64, PrimitiveType.Real64); break; case Mnemonic.lfdux: RewriteLzux(PrimitiveType.Real64, PrimitiveType.Real64); break; case Mnemonic.lfdx: RewriteLzx(PrimitiveType.Real64, PrimitiveType.Real64); break; case Mnemonic.lfs: RewriteLfs(); break; case Mnemonic.lfsu: RewriteLzu(PrimitiveType.Real32, PrimitiveType.Real64); break; case Mnemonic.lfsux: RewriteLzux(PrimitiveType.Real32, PrimitiveType.Real64); break; case Mnemonic.lfsx: RewriteLzx(PrimitiveType.Real32, PrimitiveType.Real64); break; case Mnemonic.lha: RewriteLa(PrimitiveType.Int16, arch.SignedWord); break; case Mnemonic.lhax: RewriteLax(PrimitiveType.Int16, arch.SignedWord); break; case Mnemonic.lhau: RewriteLau(PrimitiveType.Int16, arch.SignedWord); break; case Mnemonic.lhaux: RewriteLaux(PrimitiveType.Int16, arch.SignedWord); break; case Mnemonic.lhbrx: RewriteLhbrx(); break; case Mnemonic.lhz: RewriteLz(PrimitiveType.Word16, arch.WordWidth); break; case Mnemonic.lhzu: RewriteLzu(PrimitiveType.Word16, arch.WordWidth); break; case Mnemonic.lhzx: RewriteLzx(PrimitiveType.Word16, arch.WordWidth); break; case Mnemonic.lmw: RewriteLmw(); break; case Mnemonic.lq: RewriteLq(); break; case Mnemonic.lvewx: RewriteLvewx(); break; case Mnemonic.lvlx: case Mnemonic.lvlx128: RewriteLvlx(); break; case Mnemonic.lvrx128: RewriteLvrx(); break; case Mnemonic.lvsl: RewriteLvsl(); break; case Mnemonic.lvx: case Mnemonic.lvx128: RewriteLzx(PrimitiveType.Word128, PrimitiveType.Word128); break; case Mnemonic.lwarx: RewriteLarx("__lwarx", PrimitiveType.Word32); break; case Mnemonic.lwax: RewriteLax(PrimitiveType.Int32, arch.SignedWord); break; case Mnemonic.lwbrx: RewriteLwbrx(); break; case Mnemonic.lwz: RewriteLz(PrimitiveType.Word32, arch.WordWidth); break; case Mnemonic.lwzu: RewriteLzu(PrimitiveType.Word32, arch.WordWidth); break; case Mnemonic.lwzux: RewriteLzux(PrimitiveType.Word32, arch.WordWidth); break; case Mnemonic.lwzx: RewriteLzx(PrimitiveType.Word32, arch.WordWidth); break; case Mnemonic.mcrf: RewriteMcrf(); break; case Mnemonic.mfcr: RewriteMfcr(); break; case Mnemonic.mfctr: RewriteMfctr(); break; case Mnemonic.mftb: RewriteMftb(); break; case Mnemonic.mffs: RewriteMffs(); break; case Mnemonic.mflr: RewriteMflr(); break; case Mnemonic.mfmsr: RewriteMfmsr(); break; case Mnemonic.mfspr: RewriteMfspr(); break; case Mnemonic.mtcrf: RewriteMtcrf(); break; case Mnemonic.mtctr: RewriteMtctr(); break; case Mnemonic.mtfsf: RewriteMtfsf(); break; case Mnemonic.mtmsr: RewriteMtmsr(PrimitiveType.Word32); break; case Mnemonic.mtmsrd: RewriteMtmsr(PrimitiveType.Word64); break; case Mnemonic.mtspr: RewriteMtspr(); break; case Mnemonic.mtlr: RewriteMtlr(); break; case Mnemonic.mulhw: RewriteMulhw(); break; case Mnemonic.mulhwu: RewriteMulhwu(); break; case Mnemonic.mulhhwu: RewriteMulhhwu(); break; case Mnemonic.mulli: RewriteMull(); break; case Mnemonic.mulld: RewriteMull(); break; case Mnemonic.mullw: RewriteMull(); break; case Mnemonic.neg: RewriteNeg(); break; case Mnemonic.nand: RewriteAnd(true); break; case Mnemonic.nor: RewriteOr(true); break; case Mnemonic.or: RewriteOr(false); break; case Mnemonic.orc: RewriteOrc(false); break; case Mnemonic.ori: RewriteOr(false); break; case Mnemonic.oris: RewriteOris(); break; case Mnemonic.ps_abs: RewritePairedInstruction_Src1("__ps_abs"); break; case Mnemonic.ps_add: RewritePairedInstruction_Src2("__ps_add"); break; case Mnemonic.ps_cmpo0: Rewrite_ps_cmpo("__ps_cmpo0"); break; case Mnemonic.ps_div: RewritePairedInstruction_Src2("__ps_div"); break; case Mnemonic.psq_l: Rewrite_psq_l(false); break; case Mnemonic.psq_lu: Rewrite_psq_l(true); break; case Mnemonic.psq_lx: Rewrite_psq_l(false); break; case Mnemonic.psq_lux: Rewrite_psq_l(true); break; case Mnemonic.ps_madd: RewritePairedInstruction_Src3("__ps_madd"); break; case Mnemonic.ps_madds0: RewritePairedInstruction_Src3("__ps_madds0"); break; case Mnemonic.ps_madds1: RewritePairedInstruction_Src3("__ps_madds1"); break; case Mnemonic.ps_merge00: RewritePairedInstruction_Src2("__ps_merge00"); break; case Mnemonic.ps_merge01: RewritePairedInstruction_Src2("__ps_merge01"); break; case Mnemonic.ps_merge10: RewritePairedInstruction_Src2("__ps_merge10"); break; case Mnemonic.ps_merge11: RewritePairedInstruction_Src2("__ps_merge11"); break; case Mnemonic.ps_mr: Rewrite_ps_mr(); break; case Mnemonic.ps_mul: RewritePairedInstruction_Src2("__ps_mul"); break; case Mnemonic.ps_muls0: RewritePairedInstruction_Src2("__ps_muls0"); break; case Mnemonic.ps_muls1: RewritePairedInstruction_Src2("__ps_muls1"); break; case Mnemonic.ps_nmadd: RewritePairedInstruction_Src3("__ps_nmadd"); break; case Mnemonic.ps_nmsub: RewritePairedInstruction_Src3("__ps_nmsub"); break; case Mnemonic.ps_nabs: RewritePairedInstruction_Src1("__ps_nabs"); break; case Mnemonic.ps_neg: RewritePairedInstruction_Src1("__ps_neg"); break; case Mnemonic.ps_res: RewritePairedInstruction_Src1("__ps_res"); break; case Mnemonic.ps_rsqrte: RewritePairedInstruction_Src1("__ps_rsqrte"); break; case Mnemonic.ps_sel: RewritePairedInstruction_Src3("__ps_sel"); break; case Mnemonic.ps_sub: RewritePairedInstruction_Src2("__ps_sub"); break; case Mnemonic.ps_sum0: RewritePairedInstruction_Src3("__ps_sum0"); break; case Mnemonic.psq_st: Rewrite_psq_st(false); break; case Mnemonic.psq_stu: Rewrite_psq_st(true); break; case Mnemonic.psq_stx: Rewrite_psq_st(false); break; case Mnemonic.psq_stux: Rewrite_psq_st(true); break; case Mnemonic.rfi: RewriteRfi(); break; case Mnemonic.rldicl: RewriteRldicl(); break; case Mnemonic.rldicr: RewriteRldicr(); break; case Mnemonic.rldimi: RewriteRldimi(); break; case Mnemonic.rlwinm: RewriteRlwinm(); break; case Mnemonic.rlwimi: RewriteRlwimi(); break; case Mnemonic.rlwnm: RewriteRlwnm(); break; case Mnemonic.sc: RewriteSc(); break; case Mnemonic.sld: RewriteSl(PrimitiveType.Word64); break; case Mnemonic.slw: RewriteSl(PrimitiveType.Word32); break; case Mnemonic.srad: RewriteSra(); break; case Mnemonic.sradi: RewriteSra(); break; case Mnemonic.sraw: RewriteSra(); break; case Mnemonic.srawi: RewriteSra(); break; case Mnemonic.srd: RewriteSrw(); break; case Mnemonic.srw: RewriteSrw(); break; case Mnemonic.stb: RewriteSt(PrimitiveType.Byte); break; case Mnemonic.stbu: RewriteStu(PrimitiveType.Byte); break; case Mnemonic.stbux: RewriteStux(PrimitiveType.Byte); break; case Mnemonic.stbx: RewriteStx(PrimitiveType.Byte); break; case Mnemonic.std: RewriteSt(PrimitiveType.Word64); break; case Mnemonic.stdcx: RewriteStcx("__stdcx", PrimitiveType.Word64); break; case Mnemonic.stdu: RewriteStu(PrimitiveType.Word64); break; case Mnemonic.stdx: RewriteStx(PrimitiveType.Word64); break; case Mnemonic.stfd: RewriteSt(PrimitiveType.Real64); break; case Mnemonic.stfdu: RewriteStu(PrimitiveType.Real64); break; case Mnemonic.stfdux: RewriteStux(PrimitiveType.Real64); break; case Mnemonic.stfdx: RewriteStx(PrimitiveType.Real64); break; case Mnemonic.stfiwx: RewriteStx(PrimitiveType.Int32); break; case Mnemonic.stfs: RewriteSt(PrimitiveType.Real32); break; case Mnemonic.stfsu: RewriteStu(PrimitiveType.Real32); break; case Mnemonic.stfsx: RewriteStx(PrimitiveType.Real32); break; case Mnemonic.sth: RewriteSt(PrimitiveType.Word16); break; case Mnemonic.sthu: RewriteStu(PrimitiveType.Word16); break; case Mnemonic.sthx: RewriteStx(PrimitiveType.Word16); break; case Mnemonic.stmw: RewriteStmw(); break; case Mnemonic.stvewx: RewriteStvewx(); break; case Mnemonic.stvx: RewriteStx(PrimitiveType.Word128); break; case Mnemonic.stvx128: RewriteStx(PrimitiveType.Word128); break; case Mnemonic.stvlx128: RewriteStx(PrimitiveType.Word128); break; case Mnemonic.stvrx128: RewriteStx(PrimitiveType.Word128); break; case Mnemonic.stw: RewriteSt(PrimitiveType.Word32); break; case Mnemonic.stwbrx: RewriteStwbrx(); break; case Mnemonic.stwcx: RewriteStcx("__stwcx", PrimitiveType.Word32); break; case Mnemonic.stwu: RewriteStu(PrimitiveType.Word32); break; case Mnemonic.stwux: RewriteStux(PrimitiveType.Word32); break; case Mnemonic.stwx: RewriteStx(PrimitiveType.Word32); break; case Mnemonic.subf: RewriteSubf(); break; case Mnemonic.subfc: RewriteSubfc(); break; case Mnemonic.subfe: RewriteSubfe(); break; case Mnemonic.subfic: RewriteSubfic(); break; case Mnemonic.subfze: RewriteSubfze(); break; case Mnemonic.sync: RewriteSync(); break; case Mnemonic.td: RewriteTrap(PrimitiveType.Word64); break; case Mnemonic.tdi: RewriteTrap(PrimitiveType.Word64); break; case Mnemonic.tw: RewriteTrap(PrimitiveType.Word32); break; case Mnemonic.twi: RewriteTrap(PrimitiveType.Word32); break; case Mnemonic.vaddfp: RewriteVaddfp(); break; case Mnemonic.vaddubm: RewriteVectorBinOp("__vaddubm", PrimitiveType.UInt8); break; case Mnemonic.vaddubs: RewriteVectorBinOp("__vaddubs", PrimitiveType.UInt8); break; case Mnemonic.vadduwm: RewriteVectorBinOp("__vadduwm", PrimitiveType.UInt32); break; case Mnemonic.vadduqm: RewriteAdd(); break; case Mnemonic.vand: case Mnemonic.vand128: RewriteAnd(false); break; case Mnemonic.vandc: RewriteAndc(); break; case Mnemonic.vcfsx: RewriteVct("__vcfsx", PrimitiveType.Real32); break; case Mnemonic.vcfpsxws128: RewriteVcfpsxws("__vcfpsxws"); break; case Mnemonic.vcmpbfp: case Mnemonic.vcmpbfp128: RewriteVcmpfp("__vcmpebfp"); break; case Mnemonic.vcmpeqfp: case Mnemonic.vcmpeqfp128: RewriteVcmpfp("__vcmpeqfp"); break; case Mnemonic.vcmpgtfp: case Mnemonic.vcmpgtfp128: RewriteVcmpfp("__vcmpgtfp"); break; case Mnemonic.vcmpgtuw: RewriteVcmpu("__vcmpgtuw", PrimitiveType.UInt32); break; case Mnemonic.vcmpequb: RewriteVcmpu("__vcmpequb", PrimitiveType.UInt8); break; case Mnemonic.vcmpequd: RewriteVcmpu("__vcmpequd", PrimitiveType.UInt64); break; case Mnemonic.vcmpequw: RewriteVcmpu("__vcmpequw", PrimitiveType.UInt32); break; case Mnemonic.vcsxwfp128: RewriteVcsxwfp("__vcsxwfp"); break; case Mnemonic.vctsxs: RewriteVct("__vctsxs", PrimitiveType.Int32); break; case Mnemonic.vexptefp128: RewriteVectorUnary("__vexptefp"); break; case Mnemonic.vlogefp128: RewriteVectorUnary("__vlogefp"); break; case Mnemonic.vmaddfp: RewriteVmaddfp(); break; case Mnemonic.vmaddcfp128: RewriteVectorBinOp("__vmaddcfp", PrimitiveType.Real32); break; case Mnemonic.vmaxfp128: RewriteVectorBinOp("__vmaxfp", PrimitiveType.Real32); break; case Mnemonic.vminfp128: RewriteVectorBinOp("__vminfp", PrimitiveType.Real32); break; case Mnemonic.vmaxub: RewriteVectorBinOp("__vmaxub", PrimitiveType.UInt8); break; case Mnemonic.vmaxuh: RewriteVectorBinOp("__vmaxuh", PrimitiveType.UInt16); break; case Mnemonic.vmladduhm: RewriteVectorBinOp("__vmladduhm", PrimitiveType.UInt16); break; case Mnemonic.vmrghw: case Mnemonic.vmrghw128: RewriteVmrghw(); break; case Mnemonic.vmrglw: case Mnemonic.vmrglw128: RewriteVmrglw(); break; case Mnemonic.vmsub3fp128: RewriteVectorBinOp("__vmsub3fp", PrimitiveType.Real32); break; case Mnemonic.vmsub4fp128: RewriteVectorBinOp("__vmsub4fp", PrimitiveType.Real32); break; //$REVIEW: is it correct? case Mnemonic.vmulfp128: RewriteVectorBinOp("__vmulfp", PrimitiveType.Real32); break; //$REVIEW: is it correct? case Mnemonic.vnmsubfp: RewriteVnmsubfp(); break; case Mnemonic.vor: case Mnemonic.vor128: RewriteVor(); break; case Mnemonic.vperm: case Mnemonic.vperm128: RewriteVperm(); break; case Mnemonic.vpkd3d128: RewriterVpkD3d(); break; case Mnemonic.vrefp: case Mnemonic.vrefp128: RewriteVrefp(); break; case Mnemonic.vrfin128: RewriteVectorUnary("__vrfin"); break; case Mnemonic.vrfiz128: RewriteVectorUnary("__vrfiz"); break; case Mnemonic.vrlimi128: RewriteVrlimi(); break; case Mnemonic.vrsqrtefp: case Mnemonic.vrsqrtefp128: RewriteVrsqrtefp(); break; case Mnemonic.vsel: RewriteVsel(); break; case Mnemonic.vsldoi: RewriteVsldoi(); break; case Mnemonic.vslw: case Mnemonic.vslw128: RewriteVsxw("__vslw"); break; case Mnemonic.vspltisw: case Mnemonic.vspltisw128: RewriteVspltisw(); break; case Mnemonic.vspltw: case Mnemonic.vspltw128: RewriteVspltw(); break; case Mnemonic.vsrw128: RewriteVsxw("__vsrw"); break; case Mnemonic.vsubfp: case Mnemonic.vsubfp128: RewriteVsubfp(); break; case Mnemonic.vupkd3d128: RewriteVupkd3d(); break; case Mnemonic.vxor: case Mnemonic.vxor128: RewriteXor(false); break; case Mnemonic.xor: RewriteXor(false); break; case Mnemonic.xori: RewriteXor(false); break; case Mnemonic.xoris: RewriteXoris(); break; } yield return(new RtlInstructionCluster(addr, 4, this.rtlInstructions.ToArray()) { Class = rtlc }); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { var instr = dasm.Current; this.rtlInstructions = new List <RtlInstruction>(); this.rtlc = RtlClass.Linear; this.m = new RtlEmitter(rtlInstructions); switch (instr.opcode) { default: host.Error( instr.Address, string.Format("MIPS instruction '{0}' is not supported yet.", instr)); EmitUnitTest(); goto case Opcode.illegal; case Opcode.illegal: rtlc = RtlClass.Invalid; m.Invalid(); break; case Opcode.add: case Opcode.addi: case Opcode.addiu: case Opcode.addu: RewriteAdd(instr, PrimitiveType.Word32); break; case Opcode.add_s: RewriteFpuBinopS(instr, m.FAdd); break; case Opcode.add_d: RewriteFpuBinopD(instr, m.FAdd); break; case Opcode.and: case Opcode.andi: RewriteAnd(instr); break; case Opcode.bc1f: RewriteBranchConditional1(instr, false); break; case Opcode.bc1t: RewriteBranchConditional1(instr, true); break; case Opcode.beq: RewriteBranch(instr, m.Eq, false); break; case Opcode.beql: RewriteBranchLikely(instr, m.Eq); break; case Opcode.bgez: RewriteBranch0(instr, m.Ge, false); break; case Opcode.bgezl: RewriteBranch0(instr, m.Ge, true); break; case Opcode.bgezal: RewriteBgezal(instr); break; case Opcode.bgezall: RewriteBranch0(instr, m.Ge, true); break; case Opcode.bgtz: RewriteBranch0(instr, m.Gt, false); break; case Opcode.bgtzl: RewriteBranch0(instr, m.Gt, true); break; case Opcode.blez: RewriteBranch0(instr, m.Le, false); break; case Opcode.blezl: RewriteBranch0(instr, m.Le, true); break; case Opcode.bltz: RewriteBranch0(instr, m.Lt, false); break; case Opcode.bltzl: RewriteBranch0(instr, m.Lt, true); break; case Opcode.bltzal: RewriteBranch0(instr, m.Lt, true); break; case Opcode.bltzall: RewriteBranch0(instr, m.Lt, true); break; case Opcode.bne: RewriteBranch(instr, m.Ne, false); break; case Opcode.bnel: RewriteBranchLikely(instr, m.Ne); break; case Opcode.@break: RewriteBreak(instr); break; case Opcode.c_le_d: RewriteFpuCmpD(instr, Operator.Fle); break; case Opcode.c_le_s: RewriteFpuCmpD(instr, Operator.Fle); break; case Opcode.c_lt_d: RewriteFpuCmpD(instr, Operator.Flt); break; case Opcode.c_lt_s: RewriteFpuCmpD(instr, Operator.Flt); break; case Opcode.c_eq_d: RewriteFpuCmpD(instr, Operator.Feq); break; case Opcode.c_eq_s: RewriteFpuCmpD(instr, Operator.Feq); break; case Opcode.cfc1: RewriteCfc1(instr); break; case Opcode.ctc1: RewriteCtc1(instr); break; case Opcode.cvt_d_l: RewriteCvtD(instr, PrimitiveType.Real64); break; case Opcode.cvt_s_d: RewriteCvtD(instr, PrimitiveType.Real32); break; case Opcode.cvt_w_d: RewriteCvtD(instr, PrimitiveType.Int32); break; case Opcode.dadd: case Opcode.daddi: RewriteAdd(instr, PrimitiveType.Word64); break; case Opcode.daddiu: case Opcode.daddu: RewriteAdd(instr, PrimitiveType.Word64); break; case Opcode.ddiv: RewriteDiv(instr, m.SDiv); break; case Opcode.ddivu: RewriteDiv(instr, m.UDiv); break; case Opcode.div: RewriteDiv(instr, m.SDiv); break; case Opcode.divu: RewriteDiv(instr, m.UDiv); break; case Opcode.div_d: RewriteFpuBinopD(instr, m.FDiv); break; case Opcode.dmfc0: RewriteMfc0(instr); break; case Opcode.dmfc1: RewriteMfc1(instr); break; case Opcode.dmtc0: RewriteMtc0(instr); break; case Opcode.dmtc1: RewriteMtc1(instr); break; case Opcode.dmult: RewriteMul(instr, m.SMul, PrimitiveType.Int128); break; case Opcode.dmultu: RewriteMul(instr, m.UMul, PrimitiveType.UInt128); break; case Opcode.dsll: RewriteSll(instr); break; case Opcode.dsll32: RewriteDshift32(instr, m.Shl); break; case Opcode.dsllv: RewriteSrl(instr); break; case Opcode.dsra: RewriteSra(instr); break; case Opcode.dsra32: RewriteDshift32(instr, m.Sar); break; case Opcode.dsrav: RewriteSra(instr); break; case Opcode.dsrl: RewriteSrl(instr); break; case Opcode.dsrl32: RewriteDshift32(instr, m.Shr); break; case Opcode.dsrlv: RewriteSrl(instr); break; case Opcode.dsub: case Opcode.dsubu: RewriteSub(instr, PrimitiveType.Word64); break; case Opcode.eret: RewriteEret(instr); break; case Opcode.j: RewriteJump(instr); break; case Opcode.jal: RewriteJal(instr); break; case Opcode.jalr: RewriteJalr(instr); break; case Opcode.jr: RewriteJr(instr); break; case Opcode.lb: RewriteLoad(instr, PrimitiveType.SByte); break; case Opcode.lbu: RewriteLoad(instr, PrimitiveType.Byte); break; case Opcode.ld: RewriteLoad(instr, PrimitiveType.Word64); break; case Opcode.ldl: RewriteLdl(instr); break; case Opcode.ldr: RewriteLdr(instr); break; case Opcode.ldc1: RewriteLdc1(instr); break; case Opcode.lh: RewriteLoad(instr, PrimitiveType.Int16); break; case Opcode.lhu: RewriteLoad(instr, PrimitiveType.UInt16); break; case Opcode.ll: RewriteLoadLinked32(instr); break; case Opcode.lld: RewriteLoadLinked64(instr); break; case Opcode.lui: RewriteLui(instr); break; case Opcode.lw: RewriteLoad(instr, PrimitiveType.Int32); break; case Opcode.lwc1: RewriteLoad(instr, PrimitiveType.Real32); break; case Opcode.lwl: RewriteLwl(instr); break; case Opcode.lwr: RewriteLwr(instr); break; case Opcode.lwu: RewriteLoad(instr, PrimitiveType.UInt32); break; case Opcode.mfc0: RewriteMfc0(instr); break; case Opcode.mfc1: RewriteMfc1(instr); break; case Opcode.mfhi: RewriteMf(instr, arch.hi); break; case Opcode.mflo: RewriteMf(instr, arch.lo); break; case Opcode.mtc0: RewriteMtc0(instr); break; case Opcode.mthi: RewriteMt(instr, arch.hi); break; case Opcode.mtlo: RewriteMt(instr, arch.lo); break; case Opcode.movf: RewriteMovft(instr, false); break; case Opcode.movn: RewriteMovCc(instr, m.Ne0); break; case Opcode.movt: RewriteMovft(instr, true); break; case Opcode.movz: RewriteMovCc(instr, m.Eq0); break; case Opcode.mov_d: RewriteCopy(instr); break; case Opcode.mov_s: RewriteCopy(instr); break; case Opcode.mtc1: RewriteMtc1(instr); break; case Opcode.mul: RewriteMul(instr, m.SMul, PrimitiveType.Int32); break; case Opcode.mult: RewriteMul(instr, m.SMul, PrimitiveType.Int64); break; case Opcode.multu: RewriteMul(instr, m.UMul, PrimitiveType.UInt64); break; case Opcode.mul_s: RewriteMul(instr, m.FMul, PrimitiveType.Real32); break; case Opcode.mul_d: RewriteMulD(instr); break; case Opcode.nop: m.Nop(); break; case Opcode.nor: RewriteNor(instr); break; case Opcode.or: case Opcode.ori: RewriteOr(instr); break; case Opcode.pref: case Opcode.prefx: RewritePrefx(instr); break; case Opcode.sb: RewriteStore(instr); break; case Opcode.sc: RewriteStoreConditional32(instr); break; case Opcode.scd: RewriteStoreConditional64(instr); break; case Opcode.sd: RewriteStore(instr); break; case Opcode.sdc1: RewriteStore(instr); break; case Opcode.sdl: RewriteSdl(instr); break; case Opcode.sdr: RewriteSdr(instr); break; case Opcode.sh: RewriteStore(instr); break; case Opcode.sll: case Opcode.sllv: RewriteSll(instr); break; case Opcode.slt: RewriteSxx(instr, m.Lt); break; case Opcode.slti: RewriteSxx(instr, m.Lt); break; case Opcode.sltiu: RewriteSxx(instr, m.Ult); break; case Opcode.sltu: RewriteSxx(instr, m.Ult); break; case Opcode.sra: case Opcode.srav: RewriteSra(instr); break; case Opcode.srl: case Opcode.srlv: RewriteSrl(instr); break; case Opcode.sub: case Opcode.subu: RewriteSub(instr, PrimitiveType.Word32); break; case Opcode.sub_d: RewriteFpuBinopD(instr, m.FSub); break; case Opcode.sw: case Opcode.swc1: RewriteStore(instr); break; case Opcode.swl: RewriteSwl(instr); break; case Opcode.swr: RewriteSwr(instr); break; case Opcode.sync: RewriteSync(instr); break; case Opcode.syscall: RewriteSyscall(instr); break; case Opcode.teq: RewriteTrap(instr, m.Eq); break; case Opcode.tge: RewriteTrap(instr, m.Ge); break; case Opcode.tgeu: RewriteTrap(instr, m.Uge); break; case Opcode.tgeiu: RewriteTrapi(instr, m.Uge); break; case Opcode.tlbp: RewriteTlbp(instr); break; case Opcode.tlbr: RewriteTlbr(instr); break; case Opcode.tlbwi: RewriteTlbwi(instr); break; case Opcode.tlbwr: RewriteTlbwr(instr); break; case Opcode.tlt: RewriteTrap(instr, m.Lt); break; case Opcode.tlti: RewriteTrapi(instr, m.Lt); break; case Opcode.tltu: RewriteTrap(instr, m.Ult); break; case Opcode.tne: RewriteTrap(instr, m.Ne); break; case Opcode.tnei: RewriteTrapi(instr, m.Ne); break; case Opcode.trunc_l_d: RewriteTrunc(instr, "trunc", PrimitiveType.Real64, PrimitiveType.Int64); break; case Opcode.wait: RewriteWait(instr); break; case Opcode.xor: case Opcode.xori: RewriteXor(instr); break; case Opcode.rdhwr: RewriteReadHardwareRegister(instr); break; } yield return(new RtlInstructionCluster( instr.Address, 4, rtlInstructions.ToArray()) { Class = rtlc }); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { rtlc = RtlClass.Linear; var instrs = new List <RtlInstruction>(); m = new RtlEmitter(instrs); this.instr = dasm.Current; switch (instr.Opcode) { default: host.Error( instr.Address, string.Format( "Rewriting of TLCS-900 instruction '{0}' not implemented yet.", instr.Opcode)); EmitUnitTest(); Invalid(); break; case Opcode.invalid: Invalid(); break; case Opcode.adc: RewriteAdcSbc(m.IAdd, "****0*"); break; case Opcode.add: RewriteBinOp(m.IAdd, "***V0*"); break; case Opcode.and: RewriteBinOp(m.And, "**1*00"); break; case Opcode.bit: RewriteBit(); break; case Opcode.bs1b: RewriteBs1b(); break; case Opcode.call: RewriteCall(); break; case Opcode.calr: RewriteCall(); break; case Opcode.ccf: RewriteCcf(); break; case Opcode.chg: RewriteChg(); break; case Opcode.cp: RewriteCp("SZHV1C"); break; case Opcode.daa: RewriteDaa("****-*"); break; case Opcode.dec: RewriteIncDec(m.ISub, "****1-"); break; case Opcode.decf: RewriteDecf(); break; case Opcode.div: RewriteDiv(m.UDiv, "---V--"); break; case Opcode.divs: RewriteDiv(m.SDiv, "---V--"); break; case Opcode.djnz: RewriteDjnz(); break; case Opcode.ei: RewriteEi(); break; case Opcode.ex: RewriteEx(); break; case Opcode.halt: RewriteHalt(); break; case Opcode.inc: RewriteIncDec(m.IAdd, "****0-"); break; case Opcode.incf: RewriteIncf(); break; case Opcode.lda: RewriteLda(); break; case Opcode.jp: RewriteJp(); break; case Opcode.jr: RewriteJp(); break; case Opcode.ld: RewriteLd(); break; case Opcode.ldf: RewriteLdf(); break; case Opcode.ldir: RewriteLdir(PrimitiveType.Byte, "--000-"); break; case Opcode.ldirw: RewriteLdir(PrimitiveType.Word16, "--000-"); break; case Opcode.mul: RewriteMul(m.UMul); break; case Opcode.muls: RewriteMul(m.SMul); break; case Opcode.nop: m.Nop(); break; case Opcode.or: RewriteBinOp(m.Or, "**0*00"); break; case Opcode.pop: RewritePop(); break; case Opcode.push: RewritePush(); break; case Opcode.rcf: RewriteRcf(); break; case Opcode.res: RewriteRes(); break; case Opcode.ret: RewriteRet(); break; case Opcode.retd: RewriteRetd(); break; case Opcode.reti: RewriteReti(); break; case Opcode.sbc: RewriteAdcSbc(m.ISub, "****1*"); break; case Opcode.scc: RewriteScc(); break; case Opcode.scf: RewriteScf(); break; case Opcode.set: RewriteSet(); break; case Opcode.sla: RewriteShift(m.Shl, "**0*0*"); break; case Opcode.sll: RewriteShift(m.Shl, "**0*0*"); break; case Opcode.srl: RewriteShift(m.Shr, "**0*0*"); break; case Opcode.sub: RewriteBinOp(m.ISub, "***V1*"); break; case Opcode.swi: RewriteSwi(); break; case Opcode.xor: RewriteBinOp(m.Xor, "**0*00"); break; case Opcode.zcf: RewriteZcf(); break; } yield return(new RtlInstructionCluster(instr.Address, instr.Length, instrs.ToArray()) { Class = rtlc }); } }
public void Error(ulong uAddress, string error) { host.Error(m.CreateAddress(uAddress), error); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (instrs.MoveNext()) { if (!instrs.Current.TryGetInternal(out this.instr)) { throw new AddressCorrelatedException( instrs.Current.Address, "Invalid opcode cannot be rewritten to IR."); } this.ops = instr.ArchitectureDetail.Operands; this.ric = new RtlInstructionCluster(instrs.Current.Address, instr.Bytes.Length); this.ric.Class = RtlClass.Linear; this.emitter = new RtlEmitter(ric.Instructions); switch (instr.Id) { default: case Opcode.ADC: case Opcode.ADR: case Opcode.AESD: case Opcode.AESE: case Opcode.AESIMC: case Opcode.AESMC: case Opcode.BFC: case Opcode.BFI: case Opcode.BKPT: case Opcode.BXJ: case Opcode.CDP: case Opcode.CDP2: case Opcode.CLREX: case Opcode.CLZ: case Opcode.CPS: case Opcode.CRC32B: case Opcode.CRC32CB: case Opcode.CRC32CH: case Opcode.CRC32CW: case Opcode.CRC32H: case Opcode.CRC32W: case Opcode.DBG: case Opcode.DMB: case Opcode.DSB: case Opcode.VMOV: case Opcode.FLDMDBX: case Opcode.FLDMIAX: case Opcode.VMRS: case Opcode.FSTMDBX: case Opcode.FSTMIAX: case Opcode.HINT: case Opcode.HLT: case Opcode.ISB: case Opcode.LDA: case Opcode.LDAB: case Opcode.LDAEX: case Opcode.LDAEXB: case Opcode.LDAEXD: case Opcode.LDAEXH: case Opcode.LDAH: case Opcode.LDC2L: case Opcode.LDC2: case Opcode.LDCL: case Opcode.LDC: case Opcode.LDMDA: case Opcode.LDMIB: case Opcode.LDRBT: case Opcode.LDRD: case Opcode.LDREX: case Opcode.LDREXB: case Opcode.LDREXD: case Opcode.LDREXH: case Opcode.LDRHT: case Opcode.LDRSBT: case Opcode.LDRSHT: case Opcode.LDRT: case Opcode.MCR: case Opcode.MCR2: case Opcode.MCRR: case Opcode.MCRR2: case Opcode.MLA: case Opcode.MLS: case Opcode.MOVT: case Opcode.MOVW: case Opcode.MRC: case Opcode.MRC2: case Opcode.MRRC: case Opcode.MRRC2: case Opcode.MRS: case Opcode.MSR: case Opcode.MUL: case Opcode.PKHBT: case Opcode.PKHTB: case Opcode.PLDW: case Opcode.PLD: case Opcode.PLI: case Opcode.QADD: case Opcode.QADD16: case Opcode.QADD8: case Opcode.QASX: case Opcode.QDADD: case Opcode.QDSUB: case Opcode.QSAX: case Opcode.QSUB: case Opcode.QSUB16: case Opcode.QSUB8: case Opcode.RBIT: case Opcode.REV: case Opcode.REV16: case Opcode.REVSH: case Opcode.RFEDA: case Opcode.RFEDB: case Opcode.RFEIA: case Opcode.RFEIB: case Opcode.RSC: case Opcode.SADD16: case Opcode.SADD8: case Opcode.SASX: case Opcode.SBC: case Opcode.SBFX: case Opcode.SDIV: case Opcode.SEL: case Opcode.SETEND: case Opcode.SHA1C: case Opcode.SHA1H: case Opcode.SHA1M: case Opcode.SHA1P: case Opcode.SHA1SU0: case Opcode.SHA1SU1: case Opcode.SHA256H: case Opcode.SHA256H2: case Opcode.SHA256SU0: case Opcode.SHA256SU1: case Opcode.SHADD16: case Opcode.SHADD8: case Opcode.SHASX: case Opcode.SHSAX: case Opcode.SHSUB16: case Opcode.SHSUB8: case Opcode.SMC: case Opcode.SMLABB: case Opcode.SMLABT: case Opcode.SMLAD: case Opcode.SMLADX: case Opcode.SMLAL: case Opcode.SMLALBB: case Opcode.SMLALBT: case Opcode.SMLALD: case Opcode.SMLALDX: case Opcode.SMLALTB: case Opcode.SMLALTT: case Opcode.SMLATB: case Opcode.SMLATT: case Opcode.SMLAWB: case Opcode.SMLAWT: case Opcode.SMLSD: case Opcode.SMLSDX: case Opcode.SMLSLD: case Opcode.SMLSLDX: case Opcode.SMMLA: case Opcode.SMMLAR: case Opcode.SMMLS: case Opcode.SMMLSR: case Opcode.SMMUL: case Opcode.SMMULR: case Opcode.SMUAD: case Opcode.SMUADX: case Opcode.SMULBB: case Opcode.SMULBT: case Opcode.SMULL: case Opcode.SMULTB: case Opcode.SMULTT: case Opcode.SMULWB: case Opcode.SMULWT: case Opcode.SMUSD: case Opcode.SMUSDX: case Opcode.SRSDA: case Opcode.SRSDB: case Opcode.SRSIA: case Opcode.SRSIB: case Opcode.SSAT: case Opcode.SSAT16: case Opcode.SSAX: case Opcode.SSUB16: case Opcode.SSUB8: case Opcode.STC2L: case Opcode.STC2: case Opcode.STCL: case Opcode.STC: case Opcode.STL: case Opcode.STLB: case Opcode.STLEX: case Opcode.STLEXB: case Opcode.STLEXD: case Opcode.STLEXH: case Opcode.STLH: case Opcode.STMDA: case Opcode.STRBT: case Opcode.STRD: case Opcode.STREX: case Opcode.STREXB: case Opcode.STREXD: case Opcode.STREXH: case Opcode.STRHT: case Opcode.STRT: case Opcode.SWP: case Opcode.SWPB: case Opcode.SXTAB: case Opcode.SXTAB16: case Opcode.SXTAH: case Opcode.SXTB: case Opcode.SXTB16: case Opcode.SXTH: case Opcode.TRAP: case Opcode.UADD16: case Opcode.UADD8: case Opcode.UASX: case Opcode.UBFX: case Opcode.UDF: case Opcode.UDIV: case Opcode.UHADD16: case Opcode.UHADD8: case Opcode.UHASX: case Opcode.UHSAX: case Opcode.UHSUB16: case Opcode.UHSUB8: case Opcode.UMAAL: case Opcode.UMLAL: case Opcode.UMULL: case Opcode.UQADD16: case Opcode.UQADD8: case Opcode.UQASX: case Opcode.UQSAX: case Opcode.UQSUB16: case Opcode.UQSUB8: case Opcode.USAD8: case Opcode.USADA8: case Opcode.USAT: case Opcode.USAT16: case Opcode.USAX: case Opcode.USUB16: case Opcode.USUB8: case Opcode.UXTAB: case Opcode.UXTAB16: case Opcode.UXTAH: case Opcode.UXTB: case Opcode.UXTB16: case Opcode.UXTH: case Opcode.VABAL: case Opcode.VABA: case Opcode.VABDL: case Opcode.VABD: case Opcode.VABS: case Opcode.VACGE: case Opcode.VACGT: case Opcode.VADD: case Opcode.VADDHN: case Opcode.VADDL: case Opcode.VADDW: case Opcode.VAND: case Opcode.VBIC: case Opcode.VBIF: case Opcode.VBIT: case Opcode.VBSL: case Opcode.VCEQ: case Opcode.VCGE: case Opcode.VCGT: case Opcode.VCLE: case Opcode.VCLS: case Opcode.VCLT: case Opcode.VCLZ: case Opcode.VCMP: case Opcode.VCMPE: case Opcode.VCNT: case Opcode.VCVTA: case Opcode.VCVTB: case Opcode.VCVT: case Opcode.VCVTM: case Opcode.VCVTN: case Opcode.VCVTP: case Opcode.VCVTT: case Opcode.VDIV: case Opcode.VDUP: case Opcode.VEOR: case Opcode.VEXT: case Opcode.VFMA: case Opcode.VFMS: case Opcode.VFNMA: case Opcode.VFNMS: case Opcode.VHADD: case Opcode.VHSUB: case Opcode.VLD1: case Opcode.VLD2: case Opcode.VLD3: case Opcode.VLD4: case Opcode.VLDMDB: case Opcode.VLDMIA: case Opcode.VLDR: case Opcode.VMAXNM: case Opcode.VMAX: case Opcode.VMINNM: case Opcode.VMIN: case Opcode.VMLA: case Opcode.VMLAL: case Opcode.VMLS: case Opcode.VMLSL: case Opcode.VMOVL: case Opcode.VMOVN: case Opcode.VMSR: case Opcode.VMUL: case Opcode.VMULL: case Opcode.VMVN: case Opcode.VNEG: case Opcode.VNMLA: case Opcode.VNMLS: case Opcode.VNMUL: case Opcode.VORN: case Opcode.VORR: case Opcode.VPADAL: case Opcode.VPADDL: case Opcode.VPADD: case Opcode.VPMAX: case Opcode.VPMIN: case Opcode.VQABS: case Opcode.VQADD: case Opcode.VQDMLAL: case Opcode.VQDMLSL: case Opcode.VQDMULH: case Opcode.VQDMULL: case Opcode.VQMOVUN: case Opcode.VQMOVN: case Opcode.VQNEG: case Opcode.VQRDMULH: case Opcode.VQRSHL: case Opcode.VQRSHRN: case Opcode.VQRSHRUN: case Opcode.VQSHL: case Opcode.VQSHLU: case Opcode.VQSHRN: case Opcode.VQSHRUN: case Opcode.VQSUB: case Opcode.VRADDHN: case Opcode.VRECPE: case Opcode.VRECPS: case Opcode.VREV16: case Opcode.VREV32: case Opcode.VREV64: case Opcode.VRHADD: case Opcode.VRINTA: case Opcode.VRINTM: case Opcode.VRINTN: case Opcode.VRINTP: case Opcode.VRINTR: case Opcode.VRINTX: case Opcode.VRINTZ: case Opcode.VRSHL: case Opcode.VRSHRN: case Opcode.VRSHR: case Opcode.VRSQRTE: case Opcode.VRSQRTS: case Opcode.VRSRA: case Opcode.VRSUBHN: case Opcode.VSELEQ: case Opcode.VSELGE: case Opcode.VSELGT: case Opcode.VSELVS: case Opcode.VSHLL: case Opcode.VSHL: case Opcode.VSHRN: case Opcode.VSHR: case Opcode.VSLI: case Opcode.VSQRT: case Opcode.VSRA: case Opcode.VSRI: case Opcode.VST1: case Opcode.VST2: case Opcode.VST3: case Opcode.VST4: case Opcode.VSTMDB: case Opcode.VSTMIA: case Opcode.VSTR: case Opcode.VSUB: case Opcode.VSUBHN: case Opcode.VSUBL: case Opcode.VSUBW: case Opcode.VSWP: case Opcode.VTBL: case Opcode.VTBX: case Opcode.VCVTR: case Opcode.VTRN: case Opcode.VTST: case Opcode.VUZP: case Opcode.VZIP: case Opcode.ADDW: case Opcode.ASR: case Opcode.DCPS1: case Opcode.DCPS2: case Opcode.DCPS3: case Opcode.IT: case Opcode.LSL: case Opcode.LSR: case Opcode.ASRS: case Opcode.LSRS: case Opcode.ORN: case Opcode.ROR: case Opcode.RRX: case Opcode.SUBS: case Opcode.SUBW: case Opcode.TBB: case Opcode.TBH: case Opcode.CBNZ: case Opcode.CBZ: case Opcode.MOVS: case Opcode.POP: case Opcode.YIELD: case Opcode.WFE: case Opcode.WFI: case Opcode.SEV: case Opcode.SEVL: case Opcode.VPUSH: case Opcode.VPOP: host.Error( instrs.Current.Address, string.Format( "Rewriting ARM opcode '{0}' is not supported yet.", instr.Mnemonic)); emitter.Invalid(); break; case Opcode.AND: RewriteBinOp(emitter.And, instr.ArchitectureDetail.UpdateFlags); break; case Opcode.ADD: RewriteBinOp(emitter.IAdd, instr.ArchitectureDetail.UpdateFlags); break; case Opcode.EOR: RewriteBinOp(emitter.Xor, instr.ArchitectureDetail.UpdateFlags); break; case Opcode.B: RewriteB(false); break; case Opcode.BIC: RewriteBic(); break; case Opcode.BL: RewriteB(true); break; case Opcode.BLX: RewriteB(true); break; case Opcode.BX: RewriteB(false); break; case Opcode.CMN: RewriteCmn(); break; case Opcode.CMP: RewriteCmp(); break; case Opcode.LDR: RewriteLdr(PrimitiveType.Word32); break; case Opcode.LDRB: RewriteLdr(PrimitiveType.Byte); break; case Opcode.LDRH: RewriteLdr(PrimitiveType.UInt16); break; case Opcode.LDRSB: RewriteLdr(PrimitiveType.SByte); break; case Opcode.LDRSH: RewriteLdr(PrimitiveType.Int16); break; case Opcode.LDM: RewriteLdm(); break; case Opcode.LDMDB: RewriteLdm(); break; case Opcode.NOP: emitter.Nop(); break; case Opcode.MOV: RewriteMov(); break; case Opcode.MVN: RewriteUnaryOp(Operator.Not); break; case Opcode.ORR: RewriteBinOp(emitter.Or, false); break; case Opcode.PUSH: RewritePush(); break; case Opcode.RSB: RewriteRevBinOp(Operator.ISub, instr.ArchitectureDetail.UpdateFlags); break; case Opcode.STM: RewriteStm(); break; case Opcode.STMDB: RewriteStm(); break; case Opcode.STMIB: RewriteStmib(); break; case Opcode.STR: RewriteStr(PrimitiveType.Word32); break; case Opcode.STRB: RewriteStr(PrimitiveType.Byte); break; case Opcode.STRH: RewriteStr(PrimitiveType.UInt16); break; case Opcode.SUB: RewriteBinOp(emitter.ISub, instr.ArchitectureDetail.UpdateFlags); break; case Opcode.SVC: RewriteSvc(); break; case Opcode.TEQ: RewriteTeq(); break; case Opcode.TST: RewriteTst(); break; } yield return(ric); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { var instr = dasm.Current; var rtlInstructions = new List <RtlInstruction>(); this.iclass = instr.InstructionClass; this.m = new RtlEmitter(rtlInstructions); switch (instr.Mnemonic) { default: host.Error( instr.Address, string.Format("MIPS instruction '{0}' is not supported yet.", instr)); EmitUnitTest(); goto case Mnemonic.illegal; case Mnemonic.illegal: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.addi: RewriteBinary(instr, m.IAdd); break; case Mnemonic.addiu: RewriteBinary(instr, m.IAdd); break; case Mnemonic.addu: RewriteBinary(instr, m.IAdd); break; case Mnemonic.b: RewriteB(instr); break; case Mnemonic.beqz: RewriteBeqz(instr); break; case Mnemonic.bnez: RewriteBnez(instr); break; case Mnemonic.cmpi: RewriteCmp(instr); break; case Mnemonic.jal: RewriteJal(instr); break; case Mnemonic.jalx: RewriteJalx(instr); break; case Mnemonic.lb: RewriteLoad(instr, PrimitiveType.SByte); break; case Mnemonic.lbu: RewriteLoad(instr, PrimitiveType.Byte); break; case Mnemonic.lh: RewriteLoad(instr, PrimitiveType.Int16); break; case Mnemonic.lhu: RewriteLoad(instr, PrimitiveType.UInt16); break; case Mnemonic.la: RewriteMove(instr); break; case Mnemonic.li: RewriteMove(instr); break; case Mnemonic.lw: RewriteLoad(instr, PrimitiveType.Word32); break; case Mnemonic.mfhi: RewriteMf(instr, arch.hi); break; case Mnemonic.mflo: RewriteMf(instr, arch.lo); break; case Mnemonic.move: RewriteMove(instr); break; case Mnemonic.neg: RewriteUnary(instr, m.Neg); break; case Mnemonic.save: RewriteSave(instr); break; case Mnemonic.sb: RewriteStore(instr); break; case Mnemonic.sh: RewriteStore(instr); break; case Mnemonic.sll: RewriteBinary(instr, m.Shl); break; case Mnemonic.sllv: RewriteBinary(instr, m.Shl); break; case Mnemonic.slt: RewriteScc(instr, m.Lt); break; case Mnemonic.slti: RewriteScc(instr, m.Lt); break; case Mnemonic.sltiu: RewriteScc(instr, m.Ult); break; case Mnemonic.sra: RewriteBinary(instr, m.Sar); break; case Mnemonic.srav: RewriteBinary(instr, m.Sar); break; case Mnemonic.srl: RewriteBinary(instr, m.Shr); break; case Mnemonic.srlv: RewriteBinary(instr, m.Shr); break; case Mnemonic.subu: RewriteBinary(instr, m.ISub); break; case Mnemonic.sw: RewriteStore(instr); break; case Mnemonic.xor: RewriteBinary(instr, m.Xor); break; } yield return(new RtlInstructionCluster(instr.Address, instr.Length, rtlInstructions.ToArray()) { Class = iclass, }); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var rtls = new List <RtlInstruction>(); m = new RtlEmitter(rtls); this.iclass = instr.InstructionClass; switch (instr.Mnemonic) { default: host.Error(instr.Address, $"WE32100 instruction '{instr}' is not supported yet."); EmitUnitTest(); goto case Mnemonic.invalid; case Mnemonic.invalid: m.Invalid(); iclass = InstrClass.Invalid; break; case Mnemonic.addb2: RewriteArithmetic2(m.IAdd, PrimitiveType.Byte); break; case Mnemonic.addh2: RewriteArithmetic2(m.IAdd, PrimitiveType.Word16); break; case Mnemonic.addw2: RewriteArithmetic2(m.IAdd, PrimitiveType.Word32); break; case Mnemonic.addb3: RewriteArithmetic3(m.IAdd, PrimitiveType.Byte); break; case Mnemonic.addh3: RewriteArithmetic3(m.IAdd, PrimitiveType.Word16); break; case Mnemonic.addw3: RewriteArithmetic3(m.IAdd, PrimitiveType.Word32); break; case Mnemonic.andb2: RewriteLogical2(m.And, PrimitiveType.Byte); break; case Mnemonic.andh2: RewriteLogical2(m.And, PrimitiveType.Word16); break; case Mnemonic.andw2: RewriteLogical2(m.And, PrimitiveType.Word32); break; case Mnemonic.andb3: RewriteLogical3(m.And, PrimitiveType.Byte); break; case Mnemonic.andh3: RewriteLogical3(m.And, PrimitiveType.Word16); break; case Mnemonic.andw3: RewriteLogical3(m.And, PrimitiveType.Word32); break; case Mnemonic.dech: RewriteUnary(e => m.ISub(e, 1), PrimitiveType.Word16, NZVC); break; case Mnemonic.movb: RewriteMov(PrimitiveType.Byte); break; case Mnemonic.subb2: RewriteArithmetic2(m.ISub, PrimitiveType.Byte); break; case Mnemonic.subh2: RewriteArithmetic2(m.ISub, PrimitiveType.Word16); break; case Mnemonic.subw2: RewriteArithmetic2(m.ISub, PrimitiveType.Word32); break; case Mnemonic.xorb2: RewriteLogical2(m.Xor, PrimitiveType.Byte); break; case Mnemonic.xorh2: RewriteLogical2(m.Xor, PrimitiveType.Word16); break; case Mnemonic.xorw2: RewriteLogical2(m.Xor, PrimitiveType.Word32); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); } }