void tlcs870_device::do_CLR_gbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles CLR g.b 1110 1ggg 0100 1bbb Z * - - 3 */ m_cycles = 3; uint8_t val = get_reg8(opbyte0 & 0x7); const uint8_t bitpos = opbyte1 & 0x7; const int bitused = (1 << bitpos); if (val & bitused) // Zero flag gets set based on original value of bit? { clear_ZF(); clear_JF(); // 'Z' (so copy Z flag?) } else { set_ZF(); set_JF(); // 'Z' } val &= ~bitused; set_reg8(opbyte0 & 0x7, val); }
void tlcs870_device::do_CPL_gbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles CPL g.b 1110 1ggg 1100 0bbb Z * - - 3 */ m_cycles = 3; uint8_t val = get_reg8(opbyte0 & 0x7); const uint8_t bitpos = opbyte1 & 0x7; const int bitused = (1 << bitpos); uint8_t bit = val & bitused; if (bit) // if the bit is set, clear the zero/jump flags and unset the bit { clear_ZF(); clear_JF(); val &= ~bitused; } else // if the bit isn't set, set the zero/jump flags and set the bit { set_ZF(); set_JF(); val |= bitused; } set_reg8(opbyte0 & 0x7, val); }
void tlcs870_device::do_CPL_inpp_indirectbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles CPL (DE).g 1110 1ggg 1001 0010 Z * - - 5 CPL (HL).g 1110 1ggg 1001 0011 Z * - - 5 */ m_cycles = 5; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL m_read_input_port = 0; // reads output latch, not actual ports if accessing memory mapped ports uint8_t val = RM8(addr); uint8_t bit = val & bitused; if (bit) // if the bit is set, clear the zero/jump flags and unset the bit { clear_ZF(); clear_JF(); val &= ~bitused; } else // if the bit isn't set, set the zero/jump flags and set the bit { set_ZF(); set_JF(); val |= bitused; } WM8(addr, val); }
void tlcs870_device::do_CLR_inppbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles CLR (DE).g 1110 1ggg 1000 1010 Z * - - 5 CLR (HL).g 1110 1ggg 1000 1011 Z * - - 5 */ m_cycles = 5; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL m_read_input_port = 0; // reads output latch, not actual ports if accessing memory mapped ports uint8_t val = RM8(addr); if (val & bitused) // Zero flag gets set based on original value of bit? { clear_ZF(); clear_JF(); // 'Z' (so copy Z flag?) } else { set_ZF(); set_JF(); // 'Z' } val &= ~bitused; WM8(addr, val); }
void tlcs870_device::do_SET_inppbit(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles SET (DE).g 1110 1ggg 1000 0010 Z * - - 5 SET (HL).g 1110 1ggg 1000 0011 Z * - - 5 */ m_cycles = 5; const uint8_t bitpos = get_reg8(opbyte0 & 7) & 0x7; const uint8_t bitused = 1 << bitpos; const uint16_t addr = get_reg16((opbyte1 & 1) + 2); // DE or HL uint8_t val = RM8(addr); if (val & bitused) // Zero flag gets set based on original value of bit? { clear_ZF(); clear_JF(); // 'Z' (so copy Z flag?) } else { set_ZF(); set_JF(); // 'Z' } val |= bitused; WM8(addr, val); }
void bx_cpu_c::CMPXCHG_EbGb(BxInstruction_t *i) { #if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4) Bit8u op2_8, op1_8, diff_8; /* op1_8 is a register or memory reference */ if (i->mod == 0xc0) { op1_8 = BX_READ_8BIT_REG(i->rm); } else { /* pointer, segment address pair */ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8); } diff_8 = AL - op1_8; SET_FLAGS_OSZAPC_8(AL, op1_8, diff_8, BX_INSTR_CMP8); if (diff_8 == 0) { // if accumulator == dest // ZF = 1 set_ZF(1); // dest <-- src op2_8 = BX_READ_8BIT_REG(i->nnn); if (i->mod == 0xc0) { BX_WRITE_8BIT_REG(i->rm, op2_8); } else { write_RMW_virtual_byte(op2_8); } } else { // ZF = 0 set_ZF(0); // accumulator <-- dest AL = op1_8; } #else BX_PANIC(("CMPXCHG_EbGb:")); #endif }
void bx_cpu_c::BSF_GvEv(BxInstruction_t *i) { #if BX_CPU_LEVEL < 3 BX_PANIC(("BSF_GvEv(): not supported on < 386")); #else if (i->os_32) { /* 32 bit operand size mode */ /* for 32 bit operand size mode */ Bit32u op1_32, op2_32; /* op2_32 is a register or memory reference */ if (i->mod == 0xc0) { op2_32 = BX_READ_32BIT_REG(i->rm); } else { /* pointer, segment address pair */ read_virtual_dword(i->seg, i->rm_addr, &op2_32); } if (op2_32 == 0) { set_ZF(1); /* op1_32 undefined */ return; } op1_32 = 0; while ( (op2_32 & 0x01) == 0 ) { op1_32++; op2_32 >>= 1; } set_ZF(0); /* now write result back to destination */ BX_WRITE_32BIT_REG(i->nnn, op1_32); }
void tlcs870_device::do_LD_r_g(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles LD r, g 1110 1ggg 0101 1rrr 1 Z - - 2 */ m_cycles = 2; const uint8_t val = get_reg8(opbyte0 & 0x7); set_reg8(opbyte1 & 0x7, val); set_JF(); if (val == 0x00) set_ZF(); else clear_ZF(); }
void tlcs870_device::do_XCH_r_g(const uint8_t opbyte0, const uint8_t opbyte1) { /* OP (opbyte0) (immval0) (opbyte1) (immval1) (immval2) JF ZF CF HF cycles XCG r, g 1110 1ggg 1010 1rrr 1 Z - - 3 */ m_cycles = 3; const uint8_t val = get_reg8(opbyte0 & 0x7); const uint8_t r = get_reg8(opbyte1 & 0x7); set_reg8(opbyte1 & 0x7, val); set_reg8(opbyte0 & 0x7, r); set_JF(); if (val == 0x00) set_ZF(); else clear_ZF(); }
Da_emulate_result Da_emulate(Da* d, CONTEXT * ctx, MemoryCache *mem, bool emulate_FS_accesses, address FS) { #ifdef _WIN64 return DA_NOT_EMULATED; #endif //bool SF=IS_SET(ctx->EFlags, FLAG_SF); //bool OF=IS_SET(ctx->EFlags, FLAG_OF); //bool ZF=IS_SET(ctx->EFlags, FLAG_ZF); bool CF=IS_SET(ctx->EFlags, FLAG_CF); bool b; if (x86_emu_debug) { // FIXME: write to log also? L ("%s() begin: [", __func__); Da_DumpString(&cur_fds, d); L ("]\n"); }; if ((emulate_FS_accesses==false && IS_SET(d->prefix_codes, PREFIX_FS)) || (IS_SET(d->prefix_codes, PREFIX_SS) || IS_SET(d->prefix_codes, PREFIX_GS))) { if (x86_emu_debug) L ("%s() skipping (data selector prefix present) at 0x" PRI_ADR_HEX "\n", __func__, CONTEXT_get_PC(ctx)); return DA_EMULATED_CANNOT_READ_MEMORY; }; switch (d->ins_code) { case I_CDQ: { uint32_t a=CONTEXT_get_Accum (ctx)&0xFFFFFFFF; CONTEXT_set_xDX (ctx, (a&0x80000000) ? 0xFFFFFFFF : 0); goto add_to_PC_and_return_OK; }; break; case I_PUSH: { address rt_adr; obj v; b=Da_op_get_value_of_op (&d->op[0], &rt_adr, ctx, mem, __FILE__, __LINE__, &v, d->prefix_codes, FS); if (b==false) { if (x86_emu_debug) L ("%s() I_PUSH: can't read memory\n", __func__); return DA_EMULATED_CANNOT_READ_MEMORY; }; b=DO_PUSH (ctx, mem, obj_get_as_REG(&v)); if (b==false) { if (x86_emu_debug) L ("%s() I_PUSH: can't write memory\n", __func__); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; }; break; case I_PUSHFD: if (DO_PUSH (ctx, mem, ctx->EFlags | FLAG_TF)==false) { if (x86_emu_debug) L ("%s() I_PUSHFD: can't write memory\n", __func__); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; break; case I_POP: { REG val; if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj v; obj_tetrabyte2 (val, &v); Da_op_set_value_of_op (&d->op[0], &v, ctx, mem, d->prefix_codes, FS); goto add_to_PC_and_return_OK; }; break; case I_POPFD: { REG val; if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; ctx->EFlags=val; goto add_to_PC_and_return_OK; }; break; case I_LEAVE: { //ESP <- EBP //POP EBP REG val; CONTEXT_set_SP(ctx, CONTEXT_get_BP(ctx)); if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; // FIXME: а надо еще SP назад возвращать! CONTEXT_set_BP(ctx, val); goto add_to_PC_and_return_OK; }; break; case I_REP_STOSB: case I_REP_STOSW: case I_REP_STOSD: { BYTE *buf; bool DF=IS_SET(ctx->EFlags, FLAG_DF); if (DF) return DA_NOT_EMULATED; // not supported... bug here SIZE_T BUF_SIZE; if (d->ins_code==I_REP_STOSB) BUF_SIZE=CONTEXT_get_xCX (ctx); else if (d->ins_code==I_REP_STOSW) BUF_SIZE=CONTEXT_get_xCX (ctx)*2; else if (d->ins_code==I_REP_STOSD) BUF_SIZE=CONTEXT_get_xCX (ctx)*4; buf=DMALLOC(BYTE, BUF_SIZE, "buf"); if (d->ins_code==I_REP_STOSB) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! buf[i]=CONTEXT_get_Accum(ctx)&0xFF; } else if (d->ins_code==I_REP_STOSW) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! ((WORD*)buf)[i]=CONTEXT_get_Accum(ctx)&0xFFFF; } else if (d->ins_code==I_REP_STOSD) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! ((DWORD*)buf)[i]=(DWORD)(CONTEXT_get_Accum(ctx)&0xFFFFFFFF); } else { oassert(0); }; if (MC_WriteBuffer (mem, CONTEXT_get_xDI (ctx), BUF_SIZE, buf)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; DFREE(buf); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE); CONTEXT_set_xCX (ctx, 0); goto add_to_PC_and_return_OK; }; break; case I_REP_MOVSB: case I_REP_MOVSW: case I_REP_MOVSD: { BYTE *buf; bool DF=IS_SET(ctx->EFlags, FLAG_DF); if (DF) return DA_NOT_EMULATED; // not supported... bug here SIZE_T BUF_SIZE; SIZE_T sizeof_element; if (d->ins_code==I_REP_MOVSB) sizeof_element=1; else if (d->ins_code==I_REP_MOVSW) sizeof_element=2; else if (d->ins_code==I_REP_MOVSD) sizeof_element=4; else { oassert(0); }; BUF_SIZE=CONTEXT_get_xCX(ctx)*sizeof_element; //printf ("%s() BUF_SIZE=0x%x\n", __func__, BUF_SIZE); //printf ("%s() (before) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx)); //printf ("%s() (before) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx)); buf=DMALLOC(BYTE, BUF_SIZE, "buf"); address blk_src=CONTEXT_get_xSI(ctx); address blk_dst=CONTEXT_get_xDI(ctx); if (DF) { blk_src-=BUF_SIZE; // +sizeof_element; blk_dst-=BUF_SIZE; // +sizeof_element; }; if (MC_ReadBuffer (mem, blk_src, BUF_SIZE, buf)==false) { DFREE(buf); return DA_EMULATED_CANNOT_READ_MEMORY; }; if (MC_WriteBuffer (mem, blk_dst, BUF_SIZE, buf)==false) { DFREE(buf); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; DFREE(buf); if (DF==false) { CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) + BUF_SIZE); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE); } else { CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) - BUF_SIZE); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) - BUF_SIZE); }; CONTEXT_set_xCX (ctx, 0); //printf ("%s() (after) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx)); //printf ("%s() (after) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx)); goto add_to_PC_and_return_OK; }; case I_STD: SET_BIT (ctx->EFlags, FLAG_DF); goto add_to_PC_and_return_OK; case I_CLD: REMOVE_BIT (ctx->EFlags, FLAG_DF); goto add_to_PC_and_return_OK; case I_RETN: { WORD ret_arg=0; if (d->ops_total==1) { oassert (d->op[0].type==DA_OP_TYPE_VALUE); ret_arg=obj_get_as_wyde(&d->op[0].val._v); // RETN arg is 16-bit }; address newPC; if (DO_POP(ctx, mem, &newPC)==false) return DA_EMULATED_CANNOT_READ_MEMORY; CONTEXT_set_SP(ctx, CONTEXT_get_SP(ctx)+ret_arg); CONTEXT_set_PC(ctx, newPC); return DA_EMULATED_OK; }; break; case I_ADD: case I_ADC: case I_INC: { //L (__FUNCTION__ "() I_ADD/I_INC begin: [%s]\n", ToString().c_str()); obj rt1, rt2; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (d->ins_code==I_ADD || d->ins_code==I_ADC) { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; } else { // INC case // make second op 1 obj_REG2_and_set_type (rt1.t, 1, 0, &rt2); }; obj res_sum; obj_add (&rt1, &rt2, &res_sum); if (d->ins_code==I_ADC && CF) obj_increment(&res_sum); set_PF (ctx, &res_sum); set_SF (ctx, &res_sum); set_ZF (ctx, &res_sum); set_AF (ctx, &rt1, &rt2, &res_sum); if (d->ins_code==I_ADD || d->ins_code==I_ADC) set_or_clear_flag (ctx, FLAG_CF, obj_compare (&res_sum, &rt1)==-1); // res_sum < rt1 octabyte tmp=((zero_extend_to_REG(&rt1) ^ zero_extend_to_REG(&rt2) ^ get_sign_bit (d->op[0].value_width_in_bits)) & (zero_extend_to_REG(&res_sum) ^ zero_extend_to_REG(&rt1))) & get_sign_bit (d->op[0].value_width_in_bits); set_or_clear_flag (ctx, FLAG_OF, tmp); b=Da_op_set_value_of_op (&d->op[0], &res_sum, ctx, mem, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; break; case I_NOT: { obj rt1, res; REG rt1_adr; if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj_NOT(&rt1, &res); if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS)) goto add_to_PC_and_return_OK; }; break; case I_NEG: { obj rt1, res; REG rt1_adr; if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj_NEG(&rt1, &res); set_or_clear_flag (ctx, FLAG_CF, obj_is_zero(&rt1)==false); set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); set_or_clear_flag (ctx, FLAG_AF, (0 ^ obj_get_4th_bit(&rt1)) ^ obj_get_4th_bit(&res)); REMOVE_BIT (ctx->EFlags, FLAG_OF); //SET_BIT (ctx->EFlags, FLAG_AF); if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS)) goto add_to_PC_and_return_OK; }; break; case I_OR: case I_XOR: case I_AND: case I_TEST: { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); obj rt1, rt2, res; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; switch (d->ins_code) { case I_OR: obj_OR(&rt1, &rt2, &res); break; case I_XOR: obj_XOR(&rt1, &rt2, &res); break; case I_TEST: case I_AND: obj_AND(&rt1, &rt2, &res); break; default: oassert(0); break; }; set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); REMOVE_BIT (ctx->EFlags, FLAG_AF); REMOVE_BIT (ctx->EFlags, FLAG_CF); REMOVE_BIT (ctx->EFlags, FLAG_OF); if (d->ins_code==I_TEST) b=true; else b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS); if (b) goto add_to_PC_and_return_OK; else return DA_EMULATED_CANNOT_WRITE_MEMORY; }; break; case I_DEC: case I_SUB: case I_SBB: case I_CMP: { if (d->ins_code==I_SUB || d->ins_code==I_SBB || d->ins_code==I_CMP) { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); }; obj rt1, rt2; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (d->ins_code==I_DEC) { // make second op 1 obj_REG2_and_set_type (rt1.t, 1, 0, &rt2); } else { b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; }; obj res; obj_subtract (&rt1, &rt2, &res); if (d->ins_code==I_SBB && CF) obj_decrement (&res); set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); set_AF (ctx, &rt1, &rt2, &res); if (d->ins_code==I_SBB) { int tmp=(obj_compare (&rt1, &res)==-1 /* rt1<res */) || (CF && obj_get_as_tetrabyte(&rt2)==0xffffffff); set_or_clear_flag (ctx, FLAG_CF, tmp); } else { if (d->ins_code!=I_DEC) // DEC leave CF flag unaffected set_or_clear_flag (ctx, FLAG_CF, obj_compare (&rt1, &rt2)==-1); /* rt1<rt2 */ }; octabyte tmp=((zero_extend_to_octabyte(&rt1) ^ zero_extend_to_octabyte(&rt2)) & (zero_extend_to_octabyte(&res) ^ zero_extend_to_octabyte(&rt1))) & get_sign_bit (d->op[0].value_width_in_bits); set_or_clear_flag (ctx, FLAG_OF, tmp); if (d->ins_code==I_CMP) b=true; else b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS); if (b) goto add_to_PC_and_return_OK; else return DA_EMULATED_CANNOT_WRITE_MEMORY; }; break; case I_XCHG: { REG op1_adr, op2_adr; obj op1; b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj op2; b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (Da_op_set_value_of_op (&d->op[0], &op2, ctx, mem, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; if (Da_op_set_value_of_op (&d->op[1], &op1, ctx, mem, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; break; case I_MOV: case I_MOVDQA: case I_MOVDQU: return Da_emulate_MOV_op1_op2(d, ctx, mem, d->prefix_codes, FS); case I_MOVZX: case I_MOVSX: { address rt_adr; obj op2; bool b=Da_op_get_value_of_op(&d->op[1], &rt_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) { /* if (L_verbose_level>=2) { printf (__FUNCTION__ "(): ["); Da_DumpString(d); printf ("]: can't read src (2nd) operand\n"); }; */ return DA_EMULATED_CANNOT_WRITE_MEMORY; }; obj to_be_stored_v; if (d->ins_code==I_MOVZX) { enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits); obj_zero_extend (&op2, op1_type_will_be, &to_be_stored_v); } else if (d->ins_code==I_MOVSX) { enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits); obj_sign_extend (&op2, op1_type_will_be, &to_be_stored_v); } else { oassert (0); }; b=Da_op_set_value_of_op (&d->op[0], &to_be_stored_v, ctx, mem, d->prefix_codes, FS); if (b==false) { /* if (L_verbose_level>=2) { printf(__FUNCTION__ "(): ["); Da_DumpString(d); printf ("]: can't write dst (1st) operand\n"); }; */ return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; }; case I_NOP: goto add_to_PC_and_return_OK; case I_LEA: { address a=(address)Da_op_calc_adr_of_op(&d->op[1], ctx, mem, d->prefix_codes, FS); obj val; obj_tetrabyte2(a, &val); b=Da_op_set_value_of_op (&d->op[0], &val, ctx, mem, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; case I_SAR: case I_SHR: case I_SHL: { // http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH06/CH06-3.html REG op1_adr, op2_adr; obj op1; bool b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; // should be read anyway! obj op2; b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; #ifdef _WIN64 obj_AND_with (&op2, 0x3F); #else obj_AND_with (&op2, 0x1F); #endif if (obj_is_zero(&op2)==false) { unsigned new_CF; if (d->ins_code==I_SHR || d->ins_code==I_SAR) new_CF=(zero_extend_to_octabyte(&op1) >> (obj_get_as_byte (&op2) - 1)) & 1; else // SHL new_CF=(zero_extend_to_octabyte(&op1) >> (obj_width_in_bits(&op1) - obj_get_as_byte (&op2))) & 1; obj new_op1; if (d->ins_code==I_SHR) { REG new_v=zero_extend_to_REG(&op1) >> obj_get_as_byte (&op2); obj_REG2_and_set_type(op1.t, new_v, 0, &new_op1); } else if (d->ins_code==I_SAR)