Floating Point Unit¶
This chapter 1 describes the Floating Point Unit (FPU) emulated in EduMIPS64.
In the first paragraph we introduce the double format, the special floating point values defined in the IEEE 754 standard and the exceptions that floating point computations can raise.
In the second paragraph we explain how EduMIPS64 allows users to enable or disable the IEEE floating point traps.
In the third paragraph we describe how double precision numbers and special values can be specified in the source programs.
In the fourth paragraph, we introduce the FCSR register, used by the FPU to represent its state. It contains information about rounding, the boolean results of comparison operations and the policies for handling IEEE floating point exceptions.
In the fifth and last paragraph, we present all the MIPS64 floating point instructions that have been implemented in EduMIPS64.
Before starting the discussion about the FPU, we define the domain of floating point double precision numbers as [-1.79E308,-4.94E-324] ⋃ {0} ⋃ [4.94E-324,1.79E308].
- 1
This chapter is part of the Bachelor’s degree thesis by Massimo Trubia: “Progetto e implementazione di un modello di Floating Point Unit per un simulatore di CPU MIPS64”.
Special values¶
Floating point arithmetics allows the programmer to choose whether to stop the computation or not, if invalid operations are carried on. In this scenario, operations like the division between zeroes or square roots of negative numbers must produce a result that, not being a number (NaN) is treated as somehting different.
NaN or Invalid Operation¶
The IEEE Standard for Floating-Point Arithmetic (IEEE 754) defined that invalid arithmetic operations can either signal the error while the program is running (using a trap for the IEEE exception Invalid Operation) or return as a result the special value QNan (Quit Not a Number). Another NaN value, that inconditionally raises the same trap once it is detected as being one of the operands, is SNan (Signalling Not a Number). This value is seldom used in applications, and historically it has been used to initialize variables.
Zeroes or Underflows¶
Another special value defined by the standard is zero. Since the double format does not include the zero in its domain, it is considered a special value. There is a positive zero and a negative zero: the former is used when a representation of a negative number ∈ ]-4.94E-324,0[) is attempted, and a result is required (as opposed to allowing an Underflow trap), while the latter is used when the number that should be represented is ∈ [0,4.94E-324[, and the Underflow trap is disabled.
Infinites or Overflows¶
When a program attempts to represent a value with an extremely large absolute value (∈ ]-∞,-1.79E308[ ⋃ ]1.79E308,+∞[), that is outside the domain of double values, the CPU returns either -∞ or +∞. The alternative is to trigger a trap for the exceptional Overflow condition.
Infinites can also be returned in case of a division by zero; in that case the sign of the infinite is given by the product of the sign of the zero and the sign of the dividend. The Divide by zero trap can be alternatively raised.
Exception configuration¶
EduMIPS64 allows the user to enable or disable the traps for 4 of the 5 IEEE exceptions, through the FPU Exceptions tab in the Configure → Settings window. If any of them is disabled, the respective special value will be returned (as described in Special values).
The .double directive¶
The .double
directive must be used in the .data
section of source
files, and allows to allocate a memory cell for a double value.
The directive can be used in 2 ways:
variable-name: .double double_number
variable-name: .double keyword
where double_number
can be represented either in extended notation
(1.0,0.003
), or in scientific notation(3.7E-12,0.5E32
).
keyword
can be POSITIVEINFINITY
, NEGATIVEINFINITY
,
POSITIVEZERO
, NEGATIVEZERO
, SNAN
e QNAN
,
thus allowing to directly insert in memory the special values.
The FCSR register¶
The FCSR (Floating point Control Status Register) is the register that controls several functional aspects of the FPU. It is 32 bits long and it is represented in the statistics window.
The FCC field is 8 bits wide, from 0 to 7. The conditional instructions
(C.EQ.D,C.LT.D
) use it to save the boolean result of comparisons between
two registers.
The Cause, Enables and Flag fields handle the dynamics of IEEE exceptions described in Special values. Each of them is composed of 5 bits, V (Invalid Operation), Z (Divide by Zero), O (Overflow), U (Underflow) and I (Inexact); the latter is not yet used.
The Clause field bits are set if the corresponding IEEE exceptions occur during the execution of a program.
The Enable field bits are set through the configuration window and show the IEEE exceptions for which traps are enabled.
The Flag field shows the exceptions that have happened but, since the trap is not enabled for that particular exception, have returned special values (the ones described in Special values).
The RM field describes the rounding method currently in use to convert
floating point numbers to integers (see the description of the CVT.L.D
instruction).
Instruction set¶
This section describes the MIPS64 FPU instruction implemented by EduMIPS64;
they are listed in alphabetic order. The operations performed by the
instruction are described using a notation according to which the i-th
memory cell is represented as memory[i]
, and the FCC fields of the FCSR
register are FCSR_FCC[cc]
, cc
∈ [0,7].
In some instructions, to avoid ambiguity, the registers are represented as
GPR[i]
and FPR[i]
, i
∈ [0,31], but in most cases we just use the
rx
or fx
notation, with x
∈ {d,s,t}. The three letters are used to
indicate the purpose of each register (destination, source, third). Lastly,
the values returned by conversion operations are represented with the
following notation: convert_conversiontype(register[,rounding_type])
,
where the rounding_type
parameter is optional.
Some examples for the FPU instructions are available at
http://www.edumips.org/attachment/wiki/Upload/FPUMaxSamples.rar
.
ADD.D fd, fs, ft
Description:
fd = fs + ft
Exceptions: Overflow and underflow traps are generated if the result cannot be represented according to IEEE 754. Invalid operation is raised if fs or ft contain QNaN or SNan, or if an invalid operation (+∞ - ∞) is executed.
BC1F cc, offset
Description:
if FCSR_FCC[cc] == 0 then branch
If
FCSR_FCC[cc]
is false, do a PC-relative branch.Example:
C.EQ.D 7,f1,f2 BC1F 7,label
In this example,
C.EQ.D
checks iff1
andf2
are equal, writing the results of the comparison in the 7th bit of the FCC field of the FCSR register. After that,BC1F
jumps tolabel
if the result of the comparison is 0 (false).BC1T cc, offset
Description:
if FCSR_FCC[cc] == 1 then branch
If
FCSR_FCC[cc]
is true, do a PC-relative branch.Example:
C.EQ.D 7,f1,f2 BC1T 7,label
In this example,
C.EQ.D
checks iff1
andf2
are equal, writing the results of the comparison in the 7th bit of the FCC field of the FCSR register. After that,BC1F
jumps tolabel
if the result of the comparison is 1 (false).C.EQ.D cc, fs, ft
Description:
FCSR_FCC[cc] = (fs==ft)
Checks if
fs
is equal toft
, and saves the result of the comparison inFCSR_FCC[cc]
. See examples forBC1T
,BC1F
.Exceptions: Invalid Operation can be thrown if
fs
orft
contain QNaN (trap is triggered if it is enabled) o SNaN (trap is always triggered).C.LT.D cc, fs, ft
Description:
FCSR_FCC[cc] = (fs<ft)
Checks if
fs
is smaller thanft
, and saves the result of the comparison inFCSR_FCC[cc]
.Example:
C.LT.D 2,f1,f2 BC1T 2,target
In this example,
C.LT.D
checks iff1
is smaller thanf2
, and saves the result of the comparison in the second bit of the FCC field of the FCSR register. After that,BC1T
jumps totarget
if that bit is set to 1.Exceptions: Invalid Operation can be thrown if
fs
orft
contain QNaN (trap is triggered if it is enabled) o SNaN (trap is always triggered).CVT.D.L fd, fs
Description:
fd = convert_longToDouble(fs)
Converts a long to a double.
Example:
DMTC1 r6,f5 CVT.D.L f5,f5
In this example,
DMTC1
copies the value of GPR r6 to FPR f5; after thatCVT.D.L
converts the value stored in f5 from long to double. If for instance r6 contains the value 52, after the execution ofDMTC1
the binary representation of 52 gets copied to f5. After the execution ofCVT.D.L
, f5 contains the IEEE 754 representation of 52.0.Exceptions: Invalid Operation is thrown if fs contains QNaN, SNaN or an infinite.
CVT.D.W fd, fs
Description:
fd = convert_IntToDouble(fs)
Converts an int to a double.
Example:
MTC1 r6,f5 CVT.D.W f5,f5
In this example,
MTC1
copies the lower 32 bit of the GPR r6 into the FPR f5. Then,CVT.D.W
, reads f5 as an int, and converts it to double.If we had
r6=0xAAAAAAAABBBBBBBB
, after the execution ofMTC1
we getf5=0xXXXXXXXXBBBBBBBB
; its upper 32 bits (XX..X
) are now UNDEFINED (haven’t been overwritten).CVT.D.W
interprets f5 as an int (f5=-1145324613
), and converts it to double(f5=0xC1D1111111400000 =-1.145324613E9
).Exceptions: Invalid Operation is thrown if fs contains QNaN, SNaN or an infinite.
CVT.L.D fd, fs
Description:
fd = convert_doubleToLong(fs, CurrentRoundingMode)
Converts a double to a long, rounding it before the conversion.
Example:
CVT.L.D f5,f5 DMFC1 r6,f5
CVT.L.D
the double value in f5 to a long; thenDMFC1
copies f5 to r6; the result of this operation depends on the current rounding modality, that can be set in the FPU Rounding tab of the Configure → Settings window.
Tipo |
RM field |
f5 register |
r6 register |
---|---|---|---|
To nearest |
0 |
6.4 |
6 |
To nearest |
0 |
6.8 |
7 |
To nearest |
0 |
6.5 |
6 (to even) |
To nearest |
0 |
7.5 |
8 (to even) |
Towards 0 |
1 |
7.1 |
7 |
Towards 0 |
1 |
-2.3 |
-2 |
Towards ∞ |
2 |
4.2 |
5 |
Towards ∞ |
2 |
-3.9 |
-3 |
Towards -∞ |
3 |
4.2 |
4 |
Towards -∞ |
3 |
-3.9 |
-4 |
CVT.W.D fd, fs
Description:
fd = convert_DoubleToInt(fs, CurrentRoundingMode)
Converts a double to an int, using the current rounding modality.
Exceptions: Invalid Operation is thrown if fs contains an infinite value, any NaN or the results is outside the signed int domain [-2 63, 2 63 -1]
DIV.D fd, fs, ft
Description:
fd = fs \div ft
Exceptions: Overflow or Underflow are raised if the results cannot be represented using the IEEE 754 standard. Invalid Operation is raised if fs or ft contain QNaN or SNan, or if an invalid operation is executed (0div0,∞ div ∞). Divide by zero is raised if a division by zero is attempted with a dividend that is not QNaN or SNaN.
DMFC1 rt,fs
Description:
rt = fs
Executes a bit per bit copy of the FPR fs into the GPR rt.
DMTC1 rt, fs
Description:
fs = rt
Executes a bit per bit copy of the GPR rt into the FPR fs.
L.D ft, offset(base)
Description:
ft = memory[GPR[base] + offset]
Loads from memory a doubleword and stores it in ft.
Note
L.D is not present in the MIPS64 ISA, it is an alias for LDC1
that is present in EduMIPS64 for compatibility with WinMIPS64.
LDC1 ft, offset(base)
Description:
memory[GPR[base] + offset]
Loads from memory a doubleword and stores it in ft.
LWC1 ft, offset(base)
Description:
ft = memory[GPR[base] + offset]
Loads from memory a word and stores it in ft.
MFC1 rt, fs
Description:
rt = readInt(fs)
Reads the fs FPR as an int and writes its value to the rt GPR as long. Example:
MFC1 r6,f5 SD r6,mem(R0)
Let
f5=0xAAAAAAAABBBBBBBB
;MFC1
reads f5 as an int (lower 32 bits), interpretingBBBBBBBB
as-1145324613
, and writes the value to f6 (64 bits). After the execution ofMFC1
,r6=0xFFFFFFFFBBBBBBBB = -1145324613
. So theSD
instruction will write to memory a doubleword with this value, since the sign in r6 was extended.MOVF.D fd, fs, cc
Description:
if FCSR_FCC[cc] == 0 then fd=fs
If FCSR_FCC[cc] is false, the copies fs to fd.
MOVT.D fd, fs, cc
Description:
if FCSR_FCC[cc] == 1 then fd=fs
If FCSR_FCC[cc] is true, the copies fs to fd.
MOV.D fd, fs
Description:
fd = fs
Copies fs to fd.
MOVN.D fd, fs, rt
Description:
if rt != 0 then fd=fs
If rt is not zero, copies fs to fd.
MOVZ.D fd, fs, rt
Description:
if rt == 0 then fd=fs
If rt is equal to zero, copies fs to fd.
MTC1 rt, fs
Description: fs = rt 0..31
Copies the lower 32 bit of rt to fs.
Example:
MTC1 r6,f5
Let
r5=0xAAAAAAAABBBBBBBB
;MTC1
reads the lower 32 bits of r5 copying them to the 32 lower bits of f5. The higher 32 bits of f5 are not overwritten.MUL.D fd, fs, ft
Description:
fd = fs × ft
Exceptions: Overflow or Underflow are raised if the results cannot be represented using the IEEE 754 standard. Invalid Operation is raised if fs or ft contain QNaN or SNan, or if an invalid operation is executed (multiply by ∞ OR BY QNaN).
S.D ft, offset(base)
Description:
memory[base+offset] = ft
Copies ft to memory.
Note
S.D is not present in the MIPS64 ISA, it is an alias for SDC1
that is present in EduMIPS64 for compatibility with WinMIPS64.
SDC1 ft, offset(base)
Description:
memory[base+offset] = ft
Copies ft to memory.
SUB.D fd, fs, ft
Description:
fd = fs-ft
Exceptions: Overflow and underflow traps are generated if the result cannot be represented according to IEEE 753. Invalid operation is raised if fs or ft contain QNaN or SNan, or if an invalid operation (+∞ - ∞) is executed.
SWC1 ft, offset(base)
Description:
memory[base+offset] = ft
Copies the lower 32 bits of ft to memory.