/*
* $Id$
*
* Copyright (C) 2003-2016 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.assembler.x86;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import org.jnode.assembler.BootImageNativeStream;
import org.jnode.assembler.Label;
import org.jnode.assembler.NativeStream;
import org.jnode.assembler.ObjectResolver;
import org.jnode.assembler.UnresolvedObjectRefException;
import org.jnode.assembler.x86.X86Register.CRX;
import org.jnode.assembler.x86.X86Register.GPR;
import org.jnode.assembler.x86.X86Register.GPR32;
import org.jnode.assembler.x86.X86Register.GPR64;
import org.jnode.assembler.x86.X86Register.MMX;
import org.jnode.assembler.x86.X86Register.SR;
import org.jnode.vm.CpuID;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.x86.X86CpuID;
/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
* @author Levente S\u00e1ntha (lsantha@users.sourceforge.net)
*/
public abstract class X86Assembler extends NativeStream implements BootImageNativeStream, X86Constants {
/**
* Current mode is 32-bit
*/
protected final boolean code32;
/**
* Current mode is 64-bit
*/
protected final boolean code64;
protected final X86CpuID cpuId;
protected final Mode mode;
protected X86Assembler() {
this.cpuId = X86CpuID.createID("pentium");
this.mode = X86Constants.Mode.CODE32;
this.code32 = mode.is32();
this.code64 = mode.is64();
}
/**
* Initialize this instance
*
* @param cpuId
*/
public X86Assembler(X86CpuID cpuId, Mode mode) {
this.cpuId = cpuId;
this.mode = mode;
this.code32 = mode.is32();
this.code64 = mode.is64();
}
/**
* Align on a given value
*
* @param value
* @return The number of bytes needed to align.
*/
public abstract int align(int value);
/**
* Gets a 32-bit integer from a given offset.
*
* @param offset
* @return int
*/
public abstract int get32(int offset);
/**
* Gets an 8-bit integer from a given offset.
*
* @param offset
* @return int
*/
public abstract int get8(int offset);
/**
* Returns the base address.
*
* @return long
*/
public abstract long getBaseAddr();
/**
* Return the actual bytes. This array may be longer then getLength() *
*
* @return The actual bytes
*/
public abstract byte[] getBytes();
/**
* Gets the identification of the CPU for which this stream will produce
* data.
*/
public final CpuID getCPUID() {
return cpuId;
}
/**
* Get the length in bytes of valid data
*
* @return the length of valid data
*/
public abstract int getLength();
/**
* Gets the operating mode.
*
* @return the target operating mode.
*/
public final X86Constants.Mode getMode() {
return mode;
}
/**
* Gets an objectref for a given object.
*
* @param keyObj
* @return ObjectRef
*/
public abstract ObjectRef getObjectRef(Object keyObj);
/**
* Gets all references of objects as instanceof ObjectRef.
*
* @return Collection
*/
public abstract Collection<? extends ObjectRef> getObjectRefs();
/**
* Gets the number of all references of objects.
*
* @return Collection
*/
public abstract int getObjectRefsCount();
/**
* @return ObjectResolver
*/
public abstract ObjectResolver getResolver();
/**
* Gets all unresolved references of objects as instanceof ObjectRef.
*
* @return Collection
*/
public abstract Collection<?> getUnresolvedObjectRefs();
/**
* Gets the size of a word in bytes.
*
* @return 4 or 8 depending on the operating mode.
*/
public final int getWordSize() {
return mode.is32() ? 4 : 8;
}
/**
* Gets the identification of the CPU for which this stream will produce
* data.
*/
public final X86CpuID getX86CPUID() {
return cpuId;
}
/**
* Are there unresolved references?
*
* @return True if there are unresolved references, false otherwise
*/
public abstract boolean hasUnresolvedObjectRefs();
/**
* @return Returns the code32.
*/
public final boolean isCode32() {
return this.code32;
}
/**
* @return Returns the code64.
*/
public final boolean isCode64() {
return this.code64;
}
/**
* Is logging enabled. This method will only return true on on debug like
* implementations.
*
* @return boolean
*/
public abstract boolean isLogEnabled();
/**
* Is this a text stream. In that case there is not actual generated code,
* so length calculations are invalid.
*
* @return true or false
*/
public abstract boolean isTextStream();
/**
* Write a log message. This method is only implemented on debug like
* implementations.
*
* @param msg
*/
public abstract void log(Object msg);
/**
* Sets a 32-bit integer at a given offset.
*
* @param offset
* @param v32
*/
public abstract void set32(int offset, int v32);
/**
* Sets an 16-bit integer at a given offset.
*
* @param offset
* @param v16
*/
public abstract void set16(int offset, int v16);
/**
* Sets an 8-bit integer at a given offset.
*
* @param offset
* @param v8
*/
public abstract void set8(int offset, int v8);
public final void setWord(int offset, long word) {
if (mode.is32()) {
set32(offset, (int) word);
} else {
set64(offset, word);
}
}
/**
* Sets the target offset of a given label to the current position.
*
* @param label
*/
public abstract ObjectRef setObjectRef(Object label);
/**
* Sets the resolver.
*
* @param resolver The resolver to set
*/
public abstract void setResolver(ObjectResolver resolver);
/**
* Start a new object and write its header, returning an
* {@link org.jnode.assembler.NativeStream.ObjectInfo} instance.
* The <code>markEnd</code> method must be called on the ObjectInfo
* instance once all data has been written for the object started.
*
* @param cls
* @return The info for the started object
*/
public abstract ObjectInfo startObject(VmType<?> cls);
/**
* Remove count bytes from the end of the generated stream.
*
* @param count
*/
public abstract void trim(int count);
/**
* Append a series of bytes from the current position.
*
* @param data
* @param ofs
* @param len
*/
public abstract void write(byte[] data, int ofs, int len);
/**
* Append a 16-bit int from the current position.
*
* @param v16
*/
public abstract void write16(int v16);
/**
* Append a 32-bit int from the current position.
*
* @param v32
*/
public abstract void write32(int v32);
/**
* Append a 64-bit int from the current position.
*
* @param v64
*/
public abstract void write64(long v64);
/**
* Append a 8-bit int from the current position.
*
* @param v8
*/
public abstract void write8(int v8);
public final void writeWord(long word) {
if (mode.is32()) {
write32((int) word);
} else {
write64(word);
}
}
/**
* Create a ADC dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeADC(GPR dstReg, GPR srcReg);
/**
* Create a ADC dstReg, [srcReg+srcDisp]
*
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeADC(GPR dstReg, GPR srcReg, int srcDisp);
/**
* Create a ADC dstReg, imm32
*
* @param dstReg
* @param imm32
*/
public abstract void writeADC(GPR dstReg, int imm32);
/**
* Create a ADC [dstReg+dstDisp], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeADC(GPR dstReg, int dstDisp, GPR srcReg);
/**
* Create a ADC [dstReg+dstDisp], imm32
*
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeADC(int operandSize, GPR dstReg, int dstDisp, int imm32);
/**
* Create a ADD dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeADD(GPR dstReg, GPR srcReg);
/**
* Create a ADD dstReg, [srcReg+srcDisp]
*
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeADD(GPR dstReg, GPR srcReg, int srcDisp);
/**
* @param dstReg
* @param imm32
*/
public abstract void writeADD(GPR dstReg, int imm32);
/**
* @param operandSize
* @param dstDisp
* @param imm32
*/
public abstract void writeADD(int operandSize, int dstDisp, int imm32);
/**
* Create a ADD [dstReg+dstDisp], <srcReg>
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeADD(GPR dstReg, int dstDisp, GPR srcReg);
/**
* Create a ADD [dstReg+dstDisp], imm32
*
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeADD(int operandSize, GPR dstReg, int dstDisp, int imm32);
/**
* Create a ADD [dstReg:dstDisp], imm32
*
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeADD(int operandSize, SR dstReg, int dstDisp, int imm32);
/**
* Create ADD reg, memPtr32
*
* @param reg
* @param memPtr32
*/
public abstract void writeADD_MEM(GPR reg, int memPtr32);
/**
* Create a AND dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeAND(GPR dstReg, GPR srcReg);
/**
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeAND(GPR dstReg, GPR srcReg, int srcDisp);
/**
* Create a AND reg, imm32
*
* @param reg
* @param imm32
*/
public abstract void writeAND(GPR reg, int imm32);
/**
* @param operandSize
* @param dstDisp
* @param imm32
*/
public abstract void writeAND(int operandSize, int dstDisp, int imm32);
/**
* Create a AND [dstReg+dstDisp], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeAND(GPR dstReg, int dstDisp, GPR srcReg);
/**
* @param operandSize
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeAND(int operandSize, SR dstReg, int dstDisp, int imm32);
/**
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeAND(int operandSize, GPR dstReg, int dstDisp, int imm32);
/**
* Create a OPERATION dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public final void writeArithOp(int operation, GPR dstReg, GPR srcReg) {
switch (operation) {
case X86Operation.ADD:
writeADD(dstReg, srcReg);
break;
case X86Operation.ADC:
writeADC(dstReg, srcReg);
break;
case X86Operation.SUB:
writeSUB(dstReg, srcReg);
break;
case X86Operation.SBB:
writeSBB(dstReg, srcReg);
break;
case X86Operation.AND:
writeAND(dstReg, srcReg);
break;
case X86Operation.OR:
writeOR(dstReg, srcReg);
break;
case X86Operation.XOR:
writeXOR(dstReg, srcReg);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Create a OPERATION dstReg, [srcReg+srcDisp]
*
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public final void writeArithOp(int operation, GPR dstReg, GPR srcReg,
int srcDisp) {
switch (operation) {
case X86Operation.ADD:
writeADD(dstReg, srcReg, srcDisp);
break;
case X86Operation.ADC:
writeADC(dstReg, srcReg, srcDisp);
break;
case X86Operation.SUB:
writeSUB(dstReg, srcReg, srcDisp);
break;
case X86Operation.SBB:
writeSBB(dstReg, srcReg, srcDisp);
break;
case X86Operation.AND:
writeAND(dstReg, srcReg, srcDisp);
break;
case X86Operation.OR:
writeOR(dstReg, srcReg, srcDisp);
break;
case X86Operation.XOR:
writeXOR(dstReg, srcReg, srcDisp);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* @param dstReg
* @param imm32
*/
public final void writeArithOp(int operation, GPR dstReg, int imm32) {
switch (operation) {
case X86Operation.ADD:
writeADD(dstReg, imm32);
break;
case X86Operation.ADC:
writeADC(dstReg, imm32);
break;
case X86Operation.SUB:
writeSUB(dstReg, imm32);
break;
case X86Operation.SBB:
writeSBB(dstReg, imm32);
break;
case X86Operation.AND:
writeAND(dstReg, imm32);
break;
case X86Operation.OR:
writeOR(dstReg, imm32);
break;
case X86Operation.XOR:
writeXOR(dstReg, imm32);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Create a OPERATION [dstReg+dstDisp], <srcReg>
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public final void writeArithOp(int operation, GPR dstReg, int dstDisp,
GPR srcReg) {
switch (operation) {
case X86Operation.ADD:
writeADD(dstReg, dstDisp, srcReg);
break;
case X86Operation.ADC:
writeADC(dstReg, dstDisp, srcReg);
break;
case X86Operation.SUB:
writeSUB(dstReg, dstDisp, srcReg);
break;
case X86Operation.SBB:
writeSBB(dstReg, dstDisp, srcReg);
break;
case X86Operation.AND:
writeAND(dstReg, dstDisp, srcReg);
break;
case X86Operation.OR:
writeOR(dstReg, dstDisp, srcReg);
break;
case X86Operation.XOR:
writeXOR(dstReg, dstDisp, srcReg);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Create a OPERATION [dstReg+dstDisp], imm32
*
* @param dstReg
* @param dstDisp
* @param imm32
*/
public final void writeArithOp(int operation, int operandSize, GPR dstReg, int dstDisp,
int imm32) {
testOperandSize(operandSize, BITS32 | BITS64);
switch (operation) {
case X86Operation.ADD:
writeADD(operandSize, dstReg, dstDisp, imm32);
break;
case X86Operation.ADC:
writeADC(operandSize, dstReg, dstDisp, imm32);
break;
case X86Operation.SUB:
writeSUB(operandSize, dstReg, dstDisp, imm32);
break;
case X86Operation.SBB:
writeSBB(operandSize, dstReg, dstDisp, imm32);
break;
case X86Operation.AND:
writeAND(operandSize, dstReg, dstDisp, imm32);
break;
case X86Operation.OR:
writeOR(operandSize, dstReg, dstDisp, imm32);
break;
case X86Operation.XOR:
writeXOR(operandSize, dstReg, dstDisp, imm32);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Write an sseSD dst, [src+srcDisp] operation for 64-bit fp operations.
*
* @param dst Must be an xmm register
* @param src Must be an gpr register
* @param srcDisp
*/
public abstract void writeArithSSEDOp(int operation, X86Register.XMM dst,
X86Register.GPR src, int srcDisp);
/**
* Write an sseSD dst, src operation for 64-bit fp operations.
*
* @param dst Must be an xmm register
* @param src Must be an xmm register
*/
public abstract void writeArithSSEDOp(int operation, X86Register.XMM dst,
X86Register.XMM src);
/**
* Write an sseSS dst, [src+srcDisp] operation for 32-bit fp operations.
*
* @param dst Must be an xmm register
* @param src Must be an gpr register
* @param srcDisp
*/
public abstract void writeArithSSESOp(int operation, X86Register.XMM dst,
X86Register.GPR src, int srcDisp);
/**
* Write an sseSD dst, src operation for 32-bit fp operations.
*
* @param dst Must be an xmm register
* @param src Must be an xmm register
*/
public abstract void writeArithSSESOp(int operation, X86Register.XMM dst,
X86Register.XMM src);
/**
* Create a bound lReg, [rReg+rDisp]
* Only valid in 32-bit mode.
*
* @param lReg
* @param rReg
* @param rDisp
* @throws InvalidOpcodeException in 64-bit mode.
*/
public abstract void writeBOUND(GPR lReg, GPR rReg, int rDisp)
throws InvalidOpcodeException;
/**
* Create a int3
*/
public abstract void writeBreakPoint();
/**
* Write a bts reg, imm32.
*
* @param reg
* @param imm32
*/
public abstract void writeBTS(GPR reg, int imm32);
/**
* Create a call to address stored in the given register.
*
* @param reg
*/
public abstract void writeCALL(GPR reg);
/**
* Create a call to address stored at the given
* [regBase+regIndex*scale+disp].
*
* @param regBase
* @param regIndex
* @param scale
* @param disp
*/
public abstract void writeCALL(GPR regBase, GPR regIndex, int scale,
int disp);
/**
* Create a call to address stored at the given
* [regIndex*scale+disp].
*
* @param regIndex
* @param scale
* @param disp
*/
public abstract void writeCALL(GPR regIndex, int scale, int disp);
/**
* Create a call to address stored at the given [reg+offset].
*
* @param reg
* @param offset
*/
public abstract void writeCALL(GPR reg, int offset);
/**
* Create a call to address stored at the given [reg+offset].
*
* @param reg
* @param offset
*/
public abstract void writeCALL_FAR(GPR reg, int offset);
/**
* Create a relative call to a given label
*
* @param label
*/
public abstract void writeCALL(Label label);
/**
* Create a call to address stored at the given offset in the given table
* pointer.
*
* @param tablePtr
* @param offset
* @param rawAddress If true, tablePtr is a raw address
*/
public abstract void writeCALL(Object tablePtr, int offset,
boolean rawAddress);
/**
* Create a cdq
* Sign extend EAX to EDX:EAX in 32-bit operand size.
* Sign extend RAX to RDX:RAX in 64-bit operand size.
*/
public abstract void writeCDQ(int operandSize);
/**
* Create a cdqe.
* Sign extend EAX to RAX.
* Only valid in 64-bit mode.
*/
public abstract void writeCDQE()
throws InvalidOpcodeException;
/**
*/
public abstract void writeCLD();
/**
*/
public abstract void writeCLI();
/**
*/
public abstract void writeCLTS();
/**
* Create a CMOVcc dst,src
*
* @param ccOpcode
* @param dst
* @param src
* @throws InvalidOpcodeException If no CMOV feature.
*/
public abstract void writeCMOVcc(int ccOpcode, GPR dst, GPR src)
throws InvalidOpcodeException;
/**
* Create a CMOVcc dst,[src+srcDisp]
*
* @param dst
* @param src
* @param srcDisp
* @throws InvalidOpcodeException If no CMOV feature.
*/
public abstract void writeCMOVcc(int ccOpcode, GPR dst, GPR src, int srcDisp)
throws InvalidOpcodeException;
/**
* Create a CMP reg1, reg2
*
* @param reg1
* @param reg2
*/
public abstract void writeCMP(GPR reg1, GPR reg2);
/**
* Create a CMP reg1, [reg2:disp]
*
* @param reg1
* @param reg2
* @param disp
*/
public abstract void writeCMP(GPR reg1, SR reg2, int disp);
/**
* Create a CMP reg1, [reg2+disp]
*
* @param reg1
* @param reg2
* @param disp
*/
public abstract void writeCMP(GPR reg1, GPR reg2, int disp);
/**
* Create a CMP [reg1+disp], reg2
*
* @param reg1
* @param disp
* @param reg2
*/
public abstract void writeCMP(GPR reg1, int disp, GPR reg2);
/**
* Create a CMP reg, imm32
*
* @param reg
* @param imm32
*/
public abstract void writeCMP_Const(GPR reg, int imm32);
/**
* Create a CMP [reg+disp], imm32
*
* @param reg
* @param disp
* @param imm32
*/
public abstract void writeCMP_Const(int operandSize, GPR reg, int disp, int imm32);
/**
* Create a CMP [dstReg:dstDisp], imm32
*
* @param operandSize
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeCMP_Const(int operandSize, SR dstReg, int dstDisp, int imm32);
/**
* Create a CMP EAX, imm32 or CMP rax, imm32
*
* @param operandSize BITS32 or BITS64
* @param imm32
*/
public abstract void writeCMP_EAX(int operandSize, int imm32);
/**
* Create a CMP reg,[memPtr]
*
* @param reg
* @param memPtr
*/
public abstract void writeCMP_MEM(GPR reg, int memPtr);
/**
* Create a CMP size [memPtr], imm32
*
* @param operandSize BITS32 or BITS64
* @param memPtr
* @param imm32
*/
public abstract void writeCMP_MEM(int operandSize, int memPtr, int imm32);
/**
* Create a CMPXCHG [dstReg], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
* @param lock
*/
public abstract void writeCMPXCHG_EAX(GPR dstReg, int dstDisp, GPR srcReg,
boolean lock);
/**
* Create a cpuid
*/
public abstract void writeCPUID();
/**
* Create a dec reg32
*
* @param dstReg
*/
public abstract void writeDEC(GPR dstReg);
/**
* Create a dec size [dstReg+dstDisp]
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
*/
public abstract void writeDEC(int operandSize, GPR dstReg, int dstDisp);
/**
* Create a div eax, srcReg
*
* @param srcReg
*/
public abstract void writeDIV_EAX(GPR srcReg);
/**
* Create a emms
*/
public abstract void writeEMMS();
/**
* Create a fadd dword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFADD32(GPR srcReg, int srcDisp);
/**
* Create a fadd qword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFADD64(GPR srcReg, int srcDisp);
/**
* Create a faddp fpuReg fpuReg + ST0 to fpuReg and pop ST0
*
* @param fpuReg
*/
public abstract void writeFADDP(X86Register fpuReg);
/**
* Create a fchs
*/
public abstract void writeFCHS();
/**
* Create a fdiv dword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFDIV32(GPR srcReg, int srcDisp);
/**
* Create a fdiv qword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFDIV64(GPR srcReg, int srcDisp);
/**
* Create a fdivp fpuReg fpuReg / ST0 to fpuReg ; pop ST0
*
* @param fpuReg
*/
public abstract void writeFDIVP(X86Register fpuReg);
/**
* Create a ffree
*
* @param fReg
*/
public abstract void writeFFREE(X86Register fReg);
/**
* Create a fild dword [dstReg+dstDisp]
*
* @param dstReg
* @param dstDisp
*/
public abstract void writeFILD32(GPR dstReg, int dstDisp);
/**
* Create a fild qword [dstReg+dstDisp]
*
* @param dstReg
* @param dstDisp
*/
public abstract void writeFILD64(GPR dstReg, int dstDisp);
/**
* Create a fistp dword [dstReg+dstDisp]
*
* @param dstReg
* @param dstDisp
*/
public abstract void writeFISTP32(GPR dstReg, int dstDisp);
/**
* Create a fistp qword [dstReg+dstDisp]
*
* @param dstReg
* @param dstDisp
*/
public abstract void writeFISTP64(GPR dstReg, int dstDisp);
/**
* Create a fld dword [srcBaseReg+scrIndexReg*srcScale+srcDisp]
*
* @param srcBaseReg
* @param srcIndexReg
* @param srcScale
* @param srcDisp
*/
public abstract void writeFLD32(GPR srcBaseReg, GPR srcIndexReg,
int srcScale, int srcDisp);
/**
* Create a fld dword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFLD32(GPR srcReg, int srcDisp);
/**
* Create a fld qword [srcBaseReg+scrIndexReg*srcScale+srcDisp]
*
* @param srcBaseReg
* @param srcIndexReg
* @param srcScale
* @param srcDisp
*/
public abstract void writeFLD64(GPR srcBaseReg, GPR srcIndexReg,
int srcScale, int srcDisp);
/**
* Create a fld qword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFLD64(GPR srcReg, int srcDisp);
/**
* Create a fldcw word [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFLDCW(GPR srcReg, int srcDisp);
/**
* Create a fmul dword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFMUL32(GPR srcReg, int srcDisp);
/**
* Create a fmul qword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFMUL64(GPR srcReg, int srcDisp);
/**
* Create a fmulp fpuReg fpuReg * ST0 to fpuReg ; pop ST0
*
* @param fpuReg
*/
public abstract void writeFMULP(X86Register fpuReg);
/**
* Create a fninit
*/
public abstract void writeFNINIT();
/**
* Create a fnsave [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFNSAVE(GPR srcReg, int srcDisp);
/**
* Create a fnstsw, Store fp status word in AX
*/
public abstract void writeFNSTSW_AX();
/**
* Create a fprem
*/
public abstract void writeFPREM();
/**
* Create a frstor [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFRSTOR(GPR srcReg, int srcDisp);
/**
* Create a fstcw word [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFSTCW(GPR srcReg, int srcDisp);
/**
* Create a fstp fpuReg
*
* @param fpuReg
*/
public abstract void writeFSTP(X86Register fpuReg);
/**
* Create a fstp dword [dstReg+dstDisp]
*
* @param dstReg
* @param dstDisp
*/
public abstract void writeFSTP32(GPR dstReg, int dstDisp);
/**
* Create a fstp qword [dstReg+dstDisp]
*
* @param dstReg
* @param dstDisp
*/
public abstract void writeFSTP64(GPR dstReg, int dstDisp);
/**
* Create a fsub dword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFSUB32(GPR srcReg, int srcDisp);
/**
* Create a fsub qword [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFSUB64(GPR srcReg, int srcDisp);
/**
* Create a fsubp fpuReg fpuReg - ST0 to fpuReg & pop ST0
*
* @param fpuReg
*/
public abstract void writeFSUBP(X86Register fpuReg);
/**
* Create a fucompp, Compare - Pop twice
*/
public abstract void writeFUCOMPP();
/**
* Create a fxch fpuReg Swap ST0 and fpuReg
*/
public abstract void writeFXCH(X86Register fpuReg);
/**
* Create a fxrstor [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFXRSTOR(GPR srcReg, int srcDisp);
/**
* Create a fxsave [srcReg+srcDisp]
*
* @param srcReg
* @param srcDisp
*/
public abstract void writeFXSAVE(GPR srcReg, int srcDisp);
/**
* Create a hlt
*/
public abstract void writeHLT();
/**
* Create a idiv eax, srcReg
*
* @param srcReg
*/
public abstract void writeIDIV_EAX(GPR srcReg);
/**
* Create a idiv eax, [src+srcDisp] or idiv rax, [src+srcDisp]
*
* @param operandSize BITS32 or BITS64
* @param src
* @param srcDisp
*/
public abstract void writeIDIV_EAX(int operandSize, GPR src, int srcDisp);
/**
* @param dstReg
* @param srcReg
*/
public abstract void writeIMUL(GPR dstReg, GPR srcReg);
/**
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeIMUL(GPR dstReg, GPR srcReg, int srcDisp);
/**
* @param dstReg
* @param srcReg
* @param imm32
*/
public abstract void writeIMUL_3(GPR dstReg, GPR srcReg, int imm32);
/**
* Create a three operand imul.
*
* @param dstReg
* @param srcReg
* @param srcDisp
* @param imm32
*/
public abstract void writeIMUL_3(GPR dstReg, GPR srcReg, int srcDisp,
int imm32);
/**
* Create a imul eax, srcReg
*
* @param srcReg
*/
public abstract void writeIMUL_EAX(GPR srcReg);
/**
* Create an in
*
* @param operandSize
* @param imm8
*/
public abstract void writeIN(int operandSize, int imm8);
/**
* Create an in
*
* @param operandSize
*/
public abstract void writeIN(int operandSize);
/**
* Create a inc dstReg
*
* @param dstReg
*/
public abstract void writeINC(GPR dstReg);
/**
* Create a inc size [dstReg:disp]
*
* @param operandSize
* @param dstReg
* @param disp
*/
public abstract void writeINC(int operandSize, SR dstReg, int disp);
/**
* Create a inc size [dstReg+disp]
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param disp
*/
public abstract void writeINC(int operandSize, GPR dstReg, int disp);
/**
* @param operandSize
* @param dstReg
* @param dstIdxReg
* @param scale
* @param disp
*/
public abstract void writeINC(int operandSize, GPR dstReg, GPR dstIdxReg, int scale, int disp);
public abstract void writeINC(int operandSize, int dstDisp);
/**
* Create a int vector
*
* @param vector
*/
public abstract void writeINT(int vector);
/**
* Create a iret
*/
public abstract void writeIRET();
/**
* Create a iretq
*/
public abstract void writeIRETQ();
/**
* Create a conditional jump to a label The opcode sequence is: 0x0f
* <jumpOpcode><rel32>
*
* @param label
* @param jumpOpcode
*/
public abstract void writeJCC(Label label, int jumpOpcode);
/**
* Create a conditional jump to a label.
*
* @param label
*/
public abstract void writeJECXZ(Label label);
/**
* Create a absolute jump to address in register
*
* @param reg32
*/
public abstract void writeJMP(GPR reg32);
/**
* Create a absolute jump to [reg32+disp]
*
* @param reg32
*/
public abstract void writeJMP(GPR reg32, int disp);
/**
* Create a relative jump to a given label
*
* @param label
*/
public abstract void writeJMP(Label label);
/**
* Create a absolute jump to address stored at the given offset (in
* register) in the given table pointer.
*
* @param tablePtr
* @param offsetReg
*/
public abstract void writeJMP(Object tablePtr, GPR offsetReg);
/**
* Create a absolute jump to address stored at the given offset in the given
* table pointer.
*
* @param tablePtr
* @param offset
* @param rawAddress If true, tablePtr is a raw address
*/
public abstract void writeJMP(Object tablePtr, int offset,
boolean rawAddress);
public abstract void writeJMP(int operandSize, int seg, int disp);
/**
* Create a ldmxcsr [srcReg+disp]
*
* @param srcReg
* @param disp
*/
public abstract void writeLDMXCSR(GPR srcReg, int disp);
/**
* Create a lea dstReg,[srcReg+srcIdxReg*scale+disp]
*
* @param dstReg
* @param srcReg
* @param srcIdxReg
* @param scale
* @param disp
*/
public abstract void writeLEA(GPR dstReg, GPR srcReg, GPR srcIdxReg,
int scale, int disp);
/**
* Create a lea dstReg,[srcReg+disp]
*
* @param dstReg
* @param srcReg
* @param disp
*/
public abstract void writeLEA(GPR dstReg, GPR srcReg, int disp);
/**
* @param dstReg
* @param srcIdxReg
* @param scale
* @param disp
*/
public abstract void writeLEA(GPR dstReg, GPR srcIdxReg, int scale, int disp);
/**
* Create lgdt [disp]
*
* @param disp
*/
public abstract void writeLGDT(int disp);
/**
* Create lidt [disp]
*
* @param disp
*/
public abstract void writeLIDT(int disp);
/**
* Create a lmsw reg
*
* @param srcReg
*/
public abstract void writeLMSW(GPR srcReg);
/**
* Create a LODSD
*/
public abstract void writeLODSD();
/**
* Create a LODSW
*/
public abstract void writeLODSW();
/**
* Create a LOOP label instruction. The given label must have be resolved
* before!
*
* @param label
* @throws UnresolvedObjectRefException
*/
public abstract void writeLOOP(Label label)
throws UnresolvedObjectRefException;
/**
* Create a ltr reg
*
* @param srcReg
*/
public abstract void writeLTR(GPR srcReg);
/**
* Create a mov <dstReg>, <srcReg>
*
* @param dstReg
* @param srcReg
*/
public abstract void writeMOV(GPR dstReg, CRX srcReg);
/**
* Create a mov <dstReg>, <srcReg>
*
* @param dstReg
* @param srcReg
*/
public abstract void writeMOV(CRX dstReg, GPR srcReg);
/**
* Create a mov <dstReg>, <srcReg>
*
* @param dstReg
* @param srcReg
*/
public abstract void writeMOV(GPR dstReg, SR srcReg);
/**
* Create a mov <dstReg>, <srcReg>
*
* @param dstReg
* @param srcReg
*/
public abstract void writeMOV(SR dstReg, GPR srcReg);
/**
* Create a mov dstReg, [srcReg+srcDisp]
*
* @param dstReg
* @param srcReg
* @param srcDisp
*/
// public abstract void writeMOV(SR dstReg, GPR srcReg, int srcDisp);
/**
* Create a mov [dstReg+dstDisp], <srcReg>
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
// public abstract void writeMOV(GPR dstReg, int dstDisp, SR srcReg);
/**
* Create a mov <dstReg>, <srcReg>
*
* @param operandSize
* @param dstReg
* @param srcReg
*/
public abstract void writeMOV(int operandSize, GPR dstReg, GPR srcReg);
/**
* Create a mov dstReg, [srcReg+srcIdxReg*scale+srcDisp]
*
* @param operandSize
* @param dstReg
* @param srcReg
* @param srcIdxReg
* @param scale
* @param srcDisp
*/
public abstract void writeMOV(int operandSize, GPR dstReg, GPR srcReg,
GPR srcIdxReg, int scale, int srcDisp);
/**
* Create a mov dstReg, [srcReg:srcDisp]
*
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeMOV(GPR dstReg, SR srcReg, int srcDisp);
/**
* Create a mov dstReg, [srcReg+srcDisp]
*
* @param operandSize
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeMOV(int operandSize, GPR dstReg, GPR srcReg,
int srcDisp);
/**
* Create a mov [dstReg+dstIdxReg*scale+dstDisp], <srcReg>
*
* @param operandSize
* @param dstReg
* @param dstIdxReg
* @param scale
* @param dstDisp
* @param srcReg
*/
public abstract void writeMOV(int operandSize, GPR dstReg, GPR dstIdxReg,
int scale, int dstDisp, GPR srcReg);
/**
* Create a mov [dstReg+dstDisp], srcReg
*
* @param operandSize
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeMOV(int operandSize, GPR dstReg, int dstDisp,
GPR srcReg);
/**
* Create a mov [dstReg:dstDisp], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeMOV(SR dstReg, int dstDisp, GPR srcReg);
/**
* @param dstReg
* @param srcDisp
*/
public abstract void writeMOV(GPR dstReg, int srcDisp);
/**
* @param dstDisp
* @param srcReg
*/
public abstract void writeMOV(int dstDisp, GPR srcReg);
/**
* @param operandSize
* @param dstDisp
* @param imm32
*/
public abstract void writeMOV_Const(int operandSize, int dstDisp, int imm32);
/**
* Create a MOV reg,imm32 or MOV reg,imm64 depending on the reg size.
*
* @param dstReg
* @param imm32
*/
public abstract void writeMOV_Const(GPR dstReg, int imm32);
/**
* Create a MOV reg,imm64 depending on the reg size.
* Only valid in 64-bit mode.
*
* @param dstReg
* @param imm64
* @throws InvalidOpcodeException In 32-bit modes.
*/
public abstract void writeMOV_Const(GPR dstReg, long imm64)
throws InvalidOpcodeException;
/**
* Create a mov size [dstReg:dstDisp], imm32
*
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeMOV_Const(int operandSize, SR dstReg, int dstDisp, int imm32);
/**
* Create a mov size [destReg+destDisp], imm32
*
* @param destReg
* @param destDisp
* @param imm32
*/
public abstract void writeMOV_Const(int operandSize, GPR destReg, int destDisp, int imm32);
/**
* Create a mov <reg>, <label>
*
* @param dstReg
* @param label
*/
public abstract void writeMOV_Const(GPR dstReg, Object label);
/**
* Create a mov size [destReg+dstIdxReg*scale+destDisp], imm32
*
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeMOV_Const(int operandSize, GPR dstReg, GPR dstIdxReg, int scale,
int dstDisp, int imm32);
/**
* Create a movd mm,[reg + disp]
*
* @param operandSize
* @param mmx
* @param reg
* @param disp
*/
public abstract void writeMOVD(int operandSize, MMX mmx, GPR reg, int disp);
/**
* Create a movd [reg + disp],mm
*
* @param operandSize
* @param dstReg
* @param dstDisp
* @param srcMmx
*/
public abstract void writeMOVD(int operandSize, GPR dstReg, int dstDisp, MMX srcMmx);
/**
* Create a movq mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writeMOVQ(MMX dstMmx, MMX srcMmx);
/**
* Create a movq mm,[reg + disp]
*
* @param operandSize
* @param dstMmx
* @param srcGpr
* @param srcDisp
*/
public abstract void writeMOVQ(int operandSize, MMX dstMmx, GPR srcGpr, int srcDisp);
/**
* Create a movq mm,[disp]
*
* @param operandSize
* @param dstMmx
* @param srcDisp
*/
public abstract void writeMOVQ(int operandSize, MMX dstMmx, int srcDisp);
/**
* Create a movsb
*/
public abstract void writeMOVSB();
/**
* Create a movsd
*/
public abstract void writeMOVSD();
/**
* Create a movsd [dst+dstDisp],src
*
* @param dst
* @param src
*/
public abstract void writeMOVSD(X86Register.GPR dst, int dstDisp,
X86Register.XMM src);
/**
* Create a movsd dst,[src+srcDisp]
*
* @param dst
* @param src
*/
public abstract void writeMOVSD(X86Register.XMM dst, X86Register.GPR src,
int srcDisp);
/**
* Create a movsd dst,src
*
* @param dst
* @param src
*/
public abstract void writeMOVSD(X86Register.XMM dst, X86Register.XMM src);
/**
* Create a movss [dst+dstDisp],src
*
* @param dst
* @param src
*/
public abstract void writeMOVSS(X86Register.GPR dst, int dstDisp,
X86Register.XMM src);
/**
* Create a movss dst,[src+srcDisp]
*
* @param dst
* @param src
*/
public abstract void writeMOVSS(X86Register.XMM dst, X86Register.GPR src,
int srcDisp);
/**
* Create a movss dst,src
*
* @param dst
* @param src
*/
public abstract void writeMOVSS(X86Register.XMM dst, X86Register.XMM src);
/**
* Create a movsx <dstReg>, <srcReg>
*
* @param dstReg
* @param srcReg
* @param srcSize
*/
public abstract void writeMOVSX(GPR dstReg, GPR srcReg, int srcSize);
public abstract void writeMOVSX(GPR dstReg, GPR srcReg, int srcDisp,
int size);
/**
* Create a movsxd dstReg, srcReg.
* Sign extends the srcReg to dstReg.
* Only valid in 64-bit mode.
*
* @param dstReg
* @param srcReg
*/
public abstract void writeMOVSXD(GPR64 dstReg, GPR32 srcReg)
throws InvalidOpcodeException;
/**
* Create a movsw
*/
public abstract void writeMOVSW();
/**
* Create a movzx <dstReg>, <srcReg>
*
* @param dstReg
* @param srcReg
* @param srcSize
*/
public abstract void writeMOVZX(GPR dstReg, GPR srcReg, int srcSize);
public abstract void writeMOVZX(GPR dstReg, GPR srcReg, int srcDisp,
int size);
/**
* Create a mul eax, srcReg
*
* @param srcReg
*/
public abstract void writeMUL_EAX(GPR srcReg);
/**
* Create a neg dstReg
*
* @param dstReg
*/
public abstract void writeNEG(GPR dstReg);
/**
* Create a neg size [dstReg+dstDisp]
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
*/
public abstract void writeNEG(int operandSize, GPR dstReg, int dstDisp);
/**
* Create a nop
*/
public abstract void writeNOP();
/**
* Create a not dstReg
*
* @param dstReg
*/
public abstract void writeNOT(GPR dstReg);
/**
* Create a not size [dstReg+dstDisp]
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
*/
public abstract void writeNOT(int operandSize, GPR dstReg, int dstDisp);
/**
* Create a OR dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeOR(GPR dstReg, GPR srcReg);
/**
* Create an out
*
* @param operandSize
* @param imm8
*/
public abstract void writeOUT(int operandSize, int imm8);
/**
* Create an out
*
* @param operandSize
*/
public abstract void writeOUT(int operandSize);
/**
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeOR(GPR dstReg, GPR srcReg, int srcDisp);
/**
* @param dstReg
* @param imm32
*/
public abstract void writeOR(GPR dstReg, int imm32);
/**
* Create a OR [dstReg+dstDisp], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeOR(GPR dstReg, int dstDisp, GPR srcReg);
/**
* @param operandSize
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeOR(int operandSize, SR dstReg, int dstDisp, int imm32);
/**
* @param operandSize
* @param dstDisp
* @param imm32
*/
public abstract void writeOR(int operandSize, int dstDisp, int imm32);
/**
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeOR(int operandSize, GPR dstReg, int dstDisp, int imm32);
/**
* Create a packuswb mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePACKUSWB(MMX dstMmx, MMX srcMmx);
/**
* Create a paddw mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePADDW(MMX dstMmx, MMX srcMmx);
/**
* Create a pand mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePAND(MMX dstMmx, MMX srcMmx);
/**
* Create a pcmpgtw mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePCMPGTW(MMX dstMmx, MMX srcMmx);
/**
* Create a pmullw mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePMULLW(MMX dstMmx, MMX srcMmx);
/**
* Create a pop reg32
*
* @param dstReg
*/
public abstract void writePOP(GPR dstReg);
/**
* Create a pop sreg
*
* @param dstReg
*/
public abstract void writePOP(SR dstReg);
/**
* Create a pop dword [reg32+disp]
*
* @param dstReg
* @param dstDisp
*/
public abstract void writePOP(GPR dstReg, int dstDisp);
/**
* Create a popa
*
* @throws InvalidOpcodeException In 64-bit mode.
*/
public abstract void writePOPA()
throws InvalidOpcodeException;
/**
* Create a popf.
*/
public abstract void writePOPF();
/**
* Write an prefix byte
*
* @param prefix
*/
public abstract void writePrefix(int prefix);
/**
* Create a pshufw mm,mm,imm8
*
* @param dstMmx
* @param srcMmx
* @param imm8
*/
public abstract void writePSHUFW(MMX dstMmx, MMX srcMmx, int imm8);
/**
* Create a psrlw mm,imm8
*
* @param mmx
* @param imm8
*/
public abstract void writePSRLW(MMX mmx, int imm8);
/**
* Create a psubw mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePSUBW(MMX dstMmx, MMX srcMmx);
/**
* Create punpcklbw mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePUNPCKLBW(MMX dstMmx, MMX srcMmx);
/**
* Create a push reg32
*
* @param srcReg
* @return The ofset of the start of the instruction.
*/
public abstract int writePUSH(GPR srcReg);
/**
* Create a push sreg
*
* @param srcReg
* @return The ofset of the start of the instruction.
*/
public abstract int writePUSH(SR srcReg);
/**
* Create a push dword [baseReg+indexReg*scale+disp]
*
* @param srcBaseReg
* @param srcIndexReg
* @param srcScale
* @param srcDisp
* @return The ofset of the start of the instruction.
*/
public abstract int writePUSH(GPR srcBaseReg, GPR srcIndexReg,
int srcScale, int srcDisp);
/**
* Create a push dword [reg32+disp]
*
* @param srcReg
* @param srcDisp
* @return The ofset of the start of the instruction.
*/
public abstract int writePUSH(GPR srcReg, int srcDisp);
/**
* Create a push dword [sr:disp]
*
* @param sr
* @param srcDisp
* @return The ofset of the start of the instruction.
*/
public abstract int writePUSH(SR sr, int srcDisp);
/**
* Create a push dword <imm32>
*
* @param imm32
* @return The ofset of the start of the instruction.
*/
public abstract int writePUSH(int imm32);
// PR
/**
* Create a push dword <object>
*
* @param objRef
* @return The offset of the start of the instruction.
*/
public abstract int writePUSH_Const(Object objRef);
/**
* Create a pusha
*
* @throws InvalidOpcodeException In 64-bit mode.
*/
public abstract void writePUSHA()
throws InvalidOpcodeException;
/**
* Create a pushf.
*/
public abstract void writePUSHF();
/**
* Create a pxor mm,mm
*
* @param dstMmx
* @param srcMmx
*/
public abstract void writePXOR(MMX dstMmx, MMX srcMmx);
/**
* Create a RDTSC (get timestamp into edx:eax
*/
public abstract void writeRDTSC();
/**
* Create a RDMSR (get model specific register pointed to by ecx into edx:eax)
*/
public abstract void writeRDMSR();
/**
* Create 32-bit offset relative to the current (after this offset) offset.
*
* @param label
*/
public abstract void writeRelativeObjectRef(Label label);
/**
* Create a ret near to caller
*/
public abstract void writeRET();
/**
* Create a ret imm16 near to caller
*
* @param imm16
*/
public abstract void writeRET(int imm16);
/**
* Create a sahf
*/
public abstract void writeSAHF();
/**
* Create a SAL dstReg,imm8
*
* @param dstReg
* @param imm8
*/
public abstract void writeSAL(GPR dstReg, int imm8);
/**
* Create a SAL size [dstReg+dstDisp], imm8
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
* @param imm8
*/
public abstract void writeSAL(int operandSize, GPR dstReg, int dstDisp, int imm8);
/**
* Create a SAL dstReg,cl
*
* @param dstReg
*/
public abstract void writeSAL_CL(GPR dstReg);
/**
* Create a SAL size [dstReg+dstDisp], CL
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
*/
public abstract void writeSAL_CL(int operandSize, GPR dstReg, int dstDisp);
/**
* Create a SAR dstReg,imm8
*
* @param dstReg
* @param imm8
*/
public abstract void writeSAR(GPR dstReg, int imm8);
/**
* Create a SAR size [dstReg+dstDisp], imm8
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
* @param imm8
*/
public abstract void writeSAR(int operandSize, GPR dstReg, int dstDisp, int imm8);
/**
* Create a SAR dstReg,cl
*
* @param dstReg
*/
public abstract void writeSAR_CL(GPR dstReg);
/**
* Create a SAL size [dstReg+dstDisp], CL
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
*/
public abstract void writeSAR_CL(int operandSize, GPR dstReg, int dstDisp);
/**
* Create a SBB dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeSBB(GPR dstReg, GPR srcReg);
/**
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeSBB(GPR dstReg, GPR srcReg, int srcDisp);
/**
* Create a SBB dstReg, imm32
*
* @param dstReg
* @param imm32
*/
public abstract void writeSBB(GPR dstReg, int imm32);
/**
* Create a SBB [dstReg+dstDisp], <srcReg>
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeSBB(GPR dstReg, int dstDisp, GPR srcReg);
/**
* Create a SBB dword [dstReg+dstDisp], <imm32>
*
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeSBB(int operandSize, GPR dstReg, int dstDisp, int imm32);
/**
* Create a SETcc dstReg. Sets the given 8-bit operand to zero if its
* condition is not satisfied, and to 1 if it is.
*
* @param dstReg
* @param cc
*/
public abstract void writeSETCC(GPR dstReg, int cc);
/**
* Write a shift operation. OPERATION dst,imm8
*
* @param operation
* @param dst
* @param imm8
*/
public final void writeShift(int operation, GPR dst, int imm8) {
switch (operation) {
case X86Operation.SAL:
writeSAL(dst, imm8);
break;
case X86Operation.SAR:
writeSAR(dst, imm8);
break;
case X86Operation.SHL:
writeSHL(dst, imm8);
break;
case X86Operation.SHR:
writeSHR(dst, imm8);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Write a shift operation. OPERATION [dst+dstDisp],imm8
*
* @param operation
* @param dst
* @param imm8
*/
public final void writeShift(int operation, int operandSize, GPR dst, int dstDisp, int imm8) {
testOperandSize(operandSize, BITS32 | BITS64);
switch (operation) {
case X86Operation.SAL:
writeSAL(operandSize, dst, dstDisp, imm8);
break;
case X86Operation.SAR:
writeSAR(operandSize, dst, dstDisp, imm8);
break;
case X86Operation.SHL:
writeSHL(operandSize, dst, dstDisp, imm8);
break;
case X86Operation.SHR:
writeSHR(operandSize, dst, dstDisp, imm8);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Write a shift operation. OPERATION dst,CL
*
* @param operation
* @param dst
*/
public final void writeShift_CL(int operation, GPR dst) {
switch (operation) {
case X86Operation.SAL:
writeSAL_CL(dst);
break;
case X86Operation.SAR:
writeSAR_CL(dst);
break;
case X86Operation.SHL:
writeSHL_CL(dst);
break;
case X86Operation.SHR:
writeSHR_CL(dst);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Write a shift operation. OPERATION [dst+dstDisp],CL
*
* @param operation
* @param dst
* @param dstDisp
*/
public final void writeShift_CL(int operation, int operandSize, GPR dst, int dstDisp) {
testOperandSize(operandSize, BITS32 | BITS64);
switch (operation) {
case X86Operation.SAL:
writeSAL_CL(operandSize, dst, dstDisp);
break;
case X86Operation.SAR:
writeSAR_CL(operandSize, dst, dstDisp);
break;
case X86Operation.SHL:
writeSHL_CL(operandSize, dst, dstDisp);
break;
case X86Operation.SHR:
writeSHR_CL(operandSize, dst, dstDisp);
break;
default:
throw new IllegalArgumentException("Invalid operation " + operation);
}
}
/**
* Create a SHL dstReg,imm8
*
* @param dstReg
* @param imm8
*/
public abstract void writeSHL(GPR dstReg, int imm8);
/**
* Create a SHL size [dstReg+dstDisp],imm8
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
* @param imm8
*/
public abstract void writeSHL(int operandSize, GPR dstReg, int dstDisp, int imm8);
/**
* Create a SHL dstReg,cl
*
* @param dstReg
*/
public abstract void writeSHL_CL(GPR dstReg);
/**
* Create a SHL size [dstReg+dstDisp],cl
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
*/
public abstract void writeSHL_CL(int operandSize, GPR dstReg, int dstDisp);
/**
* Create a SHLD dstReg,srcReg,cl
*
* @param dstReg
* @param srcReg
*/
public abstract void writeSHLD_CL(GPR dstReg, GPR srcReg);
/**
* Create a SHL dstReg,imm8
*
* @param dstReg
* @param imm8
*/
public abstract void writeSHR(GPR dstReg, int imm8);
/**
* Create a SHR size [dstReg+dstDisp], imm8
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
* @param imm8
*/
public abstract void writeSHR(int operandSize, GPR dstReg, int dstDisp, int imm8);
/**
* Create a SHR dstReg,cl
*
* @param dstReg
*/
public abstract void writeSHR_CL(GPR dstReg);
/**
* Create a SHR size [dstReg+dstDisp], CL
*
* @param operandSize BITS32 or BITS64
* @param dstReg
* @param dstDisp
*/
public abstract void writeSHR_CL(int operandSize, GPR dstReg, int dstDisp);
/**
* Create a SHRD dstReg,srcReg,cl
*
* @param dstReg
* @param srcReg
*/
public abstract void writeSHRD_CL(GPR dstReg, GPR srcReg);
/**
* Create a STD
*/
public abstract void writeSTD();
/**
* Create a STI
*/
public abstract void writeSTI();
/**
* Create a stmxcsr [srcReg+disp]
*
* @param srcReg
* @param disp
*/
public abstract void writeSTMXCSR(GPR srcReg, int disp);
/**
* Create a STOSB
*/
public abstract void writeSTOSB();
/**
* Create a STOSD
*/
public abstract void writeSTOSD();
/**
* Create a STOSQ
*/
public abstract void writeSTOSQ();
/**
* Create a STOSW
*/
public abstract void writeSTOSW();
/**
* Create a SUB dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeSUB(GPR dstReg, GPR srcReg);
/**
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeSUB(GPR dstReg, GPR srcReg, int srcDisp);
/**
* Create a SUB reg, imm32
*
* @param reg
* @param imm32
*/
public abstract void writeSUB(GPR reg, int imm32);
/**
* @param dstDisp
* @param srcReg
*/
public abstract void writeSUB(int dstDisp, GPR srcReg);
/**
* Create a SUB [dstReg+dstDisp], <srcReg>
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeSUB(GPR dstReg, int dstDisp, GPR srcReg);
/**
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeSUB(int operandSize, GPR dstReg, int dstDisp, int imm32);
/**
* @param operandSize
* @param reg
* @param disp
* @param imm32
*/
public abstract void writeTEST(int operandSize, SR reg, int disp, int imm32);
/**
* Create a TEST reg1, reg2
*
* @param reg1
* @param reg2
*/
public abstract void writeTEST(GPR reg1, GPR reg2);
/**
* Create a TEST reg, imm32
*
* @param reg
* @param imm32
*/
public abstract void writeTEST(GPR reg, int imm32);
/**
* Create a TEST size [reg+disp], imm32
*
* @param operandSize BITS32 or BITS64
* @param reg
* @param disp
* @param imm32
*/
public abstract void writeTEST(int operandSize, GPR reg, int disp, int imm32);
/**
* Create a TEST al, imm8
*
* @param value
*/
public abstract void writeTEST_AL(int value);
/**
* Create a TEST eax, imm32, TEST rax, imm32
*
* @param operandSize BITS32 or BITS64
* @param value
*/
public abstract void writeTEST_EAX(int operandSize, int value);
public abstract void writeTEST(int operandSize, int destDisp, int imm32);
/**
* Create a WRMSR (set model specific register pointed to by ecx from edx:eax)
*/
public abstract void writeWRMSR();
/**
* Write my contents to the given stream.
*
* @param os
* @throws IOException
*/
public abstract void writeTo(OutputStream os) throws IOException;
/**
* @param dstDisp
* @param srcReg
*/
public abstract void writeXCHG(int dstDisp, GPR srcReg);
/**
* Write XCHG dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeXCHG(GPR dstReg, GPR srcReg);
/**
* Write XCHG [dstReg+dstDisp], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeXCHG(GPR dstReg, int dstDisp, GPR srcReg);
/**
* Write XCHG [dstReg:dstDisp], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeXCHG(SR dstReg, int dstDisp, GPR srcReg);
/**
* Create a XOR dstReg, srcReg
*
* @param dstReg
* @param srcReg
*/
public abstract void writeXOR(GPR dstReg, GPR srcReg);
// LS
/**
* @param dstReg
* @param srcReg
* @param srcDisp
*/
public abstract void writeXOR(GPR dstReg, GPR srcReg, int srcDisp);
// LS
/**
* @param dstReg
* @param imm32
*/
public abstract void writeXOR(GPR dstReg, int imm32);
/**
* Create a XOR [dstReg+dstDisp], srcReg
*
* @param dstReg
* @param dstDisp
* @param srcReg
*/
public abstract void writeXOR(GPR dstReg, int dstDisp, GPR srcReg);
/**
* @param dstReg
* @param dstDisp
* @param imm32
*/
public abstract void writeXOR(int operandSize, GPR dstReg, int dstDisp, int imm32);
/**
* Test for a valid operand size.
*
* @param operandSize The given operand size.
* @param allowedMask The allowed operand sizes.
*/
protected final void testOperandSize(int operandSize, int allowedMask) {
if ((operandSize & allowedMask) != operandSize) {
throw new IllegalArgumentException("Invalid operand size " + operandSize);
}
}
/**
* Test for a valid size of the given register.
*
* @param reg The register to test
* @param allowedMask The allowed sizes.
*/
protected final void testSize(X86Register reg, int allowedMask) {
final int size = reg.getSize();
if ((size & allowedMask) != size) {
throw new IllegalArgumentException("Invalid register size " + size);
}
}
}