Commit 9a119ff6c1cba1fde88bf6275d6ba40c95d35dce
1 parent
f51bbbfe
ARM TCG conversion 3/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4140 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
65 additions
and
196 deletions
target-arm/op.c
... | ... | @@ -317,55 +317,6 @@ void OPPROTO op_clrex(void) |
317 | 317 | cpu_unlock(); |
318 | 318 | } |
319 | 319 | |
320 | -/* shifts */ | |
321 | - | |
322 | -/* T1 based, set C flag */ | |
323 | -void OPPROTO op_shll_T1_im_cc(void) | |
324 | -{ | |
325 | - env->CF = (T1 >> (32 - PARAM1)) & 1; | |
326 | - T1 = T1 << PARAM1; | |
327 | -} | |
328 | - | |
329 | -void OPPROTO op_shrl_T1_im_cc(void) | |
330 | -{ | |
331 | - env->CF = (T1 >> (PARAM1 - 1)) & 1; | |
332 | - T1 = (uint32_t)T1 >> PARAM1; | |
333 | -} | |
334 | - | |
335 | -void OPPROTO op_shrl_T1_0_cc(void) | |
336 | -{ | |
337 | - env->CF = (T1 >> 31) & 1; | |
338 | - T1 = 0; | |
339 | -} | |
340 | - | |
341 | -void OPPROTO op_sarl_T1_im_cc(void) | |
342 | -{ | |
343 | - env->CF = (T1 >> (PARAM1 - 1)) & 1; | |
344 | - T1 = (int32_t)T1 >> PARAM1; | |
345 | -} | |
346 | - | |
347 | -void OPPROTO op_sarl_T1_0_cc(void) | |
348 | -{ | |
349 | - env->CF = (T1 >> 31) & 1; | |
350 | - T1 = (int32_t)T1 >> 31; | |
351 | -} | |
352 | - | |
353 | -void OPPROTO op_rorl_T1_im_cc(void) | |
354 | -{ | |
355 | - int shift; | |
356 | - shift = PARAM1; | |
357 | - env->CF = (T1 >> (shift - 1)) & 1; | |
358 | - T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift)); | |
359 | -} | |
360 | - | |
361 | -void OPPROTO op_rrxl_T1_cc(void) | |
362 | -{ | |
363 | - uint32_t c; | |
364 | - c = T1 & 1; | |
365 | - T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31); | |
366 | - env->CF = c; | |
367 | -} | |
368 | - | |
369 | 320 | /* T1 based, use T0 as shift count */ |
370 | 321 | |
371 | 322 | void OPPROTO op_shll_T1_T0(void) |
... | ... | @@ -573,83 +524,6 @@ void OPPROTO op_subl_T0_T1_usaturate(void) |
573 | 524 | FORCE_RET(); |
574 | 525 | } |
575 | 526 | |
576 | -/* Thumb shift by immediate */ | |
577 | -void OPPROTO op_shll_T0_im_thumb_cc(void) | |
578 | -{ | |
579 | - int shift; | |
580 | - shift = PARAM1; | |
581 | - if (shift != 0) { | |
582 | - env->CF = (T0 >> (32 - shift)) & 1; | |
583 | - T0 = T0 << shift; | |
584 | - } | |
585 | - env->NZF = T0; | |
586 | - FORCE_RET(); | |
587 | -} | |
588 | - | |
589 | -void OPPROTO op_shll_T0_im_thumb(void) | |
590 | -{ | |
591 | - T0 = T0 << PARAM1; | |
592 | - FORCE_RET(); | |
593 | -} | |
594 | - | |
595 | -void OPPROTO op_shrl_T0_im_thumb_cc(void) | |
596 | -{ | |
597 | - int shift; | |
598 | - | |
599 | - shift = PARAM1; | |
600 | - if (shift == 0) { | |
601 | - env->CF = ((uint32_t)T0) >> 31; | |
602 | - T0 = 0; | |
603 | - } else { | |
604 | - env->CF = (T0 >> (shift - 1)) & 1; | |
605 | - T0 = T0 >> shift; | |
606 | - } | |
607 | - env->NZF = T0; | |
608 | - FORCE_RET(); | |
609 | -} | |
610 | - | |
611 | -void OPPROTO op_shrl_T0_im_thumb(void) | |
612 | -{ | |
613 | - int shift; | |
614 | - | |
615 | - shift = PARAM1; | |
616 | - if (shift == 0) { | |
617 | - T0 = 0; | |
618 | - } else { | |
619 | - T0 = T0 >> shift; | |
620 | - } | |
621 | - FORCE_RET(); | |
622 | -} | |
623 | - | |
624 | -void OPPROTO op_sarl_T0_im_thumb_cc(void) | |
625 | -{ | |
626 | - int shift; | |
627 | - | |
628 | - shift = PARAM1; | |
629 | - if (shift == 0) { | |
630 | - T0 = ((int32_t)T0) >> 31; | |
631 | - env->CF = T0 & 1; | |
632 | - } else { | |
633 | - env->CF = (T0 >> (shift - 1)) & 1; | |
634 | - T0 = ((int32_t)T0) >> shift; | |
635 | - } | |
636 | - env->NZF = T0; | |
637 | - FORCE_RET(); | |
638 | -} | |
639 | - | |
640 | -void OPPROTO op_sarl_T0_im_thumb(void) | |
641 | -{ | |
642 | - int shift; | |
643 | - | |
644 | - shift = PARAM1; | |
645 | - if (shift == 0) { | |
646 | - env->CF = T0 & 1; | |
647 | - } else { | |
648 | - T0 = ((int32_t)T0) >> shift; | |
649 | - } | |
650 | - FORCE_RET(); | |
651 | -} | |
652 | - | |
653 | 527 | /* exceptions */ |
654 | 528 | |
655 | 529 | void OPPROTO op_swi(void) | ... | ... |
target-arm/translate.c
... | ... | @@ -228,12 +228,14 @@ static void gen_add16(TCGv t0, TCGv t1) |
228 | 228 | dead_tmp(t1); |
229 | 229 | } |
230 | 230 | |
231 | +#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF)) | |
232 | + | |
231 | 233 | /* Set CF to the top bit of var. */ |
232 | 234 | static void gen_set_CF_bit31(TCGv var) |
233 | 235 | { |
234 | 236 | TCGv tmp = new_tmp(); |
235 | 237 | tcg_gen_shri_i32(tmp, var, 31); |
236 | - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, CF)); | |
238 | + gen_set_CF(var); | |
237 | 239 | dead_tmp(tmp); |
238 | 240 | } |
239 | 241 | |
... | ... | @@ -282,31 +284,67 @@ static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i) |
282 | 284 | dead_tmp(tmp); |
283 | 285 | } |
284 | 286 | |
285 | -/* Shift by immediate. Includes special handling for shift == 0. */ | |
286 | -static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift) | |
287 | +static void shifter_out_im(TCGv var, int shift) | |
287 | 288 | { |
288 | - if (shift != 0) { | |
289 | - switch (shiftop) { | |
290 | - case 0: tcg_gen_shli_i32(var, var, shift); break; | |
291 | - case 1: tcg_gen_shri_i32(var, var, shift); break; | |
292 | - case 2: tcg_gen_sari_i32(var, var, shift); break; | |
293 | - case 3: tcg_gen_rori_i32(var, var, shift); break; | |
294 | - } | |
289 | + TCGv tmp = new_tmp(); | |
290 | + if (shift == 0) { | |
291 | + tcg_gen_andi_i32(tmp, var, 1); | |
295 | 292 | } else { |
296 | - TCGv tmp; | |
293 | + tcg_gen_shri_i32(tmp, var, shift); | |
294 | + if (shift != 31); | |
295 | + tcg_gen_andi_i32(tmp, tmp, 1); | |
296 | + } | |
297 | + gen_set_CF(tmp); | |
298 | + dead_tmp(tmp); | |
299 | +} | |
297 | 300 | |
298 | - switch (shiftop) { | |
299 | - case 0: break; | |
300 | - case 1: tcg_gen_movi_i32(var, 0); break; | |
301 | - case 2: tcg_gen_sari_i32(var, var, 31); break; | |
302 | - case 3: /* rrx */ | |
303 | - tcg_gen_shri_i32(var, var, 1); | |
304 | - tmp = new_tmp(); | |
301 | +/* Shift by immediate. Includes special handling for shift == 0. */ | |
302 | +static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags) | |
303 | +{ | |
304 | + switch (shiftop) { | |
305 | + case 0: /* LSL */ | |
306 | + if (shift != 0) { | |
307 | + if (flags) | |
308 | + shifter_out_im(var, 32 - shift); | |
309 | + tcg_gen_shli_i32(var, var, shift); | |
310 | + } | |
311 | + break; | |
312 | + case 1: /* LSR */ | |
313 | + if (shift == 0) { | |
314 | + if (flags) { | |
315 | + tcg_gen_shri_i32(var, var, 31); | |
316 | + gen_set_CF(var); | |
317 | + } | |
318 | + tcg_gen_movi_i32(var, 0); | |
319 | + } else { | |
320 | + if (flags) | |
321 | + shifter_out_im(var, shift - 1); | |
322 | + tcg_gen_shri_i32(var, var, shift); | |
323 | + } | |
324 | + break; | |
325 | + case 2: /* ASR */ | |
326 | + if (shift == 0) | |
327 | + shift = 32; | |
328 | + if (flags) | |
329 | + shifter_out_im(var, shift - 1); | |
330 | + if (shift == 32) | |
331 | + shift = 31; | |
332 | + tcg_gen_sari_i32(var, var, shift); | |
333 | + break; | |
334 | + case 3: /* ROR/RRX */ | |
335 | + if (shift != 0) { | |
336 | + if (flags) | |
337 | + shifter_out_im(var, shift - 1); | |
338 | + tcg_gen_rori_i32(var, var, shift); break; | |
339 | + } else { | |
340 | + TCGv tmp = new_tmp(); | |
305 | 341 | tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF)); |
342 | + if (flags) | |
343 | + shifter_out_im(var, 0); | |
344 | + tcg_gen_shri_i32(var, var, 1); | |
306 | 345 | tcg_gen_shli_i32(tmp, tmp, 31); |
307 | 346 | tcg_gen_or_i32(var, var, tmp); |
308 | 347 | dead_tmp(tmp); |
309 | - break; | |
310 | 348 | } |
311 | 349 | } |
312 | 350 | }; |
... | ... | @@ -392,20 +430,6 @@ const uint8_t table_logic_cc[16] = { |
392 | 430 | 1, /* mvn */ |
393 | 431 | }; |
394 | 432 | |
395 | -static GenOpFunc1 *gen_shift_T1_im_cc[4] = { | |
396 | - gen_op_shll_T1_im_cc, | |
397 | - gen_op_shrl_T1_im_cc, | |
398 | - gen_op_sarl_T1_im_cc, | |
399 | - gen_op_rorl_T1_im_cc, | |
400 | -}; | |
401 | - | |
402 | -static GenOpFunc *gen_shift_T1_0_cc[4] = { | |
403 | - NULL, | |
404 | - gen_op_shrl_T1_0_cc, | |
405 | - gen_op_sarl_T1_0_cc, | |
406 | - gen_op_rrxl_T1_cc, | |
407 | -}; | |
408 | - | |
409 | 433 | static GenOpFunc *gen_shift_T1_T0[4] = { |
410 | 434 | gen_op_shll_T1_T0, |
411 | 435 | gen_op_shrl_T1_T0, |
... | ... | @@ -420,18 +444,6 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = { |
420 | 444 | gen_op_rorl_T1_T0_cc, |
421 | 445 | }; |
422 | 446 | |
423 | -static GenOpFunc1 *gen_shift_T0_im_thumb_cc[3] = { | |
424 | - gen_op_shll_T0_im_thumb_cc, | |
425 | - gen_op_shrl_T0_im_thumb_cc, | |
426 | - gen_op_sarl_T0_im_thumb_cc, | |
427 | -}; | |
428 | - | |
429 | -static GenOpFunc1 *gen_shift_T0_im_thumb[3] = { | |
430 | - gen_op_shll_T0_im_thumb, | |
431 | - gen_op_shrl_T0_im_thumb, | |
432 | - gen_op_sarl_T0_im_thumb, | |
433 | -}; | |
434 | - | |
435 | 447 | /* Set PC and thumb state from T0. Clobbers T0. */ |
436 | 448 | static inline void gen_bx(DisasContext *s) |
437 | 449 | { |
... | ... | @@ -530,7 +542,7 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) |
530 | 542 | shift = (insn >> 7) & 0x1f; |
531 | 543 | shiftop = (insn >> 5) & 3; |
532 | 544 | offset = load_reg(s, rm); |
533 | - gen_arm_shift_im(offset, shiftop, shift); | |
545 | + gen_arm_shift_im(offset, shiftop, shift, 0); | |
534 | 546 | if (!(insn & (1 << 23))) |
535 | 547 | tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset); |
536 | 548 | else |
... | ... | @@ -5126,15 +5138,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) |
5126 | 5138 | shiftop = (insn >> 5) & 3; |
5127 | 5139 | if (!(insn & (1 << 4))) { |
5128 | 5140 | shift = (insn >> 7) & 0x1f; |
5129 | - if (logic_cc) { | |
5130 | - if (shift != 0) { | |
5131 | - gen_shift_T1_im_cc[shiftop](shift); | |
5132 | - } else if (shiftop != 0) { | |
5133 | - gen_shift_T1_0_cc[shiftop](); | |
5134 | - } | |
5135 | - } else { | |
5136 | - gen_arm_shift_im(cpu_T[1], shiftop, shift); | |
5137 | - } | |
5141 | + gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc); | |
5138 | 5142 | } else { |
5139 | 5143 | rs = (insn >> 8) & 0xf; |
5140 | 5144 | gen_movl_T0_reg(s, rs); |
... | ... | @@ -6243,15 +6247,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) |
6243 | 6247 | shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); |
6244 | 6248 | conds = (insn & (1 << 20)) != 0; |
6245 | 6249 | logic_cc = (conds && thumb2_logic_op(op)); |
6246 | - if (logic_cc) { | |
6247 | - if (shift != 0) { | |
6248 | - gen_shift_T1_im_cc[shiftop](shift); | |
6249 | - } else if (shiftop != 0) { | |
6250 | - gen_shift_T1_0_cc[shiftop](); | |
6251 | - } | |
6252 | - } else { | |
6253 | - gen_arm_shift_im(cpu_T[1], shiftop, shift); | |
6254 | - } | |
6250 | + gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc); | |
6255 | 6251 | if (gen_thumb2_data_op(s, op, conds, 0)) |
6256 | 6252 | goto illegal_op; |
6257 | 6253 | if (rd != 15) |
... | ... | @@ -6960,12 +6956,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) |
6960 | 6956 | /* shift immediate */ |
6961 | 6957 | rm = (insn >> 3) & 7; |
6962 | 6958 | shift = (insn >> 6) & 0x1f; |
6963 | - gen_movl_T0_reg(s, rm); | |
6964 | - if (s->condexec_mask) | |
6965 | - gen_shift_T0_im_thumb[op](shift); | |
6966 | - else | |
6967 | - gen_shift_T0_im_thumb_cc[op](shift); | |
6968 | - gen_movl_reg_T0(s, rd); | |
6959 | + tmp = load_reg(s, rm); | |
6960 | + gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0); | |
6961 | + if (!s->condexec_mask) | |
6962 | + gen_logic_CC(tmp); | |
6963 | + store_reg(s, rd, tmp); | |
6969 | 6964 | } |
6970 | 6965 | break; |
6971 | 6966 | case 2: case 3: | ... | ... |