# 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 * fcvtfg FRT,RB,IT (Rc=0) * fcvtfg. 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(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 * fcvtfgs FRT,RB,IT (Rc=0) * fcvtfgs. 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 * fcvttg RT,FRB,CVM,IT (OE=0 Rc=0) * fcvttg. RT,FRB,CVM,IT (OE=0 Rc=1) * fcvttgo RT,FRB,CVM,IT (OE=1 Rc=0) * fcvttgo. 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 <- 0xFFFF_FFFF case(1): # Unsigned 32-bit range_min <- bfp_CONVERT_FROM_UI32(0) range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF) js_mask <- 0xFFFF_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(range_max) else # Signed 32/64-bit result <- si64_CONVERT_FROM_BFP(range_max) 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(range_max) else # Signed 32/64-bit result <- si64_CONVERT_FROM_BFP(range_max) default: # JavaScript semantics # CVM = 6, 7 are illegal instructions # this works because the largest type we try to convert from has # 53 significand bits, and the largest type we try to 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) 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 FPSCR[FR] <- inc_flag FPSCR[FI] <- xx_flag if IsNaN(src) | ¬bfp_COMPARE_EQ(src, result_bfp) then overflow <- 1 # signals SO only when OE = 1 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 # [DRAFT] Floating Convert To Integer In GPR Single XO-Form * fcvttgs RT,FRB,CVM,IT (OE=0 Rc=0) * fcvttgs. RT,FRB,CVM,IT (OE=0 Rc=1) * fcvttgso RT,FRB,CVM,IT (OE=1 Rc=0) * fcvttgso. RT,FRB,CVM,IT (OE=1 Rc=1) Pseudo-code: # based on xscvdpuxws reset_xflags() src <- bfp_CONVERT_FROM_BFP32(SINGLE((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 <- 0xFFFF_FFFF case(1): # Unsigned 32-bit range_min <- bfp_CONVERT_FROM_UI32(0) range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF) js_mask <- 0xFFFF_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(range_max) else # Signed 32/64-bit result <- si64_CONVERT_FROM_BFP(range_max) 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(range_max) else # Signed 32/64-bit result <- si64_CONVERT_FROM_BFP(range_max) default: # JavaScript semantics # CVM = 6, 7 are illegal instructions # this works because the largest type we try to convert from has # 53 significand bits, and the largest type we try to 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) 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 FPSCR[FR] <- inc_flag FPSCR[FI] <- xx_flag if IsNaN(src) | ¬bfp_COMPARE_EQ(src, result_bfp) then overflow <- 1 # signals SO only when OE = 1 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