xed-encoder-hl.h

Go to the documentation of this file.
00001 /*BEGIN_LEGAL 
00002 Intel Open Source License 
00003 
00004 Copyright (c) 2002-2015 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

Generated on Wed Jan 21 02:16:58 2015 for XED by  doxygen 1.5.1-p1