extract fp->int conversion overview to separate page
[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 # Move To/From Floating-Point Register Instructions
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 Floating-Point Register
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 Floating-Point Register 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 Floating-Point Register
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 Floating-Point Register 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 # Conversion To/From Floating-Point Register Instructions
174
175 ## Convert To Floating-Point Register
176
177 ```
178 ctfpr FRT, RB, IT
179 ctfpr. FRT, RB, IT
180 ```
181
182 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
183 |-----|------|-------|-------|-------|-------|----|--------|
184 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
185
186 ```
187 if IT[0] = 0 then # 32-bit int -> 64-bit float
188 # rounding never necessary, so don't touch FPSCR
189 # based off xvcvsxwdp
190 if IT = 0 then # Signed 32-bit
191 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
192 else # IT = 1 -- Unsigned 32-bit
193 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
194 FRT <- bfp64_CONVERT_FROM_BFP(src)
195 else
196 # rounding may be necessary. based off xscvuxdsp
197 reset_xflags()
198 switch(IT)
199 case(0): # Signed 32-bit
200 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
201 case(1): # Unsigned 32-bit
202 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
203 case(2): # Signed 64-bit
204 src <- bfp_CONVERT_FROM_SI64((RB))
205 default: # Unsigned 64-bit
206 src <- bfp_CONVERT_FROM_UI64((RB))
207 rnd <- bfp_ROUND_TO_BFP64(0b0, FPSCR.RN, src)
208 result <- bfp64_CONVERT_FROM_BFP(rnd)
209 cls <- fprf_CLASS_BFP64(result)
210
211 if xx_flag = 1 then SetFX(FPSCR.XX)
212
213 FRT <- result
214 FPSCR.FPRF <- cls
215 FPSCR.FR <- inc_flag
216 FPSCR.FI <- xx_flag
217 ```
218 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
219 don't remove them -->
220
221 Convert from a unsigned/signed 32/64-bit integer in RB to a 64-bit
222 float in FRT.
223
224 If converting from a unsigned/signed 32-bit integer to a 64-bit float,
225 rounding is never necessary, so `FPSCR` is unmodified and exceptions are
226 never raised. Otherwise, `FPSCR` is modified and exceptions are raised
227 as usual.
228
229 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
230 operations.
231
232 Special Registers altered:
233
234 ```
235 CR1 (if Rc=1)
236 FPRF FR FI FX XX (if IT[0]=1)
237 ```
238
239 ### Assembly Aliases
240
241 | Assembly Alias | Full Instruction |
242 |--------------------|---------------------|
243 | `ctfprw FRT, RB` | `ctfpr FRT, RB, 0` |
244 | `ctfprw. FRT, RB` | `ctfpr. FRT, RB, 0` |
245 | `ctfpruw FRT, RB` | `ctfpr FRT, RB, 1` |
246 | `ctfpruw. FRT, RB` | `ctfpr. FRT, RB, 1` |
247 | `ctfprd FRT, RB` | `ctfpr FRT, RB, 2` |
248 | `ctfprd. FRT, RB` | `ctfpr. FRT, RB, 2` |
249 | `ctfprud FRT, RB` | `ctfpr FRT, RB, 3` |
250 | `ctfprud. FRT, RB` | `ctfpr. FRT, RB, 3` |
251
252 ----------
253
254 \newpage{}
255
256 ## Convert To Floating-Point Register Single
257
258 ```
259 ctfprs FRT, RB, IT
260 ctfprs. FRT, RB, IT
261 ```
262
263 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21-30 | 31 | Form |
264 |-----|------|-------|-------|-------|-------|----|--------|
265 | PO | FRT | IT | // | RB | XO | Rc | X-Form |
266
267 ```
268 # rounding may be necessary. based off xscvuxdsp
269 reset_xflags()
270 switch(IT)
271 case(0): # Signed 32-bit
272 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
273 case(1): # Unsigned 32-bit
274 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
275 case(2): # Signed 64-bit
276 src <- bfp_CONVERT_FROM_SI64((RB))
277 default: # Unsigned 64-bit
278 src <- bfp_CONVERT_FROM_UI64((RB))
279 rnd <- bfp_ROUND_TO_BFP32(FPSCR.RN, src)
280 result32 <- bfp32_CONVERT_FROM_BFP(rnd)
281 cls <- fprf_CLASS_BFP32(result32)
282 result <- DOUBLE(result32)
283
284 if xx_flag = 1 then SetFX(FPSCR.XX)
285
286 FRT <- result
287 FPSCR.FPRF <- cls
288 FPSCR.FR <- inc_flag
289 FPSCR.FI <- xx_flag
290 ```
291 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
292 don't remove them -->
293
294 Convert from a unsigned/signed 32/64-bit integer in RB to a 32-bit
295 float in FRT, following the usual 32-bit float in 64-bit float format.
296 `FPSCR` is modified and exceptions are raised as usual.
297
298 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
299 operations.
300
301 Special Registers altered:
302
303 ```
304 CR1 (if Rc=1)
305 FPRF FR FI FX XX
306 ```
307
308 ### Assembly Aliases
309
310 | Assembly Alias | Full Instruction |
311 |---------------------|---------------------|
312 | `ctfprws FRT, RB` | `ctfpr FRT, RB, 0` |
313 | `ctfprws. FRT, RB` | `ctfpr. FRT, RB, 0` |
314 | `ctfpruws FRT, RB` | `ctfpr FRT, RB, 1` |
315 | `ctfpruws. FRT, RB` | `ctfpr. FRT, RB, 1` |
316 | `ctfprds FRT, RB` | `ctfpr FRT, RB, 2` |
317 | `ctfprds. FRT, RB` | `ctfpr. FRT, RB, 2` |
318 | `ctfpruds FRT, RB` | `ctfpr FRT, RB, 3` |
319 | `ctfpruds. FRT, RB` | `ctfpr. FRT, RB, 3` |
320
321 ----------
322
323 \newpage{}
324
325 ## Convert From Floating-Point Register
326
327 ```
328 cffpr RT, FRB, CVM, IT
329 cffpr. RT, FRB, CVM, IT
330 cffpro RT, FRB, CVM, IT
331 cffpro. RT, FRB, CVM, IT
332 ```
333
334 | 0-5 | 6-10 | 11-12 | 13-15 | 16-20 | 21 | 22-30 | 31 | Form |
335 |-----|------|-------|-------|-------|----|-------|----|---------|
336 | PO | RT | IT | CVM | FRB | OE | XO | Rc | XO-Form |
337
338 ```
339 # based on xscvdpuxws
340 reset_xflags()
341 src <- bfp_CONVERT_FROM_BFP64((FRB))
342
343 switch(IT)
344 case(0): # Signed 32-bit
345 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
346 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
347 js_mask <- 0x0000_0000_FFFF_FFFF
348 case(1): # Unsigned 32-bit
349 range_min <- bfp_CONVERT_FROM_UI32(0)
350 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
351 js_mask <- 0x0000_0000_FFFF_FFFF
352 case(2): # Signed 64-bit
353 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
354 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
355 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
356 default: # Unsigned 64-bit
357 range_min <- bfp_CONVERT_FROM_UI64(0)
358 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
359 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
360
361 if (CVM[2] = 1) | (FPSCR.RN = 0b01) then
362 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
363 else if FPSCR.RN = 0b00 then
364 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
365 else if FPSCR.RN = 0b10 then
366 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
367 else if FPSCR.RN = 0b11 then
368 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
369
370 switch(CVM)
371 case(0, 1): # OpenPower semantics
372 if IsNaN(rnd) then
373 result <- si64_CONVERT_FROM_BFP(range_min)
374 else if bfp_COMPARE_GT(rnd, range_max) then
375 result <- ui64_CONVERT_FROM_BFP(range_max)
376 else if bfp_COMPARE_LT(rnd, range_min) then
377 result <- si64_CONVERT_FROM_BFP(range_min)
378 else if IT[1] = 1 then # Unsigned 32/64-bit
379 result <- ui64_CONVERT_FROM_BFP(rnd)
380 else # Signed 32/64-bit
381 result <- si64_CONVERT_FROM_BFP(rnd)
382 case(2, 3): # Java/Saturating semantics
383 if IsNaN(rnd) then
384 result <- [0] * 64
385 else if bfp_COMPARE_GT(rnd, range_max) then
386 result <- ui64_CONVERT_FROM_BFP(range_max)
387 else if bfp_COMPARE_LT(rnd, range_min) then
388 result <- si64_CONVERT_FROM_BFP(range_min)
389 else if IT[1] = 1 then # Unsigned 32/64-bit
390 result <- ui64_CONVERT_FROM_BFP(rnd)
391 else # Signed 32/64-bit
392 result <- si64_CONVERT_FROM_BFP(rnd)
393 default: # JavaScript semantics
394 # CVM = 6, 7 are illegal instructions
395 # using a 128-bit intermediate works here because the largest type
396 # this instruction can convert from has 53 significand bits, and
397 # the largest type this instruction can convert to has 64 bits,
398 # and the sum of those is strictly less than the 128 bits of the
399 # intermediate result.
400 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
401 if IsInf(rnd) | IsNaN(rnd) then
402 result <- [0] * 64
403 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
404 result <- [0] * 64
405 else
406 result128 <- si128_CONVERT_FROM_BFP(rnd)
407 result <- result128[64:127] & js_mask
408
409 switch(IT)
410 case(0): # Signed 32-bit
411 result <- EXTS64(result[32:63])
412 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
413 case(1): # Unsigned 32-bit
414 result <- EXTZ64(result[32:63])
415 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
416 case(2): # Signed 64-bit
417 result_bfp <- bfp_CONVERT_FROM_SI64(result)
418 default: # Unsigned 64-bit
419 result_bfp <- bfp_CONVERT_FROM_UI64(result)
420
421 overflow <- 0 # signals SO only when OE = 1
422 if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
423 overflow <- 1 # signals SO only when OE = 1
424 vxcvi_flag <- 1
425 xx_flag <- 0
426 inc_flag <- 0
427 else
428 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
429 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
430
431 if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
432 if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
433 if xx_flag = 1 then SetFX(FPSCR.XX)
434
435 vx_flag <- vxsnan_flag | vxcvi_flag
436 vex_flag <- FPSCR.VE & vx_flag
437 if vex_flag = 0 then
438 RT <- result
439 FPSCR.FPRF <- undefined
440 FPSCR.FR <- inc_flag
441 FPSCR.FI <- xx_flag
442 else
443 FPSCR.FR <- 0
444 FPSCR.FI <- 0
445 ```
446
447 Convert from 64-bit float in FRB to a unsigned/signed 32/64-bit integer
448 in RT, with the conversion overflow/rounding semantics following the
449 chosen `CVM` value. `FPSCR` is modified and exceptions are raised as usual.
450
451 These instructions have an Rc=1 mode which sets CR0 in the normal
452 way for any instructions producing a GPR result. Additionally, when OE=1,
453 if the numerical value of the FP number is not 100% accurately preserved
454 (due to truncation or saturation and including when the FP number was
455 NaN) then this is considered to be an Integer Overflow condition, and
456 CR0.SO, XER.SO and XER.OV are all set as normal for any GPR instructions
457 that overflow. When `RT` is not written (`vex_flag = 1`), all CR0 bits
458 except SO are undefined.
459
460 Special Registers altered:
461
462 ```
463 CR0 (if Rc=1)
464 XER SO, OV, OV32 (if OE=1)
465 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
466 ```
467
468 ### Assembly Aliases
469
470 | Assembly Alias | Full Instruction |
471 |--------------------------|---------------------------|
472 | `cffprw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 0` |
473 | `cffprw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 0` |
474 | `cffprwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 0` |
475 | `cffprwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 0` |
476 | `cffpruw RT, FRB, CVM` | `cffpr RT, FRB, CVM, 1` |
477 | `cffpruw. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 1` |
478 | `cffpruwo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 1` |
479 | `cffpruwo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 1` |
480 | `cffprd RT, FRB, CVM` | `cffpr RT, FRB, CVM, 2` |
481 | `cffprd. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 2` |
482 | `cffprdo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 2` |
483 | `cffprdo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 2` |
484 | `cffprud RT, FRB, CVM` | `cffpr RT, FRB, CVM, 3` |
485 | `cffprud. RT, FRB, CVM` | `cffpr. RT, FRB, CVM, 3` |
486 | `cffprudo RT, FRB, CVM` | `cffpro RT, FRB, CVM, 3` |
487 | `cffprudo. RT, FRB, CVM` | `cffpro. RT, FRB, CVM, 3` |