match v3.1B section 4.6.7.2 Floating-Point Convert To/From Integer Instructions
[libreriscv.git] / openpower / sv / int_fp_mv / moves_and_conversions.mdwn
1 <!-- main body for int_fp_mv.mdwn (without fmvis/fishmv) and ls006.fpintmv.mdwn -->
2 # Immediate Tables
3
4 Tables that are used by
5 `mffpr[s][.]`/`mtfpr[s]`/`cffpr[o][.]`/`ctfpr[s][.]`:
6
7 ## `IT` -- Integer Type
8
9 | `IT` | Integer Type | Assembly Alias Mnemonic |
10 |------|-----------------|-------------------------|
11 | 0 | Signed 32-bit | `<op>w` |
12 | 1 | Unsigned 32-bit | `<op>uw` |
13 | 2 | Signed 64-bit | `<op>d` |
14 | 3 | Unsigned 64-bit | `<op>ud` |
15
16 ## `CVM` -- Float to Integer Conversion Mode
17
18 | `CVM` | `rounding_mode` | Semantics |
19 |-------|-----------------|----------------------------------|
20 | 000 | from `FPSCR` | [OpenPower semantics] |
21 | 001 | Truncate | [OpenPower semantics] |
22 | 010 | from `FPSCR` | [Java/Saturating semantics] |
23 | 011 | Truncate | [Java/Saturating semantics] |
24 | 100 | from `FPSCR` | [JavaScript semantics] |
25 | 101 | Truncate | [JavaScript semantics] |
26 | rest | -- | illegal instruction trap for now |
27
28 [OpenPower semantics]: #fp-to-int-openpower-conversion-semantics
29 [Java/Saturating semantics]: #fp-to-int-java-saturating-conversion-semantics
30 [JavaScript semantics]: #fp-to-int-javascript-conversion-semantics
31
32 ----------
33
34 # Move To/From Floating-Point Register Instructions
35
36 These instructions perform a copy from one register file to another, as if by
37 using a GPR/FPR store, followed by a FPR/GPR load.
38
39 ## Move From Floating-Point Register
40
41 ```
42 mffpr RT, FRB
43 mffpr. RT, FRB
44 ```
45
46 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
47 |-----|------|-------|-------|-------|----|--------|
48 | PO | RT | // | FRB | XO | Rc | X-Form |
49
50 ```
51 RT <- (FRB)
52 ```
53
54 The contents of `FPR[FRB]` are placed into `GPR[RT]`.
55
56 Special Registers altered:
57
58 ```
59 CR0 (if Rc=1)
60 ```
61
62 Architecture Note:
63
64 `mffpr` is equivalent to the combination of `stfd` followed by `ld`.
65
66 Architecture Note:
67
68 `mffpr` is a separate instruction from `mfvsrd` because `mfvsrd` requires
69 VSX which may not be available on simpler implementations.
70 Additionally, SVP64 may treat VSX instructions differently than SFFS
71 instructions in a future version of the architecture.
72
73 ----------
74
75 ## Move From Floating-Point Register Single
76
77 ```
78 mffprs RT, FRB
79 mffprs. RT, FRB
80 ```
81
82 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
83 |-----|------|-------|-------|-------|----|--------|
84 | PO | RT | // | FRB | XO | Rc | X-Form |
85
86 ```
87 RT <- [0] * 32 || SINGLE((FRB))
88 ```
89
90 The contents of `FPR[FRB]` are converted to BFP32 by using `SINGLE`, then
91 zero-extended to 64-bits, and the result stored in `GPR[RT]`.
92
93 Special Registers altered:
94
95 ```
96 CR0 (if Rc=1)
97 ```
98
99 Architecture Note:
100
101 `mffprs` is equivalent to the combination of `stfs` followed by `lwz`.
102
103 ----------
104
105 \newpage{}
106
107 ## Move To Floating-Point Register
108
109 ```
110 mtfpr FRT, RB
111 ```
112
113 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
114 |-----|------|-------|-------|-------|----|--------|
115 | PO | FRT | // | RB | XO | // | X-Form |
116
117 ```
118 FRT <- (RB)
119 ```
120
121 The contents of `GPR[RB]` are placed into `FPR[FRT]`.
122
123 Special Registers altered:
124
125 ```
126 None
127 ```
128
129 Architecture Note:
130
131 `mtfpr` is equivalent to the combination of `std` followed by `lfd`.
132
133 Architecture Note:
134
135 `mtfpr` is a separate instruction from `mtvsrd` because `mtvsrd` requires
136 VSX which may not be available on simpler implementations.
137 Additionally, SVP64 may treat VSX instructions differently than SFFS
138 instructions in a future version of the architecture.
139
140 ----------
141
142 ## Move To Floating-Point Register Single
143
144 ```
145 mtfprs FRT, RB
146 ```
147
148 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
149 |-----|------|-------|-------|-------|----|--------|
150 | PO | FRT | // | RB | XO | // | X-Form |
151
152 ```
153 FRT <- DOUBLE((RB)[32:63])
154 ```
155
156 The contents of bits 32:63 of `GPR[RB]` are converted to BFP64 by using
157 `DOUBLE`, then the result is stored in `GPR[RT]`.
158
159 Special Registers altered:
160
161 ```
162 None
163 ```
164
165 Architecture Note:
166
167 `mtfprs` is equivalent to the combination of `stw` followed by `lfs`.
168
169 ----------
170
171 \newpage{}
172
173 # Conversion To/From Floating-Point Register Instructions
174
175 ## Convert To Floating-Point Register
176
177 ```
178 ctfpr FRT, RB, IT
179 ctfpr. FRT, RB, IT
180 ```
181
182 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
183 |-----|------|-------|-------|-------|-------|----|--------|
184 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
185
186 ```
187 if IT[0] = 0 then # 32-bit int -> 64-bit float
188 # rounding never necessary, so don't touch FPSCR
189 # based off xvcvsxwdp
190 if IT = 0 then # Signed 32-bit
191 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
192 else # IT = 1 -- Unsigned 32-bit
193 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
194 FRT <- bfp64_CONVERT_FROM_BFP(src)
195 else
196 # rounding may be necessary. based off xscvuxdsp
197 reset_xflags()
198 switch(IT)
199 case(0): # Signed 32-bit
200 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
201 case(1): # Unsigned 32-bit
202 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
203 case(2): # Signed 64-bit
204 src <- bfp_CONVERT_FROM_SI64((RB))
205 default: # Unsigned 64-bit
206 src <- bfp_CONVERT_FROM_UI64((RB))
207 rnd <- bfp_ROUND_TO_BFP64(0b0, FPSCR.RN, src)
208 result <- bfp64_CONVERT_FROM_BFP(rnd)
209 cls <- fprf_CLASS_BFP64(result)
210
211 if xx_flag = 1 then SetFX(FPSCR.XX)
212
213 FRT <- result
214 FPSCR.FPRF <- cls
215 FPSCR.FR <- inc_flag
216 FPSCR.FI <- xx_flag
217 ```
218 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
219 don't remove them -->
220
221 Convert from a unsigned/signed 32/64-bit integer in RB to a 64-bit
222 float in FRT.
223
224 If converting from a unsigned/signed 32-bit integer to a 64-bit float,
225 rounding is never necessary, so `FPSCR` is unmodified and exceptions are
226 never raised. Otherwise, `FPSCR` is modified and exceptions are raised
227 as usual.
228
229 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
230 operations.
231
232 Special Registers altered:
233
234 ```
235 CR1 (if Rc=1)
236 FPRF FR FI FX XX (if IT[0]=1)
237 ```
238
239 ### Assembly Aliases
240
241 | Assembly Alias | Full Instruction |
242 |--------------------|---------------------|
243 | `ctfprw FRT, RB` | `ctfpr FRT, RB, 0` |
244 | `ctfprw. FRT, RB` | `ctfpr. FRT, RB, 0` |
245 | `ctfpruw FRT, RB` | `ctfpr FRT, RB, 1` |
246 | `ctfpruw. FRT, RB` | `ctfpr. FRT, RB, 1` |
247 | `ctfprd FRT, RB` | `ctfpr FRT, RB, 2` |
248 | `ctfprd. FRT, RB` | `ctfpr. FRT, RB, 2` |
249 | `ctfprud FRT, RB` | `ctfpr FRT, RB, 3` |
250 | `ctfprud. FRT, RB` | `ctfpr. FRT, RB, 3` |
251
252 ----------
253
254 \newpage{}
255
256 ## Convert To Floating-Point Register Single
257
258 ```
259 ctfprs FRT, RB, IT
260 ctfprs. FRT, RB, IT
261 ```
262
263 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
264 |-----|------|-------|-------|-------|-------|----|--------|
265 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
266
267 ```
268 # rounding may be necessary. based off xscvuxdsp
269 reset_xflags()
270 switch(IT)
271 case(0): # Signed 32-bit
272 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
273 case(1): # Unsigned 32-bit
274 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
275 case(2): # Signed 64-bit
276 src <- bfp_CONVERT_FROM_SI64((RB))
277 default: # Unsigned 64-bit
278 src <- bfp_CONVERT_FROM_UI64((RB))
279 rnd <- bfp_ROUND_TO_BFP32(FPSCR.RN, src)
280 result32 <- bfp32_CONVERT_FROM_BFP(rnd)
281 cls <- fprf_CLASS_BFP32(result32)
282 result <- DOUBLE(result32)
283
284 if xx_flag = 1 then SetFX(FPSCR.XX)
285
286 FRT <- result
287 FPSCR.FPRF <- cls
288 FPSCR.FR <- inc_flag
289 FPSCR.FI <- xx_flag
290 ```
291 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
292 don't remove them -->
293
294 Convert from a unsigned/signed 32/64-bit integer in RB to a 32-bit
295 float in FRT, following the usual 32-bit float in 64-bit float format.
296 `FPSCR` is modified and exceptions are raised as usual.
297
298 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
299 operations.
300
301 Special Registers altered:
302
303 ```
304 CR1 (if Rc=1)
305 FPRF FR FI FX XX
306 ```
307
308 ### Assembly Aliases
309
310 | Assembly Alias | Full Instruction |
311 |---------------------|---------------------|
312 | `ctfprws FRT, RB` | `ctfpr FRT, RB, 0` |
313 | `ctfprws. FRT, RB` | `ctfpr. FRT, RB, 0` |
314 | `ctfpruws FRT, RB` | `ctfpr FRT, RB, 1` |
315 | `ctfpruws. FRT, RB` | `ctfpr. FRT, RB, 1` |
316 | `ctfprds FRT, RB` | `ctfpr FRT, RB, 2` |
317 | `ctfprds. FRT, RB` | `ctfpr. FRT, RB, 2` |
318 | `ctfpruds FRT, RB` | `ctfpr FRT, RB, 3` |
319 | `ctfpruds. FRT, RB` | `ctfpr. FRT, RB, 3` |
320
321 ----------
322
323 \newpage{}
324
325 ## Floating-point to Integer Conversion Overview
326
327 <div id="fpr-to-gpr-conversion-mode"></div>
328
329 IEEE 754 doesn't specify what results are obtained when converting a NaN
330 or out-of-range floating-point value to integer, so different programming
331 languages and ISAs have made different choices. Below is an overview
332 of the different variants, listing the languages and hardware that
333 implements each variant.
334
335 For convenience, those different conversion semantics will be given names
336 based on which common ISA or programming language uses them, since there
337 may not be an established name for them:
338
339 **Standard OpenPower conversion**
340
341 This conversion performs "saturation with NaN converted to minimum
342 valid integer". This is also exactly the same as the x86 ISA conversion
343 semantics. OpenPOWER however has instructions for both:
344
345 * rounding mode read from FPSCR
346 * rounding mode always set to truncate
347
348 **Java/Saturating conversion**
349
350 For the sake of simplicity, the FP -> Integer conversion semantics
351 generalized from those used by Java's semantics (and Rust's `as`
352 operator) will be referred to as [Java/Saturating conversion
353 semantics](#fp-to-int-java-saturating-conversion-semantics).
354
355 Those same semantics are used in some way by all of the following
356 languages (not necessarily for the default conversion method):
357
358 * Java's
359 [FP -> Integer conversion](https://docs.oracle.com/javase/specs/jls/se16/html/jls-5.html#jls-5.1.3)
360 (only for long/int results)
361 * Rust's FP -> Integer conversion using the
362 [`as` operator](https://doc.rust-lang.org/reference/expressions/operator-expr.html#semantics)
363 * LLVM's
364 [`llvm.fptosi.sat`](https://llvm.org/docs/LangRef.html#llvm-fptosi-sat-intrinsic) and
365 [`llvm.fptoui.sat`](https://llvm.org/docs/LangRef.html#llvm-fptoui-sat-intrinsic) intrinsics
366 * SPIR-V's OpenCL dialect's
367 [`OpConvertFToU`](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpConvertFToU) and
368 [`OpConvertFToS`](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpConvertFToS)
369 instructions when decorated with
370 [the `SaturatedConversion` decorator](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_decoration_a_decoration).
371 * WebAssembly has also introduced
372 [trunc_sat_u](ttps://webassembly.github.io/spec/core/exec/numerics.html#op-trunc-sat-u) and
373 [trunc_sat_s](https://webassembly.github.io/spec/core/exec/numerics.html#op-trunc-sat-s)
374
375 **JavaScript conversion**
376
377 For the sake of simplicity, the FP -> Integer conversion
378 semantics generalized from those used by JavaScripts's `ToInt32`
379 abstract operation will be referred to as [JavaScript conversion
380 semantics](#fp-to-int-javascript-conversion-semantics).
381
382 This instruction is present in ARM assembler as FJCVTZS
383 <https://developer.arm.com/documentation/dui0801/g/hko1477562192868>
384
385 **Rc=1 and OE=1**
386
387 All of these instructions have an Rc=1 mode which sets CR0
388 in the normal way for any instructions producing a GPR result.
389 Additionally, when OE=1, if the numerical value of the FP number
390 is not 100% accurately preserved (due to truncation or saturation
391 and including when the FP number was NaN) then this is considered
392 to be an integer Overflow condition, and CR0.SO, XER.SO and XER.OV
393 are all set as normal for any GPR instructions that overflow.
394
395 \newpage{}
396
397 ### FP to Integer Conversion Simplified Pseudo-code
398
399 Key for pseudo-code:
400
401 | term | result type | definition |
402 |---------------------------|-------------|-----------------------------------------------------------------------------------------------|
403 | `fp` | -- | `f32` or `f64` (or other types from SimpleV) |
404 | `int` | -- | `u32`/`u64`/`i32`/`i64` (or other types from SimpleV) |
405 | `uint` | -- | the unsigned integer of the same bit-width as `int` |
406 | `int::BITS` | `int` | the bit-width of `int` |
407 | `uint::MIN_VALUE` | `uint` | the minimum value `uint` can store: `0` |
408 | `uint::MAX_VALUE` | `uint` | the maximum value `uint` can store: `2^int::BITS - 1` |
409 | `int::MIN_VALUE` | `int` | the minimum value `int` can store : `-2^(int::BITS-1)` |
410 | `int::MAX_VALUE` | `int` | the maximum value `int` can store : `2^(int::BITS-1) - 1` |
411 | `int::VALUE_COUNT` | Integer | the number of different values `int` can store (`2^int::BITS`). too big to fit in `int`. |
412 | `rint(fp, rounding_mode)` | `fp` | rounds the floating-point value `fp` to an integer according to rounding mode `rounding_mode` |
413
414 <div id="fp-to-int-openpower-conversion-semantics"></div>
415 OpenPower conversion semantics (section A.2 page 1009 (page 1035) of
416 Power ISA v3.1B):
417
418 ```
419 def fp_to_int_open_power<fp, int>(v: fp) -> int:
420 if v is NaN:
421 return int::MIN_VALUE
422 if v >= int::MAX_VALUE:
423 return int::MAX_VALUE
424 if v <= int::MIN_VALUE:
425 return int::MIN_VALUE
426 return (int)rint(v, rounding_mode)
427 ```
428
429 <div id="fp-to-int-java-saturating-conversion-semantics"></div>
430 [Java/Saturating conversion semantics](https://docs.oracle.com/javase/specs/jls/se16/html/jls-5.html#jls-5.1.3)
431 (only for long/int results)
432 (with adjustment to add non-truncate rounding modes):
433
434 ```
435 def fp_to_int_java_saturating<fp, int>(v: fp) -> int:
436 if v is NaN:
437 return 0
438 if v >= int::MAX_VALUE:
439 return int::MAX_VALUE
440 if v <= int::MIN_VALUE:
441 return int::MIN_VALUE
442 return (int)rint(v, rounding_mode)
443 ```
444
445 <div id="fp-to-int-javascript-conversion-semantics"></div>
446 Section 7.1 of the ECMAScript / JavaScript
447 [conversion semantics](https://262.ecma-international.org/11.0/#sec-toint32)
448 (with adjustment to add non-truncate rounding modes):
449
450 ```
451 def fp_to_int_java_script<fp, int>(v: fp) -> int:
452 if v is NaN or infinite:
453 return 0
454 v = rint(v, rounding_mode) # assume no loss of precision in result
455 v = v mod int::VALUE_COUNT # 2^32 for i32, 2^64 for i64, result is non-negative
456 bits = (uint)v
457 return (int)bits
458 ```
459
460 ----------
461
462 \newpage{}
463
464 ## Convert From Floating-Point Register
465
466 ```
467 cffpr RT, FRB, CVM, IT
468 cffpr. RT, FRB, CVM, IT
469 cffpro RT, FRB, CVM, IT
470 cffpro. RT, FRB, CVM, IT
471 ```
472
473 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21 | 22-30 | 31 | Form |
474 |-----|------|-------|-------|-------|----|-------|----|---------|
475 | PO | RT | IT | CVM | FRB | OE | XO | Rc | XO-Form |
476
477 ```
478 # based on xscvdpuxws
479 reset_xflags()
480 src <- bfp_CONVERT_FROM_BFP64((FRB))
481
482 switch(IT)
483 case(0): # Signed 32-bit
484 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
485 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
486 js_mask <- 0x0000_0000_FFFF_FFFF
487 case(1): # Unsigned 32-bit
488 range_min <- bfp_CONVERT_FROM_UI32(0)
489 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
490 js_mask <- 0x0000_0000_FFFF_FFFF
491 case(2): # Signed 64-bit
492 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
493 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
494 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
495 default: # Unsigned 64-bit
496 range_min <- bfp_CONVERT_FROM_UI64(0)
497 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
498 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
499
500 if (CVM[2] = 1) | (FPSCR.RN = 0b01) then
501 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
502 else if FPSCR.RN = 0b00 then
503 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
504 else if FPSCR.RN = 0b10 then
505 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
506 else if FPSCR.RN = 0b11 then
507 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
508
509 switch(CVM)
510 case(0, 1): # OpenPower semantics
511 if IsNaN(rnd) then
512 result <- si64_CONVERT_FROM_BFP(range_min)
513 else if bfp_COMPARE_GT(rnd, range_max) then
514 result <- ui64_CONVERT_FROM_BFP(range_max)
515 else if bfp_COMPARE_LT(rnd, range_min) then
516 result <- si64_CONVERT_FROM_BFP(range_min)
517 else if IT[1] = 1 then # Unsigned 32/64-bit
518 result <- ui64_CONVERT_FROM_BFP(rnd)
519 else # Signed 32/64-bit
520 result <- si64_CONVERT_FROM_BFP(rnd)
521 case(2, 3): # Java/Saturating semantics
522 if IsNaN(rnd) then
523 result <- [0] * 64
524 else if bfp_COMPARE_GT(rnd, range_max) then
525 result <- ui64_CONVERT_FROM_BFP(range_max)
526 else if bfp_COMPARE_LT(rnd, range_min) then
527 result <- si64_CONVERT_FROM_BFP(range_min)
528 else if IT[1] = 1 then # Unsigned 32/64-bit
529 result <- ui64_CONVERT_FROM_BFP(rnd)
530 else # Signed 32/64-bit
531 result <- si64_CONVERT_FROM_BFP(rnd)
532 default: # JavaScript semantics
533 # CVM = 6, 7 are illegal instructions
534 # using a 128-bit intermediate works here because the largest type
535 # this instruction can convert from has 53 significand bits, and
536 # the largest type this instruction can convert to has 64 bits,
537 # and the sum of those is strictly less than the 128 bits of the
538 # intermediate result.
539 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
540 if IsInf(rnd) | IsNaN(rnd) then
541 result <- [0] * 64
542 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
543 result <- [0] * 64
544 else
545 result128 <- si128_CONVERT_FROM_BFP(rnd)
546 result <- result128[64:127] & js_mask
547
548 switch(IT)
549 case(0): # Signed 32-bit
550 result <- EXTS64(result[32:63])
551 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
552 case(1): # Unsigned 32-bit
553 result <- EXTZ64(result[32:63])
554 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
555 case(2): # Signed 64-bit
556 result_bfp <- bfp_CONVERT_FROM_SI64(result)
557 default: # Unsigned 64-bit
558 result_bfp <- bfp_CONVERT_FROM_UI64(result)
559
560 overflow <- 0 # signals SO only when OE = 1
561 if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
562 overflow <- 1 # signals SO only when OE = 1
563 vxcvi_flag <- 1
564 xx_flag <- 0
565 inc_flag <- 0
566 else
567 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
568 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
569
570 if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
571 if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
572 if xx_flag = 1 then SetFX(FPSCR.XX)
573
574 vx_flag <- vxsnan_flag | vxcvi_flag
575 vex_flag <- FPSCR.VE & vx_flag
576 if vex_flag = 0 then
577 RT <- result
578 FPSCR.FPRF <- undefined
579 FPSCR.FR <- inc_flag
580 FPSCR.FI <- xx_flag
581 else
582 FPSCR.FR <- 0
583 FPSCR.FI <- 0
584 ```
585
586 Convert from 64-bit float in FRB to a unsigned/signed 32/64-bit integer
587 in RT, with the conversion overflow/rounding semantics following the
588 chosen `CVM` value. `FPSCR` is modified and exceptions are raised as usual.
589
590 These instructions have an Rc=1 mode which sets CR0 in the normal
591 way for any instructions producing a GPR result. Additionally, when OE=1,
592 if the numerical value of the FP number is not 100% accurately preserved
593 (due to truncation or saturation and including when the FP number was
594 NaN) then this is considered to be an Integer Overflow condition, and
595 CR0.SO, XER.SO and XER.OV are all set as normal for any GPR instructions
596 that overflow. When `RT` is not written (`vex_flag = 1`), all CR0 bits
597 except SO are undefined.
598
599 Special Registers altered:
600
601 ```
602 CR0 (if Rc=1)
603 XER SO, OV, OV32 (if OE=1)
604 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
605 ```
606
607 ### Assembly Aliases
608
609 | Assembly Alias | Full Instruction |
610 |--------------------------|---------------------------|
611 | `cffprw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 0` |
612 | `cffprw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 0` |
613 | `cffprwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 0` |
614 | `cffprwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 0` |
615 | `cffpruw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 1` |
616 | `cffpruw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 1` |
617 | `cffpruwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 1` |
618 | `cffpruwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 1` |
619 | `cffprd RT, FRB, CVM` | `cffpr RT, FRB, CVM, 2` |
620 | `cffprd. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 2` |
621 | `cffprdo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 2` |
622 | `cffprdo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 2` |
623 | `cffprud RT, FRB, CVM` | `cffpr RT, FRB, CVM, 3` |
624 | `cffprud. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 3` |
625 | `cffprudo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 3` |
626 | `cffprudo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 3` |