Refine stack overflow and underflow for the fpu a bit.
Overflow is still treated as Exit. Underflow is ignored in release mode as it happens every now and then and doesn't seem to cause issues if ignored, thus restoring 0.74 behaviour. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4199
This commit is contained in:
parent
c9c97f13af
commit
4a1ef4d3d7
3 changed files with 96 additions and 5 deletions
|
@ -19,6 +19,11 @@
|
|||
#ifndef DOSBOX_FPU_H
|
||||
#define DOSBOX_FPU_H
|
||||
|
||||
#ifndef DOSBOX_DOSBOX_H
|
||||
//So the right config.h gets included for C_DEBUG
|
||||
#include "dosbox.h"
|
||||
#endif
|
||||
|
||||
#ifndef DOSBOX_MEM_H
|
||||
#include "mem.h"
|
||||
#endif
|
||||
|
@ -150,5 +155,22 @@ static INLINE void FPU_SET_C3(Bitu C){
|
|||
if(C) fpu.sw |= 0x4000;
|
||||
}
|
||||
|
||||
#define DB_FPU_STACK_CHECK_NONE 0
|
||||
#define DB_FPU_STACK_CHECK_LOG 1
|
||||
#define DB_FPU_STACK_CHECK_EXIT 2
|
||||
//NONE is 0.74 behavior: not care about stack overflow/underflow
|
||||
//Overflow is always logged/exited on.
|
||||
//Underflow can be controlled with by this.
|
||||
//LOG is giving a message when encountered
|
||||
//EXIT is to hard exit.
|
||||
//Currently pop is ignored in release mode and overflow is exit.
|
||||
//in debug mode: pop will log and overflow is exit.
|
||||
#if C_DEBUG
|
||||
#define DB_FPU_STACK_CHECK_POP DB_FPU_STACK_CHECK_LOG
|
||||
#define DB_FPU_STACK_CHECK_PUSH DB_FPU_STACK_CHECK_EXIT
|
||||
#else
|
||||
#define DB_FPU_STACK_CHECK_POP DB_FPU_STACK_CHECK_NONE
|
||||
#define DB_FPU_STACK_CHECK_PUSH DB_FPU_STACK_CHECK_EXIT
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef DOSBOX_FPU_H
|
||||
#include "fpu.h"
|
||||
#endif
|
||||
|
||||
|
||||
static void FPU_FINIT(void) {
|
||||
|
@ -43,7 +46,23 @@ static void FPU_FNOP(void){
|
|||
|
||||
static void FPU_PREP_PUSH(void){
|
||||
TOP = (TOP - 1) &7;
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow");
|
||||
#if DB_FPU_STACK_CHECK_PUSH > DB_FPU_STACK_CHECK_NONE
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) {
|
||||
#if DB_FPU_STACK_CHECK_PUSH == DB_FPU_STACK_CHECK_EXIT
|
||||
E_Exit("FPU stack overflow");
|
||||
#else
|
||||
if (fpu.cw&1) { // Masked ?
|
||||
fpu.sw &= 0x1; //Invalid Operation
|
||||
fpu.sw &= 0x40; //Stack Fault
|
||||
FPU_SET_C1(1); //Register is used.
|
||||
//No need to set 0x80 as the exception is masked.
|
||||
LOG(LOG_FPU,LOG_ERROR)("Masked stack overflow encountered!");
|
||||
} else {
|
||||
E_Exit("FPU stack overflow"); //Exit as this is bad
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
fpu.tags[TOP] = TAG_Valid;
|
||||
}
|
||||
|
||||
|
@ -56,7 +75,23 @@ static void FPU_PUSH(double in){
|
|||
|
||||
|
||||
static void FPU_FPOP(void){
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow");
|
||||
#if DB_FPU_STACK_CHECK_POP > DB_FPU_STACK_CHECK_NONE
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) {
|
||||
#if DB_FPU_STACK_CHECK_POP == DB_FPU_STACK_CHECK_EXIT
|
||||
E_Exit("FPU stack underflow");
|
||||
#else
|
||||
if (fpu.cw&1) { // Masked ?
|
||||
fpu.sw &= 0x1; //Invalid Operation
|
||||
fpu.sw &= 0x40; //Stack Fault
|
||||
FPU_SET_C1(0); //Register is free.
|
||||
//No need to set 0x80 as the exception is masked.
|
||||
LOG(LOG_FPU,LOG_ERROR)("Masked stack underflow encountered!");
|
||||
} else {
|
||||
LOG_MSG("Unmasked Stack underflow!"); //Also log in release mode
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
fpu.tags[TOP]=TAG_Empty;
|
||||
//maybe set zero in it as well
|
||||
TOP = ((TOP+1)&7);
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DOSBOX_FPU_H
|
||||
#include "fpu.h"
|
||||
#endif
|
||||
|
||||
// #define WEAK_EXCEPTIONS
|
||||
|
||||
|
@ -957,12 +959,44 @@ static void FPU_FNOP(void){
|
|||
|
||||
static void FPU_PREP_PUSH(void){
|
||||
TOP = (TOP - 1) &7;
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow");
|
||||
#if DB_FPU_STACK_CHECK_PUSH > DB_FPU_STACK_CHECK_NONE
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) {
|
||||
#if DB_FPU_STACK_CHECK_PUSH == DB_FPU_STACK_CHECK_EXIT
|
||||
E_Exit("FPU stack overflow");
|
||||
#else
|
||||
if (fpu.cw&1) { // Masked ?
|
||||
fpu.sw &= 0x1; //Invalid Operation
|
||||
fpu.sw &= 0x40; //Stack Fault
|
||||
FPU_SET_C1(1); //Register is used.
|
||||
//No need to set 0x80 as the exception is masked.
|
||||
LOG(LOG_FPU,LOG_ERROR)("Masked stack overflow encountered!");
|
||||
} else {
|
||||
E_Exit("FPU stack overflow"); //Exit as this is bad
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
fpu.tags[TOP] = TAG_Valid;
|
||||
}
|
||||
|
||||
static void FPU_FPOP(void){
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow");
|
||||
#if DB_FPU_STACK_CHECK_POP > DB_FPU_STACK_CHECK_NONE
|
||||
if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) {
|
||||
#if DB_FPU_STACK_CHECK_POP == DB_FPU_STACK_CHECK_EXIT
|
||||
E_Exit("FPU stack underflow");
|
||||
#else
|
||||
if (fpu.cw&1) { // Masked ?
|
||||
fpu.sw &= 0x1; //Invalid Operation
|
||||
fpu.sw &= 0x40; //Stack Fault
|
||||
FPU_SET_C1(0); //Register is free.
|
||||
//No need to set 0x80 as the exception is masked.
|
||||
LOG(LOG_FPU,LOG_ERROR)("Masked stack underflow encountered!");
|
||||
} else {
|
||||
LOG_MSG("Unmasked Stack underflow!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
fpu.tags[TOP] = TAG_Empty;
|
||||
TOP = ((TOP+1)&7);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue