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 257 cs_base = 0;
258 258 pc = env->pc;
259 259 #elif defined(TARGET_CRIS)
260   - flags = 0;
  260 + flags = env->pregs[PR_CCS];
261 261 cs_base = 0;
262 262 pc = env->pc;
263 263 #else
... ...
target-cris/cpu.h
... ... @@ -38,6 +38,28 @@
38 38 #define EXCP_MMU_FAULT 4
39 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 63 /* CPU flags. */
42 64 #define S_FLAG 0x200
43 65 #define R_FLAG 0x100
... ... @@ -77,27 +99,16 @@
77 99 #define NB_MMU_MODES 2
78 100  
79 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 102 uint32_t regs[16];
  103 + /* P0 - P15 are referred to as special registers in the docs. */
98 104 uint32_t pregs[16];
  105 +
  106 + /* Pseudo register for the PC. Not directly accessable on CRIS. */
99 107 uint32_t pc;
100 108  
  109 + /* Pseudo register for the kernel stack. */
  110 + uint32_t ksp;
  111 +
101 112 /* These are setup up by the guest code just before transfering the
102 113 control back to the host. */
103 114 int jmp;
... ... @@ -114,20 +125,19 @@ typedef struct CPUCRISState {
114 125 /* size of the operation, 1 = byte, 2 = word, 4 = dword. */
115 126 int cc_size;
116 127  
117   - /* extended arithmetics. */
  128 + /* Extended arithmetics. */
118 129 int cc_x_live;
119 130 int cc_x;
120 131  
121   - int features;
122   -
123 132 int exception_index;
124 133 int interrupt_request;
125 134 int interrupt_vector;
126 135 int fault_vector;
127 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 142 struct
133 143 {
... ... @@ -136,6 +146,31 @@ typedef struct CPUCRISState {
136 146 int exec_stores;
137 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 174 jmp_buf jmp_env;
140 175 CPU_COMMON
141 176 } CPUCRISState;
... ... @@ -225,40 +260,20 @@ void register_cris_insns (CPUCRISState *env);
225 260 #define MMU_MODE0_SUFFIX _kernel
226 261 #define MMU_MODE1_SUFFIX _user
227 262 #define MMU_USER_IDX 1
228   -/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */
229 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 268 /* Support function regs. */
255 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 279 #endif
... ...
target-cris/helper.c
... ... @@ -61,7 +61,7 @@ static void cris_shift_ccs(CPUState *env)
61 61 uint32_t ccs;
62 62 /* Apply the ccs shift. */
63 63 ccs = env->pregs[PR_CCS];
64   - ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
  64 + ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
65 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 73 int r = -1;
74 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 77 address &= TARGET_PAGE_MASK;
78 78 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
79 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 86 else
87 87 {
88 88 phy = res.phy;
89   - prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  89 + prot = res.prot;
  90 + address &= TARGET_PAGE_MASK;
90 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 97 return r;
96 98 }
97 99  
... ... @@ -100,8 +102,8 @@ void do_interrupt(CPUState *env)
100 102 int ex_vec = -1;
101 103  
102 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 108 switch (env->exception_index)
107 109 {
... ... @@ -113,40 +115,46 @@ void do_interrupt(CPUState *env)
113 115 break;
114 116  
115 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 118 ex_vec = env->fault_vector;
  119 + env->pregs[PR_ERP] = env->pc;
120 120 break;
121 121  
122 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 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 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 160 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
... ...
target-cris/helper.h
1 1 #define TCG_HELPER_PROTO
2 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 73 val <<= offset;
74 74  
75 75 val &= mask;
76   - D(printf ("val=%x mask=%x dst=%x\n", val, mask, *dst));
77 76 *dst &= ~(mask);
78 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 100 static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
82 101 CPUState *env, uint32_t vaddr,
83 102 int rw, int usermode)
... ... @@ -88,53 +107,63 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
88 107 uint32_t tlb_vpn, tlb_pfn = 0;
89 108 int tlb_pid, tlb_g, tlb_v, tlb_k, tlb_w, tlb_x;
90 109 int cfg_v, cfg_k, cfg_w, cfg_x;
91   - int i, match = 0;
  110 + int set, match = 0;
92 111 uint32_t r_cause;
93 112 uint32_t r_cfg;
94 113 int rwcause;
95   - int update_sel = 0;
  114 + int mmu = 1; /* Data mmu is default. */
  115 + int vect_base;
96 116  
97 117 r_cause = env->sregs[SFR_R_MM_CAUSE];
98 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 130 vpage = vaddr >> 13;
102   - idx = vpage & 15;
103 131  
104 132 /* We know the index which to check on each set.
105 133 Scan both I and D. */
106 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 139 tlb_vpn = EXTRACT_FIELD(hi, 13, 31);
113 140 tlb_pfn = EXTRACT_FIELD(lo, 13, 31);
114 141  
115 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 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 154 tlb_vpn = EXTRACT_FIELD(hi, 13, 31);
126 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 159 if (tlb_vpn == vpage) {
131 160 match = 1;
132 161 break;
133 162 }
134 163 }
135 164  
  165 + res->bf_vec = vect_base;
136 166 if (match) {
137   -
138 167 cfg_w = EXTRACT_FIELD(r_cfg, 19, 19);
139 168 cfg_k = EXTRACT_FIELD(r_cfg, 18, 18);
140 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 187 set_exception_vector(0x0a, d_mmu_access);
159 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 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 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 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 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 235 set_field(&r_cause, vpage, 13, 19);
197 236 set_field(&r_cause, env->pregs[PR_PID], 0, 8);
198 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 245 vaddr, vpage,
204 246 tlb_vpn, tlb_pfn, tlb_pid,
205 247 env->pregs[PR_PID],
206 248 r_cause,
207 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 252 res->pfn = tlb_pfn;
211 253 return !match;
... ... @@ -236,10 +278,17 @@ int cris_mmu_translate(struct cris_mmu_result_t *res,
236 278 int seg;
237 279 int miss = 0;
238 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 288 if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
241 289 res->phy = vaddr;
242   - return 0;
  290 + res->prot = PAGE_BITS;
  291 + goto done;
243 292 }
244 293  
245 294 seg = vaddr >> 28;
... ... @@ -251,17 +300,16 @@ int cris_mmu_translate(struct cris_mmu_result_t *res,
251 300 base = cris_mmu_translate_seg(env, seg);
252 301 phy = base | (0x0fffffff & vaddr);
253 302 res->phy = phy;
  303 + res->prot = PAGE_BITS;
254 304 }
255 305 else
256 306 {
257 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 313 return miss;
266 314 }
267 315 #endif
... ...
target-cris/mmu.h
... ... @@ -7,6 +7,7 @@ struct cris_mmu_result_t
7 7 {
8 8 uint32_t phy;
9 9 uint32_t pfn;
  10 + int prot;
10 11 int bf_vec;
11 12 };
12 13  
... ...
target-cris/op.c
... ... @@ -192,17 +192,32 @@ void OPPROTO op_ccs_lshift (void)
192 192 }
193 193 void OPPROTO op_ccs_rshift (void)
194 194 {
195   - uint32_t ccs;
  195 + register uint32_t ccs;
196 196  
197 197 /* Apply the ccs shift. */
198 198 ccs = env->pregs[PR_CCS];
199 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 207 env->pregs[PR_CCS] = ccs;
  208 +
201 209 RETURN();
202 210 }
203 211  
204 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 221 env->pregs[PR_CCS] |= PARAM1;
207 222 RETURN();
208 223 }
... ... @@ -265,7 +280,11 @@ void OPPROTO op_movl_flags_T0 (void)
265 280  
266 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 288 RETURN();
270 289 }
271 290  
... ... @@ -285,7 +304,10 @@ void OPPROTO op_movl_tlb_hi_T0 (void)
285 304 void OPPROTO op_movl_tlb_lo_T0 (void)
286 305 {
287 306 uint32_t srs;
  307 +
  308 + env->pregs[PR_SRS] &= 3;
288 309 srs = env->pregs[PR_SRS];
  310 +
289 311 if (srs == 1 || srs == 2)
290 312 {
291 313 uint32_t set;
... ... @@ -309,7 +331,28 @@ void OPPROTO op_movl_tlb_lo_T0 (void)
309 331  
310 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 356 RETURN();
314 357 }
315 358  
... ... @@ -363,340 +406,6 @@ void OPPROTO op_update_cc_x (void)
363 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 409 void OPPROTO op_extb_T0_T0 (void)
701 410 {
702 411 T0 = ((int8_t)T0);
... ... @@ -1274,17 +983,3 @@ void OPPROTO op_jmp1 (void)
1274 983 env->pc = env->btarget;
1275 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 59 generated code */
60 60 saved_env = env;
61 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 65 ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
63 66 if (__builtin_expect(ret, 0)) {
64 67 if (retaddr) {
... ... @@ -80,16 +83,380 @@ void helper_tlb_update(uint32_t T0)
80 83 {
81 84 #if !defined(CONFIG_USER_ONLY)
82 85 uint32_t vaddr;
  86 + uint32_t srs = env->pregs[PR_SRS];
  87 +
  88 + if (srs != 1 && srs != 2)
  89 + return;
83 90  
84 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 94 tlb_flush_page(env, vaddr);
87 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 131 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
91 132 int is_asi)
92 133 {
93 134 D(printf("%s addr=%x w=%d ex=%d asi=%d\n",
94 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 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 28 #include <stdarg.h>
23 29 #include <stdlib.h>
24 30 #include <stdio.h>
... ... @@ -48,6 +54,7 @@
48 54 #define DIS(x)
49 55 #endif
50 56  
  57 +#define D(x)
51 58 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
52 59 #define BUG_ON(x) ({if (x) BUG();})
53 60  
... ... @@ -73,10 +80,13 @@ TCGv cc_op;
73 80 TCGv cc_size;
74 81 TCGv cc_mask;
75 82  
  83 +TCGv env_btarget;
  84 +TCGv env_pc;
  85 +
76 86 /* This is the state at translation time. */
77 87 typedef struct DisasContext {
78 88 CPUState *env;
79   - target_ulong pc, insn_pc;
  89 + target_ulong pc, ppc;
80 90  
81 91 /* Decoder. */
82 92 uint32_t ir;
... ... @@ -91,12 +101,13 @@ typedef struct DisasContext {
91 101 int cc_op;
92 102 int cc_size;
93 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 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 111 int is_jmp;
101 112 int dyn_jmp;
102 113  
... ... @@ -119,37 +130,6 @@ static void gen_BUG(DisasContext *dc, char *file, int line)
119 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 133 const char *regnames[] =
154 134 {
155 135 "$r0", "$r1", "$r2", "$r3",
... ... @@ -182,35 +162,65 @@ int preg_sizes[] = {
182 162 #define t_gen_mov_env_TN(member, tn) \
183 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 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 182 tcg_gen_ld_tl(tn, cpu_env, offset);
193 183 }
194 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 188 tcg_gen_st_tl(tn, cpu_env, offset);
197 189 }
198 190  
199 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 195 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
202 196 tcg_gen_mov_tl(tn, tcg_const_tl(0));
203 197 else if (r == PR_VR)
204 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 207 else
206 208 tcg_gen_mov_tl(tn, cpu_PR[r]);
207 209 }
208 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 214 if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
211 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 222 tcg_gen_mov_tl(cpu_PR[r], tn);
  223 + }
214 224 }
215 225  
216 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 263 tcg_gen_sar_tl(d, a, b);
254 264 tcg_gen_brcond_tl(TCG_COND_LE, b, tcg_const_tl(31), l1);
255 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 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 282 tcg_gen_trunc_i64_i32(d, t0);
275 283 tcg_gen_shri_i64(t0, t0, 32);
276 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 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 302 tcg_gen_trunc_i64_i32(d, t0);
292 303 tcg_gen_shri_i64(t0, t0, 32);
293 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 310 /* Extended arithmetics on CRIS. */
... ... @@ -305,6 +319,7 @@ static inline void t_gen_add_flag(TCGv d, int flag)
305 319 if (flag)
306 320 tcg_gen_shri_tl(c, c, flag);
307 321 tcg_gen_add_tl(d, d, c);
  322 + tcg_gen_discard_tl(c);
308 323 }
309 324  
310 325 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 339 tcg_gen_and_tl(x, x, c);
325 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 345 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 359 tcg_gen_and_tl(x, x, c);
343 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 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 378 tcg_gen_shri_tl(t, org_s, 8);
360 379 tcg_gen_andi_tl(t, t, 0x00ff00ff);
361 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 385 /* Swap the halfwords of the s operand. */
... ... @@ -371,6 +392,7 @@ static inline void t_gen_swapw(TCGv d, TCGv s)
371 392 tcg_gen_shli_tl(d, t, 16);
372 393 tcg_gen_shri_tl(t, t, 16);
373 394 tcg_gen_or_tl(d, d, t);
  395 + tcg_gen_discard_tl(t);
374 396 }
375 397  
376 398 /* Reverse the within each byte.
... ... @@ -417,6 +439,8 @@ static inline void t_gen_swapr(TCGv d, TCGv s)
417 439 tcg_gen_andi_tl(t, t, bitrev[i].mask);
418 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 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 473  
450 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 484 static void cris_evaluate_flags(DisasContext *dc)
462 485 {
463 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 491 switch (dc->cc_op)
465 492 {
466 493 case CC_OP_MCP:
467   - gen_op_evaluate_flags_mcp ();
  494 + tcg_gen_helper_0_0(helper_evaluate_flags_mcp);
468 495 break;
469 496 case CC_OP_MULS:
470   - gen_op_evaluate_flags_muls ();
  497 + tcg_gen_helper_0_0(helper_evaluate_flags_muls);
471 498 break;
472 499 case CC_OP_MULU:
473   - gen_op_evaluate_flags_mulu ();
  500 + tcg_gen_helper_0_0(helper_evaluate_flags_mulu);
474 501 break;
475 502 case CC_OP_MOVE:
476 503 switch (dc->cc_size)
477 504 {
478 505 case 4:
479   - gen_op_evaluate_flags_move_4();
  506 + tcg_gen_helper_0_0(helper_evaluate_flags_move_4);
480 507 break;
481 508 case 2:
482   - gen_op_evaluate_flags_move_2();
  509 + tcg_gen_helper_0_0(helper_evaluate_flags_move_2);
483 510 break;
484 511 default:
485   - gen_op_evaluate_flags ();
  512 + tcg_gen_helper_0_0(helper_evaluate_flags);
486 513 break;
487 514 }
488 515 break;
489   -
  516 + case CC_OP_FLAGS:
  517 + /* live. */
  518 + break;
490 519 default:
491 520 {
492 521 switch (dc->cc_size)
493 522 {
494 523 case 4:
495   - gen_op_evaluate_flags_alu_4 ();
  524 + tcg_gen_helper_0_0(helper_evaluate_flags_alu_4);
496 525 break;
497 526 default:
498   - gen_op_evaluate_flags ();
  527 + tcg_gen_helper_0_0(helper_evaluate_flags);
499 528 break;
500 529 }
501 530 }
... ... @@ -525,16 +554,11 @@ static void cris_cc_mask(DisasContext *dc, unsigned int mask)
525 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 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 560 dc->cc_size = size;
537   - tcg_gen_movi_tl(cc_size, size);
  561 + dc->flags_live = 0;
538 562 }
539 563  
540 564 /* op is the operation.
... ... @@ -545,10 +569,8 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
545 569 {
546 570 int writeback = 1;
547 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 573 tcg_gen_mov_tl(cc_dest, cpu_T[0]);
551   - tcg_gen_movi_tl(cc_mask, dc->cc_mask);
552 574  
553 575 /* FIXME: This shouldn't be needed. But we don't pass the
554 576 tests without it. Investigate. */
... ... @@ -623,6 +645,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
623 645 mof = tcg_temp_new(TCG_TYPE_TL);
624 646 t_gen_muls(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
625 647 t_gen_mov_preg_TN(PR_MOF, mof);
  648 + tcg_gen_discard_tl(mof);
626 649 }
627 650 break;
628 651 case CC_OP_MULU:
... ... @@ -631,6 +654,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
631 654 mof = tcg_temp_new(TCG_TYPE_TL);
632 655 t_gen_mulu(cpu_T[0], mof, cpu_T[0], cpu_T[1]);
633 656 t_gen_mov_preg_TN(PR_MOF, mof);
  657 + tcg_gen_discard_tl(mof);
634 658 }
635 659 break;
636 660 case CC_OP_DSTEP:
... ... @@ -820,10 +844,10 @@ static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond)
820 844 gen_tst_cc (dc, cond);
821 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 851 /* Dynamic jumps, when the dest is in a live reg for example. */
828 852 void cris_prepare_dyn_jmp (DisasContext *dc)
829 853 {
... ... @@ -844,36 +868,46 @@ void cris_prepare_jmp (DisasContext *dc, uint32_t dst)
844 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 879 if (size == 1) {
850 880 if (sign)
851   - gen_op_ldb_T0_T0(dc);
  881 + tcg_gen_qemu_ld8s(dst, addr, mem_index);
852 882 else
853   - gen_op_ldub_T0_T0(dc);
  883 + tcg_gen_qemu_ld8u(dst, addr, mem_index);
854 884 }
855 885 else if (size == 2) {
856 886 if (sign)
857   - gen_op_ldw_T0_T0(dc);
  887 + tcg_gen_qemu_ld16s(dst, addr, mem_index);
858 888 else
859   - gen_op_lduw_T0_T0(dc);
  889 + tcg_gen_qemu_ld16u(dst, addr, mem_index);
860 890 }
861 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 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 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 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 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 1029 tcg_gen_movi_tl(cpu_T[1], imm);
996 1030 dc->postinc = 0;
997 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 1033 if (s_ext)
1002 1034 t_gen_sext(cpu_T[1], cpu_T[1], memsize);
1003 1035 else
... ... @@ -1021,6 +1053,8 @@ static const char *cc_name(int cc)
1021 1053 }
1022 1054 #endif
1023 1055  
  1056 +/* Start of insn decoders. */
  1057 +
1024 1058 static unsigned int dec_bccq(DisasContext *dc)
1025 1059 {
1026 1060 int32_t offset;
... ... @@ -1043,7 +1077,7 @@ static unsigned int dec_bccq(DisasContext *dc)
1043 1077 }
1044 1078 static unsigned int dec_addoq(DisasContext *dc)
1045 1079 {
1046   - uint32_t imm;
  1080 + int32_t imm;
1047 1081  
1048 1082 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
1049 1083 imm = sign_extend(dc->op1, 7);
... ... @@ -1051,9 +1085,7 @@ static unsigned int dec_addoq(DisasContext *dc)
1051 1085 DIS(fprintf (logfile, "addoq %d, $r%u\n", imm, dc->op2));
1052 1086 cris_cc_mask(dc, 0);
1053 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 1089 return 2;
1058 1090 }
1059 1091 static unsigned int dec_addq(DisasContext *dc)
... ... @@ -1140,7 +1172,7 @@ static unsigned int dec_btstq(DisasContext *dc)
1140 1172 t_gen_mov_TN_im(cpu_T[1], dc->op1);
1141 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 1176 t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1145 1177 dc->flags_live = 1;
1146 1178 return 2;
... ... @@ -1461,11 +1493,11 @@ static unsigned int dec_addi_r(DisasContext *dc)
1461 1493 static unsigned int dec_addi_acr(DisasContext *dc)
1462 1494 {
1463 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 1497 cris_cc_mask(dc, 0);
1466 1498 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1467 1499 t_gen_lsl(cpu_T[0], cpu_T[0], tcg_const_tl(dc->zzsize));
1468   -
  1500 +
1469 1501 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1470 1502 t_gen_mov_reg_TN(R_ACR, cpu_T[0]);
1471 1503 return 2;
... ... @@ -1490,7 +1522,7 @@ static unsigned int dec_btst_r(DisasContext *dc)
1490 1522 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
1491 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 1526 t_gen_mov_preg_TN(PR_CCS, cpu_T[0]);
1495 1527 dc->flags_live = 1;
1496 1528 return 2;
... ... @@ -1630,12 +1662,15 @@ static unsigned int dec_setclrf(DisasContext *dc)
1630 1662  
1631 1663 /* Simply decode the flags. */
1632 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 1668 if (set)
1635 1669 gen_op_setf(flags);
1636 1670 else
1637 1671 gen_op_clrf(flags);
1638 1672 dc->flags_live = 1;
  1673 + dc->clear_x = 0;
1639 1674 return 2;
1640 1675 }
1641 1676  
... ... @@ -1669,8 +1704,25 @@ static unsigned int dec_move_rp(DisasContext *dc)
1669 1704 {
1670 1705 DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
1671 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 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 1726 return 2;
1675 1727 }
1676 1728 static unsigned int dec_move_pr(DisasContext *dc)
... ... @@ -1681,7 +1733,10 @@ static unsigned int dec_move_pr(DisasContext *dc)
1681 1733 Treat it specially. */
1682 1734 if (dc->op2 == 0)
1683 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 1740 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
1686 1741 crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, preg_sizes[dc->op2]);
1687 1742 return 2;
... ... @@ -1696,8 +1751,8 @@ static unsigned int dec_move_mr(DisasContext *dc)
1696 1751 dc->op1, dc->postinc ? "+]" : "]",
1697 1752 dc->op2));
1698 1753  
1699   - cris_cc_mask(dc, CC_MASK_NZ);
1700 1754 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1755 + cris_cc_mask(dc, CC_MASK_NZ);
1701 1756 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, memsize);
1702 1757 do_postinc(dc, memsize);
1703 1758 return insn_len;
... ... @@ -1713,8 +1768,8 @@ static unsigned int dec_movs_m(DisasContext *dc)
1713 1768 dc->op2));
1714 1769  
1715 1770 /* sign extend. */
1716   - cris_cc_mask(dc, CC_MASK_NZ);
1717 1771 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1772 + cris_cc_mask(dc, CC_MASK_NZ);
1718 1773 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1719 1774 do_postinc(dc, memsize);
1720 1775 return insn_len;
... ... @@ -1730,8 +1785,8 @@ static unsigned int dec_addu_m(DisasContext *dc)
1730 1785 dc->op2));
1731 1786  
1732 1787 /* sign extend. */
1733   - cris_cc_mask(dc, CC_MASK_NZVC);
1734 1788 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1789 + cris_cc_mask(dc, CC_MASK_NZVC);
1735 1790 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1736 1791 do_postinc(dc, memsize);
1737 1792 return insn_len;
... ... @@ -1747,8 +1802,8 @@ static unsigned int dec_adds_m(DisasContext *dc)
1747 1802 dc->op2));
1748 1803  
1749 1804 /* sign extend. */
1750   - cris_cc_mask(dc, CC_MASK_NZVC);
1751 1805 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1806 + cris_cc_mask(dc, CC_MASK_NZVC);
1752 1807 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, 4);
1753 1808 do_postinc(dc, memsize);
1754 1809 return insn_len;
... ... @@ -1764,8 +1819,8 @@ static unsigned int dec_subu_m(DisasContext *dc)
1764 1819 dc->op2));
1765 1820  
1766 1821 /* sign extend. */
1767   - cris_cc_mask(dc, CC_MASK_NZVC);
1768 1822 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1823 + cris_cc_mask(dc, CC_MASK_NZVC);
1769 1824 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1770 1825 do_postinc(dc, memsize);
1771 1826 return insn_len;
... ... @@ -1781,8 +1836,8 @@ static unsigned int dec_subs_m(DisasContext *dc)
1781 1836 dc->op2));
1782 1837  
1783 1838 /* sign extend. */
1784   - cris_cc_mask(dc, CC_MASK_NZVC);
1785 1839 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1840 + cris_cc_mask(dc, CC_MASK_NZVC);
1786 1841 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4);
1787 1842 do_postinc(dc, memsize);
1788 1843 return insn_len;
... ... @@ -1798,8 +1853,8 @@ static unsigned int dec_movu_m(DisasContext *dc)
1798 1853 dc->op1, dc->postinc ? "+]" : "]",
1799 1854 dc->op2));
1800 1855  
1801   - cris_cc_mask(dc, CC_MASK_NZ);
1802 1856 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1857 + cris_cc_mask(dc, CC_MASK_NZ);
1803 1858 crisv32_alu_op(dc, CC_OP_MOVE, dc->op2, 4);
1804 1859 do_postinc(dc, memsize);
1805 1860 return insn_len;
... ... @@ -1814,8 +1869,8 @@ static unsigned int dec_cmpu_m(DisasContext *dc)
1814 1869 dc->op1, dc->postinc ? "+]" : "]",
1815 1870 dc->op2));
1816 1871  
1817   - cris_cc_mask(dc, CC_MASK_NZVC);
1818 1872 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1873 + cris_cc_mask(dc, CC_MASK_NZVC);
1819 1874 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4);
1820 1875 do_postinc(dc, memsize);
1821 1876 return insn_len;
... ... @@ -1830,8 +1885,8 @@ static unsigned int dec_cmps_m(DisasContext *dc)
1830 1885 dc->op1, dc->postinc ? "+]" : "]",
1831 1886 dc->op2));
1832 1887  
1833   - cris_cc_mask(dc, CC_MASK_NZVC);
1834 1888 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1889 + cris_cc_mask(dc, CC_MASK_NZVC);
1835 1890 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1836 1891 do_postinc(dc, memsize);
1837 1892 return insn_len;
... ... @@ -1846,8 +1901,8 @@ static unsigned int dec_cmp_m(DisasContext *dc)
1846 1901 dc->op1, dc->postinc ? "+]" : "]",
1847 1902 dc->op2));
1848 1903  
1849   - cris_cc_mask(dc, CC_MASK_NZVC);
1850 1904 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1905 + cris_cc_mask(dc, CC_MASK_NZVC);
1851 1906 crisv32_alu_op(dc, CC_OP_CMP, dc->op2, memsize_zz(dc));
1852 1907 do_postinc(dc, memsize);
1853 1908 return insn_len;
... ... @@ -1862,9 +1917,10 @@ static unsigned int dec_test_m(DisasContext *dc)
1862 1917 dc->op1, dc->postinc ? "+]" : "]",
1863 1918 dc->op2));
1864 1919  
  1920 + insn_len = dec_prep_alu_m(dc, 0, memsize);
