translate.c (0c2e96c1703041badf675993247351f629b4ab20) translate.c (633c42834c7bbd528fdb0971c3d2f994a5137072)
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 Copyright (C) 2003-2005 Fabrice Bellard
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public

--- 23 unchanged lines hidden (view full) ---

32#include "exec/translator.h"
33#include "exec/log.h"
34#include "asi.h"
35
36#define HELPER_H "helper.h"
37#include "exec/helper-info.c.inc"
38#undef HELPER_H
39
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 Copyright (C) 2003-2005 Fabrice Bellard
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public

--- 23 unchanged lines hidden (view full) ---

32#include "exec/translator.h"
33#include "exec/log.h"
34#include "asi.h"
35
36#define HELPER_H "helper.h"
37#include "exec/helper-info.c.inc"
38#undef HELPER_H
39
40#define DYNAMIC_PC 1 /* dynamic pc value */
41#define JUMP_PC 2 /* dynamic pc value which takes only two values
42 according to jump_pc[T2] */
40/* Dynamic PC, must exit to main loop. */
41#define DYNAMIC_PC 1
42/* Dynamic PC, one of two values according to jump_pc[T2]. */
43#define JUMP_PC 2
44/* Dynamic PC, may lookup next TB. */
45#define DYNAMIC_PC_LOOKUP 3
43
44#define DISAS_EXIT DISAS_TARGET_0
45
46/* global register indexes */
47static TCGv_ptr cpu_regwptr;
48static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
49static TCGv_i32 cpu_cc_op;
50static TCGv_i32 cpu_psr;

--- 845 unchanged lines hidden (view full) ---

