ae74582d0a700eb5e198860a865575ffce9d8c81
[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` | [P-Type] |
21 | 001 | Truncate | [P-Type] |
22 | 010 | from `FPSCR` | [S-Type] |
23 | 011 | Truncate | [S-Type] |
24 | 100 | from `FPSCR` | [E-Type] |
25 | 101 | Truncate | [E-Type] |
26 | rest | -- | invalid |
27
28 [P-Type]: #fpr-to-gpr-conversion-p-type
29 [S-Type]: #fpr-to-gpr-conversion-s-type
30 [E-Type]: #fpr-to-gpr-conversion-e-type
31
32 ----------
33
34 \newpage{}
35
36 # Move To/From Floating-Point Register Instructions
37
38 These instructions perform a copy from one register file to another, as if by
39 using a GPR/FPR store, followed by a FPR/GPR load.
40
41 ## Move From Floating-Point Register
42
43 ```
44 mffpr RT, FRB
45 mffpr. RT, FRB
46 ```
47
48 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
49 |-----|------|-------|-------|-------|----|--------|
50 | PO | RT | // | FRB | XO | Rc | X-Form |
51
52 ```
53 RT <- (FRB)
54 ```
55
56 The contents of `FPR[FRB]` are placed into `GPR[RT]`.
57
58 Special Registers altered:
59
60 ```
61 CR0 (if Rc=1)
62 ```
63
64 Architecture Note:
65
66 `mffpr` is equivalent to the combination of `stfd` followed by `ld`.
67
68 Architecture Note:
69
70 `mffpr` is a separate instruction from `mfvsrd` because `mfvsrd` requires
71 VSX which may not be available on simpler implementations.
72 Additionally, SVP64 may treat VSX instructions differently than SFFS
73 instructions in a future version of the architecture.
74
75 ----------
76
77 ## Move From Floating-Point Register Single
78
79 ```
80 mffprs RT, FRB
81 mffprs. RT, FRB
82 ```
83
84 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
85 |-----|------|-------|-------|-------|----|--------|
86 | PO | RT | // | FRB | XO | Rc | X-Form |
87
88 ```
89 RT <- [0] * 32 || SINGLE((FRB))
90 ```
91
92 The contents of `FPR[FRB]` are converted to BFP32 by using `SINGLE`, then
93 zero-extended to 64-bits, and the result stored in `GPR[RT]`.
94
95 Special Registers altered:
96
97 ```
98 CR0 (if Rc=1)
99 ```
100
101 Architecture Note:
102
103 `mffprs` is equivalent to the combination of `stfs` followed by `lwz`.
104
105 ----------
106
107 \newpage{}
108
109 ## Move To Floating-Point Register
110
111 ```
112 mtfpr FRT, RB
113 ```
114
115 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
116 |-----|------|-------|-------|-------|----|--------|
117 | PO | FRT | // | RB | XO | // | X-Form |
118
119 ```
120 FRT <- (RB)
121 ```
122
123 The contents of `GPR[RB]` are placed into `FPR[FRT]`.
124
125 Special Registers altered:
126
127 ```
128 None
129 ```
130
131 Architecture Note:
132
133 `mtfpr` is equivalent to the combination of `std` followed by `lfd`.
134
135 Architecture Note:
136
137 `mtfpr` is a separate instruction from `mtvsrd` because `mtvsrd` requires
138 VSX which may not be available on simpler implementations.
139 Additionally, SVP64 may treat VSX instructions differently than SFFS
140 instructions in a future version of the architecture.
141
142 ----------
143
144 ## Move To Floating-Point Register Single
145
146 ```
147 mtfprs FRT, RB
148 ```
149
150 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
151 |-----|------|-------|-------|-------|----|--------|
152 | PO | FRT | // | RB | XO | // | X-Form |
153
154 ```
155 FRT <- DOUBLE((RB)[32:63])
156 ```
157
158 The contents of bits 32:63 of `GPR[RB]` are converted to BFP64 by using
159 `DOUBLE`, then the result is stored in `GPR[RT]`.
160
161 Special Registers altered:
162
163 ```
164 None
165 ```
166
167 Architecture Note:
168
169 `mtfprs` is equivalent to the combination of `stw` followed by `lfs`.
170
171 ----------
172
173 \newpage{}
174
175 # Conversion To/From Floating-Point Register Instructions
176
177 ## Convert To Floating-Point Register
178
179 ```
180 ctfpr FRT, RB, IT
181 ctfpr. FRT, RB, IT
182 ```
183
184 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
185 |-----|------|-------|-------|-------|-------|----|--------|
186 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
187
188 ```
189 if IT[0] = 0 then # 32-bit int -> 64-bit float
190 # rounding never necessary, so don't touch FPSCR
191 # based off xvcvsxwdp
192 if IT = 0 then # Signed 32-bit
193 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
194 else # IT = 1 -- Unsigned 32-bit
195 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
196 FRT <- bfp64_CONVERT_FROM_BFP(src)
197 else
198 # rounding may be necessary. based off xscvuxdsp
199 reset_xflags()
200 switch(IT)
201 case(0): # Signed 32-bit
202 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
203 case(1): # Unsigned 32-bit
204 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
205 case(2): # Signed 64-bit
206 src <- bfp_CONVERT_FROM_SI64((RB))
207 default: # Unsigned 64-bit
208 src <- bfp_CONVERT_FROM_UI64((RB))
209 rnd <- bfp_ROUND_TO_BFP64(0b0, FPSCR.RN, src)
210 result <- bfp64_CONVERT_FROM_BFP(rnd)
211 cls <- fprf_CLASS_BFP64(result)
212
213 if xx_flag = 1 then SetFX(FPSCR.XX)
214
215 FRT <- result
216 FPSCR.FPRF <- cls
217 FPSCR.FR <- inc_flag
218 FPSCR.FI <- xx_flag
219 ```
220 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
221 don't remove them -->
222
223 Convert from a unsigned/signed 32/64-bit integer in RB to a 64-bit
224 float in FRT.
225
226 If converting from a unsigned/signed 32-bit integer to a 64-bit float,
227 rounding is never necessary, so `FPSCR` is unmodified and exceptions are
228 never raised. Otherwise, `FPSCR` is modified and exceptions are raised
229 as usual.
230
231 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
232 operations.
233
234 Special Registers altered:
235
236 ```
237 CR1 (if Rc=1)
238 FPRF FR FI FX XX (if IT[0]=1)
239 ```
240
241 ### Assembly Aliases
242
243 | Assembly Alias | Full Instruction |
244 |--------------------|---------------------|
245 | `ctfprw FRT, RB` | `ctfpr FRT, RB, 0` |
246 | `ctfprw. FRT, RB` | `ctfpr. FRT, RB, 0` |
247 | `ctfpruw FRT, RB` | `ctfpr FRT, RB, 1` |
248 | `ctfpruw. FRT, RB` | `ctfpr. FRT, RB, 1` |
249 | `ctfprd FRT, RB` | `ctfpr FRT, RB, 2` |
250 | `ctfprd. FRT, RB` | `ctfpr. FRT, RB, 2` |
251 | `ctfprud FRT, RB` | `ctfpr FRT, RB, 3` |
252 | `ctfprud. FRT, RB` | `ctfpr. FRT, RB, 3` |
253
254 ----------
255
256 \newpage{}
257
258 ## Convert To Floating-Point Register Single
259
260 ```
261 ctfprs FRT, RB, IT
262 ctfprs. FRT, RB, IT
263 ```
264
265 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
266 |-----|------|-------|-------|-------|-------|----|--------|
267 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
268
269 ```
270 # rounding may be necessary. based off xscvuxdsp
271 reset_xflags()
272 switch(IT)
273 case(0): # Signed 32-bit
274 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
275 case(1): # Unsigned 32-bit
276 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
277 case(2): # Signed 64-bit
278 src <- bfp_CONVERT_FROM_SI64((RB))
279 default: # Unsigned 64-bit
280 src <- bfp_CONVERT_FROM_UI64((RB))
281 rnd <- bfp_ROUND_TO_BFP32(FPSCR.RN, src)
282 result32 <- bfp32_CONVERT_FROM_BFP(rnd)
283 cls <- fprf_CLASS_BFP32(result32)
284 result <- DOUBLE(result32)
285
286 if xx_flag = 1 then SetFX(FPSCR.XX)
287
288 FRT <- result
289 FPSCR.FPRF <- cls
290 FPSCR.FR <- inc_flag
291 FPSCR.FI <- xx_flag
292 ```
293 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
294 don't remove them -->
295
296 Convert from a unsigned/signed 32/64-bit integer in RB to a 32-bit
297 float in FRT, following the usual 32-bit float in 64-bit float format.
298 `FPSCR` is modified and exceptions are raised as usual.
299
300 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
301 operations.
302
303 Special Registers altered:
304
305 ```
306 CR1 (if Rc=1)
307 FPRF FR FI FX XX
308 ```
309
310 ### Assembly Aliases
311
312 | Assembly Alias | Full Instruction |
313 |---------------------|---------------------|
314 | `ctfprws FRT, RB` | `ctfpr FRT, RB, 0` |
315 | `ctfprws. FRT, RB` | `ctfpr. FRT, RB, 0` |
316 | `ctfpruws FRT, RB` | `ctfpr FRT, RB, 1` |
317 | `ctfpruws. FRT, RB` | `ctfpr. FRT, RB, 1` |
318 | `ctfprds FRT, RB` | `ctfpr FRT, RB, 2` |
319 | `ctfprds. FRT, RB` | `ctfpr. FRT, RB, 2` |
320 | `ctfpruds FRT, RB` | `ctfpr FRT, RB, 3` |
321 | `ctfpruds. FRT, RB` | `ctfpr. FRT, RB, 3` |
322
323 ----------
324
325 \newpage{}
326
327 ## Convert From Floating-Point Register
328
329 ```
330 cffpr RT, FRB, CVM, IT
331 cffpr. RT, FRB, CVM, IT
332 cffpro RT, FRB, CVM, IT
333 cffpro. RT, FRB, CVM, IT
334 ```
335
336 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21 | 22-30 | 31 | Form |
337 |-----|------|-------|-------|-------|----|-------|----|---------|
338 | PO | RT | IT | CVM | FRB | OE | XO | Rc | XO-Form |
339
340 **TODO: move to Appendix (it's too large. also it really should be executable
341 and pulled in "automatically" from the openpower-isa directory, into the
342 PDF but also as an ikiwiki underlay - just not here: in the RFC directory)**
343
344 For the pseudocode of this instruction see Appendix {insert automated reference}
345
346 ```
347 # based on xscvdpuxws
348 reset_xflags()
349 src <- bfp_CONVERT_FROM_BFP64((FRB))
350
351 switch(IT)
352 case(0): # Signed 32-bit
353 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
354 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
355 js_mask <- 0x0000_0000_FFFF_FFFF
356 case(1): # Unsigned 32-bit
357 range_min <- bfp_CONVERT_FROM_UI32(0)
358 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
359 js_mask <- 0x0000_0000_FFFF_FFFF
360 case(2): # Signed 64-bit
361 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
362 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
363 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
364 default: # Unsigned 64-bit
365 range_min <- bfp_CONVERT_FROM_UI64(0)
366 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
367 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
368
369 if (CVM[2] = 1) | (FPSCR.RN = 0b01) then
370 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
371 else if FPSCR.RN = 0b00 then
372 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
373 else if FPSCR.RN = 0b10 then
374 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
375 else if FPSCR.RN = 0b11 then
376 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
377
378 switch(CVM)
379 case(0, 1): # P-Type
380 if IsNaN(rnd) then
381 result <- si64_CONVERT_FROM_BFP(range_min)
382 else if bfp_COMPARE_GT(rnd, range_max) then
383 result <- ui64_CONVERT_FROM_BFP(range_max)
384 else if bfp_COMPARE_LT(rnd, range_min) then
385 result <- si64_CONVERT_FROM_BFP(range_min)
386 else if IT[1] = 1 then # Unsigned 32/64-bit
387 result <- ui64_CONVERT_FROM_BFP(rnd)
388 else # Signed 32/64-bit
389 result <- si64_CONVERT_FROM_BFP(rnd)
390 case(2, 3): # S-Type
391 if IsNaN(rnd) then
392 result <- [0] * 64
393 else if bfp_COMPARE_GT(rnd, range_max) then
394 result <- ui64_CONVERT_FROM_BFP(range_max)
395 else if bfp_COMPARE_LT(rnd, range_min) then
396 result <- si64_CONVERT_FROM_BFP(range_min)
397 else if IT[1] = 1 then # Unsigned 32/64-bit
398 result <- ui64_CONVERT_FROM_BFP(rnd)
399 else # Signed 32/64-bit
400 result <- si64_CONVERT_FROM_BFP(rnd)
401 default: # E-Type
402 # CVM = 6, 7 are illegal instructions
403 # using a 128-bit intermediate works here because the largest type
404 # this instruction can convert from has 53 significand bits, and
405 # the largest type this instruction can convert to has 64 bits,
406 # and the sum of those is strictly less than the 128 bits of the
407 # intermediate result.
408 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
409 if IsInf(rnd) | IsNaN(rnd) then
410 result <- [0] * 64
411 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
412 result <- [0] * 64
413 else
414 result128 <- si128_CONVERT_FROM_BFP(rnd)
415 result <- result128[64:127] & js_mask
416
417 switch(IT)
418 case(0): # Signed 32-bit
419 result <- EXTS64(result[32:63])
420 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
421 case(1): # Unsigned 32-bit
422 result <- EXTZ64(result[32:63])
423 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
424 case(2): # Signed 64-bit
425 result_bfp <- bfp_CONVERT_FROM_SI64(result)
426 default: # Unsigned 64-bit
427 result_bfp <- bfp_CONVERT_FROM_UI64(result)
428
429 overflow <- 0 # signals SO only when OE = 1
430 if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
431 overflow <- 1 # signals SO only when OE = 1
432 vxcvi_flag <- 1
433 xx_flag <- 0
434 inc_flag <- 0
435 else
436 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
437 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
438
439 if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
440 if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
441 if xx_flag = 1 then SetFX(FPSCR.XX)
442
443 vx_flag <- vxsnan_flag | vxcvi_flag
444 vex_flag <- FPSCR.VE & vx_flag
445 if vex_flag = 0 then
446 RT <- result
447 FPSCR.FPRF <- undefined
448 FPSCR.FR <- inc_flag
449 FPSCR.FI <- xx_flag
450 else
451 FPSCR.FR <- 0
452 FPSCR.FI <- 0
453 ```
454
455 Convert from 64-bit float in FRB to a unsigned/signed 32/64-bit integer
456 in RT, with the conversion overflow/rounding semantics following the
457 chosen `CVM` value. `FPSCR` is modified and exceptions are raised as usual.
458
459 This instruction has an Rc=1 mode which sets CR0 in the normal
460 way for any instructions producing a GPR result. Additionally, when OE=1,
461 if the numerical value of the FP number is not 100% accurately preserved
462 (due to truncation or saturation and including when the FP number was
463 NaN) then this is considered to be an Integer Overflow condition, and
464 CR0.SO, XER.SO and XER.OV are all set as normal for any GPR instructions
465 that overflow. When `RT` is not written (`vex_flag = 1`), all CR0 bits
466 except SO are undefined.
467
468 Special Registers altered:
469
470 ```
471 CR0 (if Rc=1)
472 XER SO, OV, OV32 (if OE=1)
473 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
474 ```
475
476 ### Assembly Aliases
477
478 | Assembly Alias | Full Instruction |
479 |--------------------------|---------------------------|
480 | `cffprw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 0` |
481 | `cffprw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 0` |
482 | `cffprwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 0` |
483 | `cffprwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 0` |
484 | `cffpruw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 1` |
485 | `cffpruw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 1` |
486 | `cffpruwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 1` |
487 | `cffpruwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 1` |
488 | `cffprd RT, FRB, CVM` | `cffpr RT, FRB, CVM, 2` |
489 | `cffprd. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 2` |
490 | `cffprdo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 2` |
491 | `cffprdo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 2` |
492 | `cffprud RT, FRB, CVM` | `cffpr RT, FRB, CVM, 3` |
493 | `cffprud. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 3` |
494 | `cffprudo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 3` |
495 | `cffprudo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 3` |
496