public Constant GetFlagGroup(uint mask) { bool sigle = Bits.IsSingleBitSet(mask); if ((mask & validFlags) == mask) { if (sigle) { return(Constant.Bool((flags & mask) != 0)); } else { return(Constant.Byte((byte)(flags & mask))); } } else { return(Constant.Invalid); } }
public void CceShlRclPattern() { var p = new ProgramBuilder(); p.Add("main", (m) => { var C = m.Flags("C"); var r1 = MockReg(m, 1); var r2 = MockReg(m, 2); m.Assign(r1, m.Shl(r1, 1)); m.Assign(C, m.Cond(r1)); m.Assign(r2, m.Fn( new PseudoProcedure(PseudoProcedure.RolC, r2.DataType, 2), r2, Constant.Byte(1), C)); m.Assign(C, m.Cond(r2)); m.MStore(m.Word32(0x3000), r1); m.MStore(m.Word32(0x3004), r2); }); RunTest(p, "Analysis/CceShlRclPattern.txt"); }
public void RewriteRotation(string procName) { Expression opDst; if (di.op2 != null) { var opSrc = orw.RewriteSrc(di.op1, di.Address); opDst = orw.RewriteDst(di.op2, di.Address, opSrc, (s, d) => host.PseudoProcedure(procName, di.dataWidth, d, s)); } else { opDst = orw.RewriteDst(di.op1, di.Address, Constant.Byte(1), (s, d) => host.PseudoProcedure(procName, PrimitiveType.Word32, d, s)); } emitter.Assign( orw.FlagGroup(FlagM.CF | FlagM.NF | FlagM.ZF), emitter.Cond(opDst)); emitter.Assign(orw.FlagGroup(FlagM.VF), Constant.False()); }
public void CceShrRcrPattern() { var p = new ProgramBuilder(new FakeArchitecture(new ServiceContainer())); p.Add("main", (m) => { var C = m.Flags("C"); var r1 = MockReg(m, 1); var r2 = MockReg(m, 2); m.Assign(r1, m.Shr(r1, 1)); m.Assign(C, m.Cond(r1)); m.Assign(r2, m.Fn( new IntrinsicProcedure(IntrinsicProcedure.RorC, true, r2.DataType, 2), r2, Constant.Byte(1), C)); m.Assign(C, m.Cond(r2)); m.MStore(m.Word32(0x3000), r2); m.MStore(m.Word32(0x3004), r1); m.Return(); }); RunTest(p, "Analysis/CceShrRcrPattern.txt"); }
protected override void BuildBody() { var sp = Frame.EnsureRegister(Registers.sp); var a = Frame.EnsureRegister(Registers.a); var c = Frame.EnsureRegister(Registers.c); var h = Frame.EnsureRegister(Registers.h); var l = Frame.EnsureRegister(Registers.l); var C = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("C")); var Z = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("Z")); var SZC = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("SZC")); var SZP = Frame.EnsureFlagGroup(Architecture.GetFlagGroup("SZP")); var rorc = new IntrinsicProcedure( IntrinsicProcedure.RorC, true, PrimitiveType.Byte, 3); Assign(sp, Frame.FramePointer); Label("m1Loop"); Assign(a, h); Assign(a, Or(a, a)); Assign(SZC, Cond(a)); Assign(C, Constant.False()); Assign(a, Shr(a, Constant.Byte(1))); Assign(C, Cond(a)); Assign(h, a); Assign(a, l); Assign(a, Fn(rorc, a, Constant.Byte(1), C)); Assign(C, Cond(a)); Assign(l, a); Assign(c, ISub(c, 1)); Assign(SZP, Cond(c)); BranchIf(Test(ConditionCode.NE, Z), "m1Loop"); Label("m2Done"); MStore(Word32(0x1000), l); MStore(Word32(0x1001), h); Return(); }
private Expression RewriteSrc(MachineOperand op) { switch (op) { case RegisterOperand regOp: if (regOp.Register == Registers.pc) { return(instr.Address + instr.Length); } else { return(binder.EnsureRegister(regOp.Register)); } case ImmediateOperand immOp: if (dasm.Current.DataWidth !.Size == 1) { return(Constant.Byte((byte)immOp.Value.ToInt32())); } else { return(immOp.Value); }
private ImmediateOperand GetImmediateUnsignedField(string fmt, ref int i, uint wInstr) { int offset = 0; while (Char.IsDigit(fmt[++i])) { offset = offset * 10 + (fmt[i] - '0'); } ++i; int size = 0; while (i < fmt.Length && Char.IsDigit(fmt[i])) { size = size * 10 + (fmt[i] - '0'); if (i >= fmt.Length) { break; } ++i; } uint mask = (1u << size) - 1u; return(new ImmediateOperand(Constant.Byte((byte)((wInstr >> offset) & mask)))); }
public PICInstructionMem2Mem(Mnemonic mnemonic, byte srcidx, byte dstidx) : base(mnemonic, new PICOperandFSRIndexation(Constant.Byte(srcidx)), new PICOperandFSRIndexation(Constant.Byte(dstidx))) { }
public void SefConstant() { var c = Constant.Byte(3); Assert.IsFalse(sef.HasSideEffect(c)); }
public void Bctr() { Add(new PowerPcInstruction(Opcode.bcctr, new ImmediateOperand(Constant.Byte(0x20)), null, null, false)); }
public PICInstructionMem2Mem(Mnemonic mnemonic, byte srcidx, uint dstaddr) : base(mnemonic, new PICOperandFSRIndexation(Constant.Byte(srcidx)), new PICOperandDataMemoryAddress(dstaddr)) { }
private static Pdp11Instruction NonDoubleOperandInstruction(ushort opcode, Pdp11Disassembler dasm) { switch ((opcode >> 8)) { case 0x01: return(dasm.BranchInstruction(opcode, Opcode.br)); case 0x02: return(dasm.BranchInstruction(opcode, Opcode.bne)); case 0x03: return(dasm.BranchInstruction(opcode, Opcode.beq)); case 0x04: return(dasm.BranchInstruction(opcode, Opcode.bge)); case 0x05: return(dasm.BranchInstruction(opcode, Opcode.blt)); case 0x06: return(dasm.BranchInstruction(opcode, Opcode.bgt)); case 0x07: return(dasm.BranchInstruction(opcode, Opcode.ble)); case 0x80: return(dasm.BranchInstruction(opcode, Opcode.bpl)); case 0x81: return(dasm.BranchInstruction(opcode, Opcode.bmi)); case 0x82: return(dasm.BranchInstruction(opcode, Opcode.bhi)); case 0x83: return(dasm.BranchInstruction(opcode, Opcode.blos)); case 0x84: return(dasm.BranchInstruction(opcode, Opcode.bvc)); case 0x85: return(dasm.BranchInstruction(opcode, Opcode.bvs)); case 0x86: return(dasm.BranchInstruction(opcode, Opcode.bcc)); case 0x87: return(dasm.BranchInstruction(opcode, Opcode.bcs)); } var dataWidth = dasm.DataWidthFromSizeBit(opcode & 0x8000u); int cop = 1; MachineOperand op1 = null; MachineOperand op2 = null; Opcode oc = Opcode.illegal; switch ((opcode >> 6) & 0x3FF) { case 0x000: switch (opcode & 0x3F) { case 0x00: cop = 0; oc = Opcode.halt; break; case 0x01: cop = 0; oc = Opcode.wait; break; case 0x02: cop = 0; oc = Opcode.rti; break; case 0x03: cop = 0; oc = Opcode.bpt; break; case 0x04: cop = 0; oc = Opcode.iot; break; case 0x05: cop = 0; oc = Opcode.reset; break; case 0x06: cop = 0; oc = Opcode.rtt; break; case 0x07: cop = 0; oc = Opcode.illegal; break; } break; case 0x001: op1 = dasm.DecodeOperand(opcode); oc = Opcode.jmp; break; case 0x002: switch (opcode & 0x38) { case 0: op1 = dasm.DecodeOperand(opcode & 7); oc = Opcode.rts; break; case 3: op1 = dasm.DecodeOperand(opcode); oc = Opcode.spl; break; case 0x20: case 0x28: case 0x30: case 0x38: return(dasm.DecodeCondCode(opcode)); } break; case 0x003: oc = Opcode.swab; op1 = dasm.DecodeOperand(opcode); dataWidth = PrimitiveType.Byte; break; case 0x020: case 0x021: case 0x022: case 0x023: case 0x024: case 0x025: case 0x026: case 0x027: oc = Opcode.jsr; cop = 2; op1 = Reg(opcode >> 6, dasm); op2 = dasm.DecodeOperand(opcode); dataWidth = PrimitiveType.Word16; break; case 0x220: case 0x221: case 0x222: case 0x223: oc = Opcode.emt; op1 = new ImmediateOperand(Constant.Byte((byte)opcode)); break; case 0x224: case 0x225: case 0x226: case 0x227: oc = Opcode.trap; op1 = new ImmediateOperand(Constant.Byte((byte)opcode)); break; case 0x028: case 0x228: oc = dataWidth.Size == 1 ? Opcode.clrb : Opcode.clr; op1 = dasm.DecodeOperand(opcode); break; case 0x029: case 0x229: oc = Opcode.com; op1 = dasm.DecodeOperand(opcode); break; case 0x02A: case 0x22A: oc = Opcode.inc; op1 = dasm.DecodeOperand(opcode); break; case 0x02B: case 0x22B: oc = Opcode.dec; op1 = dasm.DecodeOperand(opcode); break; case 0x02C: case 0x22C: oc = Opcode.neg; op1 = dasm.DecodeOperand(opcode); break; case 0x02D: case 0x22D: oc = Opcode.adc; op1 = dasm.DecodeOperand(opcode); break; case 0x02E: case 0x22E: oc = Opcode.sbc; op1 = dasm.DecodeOperand(opcode); break; case 0x02F: case 0x22F: oc = Opcode.tst; op1 = dasm.DecodeOperand(opcode); break; case 0x030: case 0x230: oc = Opcode.ror; op1 = dasm.DecodeOperand(opcode); break; case 0x031: case 0x231: oc = Opcode.rol; op1 = dasm.DecodeOperand(opcode); break; case 0x032: case 0x232: oc = Opcode.asr; op1 = dasm.DecodeOperand(opcode); break; case 0x033: case 0x233: oc = Opcode.asl; op1 = dasm.DecodeOperand(opcode); break; case 0x034: oc = Opcode.mark; op1 = new ImmediateOperand(Constant.Byte((byte)opcode)); break; case 0x234: oc = Opcode.mtps; op1 = dasm.DecodeOperand(opcode); break; case 0x035: oc = Opcode.mfpi; op1 = dasm.DecodeOperand(opcode); break; case 0x235: oc = Opcode.mfpd; op1 = dasm.DecodeOperand(opcode); break; case 0x036: oc = Opcode.mtpi; op1 = dasm.DecodeOperand(opcode); break; case 0x236: oc = Opcode.mtpd; op1 = dasm.DecodeOperand(opcode); break; case 0x037: oc = Opcode.sxt; op1 = dasm.DecodeOperand(opcode); break; case 0x237: oc = Opcode.mfps; op1 = dasm.DecodeOperand(opcode); break; } if (cop > 0 && op1 == null || cop > 1 && op2 == null) { return(new Pdp11Instruction { Opcode = Opcode.illegal }); } return(new Pdp11Instruction { Opcode = oc, DataWidth = dataWidth, op1 = op1, op2 = op2, }); }
private Expression RewriteSrc(MachineOperand op) { var memOp = op as MemoryOperand; if (memOp != null) { var r = frame.EnsureRegister(memOp.Register); var tmp = frame.CreateTemporary(op.Width); switch (memOp.Mode) { default: throw new AddressCorrelatedException( instrs.Current.Address, "Not implemented: addressing mode {0}.", memOp.Mode); case AddressMode.RegDef: return(m.Load(this.instrs.Current.DataWidth, r)); case AddressMode.Absolute: return(m.Load( instrs.Current.DataWidth, Address.Ptr16(memOp.EffectiveAddress))); case AddressMode.AutoIncr: m.Assign(tmp, m.Load(op.Width, r)); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoIncrDef: m.Assign(tmp, m.Load(op.Width, m.Load(PrimitiveType.Ptr16, r))); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoDecr: m.Assign(r, m.ISub(r, memOp.Width.Size)); return(m.Load(op.Width, r)); case AddressMode.AutoDecrDef: m.Assign(r, m.ISub(r, memOp.Width.Size)); m.Assign(tmp, m.Load(op.Width, m.Load(PrimitiveType.Ptr16, r))); return(tmp); case AddressMode.Indexed: if (memOp.Register == Registers.pc) { var offset = (short)memOp.EffectiveAddress; var addrBase = (long)rtlCluster.Address.ToLinear(); var addr = Address.Ptr16((ushort)(2 + addrBase + offset)); return(m.Load(memOp.Width, addr)); } else { return(m.Load( this.instrs.Current.DataWidth, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))); } case AddressMode.IndexedDef: return(m.Load( this.instrs.Current.DataWidth, m.Load( PrimitiveType.Ptr16, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress))))); } return(tmp); } var regOp = op as RegisterOperand; if (regOp != null) { return(frame.EnsureRegister(regOp.Register)); } var immOp = op as ImmediateOperand; if (immOp != null) { if (instrs.Current.DataWidth.Size == 1) { return(Constant.Byte((byte)immOp.Value.ToInt32())); } else { return(immOp.Value); } } var addrOp = op as AddressOperand; if (addrOp != null) { return(addrOp.Address); } throw new NotImplementedException(); }
void RewriteRlwinm() { var rd = RewriteOperand(instr.Operands[0]); var rs = RewriteOperand(instr.Operands[1]); byte sh = ((Constant)RewriteOperand(instr.Operands[2])).ToByte(); byte mb = ((Constant)RewriteOperand(instr.Operands[3])).ToByte(); byte me = ((Constant)RewriteOperand(instr.Operands[4])).ToByte(); uint maskBegin = (uint)(1ul << (32 - mb)); uint maskEnd = 1u << (31 - me); uint mask = maskBegin - maskEnd; //Extract and left justify immediate extlwi RA, RS, n, b rlwinm RA, RS, b, 0, n-1 32 > n > 0 //Extract and right justify immediate extrwi RA, RS, n, b rlwinm RA, RS, b+n, 32-n, 31 32 > n > 0 & b+n =< 32 //Insert from left immediate inslwi RA, RS, n, b rlwinm RA, RS, 32-b, b, (b+n)-1 b+n <=32 & 32>n > 0 & 32 > b >= 0 //Insert from right immediate insrwi RA, RS, n, b rlwinm RA, RS, 32-(b+n), b, (b+n)-1 b+n <= 32 & 32>n > 0 //Rotate left immediate rotlwi RA, RS, n rlwinm RA, RS, n, 0, 31 32 > n >= 0 //Rotate right immediate rotrwi RA, RS, n rlwinm RA, RS, 32-n, 0, 31 32 > n >= 0 //Rotate left rotlw RA, RS, b rlwinm RA, RS, RB, 0, 31 None //Shift left immediate slwi RA, RS, n rlwinm RA, RS, n, 0, 31-n 32 > n >= 0 //Shift right immediate srwi RA, RS, n rlwinm RA, RS, 32-n, n, 31 32 > n >= 0 //Clear left immediate clrlwi RA, RS, n rlwinm RA, RS, 0, n, 31 32 > n >= 0 //Clear right immediate clrrwi RA, RS, n rlwinm RA, RS, 0, 0, 31-n 32 > n >= 0 //Clear left and shift left immediate clrslwi RA, RS, b, n rlwinm RA, RS, b-n, 31-n b-n >= 0 & 32 > n >= 0 & 32 > b>= 0 if (sh == 0) { m.Assign(rd, m.And(rs, Constant.UInt32(mask))); } else if (mb == 32 - sh && me == 31) { m.Assign(rd, m.Shr(rs, (byte)(32 - sh))); } else if (mb == 0 && me == 31 - sh) { m.Assign(rd, m.Shl(rs, sh)); } else if (mb == 0 && me == 31) { if (sh < 16) { m.Assign(rd, host.PseudoProcedure(PseudoProcedure.Rol, PrimitiveType.Word32, rs, Constant.Byte(sh))); } else { m.Assign(rd, host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, rs, Constant.Byte((byte)(32 - sh)))); } } else if (me == 31) { int n = 32 - mb; int b = sh - n; mask = (1u << b) - 1; m.Assign(rd, m.And( m.Shr(rs, Constant.Byte((byte)n)), Constant.Word32(mask))); } else if (mb <= me) { if (me < 32 - sh) { // [ llll] // [ mmm....] m.Assign(rd, m.And( m.Shl(rs, Constant.Byte((byte)sh)), Constant.Word32(mask))); MaybeEmitCr0(rd); return; } else if (mb >= 32 - sh) { // [ ll] // [ m.] m.Assign(rd, m.And( m.Shr(rs, Constant.Byte((byte)(32 - sh))), Constant.Word32(mask))); MaybeEmitCr0(rd); return; } } else { //$TODO: yeah, this one is hard... m.Assign(rd, host.PseudoProcedure( "__rlwinm", PrimitiveType.Word32, rs, Constant.Byte(sh), Constant.Byte(mb), Constant.Byte(me))); } //Error,10034E20,rlwinm r9,r31,1D,1B,1D not handled yet. //Error,10028B50,rlwinm r8,r8,04,18,1B not handled yet. //Error,1002641C,rlwinm r4,r4,04,18,1B not handled yet. //Error,10026364,rlwinm r4,r4,04,18,1B not handled yet. //Error,1003078C,rlwinm r8,r8,04,1A,1B not handled yet. //Error,100294D4,rlwinm r0,r0,04,18,1B not handled yet. //Error,100338A0,rlwinm r4,r11,08,08,0F not handled yet. //rlwinm r12,r2,09,1D,09 MaybeEmitCr0(rd); }
private void Rewrite_CLRW() { m.Assign(Wreg, Constant.Byte(0)); m.Assign(binder.EnsureFlagGroup(PICRegisters.Z), Constant.Bool(true)); }
private void RewriteRldicr() { var rd = RewriteOperand(instr.Operands[0]); var rs = RewriteOperand(instr.Operands[1]); byte sh = ((Constant)RewriteOperand(instr.Operands[2])).ToByte(); byte me = ((Constant)RewriteOperand(instr.Operands[3])).ToByte(); ulong maskEnd = 0ul - (ulong)(1ul << (63 - me)); // Extract double word and right justify immediate | extrdi RA, RS, n, b | rldicl RA, RS, b + n, 64 - n | n > 0 // Rotate double word left immediate | rotldi RA, RS, n | rldicl RA, RS, n, 0 | None // Rotate double word right immediate | rotrdi RA, RS, n | rldicl RA, RS, 64 - n, 0 | None // Rotate double word right immediate | srdi RA, RS, n | rldicl RA, RS, 64 - n, n | n < 64 // Clear left double word immediate | clrldi RA, RS, n | rldicl RA, RS, 0, n | n < 64 // Extract double word and left justify immediate | extldi RA, RS, n, b | rldicr RA, RS, b, n - 1 | None // Shift left double word immediate | sldi RA, RS, n | rldicr RA, RS, n, 63 - n | None // Clear right double word immediate | clrrdi RA, RS, n | rldicr RA, RS, 0, 63 - n | None // Clear left double word and shift left immediate | clrlsldi RA, RS, b, n | rldic RA, RS, n, b - n | None // Insert double word from right immediate | insrdi RA, RS, n, b | rldimi RA, RS, 64 - (b + n), b | None // Rotate double word left | rotld RA, RS, RB | rldcl RA, RS, RB, 0 | None if (sh + me == 63) { // sldi m.Assign(rd, m.Shl(rs, sh)); } else if (me == 63) { // rotldi: The mask is 0b111.....111, so we have a full rotation m.Assign(rd, host.Intrinsic( IntrinsicProcedure.Rol, true, PrimitiveType.Word64, rs, Constant.Byte(sh))); } else if (me != 0 && sh > 0) { //$TODO: check this logic var wordSize = me - 1; if (wordSize <= 0) { iclass = InstrClass.Invalid; m.Invalid(); return; } var bitpos = 63 - sh; // convert to reko's little endian bit positions. var dt = PrimitiveType.CreateWord(wordSize); var slice = m.Convert(m.Slice(dt, rs, bitpos), dt, rd.DataType); m.Assign( rd, m.Shl(slice, 64 - wordSize)); } else if (sh == 0) { // No rotation, just mask the low bits. var mask = (ulong)-(1L << (63 - me)); m.Assign(rd, m.And(rs, mask)); } else { host.Error( instr.Address, string.Format("PowerPC instruction '{0}' is not supported yet.", instr)); EmitUnitTest(); iclass = InstrClass.Invalid; m.Invalid(); return; } MaybeEmitCr0(rd); }
void RewriteRldicl() { var rd = RewriteOperand(instr.Operands[0]); var rs = RewriteOperand(instr.Operands[1]); byte sh = ((Constant)RewriteOperand(instr.Operands[2])).ToByte(); byte mb = ((Constant)RewriteOperand(instr.Operands[3])).ToByte(); ulong maskBegin = (ulong)(1ul << (64 - mb)) - 1; if (sh == 0) { m.Assign(rd, m.And(rs, Constant.Word64(maskBegin))); } else if (sh + mb == 64) { m.Assign(rd, m.Shr(rs, (byte)mb)); } else if (sh == 0x3F && mb == 0x3F) { m.Assign(rd, m.Shr(rs, (byte)mb)); } else if (sh < mb) { m.Assign(rd, m.And( m.Shl(rs, (byte)sh), maskBegin)); } else if (sh == 0x39 && mb == 0x38) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x31 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x10 && mb == 0x2F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x08 && mb == 0x37) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x18 && mb == 0x27) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x20 && mb == 0x1F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x02 && mb == 0x1E) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x38 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x37 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x21 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x08 && mb == 0x30) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x3D && mb == 0x23) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x3E && mb == 0x22) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (mb == 0x00) { m.Assign(rd, host.PseudoProcedure(PseudoProcedure.Rol, rd.DataType, rs, Constant.Byte((byte)sh))); } else { host.Error( instr.Address, string.Format("PowerPC instruction '{0}' is not supported yet.", instr)); EmitUnitTest(); rtlc = InstrClass.Invalid; m.Invalid(); return; } MaybeEmitCr0(rd); }
void RewriteRldicl() { var rd = RewriteOperand(instr.Operands[0]); var rs = RewriteOperand(instr.Operands[1]); byte sh = ((Constant)RewriteOperand(instr.Operands[2])).ToByte(); byte mb = ((Constant)RewriteOperand(instr.Operands[3])).ToByte(); ulong maskBegin = (1ul << (64 - mb)) - 1; if (sh == 0) { m.Assign(rd, m.And(rs, Constant.Word64(maskBegin))); } else if (sh + mb == 64) { m.Assign(rd, m.Shr(rs, mb)); } else if (sh == 0x3F && mb == 0x3F) { m.Assign(rd, m.Shr(rs, mb)); } else if (sh < mb) { m.Assign(rd, m.And( m.Shl(rs, (byte)sh), maskBegin)); } else if (mb == 0x00) { m.Assign(rd, host.Intrinsic(IntrinsicProcedure.Rol, true, rd.DataType, rs, Constant.Byte((byte)sh))); } else { var beExtBitpos = (sh + mb) - 64; var extBitsize = 64 - mb; if (0 <= beExtBitpos && beExtBitpos < 64) { //$TODO: check this logic. var dtSlice = PrimitiveType.CreateWord(extBitsize); m.Assign(rd, m.Convert(m.Slice(dtSlice, rs, 63 - beExtBitpos), dtSlice, rd.DataType)); } else if (sh == 0x39 && mb == 0x38) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x31 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x10 && mb == 0x2F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x08 && mb == 0x37) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x18 && mb == 0x27) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x20 && mb == 0x1F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x02 && mb == 0x1E) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x38 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x37 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x21 && mb == 0x3F) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x08 && mb == 0x30) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x3D && mb == 0x23) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else if (sh == 0x3E && mb == 0x22) { m.Assign(rd, m.And( m.Shr(rs, (byte)(64 - sh)), maskBegin)); } else { host.Error( instr.Address, string.Format("PowerPC instruction '{0}' is not supported yet.", instr)); EmitUnitTest(); iclass = InstrClass.Invalid; m.Invalid(); return; } } MaybeEmitCr0(rd); }
public PICInstructionMem2Mem(Opcode opcode, byte srcidx, byte dstidx) : base(opcode, new PICOperandFSRIndexation(Constant.Byte(srcidx)), new PICOperandFSRIndexation(Constant.Byte(dstidx))) { }
public PICInstructionMem2Mem(Opcode opcode, byte srcidx, uint dstaddr) : base(opcode, new PICOperandFSRIndexation(Constant.Byte(srcidx)), new PICOperandDataMemoryAddress(dstaddr)) { }
private void RewriteSETF() { var(indMode, memPtr) = GetUnaryPtrs(instrCurr.Operands[0], out Expression memExpr); ArithAssignIndirect(memExpr, Constant.Byte(255), indMode, memPtr); }
public static ImmediateOperand Byte(byte value) { return(new ImmediateOperand(Constant.Byte(value))); }
private void Rewrite_CLRF() { GetSrc(out var srcMem); m.Assign(srcMem, Constant.Byte(0)); m.Assign(binder.EnsureFlagGroup(PICRegisters.Z), Constant.Bool(true)); }
void RewriteRlwinm() { var rd = RewriteOperand(instr.op1); var rs = RewriteOperand(instr.op2); byte sh = ((Constant)RewriteOperand(instr.op3)).ToByte(); byte mb = ((Constant)RewriteOperand(instr.op4)).ToByte(); byte me = ((Constant)RewriteOperand(instr.op5)).ToByte(); uint maskBegin = (uint)(1ul << (32 - mb)); uint maskEnd = 1u << (31 - me); uint mask = maskBegin - maskEnd; //Extract and left justify immediate extlwi RA, RS, n, b rlwinm RA, RS, b, 0, n-1 32 > n > 0 //Extract and right justify immediate extrwi RA, RS, n, b rlwinm RA, RS, b+n, 32-n, 31 32 > n > 0 & b+n =< 32 //Insert from left immediate inslwi RA, RS, n, b rlwinm RA, RS, 32-b, b, (b+n)-1 b+n <=32 & 32>n > 0 & 32 > b >= 0 //Insert from right immediate insrwi RA, RS, n, b rlwinm RA, RS, 32-(b+n), b, (b+n)-1 b+n <= 32 & 32>n > 0 //Rotate left immediate rotlwi RA, RS, n rlwinm RA, RS, n, 0, 31 32 > n >= 0 //Rotate right immediate rotrwi RA, RS, n rlwinm RA, RS, 32-n, 0, 31 32 > n >= 0 //Rotate left rotlw RA, RS, b rlwinm RA, RS, RB, 0, 31 None //Shift left immediate slwi RA, RS, n rlwinm RA, RS, n, 0, 31-n 32 > n >= 0 //Shift right immediate srwi RA, RS, n rlwinm RA, RS, 32-n, n, 31 32 > n >= 0 //Clear left immediate clrlwi RA, RS, n rlwinm RA, RS, 0, n, 31 32 > n >= 0 //Clear right immediate clrrwi RA, RS, n rlwinm RA, RS, 0, 0, 31-n 32 > n >= 0 //Clear left and shift left immediate clrslwi RA, RS, b, n rlwinm RA, RS, b-n, 31-n b-n >= 0 & 32 > n >= 0 & 32 > b>= 0 if (sh == 0) { emitter.Assign(rd, emitter.And(rs, Constant.UInt32(mask))); return; } else if (mb == 32 - sh && me == 31) { emitter.Assign(rd, emitter.Shr(rs, (byte)(32-sh))); return; } else if (mb == 0 && me == 31-sh) { emitter.Assign(rd, emitter.Shl(rs, sh)); return; } else if (mb == 0 && me == 31) { if (sh < 16) emitter.Assign(rd, host.PseudoProcedure(PseudoProcedure.Rol, PrimitiveType.Word32, rs, Constant.Byte(sh))); else emitter.Assign(rd, host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, rs, Constant.Byte((byte)(32 - sh)))); return; } else if (me == 31) { int n = 32 - mb; int b = sh - n; mask = (1u << b) - 1; emitter.Assign(rd, emitter.And( emitter.Shr(rs, Constant.Byte((byte)n)), Constant.Word32(mask))); return; } else if (mb <= me) { if (me < 32 - sh) { // [ llll] // [ mmm....] emitter.Assign(rd, emitter.And( emitter.Shl(rs, Constant.Byte((byte)sh)), Constant.Word32(mask))); return; } else if (mb >= 32 - sh) { // [ ll] // [ m.] emitter.Assign(rd, emitter.And( emitter.Shr(rs, Constant.Byte((byte)(32-sh))), Constant.Word32(mask))); return; } } else throw new AddressCorrelatedException(dasm.Current.Address, "{0} not handled yet.", dasm.Current); //Error,10034E20,rlwinm r9,r31,1D,1B,1D not handled yet. //Error,10028B50,rlwinm r8,r8,04,18,1B not handled yet. //Error,1002641C,rlwinm r4,r4,04,18,1B not handled yet. //Error,10026364,rlwinm r4,r4,04,18,1B not handled yet. //Error,1003078C,rlwinm r8,r8,04,1A,1B not handled yet. //Error,100294D4,rlwinm r0,r0,04,18,1B not handled yet. //Error,100338A0,rlwinm r4,r11,08,08,0F not handled yet. }
private void Rewrite_INCF() { GetSrcAndDst(out var srcMem, out var dstMem); m.Assign(dstMem, m.IAdd(srcMem, Constant.Byte(1))); SetStatusFlags(dstMem); }
public HExpr Byte(byte b) { return(MapToHandle(Constant.Byte(b))); }
private Expression RewriteSrc(MachineOperand op) { switch (op) { case RegisterOperand regOp: if (regOp.Register == Registers.pc) { return(instr.Address + instr.Length); } else { return(binder.EnsureRegister(regOp.Register)); } case ImmediateOperand immOp: if (dasm.Current.DataWidth.Size == 1) { return(Constant.Byte((byte)immOp.Value.ToInt32())); } else { return(immOp.Value); } case AddressOperand addrOp: return(addrOp.Address); case MemoryOperand memOp: var r = binder.EnsureRegister(memOp.Register); var tmp = binder.CreateTemporary(op.Width); switch (memOp.Mode) { default: throw new AddressCorrelatedException( dasm.Current.Address, "Not implemented: addressing mode {0}.", memOp.Mode); case AddressMode.RegDef: return(m.Mem(this.dasm.Current.DataWidth, r)); case AddressMode.Absolute: return(m.Mem( dasm.Current.DataWidth, Address.Ptr16(memOp.EffectiveAddress))); case AddressMode.AutoIncr: m.Assign(tmp, m.Mem(op.Width, r)); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoIncrDef: m.Assign(tmp, m.Mem(op.Width, m.Mem(PrimitiveType.Ptr16, r))); m.Assign(r, m.IAdd(r, memOp.Width.Size)); break; case AddressMode.AutoDecr: m.Assign(r, m.ISub(r, memOp.Width.Size)); return(m.Mem(op.Width, r)); case AddressMode.AutoDecrDef: m.Assign(r, m.ISub(r, memOp.Width.Size)); m.Assign(tmp, m.Mem(op.Width, m.Mem(PrimitiveType.Ptr16, r))); return(tmp); case AddressMode.Indexed: if (memOp.Register == Registers.pc) { var offset = (short)memOp.EffectiveAddress; var addrBase = (long)instr.Address.ToLinear(); var addr = Address.Ptr16((ushort)(2 + addrBase + offset)); return(m.Mem(memOp.Width, addr)); } else { return(m.Mem( this.dasm.Current.DataWidth, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress)))); } case AddressMode.IndexedDef: if (memOp.Register == Registers.pc) { var addr = this.dasm.Current.Address + this.dasm.Current.Length + memOp.EffectiveAddress; m.Assign(tmp, m.Mem(PrimitiveType.Ptr16, addr)); m.Assign(tmp, m.Mem(memOp.Width, tmp)); return(tmp); } else { return(m.Mem( this.dasm.Current.DataWidth, m.Mem( PrimitiveType.Ptr16, m.IAdd(r, Constant.Word16(memOp.EffectiveAddress))))); } } return(tmp); } throw new NotImplementedException(); }
private Expression Ror1(Expression e) { return(host.Intrinsic(IntrinsicProcedure.Ror, true, e.DataType, e, Constant.Byte(1))); }
private void RewriteSel() { var bank = (RegisterBankOperand)instr.Operands[0]; m.SideEffect(host.PseudoProcedure("__select_register_bank", VoidType.Instance, Constant.Byte((byte)bank.Bank))); }
private Expression Ror1(Expression e) { return(host.PseudoProcedure(PseudoProcedure.Ror, e.DataType, e, Constant.Byte(1))); }