Commit cf1d97f07480b6197aebc489938b4e1fed78d3e7

Authored by edgar_igl
1 parent 3bd8c5e4

CRIS: Improve TLB management and handle delayslots at page boundaries.

* Dont flush the entire qemu tlb when the $pid changes. Instead we go through
  the guests TLB and choose entries that need to be flushed.
* Add env->dslot and handle delayslots at pageboundaries.
* Remove some unused code.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4450 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -261,6 +261,7 @@ static inline TranslationBlock *tb_find_fast(void) @@ -261,6 +261,7 @@ static inline TranslationBlock *tb_find_fast(void)
261 pc = env->pc; 261 pc = env->pc;
262 #elif defined(TARGET_CRIS) 262 #elif defined(TARGET_CRIS)
263 flags = env->pregs[PR_CCS] & U_FLAG; 263 flags = env->pregs[PR_CCS] & U_FLAG;
  264 + flags |= env->dslot;
264 cs_base = 0; 265 cs_base = 0;
265 pc = env->pc; 266 pc = env->pc;
266 #else 267 #else
target-cris/cpu.h
@@ -107,11 +107,10 @@ typedef struct CPUCRISState { @@ -107,11 +107,10 @@ typedef struct CPUCRISState {
107 /* Pseudo register for the kernel stack. */ 107 /* Pseudo register for the kernel stack. */
108 uint32_t ksp; 108 uint32_t ksp;
109 109
110 - /* These are setup up by the guest code just before transfering the  
111 - control back to the host. */  
112 - int jmp;  
113 - uint32_t btarget; 110 + /* Branch. */
  111 + int dslot;
114 int btaken; 112 int btaken;
  113 + uint32_t btarget;
115 114
116 /* Condition flag tracking. */ 115 /* Condition flag tracking. */
117 uint32_t cc_op; 116 uint32_t cc_op;
@@ -119,10 +118,8 @@ typedef struct CPUCRISState { @@ -119,10 +118,8 @@ typedef struct CPUCRISState {
119 uint32_t cc_dest; 118 uint32_t cc_dest;
120 uint32_t cc_src; 119 uint32_t cc_src;
121 uint32_t cc_result; 120 uint32_t cc_result;
122 -  
123 /* size of the operation, 1 = byte, 2 = word, 4 = dword. */ 121 /* size of the operation, 1 = byte, 2 = word, 4 = dword. */
124 int cc_size; 122 int cc_size;
125 -  
126 /* Extended arithmetics. */ 123 /* Extended arithmetics. */
127 int cc_x_live; 124 int cc_x_live;
128 int cc_x; 125 int cc_x;
@@ -137,13 +134,6 @@ typedef struct CPUCRISState { @@ -137,13 +134,6 @@ typedef struct CPUCRISState {
137 uint32_t debug2; 134 uint32_t debug2;
138 uint32_t debug3; 135 uint32_t debug3;
139 136
140 - struct  
141 - {  
142 - int exec_insns;  
143 - int exec_loads;  
144 - int exec_stores;  
145 - } stats;  
146 -  
147 /* FIXME: add a check in the translator to avoid writing to support 137 /* FIXME: add a check in the translator to avoid writing to support
148 register sets beyond the 4th. The ISA allows up to 256! but in 138 register sets beyond the 4th. The ISA allows up to 256! but in
149 practice there is no core that implements more than 4. 139 practice there is no core that implements more than 4.
target-cris/helper.c
@@ -97,9 +97,10 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -97,9 +97,10 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
97 r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu); 97 r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
98 } 98 }
99 if (r > 0) 99 if (r > 0)
100 - D(fprintf(logfile, "%s returns %d irqreq=%x addr=%x ismmu=%d vec=%x\n",  
101 - __func__, r, env->interrupt_request,  
102 - address, is_softmmu, res.bf_vec)); 100 + D(fprintf(logfile, "%s returns %d irqreq=%x addr=%x"
  101 + " phy=%x ismmu=%d vec=%x pc=%x\n",
  102 + __func__, r, env->interrupt_request,
  103 + address, res.phy, is_softmmu, res.bf_vec, env->pc));
103 return r; 104 return r;
104 } 105 }
105 106
@@ -138,13 +139,19 @@ void do_interrupt(CPUState *env) @@ -138,13 +139,19 @@ void do_interrupt(CPUState *env)
138 break; 139 break;
139 } 140 }
140 141
141 - if ((env->pregs[PR_CCS] & U_FLAG)) {  
142 - D(fprintf(logfile, "excp isr=%x PC=%x SP=%x ERP=%x pid=%x ccs=%x cc=%d %x\n",  
143 - ex_vec, env->pc, 142 + if (env->dslot) {
  143 + D(fprintf(logfile, "excp isr=%x PC=%x ds=%d SP=%x"
  144 + " ERP=%x pid=%x ccs=%x cc=%d %x\n",
  145 + ex_vec, env->pc, env->dslot,
144 env->regs[R_SP], 146 env->regs[R_SP],
145 env->pregs[PR_ERP], env->pregs[PR_PID], 147 env->pregs[PR_ERP], env->pregs[PR_PID],
146 env->pregs[PR_CCS], 148 env->pregs[PR_CCS],
147 env->cc_op, env->cc_mask)); 149 env->cc_op, env->cc_mask));
  150 + /* We loose the btarget, btaken state here so rexec the
  151 + branch. */
  152 + env->pregs[PR_ERP] -= env->dslot;
  153 + /* Exception starts with dslot cleared. */
  154 + env->dslot = 0;
148 } 155 }
149 156
150 env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4); 157 env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
target-cris/helper.h
1 #define TCG_HELPER_PROTO 1 #define TCG_HELPER_PROTO
2 2
3 void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); 3 void TCG_HELPER_PROTO helper_raise_exception(uint32_t index);
  4 +void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid);
4 void TCG_HELPER_PROTO helper_tlb_flush(void); 5 void TCG_HELPER_PROTO helper_tlb_flush(void);
5 void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); 6 void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2);
6 void TCG_HELPER_PROTO helper_dummy(void); 7 void TCG_HELPER_PROTO helper_dummy(void);
target-cris/mmu.c
@@ -174,8 +174,9 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, @@ -174,8 +174,9 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
174 tlb_pfn = EXTRACT_FIELD(lo, 13, 31); 174 tlb_pfn = EXTRACT_FIELD(lo, 13, 31);
175 tlb_g = EXTRACT_FIELD(lo, 4, 4); 175 tlb_g = EXTRACT_FIELD(lo, 4, 4);
176 176
177 - D(printf("TLB[%d][%d] v=%x vpage=%x -> pfn=%x lo=%x hi=%x\n",  
178 - i, idx, tlb_vpn, vpage, tlb_pfn, lo, hi)); 177 + D(fprintf(logfile,
  178 + "TLB[%d][%d][%d] v=%x vpage=%x->pfn=%x lo=%x hi=%x\n",
  179 + mmu, set, idx, tlb_vpn, vpage, tlb_pfn, lo, hi));
179 if ((tlb_g || (tlb_pid == (env->pregs[PR_PID] & 0xff))) 180 if ((tlb_g || (tlb_pid == (env->pregs[PR_PID] & 0xff)))
180 && tlb_vpn == vpage) { 181 && tlb_vpn == vpage) {
181 match = 1; 182 match = 1;
@@ -224,7 +225,6 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, @@ -224,7 +225,6 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
224 res->bf_vec = vect_base + 3; 225 res->bf_vec = vect_base + 3;
225 } else if (cfg_v && !tlb_v) { 226 } else if (cfg_v && !tlb_v) {
226 D(printf ("tlb: invalid %x\n", vaddr)); 227 D(printf ("tlb: invalid %x\n", vaddr));
227 - set_field(&r_cause, rwcause, 8, 9);  
228 match = 0; 228 match = 0;
229 res->bf_vec = vect_base + 1; 229 res->bf_vec = vect_base + 1;
230 } 230 }
@@ -287,21 +287,42 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, @@ -287,21 +287,42 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
287 return !match; 287 return !match;
288 } 288 }
289 289
290 -/* Give us the vaddr corresponding to the latest TLB update. */  
291 -target_ulong cris_mmu_tlb_latest_update(CPUState *env) 290 +void cris_mmu_flush_pid(CPUState *env, uint32_t pid)
292 { 291 {
293 - uint32_t sel = env->sregs[SFR_RW_MM_TLB_SEL];  
294 - uint32_t vaddr;  
295 - uint32_t hi;  
296 - int set;  
297 - int idx;  
298 -  
299 - idx = EXTRACT_FIELD(sel, 0, 4);  
300 - set = EXTRACT_FIELD(sel, 4, 5);  
301 -  
302 - hi = env->tlbsets[1][set][idx].hi;  
303 - vaddr = EXTRACT_FIELD(hi, 13, 31);  
304 - return vaddr << TARGET_PAGE_BITS; 292 + target_ulong vaddr;
  293 + unsigned int idx;
  294 + uint32_t lo, hi;
  295 + uint32_t tlb_vpn;
  296 + int tlb_pid, tlb_g, tlb_v, tlb_k;
  297 + unsigned int set;
  298 + unsigned int mmu;
  299 +
  300 + pid &= 0xff;
  301 + for (mmu = 0; mmu < 2; mmu++) {
  302 + for (set = 0; set < 4; set++)
  303 + {
  304 + for (idx = 0; idx < 16; idx++) {
  305 + lo = env->tlbsets[mmu][set][idx].lo;
  306 + hi = env->tlbsets[mmu][set][idx].hi;
  307 +
  308 + tlb_vpn = EXTRACT_FIELD(hi, 13, 31);
  309 + tlb_pid = EXTRACT_FIELD(hi, 0, 7);
  310 + tlb_g = EXTRACT_FIELD(lo, 4, 4);
  311 + tlb_v = EXTRACT_FIELD(lo, 3, 3);
  312 + tlb_k = EXTRACT_FIELD(lo, 2, 2);
  313 +
  314 + /* Kernel protected areas need to be flushed
  315 + as well. */
  316 + if (tlb_v && !tlb_g) {
  317 + vaddr = tlb_vpn << TARGET_PAGE_BITS;
  318 + D(fprintf(logfile,
  319 + "flush pid=%x vaddr=%x\n",
  320 + pid, vaddr));
  321 + tlb_flush_page(env, vaddr);
  322 + }
  323 + }
  324 + }
  325 + }
305 } 326 }
306 327
307 int cris_mmu_translate(struct cris_mmu_result_t *res, 328 int cris_mmu_translate(struct cris_mmu_result_t *res,
target-cris/mmu.h
@@ -11,7 +11,7 @@ struct cris_mmu_result_t @@ -11,7 +11,7 @@ struct cris_mmu_result_t
11 int bf_vec; 11 int bf_vec;
12 }; 12 };
13 13
14 -target_ulong cris_mmu_tlb_latest_update(CPUState *env); 14 +void cris_mmu_flush_pid(CPUState *env, uint32_t pid);
15 int cris_mmu_translate(struct cris_mmu_result_t *res, 15 int cris_mmu_translate(struct cris_mmu_result_t *res,
16 CPUState *env, uint32_t vaddr, 16 CPUState *env, uint32_t vaddr,
17 int rw, int mmu_idx); 17 int rw, int mmu_idx);
target-cris/op_helper.c
@@ -85,6 +85,13 @@ void helper_raise_exception(uint32_t index) @@ -85,6 +85,13 @@ void helper_raise_exception(uint32_t index)
85 cpu_loop_exit(); 85 cpu_loop_exit();
86 } 86 }
87 87
  88 +void helper_tlb_flush_pid(uint32_t pid)
  89 +{
  90 +#if !defined(CONFIG_USER_ONLY)
  91 + cris_mmu_flush_pid(env, pid);
  92 +#endif
  93 +}
  94 +
88 void helper_tlb_flush(void) 95 void helper_tlb_flush(void)
89 { 96 {
90 tlb_flush(env, 1); 97 tlb_flush(env, 1);
@@ -100,6 +107,10 @@ void helper_dummy(void) @@ -100,6 +107,10 @@ void helper_dummy(void)
100 107
101 } 108 }
102 109
  110 +/* Used by the tlb decoder. */
  111 +#define EXTRACT_FIELD(src, start, end) \
  112 + (((src) >> start) & ((1 << (end - start + 1)) - 1))
  113 +
103 void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg) 114 void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
104 { 115 {
105 uint32_t srs; 116 uint32_t srs;
@@ -120,10 +131,7 @@ void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg) @@ -120,10 +131,7 @@ void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
120 uint32_t idx; 131 uint32_t idx;
121 uint32_t lo, hi; 132 uint32_t lo, hi;
122 uint32_t vaddr; 133 uint32_t vaddr;
123 -  
124 - vaddr = cris_mmu_tlb_latest_update(env);  
125 - D(fprintf(logfile, "tlb flush vaddr=%x\n", vaddr));  
126 - tlb_flush_page(env, vaddr); 134 + int tlb_v;
127 135
128 idx = set = env->sregs[SFR_RW_MM_TLB_SEL]; 136 idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
129 set >>= 4; 137 set >>= 4;
@@ -134,8 +142,19 @@ void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg) @@ -134,8 +142,19 @@ void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
134 lo = env->sregs[SFR_RW_MM_TLB_LO]; 142 lo = env->sregs[SFR_RW_MM_TLB_LO];
135 /* Writes are done via r_mm_cause. */ 143 /* Writes are done via r_mm_cause. */
136 hi = env->sregs[SFR_R_MM_CAUSE]; 144 hi = env->sregs[SFR_R_MM_CAUSE];
  145 +
  146 + vaddr = EXTRACT_FIELD(env->tlbsets[srs-1][set][idx].hi,
  147 + 13, 31);
  148 + vaddr <<= TARGET_PAGE_BITS;
  149 + tlb_v = EXTRACT_FIELD(env->tlbsets[srs-1][set][idx].lo,
  150 + 3, 3);
137 env->tlbsets[srs - 1][set][idx].lo = lo; 151 env->tlbsets[srs - 1][set][idx].lo = lo;
138 env->tlbsets[srs - 1][set][idx].hi = hi; 152 env->tlbsets[srs - 1][set][idx].hi = hi;
  153 +
  154 + D(fprintf(logfile,
  155 + "tlb flush vaddr=%x v=%d pc=%x\n",
  156 + vaddr, tlb_v, env->pc));
  157 + tlb_flush_page(env, vaddr);
139 } 158 }
140 } 159 }
141 #endif 160 #endif
target-cris/translate.c
@@ -21,8 +21,7 @@ @@ -21,8 +21,7 @@
21 21
22 /* 22 /*
23 * FIXME: 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. 24 + * The condition code translation is in need of attention.
26 */ 25 */
27 26
28 #include <stdarg.h> 27 #include <stdarg.h>
@@ -40,13 +39,6 @@ @@ -40,13 +39,6 @@
40 #include "crisv32-decode.h" 39 #include "crisv32-decode.h"
41 #include "qemu-common.h" 40 #include "qemu-common.h"
42 41
43 -#define CRIS_STATS 0  
44 -#if CRIS_STATS  
45 -#define STATS(x) x  
46 -#else  
47 -#define STATS(x)  
48 -#endif  
49 -  
50 #define DISAS_CRIS 0 42 #define DISAS_CRIS 0
51 #if DISAS_CRIS 43 #if DISAS_CRIS
52 #define DIS(x) x 44 #define DIS(x) x
@@ -109,25 +101,18 @@ typedef struct DisasContext { @@ -109,25 +101,18 @@ typedef struct DisasContext {
109 101
110 int user; /* user or kernel mode. */ 102 int user; /* user or kernel mode. */
111 int is_jmp; 103 int is_jmp;
112 - int dyn_jmp;  
113 104
114 - uint32_t delayed_pc;  
115 int delayed_branch; 105 int delayed_branch;
116 - int bcc;  
117 - uint32_t condlabel;  
118 106
119 struct TranslationBlock *tb; 107 struct TranslationBlock *tb;
120 int singlestep_enabled; 108 int singlestep_enabled;
121 } DisasContext; 109 } DisasContext;
122 110
123 -void cris_prepare_jmp (DisasContext *dc, uint32_t dst);  
124 static void gen_BUG(DisasContext *dc, char *file, int line) 111 static void gen_BUG(DisasContext *dc, char *file, int line)
125 { 112 {
126 printf ("BUG: pc=%x %s %d\n", dc->pc, file, line); 113 printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
127 fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line); 114 fprintf (logfile, "BUG: pc=%x %s %d\n", dc->pc, file, line);
128 - cpu_dump_state (dc->env, stdout, fprintf, 0);  
129 - fflush(NULL);  
130 - cris_prepare_jmp (dc, 0x70000000 + line); 115 + cpu_abort(dc->env, "%s:%d\n", file, line);
131 } 116 }
132 117
133 const char *regnames[] = 118 const char *regnames[] =
@@ -207,7 +192,7 @@ static inline void t_gen_mov_TN_preg(TCGv tn, int r) @@ -207,7 +192,7 @@ static inline void t_gen_mov_TN_preg(TCGv tn, int r)
207 else 192 else
208 tcg_gen_mov_tl(tn, cpu_PR[r]); 193 tcg_gen_mov_tl(tn, cpu_PR[r]);
209 } 194 }
210 -static inline void t_gen_mov_preg_TN(int r, TCGv tn) 195 +static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
211 { 196 {
212 if (r < 0 || r > 15) 197 if (r < 0 || r > 15)
213 fprintf(stderr, "wrong register write $p%d\n", r); 198 fprintf(stderr, "wrong register write $p%d\n", r);
@@ -216,10 +201,9 @@ static inline void t_gen_mov_preg_TN(int r, TCGv tn) @@ -216,10 +201,9 @@ static inline void t_gen_mov_preg_TN(int r, TCGv tn)
216 else if (r == PR_SRS) 201 else if (r == PR_SRS)
217 tcg_gen_andi_tl(cpu_PR[r], tn, 3); 202 tcg_gen_andi_tl(cpu_PR[r], tn, 3);
218 else { 203 else {
219 - if (r == PR_PID) {  
220 - tcg_gen_helper_0_0(helper_tlb_flush);  
221 - }  
222 tcg_gen_mov_tl(cpu_PR[r], tn); 204 tcg_gen_mov_tl(cpu_PR[r], tn);
  205 + if (r == PR_PID)
  206 + tcg_gen_helper_0_1(helper_tlb_flush_pid, tn);
223 } 207 }
224 } 208 }
225 209
@@ -596,7 +580,7 @@ static inline void t_gen_swapr(TCGv d, TCGv s) @@ -596,7 +580,7 @@ static inline void t_gen_swapr(TCGv d, TCGv s)
596 tcg_gen_discard_tl(org_s); 580 tcg_gen_discard_tl(org_s);
597 } 581 }
598 582
599 -static void t_gen_cc_jmp(target_ulong pc_true, target_ulong pc_false) 583 +static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
600 { 584 {
601 TCGv btaken; 585 TCGv btaken;
602 int l1; 586 int l1;
@@ -606,9 +590,9 @@ static void t_gen_cc_jmp(target_ulong pc_true, target_ulong pc_false) @@ -606,9 +590,9 @@ static void t_gen_cc_jmp(target_ulong pc_true, target_ulong pc_false)
606 590
607 /* Conditional jmp. */ 591 /* Conditional jmp. */
608 t_gen_mov_TN_env(btaken, btaken); 592 t_gen_mov_TN_env(btaken, btaken);
609 - tcg_gen_movi_tl(env_pc, pc_false); 593 + tcg_gen_mov_tl(env_pc, pc_false);
610 tcg_gen_brcond_tl(TCG_COND_EQ, btaken, tcg_const_tl(0), l1); 594 tcg_gen_brcond_tl(TCG_COND_EQ, btaken, tcg_const_tl(0), l1);
611 - tcg_gen_movi_tl(env_pc, pc_true); 595 + tcg_gen_mov_tl(env_pc, pc_true);
612 gen_set_label(l1); 596 gen_set_label(l1);
613 597
614 tcg_gen_discard_tl(btaken); 598 tcg_gen_discard_tl(btaken);
@@ -740,10 +724,11 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -740,10 +724,11 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
740 int writeback = 1; 724 int writeback = 1;
741 if (dc->update_cc) { 725 if (dc->update_cc) {
742 cris_update_cc_op(dc, op, size); 726 cris_update_cc_op(dc, op, size);
743 - tcg_gen_mov_tl(cc_dest, cpu_T[0]); 727 + if (op != CC_OP_MOVE)
  728 + tcg_gen_mov_tl(cc_dest, cpu_T[0]);
744 729
745 /* FIXME: This shouldn't be needed. But we don't pass the 730 /* FIXME: This shouldn't be needed. But we don't pass the
746 - tests without it. Investigate. */ 731 + tests without it. Investigate. */
747 t_gen_mov_env_TN(cc_x_live, tcg_const_tl(dc->flagx_live)); 732 t_gen_mov_env_TN(cc_x_live, tcg_const_tl(dc->flagx_live));
748 t_gen_mov_env_TN(cc_x, tcg_const_tl(dc->flags_x)); 733 t_gen_mov_env_TN(cc_x, tcg_const_tl(dc->flags_x));
749 } 734 }
@@ -812,7 +797,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -812,7 +797,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
812 TCGv mof; 797 TCGv mof;
813 mof = tcg_temp_new(TCG_TYPE_TL); 798 mof = tcg_temp_new(TCG_TYPE_TL);
814 t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]); 799 t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
815 - t_gen_mov_preg_TN(PR_MOF, mof); 800 + t_gen_mov_preg_TN(dc, PR_MOF, mof);
816 tcg_gen_discard_tl(mof); 801 tcg_gen_discard_tl(mof);
817 } 802 }
818 break; 803 break;
@@ -821,7 +806,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -821,7 +806,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
821 TCGv mof; 806 TCGv mof;
822 mof = tcg_temp_new(TCG_TYPE_TL); 807 mof = tcg_temp_new(TCG_TYPE_TL);
823 t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]); 808 t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
824 - t_gen_mov_preg_TN(PR_MOF, mof); 809 + t_gen_mov_preg_TN(dc, PR_MOF, mof);
825 tcg_gen_discard_tl(mof); 810 tcg_gen_discard_tl(mof);
826 } 811 }
827 break; 812 break;
@@ -875,12 +860,6 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -875,12 +860,6 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
875 } 860 }
876 if (dc->update_cc) 861 if (dc->update_cc)
877 tcg_gen_mov_tl(cc_result, cpu_T[0]); 862 tcg_gen_mov_tl(cc_result, cpu_T[0]);
878 -  
879 - {  
880 - /* TODO: Optimize this. */  
881 - if (!dc->flagx_live)  
882 - cris_evaluate_flags(dc);  
883 - }  
884 } 863 }
885 864
886 static int arith_cc(DisasContext *dc) 865 static int arith_cc(DisasContext *dc)
@@ -1073,7 +1052,6 @@ static void gen_tst_cc (DisasContext *dc, int cond) @@ -1073,7 +1052,6 @@ static void gen_tst_cc (DisasContext *dc, int cond)
1073 tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], P_FLAG); 1052 tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], P_FLAG);
1074 break; 1053 break;
1075 case CC_A: 1054 case CC_A:
1076 - cris_evaluate_flags(dc);  
1077 tcg_gen_movi_tl(cpu_T[0], 1); 1055 tcg_gen_movi_tl(cpu_T[0], 1);
1078 break; 1056 break;
1079 default: 1057 default:
@@ -1087,14 +1065,13 @@ static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond) @@ -1087,14 +1065,13 @@ static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
1087 /* This helps us re-schedule the micro-code to insns in delay-slots 1065 /* This helps us re-schedule the micro-code to insns in delay-slots
1088 before the actual jump. */ 1066 before the actual jump. */
1089 dc->delayed_branch = 2; 1067 dc->delayed_branch = 2;
1090 - dc->delayed_pc = dc->pc + offset;  
1091 - dc->bcc = cond;  
1092 if (cond != CC_A) 1068 if (cond != CC_A)
1093 { 1069 {
1094 gen_tst_cc (dc, cond); 1070 gen_tst_cc (dc, cond);
1095 t_gen_mov_env_TN(btaken, cpu_T[0]); 1071 t_gen_mov_env_TN(btaken, cpu_T[0]);
1096 - }  
1097 - tcg_gen_movi_tl(env_btarget, dc->delayed_pc); 1072 + } else
  1073 + t_gen_mov_env_TN(btaken, tcg_const_tl(1));
  1074 + tcg_gen_movi_tl(env_btarget, dc->pc + offset);
1098 } 1075 }
1099 1076
1100 1077
@@ -1104,18 +1081,7 @@ void cris_prepare_dyn_jmp (DisasContext *dc) @@ -1104,18 +1081,7 @@ void cris_prepare_dyn_jmp (DisasContext *dc)
1104 /* This helps us re-schedule the micro-code to insns in delay-slots 1081 /* This helps us re-schedule the micro-code to insns in delay-slots
1105 before the actual jump. */ 1082 before the actual jump. */
1106 dc->delayed_branch = 2; 1083 dc->delayed_branch = 2;
1107 - dc->dyn_jmp = 1;  
1108 - dc->bcc = CC_A;  
1109 -}  
1110 -  
1111 -void cris_prepare_jmp (DisasContext *dc, uint32_t dst)  
1112 -{  
1113 - /* This helps us re-schedule the micro-code to insns in delay-slots  
1114 - before the actual jump. */  
1115 - dc->delayed_branch = 2;  
1116 - dc->delayed_pc = dst;  
1117 - dc->dyn_jmp = 0;  
1118 - dc->bcc = CC_A; 1084 + t_gen_mov_env_TN(btaken, tcg_const_tl(1));
1119 } 1085 }
1120 1086
1121 void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 1087 void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
@@ -1123,6 +1089,7 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr, @@ -1123,6 +1089,7 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
1123 { 1089 {
1124 int mem_index = cpu_mmu_index(dc->env); 1090 int mem_index = cpu_mmu_index(dc->env);
1125 1091
  1092 + cris_evaluate_flags(dc);
1126 if (size == 1) { 1093 if (size == 1) {
1127 if (sign) 1094 if (sign)
1128 tcg_gen_qemu_ld8s(dst, addr, mem_index); 1095 tcg_gen_qemu_ld8s(dst, addr, mem_index);
@@ -1236,10 +1203,7 @@ static void dec_prep_alu_r(DisasContext *dc, int rs, int rd, @@ -1236,10 +1203,7 @@ static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
1236 t_gen_zext(cpu_T[0], cpu_R[rd], size); 1203 t_gen_zext(cpu_T[0], cpu_R[rd], size);
1237 } 1204 }
1238 1205
1239 -/* Prepare T0 and T1 for a memory + alu operation.  
1240 - s_ext decides if the operand1 should be sign-extended or zero-extended when  
1241 - needed. */  
1242 -static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize) 1206 +static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize)
1243 { 1207 {
1244 unsigned int rs, rd; 1208 unsigned int rs, rd;
1245 uint32_t imm; 1209 uint32_t imm;
@@ -1272,7 +1236,7 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize) @@ -1272,7 +1236,7 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
1272 imm = ldl_code(dc->pc + 2); 1236 imm = ldl_code(dc->pc + 2);
1273 1237
1274 DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n", 1238 DIS(fprintf (logfile, "imm=%x rd=%d sext=%d ms=%d\n",
1275 - imm, rd, s_ext, memsize)); 1239 + imm, rd, s_ext, memsize));
1276 tcg_gen_movi_tl(cpu_T[1], imm); 1240 tcg_gen_movi_tl(cpu_T[1], imm);
1277 dc->postinc = 0; 1241 dc->postinc = 0;
1278 } else { 1242 } else {
@@ -1282,9 +1246,20 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize) @@ -1282,9 +1246,20 @@ static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
1282 else 1246 else
1283 t_gen_zext(cpu_T[1], cpu_T[1], memsize); 1247 t_gen_zext(cpu_T[1], cpu_T[1], memsize);
1284 } 1248 }
  1249 + return insn_len;
  1250 +}
  1251 +
  1252 +/* Prepare T0 and T1 for a memory + alu operation.
  1253 + s_ext decides if the operand1 should be sign-extended or zero-extended when
  1254 + needed. */
  1255 +static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize)
  1256 +{
  1257 + int insn_len;
  1258 +
  1259 + insn_len = dec_prep_move_m(dc, s_ext, memsize);
1285 1260
1286 /* put dest in T0. */ 1261 /* put dest in T0. */
1287 - t_gen_mov_TN_reg(cpu_T[0], rd); 1262 + tcg_gen_mov_tl(cpu_T[0], cpu_R[dc->op2]);
1288 return insn_len; 1263 return insn_len;
1289 } 1264 }
1290 1265
@@ -1421,7 +1396,7 @@ static unsigned int dec_btstq(DisasContext *dc) @@ -1421,7 +1396,7 @@ static unsigned int dec_btstq(DisasContext *dc)
1421 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); 1396 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1422 1397
1423 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 1398 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1424 - t_gen_mov_preg_TN(PR_CCS, cpu_T[0]); 1399 + t_gen_mov_preg_TN(dc, PR_CCS, cpu_T[0]);
1425 dc->flags_live = 1; 1400 dc->flags_live = 1;
1426 return 2; 1401 return 2;
1427 } 1402 }
@@ -1702,7 +1677,9 @@ static char * swapmode_name(int mode, char *modename) { @@ -1702,7 +1677,9 @@ static char * swapmode_name(int mode, char *modename) {
1702 1677
1703 static unsigned int dec_swap_r(DisasContext *dc) 1678 static unsigned int dec_swap_r(DisasContext *dc)
1704 { 1679 {
1705 - DIS(char modename[4]); 1680 +#if DISAS_CRIS
  1681 + char modename[4];
  1682 +#endif
1706 DIS(fprintf (logfile, "swap%s $r%u\n", 1683 DIS(fprintf (logfile, "swap%s $r%u\n",
1707 swapmode_name(dc->op2, modename), dc->op1)); 1684 swapmode_name(dc->op2, modename), dc->op1));
1708 1685
@@ -1777,7 +1754,7 @@ static unsigned int dec_btst_r(DisasContext *dc) @@ -1777,7 +1754,7 @@ static unsigned int dec_btst_r(DisasContext *dc)
1777 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); 1754 crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4);
1778 1755
1779 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 1756 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1780 - t_gen_mov_preg_TN(PR_CCS, cpu_T[0]); 1757 + t_gen_mov_preg_TN(dc, PR_CCS, cpu_T[0]);
1781 dc->flags_live = 1; 1758 dc->flags_live = 1;
1782 return 2; 1759 return 2;
1783 } 1760 }
@@ -1900,14 +1877,16 @@ static unsigned int dec_setclrf(DisasContext *dc) @@ -1900,14 +1877,16 @@ static unsigned int dec_setclrf(DisasContext *dc)
1900 flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4) 1877 flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
1901 | EXTRACT_FIELD(dc->ir, 0, 3); 1878 | EXTRACT_FIELD(dc->ir, 0, 3);
1902 DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags)); 1879 DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags));
1903 - if (set && flags == 0) 1880 + if (set && flags == 0) {
1904 DIS(fprintf (logfile, "nop\n")); 1881 DIS(fprintf (logfile, "nop\n"));
1905 - else if (!set && (flags & 0x20)) 1882 + } else if (!set && (flags & 0x20)) {
1906 DIS(fprintf (logfile, "di\n")); 1883 DIS(fprintf (logfile, "di\n"));
1907 - else 1884 + }
  1885 + else {
1908 DIS(fprintf (logfile, "%sf %x\n", 1886 DIS(fprintf (logfile, "%sf %x\n",
1909 - set ? "set" : "clr", 1887 + set ? "set" : "clr",
1910 flags)); 1888 flags));
  1889 + }
1911 1890
1912 if (set && (flags & X_FLAG)) { 1891 if (set && (flags & X_FLAG)) {
1913 dc->flagx_live = 1; 1892 dc->flagx_live = 1;
@@ -1924,7 +1903,7 @@ static unsigned int dec_setclrf(DisasContext *dc) @@ -1924,7 +1903,7 @@ static unsigned int dec_setclrf(DisasContext *dc)
1924 /* Enter user mode. */ 1903 /* Enter user mode. */
1925 t_gen_mov_env_TN(ksp, cpu_R[R_SP]); 1904 t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
1926 tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]); 1905 tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
1927 - dc->is_jmp = DISAS_UPDATE; 1906 + dc->is_jmp = DISAS_NEXT;
1928 } 1907 }
1929 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags); 1908 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
1930 } 1909 }
@@ -1971,7 +1950,7 @@ static unsigned int dec_move_rp(DisasContext *dc) @@ -1971,7 +1950,7 @@ static unsigned int dec_move_rp(DisasContext *dc)
1971 else 1950 else
1972 t_gen_mov_TN_reg(cpu_T[0], dc->op1); 1951 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
1973 1952
1974 - t_gen_mov_preg_TN(dc->op2, cpu_T[0]); 1953 + t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]);
1975 if (dc->op2 == PR_CCS) { 1954 if (dc->op2 == PR_CCS) {
1976 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 1955 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
1977 dc->flags_live = 1; 1956 dc->flags_live = 1;
@@ -2004,7 +1983,7 @@ static unsigned int dec_move_mr(DisasContext *dc) @@ -2004,7 +1983,7 @@ static unsigned int dec_move_mr(DisasContext *dc)
2004 dc->op1, dc->postinc ? "+]" : "]", 1983 dc->op1, dc->postinc ? "+]" : "]",
2005 dc->op2)); 1984 dc->op2));
2006 1985
2007 - insn_len = dec_prep_alu_m(dc, 0, memsize); 1986 + insn_len = dec_prep_move_m(dc, 0, memsize);
2008 cris_cc_mask(dc, CC_MASK_NZ); 1987 cris_cc_mask(dc, CC_MASK_NZ);
2009 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize); 1988 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
2010 do_postinc(dc, memsize); 1989 do_postinc(dc, memsize);
@@ -2317,7 +2296,7 @@ static unsigned int dec_move_mp(DisasContext *dc) @@ -2317,7 +2296,7 @@ static unsigned int dec_move_mp(DisasContext *dc)
2317 } 2296 }
2318 } 2297 }
2319 2298
2320 - t_gen_mov_preg_TN(dc->op2, cpu_T[1]); 2299 + t_gen_mov_preg_TN(dc, dc->op2, cpu_T[1]);
2321 2300
2322 do_postinc(dc, memsize); 2301 do_postinc(dc, memsize);
2323 return insn_len; 2302 return insn_len;
@@ -2337,7 +2316,6 @@ static unsigned int dec_move_pm(DisasContext *dc) @@ -2337,7 +2316,6 @@ static unsigned int dec_move_pm(DisasContext *dc)
2337 if (dc->op2 == PR_CCS) 2316 if (dc->op2 == PR_CCS)
2338 cris_evaluate_flags(dc); 2317 cris_evaluate_flags(dc);
2339 t_gen_mov_TN_preg(cpu_T[1], dc->op2); 2318 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
2340 -  
2341 gen_store(dc, cpu_R[dc->op1], cpu_T[1], memsize); 2319 gen_store(dc, cpu_R[dc->op1], cpu_T[1], memsize);
2342 2320
2343 cris_cc_mask(dc, 0); 2321 cris_cc_mask(dc, 0);
@@ -2482,7 +2460,7 @@ static unsigned int dec_jas_im(DisasContext *dc) @@ -2482,7 +2460,7 @@ static unsigned int dec_jas_im(DisasContext *dc)
2482 cris_cc_mask(dc, 0); 2460 cris_cc_mask(dc, 0);
2483 /* Store the return address in Pd. */ 2461 /* Store the return address in Pd. */
2484 tcg_gen_movi_tl(env_btarget, imm); 2462 tcg_gen_movi_tl(env_btarget, imm);
2485 - t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8)); 2463 + t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
2486 cris_prepare_dyn_jmp(dc); 2464 cris_prepare_dyn_jmp(dc);
2487 return 6; 2465 return 6;
2488 } 2466 }
@@ -2499,7 +2477,7 @@ static unsigned int dec_jasc_im(DisasContext *dc) @@ -2499,7 +2477,7 @@ static unsigned int dec_jasc_im(DisasContext *dc)
2499 tcg_gen_movi_tl(cpu_T[0], imm); 2477 tcg_gen_movi_tl(cpu_T[0], imm);
2500 tcg_gen_mov_tl(env_btarget, cpu_T[0]); 2478 tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2501 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4); 2479 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4);
2502 - t_gen_mov_preg_TN(dc->op2, cpu_T[0]); 2480 + t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]);
2503 cris_prepare_dyn_jmp(dc); 2481 cris_prepare_dyn_jmp(dc);
2504 return 6; 2482 return 6;
2505 } 2483 }
@@ -2512,7 +2490,7 @@ static unsigned int dec_jasc_r(DisasContext *dc) @@ -2512,7 +2490,7 @@ static unsigned int dec_jasc_r(DisasContext *dc)
2512 t_gen_mov_TN_reg(cpu_T[0], dc->op1); 2490 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2513 tcg_gen_mov_tl(env_btarget, cpu_T[0]); 2491 tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2514 tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4); 2492 tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4);
2515 - t_gen_mov_preg_TN(dc->op2, cpu_T[0]); 2493 + t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]);
2516 cris_prepare_dyn_jmp(dc); 2494 cris_prepare_dyn_jmp(dc);
2517 return 2; 2495 return 2;
2518 } 2496 }
@@ -2547,7 +2525,7 @@ static unsigned int dec_bas_im(DisasContext *dc) @@ -2547,7 +2525,7 @@ static unsigned int dec_bas_im(DisasContext *dc)
2547 tcg_gen_movi_tl(cpu_T[0], dc->pc + simm); 2525 tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2548 tcg_gen_mov_tl(env_btarget, cpu_T[0]); 2526 tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2549 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8); 2527 tcg_gen_movi_tl(cpu_T[0], dc->pc + 8);
2550 - t_gen_mov_preg_TN(dc->op2, cpu_T[0]); 2528 + t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]);
2551 cris_prepare_dyn_jmp(dc); 2529 cris_prepare_dyn_jmp(dc);
2552 return 6; 2530 return 6;
2553 } 2531 }
@@ -2563,7 +2541,7 @@ static unsigned int dec_basc_im(DisasContext *dc) @@ -2563,7 +2541,7 @@ static unsigned int dec_basc_im(DisasContext *dc)
2563 tcg_gen_movi_tl(cpu_T[0], dc->pc + simm); 2541 tcg_gen_movi_tl(cpu_T[0], dc->pc + simm);
2564 tcg_gen_mov_tl(env_btarget, cpu_T[0]); 2542 tcg_gen_mov_tl(env_btarget, cpu_T[0]);
2565 tcg_gen_movi_tl(cpu_T[0], dc->pc + 12); 2543 tcg_gen_movi_tl(cpu_T[0], dc->pc + 12);
2566 - t_gen_mov_preg_TN(dc->op2, cpu_T[0]); 2544 + t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]);
2567 cris_prepare_dyn_jmp(dc); 2545 cris_prepare_dyn_jmp(dc);
2568 return 6; 2546 return 6;
2569 } 2547 }
@@ -2785,8 +2763,42 @@ static void check_breakpoint(CPUState *env, DisasContext *dc) @@ -2785,8 +2763,42 @@ static void check_breakpoint(CPUState *env, DisasContext *dc)
2785 } 2763 }
2786 } 2764 }
2787 2765
  2766 +
  2767 +/*
  2768 + * Delay slots on QEMU/CRIS.
  2769 + *
  2770 + * If an exception hits on a delayslot, the core will let ERP (the Exception
  2771 + * Return Pointer) point to the branch (the previous) insn and set the lsb to
  2772 + * to give SW a hint that the exception actually hit on the dslot.
  2773 + *
  2774 + * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
  2775 + * the core and any jmp to an odd addresses will mask off that lsb. It is
  2776 + * simply there to let sw know there was an exception on a dslot.
  2777 + *
  2778 + * When the software returns from an exception, the branch will re-execute.
  2779 + * On QEMU care needs to be taken when a branch+delayslot sequence is broken
  2780 + * and the branch and delayslot dont share pages.
  2781 + *
  2782 + * The TB contaning the branch insn will set up env->btarget and evaluate
  2783 + * env->btaken. When the translation loop exits we will note that the branch
  2784 + * sequence is broken and let env->dslot be the size of the branch insn (those
  2785 + * vary in length).
  2786 + *
  2787 + * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
  2788 + * set). It will also expect to have env->dslot setup with the size of the
  2789 + * delay slot so that env->pc - env->dslot point to the branch insn. This TB
  2790 + * will execute the dslot and take the branch, either to btarget or just one
  2791 + * insn ahead.
  2792 + *
  2793 + * When exceptions occur, we check for env->dslot in do_interrupt to detect
  2794 + * broken branch sequences and setup $erp accordingly (i.e let it point to the
  2795 + * branch and set lsb). Then env->dslot gets cleared so that the exception
  2796 + * handler can enter. When returning from exceptions (jump $erp) the lsb gets
  2797 + * masked off and we will reexecute the branch insn.
  2798 + *
  2799 + */
  2800 +
2788 /* generate intermediate code for basic block 'tb'. */ 2801 /* generate intermediate code for basic block 'tb'. */
2789 -struct DisasContext ctx;  
2790 static int 2802 static int
2791 gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, 2803 gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2792 int search_pc) 2804 int search_pc)
@@ -2795,6 +2807,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2795,6 +2807,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2795 uint32_t pc_start; 2807 uint32_t pc_start;
2796 unsigned int insn_len; 2808 unsigned int insn_len;
2797 int j, lj; 2809 int j, lj;
  2810 + struct DisasContext ctx;
2798 struct DisasContext *dc = &ctx; 2811 struct DisasContext *dc = &ctx;
2799 uint32_t next_page_start; 2812 uint32_t next_page_start;
2800 2813
@@ -2803,8 +2816,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2803,8 +2816,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2803 2816
2804 /* Odd PC indicates that branch is rexecuting due to exception in the 2817 /* Odd PC indicates that branch is rexecuting due to exception in the
2805 * delayslot, like in real hw. 2818 * delayslot, like in real hw.
2806 - * FIXME: we need to handle the case were the branch and the insn in  
2807 - * the delayslot do not share pages.  
2808 */ 2819 */
2809 pc_start = tb->pc & ~1; 2820 pc_start = tb->pc & ~1;
2810 dc->env = env; 2821 dc->env = env;
@@ -2820,19 +2831,24 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2820,19 +2831,24 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2820 dc->flagx_live = 0; 2831 dc->flagx_live = 0;
2821 dc->flags_x = 0; 2832 dc->flags_x = 0;
2822 dc->cc_mask = 0; 2833 dc->cc_mask = 0;
  2834 + dc->update_cc = 0;
2823 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 2835 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
2824 2836
2825 - dc->user = env->pregs[PR_CCS] & U_FLAG;  
2826 - dc->delayed_branch = 0; 2837 + /* Decode TB flags. */
  2838 + dc->user = tb->flags & U_FLAG;
  2839 + dc->delayed_branch = !!(tb->flags & 7);
2827 2840
2828 if (loglevel & CPU_LOG_TB_IN_ASM) { 2841 if (loglevel & CPU_LOG_TB_IN_ASM) {
2829 fprintf(logfile, 2842 fprintf(logfile,
2830 - "search=%d pc=%x ccs=%x pid=%x usp=%x dbg=%x %x %x\n" 2843 + "srch=%d pc=%x %x bt=%x ds=%lld ccs=%x\n"
  2844 + "pid=%x usp=%x dbg=%x %x %x\n"
2831 "%x.%x.%x.%x\n" 2845 "%x.%x.%x.%x\n"
2832 "%x.%x.%x.%x\n" 2846 "%x.%x.%x.%x\n"
2833 "%x.%x.%x.%x\n" 2847 "%x.%x.%x.%x\n"
2834 "%x.%x.%x.%x\n", 2848 "%x.%x.%x.%x\n",
2835 - search_pc, env->pc, env->pregs[PR_CCS], 2849 + search_pc, dc->pc, dc->ppc,
  2850 + env->btarget, tb->flags & 7,
  2851 + env->pregs[PR_CCS],
2836 env->pregs[PR_PID], env->pregs[PR_USP], 2852 env->pregs[PR_PID], env->pregs[PR_USP],
2837 env->debug1, env->debug2, env->debug3, 2853 env->debug1, env->debug2, env->debug3,
2838 env->regs[0], env->regs[1], env->regs[2], env->regs[3], 2854 env->regs[0], env->regs[1], env->regs[2], env->regs[3],
@@ -2860,14 +2876,17 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2860,14 +2876,17 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2860 while (lj < j) 2876 while (lj < j)
2861 gen_opc_instr_start[lj++] = 0; 2877 gen_opc_instr_start[lj++] = 0;
2862 } 2878 }
2863 - if (dc->delayed_branch == 1) { 2879 + if (dc->delayed_branch == 1)
2864 gen_opc_pc[lj] = dc->ppc | 1; 2880 gen_opc_pc[lj] = dc->ppc | 1;
2865 - gen_opc_instr_start[lj] = 0;  
2866 - }  
2867 - else { 2881 + else
2868 gen_opc_pc[lj] = dc->pc; 2882 gen_opc_pc[lj] = dc->pc;
2869 - gen_opc_instr_start[lj] = 1;  
2870 - } 2883 + gen_opc_instr_start[lj] = 1;
  2884 + }
  2885 +
  2886 + /* Pretty disas. */
  2887 + DIS(fprintf(logfile, "%x ", dc->pc));
  2888 + if (search_pc) {
  2889 + DIS(fprintf(logfile, "%x ", dc->pc));
2871 } 2890 }
2872 2891
2873 dc->clear_x = 1; 2892 dc->clear_x = 1;
@@ -2881,17 +2900,13 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2881,17 +2900,13 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2881 actually genereating any host code, the simulator will just 2900 actually genereating any host code, the simulator will just
2882 loop doing nothing for on this program location. */ 2901 loop doing nothing for on this program location. */
2883 if (dc->delayed_branch) { 2902 if (dc->delayed_branch) {
  2903 + t_gen_mov_env_TN(dslot, tcg_const_tl(0));
2884 dc->delayed_branch--; 2904 dc->delayed_branch--;
2885 if (dc->delayed_branch == 0) 2905 if (dc->delayed_branch == 0)
2886 { 2906 {
2887 - if (dc->bcc == CC_A) {  
2888 - tcg_gen_mov_tl(env_pc, env_btarget);  
2889 - dc->is_jmp = DISAS_JUMP;  
2890 - }  
2891 - else {  
2892 - t_gen_cc_jmp(dc->delayed_pc, dc->pc);  
2893 - dc->is_jmp = DISAS_JUMP;  
2894 - } 2907 + t_gen_cc_jmp(env_btarget,
  2908 + tcg_const_tl(dc->pc));
  2909 + dc->is_jmp = DISAS_JUMP;
2895 } 2910 }
2896 } 2911 }
2897 2912
@@ -2900,15 +2915,16 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, @@ -2900,15 +2915,16 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2900 if (!(tb->pc & 1) && env->singlestep_enabled) 2915 if (!(tb->pc & 1) && env->singlestep_enabled)
2901 break; 2916 break;
2902 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end 2917 } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
2903 - && ((dc->pc < next_page_start) || dc->delayed_branch)); 2918 + && (dc->pc < next_page_start));
2904 2919
  2920 + /* Broken branch+delayslot sequence. */
2905 if (dc->delayed_branch == 1) { 2921 if (dc->delayed_branch == 1) {
2906 - /* Reexecute the last insn. */  
2907 - dc->pc = dc->ppc | 1; 2922 + /* Set env->dslot to the size of the branch insn. */
  2923 + t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
2908 } 2924 }
2909 2925
2910 if (!dc->is_jmp) { 2926 if (!dc->is_jmp) {
2911 - D(printf("!jmp pc=%x jmp=%d db=%d\n", dc->pc, 2927 + D(fprintf(logfile, "!jmp pc=%x jmp=%d db=%d\n", dc->pc,
2912 dc->is_jmp, dc->delayed_branch)); 2928 dc->is_jmp, dc->delayed_branch));
2913 /* T0 and env_pc should hold the new pc. */ 2929 /* T0 and env_pc should hold the new pc. */
2914 tcg_gen_movi_tl(cpu_T[0], dc->pc); 2930 tcg_gen_movi_tl(cpu_T[0], dc->pc);
@@ -3079,6 +3095,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) @@ -3079,6 +3095,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
3079 TCG_HELPER(helper_dummy); 3095 TCG_HELPER(helper_dummy);
3080 3096
3081 TCG_HELPER(helper_tlb_flush); 3097 TCG_HELPER(helper_tlb_flush);
  3098 + TCG_HELPER(helper_tlb_flush_pid);
3082 TCG_HELPER(helper_movl_sreg_reg); 3099 TCG_HELPER(helper_movl_sreg_reg);
3083 TCG_HELPER(helper_movl_reg_sreg); 3100 TCG_HELPER(helper_movl_reg_sreg);
3084 TCG_HELPER(helper_rfe); 3101 TCG_HELPER(helper_rfe);