1865 1921 cris_cc_mask(dc, CC_MASK_NZ);
1866 1922 gen_op_clrf(3);
1867   - insn_len = dec_prep_alu_m(dc, 0, memsize);
  1923 +
1868 1924 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1869 1925 tcg_gen_movi_tl(cpu_T[1], 0);
1870 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 1937 dc->op1, dc->postinc ? "+]" : "]",
1882 1938 dc->op2));
1883 1939  
1884   - cris_cc_mask(dc, CC_MASK_NZ);
1885 1940 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1941 + cris_cc_mask(dc, CC_MASK_NZ);
1886 1942 crisv32_alu_op(dc, CC_OP_AND, dc->op2, memsize_zz(dc));
1887 1943 do_postinc(dc, memsize);
1888 1944 return insn_len;
... ... @@ -1897,8 +1953,8 @@ static unsigned int dec_add_m(DisasContext *dc)
1897 1953 dc->op1, dc->postinc ? "+]" : "]",
1898 1954 dc->op2));
1899 1955  
1900   - cris_cc_mask(dc, CC_MASK_NZVC);
1901 1956 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1957 + cris_cc_mask(dc, CC_MASK_NZVC);
1902 1958 crisv32_alu_op(dc, CC_OP_ADD, dc->op2, memsize_zz(dc));
1903 1959 do_postinc(dc, memsize);
1904 1960 return insn_len;
... ... @@ -1913,8 +1969,8 @@ static unsigned int dec_addo_m(DisasContext *dc)
1913 1969 dc->op1, dc->postinc ? "+]" : "]",
1914 1970 dc->op2));
1915 1971  
1916   - cris_cc_mask(dc, 0);
1917 1972 insn_len = dec_prep_alu_m(dc, 1, memsize);
  1973 + cris_cc_mask(dc, 0);
1918 1974 crisv32_alu_op(dc, CC_OP_ADD, R_ACR, 4);
1919 1975 do_postinc(dc, memsize);
1920 1976 return insn_len;
... ... @@ -1929,8 +1985,8 @@ static unsigned int dec_bound_m(DisasContext *dc)
1929 1985 dc->op1, dc->postinc ? "+]" : "]",
1930 1986 dc->op2));
1931 1987  
1932   - cris_cc_mask(dc, CC_MASK_NZ);
1933 1988 insn_len = dec_prep_alu_m(dc, 0, memsize);
  1989 + cris_cc_mask(dc, CC_MASK_NZ);
1934 1990 crisv32_alu_op(dc, CC_OP_BOUND, dc->op2, 4);
1935 1991 do_postinc(dc, memsize);
1936 1992 return insn_len;
... ... @@ -1944,8 +2000,8 @@ static unsigned int dec_addc_mr(DisasContext *dc)
1944 2000 dc->op2));
1945 2001  
1946 2002 cris_evaluate_flags(dc);
1947   - cris_cc_mask(dc, CC_MASK_NZVC);
1948 2003 insn_len = dec_prep_alu_m(dc, 0, 4);
  2004 + cris_cc_mask(dc, CC_MASK_NZVC);
1949 2005 crisv32_alu_op(dc, CC_OP_ADDC, dc->op2, 4);
1950 2006 do_postinc(dc, 4);
1951 2007 return insn_len;
... ... @@ -1960,8 +2016,8 @@ static unsigned int dec_sub_m(DisasContext *dc)
1960 2016 dc->op1, dc->postinc ? "+]" : "]",
1961 2017 dc->op2, dc->ir, dc->zzsize));
1962 2018  
1963   - cris_cc_mask(dc, CC_MASK_NZVC);
1964 2019 insn_len = dec_prep_alu_m(dc, 0, memsize);
  2020 + cris_cc_mask(dc, CC_MASK_NZVC);
1965 2021 crisv32_alu_op(dc, CC_OP_SUB, dc->op2, memsize);
1966 2022 do_postinc(dc, memsize);
1967 2023 return insn_len;
... ... @@ -1976,8 +2032,8 @@ static unsigned int dec_or_m(DisasContext *dc)
1976 2032 dc->op1, dc->postinc ? "+]" : "]",
1977 2033 dc->op2, dc->pc));
1978 2034  
1979   - cris_cc_mask(dc, CC_MASK_NZ);
1980 2035 insn_len = dec_prep_alu_m(dc, 0, memsize);
  2036 + cris_cc_mask(dc, CC_MASK_NZ);
1981 2037 crisv32_alu_op(dc, CC_OP_OR, dc->op2, memsize_zz(dc));
1982 2038 do_postinc(dc, memsize);
1983 2039 return insn_len;
... ... @@ -1994,8 +2050,18 @@ static unsigned int dec_move_mp(DisasContext *dc)
1994 2050 dc->postinc ? "+]" : "]",
1995 2051 dc->op2));
1996 2052  
1997   - cris_cc_mask(dc, 0);
1998 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 2065 t_gen_mov_preg_TN(dc->op2, cpu_T[1]);
2000 2066  
2001 2067 do_postinc(dc, memsize);
... ... @@ -2012,11 +2078,11 @@ static unsigned int dec_move_pm(DisasContext *dc)
2012 2078 memsize_char(memsize),
2013 2079 dc->op2, dc->op1, dc->postinc ? "+]" : "]"));
2014 2080  
2015   - cris_cc_mask(dc, 0);
2016 2081 /* prepare store. Address in T0, value in T1. */
2017 2082 t_gen_mov_TN_preg(cpu_T[1], dc->op2);
2018 2083 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2019 2084 gen_store_T0_T1(dc, memsize);
  2085 + cris_cc_mask(dc, 0);
