Commit 6231868b110365d0d870c2f4974bfba26ccb86a9
1 parent
c1e1a491
CRIS: Purify some of the flag evaluation helpers.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6227 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
154 additions
and
160 deletions
target-cris/helper.h
... | ... | @@ -13,13 +13,13 @@ DEF_HELPER_2(movl_reg_sreg, void, i32, i32) |
13 | 13 | DEF_HELPER_FLAGS_1(lz, TCG_CALL_PURE, i32, i32); |
14 | 14 | DEF_HELPER_FLAGS_3(btst, TCG_CALL_PURE, i32, i32, i32, i32); |
15 | 15 | |
16 | -DEF_HELPER_0(evaluate_flags_muls, void) | |
17 | -DEF_HELPER_0(evaluate_flags_mulu, void) | |
18 | -DEF_HELPER_0(evaluate_flags_mcp, void) | |
19 | -DEF_HELPER_0(evaluate_flags_alu_4, void) | |
20 | -DEF_HELPER_0(evaluate_flags_sub_4, void) | |
21 | -DEF_HELPER_0(evaluate_flags_move_4, void) | |
22 | -DEF_HELPER_0(evaluate_flags_move_2, void) | |
16 | +DEF_HELPER_FLAGS_3(evaluate_flags_muls, TCG_CALL_PURE, i32, i32, i32, i32) | |
17 | +DEF_HELPER_FLAGS_3(evaluate_flags_mulu, TCG_CALL_PURE, i32, i32, i32, i32) | |
18 | +DEF_HELPER_FLAGS_4(evaluate_flags_mcp, TCG_CALL_PURE, i32, i32, i32, i32, i32) | |
19 | +DEF_HELPER_FLAGS_4(evaluate_flags_alu_4, TCG_CALL_PURE, i32, i32, i32, i32, i32) | |
20 | +DEF_HELPER_FLAGS_4(evaluate_flags_sub_4, TCG_CALL_PURE, i32, i32, i32, i32, i32) | |
21 | +DEF_HELPER_FLAGS_2(evaluate_flags_move_4, TCG_CALL_PURE, i32, i32, i32) | |
22 | +DEF_HELPER_FLAGS_2(evaluate_flags_move_2, TCG_CALL_PURE, i32, i32, i32) | |
23 | 23 | DEF_HELPER_0(evaluate_flags, void) |
24 | 24 | DEF_HELPER_0(top_evaluate_flags, void) |
25 | 25 | ... | ... |
target-cris/op_helper.c
... | ... | @@ -275,7 +275,7 @@ uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs) |
275 | 275 | return ccs; |
276 | 276 | } |
277 | 277 | |
278 | -static void evaluate_flags_writeback(uint32_t flags) | |
278 | +static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs) | |
279 | 279 | { |
280 | 280 | unsigned int x, z, mask; |
281 | 281 | |
... | ... | @@ -289,27 +289,19 @@ static void evaluate_flags_writeback(uint32_t flags) |
289 | 289 | flags &= mask; |
290 | 290 | |
291 | 291 | /* all insn clear the x-flag except setf or clrf. */ |
292 | - env->pregs[PR_CCS] &= ~mask; | |
293 | - env->pregs[PR_CCS] |= flags; | |
292 | + ccs &= ~mask; | |
293 | + ccs |= flags; | |
294 | + return ccs; | |
294 | 295 | } |
295 | 296 | |
296 | -void helper_evaluate_flags_muls(void) | |
297 | +uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof) | |
297 | 298 | { |
298 | - uint32_t src; | |
299 | - uint32_t dst; | |
300 | - uint32_t res; | |
301 | 299 | uint32_t flags = 0; |
302 | 300 | int64_t tmp; |
303 | - int32_t mof; | |
304 | 301 | int dneg; |
305 | 302 | |
306 | - src = env->cc_src; | |
307 | - dst = env->cc_dest; | |
308 | - res = env->cc_result; | |
309 | - | |
310 | 303 | dneg = ((int32_t)res) < 0; |
311 | 304 | |
312 | - mof = env->pregs[PR_MOF]; | |
313 | 305 | tmp = mof; |
314 | 306 | tmp <<= 32; |
315 | 307 | tmp |= res; |
... | ... | @@ -320,23 +312,14 @@ void helper_evaluate_flags_muls(void) |
320 | 312 | if ((dneg && mof != -1) |
321 | 313 | || (!dneg && mof != 0)) |
322 | 314 | flags |= V_FLAG; |
323 | - evaluate_flags_writeback(flags); | |
315 | + return evaluate_flags_writeback(flags, ccs); | |
324 | 316 | } |
325 | 317 | |
326 | -void helper_evaluate_flags_mulu(void) | |
318 | +uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof) | |
327 | 319 | { |
328 | - uint32_t src; | |
329 | - uint32_t dst; | |
330 | - uint32_t res; | |
331 | 320 | uint32_t flags = 0; |
332 | 321 | uint64_t tmp; |
333 | - uint32_t mof; | |
334 | 322 | |
335 | - src = env->cc_src; | |
336 | - dst = env->cc_dest; | |
337 | - res = env->cc_result; | |
338 | - | |
339 | - mof = env->pregs[PR_MOF]; | |
340 | 323 | tmp = mof; |
341 | 324 | tmp <<= 32; |
342 | 325 | tmp |= res; |
... | ... | @@ -347,19 +330,16 @@ void helper_evaluate_flags_mulu(void) |
347 | 330 | if (mof) |
348 | 331 | flags |= V_FLAG; |
349 | 332 | |
350 | - evaluate_flags_writeback(flags); | |
333 | + return evaluate_flags_writeback(flags, ccs); | |
351 | 334 | } |
352 | 335 | |
353 | -void helper_evaluate_flags_mcp(void) | |
336 | +uint32_t helper_evaluate_flags_mcp(uint32_t ccs, | |
337 | + uint32_t src, uint32_t dst, uint32_t res) | |
354 | 338 | { |
355 | - uint32_t src; | |
356 | - uint32_t dst; | |
357 | - uint32_t res; | |
358 | 339 | uint32_t flags = 0; |
359 | 340 | |
360 | - src = env->cc_src & 0x80000000; | |
361 | - dst = env->cc_dest & 0x80000000; | |
362 | - res = env->cc_result; | |
341 | + src = src & 0x80000000; | |
342 | + dst = dst & 0x80000000; | |
363 | 343 | |
364 | 344 | if ((res & 0x80000000L) != 0L) |
365 | 345 | { |
... | ... | @@ -379,19 +359,16 @@ void helper_evaluate_flags_mcp(void) |
379 | 359 | flags |= R_FLAG; |
380 | 360 | } |
381 | 361 | |
382 | - evaluate_flags_writeback(flags); | |
362 | + return evaluate_flags_writeback(flags, ccs); | |
383 | 363 | } |
384 | 364 | |
385 | -void helper_evaluate_flags_alu_4(void) | |
365 | +uint32_t helper_evaluate_flags_alu_4(uint32_t ccs, | |
366 | + uint32_t src, uint32_t dst, uint32_t res) | |
386 | 367 | { |
387 | - uint32_t src; | |
388 | - uint32_t dst; | |
389 | - uint32_t res; | |
390 | 368 | uint32_t flags = 0; |
391 | 369 | |
392 | - src = env->cc_src & 0x80000000; | |
393 | - dst = env->cc_dest & 0x80000000; | |
394 | - res = env->cc_result; | |
370 | + src = src & 0x80000000; | |
371 | + dst = dst & 0x80000000; | |
395 | 372 | |
396 | 373 | if ((res & 0x80000000L) != 0L) |
397 | 374 | { |
... | ... | @@ -411,19 +388,16 @@ void helper_evaluate_flags_alu_4(void) |
411 | 388 | flags |= C_FLAG; |
412 | 389 | } |
413 | 390 | |
414 | - evaluate_flags_writeback(flags); | |
391 | + return evaluate_flags_writeback(flags, ccs); | |
415 | 392 | } |
416 | 393 | |
417 | -void helper_evaluate_flags_sub_4(void) | |
394 | +uint32_t helper_evaluate_flags_sub_4(uint32_t ccs, | |
395 | + uint32_t src, uint32_t dst, uint32_t res) | |
418 | 396 | { |
419 | - uint32_t src; | |
420 | - uint32_t dst; | |
421 | - uint32_t res; | |
422 | 397 | uint32_t flags = 0; |
423 | 398 | |
424 | - src = (~env->cc_src) & 0x80000000; | |
425 | - dst = env->cc_dest & 0x80000000; | |
426 | - res = env->cc_result; | |
399 | + src = (~src) & 0x80000000; | |
400 | + dst = dst & 0x80000000; | |
427 | 401 | |
428 | 402 | if ((res & 0x80000000L) != 0L) |
429 | 403 | { |
... | ... | @@ -444,47 +418,37 @@ void helper_evaluate_flags_sub_4(void) |
444 | 418 | } |
445 | 419 | |
446 | 420 | flags ^= C_FLAG; |
447 | - evaluate_flags_writeback(flags); | |
421 | + return evaluate_flags_writeback(flags, ccs); | |
448 | 422 | } |
449 | 423 | |
450 | -void helper_evaluate_flags_move_4 (void) | |
424 | +uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res) | |
451 | 425 | { |
452 | - uint32_t res; | |
453 | 426 | uint32_t flags = 0; |
454 | 427 | |
455 | - res = env->cc_result; | |
456 | - | |
457 | 428 | if ((int32_t)res < 0) |
458 | 429 | flags |= N_FLAG; |
459 | 430 | else if (res == 0L) |
460 | 431 | flags |= Z_FLAG; |
461 | 432 | |
462 | - evaluate_flags_writeback(flags); | |
433 | + return evaluate_flags_writeback(flags, ccs); | |
463 | 434 | } |
464 | -void helper_evaluate_flags_move_2 (void) | |
435 | +uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res) | |
465 | 436 | { |
466 | - uint32_t src; | |
467 | 437 | uint32_t flags = 0; |
468 | - uint16_t res; | |
469 | - | |
470 | - src = env->cc_src; | |
471 | - res = env->cc_result; | |
472 | 438 | |
473 | 439 | if ((int16_t)res < 0L) |
474 | 440 | flags |= N_FLAG; |
475 | 441 | else if (res == 0) |
476 | 442 | flags |= Z_FLAG; |
477 | 443 | |
478 | - evaluate_flags_writeback(flags); | |
444 | + return evaluate_flags_writeback(flags, ccs); | |
479 | 445 | } |
480 | 446 | |
481 | 447 | /* TODO: This is expensive. We could split things up and only evaluate part of |
482 | 448 | CCR on a need to know basis. For now, we simply re-evaluate everything. */ |
483 | -void helper_evaluate_flags (void) | |
449 | +void helper_evaluate_flags(void) | |
484 | 450 | { |
485 | - uint32_t src; | |
486 | - uint32_t dst; | |
487 | - uint32_t res; | |
451 | + uint32_t src, dst, res; | |
488 | 452 | uint32_t flags = 0; |
489 | 453 | |
490 | 454 | src = env->cc_src; |
... | ... | @@ -595,11 +559,10 @@ void helper_evaluate_flags (void) |
595 | 559 | break; |
596 | 560 | } |
597 | 561 | |
598 | - if (env->cc_op == CC_OP_SUB | |
599 | - || env->cc_op == CC_OP_CMP) { | |
562 | + if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP) | |
600 | 563 | flags ^= C_FLAG; |
601 | - } | |
602 | - evaluate_flags_writeback(flags); | |
564 | + | |
565 | + env->pregs[PR_CCS] = evaluate_flags_writeback(flags, env->pregs[PR_CCS]); | |
603 | 566 | } |
604 | 567 | |
605 | 568 | void helper_top_evaluate_flags(void) |
... | ... | @@ -607,13 +570,19 @@ void helper_top_evaluate_flags(void) |
607 | 570 | switch (env->cc_op) |
608 | 571 | { |
609 | 572 | case CC_OP_MCP: |
610 | - helper_evaluate_flags_mcp(); | |
573 | + env->pregs[PR_CCS] = helper_evaluate_flags_mcp( | |
574 | + env->pregs[PR_CCS], env->cc_src, | |
575 | + env->cc_dest, env->cc_result); | |
611 | 576 | break; |
612 | 577 | case CC_OP_MULS: |
613 | - helper_evaluate_flags_muls(); | |
578 | + env->pregs[PR_CCS] = helper_evaluate_flags_muls( | |
579 | + env->pregs[PR_CCS], env->cc_result, | |
580 | + env->pregs[PR_MOF]); | |
614 | 581 | break; |
615 | 582 | case CC_OP_MULU: |
616 | - helper_evaluate_flags_mulu(); | |
583 | + env->pregs[PR_CCS] = helper_evaluate_flags_mulu( | |
584 | + env->pregs[PR_CCS], env->cc_result, | |
585 | + env->pregs[PR_MOF]); | |
617 | 586 | break; |
618 | 587 | case CC_OP_MOVE: |
619 | 588 | case CC_OP_AND: |
... | ... | @@ -622,26 +591,36 @@ void helper_top_evaluate_flags(void) |
622 | 591 | case CC_OP_ASR: |
623 | 592 | case CC_OP_LSR: |
624 | 593 | case CC_OP_LSL: |
625 | - switch (env->cc_size) | |
626 | - { | |
627 | - case 4: | |
628 | - helper_evaluate_flags_move_4(); | |
629 | - break; | |
630 | - case 2: | |
631 | - helper_evaluate_flags_move_2(); | |
632 | - break; | |
633 | - default: | |
634 | - helper_evaluate_flags(); | |
635 | - break; | |
636 | - } | |
637 | - break; | |
594 | + switch (env->cc_size) | |
595 | + { | |
596 | + case 4: | |
597 | + env->pregs[PR_CCS] = | |
598 | + helper_evaluate_flags_move_4( | |
599 | + env->pregs[PR_CCS], | |
600 | + env->cc_result); | |
601 | + break; | |
602 | + case 2: | |
603 | + env->pregs[PR_CCS] = | |
604 | + helper_evaluate_flags_move_2( | |
605 | + env->pregs[PR_CCS], | |
606 | + env->cc_result); | |
607 | + break; | |
608 | + default: | |
609 | + helper_evaluate_flags(); | |
610 | + break; | |
611 | + } | |
612 | + break; | |
638 | 613 | case CC_OP_FLAGS: |
639 | 614 | /* live. */ |
640 | 615 | break; |
641 | 616 | case CC_OP_SUB: |
642 | 617 | case CC_OP_CMP: |
643 | 618 | if (env->cc_size == 4) |
644 | - helper_evaluate_flags_sub_4(); | |
619 | + env->pregs[PR_CCS] = | |
620 | + helper_evaluate_flags_sub_4( | |
621 | + env->pregs[PR_CCS], | |
622 | + env->cc_src, env->cc_dest, | |
623 | + env->cc_result); | |
645 | 624 | else |
646 | 625 | helper_evaluate_flags(); |
647 | 626 | break; |
... | ... | @@ -649,12 +628,16 @@ void helper_top_evaluate_flags(void) |
649 | 628 | { |
650 | 629 | switch (env->cc_size) |
651 | 630 | { |
652 | - case 4: | |
653 | - helper_evaluate_flags_alu_4(); | |
654 | - break; | |
655 | - default: | |
656 | - helper_evaluate_flags(); | |
657 | - break; | |
631 | + case 4: | |
632 | + env->pregs[PR_CCS] = | |
633 | + helper_evaluate_flags_alu_4( | |
634 | + env->pregs[PR_CCS], | |
635 | + env->cc_src, env->cc_dest, | |
636 | + env->cc_result); | |
637 | + break; | |
638 | + default: | |
639 | + helper_evaluate_flags(); | |
640 | + break; | |
658 | 641 | } |
659 | 642 | } |
660 | 643 | break; | ... | ... |
target-cris/translate.c
... | ... | @@ -565,74 +565,85 @@ static void cris_flush_cc_state(DisasContext *dc) |
565 | 565 | |
566 | 566 | static void cris_evaluate_flags(DisasContext *dc) |
567 | 567 | { |
568 | - if (!dc->flags_uptodate) { | |
569 | - cris_flush_cc_state(dc); | |
568 | + if (dc->flags_uptodate) | |
569 | + return; | |
570 | 570 | |
571 | - switch (dc->cc_op) | |
571 | + cris_flush_cc_state(dc); | |
572 | + | |
573 | + switch (dc->cc_op) | |
574 | + { | |
575 | + case CC_OP_MCP: | |
576 | + gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], | |
577 | + cpu_PR[PR_CCS], cc_src, | |
578 | + cc_dest, cc_result); | |
579 | + break; | |
580 | + case CC_OP_MULS: | |
581 | + gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], | |
582 | + cpu_PR[PR_CCS], cc_result, | |
583 | + cpu_PR[PR_MOF]); | |
584 | + break; | |
585 | + case CC_OP_MULU: | |
586 | + gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], | |
587 | + cpu_PR[PR_CCS], cc_result, | |
588 | + cpu_PR[PR_MOF]); | |
589 | + break; | |
590 | + case CC_OP_MOVE: | |
591 | + case CC_OP_AND: | |
592 | + case CC_OP_OR: | |
593 | + case CC_OP_XOR: | |
594 | + case CC_OP_ASR: | |
595 | + case CC_OP_LSR: | |
596 | + case CC_OP_LSL: | |
597 | + switch (dc->cc_size) | |
572 | 598 | { |
573 | - case CC_OP_MCP: | |
574 | - gen_helper_evaluate_flags_mcp(); | |
575 | - break; | |
576 | - case CC_OP_MULS: | |
577 | - gen_helper_evaluate_flags_muls(); | |
578 | - break; | |
579 | - case CC_OP_MULU: | |
580 | - gen_helper_evaluate_flags_mulu(); | |
581 | - break; | |
582 | - case CC_OP_MOVE: | |
583 | - case CC_OP_AND: | |
584 | - case CC_OP_OR: | |
585 | - case CC_OP_XOR: | |
586 | - case CC_OP_ASR: | |
587 | - case CC_OP_LSR: | |
588 | - case CC_OP_LSL: | |
589 | - switch (dc->cc_size) | |
590 | - { | |
591 | - case 4: | |
592 | - gen_helper_evaluate_flags_move_4(); | |
593 | - break; | |
594 | - case 2: | |
595 | - gen_helper_evaluate_flags_move_2(); | |
596 | - break; | |
597 | - default: | |
598 | - gen_helper_evaluate_flags(); | |
599 | - break; | |
600 | - } | |
601 | - break; | |
602 | - case CC_OP_FLAGS: | |
603 | - /* live. */ | |
604 | - break; | |
605 | - case CC_OP_SUB: | |
606 | - case CC_OP_CMP: | |
607 | - if (dc->cc_size == 4) | |
608 | - gen_helper_evaluate_flags_sub_4(); | |
609 | - else | |
610 | - gen_helper_evaluate_flags(); | |
599 | + case 4: | |
600 | + gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS], | |
601 | + cpu_PR[PR_CCS], cc_result); | |
602 | + break; | |
603 | + case 2: | |
604 | + gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS], | |
605 | + cpu_PR[PR_CCS], cc_result); | |
606 | + break; | |
607 | + default: | |
608 | + gen_helper_evaluate_flags(); | |
609 | + break; | |
610 | + } | |
611 | + break; | |
612 | + case CC_OP_FLAGS: | |
613 | + /* live. */ | |
614 | + break; | |
615 | + case CC_OP_SUB: | |
616 | + case CC_OP_CMP: | |
617 | + if (dc->cc_size == 4) | |
618 | + gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], | |
619 | + cpu_PR[PR_CCS], cc_src, cc_dest, cc_result); | |
620 | + else | |
621 | + gen_helper_evaluate_flags(); | |
611 | 622 | |
623 | + break; | |
624 | + default: | |
625 | + switch (dc->cc_size) | |
626 | + { | |
627 | + case 4: | |
628 | + gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], | |
629 | + cpu_PR[PR_CCS], cc_src, cc_dest, cc_result); | |
612 | 630 | break; |
613 | 631 | default: |
614 | - switch (dc->cc_size) | |
615 | - { | |
616 | - case 4: | |
617 | - gen_helper_evaluate_flags_alu_4(); | |
618 | - break; | |
619 | - default: | |
620 | - gen_helper_evaluate_flags(); | |
621 | - break; | |
622 | - } | |
623 | - break; | |
632 | + gen_helper_evaluate_flags(); | |
633 | + break; | |
624 | 634 | } |
625 | - if (dc->flagx_known) { | |
626 | - if (dc->flags_x) | |
627 | - tcg_gen_ori_tl(cpu_PR[PR_CCS], | |
628 | - cpu_PR[PR_CCS], X_FLAG); | |
629 | - else | |
630 | - tcg_gen_andi_tl(cpu_PR[PR_CCS], | |
631 | - cpu_PR[PR_CCS], ~X_FLAG); | |
632 | - } | |
633 | - | |
634 | - dc->flags_uptodate = 1; | |
635 | + break; | |
635 | 636 | } |
637 | + | |
638 | + if (dc->flagx_known) { | |
639 | + if (dc->flags_x) | |
640 | + tcg_gen_ori_tl(cpu_PR[PR_CCS], | |
641 | + cpu_PR[PR_CCS], X_FLAG); | |
642 | + else | |
643 | + tcg_gen_andi_tl(cpu_PR[PR_CCS], | |
644 | + cpu_PR[PR_CCS], ~X_FLAG); | |
645 | + } | |
646 | + dc->flags_uptodate = 1; | |
636 | 647 | } |
637 | 648 | |
638 | 649 | static void cris_cc_mask(DisasContext *dc, unsigned int mask) | ... | ... |