void BX_CPP_AttrRegparmN(1) BX_CPU_C::FST_STi(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); int pop_stack = i->nnn() & 1; // handle special case of FSTP opcode @ 0xDF 0xD0..D7 if (i->b1() == 0xdf) pop_stack = 1; clear_C1(); if (IS_TAG_EMPTY(0)) { BX_CPU_THIS_PTR FPU_stack_underflow(i->rm(), pop_stack); return; } floatx80 st0_reg = BX_READ_FPU_REG(0); BX_WRITE_FPU_REG(st0_reg, i->rm()); if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); #else BX_INFO(("FST(P)_STi: required FPU, configure --enable-fpu")); #endif }
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_DOUBLE_REAL(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i)); clear_C1(); if (! IS_TAG_EMPTY(-1)) { BX_CPU_THIS_PTR FPU_stack_overflow(); return; } float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); // convert to floatx80 format floatx80 result = float64_to_floatx80(load_reg, status); if (BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) return; BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); #else BX_INFO(("FLD_DOUBLE_REAL: required FPU, configure --enable-fpu")); #endif }
/* DD /1 */ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISTTP64(bxInstruction_c *i) { #if BX_SUPPORT_SSE >= 3 BX_CPU_THIS_PTR prepareFPU(i); Bit64s save_reg = int64_indefinite; /* The masked response */ clear_C1(); if (IS_TAG_EMPTY(0)) { BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow); if (! (BX_CPU_THIS_PTR the_i387.is_IA_masked())) return; } else { float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); save_reg = floatx80_to_int64_round_to_zero(BX_READ_FPU_REG(0), status); if (BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) return; } write_virtual_qword(i->seg(), RMAddr(i), (Bit64u)(save_reg)); BX_CPU_THIS_PTR the_i387.FPU_pop(); #else BX_INFO(("FISTTP64: required SSE3, use --enable-sse option")); UndefinedOpcode(i); #endif }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_DOUBLE_REAL(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i)); FPU_update_last_instruction(i); clear_C1(); if (! IS_TAG_EMPTY(-1)) { FPU_stack_overflow(); BX_NEXT_INSTR(i); } float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); // convert to floatx80 format floatx80 result = float64_to_floatx80(load_reg, status); unsigned unmasked = FPU_exception(status.float_exception_flags); if (! (unmasked & FPU_CW_Invalid)) { BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); } BX_NEXT_INSTR(i); }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMI_ST0_STj(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); BX_CPU_THIS_PTR FPU_update_last_instruction(i); int pop_stack = i->b1() & 4; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm())) { FPU_exception(FPU_EX_Stack_Underflow); setEFlagsOSZAPC(EFlagsZFMask | EFlagsPFMask | EFlagsCFMask); if(BX_CPU_THIS_PTR the_i387.is_IA_masked()) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); } float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->rm()), status); BX_CPU_THIS_PTR write_eflags_fpu_compare(rc); if (! FPU_exception(status.float_exception_flags)) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_STi(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); FPU_update_last_instruction(i); clear_C1(); if (! IS_TAG_EMPTY(-1)) { FPU_stack_overflow(); BX_NEXT_INSTR(i); } floatx80 sti_reg = floatx80_default_nan; if (IS_TAG_EMPTY(i->rm())) { FPU_exception(FPU_EX_Stack_Underflow); if (! BX_CPU_THIS_PTR the_i387.is_IA_masked()) BX_NEXT_INSTR(i); } else { sti_reg = BX_READ_FPU_REG(i->rm()); } BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(sti_reg, 0); BX_NEXT_INSTR(i); }
/* DB /7 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FSTP_EXTENDED_REAL(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); FPU_update_last_instruction(i); clear_C1(); floatx80 save_reg = floatx80_default_nan; /* The masked response */ if (IS_TAG_EMPTY(0)) { FPU_exception(FPU_EX_Stack_Underflow); if (! BX_CPU_THIS_PTR the_i387.is_IA_masked()) BX_NEXT_INSTR(i); } else { save_reg = BX_READ_FPU_REG(0); } write_virtual_qword(i->seg(), RMAddr(i), save_reg.fraction); write_virtual_word(i->seg(), (RMAddr(i) + 8) & i->asize_mask(), save_reg.exp); BX_CPU_THIS_PTR the_i387.FPU_pop(); BX_NEXT_INSTR(i); }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FST_STi(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); FPU_update_last_instruction(i); int pop_stack = i->nnn() & 1; // handle special case of FSTP opcode @ 0xDF 0xD0..D7 if (i->b1() == 0xdf) pop_stack = 1; clear_C1(); if (IS_TAG_EMPTY(0)) { FPU_stack_underflow(i->rm(), pop_stack); } else { floatx80 st0_reg = BX_READ_FPU_REG(0); BX_WRITE_FPU_REG(st0_reg, i->rm()); if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); }
/* DA E9 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FUCOMPP(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); BX_CPU_THIS_PTR FPU_update_last_instruction(i); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1)) { FPU_exception(FPU_EX_Stack_Underflow); setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3); if(BX_CPU_THIS_PTR the_i387.is_IA_masked()) { BX_CPU_THIS_PTR the_i387.FPU_pop(); BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); } float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); int rc = floatx80_compare_quiet(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), status); setcc(status_word_flags_fpu_compare(rc)); if (! FPU_exception(status.float_exception_flags)) { BX_CPU_THIS_PTR the_i387.FPU_pop(); BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FCMOV_ST0_STj(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); BX_CPU_THIS_PTR FPU_update_last_instruction(i); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm())) { FPU_stack_underflow(0); BX_NEXT_INSTR(i); } floatx80 sti_reg = BX_READ_FPU_REG(i->rm()); bx_bool condition = 0; switch(i->nnn() & 3) { case 0: condition = get_CF(); break; case 1: condition = get_ZF(); break; case 2: condition = get_CF() || get_ZF(); break; case 3: condition = get_PF(); break; default: BX_PANIC(("FCMOV_ST0_STj: default case")); } if (i->b1() & 1) condition = !condition; if (condition) BX_WRITE_FPU_REG(sti_reg, 0); BX_NEXT_INSTR(i); }
/* DB /7 */ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSTP_EXTENDED_REAL(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); clear_C1(); floatx80 save_reg = floatx80_default_nan; /* The masked response */ if (IS_TAG_EMPTY(0)) { BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow); if (! (BX_CPU_THIS_PTR the_i387.is_IA_masked())) return; } else { save_reg = BX_READ_FPU_REG(0); } write_virtual_tword(i->seg(), RMAddr(i), &save_reg); BX_CPU_THIS_PTR the_i387.FPU_pop(); #else BX_INFO(("FSTP_EXTENDED_REAL: required FPU, configure --enable-fpu")); #endif }
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_STi(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); clear_C1(); if (! IS_TAG_EMPTY(-1)) { BX_CPU_THIS_PTR FPU_stack_overflow(); return; } if (IS_TAG_EMPTY(i->rm())) { BX_CPU_THIS_PTR FPU_stack_underflow(0); return; } floatx80 sti_reg = BX_READ_FPU_REG(i->rm()); BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(sti_reg, 0); #else BX_INFO(("FLD_STi: required FPU, configure --enable-fpu")); #endif }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_DOUBLE_REAL(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); int pop_stack = i->nnn() & 1, rc; RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i)); BX_CPU_THIS_PTR FPU_update_last_instruction(i); clear_C1(); if (IS_TAG_EMPTY(0)) { FPU_exception(FPU_EX_Stack_Underflow); setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3); if(BX_CPU_THIS_PTR the_i387.is_IA_masked()) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); } float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); floatx80 a = BX_READ_FPU_REG(0); if (floatx80_is_nan(a) || floatx80_is_unsupported(a) || float64_is_nan(load_reg)) { rc = float_relation_unordered; float_raise(status, float_flag_invalid); } else { rc = floatx80_compare(a, float64_to_floatx80(load_reg, status), status); } setcc(status_word_flags_fpu_compare(rc)); if (! FPU_exception(status.float_exception_flags)) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FIST_DWORD_INTEGER(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); FPU_update_last_instruction(i); Bit16u x87_sw = FPU_PARTIAL_STATUS; Bit32s save_reg = int32_indefinite; /* The masked response */ int pop_stack = i->nnn() & 1; clear_C1(); if (IS_TAG_EMPTY(0)) { FPU_exception(FPU_EX_Stack_Underflow); if (! BX_CPU_THIS_PTR the_i387.is_IA_masked()) BX_NEXT_INSTR(i); } else { float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); save_reg = floatx80_to_int32(BX_READ_FPU_REG(0), status); if (FPU_exception(status.float_exception_flags, 1)) BX_NEXT_INSTR(i); } // store to the memory might generate an exception, in this case origial FPU_SW must be kept swap_values16u(x87_sw, FPU_PARTIAL_STATUS); write_virtual_dword(i->seg(), RMAddr(i), (Bit32u)(save_reg)); FPU_PARTIAL_STATUS = x87_sw; if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); BX_NEXT_INSTR(i); }
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLDPI(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); clear_C1(); if (! IS_TAG_EMPTY(-1)) { BX_CPU_THIS_PTR FPU_stack_overflow(); return; } BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(FPU_round_const(Const_PI, DOWN_OR_CHOP() ? -1 : 0), 0); #else BX_INFO(("FLDPI: required FPU, configure --enable-fpu")); #endif }
/* DF /4 */ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FBLD_PACKED_BCD(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); // read packed bcd from memory Bit16u hi2 = read_virtual_word (i->seg(), RMAddr(i) + 8); Bit64u lo8 = read_virtual_qword(i->seg(), RMAddr(i)); clear_C1(); if (! IS_TAG_EMPTY(-1)) { BX_CPU_THIS_PTR FPU_stack_overflow(); return; } // convert packed BCD to 64-bit integer Bit64s scale = 1; Bit64s val64 = 0; for (int n = 0; n < 16; n++) { val64 += (lo8 & 0x0f) * scale; lo8 >>= 4; scale *= 10; } val64 += (hi2 & 0x0f) * scale; val64 += ((hi2>>4) & 0x0f) * scale * 10; floatx80 result = int64_to_floatx80(val64); if (hi2 & 0x8000) // set negative floatx80_chs(result); BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); #else BX_INFO(("FBLD_PACKED_BCD: required FPU, configure --enable-fpu")); #endif }
/* DF /4 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FBLD_PACKED_BCD(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); Bit16u hi2 = read_virtual_word(i->seg(), (RMAddr(i) + 8) & i->asize_mask()); Bit64u lo8 = read_virtual_qword(i->seg(), RMAddr(i)); FPU_update_last_instruction(i); clear_C1(); if (! IS_TAG_EMPTY(-1)) { FPU_stack_overflow(); BX_NEXT_INSTR(i); } // convert packed BCD to 64-bit integer Bit64s scale = 1; Bit64s val64 = 0; for (int n = 0; n < 16; n++) { val64 += (lo8 & 0x0f) * scale; lo8 >>= 4; scale *= 10; } val64 += (hi2 & 0x0f) * scale; val64 += ((hi2>>4) & 0x0f) * scale * 10; floatx80 result = int64_to_floatx80(val64); if (hi2 & 0x8000) // set negative floatx80_chs(result); BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); BX_NEXT_INSTR(i); }
/* DF /5 */ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FILD_QWORD_INTEGER(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); Bit64s load_reg = (Bit64s) read_virtual_qword(i->seg(), RMAddr(i)); clear_C1(); if (! IS_TAG_EMPTY(-1)) { BX_CPU_THIS_PTR FPU_stack_overflow(); return; } floatx80 result = int64_to_floatx80(load_reg); BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); #else BX_INFO(("FILD_QWORD_INTEGER: required FPU, configure --enable-fpu")); #endif }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FICOM_WORD_INTEGER(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); int pop_stack = i->nnn() & 1; RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); Bit16s load_reg = (Bit16s) read_virtual_word(i->seg(), RMAddr(i)); BX_CPU_THIS_PTR FPU_update_last_instruction(i); clear_C1(); if (IS_TAG_EMPTY(0)) { FPU_exception(FPU_EX_Stack_Underflow); setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3); if(BX_CPU_THIS_PTR the_i387.is_IA_masked()) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); } float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); int rc = floatx80_compare(BX_READ_FPU_REG(0), int32_to_floatx80((Bit32s)(load_reg)), status); setcc(status_word_flags_fpu_compare(rc)); if (! FPU_exception(status.float_exception_flags)) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); }
/* DF /5 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FILD_QWORD_INTEGER(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); Bit64s load_reg = (Bit64s) read_virtual_qword(i->seg(), RMAddr(i)); FPU_update_last_instruction(i); clear_C1(); if (! IS_TAG_EMPTY(-1)) { FPU_stack_overflow(); } else { floatx80 result = int64_to_floatx80(load_reg); BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); } BX_NEXT_INSTR(i); }
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_EXTENDED_REAL(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); floatx80 result; read_virtual_tword(i->seg(), RMAddr(i), &result); clear_C1(); if (! IS_TAG_EMPTY(-1)) { BX_CPU_THIS_PTR FPU_stack_overflow(); return; } BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); #else BX_INFO(("FLD_EXTENDED_REAL: required FPU, configure --enable-fpu")); #endif }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FCOM_STi(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); BX_CPU_THIS_PTR FPU_update_last_instruction(i); int pop_stack = i->nnn() & 1; // handle special case of FSTP opcode @ 0xDE 0xD0..D7 if (i->b1() == 0xde) pop_stack = 1; clear_C1(); if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->rm())) { FPU_exception(FPU_EX_Stack_Underflow); setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3); if(BX_CPU_THIS_PTR the_i387.is_IA_masked()) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); } float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); int rc = floatx80_compare(BX_READ_FPU_REG(0), BX_READ_FPU_REG(i->rm()), status); setcc(status_word_flags_fpu_compare(rc)); if (! FPU_exception(status.float_exception_flags)) { if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); } BX_NEXT_INSTR(i); }
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIST_DWORD_INTEGER(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); Bit32s save_reg = int32_indefinite; /* The masked response */ int pop_stack = i->nnn() & 1; clear_C1(); if (IS_TAG_EMPTY(0)) { BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow); if (! (BX_CPU_THIS_PTR the_i387.is_IA_masked())) return; } else { float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); save_reg = floatx80_to_int32(BX_READ_FPU_REG(0), status); if (BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) return; } write_virtual_dword(i->seg(), RMAddr(i), (Bit32u)(save_reg)); if (pop_stack) BX_CPU_THIS_PTR the_i387.FPU_pop(); #else BX_INFO(("FIST(P)_DWORD_INTEGER: required FPU, configure --enable-fpu")); #endif }
/* D9 E4 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FTST(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); BX_CPU_THIS_PTR FPU_update_last_instruction(i); clear_C1(); if (IS_TAG_EMPTY(0)) { FPU_exception(FPU_EX_Stack_Underflow); setcc(FPU_SW_C0|FPU_SW_C2|FPU_SW_C3); } else { extern const floatx80 Const_Z; float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); int rc = floatx80_compare(BX_READ_FPU_REG(0), Const_Z, status); setcc(status_word_flags_fpu_compare(rc)); FPU_exception(status.float_exception_flags); } BX_NEXT_INSTR(i); }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FLD_EXTENDED_REAL(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); floatx80 result; RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); result.fraction = read_virtual_qword(i->seg(), RMAddr(i)); result.exp = read_virtual_word(i->seg(), (RMAddr(i)+8) & i->asize_mask()); FPU_update_last_instruction(i); clear_C1(); if (! IS_TAG_EMPTY(-1)) { FPU_stack_overflow(); } else { BX_CPU_THIS_PTR the_i387.FPU_push(); BX_WRITE_FPU_REG(result, 0); } BX_NEXT_INSTR(i); }
/* D9 E5 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FXAM(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); BX_CPU_THIS_PTR FPU_update_last_instruction(i); floatx80 reg = BX_READ_FPU_REG(0); int sign = floatx80_sign(reg); /* * Examine the contents of the ST(0) register and sets the condition * code flags C0, C2 and C3 in the FPU status word to indicate the * class of value or number in the register. */ if (IS_TAG_EMPTY(0)) { setcc(FPU_SW_C3|FPU_SW_C1|FPU_SW_C0); } else { float_class_t aClass = floatx80_class(reg); switch(aClass) { case float_zero: setcc(FPU_SW_C3|FPU_SW_C1); break; case float_NaN: // unsupported handled as NaNs if (floatx80_is_unsupported(reg)) { setcc(FPU_SW_C1); } else { setcc(FPU_SW_C1|FPU_SW_C0); } break; case float_negative_inf: case float_positive_inf: setcc(FPU_SW_C2|FPU_SW_C1|FPU_SW_C0); break; case float_denormal: setcc(FPU_SW_C3|FPU_SW_C2|FPU_SW_C1); break; case float_normalized: setcc(FPU_SW_C2|FPU_SW_C1); break; } } /* * The C1 flag is set to the sign of the value in ST(0), regardless * of whether the register is empty or full. */ if (! sign) clear_C1(); BX_NEXT_INSTR(i); }
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::FBSTP_PACKED_BCD(bxInstruction_c *i) { BX_CPU_THIS_PTR prepareFPU(i); RMAddr(i) = BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); FPU_update_last_instruction(i); Bit16u x87_sw = FPU_PARTIAL_STATUS; /* * The packed BCD integer indefinite encoding (FFFFC000000000000000H) * is stored in response to a masked floating-point invalid-operation * exception. */ Bit16u save_reg_hi = 0xFFFF; Bit64u save_reg_lo = BX_CONST64(0xC000000000000000); clear_C1(); if (IS_TAG_EMPTY(0)) { FPU_exception(FPU_EX_Stack_Underflow); if (! BX_CPU_THIS_PTR the_i387.is_IA_masked()) BX_NEXT_INSTR(i); } else { float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); floatx80 reg = BX_READ_FPU_REG(0); Bit64s save_val = floatx80_to_int64(reg, status); int sign = (reg.exp & 0x8000) != 0; if (sign) save_val = -save_val; if (save_val > BX_CONST64(999999999999999999)) { status.float_exception_flags = float_flag_invalid; // throw away other flags } if (! (status.float_exception_flags & float_flag_invalid)) { save_reg_hi = (sign) ? 0x8000 : 0; save_reg_lo = 0; for (int i=0; i<16; i++) { save_reg_lo += ((Bit64u)(save_val % 10)) << (4*i); save_val /= 10; } save_reg_hi += (Bit16u)(save_val % 10); save_val /= 10; save_reg_hi += (Bit16u)(save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ if (FPU_exception(status.float_exception_flags, 1)) BX_NEXT_INSTR(i); } // store to the memory might generate an exception, in this case origial FPU_SW must be kept swap_values16u(x87_sw, FPU_PARTIAL_STATUS); // write packed bcd to memory write_virtual_qword(i->seg(), RMAddr(i), save_reg_lo); write_virtual_word(i->seg(), (RMAddr(i) + 8) & i->asize_mask(), save_reg_hi); FPU_PARTIAL_STATUS = x87_sw; BX_CPU_THIS_PTR the_i387.FPU_pop(); BX_NEXT_INSTR(i); }
void BX_CPP_AttrRegparmN(1) BX_CPU_C::FBSTP_PACKED_BCD(bxInstruction_c *i) { #if BX_SUPPORT_FPU BX_CPU_THIS_PTR prepareFPU(i); /* * The packed BCD integer indefinite encoding (FFFFC000000000000000H) * is stored in response to a masked floating-point invalid-operation * exception. */ Bit16u save_reg_hi = 0xFFFF; Bit64u save_reg_lo = BX_CONST64(0xC000000000000000); clear_C1(); if (IS_TAG_EMPTY(0)) { BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow); if (! (BX_CPU_THIS_PTR the_i387.is_IA_masked())) return; } else { float_status_t status = FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387.get_control_word()); floatx80 reg = BX_READ_FPU_REG(0); Bit64s save_val = floatx80_to_int64(reg, status); int sign = (reg.exp & 0x8000) != 0; if (sign) save_val = -save_val; if (save_val > BX_CONST64(999999999999999999)) { float_raise(status, float_flag_invalid); } if (! (status.float_exception_flags & float_flag_invalid)) { save_reg_hi = (sign) ? 0x8000 : 0; save_reg_lo = 0; for (int i=0; i<16; i++) { save_reg_lo += ((Bit64u)(save_val % 10)) << (4*i); save_val /= 10; } save_reg_hi += (Bit16u)(save_val % 10); save_val /= 10; save_reg_hi += (Bit16u)(save_val % 10) << 4; } /* check for fpu arithmetic exceptions */ if (BX_CPU_THIS_PTR FPU_exception(status.float_exception_flags)) return; } // write packed bcd to memory write_virtual_qword(i->seg(), RMAddr(i), save_reg_lo); write_virtual_word (i->seg(), RMAddr(i) + 8, save_reg_hi); BX_CPU_THIS_PTR the_i387.FPU_pop(); #else BX_INFO(("FBSTP_PACKED_BCD: required FPU, configure --enable-fpu")); #endif }