45a2d7a2c7bfdb9489cdf7ac9bcd7d9968f629c9
[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 # Moves
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 FPR
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 FPR 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 FPR
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 FPR 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 # Conversions
174
175 Unlike the move instructions
176 these instructions perform conversions between Integer and
177 Floating Point. Truncation can therefore occur, as well
178 as exceptions.
179
180 ## Convert To FPR
181
182 ```
183 ctfpr FRT, RB, IT
184 ctfpr. FRT, RB, IT
185 ```
186
187 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
188 |-----|------|-------|-------|-------|-------|----|--------|
189 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
190
191 ```
192 if IT[0] = 0 then # 32-bit int -> 64-bit float
193 # rounding never necessary, so don't touch FPSCR
194 # based off xvcvsxwdp
195 if IT = 0 then # Signed 32-bit
196 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
197 else # IT = 1 -- Unsigned 32-bit
198 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
199 FRT <- bfp64_CONVERT_FROM_BFP(src)
200 else
201 # rounding may be necessary. based off xscvuxdsp
202 reset_xflags()
203 switch(IT)
204 case(0): # Signed 32-bit
205 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
206 case(1): # Unsigned 32-bit
207 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
208 case(2): # Signed 64-bit
209 src <- bfp_CONVERT_FROM_SI64((RB))
210 default: # Unsigned 64-bit
211 src <- bfp_CONVERT_FROM_UI64((RB))
212 rnd <- bfp_ROUND_TO_BFP64(0b0, FPSCR.RN, src)
213 result <- bfp64_CONVERT_FROM_BFP(rnd)
214 cls <- fprf_CLASS_BFP64(result)
215
216 if xx_flag = 1 then SetFX(FPSCR.XX)
217
218 FRT <- result
219 FPSCR.FPRF <- cls
220 FPSCR.FR <- inc_flag
221 FPSCR.FI <- xx_flag
222 ```
223 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
224 don't remove them -->
225
226 Convert from a unsigned/signed 32/64-bit integer in RB to a 64-bit
227 float in FRT.
228
229 If converting from a unsigned/signed 32-bit integer to a 64-bit float,
230 rounding is never necessary, so `FPSCR` is unmodified and exceptions are
231 never raised. Otherwise, `FPSCR` is modified and exceptions are raised
232 as usual.
233
234 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
235 operations.
236
237 Special Registers altered:
238
239 ```
240 CR1 (if Rc=1)
241 FPRF FR FI FX XX (if IT[0]=1)
242 ```
243
244 ### Assembly Aliases
245
246 | Assembly Alias | Full Instruction |
247 |--------------------|---------------------|
248 | `ctfprw FRT, RB` | `ctfpr FRT, RB, 0` |
249 | `ctfprw. FRT, RB` | `ctfpr. FRT, RB, 0` |
250 | `ctfpruw FRT, RB` | `ctfpr FRT, RB, 1` |
251 | `ctfpruw. FRT, RB` | `ctfpr. FRT, RB, 1` |
252 | `ctfprd FRT, RB` | `ctfpr FRT, RB, 2` |
253 | `ctfprd. FRT, RB` | `ctfpr. FRT, RB, 2` |
254 | `ctfprud FRT, RB` | `ctfpr FRT, RB, 3` |
255 | `ctfprud. FRT, RB` | `ctfpr. FRT, RB, 3` |
256
257 ----------
258
259 \newpage{}
260
261 ## Convert To FPR Single
262
263 ```
264 ctfprs FRT, RB, IT
265 ctfprs. FRT, RB, IT
266 ```
267
268 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
269 |-----|------|-------|-------|-------|-------|----|--------|
270 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
271
272 ```
273 # rounding may be necessary. based off xscvuxdsp
274 reset_xflags()
275 switch(IT)
276 case(0): # Signed 32-bit
277 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
278 case(1): # Unsigned 32-bit
279 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
280 case(2): # Signed 64-bit
281 src <- bfp_CONVERT_FROM_SI64((RB))
282 default: # Unsigned 64-bit
283 src <- bfp_CONVERT_FROM_UI64((RB))
284 rnd <- bfp_ROUND_TO_BFP32(FPSCR.RN, src)
285 result32 <- bfp32_CONVERT_FROM_BFP(rnd)
286 cls <- fprf_CLASS_BFP32(result32)
287 result <- DOUBLE(result32)
288
289 if xx_flag = 1 then SetFX(FPSCR.XX)
290
291 FRT <- result
292 FPSCR.FPRF <- cls
293 FPSCR.FR <- inc_flag
294 FPSCR.FI <- xx_flag
295 ```
296 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
297 don't remove them -->
298
299 Convert from a unsigned/signed 32/64-bit integer in RB to a 32-bit
300 float in FRT, following the usual 32-bit float in 64-bit float format.
301 `FPSCR` is modified and exceptions are raised as usual.
302
303 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
304 operations.
305
306 Special Registers altered:
307
308 ```
309 CR1 (if Rc=1)
310 FPRF FR FI FX XX
311 ```
312
313 ### Assembly Aliases
314
315 | Assembly Alias | Full Instruction |
316 |---------------------|---------------------|
317 | `ctfprws FRT, RB` | `ctfpr FRT, RB, 0` |
318 | `ctfprws. FRT, RB` | `ctfpr. FRT, RB, 0` |
319 | `ctfpruws FRT, RB` | `ctfpr FRT, RB, 1` |
320 | `ctfpruws. FRT, RB` | `ctfpr. FRT, RB, 1` |
321 | `ctfprds FRT, RB` | `ctfpr FRT, RB, 2` |
322 | `ctfprds. FRT, RB` | `ctfpr. FRT, RB, 2` |
323 | `ctfpruds FRT, RB` | `ctfpr FRT, RB, 3` |
324 | `ctfpruds. FRT, RB` | `ctfpr. FRT, RB, 3` |
325
326 ----------
327
328 \newpage{}
329
330 ## Floating-point to Integer Conversion Overview
331
332 <div id="fpr-to-gpr-conversion-mode"></div>
333
334 IEEE 754 doesn't specify what results are obtained when converting a NaN
335 or out-of-range floating-point value to integer, so different programming
336 languages and ISAs have made different choices. Below is an overview
337 of the different variants, listing the languages and hardware that
338 implements each variant.
339
340 For convenience, those different conversion semantics will be given names
341 based on which common ISA or programming language uses them, since there
342 may not be an established name for them:
343
344 **Standard OpenPower conversion**
345
346 This conversion performs "saturation with NaN converted to minimum
347 valid integer". This is also exactly the same as the x86 ISA conversion
348 semantics. OpenPOWER however has instructions for both:
349
350 * rounding mode read from FPSCR
351 * rounding mode always set to truncate
352
353 **Java/Saturating conversion**
354
355 For the sake of simplicity, the FP -> Integer conversion semantics
356 generalized from those used by Java's semantics (and Rust's `as`
357 operator) will be referred to as [Java/Saturating conversion
358 semantics](#fp-to-int-java-saturating-conversion-semantics).
359
360 Those same semantics are used in some way by all of the following
361 languages (not necessarily for the default conversion method):
362
363 * Java's
364 [FP -> Integer conversion](https://docs.oracle.com/javase/specs/jls/se16/html/jls-5.html#jls-5.1.3)
365 (only for long/int results)
366 * Rust's FP -> Integer conversion using the
367 [`as` operator](https://doc.rust-lang.org/reference/expressions/operator-expr.html#semantics)
368 * LLVM's
369 [`llvm.fptosi.sat`](https://llvm.org/docs/LangRef.html#llvm-fptosi-sat-intrinsic) and
370 [`llvm.fptoui.sat`](https://llvm.org/docs/LangRef.html#llvm-fptoui-sat-intrinsic) intrinsics
371 * SPIR-V's OpenCL dialect's
372 [`OpConvertFToU`](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpConvertFToU) and
373 [`OpConvertFToS`](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#OpConvertFToS)
374 instructions when decorated with
375 [the `SaturatedConversion` decorator](https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html#_a_id_decoration_a_decoration).
376 * WebAssembly has also introduced
377 [trunc_sat_u](ttps://webassembly.github.io/spec/core/exec/numerics.html#op-trunc-sat-u) and
378 [trunc_sat_s](https://webassembly.github.io/spec/core/exec/numerics.html#op-trunc-sat-s)
379
380 **JavaScript conversion**
381
382 For the sake of simplicity, the FP -> Integer conversion
383 semantics generalized from those used by JavaScripts's `ToInt32`
384 abstract operation will be referred to as [JavaScript conversion
385 semantics](#fp-to-int-javascript-conversion-semantics).
386
387 This instruction is present in ARM assembler as FJCVTZS
388 <https://developer.arm.com/documentation/dui0801/g/hko1477562192868>
389
390 **Rc=1 and OE=1**
391
392 All of these instructions have an Rc=1 mode which sets CR0
393 in the normal way for any instructions producing a GPR result.
394 Additionally, when OE=1, if the numerical value of the FP number
395 is not 100% accurately preserved (due to truncation or saturation
396 and including when the FP number was NaN) then this is considered
397 to be an integer Overflow condition, and CR0.SO, XER.SO and XER.OV
398 are all set as normal for any GPR instructions that overflow.
399
400 \newpage{}
401
402 ### FP to Integer Conversion Simplified Pseudo-code
403
404 Key for pseudo-code:
405
406 | term | result type | definition |
407 |---------------------------|-------------|-----------------------------------------------------------------------------------------------|
408 | `fp` | -- | `f32` or `f64` (or other types from SimpleV) |
409 | `int` | -- | `u32`/`u64`/`i32`/`i64` (or other types from SimpleV) |
410 | `uint` | -- | the unsigned integer of the same bit-width as `int` |
411 | `int::BITS` | `int` | the bit-width of `int` |
412 | `uint::MIN_VALUE` | `uint` | the minimum value `uint` can store: `0` |
413 | `uint::MAX_VALUE` | `uint` | the maximum value `uint` can store: `2^int::BITS - 1` |
414 | `int::MIN_VALUE` | `int` | the minimum value `int` can store : `-2^(int::BITS-1)` |
415 | `int::MAX_VALUE` | `int` | the maximum value `int` can store : `2^(int::BITS-1) - 1` |
416 | `int::VALUE_COUNT` | Integer | the number of different values `int` can store (`2^int::BITS`). too big to fit in `int`. |
417 | `rint(fp, rounding_mode)` | `fp` | rounds the floating-point value `fp` to an integer according to rounding mode `rounding_mode` |
418
419 <div id="fp-to-int-openpower-conversion-semantics"></div>
420 OpenPower conversion semantics (section A.2 page 1009 (page 1035) of
421 Power ISA v3.1B):
422
423 ```
424 def fp_to_int_open_power<fp, int>(v: fp) -> int:
425 if v is NaN:
426 return int::MIN_VALUE
427 if v >= int::MAX_VALUE:
428 return int::MAX_VALUE
429 if v <= int::MIN_VALUE:
430 return int::MIN_VALUE
431 return (int)rint(v, rounding_mode)
432 ```
433
434 <div id="fp-to-int-java-saturating-conversion-semantics"></div>
435 [Java/Saturating conversion semantics](https://docs.oracle.com/javase/specs/jls/se16/html/jls-5.html#jls-5.1.3)
436 (only for long/int results)
437 (with adjustment to add non-truncate rounding modes):
438
439 ```
440 def fp_to_int_java_saturating<fp, int>(v: fp) -> int:
441 if v is NaN:
442 return 0
443 if v >= int::MAX_VALUE:
444 return int::MAX_VALUE
445 if v <= int::MIN_VALUE:
446 return int::MIN_VALUE
447 return (int)rint(v, rounding_mode)
448 ```
449
450 <div id="fp-to-int-javascript-conversion-semantics"></div>
451 Section 7.1 of the ECMAScript / JavaScript
452 [conversion semantics](https://262.ecma-international.org/11.0/#sec-toint32)
453 (with adjustment to add non-truncate rounding modes):
454
455 ```
456 def fp_to_int_java_script<fp, int>(v: fp) -> int:
457 if v is NaN or infinite:
458 return 0
459 v = rint(v, rounding_mode) # assume no loss of precision in result
460 v = v mod int::VALUE_COUNT # 2^32 for i32, 2^64 for i64, result is non-negative
461 bits = (uint)v
462 return (int)bits
463 ```
464
465 ----------
466
467 \newpage{}
468
469 ## Convert From FPR
470
471 ```
472 cffpr RT, FRB, CVM, IT
473 cffpr. RT, FRB, CVM, IT
474 cffpro RT, FRB, CVM, IT
475 cffpro. RT, FRB, CVM, IT
476 ```
477
478 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21 | 22-30 | 31 | Form |
479 |-----|------|-------|-------|-------|----|-------|----|---------|
480 | PO | RT | IT | CVM | FRB | OE | XO | Rc | XO-Form |
481
482 ```
483 # based on xscvdpuxws
484 reset_xflags()
485 src <- bfp_CONVERT_FROM_BFP64((FRB))
486
487 switch(IT)
488 case(0): # Signed 32-bit
489 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
490 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
491 js_mask <- 0x0000_0000_FFFF_FFFF
492 case(1): # Unsigned 32-bit
493 range_min <- bfp_CONVERT_FROM_UI32(0)
494 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
495 js_mask <- 0x0000_0000_FFFF_FFFF
496 case(2): # Signed 64-bit
497 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
498 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
499 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
500 default: # Unsigned 64-bit
501 range_min <- bfp_CONVERT_FROM_UI64(0)
502 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
503 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
504
505 if (CVM[2] = 1) | (FPSCR.RN = 0b01) then
506 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
507 else if FPSCR.RN = 0b00 then
508 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
509 else if FPSCR.RN = 0b10 then
510 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
511 else if FPSCR.RN = 0b11 then
512 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
513
514 switch(CVM)
515 case(0, 1): # OpenPower semantics
516 if IsNaN(rnd) then
517 result <- si64_CONVERT_FROM_BFP(range_min)
518 else if bfp_COMPARE_GT(rnd, range_max) then
519 result <- ui64_CONVERT_FROM_BFP(range_max)
520 else if bfp_COMPARE_LT(rnd, range_min) then
521 result <- si64_CONVERT_FROM_BFP(range_min)
522 else if IT[1] = 1 then # Unsigned 32/64-bit
523 result <- ui64_CONVERT_FROM_BFP(rnd)
524 else # Signed 32/64-bit
525 result <- si64_CONVERT_FROM_BFP(rnd)
526 case(2, 3): # Java/Saturating semantics
527 if IsNaN(rnd) then
528 result <- [0] * 64
529 else if bfp_COMPARE_GT(rnd, range_max) then
530 result <- ui64_CONVERT_FROM_BFP(range_max)
531 else if bfp_COMPARE_LT(rnd, range_min) then
532 result <- si64_CONVERT_FROM_BFP(range_min)
533 else if IT[1] = 1 then # Unsigned 32/64-bit
534 result <- ui64_CONVERT_FROM_BFP(rnd)
535 else # Signed 32/64-bit
536 result <- si64_CONVERT_FROM_BFP(rnd)
537 default: # JavaScript semantics
538 # CVM = 6, 7 are illegal instructions
539 # using a 128-bit intermediate works here because the largest type
540 # this instruction can convert from has 53 significand bits, and
541 # the largest type this instruction can convert to has 64 bits,
542 # and the sum of those is strictly less than the 128 bits of the
543 # intermediate result.
544 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
545 if IsInf(rnd) | IsNaN(rnd) then
546 result <- [0] * 64
547 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
548 result <- [0] * 64
549 else
550 result128 <- si128_CONVERT_FROM_BFP(rnd)
551 result <- result128[64:127] & js_mask
552
553 switch(IT)
554 case(0): # Signed 32-bit
555 result <- EXTS64(result[32:63])
556 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
557 case(1): # Unsigned 32-bit
558 result <- EXTZ64(result[32:63])
559 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
560 case(2): # Signed 64-bit
561 result_bfp <- bfp_CONVERT_FROM_SI64(result)
562 default: # Unsigned 64-bit
563 result_bfp <- bfp_CONVERT_FROM_UI64(result)
564
565 overflow <- 0 # signals SO only when OE = 1
566 if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
567 overflow <- 1 # signals SO only when OE = 1
568 vxcvi_flag <- 1
569 xx_flag <- 0
570 inc_flag <- 0
571 else
572 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
573 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
574
575 if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
576 if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
577 if xx_flag = 1 then SetFX(FPSCR.XX)
578
579 vx_flag <- vxsnan_flag | vxcvi_flag
580 vex_flag <- FPSCR.VE & vx_flag
581 if vex_flag = 0 then
582 RT <- result
583 FPSCR.FPRF <- undefined
584 FPSCR.FR <- inc_flag
585 FPSCR.FI <- xx_flag
586 else
587 FPSCR.FR <- 0
588 FPSCR.FI <- 0
589 ```
590
591 Convert from 64-bit float in FRB to a unsigned/signed 32/64-bit integer
592 in RT, with the conversion overflow/rounding semantics following the
593 chosen `CVM` value. `FPSCR` is modified and exceptions are raised as usual.
594
595 These instructions have an Rc=1 mode which sets CR0 in the normal
596 way for any instructions producing a GPR result. Additionally, when OE=1,
597 if the numerical value of the FP number is not 100% accurately preserved
598 (due to truncation or saturation and including when the FP number was
599 NaN) then this is considered to be an Integer Overflow condition, and
600 CR0.SO, XER.SO and XER.OV are all set as normal for any GPR instructions
601 that overflow. When `RT` is not written (`vex_flag = 1`), all CR0 bits
602 except SO are undefined.
603
604 Special Registers altered:
605
606 ```
607 CR0 (if Rc=1)
608 XER SO, OV, OV32 (if OE=1)
609 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
610 ```
611
612 ### Assembly Aliases
613
614 | Assembly Alias | Full Instruction |
615 |--------------------------|---------------------------|
616 | `cffprw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 0` |
617 | `cffprw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 0` |
618 | `cffprwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 0` |
619 | `cffprwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 0` |
620 | `cffpruw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 1` |
621 | `cffpruw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 1` |
622 | `cffpruwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 1` |
623 | `cffpruwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 1` |
624 | `cffprd RT, FRB, CVM` | `cffpr RT, FRB, CVM, 2` |
625 | `cffprd. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 2` |
626 | `cffprdo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 2` |
627 | `cffprdo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 2` |
628 | `cffprud RT, FRB, CVM` | `cffpr RT, FRB, CVM, 3` |
629 | `cffprud. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 3` |
630 | `cffprudo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 3` |
631 | `cffprudo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 3` |