power_insn: decrease LDSTMode class nesting
[openpower-isa.git] / openpower / isafunctions / double2single.mdwn
1 # A.1 Floating-Point Round to Single-Precision Model
2
3 The following describes algorithmically the operation of the Floating
4 Round to Single-Precision instruction.
5
6 <!-- OPF_PowerISA_v3.1B.pdf Book I Section A.1 page 1031-1034 -->
7
8 def FRSP(FRB, FPSCR):
9 if ((FRB)[1:11] <u 897) & ((FRB)[1:63] >u 0) then
10 if FPSCR['UE'] = 0 then
11 return FRSP_Disabled_Exponent_Underflow(FRB, FPSCR)
12 if FPSCR['UE'] = 1 then
13 return FRSP_Enabled_Exponent_Underflow(FRB, FPSCR)
14
15 if ((FRB)[1:11] >u 1150) & ((FRB)[1:11] <u 2047) then
16 if FPSCR['OE'] = 0 then
17 return FRSP_Disabled_Exponent_Overflow(FRB, FPSCR)
18 if FPSCR['OE'] = 1 then
19 return FRSP_Enabled_Exponent_Overflow(FRB, FPSCR)
20
21 if ((FRB)[1:11] >u 896) & ((FRB)[1:11] <u 1151) then
22 return FRSP_Normal_Operand(FRB, FPSCR)
23
24 if (FRB)[1:63] = 0 then
25 return FRSP_Zero_Operand(FRB, FPSCR)
26
27 if (FRB)[1:11] = 2047 then
28 if (FRB)[12:63] = 0 then
29 return FRSP_Infinity_Operand(FRB, FPSCR)
30 if (FRB)[12] = 1 then
31 return FRSP_QNaN_Operand(FRB, FPSCR)
32 if ((FRB)[12] = 0) & ((FRB)[13:63] >u 0) then
33 return FRSP_SNaN_Operand(FRB, FPSCR)
34
35 def FRSP_Disabled_Exponent_Underflow(FRB, FPSCR):
36 sign <- (FRB)[0]
37 frac[0:52] <- 0
38 exp <- 0
39 if (FRB)[1:11] = 0 then
40 exp <- -1022
41 frac[0:52] <- 0b0 || (FRB)[12:63]
42 if (FRB)[1:11] >u 0 then
43 exp <- (FRB)[1:11] - 1023
44 frac[0:52] <- 0b1 || (FRB)[12:63]
45
46 # Denormalize operand:
47 G <- 0b0
48 R <- 0b0
49 X <- 0b0
50 do while exp < -126
51 exp <- exp + 1
52 X <- X | R
53 R <- G
54 G <- frac[52]
55 frac[0:52] <- 0b0 || frac[0:51]
56
57 FPSCR['UX'] <- (frac[24:52] || G || R || X) >u 0
58 exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], G, R, X, FPSCR)
59 FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
60 FRT <- [0b0] * 64
61 if frac[0:52] = 0 then
62 FRT[0] <- sign
63 FRT[1:63] <- 0
64 if sign = 0 then FPSCR['FPRF'] <- '+ zero'
65 if sign = 1 then FPSCR['FPRF'] <- '- zero'
66 if frac[0:52] >u 0 then
67 if frac[0] = 1 then
68 if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
69 if sign = 1 then FPSCR['FPRF'] <- '- normal number'
70 if frac[0] = 0 then
71 if sign = 0 then FPSCR['FPRF'] <- '+ denormalized number'
72 if sign = 1 then FPSCR['FPRF'] <- '- denormalized number'
73
74 # Normalize operand:
75 do while frac[0] = 0
76 exp <- exp-1
77 frac[0:52] <- frac[1:52] || 0b0
78
79 FRT[0] <- sign
80 FRT[1:11] <- exp + 1023
81 FRT[12:63] <- frac[1:52]
82 return FRT, FPSCR
83
84 def FRSP_Enabled_Exponent_Underflow(FRB, FPSCR):
85 FPSCR['UX'] <- 1
86 sign <- (FRB)[0]
87 frac <- [0b0] * 53
88 exp <- 0
89 if (FRB)[1:11] = 0 then
90 exp <- -1022
91 frac[0:52] <- 0b0 || (FRB)[12:63]
92 if (FRB)[1:11] >u 0 then
93 exp <- (FRB)[1:11] - 1023
94 frac[0:52] <- 0b1 || (FRB)[12:63]
95
96 # Normalize operand:
97 do while frac[0] = 0
98 exp <- exp - 1
99 frac[0:52] <- frac[1:52] || 0b0
100
101 exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0, FPSCR)
102 FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
103 exp <- exp + 192
104 FRT <- [0b0] * 64
105 FRT[0] <- sign
106 FRT[1:11] <- exp + 1023
107 FRT[12:63] <- frac[1:52]
108 if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
109 if sign = 1 then FPSCR['FPRF'] <- '- normal number'
110 return FRT, FPSCR
111
112 def FRSP_Disabled_Exponent_Overflow(FRB, FPSCR):
113 FPSCR['OX'] <- 1
114 FRT <- [0b0] * 64
115 if FPSCR['RN'] = 0b00 then # Round to Nearest
116 if (FRB)[0] = 0 then FRT <- 0x7FF0_0000_0000_0000
117 if (FRB)[0] = 1 then FRT <- 0xFFF0_0000_0000_0000
118 if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ infinity'
119 if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- infinity'
120 if FPSCR['RN'] = 0b01 then # Round toward Zero
121 if (FRB)[0] = 0 then FRT <- 0x47EF_FFFF_E000_0000
122 if (FRB)[0] = 1 then FRT <- 0xC7EF_FFFF_E000_0000
123 if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ normal number'
124 if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- normal number'
125 if FPSCR['RN'] = 0b10 then # Round toward +Infinity
126 if (FRB)[0] = 0 then FRT <- 0x7FF0_0000_0000_0000
127 if (FRB)[0] = 1 then FRT <- 0xC7EF_FFFF_E000_0000
128 if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ infinity'
129 if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- normal number'
130 if FPSCR['RN'] = 0b11 then # Round toward -Infinity
131 if (FRB)[0] = 0 then FRT <- 0x47EF_FFFF_E000_0000
132 if (FRB)[0] = 1 then FRT <- 0xFFF0_0000_0000_0000
133 if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ normal number'
134 if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- infinity'
135 FPSCR['FR'] <- undefined(0) # FIXME: figure out what values POWER9 uses
136 FPSCR['FI'] <- 1
137 FPSCR['XX'] <- 1
138 return FRT, FPSCR
139
140 def FRSP_Enabled_Exponent_Overflow(FRB, FPSCR):
141 sign <- (FRB)[0]
142 exp <- (FRB)[1:11] - 1023
143 frac <- [0b0] * 53
144 frac[0:52] <- 0b1 || (FRB)[12:63]
145 exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0, FPSCR)
146 FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
147 # Enabled Overflow:
148 FPSCR['OX'] <- 1
149 exp <- exp - 192
150 FRT <- [0b0] * 64
151 FRT[0] <- sign
152 FRT[1:11] <- exp + 1023
153 FRT[12:63] <- frac[1:52]
154 if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
155 if sign = 1 then FPSCR['FPRF'] <- '- normal number'
156 return FRT, FPSCR
157
158 def FRSP_Zero_Operand(FRB, FPSCR):
159 FRT <- (FRB)
160 if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ zero'
161 if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- zero'
162 FPSCR['FRFI'] <- 0b00
163 return FRT, FPSCR
164
165 def FRSP_Infinity_Operand(FRB, FPSCR):
166 FRT <- (FRB)
167 if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ infinity'
168 if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- infinity'
169 FPSCR['FRFI'] <- 0b00
170 return FRT, FPSCR
171
172 def FRSP_QNaN_Operand(FRB, FPSCR):
173 FRT <- (FRB)[0:34] || [0b0] * 29
174 FPSCR['FPRF'] <- 'QNaN'
175 FPSCR['FR'] <- 0b0
176 FPSCR['FI'] <- 0b0
177 return FRT, FPSCR
178
179 def FRSP_SNaN_Operand(FRB, FPSCR):
180 FPSCR['VXSNAN'] <- 1
181 FRT <- [0b0] * 64
182 if FPSCR['VE'] = 0 then
183 FRT[0:11] <- (FRB)[0:11]
184 FRT[12] <- 1
185 FRT[13:63] <- (FRB)[13:34] || [0b0] * 29
186 FPSCR['FPRF'] <- 'QNaN'
187 FPSCR['FR'] <- 0b0
188 FPSCR['FI'] <- 0b0
189 return FRT, FPSCR
190
191 def FRSP_Normal_Operand(FRB, FPSCR):
192 sign <- (FRB)[0]
193 exp <- (FRB)[1:11] - 1023
194 frac <- [0b0] * 53
195 frac[0:52] <- 0b1 || (FRB)[12:63]
196 exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0, FPSCR)
197 FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
198 if (exp > 127) & (FPSCR['OE'] = 0) then
199 return FRSP_Disabled_Exponent_Overflow(FRB, FPSCR)
200 if (exp > 127) & (FPSCR['OE'] = 1) then
201 return FRSP_Enabled_Overflow(FRB, FPSCR)
202 FRT <- [0b0] * 64
203 FRT[0] <- sign
204 FRT[1:11] <- exp + 1023
205 FRT[12:63] <- frac[1:52]
206 if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
207 if sign = 1 then FPSCR['FPRF'] <- '- normal number'
208 return FRT, FPSCR
209
210 def Round_Single(sign, exp, frac, G, R, X, FPSCR):
211 inc <- 0
212 lsb <- frac[23]
213 gbit <- frac[24]
214 rbit <- frac[25]
215 xbit <- (frac[26:52]||G||R||X) != 0
216 if FPSCR['RN'] = 0b00 then # Round to Nearest
217 # comparisons ignore u bits
218 if (lsb || gbit) = 0b11 then inc <- 1
219 if (lsb || gbit || rbit) = 0b011 then inc <- 1
220 if (lsb || gbit || xbit) = 0b011 then inc <- 1
221 if FPSCR['RN'] = 0b10 then # Round toward + Infinity
222 # comparisons ignore u bits
223 if (sign || gbit) = 0b01 then inc <- 1
224 if (sign || rbit) = 0b01 then inc <- 1
225 if (sign || xbit) = 0b01 then inc <- 1
226 if FPSCR['RN'] = 0b11 then # Round toward - Infinity
227 # comparisons ignore u bits
228 if (sign || gbit) = 0b11 then inc <- 1
229 if (sign || rbit) = 0b11 then inc <- 1
230 if (sign || xbit) = 0b11 then inc <- 1
231 frac[0:23] <- frac[0:23] + inc
232 if (inc = 1) & (frac[0:23] = 0) then
233 frac[0:23] <- 0b1 || frac[0:22]
234 exp <- exp + 1
235 frac[24:52] <- [0b0] * 29
236 FPSCR['FR'] <- inc
237 FPSCR['FI'] <- gbit | rbit | xbit
238 return exp, frac, FPSCR
239
240 <!-- Power ISA v3.0B p140 section 4.6.2 -->
241
242 def DOUBLE(WORD):
243 exp <- [0] * 11
244 frac <- [0] * 53
245 sign <- 0b0
246 FRT <- [0] * 64
247 # Normalized Operand
248 if (WORD[1:8] >u 0) & (WORD[1:8] <u 255) then
249 FRT[0:1] <- WORD[0:1]
250 FRT[2] <- ¬WORD[1]
251 FRT[3] <- ¬WORD[1]
252 FRT[4] <- ¬WORD[1]
253 FRT[5:63] <- WORD[2:31] || [0]*29
254 # Denormalized Operand
255 if (WORD[1:8] = 0) & (WORD[9:31] != 0) then
256 sign <- WORD[0]
257 exp <- -126
258 frac[0:52] <- 0b0 || WORD[9:31] || [0]*29
259 #normalize the operand
260 do while frac[0] = 0
261 frac[0:52] <- frac[1:52] || 0b0
262 exp <- exp - 1
263 FRT[0] <- sign
264 FRT[1:11] <- exp + 1023
265 FRT[12:63] <- frac[1:52]
266 # Zero / Infinity / NaN
267 if (WORD[1:8] = 255) | (WORD[1:31] = 0) then
268 FRT[0:1] <- WORD[0:1]
269 FRT[2] <- WORD[1]
270 FRT[3] <- WORD[1]
271 FRT[4] <- WORD[1]
272 FRT[5:63] <- WORD[2:31] || [0]*29
273 return FRT