Home | History | Annotate | Download | only in libnvmm

Lines Matching defs:instr

1824 node_overflow(struct x86_decode_fsm *fsm, struct x86_instr *instr)
1853 resolve_special_register(struct x86_instr *instr, uint8_t enc, size_t regsize)
1860 return &gpr_map__special[instr->rexpref.present][enc][regsize-1];
1868 node_movs(struct x86_decode_fsm *fsm, struct x86_instr *instr)
1872 adrsize = instr->address_size;
1875 instr->src.type = STORE_REG;
1876 instr->src.u.reg = &gpr_map__special[1][2][adrsize-1];
1877 instr->src.disp.type = DISP_0;
1880 instr->dst.type = STORE_REG;
1881 instr->dst.u.reg = &gpr_map__special[1][3][adrsize-1];
1882 instr->dst.disp.type = DISP_0;
1883 instr->dst.hardseg = NVMM_X64_SEG_ES;
1897 node_cmps(struct x86_decode_fsm *fsm, struct x86_instr *instr)
1901 adrsize = instr->address_size;
1904 instr->src.type = STORE_REG;
1905 instr->src.u.reg = &gpr_map__special[1][2][adrsize-1];
1906 instr->src.disp.type = DISP_0;
1909 instr->dst.type = STORE_REG;
1910 instr->dst.u.reg = &gpr_map__special[1][3][adrsize-1];
1911 instr->dst.disp.type = DISP_0;
1912 instr->dst.hardseg = NVMM_X64_SEG_ES;
1924 node_stlo(struct x86_decode_fsm *fsm, struct x86_instr *instr)
1926 const struct x86_opcode *opcode = instr->opcode;
1930 adrsize = instr->address_size;
1931 regsize = instr->operand_size;
1934 streg = &instr->src;
1935 stlo = &instr->dst;
1937 streg = &instr->dst;
1938 stlo = &instr->src;
1961 node_dmo(struct x86_decode_fsm *fsm, struct x86_instr *instr)
1963 const struct x86_opcode *opcode = instr->opcode;
1967 adrsize = instr->address_size;
1968 regsize = instr->operand_size;
1971 streg = &instr->src;
1972 stdmo = &instr->dst;
1974 streg = &instr->dst;
1975 stdmo = &instr->src;
2007 node_immediate(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2009 const struct x86_opcode *opcode = instr->opcode;
2015 store = &instr->src;
2016 immsize = instr->operand_size;
2040 node_disp(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2042 const struct x86_opcode *opcode = instr->opcode;
2046 if (instr->strm->disp.type == DISP_1) {
2048 } else if (instr->strm->disp.type == DISP_2) {
2050 } else if (instr->strm->disp.type == DISP_4) {
2064 instr->strm->disp.data = data;
2080 node_dual(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2084 reg1 = gpr_dual_reg1_rm[instr->regmodrm.rm];
2086 if (instr->regmodrm.rm == 0b000 ||
2087 instr->regmodrm.rm == 0b010) {
2089 } else if (instr->regmodrm.rm == 0b001 ||
2090 instr->regmodrm.rm == 0b011) {
2096 instr->strm->type = STORE_DUALREG;
2097 instr->strm->u.dualreg.reg1 = reg1;
2098 instr->strm->u.dualreg.reg2 = reg2;
2100 if (instr->strm->disp.type == DISP_NONE) {
2102 } else if (instr->strm->disp.type == DISP_0) {
2104 if (instr->opcode->immediate) {
2117 get_register_idx(struct x86_instr *instr, uint8_t index)
2123 regsize = instr->address_size;
2124 reg = &gpr_map[instr->rexpref.x][enc][regsize-1];
2127 reg = resolve_special_register(instr, enc, regsize);
2134 get_register_bas(struct x86_instr *instr, uint8_t base)
2140 regsize = instr->address_size;
2141 reg = &gpr_map[instr->rexpref.b][enc][regsize-1];
2143 reg = resolve_special_register(instr, enc, regsize);
2150 node_sib(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2165 opcode = instr->opcode;
2170 if (index == 0b100 && !instr->rexpref.x) {
2175 if (instr->regmodrm.mod == 0b00 && base == 0b101) {
2177 instr->strm->disp.type = DISP_4;
2181 instr->strm->type = STORE_SIB;
2182 instr->strm->u.sib.scale = (1 << scale);
2184 instr->strm->u.sib.idx = get_register_idx(instr, index);
2186 instr->strm->u.sib.bas = get_register_bas(instr, base);
2189 if (instr->strm->disp.type == DISP_1 ||
2190 instr->strm->disp.type == DISP_2 ||
2191 instr->strm->disp.type == DISP_4) {
2203 get_register_reg(struct x86_instr *instr, const struct x86_opcode *opcode)
2205 uint8_t enc = instr->regmodrm.reg;
2209 regsize = instr->operand_size;
2211 reg = &gpr_map[instr->rexpref.r][enc][regsize-1];
2213 reg = resolve_special_register(instr, enc, regsize);
2220 get_register_rm(struct x86_instr *instr, const struct x86_opcode *opcode)
2222 uint8_t enc = instr->regmodrm.rm;
2226 if (instr->strm->disp.type == DISP_NONE) {
2227 regsize = instr->operand_size;
2230 regsize = instr->address_size;
2233 reg = &gpr_map[instr->rexpref.b][enc][regsize-1];
2235 reg = resolve_special_register(instr, enc, regsize);
2242 has_sib(struct x86_instr *instr)
2244 return (instr->address_size != 2 && /* no SIB in 16bit addressing */
2245 instr->regmodrm.mod != 0b11 &&
2246 instr->regmodrm.rm == 0b100);
2250 is_rip_relative(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2253 instr->regmodrm.mod == 0b00 &&
2254 instr->regmodrm.rm == 0b101);
2258 is_disp32_only(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2261 instr->address_size != 2 && /* no disp32-only in 16bit addressing */
2262 instr->regmodrm.mod == 0b00 &&
2263 instr->regmodrm.rm == 0b101);
2267 is_disp16_only(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2269 return (instr->address_size == 2 && /* disp16-only only in 16bit addr */
2270 instr->regmodrm.mod == 0b00 &&
2271 instr->regmodrm.rm == 0b110);
2275 is_dual(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2277 return (instr->address_size == 2 &&
2278 instr->regmodrm.mod != 0b11 &&
2279 instr->regmodrm.rm <= 0b011);
2283 get_disp_type(struct x86_instr *instr)
2285 switch (instr->regmodrm.mod) {
2291 if (__predict_false(instr->address_size == 2)) {
2303 node_regmodrm(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2314 opcode = instr->opcode;
2316 instr->regmodrm.rm = ((byte & 0b00000111) >> 0);
2317 instr->regmodrm.reg = ((byte & 0b00111000) >> 3);
2318 instr->regmodrm.mod = ((byte & 0b11000000) >> 6);
2321 strg = &instr->src;
2322 strm = &instr->dst;
2324 strm = &instr->src;
2325 strg = &instr->dst;
2329 instr->strm = strm;
2336 if (group1[instr->regmodrm.reg].emul == NULL) {
2339 instr->emul = group1[instr->regmodrm.reg].emul;
2341 if (group3[instr->regmodrm.reg].emul == NULL) {
2344 instr->emul = group3[instr->regmodrm.reg].emul;
2346 if (group11[instr->regmodrm.reg].emul == NULL) {
2349 instr->emul = group11[instr->regmodrm.reg].emul;
2353 reg = get_register_reg(instr, opcode);
2362 strm->disp.type = get_disp_type(instr);
2364 if (has_sib(instr)) {
2370 if (is_rip_relative(fsm, instr)) {
2379 if (is_disp32_only(fsm, instr)) {
2388 if (__predict_false(is_disp16_only(fsm, instr))) {
2397 if (__predict_false(is_dual(fsm, instr))) {
2403 reg = get_register_rm(instr, opcode);
2432 get_operand_size(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2434 const struct x86_opcode *opcode = instr->opcode;
2440 } else if (instr->rexpref.present && instr->rexpref.w) {
2444 if (instr->legpref.opr_ovr) {
2450 if (instr->legpref.opr_ovr) {
2462 get_address_size(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2465 if (__predict_false(instr->legpref.adr_ovr)) {
2472 if (__predict_false(instr->legpref.adr_ovr)) {
2479 if (__predict_false(instr->legpref.adr_ovr)) {
2486 node_primary_opcode(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2500 instr->opcode = opcode;
2501 instr->emul = opcode->emul;
2502 instr->operand_size = get_operand_size(fsm, instr);
2503 instr->address_size = get_address_size(fsm, instr);
2505 if (fsm->is64bit && (instr->operand_size == 4)) {
2507 instr->zeroextend_mask = ~size_to_mask(4);
2529 node_secondary_opcode(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2543 instr->opcode = opcode;
2544 instr->emul = opcode->emul;
2545 instr->operand_size = get_operand_size(fsm, instr);
2546 instr->address_size = get_address_size(fsm, instr);
2548 if (fsm->is64bit && (instr->operand_size == 4)) {
2550 instr->zeroextend_mask = ~size_to_mask(4);
2558 instr->zeroextend_mask |= size_to_mask(instr->operand_size);
2559 instr->zeroextend_mask &= ~size_to_mask(opcode->defsize);
2560 instr->operand_size = opcode->defsize;
2573 node_main(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2592 } else if (!instr->rexpref.present) {
2608 node_rex_prefix(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2610 struct x86_rexpref *rexpref = &instr->rexpref;
2635 node_legacy_prefix(struct x86_decode_fsm *fsm, struct x86_instr *instr)
2644 instr->legpref.opr_ovr = 1;
2646 instr->legpref.seg = NVMM_X64_SEG_DS;
2648 instr->legpref.seg = NVMM_X64_SEG_ES;
2650 instr->legpref.rep = 1;
2652 instr->legpref.seg = NVMM_X64_SEG_GS;
2654 instr->legpref.seg = NVMM_X64_SEG_FS;
2656 instr->legpref.adr_ovr = 1;
2658 instr->legpref.seg = NVMM_X64_SEG_CS;
2660 instr->legpref.seg = NVMM_X64_SEG_SS;
2662 instr->legpref.repn = 1;
2676 x86_decode(uint8_t *inst_bytes, size_t inst_len, struct x86_instr *instr,
2682 memset(instr, 0, sizeof(*instr));
2683 instr->legpref.seg = -1;
2684 instr->src.hardseg = -1;
2685 instr->dst.hardseg = -1;
2696 ret = (*fsm.fn)(&fsm, instr);
2710 instr->len = fsm.buf - inst_bytes;
2717 #define EXEC_INSTR(sz, instr) \
2719 exec_##instr##sz(uint##sz##_t op1, uint##sz##_t op2, uint64_t *rflags) \
2723 #instr" %2, %3;" \
2732 #define EXEC_DISPATCHER(instr) \
2734 exec_##instr(uint64_t op1, uint64_t op2, uint64_t *rflags, size_t opsize) \
2738 return exec_##instr##8(op1, op2, rflags); \
2740 return exec_##instr##16(op1, op2, rflags); \
2742 return exec_##instr##32(op1, op2, rflags); \
2744 return exec_##instr##64(op1, op2, rflags); \
3029 gpr_read_address(struct x86_instr *instr, struct nvmm_x64_state *state, int gpr)
3034 val &= size_to_mask(instr->address_size);
3040 store_to_gva(struct nvmm_x64_state *state, struct x86_instr *instr,
3051 gva += gpr_read_address(instr, state, sib->bas->num);
3053 reg = gpr_read_address(instr, state, sib->idx->num);
3061 gva = gpr_read_address(instr, state, store->u.reg->num);
3064 gva = gpr_read_address(instr, state, store->u.dualreg.reg1) +
3065 gpr_read_address(instr, state, store->u.dualreg.reg2);
3077 if (__predict_false(instr->legpref.seg != -1)) {
3078 seg = instr->legpref.seg;
3189 struct x86_instr *instr)
3198 size = instr->operand_size;
3202 ret = store_to_gva(state, instr, &instr->src, &gva, size);
3210 ret = store_to_gva(state, instr, &instr->dst, &gva, size);
3219 * (*instr->emul->func)(vcpu, &mem, state->gprs);
3235 struct x86_instr *instr)
3244 size = instr->operand_size;
3248 ret = store_to_gva(state, instr, &instr->src, &gva, size);
3256 ret = store_to_gva(state, instr, &instr->dst, &gva, size);
3265 * (*instr->emul->func)(vcpu, &mem, state->gprs);
3289 struct x86_instr *instr)
3302 mem.size = instr->operand_size;
3306 switch (instr->src.type) {
3308 if (instr->src.disp.type != DISP_NONE) {
3317 if (instr->src.disp.type == DISP_NONE) {
3336 switch (instr->src.type) {
3340 if (__predict_false(instr->src.disp.type != DISP_NONE)) {
3343 val = state->gprs[instr->src.u.reg->num];
3344 val = __SHIFTOUT(val, instr->src.u.reg->mask);
3350 memcpy(mem.data, &instr->src.u.imm.data, mem.size);
3355 } else if (instr->emul->readreg) {
3358 if (__predict_false(instr->dst.type != STORE_REG)) {
3361 if (__predict_false(instr->dst.disp.type != DISP_NONE)) {
3364 val = state->gprs[instr->dst.u.reg->num];
3365 val = __SHIFTOUT(val, instr->dst.u.reg->mask);
3369 (*instr->emul->func)(vcpu, &mem, state->gprs);
3371 if (instr->emul->notouch) {
3380 if (__predict_false(instr->dst.type != STORE_REG)) {
3383 if (__predict_false(instr->dst.disp.type != DISP_NONE)) {
3387 val = __SHIFTIN(val, instr->dst.u.reg->mask);
3388 state->gprs[instr->dst.u.reg->num] &= ~instr->dst.u.reg->mask;
3389 state->gprs[instr->dst.u.reg->num] |= val;
3390 state->gprs[instr->dst.u.reg->num] &= ~instr->zeroextend_mask;
3391 } else if (instr->emul->backprop) {
3395 if (__predict_false(instr->src.type != STORE_REG)) {
3398 if (__predict_false(instr->src.disp.type != DISP_NONE)) {
3402 val = __SHIFTIN(val, instr->src.u.reg->mask);
3403 state->gprs[instr->src.u.reg->num] &= ~instr->src.u.reg->mask;
3404 state->gprs[instr->src.u.reg->num] |= val;
3405 state->gprs[instr->src.u.reg->num] &= ~instr->zeroextend_mask;
3416 struct x86_instr instr;
3442 &instr, state);
3448 if (instr.legpref.rep || instr.legpref.repn) {
3449 cnt = rep_get_cnt(state, instr.address_size);
3451 state->gprs[NVMM_X64_GPR_RIP] += instr.len;
3456 if (instr.opcode->movs) {
3457 ret = assist_mem_movs(mach, vcpu, &instr);
3458 } else if (instr.opcode->cmps) {
3459 instr.legpref.repe = !instr.legpref.repn;
3460 ret = assist_mem_cmps(mach, vcpu, &instr);
3462 ret = assist_mem_single(mach, vcpu, &instr);
3469 if (instr.legpref.rep || instr.legpref.repn) {
3471 rep_set_cnt(state, instr.address_size, cnt);
3473 state->gprs[NVMM_X64_GPR_RIP] += instr.len;
3474 } else if (__predict_false(instr.legpref.repn)) {
3477 state->gprs[NVMM_X64_GPR_RIP] += instr.len;
3479 } else if (__predict_false(instr.legpref.repe)) {
3482 state->gprs[NVMM_X64_GPR_RIP] += instr.len;
3486 state->gprs[NVMM_X64_GPR_RIP] += instr.len;