fix fcvttg FPSCR.FR computation
[openpower-isa.git] / openpower / isa / fpcvt.mdwn
1 <!-- X Instructions here described in PowerISA Version 3.0 B Book 1 -->
2
3 <!-- Section 4.6.7 Floating-point Rounding and Conversion instructions. P 159 - 166 -->
4
5 # Floating Convert with round Signed Doubleword to Single-Precision format
6
7 X-Form
8
9 * fcfids FRT,FRB (Rc=0)
10 * fcfids. FRT,FRB (Rc=1)
11
12 Pseudo-code:
13
14 FRT <- INT2FP(FRB, 'sint2single')
15
16 Special Registers Altered:
17
18 FPRF FR FI
19 FX XX
20 CR1 (if Rc=1)
21
22 # [DRAFT] Floating Convert From Integer In GPR
23
24 X-Form
25
26 * fcvtfg FRT,RB,IT (Rc=0)
27 * fcvtfg. FRT,RB,IT (Rc=1)
28
29 Pseudo-code:
30
31 if IT[0] = 0 then # 32-bit int -> 64-bit float
32 # rounding never necessary, so don't touch FPSCR
33 # based off xvcvsxwdp
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)
39 else
40 # rounding may be necessary. based off xscvuxdsp
41 reset_xflags()
42 switch(IT)
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)
55 FRT <- result
56 FPSCR.FPRF <- cls
57 FPSCR.FR <- inc_flag
58 FPSCR.FI <- xx_flag
59
60 Special Registers Altered:
61
62 CR1 (if Rc=1)
63 FPRF FR FI FX XX (if IT[0]=1)
64
65 # [DRAFT] Floating Convert From Integer In GPR Single
66
67 X-Form
68
69 * fcvtfgs FRT,RB,IT (Rc=0)
70 * fcvtfgs. FRT,RB,IT (Rc=1)
71
72 Pseudo-code:
73
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
77 reset_xflags()
78 switch(IT)
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)
92 FRT <- result
93 FPSCR.FPRF <- cls
94 FPSCR.FR <- inc_flag
95 FPSCR.FI <- xx_flag
96
97 Special Registers Altered:
98
99 CR1 (if Rc=1)
100 FPRF FR FI FX XX
101
102 # [DRAFT] Floating Convert To Integer In GPR
103
104 XO-Form
105
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)
110
111 Pseudo-code:
112
113 # based on xscvdpuxws
114 reset_xflags()
115 src <- bfp_CONVERT_FROM_BFP64((FRB))
116 switch(IT)
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 <- 0x0000_0000_FFFF_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 <- 0x0000_0000_FFFF_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)
141 switch(CVM)
142 case(0, 1): # OpenPower semantics
143 if IsNaN(rnd) then
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(rnd)
151 else # Signed 32/64-bit
152 result <- si64_CONVERT_FROM_BFP(rnd)
153 case(2, 3): # Java/Saturating semantics
154 if IsNaN(rnd) then
155 result <- [0] * 64
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(rnd)
162 else # Signed 32/64-bit
163 result <- si64_CONVERT_FROM_BFP(rnd)
164 default: # JavaScript semantics
165 # CVM = 6, 7 are illegal instructions
166 # using a 128-bit intermediate works here because the largest type
167 # this instruction can convert from has 53 significand bits, and
168 # the largest type this instruction can convert to has 64 bits,
169 # and the sum of those is strictly less than the 128 bits of the
170 # intermediate result.
171 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
172 if IsInf(rnd) | IsNaN(rnd) then
173 result <- [0] * 64
174 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
175 result <- [0] * 64
176 else
177 result128 <- si128_CONVERT_FROM_BFP(rnd)
178 result <- result128[64:127] & js_mask
179 switch(IT)
180 case(0): # Signed 32-bit
181 result <- EXTS64(result[32:63])
182 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
183 case(1): # Unsigned 32-bit
184 result <- EXTZ64(result[32:63])
185 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
186 case(2): # Signed 64-bit
187 result_bfp <- bfp_CONVERT_FROM_SI64(result)
188 default: # Unsigned 64-bit
189 result_bfp <- bfp_CONVERT_FROM_UI64(result)
190 overflow <- 0 # signals SO only when OE = 1
191 if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
192 overflow <- 1 # signals SO only when OE = 1
193 vxcvi_flag <- 1
194 xx_flag <- 0
195 inc_flag <- 0
196 else
197 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
198 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
199 if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
200 if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
201 if xx_flag = 1 then SetFX(FPSCR.XX)
202 vx_flag <- vxsnan_flag | vxcvi_flag
203 vex_flag <- FPSCR.VE & vx_flag
204 if vex_flag = 0 then
205 RT <- result
206 FPSCR.FPRF <- undefined(0b00000)
207 FPSCR.FR <- inc_flag
208 FPSCR.FI <- xx_flag
209 else
210 FPSCR.FR <- 0
211 FPSCR.FI <- 0
212
213 Special Registers Altered:
214
215 CR0 (if Rc=1)
216 SO OV OV32 (if OE=1)
217 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV
218
219 # [DRAFT] Floating Convert To Integer In GPR Single
220
221 XO-Form
222
223 * fcvttgs RT,FRB,CVM,IT (OE=0 Rc=0)
224 * fcvttgs. RT,FRB,CVM,IT (OE=0 Rc=1)
225 * fcvttgso RT,FRB,CVM,IT (OE=1 Rc=0)
226 * fcvttgso. RT,FRB,CVM,IT (OE=1 Rc=1)
227
228 Pseudo-code:
229
230 # based on xscvdpuxws
231 reset_xflags()
232 src <- bfp_CONVERT_FROM_BFP32(SINGLE((FRB)))
233 switch(IT)
234 case(0): # Signed 32-bit
235 range_min <- bfp_CONVERT_FROM_SI32(0x8000_0000)
236 range_max <- bfp_CONVERT_FROM_SI32(0x7FFF_FFFF)
237 js_mask <- 0x0000_0000_FFFF_FFFF
238 case(1): # Unsigned 32-bit
239 range_min <- bfp_CONVERT_FROM_UI32(0)
240 range_max <- bfp_CONVERT_FROM_UI32(0xFFFF_FFFF)
241 js_mask <- 0x0000_0000_FFFF_FFFF
242 case(2): # Signed 64-bit
243 range_min <- bfp_CONVERT_FROM_SI64(-0x8000_0000_0000_0000)
244 range_max <- bfp_CONVERT_FROM_SI64(0x7FFF_FFFF_FFFF_FFFF)
245 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
246 default: # Unsigned 64-bit
247 range_min <- bfp_CONVERT_FROM_UI64(0)
248 range_max <- bfp_CONVERT_FROM_UI64(0xFFFF_FFFF_FFFF_FFFF)
249 js_mask <- 0xFFFF_FFFF_FFFF_FFFF
250 if (CVM[2] = 1) | (FPSCR.RN = 0b01) then
251 rnd <- bfp_ROUND_TO_INTEGER_TRUNC(src)
252 else if FPSCR.RN = 0b00 then
253 rnd <- bfp_ROUND_TO_INTEGER_NEAR_EVEN(src)
254 else if FPSCR.RN = 0b10 then
255 rnd <- bfp_ROUND_TO_INTEGER_CEIL(src)
256 else if FPSCR.RN = 0b11 then
257 rnd <- bfp_ROUND_TO_INTEGER_FLOOR(src)
258 switch(CVM)
259 case(0, 1): # OpenPower semantics
260 if IsNaN(rnd) then
261 result <- si64_CONVERT_FROM_BFP(range_min)
262 else if bfp_COMPARE_GT(rnd, range_max) then
263 result <- ui64_CONVERT_FROM_BFP(range_max)
264 else if bfp_COMPARE_LT(rnd, range_min) then
265 result <- si64_CONVERT_FROM_BFP(range_min)
266 else if IT[1] = 1 then # Unsigned 32/64-bit
267 result <- ui64_CONVERT_FROM_BFP(rnd)
268 else # Signed 32/64-bit
269 result <- si64_CONVERT_FROM_BFP(rnd)
270 case(2, 3): # Java/Saturating semantics
271 if IsNaN(rnd) then
272 result <- [0] * 64
273 else if bfp_COMPARE_GT(rnd, range_max) then
274 result <- ui64_CONVERT_FROM_BFP(range_max)
275 else if bfp_COMPARE_LT(rnd, range_min) then
276 result <- si64_CONVERT_FROM_BFP(range_min)
277 else if IT[1] = 1 then # Unsigned 32/64-bit
278 result <- ui64_CONVERT_FROM_BFP(rnd)
279 else # Signed 32/64-bit
280 result <- si64_CONVERT_FROM_BFP(rnd)
281 default: # JavaScript semantics
282 # CVM = 6, 7 are illegal instructions
283 # using a 128-bit intermediate works here because the largest type
284 # this instruction can convert from has 53 significand bits, and
285 # the largest type this instruction can convert to has 64 bits,
286 # and the sum of those is strictly less than the 128 bits of the
287 # intermediate result.
288 limit <- bfp_CONVERT_FROM_UI128([1] * 128)
289 if IsInf(rnd) | IsNaN(rnd) then
290 result <- [0] * 64
291 else if bfp_COMPARE_GT(bfp_ABSOLUTE(rnd), limit) then
292 result <- [0] * 64
293 else
294 result128 <- si128_CONVERT_FROM_BFP(rnd)
295 result <- result128[64:127] & js_mask
296 switch(IT)
297 case(0): # Signed 32-bit
298 result <- EXTS64(result[32:63])
299 result_bfp <- bfp_CONVERT_FROM_SI32(result[32:63])
300 case(1): # Unsigned 32-bit
301 result <- EXTZ64(result[32:63])
302 result_bfp <- bfp_CONVERT_FROM_UI32(result[32:63])
303 case(2): # Signed 64-bit
304 result_bfp <- bfp_CONVERT_FROM_SI64(result)
305 default: # Unsigned 64-bit
306 result_bfp <- bfp_CONVERT_FROM_UI64(result)
307 overflow <- 0 # signals SO only when OE = 1
308 if IsNaN(src) | ¬bfp_COMPARE_EQ(rnd, result_bfp) then
309 overflow <- 1 # signals SO only when OE = 1
310 vxcvi_flag <- 1
311 xx_flag <- 0
312 inc_flag <- 0
313 else
314 xx_flag <- ¬bfp_COMPARE_EQ(src, result_bfp)
315 inc_flag <- bfp_COMPARE_GT(bfp_ABSOLUTE(result_bfp), bfp_ABSOLUTE(src))
316 if vxsnan_flag = 1 then SetFX(FPSCR.VXSNAN)
317 if vxcvi_flag = 1 then SetFX(FPSCR.VXCVI)
318 if xx_flag = 1 then SetFX(FPSCR.XX)
319 vx_flag <- vxsnan_flag | vxcvi_flag
320 vex_flag <- FPSCR.VE & vx_flag
321 if vex_flag = 0 then
322 RT <- result
323 FPSCR.FPRF <- undefined(0b00000)
324 FPSCR.FR <- inc_flag
325 FPSCR.FI <- xx_flag
326 else
327 FPSCR.FR <- 0
328 FPSCR.FI <- 0
329
330 Special Registers Altered:
331
332 CR0 (if Rc=1)
333 SO OV OV32 (if OE=1)
334 FPRF=0bUUUUU FR FI FX XX VXSNAN VXCV