COP1: Difference between revisions

1,890 bytes added ,  1 year ago
no edit summary
No edit summary
No edit summary
Line 119:
* Perform operation
* Set "Cause: Inexact"
* If "Enable: Inexact" is true, fire exception. Otherwise, set "Flag: Inexact" and put result value into destination register.
 
This means that Cause be looked at to see the result of the directly preceding instruction. Flags however are cumulative: They are true if any instruction since the last clear signaled that exception, assuming the exception was disabled.
Line 163:
|}
 
Knowing this, determining special cases and certain operations can be done by donethrough simple bit operations:
<code><pre>
fn is_zero(f: u32) -> bool { f & 0x7FFF_FFFF == 0 }
Line 172:
fn negate(f: u32) -> bool { f ^ 0x8000_0000 }
</pre></code>
 
== Special Cases ==
The COP1 will never on its own produce either a subnormal or a qNAN.
 
The following rules applies to calculating instructions (ADD.X, SUB.X, DIV.X, MUL.X, SQRT.X, ABS, NEG.X, CVT.Y.X, ROUND.Y.X, TRUNC.Y.X, FLOOR.Y.X, CEIL.Y.X, where X is S/D):
* If an input is sNAN, fire Unimplemented Operation
* If an input is subnormal, fire Unimplemented Operation
* If an input is qNAN, signal Invalid Operation and set result to sNAN (specifically 0x7FBFFFFF (for floats) or 0x7FF7FFFFFFFFFFFF (for doubles)) (exceptions: CVT.W.x and CVT.L.x also fire Unimplemented Operation as NAN can not be represented as an integer)
* Perform the operation
* If the operation underflowed, the following happens:
* If "Flush Denorm To Zero" is 1 AND "Enable: Underflow" is 0 AND "Enable: Inexact" is 0, the result is flushed and Underflow and Inexact are signaled. In most cases this means that it is set to 0 or "negative 0". (Two exception: If the rounding mode is "Ceil" and the result is positive, it will be set to the smallest positive value instead; similarly, "Floor" will set a negative result to the negative value that is closest to 0).
* Otherwise, fire Unimplemented Operations
* If the operation is invalid (for example: Infinity-Infinity, 0.0 / 0.0 or SQRT(-2)), set result to sNAN (specifically 0x7FBFFFFF (for floats) or 0x7FF7FFFFFFFFFFFF (for doubles)) and signal Invalid Operation is signaled.
* If the operation was a division by zero, signal division by zero
* If the operation overflowed, signal Overflow and Inexact and set result to Infinite or -Infinity
* If the operation was inexact, signal inexact
 
MOV.S and MOV.D are special: They just copy the bits and never fire or signal exceptions. They also don't clear the Cause bits.
 
== Comparisons ==
The COP1 has plenty of compare instructions
14

edits