Commit 9a119ff6c1cba1fde88bf6275d6ba40c95d35dce

Authored by pbrook
1 parent f51bbbfe

ARM TCG conversion 3/16.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4140 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/op.c
@@ -317,55 +317,6 @@ void OPPROTO op_clrex(void) @@ -317,55 +317,6 @@ void OPPROTO op_clrex(void)
317 cpu_unlock(); 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 /* T1 based, use T0 as shift count */ 320 /* T1 based, use T0 as shift count */
370 321
371 void OPPROTO op_shll_T1_T0(void) 322 void OPPROTO op_shll_T1_T0(void)
@@ -573,83 +524,6 @@ void OPPROTO op_subl_T0_T1_usaturate(void) @@ -573,83 +524,6 @@ void OPPROTO op_subl_T0_T1_usaturate(void)
573 FORCE_RET(); 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 /* exceptions */ 527 /* exceptions */
654 528
655 void OPPROTO op_swi(void) 529 void OPPROTO op_swi(void)
target-arm/translate.c
@@ -228,12 +228,14 @@ static void gen_add16(TCGv t0, TCGv t1) @@ -228,12 +228,14 @@ static void gen_add16(TCGv t0, TCGv t1)
228 dead_tmp(t1); 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 /* Set CF to the top bit of var. */ 233 /* Set CF to the top bit of var. */
232 static void gen_set_CF_bit31(TCGv var) 234 static void gen_set_CF_bit31(TCGv var)
233 { 235 {
234 TCGv tmp = new_tmp(); 236 TCGv tmp = new_tmp();
235 tcg_gen_shri_i32(tmp, var, 31); 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 dead_tmp(tmp); 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,31 +284,67 @@ static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
282 dead_tmp(tmp); 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 } else { 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 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUState, CF)); 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 tcg_gen_shli_i32(tmp, tmp, 31); 345 tcg_gen_shli_i32(tmp, tmp, 31);
307 tcg_gen_or_i32(var, var, tmp); 346 tcg_gen_or_i32(var, var, tmp);
308 dead_tmp(tmp); 347 dead_tmp(tmp);
309 - break;  
310 } 348 }
311 } 349 }
312 }; 350 };
@@ -392,20 +430,6 @@ const uint8_t table_logic_cc[16] = { @@ -392,20 +430,6 @@ const uint8_t table_logic_cc[16] = {
392 1, /* mvn */ 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 static GenOpFunc *gen_shift_T1_T0[4] = { 433 static GenOpFunc *gen_shift_T1_T0[4] = {
410 gen_op_shll_T1_T0, 434 gen_op_shll_T1_T0,
411 gen_op_shrl_T1_T0, 435 gen_op_shrl_T1_T0,
@@ -420,18 +444,6 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = { @@ -420,18 +444,6 @@ static GenOpFunc *gen_shift_T1_T0_cc[4] = {
420 gen_op_rorl_T1_T0_cc, 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 /* Set PC and thumb state from T0. Clobbers T0. */ 447 /* Set PC and thumb state from T0. Clobbers T0. */
436 static inline void gen_bx(DisasContext *s) 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,7 +542,7 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
530 shift = (insn >> 7) & 0x1f; 542 shift = (insn >> 7) & 0x1f;
531 shiftop = (insn >> 5) & 3; 543 shiftop = (insn >> 5) & 3;
532 offset = load_reg(s, rm); 544 offset = load_reg(s, rm);
533 - gen_arm_shift_im(offset, shiftop, shift); 545 + gen_arm_shift_im(offset, shiftop, shift, 0);
534 if (!(insn & (1 << 23))) 546 if (!(insn & (1 << 23)))
535 tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset); 547 tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset);
536 else 548 else
@@ -5126,15 +5138,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5126,15 +5138,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5126 shiftop = (insn >> 5) & 3; 5138 shiftop = (insn >> 5) & 3;
5127 if (!(insn & (1 << 4))) { 5139 if (!(insn & (1 << 4))) {
5128 shift = (insn >> 7) & 0x1f; 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 } else { 5142 } else {
5139 rs = (insn >> 8) & 0xf; 5143 rs = (insn >> 8) & 0xf;
5140 gen_movl_T0_reg(s, rs); 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,15 +6247,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6243 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); 6247 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
6244 conds = (insn & (1 << 20)) != 0; 6248 conds = (insn & (1 << 20)) != 0;
6245 logic_cc = (conds && thumb2_logic_op(op)); 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 if (gen_thumb2_data_op(s, op, conds, 0)) 6251 if (gen_thumb2_data_op(s, op, conds, 0))
6256 goto illegal_op; 6252 goto illegal_op;
6257 if (rd != 15) 6253 if (rd != 15)
@@ -6960,12 +6956,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) @@ -6960,12 +6956,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
6960 /* shift immediate */ 6956 /* shift immediate */
6961 rm = (insn >> 3) & 7; 6957 rm = (insn >> 3) & 7;
6962 shift = (insn >> 6) & 0x1f; 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 break; 6965 break;
6971 case 2: case 3: 6966 case 2: case 3: