xed-encoder-hl.h

Go to the documentation of this file.
00001 /*BEGIN_LEGAL 
00002 Intel Open Source License 
00003 
00004 Copyright (c) 2002-2009 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  xed_enc_displacement_t xdisp(xed_uint64_t   displacement,
00052                                                 xed_uint32_t   displacement_width   ) {
00053     xed_enc_displacement_t x;
00054     x.displacement = displacement;
00055     x.displacement_width = displacement_width;
00056     return x;
00057 }
00059 
00060 typedef struct {
00061     xed_reg_enum_t seg;
00062     xed_reg_enum_t base;
00063     xed_reg_enum_t index;
00064     xed_uint32_t   scale;
00065     xed_enc_displacement_t disp;
00066 } xed_memop_t;
00067 
00068 
00069 typedef enum {
00070     XED_ENCODER_OPERAND_TYPE_INVALID,
00071     XED_ENCODER_OPERAND_TYPE_BRDISP,
00072     XED_ENCODER_OPERAND_TYPE_REG,
00073     XED_ENCODER_OPERAND_TYPE_IMM0,
00074     XED_ENCODER_OPERAND_TYPE_SIMM0,
00075     XED_ENCODER_OPERAND_TYPE_IMM1,
00076     XED_ENCODER_OPERAND_TYPE_MEM,
00077     XED_ENCODER_OPERAND_TYPE_PTR,
00078     XED_ENCODER_OPERAND_TYPE_SEG0,  /* special for things with suppressed implicit memops */
00079     XED_ENCODER_OPERAND_TYPE_SEG1,  /* special for things with suppressed implicit memops */
00080     XED_ENCODER_OPERAND_TYPE_OTHER  /* specific operand storage fields -- must supply a name */
00081 } xed_encoder_operand_type_t;
00082 
00083 typedef struct {
00084     xed_encoder_operand_type_t  type;
00085     union {
00086         xed_reg_enum_t reg;
00087         xed_int32_t brdisp;
00088         xed_uint64_t imm0;
00089         xed_uint8_t imm1;
00090         struct {
00091             xed_operand_enum_t operand_name;
00092             xed_uint32_t       value;
00093         } s;
00094         xed_memop_t mem;
00095     } u;
00096     xed_uint32_t width;
00097 } xed_encoder_operand_t;
00098 
00100 
00101 
00102 
00103 static XED_INLINE  xed_encoder_operand_t xrelbr(xed_int32_t brdisp, xed_uint_t width) {
00104     xed_encoder_operand_t o;
00105     o.type = XED_ENCODER_OPERAND_TYPE_BRDISP;
00106     o.u.brdisp = brdisp;
00107     o.width = width;
00108     return o;
00109 }
00111 
00113 
00114 
00115 
00116 static XED_INLINE  xed_encoder_operand_t xptr(xed_int32_t brdisp, xed_uint_t width) {
00117     xed_encoder_operand_t o;
00118     o.type = XED_ENCODER_OPERAND_TYPE_PTR;
00119     o.u.brdisp = brdisp;
00120     o.width = width;
00121     return o;
00122 }
00124 
00126 
00127 
00128 
00129 static XED_INLINE  xed_encoder_operand_t xreg(xed_reg_enum_t reg) {
00130     xed_encoder_operand_t o;
00131     o.type = XED_ENCODER_OPERAND_TYPE_REG;
00132     o.u.reg = reg;
00133     o.width = 0;
00134     return o;
00135 }
00136 
00139 static XED_INLINE  xed_encoder_operand_t imm0(xed_uint64_t v, xed_uint_t width) {
00140     xed_encoder_operand_t o;
00141     o.type = XED_ENCODER_OPERAND_TYPE_IMM0;
00142     o.u.imm0 = v;
00143     o.width = width;
00144     return o;
00145 }
00148 static XED_INLINE  xed_encoder_operand_t simm0(xed_int32_t v, xed_uint_t width) {
00149     xed_encoder_operand_t o;
00150     o.type = XED_ENCODER_OPERAND_TYPE_SIMM0;
00151     /* sign conversion: we store the int32 in an uint64. It gets sign
00152     extended.  Later we convert it to the right width for the
00153     instruction. The maximum width of a signed immediate is currently
00154     32b. */
00155     o.u.imm0 = v;
00156     o.width = width;
00157     return o;
00158 }
00159 
00162 static XED_INLINE  xed_encoder_operand_t imm1(xed_uint8_t v) {
00163     xed_encoder_operand_t o;
00164     o.type = XED_ENCODER_OPERAND_TYPE_IMM1;
00165     o.u.imm1 = v; 
00166     o.width = 8;
00167     return o;
00168 }
00169 
00170 
00173 static XED_INLINE  xed_encoder_operand_t xother(xed_operand_enum_t operand_name,
00174                                                 xed_int32_t value) {
00175     xed_encoder_operand_t o;
00176     o.type = XED_ENCODER_OPERAND_TYPE_OTHER;
00177     o.u.s.operand_name = operand_name;
00178     o.u.s.value = value;
00179     o.width = 0;
00180     return o;
00181 }
00183 
00184 
00186 
00188 
00189 
00192 static XED_INLINE  xed_encoder_operand_t xseg0(xed_reg_enum_t seg0) {
00193     xed_encoder_operand_t o;
00194     o.type = XED_ENCODER_OPERAND_TYPE_SEG0;
00195     o.u.reg = seg0;
00196     return o;
00197 }
00198 
00201 static XED_INLINE  xed_encoder_operand_t xseg1(xed_reg_enum_t seg1) {
00202     xed_encoder_operand_t o;
00203     o.type = XED_ENCODER_OPERAND_TYPE_SEG1;
00204     o.u.reg = seg1;
00205     return o;
00206 }
00207 
00210 static XED_INLINE  xed_encoder_operand_t xmem_b(xed_reg_enum_t base, xed_uint_t width) {
00211     xed_encoder_operand_t o;
00212     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
00213     o.u.mem.base = base;
00214     o.u.mem.seg = XED_REG_INVALID;
00215     o.u.mem.index= XED_REG_INVALID;
00216     o.u.mem.scale = 0;
00217     o.u.mem.disp.displacement = 0;
00218     o.u.mem.disp.displacement_width = 0;
00219     o.width = width;
00220     return o;
00221 }
00222 
00225 static XED_INLINE  xed_encoder_operand_t xmem_bd(xed_reg_enum_t base, 
00226                               xed_enc_displacement_t disp,
00227                               xed_uint_t width) {
00228     xed_encoder_operand_t o;
00229     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
00230     o.u.mem.base = base;
00231     o.u.mem.seg = XED_REG_INVALID;
00232     o.u.mem.index= XED_REG_INVALID;
00233     o.u.mem.scale = 0;
00234     o.u.mem.disp =disp;
00235     o.width = width;
00236     return o;
00237 }
00238 
00241 static XED_INLINE  xed_encoder_operand_t xmem_bisd(xed_reg_enum_t base, 
00242                                 xed_reg_enum_t index, 
00243                                 xed_uint_t scale,
00244                                 xed_enc_displacement_t disp,
00245                                 xed_uint_t width) {
00246     xed_encoder_operand_t o;
00247     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
00248     o.u.mem.base = base;
00249     o.u.mem.seg = XED_REG_INVALID;
00250     o.u.mem.index= index;
00251     o.u.mem.scale = scale;
00252     o.u.mem.disp = disp;
00253     o.width = width;
00254     return o;
00255 }
00256 
00257 
00260 static XED_INLINE  xed_encoder_operand_t xmem_gb(xed_reg_enum_t seg, xed_reg_enum_t base, xed_uint_t width) {
00261     xed_encoder_operand_t o;
00262     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
00263     o.u.mem.base = base;
00264     o.u.mem.seg = seg;
00265     o.u.mem.index= XED_REG_INVALID;
00266     o.u.mem.scale = 0;
00267     o.u.mem.disp.displacement = 0;
00268     o.u.mem.disp.displacement_width = 0;
00269     o.width = width;
00270     return o;
00271 }
00272 
00275 static XED_INLINE  xed_encoder_operand_t xmem_gbd(xed_reg_enum_t seg, xed_reg_enum_t base, 
00276                                xed_enc_displacement_t disp,
00277                                xed_uint_t width) {
00278     xed_encoder_operand_t o;
00279     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
00280     o.u.mem.base = base;
00281     o.u.mem.seg = seg;
00282     o.u.mem.index= XED_REG_INVALID;
00283     o.u.mem.scale = 0;
00284     o.u.mem.disp = disp;
00285     o.width = width;
00286     return o;
00287 }
00288 
00291 static XED_INLINE  xed_encoder_operand_t xmem_gd(xed_reg_enum_t seg,
00292                                xed_enc_displacement_t disp,
00293                                xed_uint_t width) {
00294     xed_encoder_operand_t o;
00295     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
00296     o.u.mem.base = XED_REG_INVALID;
00297     o.u.mem.seg = seg;
00298     o.u.mem.index= XED_REG_INVALID;
00299     o.u.mem.scale = 0;
00300     o.u.mem.disp = disp;
00301     o.width = width;
00302     return o;
00303 }
00304 
00307 static XED_INLINE  xed_encoder_operand_t xmem_gbisd(xed_reg_enum_t seg, 
00308                                  xed_reg_enum_t base, 
00309                                  xed_reg_enum_t index, 
00310                                  xed_uint_t scale,
00311                                  xed_enc_displacement_t disp, 
00312                                  xed_uint_t width) {
00313     xed_encoder_operand_t o;
00314     o.type = XED_ENCODER_OPERAND_TYPE_MEM;
00315     o.u.mem.base = base;
00316     o.u.mem.seg = seg;
00317     o.u.mem.index= index;
00318     o.u.mem.scale = scale;
00319     o.u.mem.disp = disp;
00320     o.width = width;
00321     return o;
00322 }
00324 
00325 typedef union {
00326     struct {
00327         xed_uint32_t rep               :1;
00328         xed_uint32_t repne             :1;
00329         xed_uint32_t lock              :1;
00330         xed_uint32_t br_hint_taken     :1;
00331         xed_uint32_t br_hint_not_taken :1;
00332     } s;
00333     xed_uint32_t i;
00334 }  xed_encoder_prefixes_t;
00335 
00336 #define XED_ENCODER_OPERANDS_MAX 5 /* FIXME */
00337 typedef struct {
00338     xed_state_t mode;
00339     xed_iclass_enum_t iclass; /*FIXME: use iform instead? or allow either */
00340     xed_uint32_t effective_operand_width;
00341 
00342     /* the effective_address_width is only requires to be set for
00343      *  instructions * with implicit suppressed memops or memops with no
00344      *  base or index regs.  When base or index regs are present, XED pick
00345      *  this up automatically from the register names.
00346 
00347      * FIXME: make effective_address_width required by all encodes for
00348      * unifority. Add to xed_inst[0123]() APIs??? */
00349     xed_uint32_t effective_address_width; 
00350 
00351     xed_encoder_prefixes_t prefixes;
00352     xed_uint32_t noperands;
00353     xed_encoder_operand_t operands[XED_ENCODER_OPERANDS_MAX];
00354 } xed_encoder_instruction_t;
00355 
00357 
00358 
00359 
00360 
00361 
00362 
00363 static XED_INLINE void xaddr(xed_encoder_instruction_t* x, 
00364                              xed_uint_t width) {
00365     x->effective_address_width = width;
00366 }
00367 
00368 
00370 static XED_INLINE  void xrep(xed_encoder_instruction_t* x) { 
00371     x->prefixes.s.rep=1;
00372 }
00373 
00375 static XED_INLINE  void xrepne(xed_encoder_instruction_t* x) { 
00376     x->prefixes.s.repne=1;
00377 }
00378 
00380 static XED_INLINE  void xlock(xed_encoder_instruction_t* x) { 
00381     x->prefixes.s.lock=1;
00382 }
00383 
00384 
00385 
00386 
00389 XED_DLL_EXPORT xed_bool_t xed_convert_to_encoder_request(xed_encoder_request_t* out,
00390                                                          xed_encoder_instruction_t* in);
00391 
00393 
00395 /* FIXME: rather than return the xed_encoder_instruction_t I can make
00396  * another version that returns a xed_encoder_request_t. Saves silly
00397  * copying. Although the xed_encoder_instruction_t might be handy for
00398  * having code templates that get customized & passed to encoder later. */
00401 
00402 
00405 static XED_INLINE  void xed_inst0(
00406     xed_encoder_instruction_t* inst,
00407     xed_state_t mode,
00408     xed_iclass_enum_t iclass,
00409     xed_uint_t effective_operand_width) {
00410 
00411     inst->mode=mode;
00412     inst->iclass = iclass;
00413     inst->effective_operand_width = effective_operand_width;
00414     inst->effective_address_width = 0;
00415     inst->prefixes.i = 0;
00416     inst->noperands = 0;
00417 }
00418 
00421 static XED_INLINE  void xed_inst1(
00422     xed_encoder_instruction_t* inst,
00423     xed_state_t mode,
00424     xed_iclass_enum_t iclass,
00425     xed_uint_t effective_operand_width,
00426     xed_encoder_operand_t op0) {
00427     
00428     inst->mode=mode;
00429     inst->iclass = iclass;
00430     inst->effective_operand_width = effective_operand_width;
00431     inst->effective_address_width = 0;
00432     inst->prefixes.i = 0;
00433     inst->operands[0] = op0;
00434     inst->noperands = 1;
00435 }
00436 
00439 static XED_INLINE  void xed_inst2(
00440     xed_encoder_instruction_t* inst,
00441     xed_state_t mode,
00442     xed_iclass_enum_t iclass,
00443     xed_uint_t effective_operand_width,
00444     xed_encoder_operand_t op0,
00445     xed_encoder_operand_t op1) {
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->operands[1] = op1;
00454     inst->noperands = 2;
00455 }
00456 
00459 static XED_INLINE  void xed_inst3(
00460     xed_encoder_instruction_t* inst,
00461     xed_state_t mode,
00462     xed_iclass_enum_t iclass,
00463     xed_uint_t effective_operand_width,
00464     xed_encoder_operand_t op0,
00465     xed_encoder_operand_t op1,
00466     xed_encoder_operand_t op2) {
00467 
00468     inst->mode=mode;
00469     inst->iclass = iclass;
00470     inst->effective_operand_width = effective_operand_width;
00471     inst->effective_address_width = 0;
00472     inst->prefixes.i = 0;
00473     inst->operands[0] = op0;
00474     inst->operands[1] = op1;
00475     inst->operands[2] = op2;
00476     inst->noperands = 3;
00477 }
00478 
00479 
00482 static XED_INLINE  void xed_inst4(
00483     xed_encoder_instruction_t* inst,
00484     xed_state_t mode,
00485     xed_iclass_enum_t iclass,
00486     xed_uint_t effective_operand_width,
00487     xed_encoder_operand_t op0,
00488     xed_encoder_operand_t op1,
00489     xed_encoder_operand_t op2,
00490     xed_encoder_operand_t op3) {
00491 
00492     inst->mode=mode;
00493     inst->iclass = iclass;
00494     inst->effective_operand_width = effective_operand_width;
00495     inst->effective_address_width = 0;
00496     inst->prefixes.i = 0;
00497     inst->operands[0] = op0;
00498     inst->operands[1] = op1;
00499     inst->operands[2] = op2;
00500     inst->operands[3] = op3;
00501     inst->noperands = 4;
00502 }
00503 
00506 static XED_INLINE  void xed_inst5(
00507     xed_encoder_instruction_t* inst,
00508     xed_state_t mode,
00509     xed_iclass_enum_t iclass,
00510     xed_uint_t effective_operand_width,
00511     xed_encoder_operand_t op0,
00512     xed_encoder_operand_t op1,
00513     xed_encoder_operand_t op2,
00514     xed_encoder_operand_t op3,
00515     xed_encoder_operand_t op4) {
00516 
00517     inst->mode=mode;
00518     inst->iclass = iclass;
00519     inst->effective_operand_width = effective_operand_width;
00520     inst->effective_address_width = 0;
00521     inst->prefixes.i = 0;
00522     inst->operands[0] = op0;
00523     inst->operands[1] = op1;
00524     inst->operands[2] = op2;
00525     inst->operands[3] = op3;
00526     inst->operands[4] = op4;
00527     inst->noperands = 5;
00528 }
00529 
00530 
00534 static XED_INLINE  void xed_inst(
00535     xed_encoder_instruction_t* inst,
00536     xed_state_t mode,
00537     xed_iclass_enum_t iclass,
00538     xed_uint_t effective_operand_width,
00539     xed_uint_t number_of_operands,
00540     const xed_encoder_operand_t* operand_array) {
00541 
00542     xed_uint_t i;
00543     inst->mode=mode;
00544     inst->iclass = iclass;
00545     inst->effective_operand_width = effective_operand_width;
00546     inst->effective_address_width = 0;
00547     inst->prefixes.i = 0;
00548     xed_assert(number_of_operands < XED_ENCODER_OPERANDS_MAX);
00549     for(i=0;i<number_of_operands;i++) {
00550         inst->operands[i] = operand_array[i];
00551     }
00552     inst->noperands = number_of_operands;
00553 }
00554 
00556 
00557 /*
00558  xed_encoder_instruction_t x,y;
00559 
00560  xed_inst2(&x, state, XED_ICLASS_ADD, 32, 
00561            xreg(XED_REG_EAX), 
00562            xmem_bd(XED_REG_EDX, xdisp(0x11223344, 32), 32));
00563   
00564  xed_inst2(&y, state, XED_ICLASS_ADD, 32, 
00565            xreg(XED_REG_EAX), 
00566            xmem_gbisd(XED_REG_FS, XED_REG_EAX, XED_REG_ESI,4, xdisp(0x11223344, 32), 32));
00567 
00568  */
00569 
00570 #endif

Generated on Tue Dec 15 03:23:29 2009 for XED2 by  doxygen 1.4.6