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 |
341 # based on xscvdpuxws
343 src <- bfp_CONVERT_FROM_BFP64((FRB))
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
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)
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)
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)
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
405 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
408 result128 <- si128_CONVERT_FROM_BFP(rnd)
409 result <- result128[64:127] & js_mask
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)
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
430 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
431 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
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)
437 vx_flag <- vxsnan_flag | vxcvi_flag
438 vex_flag <- FPSCR.VE & vx_flag
441 FPSCR.FPRF <- undefined
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.
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.
462 Special Registers altered:
466 XER SO, OV, OV32 (if OE=1)
467 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
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` |