- Main Page
- Modules
- Data Structures
- Files

- Search for |

- File List
- Globals

# xed-encoder-hl.h

Go to the documentation of this file.

    00001 /*BEGIN_LEGAL
    00002 Intel Open Source License
    00003
    00004 Copyright (c) 2002-2014 Intel Corporation. All rights reserved.
    00005
    00006 Redistribution and use in source and binary forms, with or without
    00007 modification, are permitted provided that the following conditions are
    00008 met:
    00009
    00010 Redistributions of source code must retain the above copyright notice,
    00011 this list of conditions and the following disclaimer.  Redistributions
    00012 in binary form must reproduce the above copyright notice, this list of
    00013 conditions and the following disclaimer in the documentation and/or
    00014 other materials provided with the distribution.  Neither the name of
    00015 the Intel Corporation nor the names of its contributors may be used to
    00016 endorse or promote products derived from this software without
    00017 specific prior written permission.
    00018
    00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    00020 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    00021 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    00022 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
    00023 ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    00024 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    00025 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    00026 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    00027 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00028 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    00029 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00030 END_LEGAL */
    00031
    00032 #ifndef _XED_ENCODER_HL_H_
    00033 # define _XED_ENCODER_HL_H_
    00034 #include "xed-types.h"
    00035 #include "xed-reg-enum.h"
    00036 #include "xed-state.h"
    00037 #include "xed-iclass-enum.h"
    00038 #include "xed-portability.h"
    00039 #include "xed-encode.h"
    00040
    00041
    00042 typedef struct {
    00043     xed_uint64_t   displacement;
    00044     xed_uint32_t   displacement_width;
    00045 } xed_enc_displacement_t; /* fixme bad name */
    00046
    00048
    00049
    00050
    00051 static XED_INLINE
    00052 xed_enc_displacement_t xed_disp(xed_uint64_t   displacement,
    00053                                 xed_uint32_t   displacement_width   ) {
    00054     xed_enc_displacement_t x;
    00055     x.displacement = displacement;
    00056     x.displacement_width = displacement_width;
    00057     return x;
    00058 }
    00060
    00061 typedef struct {
    00062     xed_reg_enum_t seg;
    00063     xed_reg_enum_t base;
    00064     xed_reg_enum_t index;
    00065     xed_uint32_t   scale;
    00066     xed_enc_displacement_t disp;
    00067 } xed_memop_t;
    00068
    00069
    00070 typedef enum {
    00071     XED_ENCODER_OPERAND_TYPE_INVALID,
    00072     XED_ENCODER_OPERAND_TYPE_BRDISP,
    00073     XED_ENCODER_OPERAND_TYPE_REG,
    00074     XED_ENCODER_OPERAND_TYPE_IMM0,
    00075     XED_ENCODER_OPERAND_TYPE_SIMM0,
    00076     XED_ENCODER_OPERAND_TYPE_IMM1,
    00077     XED_ENCODER_OPERAND_TYPE_MEM,
    00078     XED_ENCODER_OPERAND_TYPE_PTR,
    00079
    00080      /* special for things with suppressed implicit memops */
    00081     XED_ENCODER_OPERAND_TYPE_SEG0,
    00082
    00083      /* special for things with suppressed implicit memops */
    00084     XED_ENCODER_OPERAND_TYPE_SEG1,
    00085
    00086     /* specific operand storage fields -- must supply a name */
    00087     XED_ENCODER_OPERAND_TYPE_OTHER
    00088 } xed_encoder_operand_type_t;
    00089
    00090 typedef struct {
    00091     xed_encoder_operand_type_t  type;
    00092     union {
    00093         xed_reg_enum_t reg;
    00094         xed_int32_t brdisp;
    00095         xed_uint64_t imm0;
    00096         xed_uint8_t imm1;
    00097         struct {
    00098             xed_operand_enum_t operand_name;
    00099             xed_uint32_t       value;
    00100         } s;
    00101         xed_memop_t mem;
    00102     } u;
    00103     xed_uint32_t width;
    00104 } xed_encoder_operand_t;
    00105
    00107
    00108
    00109
    00110 static XED_INLINE  xed_encoder_operand_t xed_relbr(xed_int32_t brdisp,
    00111                                                    xed_uint_t width) {
    00112     xed_encoder_operand_t o;
    00113     o.type = XED_ENCODER_OPERAND_TYPE_BRDISP;
    00114     o.u.brdisp = brdisp;
    00115     o.width = width;
    00116     return o;
    00117 }
    00119
    00121
    00122
    00123
    00124
    00125 static XED_INLINE  xed_encoder_operand_t xed_ptr(xed_int32_t brdisp,
    00126                                                  xed_uint_t width) {
    00127     xed_encoder_operand_t o;
    00128     o.type = XED_ENCODER_OPERAND_TYPE_PTR;
    00129     o.u.brdisp = brdisp;
    00130     o.width = width;
    00131     return o;
    00132 }
    00134
    00136
    00137
    00138
    00139 static XED_INLINE  xed_encoder_operand_t xed_reg(xed_reg_enum_t reg) {
    00140     xed_encoder_operand_t o;
    00141     o.type = XED_ENCODER_OPERAND_TYPE_REG;
    00142     o.u.reg = reg;
    00143     o.width = 0;
    00144     return o;
    00145 }
    00146
    00149 static XED_INLINE  xed_encoder_operand_t xed_imm0(xed_uint64_t v,
    00150                                                   xed_uint_t width) {
    00151     xed_encoder_operand_t o;
    00152     o.type = XED_ENCODER_OPERAND_TYPE_IMM0;
    00153     o.u.imm0 = v;
    00154     o.width = width;
    00155     return o;
    00156 }
    00159 static XED_INLINE  xed_encoder_operand_t xed_simm0(xed_int32_t v,
    00160                                                    xed_uint_t width) {
    00161     xed_encoder_operand_t o;
    00162     o.type = XED_ENCODER_OPERAND_TYPE_SIMM0;
    00163     /* sign conversion: we store the int32 in an uint64. It gets sign
    00164     extended.  Later we convert it to the right width for the
    00165     instruction. The maximum width of a signed immediate is currently
    00166     32b. */
    00167     o.u.imm0 = v;
    00168     o.width = width;
    00169     return o;
    00170 }
    00171
    00174 static XED_INLINE  xed_encoder_operand_t xed_imm1(xed_uint8_t v) {
    00175     xed_encoder_operand_t o;
    00176     o.type = XED_ENCODER_OPERAND_TYPE_IMM1;
    00177     o.u.imm1 = v;
    00178     o.width = 8;
    00179     return o;
    00180 }
    00181
    00182
    00185 static XED_INLINE  xed_encoder_operand_t xed_other(
    00186                                             xed_operand_enum_t operand_name,
    00187                                             xed_int32_t value) {
    00188     xed_encoder_operand_t o;
    00189     o.type = XED_ENCODER_OPERAND_TYPE_OTHER;
    00190     o.u.s.operand_name = operand_name;
    00191     o.u.s.value = value;
    00192     o.width = 0;
    00193     return o;
    00194 }
    00196
    00197
    00199
    00201
    00202
    00205 static XED_INLINE  xed_encoder_operand_t xed_seg0(xed_reg_enum_t seg0) {
    00206     xed_encoder_operand_t o;
    00207     o.type = XED_ENCODER_OPERAND_TYPE_SEG0;
    00208     o.u.reg = seg0;
    00209     return o;
    00210 }
    00211
    00214 static XED_INLINE  xed_encoder_operand_t xed_seg1(xed_reg_enum_t seg1) {
    00215     xed_encoder_operand_t o;
    00216     o.type = XED_ENCODER_OPERAND_TYPE_SEG1;
    00217     o.u.reg = seg1;
    00218     return o;
    00219 }
    00220
    00223 static XED_INLINE  xed_encoder_operand_t xed_mem_b(xed_reg_enum_t base,
    00224                                                    xed_uint_t width) {
    00225     xed_encoder_operand_t o;
    00226     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
    00227     o.u.mem.base = base;
    00228     o.u.mem.seg = XED_REG_INVALID;
    00229     o.u.mem.index= XED_REG_INVALID;
    00230     o.u.mem.scale = 0;
    00231     o.u.mem.disp.displacement = 0;
    00232     o.u.mem.disp.displacement_width = 0;
    00233     o.width = width;
    00234     return o;
    00235 }
    00236
    00239 static XED_INLINE  xed_encoder_operand_t xed_mem_bd(xed_reg_enum_t base,
    00240                               xed_enc_displacement_t disp,
    00241                               xed_uint_t width) {
    00242     xed_encoder_operand_t o;
    00243     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
    00244     o.u.mem.base = base;
    00245     o.u.mem.seg = XED_REG_INVALID;
    00246     o.u.mem.index= XED_REG_INVALID;
    00247     o.u.mem.scale = 0;
    00248     o.u.mem.disp =disp;
    00249     o.width = width;
    00250     return o;
    00251 }
    00252
    00255 static XED_INLINE  xed_encoder_operand_t xed_mem_bisd(xed_reg_enum_t base,
    00256                                 xed_reg_enum_t index,
    00257                                 xed_uint_t scale,
    00258                                 xed_enc_displacement_t disp,
    00259                                 xed_uint_t width) {
    00260     xed_encoder_operand_t o;
    00261     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
    00262     o.u.mem.base = base;
    00263     o.u.mem.seg = XED_REG_INVALID;
    00264     o.u.mem.index= index;
    00265     o.u.mem.scale = scale;
    00266     o.u.mem.disp = disp;
    00267     o.width = width;
    00268     return o;
    00269 }
    00270
    00271
    00274 static XED_INLINE  xed_encoder_operand_t xed_mem_gb(xed_reg_enum_t seg,
    00275                                                     xed_reg_enum_t base,
    00276                                                     xed_uint_t width) {
    00277     xed_encoder_operand_t o;
    00278     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
    00279     o.u.mem.base = base;
    00280     o.u.mem.seg = seg;
    00281     o.u.mem.index= XED_REG_INVALID;
    00282     o.u.mem.scale = 0;
    00283     o.u.mem.disp.displacement = 0;
    00284     o.u.mem.disp.displacement_width = 0;
    00285     o.width = width;
    00286     return o;
    00287 }
    00288
    00291 static XED_INLINE  xed_encoder_operand_t xed_mem_gbd(xed_reg_enum_t seg,
    00292                                                   xed_reg_enum_t base,
    00293                                                   xed_enc_displacement_t disp,
    00294                                                   xed_uint_t width) {
    00295     xed_encoder_operand_t o;
    00296     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
    00297     o.u.mem.base = base;
    00298     o.u.mem.seg = seg;
    00299     o.u.mem.index= XED_REG_INVALID;
    00300     o.u.mem.scale = 0;
    00301     o.u.mem.disp = disp;
    00302     o.width = width;
    00303     return o;
    00304 }
    00305
    00308 static XED_INLINE  xed_encoder_operand_t xed_mem_gd(xed_reg_enum_t seg,
    00309                                xed_enc_displacement_t disp,
    00310                                xed_uint_t width) {
    00311     xed_encoder_operand_t o;
    00312     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
    00313     o.u.mem.base = XED_REG_INVALID;
    00314     o.u.mem.seg = seg;
    00315     o.u.mem.index= XED_REG_INVALID;
    00316     o.u.mem.scale = 0;
    00317     o.u.mem.disp = disp;
    00318     o.width = width;
    00319     return o;
    00320 }
    00321
    00324 static XED_INLINE  xed_encoder_operand_t xed_mem_gbisd(xed_reg_enum_t seg,
    00325                                  xed_reg_enum_t base,
    00326                                  xed_reg_enum_t index,
    00327                                  xed_uint_t scale,
    00328                                  xed_enc_displacement_t disp,
    00329                                  xed_uint_t width) {
    00330     xed_encoder_operand_t o;
    00331     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
    00332     o.u.mem.base = base;
    00333     o.u.mem.seg = seg;
    00334     o.u.mem.index= index;
    00335     o.u.mem.scale = scale;
    00336     o.u.mem.disp = disp;
    00337     o.width = width;
    00338     return o;
    00339 }
    00341
    00342 typedef union {
    00343     struct {
    00344         xed_uint32_t rep               :1;
    00345         xed_uint32_t repne             :1;
    00346         xed_uint32_t lock              :1;
    00347         xed_uint32_t br_hint_taken     :1;
    00348         xed_uint32_t br_hint_not_taken :1;
    00349     } s;
    00350     xed_uint32_t i;
    00351 }  xed_encoder_prefixes_t;
    00352
    00353 #define XED_ENCODER_OPERANDS_MAX 5 /* FIXME */
    00354 typedef struct {
    00355     xed_state_t mode;
    00356     xed_iclass_enum_t iclass; /*FIXME: use iform instead? or allow either */
    00357     xed_uint32_t effective_operand_width;
    00358
    00359     /* the effective_address_width is only requires to be set for
    00360      *  instructions * with implicit suppressed memops or memops with no
    00361      *  base or index regs.  When base or index regs are present, XED pick
    00362      *  this up automatically from the register names.
    00363
    00364      * FIXME: make effective_address_width required by all encodes for
    00365      * unifority. Add to xed_inst[0123]() APIs??? */
    00366     xed_uint32_t effective_address_width;
    00367
    00368     xed_encoder_prefixes_t prefixes;
    00369     xed_uint32_t noperands;
    00370     xed_encoder_operand_t operands[XED_ENCODER_OPERANDS_MAX];
    00371 } xed_encoder_instruction_t;
    00372
    00374
    00375
    00376
    00377
    00378
    00379
    00380 static XED_INLINE void xed_addr(xed_encoder_instruction_t* x,
    00381                                 xed_uint_t width) {
    00382     x->effective_address_width = width;
    00383 }
    00384
    00385
    00387 static XED_INLINE  void xed_rep(xed_encoder_instruction_t* x) {
    00388     x->prefixes.s.rep=1;
    00389 }
    00390
    00392 static XED_INLINE  void xed_repne(xed_encoder_instruction_t* x) {
    00393     x->prefixes.s.repne=1;
    00394 }
    00395
    00397 static XED_INLINE  void xed_lock(xed_encoder_instruction_t* x) {
    00398     x->prefixes.s.lock=1;
    00399 }
    00400
    00401
    00402
    00403
    00407 XED_DLL_EXPORT xed_bool_t
    00408 xed_convert_to_encoder_request(xed_encoder_request_t* out,
    00409                                xed_encoder_instruction_t* in);
    00410
    00412
    00414 /* FIXME: rather than return the xed_encoder_instruction_t I can make
    00415  * another version that returns a xed_encoder_request_t. Saves silly
    00416  * copying. Although the xed_encoder_instruction_t might be handy for
    00417  * having code templates that get customized & passed to encoder later. */
    00420
    00421
    00424 static XED_INLINE  void xed_inst0(
    00425     xed_encoder_instruction_t* inst,
    00426     xed_state_t mode,
    00427     xed_iclass_enum_t iclass,
    00428     xed_uint_t effective_operand_width) {
    00429
    00430     inst->mode=mode;
    00431     inst->iclass = iclass;
    00432     inst->effective_operand_width = effective_operand_width;
    00433     inst->effective_address_width = 0;
    00434     inst->prefixes.i = 0;
    00435     inst->noperands = 0;
    00436 }
    00437
    00440 static XED_INLINE  void xed_inst1(
    00441     xed_encoder_instruction_t* inst,
    00442     xed_state_t mode,
    00443     xed_iclass_enum_t iclass,
    00444     xed_uint_t effective_operand_width,
    00445     xed_encoder_operand_t op0) {
    00446
    00447     inst->mode=mode;
    00448     inst->iclass = iclass;
    00449     inst->effective_operand_width = effective_operand_width;
    00450     inst->effective_address_width = 0;
    00451     inst->prefixes.i = 0;
    00452     inst->operands[0] = op0;
    00453     inst->noperands = 1;
    00454 }
    00455
    00458 static XED_INLINE  void xed_inst2(
    00459     xed_encoder_instruction_t* inst,
    00460     xed_state_t mode,
    00461     xed_iclass_enum_t iclass,
    00462     xed_uint_t effective_operand_width,
    00463     xed_encoder_operand_t op0,
    00464     xed_encoder_operand_t op1) {
    00465
    00466     inst->mode=mode;
    00467     inst->iclass = iclass;
    00468     inst->effective_operand_width = effective_operand_width;
    00469     inst->effective_address_width = 0;
    00470     inst->prefixes.i = 0;
    00471     inst->operands[0] = op0;
    00472     inst->operands[1] = op1;
    00473     inst->noperands = 2;
    00474 }
    00475
    00478 static XED_INLINE  void xed_inst3(
    00479     xed_encoder_instruction_t* inst,
    00480     xed_state_t mode,
    00481     xed_iclass_enum_t iclass,
    00482     xed_uint_t effective_operand_width,
    00483     xed_encoder_operand_t op0,
    00484     xed_encoder_operand_t op1,
    00485     xed_encoder_operand_t op2) {
    00486
    00487     inst->mode=mode;
    00488     inst->iclass = iclass;
    00489     inst->effective_operand_width = effective_operand_width;
    00490     inst->effective_address_width = 0;
    00491     inst->prefixes.i = 0;
    00492     inst->operands[0] = op0;
    00493     inst->operands[1] = op1;
    00494     inst->operands[2] = op2;
    00495     inst->noperands = 3;
    00496 }
    00497
    00498
    00501 static XED_INLINE  void xed_inst4(
    00502     xed_encoder_instruction_t* inst,
    00503     xed_state_t mode,
    00504     xed_iclass_enum_t iclass,
    00505     xed_uint_t effective_operand_width,
    00506     xed_encoder_operand_t op0,
    00507     xed_encoder_operand_t op1,
    00508     xed_encoder_operand_t op2,
    00509     xed_encoder_operand_t op3) {
    00510
    00511     inst->mode=mode;
    00512     inst->iclass = iclass;
    00513     inst->effective_operand_width = effective_operand_width;
    00514     inst->effective_address_width = 0;
    00515     inst->prefixes.i = 0;
    00516     inst->operands[0] = op0;
    00517     inst->operands[1] = op1;
    00518     inst->operands[2] = op2;
    00519     inst->operands[3] = op3;
    00520     inst->noperands = 4;
    00521 }
    00522
    00525 static XED_INLINE  void xed_inst5(
    00526     xed_encoder_instruction_t* inst,
    00527     xed_state_t mode,
    00528     xed_iclass_enum_t iclass,
    00529     xed_uint_t effective_operand_width,
    00530     xed_encoder_operand_t op0,
    00531     xed_encoder_operand_t op1,
    00532     xed_encoder_operand_t op2,
    00533     xed_encoder_operand_t op3,
    00534     xed_encoder_operand_t op4) {
    00535
    00536     inst->mode=mode;
    00537     inst->iclass = iclass;
    00538     inst->effective_operand_width = effective_operand_width;
    00539     inst->effective_address_width = 0;
    00540     inst->prefixes.i = 0;
    00541     inst->operands[0] = op0;
    00542     inst->operands[1] = op1;
    00543     inst->operands[2] = op2;
    00544     inst->operands[3] = op3;
    00545     inst->operands[4] = op4;
    00546     inst->noperands = 5;
    00547 }
    00548
    00549
    00553 static XED_INLINE  void xed_inst(
    00554     xed_encoder_instruction_t* inst,
    00555     xed_state_t mode,
    00556     xed_iclass_enum_t iclass,
    00557     xed_uint_t effective_operand_width,
    00558     xed_uint_t number_of_operands,
    00559     const xed_encoder_operand_t* operand_array) {
    00560
    00561     xed_uint_t i;
    00562     inst->mode=mode;
    00563     inst->iclass = iclass;
    00564     inst->effective_operand_width = effective_operand_width;
    00565     inst->effective_address_width = 0;
    00566     inst->prefixes.i = 0;
    00567     xed_assert(number_of_operands < XED_ENCODER_OPERANDS_MAX);
    00568     for(i=0;i<number_of_operands;i++) {
    00569         inst->operands[i] = operand_array[i];
    00570     }
    00571     inst->noperands = number_of_operands;
    00572 }
    00573
    00575
    00576 /*
    00577  xed_encoder_instruction_t x,y;
    00578
    00579  xed_inst2(&x, state, XED_ICLASS_ADD, 32,
    00580            xed_reg(XED_REG_EAX),
    00581            xed_mem_bd(XED_REG_EDX, xed_disp(0x11223344, 32), 32));
    00582
    00583  xed_inst2(&y, state, XED_ICLASS_ADD, 32,
    00584            xed_reg(XED_REG_EAX),
    00585            xed_mem_gbisd(XED_REG_FS, XED_REG_EAX, XED_REG_ESI,4,
    00586                       xed_disp(0x11223344, 32), 32));
    00587
    00588  */
    00589
    00590 #endif