bug 1015:deferring the TODO, it can wait. spelling. whitespace
[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 ```
341 # based on xscvdpuxws
342 reset_xflags()
343 src <- bfp_CONVERT_FROM_BFP64((FRB))
344
345 switch(IT)
346 case(0): # Signed 32-bit
347 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
348 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
349 js_mask <- 0x0000_0000_FFFF_FFFF
350 case(1): # Unsigned 32-bit
351 range_min <- bfp_CONVERT_FROM_UI32(0)
352 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
353 js_mask <- 0x0000_0000_FFFF_FFFF
354 case(2): # Signed 64-bit
355 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
356 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
357 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
358 default: # Unsigned 64-bit
359 range_min <- bfp_CONVERT_FROM_UI64(0)
360 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
361 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
362
363 if (CVM[2] = 1) | (FPSCR.RN = 0b01) then
364 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
365 else if FPSCR.RN = 0b00 then
366 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
367 else if FPSCR.RN = 0b10 then
368 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
369 else if FPSCR.RN = 0b11 then
370 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
371
372 switch(CVM)
373 case(0, 1): # P-Type
374 if IsNaN(rnd) then
375 result <- si64_CONVERT_FROM_BFP(range_min)
376 else if bfp_COMPARE_GT(rnd, range_max) then
377 result <- ui64_CONVERT_FROM_BFP(range_max)
378 else if bfp_COMPARE_LT(rnd, range_min) then
379 result <- si64_CONVERT_FROM_BFP(range_min)
380 else if IT[1] = 1 then # Unsigned 32/64-bit
381 result <- ui64_CONVERT_FROM_BFP(rnd)
382 else # Signed 32/64-bit
383 result <- si64_CONVERT_FROM_BFP(rnd)
384 case(2, 3): # S-Type
385 if IsNaN(rnd) then
386 result <- [0] * 64
387 else if bfp_COMPARE_GT(rnd, range_max) then
388 result <- ui64_CONVERT_FROM_BFP(range_max)
389 else if bfp_COMPARE_LT(rnd, range_min) then
390 result <- si64_CONVERT_FROM_BFP(range_min)
391 else if IT[1] = 1 then # Unsigned 32/64-bit
392 result <- ui64_CONVERT_FROM_BFP(rnd)
393 else # Signed 32/64-bit
394 result <- si64_CONVERT_FROM_BFP(rnd)
395 default: # E-Type
396 # CVM = 6, 7 are illegal instructions
397 # using a 128-bit intermediate works here because the largest type
398 # this instruction can convert from has 53 significand bits, and
399 # the largest type this instruction can convert to has 64 bits,
400 # and the sum of those is strictly less than the 128 bits of the
401 # intermediate result.
402 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
403 if IsInf(rnd) | IsNaN(rnd) then
404 result <- [0] * 64
405 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
406 result <- [0] * 64
407 else
408 result128 <- si128_CONVERT_FROM_BFP(rnd)
409 result <- result128[64:127] & js_mask
410
411 switch(IT)
412 case(0): # Signed 32-bit
413 result <- EXTS64(result[32:63])
414 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
415 case(1): # Unsigned 32-bit
416 result <- EXTZ64(result[32:63])
417 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
418 case(2): # Signed 64-bit
419 result_bfp <- bfp_CONVERT_FROM_SI64(result)
420 default: # Unsigned 64-bit
421 result_bfp <- bfp_CONVERT_FROM_UI64(result)
422
423 overflow <- 0 # signals SO only when OE = 1
424 if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
425 overflow <- 1 # signals SO only when OE = 1
426 vxcvi_flag <- 1
427 xx_flag <- 0
428 inc_flag <- 0
429 else
430 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
431 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
432
433 if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
434 if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
435 if xx_flag = 1 then SetFX(FPSCR.XX)
436
437 vx_flag <- vxsnan_flag | vxcvi_flag
438 vex_flag <- FPSCR.VE & vx_flag
439 if vex_flag = 0 then
440 RT <- result
441 FPSCR.FPRF <- undefined
442 FPSCR.FR <- inc_flag
443 FPSCR.FI <- xx_flag
444 else
445 FPSCR.FR <- 0
446 FPSCR.FI <- 0
447 ```
448
449 Convert from 64-bit float in FRB to a unsigned/signed 32/64-bit integer
450 in RT, with the conversion overflow/rounding semantics following the
451 chosen `CVM` value. `FPSCR` is modified and exceptions are raised as usual.
452
453 This instruction has an Rc=1 mode which sets CR0 in the normal
454 way for any instructions producing a GPR result. Additionally, when OE=1,
455 if the numerical value of the FP number is not 100% accurately preserved
456 (due to truncation or saturation and including when the FP number was
457 NaN) then this is considered to be an Integer Overflow condition, and
458 CR0.SO, XER.SO and XER.OV are all set as normal for any GPR instructions
459 that overflow. When `RT` is not written (`vex_flag = 1`), all CR0 bits
460 except SO are undefined.
461
462 Special Registers altered:
463
464 ```
465 CR0 (if Rc=1)
466 XER SO, OV, OV32 (if OE=1)
467 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
468 ```
469
470 ### Assembly Aliases
471
472 | Assembly Alias | Full Instruction |
473 |--------------------------|---------------------------|
474 | `cffprw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 0` |
475 | `cffprw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 0` |
476 | `cffprwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 0` |
477 | `cffprwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 0` |
478 | `cffpruw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 1` |
479 | `cffpruw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 1` |
480 | `cffpruwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 1` |
481 | `cffpruwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 1` |
482 | `cffprd RT, FRB, CVM` | `cffpr RT, FRB, CVM, 2` |
483 | `cffprd. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 2` |
484 | `cffprdo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 2` |
485 | `cffprdo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 2` |
486 | `cffprud RT, FRB, CVM` | `cffpr RT, FRB, CVM, 3` |
487 | `cffprud. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 3` |
488 | `cffprudo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 3` |
489 | `cffprudo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 3` |
490