896
897 dc->base.is_jmp = DISAS_NORETURN;
898}
899
900static void gen_branch_n(DisasContext *dc, target_ulong pc1)
901{
902 target_ulong npc = dc->npc;
903
46
47#define DISAS_EXIT DISAS_TARGET_0
48
49/* global register indexes */
50static TCGv_ptr cpu_regwptr;
51static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
52static TCGv_i32 cpu_cc_op;
53static TCGv_i32 cpu_psr;

--- 845 unchanged lines hidden (view full) ---

899
900 dc->base.is_jmp = DISAS_NORETURN;
901}
902
903static void gen_branch_n(DisasContext *dc, target_ulong pc1)
904{
905 target_ulong npc = dc->npc;
906
904 if (likely(npc != DYNAMIC_PC)) {
907 if (npc & 3) {
908 switch (npc) {
909 case DYNAMIC_PC:
910 case DYNAMIC_PC_LOOKUP:
911 tcg_gen_mov_tl(cpu_pc, cpu_npc);
912 tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
913 tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc,
914 cpu_cond, tcg_constant_tl(0),
915 tcg_constant_tl(pc1), cpu_npc);
916 dc->pc = npc;
917 break;
918 default:
919 g_assert_not_reached();
920 }
921 } else {
905 dc->pc = npc;
906 dc->jump_pc[0] = pc1;
907 dc->jump_pc[1] = npc + 4;
908 dc->npc = JUMP_PC;
922 dc->pc = npc;
923 dc->jump_pc[0] = pc1;
924 dc->jump_pc[1] = npc + 4;
925 dc->npc = JUMP_PC;
909 } else {
910 TCGv t, z;
911
912 tcg_gen_mov_tl(cpu_pc, cpu_npc);
913
914 tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
915 t = tcg_constant_tl(pc1);
916 z = tcg_constant_tl(0);
917 tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, z, t, cpu_npc);
918
919 dc->pc = DYNAMIC_PC;
920 }
921}
922
923static void gen_generic_branch(DisasContext *dc)
924{
925 TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
926 TCGv npc1 = tcg_constant_tl(dc->jump_pc[1]);
927 TCGv zero = tcg_constant_tl(0);

--- 8 unchanged lines hidden (view full) ---

936 if (dc->npc == JUMP_PC) {
937 gen_generic_branch(dc);
938 dc->npc = DYNAMIC_PC;
939 }
940}
941
942static void save_npc(DisasContext *dc)
943{
926 }
927}
928
929static void gen_generic_branch(DisasContext *dc)
930{
931 TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
932 TCGv npc1 = tcg_constant_tl(dc->jump_pc[1]);
933 TCGv zero = tcg_constant_tl(0);

--- 8 unchanged lines hidden (view full) ---

942 if (dc->npc == JUMP_PC) {
943 gen_generic_branch(dc);
944 dc->npc = DYNAMIC_PC;
945 }
946}
947
948static void save_npc(DisasContext *dc)
949{
944 if (dc->npc == JUMP_PC) {
945 gen_generic_branch(dc);
946 dc->npc = DYNAMIC_PC;
947 } else if (dc->npc != DYNAMIC_PC) {
950 if (dc->npc & 3) {
951 switch (dc->npc) {
952 case JUMP_PC:
953 gen_generic_branch(dc);
954 dc->npc = DYNAMIC_PC;
955 break;
956 case DYNAMIC_PC:
957 case DYNAMIC_PC_LOOKUP:
958 break;
959 default:
960 g_assert_not_reached();
961 }
962 } else {
948 tcg_gen_movi_tl(cpu_npc, dc->npc);
949 }
950}
951
952static void update_psr(DisasContext *dc)
953{
954 if (dc->cc_op != CC_OP_FLAGS) {
955 dc->cc_op = CC_OP_FLAGS;

--- 16 unchanged lines hidden (view full) ---

972
973static void gen_check_align(TCGv addr, int mask)
974{
975 gen_helper_check_align(cpu_env, addr, tcg_constant_i32(mask));
976}
977
978static void gen_mov_pc_npc(DisasContext *dc)
979{
963 tcg_gen_movi_tl(cpu_npc, dc->npc);
964 }
965}
966
967static void update_psr(DisasContext *dc)
968{
969 if (dc->cc_op != CC_OP_FLAGS) {
970 dc->cc_op = CC_OP_FLAGS;

--- 16 unchanged lines hidden (view full) ---

987
988static void gen_check_align(TCGv addr, int mask)
989{
990 gen_helper_check_align(cpu_env, addr, tcg_constant_i32(mask));
991}
992
993static void gen_mov_pc_npc(DisasContext *dc)
994{
980 if (dc->npc == JUMP_PC) {
981 gen_generic_branch(dc);
982 tcg_gen_mov_tl(cpu_pc, cpu_npc);
983 dc->pc = DYNAMIC_PC;
984 } else if (dc->npc == DYNAMIC_PC) {
985 tcg_gen_mov_tl(cpu_pc, cpu_npc);
986 dc->pc = DYNAMIC_PC;
995 if (dc->npc & 3) {
996 switch (dc->npc) {
997 case JUMP_PC:
998 gen_generic_branch(dc);
999 tcg_gen_mov_tl(cpu_pc, cpu_npc);
1000 dc->pc = DYNAMIC_PC;
1001 break;
1002 case DYNAMIC_PC:
1003 case DYNAMIC_PC_LOOKUP:
1004 tcg_gen_mov_tl(cpu_pc, cpu_npc);
1005 dc->pc = dc->npc;
1006 break;
1007 default:
1008 g_assert_not_reached();
1009 }
987 } else {
988 dc->pc = dc->npc;
989 }
990}
991
992static void gen_op_next_insn(void)
993{
994 tcg_gen_mov_tl(cpu_pc, cpu_npc);

--- 4501 unchanged lines hidden (view full) ---

5496 }
5497 } else {
5498 goto illegal_insn;
5499 }
5500 }
5501 break;
5502 }
5503 /* default case for non jump instructions */
1010 } else {
1011 dc->pc = dc->npc;
1012 }
1013}
1014
1015static void gen_op_next_insn(void)
1016{
1017 tcg_gen_mov_tl(cpu_pc, cpu_npc);

--- 4501 unchanged lines hidden (view full) ---

5519 }
5520 } else {
5521 goto illegal_insn;
5522 }
5523 }
5524 break;
5525 }
5526 /* default case for non jump instructions */
5504 if (dc->npc == DYNAMIC_PC) {
5505 dc->pc = DYNAMIC_PC;
5506 gen_op_next_insn();
5507 } else if (dc->npc == JUMP_PC) {
5508 /* we can do a static jump */
5509 gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
5510 dc->base.is_jmp = DISAS_NORETURN;
5527 if (dc->npc & 3) {
5528 switch (dc->npc) {
5529 case DYNAMIC_PC:
5530 case DYNAMIC_PC_LOOKUP:
5531 dc->pc = dc->npc;
5532 gen_op_next_insn();
5533 break;
5534 case JUMP_PC:
5535 /* we can do a static jump */
5536 gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
5537 dc->base.is_jmp = DISAS_NORETURN;
5538 break;
5539 default:
5540 g_assert_not_reached();
5541 }
5511 } else {
5512 dc->pc = dc->npc;
5513 dc->npc = dc->npc + 4;
5514 }
5515 jmp_insn:
5516 return;
5517 illegal_insn:
5518 gen_exception(dc, TT_ILL_INSN);

--- 54 unchanged lines hidden (view full) ---

5573
5574static void sparc_tr_tb_start(DisasContextBase *db, CPUState *cs)
5575{
5576}
5577
5578static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
5579{
5580 DisasContext *dc = container_of(dcbase, DisasContext, base);
5542 } else {
5543 dc->pc = dc->npc;
5544 dc->npc = dc->npc + 4;
5545 }
5546 jmp_insn:
5547 return;
5548 illegal_insn:
5549 gen_exception(dc, TT_ILL_INSN);

--- 54 unchanged lines hidden (view full) ---

5604
5605static void sparc_tr_tb_start(DisasContextBase *db, CPUState *cs)
5606{
5607}
5608
5609static void sparc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
5610{
5611 DisasContext *dc = container_of(dcbase, DisasContext, base);
5612 target_ulong npc = dc->npc;
5581
5613
5582 if (dc->npc == JUMP_PC) {
5583 assert(dc->jump_pc[1] == dc->pc + 4);
5584 tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC);
5585 } else {
5586 tcg_gen_insn_start(dc->pc, dc->npc);
5614 if (npc & 3) {
5615 switch (npc) {
5616 case JUMP_PC:
5617 assert(dc->jump_pc[1] == dc->pc + 4);
5618 npc = dc->jump_pc[0] | JUMP_PC;
5619 break;
5620 case DYNAMIC_PC:
5621 case DYNAMIC_PC_LOOKUP:
5622 npc = DYNAMIC_PC;
5623 break;
5624 default:
5625 g_assert_not_reached();
5626 }
5587 }
5627 }
5628 tcg_gen_insn_start(dc->pc, npc);
5588}
5589
5590static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
5591{
5592 DisasContext *dc = container_of(dcbase, DisasContext, base);
5593 CPUSPARCState *env = cs->env_ptr;
5594 unsigned int insn;
5595

--- 7 unchanged lines hidden (view full) ---

5603 if (dc->pc != dc->base.pc_next) {
5604 dc->base.is_jmp = DISAS_TOO_MANY;
5605 }
5606}
5607
5608static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
5609{
5610 DisasContext *dc = container_of(dcbase, DisasContext, base);
5629}
5630
5631static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
5632{
5633 DisasContext *dc = container_of(dcbase, DisasContext, base);
5634 CPUSPARCState *env = cs->env_ptr;
5635 unsigned int insn;
5636

--- 7 unchanged lines hidden (view full) ---

5644 if (dc->pc != dc->base.pc_next) {
5645 dc->base.is_jmp = DISAS_TOO_MANY;
5646 }
5647}
5648
5649static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
5650{
5651 DisasContext *dc = container_of(dcbase, DisasContext, base);
5652 bool may_lookup;
5611
5612 switch (dc->base.is_jmp) {
5613 case DISAS_NEXT:
5614 case DISAS_TOO_MANY:
5653
5654 switch (dc->base.is_jmp) {
5655 case DISAS_NEXT:
5656 case DISAS_TOO_MANY:
5615 if (dc->pc != DYNAMIC_PC &&
5616 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
5657 if (((dc->pc | dc->npc) & 3) == 0) {
5617 /* static PC and NPC: we can use direct chaining */
5618 gen_goto_tb(dc, 0, dc->pc, dc->npc);
5658 /* static PC and NPC: we can use direct chaining */
5659 gen_goto_tb(dc, 0, dc->pc, dc->npc);
5619 } else {
5620 if (dc->pc != DYNAMIC_PC) {
5621 tcg_gen_movi_tl(cpu_pc, dc->pc);
5660 break;
5661 }
5662
5663 if (dc->pc & 3) {
5664 switch (dc->pc) {
5665 case DYNAMIC_PC_LOOKUP:
5666 may_lookup = true;
5667 break;
5668 case DYNAMIC_PC:
5669 may_lookup = false;
5670 break;
5671 default:
5672 g_assert_not_reached();
5622 }
5673 }
5623 save_npc(dc);
5674 } else {
5675 tcg_gen_movi_tl(cpu_pc, dc->pc);
5676 may_lookup = true;
5677 }
5678
5679 save_npc(dc);
5680 if (may_lookup) {
5681 tcg_gen_lookup_and_goto_ptr();
5682 } else {
5624 tcg_gen_exit_tb(NULL, 0);
5625 }
5626 break;
5627
5628 case DISAS_NORETURN:
5629 break;
5630
5631 case DISAS_EXIT:

--- 143 unchanged lines hidden ---
5683 tcg_gen_exit_tb(NULL, 0);
5684 }
5685 break;
5686
5687 case DISAS_NORETURN:
5688 break;
5689
5690 case DISAS_EXIT:

--- 143 unchanged lines hidden ---