Chapter …
Project #2:
Half Precision Arithmetic
IEEE Floating-Point Format
5-bit
10-bit
Half-Precision
23-bit
8-bit
Single-Precision
11-bit
32-bit (Fraction)
Double Precision
20-bit (Fraction)
Pseudo Half-Precision (PHP)
8-bit
0,[-14,15],255
10-bit
Pseudo Half –Precision (PHP)
(Extra bits used for rounding)
PHP is the same as single precision except for
At least 13 rightmost bits in the fraction are zeroed out
More bits are zeroed out in denorm numbers
The range of exponent for normal numbers is limited either 0, 255, or between -14 and 15
Both PHP and single precision number have identical special numbers .
In summary, PHP is simply a subset of single precision numbers which are all the numbers in half-precision
Why PHP (Pseudo Half Precision)?
Hold intermediate results during conversion from single precision to true half precision
Single precision arithmetic instructions can work on PHP numbers, not on true half precision numbers.
PHP is simply a subset of single precision numbers.
The 23 bits in fraction can hold intermediate results for rounding purpose
Can print PHP like single precision
li $v0, 2 # print both single precision and PHP
syscall
8-bit
0,[-14,15],255
10-bit
Pseudo Half –Precision (PHP)
(Extra bits used for rounding)
Single Precision PHP
23-bit
8-bit
Single–Precision X (input in $f12)
8-bit
0,[-14,15],255
10-bit
Pseudo Half–Precision Y (output in $f0)
(Extra bits used for rounding)
If X = infinity, NaN, then y=x
If |X| > 65504, then y = infinity
If |X| < 2-24, then , y = 0
If 2-24 |X| < 2-14, then y is denorm
y=x with fraction rounded to < 10 bits Otherwise,
y=x with fraction rounded to 10 bits
Function Call
jal cvt.php.s
Example: Single Precision PHP
cvt.php.s:
mfc1 $t0, $f12
# mark off 13 LSB bits
andi $t0, $$t0, 0xFFFFE000
mtc1 $t0, $f0
Jr $ra
1111 1111 11, 00 0000 0000 111
0111 1111
Single–Precision X (input in $f12)
0111 1111
1111 1111 11
Pseudo Half –Precision Y (output in $f0)
0000 0000 0000 0
X =1.1111 1111 11, 00000000000 111 20
(Round down)
Y =1.11111111111 0000000000000 20
Example: Single Precision PHP
1001 1111 11, 10 0000 0000 111
0111 1111
Single–Precision X (input in $f12)
0111 1111
1010 0000 00
Pseudo Half –Precision Y (output in $f0)
0000 0000 0000 0
X =1.1001 1111 11, 10 0000 0000 111 20
(Round up)
Y =1.1010 0000 00 0000000000000 20
cvt.php.s:
mfc1 $t0, $f12
# mark off 13 LSB bits
andi $t0, $$t0, 0xFFFFE000
addi $t0, 0x00002000
mtc1 $t0, $f0
Jr $ra
Example: Single Precision PHP
1111 1111 11, 10 0000 0000 111
1000 1111
Single–Precision X (input in $f12)
1111 1111
0000 0000 00
Pseudo Half–Precision (output in $f0)
0000 0000 0000 0
X =1.1111111111, 10000000000111 216
(> largest PHP 1.1111111111 215)
Y = Infinity
cvt.php.s: # infinity
l.s $f13, LARGEST
c.le.s $f12, $f13
bc1t normal
l.s $f0, infinity
Jr $ra
Normal:
# consider other cases
Example: Single Precision PHP
0011 1111 11, 10 0000 0000 111
1111 1111
Single–Precision X (input in $f12)
1111 1111
1111 1111 11
Pseudo Half–Precision (output in $f0)
0000 0000 0000 0
Y = NaN
cvt.php.s:
l.s $f13, LARGEST
c.gt.s $f12, $f13
bc1t else
Move.s $f0, $f12
Jr $ra
else:
# consider other cases
PHP Single Precision
There is no need to convert PHP to single precision numbers.
PHP numbers are simply a subset of single precision numbers.
Half-Precision (output in $v0)
Half Precision PHP
Y
5 bits
Z
10 bits
X
8 bits
W
10 bits
PHP (input in $f12)
(bits used for rounding)
Function Call
jal cvt.h.php
If X=255 Y=31 (infinity, NaN)
If |f12| 10-24 Y = Z = 0 (Zero)
If |f12| 10-14 (normal) Y=X-127 +15, Z = W
Otherwise (f12 is denorm) Y=0, Z= 1.W >> -(X-127+15)
Half-Precision (output in $v0)
Example: Half Precision PHP
Y
11111
Z
xxxx xxxx xx
X
1111 1111
W
xxxx xxxx xx
PHP (input in $f12)
(bits used for rounding)
Function Call
jal cvt.h.php
If X=255 Y=31 (infinity, NaN)
Half Precision PHP
Function Call
jal cvt.php.h
If X=31 Y= 255, Z=W (infinity, NaN)
If 0