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