public ArmMemoryOperand(PrimitiveType width, RegisterStorage regBase, MachineOperand offset) : base(width) { if (width == null) throw new ArgumentNullException("width"); Base = regBase; Offset = offset; }
public ShiftOperand(MachineOperand op, Opcode opcode, MachineOperand shAmt) : base(op.Width) { this.Operand = op; this.Opcode = opcode; this.Shift = shAmt; }
public void Write(MachineOperand op, MachineInstructionWriter writer) { var imm = op as ImmediateOperand; if (imm != null) { writer.Write("#"); int imm8 = imm.Value.ToInt32(); if (imm8 > 256 && ((imm8 & (imm8 - 1)) == 0)) { /* only one bit set, and that later than bit 8. * Represent as 1<<... . */ writer.Write("1<<"); { uint n = 0; while ((imm8 & 15) == 0) { n += 4; imm8 = imm8 >> 4; } // Now imm8 is 1, 2, 4 or 8. n += (uint)((0x30002010 >> (int)(4 * (imm8 - 1))) & 15); writer.Write(n); } } else { var fmt = (-9 <= imm8 && imm8 <= 9) ? "{0}{1}" : "&{0}{1:X}"; var sign = ""; if (((int)imm8) < 0 && ((int)imm8) > -100) { imm8 = -imm8; sign = "-"; } writer.Write(fmt,sign,imm8); } return; } var adr = op as AddressOperand; if (adr != null) { adr.Write(false, writer); return; } var mem = op as ArmMemoryOperand; if (mem != null) { mem.Write(false, writer); return; } var sh = op as ShiftOperand; if (sh != null) { sh.Write(false, writer); return; } if (op == null) writer.Write("<null>"); else op.Write(false, writer); }
private void Write(MachineOperand op, MachineInstructionWriter writer) { var reg = op as RegisterOperand; if (reg != null) { writer.Write("%{0}", reg.Register.Name); return; } var imm = op as ImmediateOperand; if (imm != null) { writer.Write(imm.Value.ToString()); return; } var mem = op as MemoryOperand; if (mem != null) { mem.Write(false, writer); return; } var idx = op as IndexedMemoryOperand; if (idx != null) { idx.Write(false, writer); return; } writer.Write(op.ToString()); }
public PowerPcInstruction(Opcode opcode, MachineOperand op1, MachineOperand op2, MachineOperand op3, bool setsCR0) { this.opcode = opcode; this.op1 = op1; this.op2 = op2; this.op3 = op3; this.setsCR0 = setsCR0; }
private void OpToString(MachineOperand op, MachineInstructionWriter writer) { if (op is ImmediateOperand) { writer.Write("#" + op.ToString()); } else { writer.Write(op.ToString()); } }
public IntelInstruction(Opcode code, PrimitiveType dataWidth, PrimitiveType addrWidth, params MachineOperand [] ops) { this.code = code; this.dataWidth = dataWidth; this.addrWidth = addrWidth; if (ops.Length >= 1) { op1 = ops[0]; if (ops.Length >= 2) { op2 = ops[1]; if (ops.Length == 3) op3 = ops[2]; else if (ops.Length >= 4) throw new ArgumentException("Too many operands."); } } }
public Expression Transform(IntelInstruction instr, MachineOperand op, PrimitiveType opWidth, X86State state) { var reg = op as RegisterOperand; if (reg != null) return AluRegister(reg); var mem = op as MemoryOperand; if (mem != null) return CreateMemoryAccess(instr, mem, opWidth, state); var imm = op as ImmediateOperand; if (imm != null) return CreateConstant(imm, opWidth); var fpu = op as FpuOperand; if (fpu != null) return FpuRegister(fpu.StNumber, state); var addr = op as AddressOperand; if (addr != null) return addr.Address; throw new NotImplementedException(string.Format("Operand {0}", op)); }
private void Call(MachineOperand op) { Push(InstructionPointer.ToLinear() + (uint)dasm.Current.Length); // Push return value on stack TWord l = Read(op); if (envEmulator.InterceptCall(this, l)) return; InstructionPointer = Address.Ptr32(l); }
private void Rol(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); byte sh = (byte)Read(src); TWord r = (l << sh) | (l >> (32 - sh)); Write(dst, r); Flags = (r == 0 ? Zmask : 0u); // Zero }
private void Shr(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); byte sh = (byte)Read(src); TWord r = l >> sh; Write(dst, r); Flags = (r == 0 ? Zmask : 0u); // Zero }
private bool ImplicitWidth(MachineOperand op) { return op is RegisterOperand || op is X86AddressOperand || op is FpuOperand; }
private void Add(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); TWord r = Read(src); if (src.Width.Size < dst.Width.Size) r = (TWord)(sbyte)r; TWord sum = l + r; Write(dst, sum); uint ov = ((~(l ^ r) & (l ^ sum)) & 0x80000000u) >> 20; Flags = (r > sum ? 1u : 0u) | // Carry (sum == 0 ? 1u << 6: 0u) | // Zero (ov) // Overflow ; }
private void Inc(MachineOperand op) { TWord old = Read(op); TWord gnu = old + 1; Write(op, gnu); uint ov = ((old ^ gnu) & gnu & 0x80000000u) >> 20; Flags = Flags & Cmask | // Carry preserved (gnu == 0 ? Zmask : 0u) | // Zero ov; //$BUG: }
private TWord Read(MachineOperand op) { var r = op as RegisterOperand; if (r != null) { return ReadRegister(r.Register); } var i = op as ImmediateOperand; if (i != null) return i.Value.ToUInt32(); var a = op as AddressOperand; if (a != null) return a.Address.ToUInt32(); var m = op as MemoryOperand; if (m != null) { TWord ea = GetEffectiveAddress(m); byte b; switch (op.Width.Size) { case 1: if (!img.TryReadByte(Address.Ptr32(ea), out b)) throw new IndexOutOfRangeException(); else return b; case 4: return img.ReadLeUInt32(Address.Ptr32(ea)); } throw new NotImplementedException(); } throw new NotImplementedException(); }
private void Sub(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); TWord r = Read(src); if (src.Width.Size < dst.Width.Size) r = (TWord)(sbyte)r; r = ~r + 1u; // Two's complement subtraction. TWord diff = l + r; Write(dst, diff); uint ov = ((~(l ^ r) & (l ^ diff)) & 0x80000000u) >> 20; Flags = (l < diff ? 1u : 0u) | // Carry (diff == 0 ? Zmask : 0u) | // Zero (ov) // Overflow ; }
private void Jump(MachineOperand op) { TWord l = Read(op); InstructionPointer = Address.Ptr32(l); }
public ParsedOperand(MachineOperand op) { this.op = op; this.sym = null; }
public ParsedOperand(MachineOperand op, Symbol sym) { this.op = op; this.sym = sym; }
public ParsedOperand(MachineOperand op, Symbol sym, bool longJmp) { this.op = op; this.sym = sym; this.longJmp = longJmp; }
private void Cmp(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); TWord r = Read(src); if (src.Width.Size < dst.Width.Size) r = (TWord)(sbyte)r; r = ~r + 1u; TWord diff = l + r; uint ov = ((~(l ^ r) & (l ^ diff)) & 0x80000000u) >> 20; Flags = (l < diff ? 1u : 0u) | // Carry (diff == 0 ? Zmask : 0u) | // Zero (ov) // Overflow ; }
public ShiftOperand(Opcode opcode, MachineOperand op) : base(op.Width) { this.Opcode = opcode; this.Shift = op; }
private void And(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); TWord r = Read(src); if (src.Width.Size < dst.Width.Size) r = (TWord)(sbyte)r; var and = l & r; Write(dst, and); Flags = 0 | // Clear Carry (and == 0 ? Zmask : 0u) | // Zero 0; // Clear Overflow }
public ShiftOperand(MachineOperand op, Opcode opcode, int shAmt) : this(op, opcode, ArmImmediateOperand.Byte((byte)shAmt)) { }
private void Xor(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); TWord r = Read(src); if (src.Width.Size < dst.Width.Size) r = (TWord)(sbyte)r; var xor = l ^ r; Write(dst, xor); Flags = 0 | // Carry (xor == 0 ? Zmask : 0u) | // Zero 0; // Overflow }
public void Loop(MachineOperand op) { var c = ReadRegister(X86.Registers.ecx) -1u; WriteRegister(X86.Registers.ecx, c); if (c != 0) InstructionPointer = ((AddressOperand)op).Address; }
private void Write(MachineOperand op, TWord w) { var r = op as RegisterOperand; if (r != null) { WriteRegister(r.Register, w); return; } var m = op as MemoryOperand; if (m != null) { var ea = GetEffectiveAddress(m); switch (op.Width.Size) { case 1: img.WriteByte(Address.Ptr32(ea), (byte)w); return; case 4: img.WriteLeUInt32(Address.Ptr32(ea), (UInt32)w); return; } throw new NotImplementedException(); } throw new NotImplementedException(); }
private void Branch(ConditionCode code, MachineOperand op) { emitter.Branch(emitter.Test(code, orw.FlagGroup(FlagM.FPUF)), OperandAsCodeAddress( op), RtlClass.ConditionalTransfer); }
private void Xchg(MachineOperand op1, MachineOperand op2) { var tmp = Read(op1); Write(op1, Read(op2)); Write(op2, tmp); }
private void Adc(MachineOperand dst, MachineOperand src) { TWord l = Read(dst); TWord r = Read(src); TWord sum = l + r + (Flags & 1); Write(dst, sum); var newCy = ((l & r) | ((l | r) & (~(sum)))) >> 31; uint ov = ((~(l ^ r) & (l ^ sum)) & 0x80000000u) >> 20; Flags = (newCy) | // Carry (sum == 0 ? 1u << 6 : 0u) | // Zero (ov) // Overflow ; }