Revision fb0eaffc target-ppc/helper.c
b/target-ppc/helper.c | ||
---|---|---|
121 | 121 |
} |
122 | 122 |
|
123 | 123 |
/* The 32 MSB of the target fpr are undefined. They'll be zero... */ |
124 |
uint32_t do_load_fpscr (void) |
|
124 |
/* Floating point operations helpers */ |
|
125 |
void do_load_fpscr (void) |
|
125 | 126 |
{ |
126 |
return (fpscr_fx << FPSCR_FX) | |
|
127 |
(fpscr_fex << FPSCR_FEX) | |
|
128 |
(fpscr_vx << FPSCR_VX) | |
|
129 |
(fpscr_ox << FPSCR_OX) | |
|
130 |
(fpscr_ux << FPSCR_UX) | |
|
131 |
(fpscr_zx << FPSCR_ZX) | |
|
132 |
(fpscr_xx << FPSCR_XX) | |
|
133 |
(fpscr_vsxnan << FPSCR_VXSNAN) | |
|
134 |
(fpscr_vxisi << FPSCR_VXISI) | |
|
135 |
(fpscr_vxidi << FPSCR_VXIDI) | |
|
136 |
(fpscr_vxzdz << FPSCR_VXZDZ) | |
|
137 |
(fpscr_vximz << FPSCR_VXIMZ) | |
|
138 |
(fpscr_fr << FPSCR_FR) | |
|
139 |
(fpscr_fi << FPSCR_FI) | |
|
140 |
(fpscr_fprf << FPSCR_FPRF) | |
|
141 |
(fpscr_vxsoft << FPSCR_VXSOFT) | |
|
142 |
(fpscr_vxsqrt << FPSCR_VXSQRT) | |
|
143 |
(fpscr_oe << FPSCR_OE) | |
|
144 |
(fpscr_ue << FPSCR_UE) | |
|
145 |
(fpscr_ze << FPSCR_ZE) | |
|
146 |
(fpscr_xe << FPSCR_XE) | |
|
147 |
(fpscr_ni << FPSCR_NI) | |
|
148 |
(fpscr_rn << FPSCR_RN); |
|
127 |
/* The 32 MSB of the target fpr are undefined. |
|
128 |
* They'll be zero... |
|
129 |
*/ |
|
130 |
union { |
|
131 |
double d; |
|
132 |
struct { |
|
133 |
uint32_t u[2]; |
|
134 |
} s; |
|
135 |
} u; |
|
136 |
int i; |
|
137 |
|
|
138 |
u.s.u[0] = 0; |
|
139 |
u.s.u[1] = 0; |
|
140 |
for (i = 0; i < 8; i++) |
|
141 |
u.s.u[1] |= env->fpscr[i] << (4 * i); |
|
142 |
FT0 = u.d; |
|
149 | 143 |
} |
150 | 144 |
|
151 |
/* We keep only 32 bits of input... */ |
|
152 |
/* For now, this is COMPLETELY BUGGY ! */ |
|
153 |
void do_store_fpscr (uint8_t mask, uint32_t fp) |
|
145 |
void do_store_fpscr (uint32_t mask) |
|
154 | 146 |
{ |
147 |
/* |
|
148 |
* We use only the 32 LSB of the incoming fpr |
|
149 |
*/ |
|
150 |
union { |
|
151 |
double d; |
|
152 |
struct { |
|
153 |
uint32_t u[2]; |
|
154 |
} s; |
|
155 |
} u; |
|
155 | 156 |
int i; |
156 | 157 |
|
157 |
for (i = 0; i < 7; i++) { |
|
158 |
if ((mask & (1 << i)) == 0) |
|
159 |
fp &= ~(0xf << (4 * i)); |
|
158 |
u.d = FT0; |
|
159 |
if (mask & 0x80) |
|
160 |
env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[1] >> 28) & ~0x9); |
|
161 |
for (i = 1; i < 7; i++) { |
|
162 |
if (mask & (1 << (7 - i))) |
|
163 |
env->fpscr[i] = (u.s.u[1] >> (4 * (7 - i))) & 0xF; |
|
164 |
} |
|
165 |
/* TODO: update FEX & VX */ |
|
166 |
/* Set rounding mode */ |
|
167 |
switch (env->fpscr[0] & 0x3) { |
|
168 |
case 0: |
|
169 |
/* Best approximation (round to nearest) */ |
|
170 |
fesetround(FE_TONEAREST); |
|
171 |
break; |
|
172 |
case 1: |
|
173 |
/* Smaller magnitude (round toward zero) */ |
|
174 |
fesetround(FE_TOWARDZERO); |
|
175 |
break; |
|
176 |
case 2: |
|
177 |
/* Round toward +infinite */ |
|
178 |
fesetround(FE_UPWARD); |
|
179 |
break; |
|
180 |
case 3: |
|
181 |
/* Round toward -infinite */ |
|
182 |
fesetround(FE_DOWNWARD); |
|
183 |
break; |
|
160 | 184 |
} |
161 |
if ((mask & 80) != 0) |
|
162 |
fpscr_fx = (fp >> FPSCR_FX) & 0x01; |
|
163 |
fpscr_fex = (fp >> FPSCR_FEX) & 0x01; |
|
164 |
fpscr_vx = (fp >> FPSCR_VX) & 0x01; |
|
165 |
fpscr_ox = (fp >> FPSCR_OX) & 0x01; |
|
166 |
fpscr_ux = (fp >> FPSCR_UX) & 0x01; |
|
167 |
fpscr_zx = (fp >> FPSCR_ZX) & 0x01; |
|
168 |
fpscr_xx = (fp >> FPSCR_XX) & 0x01; |
|
169 |
fpscr_vsxnan = (fp >> FPSCR_VXSNAN) & 0x01; |
|
170 |
fpscr_vxisi = (fp >> FPSCR_VXISI) & 0x01; |
|
171 |
fpscr_vxidi = (fp >> FPSCR_VXIDI) & 0x01; |
|
172 |
fpscr_vxzdz = (fp >> FPSCR_VXZDZ) & 0x01; |
|
173 |
fpscr_vximz = (fp >> FPSCR_VXIMZ) & 0x01; |
|
174 |
fpscr_fr = (fp >> FPSCR_FR) & 0x01; |
|
175 |
fpscr_fi = (fp >> FPSCR_FI) & 0x01; |
|
176 |
fpscr_fprf = (fp >> FPSCR_FPRF) & 0x1F; |
|
177 |
fpscr_vxsoft = (fp >> FPSCR_VXSOFT) & 0x01; |
|
178 |
fpscr_vxsqrt = (fp >> FPSCR_VXSQRT) & 0x01; |
|
179 |
fpscr_oe = (fp >> FPSCR_OE) & 0x01; |
|
180 |
fpscr_ue = (fp >> FPSCR_UE) & 0x01; |
|
181 |
fpscr_ze = (fp >> FPSCR_ZE) & 0x01; |
|
182 |
fpscr_xe = (fp >> FPSCR_XE) & 0x01; |
|
183 |
fpscr_ni = (fp >> FPSCR_NI) & 0x01; |
|
184 |
fpscr_rn = (fp >> FPSCR_RN) & 0x03; |
|
185 | 185 |
} |
186 | 186 |
|
187 | 187 |
int32_t do_sraw(int32_t value, uint32_t shift) |
... | ... | |
220 | 220 |
int sh; |
221 | 221 |
|
222 | 222 |
for (; count > 3; count -= 4, src += 4) { |
223 |
if (reg == 32) |
|
224 |
reg = 0; |
|
225 | 223 |
ugpr(reg++) = ld32(src); |
224 |
if (T2 == 32) |
|
225 |
T2 = 0; |
|
226 | 226 |
} |
227 | 227 |
if (count > 0) { |
228 |
for (sh = 24, tmp = 0; count > 0; count--, src++, sh -= 8) { |
|
229 |
if (reg == 32) |
|
230 |
reg = 0; |
|
231 |
tmp |= ld8(src) << sh; |
|
232 |
if (sh == 0) { |
|
233 |
sh = 32; |
|
234 |
ugpr(reg++) = tmp; |
|
235 | 228 |
tmp = 0; |
236 |
} |
|
229 |
for (sh = 24; count > 0; count--, src++, sh -= 8) { |
|
230 |
tmp |= ld8(src) << sh; |
|
237 | 231 |
} |
238 | 232 |
ugpr(reg) = tmp; |
239 | 233 |
} |
... | ... | |
244 | 238 |
int sh; |
245 | 239 |
|
246 | 240 |
for (; count > 3; count -= 4, dest += 4) { |
241 |
st32(dest, ugpr(reg++)); |
|
247 | 242 |
if (reg == 32) |
248 | 243 |
reg = 0; |
249 |
st32(dest, ugpr(reg++)); |
|
250 | 244 |
} |
251 | 245 |
if (count > 0) { |
252 | 246 |
for (sh = 24; count > 0; count--, dest++, sh -= 8) { |
253 |
if (reg == 32) |
|
254 |
reg = 0; |
|
255 | 247 |
st8(dest, (ugpr(reg) >> sh) & 0xFF); |
256 |
if (sh == 0) { |
|
257 |
sh = 32; |
|
258 |
reg++; |
|
259 | 248 |
} |
260 | 249 |
} |
250 |
} |
|
251 |
|
|
252 |
void do_dcbz (void) |
|
253 |
{ |
|
254 |
int i; |
|
255 |
|
|
256 |
/* Assume cache line size is 32 */ |
|
257 |
for (i = 0; i < 8; i++) { |
|
258 |
st32(T0, 0); |
|
259 |
T0 += 4; |
|
261 | 260 |
} |
262 | 261 |
} |
262 |
|
|
263 |
/* Instruction cache invalidation helper */ |
|
264 |
void do_icbi (void) |
|
265 |
{ |
|
266 |
tb_invalidate_page(T0); |
|
267 |
} |
Also available in: Unified diff