2020 2086 if (dc->postinc)
2021 2087 {
2022 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 2098 DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,
2033 2099 dc->postinc ? "+]" : "]", dc->op2));
2034 2100  
2035   - cris_cc_mask(dc, 0);
2036 2101 /* fetch the address into T0 and T1. */
2037 2102 t_gen_mov_TN_reg(cpu_T[1], dc->op1);
2038 2103 for (i = 0; i <= dc->op2; i++) {
2039 2104 /* Perform the load onto regnum i. Always dword wide. */
2040 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 2107 tcg_gen_addi_tl(cpu_T[1], cpu_T[1], 4);
2044 2108 }
2045 2109 /* writeback the updated pointer value. */
2046 2110 if (dc->postinc)
2047 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 2115 return 2;
2049 2116 }
2050 2117  
... ... @@ -2055,7 +2122,6 @@ static unsigned int dec_movem_rm(DisasContext *dc)
2055 2122 DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
2056 2123 dc->postinc ? "+]" : "]"));
2057 2124  
2058   - cris_cc_mask(dc, 0);
2059 2125 for (i = 0; i <= dc->op2; i++) {
2060 2126 /* Fetch register i into T1. */
2061 2127 t_gen_mov_TN_reg(cpu_T[1], i);
... ... @@ -2073,6 +2139,7 @@ static unsigned int dec_movem_rm(DisasContext *dc)
2073 2139 /* writeback the updated pointer value. */
2074 2140 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2075 2141 }
  2142 + cris_cc_mask(dc, 0);
2076 2143 return 2;
2077 2144 }
2078 2145  
... ... @@ -2085,7 +2152,6 @@ static unsigned int dec_move_rm(DisasContext *dc)
2085 2152 DIS(fprintf (logfile, "move.%d $r%u, [$r%u]\n",
2086 2153 memsize, dc->op2, dc->op1));
2087 2154  
2088   - cris_cc_mask(dc, 0);
2089 2155 /* prepare store. */
2090 2156 t_gen_mov_TN_reg(cpu_T[0], dc->op1);
2091 2157 t_gen_mov_TN_reg(cpu_T[1], dc->op2);
... ... @@ -2095,6 +2161,7 @@ static unsigned int dec_move_rm(DisasContext *dc)
2095 2161 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], memsize);
2096 2162 t_gen_mov_reg_TN(dc->op1, cpu_T[0]);
2097 2163 }
  2164 + cris_cc_mask(dc, 0);
2098 2165 return 2;
2099 2166 }
2100 2167  
... ... @@ -2112,13 +2179,17 @@ static unsigned int dec_lapc_im(DisasContext *dc)
2112 2179 {
2113 2180 unsigned int rd;
2114 2181 int32_t imm;
  2182 + int32_t pc;
2115 2183  
2116 2184 rd = dc->op2;
2117 2185  
2118 2186 cris_cc_mask(dc, 0);
2119 2187 imm = ldl_code(dc->pc + 2);
2120 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 2193 return 6;
2123 2194 }
2124 2195  
... ... @@ -2127,9 +2198,10 @@ static unsigned int dec_jump_p(DisasContext *dc)
2127 2198 {
2128 2199 DIS(fprintf (logfile, "jump $p%u\n", dc->op2));
2129 2200 cris_cc_mask(dc, 0);
2130   - /* Store the return address in Pd. */
  2201 +
2131 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 2205 cris_prepare_dyn_jmp(dc);
2134 2206 return 2;
2135 2207 }
... ... @@ -2139,11 +2211,12 @@ static unsigned int dec_jas_r(DisasContext *dc)
2139 2211 {
2140 2212 DIS(fprintf (logfile, "jas $r%u, $p%u\n", dc->op1, dc->op2));
2141 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 2220 cris_prepare_dyn_jmp(dc);
2148 2221 return 2;
2149 2222 }
... ... @@ -2157,7 +2230,7 @@ static unsigned int dec_jas_im(DisasContext *dc)
2157 2230 DIS(fprintf (logfile, "jas 0x%x\n", imm));
2158 2231 cris_cc_mask(dc, 0);
2159 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 2234 t_gen_mov_preg_TN(dc->op2, tcg_const_tl(dc->pc + 8));
2162 2235 cris_prepare_dyn_jmp(dc);
2163 2236 return 6;
... ... @@ -2260,6 +2333,11 @@ static unsigned int dec_rfe_etc(DisasContext *dc)
2260 2333 /* rfe. */
2261 2334 cris_evaluate_flags(dc);
2262 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 2341 break;
2264 2342 case 5:
2265 2343 /* rfn. */
... ... @@ -2271,7 +2349,7 @@ static unsigned int dec_rfe_etc(DisasContext *dc)
2271 2349 t_gen_mov_env_TN(pc, cpu_T[0]);
2272 2350 /* Breaks start at 16 in the exception vector. */
2273 2351 gen_op_break_im(dc->op1 + 16);
2274   - dc->is_jmp = DISAS_SWI;
  2352 + dc->is_jmp = DISAS_UPDATE;
2275 2353 break;
2276 2354 default:
2277 2355 printf ("op2=%x\n", dc->op2);
... ... @@ -2477,6 +2555,9 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2477 2555 if (!logfile)
2478 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 2561 pc_start = tb->pc;
2481 2562 dc->env = env;
2482 2563 dc->tb = tb;
... ... @@ -2484,10 +2565,35 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2484 2565 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2485 2566  
2486 2567 dc->is_jmp = DISAS_NEXT;
  2568 + dc->ppc = pc_start;
2487 2569 dc->pc = pc_start;
2488 2570 dc->singlestep_enabled = env->singlestep_enabled;
  2571 + dc->flags_live = 1;
2489 2572 dc->flagx_live = 0;
2490 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 2598 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2493 2599 lj = -1;
... ... @@ -2505,14 +2611,23 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2505 2611 while (lj < j)
2506 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 2625 insn_len = cris_decoder(dc);
2513 2626 STATS(gen_op_exec_insn());
  2627 + dc->ppc = dc->pc;
2514 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 2632 /* Check for delayed branches here. If we do it before
2518 2633 actually genereating any host code, the simulator will just
... ... @@ -2523,12 +2638,12 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2523 2638 {
2524 2639 if (dc->bcc == CC_A) {
2525 2640 gen_op_jmp1 ();
2526   - dc->is_jmp = DISAS_UPDATE;
  2641 + dc->is_jmp = DISAS_JUMP;
2527 2642 }
2528 2643 else {
2529 2644 /* Conditional jmp. */
2530 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 2651 if (env->singlestep_enabled)
2537 2652 break;
2538 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 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 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 2669 cris_evaluate_flags (dc);
... ... @@ -2580,7 +2703,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
2580 2703 fprintf(logfile, "--------------\n");
2581 2704 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2582 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 2709 #endif
2586 2710 return 0;
... ... @@ -2626,7 +2750,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
2626 2750 cpu_fprintf(f, "\n");
2627 2751 }
2628 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 2754 if (srs < 256) {
2631 2755 for (i = 0; i < 16; i++) {
2632 2756 cpu_fprintf(f, "s%2.2d=%8.8x ",
... ... @@ -2682,6 +2806,13 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
2682 2806 offsetof(CPUState, cc_mask),
2683 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 2816 for (i = 0; i < 16; i++) {
2686 2817 cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
2687 2818 offsetof(CPUState, regs[i]),
... ... @@ -2693,6 +2824,21 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
2693 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 2842 cpu_reset(env);
2697 2843 return env;
2698 2844 }
... ... @@ -2701,10 +2847,17 @@ void cpu_reset (CPUCRISState *env)
2701 2847 {
2702 2848 memset(env, 0, offsetof(CPUCRISState, breakpoints));
2703 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 2859 void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
2707 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 }
... ...