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