Notes on FPU stack faults (which only affects the 80387 and up, which isn't fully supported yet)
This commit is contained in:
parent
7a0147c122
commit
3bad5547c2
2 changed files with 14 additions and 2 deletions
|
|
@ -554,7 +554,7 @@ var X86 = {
|
||||||
OE: 0x0008, // bit 3: Overflow
|
OE: 0x0008, // bit 3: Overflow
|
||||||
UE: 0x0010, // bit 4: Underflow
|
UE: 0x0010, // bit 4: Underflow
|
||||||
PE: 0x0020, // bit 5: Precision
|
PE: 0x0020, // bit 5: Precision
|
||||||
SF: 0x0040, // bit 6: Stack Fault (80387 and later)
|
SF: 0x0040, // bit 6: Stack Fault (80387 and later; triggers an Invalid Operation exception)
|
||||||
EXC: 0x007F, // all of the above exceptions
|
EXC: 0x007F, // all of the above exceptions
|
||||||
ES: 0x0080, // bit 7: Error/Exception Status/Summary (Interrupt Request on 8087)
|
ES: 0x0080, // bit 7: Error/Exception Status/Summary (Interrupt Request on 8087)
|
||||||
C0: 0x0100, // bit 8: Condition Code 0
|
C0: 0x0100, // bit 8: Condition Code 0
|
||||||
|
|
|
||||||
|
|
@ -427,7 +427,16 @@ X86FPU.prototype.opUnimplemented = function()
|
||||||
X86FPU.prototype.checkException = function()
|
X86FPU.prototype.checkException = function()
|
||||||
{
|
{
|
||||||
this.regStatus &= ~X86.FPU.STATUS.ES;
|
this.regStatus &= ~X86.FPU.STATUS.ES;
|
||||||
if (this.regStatus & (~this.regControl & X86.FPU.STATUS.EXC)) {
|
/*
|
||||||
|
* NOTE: The "Stack Fault" (SF) status bit wasn't introduced until the 80387, so it triggers the pre-existing
|
||||||
|
* "Invalid Operation" (IE) exception; there is no corresponding "Stack Fault" (SE) exception, and the matching
|
||||||
|
* control bit is still reserved. Consequently, X86.FPU.CONTROL.EXC is a *subset* of X86.FPU.STATUS.EXC (0x3F
|
||||||
|
* instead of 0x7F).
|
||||||
|
*
|
||||||
|
* However, we shouldn't have to do anything special when SF is set, because any setException() call that sets
|
||||||
|
* SF should ALSO set IE.
|
||||||
|
*/
|
||||||
|
if (this.regStatus & (~this.regControl & X86.FPU.CONTROL.EXC)) {
|
||||||
this.regStatus |= X86.FPU.STATUS.ES; // set ES whenever one or more unmasked EXC bits are set
|
this.regStatus |= X86.FPU.STATUS.ES; // set ES whenever one or more unmasked EXC bits are set
|
||||||
}
|
}
|
||||||
if ((this.regStatus & X86.FPU.STATUS.ES) && !(this.regControl & X86.FPU.CONTROL.IEM)) {
|
if ((this.regStatus & X86.FPU.STATUS.ES) && !(this.regControl & X86.FPU.CONTROL.IEM)) {
|
||||||
|
|
@ -451,6 +460,9 @@ X86FPU.prototype.checkException = function()
|
||||||
* PE (0x0020 bit 5: Precision)
|
* PE (0x0020 bit 5: Precision)
|
||||||
* SF (0x0040 bit 6: Stack Fault; 80387 and later)
|
* SF (0x0040 bit 6: Stack Fault; 80387 and later)
|
||||||
*
|
*
|
||||||
|
* Also, as noted in checkException(), any time you set the SF bit, you should also set the IE bit, because
|
||||||
|
* Stack Fault is a subset of Invalid Operation. TODO: We should include a test for that in the assertion below.
|
||||||
|
*
|
||||||
* @this {X86FPU}
|
* @this {X86FPU}
|
||||||
* @param {number} n (one or more of the above error status bits)
|
* @param {number} n (one or more of the above error status bits)
|
||||||
* @return {boolean} (true if unmasked exception exists, false if not)
|
* @return {boolean} (true if unmasked exception exists, false if not)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue