1 <!-- X Instructions here described in PowerISA Version 3.0 B Book 1 -->
3 <!-- Section 4.6.7 Floating-point Rounding and Conversion instructions. P 159 - 166 -->
5 # Floating Convert with round Signed Doubleword to Single-Precision format
9 * fcfids FRT,FRB (Rc=0)
10 * fcfids. FRT,FRB (Rc=1)
14 FRT <- INT2FP(FRB, 'sint2single')
16 Special Registers Altered:
22 # [DRAFT] Floating Convert From Integer In GPR
26 * fcvtfg FRT,RB,IT (Rc=0)
27 * fcvtfg. FRT,RB,IT (Rc=1)
31 if IT[0] = 0 then # 32-bit int -> 64-bit float
32 # rounding never necessary, so don't touch FPSCR
34 if IT = 0 then # Signed 32-bit
35 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
36 else # IT = 1 -- Unsigned 32-bit
37 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
38 FRT <- bfp64_CONVERT_FROM_BFP(src)
40 # rounding may be necessary. based off xscvuxdsp
43 case(0): # Signed 32-bit
44 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
45 case(1): # Unsigned 32-bit
46 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
47 case(2): # Signed 64-bit
48 src <- bfp_CONVERT_FROM_SI64((RB))
49 default: # Unsigned 64-bit
50 src <- bfp_CONVERT_FROM_UI64((RB))
51 rnd <- bfp_ROUND_TO_BFP64(FPSCR[RN], src)
52 result <- bfp64_CONVERT_FROM_BFP(rnd)
53 cls <- fprf_CLASS_BFP64(result)
54 if xx_flag = 1 then SetFX(FPSCR[XX])
60 Special Registers Altered:
63 FPRF FR FI FX XX (if IT[0]=1)
65 # [DRAFT] Floating Convert From Integer In GPR Single
69 * fcvtfgs FRT,RB,IT (Rc=0)
70 * fcvtfgs. FRT,RB,IT (Rc=1)
74 <!-- note the PowerISA spec. explicitly has empty lines before/after SetFX, -->
75 <!-- don't remove them -->
76 # rounding may be necessary. based off xscvuxdsp
79 case(0): # Signed 32-bit
80 src <- bfp_CONVERT_FROM_SI32((RB)[32:63])
81 case(1): # Unsigned 32-bit
82 src <- bfp_CONVERT_FROM_UI32((RB)[32:63])
83 case(2): # Signed 64-bit
84 src <- bfp_CONVERT_FROM_SI64((RB))
85 default: # Unsigned 64-bit
86 src <- bfp_CONVERT_FROM_UI64((RB))
87 rnd <- bfp_ROUND_TO_BFP32(FPSCR[RN], src)
88 result32 <- bfp32_CONVERT_FROM_BFP(rnd)
89 cls <- fprf_CLASS_BFP32(result32)
90 result <- DOUBLE(result32)
91 if xx_flag = 1 then SetFX(FPSCR[XX])
97 Special Registers Altered:
102 # [DRAFT] Floating Convert To Integer In GPR
106 * fcvttg RT,FRB,CVM,IT (OE=0 Rc=0)
107 * fcvttg. RT,FRB,CVM,IT (OE=0 Rc=1)
108 * fcvttgo RT,FRB,CVM,IT (OE=1 Rc=0)
109 * fcvttgo. RT,FRB,CVM,IT (OE=1 Rc=1)
113 # based on xscvdpuxws
115 src <- bfp_CONVERT_FROM_BFP64((FRB))
117 case(0): # Signed 32-bit
118 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
119 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
120 js_mask <- 0xFFFF_FFFF
121 case(1): # Unsigned 32-bit
122 range_min <- bfp_CONVERT_FROM_UI32(0)
123 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
124 js_mask <- 0xFFFF_FFFF
125 case(2): # Signed 64-bit
126 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
127 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
128 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
129 default: # Unsigned 64-bit
130 range_min <- bfp_CONVERT_FROM_UI64(0)
131 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
132 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
133 if (CVM[2] = 1) | (FPSCR[RN] = 0b01) then
134 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
135 else if FPSCR[RN] = 0b00 then
136 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
137 else if FPSCR[RN] = 0b10 then
138 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
139 else if FPSCR[RN] = 0b11 then
140 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
142 case(0, 1): # OpenPower semantics
144 result <- si64_CONVERT_FROM_BFP(range_min)
145 else if bfp_COMPARE_GT(rnd, range_max) then
146 result <- ui64_CONVERT_FROM_BFP(range_max)
147 else if bfp_COMPARE_LT(rnd, range_min) then
148 result <- si64_CONVERT_FROM_BFP(range_min)
149 else if IT[1] = 1 then # Unsigned 32/64-bit
150 result <- ui64_CONVERT_FROM_BFP(range_max)
151 else # Signed 32/64-bit
152 result <- si64_CONVERT_FROM_BFP(range_max)
153 case(2, 3): # Java/Saturating semantics
156 else if bfp_COMPARE_GT(rnd, range_max) then
157 result <- ui64_CONVERT_FROM_BFP(range_max)
158 else if bfp_COMPARE_LT(rnd, range_min) then
159 result <- si64_CONVERT_FROM_BFP(range_min)
160 else if IT[1] = 1 then # Unsigned 32/64-bit
161 result <- ui64_CONVERT_FROM_BFP(range_max)
162 else # Signed 32/64-bit
163 result <- si64_CONVERT_FROM_BFP(range_max)
164 default: # JavaScript semantics
165 # CVM = 6, 7 are illegal instructions
166 # this works because the largest type we try to convert from has
167 # 53 significand bits, and the largest type we try to convert to
168 # has 64 bits, and the sum of those is strictly less than the 128
169 # bits of the intermediate result.
170 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
171 if IsInf(rnd) | IsNaN(rnd) then
173 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
176 result128 <- si128_CONVERT_FROM_BFP(rnd)
177 result <- result128[64:127] & js_mask
179 case(0): # Signed 32-bit
180 result <- EXTS64(result[32:63])
181 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
182 case(1): # Unsigned 32-bit
183 result <- EXTZ64(result[32:63])
184 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
185 case(2): # Signed 64-bit
186 result_bfp <- bfp_CONVERT_FROM_SI64(result)
187 default: # Unsigned 64-bit
188 result_bfp <- bfp_CONVERT_FROM_UI64(result)
189 if vxsnan_flag = 1 then SetFX(FPSCR[VXSNAN])
190 if vxcvi_flag = 1 then SetFX(FPSCR[VXCVI])
191 if xx_flag = 1 then SetFX(FPSCR[XX])
192 vx_flag <- vxsnan_flag | vxcvi_flag
193 vex_flag <- FPSCR[VE] & vx_flag
196 FPSCR[FPRF] <- undefined
197 FPSCR[FR] <- inc_flag
199 if IsNaN(src) | ¬bfp_COMPARE_EQ(src, result_bfp) then
200 overflow <- 1 # signals SO only when OE = 1
205 Special Registers Altered:
209 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
211 # [DRAFT] Floating Convert To Integer In GPR Single
215 * fcvttgs RT,FRB,CVM,IT (OE=0 Rc=0)
216 * fcvttgs. RT,FRB,CVM,IT (OE=0 Rc=1)
217 * fcvttgso RT,FRB,CVM,IT (OE=1 Rc=0)
218 * fcvttgso. RT,FRB,CVM,IT (OE=1 Rc=1)
222 # based on xscvdpuxws
224 src <- bfp_CONVERT_FROM_BFP32(SINGLE((FRB)))
226 case(0): # Signed 32-bit
227 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
228 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
229 js_mask <- 0xFFFF_FFFF
230 case(1): # Unsigned 32-bit
231 range_min <- bfp_CONVERT_FROM_UI32(0)
232 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
233 js_mask <- 0xFFFF_FFFF
234 case(2): # Signed 64-bit
235 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
236 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
237 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
238 default: # Unsigned 64-bit
239 range_min <- bfp_CONVERT_FROM_UI64(0)
240 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
241 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
242 if (CVM[2] = 1) | (FPSCR[RN] = 0b01) then
243 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
244 else if FPSCR[RN] = 0b00 then
245 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
246 else if FPSCR[RN] = 0b10 then
247 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
248 else if FPSCR[RN] = 0b11 then
249 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
251 case(0, 1): # OpenPower semantics
253 result <- si64_CONVERT_FROM_BFP(range_min)
254 else if bfp_COMPARE_GT(rnd, range_max) then
255 result <- ui64_CONVERT_FROM_BFP(range_max)
256 else if bfp_COMPARE_LT(rnd, range_min) then
257 result <- si64_CONVERT_FROM_BFP(range_min)
258 else if IT[1] = 1 then # Unsigned 32/64-bit
259 result <- ui64_CONVERT_FROM_BFP(range_max)
260 else # Signed 32/64-bit
261 result <- si64_CONVERT_FROM_BFP(range_max)
262 case(2, 3): # Java/Saturating semantics
265 else if bfp_COMPARE_GT(rnd, range_max) then
266 result <- ui64_CONVERT_FROM_BFP(range_max)
267 else if bfp_COMPARE_LT(rnd, range_min) then
268 result <- si64_CONVERT_FROM_BFP(range_min)
269 else if IT[1] = 1 then # Unsigned 32/64-bit
270 result <- ui64_CONVERT_FROM_BFP(range_max)
271 else # Signed 32/64-bit
272 result <- si64_CONVERT_FROM_BFP(range_max)
273 default: # JavaScript semantics
274 # CVM = 6, 7 are illegal instructions
275 # this works because the largest type we try to convert from has
276 # 53 significand bits, and the largest type we try to convert to
277 # has 64 bits, and the sum of those is strictly less than the 128
278 # bits of the intermediate result.
279 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
280 if IsInf(rnd) | IsNaN(rnd) then
282 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
285 result128 <- si128_CONVERT_FROM_BFP(rnd)
286 result <- result128[64:127] & js_mask
288 case(0): # Signed 32-bit
289 result <- EXTS64(result[32:63])
290 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
291 case(1): # Unsigned 32-bit
292 result <- EXTZ64(result[32:63])
293 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
294 case(2): # Signed 64-bit
295 result_bfp <- bfp_CONVERT_FROM_SI64(result)
296 default: # Unsigned 64-bit
297 result_bfp <- bfp_CONVERT_FROM_UI64(result)
298 if vxsnan_flag = 1 then SetFX(FPSCR[VXSNAN])
299 if vxcvi_flag = 1 then SetFX(FPSCR[VXCVI])
300 if xx_flag = 1 then SetFX(FPSCR[XX])
301 vx_flag <- vxsnan_flag | vxcvi_flag
302 vex_flag <- FPSCR[VE] & vx_flag
305 FPSCR[FPRF] <- undefined
306 FPSCR[FR] <- inc_flag
308 if IsNaN(src) | ¬bfp_COMPARE_EQ(src, result_bfp) then
309 overflow <- 1 # signals SO only when OE = 1
314 Special Registers Altered:
318 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV