Revision 9ef39277 target-arm/op_helper.c
b/target-arm/op_helper.c | ||
---|---|---|
29 | 29 |
cpu_loop_exit(env); |
30 | 30 |
} |
31 | 31 |
|
32 |
uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, |
|
32 |
uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
|
|
33 | 33 |
uint32_t rn, uint32_t maxindex) |
34 | 34 |
{ |
35 | 35 |
uint32_t val; |
... | ... | |
101 | 101 |
|
102 | 102 |
/* FIXME: Pass an explicit pointer to QF to CPUARMState, and move saturating |
103 | 103 |
instructions into helper.c */ |
104 |
uint32_t HELPER(add_setq)(uint32_t a, uint32_t b) |
|
104 |
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
105 | 105 |
{ |
106 | 106 |
uint32_t res = a + b; |
107 | 107 |
if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) |
... | ... | |
109 | 109 |
return res; |
110 | 110 |
} |
111 | 111 |
|
112 |
uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b) |
|
112 |
uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
113 | 113 |
{ |
114 | 114 |
uint32_t res = a + b; |
115 | 115 |
if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) { |
... | ... | |
119 | 119 |
return res; |
120 | 120 |
} |
121 | 121 |
|
122 |
uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b) |
|
122 |
uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
123 | 123 |
{ |
124 | 124 |
uint32_t res = a - b; |
125 | 125 |
if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) { |
... | ... | |
129 | 129 |
return res; |
130 | 130 |
} |
131 | 131 |
|
132 |
uint32_t HELPER(double_saturate)(int32_t val) |
|
132 |
uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val)
|
|
133 | 133 |
{ |
134 | 134 |
uint32_t res; |
135 | 135 |
if (val >= 0x40000000) { |
... | ... | |
144 | 144 |
return res; |
145 | 145 |
} |
146 | 146 |
|
147 |
uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b) |
|
147 |
uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
148 | 148 |
{ |
149 | 149 |
uint32_t res = a + b; |
150 | 150 |
if (res < a) { |
... | ... | |
154 | 154 |
return res; |
155 | 155 |
} |
156 | 156 |
|
157 |
uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b) |
|
157 |
uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
158 | 158 |
{ |
159 | 159 |
uint32_t res = a - b; |
160 | 160 |
if (res > a) { |
... | ... | |
165 | 165 |
} |
166 | 166 |
|
167 | 167 |
/* Signed saturation. */ |
168 |
static inline uint32_t do_ssat(int32_t val, int shift) |
|
168 |
static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
|
|
169 | 169 |
{ |
170 | 170 |
int32_t top; |
171 | 171 |
uint32_t mask; |
... | ... | |
183 | 183 |
} |
184 | 184 |
|
185 | 185 |
/* Unsigned saturation. */ |
186 |
static inline uint32_t do_usat(int32_t val, int shift) |
|
186 |
static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
|
|
187 | 187 |
{ |
188 | 188 |
uint32_t max; |
189 | 189 |
|
... | ... | |
199 | 199 |
} |
200 | 200 |
|
201 | 201 |
/* Signed saturate. */ |
202 |
uint32_t HELPER(ssat)(uint32_t x, uint32_t shift) |
|
202 |
uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
|
|
203 | 203 |
{ |
204 |
return do_ssat(x, shift); |
|
204 |
return do_ssat(env, x, shift);
|
|
205 | 205 |
} |
206 | 206 |
|
207 | 207 |
/* Dual halfword signed saturate. */ |
208 |
uint32_t HELPER(ssat16)(uint32_t x, uint32_t shift) |
|
208 |
uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
|
|
209 | 209 |
{ |
210 | 210 |
uint32_t res; |
211 | 211 |
|
212 |
res = (uint16_t)do_ssat((int16_t)x, shift); |
|
213 |
res |= do_ssat(((int32_t)x) >> 16, shift) << 16; |
|
212 |
res = (uint16_t)do_ssat(env, (int16_t)x, shift);
|
|
213 |
res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
|
|
214 | 214 |
return res; |
215 | 215 |
} |
216 | 216 |
|
217 | 217 |
/* Unsigned saturate. */ |
218 |
uint32_t HELPER(usat)(uint32_t x, uint32_t shift) |
|
218 |
uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
|
|
219 | 219 |
{ |
220 |
return do_usat(x, shift); |
|
220 |
return do_usat(env, x, shift);
|
|
221 | 221 |
} |
222 | 222 |
|
223 | 223 |
/* Dual halfword unsigned saturate. */ |
224 |
uint32_t HELPER(usat16)(uint32_t x, uint32_t shift) |
|
224 |
uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
|
|
225 | 225 |
{ |
226 | 226 |
uint32_t res; |
227 | 227 |
|
228 |
res = (uint16_t)do_usat((int16_t)x, shift); |
|
229 |
res |= do_usat(((int32_t)x) >> 16, shift) << 16; |
|
228 |
res = (uint16_t)do_usat(env, (int16_t)x, shift);
|
|
229 |
res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
|
|
230 | 230 |
return res; |
231 | 231 |
} |
232 | 232 |
|
... | ... | |
243 | 243 |
cpu_loop_exit(env); |
244 | 244 |
} |
245 | 245 |
|
246 |
uint32_t HELPER(cpsr_read)(void)
|
|
246 |
uint32_t HELPER(cpsr_read)(CPUARMState *env)
|
|
247 | 247 |
{ |
248 | 248 |
return cpsr_read(env) & ~CPSR_EXEC; |
249 | 249 |
} |
... | ... | |
254 | 254 |
} |
255 | 255 |
|
256 | 256 |
/* Access to user mode registers from privileged modes. */ |
257 |
uint32_t HELPER(get_user_reg)(uint32_t regno) |
|
257 |
uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
|
|
258 | 258 |
{ |
259 | 259 |
uint32_t val; |
260 | 260 |
|
... | ... | |
329 | 329 |
The only way to do that in TCG is a conditional branch, which clobbers |
330 | 330 |
all our temporaries. For now implement these as helper functions. */ |
331 | 331 |
|
332 |
uint32_t HELPER (add_cc)(uint32_t a, uint32_t b) |
|
332 |
uint32_t HELPER (add_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
333 | 333 |
{ |
334 | 334 |
uint32_t result; |
335 | 335 |
result = a + b; |
... | ... | |
339 | 339 |
return result; |
340 | 340 |
} |
341 | 341 |
|
342 |
uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b) |
|
342 |
uint32_t HELPER(adc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
343 | 343 |
{ |
344 | 344 |
uint32_t result; |
345 | 345 |
if (!env->CF) { |
... | ... | |
354 | 354 |
return result; |
355 | 355 |
} |
356 | 356 |
|
357 |
uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b) |
|
357 |
uint32_t HELPER(sub_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
358 | 358 |
{ |
359 | 359 |
uint32_t result; |
360 | 360 |
result = a - b; |
... | ... | |
364 | 364 |
return result; |
365 | 365 |
} |
366 | 366 |
|
367 |
uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b) |
|
367 |
uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
|
|
368 | 368 |
{ |
369 | 369 |
uint32_t result; |
370 | 370 |
if (!env->CF) { |
... | ... | |
381 | 381 |
|
382 | 382 |
/* Similarly for variable shift instructions. */ |
383 | 383 |
|
384 |
uint32_t HELPER(shl)(uint32_t x, uint32_t i) |
|
384 |
uint32_t HELPER(shl)(CPUARMState *env, uint32_t x, uint32_t i)
|
|
385 | 385 |
{ |
386 | 386 |
int shift = i & 0xff; |
387 | 387 |
if (shift >= 32) |
... | ... | |
389 | 389 |
return x << shift; |
390 | 390 |
} |
391 | 391 |
|
392 |
uint32_t HELPER(shr)(uint32_t x, uint32_t i) |
|
392 |
uint32_t HELPER(shr)(CPUARMState *env, uint32_t x, uint32_t i)
|
|
393 | 393 |
{ |
394 | 394 |
int shift = i & 0xff; |
395 | 395 |
if (shift >= 32) |
... | ... | |
397 | 397 |
return (uint32_t)x >> shift; |
398 | 398 |
} |
399 | 399 |
|
400 |
uint32_t HELPER(sar)(uint32_t x, uint32_t i) |
|
400 |
uint32_t HELPER(sar)(CPUARMState *env, uint32_t x, uint32_t i)
|
|
401 | 401 |
{ |
402 | 402 |
int shift = i & 0xff; |
403 | 403 |
if (shift >= 32) |
... | ... | |
405 | 405 |
return (int32_t)x >> shift; |
406 | 406 |
} |
407 | 407 |
|
408 |
uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i) |
|
408 |
uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
|
409 | 409 |
{ |
410 | 410 |
int shift = i & 0xff; |
411 | 411 |
if (shift >= 32) { |
... | ... | |
421 | 421 |
return x; |
422 | 422 |
} |
423 | 423 |
|
424 |
uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i) |
|
424 |
uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
|
425 | 425 |
{ |
426 | 426 |
int shift = i & 0xff; |
427 | 427 |
if (shift >= 32) { |
... | ... | |
437 | 437 |
return x; |
438 | 438 |
} |
439 | 439 |
|
440 |
uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i) |
|
440 |
uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
|
441 | 441 |
{ |
442 | 442 |
int shift = i & 0xff; |
443 | 443 |
if (shift >= 32) { |
... | ... | |
450 | 450 |
return x; |
451 | 451 |
} |
452 | 452 |
|
453 |
uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i) |
|
453 |
uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
|
|
454 | 454 |
{ |
455 | 455 |
int shift1, shift; |
456 | 456 |
shift1 = i & 0xff; |
Also available in: Unified diff