Floating Convert with round Signed Doubleword to Single-Precision format

X-Form

  • fcfids FRT,FRB (Rc=0)
  • fcfids. FRT,FRB (Rc=1)

Pseudo-code:

FRT <- INT2FP(FRB, 'sint2single')

Special Registers Altered:

FPRF FR FI
FX XX
CR1        (if Rc=1)

[DRAFT] Floating Convert From Integer In GPR

X-Form

  • ctfpr FRT,RB,IT (Rc=0)
  • ctfpr. FRT,RB,IT (Rc=1)

Pseudo-code:

if IT[0] = 0 then  # 32-bit int -> 64-bit float
    # rounding never necessary, so don't touch FPSCR
    # based off xvcvsxwdp
    if IT = 0 then  # Signed 32-bit
        src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
    else  # IT = 1 -- Unsigned 32-bit
        src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
    FRT <- bfp64_CONVERT_FROM_BFP(src)
else
    # rounding may be necessary. based off xscvuxdsp
    reset_xflags()
    switch(IT)
        case(0):  # Signed 32-bit
            src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
        case(1):  # Unsigned 32-bit
            src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
        case(2):  # Signed 64-bit
            src <- bfp_CONVERT_FROM_SI64((RB))
        default:  # Unsigned 64-bit
            src <- bfp_CONVERT_FROM_UI64((RB))
    rnd <- bfp_ROUND_TO_BFP64(0b0, FPSCR.RN, src)
    result <- bfp64_CONVERT_FROM_BFP(rnd)
    cls <- fprf_CLASS_BFP64(result)
    if xx_flag = 1 then SetFX(FPSCR.XX)
    FRT <- result
    FPSCR.FPRF <- cls
    FPSCR.FR <- inc_flag
    FPSCR.FI <- xx_flag

Special Registers Altered:

CR1          (if Rc=1)
FPRF FR FI FX XX  (if IT[0]=1)

[DRAFT] Floating Convert From Integer In GPR Single

X-Form

  • ctfprs FRT,RB,IT (Rc=0)
  • ctfprs. FRT,RB,IT (Rc=1)

Pseudo-code:

# rounding may be necessary. based off xscvuxdsp
reset_xflags()
switch(IT)
    case(0):  # Signed 32-bit
        src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
    case(1):  # Unsigned 32-bit
        src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
    case(2):  # Signed 64-bit
        src <- bfp_CONVERT_FROM_SI64((RB))
    default:  # Unsigned 64-bit
        src <- bfp_CONVERT_FROM_UI64((RB))
rnd <- bfp_ROUND_TO_BFP32(FPSCR.RN, src)
result32 <- bfp32_CONVERT_FROM_BFP(rnd)
cls <- fprf_CLASS_BFP32(result32)
result <- DOUBLE(result32)
if xx_flag = 1 then SetFX(FPSCR.XX)
FRT <- result
FPSCR.FPRF <- cls
FPSCR.FR <- inc_flag
FPSCR.FI <- xx_flag

Special Registers Altered:

CR1          (if Rc=1)
FPRF FR FI FX XX

[DRAFT] Floating Convert To Integer In GPR

XO-Form

  • cffpr RT,FRB,CVM,IT (OE=0 Rc=0)
  • cffpr. RT,FRB,CVM,IT (OE=0 Rc=1)
  • cffpro RT,FRB,CVM,IT (OE=1 Rc=0)
  • cffpro. RT,FRB,CVM,IT (OE=1 Rc=1)

Pseudo-code:

# based on xscvdpuxws
reset_xflags()
src <- bfp_CONVERT_FROM_BFP64((FRB))
switch(IT)
    case(0):  # Signed 32-bit
        range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
        range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
        js_mask <- 0x0000_0000_FFFF_FFFF
    case(1):  # Unsigned 32-bit
        range_min <- bfp_CONVERT_FROM_UI32(0)
        range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
        js_mask <- 0x0000_0000_FFFF_FFFF
    case(2):  # Signed 64-bit
        range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
        range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
        js_mask <- 0xFFFF_FFFF_FFFF_FFFF
    default:  # Unsigned 64-bit
        range_min <- bfp_CONVERT_FROM_UI64(0)
        range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
        js_mask <- 0xFFFF_FFFF_FFFF_FFFF
if (CVM[2] = 1) | (FPSCR.RN = 0b01) then
    rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
else if FPSCR.RN = 0b00 then
    rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
else if FPSCR.RN = 0b10 then
    rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
else if FPSCR.RN = 0b11 then
    rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
switch(CVM)
    case(0, 1):  # OpenPower semantics
        if IsNaN(rnd) then
            result <- si64_CONVERT_FROM_BFP(range_min)
        else if bfp_COMPARE_GT(rnd, range_max) then
            result <- ui64_CONVERT_FROM_BFP(range_max)
        else if bfp_COMPARE_LT(rnd, range_min) then
            result <- si64_CONVERT_FROM_BFP(range_min)
        else if IT[1] = 1 then  # Unsigned 32/64-bit
            result <- ui64_CONVERT_FROM_BFP(rnd)
        else  # Signed 32/64-bit
            result <- si64_CONVERT_FROM_BFP(rnd)
    case(2, 3):  # Java/Saturating semantics
        if IsNaN(rnd) then
            result <- [0] * 64
        else if bfp_COMPARE_GT(rnd, range_max) then
            result <- ui64_CONVERT_FROM_BFP(range_max)
        else if bfp_COMPARE_LT(rnd, range_min) then
            result <- si64_CONVERT_FROM_BFP(range_min)
        else if IT[1] = 1 then  # Unsigned 32/64-bit
            result <- ui64_CONVERT_FROM_BFP(rnd)
        else  # Signed 32/64-bit
            result <- si64_CONVERT_FROM_BFP(rnd)
    default:  # JavaScript semantics
        # CVM = 6, 7 are illegal instructions
        # using a 128-bit intermediate works here because the largest type
        # this instruction can convert from has 53 significand bits, and
        # the largest type this instruction can convert to has 64 bits,
        # and the sum of those is strictly less than the 128 bits of the
        # intermediate result.
        limit <- bfp_CONVERT_FROM_UI128([1] * 128)
        if IsInf(rnd) | IsNaN(rnd) then
            result <- [0] * 64
        else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
            result <- [0] * 64
        else
            result128 <- si128_CONVERT_FROM_BFP(rnd)
            result <- result128[64:127] & js_mask
switch(IT)
    case(0):  # Signed 32-bit
        result <- EXTS64(result[32:63])
        result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
    case(1):  # Unsigned 32-bit
        result <- EXTZ64(result[32:63])
        result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
    case(2):  # Signed 64-bit
        result_bfp <- bfp_CONVERT_FROM_SI64(result)
    default:  # Unsigned 64-bit
        result_bfp <- bfp_CONVERT_FROM_UI64(result)
overflow <- 0  # signals SO only when OE = 1
if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
    overflow <- 1  # signals SO only when OE = 1
    vxcvi_flag <- 1
    xx_flag <- 0
    inc_flag <- 0
else
    xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
    inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
if xx_flag = 1 then SetFX(FPSCR.XX)
vx_flag <- vxsnan_flag | vxcvi_flag
vex_flag <- FPSCR.VE & vx_flag
if vex_flag = 0 then
    RT <- result
    FPSCR.FPRF <- undefined(0b00000)
    FPSCR.FR <- inc_flag
    FPSCR.FI <- xx_flag
else
    FPSCR.FR <- 0
    FPSCR.FI <- 0

Special Registers Altered:

CR0                     (if Rc=1)
SO OV OV32              (if OE=1)
FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV