Commit b41f7df0189dbda34be3944a48db3b98348e4bc6

Authored by edgar_igl
1 parent ff56ff7a

CRIS updates:

* Support both the I and D MMUs and improve the accuracy of the MMU model.
* Handle the automatic user/kernel stack pointer switching when leaving or entering user mode.
* Move the CCS evaluation into helper funcs.
* Make sure user-mode cannot change flags only writeable in kernel mode.
* More conversion of the translator into TCG.
* Handle exceptions while in a delayslot.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4299 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -257,7 +257,7 @@ static inline TranslationBlock *tb_find_fast(void) @@ -257,7 +257,7 @@ static inline TranslationBlock *tb_find_fast(void)
257 cs_base = 0; 257 cs_base = 0;
258 pc = env->pc; 258 pc = env->pc;
259 #elif defined(TARGET_CRIS) 259 #elif defined(TARGET_CRIS)
260 - flags = 0; 260 + flags = env->pregs[PR_CCS];
261 cs_base = 0; 261 cs_base = 0;
262 pc = env->pc; 262 pc = env->pc;
263 #else 263 #else
target-cris/cpu.h
@@ -38,6 +38,28 @@ @@ -38,6 +38,28 @@
38 #define EXCP_MMU_FAULT 4 38 #define EXCP_MMU_FAULT 4
39 #define EXCP_BREAK 16 /* trap. */ 39 #define EXCP_BREAK 16 /* trap. */
40 40
  41 +/* Register aliases. R0 - R15 */
  42 +#define R_FP 8
  43 +#define R_SP 14
  44 +#define R_ACR 15
  45 +
  46 +/* Support regs, P0 - P15 */
  47 +#define PR_BZ 0
  48 +#define PR_VR 1
  49 +#define PR_PID 2
  50 +#define PR_SRS 3
  51 +#define PR_WZ 4
  52 +#define PR_EXS 5
  53 +#define PR_EDA 6
  54 +#define PR_MOF 7
  55 +#define PR_DZ 8
  56 +#define PR_EBP 9
  57 +#define PR_ERP 10
  58 +#define PR_SRP 11
  59 +#define PR_CCS 13
  60 +#define PR_USP 14
  61 +#define PR_SPC 15
  62 +
41 /* CPU flags. */ 63 /* CPU flags. */
42 #define S_FLAG 0x200 64 #define S_FLAG 0x200
43 #define R_FLAG 0x100 65 #define R_FLAG 0x100
@@ -77,27 +99,16 @@ @@ -77,27 +99,16 @@
77 #define NB_MMU_MODES 2 99 #define NB_MMU_MODES 2
78 100
79 typedef struct CPUCRISState { 101 typedef struct CPUCRISState {
80 - uint32_t debug1;  
81 - uint32_t debug2;  
82 - uint32_t debug3;  
83 -  
84 - /*  
85 - * We just store the stores to the tlbset here for later evaluation  
86 - * when the hw needs access to them.  
87 - *  
88 - * One for I and another for D.  
89 - */  
90 - struct  
91 - {  
92 - uint32_t hi;  
93 - uint32_t lo;  
94 - } tlbsets[2][4][16];  
95 -  
96 - uint32_t sregs[256][16]; /* grrr why so many?? */  
97 uint32_t regs[16]; 102 uint32_t regs[16];
  103 + /* P0 - P15 are referred to as special registers in the docs. */
98 uint32_t pregs[16]; 104 uint32_t pregs[16];
  105 +
  106 + /* Pseudo register for the PC. Not directly accessable on CRIS. */
99 uint32_t pc; 107 uint32_t pc;
100 108
  109 + /* Pseudo register for the kernel stack. */
  110 + uint32_t ksp;
  111 +
101 /* These are setup up by the guest code just before transfering the 112 /* These are setup up by the guest code just before transfering the
102 control back to the host. */ 113 control back to the host. */
103 int jmp; 114 int jmp;
@@ -114,20 +125,19 @@ typedef struct CPUCRISState { @@ -114,20 +125,19 @@ typedef struct CPUCRISState {
114 /* size of the operation, 1 = byte, 2 = word, 4 = dword. */ 125 /* size of the operation, 1 = byte, 2 = word, 4 = dword. */
115 int cc_size; 126 int cc_size;
116 127
117 - /* extended arithmetics. */ 128 + /* Extended arithmetics. */
118 int cc_x_live; 129 int cc_x_live;
119 int cc_x; 130 int cc_x;
120 131
121 - int features;  
122 -  
123 int exception_index; 132 int exception_index;
124 int interrupt_request; 133 int interrupt_request;
125 int interrupt_vector; 134 int interrupt_vector;
126 int fault_vector; 135 int fault_vector;
127 int trap_vector; 136 int trap_vector;
128 137
129 - int user_mode_only;  
130 - int halted; 138 + uint32_t debug1;
  139 + uint32_t debug2;
  140 + uint32_t debug3;
131 141
132 struct 142 struct
133 { 143 {
@@ -136,6 +146,31 @@ typedef struct CPUCRISState { @@ -136,6 +146,31 @@ typedef struct CPUCRISState {
136 int exec_stores; 146 int exec_stores;
137 } stats; 147 } stats;
138 148
  149 + /* FIXME: add a check in the translator to avoid writing to support
  150 + register sets beyond the 4th. The ISA allows up to 256! but in
  151 + practice there is no core that implements more than 4.
  152 +
  153 + Support function registers are used to control units close to the
  154 + core. Accesses do not pass down the normal hierarchy.
  155 + */
  156 + uint32_t sregs[4][16];
  157 +
  158 + /*
  159 + * We just store the stores to the tlbset here for later evaluation
  160 + * when the hw needs access to them.
  161 + *
  162 + * One for I and another for D.
  163 + */
  164 + struct
  165 + {
  166 + uint32_t hi;
  167 + uint32_t lo;
  168 + } tlbsets[2][4][16];
  169 +
  170 + int features;
  171 + int user_mode_only;
  172 + int halted;
  173 +
139 jmp_buf jmp_env; 174 jmp_buf jmp_env;
140 CPU_COMMON 175 CPU_COMMON
141 } CPUCRISState; 176 } CPUCRISState;
@@ -225,40 +260,20 @@ void register_cris_insns (CPUCRISState *env); @@ -225,40 +260,20 @@ void register_cris_insns (CPUCRISState *env);
225 #define MMU_MODE0_SUFFIX _kernel 260 #define MMU_MODE0_SUFFIX _kernel
226 #define MMU_MODE1_SUFFIX _user 261 #define MMU_MODE1_SUFFIX _user
227 #define MMU_USER_IDX 1 262 #define MMU_USER_IDX 1
228 -/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */  
229 static inline int cpu_mmu_index (CPUState *env) 263 static inline int cpu_mmu_index (CPUState *env)
230 { 264 {
231 - return 0; 265 + return !!(env->pregs[PR_CCS] & U_FLAG);
232 } 266 }
233 267
234 -#include "cpu-all.h"  
235 -  
236 -/* Register aliases. R0 - R15 */  
237 -#define R_FP 8  
238 -#define R_SP 14  
239 -#define R_ACR 15  
240 -  
241 -/* Support regs, P0 - P15 */  
242 -#define PR_BZ 0  
243 -#define PR_VR 1  
244 -#define PR_PID 2  
245 -#define PR_SRS 3  
246 -#define PR_WZ 4  
247 -#define PR_MOF 7  
248 -#define PR_DZ 8  
249 -#define PR_EBP 9  
250 -#define PR_ERP 10  
251 -#define PR_SRP 11  
252 -#define PR_CCS 13  
253 -  
254 /* Support function regs. */ 268 /* Support function regs. */
255 #define SFR_RW_GC_CFG 0][0 269 #define SFR_RW_GC_CFG 0][0
256 -#define SFR_RW_MM_CFG 2][0  
257 -#define SFR_RW_MM_KBASE_LO 2][1  
258 -#define SFR_RW_MM_KBASE_HI 2][2  
259 -#define SFR_R_MM_CAUSE 2][3  
260 -#define SFR_RW_MM_TLB_SEL 2][4  
261 -#define SFR_RW_MM_TLB_LO 2][5  
262 -#define SFR_RW_MM_TLB_HI 2][6 270 +#define SFR_RW_MM_CFG env->pregs[PR_SRS]][0
  271 +#define SFR_RW_MM_KBASE_LO env->pregs[PR_SRS]][1
  272 +#define SFR_RW_MM_KBASE_HI env->pregs[PR_SRS]][2
  273 +#define SFR_R_MM_CAUSE env->pregs[PR_SRS]][3
  274 +#define SFR_RW_MM_TLB_SEL env->pregs[PR_SRS]][4
  275 +#define SFR_RW_MM_TLB_LO env->pregs[PR_SRS]][5
  276 +#define SFR_RW_MM_TLB_HI env->pregs[PR_SRS]][6
263 277
  278 +#include "cpu-all.h"
264 #endif 279 #endif
target-cris/helper.c
@@ -61,7 +61,7 @@ static void cris_shift_ccs(CPUState *env) @@ -61,7 +61,7 @@ static void cris_shift_ccs(CPUState *env)
61 uint32_t ccs; 61 uint32_t ccs;
62 /* Apply the ccs shift. */ 62 /* Apply the ccs shift. */
63 ccs = env->pregs[PR_CCS]; 63 ccs = env->pregs[PR_CCS];
64 - ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2); 64 + ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
65 env->pregs[PR_CCS] = ccs; 65 env->pregs[PR_CCS] = ccs;
66 } 66 }
67 67
@@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
73 int r = -1; 73 int r = -1;
74 target_ulong phy; 74 target_ulong phy;
75 75
76 - D(printf ("%s addr=%x pc=%x\n", __func__, address, env->pc)); 76 + D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
77 address &= TARGET_PAGE_MASK; 77 address &= TARGET_PAGE_MASK;
78 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 78 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
79 miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); 79 miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
@@ -86,12 +86,14 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -86,12 +86,14 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
86 else 86 else
87 { 87 {
88 phy = res.phy; 88 phy = res.phy;
89 - prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 89 + prot = res.prot;
  90 + address &= TARGET_PAGE_MASK;
90 r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu); 91 r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
91 } 92 }
92 - D(printf("%s returns %d irqreq=%x addr=%x ismmu=%d\n",  
93 - __func__, r, env->interrupt_request,  
94 - address, is_softmmu)); 93 + if (r > 0)
  94 + D(fprintf(logfile, "%s returns %d irqreq=%x addr=%x ismmu=%d vec=%x\n",
  95 + __func__, r, env->interrupt_request,
  96 + address, is_softmmu, res.bf_vec));
95 return r; 97 return r;
96 } 98 }
97 99
@@ -100,8 +102,8 @@ void do_interrupt(CPUState *env) @@ -100,8 +102,8 @@ void do_interrupt(CPUState *env)
100 int ex_vec = -1; 102 int ex_vec = -1;
101 103
102 D(fprintf (stderr, "exception index=%d interrupt_req=%d\n", 104 D(fprintf (stderr, "exception index=%d interrupt_req=%d\n",
103 - env->exception_index,  
104 - env->interrupt_request)); 105 + env->exception_index,
  106 + env->interrupt_request));
105 107
106 switch (env->exception_index) 108 switch (env->exception_index)
107 { 109 {
@@ -113,40 +115,46 @@ void do_interrupt(CPUState *env) @@ -113,40 +115,46 @@ void do_interrupt(CPUState *env)
113 break; 115 break;
114 116
115 case EXCP_MMU_FAULT: 117 case EXCP_MMU_FAULT:
116 - /* ERP is already setup by translate-all.c through  
117 - re-translation of the aborted TB combined with  
118 - pc searching. */  
119 ex_vec = env->fault_vector; 118 ex_vec = env->fault_vector;
  119 + env->pregs[PR_ERP] = env->pc;
120 break; 120 break;
121 121
122 default: 122 default:
123 - {  
124 - /* Maybe the irq was acked by sw before we got a  
125 - change to take it. */  
126 - if (env->interrupt_request & CPU_INTERRUPT_HARD) {  
127 - /* Vectors below 0x30 are internal  
128 - exceptions, i.e not interrupt requests  
129 - from the interrupt controller. */  
130 - if (env->interrupt_vector < 0x30)  
131 - return;  
132 - /* Is the core accepting interrupts? */  
133 - if (!(env->pregs[PR_CCS] & I_FLAG)) {  
134 - return;  
135 - }  
136 - /* The interrupt controller gives us the  
137 - vector. */  
138 - ex_vec = env->interrupt_vector;  
139 - /* Normal interrupts are taken between  
140 - TB's. env->pc is valid here. */  
141 - env->pregs[PR_ERP] = env->pc;  
142 - }  
143 - }  
144 - break; 123 + /* Is the core accepting interrupts? */
  124 + if (!(env->pregs[PR_CCS] & I_FLAG))
  125 + return;
  126 + /* The interrupt controller gives us the
  127 + vector. */
  128 + ex_vec = env->interrupt_vector;
  129 + /* Normal interrupts are taken between
  130 + TB's. env->pc is valid here. */
  131 + env->pregs[PR_ERP] = env->pc;
  132 + break;
  133 + }
  134 +
  135 + if ((env->pregs[PR_CCS] & U_FLAG)) {
  136 + D(fprintf(logfile, "excp isr=%x PC=%x ERP=%x pid=%x ccs=%x cc=%d %x\n",
  137 + ex_vec, env->pc,
  138 + env->pregs[PR_ERP], env->pregs[PR_PID],
  139 + env->pregs[PR_CCS],
  140 + env->cc_op, env->cc_mask));
145 } 141 }
  142 +
146 env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4); 143 env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
147 - /* Apply the CRIS CCS shift. */ 144 +
  145 + if (env->pregs[PR_CCS] & U_FLAG) {
  146 + /* Swap stack pointers. */
  147 + env->pregs[PR_USP] = env->regs[R_SP];
  148 + env->regs[R_SP] = env->ksp;
  149 + }
  150 +
  151 + /* Apply the CRIS CCS shift. Clears U if set. */
148 cris_shift_ccs(env); 152 cris_shift_ccs(env);
149 - D(printf ("%s ebp=%x isr=%x vec=%x\n", __func__, ebp, isr, ex_vec)); 153 + D(fprintf (logfile, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
  154 + __func__, env->pc, ex_vec,
  155 + env->pregs[PR_CCS],
  156 + env->pregs[PR_PID],
  157 + env->pregs[PR_ERP]));
150 } 158 }
151 159
152 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) 160 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
target-cris/helper.h
1 #define TCG_HELPER_PROTO 1 #define TCG_HELPER_PROTO
2 void TCG_HELPER_PROTO helper_tlb_update(uint32_t T0); 2 void TCG_HELPER_PROTO helper_tlb_update(uint32_t T0);
  3 +void TCG_HELPER_PROTO helper_tlb_flush(void);
  4 +void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2);
  5 +void TCG_HELPER_PROTO helper_dummy(void);
  6 +void TCG_HELPER_PROTO helper_rfe(void);
  7 +void TCG_HELPER_PROTO helper_store(uint32_t a0);
3 8
  9 +void TCG_HELPER_PROTO helper_evaluate_flags_muls(void);
  10 +void TCG_HELPER_PROTO helper_evaluate_flags_mulu(void);
  11 +void TCG_HELPER_PROTO helper_evaluate_flags_mcp(void);
  12 +void TCG_HELPER_PROTO helper_evaluate_flags_alu_4(void);
  13 +void TCG_HELPER_PROTO helper_evaluate_flags_move_4 (void);
  14 +void TCG_HELPER_PROTO helper_evaluate_flags_move_2 (void);
  15 +void TCG_HELPER_PROTO helper_evaluate_flags (void);
target-cris/mmu.c
@@ -73,11 +73,30 @@ static inline void set_field(uint32_t *dst, unsigned int val, @@ -73,11 +73,30 @@ static inline void set_field(uint32_t *dst, unsigned int val,
73 val <<= offset; 73 val <<= offset;
74 74
75 val &= mask; 75 val &= mask;
76 - D(printf ("val=%x mask=%x dst=%x\n", val, mask, *dst));  
77 *dst &= ~(mask); 76 *dst &= ~(mask);
78 *dst |= val; 77 *dst |= val;
79 } 78 }
80 79
  80 +static void dump_tlb(CPUState *env, int mmu)
  81 +{
  82 + int set;
  83 + int idx;
  84 + uint32_t hi, lo, tlb_vpn, tlb_pfn;
  85 +
  86 + for (set = 0; set < 4; set++) {
  87 + for (idx = 0; idx < 16; idx++) {
  88 + lo = env->tlbsets[mmu][set][idx].lo;
  89 + hi = env->tlbsets[mmu][set][idx].hi;
  90 + tlb_vpn = EXTRACT_FIELD(hi, 13, 31);
  91 + tlb_pfn = EXTRACT_FIELD(lo, 13, 31);
  92 +
  93 + printf ("TLB: [%d][%d] hi=%x lo=%x v=%x p=%x\n",
  94 + set, idx, hi, lo, tlb_vpn, tlb_pfn);
  95 + }
  96 + }
  97 +}
  98 +
  99 +/* rw 0 = read, 1 = write, 2 = exec. */
81 static int cris_mmu_translate_page(struct cris_mmu_result_t *res, 100 static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
82 CPUState *env, uint32_t vaddr, 101 CPUState *env, uint32_t vaddr,
83 int rw, int usermode) 102 int rw, int usermode)
@@ -88,53 +107,63 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, @@ -88,53 +107,63 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
88 uint32_t tlb_vpn, tlb_pfn = 0; 107 uint32_t tlb_vpn, tlb_pfn = 0;
89 int tlb_pid, tlb_g, tlb_v, tlb_k, tlb_w, tlb_x; 108 int tlb_pid, tlb_g, tlb_v, tlb_k, tlb_w, tlb_x;
90 int cfg_v, cfg_k, cfg_w, cfg_x; 109 int cfg_v, cfg_k, cfg_w, cfg_x;
91 - int i, match = 0; 110 + int set, match = 0;
92 uint32_t r_cause; 111 uint32_t r_cause;
93 uint32_t r_cfg; 112 uint32_t r_cfg;
94 int rwcause; 113 int rwcause;
95 - int update_sel = 0; 114 + int mmu = 1; /* Data mmu is default. */
  115 + int vect_base;
96 116
97 r_cause = env->sregs[SFR_R_MM_CAUSE]; 117 r_cause = env->sregs[SFR_R_MM_CAUSE];
98 r_cfg = env->sregs[SFR_RW_MM_CFG]; 118 r_cfg = env->sregs[SFR_RW_MM_CFG];
99 - rwcause = rw ? CRIS_MMU_ERR_WRITE : CRIS_MMU_ERR_READ; 119 +
  120 + switch (rw) {
  121 + case 2: rwcause = CRIS_MMU_ERR_EXEC; mmu = 0; break;
  122 + case 1: rwcause = CRIS_MMU_ERR_WRITE; break;
  123 + default:
  124 + case 0: rwcause = CRIS_MMU_ERR_READ; break;
  125 + }
  126 +
  127 + /* I exception vectors 4 - 7, D 8 - 11. */
  128 + vect_base = (mmu + 1) * 4;
100 129
101 vpage = vaddr >> 13; 130 vpage = vaddr >> 13;
102 - idx = vpage & 15;  
103 131
104 /* We know the index which to check on each set. 132 /* We know the index which to check on each set.
105 Scan both I and D. */ 133 Scan both I and D. */
106 #if 0 134 #if 0
107 - for (i = 0; i < 4; i++) {  
108 - int j;  
109 - for (j = 0; j < 16; j++) {  
110 - lo = env->tlbsets[1][i][j].lo;  
111 - hi = env->tlbsets[1][i][j].hi; 135 + for (set = 0; set < 4; set++) {
  136 + for (idx = 0; idx < 16; idx++) {
  137 + lo = env->tlbsets[mmu][set][idx].lo;
  138 + hi = env->tlbsets[mmu][set][idx].hi;
112 tlb_vpn = EXTRACT_FIELD(hi, 13, 31); 139 tlb_vpn = EXTRACT_FIELD(hi, 13, 31);
113 tlb_pfn = EXTRACT_FIELD(lo, 13, 31); 140 tlb_pfn = EXTRACT_FIELD(lo, 13, 31);
114 141
115 printf ("TLB: [%d][%d] hi=%x lo=%x v=%x p=%x\n", 142 printf ("TLB: [%d][%d] hi=%x lo=%x v=%x p=%x\n",
116 - i, j, hi, lo, tlb_vpn, tlb_pfn); 143 + set, idx, hi, lo, tlb_vpn, tlb_pfn);
117 } 144 }
118 } 145 }
119 #endif 146 #endif
120 - for (i = 0; i < 4; i++) 147 +
  148 + idx = vpage & 15;
  149 + for (set = 0; set < 4; set++)
121 { 150 {
122 - lo = env->tlbsets[1][i][idx].lo;  
123 - hi = env->tlbsets[1][i][idx].hi; 151 + lo = env->tlbsets[mmu][set][idx].lo;
  152 + hi = env->tlbsets[mmu][set][idx].hi;
124 153
125 tlb_vpn = EXTRACT_FIELD(hi, 13, 31); 154 tlb_vpn = EXTRACT_FIELD(hi, 13, 31);
126 tlb_pfn = EXTRACT_FIELD(lo, 13, 31); 155 tlb_pfn = EXTRACT_FIELD(lo, 13, 31);
127 156
128 - D(printf ("TLB[%d][%d] tlbv=%x vpage=%x -> pfn=%x\n",  
129 - i, idx, tlb_vpn, vpage, tlb_pfn)); 157 + D(printf("TLB[%d][%d] v=%x vpage=%x -> pfn=%x lo=%x hi=%x\n",
  158 + i, idx, tlb_vpn, vpage, tlb_pfn, lo, hi));
130 if (tlb_vpn == vpage) { 159 if (tlb_vpn == vpage) {
131 match = 1; 160 match = 1;
132 break; 161 break;
133 } 162 }
134 } 163 }
135 164
  165 + res->bf_vec = vect_base;
136 if (match) { 166 if (match) {
137 -  
138 cfg_w = EXTRACT_FIELD(r_cfg, 19, 19); 167 cfg_w = EXTRACT_FIELD(r_cfg, 19, 19);
139 cfg_k = EXTRACT_FIELD(r_cfg, 18, 18); 168 cfg_k = EXTRACT_FIELD(r_cfg, 18, 18);
140 cfg_x = EXTRACT_FIELD(r_cfg, 17, 17); 169 cfg_x = EXTRACT_FIELD(r_cfg, 17, 17);
@@ -158,54 +187,67 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, @@ -158,54 +187,67 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
158 set_exception_vector(0x0a, d_mmu_access); 187 set_exception_vector(0x0a, d_mmu_access);
159 set_exception_vector(0x0b, d_mmu_write); 188 set_exception_vector(0x0b, d_mmu_write);
160 */ 189 */
161 - if (cfg_v && !tlb_v) {  
162 - printf ("tlb: invalid\n");  
163 - set_field(&r_cause, rwcause, 8, 9); 190 + if (!tlb_g
  191 + && tlb_pid != (env->pregs[PR_PID] & 0xff)) {
  192 + D(printf ("tlb: wrong pid %x %x pc=%x\n",
  193 + tlb_pid, env->pregs[PR_PID], env->pc));
164 match = 0; 194 match = 0;
165 - res->bf_vec = 0x9;  
166 - update_sel = 1;  
167 - }  
168 - else if (!tlb_g  
169 - && tlb_pid != 0xff  
170 - && tlb_pid != env->pregs[PR_PID]  
171 - && cfg_w && !tlb_w) {  
172 - printf ("tlb: wrong pid\n"); 195 + res->bf_vec = vect_base;
  196 + } else if (rw == 1 && cfg_w && !tlb_w) {
  197 + D(printf ("tlb: write protected %x lo=%x\n",
  198 + vaddr, lo));
173 match = 0; 199 match = 0;
174 - res->bf_vec = 0xa;  
175 - }  
176 - else if (rw && cfg_w && !tlb_w) {  
177 - printf ("tlb: write protected\n"); 200 + res->bf_vec = vect_base + 3;
  201 + } else if (cfg_v && !tlb_v) {
  202 + D(printf ("tlb: invalid %x\n", vaddr));
  203 + set_field(&r_cause, rwcause, 8, 9);
178 match = 0; 204 match = 0;
179 - res->bf_vec = 0xb; 205 + res->bf_vec = vect_base + 1;
180 } 206 }
181 - } else  
182 - update_sel = 1;  
183 207
184 - if (update_sel) {  
185 - /* miss. */  
186 - env->sregs[SFR_RW_MM_TLB_SEL] = 0;  
187 - D(printf ("tlb: miss %x vp=%x\n",  
188 - env->sregs[SFR_RW_MM_TLB_SEL], vpage & 15));  
189 - set_field(&env->sregs[SFR_RW_MM_TLB_SEL], vpage & 15, 0, 4);  
190 - set_field(&env->sregs[SFR_RW_MM_TLB_SEL], 0, 4, 5);  
191 - res->bf_vec = 0x8; 208 + res->prot = 0;
  209 + if (match) {
  210 + res->prot |= PAGE_READ;
  211 + if (tlb_w)
  212 + res->prot |= PAGE_WRITE;
  213 + if (tlb_x)
  214 + res->prot |= PAGE_EXEC;
  215 + }
  216 + else
  217 + D(dump_tlb(env, mmu));
  218 +
  219 + env->sregs[SFR_RW_MM_TLB_HI] = hi;
  220 + env->sregs[SFR_RW_MM_TLB_LO] = lo;
192 } 221 }
193 222
194 if (!match) { 223 if (!match) {
195 - set_field(&r_cause, rwcause, 8, 9); 224 + /* miss. */
  225 + idx = vpage & 15;
  226 + set = 0;
  227 +
  228 + /* Update RW_MM_TLB_SEL. */
  229 + env->sregs[SFR_RW_MM_TLB_SEL] = 0;
  230 + set_field(&env->sregs[SFR_RW_MM_TLB_SEL], idx, 0, 4);
  231 + set_field(&env->sregs[SFR_RW_MM_TLB_SEL], set, 4, 5);
  232 +
  233 + /* Update RW_MM_CAUSE. */
  234 + set_field(&r_cause, rwcause, 8, 2);
196 set_field(&r_cause, vpage, 13, 19); 235 set_field(&r_cause, vpage, 13, 19);
197 set_field(&r_cause, env->pregs[PR_PID], 0, 8); 236 set_field(&r_cause, env->pregs[PR_PID], 0, 8);
198 env->sregs[SFR_R_MM_CAUSE] = r_cause; 237 env->sregs[SFR_R_MM_CAUSE] = r_cause;
  238 + D(printf("refill vaddr=%x pc=%x\n", vaddr, env->pc));
199 } 239 }
200 - D(printf ("%s mtch=%d pc=%x va=%x vpn=%x tlbvpn=%x pfn=%x pid=%x"  
201 - " %x cause=%x sel=%x r13=%x\n",  
202 - __func__, match, env->pc, 240 +
  241 +
  242 + D(printf ("%s rw=%d mtch=%d pc=%x va=%x vpn=%x tlbvpn=%x pfn=%x pid=%x"
  243 + " %x cause=%x sel=%x sp=%x %x %x\n",
  244 + __func__, rw, match, env->pc,
203 vaddr, vpage, 245 vaddr, vpage,
204 tlb_vpn, tlb_pfn, tlb_pid, 246 tlb_vpn, tlb_pfn, tlb_pid,
205 env->pregs[PR_PID], 247 env->pregs[PR_PID],
206 r_cause, 248 r_cause,
207 env->sregs[SFR_RW_MM_TLB_SEL], 249 env->sregs[SFR_RW_MM_TLB_SEL],
208 - env->regs[13])); 250 + env->regs[R_SP], env->pregs[PR_USP], env->ksp));
209 251
210 res->pfn = tlb_pfn; 252 res->pfn = tlb_pfn;
211 return !match; 253 return !match;
@@ -236,10 +278,17 @@ int cris_mmu_translate(struct cris_mmu_result_t *res, @@ -236,10 +278,17 @@ int cris_mmu_translate(struct cris_mmu_result_t *res,
236 int seg; 278 int seg;
237 int miss = 0; 279 int miss = 0;
238 int is_user = mmu_idx == MMU_USER_IDX; 280 int is_user = mmu_idx == MMU_USER_IDX;
  281 + uint32_t old_srs;
  282 +
  283 + old_srs= env->pregs[PR_SRS];
  284 +
  285 + /* rw == 2 means exec, map the access to the insn mmu. */
  286 + env->pregs[PR_SRS] = rw == 2 ? 1 : 2;
239 287
240 if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) { 288 if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
241 res->phy = vaddr; 289 res->phy = vaddr;
242 - return 0; 290 + res->prot = PAGE_BITS;
  291 + goto done;
243 } 292 }
244 293
245 seg = vaddr >> 28; 294 seg = vaddr >> 28;
@@ -251,17 +300,16 @@ int cris_mmu_translate(struct cris_mmu_result_t *res, @@ -251,17 +300,16 @@ int cris_mmu_translate(struct cris_mmu_result_t *res,
251 base = cris_mmu_translate_seg(env, seg); 300 base = cris_mmu_translate_seg(env, seg);
252 phy = base | (0x0fffffff & vaddr); 301 phy = base | (0x0fffffff & vaddr);
253 res->phy = phy; 302 res->phy = phy;
  303 + res->prot = PAGE_BITS;
254 } 304 }
255 else 305 else
256 { 306 {
257 miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user); 307 miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user);
258 - if (!miss) {  
259 - phy &= 8191;  
260 - phy |= (res->pfn << 13);  
261 - res->phy = phy;  
262 - } 308 + phy = (res->pfn << 13);
  309 + res->phy = phy;
263 } 310 }
264 - D(printf ("miss=%d v=%x -> p=%x\n", miss, vaddr, phy)); 311 + done:
  312 + env->pregs[PR_SRS] = old_srs;
265 return miss; 313 return miss;
266 } 314 }
267 #endif 315 #endif
target-cris/mmu.h
@@ -7,6 +7,7 @@ struct cris_mmu_result_t @@ -7,6 +7,7 @@ struct cris_mmu_result_t
7 { 7 {
8 uint32_t phy; 8 uint32_t phy;
9 uint32_t pfn; 9 uint32_t pfn;
  10 + int prot;
10 int bf_vec; 11 int bf_vec;
11 }; 12 };
12 13
target-cris/op.c
@@ -192,17 +192,32 @@ void OPPROTO op_ccs_lshift (void) @@ -192,17 +192,32 @@ void OPPROTO op_ccs_lshift (void)
192 } 192 }
193 void OPPROTO op_ccs_rshift (void) 193 void OPPROTO op_ccs_rshift (void)
194 { 194 {
195 - uint32_t ccs; 195 + register uint32_t ccs;
196 196
197 /* Apply the ccs shift. */ 197 /* Apply the ccs shift. */
198 ccs = env->pregs[PR_CCS]; 198 ccs = env->pregs[PR_CCS];
199 ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10); 199 ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10);
  200 + if (ccs & U_FLAG)
  201 + {
  202 + /* Enter user mode. */
  203 + env->ksp = env->regs[R_SP];
  204 + env->regs[R_SP] = env->pregs[PR_USP];
  205 + }
  206 +
200 env->pregs[PR_CCS] = ccs; 207 env->pregs[PR_CCS] = ccs;
  208 +
201 RETURN(); 209 RETURN();
202 } 210 }
203 211
204 void OPPROTO op_setf (void) 212 void OPPROTO op_setf (void)
205 { 213 {
  214 + if (!(env->pregs[PR_CCS] & U_FLAG) && (PARAM1 & U_FLAG))
  215 + {
  216 + /* Enter user mode. */
  217 + env->ksp = env->regs[R_SP];
  218 + env->regs[R_SP] = env->pregs[PR_USP];
  219 + }
  220 +
206 env->pregs[PR_CCS] |= PARAM1; 221 env->pregs[PR_CCS] |= PARAM1;
207 RETURN(); 222 RETURN();
208 } 223 }
@@ -265,7 +280,11 @@ void OPPROTO op_movl_flags_T0 (void) @@ -265,7 +280,11 @@ void OPPROTO op_movl_flags_T0 (void)
265 280
266 void OPPROTO op_movl_sreg_T0 (void) 281 void OPPROTO op_movl_sreg_T0 (void)
267 { 282 {
268 - env->sregs[env->pregs[PR_SRS]][PARAM1] = T0; 283 + uint32_t srs;
  284 + srs = env->pregs[PR_SRS];
  285 + srs &= 3;
  286 +
  287 + env->sregs[srs][PARAM1] = T0;
269 RETURN(); 288 RETURN();
270 } 289 }
271 290
@@ -285,7 +304,10 @@ void OPPROTO op_movl_tlb_hi_T0 (void) @@ -285,7 +304,10 @@ void OPPROTO op_movl_tlb_hi_T0 (void)
285 void OPPROTO op_movl_tlb_lo_T0 (void) 304 void OPPROTO op_movl_tlb_lo_T0 (void)
286 { 305 {
287 uint32_t srs; 306 uint32_t srs;
  307 +
  308 + env->pregs[PR_SRS] &= 3;
288 srs = env->pregs[PR_SRS]; 309 srs = env->pregs[PR_SRS];
  310 +
289 if (srs == 1 || srs == 2) 311 if (srs == 1 || srs == 2)
290 { 312 {
291 uint32_t set; 313 uint32_t set;
@@ -309,7 +331,28 @@ void OPPROTO op_movl_tlb_lo_T0 (void) @@ -309,7 +331,28 @@ void OPPROTO op_movl_tlb_lo_T0 (void)
309 331
310 void OPPROTO op_movl_T0_sreg (void) 332 void OPPROTO op_movl_T0_sreg (void)
311 { 333 {
312 - T0 = env->sregs[env->pregs[PR_SRS]][PARAM1]; 334 + uint32_t srs;
  335 + env->pregs[PR_SRS] &= 3;
  336 + srs = env->pregs[PR_SRS];
  337 +
  338 + if (srs == 1 || srs == 2)
  339 + {
  340 + uint32_t set;
  341 + uint32_t idx;
  342 + uint32_t lo, hi;
  343 +
  344 + idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
  345 + set >>= 4;
  346 + set &= 3;
  347 + idx &= 15;
  348 +
  349 + /* Update the mirror regs. */
  350 + hi = env->tlbsets[srs - 1][set][idx].hi;
  351 + lo = env->tlbsets[srs - 1][set][idx].lo;
  352 + env->sregs[SFR_RW_MM_TLB_HI] = hi;
  353 + env->sregs[SFR_RW_MM_TLB_LO] = lo;
  354 + }
  355 + T0 = env->sregs[srs][PARAM1];
313 RETURN(); 356 RETURN();
314 } 357 }
315 358
@@ -363,340 +406,6 @@ void OPPROTO op_update_cc_x (void) @@ -363,340 +406,6 @@ void OPPROTO op_update_cc_x (void)
363 RETURN(); 406 RETURN();
364 } 407 }
365 408
366 -/* FIXME: is this allowed? */  
367 -extern inline void evaluate_flags_writeback(uint32_t flags)  
368 -{  
369 - int x;  
370 -  
371 - /* Extended arithmetics, leave the z flag alone. */  
372 - env->debug3 = env->pregs[PR_CCS];  
373 -  
374 - if (env->cc_x_live)  
375 - x = env->cc_x;  
376 - else  
377 - x = env->pregs[PR_CCS] & X_FLAG;  
378 -  
379 - if ((x || env->cc_op == CC_OP_ADDC)  
380 - && flags & Z_FLAG)  
381 - env->cc_mask &= ~Z_FLAG;  
382 -  
383 - /* all insn clear the x-flag except setf or clrf. */  
384 - env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);  
385 - flags &= env->cc_mask;  
386 - env->pregs[PR_CCS] |= flags;  
387 - RETURN();  
388 -}  
389 -  
390 -void OPPROTO op_evaluate_flags_muls(void)  
391 -{  
392 - uint32_t src;  
393 - uint32_t dst;  
394 - uint32_t res;  
395 - uint32_t flags = 0;  
396 - /* were gonna have to redo the muls. */  
397 - int64_t tmp, t0 ,t1;  
398 - int32_t mof;  
399 - int dneg;  
400 -  
401 - src = env->cc_src;  
402 - dst = env->cc_dest;  
403 - res = env->cc_result;  
404 -  
405 -  
406 - /* cast into signed values to make GCC sign extend. */  
407 - t0 = (int32_t)src;  
408 - t1 = (int32_t)dst;  
409 - dneg = ((int32_t)res) < 0;  
410 -  
411 - tmp = t0 * t1;  
412 - mof = tmp >> 32;  
413 - if (tmp == 0)  
414 - flags |= Z_FLAG;  
415 - else if (tmp < 0)  
416 - flags |= N_FLAG;  
417 - if ((dneg && mof != -1)  
418 - || (!dneg && mof != 0))  
419 - flags |= V_FLAG;  
420 - evaluate_flags_writeback(flags);  
421 - RETURN();  
422 -}  
423 -  
424 -void OPPROTO op_evaluate_flags_mulu(void)  
425 -{  
426 - uint32_t src;  
427 - uint32_t dst;  
428 - uint32_t res;  
429 - uint32_t flags = 0;  
430 - /* were gonna have to redo the muls. */  
431 - uint64_t tmp, t0 ,t1;  
432 - uint32_t mof;  
433 -  
434 - src = env->cc_src;  
435 - dst = env->cc_dest;  
436 - res = env->cc_result;  
437 -  
438 -  
439 - /* cast into signed values to make GCC sign extend. */  
440 - t0 = src;  
441 - t1 = dst;  
442 -  
443 - tmp = t0 * t1;  
444 - mof = tmp >> 32;  
445 - if (tmp == 0)  
446 - flags |= Z_FLAG;  
447 - else if (tmp >> 63)  
448 - flags |= N_FLAG;  
449 - if (mof)  
450 - flags |= V_FLAG;  
451 -  
452 - evaluate_flags_writeback(flags);  
453 - RETURN();  
454 -}  
455 -  
456 -void OPPROTO op_evaluate_flags_mcp(void)  
457 -{  
458 - uint32_t src;  
459 - uint32_t dst;  
460 - uint32_t res;  
461 - uint32_t flags = 0;  
462 -  
463 - src = env->cc_src;  
464 - dst = env->cc_dest;  
465 - res = env->cc_result;  
466 -  
467 - if ((res & 0x80000000L) != 0L)  
468 - {  
469 - flags |= N_FLAG;  
470 - if (((src & 0x80000000L) == 0L)  
471 - && ((dst & 0x80000000L) == 0L))  
472 - {  
473 - flags |= V_FLAG;  
474 - }  
475 - else if (((src & 0x80000000L) != 0L) &&  
476 - ((dst & 0x80000000L) != 0L))  
477 - {  
478 - flags |= R_FLAG;  
479 - }  
480 - }  
481 - else  
482 - {  
483 - if (res == 0L)  
484 - flags |= Z_FLAG;  
485 - if (((src & 0x80000000L) != 0L)  
486 - && ((dst & 0x80000000L) != 0L))  
487 - flags |= V_FLAG;  
488 - if ((dst & 0x80000000L) != 0L  
489 - || (src & 0x80000000L) != 0L)  
490 - flags |= R_FLAG;  
491 - }  
492 -  
493 - evaluate_flags_writeback(flags);  
494 - RETURN();  
495 -}  
496 -  
497 -void OPPROTO op_evaluate_flags_alu_4(void)  
498 -{  
499 - uint32_t src;  
500 - uint32_t dst;  
501 - uint32_t res;  
502 - uint32_t flags = 0;  
503 -  
504 - src = env->cc_src;  
505 - dst = env->cc_dest;  
506 - res = env->cc_result;  
507 -  
508 - if ((res & 0x80000000L) != 0L)  
509 - {  
510 - flags |= N_FLAG;  
511 - if (((src & 0x80000000L) == 0L)  
512 - && ((dst & 0x80000000L) == 0L))  
513 - {  
514 - flags |= V_FLAG;  
515 - }  
516 - else if (((src & 0x80000000L) != 0L) &&  
517 - ((dst & 0x80000000L) != 0L))  
518 - {  
519 - flags |= C_FLAG;  
520 - }  
521 - }  
522 - else  
523 - {  
524 - if (res == 0L)  
525 - flags |= Z_FLAG;  
526 - if (((src & 0x80000000L) != 0L)  
527 - && ((dst & 0x80000000L) != 0L))  
528 - flags |= V_FLAG;  
529 - if ((dst & 0x80000000L) != 0L  
530 - || (src & 0x80000000L) != 0L)  
531 - flags |= C_FLAG;  
532 - }  
533 -  
534 - if (env->cc_op == CC_OP_SUB  
535 - || env->cc_op == CC_OP_CMP) {  
536 - flags ^= C_FLAG;  
537 - }  
538 - evaluate_flags_writeback(flags);  
539 - RETURN();  
540 -}  
541 -  
542 -void OPPROTO op_evaluate_flags_move_4 (void)  
543 -{  
544 - uint32_t src;  
545 - uint32_t res;  
546 - uint32_t flags = 0;  
547 -  
548 - src = env->cc_src;  
549 - res = env->cc_result;  
550 -  
551 - if ((int32_t)res < 0)  
552 - flags |= N_FLAG;  
553 - else if (res == 0L)  
554 - flags |= Z_FLAG;  
555 -  
556 - evaluate_flags_writeback(flags);  
557 - RETURN();  
558 -}  
559 -void OPPROTO op_evaluate_flags_move_2 (void)  
560 -{  
561 - uint32_t src;  
562 - uint32_t flags = 0;  
563 - uint16_t res;  
564 -  
565 - src = env->cc_src;  
566 - res = env->cc_result;  
567 -  
568 - if ((int16_t)res < 0L)  
569 - flags |= N_FLAG;  
570 - else if (res == 0)  
571 - flags |= Z_FLAG;  
572 -  
573 - evaluate_flags_writeback(flags);  
574 - RETURN();  
575 -}  
576 -  
577 -/* TODO: This is expensive. We could split things up and only evaluate part of  
578 - CCR on a need to know basis. For now, we simply re-evaluate everything. */  
579 -void OPPROTO op_evaluate_flags (void)  
580 -{  
581 - uint32_t src;  
582 - uint32_t dst;  
583 - uint32_t res;  
584 - uint32_t flags = 0;  
585 -  
586 - src = env->cc_src;  
587 - dst = env->cc_dest;  
588 - res = env->cc_result;  
589 -  
590 -  
591 - /* Now, evaluate the flags. This stuff is based on  
592 - Per Zander's CRISv10 simulator. */  
593 - switch (env->cc_size)  
594 - {  
595 - case 1:  
596 - if ((res & 0x80L) != 0L)  
597 - {  
598 - flags |= N_FLAG;  
599 - if (((src & 0x80L) == 0L)  
600 - && ((dst & 0x80L) == 0L))  
601 - {  
602 - flags |= V_FLAG;  
603 - }  
604 - else if (((src & 0x80L) != 0L)  
605 - && ((dst & 0x80L) != 0L))  
606 - {  
607 - flags |= C_FLAG;  
608 - }  
609 - }  
610 - else  
611 - {  
612 - if ((res & 0xFFL) == 0L)  
613 - {  
614 - flags |= Z_FLAG;  
615 - }  
616 - if (((src & 0x80L) != 0L)  
617 - && ((dst & 0x80L) != 0L))  
618 - {  
619 - flags |= V_FLAG;  
620 - }  
621 - if ((dst & 0x80L) != 0L  
622 - || (src & 0x80L) != 0L)  
623 - {  
624 - flags |= C_FLAG;  
625 - }  
626 - }  
627 - break;  
628 - case 2:  
629 - if ((res & 0x8000L) != 0L)  
630 - {  
631 - flags |= N_FLAG;  
632 - if (((src & 0x8000L) == 0L)  
633 - && ((dst & 0x8000L) == 0L))  
634 - {  
635 - flags |= V_FLAG;  
636 - }  
637 - else if (((src & 0x8000L) != 0L)  
638 - && ((dst & 0x8000L) != 0L))  
639 - {  
640 - flags |= C_FLAG;  
641 - }  
642 - }  
643 - else  
644 - {  
645 - if ((res & 0xFFFFL) == 0L)  
646 - {  
647 - flags |= Z_FLAG;  
648 - }  
649 - if (((src & 0x8000L) != 0L)  
650 - && ((dst & 0x8000L) != 0L))  
651 - {  
652 - flags |= V_FLAG;  
653 - }  
654 - if ((dst & 0x8000L) != 0L  
655 - || (src & 0x8000L) != 0L)  
656 - {  
657 - flags |= C_FLAG;  
658 - }  
659 - }  
660 - break;  
661 - case 4:  
662 - if ((res & 0x80000000L) != 0L)  
663 - {  
664 - flags |= N_FLAG;  
665 - if (((src & 0x80000000L) == 0L)  
666 - && ((dst & 0x80000000L) == 0L))  
667 - {  
668 - flags |= V_FLAG;  
669 - }  
670 - else if (((src & 0x80000000L) != 0L) &&  
671 - ((dst & 0x80000000L) != 0L))  
672 - {  
673 - flags |= C_FLAG;  
674 - }  
675 - }  
676 - else  
677 - {  
678 - if (res == 0L)  
679 - flags |= Z_FLAG;  
680 - if (((src & 0x80000000L) != 0L)  
681 - && ((dst & 0x80000000L) != 0L))  
682 - flags |= V_FLAG;  
683 - if ((dst & 0x80000000L) != 0L  
684 - || (src & 0x80000000L) != 0L)  
685 - flags |= C_FLAG;  
686 - }  
687 - break;  
688 - default:  
689 - break;  
690 - }  
691 -  
692 - if (env->cc_op == CC_OP_SUB  
693 - || env->cc_op == CC_OP_CMP) {  
694 - flags ^= C_FLAG;  
695 - }  
696 - evaluate_flags_writeback(flags);  
697 - RETURN();  
698 -}  
699 -  
700 void OPPROTO op_extb_T0_T0 (void) 409 void OPPROTO op_extb_T0_T0 (void)
701 { 410 {
702 T0 = ((int8_t)T0); 411 T0 = ((int8_t)T0);
@@ -1274,17 +983,3 @@ void OPPROTO op_jmp1 (void) @@ -1274,17 +983,3 @@ void OPPROTO op_jmp1 (void)
1274 env->pc = env->btarget; 983 env->pc = env->btarget;
1275 RETURN(); 984 RETURN();
1276 } 985 }
1277 -  
1278 -/* Load and store */  
1279 -#define MEMSUFFIX _raw  
1280 -#include "op_mem.c"  
1281 -#undef MEMSUFFIX  
1282 -#if !defined(CONFIG_USER_ONLY)  
1283 -#define MEMSUFFIX _user  
1284 -#include "op_mem.c"  
1285 -#undef MEMSUFFIX  
1286 -  
1287 -#define MEMSUFFIX _kernel  
1288 -#include "op_mem.c"  
1289 -#undef MEMSUFFIX  
1290 -#endif  
target-cris/op_helper.c
@@ -59,6 +59,9 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) @@ -59,6 +59,9 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
59 generated code */ 59 generated code */
60 saved_env = env; 60 saved_env = env;
61 env = cpu_single_env; 61 env = cpu_single_env;
  62 +
  63 + D(fprintf(logfile, "%s ra=%x acr=%x %x\n", __func__, retaddr,
  64 + env->regs[R_ACR], saved_env->regs[R_ACR]));
62 ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); 65 ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
63 if (__builtin_expect(ret, 0)) { 66 if (__builtin_expect(ret, 0)) {
64 if (retaddr) { 67 if (retaddr) {
@@ -80,16 +83,380 @@ void helper_tlb_update(uint32_t T0) @@ -80,16 +83,380 @@ void helper_tlb_update(uint32_t T0)
80 { 83 {
81 #if !defined(CONFIG_USER_ONLY) 84 #if !defined(CONFIG_USER_ONLY)
82 uint32_t vaddr; 85 uint32_t vaddr;
  86 + uint32_t srs = env->pregs[PR_SRS];
  87 +
  88 + if (srs != 1 && srs != 2)
  89 + return;
83 90
84 vaddr = cris_mmu_tlb_latest_update(env, T0); 91 vaddr = cris_mmu_tlb_latest_update(env, T0);
85 - D(printf("flush vaddr %x\n", vaddr)); 92 + D(printf("flush old_vaddr=%x vaddr=%x T0=%x\n", vaddr,
  93 + env->sregs[SFR_R_MM_CAUSE] & TARGET_PAGE_MASK, T0));
86 tlb_flush_page(env, vaddr); 94 tlb_flush_page(env, vaddr);
87 #endif 95 #endif
88 } 96 }
89 97
  98 +void helper_tlb_flush(void)
  99 +{
  100 + tlb_flush(env, 1);
  101 +}
  102 +
  103 +void helper_dump(uint32_t a0, uint32_t a1)
  104 +{
  105 + (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1));
  106 +}
  107 +
  108 +void helper_dummy(void)
  109 +{
  110 +
  111 +}
  112 +
  113 +/* Only used for debugging at the moment. */
  114 +void helper_rfe(void)
  115 +{
  116 + D(fprintf(logfile, "rfe: erp=%x pid=%x ccs=%x btarget=%x\n",
  117 + env->pregs[PR_ERP], env->pregs[PR_PID],
  118 + env->pregs[PR_CCS],
  119 + env->btarget));
  120 +}
  121 +
  122 +void helper_store(uint32_t a0)
  123 +{
  124 + if (env->pregs[PR_CCS] & P_FLAG )
  125 + {
  126 + cpu_abort(env, "cond_store_failed! pc=%x a0=%x\n",
  127 + env->pc, a0);
  128 + }
  129 +}
  130 +
90 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, 131 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
91 int is_asi) 132 int is_asi)
92 { 133 {
93 D(printf("%s addr=%x w=%d ex=%d asi=%d\n", 134 D(printf("%s addr=%x w=%d ex=%d asi=%d\n",
94 __func__, addr, is_write, is_exec, is_asi)); 135 __func__, addr, is_write, is_exec, is_asi));
95 } 136 }
  137 +
  138 +static void evaluate_flags_writeback(uint32_t flags)
  139 +{
  140 + int x;
  141 +
  142 + /* Extended arithmetics, leave the z flag alone. */
  143 + env->debug3 = env->pregs[PR_CCS];
  144 +
  145 + if (env->cc_x_live)
  146 + x = env->cc_x;
  147 + else
  148 + x = env->pregs[PR_CCS] & X_FLAG;
  149 +
  150 + if ((x || env->cc_op == CC_OP_ADDC)
  151 + && flags & Z_FLAG)
  152 + env->cc_mask &= ~Z_FLAG;
  153 +
  154 + /* all insn clear the x-flag except setf or clrf. */
  155 + env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);
  156 + flags &= env->cc_mask;
  157 + env->pregs[PR_CCS] |= flags;
  158 + RETURN();
  159 +}
  160 +
  161 +void helper_evaluate_flags_muls(void)
  162 +{
  163 + uint32_t src;
  164 + uint32_t dst;
  165 + uint32_t res;
  166 + uint32_t flags = 0;
  167 + /* were gonna have to redo the muls. */
  168 + int64_t tmp, t0 ,t1;
  169 + int32_t mof;
  170 + int dneg;
  171 +
  172 + src = env->cc_src;
  173 + dst = env->cc_dest;
  174 + res = env->cc_result;
  175 +
  176 +
  177 + /* cast into signed values to make GCC sign extend. */
  178 + t0 = (int32_t)src;
  179 + t1 = (int32_t)dst;
  180 + dneg = ((int32_t)res) < 0;
  181 +
  182 + tmp = t0 * t1;
  183 + mof = tmp >> 32;
  184 + if (tmp == 0)
  185 + flags |= Z_FLAG;
  186 + else if (tmp < 0)
  187 + flags |= N_FLAG;
  188 + if ((dneg && mof != -1)
  189 + || (!dneg && mof != 0))
  190 + flags |= V_FLAG;
  191 + evaluate_flags_writeback(flags);
  192 +}
  193 +
  194 +void helper_evaluate_flags_mulu(void)
  195 +{
  196 + uint32_t src;
  197 + uint32_t dst;
  198 + uint32_t res;
  199 + uint32_t flags = 0;
  200 + /* were gonna have to redo the muls. */
  201 + uint64_t tmp, t0 ,t1;
  202 + uint32_t mof;
  203 +
  204 + src = env->cc_src;
  205 + dst = env->cc_dest;
  206 + res = env->cc_result;
  207 +
  208 +
  209 + /* cast into signed values to make GCC sign extend. */
  210 + t0 = src;
  211 + t1 = dst;
  212 +
  213 + tmp = t0 * t1;
  214 + mof = tmp >> 32;
  215 + if (tmp == 0)
  216 + flags |= Z_FLAG;
  217 + else if (tmp >> 63)
  218 + flags |= N_FLAG;
  219 + if (mof)
  220 + flags |= V_FLAG;
  221 +
  222 + evaluate_flags_writeback(flags);
  223 +}
  224 +
  225 +void helper_evaluate_flags_mcp(void)
  226 +{
  227 + uint32_t src;
  228 + uint32_t dst;
  229 + uint32_t res;
  230 + uint32_t flags = 0;
  231 +
  232 + src = env->cc_src;
  233 + dst = env->cc_dest;
  234 + res = env->cc_result;
  235 +
  236 + if ((res & 0x80000000L) != 0L)
  237 + {
  238 + flags |= N_FLAG;
  239 + if (((src & 0x80000000L) == 0L)
  240 + && ((dst & 0x80000000L) == 0L))
  241 + {
  242 + flags |= V_FLAG;
  243 + }
  244 + else if (((src & 0x80000000L) != 0L) &&
  245 + ((dst & 0x80000000L) != 0L))
  246 + {
  247 + flags |= R_FLAG;
  248 + }
  249 + }
  250 + else
  251 + {
  252 + if (res == 0L)
  253 + flags |= Z_FLAG;
  254 + if (((src & 0x80000000L) != 0L)
  255 + && ((dst & 0x80000000L) != 0L))
  256 + flags |= V_FLAG;
  257 + if ((dst & 0x80000000L) != 0L
  258 + || (src & 0x80000000L) != 0L)
  259 + flags |= R_FLAG;
  260 + }
  261 +
  262 + evaluate_flags_writeback(flags);
  263 +}
  264 +
  265 +void helper_evaluate_flags_alu_4(void)
  266 +{
  267 + uint32_t src;
  268 + uint32_t dst;
  269 + uint32_t res;
  270 + uint32_t flags = 0;
  271 +
  272 + src = env->cc_src;
  273 + dst = env->cc_dest;
  274 + res = env->cc_result;
  275 +
  276 + if ((res & 0x80000000L) != 0L)
  277 + {
  278 + flags |= N_FLAG;
  279 + if (((src & 0x80000000L) == 0L)
  280 + && ((dst & 0x80000000L) == 0L))
  281 + {
  282 + flags |= V_FLAG;
  283 + }
  284 + else if (((src & 0x80000000L) != 0L) &&
  285 + ((dst & 0x80000000L) != 0L))
  286 + {
  287 + flags |= C_FLAG;
  288 + }
  289 + }
  290 + else
  291 + {
  292 + if (res == 0L)
  293 + flags |= Z_FLAG;
  294 + if (((src & 0x80000000L) != 0L)
  295 + && ((dst & 0x80000000L) != 0L))
  296 + flags |= V_FLAG;
  297 + if ((dst & 0x80000000L) != 0L
  298 + || (src & 0x80000000L) != 0L)
  299 + flags |= C_FLAG;
  300 + }
  301 +
  302 + if (env->cc_op == CC_OP_SUB
  303 + || env->cc_op == CC_OP_CMP) {
  304 + flags ^= C_FLAG;
  305 + }
  306 + evaluate_flags_writeback(flags);
  307 +}
  308 +
  309 +void helper_evaluate_flags_move_4 (void)
  310 +{
  311 + uint32_t src;
  312 + uint32_t res;
  313 + uint32_t flags = 0;
  314 +
  315 + src = env->cc_src;
  316 + res = env->cc_result;
  317 +
  318 + if ((int32_t)res < 0)
  319 + flags |= N_FLAG;
  320 + else if (res == 0L)
  321 + flags |= Z_FLAG;
  322 +
  323 + evaluate_flags_writeback(flags);
  324 +}
  325 +void helper_evaluate_flags_move_2 (void)
  326 +{
  327 + uint32_t src;
  328 + uint32_t flags = 0;
  329 + uint16_t res;
  330 +
  331 + src = env->cc_src;
  332 + res = env->cc_result;
  333 +
  334 + if ((int16_t)res < 0L)
  335 + flags |= N_FLAG;
  336 + else if (res == 0)
  337 + flags |= Z_FLAG;
  338 +
  339 + evaluate_flags_writeback(flags);
  340 +}
  341 +
  342 +/* TODO: This is expensive. We could split things up and only evaluate part of
  343 + CCR on a need to know basis. For now, we simply re-evaluate everything. */
  344 +void helper_evaluate_flags (void)
  345 +{
  346 + uint32_t src;
  347 + uint32_t dst;
  348 + uint32_t res;
  349 + uint32_t flags = 0;
  350 +
  351 + src = env->cc_src;
  352 + dst = env->cc_dest;
  353 + res = env->cc_result;
  354 +
  355 +
  356 + /* Now, evaluate the flags. This stuff is based on
  357 + Per Zander's CRISv10 simulator. */
  358 + switch (env->cc_size)
  359 + {
  360 + case 1:
  361 + if ((res & 0x80L) != 0L)
  362 + {
  363 + flags |= N_FLAG;
  364 + if (((src & 0x80L) == 0L)
  365 + && ((dst & 0x80L) == 0L))
  366 + {
  367 + flags |= V_FLAG;
  368 + }
  369 + else if (((src & 0x80L) != 0L)
  370 + && ((dst & 0x80L) != 0L))
  371 + {
  372 + flags |= C_FLAG;
  373 + }
  374 + }
  375 + else
  376 + {
  377 + if ((res & 0xFFL) == 0L)
  378 + {
  379 + flags |= Z_FLAG;
  380 + }
  381 + if (((src & 0x80L) != 0L)
  382 + && ((dst & 0x80L) != 0L))
  383 + {
  384 + flags |= V_FLAG;
  385 + }
  386 + if ((dst & 0x80L) != 0L
  387 + || (src & 0x80L) != 0L)
  388 + {
  389 + flags |= C_FLAG;
  390 + }
  391 + }
  392 + break;
  393 + case 2:
  394 + if ((res & 0x8000L) != 0L)
  395 + {
  396 + flags |= N_FLAG;
  397 + if (((src & 0x8000L) == 0L)
  398 + && ((dst & 0x8000L) == 0L))
  399 + {
  400 + flags |= V_FLAG;
  401 + }
  402 + else if (((src & 0x8000L) != 0L)
  403 + && ((dst & 0x8000L) != 0L))
  404 + {
  405 + flags |= C_FLAG;
  406 + }
  407 + }
  408 + else
  409 + {
  410 + if ((res & 0xFFFFL) == 0L)
  411 + {
  412 + flags |= Z_FLAG;
  413 + }
  414 + if (((src & 0x8000L) != 0L)
  415 + && ((dst & 0x8000L) != 0L))
  416 + {
  417 + flags |= V_FLAG;
  418 + }
  419 + if ((dst & 0x8000L) != 0L
  420 + || (src & 0x8000L) != 0L)
  421 + {
  422 + flags |= C_FLAG;
  423 + }
  424 + }
  425 + break;
  426 + case 4:
  427 + if ((res & 0x80000000L) != 0L)
  428 + {
  429 + flags |= N_FLAG;
  430 + if (((src & 0x80000000L) == 0L)
  431 + && ((dst & 0x80000000L) == 0L))
  432 + {
  433 + flags |= V_FLAG;
  434 + }
  435 + else if (((src & 0x80000000L) != 0L) &&
  436 + ((dst & 0x80000000L) != 0L))
  437 + {
  438 + flags |= C_FLAG;
  439 + }
  440 + }
  441 + else
  442 + {
  443 + if (res == 0L)
  444 + flags |= Z_FLAG;
  445 + if (((src & 0x80000000L) != 0L)
  446 + && ((dst & 0x80000000L) != 0L))
  447 + flags |= V_FLAG;
  448 + if ((dst & 0x80000000L) != 0L
  449 + || (src & 0x80000000L) != 0L)
  450 + flags |= C_FLAG;
  451 + }
  452 + break;
  453 + default:
  454 + break;
  455 + }
  456 +
  457 + if (env->cc_op == CC_OP_SUB
  458 + || env->cc_op == CC_OP_CMP) {
  459 + flags ^= C_FLAG;
  460 + }
  461 + evaluate_flags_writeback(flags);
  462 +}
target-cris/translate.c
@@ -19,6 +19,12 @@ @@ -19,6 +19,12 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
  22 +/*
  23 + * FIXME:
  24 + * The condition code translation is in desperate need of attention. It's slow
  25 + * and for system simulation it seems buggy. It sucks.
  26 + */
  27 +
22 #include <stdarg.h> 28 #include <stdarg.h>
23 #include <stdlib.h> 29 #include <stdlib.h>
24 #include <stdio.h> 30 #include <stdio.h>
@@ -48,6 +54,7 @@ @@ -48,6 +54,7 @@
48 #define DIS(x) 54 #define DIS(x)
49 #endif 55 #endif
50 56
  57 +#define D(x)
51 #define BUG() (gen_BUG(dc, __FILE__, __LINE__)) 58 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
52 #define BUG_ON(x) ({if (x) BUG();}) 59 #define BUG_ON(x) ({if (x) BUG();})
53 60
@@ -73,10 +80,13 @@ TCGv cc_op; @@ -73,10 +80,13 @@ TCGv cc_op;
73 TCGv cc_size; 80 TCGv cc_size;
74 TCGv cc_mask; 81 TCGv cc_mask;
75 82
  83 +TCGv env_btarget;
  84 +TCGv env_pc;
  85 +
76 /* This is the state at translation time. */ 86 /* This is the state at translation time. */
77 typedef struct DisasContext { 87 typedef struct DisasContext {
78 CPUState *env; 88 CPUState *env;
79 - target_ulong pc, insn_pc; 89 + target_ulong pc, ppc;
80 90
81 /* Decoder. */ 91 /* Decoder. */
82 uint32_t ir; 92 uint32_t ir;
@@ -91,12 +101,13 @@ typedef struct DisasContext { @@ -91,12 +101,13 @@ typedef struct DisasContext {
91 int cc_op; 101 int cc_op;
92 int cc_size; 102 int cc_size;
93 uint32_t cc_mask; 103 uint32_t cc_mask;
94 - int flags_live;  
95 - int flagx_live; 104 + int flags_live; /* Wether or not $ccs is uptodate. */
  105 + int flagx_live; /* Wether or not flags_x has the x flag known at
  106 + translation time. */
96 int flags_x; 107 int flags_x;
97 - uint32_t tb_entry_flags; 108 + int clear_x; /* Clear x after this insn? */
98 109
99 - int memidx; /* user or kernel mode. */ 110 + int user; /* user or kernel mode. */
100 int is_jmp; 111 int is_jmp;
101 int dyn_jmp; 112 int dyn_jmp;
102 113
@@ -119,37 +130,6 @@ static void gen_BUG(DisasContext *dc, char *file, int line) @@ -119,37 +130,6 @@ static void gen_BUG(DisasContext *dc, char *file, int line)
119 cris_prepare_jmp (dc, 0x70000000 + line); 130 cris_prepare_jmp (dc, 0x70000000 + line);
120 } 131 }
121 132
122 -#ifdef CONFIG_USER_ONLY  
123 -#define GEN_OP_LD(width, reg) \  
124 - void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \  
125 - gen_op_ld##width##_T0_##reg##_raw(); \  
126 - }  
127 -#define GEN_OP_ST(width, reg) \  
128 - void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \  
129 - gen_op_st##width##_##reg##_T1_raw(); \  
130 - }  
131 -#else  
132 -#define GEN_OP_LD(width, reg) \  
133 - void gen_op_ld##width##_T0_##reg (DisasContext *dc) { \  
134 - if (dc->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \  
135 - else gen_op_ld##width##_T0_##reg##_user();\  
136 - }  
137 -#define GEN_OP_ST(width, reg) \  
138 - void gen_op_st##width##_##reg##_T1 (DisasContext *dc) { \  
139 - if (dc->memidx) gen_op_st##width##_##reg##_T1_kernel(); \  
140 - else gen_op_st##width##_##reg##_T1_user();\  
141 - }  
142 -#endif  
143 -  
144 -GEN_OP_LD(ub, T0)  
145 -GEN_OP_LD(b, T0)  
146 -GEN_OP_ST(b, T0)  
147 -GEN_OP_LD(uw, T0)  
148 -GEN_OP_LD(w, T0)  
149 -GEN_OP_ST(w, T0)  
150 -GEN_OP_LD(l, T0)  
151 -GEN_OP_ST(l, T0)  
152 -  
153 const char *regnames[] = 133 const char *regnames[] =
154 { 134 {
155 "$r0", "$r1", "$r2", "$r3", 135 "$r0", "$r1", "$r2", "$r3",
@@ -182,35 +162,65 @@ int preg_sizes[] = { @@ -182,35 +162,65 @@ int preg_sizes[] = {
182 #define t_gen_mov_env_TN(member, tn) \ 162 #define t_gen_mov_env_TN(member, tn) \
183 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn)) 163 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
184 164
185 -#define t_gen_mov_TN_reg(tn, regno) \  
186 - tcg_gen_mov_tl(tn, cpu_R[regno])  
187 -#define t_gen_mov_reg_TN(regno, tn) \  
188 - tcg_gen_mov_tl(cpu_R[regno], tn) 165 +static inline void t_gen_mov_TN_reg(TCGv tn, int r)
  166 +{
  167 + if (r < 0 || r > 15)
  168 + fprintf(stderr, "wrong register read $r%d\n", r);
  169 + tcg_gen_mov_tl(tn, cpu_R[r]);
  170 +}
  171 +static inline void t_gen_mov_reg_TN(int r, TCGv tn)
  172 +{
  173 + if (r < 0 || r > 15)
  174 + fprintf(stderr, "wrong register write $r%d\n", r);
  175 + tcg_gen_mov_tl(cpu_R[r], tn);
  176 +}
189 177
190 static inline void _t_gen_mov_TN_env(TCGv tn, int offset) 178 static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
191 { 179 {
  180 + if (offset > sizeof (CPUState))
  181 + fprintf(stderr, "wrong load from env from off=%d\n", offset);
192 tcg_gen_ld_tl(tn, cpu_env, offset); 182 tcg_gen_ld_tl(tn, cpu_env, offset);
193 } 183 }
194 static inline void _t_gen_mov_env_TN(int offset, TCGv tn) 184 static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
195 { 185 {
  186 + if (offset > sizeof (CPUState))
  187 + fprintf(stderr, "wrong store to env at off=%d\n", offset);
196 tcg_gen_st_tl(tn, cpu_env, offset); 188 tcg_gen_st_tl(tn, cpu_env, offset);
197 } 189 }
198 190
199 static inline void t_gen_mov_TN_preg(TCGv tn, int r) 191 static inline void t_gen_mov_TN_preg(TCGv tn, int r)
200 { 192 {
  193 + if (r < 0 || r > 15)
  194 + fprintf(stderr, "wrong register read $p%d\n", r);
201 if (r == PR_BZ || r == PR_WZ || r == PR_DZ) 195 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
202 tcg_gen_mov_tl(tn, tcg_const_tl(0)); 196 tcg_gen_mov_tl(tn, tcg_const_tl(0));
203 else if (r == PR_VR) 197 else if (r == PR_VR)
204 tcg_gen_mov_tl(tn, tcg_const_tl(32)); 198 tcg_gen_mov_tl(tn, tcg_const_tl(32));
  199 + else if (r == PR_EXS) {
  200 + printf("read from EXS!\n");
  201 + tcg_gen_mov_tl(tn, cpu_PR[r]);
  202 + }
  203 + else if (r == PR_EDA) {
  204 + printf("read from EDA!\n");
  205 + tcg_gen_mov_tl(tn, cpu_PR[r]);
  206 + }
205 else 207 else
206 tcg_gen_mov_tl(tn, cpu_PR[r]); 208 tcg_gen_mov_tl(tn, cpu_PR[r]);
207 } 209 }
208 static inline void t_gen_mov_preg_TN(int r, TCGv tn) 210 static inline void t_gen_mov_preg_TN(int r, TCGv tn)
209 { 211 {
  212 + if (r < 0 || r > 15)
  213 + fprintf(stderr, "wrong register write $p%d\n", r);
210 if (r == PR_BZ || r == PR_WZ || r == PR_DZ) 214 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
211 return; 215 return;
212 - else 216 + else if (r == PR_SRS)
  217 + tcg_gen_andi_tl(cpu_PR[r], tn, 3);
  218 + else {
  219 + if (r == PR_PID) {
  220 + tcg_gen_helper_0_0(helper_tlb_flush);
  221 + }
213 tcg_gen_mov_tl(cpu_PR[r], tn); 222 tcg_gen_mov_tl(cpu_PR[r], tn);
  223 + }
214 } 224 }
215 225
216 static inline void t_gen_mov_TN_im(TCGv tn, int32_t val) 226 static inline void t_gen_mov_TN_im(TCGv tn, int32_t val)
@@ -253,9 +263,7 @@ static void t_gen_asr(TCGv d, TCGv a, TCGv b) @@ -253,9 +263,7 @@ static void t_gen_asr(TCGv d, TCGv a, TCGv b)
253 tcg_gen_sar_tl(d, a, b); 263 tcg_gen_sar_tl(d, a, b);
254 tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1); 264 tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
255 /* Clear dst if shift operands were to large. */ 265 /* Clear dst if shift operands were to large. */
256 - tcg_gen_movi_tl(d, 0);  
257 - tcg_gen_brcond_tl(TCG_COND_LT, b, tcg_const_tl(0x80000000), l1);  
258 - tcg_gen_movi_tl(d, 0xffffffff); 266 + tcg_gen_sar_tl(d, a, tcg_const_tl(30));
259 gen_set_label(l1); 267 gen_set_label(l1);
260 } 268 }
261 269
@@ -274,6 +282,9 @@ static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b) @@ -274,6 +282,9 @@ static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
274 tcg_gen_trunc_i64_i32(d, t0); 282 tcg_gen_trunc_i64_i32(d, t0);
275 tcg_gen_shri_i64(t0, t0, 32); 283 tcg_gen_shri_i64(t0, t0, 32);
276 tcg_gen_trunc_i64_i32(d2, t0); 284 tcg_gen_trunc_i64_i32(d2, t0);
  285 +
  286 + tcg_gen_discard_i64(t0);
  287 + tcg_gen_discard_i64(t1);
277 } 288 }
278 289
279 /* 64-bit unsigned muls, lower result in d and upper in d2. */ 290 /* 64-bit unsigned muls, lower result in d and upper in d2. */
@@ -291,6 +302,9 @@ static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b) @@ -291,6 +302,9 @@ static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
291 tcg_gen_trunc_i64_i32(d, t0); 302 tcg_gen_trunc_i64_i32(d, t0);
292 tcg_gen_shri_i64(t0, t0, 32); 303 tcg_gen_shri_i64(t0, t0, 32);
293 tcg_gen_trunc_i64_i32(d2, t0); 304 tcg_gen_trunc_i64_i32(d2, t0);
  305 +
  306 + tcg_gen_discard_i64(t0);
  307 + tcg_gen_discard_i64(t1);
294 } 308 }
295 309
296 /* Extended arithmetics on CRIS. */ 310 /* Extended arithmetics on CRIS. */
@@ -305,6 +319,7 @@ static inline void t_gen_add_flag(TCGv d, int flag) @@ -305,6 +319,7 @@ static inline void t_gen_add_flag(TCGv d, int flag)
305 if (flag) 319 if (flag)
306 tcg_gen_shri_tl(c, c, flag); 320 tcg_gen_shri_tl(c, c, flag);
307 tcg_gen_add_tl(d, d, c); 321 tcg_gen_add_tl(d, d, c);
  322 + tcg_gen_discard_tl(c);
308 } 323 }
309 324
310 static inline void t_gen_addx_carry(TCGv d) 325 static inline void t_gen_addx_carry(TCGv d)
@@ -323,6 +338,8 @@ static inline void t_gen_addx_carry(TCGv d) @@ -323,6 +338,8 @@ static inline void t_gen_addx_carry(TCGv d)
323 338
324 tcg_gen_and_tl(x, x, c); 339 tcg_gen_and_tl(x, x, c);
325 tcg_gen_add_tl(d, d, x); 340 tcg_gen_add_tl(d, d, x);
  341 + tcg_gen_discard_tl(x);
  342 + tcg_gen_discard_tl(c);
326 } 343 }
327 344
328 static inline void t_gen_subx_carry(TCGv d) 345 static inline void t_gen_subx_carry(TCGv d)
@@ -341,6 +358,8 @@ static inline void t_gen_subx_carry(TCGv d) @@ -341,6 +358,8 @@ static inline void t_gen_subx_carry(TCGv d)
341 358
342 tcg_gen_and_tl(x, x, c); 359 tcg_gen_and_tl(x, x, c);
343 tcg_gen_sub_tl(d, d, x); 360 tcg_gen_sub_tl(d, d, x);
  361 + tcg_gen_discard_tl(x);
  362 + tcg_gen_discard_tl(c);
344 } 363 }
345 364
346 /* Swap the two bytes within each half word of the s operand. 365 /* Swap the two bytes within each half word of the s operand.
@@ -359,6 +378,8 @@ static inline void t_gen_swapb(TCGv d, TCGv s) @@ -359,6 +378,8 @@ static inline void t_gen_swapb(TCGv d, TCGv s)
359 tcg_gen_shri_tl(t, org_s, 8); 378 tcg_gen_shri_tl(t, org_s, 8);
360 tcg_gen_andi_tl(t, t, 0x00ff00ff); 379 tcg_gen_andi_tl(t, t, 0x00ff00ff);
361 tcg_gen_or_tl(d, d, t); 380 tcg_gen_or_tl(d, d, t);
  381 + tcg_gen_discard_tl(t);
  382 + tcg_gen_discard_tl(org_s);
362 } 383 }
363 384
364 /* Swap the halfwords of the s operand. */ 385 /* Swap the halfwords of the s operand. */
@@ -371,6 +392,7 @@ static inline void t_gen_swapw(TCGv d, TCGv s) @@ -371,6 +392,7 @@ static inline void t_gen_swapw(TCGv d, TCGv s)
371 tcg_gen_shli_tl(d, t, 16); 392 tcg_gen_shli_tl(d, t, 16);
372 tcg_gen_shri_tl(t, t, 16); 393 tcg_gen_shri_tl(t, t, 16);
373 tcg_gen_or_tl(d, d, t); 394 tcg_gen_or_tl(d, d, t);
  395 + tcg_gen_discard_tl(t);
374 } 396 }
375 397
376 /* Reverse the within each byte. 398 /* Reverse the within each byte.
@@ -417,6 +439,8 @@ static inline void t_gen_swapr(TCGv d, TCGv s) @@ -417,6 +439,8 @@ static inline void t_gen_swapr(TCGv d, TCGv s)
417 tcg_gen_andi_tl(t, t, bitrev[i].mask); 439 tcg_gen_andi_tl(t, t, bitrev[i].mask);
418 tcg_gen_or_tl(d, d, t); 440 tcg_gen_or_tl(d, d, t);
419 } 441 }
  442 + tcg_gen_discard_tl(t);
  443 + tcg_gen_discard_tl(org_s);
420 } 444 }
421 445
422 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) 446 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
@@ -449,53 +473,58 @@ static int sign_extend(unsigned int val, unsigned int width) @@ -449,53 +473,58 @@ static int sign_extend(unsigned int val, unsigned int width)
449 473
450 static inline void cris_clear_x_flag(DisasContext *dc) 474 static inline void cris_clear_x_flag(DisasContext *dc)
451 { 475 {
452 - if (!dc->flagx_live || dc->cc_op != CC_OP_FLAGS) {  
453 - t_gen_mov_TN_preg(cpu_T[0], PR_CCS);  
454 - tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ~X_FLAG);  
455 - t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);  
456 - dc->flagx_live = 1;  
457 - dc->flags_x = 0;  
458 - } 476 + if (!dc->flagx_live
  477 + || (dc->flagx_live && dc->flags_x)
  478 + || dc->cc_op != CC_OP_FLAGS)
  479 + tcg_gen_andi_i32(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
  480 + dc->flagx_live = 1;
  481 + dc->flags_x = 0;
459 } 482 }
460 483
461 static void cris_evaluate_flags(DisasContext *dc) 484 static void cris_evaluate_flags(DisasContext *dc)
462 { 485 {
463 if (!dc->flags_live) { 486 if (!dc->flags_live) {
  487 + tcg_gen_movi_tl(cc_op, dc->cc_op);
  488 + tcg_gen_movi_tl(cc_size, dc->cc_size);
  489 + tcg_gen_movi_tl(cc_mask, dc->cc_mask);
  490 +
464 switch (dc->cc_op) 491 switch (dc->cc_op)
465 { 492 {
466 case CC_OP_MCP: 493 case CC_OP_MCP:
467 - gen_op_evaluate_flags_mcp (); 494 + tcg_gen_helper_0_0(helper_evaluate_flags_mcp);
468 break; 495 break;
469 case CC_OP_MULS: 496 case CC_OP_MULS:
470 - gen_op_evaluate_flags_muls (); 497 + tcg_gen_helper_0_0(helper_evaluate_flags_muls);
471 break; 498 break;
472 case CC_OP_MULU: 499 case CC_OP_MULU:
473 - gen_op_evaluate_flags_mulu (); 500 + tcg_gen_helper_0_0(helper_evaluate_flags_mulu);
474 break; 501 break;
475 case CC_OP_MOVE: 502 case CC_OP_MOVE:
476 switch (dc->cc_size) 503 switch (dc->cc_size)
477 { 504 {
478 case 4: 505 case 4:
479 - gen_op_evaluate_flags_move_4(); 506 + tcg_gen_helper_0_0(helper_evaluate_flags_move_4);
480 break; 507 break;
481 case 2: 508 case 2:
482 - gen_op_evaluate_flags_move_2(); 509 + tcg_gen_helper_0_0(helper_evaluate_flags_move_2);
483 break; 510 break;
484 default: 511 default:
485 - gen_op_evaluate_flags (); 512 + tcg_gen_helper_0_0(helper_evaluate_flags);
486 break; 513 break;
487 } 514 }
488 break; 515 break;
489 - 516 + case CC_OP_FLAGS:
  517 + /* live. */
  518 + break;
490 default: 519 default:
491 { 520 {
492 switch (dc->cc_size) 521 switch (dc->cc_size)
493 { 522 {
494 case 4: 523 case 4:
495 - gen_op_evaluate_flags_alu_4 (); 524 + tcg_gen_helper_0_0(helper_evaluate_flags_alu_4);
496 break; 525 break;
497 default: 526 default:
498 - gen_op_evaluate_flags (); 527 + tcg_gen_helper_0_0(helper_evaluate_flags);
499 break; 528 break;
500 } 529 }
501 } 530 }
@@ -525,16 +554,11 @@ static void cris_cc_mask(DisasContext *dc, unsigned int mask) @@ -525,16 +554,11 @@ static void cris_cc_mask(DisasContext *dc, unsigned int mask)
525 dc->flags_live = 0; 554 dc->flags_live = 0;
526 } 555 }
527 556
528 -static void cris_update_cc_op(DisasContext *dc, int op) 557 +static void cris_update_cc_op(DisasContext *dc, int op, int size)
529 { 558 {
530 dc->cc_op = op; 559 dc->cc_op = op;
531 - dc->flags_live = 0;  
532 - tcg_gen_movi_tl(cc_op, op);  
533 -}  
534 -static void cris_update_cc_size(DisasContext *dc, int size)  
535 -{  
536 dc->cc_size = size; 560 dc->cc_size = size;
537 - tcg_gen_movi_tl(cc_size, size); 561 + dc->flags_live = 0;
538 } 562 }
539 563
540 /* op is the operation. 564 /* op is the operation.
@@ -545,10 +569,8 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -545,10 +569,8 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
545 { 569 {
546 int writeback = 1; 570 int writeback = 1;
547 if (dc->update_cc) { 571 if (dc->update_cc) {
548 - cris_update_cc_op(dc, op);  
549 - cris_update_cc_size(dc, size); 572 + cris_update_cc_op(dc, op, size);
550 tcg_gen_mov_tl(cc_dest, cpu_T[0]); 573 tcg_gen_mov_tl(cc_dest, cpu_T[0]);
551 - tcg_gen_movi_tl(cc_mask, dc->cc_mask);  
552 574
553 /* FIXME: This shouldn't be needed. But we don't pass the 575 /* FIXME: This shouldn't be needed. But we don't pass the
554 tests without it. Investigate. */ 576 tests without it. Investigate. */
@@ -623,6 +645,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -623,6 +645,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
623 mof = tcg_temp_new(TCG_TYPE_TL); 645 mof = tcg_temp_new(TCG_TYPE_TL);
624 t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]); 646 t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
625 t_gen_mov_preg_TN(PR_MOF, mof); 647 t_gen_mov_preg_TN(PR_MOF, mof);
  648 + tcg_gen_discard_tl(mof);
626 } 649 }
627 break; 650 break;
628 case CC_OP_MULU: 651 case CC_OP_MULU:
@@ -631,6 +654,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -631,6 +654,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
631 mof = tcg_temp_new(TCG_TYPE_TL); 654 mof = tcg_temp_new(TCG_TYPE_TL);
632 t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]); 655 t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
633 t_gen_mov_preg_TN(PR_MOF, mof); 656 t_gen_mov_preg_TN(PR_MOF, mof);
  657 + tcg_gen_discard_tl(mof);
634 } 658 }
635 break; 659 break;
636 case CC_OP_DSTEP: 660 case CC_OP_DSTEP:
@@ -820,10 +844,10 @@ static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond) @@ -820,10 +844,10 @@ static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
820 gen_tst_cc (dc, cond); 844 gen_tst_cc (dc, cond);
821 gen_op_evaluate_bcc (); 845 gen_op_evaluate_bcc ();
822 } 846 }
823 - tcg_gen_movi_tl(cpu_T[0], dc->delayed_pc);  
824 - t_gen_mov_env_TN(btarget, cpu_T[0]); 847 + tcg_gen_movi_tl(env_btarget, dc->delayed_pc);
825 } 848 }
826 849
  850 +
827 /* Dynamic jumps, when the dest is in a live reg for example. */ 851 /* Dynamic jumps, when the dest is in a live reg for example. */
828 void cris_prepare_dyn_jmp (DisasContext *dc) 852 void cris_prepare_dyn_jmp (DisasContext *dc)
829 { 853 {
@@ -844,36 +868,46 @@ void cris_prepare_jmp (DisasContext *dc, uint32_t dst) @@ -844,36 +868,46 @@ void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
844 dc->bcc = CC_A; 868 dc->bcc = CC_A;
845 } 869 }
846 870
847 -void gen_load_T0_T0 (DisasContext *dc, unsigned int size, int sign) 871 +void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
  872 + unsigned int size, int sign)
848 { 873 {
  874 + int mem_index = cpu_mmu_index(dc->env);
  875 +
  876 + /* FIXME: qemu_ld does not act as a barrier? */
  877 + tcg_gen_helper_0_0(helper_dummy);
  878 + cris_evaluate_flags(dc);
849 if (size == 1) { 879 if (size == 1) {
850 if (sign) 880 if (sign)
851 - gen_op_ldb_T0_T0(dc); 881 + tcg_gen_qemu_ld8s(dst, addr, mem_index);
852 else 882 else
853 - gen_op_ldub_T0_T0(dc); 883 + tcg_gen_qemu_ld8u(dst, addr, mem_index);
854 } 884 }
855 else if (size == 2) { 885 else if (size == 2) {
856 if (sign) 886 if (sign)
857 - gen_op_ldw_T0_T0(dc); 887 + tcg_gen_qemu_ld16s(dst, addr, mem_index);
858 else 888 else
859 - gen_op_lduw_T0_T0(dc); 889 + tcg_gen_qemu_ld16u(dst, addr, mem_index);
860 } 890 }
861 else { 891 else {
862 - gen_op_ldl_T0_T0(dc); 892 + tcg_gen_qemu_ld32s(dst, addr, mem_index);
863 } 893 }
864 } 894 }
865 895
866 void gen_store_T0_T1 (DisasContext *dc, unsigned int size) 896 void gen_store_T0_T1 (DisasContext *dc, unsigned int size)
867 { 897 {
  898 + int mem_index = cpu_mmu_index(dc->env);
  899 +
  900 + /* FIXME: qemu_st does not act as a barrier? */
  901 + tcg_gen_helper_0_0(helper_dummy);
  902 + cris_evaluate_flags(dc);
  903 +
868 /* Remember, operands are flipped. CRIS has reversed order. */ 904 /* Remember, operands are flipped. CRIS has reversed order. */
869 - if (size == 1) {  
870 - gen_op_stb_T0_T1(dc);  
871 - }  
872 - else if (size == 2) {  
873 - gen_op_stw_T0_T1(dc);  
874 - } 905 + if (size == 1)
  906 + tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], mem_index);
  907 + else if (size == 2)
  908 + tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], mem_index);
875 else 909 else
876 - gen_op_stl_T0_T1(dc); 910 + tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], mem_index);
877 } 911 }
878 912
879 static inline void t_gen_sext(TCGv d, TCGv s, int size) 913 static inline void t_gen_sext(TCGv d, TCGv s, int size)
@@ -995,9 +1029,7 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize) @@ -995,9 +1029,7 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
995 tcg_gen_movi_tl(cpu_T[1], imm); 1029 tcg_gen_movi_tl(cpu_T[1], imm);
996 dc->postinc = 0; 1030 dc->postinc = 0;
997 } else { 1031 } else {
998 - t_gen_mov_TN_reg(cpu_T[0], rs);  
999 - gen_load_T0_T0(dc, memsize, 0);  
1000 - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); 1032 + gen_load(dc, cpu_T[1], cpu_R[rs], memsize, 0);
1001 if (s_ext) 1033 if (s_ext)
1002 t_gen_sext(cpu_T[1], cpu_T[1], memsize); 1034 t_gen_sext(cpu_T[1], cpu_T[1], memsize);
1003 else 1035 else
@@ -1021,6 +1053,8 @@ static const char *cc_name(int cc) @@ -1021,6 +1053,8 @@ static const char *cc_name(int cc)
1021 } 1053 }
1022 #endif 1054 #endif
1023 1055
  1056 +/* Start of insn decoders. */
  1057 +
1024 static unsigned int dec_bccq(DisasContext *dc) 1058 static unsigned int dec_bccq(DisasContext *dc)
1025 { 1059 {
1026 int32_t offset; 1060 int32_t offset;
@@ -1043,7 +1077,7 @@ static unsigned int dec_bccq(DisasContext *dc) @@ -1043,7 +1077,7 @@ static unsigned int dec_bccq(DisasContext *dc)
1043 } 1077 }
1044 static unsigned int dec_addoq(DisasContext *dc) 1078 static unsigned int dec_addoq(DisasContext *dc)
1045 { 1079 {
1046 - uint32_t imm; 1080 + int32_t imm;
1047 1081
1048 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7); 1082 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1049 imm = sign_extend(dc->op1, 7); 1083 imm = sign_extend(dc->op1, 7);
@@ -1051,9 +1085,7 @@ static unsigned int dec_addoq(DisasContext *dc) @@ -1051,9 +1085,7 @@ static unsigned int dec_addoq(DisasContext *dc)
1051 DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2)); 1085 DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
1052 cris_cc_mask(dc, 0); 1086 cris_cc_mask(dc, 0);
1053 /* Fetch register operand, */ 1087 /* Fetch register operand, */
1054 - t_gen_mov_TN_reg(cpu_T[0], dc->op2);  
1055 - tcg_gen_movi_tl(cpu_T[1], imm);  
1056 - crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4); 1088 + tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
1057 return 2; 1089 return 2;
1058 } 1090 }
1059 static unsigned int dec_addq(DisasContext *dc) 1091 static unsigned int dec_addq(DisasContext *dc)
@@ -1140,7 +1172,7 @@ static unsigned int dec_btstq(DisasContext *dc) @@ -1140,7 +1172,7 @@ static unsigned int dec_btstq(DisasContext *dc)
1140 t_gen_mov_TN_im(cpu_T[1], dc->op1); 1172 t_gen_mov_TN_im(cpu_T[1], dc->op1);
1141 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); 1173 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1142 1174
1143 - cris_update_cc_op(dc, CC_OP_FLAGS); 1175 + cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1144 t_gen_mov_preg_TN(PR_CCS, cpu_T[0]); 1176 t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1145 dc->flags_live = 1; 1177 dc->flags_live = 1;
1146 return 2; 1178 return 2;
@@ -1461,11 +1493,11 @@ static unsigned int dec_addi_r(DisasContext *dc) @@ -1461,11 +1493,11 @@ static unsigned int dec_addi_r(DisasContext *dc)
1461 static unsigned int dec_addi_acr(DisasContext *dc) 1493 static unsigned int dec_addi_acr(DisasContext *dc)
1462 { 1494 {
1463 DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n", 1495 DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
1464 - memsize_char(memsize_zz(dc)), dc->op2, dc->op1)); 1496 + memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
1465 cris_cc_mask(dc, 0); 1497 cris_cc_mask(dc, 0);
1466 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); 1498 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1467 t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize)); 1499 t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1468 - 1500 +
1469 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); 1501 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1470 t_gen_mov_reg_TN(R_ACR, cpu_T[0]); 1502 t_gen_mov_reg_TN(R_ACR, cpu_T[0]);
1471 return 2; 1503 return 2;
@@ -1490,7 +1522,7 @@ static unsigned int dec_btst_r(DisasContext *dc) @@ -1490,7 +1522,7 @@ static unsigned int dec_btst_r(DisasContext *dc)
1490 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); 1522 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1491 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); 1523 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1492 1524
1493 - cris_update_cc_op(dc, CC_OP_FLAGS); 1525 + cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1494 t_gen_mov_preg_TN(PR_CCS, cpu_T[0]); 1526 t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1495 dc->flags_live = 1; 1527 dc->flags_live = 1;
1496 return 2; 1528 return 2;
@@ -1630,12 +1662,15 @@ static unsigned int dec_setclrf(DisasContext *dc) @@ -1630,12 +1662,15 @@ static unsigned int dec_setclrf(DisasContext *dc)
1630 1662
1631 /* Simply decode the flags. */ 1663 /* Simply decode the flags. */
1632 cris_evaluate_flags (dc); 1664 cris_evaluate_flags (dc);
1633 - cris_update_cc_op(dc, CC_OP_FLAGS); 1665 + cris_update_cc_op(dc, CC_OP_FLAGS, 4);
  1666 + tcg_gen_movi_tl(cc_op, dc->cc_op);
  1667 +
1634 if (set) 1668 if (set)
1635 gen_op_setf(flags); 1669 gen_op_setf(flags);
1636 else 1670 else
1637 gen_op_clrf(flags); 1671 gen_op_clrf(flags);
1638 dc->flags_live = 1; 1672 dc->flags_live = 1;
  1673 + dc->clear_x = 0;
1639 return 2; 1674 return 2;
1640 } 1675 }
1641 1676
@@ -1669,8 +1704,25 @@ static unsigned int dec_move_rp(DisasContext *dc) @@ -1669,8 +1704,25 @@ static unsigned int dec_move_rp(DisasContext *dc)
1669 { 1704 {
1670 DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2)); 1705 DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1671 cris_cc_mask(dc, 0); 1706 cris_cc_mask(dc, 0);
1672 - t_gen_mov_TN_reg(cpu_T[0], dc->op1); 1707 +
  1708 + if (dc->op2 == PR_CCS) {
  1709 + cris_evaluate_flags(dc);
  1710 + t_gen_mov_TN_reg(cpu_T[0], dc->op1);
  1711 + if (dc->user) {
  1712 + /* User space is not allowed to touch all flags. */
  1713 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x39f);
  1714 + tcg_gen_andi_tl(cpu_T[1], cpu_PR[PR_CCS], ~0x39f);
  1715 + tcg_gen_or_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
  1716 + }
  1717 + }
  1718 + else
  1719 + t_gen_mov_TN_reg(cpu_T[0], dc->op1);
  1720 +
1673 t_gen_mov_preg_TN(dc->op2, cpu_T[0]); 1721 t_gen_mov_preg_TN(dc->op2, cpu_T[0]);
  1722 + if (dc->op2 == PR_CCS) {
  1723 + cris_update_cc_op(dc, CC_OP_FLAGS, 4);
  1724 + dc->flags_live = 1;
  1725 + }
1674 return 2; 1726 return 2;
1675 } 1727 }
1676 static unsigned int dec_move_pr(DisasContext *dc) 1728 static unsigned int dec_move_pr(DisasContext *dc)
@@ -1681,7 +1733,10 @@ static unsigned int dec_move_pr(DisasContext *dc) @@ -1681,7 +1733,10 @@ static unsigned int dec_move_pr(DisasContext *dc)
1681 Treat it specially. */ 1733 Treat it specially. */
1682 if (dc->op2 == 0) 1734 if (dc->op2 == 0)
1683 tcg_gen_movi_tl(cpu_T[1], 0); 1735 tcg_gen_movi_tl(cpu_T[1], 0);
1684 - else 1736 + else if (dc->op2 == PR_CCS) {
  1737 + cris_evaluate_flags(dc);
  1738 + t_gen_mov_TN_preg(cpu_T[1], dc->op2);
  1739 + } else
1685 t_gen_mov_TN_preg(cpu_T[1], dc->op2); 1740 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1686 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]); 1741 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1687 return 2; 1742 return 2;
@@ -1696,8 +1751,8 @@ static unsigned int dec_move_mr(DisasContext *dc) @@ -1696,8 +1751,8 @@ static unsigned int dec_move_mr(DisasContext *dc)
1696 dc->op1, dc->postinc ? "+]" : "]", 1751 dc->op1, dc->postinc ? "+]" : "]",
1697 dc->op2)); 1752 dc->op2));
1698 1753
1699 - cris_cc_mask(dc, CC_MASK_NZ);  
1700 insn_len = dec_prep_alu_m(dc, 0, memsize); 1754 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1755 + cris_cc_mask(dc, CC_MASK_NZ);
1701 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize); 1756 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1702 do_postinc(dc, memsize); 1757 do_postinc(dc, memsize);
1703 return insn_len; 1758 return insn_len;
@@ -1713,8 +1768,8 @@ static unsigned int dec_movs_m(DisasContext *dc) @@ -1713,8 +1768,8 @@ static unsigned int dec_movs_m(DisasContext *dc)
1713 dc->op2)); 1768 dc->op2));
1714 1769
1715 /* sign extend. */ 1770 /* sign extend. */
1716 - cris_cc_mask(dc, CC_MASK_NZ);  
1717 insn_len = dec_prep_alu_m(dc, 1, memsize); 1771 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1772 + cris_cc_mask(dc, CC_MASK_NZ);
1718 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); 1773 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1719 do_postinc(dc, memsize); 1774 do_postinc(dc, memsize);
1720 return insn_len; 1775 return insn_len;
@@ -1730,8 +1785,8 @@ static unsigned int dec_addu_m(DisasContext *dc) @@ -1730,8 +1785,8 @@ static unsigned int dec_addu_m(DisasContext *dc)
1730 dc->op2)); 1785 dc->op2));
1731 1786
1732 /* sign extend. */ 1787 /* sign extend. */
1733 - cris_cc_mask(dc, CC_MASK_NZVC);  
1734 insn_len = dec_prep_alu_m(dc, 0, memsize); 1788 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1789 + cris_cc_mask(dc, CC_MASK_NZVC);
1735 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); 1790 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1736 do_postinc(dc, memsize); 1791 do_postinc(dc, memsize);
1737 return insn_len; 1792 return insn_len;
@@ -1747,8 +1802,8 @@ static unsigned int dec_adds_m(DisasContext *dc) @@ -1747,8 +1802,8 @@ static unsigned int dec_adds_m(DisasContext *dc)
1747 dc->op2)); 1802 dc->op2));
1748 1803
1749 /* sign extend. */ 1804 /* sign extend. */
1750 - cris_cc_mask(dc, CC_MASK_NZVC);  
1751 insn_len = dec_prep_alu_m(dc, 1, memsize); 1805 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1806 + cris_cc_mask(dc, CC_MASK_NZVC);
1752 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4); 1807 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1753 do_postinc(dc, memsize); 1808 do_postinc(dc, memsize);
1754 return insn_len; 1809 return insn_len;
@@ -1764,8 +1819,8 @@ static unsigned int dec_subu_m(DisasContext *dc) @@ -1764,8 +1819,8 @@ static unsigned int dec_subu_m(DisasContext *dc)
1764 dc->op2)); 1819 dc->op2));
1765 1820
1766 /* sign extend. */ 1821 /* sign extend. */
1767 - cris_cc_mask(dc, CC_MASK_NZVC);  
1768 insn_len = dec_prep_alu_m(dc, 0, memsize); 1822 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1823 + cris_cc_mask(dc, CC_MASK_NZVC);
1769 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); 1824 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1770 do_postinc(dc, memsize); 1825 do_postinc(dc, memsize);
1771 return insn_len; 1826 return insn_len;
@@ -1781,8 +1836,8 @@ static unsigned int dec_subs_m(DisasContext *dc) @@ -1781,8 +1836,8 @@ static unsigned int dec_subs_m(DisasContext *dc)
1781 dc->op2)); 1836 dc->op2));
1782 1837
1783 /* sign extend. */ 1838 /* sign extend. */
1784 - cris_cc_mask(dc, CC_MASK_NZVC);  
1785 insn_len = dec_prep_alu_m(dc, 1, memsize); 1839 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1840 + cris_cc_mask(dc, CC_MASK_NZVC);
1786 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); 1841 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1787 do_postinc(dc, memsize); 1842 do_postinc(dc, memsize);
1788 return insn_len; 1843 return insn_len;
@@ -1798,8 +1853,8 @@ static unsigned int dec_movu_m(DisasContext *dc) @@ -1798,8 +1853,8 @@ static unsigned int dec_movu_m(DisasContext *dc)
1798 dc->op1, dc->postinc ? "+]" : "]", 1853 dc->op1, dc->postinc ? "+]" : "]",
1799 dc->op2)); 1854 dc->op2));
1800 1855
1801 - cris_cc_mask(dc, CC_MASK_NZ);  
1802 insn_len = dec_prep_alu_m(dc, 0, memsize); 1856 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1857 + cris_cc_mask(dc, CC_MASK_NZ);
1803 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4); 1858 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1804 do_postinc(dc, memsize); 1859 do_postinc(dc, memsize);
1805 return insn_len; 1860 return insn_len;
@@ -1814,8 +1869,8 @@ static unsigned int dec_cmpu_m(DisasContext *dc) @@ -1814,8 +1869,8 @@ static unsigned int dec_cmpu_m(DisasContext *dc)
1814 dc->op1, dc->postinc ? "+]" : "]", 1869 dc->op1, dc->postinc ? "+]" : "]",
1815 dc->op2)); 1870 dc->op2));
1816 1871
1817 - cris_cc_mask(dc, CC_MASK_NZVC);  
1818 insn_len = dec_prep_alu_m(dc, 0, memsize); 1872 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1873 + cris_cc_mask(dc, CC_MASK_NZVC);
1819 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4); 1874 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1820 do_postinc(dc, memsize); 1875 do_postinc(dc, memsize);
1821 return insn_len; 1876 return insn_len;
@@ -1830,8 +1885,8 @@ static unsigned int dec_cmps_m(DisasContext *dc) @@ -1830,8 +1885,8 @@ static unsigned int dec_cmps_m(DisasContext *dc)
1830 dc->op1, dc->postinc ? "+]" : "]", 1885 dc->op1, dc->postinc ? "+]" : "]",
1831 dc->op2)); 1886 dc->op2));
1832 1887
1833 - cris_cc_mask(dc, CC_MASK_NZVC);  
1834 insn_len = dec_prep_alu_m(dc, 1, memsize); 1888 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1889 + cris_cc_mask(dc, CC_MASK_NZVC);
1835 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc)); 1890 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1836 do_postinc(dc, memsize); 1891 do_postinc(dc, memsize);
1837 return insn_len; 1892 return insn_len;
@@ -1846,8 +1901,8 @@ static unsigned int dec_cmp_m(DisasContext *dc) @@ -1846,8 +1901,8 @@ static unsigned int dec_cmp_m(DisasContext *dc)
1846 dc->op1, dc->postinc ? "+]" : "]", 1901 dc->op1, dc->postinc ? "+]" : "]",
1847 dc->op2)); 1902 dc->op2));
1848 1903
1849 - cris_cc_mask(dc, CC_MASK_NZVC);  
1850 insn_len = dec_prep_alu_m(dc, 0, memsize); 1904 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1905 + cris_cc_mask(dc, CC_MASK_NZVC);
1851 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc)); 1906 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1852 do_postinc(dc, memsize); 1907 do_postinc(dc, memsize);
1853 return insn_len; 1908 return insn_len;
@@ -1862,9 +1917,10 @@ static unsigned int dec_test_m(DisasContext *dc) @@ -1862,9 +1917,10 @@ static unsigned int dec_test_m(DisasContext *dc)
1862 dc->op1, dc->postinc ? "+]" : "]", 1917 dc->op1, dc->postinc ? "+]" : "]",
1863 dc->op2)); 1918 dc->op2));
1864 1919
  1920 + insn_len = dec_prep_alu_m(dc, 0, memsize);
1865 cris_cc_mask(dc, CC_MASK_NZ); 1921 cris_cc_mask(dc, CC_MASK_NZ);
1866 gen_op_clrf(3); 1922 gen_op_clrf(3);
1867 - insn_len = dec_prep_alu_m(dc, 0, memsize); 1923 +
1868 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); 1924 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1869 tcg_gen_movi_tl(cpu_T[1], 0); 1925 tcg_gen_movi_tl(cpu_T[1], 0);
1870 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc)); 1926 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
@@ -1881,8 +1937,8 @@ static unsigned int dec_and_m(DisasContext *dc) @@ -1881,8 +1937,8 @@ static unsigned int dec_and_m(DisasContext *dc)
1881 dc->op1, dc->postinc ? "+]" : "]", 1937 dc->op1, dc->postinc ? "+]" : "]",
1882 dc->op2)); 1938 dc->op2));
1883 1939
1884 - cris_cc_mask(dc, CC_MASK_NZ);  
1885 insn_len = dec_prep_alu_m(dc, 0, memsize); 1940 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1941 + cris_cc_mask(dc, CC_MASK_NZ);
1886 crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc)); 1942 crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1887 do_postinc(dc, memsize); 1943 do_postinc(dc, memsize);
1888 return insn_len; 1944 return insn_len;
@@ -1897,8 +1953,8 @@ static unsigned int dec_add_m(DisasContext *dc) @@ -1897,8 +1953,8 @@ static unsigned int dec_add_m(DisasContext *dc)
1897 dc->op1, dc->postinc ? "+]" : "]", 1953 dc->op1, dc->postinc ? "+]" : "]",
1898 dc->op2)); 1954 dc->op2));
1899 1955
1900 - cris_cc_mask(dc, CC_MASK_NZVC);  
1901 insn_len = dec_prep_alu_m(dc, 0, memsize); 1956 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1957 + cris_cc_mask(dc, CC_MASK_NZVC);
1902 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc)); 1958 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1903 do_postinc(dc, memsize); 1959 do_postinc(dc, memsize);
1904 return insn_len; 1960 return insn_len;
@@ -1913,8 +1969,8 @@ static unsigned int dec_addo_m(DisasContext *dc) @@ -1913,8 +1969,8 @@ static unsigned int dec_addo_m(DisasContext *dc)
1913 dc->op1, dc->postinc ? "+]" : "]", 1969 dc->op1, dc->postinc ? "+]" : "]",
1914 dc->op2)); 1970 dc->op2));
1915 1971
1916 - cris_cc_mask(dc, 0);  
1917 insn_len = dec_prep_alu_m(dc, 1, memsize); 1972 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1973 + cris_cc_mask(dc, 0);
1918 crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4); 1974 crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
1919 do_postinc(dc, memsize); 1975 do_postinc(dc, memsize);
1920 return insn_len; 1976 return insn_len;
@@ -1929,8 +1985,8 @@ static unsigned int dec_bound_m(DisasContext *dc) @@ -1929,8 +1985,8 @@ static unsigned int dec_bound_m(DisasContext *dc)
1929 dc->op1, dc->postinc ? "+]" : "]", 1985 dc->op1, dc->postinc ? "+]" : "]",
1930 dc->op2)); 1986 dc->op2));
1931 1987
1932 - cris_cc_mask(dc, CC_MASK_NZ);  
1933 insn_len = dec_prep_alu_m(dc, 0, memsize); 1988 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1989 + cris_cc_mask(dc, CC_MASK_NZ);
1934 crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4); 1990 crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1935 do_postinc(dc, memsize); 1991 do_postinc(dc, memsize);
1936 return insn_len; 1992 return insn_len;
@@ -1944,8 +2000,8 @@ static unsigned int dec_addc_mr(DisasContext *dc) @@ -1944,8 +2000,8 @@ static unsigned int dec_addc_mr(DisasContext *dc)
1944 dc->op2)); 2000 dc->op2));
1945 2001
1946 cris_evaluate_flags(dc); 2002 cris_evaluate_flags(dc);
1947 - cris_cc_mask(dc, CC_MASK_NZVC);  
1948 insn_len = dec_prep_alu_m(dc, 0, 4); 2003 insn_len = dec_prep_alu_m(dc, 0, 4);
  2004 + cris_cc_mask(dc, CC_MASK_NZVC);
1949 crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4); 2005 crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1950 do_postinc(dc, 4); 2006 do_postinc(dc, 4);
1951 return insn_len; 2007 return insn_len;
@@ -1960,8 +2016,8 @@ static unsigned int dec_sub_m(DisasContext *dc) @@ -1960,8 +2016,8 @@ static unsigned int dec_sub_m(DisasContext *dc)
1960 dc->op1, dc->postinc ? "+]" : "]", 2016 dc->op1, dc->postinc ? "+]" : "]",
1961 dc->op2, dc->ir, dc->zzsize)); 2017 dc->op2, dc->ir, dc->zzsize));
1962 2018
1963 - cris_cc_mask(dc, CC_MASK_NZVC);  
1964 insn_len = dec_prep_alu_m(dc, 0, memsize); 2019 insn_len = dec_prep_alu_m(dc, 0, memsize);
  2020 + cris_cc_mask(dc, CC_MASK_NZVC);
1965 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize); 2021 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1966 do_postinc(dc, memsize); 2022 do_postinc(dc, memsize);
1967 return insn_len; 2023 return insn_len;
@@ -1976,8 +2032,8 @@ static unsigned int dec_or_m(DisasContext *dc) @@ -1976,8 +2032,8 @@ static unsigned int dec_or_m(DisasContext *dc)
1976 dc->op1, dc->postinc ? "+]" : "]", 2032 dc->op1, dc->postinc ? "+]" : "]",
1977 dc->op2, dc->pc)); 2033 dc->op2, dc->pc));
1978 2034
1979 - cris_cc_mask(dc, CC_MASK_NZ);  
1980 insn_len = dec_prep_alu_m(dc, 0, memsize); 2035 insn_len = dec_prep_alu_m(dc, 0, memsize);
  2036 + cris_cc_mask(dc, CC_MASK_NZ);
1981 crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc)); 2037 crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1982 do_postinc(dc, memsize); 2038 do_postinc(dc, memsize);
1983 return insn_len; 2039 return insn_len;
@@ -1994,8 +2050,18 @@ static unsigned int dec_move_mp(DisasContext *dc) @@ -1994,8 +2050,18 @@ static unsigned int dec_move_mp(DisasContext *dc)
1994 dc->postinc ? "+]" : "]", 2050 dc->postinc ? "+]" : "]",
1995 dc->op2)); 2051 dc->op2));
1996 2052
1997 - cris_cc_mask(dc, 0);  
1998 insn_len = dec_prep_alu_m(dc, 0, memsize); 2053 insn_len = dec_prep_alu_m(dc, 0, memsize);
  2054 + cris_cc_mask(dc, 0);
  2055 + if (dc->op2 == PR_CCS) {
  2056 + cris_evaluate_flags(dc);
  2057 + if (dc->user) {
  2058 + /* User space is not allowed to touch all flags. */
  2059 + tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 0x39f);
  2060 + tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], ~0x39f);
  2061 + tcg_gen_or_tl(cpu_T[1], cpu_T[0], cpu_T[1]);
  2062 + }
  2063 + }
  2064 +
1999 t_gen_mov_preg_TN(dc->op2, cpu_T[1]); 2065 t_gen_mov_preg_TN(dc->op2, cpu_T[1]);
2000 2066
2001 do_postinc(dc, memsize); 2067 do_postinc(dc, memsize);
@@ -2012,11 +2078,11 @@ static unsigned int dec_move_pm(DisasContext *dc) @@ -2012,11 +2078,11 @@ static unsigned int dec_move_pm(DisasContext *dc)
2012 memsize_char(memsize), 2078 memsize_char(memsize),
2013 dc->op2, dc->op1, dc->postinc ? "+]" : "]")); 2079 dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
2014 2080
2015 - cris_cc_mask(dc, 0);  
2016 /* prepare store. Address in T0, value in T1. */ 2081 /* prepare store. Address in T0, value in T1. */
2017 t_gen_mov_TN_preg(cpu_T[1], dc->op2); 2082 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
2018 t_gen_mov_TN_reg(cpu_T[0], dc->op1); 2083 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2019 gen_store_T0_T1(dc, memsize); 2084 gen_store_T0_T1(dc, memsize);
  2085 + cris_cc_mask(dc, 0);
2020 if (dc->postinc) 2086 if (dc->postinc)
2021 { 2087 {
2022 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize); 2088 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
@@ -2032,19 +2098,20 @@ static unsigned int dec_movem_mr(DisasContext *dc) @@ -2032,19 +2098,20 @@ static unsigned int dec_movem_mr(DisasContext *dc)
2032 DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1, 2098 DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
2033 dc->postinc ? "+]" : "]", dc->op2)); 2099 dc->postinc ? "+]" : "]", dc->op2));
2034 2100
2035 - cris_cc_mask(dc, 0);  
2036 /* fetch the address into T0 and T1. */ 2101 /* fetch the address into T0 and T1. */
2037 t_gen_mov_TN_reg(cpu_T[1], dc->op1); 2102 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
2038 for (i = 0; i <= dc->op2; i++) { 2103 for (i = 0; i <= dc->op2; i++) {
2039 /* Perform the load onto regnum i. Always dword wide. */ 2104 /* Perform the load onto regnum i. Always dword wide. */
2040 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); 2105 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
2041 - gen_load_T0_T0(dc, 4, 0);  
2042 - t_gen_mov_reg_TN(i, cpu_T[0]); 2106 + gen_load(dc, cpu_R[i], cpu_T[1], 4, 0);
2043 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4); 2107 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4);
2044 } 2108 }
2045 /* writeback the updated pointer value. */ 2109 /* writeback the updated pointer value. */
2046 if (dc->postinc) 2110 if (dc->postinc)
2047 t_gen_mov_reg_TN(dc->op1, cpu_T[1]); 2111 t_gen_mov_reg_TN(dc->op1, cpu_T[1]);
  2112 +
  2113 + /* gen_load might want to evaluate the previous insns flags. */
  2114 + cris_cc_mask(dc, 0);
2048 return 2; 2115 return 2;
2049 } 2116 }
2050 2117
@@ -2055,7 +2122,6 @@ static unsigned int dec_movem_rm(DisasContext *dc) @@ -2055,7 +2122,6 @@ static unsigned int dec_movem_rm(DisasContext *dc)
2055 DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1, 2122 DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2056 dc->postinc ? "+]" : "]")); 2123 dc->postinc ? "+]" : "]"));
2057 2124
2058 - cris_cc_mask(dc, 0);  
2059 for (i = 0; i <= dc->op2; i++) { 2125 for (i = 0; i <= dc->op2; i++) {
2060 /* Fetch register i into T1. */ 2126 /* Fetch register i into T1. */
2061 t_gen_mov_TN_reg(cpu_T[1], i); 2127 t_gen_mov_TN_reg(cpu_T[1], i);
@@ -2073,6 +2139,7 @@ static unsigned int dec_movem_rm(DisasContext *dc) @@ -2073,6 +2139,7 @@ static unsigned int dec_movem_rm(DisasContext *dc)
2073 /* writeback the updated pointer value. */ 2139 /* writeback the updated pointer value. */
2074 t_gen_mov_reg_TN(dc->op1, cpu_T[0]); 2140 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2075 } 2141 }
  2142 + cris_cc_mask(dc, 0);
2076 return 2; 2143 return 2;
2077 } 2144 }
2078 2145
@@ -2085,7 +2152,6 @@ static unsigned int dec_move_rm(DisasContext *dc) @@ -2085,7 +2152,6 @@ static unsigned int dec_move_rm(DisasContext *dc)
2085 DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n", 2152 DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
2086 memsize, dc->op2, dc->op1)); 2153 memsize, dc->op2, dc->op1));
2087 2154
2088 - cris_cc_mask(dc, 0);  
2089 /* prepare store. */ 2155 /* prepare store. */
2090 t_gen_mov_TN_reg(cpu_T[0], dc->op1); 2156 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2091 t_gen_mov_TN_reg(cpu_T[1], dc->op2); 2157 t_gen_mov_TN_reg(cpu_T[1], dc->op2);
@@ -2095,6 +2161,7 @@ static unsigned int dec_move_rm(DisasContext *dc) @@ -2095,6 +2161,7 @@ static unsigned int dec_move_rm(DisasContext *dc)
2095 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize); 2161 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2096 t_gen_mov_reg_TN(dc->op1, cpu_T[0]); 2162 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2097 } 2163 }
  2164 + cris_cc_mask(dc, 0);
2098 return 2; 2165 return 2;
2099 } 2166 }
2100 2167
@@ -2112,13 +2179,17 @@ static unsigned int dec_lapc_im(DisasContext *dc) @@ -2112,13 +2179,17 @@ static unsigned int dec_lapc_im(DisasContext *dc)
2112 { 2179 {
2113 unsigned int rd; 2180 unsigned int rd;
2114 int32_t imm; 2181 int32_t imm;
  2182 + int32_t pc;
2115 2183
2116 rd = dc->op2; 2184 rd = dc->op2;
2117 2185
2118 cris_cc_mask(dc, 0); 2186 cris_cc_mask(dc, 0);
2119 imm = ldl_code(dc->pc + 2); 2187 imm = ldl_code(dc->pc + 2);
2120 DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2)); 2188 DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2));
2121 - t_gen_mov_reg_TN(rd, tcg_const_tl(dc->pc + imm)); 2189 +
  2190 + pc = dc->pc;
  2191 + pc += imm;
  2192 + t_gen_mov_reg_TN(rd, tcg_const_tl(pc));
2122 return 6; 2193 return 6;
2123 } 2194 }
2124 2195
@@ -2127,9 +2198,10 @@ static unsigned int dec_jump_p(DisasContext *dc) @@ -2127,9 +2198,10 @@ static unsigned int dec_jump_p(DisasContext *dc)
2127 { 2198 {
2128 DIS(fprintf (logfile, "jump $p%u\n", dc->op2)); 2199 DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
2129 cris_cc_mask(dc, 0); 2200 cris_cc_mask(dc, 0);
2130 - /* Store the return address in Pd. */ 2201 +
2131 t_gen_mov_TN_preg(cpu_T[0], dc->op2); 2202 t_gen_mov_TN_preg(cpu_T[0], dc->op2);
2132 - t_gen_mov_env_TN(btarget, cpu_T[0]); 2203 + /* rete will often have low bit set to indicate delayslot. */
  2204 + tcg_gen_andi_tl(env_btarget, cpu_T[0], ~1);
2133 cris_prepare_dyn_jmp(dc); 2205 cris_prepare_dyn_jmp(dc);
2134 return 2; 2206 return 2;
2135 } 2207 }
@@ -2139,11 +2211,12 @@ static unsigned int dec_jas_r(DisasContext *dc) @@ -2139,11 +2211,12 @@ static unsigned int dec_jas_r(DisasContext *dc)
2139 { 2211 {
2140 DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2)); 2212 DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
2141 cris_cc_mask(dc, 0); 2213 cris_cc_mask(dc, 0);
2142 - /* Stor the return address in Pd. */  
2143 - t_gen_mov_TN_reg(cpu_T[0], dc->op1);  
2144 - t_gen_mov_env_TN(btarget, cpu_T[0]);  
2145 - tcg_gen_movi_tl(cpu_T[0], dc->pc + 4);  
2146 - t_gen_mov_preg_TN(dc->op2, cpu_T[0]); 2214 + /* Store the return address in Pd. */
  2215 + tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
  2216 + if (dc->op2 > 15)
  2217 + abort();
  2218 + tcg_gen_movi_tl(cpu_PR[dc->op2], dc->pc + 4);
  2219 +
2147 cris_prepare_dyn_jmp(dc); 2220 cris_prepare_dyn_jmp(dc);
2148 return 2; 2221 return 2;
2149 } 2222 }
@@ -2157,7 +2230,7 @@ static unsigned int dec_jas_im(DisasContext *dc) @@ -2157,7 +2230,7 @@ static unsigned int dec_jas_im(DisasContext *dc)
2157 DIS(fprintf (logfile, "jas 0x%x\n", imm)); 2230 DIS(fprintf (logfile, "jas 0x%x\n", imm));
2158 cris_cc_mask(dc, 0); 2231 cris_cc_mask(dc, 0);
2159 /* Stor the return address in Pd. */ 2232 /* Stor the return address in Pd. */
2160 - t_gen_mov_env_TN(btarget, tcg_const_tl(imm)); 2233 + tcg_gen_movi_tl(env_btarget, imm);
2161 t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8)); 2234 t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8));
2162 cris_prepare_dyn_jmp(dc); 2235 cris_prepare_dyn_jmp(dc);
2163 return 6; 2236 return 6;
@@ -2260,6 +2333,11 @@ static unsigned int dec_rfe_etc(DisasContext *dc) @@ -2260,6 +2333,11 @@ static unsigned int dec_rfe_etc(DisasContext *dc)
2260 /* rfe. */ 2333 /* rfe. */
2261 cris_evaluate_flags(dc); 2334 cris_evaluate_flags(dc);
2262 gen_op_ccs_rshift(); 2335 gen_op_ccs_rshift();
  2336 + /* FIXME: don't set the P-FLAG if R is set. */
  2337 + tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], P_FLAG);
  2338 + /* Debug helper. */
  2339 + tcg_gen_helper_0_0(helper_rfe);
  2340 + dc->is_jmp = DISAS_UPDATE;
2263 break; 2341 break;
2264 case 5: 2342 case 5:
2265 /* rfn. */ 2343 /* rfn. */
@@ -2271,7 +2349,7 @@ static unsigned int dec_rfe_etc(DisasContext *dc) @@ -2271,7 +2349,7 @@ static unsigned int dec_rfe_etc(DisasContext *dc)
2271 t_gen_mov_env_TN(pc, cpu_T[0]); 2349 t_gen_mov_env_TN(pc, cpu_T[0]);
2272 /* Breaks start at 16 in the exception vector. */ 2350 /* Breaks start at 16 in the exception vector. */
2273 gen_op_break_im(dc->op1 + 16); 2351 gen_op_break_im(dc->op1 + 16);
2274 - dc->is_jmp = DISAS_SWI; 2352 + dc->is_jmp = DISAS_UPDATE;
2275 break; 2353 break;
2276 default: 2354 default:
2277 printf ("op2=%x\n", dc->op2); 2355 printf ("op2=%x\n", dc->op2);
@@ -2477,6 +2555,9 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2477,6 +2555,9 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2477 if (!logfile) 2555 if (!logfile)
2478 logfile = stderr; 2556 logfile = stderr;
2479 2557
  2558 + if (tb->pc & 1)
  2559 + cpu_abort(env, "unaligned pc=%x erp=%x\n",
  2560 + env->pc, env->pregs[PR_ERP]);
2480 pc_start = tb->pc; 2561 pc_start = tb->pc;
2481 dc->env = env; 2562 dc->env = env;
2482 dc->tb = tb; 2563 dc->tb = tb;
@@ -2484,10 +2565,35 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2484,10 +2565,35 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2484 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; 2565 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2485 2566
2486 dc->is_jmp = DISAS_NEXT; 2567 dc->is_jmp = DISAS_NEXT;
  2568 + dc->ppc = pc_start;
2487 dc->pc = pc_start; 2569 dc->pc = pc_start;
2488 dc->singlestep_enabled = env->singlestep_enabled; 2570 dc->singlestep_enabled = env->singlestep_enabled;
  2571 + dc->flags_live = 1;
2489 dc->flagx_live = 0; 2572 dc->flagx_live = 0;
2490 dc->flags_x = 0; 2573 dc->flags_x = 0;
  2574 + dc->cc_mask = 0;
  2575 + cris_update_cc_op(dc, CC_OP_FLAGS, 4);
  2576 +
  2577 + dc->user = env->pregs[PR_CCS] & U_FLAG;
  2578 + dc->delayed_branch = 0;
  2579 +
  2580 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  2581 + fprintf(logfile,
  2582 + "search=%d pc=%x ccs=%x pid=%x usp=%x\n"
  2583 + "%x.%x.%x.%x\n"
  2584 + "%x.%x.%x.%x\n"
  2585 + "%x.%x.%x.%x\n"
  2586 + "%x.%x.%x.%x\n",
  2587 + search_pc, env->pc, env->pregs[PR_CCS],
  2588 + env->pregs[PR_PID], env->pregs[PR_USP],
  2589 + env->regs[0], env->regs[1], env->regs[2], env->regs[3],
  2590 + env->regs[4], env->regs[5], env->regs[6], env->regs[7],
  2591 + env->regs[8], env->regs[9],
  2592 + env->regs[10], env->regs[11],
  2593 + env->regs[12], env->regs[13],
  2594 + env->regs[14], env->regs[15]);
  2595 +
  2596 + }
2491 2597
2492 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 2598 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2493 lj = -1; 2599 lj = -1;
@@ -2505,14 +2611,23 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2505,14 +2611,23 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2505 while (lj < j) 2611 while (lj < j)
2506 gen_opc_instr_start[lj++] = 0; 2612 gen_opc_instr_start[lj++] = 0;
2507 } 2613 }
2508 - gen_opc_pc[lj] = dc->pc;  
2509 - gen_opc_instr_start[lj] = 1; 2614 + if (dc->delayed_branch == 1) {
  2615 + gen_opc_pc[lj] = dc->ppc | 1;
  2616 + gen_opc_instr_start[lj] = 0;
  2617 + }
  2618 + else {
  2619 + gen_opc_pc[lj] = dc->pc;
  2620 + gen_opc_instr_start[lj] = 1;
  2621 + }
2510 } 2622 }
2511 2623
  2624 + dc->clear_x = 1;
2512 insn_len = cris_decoder(dc); 2625 insn_len = cris_decoder(dc);
2513 STATS(gen_op_exec_insn()); 2626 STATS(gen_op_exec_insn());
  2627 + dc->ppc = dc->pc;
2514 dc->pc += insn_len; 2628 dc->pc += insn_len;
2515 - cris_clear_x_flag(dc); 2629 + if (dc->clear_x)
  2630 + cris_clear_x_flag(dc);
2516 2631
2517 /* Check for delayed branches here. If we do it before 2632 /* Check for delayed branches here. If we do it before
2518 actually genereating any host code, the simulator will just 2633 actually genereating any host code, the simulator will just
@@ -2523,12 +2638,12 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2523,12 +2638,12 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2523 { 2638 {
2524 if (dc->bcc == CC_A) { 2639 if (dc->bcc == CC_A) {
2525 gen_op_jmp1 (); 2640 gen_op_jmp1 ();
2526 - dc->is_jmp = DISAS_UPDATE; 2641 + dc->is_jmp = DISAS_JUMP;
2527 } 2642 }
2528 else { 2643 else {
2529 /* Conditional jmp. */ 2644 /* Conditional jmp. */
2530 gen_op_cc_jmp (dc->delayed_pc, dc->pc); 2645 gen_op_cc_jmp (dc->delayed_pc, dc->pc);
2531 - dc->is_jmp = DISAS_UPDATE; 2646 + dc->is_jmp = DISAS_JUMP;
2532 } 2647 }
2533 } 2648 }
2534 } 2649 }
@@ -2536,11 +2651,19 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2536,11 +2651,19 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2536 if (env->singlestep_enabled) 2651 if (env->singlestep_enabled)
2537 break; 2652 break;
2538 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end 2653 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2539 - && dc->pc < next_page_start); 2654 + && ((dc->pc < next_page_start) || dc->delayed_branch));
  2655 +
  2656 + if (dc->delayed_branch == 1) {
  2657 + /* Reexecute the last insn. */
  2658 + dc->pc = dc->ppc;
  2659 + }
2540 2660
2541 if (!dc->is_jmp) { 2661 if (!dc->is_jmp) {
  2662 + D(printf("!jmp pc=%x jmp=%d db=%d\n", dc->pc,
  2663 + dc->is_jmp, dc->delayed_branch));
  2664 + /* T0 and env_pc should hold the new pc. */
2542 tcg_gen_movi_tl(cpu_T[0], dc->pc); 2665 tcg_gen_movi_tl(cpu_T[0], dc->pc);
2543 - t_gen_mov_env_TN(pc, cpu_T[0]); 2666 + tcg_gen_mov_tl(env_pc, cpu_T[0]);
2544 } 2667 }
2545 2668
2546 cris_evaluate_flags (dc); 2669 cris_evaluate_flags (dc);
@@ -2580,7 +2703,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2580,7 +2703,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2580 fprintf(logfile, "--------------\n"); 2703 fprintf(logfile, "--------------\n");
2581 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); 2704 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2582 target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0); 2705 target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
2583 - fprintf(logfile, "\n"); 2706 + fprintf(logfile, "\nisize=%d osize=%d\n",
  2707 + dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
2584 } 2708 }
2585 #endif 2709 #endif
2586 return 0; 2710 return 0;
@@ -2626,7 +2750,7 @@ void cpu_dump_state (CPUState *env, FILE *f, @@ -2626,7 +2750,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
2626 cpu_fprintf(f, "\n"); 2750 cpu_fprintf(f, "\n");
2627 } 2751 }
2628 srs = env->pregs[PR_SRS]; 2752 srs = env->pregs[PR_SRS];
2629 - cpu_fprintf(f, "\nsupport function regs bank %d:\n", srs); 2753 + cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
2630 if (srs < 256) { 2754 if (srs < 256) {
2631 for (i = 0; i < 16; i++) { 2755 for (i = 0; i < 16; i++) {
2632 cpu_fprintf(f, "s%2.2d=%8.8x ", 2756 cpu_fprintf(f, "s%2.2d=%8.8x ",
@@ -2682,6 +2806,13 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) @@ -2682,6 +2806,13 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
2682 offsetof(CPUState, cc_mask), 2806 offsetof(CPUState, cc_mask),
2683 "cc_mask"); 2807 "cc_mask");
2684 2808
  2809 + env_pc = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
  2810 + offsetof(CPUState, pc),
  2811 + "pc");
  2812 + env_btarget = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
  2813 + offsetof(CPUState, btarget),
  2814 + "btarget");
  2815 +
2685 for (i = 0; i < 16; i++) { 2816 for (i = 0; i < 16; i++) {
2686 cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, 2817 cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
2687 offsetof(CPUState, regs[i]), 2818 offsetof(CPUState, regs[i]),
@@ -2693,6 +2824,21 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) @@ -2693,6 +2824,21 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
2693 pregnames[i]); 2824 pregnames[i]);
2694 } 2825 }
2695 2826
  2827 + TCG_HELPER(helper_tlb_update);
  2828 + TCG_HELPER(helper_tlb_flush);
  2829 + TCG_HELPER(helper_rfe);
  2830 + TCG_HELPER(helper_store);
  2831 + TCG_HELPER(helper_dump);
  2832 + TCG_HELPER(helper_dummy);
  2833 +
  2834 + TCG_HELPER(helper_evaluate_flags_muls);
  2835 + TCG_HELPER(helper_evaluate_flags_mulu);
  2836 + TCG_HELPER(helper_evaluate_flags_mcp);
  2837 + TCG_HELPER(helper_evaluate_flags_alu_4);
  2838 + TCG_HELPER(helper_evaluate_flags_move_4);
  2839 + TCG_HELPER(helper_evaluate_flags_move_2);
  2840 + TCG_HELPER(helper_evaluate_flags);
  2841 +
2696 cpu_reset(env); 2842 cpu_reset(env);
2697 return env; 2843 return env;
2698 } 2844 }
@@ -2701,10 +2847,17 @@ void cpu_reset (CPUCRISState *env) @@ -2701,10 +2847,17 @@ void cpu_reset (CPUCRISState *env)
2701 { 2847 {
2702 memset(env, 0, offsetof(CPUCRISState, breakpoints)); 2848 memset(env, 0, offsetof(CPUCRISState, breakpoints));
2703 tlb_flush(env, 1); 2849 tlb_flush(env, 1);
  2850 +
  2851 +#if defined(CONFIG_USER_ONLY)
  2852 + /* start in user mode with interrupts enabled. */
  2853 + env->pregs[PR_CCS] |= U_FLAG | I_FLAG;
  2854 +#else
  2855 + env->pregs[PR_CCS] = 0;
  2856 +#endif
2704 } 2857 }
2705 2858
2706 void gen_pc_load(CPUState *env, struct TranslationBlock *tb, 2859 void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
2707 unsigned long searched_pc, int pc_pos, void *puc) 2860 unsigned long searched_pc, int pc_pos, void *puc)
2708 { 2861 {
2709 - env->pregs[PR_ERP] = gen_opc_pc[pc_pos]; 2862 + env->pc = gen_opc_pc[pc_pos];
2710 } 2863 }