summaryrefslogtreecommitdiffstats
path: root/libpixelflinger/codeflinger/x86/libenc/encoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'libpixelflinger/codeflinger/x86/libenc/encoder.h')
-rw-r--r--libpixelflinger/codeflinger/x86/libenc/encoder.h717
1 files changed, 717 insertions, 0 deletions
diff --git a/libpixelflinger/codeflinger/x86/libenc/encoder.h b/libpixelflinger/codeflinger/x86/libenc/encoder.h
new file mode 100644
index 0000000..9ac0219
--- /dev/null
+++ b/libpixelflinger/codeflinger/x86/libenc/encoder.h
@@ -0,0 +1,717 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Alexander V. Astapchuk
+ */
+/**
+ * @file
+ * @brief Simple interface for generating processor instructions.
+ *
+ * The interface works for both IA32 and EM64T. By default, only IA32
+ * capabilities are presented. To enable EM64T feature, the _EM64T_ macro
+ * must be defined (and, of course, a proper library version to be used).
+ *
+ * The interface is based on the original ia32.h encoder interface,
+ * with some simplifications and add-ons - EM64T-specific, SSE and SSE2.
+ *
+ * The interface mostly intended for existing legacy code like LIL code
+ * generator. From the implementation point of view, it's just a wrapper
+ * around the EncoderBase functionality.
+ */
+
+#ifndef _VM_ENCODER_H_
+#define _VM_ENCODER_H_
+
+#include <limits.h>
+#include "enc_base.h"
+//#include "open/types.h"
+
+#ifdef _EM64T_
+// size of general-purpose value on the stack in bytes
+#define GR_STACK_SIZE 8
+// size of floating-point value on the stack in bytes
+#define FR_STACK_SIZE 8
+
+#if defined(WIN32) || defined(_WIN64)
+ // maximum number of GP registers for inputs
+ const int MAX_GR = 4;
+ // maximum number of FP registers for inputs
+ const int MAX_FR = 4;
+ // WIN64 reserves 4 words for shadow space
+ const int SHADOW = 4 * GR_STACK_SIZE;
+#else
+ // maximum number of GP registers for inputs
+ const int MAX_GR = 6;
+ // maximum number of FP registers for inputs
+ const int MAX_FR = 8;
+ // Linux x64 doesn't reserve shadow space
+ const int SHADOW = 0;
+#endif
+
+#else
+// size of general-purpose value on the stack in bytes
+#define GR_STACK_SIZE 4
+// size of general-purpose value on the stack in bytes
+#define FR_STACK_SIZE 8
+
+// maximum number of GP registers for inputs
+const int MAX_GR = 0;
+// maximum number of FP registers for inputs
+const int MAX_FR = 0;
+#endif
+
+typedef enum Reg_No {
+#ifdef _EM64T_
+ rax_reg = 0,rbx_reg, rcx_reg, rdx_reg,
+ rdi_reg, rsi_reg, rsp_reg, rbp_reg,
+ r8_reg, r9_reg, r10_reg, r11_reg,
+ r12_reg, r13_reg, r14_reg, r15_reg,
+ xmm0_reg, xmm1_reg, xmm2_reg, xmm3_reg,
+ xmm4_reg, xmm5_reg, xmm6_reg, xmm7_reg,
+ xmm8_reg, xmm9_reg, xmm10_reg, xmm11_reg,
+ xmm12_reg, xmm13_reg, xmm14_reg, xmm15_reg,
+
+#else // !defined(_EM64T_)
+
+ eax_reg = 0,ebx_reg, ecx_reg, edx_reg,
+ edi_reg, esi_reg, esp_reg, ebp_reg,
+ xmm0_reg, xmm1_reg, xmm2_reg, xmm3_reg,
+ xmm4_reg, xmm5_reg, xmm6_reg, xmm7_reg,
+ fs_reg,
+#endif
+ /** @brief Total number of registers.*/
+ n_reg
+} Reg_No;
+//
+// instruction operand sizes: 8,16,32,64 bits
+//
+typedef enum Opnd_Size {
+ size_8 = 0,
+ size_16,
+ size_32,
+ size_64,
+ n_size,
+#ifdef _EM64T_
+ size_platf = size_64
+#else
+ size_platf = size_32
+#endif
+} Opnd_Size;
+
+//
+// opcodes for alu instructions
+//
+typedef enum ALU_Opcode {
+ add_opc = 0,or_opc, adc_opc, sbb_opc,
+ and_opc, sub_opc, xor_opc, cmp_opc,
+ n_alu
+} ALU_Opcode;
+
+//
+// opcodes for shift instructions
+//
+typedef enum Shift_Opcode {
+ shld_opc, shrd_opc, shl_opc, shr_opc,
+ sar_opc, ror_opc, max_shift_opcode=6, n_shift = 6
+} Shift_Opcode;
+
+typedef enum ConditionCode {
+ Condition_O = 0,
+ Condition_NO = 1,
+ Condition_B = 2,
+ Condition_NAE = Condition_B,
+ Condition_C = Condition_B,
+ Condition_NB = 3,
+ Condition_AE = Condition_NB,
+ Condition_NC = Condition_NB,
+ Condition_Z = 4,
+ Condition_E = Condition_Z,
+ Condition_NZ = 5,
+ Condition_NE = Condition_NZ,
+ Condition_BE = 6,
+ Condition_NA = Condition_BE,
+ Condition_NBE = 7,
+ Condition_A = Condition_NBE,
+
+ Condition_S = 8,
+ Condition_NS = 9,
+ Condition_P = 10,
+ Condition_PE = Condition_P,
+ Condition_NP = 11,
+ Condition_PO = Condition_NP,
+ Condition_L = 12,
+ Condition_NGE = Condition_L,
+ Condition_NL = 13,
+ Condition_GE = Condition_NL,
+ Condition_LE = 14,
+ Condition_NG = Condition_LE,
+ Condition_NLE = 15,
+ Condition_G = Condition_NLE,
+ Condition_Count = 16
+} ConditionCode;
+
+//
+// prefix code
+//
+typedef enum InstrPrefix {
+ no_prefix,
+ lock_prefix = 0xF0,
+ hint_branch_taken_prefix = 0x2E,
+ hint_branch_not_taken_prefix = 0x3E,
+ prefix_repne = 0xF2,
+ prefix_repnz = prefix_repne,
+ prefix_repe = 0xF3,
+ prefix_repz = prefix_repe,
+ prefix_rep = 0xF3,
+ prefix_cs = 0x2E,
+ prefix_ss = 0x36,
+ prefix_ds = 0x3E,
+ prefix_es = 0x26,
+ prefix_fs = 0x64,
+ prefix_gs = 0x65
+} InstrPrefix;
+
+
+//
+// an instruction operand
+//
+class Opnd {
+
+protected:
+ enum Tag { SignedImm, UnsignedImm, Reg, Mem, FP, XMM };
+
+ const Tag tag;
+
+ Opnd(Tag t): tag(t) {}
+
+public:
+ void * operator new(size_t, void * mem) {
+ return mem;
+ }
+
+ void operator delete(void *) {}
+
+ void operator delete(void *, void *) {}
+
+private:
+ // disallow copying
+ Opnd(const Opnd &): tag(Mem) { assert(false); }
+ Opnd& operator=(const Opnd &) { assert(false); return *this; }
+};
+typedef int I_32;
+class Imm_Opnd: public Opnd {
+
+protected:
+ union {
+#ifdef _EM64T_
+ int64 value;
+ unsigned char bytes[8];
+#else
+ I_32 value;
+ unsigned char bytes[4];
+#endif
+ };
+ Opnd_Size size;
+
+public:
+ Imm_Opnd(I_32 val, bool isSigned = true):
+ Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(size_32) {
+ if (isSigned) {
+ if (CHAR_MIN <= val && val <= CHAR_MAX) {
+ size = size_8;
+ } else if (SHRT_MIN <= val && val <= SHRT_MAX) {
+ size = size_16;
+ }
+ } else {
+ assert(val >= 0);
+ if (val <= UCHAR_MAX) {
+ size = size_8;
+ } else if (val <= USHRT_MAX) {
+ size = size_16;
+ }
+ }
+ }
+ Imm_Opnd(const Imm_Opnd& that): Opnd(that.tag), value(that.value), size(that.size) {};
+
+#ifdef _EM64T_
+ Imm_Opnd(Opnd_Size sz, int64 val, bool isSigned = true):
+ Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) {
+#ifndef NDEBUG
+ switch (size) {
+ case size_8:
+ assert(val == (int64)(I_8)val);
+ break;
+ case size_16:
+ assert(val == (int64)(int16)val);
+ break;
+ case size_32:
+ assert(val == (int64)(I_32)val);
+ break;
+ case size_64:
+ break;
+ case n_size:
+ assert(false);
+ break;
+ }
+#endif // NDEBUG
+ }
+
+ int64 get_value() const { return value; }
+
+#else
+
+ Imm_Opnd(Opnd_Size sz, I_32 val, int isSigned = true):
+ Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) {
+#ifndef NDEBUG
+ switch (size) {
+ case size_8:
+ assert((I_32)val == (I_32)(I_8)val);
+ break;
+ case size_16:
+ assert((I_32)val == (I_32)(int16)val);
+ break;
+ case size_32:
+ break;
+ case size_64:
+ case n_size:
+ assert(false);
+ break;
+ }
+#endif // NDEBUG
+ }
+
+ I_32 get_value() const { return value; }
+
+#endif
+ Opnd_Size get_size() const { return size; }
+ bool is_signed() const { return tag == SignedImm; }
+};
+
+class RM_Opnd: public Opnd {
+
+public:
+ bool is_reg() const { return tag != SignedImm && tag != UnsignedImm && tag != Mem; }
+
+protected:
+ RM_Opnd(Tag t): Opnd(t) {}
+
+private:
+ // disallow copying
+ RM_Opnd(const RM_Opnd &): Opnd(Reg) { assert(false); }
+};
+
+class R_Opnd: public RM_Opnd {
+
+protected:
+ Reg_No _reg_no;
+
+public:
+ R_Opnd(Reg_No r): RM_Opnd(Reg), _reg_no(r) {}
+ Reg_No reg_no() const { return _reg_no; }
+
+private:
+ // disallow copying
+ R_Opnd(const R_Opnd &): RM_Opnd(Reg) { assert(false); }
+};
+
+//
+// a memory operand with displacement
+// Can also serve as a full memory operand with base,index, displacement and scale.
+// Use n_reg to specify 'no register', say, for index.
+class M_Opnd: public RM_Opnd {
+
+protected:
+ Imm_Opnd m_disp;
+ Imm_Opnd m_scale;
+ R_Opnd m_index;
+ R_Opnd m_base;
+
+public:
+ //M_Opnd(Opnd_Size sz): RM_Opnd(Mem, K_M, sz), m_disp(0), m_scale(0), m_index(n_reg), m_base(n_reg) {}
+ M_Opnd(I_32 disp):
+ RM_Opnd(Mem), m_disp(disp), m_scale(0), m_index(n_reg), m_base(n_reg) {}
+ M_Opnd(Reg_No rbase, I_32 rdisp):
+ RM_Opnd(Mem), m_disp(rdisp), m_scale(0), m_index(n_reg), m_base(rbase) {}
+ M_Opnd(I_32 disp, Reg_No rbase, Reg_No rindex, unsigned scale):
+ RM_Opnd(Mem), m_disp(disp), m_scale(scale), m_index(rindex), m_base(rbase) {}
+ M_Opnd(const M_Opnd & that) : RM_Opnd(Mem),
+ m_disp((int)that.m_disp.get_value()), m_scale((int)that.m_scale.get_value()),
+ m_index(that.m_index.reg_no()), m_base(that.m_base.reg_no())
+ {}
+ //
+ inline const R_Opnd & base(void) const { return m_base; }
+ inline const R_Opnd & index(void) const { return m_index; }
+ inline const Imm_Opnd & scale(void) const { return m_scale; }
+ inline const Imm_Opnd & disp(void) const { return m_disp; }
+};
+
+//
+// a memory operand with base register and displacement
+//
+class M_Base_Opnd: public M_Opnd {
+
+public:
+ M_Base_Opnd(Reg_No base, I_32 disp) : M_Opnd(disp, base, n_reg, 0) {}
+
+private:
+ // disallow copying - but it leads to ICC errors #734 in encoder.inl
+ // M_Base_Opnd(const M_Base_Opnd &): M_Opnd(0) { assert(false); }
+};
+
+//
+// a memory operand with base register, scaled index register
+// and displacement.
+//
+class M_Index_Opnd : public M_Opnd {
+
+public:
+ M_Index_Opnd(Reg_No base, Reg_No index, I_32 disp, unsigned scale):
+ M_Opnd(disp, base, index, scale) {}
+
+private:
+ // disallow copying - but it leads to ICC errors #734 in encoder.inl
+ // M_Index_Opnd(const M_Index_Opnd &): M_Opnd(0) { assert(false); }
+};
+
+class XMM_Opnd : public Opnd {
+
+protected:
+ unsigned m_idx;
+
+public:
+ XMM_Opnd(unsigned _idx): Opnd(XMM), m_idx(_idx) {};
+ unsigned get_idx( void ) const { return m_idx; };
+
+private:
+ // disallow copying
+ XMM_Opnd(const XMM_Opnd &): Opnd(XMM) { assert(false); }
+};
+
+//
+// operand structures for ia32 registers
+//
+#ifdef _EM64T_
+
+extern R_Opnd rax_opnd;
+extern R_Opnd rcx_opnd;
+extern R_Opnd rdx_opnd;
+extern R_Opnd rbx_opnd;
+extern R_Opnd rdi_opnd;
+extern R_Opnd rsi_opnd;
+extern R_Opnd rsp_opnd;
+extern R_Opnd rbp_opnd;
+
+extern R_Opnd r8_opnd;
+extern R_Opnd r9_opnd;
+extern R_Opnd r10_opnd;
+extern R_Opnd r11_opnd;
+extern R_Opnd r12_opnd;
+extern R_Opnd r13_opnd;
+extern R_Opnd r14_opnd;
+extern R_Opnd r15_opnd;
+
+extern XMM_Opnd xmm8_opnd;
+extern XMM_Opnd xmm9_opnd;
+extern XMM_Opnd xmm10_opnd;
+extern XMM_Opnd xmm11_opnd;
+extern XMM_Opnd xmm12_opnd;
+extern XMM_Opnd xmm13_opnd;
+extern XMM_Opnd xmm14_opnd;
+extern XMM_Opnd xmm15_opnd;
+#else
+
+extern R_Opnd eax_opnd;
+extern R_Opnd ecx_opnd;
+extern R_Opnd edx_opnd;
+extern R_Opnd ebx_opnd;
+extern R_Opnd esp_opnd;
+extern R_Opnd ebp_opnd;
+extern R_Opnd esi_opnd;
+extern R_Opnd edi_opnd;
+
+#endif // _EM64T_
+
+extern XMM_Opnd xmm0_opnd;
+extern XMM_Opnd xmm1_opnd;
+extern XMM_Opnd xmm2_opnd;
+extern XMM_Opnd xmm3_opnd;
+extern XMM_Opnd xmm4_opnd;
+extern XMM_Opnd xmm5_opnd;
+extern XMM_Opnd xmm6_opnd;
+extern XMM_Opnd xmm7_opnd;
+
+#ifdef NO_ENCODER_INLINE
+ #define ENCODER_DECLARE_EXPORT
+#else
+ #define ENCODER_DECLARE_EXPORT inline
+ #include "encoder.inl"
+#endif
+
+// prefix
+ENCODER_DECLARE_EXPORT char * prefix(char * stream, InstrPrefix p);
+
+// stack push and pop instructions
+ENCODER_DECLARE_EXPORT char * push(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * push(char * stream, const Imm_Opnd & imm);
+ENCODER_DECLARE_EXPORT char * pop(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// cmpxchg or xchg
+ENCODER_DECLARE_EXPORT char * cmpxchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * xchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+
+// inc(rement), dec(rement), not, neg(ate) instructions
+ENCODER_DECLARE_EXPORT char * inc(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * dec(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * _not(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * neg(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * nop(char * stream);
+ENCODER_DECLARE_EXPORT char * int3(char * stream);
+
+// alu instructions: add, or, adc, sbb, and, sub, xor, cmp
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const M_Opnd & m, const R_Opnd & r, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// test instruction
+ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+
+// shift instructions: shl, shr, sar, shld, shrd, ror
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf);
+
+// multiply instructions: mul, imul
+ENCODER_DECLARE_EXPORT char * mul(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm, const Imm_Opnd& imm, Opnd_Size sz = size_platf);
+
+// divide instructions: div, idiv
+ENCODER_DECLARE_EXPORT char * idiv(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * div(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// data movement: mov
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const M_Opnd & m, const R_Opnd & r, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * mov(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf);
+
+ENCODER_DECLARE_EXPORT char * movsx( char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * movzx( char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+ENCODER_DECLARE_EXPORT char * movd(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm);
+ENCODER_DECLARE_EXPORT char * movd(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm);
+ENCODER_DECLARE_EXPORT char * movq(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm);
+ENCODER_DECLARE_EXPORT char * movq(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm);
+
+// sse mov
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const M_Opnd & mem, const XMM_Opnd & xmm, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+// sse add, sub, mul, div
+ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+ENCODER_DECLARE_EXPORT char * sse_mul(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_mul(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+
+// xor, compare
+ENCODER_DECLARE_EXPORT char * sse_xor(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1);
+
+ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem, bool dbl);
+
+// sse conversions
+ENCODER_DECLARE_EXPORT char * sse_cvt_si(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const M_Opnd & mem, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const XMM_Opnd & xmm, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvt_fp2dq(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_cvt_dq2fp(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl);
+ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem64);
+ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1);
+ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem32);
+ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1);
+
+// condition operations
+ENCODER_DECLARE_EXPORT char * cmov(char * stream, ConditionCode cc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * setcc(char * stream, ConditionCode cc, const RM_Opnd & rm8);
+
+// load effective address: lea
+ENCODER_DECLARE_EXPORT char * lea(char * stream, const R_Opnd & r, const M_Opnd & m, Opnd_Size sz = size_platf);
+ENCODER_DECLARE_EXPORT char * cdq(char * stream);
+ENCODER_DECLARE_EXPORT char * wait(char * stream);
+
+// control-flow instructions
+ENCODER_DECLARE_EXPORT char * loop(char * stream, const Imm_Opnd & imm);
+
+// jump with 8-bit relative
+ENCODER_DECLARE_EXPORT char * jump8(char * stream, const Imm_Opnd & imm);
+
+// jump with 32-bit relative
+ENCODER_DECLARE_EXPORT char * jump32(char * stream, const Imm_Opnd & imm);
+
+// register indirect jump
+ENCODER_DECLARE_EXPORT char * jump(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// jump to target address
+ENCODER_DECLARE_EXPORT char *jump(char * stream, char *target);
+
+// jump with displacement
+//char * jump(char * stream, I_32 disp);
+
+// conditional branch with 8-bit branch offset
+ENCODER_DECLARE_EXPORT char * branch8(char * stream, ConditionCode cc, const Imm_Opnd & imm, InstrPrefix prefix = no_prefix);
+
+// conditional branch with 32-bit branch offset
+ENCODER_DECLARE_EXPORT char * branch32(char * stream, ConditionCode cc, const Imm_Opnd & imm, InstrPrefix prefix = no_prefix);
+
+// conditional branch with target label address
+//char * branch(char * stream, ConditionCode cc, const char * target, InstrPrefix prefix = no_prefix);
+
+// conditional branch with displacement immediate
+ENCODER_DECLARE_EXPORT char * branch(char * stream, ConditionCode cc, I_32 disp, InstrPrefix prefix = no_prefix);
+
+// call with displacement
+ENCODER_DECLARE_EXPORT char * call(char * stream, const Imm_Opnd & imm);
+
+// indirect call through register or memory location
+ENCODER_DECLARE_EXPORT char * call(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf);
+
+// call target address
+ENCODER_DECLARE_EXPORT char * call(char * stream, const char * target);
+
+// return instruction
+ENCODER_DECLARE_EXPORT char * ret(char * stream);
+ENCODER_DECLARE_EXPORT char * ret(char * stream, unsigned short pop);
+ENCODER_DECLARE_EXPORT char * ret(char * stream, const Imm_Opnd & imm);
+
+// string operations
+ENCODER_DECLARE_EXPORT char * set_d(char * stream, bool set);
+ENCODER_DECLARE_EXPORT char * scas(char * stream, unsigned char prefix);
+ENCODER_DECLARE_EXPORT char * stos(char * stream, unsigned char prefix);
+
+// floating-point instructions
+
+// st(0) = st(0) fp_op m{32,64}real
+//!char * fp_op_mem(char * stream, FP_Opcode opc,const M_Opnd& mem,int is_double);
+
+// st(0) = st(0) fp_op st(i)
+//!char *fp_op(char * stream, FP_Opcode opc,unsigned i);
+
+// st(i) = st(i) fp_op st(0) ; optionally pop stack
+//!char * fp_op(char * stream, FP_Opcode opc,unsigned i,unsigned pop_stk);
+
+// compare st(0),st(1) and pop stack twice
+//!char * fcompp(char * stream);
+ENCODER_DECLARE_EXPORT char * fldcw(char * stream, const M_Opnd & mem);
+ENCODER_DECLARE_EXPORT char * fnstcw(char * stream, const M_Opnd & mem);
+ENCODER_DECLARE_EXPORT char * fnstsw(char * stream);
+//!char * fchs(char * stream);
+//!char * frem(char * stream);
+//!char * fxch(char * stream,unsigned i);
+//!char * fcomip(char * stream, unsigned i);
+
+// load from memory (as fp) into fp register stack
+ENCODER_DECLARE_EXPORT char * fld(char * stream, const M_Opnd & m, bool is_double);
+//!char *fld80(char * stream,const M_Opnd& mem);
+
+// load from memory (as int) into fp register stack
+//!char * fild(char * stream,const M_Opnd& mem,int is_long);
+
+// push st(i) onto fp register stack
+//!char * fld(char * stream,unsigned i);
+
+// push the constants 0.0 and 1.0 onto the fp register stack
+//!char * fldz(char * stream);
+//!char * fld1(char * stream);
+
+// store stack to memory (as int), always popping the stack
+ENCODER_DECLARE_EXPORT char * fist(char * stream, const M_Opnd & mem, bool is_long, bool pop_stk);
+// store stack to to memory (as fp), optionally popping the stack
+ENCODER_DECLARE_EXPORT char * fst(char * stream, const M_Opnd & m, bool is_double, bool pop_stk);
+// store ST(0) to ST(i), optionally popping the stack. Takes 1 clock
+ENCODER_DECLARE_EXPORT char * fst(char * stream, unsigned i, bool pop_stk);
+
+//!char * pushad(char * stream);
+//!char * pushfd(char * stream);
+//!char * popad(char * stream);
+//!char * popfd(char * stream);
+
+// stack frame allocation instructions: enter & leave
+//
+// enter frame_size
+//
+// is equivalent to:
+//
+// push ebp
+// mov ebp,esp
+// sub esp,frame_size
+//
+//!char *enter(char * stream,const Imm_Opnd& imm);
+
+// leave
+// is equivalent to:
+//
+// mov esp,ebp
+// pop ebp
+//!char *leave(char * stream);
+
+// sahf loads SF, ZF, AF, PF, and CF flags from eax
+//!char *sahf(char * stream);
+
+// Intrinsic FP math functions
+
+//!char *math_fsin(char * stream);
+//!char *math_fcos(char * stream);
+//!char *math_fabs(char * stream);
+//!char *math_fpatan(char * stream);
+ENCODER_DECLARE_EXPORT char * fprem(char * stream);
+ENCODER_DECLARE_EXPORT char * fprem1(char * stream);
+//!char *math_frndint(char * stream);
+//!char *math_fptan(char * stream);
+
+//
+// Add 1-7 bytes padding, with as few instructions as possible,
+// with no effect on the processor state (e.g., registers, flags)
+//
+//!char *padding(char * stream, unsigned num);
+
+// prolog and epilog code generation
+//- char *prolog(char * stream,unsigned frame_size,unsigned reg_save_mask);
+//- char *epilog(char * stream,unsigned reg_save_mask);
+
+//!extern R_Opnd reg_operand_array[];
+
+// fsave and frstor
+//!char *fsave(char * stream);
+//!char *frstor(char * stream);
+
+// lahf : Load Status Flags into AH Register
+//!char *lahf(char * stream);
+
+// mfence : Memory Fence
+//!char *mfence(char * stream);
+
+#endif // _VM_ENCODER_H_