12b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <stdio.h> 22b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <stdlib.h> 32b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <string.h> 42b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 52b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "libdis.h" 62b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "ia32_insn.h" 72b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "ia32_operand.h" 82b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "ia32_modrm.h" 92b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "ia32_reg.h" 102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "x86_imm.h" 112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "x86_operand_list.h" 122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* apply segment override to memory operand in insn */ 162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgstatic void apply_seg( x86_op_t *op, unsigned int prefixes ) { 172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (! prefixes ) return; 182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* apply overrides from prefix */ 202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org switch ( prefixes & PREFIX_REG_MASK ) { 212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case PREFIX_CS: 222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_cs_seg; break; 232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case PREFIX_SS: 242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_ss_seg; break; 252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case PREFIX_DS: 262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_ds_seg; break; 272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case PREFIX_ES: 282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_es_seg; break; 292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case PREFIX_FS: 302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_fs_seg; break; 312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case PREFIX_GS: 322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_gs_seg; break; 332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return; 362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgstatic size_t decode_operand_value( unsigned char *buf, size_t buf_len, 392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_op_t *op, x86_insn_t *insn, 402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org unsigned int addr_meth, size_t op_size, 412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org unsigned int op_value, unsigned char modrm, 422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size_t gen_regs ) { 432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size_t size = 0; 442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ++ Do Operand Addressing Method / Decode operand ++ */ 462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org switch (addr_meth) { 472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* This sets the operand Size based on the Intel Opcode Map 482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * (Vol 2, Appendix A). Letter encodings are from section 492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * A.1.1, 'Codes for Addressing Method' */ 502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ---------------------- Addressing Method -------------- */ 522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* Note that decoding mod ModR/M operand adjusts the size of 532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * the instruction, but decoding the reg operand does not. 542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * This should not cause any problems, as every 'reg' operand 552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * has an associated 'mod' operand. 562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * Goddamn-Intel-Note: 572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * Some Intel addressing methods [M, R] specify that modR/M 582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * byte may only refer to a memory address/may only refer to 592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * a register -- however Intel provides no clues on what to do 602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * if, say, the modR/M for an M opcode decodes to a register 612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * rather than a memory address ... returning 0 is out of the 622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * question, as this would be an Immediate or a RelOffset, so 632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * instead these modR/Ms are decoded with total disregard to 642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * the M, R constraints. */ 652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* MODRM -- mod operand. sets size to at least 1! */ 672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_E: /* ModR/M present, Gen reg or memory */ 682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = ia32_modrm_decode( buf, buf_len, op, insn, 692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org gen_regs ); 702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_M: /* ModR/M only refers to memory */ 722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = ia32_modrm_decode( buf, buf_len, op, insn, 732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org gen_regs ); 742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_Q: /* ModR/M present, MMX or Memory */ 762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = ia32_modrm_decode( buf, buf_len, op, insn, 772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org REG_MMX_OFFSET ); 782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_R: /* ModR/M mod == gen reg */ 802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = ia32_modrm_decode( buf, buf_len, op, insn, 812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org gen_regs ); 822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_W: /* ModR/M present, mem or SIMD reg */ 842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = ia32_modrm_decode( buf, buf_len, op, insn, 852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org REG_SIMD_OFFSET ); 862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* MODRM -- reg operand. does not effect size! */ 892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_C: /* ModR/M reg == control reg */ 902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_reg_decode( modrm, op, REG_CTRL_OFFSET ); 912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_D: /* ModR/M reg == debug reg */ 932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_reg_decode( modrm, op, REG_DEBUG_OFFSET ); 942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_G: /* ModR/M reg == gen-purpose reg */ 962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_reg_decode( modrm, op, gen_regs ); 972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_P: /* ModR/M reg == qword MMX reg */ 992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_reg_decode( modrm, op, REG_MMX_OFFSET ); 1002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_S: /* ModR/M reg == segment reg */ 1022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_reg_decode( modrm, op, REG_SEG_OFFSET ); 1032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_T: /* ModR/M reg == test reg */ 1052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_reg_decode( modrm, op, REG_TEST_OFFSET ); 1062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_V: /* ModR/M reg == SIMD reg */ 1082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_reg_decode( modrm, op, REG_SIMD_OFFSET ); 1092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* No MODRM : note these set operand type explicitly */ 1122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_A: /* No modR/M -- direct addr */ 1132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_absolute; 1142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* segment:offset address used in far calls */ 1162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_sized( buf, buf_len, 1172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org &op->data.absolute.segment, 2 ); 1182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn->addr_size == 4 ) { 1192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_sized( buf, buf_len, 1202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org &op->data.absolute.offset.off32, 4 ); 1212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 6; 1222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else { 1232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_sized( buf, buf_len, 1242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org &op->data.absolute.offset.off16, 2 ); 1252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 4; 1262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_I: /* Immediate val */ 1302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_immediate; 1312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* if it ever becomes legal to have imm as dest and 1322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * there is a src ModR/M operand, we are screwed! */ 1332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op->flags & op_signed ) { 1342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_signsized(buf, buf_len, &op->data.byte, 1352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_size); 1362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else { 1372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_sized(buf, buf_len, &op->data.byte, 1382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_size); 1392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = op_size; 1412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_J: /* Rel offset to add to IP [jmp] */ 1432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* this fills op->data.near_offset or 1442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->data.far_offset depending on the size of 1452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org the operand */ 1462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_signed; 1472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op_size == 1 ) { 1482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* one-byte near offset */ 1492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_relative_near; 1502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_signsized(buf, buf_len, 1512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org &op->data.relative_near, 1); 1522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else { 1532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* far offset...is this truly signed? */ 1542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_relative_far; 1552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_signsized(buf, buf_len, 1562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org &op->data.relative_far, op_size ); 1572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = op_size; 1592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_O: /* No ModR/M; op is word/dword offset */ 1612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* NOTE: these are actually RVAs not offsets to seg!! */ 1622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* note bene: 'O' ADDR_METH uses addr_size to 1632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org determine operand size */ 1642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_offset; 1652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_pointer; 1662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_imm_sized( buf, buf_len, &op->data.offset, 1672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org insn->addr_size ); 1682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = insn->addr_size; 1702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* Hard-coded: these are specified in the insn definition */ 1732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_F: /* EFLAGS register */ 1742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_register; 1752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 1762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_handle_register( &op->data.reg, REG_FLAGS_INDEX ); 1772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_X: /* Memory addressed by DS:SI [string] */ 1792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_expression; 1802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 1812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_ds_seg | op_pointer | op_string; 1822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_handle_register( &op->data.expression.base, 1832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org REG_DWORD_OFFSET + 6 ); 1842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */ 1862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_expression; 1872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 1882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_es_seg | op_pointer | op_string; 1892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_handle_register( &op->data.expression.base, 1902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org REG_DWORD_OFFSET + 7 ); 1912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_RR: /* Gen Register hard-coded in opcode */ 1932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_register; 1942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 1952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_handle_register( &op->data.reg, 1962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_value + gen_regs ); 1972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 1982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_RS: /* Seg Register hard-coded in opcode */ 1992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_register; 2002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 2012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_handle_register( &op->data.reg, 2022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_value + REG_SEG_OFFSET ); 2032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_RF: /* FPU Register hard-coded in opcode */ 2052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_register; 2062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 2072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_handle_register( &op->data.reg, 2082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_value + REG_FPU_OFFSET ); 2092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_RT: /* TST Register hard-coded in opcode */ 2112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_register; 2122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 2132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org ia32_handle_register( &op->data.reg, 2142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_value + REG_TEST_OFFSET ); 2152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case ADDRMETH_II: /* Immediate hard-coded in opcode */ 2172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_immediate; 2182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->data.dword = op_value; 2192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags |= op_hardcode; 2202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 2222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case 0: /* Operand is not used */ 2232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org default: 2242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ignore -- operand not used in this insn */ 2252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->type = op_unused; /* this shouldn't happen! */ 2262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 2282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 2292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return size; 2302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 2312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 2322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgstatic size_t decode_operand_size( unsigned int op_type, x86_insn_t *insn, 2332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_op_t *op ){ 2342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size_t size; 2352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 2362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ++ Do Operand Type ++ */ 2372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org switch (op_type) { 2382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* This sets the operand Size based on the Intel Opcode Map 2392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * (Vol 2, Appendix A). Letter encodings are from section 2402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * A.1.2, 'Codes for Operand Type' */ 2412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* NOTE: in this routines, 'size' refers to the size 2422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * of the operand in the raw (encoded) instruction; 2432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * 'datatype' stores the actual size and datatype 2442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * of the operand */ 2452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 2462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ------------------------ Operand Type ----------------- */ 2472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_c: /* byte or word [op size attr] */ 2482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = (insn->op_size == 4) ? 2 : 1; 2492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 4) ? op_word : op_byte; 2502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_a: /* 2 word or 2 dword [op size attr] */ 2522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* pointer to a 16:16 or 32:32 BOUNDS operand */ 2532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = (insn->op_size == 4) ? 8 : 4; 2542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 4) ? op_bounds32 : op_bounds16; 2552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_v: /* word or dword [op size attr] */ 2572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = (insn->op_size == 4) ? 4 : 2; 2582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 4) ? op_dword : op_word; 2592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_p: /* 32/48-bit ptr [op size attr] */ 2612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* technically these flags are not accurate: the 2622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * value s a 16:16 pointer or a 16:32 pointer, where 2632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * the first '16' is a segment */ 2642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = (insn->addr_size == 4) ? 6 : 4; 2652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 4) ? op_descr32 : op_descr16; 2662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_b: /* byte, ignore op-size */ 2682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 1; 2692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_byte; 2702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_w: /* word, ignore op-size */ 2722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 2; 2732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_word; 2742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_d: /* dword , ignore op-size */ 2762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 4; 2772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_dword; 2782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_s: /* 6-byte psuedo-descriptor */ 2802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ptr to 6-byte value which is 32:16 in 32-bit 2812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * mode, or 8:24:16 in 16-bit mode. The high byte 2822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * is ignored in 16-bit mode. */ 2832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 6; 2842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (insn->addr_size == 4) ? 2852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_pdescr32 : op_pdescr16; 2862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_q: /* qword, ignore op-size */ 2882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 8; 2892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_qword; 2902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_dq: /* d-qword, ignore op-size */ 2922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 16; 2932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_dqword; 2942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 2952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_ps: /* 128-bit FP data */ 2962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 16; 2972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* really this is 4 packed SP FP values */ 2982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_ssimd; 2992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_pd: /* 128-bit FP data */ 3012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 16; 3022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* really this is 2 packed DP FP values */ 3032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_dsimd; 3042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_ss: /* Scalar elem of 128-bit FP data */ 3062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 16; 3072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* this only looks at the low dword (4 bytes) 3082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * of the xmmm register passed as a param. 3092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * This is a 16-byte register where only 4 bytes 3102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * are used in the insn. Painful, ain't it? */ 3112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_sssimd; 3122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_sd: /* Scalar elem of 128-bit FP data */ 3142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 16; 3152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* this only looks at the low qword (8 bytes) 3162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * of the xmmm register passed as a param. 3172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * This is a 16-byte register where only 8 bytes 3182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * are used in the insn. Painful, again... */ 3192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_sdsimd; 3202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_pi: /* qword mmx register */ 3222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 8; 3232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_qword; 3242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_si: /* dword integer register */ 3262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 4; 3272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_dword; 3282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_fs: /* single-real */ 3302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 4; 3312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_sreal; 3322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_fd: /* double real */ 3342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 8; 3352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_dreal; 3362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_fe: /* extended real */ 3382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 10; 3392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_extreal; 3402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_fb: /* packed BCD */ 3422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 10; 3432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_bcd; 3442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_fv: /* pointer to FPU env: 14 or 28-bytes */ 3462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = (insn->addr_size == 4)? 28 : 14; 3472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 28)? op_fpuenv32: op_fpuenv16; 3482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_ft: /* pointer to FPU env: 94 or 108 bytes */ 3502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = (insn->addr_size == 4)? 108 : 94; 3512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 108)? 3522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_fpustate32: op_fpustate16; 3532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_fx: /* 512-byte register stack */ 3552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 512; 3562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_fpregset; 3572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_fp: /* floating point register */ 3592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 10; /* double extended precision */ 3602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_fpreg; 3612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_m: /* fake operand type used for "lea Gv, M" */ 3632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = insn->addr_size; 3642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 4) ? op_dword : op_word; 3652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case OPTYPE_none: /* handle weird instructions that have no encoding but use a dword datatype, like invlpg */ 3672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = 0; 3682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = op_none; 3692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case 0: 3712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org default: 3722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = insn->op_size; 3732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->datatype = (size == 4) ? op_dword : op_word; 3742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org break; 3752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 3762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return size; 3772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 3782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 3792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgsize_t ia32_decode_operand( unsigned char *buf, size_t buf_len, 3802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_insn_t *insn, unsigned int raw_op, 3812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org unsigned int raw_flags, unsigned int prefixes, 3822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org unsigned char modrm ) { 3832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org unsigned int addr_meth, op_type, op_size, gen_regs; 3842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_op_t *op; 3852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size_t size; 3862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 3872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ++ Yank optype and addr mode out of operand flags */ 3882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org addr_meth = raw_flags & ADDRMETH_MASK; 3892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_type = raw_flags & OPTYPE_MASK; 3902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 3912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( raw_flags == ARG_NONE ) { 3922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* operand is not used in this instruction */ 3932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return 0; 3942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 3952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 3962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* allocate a new operand */ 3972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op = x86_operand_new( insn ); 3982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 3992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* ++ Copy flags from opcode table to x86_insn_t */ 4002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->access = (enum x86_op_access) OP_PERM(raw_flags); 4012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op->flags = (enum x86_op_flags) (OP_FLAGS(raw_flags) >> 12); 4022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 4032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* Get size (for decoding) and datatype of operand */ 4042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_size = decode_operand_size(op_type, insn, op); 4052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 4062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* override default register set based on Operand Type */ 4072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* this allows mixing of 8, 16, and 32 bit regs in insn */ 4082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (op_size == 1) { 4092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org gen_regs = REG_BYTE_OFFSET; 4102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else if (op_size == 2) { 4112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org gen_regs = REG_WORD_OFFSET; 4122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else { 4132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org gen_regs = REG_DWORD_OFFSET; 4142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 4152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 4162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = decode_operand_value( buf, buf_len, op, insn, addr_meth, 4172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_size, raw_op, modrm, gen_regs ); 4182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 4192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* if operand is an address, apply any segment override prefixes */ 4202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op->type == op_expression || op->type == op_offset ) { 4212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org apply_seg(op, prefixes); 4222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 4232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 4242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return size; /* return number of bytes in instruction */ 4252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 426