private void RewriteBrset() { var mem = RewriteOp(instr.Operands[0]); var mask = RewriteOp(instr.Operands[1]); var dst = ((AddressOperand)instr.Operands[2]).Address; m.Branch(m.Eq0(m.And(m.Comp(mem), mask)), dst, rtlc); }
private void RewriteBclr() { var(bit, reg) = BitOp(0); EmitCc(Registers.N, host.Intrinsic("__bit", false, PrimitiveType.Bool, reg, bit)); EmitCc(Registers.Z, m.Comp(binder.EnsureFlagGroup(Registers.N))); m.Assign(reg, host.Intrinsic("__bit_clear", false, reg.DataType, reg, bit)); EmitCc(Registers.E, Constant.False()); EmitCc(Registers.V, Constant.False()); EmitCc(Registers.C, Constant.False()); }
private void RewriteCom() { var src = RewriteOp(0); var dst = RewriteOpDst(0, m.Comp(src)); EmitCc(Z, dst); }
private void RewriteAndNot() { var src1 = Operand(instr.Operands[1]); var dst = Operand(instr.Operands[0]); m.Assign(dst, m.And(dst, m.Comp(src1))); }
private void RewriteInv() { var op = Operand(instr.Operands[0]); m.Assign(op, m.Comp(op)); NZ0(op); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.iclass = this.instr.InstructionClass; var instrs = new List <RtlInstruction>(); this.m = new RtlEmitter(instrs); switch (this.instr.Mnemonic) { default: EmitUnitTest(); host.Warn( dasm.Current.Address, "AVR32 instruction '{0}' is not supported yet.", instr.Mnemonic); goto case Mnemonic.invalid; case Mnemonic.invalid: m.Invalid(); break; case Mnemonic.abs: RewriteAbs(); break; case Mnemonic.acall: RewriteAcall(); break; case Mnemonic.acr: RewriteAcr(); break; case Mnemonic.adc: RewriteAdc(); break; case Mnemonic.add: RewriteAdd(); break; case Mnemonic.andh: RewriteAndh(); break; case Mnemonic.andl: RewriteAndl(); break; case Mnemonic.and: RewriteLogical(m.And); break; case Mnemonic.andnot: RewriteLogical((a, b) => m.And(a, m.Comp(b))); break; case Mnemonic.asr: RewriteShift(m.Sar); break; case Mnemonic.bfexts: RewriteBfexts(); break; case Mnemonic.bfextu: RewriteBfextu(); break; case Mnemonic.bld: RewriteBld(); break; case Mnemonic.br: RewriteBranch(); break; case Mnemonic.bst: RewriteBst(); break; case Mnemonic.casts_b: RewriteCast(PrimitiveType.SByte, PrimitiveType.Int32); break; case Mnemonic.casts_h: RewriteCast(PrimitiveType.Int16, PrimitiveType.Int32); break; case Mnemonic.castu_b: RewriteCast(PrimitiveType.Byte, PrimitiveType.Word32); break; case Mnemonic.castu_h: RewriteCast(PrimitiveType.Word16, PrimitiveType.Word32); break; case Mnemonic.cbr: RewriteCbr(); break; case Mnemonic.com: RewriteCom(); break; case Mnemonic.clz: RewriteClz(); break; case Mnemonic.cp_b: RewriteCp_b(); break; case Mnemonic.cp_w: RewriteCp_w(); break; case Mnemonic.cpc: RewriteCpc(); break; case Mnemonic.divs: RewriteDiv(m.SDiv); break; case Mnemonic.divu: RewriteDiv(m.UDiv); break; case Mnemonic.eor: RewriteLogical(m.Xor); break; case Mnemonic.eorh: RewriteOrh(m.Xor); break; case Mnemonic.eorl: RewriteOrh(m.Xor); break; case Mnemonic.icall: RewriteCall(); break; case Mnemonic.ld_d: RewriteLd(PrimitiveType.Word64, PrimitiveType.Word64); break; case Mnemonic.ld_sb: RewriteLd(PrimitiveType.SByte, PrimitiveType.Int32); break; case Mnemonic.ld_sh: RewriteLd(PrimitiveType.Int16, PrimitiveType.Int32); break; case Mnemonic.ld_ub: RewriteLd(PrimitiveType.Byte, PrimitiveType.Word32); break; case Mnemonic.ld_uh: RewriteLd(PrimitiveType.Word16, PrimitiveType.Word32); break; case Mnemonic.ld_w: RewriteLd(PrimitiveType.Word32, PrimitiveType.Word32); break; case Mnemonic.lddpc: RewriteLddpc(); break; case Mnemonic.lddsp: RewriteLddsp(); break; case Mnemonic.ldm: RewriteLdm(); break; case Mnemonic.lsl: RewriteShift(m.Shl); break; case Mnemonic.lsr: RewriteShift(m.Shr); break; case Mnemonic.macs_d: RewriteMac_d(m.SMul); break; case Mnemonic.macu_d: RewriteMac_d(m.UMul); break; case Mnemonic.max: RewriteMax(); break; case Mnemonic.mcall: RewriteCall(); break; case Mnemonic.min: RewriteMin(); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.movh: RewriteMovh(); break; case Mnemonic.mul: RewriteMul(); break; case Mnemonic.muls_d: RewriteMul_d(m.SMul); break; case Mnemonic.mulu_d: RewriteMul_d(m.UMul); break; case Mnemonic.mustr: RewriteMustr(); break; case Mnemonic.neg: RewriteNeg(); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.or: RewriteLogical(m.Or); break; case Mnemonic.orh: RewriteOrh(m.Or); break; case Mnemonic.orl: RewriteOrl(m.Or); break; case Mnemonic.popm: RewritePopm(); break; case Mnemonic.pushm: RewritePushm(); break; case Mnemonic.ret: RewriteRet(); break; case Mnemonic.rcall: RewriteCall(); break; case Mnemonic.rjmp: RewriteGoto(); break; case Mnemonic.rol: RewriteRol(); break; case Mnemonic.ror: RewriteRor(); break; case Mnemonic.rsub: RewriteRsub(); break; case Mnemonic.sats: RewriteSat("__sats", PrimitiveType.Int32); break; case Mnemonic.satu: RewriteSat("__satu", PrimitiveType.UInt32); break; case Mnemonic.satsub_w: RewriteSatsubW(); break; case Mnemonic.sbc: RewriteSbc(); break; case Mnemonic.sbr: RewriteSbr(); break; case Mnemonic.scr: RewriteScr(); break; case Mnemonic.sr: RewriteSr(); break; case Mnemonic.stm: RewriteStm(); break; case Mnemonic.st_b: RewriteSt(PrimitiveType.Byte); break; case Mnemonic.st_h: RewriteSt(PrimitiveType.Word16); break; case Mnemonic.st_w: RewriteSt(PrimitiveType.Word32); break; case Mnemonic.st_d: RewriteSt(PrimitiveType.Word64); break; case Mnemonic.stcond: RewriteStcond(); break; case Mnemonic.stdsp: RewriteStdsp(); break; case Mnemonic.sub: RewriteSub(); break; case Mnemonic.subf: RewriteSub(); break; case Mnemonic.tst: RewriteTst(); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); } }
private void RewriteCpl() { var a = frame.EnsureRegister(Registers.a); emitter.Assign(a, emitter.Comp(a)); }
private Expression Bis(Expression a, Expression b) { return(m.And(a, m.Comp(b))); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { di = dasm.Current; ric = new RtlInstructionCluster(di.Address, di.Length); emitter = new RtlEmitter(ric.Instructions); orw = new OperandRewriter(arch, this.emitter, this.frame, di.dataWidth); switch (di.code) { case Opcode.add: RewriteBinOp((s, d) => emitter.IAdd(d, s), FlagM.CVZNX); break; case Opcode.adda: RewriteBinOp((s, d) => emitter.IAdd(d, s)); break; case Opcode.addi: RewriteArithmetic((s, d) => emitter.IAdd(d, s)); break; case Opcode.addq: RewriteAddSubq((s, d) => emitter.IAdd(d, s)); break; case Opcode.addx: RewriteAddSubx(Operator.IAdd); break; case Opcode.and: RewriteLogical((s, d) => emitter.And(d, s)); break; case Opcode.andi: RewriteLogical((s, d) => emitter.And(d, s)); break; case Opcode.asl: RewriteArithmetic((s, d) => emitter.Shl(d, s)); break; case Opcode.asr: RewriteShift((s, d) => emitter.Sar(d, s)); break; /* * * Mnemonic Condition Encoding Test * T* True 0000 1 * F* False 0001 0 * HI High 0010 C L Z * LS Low or Same 0011 C V Z * VC Overflow Clear 1000 V * VS Overflow Set 1001 V */ case Opcode.bclr: RewriteBclrBset("__bclr"); break; case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break; case Opcode.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break; case Opcode.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.blt: RewriteBcc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.bls: RewriteBcc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break; case Opcode.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break; case Opcode.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break; case Opcode.bchg: RewriteBchg(); break; case Opcode.bra: RewriteBra(); break; case Opcode.bset: RewriteBclrBset("__bset"); break; case Opcode.bsr: RewriteBsr(); break; case Opcode.btst: RewriteBtst(); break; case Opcode.clr: RewriteClr(); break; case Opcode.cmp: RewriteCmp(); break; case Opcode.cmpa: RewriteCmp(); break; case Opcode.cmpi: RewriteCmp(); break; case Opcode.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.dbhi: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break; case Opcode.dbra: RewriteDbcc(ConditionCode.None, 0); break; case Opcode.divu: RewriteDiv(Operator.UDiv); break; case Opcode.eor: RewriteLogical((s, d) => emitter.Xor(d, s)); break; case Opcode.eori: RewriteLogical((s, d) => emitter.Xor(d, s)); break; case Opcode.exg: RewriteExg(); break; case Opcode.ext: RewriteExt(); break; case Opcode.extb: RewriteExtb(); break; case Opcode.illegal: if (!RewriteIllegal()) { goto default; } break; case Opcode.jmp: RewriteJmp(); break; case Opcode.jsr: RewriteJsr(); break; case Opcode.lea: RewriteLea(); break; case Opcode.link: RewriteLink(); break; case Opcode.lsl: RewriteShift((s, d) => emitter.Shl(d, s)); break; case Opcode.lsr: RewriteShift((s, d) => emitter.Shr(d, s)); break; case Opcode.move: RewriteMove(true); break; case Opcode.movea: RewriteMove(false); break; case Opcode.moveq: RewriteMoveq(); break; case Opcode.movem: RewriteMovem(); break; case Opcode.muls: RewriteMul((s, d) => emitter.SMul(d, s)); break; case Opcode.mulu: RewriteMul((s, d) => emitter.UMul(d, s)); break; case Opcode.neg: RewriteUnary(s => emitter.Neg(s), AllConditions); break; case Opcode.negx: RewriteUnary(RewriteNegx, AllConditions); break; case Opcode.nop: continue; case Opcode.not: RewriteUnary(s => emitter.Comp(s), LogicalConditions); break; case Opcode.or: RewriteLogical((s, d) => emitter.Or(d, s)); break; case Opcode.ori: RewriteLogical((s, d) => emitter.Or(d, s)); break; case Opcode.pea: RewritePea(); break; case Opcode.rol: RewriteRotation(PseudoProcedure.Rol); break; case Opcode.ror: RewriteRotation(PseudoProcedure.Ror); break; case Opcode.roxl: RewriteRotationX(PseudoProcedure.RolC); break; case Opcode.roxr: RewriteRotationX(PseudoProcedure.RorC); break; case Opcode.rts: emitter.Return(4, 0); break; case Opcode.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break; case Opcode.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break; case Opcode.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.slt: RewriteScc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.sls: RewriteScc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break; case Opcode.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break; case Opcode.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break; case Opcode.st: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.True()); break; case Opcode.sf: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.False()); break; case Opcode.sub: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break; case Opcode.suba: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break; case Opcode.subi: RewriteArithmetic((s, d) => emitter.ISub(d, s)); break; case Opcode.subq: RewriteAddSubq((s, d) => emitter.ISub(d, s)); break; case Opcode.subx: RewriteArithmetic((s, d) => emitter.ISub(emitter.ISub(d, s), frame.EnsureFlagGroup((uint)FlagM.XF, "X", PrimitiveType.Bool))); break; case Opcode.swap: RewriteSwap(); break; case Opcode.tst: RewriteTst(); break; case Opcode.unlk: RewriteUnlk(); break; default: throw new AddressCorrelatedException( di.Address, "Rewriting M68k opcode '{0}' is not supported yet.", di.code); } yield return(ric); } yield break; }
private Expression XNor(Expression left, Expression right) { return(m.Comp(m.Xor(left, right))); }
private void RewriteCpl() { var a = binder.EnsureRegister(Registers.a); m.Assign(a, m.Comp(a)); }
private Expression Nor(Expression a, Expression b) { return(m.Comp(m.Or(a, b))); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { di = dasm.Current; var addr = di.Address; var len = di.Length; rtlInstructions = new List <RtlInstruction>(); rtlc = RtlClass.Linear; m = new RtlEmitter(rtlInstructions); orw = new OperandRewriter(arch, this.m, this.binder, di.dataWidth); switch (di.code) { default: host.Warn( di.Address, "Rewriting M68k opcode '{0}' is not supported yet.", di.code); m.Invalid(); break; case Opcode.illegal: RewriteIllegal(); break; case Opcode.add: RewriteBinOp((s, d) => m.IAdd(d, s), FlagM.CVZNX); break; case Opcode.adda: RewriteBinOp((s, d) => m.IAdd(d, s)); break; case Opcode.addi: RewriteArithmetic((s, d) => m.IAdd(d, s)); break; case Opcode.addq: RewriteAddSubq((s, d) => m.IAdd(d, s)); break; case Opcode.addx: RewriteAddSubx(m.IAdd); break; case Opcode.and: RewriteLogical((s, d) => m.And(d, s)); break; case Opcode.andi: RewriteLogical((s, d) => m.And(d, s)); break; case Opcode.asl: RewriteArithmetic((s, d) => m.Shl(d, s)); break; case Opcode.asr: RewriteShift((s, d) => m.Sar(d, s)); break; /* * * Mnemonic Condition Encoding Test * T* True 0000 1 * F* False 0001 0 * HI High 0010 C L Z * LS Low or Same 0011 C V Z * VC Overflow Clear 1000 V * VS Overflow Set 1001 V */ case Opcode.bclr: RewriteBclrBset("__bclr"); break; case Opcode.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break; case Opcode.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break; case Opcode.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.blt: RewriteBcc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.bls: RewriteBcc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break; case Opcode.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break; case Opcode.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break; case Opcode.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break; case Opcode.bchg: RewriteBchg(); break; case Opcode.bra: RewriteBra(); break; case Opcode.bset: RewriteBclrBset("__bset"); break; case Opcode.bsr: RewriteBsr(); break; case Opcode.btst: RewriteBtst(); break; case Opcode.cas: RewriteCas(); break; case Opcode.clr: RewriteClr(); break; case Opcode.chk: RewriteChk(); break; case Opcode.chk2: RewriteChk2(); break; case Opcode.cmp: RewriteCmp(); break; case Opcode.cmp2: RewriteCmp2(); break; case Opcode.cmpa: RewriteCmp(); break; case Opcode.cmpi: RewriteCmp(); break; case Opcode.cmpm: RewriteCmp(); break; case Opcode.dbeq: RewriteDbcc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.dbhi: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break; case Opcode.dbne: RewriteDbcc(ConditionCode.NE, FlagM.ZF); break; case Opcode.dbra: RewriteDbcc(ConditionCode.None, 0); break; case Opcode.divs: RewriteDiv(m.SDiv, PrimitiveType.Int16); break; case Opcode.divsl: RewriteDiv(m.SDiv, PrimitiveType.Int32); break; case Opcode.divu: RewriteDiv(m.UDiv, PrimitiveType.UInt16); break; case Opcode.eor: RewriteLogical((s, d) => m.Xor(d, s)); break; case Opcode.eori: RewriteLogical((s, d) => m.Xor(d, s)); break; case Opcode.exg: RewriteExg(); break; case Opcode.ext: RewriteExt(); break; case Opcode.extb: RewriteExtb(); break; case Opcode.fadd: RewriteFBinOp((s, d) => m.FAdd(d, s)); break; //$REVIEW: the following don't respect NaN, but NaN typically doesn't exist in HLLs. case Opcode.fbf: m.Nop(); break; case Opcode.fbnge: RewriteFbcc(ConditionCode.LT); break; case Opcode.fbnlt: RewriteFbcc(ConditionCode.GE); break; case Opcode.fbnle: RewriteFbcc(ConditionCode.GT); break; case Opcode.fbogl: RewriteFbcc(ConditionCode.NE); break; case Opcode.fbult: RewriteFbcc(ConditionCode.LT); break; case Opcode.fbun: RewriteFbcc(ConditionCode.IS_NAN); break; case Opcode.fcmp: RewriteFcmp(); break; case Opcode.fdiv: RewriteFBinOp((s, d) => m.FDiv(d, s)); break; case Opcode.fmove: RewriteFmove(); break; case Opcode.fmovecr: RewriteFmovecr(); break; case Opcode.fmovem: RewriteMovem(i => arch.GetRegister(i + Registers.fp0.Number)); break; case Opcode.fmul: RewriteFBinOp((s, d) => m.FMul(d, s)); break; case Opcode.fneg: RewriteFUnaryOp(m.Neg); break; case Opcode.fsub: RewriteFBinOp((s, d) => m.FSub(d, s)); break; case Opcode.jmp: RewriteJmp(); break; case Opcode.jsr: RewriteJsr(); break; case Opcode.lea: RewriteLea(); break; case Opcode.link: RewriteLink(); break; case Opcode.lsl: RewriteShift((s, d) => m.Shl(d, s)); break; case Opcode.lsr: RewriteShift((s, d) => m.Shr(d, s)); break; case Opcode.move: RewriteMove(true); break; case Opcode.movea: RewriteMove(false); break; case Opcode.movep: RewriteMovep(); break; case Opcode.moveq: RewriteMoveq(); break; case Opcode.movem: RewriteMovem(arch.GetRegister); break; case Opcode.muls: RewriteMul((s, d) => m.SMul(d, s)); break; case Opcode.mulu: RewriteMul((s, d) => m.UMul(d, s)); break; case Opcode.neg: RewriteUnary(s => m.Neg(s), AllConditions); break; case Opcode.negx: RewriteUnary(RewriteNegx, AllConditions); break; case Opcode.nop: m.Nop(); break; case Opcode.not: RewriteUnary(s => m.Comp(s), LogicalConditions); break; case Opcode.or: RewriteLogical((s, d) => m.Or(d, s)); break; case Opcode.ori: RewriteLogical((s, d) => m.Or(d, s)); break; case Opcode.pea: RewritePea(); break; case Opcode.rol: RewriteRotation(PseudoProcedure.Rol); break; case Opcode.ror: RewriteRotation(PseudoProcedure.Ror); break; case Opcode.roxl: RewriteRotationX(PseudoProcedure.RolC); break; case Opcode.roxr: RewriteRotationX(PseudoProcedure.RorC); break; case Opcode.rts: RewriteRts(); break; case Opcode.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break; case Opcode.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break; case Opcode.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break; case Opcode.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Opcode.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Opcode.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Opcode.slt: RewriteScc(ConditionCode.LT, FlagM.CF | FlagM.ZF); break; case Opcode.sls: RewriteScc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Opcode.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break; case Opcode.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break; case Opcode.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break; case Opcode.st: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.True()); break; case Opcode.sf: orw.RewriteMoveDst(di.op1, di.Address, PrimitiveType.Bool, Constant.False()); break; case Opcode.stop: RewriteStop(); break; case Opcode.sub: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Opcode.suba: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Opcode.subi: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Opcode.subq: RewriteAddSubq((s, d) => m.ISub(d, s)); break; case Opcode.subx: RewriteArithmetic((s, d) => m.ISub(m.ISub(d, s), binder.EnsureFlagGroup(Registers.ccr, (uint)FlagM.XF, "X", PrimitiveType.Bool))); break; case Opcode.swap: RewriteSwap(); break; case Opcode.trap: RewriteTrap(); break; case Opcode.tst: RewriteTst(); break; case Opcode.unlk: RewriteUnlk(); break; } yield return(new RtlInstructionCluster( addr, len, rtlInstructions.ToArray()) { Class = rtlc }); } yield break; }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; iclass = instr.InstructionClass; try { switch (instr.Mnemonic) { default: EmitUnitTest(); host.Warn( instr.Address, "AArch64 instruction {0} is not supported yet.", instr); goto case Mnemonic.Invalid; case Mnemonic.Invalid: iclass = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.abs: RewriteSimdUnary("__abs_{0}", Domain.SignedInt); break; case Mnemonic.adc: RewriteAdcSbc(m.IAdd); break; case Mnemonic.adcs: RewriteAdcSbc(m.IAdd, this.NZCV); break; case Mnemonic.add: RewriteMaybeSimdBinary(m.IAdd, "__add_{0}"); break; case Mnemonic.addhn: RewriteSimdBinary("__addhn_{0}", Domain.None); break; case Mnemonic.addhn2: RewriteSimdBinary("__addhn2_{0}", Domain.None); break; case Mnemonic.addp: RewriteSimdBinary("__addp_{0}", Domain.None); break; case Mnemonic.adds: RewriteBinary(m.IAdd, this.NZCV); break; case Mnemonic.addv: RewriteAddv(); break; case Mnemonic.adr: RewriteUnary(n => n); break; case Mnemonic.asrv: RewriteBinary(m.Sar); break; case Mnemonic.adrp: RewriteAdrp(); break; case Mnemonic.and: RewriteBinary(m.And); break; case Mnemonic.ands: RewriteBinary(m.And, this.NZ00); break; case Mnemonic.asr: RewriteBinary(m.Sar); break; case Mnemonic.b: RewriteB(); break; case Mnemonic.bfm: RewriteBfm(); break; case Mnemonic.bic: RewriteLogical((a, b) => m.And(a, m.Comp(b))); break; case Mnemonic.bics: RewriteBinary((a, b) => m.And(a, m.Comp(b)), NZ00); break; case Mnemonic.bif: RewriteSimdBinary("__bif_{0}", Domain.None); break; case Mnemonic.bit: RewriteSimdBinary("__bit_{0}", Domain.None); break; case Mnemonic.bl: RewriteBl(); break; case Mnemonic.blr: RewriteBlr(); break; case Mnemonic.br: RewriteBr(); break; case Mnemonic.brk: RewriteBrk(); break; case Mnemonic.bsl: RewriteBsl(); break; case Mnemonic.cbnz: RewriteCb(m.Ne0); break; case Mnemonic.cbz: RewriteCb(m.Eq0); break; case Mnemonic.ccmn: RewriteCcmn(); break; case Mnemonic.ccmp: RewriteCcmp(); break; case Mnemonic.cls: RewriteSimdUnary("__cls_{0}", Domain.None); break; case Mnemonic.clz: RewriteClz(); break; case Mnemonic.cmp: RewriteCmp(); break; case Mnemonic.cmeq: RewriteCm("__cmeq_{0}", Domain.None); break; case Mnemonic.cmge: RewriteCm("__cmge_{0}", Domain.SignedInt); break; case Mnemonic.cmgt: RewriteCm("__cmgt_{0}", Domain.SignedInt); break; case Mnemonic.cmhi: RewriteCm("__cmhi_{0}", Domain.UnsignedInt); break; case Mnemonic.cmhs: RewriteCm("__cmhs_{0}", Domain.UnsignedInt); break; case Mnemonic.cmle: RewriteCm("__cmle_{0}", Domain.SignedInt); break; case Mnemonic.cmlt: RewriteCm("__cmlt_{0}", Domain.SignedInt); break; case Mnemonic.cmtst: RewriteCm("__cmtst_{0}", Domain.None); break; case Mnemonic.cnt: RewriteSimdUnary("__cnt_{0}", Domain.None); break; case Mnemonic.csel: RewriteCsel(); break; case Mnemonic.csinc: RewriteCsinc(); break; case Mnemonic.csinv: RewriteCsinv(); break; case Mnemonic.csneg: RewriteCsneg(); break; case Mnemonic.dmb: RewriteDmb(); break; case Mnemonic.dsb: RewriteDsb(); break; case Mnemonic.dup: RewriteDup(); break; case Mnemonic.eor: RewriteBinary(m.Xor); break; case Mnemonic.eon: RewriteBinary((a, b) => m.Xor(a, m.Comp(b))); break; case Mnemonic.eret: RewriteEret(); break; case Mnemonic.ext: RewriteExt(); break; case Mnemonic.extr: RewriteExtr(); break; case Mnemonic.fabs: RewriteFabs(); break; case Mnemonic.fadd: RewriteFadd(); break; case Mnemonic.fcmp: RewriteFcmp(); break; case Mnemonic.fcmpe: RewriteFcmp(); break; //$REVIEW: this leaves out the 'e'xception part. case Mnemonic.fcsel: RewriteFcsel(); break; case Mnemonic.fcvt: RewriteFcvt(); break; case Mnemonic.fcvtms: RewriteFcvtms(); break; case Mnemonic.fcvtps: RewriteFcvtps(); break; case Mnemonic.fcvtzs: RewriteFcvtzs(); break; case Mnemonic.fdiv: RewriteMaybeSimdBinary(m.FDiv, "__fdiv_{0}", Domain.Real); break; case Mnemonic.fmadd: RewriteIntrinsicFTernary("__fmaddf", "__fmadd"); break; case Mnemonic.fmsub: RewriteIntrinsicFTernary("__fmsubf", "__fmsub"); break; case Mnemonic.fmax: RewriteIntrinsicFBinary("fmaxf", "fmax"); break; case Mnemonic.fmin: RewriteIntrinsicFBinary("fminf", "fmin"); break; case Mnemonic.fmov: RewriteFmov(); break; case Mnemonic.fmul: RewriteFmul(); break; case Mnemonic.fneg: RewriteUnary(m.FNeg); break; case Mnemonic.fnmul: RewriteFnmul(); break; case Mnemonic.fsqrt: RewriteFsqrt(); break; case Mnemonic.fsub: RewriteMaybeSimdBinary(m.FSub, "__fsub_{0}", Domain.Real); break; case Mnemonic.hlt: RewriteHlt(); break; case Mnemonic.isb: RewriteIsb(); break; case Mnemonic.ld1: RewriteLdN("__ld1"); break; case Mnemonic.ld1r: RewriteLdNr("__ld1r"); break; case Mnemonic.ld2: RewriteLdN("__ld2"); break; case Mnemonic.ld3: RewriteLdN("__ld3"); break; case Mnemonic.ld4: RewriteLdN("__ld4"); break; case Mnemonic.ldnp: RewriteLoadStorePair(true); break; case Mnemonic.ldp: RewriteLoadStorePair(true); break; case Mnemonic.ldarh: RewriteLoadAcquire("__load_acquire_{0}", PrimitiveType.Word16); break; case Mnemonic.ldaxrh: RewriteLoadAcquire("__load_acquire_exclusive_{0}", PrimitiveType.Word16); break; case Mnemonic.ldpsw: RewriteLoadStorePair(true, PrimitiveType.Int32, PrimitiveType.Int64); break; case Mnemonic.ldr: RewriteLdr(null); break; case Mnemonic.ldrb: RewriteLdr(PrimitiveType.Byte); break; case Mnemonic.ldrh: RewriteLdr(PrimitiveType.Word16); break; case Mnemonic.ldrsb: RewriteLdr(PrimitiveType.SByte); break; case Mnemonic.ldrsh: RewriteLdr(PrimitiveType.Int16); break; case Mnemonic.ldrsw: RewriteLdr(PrimitiveType.Int32, PrimitiveType.Int64); break; case Mnemonic.ldxr: RewriteLdx(instr.Operands[0].Width); break; case Mnemonic.lslv: RewriteBinary(m.Shl); break; case Mnemonic.lsrv: RewriteBinary(m.Shr); break; case Mnemonic.ldur: RewriteLdr(null); break; case Mnemonic.ldurb: RewriteLdr(PrimitiveType.Byte); break; case Mnemonic.ldurh: RewriteLdr(PrimitiveType.Word16); break; case Mnemonic.ldursb: RewriteLdr(PrimitiveType.SByte); break; case Mnemonic.ldursh: RewriteLdr(PrimitiveType.Int16); break; case Mnemonic.ldursw: RewriteLdr(PrimitiveType.Int32); break; case Mnemonic.lsl: RewriteBinary(m.Shl); break; case Mnemonic.lsr: RewriteBinary(m.Shr); break; case Mnemonic.madd: RewriteMaddSub(m.IAdd); break; case Mnemonic.mla: RewriteSimdTrinary(Domain.None); break; case Mnemonic.mls: RewriteSimdTrinary(Domain.None); break; case Mnemonic.mneg: RewriteBinary((a, b) => m.Neg(m.IMul(a, b))); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.movi: RewriteMovi(); break; case Mnemonic.movk: RewriteMovk(); break; case Mnemonic.movn: RewriteMovn(); break; case Mnemonic.movz: RewriteMovz(); break; case Mnemonic.mrs: RewriteMrs(); break; case Mnemonic.msr: RewriteMsr(); break; case Mnemonic.msub: RewriteMaddSub(m.ISub); break; case Mnemonic.mul: RewriteMaybeSimdBinary(m.IMul, "__mul_{0}"); break; case Mnemonic.mvn: RewriteUnary(m.Comp); break; case Mnemonic.mvni: RewriteLogical((a, b) => ((BigConstant)b).Complement()); break; case Mnemonic.neg: RewriteSimdUnary("__neg_{0}", Domain.SignedInt); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.not: RewriteMaybeSimdUnary(m.Comp, "__not_{0}"); break; case Mnemonic.orr: RewriteLogical(m.Or); break; case Mnemonic.orn: RewriteBinary((a, b) => m.Or(a, m.Comp(b))); break; case Mnemonic.pmul: RewriteSimdBinary("__pmul_{0}", Domain.None); break; case Mnemonic.pmull: RewriteSimdBinary("__pmull_{0}", Domain.None); break; case Mnemonic.pmull2: RewriteSimdBinary("__pmull2_{0}", Domain.None); break; case Mnemonic.prfm: RewritePrfm(); break; case Mnemonic.raddhn: RewriteSimdBinary("__raddhn_{0}", Domain.None); break; case Mnemonic.raddhn2: RewriteSimdBinary("__raddhn2_{0}", Domain.None); break; case Mnemonic.rbit: RewriteRbit(); break; case Mnemonic.ret: RewriteRet(); break; case Mnemonic.rev: RewriteRev(); break; case Mnemonic.rev16: RewriteRev16(); break; case Mnemonic.rev32: RewriteRev32(); break; case Mnemonic.rev64: RewriteSimdUnary("__rev64_{0}", Domain.None); break; case Mnemonic.ror: RewriteRor(); break; case Mnemonic.rorv: RewriteRor(); break; case Mnemonic.rshrn: RewriteSimdBinary("__rshrn_{0}", Domain.None); break; case Mnemonic.rshrn2: RewriteSimdBinary("__rshrn2_{0}", Domain.None); break; case Mnemonic.rsubhn: RewriteSimdBinary("__rsubhn_{0}", Domain.None); break; case Mnemonic.rsubhn2: RewriteSimdBinary("__rsubhn2_{0}", Domain.None); break; case Mnemonic.saba: RewriteSimdBinary("__saba_{0}", Domain.None); break; case Mnemonic.sabal: RewriteSimdBinary("__sabal_{0}", Domain.None); break; case Mnemonic.sabal2: RewriteSimdBinary("__sabal2_{0}", Domain.None); break; case Mnemonic.sabd: RewriteSimdBinary("__sabd_{0}", Domain.None); break; case Mnemonic.sabdl: RewriteSimdBinary("__sabdl_{0}", Domain.None); break; case Mnemonic.sabdl2: RewriteSimdBinary("__sabdl2_{0}", Domain.None); break; case Mnemonic.sadalp: RewriteSimdBinary("__sadalp_{0}", Domain.SignedInt); break; case Mnemonic.saddl: RewriteSimdBinary("__saddl_{0}", Domain.SignedInt); break; case Mnemonic.saddl2: RewriteSimdBinary("__saddl2_{0}", Domain.SignedInt); break; case Mnemonic.saddlp: RewriteSimdUnary("__saddlp_{0}", Domain.SignedInt); break; case Mnemonic.saddlv: RewriteSimdUnary("__saddlv_{0}", Domain.SignedInt); break; case Mnemonic.saddw: RewriteSimdBinary("__saddw_{0}", Domain.SignedInt); break; case Mnemonic.saddw2: RewriteSimdBinary("__saddw2_{0}", Domain.SignedInt); break; case Mnemonic.sbc: RewriteAdcSbc(m.ISub); break; case Mnemonic.sbcs: RewriteAdcSbc(m.ISub, NZCV); break; case Mnemonic.sbfiz: RewriteSbfiz(); break; case Mnemonic.sbfm: RewriteUSbfm("__sbfm"); break; case Mnemonic.scvtf: RewriteScvtf(); break; case Mnemonic.sdiv: RewriteBinary(m.SDiv); break; case Mnemonic.shadd: RewriteSimdBinary("__shadd_{0}", Domain.SignedInt); break; case Mnemonic.shl: RewriteSimdBinary("__shl_{0}", Domain.None); break; case Mnemonic.shll: RewriteSimdBinary("__shll_{0}", Domain.None); break; case Mnemonic.shll2: RewriteSimdBinary("__shll2_{0}", Domain.None); break; case Mnemonic.shrn: RewriteShrn(); break; case Mnemonic.shsub: RewriteSimdBinary("__shsub_{0}", Domain.SignedInt); break; case Mnemonic.sli: RewriteSimdBinary("__sli_{0}", Domain.None); break; case Mnemonic.smaddl: RewriteMaddl(PrimitiveType.Int64, m.SMul); break; case Mnemonic.smax: RewriteSimdBinary("__smax_{0}", Domain.SignedInt); break; case Mnemonic.smaxp: RewriteSimdBinary("__smaxp_{0}", Domain.SignedInt); break; case Mnemonic.smaxv: RewriteSimdReduce("__smaxv_{0}", Domain.SignedInt); break; case Mnemonic.smc: RewriteSmc(); break; case Mnemonic.smin: RewriteSimdBinary("__smin_{0}", Domain.SignedInt); break; case Mnemonic.sminp: RewriteSimdBinary("__sminp_{0}", Domain.SignedInt); break; case Mnemonic.sminv: RewriteSimdUnary("__sminv_{0}", Domain.SignedInt); break; case Mnemonic.smlal: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.smlal2: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.smlsl: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.smlsl2: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.smov: RewriteVectorElementToScalar(Domain.SignedInt); break; case Mnemonic.smsubl: RewriteSmsubl(); break; case Mnemonic.smull: RewriteMull(PrimitiveType.Int32, PrimitiveType.Int64, m.SMul); break; case Mnemonic.smull2: RewriteSimdBinary("__smull2_{0}", Domain.SignedInt); break; case Mnemonic.smulh: RewriteMulh(PrimitiveType.Int64, PrimitiveType.Int128, m.SMul); break; case Mnemonic.sqabs: RewriteSimdUnary("__sqabs_{0}", Domain.SignedInt); break; case Mnemonic.sqadd: RewriteSimdBinary("__sqadd_{0}", Domain.SignedInt); break; case Mnemonic.sqdmulh: RewriteMaybeSimdBinary(Domain.SignedInt); break; case Mnemonic.sqdmull: RewriteSimdBinary("__sqdmull_{0}", Domain.SignedInt); break; case Mnemonic.sqdmull2: RewriteSimdBinary("__sqdmull2_{0}", Domain.SignedInt); break; case Mnemonic.sqdmlal: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.sqdmlal2: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.sqdmlsl: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.sqdmlsl2: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.sqneg: RewriteSimdUnary("__sqneg_{0}", Domain.SignedInt); break; case Mnemonic.sqrdmlah: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.sqrdmlsh: RewriteSimdTrinary(Domain.SignedInt); break; case Mnemonic.sqrdmulh: RewriteSimdBinary("__sqrdmulh_{0}", Domain.SignedInt); break; case Mnemonic.sqrshl: RewriteSimdBinary("__sqrshl_{0}", Domain.SignedInt); break; case Mnemonic.sqrshrn: RewriteSimdBinary("__sqrshrn_{0}", Domain.SignedInt); break; case Mnemonic.sqrshrn2: RewriteSimdBinary("__sqrshrn2_{0}", Domain.SignedInt); break; case Mnemonic.sqrshrun: RewriteSimdBinary("__sqrshrun_{0}", Domain.SignedInt); break; case Mnemonic.sqrshrun2: RewriteSimdBinary("__sqrshrun2_{0}", Domain.SignedInt); break; case Mnemonic.sqshl: RewriteSimdBinary("__sqshl_{0}", Domain.SignedInt); break; case Mnemonic.sqshlu: RewriteSimdBinary("__sqshlu_{0}", Domain.SignedInt); break; case Mnemonic.sqshrn: RewriteSimdBinary("__sqshrn_{0}", Domain.SignedInt); break; case Mnemonic.sqshrn2: RewriteSimdBinary("__sqshrn2_{0}", Domain.SignedInt); break; case Mnemonic.sqsub: RewriteSimdBinary("__sqsub_{0}", Domain.SignedInt); break; case Mnemonic.sqxtn: RewriteSimdUnary("__sqxtn_{0}", Domain.SignedInt); break; case Mnemonic.sqxtn2: RewriteSimdUnary("__sqxtn2_{0}", Domain.SignedInt); break; case Mnemonic.sqxtun: RewriteSimdUnary("__sqxtun_{0}", Domain.SignedInt); break; case Mnemonic.sqxtun2: RewriteSimdUnary("__sqxtun2_{0}", Domain.SignedInt); break; case Mnemonic.sri: RewriteSimdBinary("__sri_{0}", Domain.SignedInt); break; case Mnemonic.srhadd: RewriteSimdBinary("__srhadd_{0}", Domain.SignedInt); break; case Mnemonic.srshl: RewriteSimdBinary("__srshl_{0}", Domain.SignedInt); break; case Mnemonic.srshr: RewriteSimdBinary("__srshr_{0}", Domain.SignedInt); break; case Mnemonic.srsra: RewriteSimdBinary("__srsra_{0}", Domain.SignedInt); break; case Mnemonic.sshl: RewriteSimdBinary("__sshl_{0}", Domain.SignedInt); break; case Mnemonic.sshll: RewriteSimdBinary("__sshll_{0}", Domain.SignedInt); break; case Mnemonic.sshll2: RewriteSimdBinary("__sshll2_{0}", Domain.SignedInt); break; case Mnemonic.sshr: RewriteSimdWithScalar("__sshr_{0}", Domain.SignedInt); break; case Mnemonic.ssra: RewriteSimdBinary("__ssra_{0}", Domain.SignedInt); break; case Mnemonic.ssubl: RewriteSimdBinary("__ssubl_{0}", Domain.SignedInt); break; case Mnemonic.ssubl2: RewriteSimdBinary("__ssubl2_{0}", Domain.SignedInt); break; case Mnemonic.ssubw: RewriteSimdBinary("__ssubw_{0}", Domain.SignedInt); break; case Mnemonic.ssubw2: RewriteSimdBinary("__ssubw2_{0}", Domain.SignedInt); break; case Mnemonic.subhn: RewriteSimdBinary("__subhn_{0}", Domain.SignedInt); break; case Mnemonic.subhn2: RewriteSimdBinary("__subhn2_{0}", Domain.SignedInt); break; case Mnemonic.suqadd: RewriteSimdBinary("__suqadd_{0}", Domain.SignedInt); break; case Mnemonic.st1: RewriteStN("__st1"); break; case Mnemonic.st2: RewriteStN("__st2"); break; case Mnemonic.st3: RewriteStN("__st3"); break; case Mnemonic.st4: RewriteStN("__st4"); break; case Mnemonic.stlr: RewriteStlr(instr.Operands[0].Width); break; case Mnemonic.stlrh: RewriteStlr(PrimitiveType.Word16); break; case Mnemonic.stp: RewriteLoadStorePair(false); break; case Mnemonic.str: RewriteStr(null); break; case Mnemonic.strb: RewriteStr(PrimitiveType.Byte); break; case Mnemonic.strh: RewriteStr(PrimitiveType.Word16); break; case Mnemonic.stur: RewriteStr(null); break; case Mnemonic.sturb: RewriteStr(PrimitiveType.Byte); break; case Mnemonic.sturh: RewriteStr(PrimitiveType.Word16); break; case Mnemonic.stxr: RewriteStx(instr.Operands[1].Width); break; case Mnemonic.stxrb: RewriteStx(PrimitiveType.Byte); break; case Mnemonic.sub: RewriteBinary(m.ISub); break; case Mnemonic.subs: RewriteBinary(m.ISub, NZCV); break; case Mnemonic.svc: RewriteSvc(); break; case Mnemonic.sxtb: RewriteUSxt(Domain.SignedInt, 8); break; case Mnemonic.sxth: RewriteUSxt(Domain.SignedInt, 16); break; case Mnemonic.sxtl: RewriteSimdUnary("__sxtl_{0}", Domain.SignedInt); break; case Mnemonic.sxtw: RewriteUSxt(Domain.SignedInt, 32); break; case Mnemonic.tbnz: RewriteTb(m.Ne0); break; case Mnemonic.tbl: RewriteTbl(); break; case Mnemonic.tbx: RewriteTbx(); break; case Mnemonic.tbz: RewriteTb(m.Eq0); break; case Mnemonic.test: RewriteTest(); break; case Mnemonic.trn1: RewriteSimdBinary("__trn1_{0}", Domain.UnsignedInt); break; case Mnemonic.trn2: RewriteSimdBinary("__trn2_{0}", Domain.UnsignedInt); break; case Mnemonic.uaba: RewriteSimdBinary("__uaba_{0}", Domain.UnsignedInt); break; case Mnemonic.uabal: RewriteSimdBinary("__uabal_{0}", Domain.UnsignedInt); break; case Mnemonic.uabal2: RewriteSimdBinary("__uabal2_{0}", Domain.UnsignedInt); break; case Mnemonic.uabd: RewriteSimdBinary("__uabd_{0}", Domain.UnsignedInt); break; case Mnemonic.uabdl: RewriteSimdBinary("__uabdl_{0}", Domain.UnsignedInt); break; case Mnemonic.uabdl2: RewriteSimdBinary("__uabdl2_{0}", Domain.UnsignedInt); break; case Mnemonic.uadalp: RewriteSimdBinary("__uadalp_{0}", Domain.UnsignedInt); break; case Mnemonic.uaddl: RewriteSimdBinary("__uaddl_{0}", Domain.UnsignedInt); break; case Mnemonic.uaddl2: RewriteSimdBinary("__uaddl2_{0}", Domain.UnsignedInt); break; case Mnemonic.uaddlp: RewriteSimdBinary("__uaddlp_{0}", Domain.UnsignedInt); break; case Mnemonic.uaddlv: RewriteSimdUnary("__uaddlv_{0}", Domain.UnsignedInt); break; case Mnemonic.uaddw: RewriteUaddw(); break; case Mnemonic.uaddw2: RewriteSimdBinary("__uaddw_{0}", Domain.UnsignedInt); break; case Mnemonic.ubfm: RewriteUSbfm("__ubfm"); break; case Mnemonic.ucvtf: RewriteIcvt("__ucvtf_{0}", Domain.UnsignedInt); break; case Mnemonic.udiv: RewriteBinary(m.UDiv); break; case Mnemonic.uhadd: RewriteSimdBinary("__uhadd_{0}", Domain.UnsignedInt); break; case Mnemonic.uhsub: RewriteSimdBinary("__uhsub_{0}", Domain.UnsignedInt); break; case Mnemonic.umaddl: RewriteMaddl(PrimitiveType.UInt64, m.UMul); break; case Mnemonic.umax: RewriteSimdBinary("__umax_{0}", Domain.UnsignedInt); break; case Mnemonic.umaxp: RewriteSimdBinary("__umaxp_{0}", Domain.UnsignedInt); break; case Mnemonic.umaxv: RewriteSimdUnary("__umaxv_{0}", Domain.UnsignedInt); break; case Mnemonic.umin: RewriteSimdBinary("__umin_{0}", Domain.UnsignedInt); break; case Mnemonic.uminp: RewriteSimdBinary("__uminp_{0}", Domain.UnsignedInt); break; case Mnemonic.uminv: RewriteSimdUnary("__uminv_{0}", Domain.UnsignedInt); break; case Mnemonic.umlal: RewriteSimdTrinary(Domain.UnsignedInt); break; case Mnemonic.umlal2: RewriteSimdTrinary(Domain.UnsignedInt); break; case Mnemonic.umlsl: RewriteSimdTrinary(Domain.UnsignedInt); break; case Mnemonic.umlsl2: RewriteSimdTrinary(Domain.UnsignedInt); break; case Mnemonic.umov: RewriteVectorElementToScalar(Domain.UnsignedInt); break; case Mnemonic.umulh: RewriteMulh(PrimitiveType.UInt64, m.UMul); break; case Mnemonic.umull: RewriteMull(PrimitiveType.UInt32, PrimitiveType.UInt64, m.UMul); break; case Mnemonic.umull2: RewriteSimdBinary("__umull2_{0}", Domain.UnsignedInt); break; case Mnemonic.uqadd: RewriteSimdBinary("__uqadd_{0}", Domain.UnsignedInt); break; case Mnemonic.uqrshl: RewriteSimdBinary("__uqrshl_{0}", Domain.UnsignedInt); break; case Mnemonic.uqrshrn: RewriteSimdBinary("__uqrshrn_{0}", Domain.UnsignedInt); break; case Mnemonic.uqrshrn2: RewriteSimdBinary("__uqrshrn2_{0}", Domain.UnsignedInt); break; case Mnemonic.uqshl: RewriteSimdBinary("__uqshl_{0}", Domain.UnsignedInt); break; case Mnemonic.uqshrn: RewriteSimdBinary("__uqshrn_{0}", Domain.UnsignedInt); break; case Mnemonic.uqshrn2: RewriteSimdBinary("__uqshrn2_{0}", Domain.UnsignedInt); break; case Mnemonic.uqsub: RewriteSimdBinary("__uqsub_{0}", Domain.UnsignedInt); break; case Mnemonic.uqxtn: RewriteSimdUnary("__uqxtn_{0}", Domain.UnsignedInt); break; case Mnemonic.uqxtn2: RewriteSimdUnary("__uqxtn2_{0}", Domain.UnsignedInt); break; case Mnemonic.urecpe: RewriteSimdUnary("__urecpe_{0}", Domain.UnsignedInt); break; case Mnemonic.urhadd: RewriteSimdBinary("__urhadd_{0}", Domain.UnsignedInt); break; case Mnemonic.urshl: RewriteSimdBinary("__urshl_{0}", Domain.UnsignedInt); break; case Mnemonic.urshr: RewriteSimdBinary("__urshr_{0}", Domain.UnsignedInt); break; case Mnemonic.ursqrte: RewriteSimdUnary("__ursqrte_{0}", Domain.UnsignedInt); break; case Mnemonic.ursra: RewriteSimdBinary("__ursra_{0}", Domain.UnsignedInt); break; case Mnemonic.ushl: RewriteMaybeSimdBinary(m.Shr, "__ushl_{0}", Domain.UnsignedInt); break; case Mnemonic.ushll: RewriteMaybeSimdBinary(m.Shr, "__ushll_{0}", Domain.UnsignedInt); break; case Mnemonic.ushll2: RewriteMaybeSimdBinary(m.Shr, "__ushll2_{0}", Domain.UnsignedInt); break; case Mnemonic.ushr: RewriteMaybeSimdBinary(m.Shr, "__ushr_{0}", Domain.UnsignedInt); break; case Mnemonic.usqadd: RewriteSimdBinary("__usqadd_{0}", Domain.UnsignedInt); break; case Mnemonic.usra: RewriteSimdBinary("__usra_{0}", Domain.UnsignedInt); break; case Mnemonic.usubl: RewriteSimdBinary("__usubl_{0}", Domain.UnsignedInt); break; case Mnemonic.usubl2: RewriteSimdBinary("__usubl2_{0}", Domain.UnsignedInt); break; case Mnemonic.usubw: RewriteSimdBinary("__usubw_{0}", Domain.UnsignedInt); break; case Mnemonic.usubw2: RewriteSimdBinary("__usubw2_{0}", Domain.UnsignedInt); break; case Mnemonic.uxtb: RewriteUSxt(Domain.UnsignedInt, 8); break; case Mnemonic.uxth: RewriteUSxt(Domain.UnsignedInt, 16); break; case Mnemonic.uxtl: RewriteSimdUnary("__uxtl_{0}", Domain.UnsignedInt); break; case Mnemonic.uxtl2: RewriteSimdUnary("__uxtl2_{0}", Domain.UnsignedInt); break; case Mnemonic.uxtw: RewriteUSxt(Domain.UnsignedInt, 32); break; case Mnemonic.uzp1: RewriteSimdBinary("__uzp1_{0}", Domain.None); break; case Mnemonic.uzp2: RewriteSimdBinary("__uzp2_{0}", Domain.None); break; case Mnemonic.xtn: RewriteSimdUnary("__xtn_{0}", Domain.None); break; case Mnemonic.xtn2: RewriteSimdUnary("__xtn2_{0}", Domain.None); break; case Mnemonic.zip1: RewriteSimdBinary("__zip1_{0}", Domain.None); break; case Mnemonic.zip2: RewriteSimdBinary("__zip2_{0}", Domain.None); break; } } catch (Exception e) { EmitUnitTest(e.Message); } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); cluster.Clear(); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { instr = dasm.Current; var addr = instr.Address; var len = instr.Length; rtlInstructions = new List <RtlInstruction>(); rtlc = instr.InstructionClass; m = new RtlEmitter(rtlInstructions); orw = new OperandRewriter(arch, this.m, this.binder, instr.dataWidth); switch (instr.Mnemonic) { default: host.Warn( instr.Address, "M68k instruction '{0}' is not supported yet.", instr.Mnemonic); m.Invalid(); break; case Mnemonic.illegal: RewriteIllegal(); break; case Mnemonic.abcd: RewriteAbcd(); break; case Mnemonic.add: RewriteBinOp((s, d) => m.IAdd(d, s), FlagM.CVZNX); break; case Mnemonic.adda: RewriteBinOp((s, d) => m.IAdd(d, s)); break; case Mnemonic.addi: RewriteArithmetic((s, d) => m.IAdd(d, s)); break; case Mnemonic.addq: RewriteAddSubq((s, d) => m.IAdd(d, s)); break; case Mnemonic.addx: RewriteAddSubx(m.IAdd); break; case Mnemonic.and: RewriteLogical((s, d) => m.And(d, s)); break; case Mnemonic.andi: RewriteLogical((s, d) => m.And(d, s)); break; case Mnemonic.asl: RewriteArithmetic((s, d) => m.Shl(d, s)); break; case Mnemonic.asr: RewriteShift((s, d) => m.Sar(d, s)); break; /* * * Mnemonic Condition Encoding Test * T* True 0000 1 * F* False 0001 0 * HI High 0010 C L Z * LS Low or Same 0011 C V Z * VC Overflow Clear 1000 V * VS Overflow Set 1001 V */ case Mnemonic.bclr: RewriteBclrBset("__bclr"); break; case Mnemonic.bcc: RewriteBcc(ConditionCode.UGE, FlagM.CF); break; case Mnemonic.bcs: RewriteBcc(ConditionCode.ULT, FlagM.CF); break; case Mnemonic.beq: RewriteBcc(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.bge: RewriteBcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Mnemonic.bgt: RewriteBcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.bhi: RewriteBcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Mnemonic.ble: RewriteBcc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.bls: RewriteBcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break; case Mnemonic.blt: RewriteBcc(ConditionCode.LT, FlagM.NF | FlagM.VF); break; case Mnemonic.bmi: RewriteBcc(ConditionCode.LT, FlagM.NF); break; case Mnemonic.bne: RewriteBcc(ConditionCode.NE, FlagM.ZF); break; case Mnemonic.bpl: RewriteBcc(ConditionCode.GT, FlagM.NF); break; case Mnemonic.bvc: RewriteBcc(ConditionCode.NO, FlagM.VF); break; case Mnemonic.bvs: RewriteBcc(ConditionCode.OV, FlagM.VF); break; case Mnemonic.bchg: RewriteBchg(); break; case Mnemonic.bkpt: RewriteBkpt(); break; case Mnemonic.bra: RewriteBra(); break; case Mnemonic.bset: RewriteBclrBset("__bset"); break; case Mnemonic.bsr: RewriteBsr(); break; case Mnemonic.btst: RewriteBtst(); break; case Mnemonic.callm: RewriteCallm(); break; case Mnemonic.cas: RewriteCas(); break; case Mnemonic.clr: RewriteClr(); break; case Mnemonic.chk: RewriteChk(); break; case Mnemonic.chk2: RewriteChk2(); break; case Mnemonic.cmp: RewriteCmp(); break; case Mnemonic.cmp2: RewriteCmp2(); break; case Mnemonic.cmpa: RewriteCmp(); break; case Mnemonic.cmpi: RewriteCmp(); break; case Mnemonic.cmpm: RewriteCmp(); break; case Mnemonic.dbcc: RewriteDbcc(ConditionCode.UGE, FlagM.CF); break; case Mnemonic.dbcs: RewriteDbcc(ConditionCode.ULT, FlagM.CF); break; case Mnemonic.dbeq: RewriteDbcc(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.dbge: RewriteDbcc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Mnemonic.dbgt: RewriteDbcc(ConditionCode.GE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.dbhi: RewriteDbcc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Mnemonic.dble: RewriteDbcc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.dbls: RewriteDbcc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break; case Mnemonic.dblt: RewriteDbcc(ConditionCode.LT, FlagM.NF | FlagM.VF); break; case Mnemonic.dbmi: RewriteDbcc(ConditionCode.LT, FlagM.NF); break; case Mnemonic.dbne: RewriteDbcc(ConditionCode.NE, FlagM.ZF); break; case Mnemonic.dbpl: RewriteDbcc(ConditionCode.GT, FlagM.NF); break; case Mnemonic.dbt: RewriteDbcc(ConditionCode.ALWAYS, 0); break; case Mnemonic.dbra: RewriteDbcc(ConditionCode.None, 0); break; case Mnemonic.divs: RewriteDiv(m.SDiv, PrimitiveType.Int16); break; case Mnemonic.divsl: RewriteDiv(m.SDiv, PrimitiveType.Int32); break; case Mnemonic.divu: RewriteDiv(m.UDiv, PrimitiveType.UInt16); break; case Mnemonic.divul: RewriteDiv(m.UDiv, PrimitiveType.UInt32); break; case Mnemonic.eor: RewriteLogical((s, d) => m.Xor(d, s)); break; case Mnemonic.eori: RewriteLogical((s, d) => m.Xor(d, s)); break; case Mnemonic.exg: RewriteExg(); break; case Mnemonic.ext: RewriteExt(); break; case Mnemonic.extb: RewriteExtb(); break; case Mnemonic.fadd: RewriteFBinOp((s, d) => m.FAdd(d, s)); break; //$REVIEW: the following don't respect NaN, but NaN typically doesn't exist in HLLs. case Mnemonic.fbf: m.Nop(); break; case Mnemonic.fblt: RewriteFbcc(ConditionCode.LT); break; case Mnemonic.fbgl: RewriteFbcc(ConditionCode.NE); break; case Mnemonic.fbgt: RewriteFbcc(ConditionCode.GT); break; case Mnemonic.fbgle: RewriteFbcc(ConditionCode.NE); break; //$BUG: should be !is_nan case Mnemonic.fbne: RewriteFbcc(ConditionCode.NE); break; case Mnemonic.fbnge: RewriteFbcc(ConditionCode.LT); break; case Mnemonic.fbngl: RewriteFbcc(ConditionCode.EQ); break; case Mnemonic.fbngle: RewriteFbcc(ConditionCode.EQ); break; //$BUG: should be is_nan case Mnemonic.fbnlt: RewriteFbcc(ConditionCode.GE); break; case Mnemonic.fbnle: RewriteFbcc(ConditionCode.GT); break; case Mnemonic.fbogl: RewriteFbcc(ConditionCode.NE); break; case Mnemonic.fbole: RewriteFbcc(ConditionCode.LE); break; case Mnemonic.fbolt: RewriteFbcc(ConditionCode.LT); break; case Mnemonic.fbogt: RewriteFbcc(ConditionCode.GT); break; case Mnemonic.fbor: RewriteFbcc(ConditionCode.EQ); break; //$REVIEW: is this correct? case Mnemonic.fbseq: RewriteFbcc(ConditionCode.EQ); break; case Mnemonic.fbsf: RewriteFbcc(ConditionCode.NEVER); break; case Mnemonic.fbsne: RewriteFbcc(ConditionCode.NE); break; case Mnemonic.fbst: RewriteFbcc(ConditionCode.ALWAYS); break; case Mnemonic.fbuge: RewriteFbcc(ConditionCode.GE); break; case Mnemonic.fbugt: RewriteFbcc(ConditionCode.GT); break; case Mnemonic.fbult: RewriteFbcc(ConditionCode.LT); break; case Mnemonic.fbun: RewriteFbcc(ConditionCode.IS_NAN); break; case Mnemonic.fasin: RewriteFasin(); break; case Mnemonic.fintrz: RewriteFintrz(); break; case Mnemonic.fcmp: RewriteFcmp(); break; case Mnemonic.fdiv: RewriteFBinOp((s, d) => m.FDiv(d, s)); break; case Mnemonic.fmove: RewriteFmove(); break; case Mnemonic.fmovecr: RewriteFmovecr(); break; case Mnemonic.fmovem: RewriteMovem(i => Registers.GetRegister(i + Registers.fp0.Number)); break; case Mnemonic.fmul: RewriteFBinOp((s, d) => m.FMul(d, s)); break; case Mnemonic.fneg: RewriteFUnaryOp(m.Neg); break; case Mnemonic.fsqrt: RewriteFsqrt(); break; case Mnemonic.fsub: RewriteFBinOp((s, d) => m.FSub(d, s)); break; case Mnemonic.ftan: RewriteFtan(); break; case Mnemonic.jmp: RewriteJmp(); break; case Mnemonic.jsr: RewriteJsr(); break; case Mnemonic.lea: RewriteLea(); break; case Mnemonic.link: RewriteLink(); break; case Mnemonic.lsl: RewriteShift((s, d) => m.Shl(d, s)); break; case Mnemonic.lsr: RewriteShift((s, d) => m.Shr(d, s)); break; case Mnemonic.move: RewriteMove(true); break; case Mnemonic.move16: RewriteMove16(); break; case Mnemonic.movea: RewriteMove(false); break; case Mnemonic.movep: RewriteMovep(); break; case Mnemonic.moveq: RewriteMoveq(); break; case Mnemonic.moves: RewriteMoves(); break; case Mnemonic.movem: RewriteMovem(Registers.GetRegister); break; case Mnemonic.muls: RewriteMul((s, d) => m.SMul(d, s)); break; case Mnemonic.mulu: RewriteMul((s, d) => m.UMul(d, s)); break; case Mnemonic.nbcd: RewriteNbcd(); break; case Mnemonic.neg: RewriteUnary(s => m.Neg(s), AllConditions); break; case Mnemonic.negx: RewriteUnary(RewriteNegx, AllConditions); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.not: RewriteUnary(s => m.Comp(s), LogicalConditions); break; case Mnemonic.or: RewriteLogical((s, d) => m.Or(d, s)); break; case Mnemonic.ori: RewriteLogical((s, d) => m.Or(d, s)); break; case Mnemonic.pack: RewritePack(); break; case Mnemonic.pea: RewritePea(); break; case Mnemonic.pflushr: RewritePflushr(); break; case Mnemonic.ptest: RewritePtest(); break; case Mnemonic.rol: RewriteRotation(PseudoProcedure.Rol); break; case Mnemonic.ror: RewriteRotation(PseudoProcedure.Ror); break; case Mnemonic.roxl: RewriteRotationX(PseudoProcedure.RolC); break; case Mnemonic.roxr: RewriteRotationX(PseudoProcedure.RorC); break; case Mnemonic.rtd: RewriteRtd(); break; case Mnemonic.rte: RewriteRte(); break; case Mnemonic.rtm: RewriteRtm(); break; case Mnemonic.rts: RewriteRts(); break; case Mnemonic.sbcd: RewriteSbcd(); break; case Mnemonic.scc: RewriteScc(ConditionCode.UGE, FlagM.CF); break; case Mnemonic.scs: RewriteScc(ConditionCode.ULT, FlagM.CF); break; case Mnemonic.seq: RewriteScc(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.sge: RewriteScc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Mnemonic.sgt: RewriteScc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.shi: RewriteScc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Mnemonic.sle: RewriteScc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.sls: RewriteScc(ConditionCode.ULE, FlagM.CF | FlagM.ZF); break; case Mnemonic.slt: RewriteScc(ConditionCode.LT, FlagM.NF | FlagM.ZF); break; case Mnemonic.smi: RewriteScc(ConditionCode.LT, FlagM.NF); break; case Mnemonic.sne: RewriteScc(ConditionCode.NE, FlagM.ZF); break; case Mnemonic.spl: RewriteScc(ConditionCode.GT, FlagM.NF); break; case Mnemonic.svc: RewriteScc(ConditionCode.NO, FlagM.VF); break; case Mnemonic.svs: RewriteScc(ConditionCode.OV, FlagM.VF); break; case Mnemonic.st: orw.RewriteMoveDst(instr.Operands[0], instr.Address, PrimitiveType.Bool, Constant.True()); break; case Mnemonic.sf: orw.RewriteMoveDst(instr.Operands[0], instr.Address, PrimitiveType.Bool, Constant.False()); break; case Mnemonic.stop: RewriteStop(); break; case Mnemonic.sub: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Mnemonic.suba: RewriteBinOp((s, d) => m.ISub(d, s)); break; case Mnemonic.subi: RewriteArithmetic((s, d) => m.ISub(d, s)); break; case Mnemonic.subq: RewriteAddSubq((s, d) => m.ISub(d, s)); break; case Mnemonic.subx: RewriteArithmetic((s, d) => m.ISub(m.ISub(d, s), binder.EnsureFlagGroup(Registers.ccr, (uint)FlagM.XF, "X", PrimitiveType.Bool))); break; case Mnemonic.swap: RewriteSwap(); break; case Mnemonic.trap: RewriteTrap(); break; case Mnemonic.trapcc: RewriteTrapCc(ConditionCode.UGE, FlagM.CF); break; case Mnemonic.trapcs: RewriteTrapCc(ConditionCode.ULT, FlagM.CF); break; case Mnemonic.trapeq: RewriteTrapCc(ConditionCode.EQ, FlagM.ZF); break; case Mnemonic.trapf: RewriteTrapCc(ConditionCode.NEVER, 0); break; case Mnemonic.trapge: RewriteTrapCc(ConditionCode.GE, FlagM.NF | FlagM.VF); break; case Mnemonic.trapgt: RewriteTrapCc(ConditionCode.GT, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.traphi: RewriteTrapCc(ConditionCode.UGT, FlagM.CF | FlagM.ZF); break; case Mnemonic.traple: RewriteTrapCc(ConditionCode.LE, FlagM.NF | FlagM.VF | FlagM.ZF); break; case Mnemonic.traplt: RewriteTrapCc(ConditionCode.LT, FlagM.CF | FlagM.VF); break; case Mnemonic.trapls: RewriteTrapCc(ConditionCode.ULE, FlagM.VF | FlagM.ZF); break; case Mnemonic.trapmi: RewriteTrapCc(ConditionCode.LT, FlagM.NF); break; case Mnemonic.trapne: RewriteTrapCc(ConditionCode.NE, FlagM.ZF); break; case Mnemonic.trappl: RewriteTrapCc(ConditionCode.GT, FlagM.NF); break; case Mnemonic.trapvc: RewriteTrapCc(ConditionCode.NO, FlagM.VF); break; case Mnemonic.trapvs: RewriteTrapCc(ConditionCode.OV, FlagM.VF); break; case Mnemonic.tas: RewriteTas(); break; case Mnemonic.tst: RewriteTst(); break; case Mnemonic.unlk: RewriteUnlk(); break; case Mnemonic.unpk: RewriteUnpk(); break; } yield return(new RtlInstructionCluster( addr, len, rtlInstructions.ToArray()) { Class = rtlc }); } yield break; }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.iclass = instr.InstructionClass; switch (instr.Mnemonic) { default: EmitUnitTest(); goto case Mnemonic.invalid; case Mnemonic.invalid: m.Invalid(); break; case Mnemonic.add: RewriteAdd(true); break; case Mnemonic.add_c: RewriteAdd_c(); break; case Mnemonic.add_l: RewriteAdd(false); break; case Mnemonic.addb: RewriteAddb(); break; case Mnemonic.addi: RewriteAddi(false); break; case Mnemonic.addi_tc: RewriteAddi(true); break; case Mnemonic.addib: RewriteAddb(); break; case Mnemonic.addil: RewriteAddi(false); break; case Mnemonic.and: RewriteLogical(m.And); break; case Mnemonic.andcm: RewriteLogical((a, b) => m.And(a, m.Comp(b))); break; case Mnemonic.bb: RewriteBb(); break; case Mnemonic.b_l: RewriteBranch(); break; case Mnemonic.be: RewriteBe(false); break; case Mnemonic.be_l: RewriteBe(true); break; case Mnemonic.bv: RewriteBv(); break; case Mnemonic.cmpb: RewriteCmpb(0, 1); break; case Mnemonic.cmpclr: RewriteCmpclr(0, 1); break; case Mnemonic.cmpib: RewriteCmpb(1, 0); break; case Mnemonic.cmpiclr: RewriteCmpclr(1, 0); break; case Mnemonic.@break: RewriteBreak(); break; case Mnemonic.depw: RewriteDepw(); break; case Mnemonic.depwi: RewriteDepwi(); break; case Mnemonic.diag: RewriteDiag(); break; case Mnemonic.ds: RewriteDs(); break; case Mnemonic.extrw: RewriteExtrw(); break; case Mnemonic.fadd: RewriteFpArithmetic(m.FAdd); break; case Mnemonic.fcnv: RewriteFcnv(); break; case Mnemonic.fcnvxf: RewriteFcnvxf(); break; case Mnemonic.fcpy: RewriteFcpy(); break; case Mnemonic.fid: RewriteFid(); break; case Mnemonic.fldd: RewriteFld(PrimitiveType.Real64); break; case Mnemonic.fldw: RewriteFld(PrimitiveType.Real32); break; case Mnemonic.fmpy: RewriteFpArithmetic(m.FMul); break; case Mnemonic.fstd: RewriteFst(PrimitiveType.Real64); break; case Mnemonic.fstw: RewriteFst(PrimitiveType.Real32); break; case Mnemonic.fsub: RewriteFpArithmetic(m.FSub); break; case Mnemonic.ldb: RewriteLd(PrimitiveType.Byte); break; case Mnemonic.ldd: RewriteLd(PrimitiveType.Word64); break; case Mnemonic.ldh: RewriteLd(PrimitiveType.Word16); break; case Mnemonic.ldil: RewriteLdil(); break; case Mnemonic.ldo: RewriteLdo(); break; case Mnemonic.ldsid: RewriteLdsid(); break; case Mnemonic.ldw: RewriteLd(PrimitiveType.Word32); break; case Mnemonic.ldwa: RewriteLd(PrimitiveType.Word32); break; case Mnemonic.mfctl: RewriteMfctl(); break; case Mnemonic.mfctl_w: RewriteMfctl(); break; case Mnemonic.movb: RewriteMovb(); break; case Mnemonic.mtctl: RewriteMtctl(); break; case Mnemonic.mtsm: RewriteMtsm(); break; case Mnemonic.mtsp: RewriteMtsp(); break; case Mnemonic.or: RewriteOr(); break; case Mnemonic.rfi: RewriteRfi("__rfi"); break; case Mnemonic.rfi_r: RewriteRfi("__rfi_r"); break; case Mnemonic.shladd: RewriteShladd(); break; case Mnemonic.shrpd: RewriteShrp(PrimitiveType.Word64, PrimitiveType.Word128); break; case Mnemonic.shrpw: RewriteShrp(PrimitiveType.Word32, PrimitiveType.Word64); break; case Mnemonic.stb: RewriteSt(PrimitiveType.Byte); break; case Mnemonic.std: RewriteSt(PrimitiveType.Word64); break; case Mnemonic.stda: RewriteSt(PrimitiveType.Word64); break; case Mnemonic.sth: RewriteSt(PrimitiveType.Word16); break; case Mnemonic.stw: RewriteSt(PrimitiveType.Word32); break; case Mnemonic.sub: RewriteSub(); break; case Mnemonic.sub_b: RewriteSub_b(); break; case Mnemonic.subi: RewriteSubi(); break; case Mnemonic.xor: RewriteLogical(m.Xor); break; } yield return(m.MakeCluster(instr.Address, instr.Length, iclass)); instrs.Clear(); } }
public HExpr Comp(HExpr a) { return(MapToHandle(m.Comp(GetExpression(a)))); }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; var cluster = new List <RtlInstruction>(); m = new RtlEmitter(cluster); rtlc = instr.InstructionClass; switch (instr.Mnemonic) { default: EmitUnitTest(); host.Warn( instr.Address, "AArch64 instruction {0} is not supported yet.", instr); goto case Mnemonic.Invalid; case Mnemonic.Invalid: rtlc = InstrClass.Invalid; m.Invalid(); break; case Mnemonic.add: RewriteMaybeSimdBinary(m.IAdd, "__add_{0}"); break; case Mnemonic.adds: RewriteBinary(m.IAdd, this.NZCV); break; case Mnemonic.addv: RewriteAddv(); break; case Mnemonic.adr: RewriteUnary(n => n); break; case Mnemonic.asrv: RewriteBinary(m.Sar); break; case Mnemonic.bic: RewriteBinary((a, b) => m.And(a, m.Comp(b))); break; case Mnemonic.adrp: RewriteAdrp(); break; case Mnemonic.and: RewriteBinary(m.And); break; case Mnemonic.ands: RewriteBinary(m.And, this.NZ00); break; case Mnemonic.asr: RewriteBinary(m.Sar); break; case Mnemonic.b: RewriteB(); break; case Mnemonic.bfm: RewriteBfm(); break; case Mnemonic.bl: RewriteBl(); break; case Mnemonic.blr: RewriteBlr(); break; case Mnemonic.br: RewriteBr(); break; case Mnemonic.cbnz: RewriteCb(m.Ne0); break; case Mnemonic.cbz: RewriteCb(m.Eq0); break; case Mnemonic.ccmn: RewriteCcmn(); break; case Mnemonic.ccmp: RewriteCcmp(); break; case Mnemonic.clz: RewriteClz(); break; case Mnemonic.cmp: RewriteCmp(); break; case Mnemonic.cmeq: RewriteCmeq(); break; case Mnemonic.csel: RewriteCsel(); break; case Mnemonic.csinc: RewriteCsinc(); break; case Mnemonic.csinv: RewriteCsinv(); break; case Mnemonic.csneg: RewriteCsneg(); break; case Mnemonic.dsb: RewriteDsb(); break; case Mnemonic.dup: RewriteDup(); break; case Mnemonic.eor: RewriteBinary(m.Xor); break; case Mnemonic.fabs: RewriteFabs(); break; case Mnemonic.fadd: RewriteFadd(); break; case Mnemonic.fcmp: RewriteFcmp(); break; case Mnemonic.fcsel: RewriteFcsel(); break; case Mnemonic.fcvt: RewriteFcvt(); break; case Mnemonic.fcvtms: RewriteFcvtms(); break; case Mnemonic.fcvtps: RewriteFcvtps(); break; case Mnemonic.fcvtzs: RewriteFcvtzs(); break; case Mnemonic.fdiv: RewriteMaybeSimdBinary(m.FDiv, "__fdiv_{0}", Domain.Real); break; case Mnemonic.fmadd: RewriteIntrinsicFTernary("__fmaddf", "__fmadd"); break; case Mnemonic.fmsub: RewriteIntrinsicFTernary("__fmsubf", "__fmsub"); break; case Mnemonic.fmax: RewriteIntrinsicFBinary("fmaxf", "fmax"); break; case Mnemonic.fmin: RewriteIntrinsicFBinary("fminf", "fmin"); break; case Mnemonic.fmov: RewriteFmov(); break; case Mnemonic.fmul: RewriteFmul(); break; case Mnemonic.fneg: RewriteUnary(m.FNeg); break; case Mnemonic.fnmul: RewriteFnmul(); break; case Mnemonic.fsqrt: RewriteFsqrt(); break; case Mnemonic.fsub: RewriteMaybeSimdBinary(m.FSub, "__fsub_{0}", Domain.Real); break; case Mnemonic.isb: RewriteIsb(); break; case Mnemonic.ld1r: RewriteLdNr("__ld1r"); break; case Mnemonic.ld2: RewriteLdN("__ld2"); break; case Mnemonic.ld3: RewriteLdN("__ld3"); break; case Mnemonic.ld4: RewriteLdN("__ld4"); break; case Mnemonic.ldp: RewriteLoadStorePair(true); break; case Mnemonic.ldpsw: RewriteLoadStorePair(true, PrimitiveType.Int32, PrimitiveType.Int64); break; case Mnemonic.ldr: RewriteLdr(null); break; case Mnemonic.ldrb: RewriteLdr(PrimitiveType.Byte); break; case Mnemonic.ldrh: RewriteLdr(PrimitiveType.Word16); break; case Mnemonic.ldrsb: RewriteLdr(PrimitiveType.SByte); break; case Mnemonic.ldrsh: RewriteLdr(PrimitiveType.Int16); break; case Mnemonic.ldrsw: RewriteLdr(PrimitiveType.Int32); break; case Mnemonic.lslv: RewriteBinary(m.Shl); break; case Mnemonic.lsrv: RewriteBinary(m.Shr); break; case Mnemonic.ldur: RewriteLdr(null); break; case Mnemonic.ldurb: RewriteLdr(PrimitiveType.Byte); break; case Mnemonic.ldurh: RewriteLdr(PrimitiveType.Word16); break; case Mnemonic.ldursb: RewriteLdr(PrimitiveType.SByte); break; case Mnemonic.ldursh: RewriteLdr(PrimitiveType.Int16); break; case Mnemonic.ldursw: RewriteLdr(PrimitiveType.Int32); break; case Mnemonic.lsl: RewriteBinary(m.Shl); break; case Mnemonic.lsr: RewriteBinary(m.Shr); break; case Mnemonic.madd: RewriteMaddSub(m.IAdd); break; case Mnemonic.mneg: RewriteBinary((a, b) => m.Neg(m.IMul(a, b))); break; case Mnemonic.msub: RewriteMaddSub(m.ISub); break; case Mnemonic.mov: RewriteMov(); break; case Mnemonic.movi: RewriteMovi(); break; case Mnemonic.movk: RewriteMovk(); break; case Mnemonic.movn: RewriteMovn(); break; case Mnemonic.movz: RewriteMovz(); break; case Mnemonic.mrs: RewriteMrs(); break; case Mnemonic.msr: RewriteMsr(); break; case Mnemonic.mul: RewriteMaybeSimdBinary(m.IMul, "__mul_{0}"); break; case Mnemonic.mvn: RewriteUnary(m.Comp); break; case Mnemonic.nop: m.Nop(); break; case Mnemonic.not: RewriteMaybeSimdUnary(m.Comp, "__not_{0}"); break; case Mnemonic.orr: RewriteBinary(m.Or); break; case Mnemonic.orn: RewriteBinary((a, b) => m.Or(a, m.Comp(b))); break; case Mnemonic.prfm: RewritePrfm(); break; case Mnemonic.ret: RewriteRet(); break; case Mnemonic.rev16: RewriteRev16(); break; case Mnemonic.ror: RewriteRor(); break; case Mnemonic.rorv: RewriteRor(); break; case Mnemonic.sbfiz: RewriteSbfiz(); break; case Mnemonic.sbfm: RewriteUSbfm("__sbfm"); break; case Mnemonic.scvtf: RewriteScvtf(); break; case Mnemonic.sdiv: RewriteBinary(m.SDiv); break; case Mnemonic.shrn: RewriteShrn(); break; case Mnemonic.smaddl: RewriteMaddl(PrimitiveType.Int64, m.SMul); break; case Mnemonic.smax: RewriteSmax(); break; case Mnemonic.smaxv: RewriteSmaxv(); break; case Mnemonic.smc: RewriteSmc(); break; case Mnemonic.smull: RewriteMull(PrimitiveType.Int64, m.SMul); break; case Mnemonic.st1: RewriteStN("__st1"); break; case Mnemonic.st2: RewriteStN("__st2"); break; case Mnemonic.st3: RewriteStN("__st3"); break; case Mnemonic.st4: RewriteStN("__st4"); break; case Mnemonic.stp: RewriteLoadStorePair(false); break; case Mnemonic.str: RewriteStr(null); break; case Mnemonic.strb: RewriteStr(PrimitiveType.Byte); break; case Mnemonic.strh: RewriteStr(PrimitiveType.Word16); break; case Mnemonic.stur: RewriteStr(null); break; case Mnemonic.sturb: RewriteStr(PrimitiveType.Byte); break; case Mnemonic.sturh: RewriteStr(PrimitiveType.Word16); break; case Mnemonic.sub: RewriteBinary(m.ISub); break; case Mnemonic.subs: RewriteBinary(m.ISub, NZCV); break; case Mnemonic.svc: RewriteSvc(); break; case Mnemonic.sxtb: RewriteUSxt(Domain.SignedInt, 8); break; case Mnemonic.sxth: RewriteUSxt(Domain.SignedInt, 16); break; case Mnemonic.sxtl: RewriteSimdUnary("__sxtl_{0}", Domain.SignedInt); break; case Mnemonic.sxtw: RewriteUSxt(Domain.SignedInt, 32); break; case Mnemonic.tbnz: RewriteTb(m.Ne0); break; case Mnemonic.tbz: RewriteTb(m.Eq0); break; case Mnemonic.test: RewriteTest(); break; case Mnemonic.uaddw: RewriteUaddw(); break; case Mnemonic.ubfm: RewriteUSbfm("__ubfm"); break; case Mnemonic.ucvtf: RewriteIcvt(Domain.UnsignedInt); break; case Mnemonic.udiv: RewriteBinary(m.UDiv); break; case Mnemonic.umaddl: RewriteMaddl(PrimitiveType.UInt64, m.UMul); break; case Mnemonic.umlal: RewriteUmlal(); break; case Mnemonic.umull: RewriteMull(PrimitiveType.UInt64, m.UMul); break; case Mnemonic.umulh: RewriteMulh(PrimitiveType.UInt64, m.UMul); break; case Mnemonic.uxtb: RewriteUSxt(Domain.UnsignedInt, 8); break; case Mnemonic.uxth: RewriteUSxt(Domain.UnsignedInt, 16); break; case Mnemonic.uxtl: RewriteSimdUnary("__uxtl_{0}", Domain.UnsignedInt); break; case Mnemonic.uxtw: RewriteUSxt(Domain.UnsignedInt, 32); break; case Mnemonic.xtn: RewriteSimdUnary("__xtn_{0}", Domain.None); break; } yield return(new RtlInstructionCluster(instr.Address, instr.Length, cluster.ToArray()) { Class = rtlc, }); } }
public IEnumerator <RtlInstructionCluster> GetEnumerator() { while (dasm.MoveNext()) { this.instr = dasm.Current; this.iclass = instr.InstructionClass; var instrs = new List <RtlInstruction>(); m = new RtlEmitter(instrs); switch (instr.Opcode) { default: EmitUnitTest(); goto case Opcode.invalid; case Opcode.invalid: m.Invalid(); break; case Opcode.add: RewriteAdd(true); break; case Opcode.add_c: RewriteAdd_c(); break; case Opcode.add_l: RewriteAdd(false); break; case Opcode.addb: RewriteAddb(); break; case Opcode.addi: RewriteAddi(false); break; case Opcode.addi_tc: RewriteAddi(true); break; case Opcode.addib: RewriteAddb(); break; case Opcode.addil: RewriteAddi(false); break; case Opcode.and: RewriteLogical(m.And); break; case Opcode.andcm: RewriteLogical((a, b) => m.And(a, m.Comp(b))); break; case Opcode.b_l: RewriteBranch(); break; case Opcode.be: RewriteBe(); break; case Opcode.be_l: RewriteBe(); break; case Opcode.bv: RewriteBv(); break; case Opcode.cmpb: RewriteCmpb(0, 1); break; case Opcode.cmpib: RewriteCmpb(1, 0); break; case Opcode.@break: RewriteBreak(); break; case Opcode.depwi: RewriteDepwi(); break; case Opcode.diag: RewriteDiag(); break; case Opcode.extrw: RewriteExtrw(); break; case Opcode.fadd: RewriteFpArithmetic(m.FAdd); break; case Opcode.fcpy: RewriteFcpy(); break; case Opcode.fid: RewriteFid(); break; case Opcode.fldd: RewriteFld(PrimitiveType.Real64); break; case Opcode.fldw: RewriteFld(PrimitiveType.Real32); break; case Opcode.fmpy: RewriteFpArithmetic(m.FMul); break; case Opcode.fstd: RewriteFst(PrimitiveType.Real64); break; case Opcode.fstw: RewriteFst(PrimitiveType.Real32); break; case Opcode.fsub: RewriteFpArithmetic(m.FSub); break; case Opcode.ldb: RewriteLd(PrimitiveType.Byte); break; case Opcode.ldd: RewriteLd(PrimitiveType.Word64); break; case Opcode.ldh: RewriteLd(PrimitiveType.Word16); break; case Opcode.ldil: RewriteLdil(); break; case Opcode.ldo: RewriteLdo(); break; case Opcode.ldsid: RewriteLdsid(); break; case Opcode.ldw: RewriteLd(PrimitiveType.Word32); break; case Opcode.ldwa: RewriteLd(PrimitiveType.Word32); break; case Opcode.mfctl: RewriteMfctl(); break; case Opcode.mfctl_w: RewriteMfctl(); break; case Opcode.mtctl: RewriteMtctl(); break; case Opcode.mtsm: RewriteMtsm(); break; case Opcode.mtsp: RewriteMtsp(); break; case Opcode.or: RewriteOr(); break; case Opcode.rfi: RewriteRfi("__rfi"); break; case Opcode.rfi_r: RewriteRfi("__rfi_r"); break; case Opcode.shladd: RewriteShladd(); break; case Opcode.shrpd: RewriteShrp(PrimitiveType.Word64, PrimitiveType.Word128); break; case Opcode.shrpw: RewriteShrp(PrimitiveType.Word32, PrimitiveType.Word64); break; case Opcode.stb: RewriteSt(PrimitiveType.Byte); break; case Opcode.std: RewriteSt(PrimitiveType.Word64); break; case Opcode.stda: RewriteSt(PrimitiveType.Word64); break; case Opcode.sth: RewriteSt(PrimitiveType.Word16); break; case Opcode.stw: RewriteSt(PrimitiveType.Word32); break; case Opcode.sub: RewriteSub(); break; case Opcode.subi: RewriteSubi(); break; } yield return(new RtlInstructionCluster(instr.Address, instr.Length, instrs.ToArray()) { Class = iclass, }); } }