encoder.h revision 0c2dc522d0e120f346cf0a40c8cf0c93346131c2
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/** 18 * @author Alexander V. Astapchuk 19 */ 20/** 21 * @file 22 * @brief Simple interface for generating processor instructions. 23 * 24 * The interface works for both IA32 and EM64T. By default, only IA32 25 * capabilities are presented. To enable EM64T feature, the _EM64T_ macro 26 * must be defined (and, of course, a proper library version to be used). 27 * 28 * The interface is based on the original ia32.h encoder interface, 29 * with some simplifications and add-ons - EM64T-specific, SSE and SSE2. 30 * 31 * The interface mostly intended for existing legacy code like LIL code 32 * generator. From the implementation point of view, it's just a wrapper 33 * around the EncoderBase functionality. 34 */ 35 36#ifndef _VM_ENCODER_H_ 37#define _VM_ENCODER_H_ 38 39#include <limits.h> 40#include "enc_base.h" 41//#include "open/types.h" 42 43#ifdef _EM64T_ 44// size of general-purpose value on the stack in bytes 45#define GR_STACK_SIZE 8 46// size of floating-point value on the stack in bytes 47#define FR_STACK_SIZE 8 48 49#if defined(WIN32) || defined(_WIN64) 50 // maximum number of GP registers for inputs 51 const int MAX_GR = 4; 52 // maximum number of FP registers for inputs 53 const int MAX_FR = 4; 54 // WIN64 reserves 4 words for shadow space 55 const int SHADOW = 4 * GR_STACK_SIZE; 56#else 57 // maximum number of GP registers for inputs 58 const int MAX_GR = 6; 59 // maximum number of FP registers for inputs 60 const int MAX_FR = 8; 61 // Linux x64 doesn't reserve shadow space 62 const int SHADOW = 0; 63#endif 64 65#else 66// size of general-purpose value on the stack in bytes 67#define GR_STACK_SIZE 4 68// size of general-purpose value on the stack in bytes 69#define FR_STACK_SIZE 8 70 71// maximum number of GP registers for inputs 72const int MAX_GR = 0; 73// maximum number of FP registers for inputs 74const int MAX_FR = 0; 75#endif 76 77typedef enum Reg_No { 78#ifdef _EM64T_ 79 rax_reg = 0,rbx_reg, rcx_reg, rdx_reg, 80 rdi_reg, rsi_reg, rsp_reg, rbp_reg, 81 r8_reg, r9_reg, r10_reg, r11_reg, 82 r12_reg, r13_reg, r14_reg, r15_reg, 83 xmm0_reg, xmm1_reg, xmm2_reg, xmm3_reg, 84 xmm4_reg, xmm5_reg, xmm6_reg, xmm7_reg, 85 xmm8_reg, xmm9_reg, xmm10_reg, xmm11_reg, 86 xmm12_reg, xmm13_reg, xmm14_reg, xmm15_reg, 87 88#else // !defined(_EM64T_) 89 90 eax_reg = 0,ebx_reg, ecx_reg, edx_reg, 91 edi_reg, esi_reg, esp_reg, ebp_reg, 92 xmm0_reg, xmm1_reg, xmm2_reg, xmm3_reg, 93 xmm4_reg, xmm5_reg, xmm6_reg, xmm7_reg, 94 fs_reg, 95#endif 96 /** @brief Total number of registers.*/ 97 n_reg 98} Reg_No; 99// 100// instruction operand sizes: 8,16,32,64 bits 101// 102typedef enum Opnd_Size { 103 size_8 = 0, 104 size_16, 105 size_32, 106 size_64, 107 n_size, 108#ifdef _EM64T_ 109 size_platf = size_64 110#else 111 size_platf = size_32 112#endif 113} Opnd_Size; 114 115// 116// opcodes for alu instructions 117// 118typedef enum ALU_Opcode { 119 add_opc = 0,or_opc, adc_opc, sbb_opc, 120 and_opc, sub_opc, xor_opc, cmp_opc, 121 n_alu 122} ALU_Opcode; 123 124// 125// opcodes for shift instructions 126// 127typedef enum Shift_Opcode { 128 shld_opc, shrd_opc, shl_opc, shr_opc, 129 sar_opc, ror_opc, max_shift_opcode=6, n_shift = 6 130} Shift_Opcode; 131 132typedef enum ConditionCode { 133 Condition_O = 0, 134 Condition_NO = 1, 135 Condition_B = 2, 136 Condition_NAE = Condition_B, 137 Condition_C = Condition_B, 138 Condition_NB = 3, 139 Condition_AE = Condition_NB, 140 Condition_NC = Condition_NB, 141 Condition_Z = 4, 142 Condition_E = Condition_Z, 143 Condition_NZ = 5, 144 Condition_NE = Condition_NZ, 145 Condition_BE = 6, 146 Condition_NA = Condition_BE, 147 Condition_NBE = 7, 148 Condition_A = Condition_NBE, 149 150 Condition_S = 8, 151 Condition_NS = 9, 152 Condition_P = 10, 153 Condition_PE = Condition_P, 154 Condition_NP = 11, 155 Condition_PO = Condition_NP, 156 Condition_L = 12, 157 Condition_NGE = Condition_L, 158 Condition_NL = 13, 159 Condition_GE = Condition_NL, 160 Condition_LE = 14, 161 Condition_NG = Condition_LE, 162 Condition_NLE = 15, 163 Condition_G = Condition_NLE, 164 Condition_Count = 16 165} ConditionCode; 166 167// 168// prefix code 169// 170typedef enum InstrPrefix { 171 no_prefix, 172 lock_prefix = 0xF0, 173 hint_branch_taken_prefix = 0x2E, 174 hint_branch_not_taken_prefix = 0x3E, 175 prefix_repne = 0xF2, 176 prefix_repnz = prefix_repne, 177 prefix_repe = 0xF3, 178 prefix_repz = prefix_repe, 179 prefix_rep = 0xF3, 180 prefix_cs = 0x2E, 181 prefix_ss = 0x36, 182 prefix_ds = 0x3E, 183 prefix_es = 0x26, 184 prefix_fs = 0x64, 185 prefix_gs = 0x65 186} InstrPrefix; 187 188 189// 190// an instruction operand 191// 192class Opnd { 193 194protected: 195 enum Tag { SignedImm, UnsignedImm, Reg, Mem, FP, XMM }; 196 197 const Tag tag; 198 199 Opnd(Tag t): tag(t) {} 200 201public: 202 void * operator new(size_t, void * mem) { 203 return mem; 204 } 205 206 void operator delete(void *) {} 207 208 void operator delete(void *, void *) {} 209 210private: 211 // disallow copying 212 Opnd(const Opnd &): tag(Mem) { assert(false); } 213 Opnd& operator=(const Opnd &) { assert(false); return *this; } 214}; 215typedef int I_32; 216class Imm_Opnd: public Opnd { 217 218protected: 219 union { 220#ifdef _EM64T_ 221 int64 value; 222 unsigned char bytes[8]; 223#else 224 I_32 value; 225 unsigned char bytes[4]; 226#endif 227 }; 228 Opnd_Size size; 229 230public: 231 Imm_Opnd(I_32 val, bool isSigned = true): 232 Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(size_32) { 233 if (isSigned) { 234 if (CHAR_MIN <= val && val <= CHAR_MAX) { 235 size = size_8; 236 } else if (SHRT_MIN <= val && val <= SHRT_MAX) { 237 size = size_16; 238 } 239 } else { 240 assert(val >= 0); 241 if (val <= UCHAR_MAX) { 242 size = size_8; 243 } else if (val <= USHRT_MAX) { 244 size = size_16; 245 } 246 } 247 } 248 Imm_Opnd(const Imm_Opnd& that): Opnd(that.tag), value(that.value), size(that.size) {}; 249 250#ifdef _EM64T_ 251 Imm_Opnd(Opnd_Size sz, int64 val, bool isSigned = true): 252 Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) { 253#ifndef NDEBUG 254 switch (size) { 255 case size_8: 256 assert(val == (int64)(I_8)val); 257 break; 258 case size_16: 259 assert(val == (int64)(int16)val); 260 break; 261 case size_32: 262 assert(val == (int64)(I_32)val); 263 break; 264 case size_64: 265 break; 266 case n_size: 267 assert(false); 268 break; 269 } 270#endif // NDEBUG 271 } 272 273 int64 get_value() const { return value; } 274 275#else 276 277 Imm_Opnd(Opnd_Size sz, I_32 val, int isSigned = true): 278 Opnd(isSigned ? SignedImm : UnsignedImm), value(val), size(sz) { 279#ifndef NDEBUG 280 switch (size) { 281 case size_8: 282 assert((I_32)val == (I_32)(I_8)val); 283 break; 284 case size_16: 285 assert((I_32)val == (I_32)(int16)val); 286 break; 287 case size_32: 288 break; 289 case size_64: 290 case n_size: 291 assert(false); 292 break; 293 } 294#endif // NDEBUG 295 } 296 297 I_32 get_value() const { return value; } 298 299#endif 300 Opnd_Size get_size() const { return size; } 301 bool is_signed() const { return tag == SignedImm; } 302}; 303 304class RM_Opnd: public Opnd { 305 306public: 307 bool is_reg() const { return tag != SignedImm && tag != UnsignedImm && tag != Mem; } 308 309protected: 310 RM_Opnd(Tag t): Opnd(t) {} 311 312private: 313 // disallow copying 314 RM_Opnd(const RM_Opnd &): Opnd(Reg) { assert(false); } 315}; 316 317class R_Opnd: public RM_Opnd { 318 319protected: 320 Reg_No _reg_no; 321 322public: 323 R_Opnd(Reg_No r): RM_Opnd(Reg), _reg_no(r) {} 324 Reg_No reg_no() const { return _reg_no; } 325 326private: 327 // disallow copying 328 R_Opnd(const R_Opnd &): RM_Opnd(Reg) { assert(false); } 329}; 330 331// 332// a memory operand with displacement 333// Can also serve as a full memory operand with base,index, displacement and scale. 334// Use n_reg to specify 'no register', say, for index. 335class M_Opnd: public RM_Opnd { 336 337protected: 338 Imm_Opnd m_disp; 339 Imm_Opnd m_scale; 340 R_Opnd m_index; 341 R_Opnd m_base; 342 343public: 344 //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) {} 345 M_Opnd(I_32 disp): 346 RM_Opnd(Mem), m_disp(disp), m_scale(0), m_index(n_reg), m_base(n_reg) {} 347 M_Opnd(Reg_No rbase, I_32 rdisp): 348 RM_Opnd(Mem), m_disp(rdisp), m_scale(0), m_index(n_reg), m_base(rbase) {} 349 M_Opnd(I_32 disp, Reg_No rbase, Reg_No rindex, unsigned scale): 350 RM_Opnd(Mem), m_disp(disp), m_scale(scale), m_index(rindex), m_base(rbase) {} 351 M_Opnd(const M_Opnd & that) : RM_Opnd(Mem), 352 m_disp((int)that.m_disp.get_value()), m_scale((int)that.m_scale.get_value()), 353 m_index(that.m_index.reg_no()), m_base(that.m_base.reg_no()) 354 {} 355 // 356 inline const R_Opnd & base(void) const { return m_base; } 357 inline const R_Opnd & index(void) const { return m_index; } 358 inline const Imm_Opnd & scale(void) const { return m_scale; } 359 inline const Imm_Opnd & disp(void) const { return m_disp; } 360}; 361 362// 363// a memory operand with base register and displacement 364// 365class M_Base_Opnd: public M_Opnd { 366 367public: 368 M_Base_Opnd(Reg_No base, I_32 disp) : M_Opnd(disp, base, n_reg, 0) {} 369 370private: 371 // disallow copying - but it leads to ICC errors #734 in encoder.inl 372 // M_Base_Opnd(const M_Base_Opnd &): M_Opnd(0) { assert(false); } 373}; 374 375// 376// a memory operand with base register, scaled index register 377// and displacement. 378// 379class M_Index_Opnd : public M_Opnd { 380 381public: 382 M_Index_Opnd(Reg_No base, Reg_No index, I_32 disp, unsigned scale): 383 M_Opnd(disp, base, index, scale) {} 384 385private: 386 // disallow copying - but it leads to ICC errors #734 in encoder.inl 387 // M_Index_Opnd(const M_Index_Opnd &): M_Opnd(0) { assert(false); } 388}; 389 390class XMM_Opnd : public Opnd { 391 392protected: 393 unsigned m_idx; 394 395public: 396 XMM_Opnd(unsigned _idx): Opnd(XMM), m_idx(_idx) {}; 397 unsigned get_idx( void ) const { return m_idx; }; 398 399private: 400 // disallow copying 401 XMM_Opnd(const XMM_Opnd &): Opnd(XMM) { assert(false); } 402}; 403 404// 405// operand structures for ia32 registers 406// 407#ifdef _EM64T_ 408 409extern R_Opnd rax_opnd; 410extern R_Opnd rcx_opnd; 411extern R_Opnd rdx_opnd; 412extern R_Opnd rbx_opnd; 413extern R_Opnd rdi_opnd; 414extern R_Opnd rsi_opnd; 415extern R_Opnd rsp_opnd; 416extern R_Opnd rbp_opnd; 417 418extern R_Opnd r8_opnd; 419extern R_Opnd r9_opnd; 420extern R_Opnd r10_opnd; 421extern R_Opnd r11_opnd; 422extern R_Opnd r12_opnd; 423extern R_Opnd r13_opnd; 424extern R_Opnd r14_opnd; 425extern R_Opnd r15_opnd; 426 427extern XMM_Opnd xmm8_opnd; 428extern XMM_Opnd xmm9_opnd; 429extern XMM_Opnd xmm10_opnd; 430extern XMM_Opnd xmm11_opnd; 431extern XMM_Opnd xmm12_opnd; 432extern XMM_Opnd xmm13_opnd; 433extern XMM_Opnd xmm14_opnd; 434extern XMM_Opnd xmm15_opnd; 435#else 436 437extern R_Opnd eax_opnd; 438extern R_Opnd ecx_opnd; 439extern R_Opnd edx_opnd; 440extern R_Opnd ebx_opnd; 441extern R_Opnd esp_opnd; 442extern R_Opnd ebp_opnd; 443extern R_Opnd esi_opnd; 444extern R_Opnd edi_opnd; 445 446#endif // _EM64T_ 447 448extern XMM_Opnd xmm0_opnd; 449extern XMM_Opnd xmm1_opnd; 450extern XMM_Opnd xmm2_opnd; 451extern XMM_Opnd xmm3_opnd; 452extern XMM_Opnd xmm4_opnd; 453extern XMM_Opnd xmm5_opnd; 454extern XMM_Opnd xmm6_opnd; 455extern XMM_Opnd xmm7_opnd; 456 457#ifdef NO_ENCODER_INLINE 458 #define ENCODER_DECLARE_EXPORT 459#else 460 #define ENCODER_DECLARE_EXPORT inline 461 #include "encoder.inl" 462#endif 463 464// prefix 465ENCODER_DECLARE_EXPORT char * prefix(char * stream, InstrPrefix p); 466 467// stack push and pop instructions 468ENCODER_DECLARE_EXPORT char * push(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 469ENCODER_DECLARE_EXPORT char * push(char * stream, const Imm_Opnd & imm); 470ENCODER_DECLARE_EXPORT char * pop(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 471 472// cmpxchg or xchg 473ENCODER_DECLARE_EXPORT char * cmpxchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf); 474ENCODER_DECLARE_EXPORT char * xchg(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf); 475 476// inc(rement), dec(rement), not, neg(ate) instructions 477ENCODER_DECLARE_EXPORT char * inc(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 478ENCODER_DECLARE_EXPORT char * dec(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 479ENCODER_DECLARE_EXPORT char * _not(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 480ENCODER_DECLARE_EXPORT char * neg(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 481ENCODER_DECLARE_EXPORT char * nop(char * stream); 482ENCODER_DECLARE_EXPORT char * int3(char * stream); 483 484// alu instructions: add, or, adc, sbb, and, sub, xor, cmp 485ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf); 486ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const M_Opnd & m, const R_Opnd & r, Opnd_Size sz = size_platf); 487ENCODER_DECLARE_EXPORT char * alu(char * stream, ALU_Opcode opc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf); 488 489// test instruction 490ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf); 491ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf); 492 493// shift instructions: shl, shr, sar, shld, shrd, ror 494ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf); 495ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, Opnd_Size sz = size_platf); 496ENCODER_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); 497ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf); 498 499// multiply instructions: mul, imul 500ENCODER_DECLARE_EXPORT char * mul(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 501ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf); 502ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz = size_platf); 503ENCODER_DECLARE_EXPORT char * imul(char * stream, const R_Opnd & r, const RM_Opnd & rm, const Imm_Opnd& imm, Opnd_Size sz = size_platf); 504 505// divide instructions: div, idiv 506ENCODER_DECLARE_EXPORT char * idiv(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 507 508// data movement: mov 509ENCODER_DECLARE_EXPORT char * mov(char * stream, const M_Opnd & m, const R_Opnd & r, Opnd_Size sz = size_platf); 510ENCODER_DECLARE_EXPORT char * mov(char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf); 511ENCODER_DECLARE_EXPORT char * mov(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf); 512 513ENCODER_DECLARE_EXPORT char * movsx( char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf); 514ENCODER_DECLARE_EXPORT char * movzx( char * stream, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf); 515 516ENCODER_DECLARE_EXPORT char * movd(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm); 517ENCODER_DECLARE_EXPORT char * movd(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm); 518ENCODER_DECLARE_EXPORT char * movq(char * stream, const RM_Opnd & rm, const XMM_Opnd & xmm); 519ENCODER_DECLARE_EXPORT char * movq(char * stream, const XMM_Opnd & xmm, const RM_Opnd & rm); 520 521// sse mov 522ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl); 523ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const M_Opnd & mem, const XMM_Opnd & xmm, bool dbl); 524ENCODER_DECLARE_EXPORT char * sse_mov(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 525 526// sse add, sub, mul, div 527ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl); 528ENCODER_DECLARE_EXPORT char * sse_add(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 529 530ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl); 531ENCODER_DECLARE_EXPORT char * sse_sub(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 532 533ENCODER_DECLARE_EXPORT char * sse_mul(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl); 534ENCODER_DECLARE_EXPORT char * sse_mul(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 535 536ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl); 537ENCODER_DECLARE_EXPORT char * sse_div(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 538 539// xor, compare 540ENCODER_DECLARE_EXPORT char * sse_xor(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1); 541 542ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 543ENCODER_DECLARE_EXPORT char * sse_compare(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem, bool dbl); 544 545// sse conversions 546ENCODER_DECLARE_EXPORT char * sse_cvt_si(char * stream, const XMM_Opnd & xmm, const M_Opnd & mem, bool dbl); 547ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const M_Opnd & mem, bool dbl); 548ENCODER_DECLARE_EXPORT char * sse_cvtt2si(char * stream, const R_Opnd & reg, const XMM_Opnd & xmm, bool dbl); 549ENCODER_DECLARE_EXPORT char * sse_cvt_fp2dq(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 550ENCODER_DECLARE_EXPORT char * sse_cvt_dq2fp(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1, bool dbl); 551ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem64); 552ENCODER_DECLARE_EXPORT char * sse_d2s(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1); 553ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const M_Opnd & mem32); 554ENCODER_DECLARE_EXPORT char * sse_s2d(char * stream, const XMM_Opnd & xmm0, const XMM_Opnd & xmm1); 555 556// condition operations 557ENCODER_DECLARE_EXPORT char * cmov(char * stream, ConditionCode cc, const R_Opnd & r, const RM_Opnd & rm, Opnd_Size sz = size_platf); 558ENCODER_DECLARE_EXPORT char * setcc(char * stream, ConditionCode cc, const RM_Opnd & rm8); 559 560// load effective address: lea 561ENCODER_DECLARE_EXPORT char * lea(char * stream, const R_Opnd & r, const M_Opnd & m, Opnd_Size sz = size_platf); 562ENCODER_DECLARE_EXPORT char * cdq(char * stream); 563ENCODER_DECLARE_EXPORT char * wait(char * stream); 564 565// control-flow instructions 566ENCODER_DECLARE_EXPORT char * loop(char * stream, const Imm_Opnd & imm); 567 568// jump with 8-bit relative 569ENCODER_DECLARE_EXPORT char * jump8(char * stream, const Imm_Opnd & imm); 570 571// jump with 32-bit relative 572ENCODER_DECLARE_EXPORT char * jump32(char * stream, const Imm_Opnd & imm); 573 574// register indirect jump 575ENCODER_DECLARE_EXPORT char * jump(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 576 577// jump to target address 578ENCODER_DECLARE_EXPORT char *jump(char * stream, char *target); 579 580// jump with displacement 581//char * jump(char * stream, I_32 disp); 582 583// conditional branch with 8-bit branch offset 584ENCODER_DECLARE_EXPORT char * branch8(char * stream, ConditionCode cc, const Imm_Opnd & imm, InstrPrefix prefix = no_prefix); 585 586// conditional branch with 32-bit branch offset 587ENCODER_DECLARE_EXPORT char * branch32(char * stream, ConditionCode cc, const Imm_Opnd & imm, InstrPrefix prefix = no_prefix); 588 589// conditional branch with target label address 590//char * branch(char * stream, ConditionCode cc, const char * target, InstrPrefix prefix = no_prefix); 591 592// conditional branch with displacement immediate 593ENCODER_DECLARE_EXPORT char * branch(char * stream, ConditionCode cc, I_32 disp, InstrPrefix prefix = no_prefix); 594 595// call with displacement 596ENCODER_DECLARE_EXPORT char * call(char * stream, const Imm_Opnd & imm); 597 598// indirect call through register or memory location 599ENCODER_DECLARE_EXPORT char * call(char * stream, const RM_Opnd & rm, Opnd_Size sz = size_platf); 600 601// call target address 602ENCODER_DECLARE_EXPORT char * call(char * stream, const char * target); 603 604// return instruction 605ENCODER_DECLARE_EXPORT char * ret(char * stream); 606ENCODER_DECLARE_EXPORT char * ret(char * stream, unsigned short pop); 607ENCODER_DECLARE_EXPORT char * ret(char * stream, const Imm_Opnd & imm); 608 609// string operations 610ENCODER_DECLARE_EXPORT char * set_d(char * stream, bool set); 611ENCODER_DECLARE_EXPORT char * scas(char * stream, unsigned char prefix); 612ENCODER_DECLARE_EXPORT char * stos(char * stream, unsigned char prefix); 613 614// floating-point instructions 615 616// st(0) = st(0) fp_op m{32,64}real 617//!char * fp_op_mem(char * stream, FP_Opcode opc,const M_Opnd& mem,int is_double); 618 619// st(0) = st(0) fp_op st(i) 620//!char *fp_op(char * stream, FP_Opcode opc,unsigned i); 621 622// st(i) = st(i) fp_op st(0) ; optionally pop stack 623//!char * fp_op(char * stream, FP_Opcode opc,unsigned i,unsigned pop_stk); 624 625// compare st(0),st(1) and pop stack twice 626//!char * fcompp(char * stream); 627ENCODER_DECLARE_EXPORT char * fldcw(char * stream, const M_Opnd & mem); 628ENCODER_DECLARE_EXPORT char * fnstcw(char * stream, const M_Opnd & mem); 629ENCODER_DECLARE_EXPORT char * fnstsw(char * stream); 630//!char * fchs(char * stream); 631//!char * frem(char * stream); 632//!char * fxch(char * stream,unsigned i); 633//!char * fcomip(char * stream, unsigned i); 634 635// load from memory (as fp) into fp register stack 636ENCODER_DECLARE_EXPORT char * fld(char * stream, const M_Opnd & m, bool is_double); 637//!char *fld80(char * stream,const M_Opnd& mem); 638 639// load from memory (as int) into fp register stack 640//!char * fild(char * stream,const M_Opnd& mem,int is_long); 641 642// push st(i) onto fp register stack 643//!char * fld(char * stream,unsigned i); 644 645// push the constants 0.0 and 1.0 onto the fp register stack 646//!char * fldz(char * stream); 647//!char * fld1(char * stream); 648 649// store stack to memory (as int), always popping the stack 650ENCODER_DECLARE_EXPORT char * fist(char * stream, const M_Opnd & mem, bool is_long, bool pop_stk); 651// store stack to to memory (as fp), optionally popping the stack 652ENCODER_DECLARE_EXPORT char * fst(char * stream, const M_Opnd & m, bool is_double, bool pop_stk); 653// store ST(0) to ST(i), optionally popping the stack. Takes 1 clock 654ENCODER_DECLARE_EXPORT char * fst(char * stream, unsigned i, bool pop_stk); 655 656//!char * pushad(char * stream); 657//!char * pushfd(char * stream); 658//!char * popad(char * stream); 659//!char * popfd(char * stream); 660 661// stack frame allocation instructions: enter & leave 662// 663// enter frame_size 664// 665// is equivalent to: 666// 667// push ebp 668// mov ebp,esp 669// sub esp,frame_size 670// 671//!char *enter(char * stream,const Imm_Opnd& imm); 672 673// leave 674// is equivalent to: 675// 676// mov esp,ebp 677// pop ebp 678//!char *leave(char * stream); 679 680// sahf loads SF, ZF, AF, PF, and CF flags from eax 681//!char *sahf(char * stream); 682 683// Intrinsic FP math functions 684 685//!char *math_fsin(char * stream); 686//!char *math_fcos(char * stream); 687//!char *math_fabs(char * stream); 688//!char *math_fpatan(char * stream); 689ENCODER_DECLARE_EXPORT char * fprem(char * stream); 690ENCODER_DECLARE_EXPORT char * fprem1(char * stream); 691//!char *math_frndint(char * stream); 692//!char *math_fptan(char * stream); 693 694// 695// Add 1-7 bytes padding, with as few instructions as possible, 696// with no effect on the processor state (e.g., registers, flags) 697// 698//!char *padding(char * stream, unsigned num); 699 700// prolog and epilog code generation 701//- char *prolog(char * stream,unsigned frame_size,unsigned reg_save_mask); 702//- char *epilog(char * stream,unsigned reg_save_mask); 703 704//!extern R_Opnd reg_operand_array[]; 705 706// fsave and frstor 707//!char *fsave(char * stream); 708//!char *frstor(char * stream); 709 710// lahf : Load Status Flags into AH Register 711//!char *lahf(char * stream); 712 713// mfence : Memory Fence 714//!char *mfence(char * stream); 715 716#endif // _VM_ENCODER_H_ 717