Added English Language description for stdu instruction
[openpower-isa.git] / openpower / isafunctions / bfp.mdwn
1 # binary-floating-point helper functions
2
3 `bfp_*` and related functions as needed by c[ft]fpr* from PowerISA v3.1B Book I
4 section 7.6.2.2
5
6 def reset_xflags():
7 vxsnan_flag <- 0
8 vximz_flag <- 0
9 vxidi_flag <- 0
10 vxisi_flag <- 0
11 vxzdz_flag <- 0
12 vxsqrt_flag <- 0
13 vxcvi_flag <- 0
14 vxvc_flag <- 0
15 ox_flag <- 0
16 ux_flag <- 0
17 xx_flag <- 0
18 zx_flag <- 0
19
20 def bfp_CONVERT_FROM_BFP64(x):
21 # x is a binary floating-point value represented in
22 # double-precision format.
23 exponent <- x[1:11]
24 fraction <- x[12:63]
25
26 result <- BFPState()
27 result.sign <- 0
28 result.exponent <- 0
29 result.significand <- 0
30 result.class.SNaN <- 0
31 result.class.QNaN <- 0
32 result.class.Infinity <- 0
33 result.class.Zero <- 0
34 result.class.Denormal <- 0
35 result.class.Normal <- 0
36 if (exponent = 2047) & (fraction[0] = 0) & (fraction != 0) then
37 # x is a SNaN
38 result.class.SNaN <- 1
39 result.sign <- x[0]
40 result.significand[0] <- 0
41 result.significand[1:52] <- fraction
42 else if (exponent = 2047) & (fraction[0] != 0) & (fraction != 0) then
43 # x is a QNaN
44 result.class.QNaN <- 1
45 result.sign <- x[0]
46 result.significand[0] <- 0
47 result.significand[1:52] <- fraction
48 else if (exponent = 2047) & (fraction = 0) then
49 # is an Infinity
50 result.class.Infinity <- 1
51 result.sign <- x[0]
52 else if (exponent = 0) & (fraction = 0) then
53 # x is a Zero
54 result.class.Zero <- 1
55 result.sign <- x[0]
56 else if (exponent = 0) & (fraction != 0) then
57 # x is a Denormal
58 result.class.Denormal <- 1
59 result.sign <- x[0]
60 result.exponent <- -1022
61 result.significand[0] <- 0
62 result.significand[1:52] <- fraction
63 do while result.significand[0] != 1
64 result.significand <- result.significand * 2
65 result.exponent <- result.exponent - 1
66 else
67 result.class.Normal <- 1
68 result.sign <- x[0]
69 result.exponent <- exponent
70 # have to do the subtraction separately since SelectableInt won't
71 # give negative results
72 result.exponent <- result.exponent - 1023
73 result.significand[0] <- 1
74 result.significand[1:52] <- fraction
75 return result
76
77 def bfp_CONVERT_FROM_BFP32(x):
78 # x is a floating-point value represented in single-precision format.
79 exponent <- x[1:8]
80 fraction <- x[9:31]
81
82 result <- BFPState()
83 result.sign <- 0
84 result.exponent <- 0
85 result.significand <- 0
86 result.class.SNaN <- 0
87 result.class.QNaN <- 0
88 result.class.Infinity <- 0
89 result.class.Zero <- 0
90 result.class.Denormal <- 0
91 result.class.Normal <- 0
92 if (exponent = 255) & (fraction[0] = 0) & (fraction != 0) then
93 # x is a SNaN
94 result.class.SNaN <- 1
95 result.sign <- x[0]
96 result.significand[0] <- 0
97 result.significand[1:23] <- fraction
98 else if (exponent = 255) & (fraction[0] != 0) & (fraction != 0) then
99 # x is a QNaN
100 result.class.QNaN <- 1
101 result.sign <- x[0]
102 result.significand[0] <- 0
103 result.significand[1:23] <- fraction
104 else if (exponent = 255) & (fraction = 0) then
105 # is an Infinity
106 result.class.Infinity <- 1
107 result.sign <- x[0]
108 else if (exponent = 0) & (fraction = 0) then
109 # x is a Zero
110 result.class.Zero <- 1
111 result.sign <- x[0]
112 else if (exponent = 0) & (fraction != 0) then
113 # x is a Denormal
114 result.class.Denormal <- 1
115 result.sign <- x[0]
116 result.exponent <- -126
117 result.significand[0] <- 0
118 result.significand[1:23] <- fraction
119 do while result.significand[0] != 1
120 result.significand <- result.significand * 2
121 result.exponent <- result.exponent - 1
122 else
123 result.class.Normal <- 1
124 result.sign <- x[0]
125 result.exponent <- exponent
126 # have to do the subtraction separately since SelectableInt won't
127 # give negative results
128 result.exponent <- result.exponent - 127
129 result.significand[0] <- 1
130 result.significand[1:23] <- fraction
131 return result
132
133 def bfp_CONVERT_FROM_SI32(x):
134 # x is an integer value represented in signed word integer format.
135
136 result <- BFPState()
137 result.sign <- 0
138 result.exponent <- 0
139 result.significand <- 0
140 result.class.SNaN <- 0
141 result.class.QNaN <- 0
142 result.class.Infinity <- 0
143 result.class.Zero <- 0
144 result.class.Denormal <- 0
145 result.class.Normal <- 0
146
147 if x = 0x0000_0000 then
148 result.class.Zero <- 1
149 else
150 result.class.Normal <- 1
151 result.sign <- x[0]
152 result.exponent <- 32
153 result.significand[0:32] <- EXTS(x)
154
155 if result.significand[0] = 1 then
156 result.sign <- 1
157 result.significand[0:32] <- -result.significand[0:32]
158 do while result.significand[0] = 0
159 result.significand <- result.significand * 2
160 result.exponent <- result.exponent - 1
161 return result
162
163 def bfp_CONVERT_FROM_SI64(x):
164 # x is an integer value represented in signed double-word integer
165 # format.
166
167 result <- BFPState()
168 result.sign <- 0
169 result.exponent <- 0
170 result.significand <- 0
171 result.class.SNaN <- 0
172 result.class.QNaN <- 0
173 result.class.Infinity <- 0
174 result.class.Zero <- 0
175 result.class.Denormal <- 0
176 result.class.Normal <- 0
177
178 if x = 0x0000_0000_0000_0000 then
179 result.class.Zero <- 1
180 else
181 result.class.Normal <- 1
182 result.sign <- x[0]
183 result.exponent <- 64
184 result.significand[0:64] <- EXTS(x)
185
186 if result.significand[0] = 1 then
187 result.sign <- 1
188 result.significand[0:64] <- -result.significand[0:64]
189 do while result.significand[0] = 0
190 result.significand <- result.significand * 2
191 result.exponent <- result.exponent - 1
192 return result
193
194 def bfp_CONVERT_FROM_SI128(x):
195 # x is a 128-bit signed integer value.
196
197 result <- BFPState()
198 result.sign <- 0
199 result.exponent <- 0
200 result.significand <- 0
201 result.class.SNaN <- 0
202 result.class.QNaN <- 0
203 result.class.Infinity <- 0
204 result.class.Zero <- 0
205 result.class.Denormal <- 0
206 result.class.Normal <- 0
207
208 if x = 0x0000_0000_0000_0000_0000_0000_0000_0000 then
209 result.class.Zero <- 1
210 else
211 result.class.Normal <- 1
212 result.sign <- x[0]
213 result.exponent <- 128
214 result.significand[0:128] <- EXTS(x)
215
216 if result.significand[0] = 1 then
217 result.sign <- 1
218 result.significand[0:128] <- -result.significand[0:128]
219 do while result.significand[0] = 0
220 result.significand <- result.significand * 2
221 result.exponent <- result.exponent - 1
222 return result
223
224 def bfp_CONVERT_FROM_UI32(x):
225 # x is an integer value represented in unsigned word integer
226 # format.
227
228 result <- BFPState()
229 result.sign <- 0
230 result.exponent <- 0
231 result.significand <- 0
232 result.class.SNaN <- 0
233 result.class.QNaN <- 0
234 result.class.Infinity <- 0
235 result.class.Zero <- 0
236 result.class.Denormal <- 0
237 result.class.Normal <- 0
238
239 if x = 0x0000_0000 then
240 result.class.Zero <- 1
241 else
242 result.class.Normal <- 1
243 result.sign <- 0
244 result.exponent <- 32
245 result.significand[0:32] <- 0b0 || x
246 do while result.significand[0] = 0
247 result.significand <- result.significand * 2
248 result.exponent <- result.exponent - 1
249 return result
250
251 def bfp_CONVERT_FROM_UI64(x):
252 # x is an integer value represented in unsigned double-word integer
253 # format.
254
255 result <- BFPState()
256 result.sign <- 0
257 result.exponent <- 0
258 result.significand <- 0
259 result.class.SNaN <- 0
260 result.class.QNaN <- 0
261 result.class.Infinity <- 0
262 result.class.Zero <- 0
263 result.class.Denormal <- 0
264 result.class.Normal <- 0
265
266 if x = 0x0000_0000_0000_0000 then
267 result.class.Zero <- 1
268 else
269 result.class.Normal <- 1
270 result.sign <- 0
271 result.exponent <- 64
272 result.significand[0:64] <- 0b0 || x
273 do while result.significand[0] = 0
274 result.significand <- result.significand * 2
275 result.exponent <- result.exponent - 1
276 return result
277
278 def bfp_CONVERT_FROM_UI128(x):
279 # x is a 128-bit unsigned integer value.
280
281 result <- BFPState()
282 result.sign <- 0
283 result.exponent <- 0
284 result.significand <- 0
285 result.class.SNaN <- 0
286 result.class.QNaN <- 0
287 result.class.Infinity <- 0
288 result.class.Zero <- 0
289 result.class.Denormal <- 0
290 result.class.Normal <- 0
291
292 if x = 0x0000_0000_0000_0000_0000_0000_0000_0000 then
293 result.class.Zero <- 1
294 else
295 result.class.Normal <- 1
296 result.sign <- 0
297 result.exponent <- 128
298 result.significand[0:128] <- 0b0 || x
299 do while result.significand[0] = 0
300 result.significand <- result.significand * 2
301 result.exponent <- result.exponent - 1
302 return result
303
304 def bfp_ROUND_TO_INTEGER(rmode, x):
305 # x is a binary floating-point value that is represented in the
306 # binary floating-point working format and has
307 # unbounded exponent range and significand precision.
308
309 if IsSNaN(x) then vxsnan_flag <- 1
310 if IsNaN(x) & ¬IsSNaN(x) then return x
311 if IsSNaN(x) then
312 result <- x
313 result.class.SNaN <- 0
314 result.class.QNaN <- 1
315 return result
316 if IsInf(x) | IsZero(x) then return x
317 result <- x
318 result.class.Denormal <- 0
319 result.class.Normal <- 0
320 exact <- 0b0
321 halfway <- 0b0
322 more_than_halfway <- 0b0
323 even <- 0b0
324 if result.exponent < -1 then
325 # all values have magnitude < 0.5
326 result.significand <- 0
327 result.exponent <- 0
328 even <- 0b1
329 else if result.exponent = -1 then
330 if result.significand[0] = 1 then
331 result.significand[0] <- 0
332 if result.significand = 0 then halfway <- 0b1
333 else more_than_halfway <- 0b1
334 result.significand <- 0
335 result.exponent <- 0
336 even <- 0b1
337 else
338 result.significand <- 0
339 int_part <- x.significand[0:x.exponent]
340 result.significand[0:x.exponent] <- int_part
341 even <- ¬int_part[x.exponent]
342 temp <- x.significand
343 temp[0:x.exponent] <- 0
344 if temp = 0 then exact <- 0b1
345 if temp[x.exponent + 1] = 1 then
346 temp[x.exponent + 1] <- 0
347 if temp = 0 then halfway <- 0b1
348 else more_than_halfway <- 0b1
349 if rmode = 0b000 then # Round to Nearest Even
350 round_up <- (¬even & halfway) | more_than_halfway
351 if rmode = 0b001 then # Round towards Zero
352 round_up <- 0b0
353 if rmode = 0b010 then # Round towards +Infinity
354 round_up <- (x.sign = 0) & ¬exact
355 if rmode = 0b011 then # Round towards -Infinity
356 round_up <- (x.sign = 1) & ¬exact
357 if rmode = 0b100 then # Round to Nearest Away
358 round_up <- halfway | more_than_halfway
359 if round_up then
360 inc_flag <- 1
361 temp <- BFPState()
362 temp.significand <- 0
363 temp.significand[result.exponent] <- 1
364 result.significand <- result.significand + temp.significand
365 if result.significand >= 2 then
366 result.significand <- truediv(result.significand, 2)
367 result.exponent <- result.exponent + 1
368 else inc_flag <- 0 # TODO: does the spec specify this?
369 if result.significand = 0 then result.class.Zero <- 1
370 else result.class.Normal <- 1
371 if ¬bfp_COMPARE_EQ(result, x) then xx_flag <- 1
372 else xx_flag <- 0 # TODO: does the spec specify this?
373 return result
374
375 def bfp_ROUND_TO_INTEGER_NEAR_EVEN(x):
376 return bfp_ROUND_TO_INTEGER(0b000, x)
377
378 def bfp_ROUND_TO_INTEGER_TRUNC(x):
379 return bfp_ROUND_TO_INTEGER(0b001, x)
380
381 def bfp_ROUND_TO_INTEGER_CEIL(x):
382 return bfp_ROUND_TO_INTEGER(0b010, x)
383
384 def bfp_ROUND_TO_INTEGER_FLOOR(x):
385 return bfp_ROUND_TO_INTEGER(0b011, x)
386
387 def bfp_ROUND_TO_INTEGER_NEAR_AWAY(x):
388 return bfp_ROUND_TO_INTEGER(0b100, x)
389
390 def bfp_COMPARE_EQ(x, y):
391 # x is a binary floating-point value represented in the
392 # binary floating-point working format.
393 # y is a binary floating-point value represented in the
394 # binary floating-point working format.
395
396 if IsNaN(x) | IsNaN(y) then
397 return 0b0
398 if IsZero(x) & IsZero(y) then
399 return 0b1
400
401 if IsInf(x) & IsInf(y) then
402 return x.sign = y.sign
403 if IsInf(x) | IsInf(y) then
404 return 0b0
405 if IsZero(x) | IsZero(y) then
406 return 0b0
407 if x.sign != y.sign then
408 return 0b0
409 if x.exponent > 0 then xs <- x.significand * pow(2, x.exponent)
410 else xs <- truediv(x.significand, pow(2, -x.exponent))
411 if y.exponent > 0 then ys <- y.significand * pow(2, y.exponent)
412 else ys <- truediv(y.significand, pow(2, -y.exponent))
413 return xs = ys
414
415 def bfp_COMPARE_GT(x, y):
416 # x is a binary floating-point value represented in the
417 # binary floating-point working format.
418 # y is a binary floating-point value represented in the
419 # binary floating-point working format.
420
421 if IsNaN(x) | IsNaN(y) then
422 return 0b0
423 if IsZero(x) & IsZero(y) then
424 return 0b0
425
426 if IsInf(x) & IsInf(y) then
427 return ¬IsNeg(x) & IsNeg(y)
428 if IsInf(x) then
429 return ¬IsNeg(x)
430 if IsInf(y) then
431 return IsNeg(y)
432 if IsZero(x) then
433 return IsNeg(y)
434 if IsZero(y) then
435 return ¬IsNeg(x)
436 if x.sign != y.sign then
437 return IsNeg(y)
438 if x.exponent > 0 then xs <- x.significand * pow(2, x.exponent)
439 else xs <- truediv(x.significand, pow(2, -x.exponent))
440 if y.exponent > 0 then ys <- y.significand * pow(2, y.exponent)
441 else ys <- truediv(y.significand, pow(2, -y.exponent))
442 if x.sign = 1 then return xs < ys
443 return xs > ys
444
445 def bfp_COMPARE_LT(x, y):
446 # x is a binary floating-point value represented in the
447 # binary floating-point working format.
448 # y is a binary floating-point value represented in the
449 # binary floating-point working format.
450
451 if IsNaN(x) | IsNaN(y) then
452 return 0b0
453 if IsZero(x) & IsZero(y) then
454 return 0b0
455
456 if IsInf(x) & IsInf(y) then
457 return IsNeg(x) & ¬IsNeg(y)
458 if IsInf(x) then
459 return IsNeg(x)
460 if IsInf(y) then
461 return ¬IsNeg(y)
462 if IsZero(x) then
463 return ¬IsNeg(y)
464 if IsZero(y) then
465 return IsNeg(x)
466 if x.sign != y.sign then
467 return IsNeg(x)
468 if x.exponent > 0 then xs <- x.significand * pow(2, x.exponent)
469 else xs <- truediv(x.significand, pow(2, -x.exponent))
470 if y.exponent > 0 then ys <- y.significand * pow(2, y.exponent)
471 else ys <- truediv(y.significand, pow(2, -y.exponent))
472 if x.sign = 1 then return xs > ys
473 return xs < ys
474
475 def bfp_ABSOLUTE(x):
476 # x is a binary floating-point value represented in the
477 # binary floating-point working format.
478 result <- x
479 result.sign <- 0
480 return result
481
482 def si32_CONVERT_FROM_BFP(x):
483 # x is an integer value represented in the
484 # binary floating-point working format.
485
486 if IsNaN(x) then
487 vxcvi_flag <- 1
488 if IsSNaN(x) then vxsnan_flag <- 1
489 return 0x8000_0000
490 else
491 temp_xx <- xx_flag
492 temp_inc <- inc_flag
493 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(x)
494 # TODO: does the spec say these are preserved?
495 xx_flag <- temp_xx
496 inc_flag <- temp_inc
497 exponent <- rnd.exponent
498 significand <- rnd.significand
499 si32max <- bfp_CONVERT_FROM_SI32(0b0 || [1] * 31)
500 si32min <- bfp_CONVERT_FROM_SI32(0b1 || [0] * 31)
501 if bfp_COMPARE_GT(rnd, si32max) then
502 vxcvi_flag <- 1
503 return 0x7FFF_FFFF
504 if bfp_COMPARE_LT(rnd, si32min) then
505 vxcvi_flag <- 1
506 return 0x8000_0000
507 else
508 if ¬bfp_COMPARE_EQ(rnd, x) then xx_flag <- 1
509 else xx_flag <- 0 # TODO: does the spec specify this?
510 inc_flag <- 0
511 # TODO: spec says this is logical shift right:
512 significand <- significand[0:31] / pow(2, 31 - exponent)
513 if IsNeg(rnd) then significand <- -significand
514 return significand[0:31]
515
516 def si64_CONVERT_FROM_BFP(x):
517 # x is an integer value represented in the
518 # binary floating-point working format.
519
520 if IsNaN(x) then
521 vxcvi_flag <- 1
522 if IsSNaN(x) then vxsnan_flag <- 1
523 return 0x8000_0000_0000_0000
524 else
525 temp_xx <- xx_flag
526 temp_inc <- inc_flag
527 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(x)
528 # TODO: does the spec say these are preserved?
529 xx_flag <- temp_xx
530 inc_flag <- temp_inc
531 exponent <- rnd.exponent
532 significand <- rnd.significand
533 si64max <- bfp_CONVERT_FROM_SI64(0b0 || [1] * 63)
534 si64min <- bfp_CONVERT_FROM_SI64(0b1 || [0] * 63)
535 if bfp_COMPARE_GT(rnd, si64max) then
536 vxcvi_flag <- 1
537 return 0x7FFF_FFFF_FFFF_FFFF
538 if bfp_COMPARE_LT(rnd, si64min) then
539 vxcvi_flag <- 1
540 return 0x8000_0000_0000_0000
541 else
542 if ¬bfp_COMPARE_EQ(rnd, x) then xx_flag <- 1
543 else xx_flag <- 0 # TODO: does the spec specify this?
544 inc_flag <- 0
545 # TODO: spec says this is logical shift right:
546 significand <- significand[0:63] / pow(2, 63 - exponent)
547 if IsNeg(rnd) then significand <- -significand
548 return significand[0:63]
549
550 def si128_CONVERT_FROM_BFP(x):
551 # x is an integer value represented in the
552 # binary floating-point working format.
553
554 if IsNaN(x) then
555 vxcvi_flag <- 1
556 if IsSNaN(x) then vxsnan_flag <- 1
557 return 0x8000_0000_0000_0000_0000_0000_0000_0000
558 else
559 temp_xx <- xx_flag
560 temp_inc <- inc_flag
561 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(x)
562 # TODO: does the spec say these are preserved?
563 xx_flag <- temp_xx
564 inc_flag <- temp_inc
565 exponent <- rnd.exponent
566 significand <- rnd.significand
567 si128max <- bfp_CONVERT_FROM_SI128(0b0 || [1] * 127)
568 si128min <- bfp_CONVERT_FROM_SI128(0b1 || [0] * 127)
569 if bfp_COMPARE_GT(rnd, si128max) then
570 vxcvi_flag <- 1
571 return 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF
572 if bfp_COMPARE_LT(rnd, si128min) then
573 vxcvi_flag <- 1
574 return 0x8000_0000_0000_0000_0000_0000_0000_0000
575 else
576 if ¬bfp_COMPARE_EQ(rnd, x) then xx_flag <- 1
577 else xx_flag <- 0 # TODO: does the spec specify this?
578 inc_flag <- 0
579 # TODO: spec says this is logical shift right:
580 significand <- significand[0:127] / pow(2, 127 - exponent)
581 if IsNeg(rnd) then significand <- -significand
582 return significand[0:127]
583
584 def ui32_CONVERT_FROM_BFP(x):
585 # x is an integer value represented in the
586 # binary floating-point working format.
587
588 if IsNaN(x) then
589 vxcvi_flag <- 1
590 if IsSNaN(x) then vxsnan_flag <- 1
591 return 0x0000_0000
592 else
593 temp_xx <- xx_flag
594 temp_inc <- inc_flag
595 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(x)
596 # TODO: does the spec say these are preserved?
597 xx_flag <- temp_xx
598 inc_flag <- temp_inc
599 exponent <- rnd.exponent
600 significand <- rnd.significand
601 ui32max <- bfp_CONVERT_FROM_UI32([1] * 32)
602 if bfp_COMPARE_GT(rnd, ui32max) then
603 vxcvi_flag <- 1
604 return 0xFFFF_FFFF
605 if IsNeg(rnd) then
606 vxcvi_flag <- 1
607 return 0x0000_0000
608 else
609 if ¬bfp_COMPARE_EQ(rnd, x) then xx_flag <- 1
610 else xx_flag <- 0 # TODO: does the spec specify this?
611 inc_flag <- 0
612 # TODO: spec says this is logical shift right:
613 significand <- significand[0:31] / pow(2, 31 - exponent)
614 return significand[0:31]
615
616 def ui64_CONVERT_FROM_BFP(x):
617 # x is an integer value represented in the
618 # binary floating-point working format.
619
620 if IsNaN(x) then
621 vxcvi_flag <- 1
622 if IsSNaN(x) then vxsnan_flag <- 1
623 return 0x0000_0000_0000_0000
624 else
625 temp_xx <- xx_flag
626 temp_inc <- inc_flag
627 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(x)
628 # TODO: does the spec say these are preserved?
629 xx_flag <- temp_xx
630 inc_flag <- temp_inc
631 exponent <- rnd.exponent
632 significand <- rnd.significand
633 ui64max <- bfp_CONVERT_FROM_UI64([1] * 64)
634 if bfp_COMPARE_GT(rnd, ui64max) then
635 vxcvi_flag <- 1
636 return 0xFFFF_FFFF_FFFF_FFFF
637 if IsNeg(rnd) then
638 vxcvi_flag <- 1
639 return 0x0000_0000_0000_0000
640 else
641 if ¬bfp_COMPARE_EQ(rnd, x) then xx_flag <- 1
642 else xx_flag <- 0 # TODO: does the spec specify this?
643 inc_flag <- 0
644 # TODO: spec says this is logical shift right:
645 significand <- significand[0:63] / pow(2, 63 - exponent)
646 return significand[0:63]
647
648 def ui128_CONVERT_FROM_BFP(x):
649 # x is an integer value represented in the
650 # binary floating-point working format.
651
652 if IsNaN(x) then
653 vxcvi_flag <- 1
654 if IsSNaN(x) then vxsnan_flag <- 1
655 return 0x0000_0000_0000_0000_0000_0000_0000_0000
656 else
657 temp_xx <- xx_flag
658 temp_inc <- inc_flag
659 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(x)
660 # TODO: does the spec say these are preserved?
661 xx_flag <- temp_xx
662 inc_flag <- temp_inc
663 exponent <- rnd.exponent
664 significand <- rnd.significand
665 ui128max <- bfp_CONVERT_FROM_UI128([1] * 128)
666 if bfp_COMPARE_GT(rnd, ui128max) then
667 vxcvi_flag <- 1
668 return 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF
669 if IsNeg(rnd) then
670 vxcvi_flag <- 1
671 return 0x0000_0000_0000_0000_0000_0000_0000_0000
672 else
673 if ¬bfp_COMPARE_EQ(rnd, x) then xx_flag <- 1
674 else xx_flag <- 0 # TODO: does the spec specify this?
675 inc_flag <- 0
676 # TODO: spec says this is logical shift right:
677 significand <- significand[0:127] / pow(2, 127 - exponent)
678 return significand[0:127]
679
680 def bfp64_CONVERT_FROM_BFP(x):
681 # x is a floating-point value represented in the binary floating-point
682 # working format.
683
684 result <- [0] * 64
685 if x.class.QNaN = 1 then
686 result[0] <- x.sign
687 result[1:11] <- 0b111_1111_1111
688 result[12:63] <- x.significand[1:52]
689 else if x.class.Infinity = 1 then
690 result[0] <- x.sign
691 result[1:11] <- 0b111_1111_1111
692 result[12:63] <- 0
693 else if x.class.Zero = 1 then
694 result[0] <- x.sign
695 result[1:63] <- 0
696 else if (x.exponent < -1022) & (FPSCR.UE = 0) then
697 result[0] <- x.sign
698 sh_cnt <- -1022 - x.exponent
699 result[1:11] <- 0b000_0000_0000
700 # TODO: spec says this is shift right
701 result[12:63] <- x.significand[1:52] / pow(2, sh_cnt)
702 else if (x.exponent < -1022) & (FPSCR.UE = 1) then
703 result[0:63] <- undefined(0) # TODO: which undefined value to use?
704 else if (x.exponent > 1023) & (FPSCR.OE = 1) then
705 result[0:63] <- undefined(0) # TODO: which undefined value to use?
706 else
707 result[0] <- x.sign
708 result[1:11] <- x.exponent + 1023
709 result[12:63] <- x.significand[1:52]
710 return result
711
712 def bfp32_CONVERT_FROM_BFP(x):
713 # x is a floating-point value represented in the binary floating-point
714 # working format.
715
716 result <- [0] * 32
717 if x.class.QNaN = 1 then
718 result[0] <- x.sign
719 result[1:8] <- 0b1111_1111
720 result[9:31] <- x.significand[1:23]
721 else if x.class.Infinity = 1 then
722 result[0] <- x.sign
723 result[1:9] <- 0b1111_1111
724 result[9:31] <- 0
725 else if x.class.Zero = 1 then
726 result[0] <- x.sign
727 result[1:31] <- 0
728 else if (x.exponent < -126) & (FPSCR.UE = 0) then
729 result[0] <- x.sign
730 sh_cnt <- -126 - x.exponent
731 result[1:8] <- 0b0000_0000
732 # TODO: spec says this is shift right
733 result[9:31] <- x.significand[1:23] / pow(2, sh_cnt)
734 else if (x.exponent < -126) & (FPSCR.UE = 1) then
735 result[0:31] <- undefined(0) # TODO: which undefined value to use?
736 else if (x.exponent > 127) & (FPSCR.OE = 1) then
737 result[0:31] <- undefined(0) # TODO: which undefined value to use?
738 else
739 result[0] <- x.sign
740 result[1:8] <- x.exponent + 127
741 result[9:31] <- x.significand[1:23]
742 return result
743
744 def bfp_ROUND_TO_BFP64(ro, rmode, x):
745 # x is a normalized binary floating-point value that is represented in
746 # the binary floating-point working format and has unbounded exponent
747 # range and significand precision.
748 # ro is a 1-bit unsigned integer and rmode is a 2-bit unsigned integer,
749 # together specifying one of five rounding modes to be used in
750 # rounding x.
751 #
752 # ro=0 rmode=0b00 Round to Nearest Even
753 # ro=0 rmode=0b01 Round towards Zero
754 # ro=0 rmode=0b10 Round towards +Infinity
755 # ro=0 rmode=0b11 Round towards -Infinity
756 # ro=1 Round to Odd
757 #
758 # Return the value x rounded to double-precision under control of the
759 # specified rounding mode.
760
761 if x.class.QNaN then return x
762 if x.class.Infinity then return x
763 if x.class.Zero then return x
764 if bfp_COMPARE_LT(bfp_ABSOLUTE(x), bfp_NMIN_BFP64()) then
765 if FPSCR.UE=0 then
766 x <- bfp_DENORM(-1022, x)
767 if (ro=0) & (rmode=0b00) then r <- bfp_ROUND_NEAR_EVEN(53, x)
768 if (ro=0) & (rmode=0b01) then r <- bfp_ROUND_TRUNC(53, x)
769 if (ro=0) & (rmode=0b10) then r <- bfp_ROUND_CEIL(53, x)
770 if (ro=0) & (rmode=0b11) then r <- bfp_ROUND_FLOOR(53, x)
771 if ro=1 then r <- bfp_ROUND_ODD(53, x)
772 ux_flag <- xx_flag
773 return r
774 else
775 x.exponent <- x.exponent + 1536
776 ux_flag <- 1
777 if (ro=0) & (rmode=0b00) then r <- bfp_ROUND_NEAR_EVEN(53, x)
778 if (ro=0) & (rmode=0b01) then r <- bfp_ROUND_TRUNC(53, x)
779 if (ro=0) & (rmode=0b10) then r <- bfp_ROUND_CEIL(53, x)
780 if (ro=0) & (rmode=0b11) then r <- bfp_ROUND_FLOOR(53, x)
781 if ro=1 then r <- bfp_ROUND_ODD(53, x)
782 if bfp_COMPARE_GT(bfp_ABSOLUTE(r), bfp_NMAX_BFP64()) then
783 if FPSCR.OE=0 then
784 if (ro=0) & (rmode=0b00) then r <- x.sign ? bfp_INFINITY() : bfp_INFINITY()
785 if (ro=0) & (rmode=0b01) then r <- x.sign ? bfp_NMAX_BFP64() : bfp_NMAX_BFP64()
786 if (ro=0) & (rmode=0b10) then r <- x.sign ? bfp_NMAX_BFP64() : bfp_INFINITY()
787 if (ro=0) & (rmode=0b11) then r <- x.sign ? bfp_INFINITY() : bfp_NMAX_BFP64()
788 if ro=1 then r <- x.sign ? bfp_NMAX_BFP64() : bfp_NMAX_BFP64()
789 r.sign <- x.sign
790 ox_flag <- 0b1
791 xx_flag <- 0b1
792 inc_flag <- undefined(0) # TODO: which undefined value to use?
793 return r
794 else
795 r.exponent <- r.exponent - 1536
796 ox_flag <- 1
797 return r
798
799 def bfp_ROUND_TO_BFP32(rmode,x):
800 # x is a normalized binary floating-point value that is represented in
801 # the binary floating-point working format and has unbounded exponent
802 # range and significand precision.
803 #
804 # rmode is a 2-bit integer value specifying one of four rounding modes.
805 #
806 # rmode=0b00 Round to Nearest Even
807 # rmode=0b01 Round towards Zero
808 # rmode=0b10 Round towards +Infinity
809 # rmode=0b11 Round towards - Infinity
810 #
811 # If x is a QNaN, Infinity, or Zero, return x. Otherwise, if x is an
812 # SNaN, set vxsnan_flag to 1 and return the corresponding QNaN
813 # representation of x. Otherwise, return the value x rounded to
814 # single-precision format’s exponent range and significand precision
815 # represented in the floating-point working format using the rounding
816 # mode specified by rmode.
817
818 if x.class.SNaN then
819 vxsnan_flag <- 1
820 return bfp_QUIET(x)
821
822 if x.class.QNaN then return x
823 if x.class.Infinity then return x
824 if x.class.Zero then return x
825
826 if bfp_COMPARE_LT(bfp_ABSOLUTE(x), bfp_NMIN_BFP32()) then
827 x <- bfp_DENORM(-126,x)
828 if rmode = 0b00 then r <- bfp_ROUND_NEAR_EVEN(24, x)
829 if rmode = 0b01 then r <- bfp_ROUND_TRUNC(24, x)
830 if rmode = 0b10 then r <- bfp_ROUND_CEIL(24, x)
831 if rmode = 0b11 then r <- bfp_ROUND_FLOOR(24, x)
832 if FPSCR.UE = 0 then
833 ux_flag <- xx_flag
834 return r
835 else
836 x.exponent <- x.exponent + 192
837 ux_flag <- 0b1
838
839 if rmode = 0b00 then r <- bfp_ROUND_NEAR_EVEN(24, x)
840 if rmode = 0b01 then r <- bfp_ROUND_TRUNC(24, x)
841 if rmode = 0b10 then r <- bfp_ROUND_CEIL(24, x)
842 if rmode = 0b11 then r <- bfp_ROUND_FLOOR(24, x)
843
844 if bfp_COMPARE_GT(bfp_ABSOLUTE(r), bfp_NMAX_BFP32()) then
845 if FPSCR.OE = 0 then
846 if rmode=0b00 then r <- x.sign ? bfp_INFINITY() : bfp_INFINITY()
847 if rmode=0b01 then r <- x.sign ? bfp_NMAX_BFP32() : bfp_NMAX_BFP32()
848 if rmode=0b10 then r <- x.sign ? bfp_NMAX_BFP32() : bfp_INFINITY()
849 if rmode=0b11 then r <- x.sign ? bfp_INFINITY() : bfp_NMAX_BFP32()
850 r.sign <- x.sign
851 ox_flag <- 0b1
852 xx_flag <- 0b1
853 inc_flag <- undefined(0) # TODO: which undefined value to use?
854 return r
855 else
856 r.exponent <- r.exponent - 192
857 ox_flag <- 0b1
858 return r
859
860 def bfp_INFINITY():
861 # The value +Infinity represented in the binary floating-point working
862 # format.
863 r <- BFPState()
864 r.class.Infinity <- 1
865 return r
866
867 def bfp_NMAX_BFP32():
868 # Return the largest finite single-precision floating-point value
869 # (i.e., 2^128 - 2^(128-24)) in the binary floating-point working
870 # format.
871 return bfp_CONVERT_FROM_BFP32(0x7F7F_FFFF)
872
873 def bfp_NMAX_BFP64():
874 # Return the largest finite double-precision floating-point value
875 # (i.e., 2^1024 - 2^(1024-53)) in the binary floating-point working
876 # format.
877 return bfp_CONVERT_FROM_BFP64(0x7FEF_FFFF_FFFF_FFFF)
878
879 def bfp_NMIN_BFP32():
880 # Return the smallest positive normalized single-precision
881 # floating-point value, 2^-126, represented in the binary
882 # floating-point working format.
883 return bfp_CONVERT_FROM_BFP32(0x0080_0000)
884
885 def bfp_NMIN_BFP64():
886 # Return the smallest positive normalized double-precision
887 # floating-point value, 2^-1022, represented in the binary
888 # floating-point working format.
889 return bfp_CONVERT_FROM_BFP64(0x0010_0000_0000_0000)
890
891 def bfp_ROUND_HELPER(p, ro, rmode, x):
892 # not part of the PowerISA v3.1B specification.
893 # helper function for the bfp_ROUND_* functions.
894 # doesn't set inc_flag or xx_flag.
895 #
896 # x is a binary floating-point value that is represented in the binary
897 # floating-point working format and has unbounded exponent range and
898 # significand precision. x must be rounded as presented, without
899 # prenormalization.
900 #
901 # p is an integer value specifying the precision (i.e., number of bits)
902 # the significand is rounded to.
903 #
904 # ro is a 1-bit unsigned integer and rmode is a 3-bit unsigned integer,
905 # together specifying one of six rounding modes to be used in
906 # rounding x.
907 #
908 # ro=0 rmode=0b000 Round to Nearest Even
909 # ro=0 rmode=0b001 Round towards Zero
910 # ro=0 rmode=0b010 Round towards +Infinity
911 # ro=0 rmode=0b011 Round towards -Infinity
912 # ro=0 rmode=0b100 Round to Nearest Away
913 # ro=1 Round to Odd
914
915 if IsInf(x) | IsNaN(x) | IsZero(x) then
916 inc_flag <- 0 # TODO: does the spec specify this?
917 xx_flag <- 0 # TODO: does the spec specify this?
918 return x
919
920 result <- x
921 result.significand <- 0
922 result.significand[0:p - 1] <- x.significand[0:p - 1]
923 exact <- x.significand = result.significand
924 halfway <- 0b0
925 more_than_half <- 0b0
926 if x.significand[p] then
927 t <- x
928 t.significand <- 0
929 t.significand[0:p] <- x.significand[0:p]
930 if t.significand = x.significand then halfway <- 0b1
931 else more_than_half <- 0b1
932 even <- ¬result.significand[p - 1]
933
934 if (ro=0) & (rmode=0b000) then # Round to Nearest Even
935 round_up <- (halfway & ¬even) | more_than_half
936 if (ro=0) & (rmode=0b001) then # Round towards Zero
937 round_up <- 0b0
938 if (ro=0) & (rmode=0b010) then # Round towards +Infinity
939 round_up <- (x.sign = 0) & ¬exact
940 if (ro=0) & (rmode=0b011) then # Round towards -Infinity
941 round_up <- (x.sign = 1) & ¬exact
942 if (ro=0) & (rmode=0b100) then # Round to Nearest Away
943 round_up <- halfway | more_than_half
944 if ro=1 then # Round to Odd
945 round_up <- ¬exact & even
946
947 if round_up then
948 result.significand[0:p-1] <- result.significand[0:p-1] + 1
949 if result.significand[0:p-1] = 0 then
950 result.significand[0] <- 1
951 result.exponent <- result.exponent + 1
952
953 if result.significand != 0 then
954 do while result.significand[0] != 1
955 result.significand <- result.significand * 2
956 result.exponent <- result.exponent - 1
957 result.class.Normal <- 1
958 result.class.Denormal <- 0
959 result.class.Zero <- 0
960 else
961 result.class.Normal <- 0
962 result.class.Denormal <- 0
963 result.class.Zero <- 1
964
965 return result
966
967 def bfp_ROUND_NEAR_EVEN(p, x):
968 # x is a binary floating-point value that is represented in the binary
969 # floating-point working format and has unbounded exponent range and
970 # significand precision. x must be rounded as presented, without
971 # prenormalization.
972 #
973 # p is an integer value specifying the precision (i.e., number of bits)
974 # the significand is rounded to.
975
976 result <- bfp_ROUND_HELPER(p, 0b0, 0b000, x)
977
978 if bfp_COMPARE_GT(bfp_ABSOLUTE(result), bfp_ABSOLUTE(x)) then
979 inc_flag <- 1
980 else inc_flag <- 0 # TODO: does the spec specify this?
981 if ¬bfp_COMPARE_EQ(result, x) then xx_flag <- 1
982 else xx_flag <- 0 # TODO: does the spec specify this?
983
984 return result
985
986 def bfp_ROUND_TRUNC(p, x):
987 # x is a binary floating-point value that is represented in the binary
988 # floating-point working format and has unbounded exponent range and
989 # significand precision. x must be rounded as presented, without
990 # prenormalization.
991 #
992 # p is an integer value specifying the precision (i.e., number of bits)
993 # the significand is rounded to.
994
995 result <- bfp_ROUND_HELPER(p, 0b0, 0b001, x)
996
997 if bfp_COMPARE_GT(bfp_ABSOLUTE(result), bfp_ABSOLUTE(x)) then
998 inc_flag <- 1
999 else inc_flag <- 0 # TODO: does the spec specify this?
1000 if ¬bfp_COMPARE_EQ(result, x) then xx_flag <- 1
1001 else xx_flag <- 0 # TODO: does the spec specify this?
1002
1003 return result
1004
1005 def bfp_ROUND_CEIL(p, x):
1006 # x is a binary floating-point value that is represented in the binary
1007 # floating-point working format and has unbounded exponent range and
1008 # significand precision. x must be rounded as presented, without
1009 # prenormalization.
1010 #
1011 # p is an integer value specifying the precision (i.e., number of bits)
1012 # the significand is rounded to.
1013
1014 result <- bfp_ROUND_HELPER(p, 0b0, 0b010, x)
1015
1016 if bfp_COMPARE_GT(bfp_ABSOLUTE(result), bfp_ABSOLUTE(x)) then
1017 inc_flag <- 1
1018 else inc_flag <- 0 # TODO: does the spec specify this?
1019 if ¬bfp_COMPARE_EQ(result, x) then xx_flag <- 1
1020 else xx_flag <- 0 # TODO: does the spec specify this?
1021
1022 return result
1023
1024 def bfp_ROUND_FLOOR(p, x):
1025 # x is a binary floating-point value that is represented in the binary
1026 # floating-point working format and has unbounded exponent range and
1027 # significand precision. x must be rounded as presented, without
1028 # prenormalization.
1029 #
1030 # p is an integer value specifying the precision (i.e., number of bits)
1031 # the significand is rounded to.
1032
1033 result <- bfp_ROUND_HELPER(p, 0b0, 0b011, x)
1034
1035 if bfp_COMPARE_GT(bfp_ABSOLUTE(result), bfp_ABSOLUTE(x)) then
1036 inc_flag <- 1
1037 else inc_flag <- 0 # TODO: does the spec specify this?
1038 if ¬bfp_COMPARE_EQ(result, x) then xx_flag <- 1
1039 else xx_flag <- 0 # TODO: does the spec specify this?
1040
1041 return result
1042
1043 def bfp_ROUND_NEAR_AWAY(p, x):
1044 # not part of the PowerISA v3.1B specification.
1045 #
1046 # x is a binary floating-point value that is represented in the binary
1047 # floating-point working format and has unbounded exponent range and
1048 # significand precision. x must be rounded as presented, without
1049 # prenormalization.
1050 #
1051 # p is an integer value specifying the precision (i.e., number of bits)
1052 # the significand is rounded to.
1053
1054 result <- bfp_ROUND_HELPER(p, 0b0, 0b100, x)
1055
1056 if bfp_COMPARE_GT(bfp_ABSOLUTE(result), bfp_ABSOLUTE(x)) then
1057 inc_flag <- 1
1058 else inc_flag <- 0 # TODO: does the spec specify this?
1059 if ¬bfp_COMPARE_EQ(result, x) then xx_flag <- 1
1060 else xx_flag <- 0 # TODO: does the spec specify this?
1061
1062 return result
1063
1064 def bfp_ROUND_ODD(p, x):
1065 # x is a binary floating-point value that is represented in the binary
1066 # floating-point working format and has unbounded exponent range and
1067 # significand precision. x must be rounded as presented, without
1068 # prenormalization.
1069 #
1070 # p is an integer value specifying the precision (i.e., number of bits)
1071 # the significand is rounded to.
1072
1073 result <- bfp_ROUND_HELPER(p, 0b1, 0b000, x)
1074
1075 if bfp_COMPARE_GT(bfp_ABSOLUTE(result), bfp_ABSOLUTE(x)) then
1076 inc_flag <- 1
1077 else inc_flag <- 0 # TODO: does the spec specify this?
1078 if ¬bfp_COMPARE_EQ(result, x) then xx_flag <- 1
1079 else xx_flag <- 0 # TODO: does the spec specify this?
1080
1081 return result
1082
1083 def fprf_CLASS_BFP64(x):
1084 # x is a floating-point value represented in double-precision format.
1085 #
1086 # Return the 5-bit code that specifies the sign and class of x.
1087
1088 v <- bfp_CONVERT_FROM_BFP64(x)
1089 if v.class.QNaN then return 0b10001
1090 if (v.sign = 1) & v.class.Infinity then return 0b01001
1091 if (v.sign = 0) & v.class.Infinity then return 0b00101
1092 if (v.sign = 1) & v.class.Zero then return 0b10010
1093 if (v.sign = 0) & v.class.Zero then return 0b00010
1094 if (v.sign = 1) & v.class.Denormal then return 0b11000
1095 if (v.sign = 0) & v.class.Denormal then return 0b10100
1096 if (v.sign = 1) & v.class.Normal then return 0b01000
1097 if (v.sign = 0) & v.class.Normal then return 0b00100
1098
1099 def fprf_CLASS_BFP32(x):
1100 # x is a floating-point value represented in single-precision format.
1101 #
1102 # Return the 5-bit code that specifies the sign and class of x.
1103
1104 v <- bfp_CONVERT_FROM_BFP32(x)
1105 if v.class.QNaN then return 0b10001
1106 if (v.sign = 1) & v.class.Infinity then return 0b01001
1107 if (v.sign = 0) & v.class.Infinity then return 0b00101
1108 if (v.sign = 1) & v.class.Zero then return 0b10010
1109 if (v.sign = 0) & v.class.Zero then return 0b00010
1110 if (v.sign = 1) & v.class.Denormal then return 0b11000
1111 if (v.sign = 0) & v.class.Denormal then return 0b10100
1112 if (v.sign = 1) & v.class.Normal then return 0b01000
1113 if (v.sign = 0) & v.class.Normal then return 0b00100