1 <!-- main body for int_fp_mv.mdwn (without fmvis/fishmv) and ls006.fpintmv.mdwn -->
4 Tables that are used by
5 `mffpr[s][.]`/`mtfpr[s]`/`cffpr[o][.]`/`ctfpr[s][.]`:
7 ## `IT` -- Integer Type
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` |
16 ## `CVM` -- Float to Integer Conversion Mode
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 |
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
36 # Move To/From Floating-Point Register Instructions
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.
41 ## Move From Floating-Point Register
48 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
49 |-----|------|-------|-------|-------|----|--------|
50 | PO | RT | // | FRB | XO | Rc | X-Form |
56 The contents of `FPR[FRB]` are placed into `GPR[RT]`.
58 Special Registers altered:
66 `mffpr` is equivalent to the combination of `stfd` followed by `ld`.
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.
77 ## Move From Floating-Point Register Single
84 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
85 |-----|------|-------|-------|-------|----|--------|
86 | PO | RT | // | FRB | XO | Rc | X-Form |
89 RT <- [0] * 32 || SINGLE((FRB))
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]`.
95 Special Registers altered:
103 `mffprs` is equivalent to the combination of `stfs` followed by `lwz`.
109 ## Move To Floating-Point Register
115 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
116 |-----|------|-------|-------|-------|----|--------|
117 | PO | FRT | // | RB | XO | // | X-Form |
123 The contents of `GPR[RB]` are placed into `FPR[FRT]`.
125 Special Registers altered:
133 `mtfpr` is equivalent to the combination of `std` followed by `lfd`.
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.
144 ## Move To Floating-Point Register Single
150 | 0-5 | 6-10 | 11-15 | 16-20 | 21-30 | 31 | Form |
151 |-----|------|-------|-------|-------|----|--------|
152 | PO | FRT | // | RB | XO | // | X-Form |
155 FRT <- DOUBLE((RB)[32:63])
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]`.
161 Special Registers altered:
169 `mtfprs` is equivalent to the combination of `stw` followed by `lfs`.
175 # Conversion To/From Floating-Point Register Instructions
177 ## Convert To Floating-Point Register
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 |
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)
198 # rounding may be necessary. based off xscvuxdsp
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)
213 if xx_flag = 1 then SetFX(FPSCR.XX)
220 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
221 don't remove them -->
223 Convert from a unsigned/signed 32/64-bit integer in RB to a 64-bit
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
231 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
234 Special Registers altered:
238 FPRF FR FI FX XX (if IT[0]=1)
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` |
258 ## Convert To Floating-Point Register Single
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 |
270 # rounding may be necessary. based off xscvuxdsp
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)
286 if xx_flag = 1 then SetFX(FPSCR.XX)
293 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX,
294 don't remove them -->
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.
300 Rc=1 tests FRT and sets CR1, exactly like all other Scalar Floating-Point
303 Special Registers altered:
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` |
327 ## Convert From Floating-Point Register
330 cffpr RT, FRB, CVM, IT
331 cffpr. RT, FRB, CVM, IT
332 cffpro RT, FRB, CVM, IT
333 cffpro. RT, FRB, CVM, IT
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 |
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)**
344 For the pseudocode of this instruction see Appendix {insert automated reference}
347 # based on xscvdpuxws
349 src <- bfp_CONVERT_FROM_BFP64((FRB))
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
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)
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)
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)
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
411 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
414 result128 <- si128_CONVERT_FROM_BFP(rnd)
415 result <- result128[64:127] & js_mask
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)
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
436 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
437 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
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)
443 vx_flag <- vxsnan_flag | vxcvi_flag
444 vex_flag <- FPSCR.VE & vx_flag
447 FPSCR.FPRF <- undefined
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.
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.
468 Special Registers altered:
472 XER SO, OV, OV32 (if OE=1)
473 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
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` |