From: Jacob Lifshay Date: Mon, 7 Aug 2023 23:04:00 +0000 (-0700) Subject: split out instructions from openpower/isa/fpcvt.mdwn X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1475d2697686f8590ec35a5f3b4dc19f4ca67293;p=openpower-isa.git split out instructions from openpower/isa/fpcvt.mdwn --- diff --git a/openpower/isa/fpcvt.mdwn b/openpower/isa/fpcvt.mdwn index bd7b0688..5127f03d 100644 --- a/openpower/isa/fpcvt.mdwn +++ b/openpower/isa/fpcvt.mdwn @@ -2,217 +2,10 @@ -# Floating Convert with round Signed Doubleword to Single-Precision format +[[!inline pagenames="openpower/isa/fpcvt/fcfids" raw="yes"]] -X-Form +[[!inline pagenames="openpower/isa/fpcvt/ctfpr" raw="yes"]] -* fcfids FRT,FRB (Rc=0) -* fcfids. FRT,FRB (Rc=1) +[[!inline pagenames="openpower/isa/fpcvt/ctfprs" raw="yes"]] -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 +[[!inline pagenames="openpower/isa/fpcvt/cffpr" raw="yes"]] diff --git a/openpower/isa/fpcvt/cffpr.mdwn b/openpower/isa/fpcvt/cffpr.mdwn new file mode 100644 index 00000000..f33f0082 --- /dev/null +++ b/openpower/isa/fpcvt/cffpr.mdwn @@ -0,0 +1,19 @@ +# [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: + + +[[!inline pagenames="openpower/isa/fpcvt/cffpr_code" raw="yes"]] + +Special Registers Altered: + + CR0 (if Rc=1) + SO OV OV32 (if OE=1) + FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV diff --git a/openpower/isa/fpcvt/cffpr_code.mdwn b/openpower/isa/fpcvt/cffpr_code.mdwn new file mode 100644 index 00000000..6873e17f --- /dev/null +++ b/openpower/isa/fpcvt/cffpr_code.mdwn @@ -0,0 +1,99 @@ + # 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 diff --git a/openpower/isa/fpcvt/ctfpr.mdwn b/openpower/isa/fpcvt/ctfpr.mdwn new file mode 100644 index 00000000..41b02c53 --- /dev/null +++ b/openpower/isa/fpcvt/ctfpr.mdwn @@ -0,0 +1,15 @@ +# [DRAFT] Floating Convert From Integer In GPR + +X-Form + +* ctfpr FRT,RB,IT (Rc=0) +* ctfpr. FRT,RB,IT (Rc=1) + +Pseudo-code: + +[[!inline pagenames="openpower/isa/fpcvt/ctfpr_code" raw="yes"]] + +Special Registers Altered: + + CR1 (if Rc=1) + FPRF FR FI FX XX (if IT[0]=1) diff --git a/openpower/isa/fpcvt/ctfpr_code.mdwn b/openpower/isa/fpcvt/ctfpr_code.mdwn new file mode 100644 index 00000000..0aa2adeb --- /dev/null +++ b/openpower/isa/fpcvt/ctfpr_code.mdwn @@ -0,0 +1,28 @@ + 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 diff --git a/openpower/isa/fpcvt/ctfprs.mdwn b/openpower/isa/fpcvt/ctfprs.mdwn new file mode 100644 index 00000000..b6288aef --- /dev/null +++ b/openpower/isa/fpcvt/ctfprs.mdwn @@ -0,0 +1,17 @@ +# [DRAFT] Floating Convert From Integer In GPR Single + +X-Form + +* ctfprs FRT,RB,IT (Rc=0) +* ctfprs. FRT,RB,IT (Rc=1) + +Pseudo-code: + + + +[[!inline pagenames="openpower/isa/fpcvt/ctfprs_code" raw="yes"]] + +Special Registers Altered: + + CR1 (if Rc=1) + FPRF FR FI FX XX diff --git a/openpower/isa/fpcvt/ctfprs_code.mdwn b/openpower/isa/fpcvt/ctfprs_code.mdwn new file mode 100644 index 00000000..6c237ad9 --- /dev/null +++ b/openpower/isa/fpcvt/ctfprs_code.mdwn @@ -0,0 +1,20 @@ + # 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 diff --git a/openpower/isa/fpcvt/fcfids.mdwn b/openpower/isa/fpcvt/fcfids.mdwn new file mode 100644 index 00000000..97cdda1f --- /dev/null +++ b/openpower/isa/fpcvt/fcfids.mdwn @@ -0,0 +1,16 @@ +# Floating Convert with round Signed Doubleword to Single-Precision format + +X-Form + +* fcfids FRT,FRB (Rc=0) +* fcfids. FRT,FRB (Rc=1) + +Pseudo-code: + +[[!inline pagenames="openpower/isa/fpcvt/fcfids_code" raw="yes"]] + +Special Registers Altered: + + FPRF FR FI + FX XX + CR1 (if Rc=1) diff --git a/openpower/isa/fpcvt/fcfids_code.mdwn b/openpower/isa/fpcvt/fcfids_code.mdwn new file mode 100644 index 00000000..810912a5 --- /dev/null +++ b/openpower/isa/fpcvt/fcfids_code.mdwn @@ -0,0 +1 @@ + FRT <- INT2FP(FRB, 'sint2single')