1 | /* |
2 | * Xtensa ISA: |
3 | * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm |
4 | * |
5 | * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab. |
6 | * All rights reserved. |
7 | * |
8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions are met: |
10 | * * Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * * Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * * Neither the name of the Open Source and Linux Lab nor the |
16 | * names of its contributors may be used to endorse or promote products |
17 | * derived from this software without specific prior written permission. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | */ |
30 | |
31 | #include "qemu/osdep.h" |
32 | |
33 | #include "cpu.h" |
34 | #include "exec/exec-all.h" |
35 | #include "disas/disas.h" |
36 | #include "tcg-op.h" |
37 | #include "qemu/log.h" |
38 | #include "qemu/qemu-print.h" |
39 | #include "exec/cpu_ldst.h" |
40 | #include "hw/semihosting/semihost.h" |
41 | #include "exec/translator.h" |
42 | |
43 | #include "exec/helper-proto.h" |
44 | #include "exec/helper-gen.h" |
45 | |
46 | #include "trace-tcg.h" |
47 | #include "exec/log.h" |
48 | |
49 | |
50 | struct DisasContext { |
51 | DisasContextBase base; |
52 | const XtensaConfig *config; |
53 | uint32_t pc; |
54 | int cring; |
55 | int ring; |
56 | uint32_t lbeg_off; |
57 | uint32_t lend; |
58 | |
59 | bool sar_5bit; |
60 | bool sar_m32_5bit; |
61 | bool sar_m32_allocated; |
62 | TCGv_i32 sar_m32; |
63 | |
64 | unsigned window; |
65 | unsigned callinc; |
66 | bool cwoe; |
67 | |
68 | bool debug; |
69 | bool icount; |
70 | TCGv_i32 next_icount; |
71 | |
72 | unsigned cpenable; |
73 | |
74 | uint32_t op_flags; |
75 | xtensa_insnbuf insnbuf; |
76 | xtensa_insnbuf slotbuf; |
77 | }; |
78 | |
79 | static TCGv_i32 cpu_pc; |
80 | static TCGv_i32 cpu_R[16]; |
81 | static TCGv_i32 cpu_FR[16]; |
82 | static TCGv_i32 cpu_MR[4]; |
83 | static TCGv_i32 cpu_BR[16]; |
84 | static TCGv_i32 cpu_BR4[4]; |
85 | static TCGv_i32 cpu_BR8[2]; |
86 | static TCGv_i32 cpu_SR[256]; |
87 | static TCGv_i32 cpu_UR[256]; |
88 | static TCGv_i32 cpu_windowbase_next; |
89 | static TCGv_i32 cpu_exclusive_addr; |
90 | static TCGv_i32 cpu_exclusive_val; |
91 | |
92 | static GHashTable *xtensa_regfile_table; |
93 | |
94 | #include "exec/gen-icount.h" |
95 | |
96 | static char *sr_name[256]; |
97 | static char *ur_name[256]; |
98 | |
99 | void xtensa_collect_sr_names(const XtensaConfig *config) |
100 | { |
101 | xtensa_isa isa = config->isa; |
102 | int n = xtensa_isa_num_sysregs(isa); |
103 | int i; |
104 | |
105 | for (i = 0; i < n; ++i) { |
106 | int sr = xtensa_sysreg_number(isa, i); |
107 | |
108 | if (sr >= 0 && sr < 256) { |
109 | const char *name = xtensa_sysreg_name(isa, i); |
110 | char **pname = |
111 | (xtensa_sysreg_is_user(isa, i) ? ur_name : sr_name) + sr; |
112 | |
113 | if (*pname) { |
114 | if (strstr(*pname, name) == NULL) { |
115 | char *new_name = |
116 | malloc(strlen(*pname) + strlen(name) + 2); |
117 | |
118 | strcpy(new_name, *pname); |
119 | strcat(new_name, "/" ); |
120 | strcat(new_name, name); |
121 | free(*pname); |
122 | *pname = new_name; |
123 | } |
124 | } else { |
125 | *pname = strdup(name); |
126 | } |
127 | } |
128 | } |
129 | } |
130 | |
131 | void xtensa_translate_init(void) |
132 | { |
133 | static const char * const regnames[] = { |
134 | "ar0" , "ar1" , "ar2" , "ar3" , |
135 | "ar4" , "ar5" , "ar6" , "ar7" , |
136 | "ar8" , "ar9" , "ar10" , "ar11" , |
137 | "ar12" , "ar13" , "ar14" , "ar15" , |
138 | }; |
139 | static const char * const fregnames[] = { |
140 | "f0" , "f1" , "f2" , "f3" , |
141 | "f4" , "f5" , "f6" , "f7" , |
142 | "f8" , "f9" , "f10" , "f11" , |
143 | "f12" , "f13" , "f14" , "f15" , |
144 | }; |
145 | static const char * const mregnames[] = { |
146 | "m0" , "m1" , "m2" , "m3" , |
147 | }; |
148 | static const char * const bregnames[] = { |
149 | "b0" , "b1" , "b2" , "b3" , |
150 | "b4" , "b5" , "b6" , "b7" , |
151 | "b8" , "b9" , "b10" , "b11" , |
152 | "b12" , "b13" , "b14" , "b15" , |
153 | }; |
154 | int i; |
155 | |
156 | cpu_pc = tcg_global_mem_new_i32(cpu_env, |
157 | offsetof(CPUXtensaState, pc), "pc" ); |
158 | |
159 | for (i = 0; i < 16; i++) { |
160 | cpu_R[i] = tcg_global_mem_new_i32(cpu_env, |
161 | offsetof(CPUXtensaState, regs[i]), |
162 | regnames[i]); |
163 | } |
164 | |
165 | for (i = 0; i < 16; i++) { |
166 | cpu_FR[i] = tcg_global_mem_new_i32(cpu_env, |
167 | offsetof(CPUXtensaState, |
168 | fregs[i].f32[FP_F32_LOW]), |
169 | fregnames[i]); |
170 | } |
171 | |
172 | for (i = 0; i < 4; i++) { |
173 | cpu_MR[i] = tcg_global_mem_new_i32(cpu_env, |
174 | offsetof(CPUXtensaState, |
175 | sregs[MR + i]), |
176 | mregnames[i]); |
177 | } |
178 | |
179 | for (i = 0; i < 16; i++) { |
180 | cpu_BR[i] = tcg_global_mem_new_i32(cpu_env, |
181 | offsetof(CPUXtensaState, |
182 | sregs[BR]), |
183 | bregnames[i]); |
184 | if (i % 4 == 0) { |
185 | cpu_BR4[i / 4] = tcg_global_mem_new_i32(cpu_env, |
186 | offsetof(CPUXtensaState, |
187 | sregs[BR]), |
188 | bregnames[i]); |
189 | } |
190 | if (i % 8 == 0) { |
191 | cpu_BR8[i / 8] = tcg_global_mem_new_i32(cpu_env, |
192 | offsetof(CPUXtensaState, |
193 | sregs[BR]), |
194 | bregnames[i]); |
195 | } |
196 | } |
197 | |
198 | for (i = 0; i < 256; ++i) { |
199 | if (sr_name[i]) { |
200 | cpu_SR[i] = tcg_global_mem_new_i32(cpu_env, |
201 | offsetof(CPUXtensaState, |
202 | sregs[i]), |
203 | sr_name[i]); |
204 | } |
205 | } |
206 | |
207 | for (i = 0; i < 256; ++i) { |
208 | if (ur_name[i]) { |
209 | cpu_UR[i] = tcg_global_mem_new_i32(cpu_env, |
210 | offsetof(CPUXtensaState, |
211 | uregs[i]), |
212 | ur_name[i]); |
213 | } |
214 | } |
215 | |
216 | cpu_windowbase_next = |
217 | tcg_global_mem_new_i32(cpu_env, |
218 | offsetof(CPUXtensaState, windowbase_next), |
219 | "windowbase_next" ); |
220 | cpu_exclusive_addr = |
221 | tcg_global_mem_new_i32(cpu_env, |
222 | offsetof(CPUXtensaState, exclusive_addr), |
223 | "exclusive_addr" ); |
224 | cpu_exclusive_val = |
225 | tcg_global_mem_new_i32(cpu_env, |
226 | offsetof(CPUXtensaState, exclusive_val), |
227 | "exclusive_val" ); |
228 | } |
229 | |
230 | void **xtensa_get_regfile_by_name(const char *name) |
231 | { |
232 | if (xtensa_regfile_table == NULL) { |
233 | xtensa_regfile_table = g_hash_table_new(g_str_hash, g_str_equal); |
234 | g_hash_table_insert(xtensa_regfile_table, |
235 | (void *)"AR" , (void *)cpu_R); |
236 | g_hash_table_insert(xtensa_regfile_table, |
237 | (void *)"MR" , (void *)cpu_MR); |
238 | g_hash_table_insert(xtensa_regfile_table, |
239 | (void *)"FR" , (void *)cpu_FR); |
240 | g_hash_table_insert(xtensa_regfile_table, |
241 | (void *)"BR" , (void *)cpu_BR); |
242 | g_hash_table_insert(xtensa_regfile_table, |
243 | (void *)"BR4" , (void *)cpu_BR4); |
244 | g_hash_table_insert(xtensa_regfile_table, |
245 | (void *)"BR8" , (void *)cpu_BR8); |
246 | } |
247 | return (void **)g_hash_table_lookup(xtensa_regfile_table, (void *)name); |
248 | } |
249 | |
250 | static inline bool option_enabled(DisasContext *dc, int opt) |
251 | { |
252 | return xtensa_option_enabled(dc->config, opt); |
253 | } |
254 | |
255 | static void init_sar_tracker(DisasContext *dc) |
256 | { |
257 | dc->sar_5bit = false; |
258 | dc->sar_m32_5bit = false; |
259 | dc->sar_m32_allocated = false; |
260 | } |
261 | |
262 | static void reset_sar_tracker(DisasContext *dc) |
263 | { |
264 | if (dc->sar_m32_allocated) { |
265 | tcg_temp_free(dc->sar_m32); |
266 | } |
267 | } |
268 | |
269 | static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa) |
270 | { |
271 | tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f); |
272 | if (dc->sar_m32_5bit) { |
273 | tcg_gen_discard_i32(dc->sar_m32); |
274 | } |
275 | dc->sar_5bit = true; |
276 | dc->sar_m32_5bit = false; |
277 | } |
278 | |
279 | static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa) |
280 | { |
281 | TCGv_i32 tmp = tcg_const_i32(32); |
282 | if (!dc->sar_m32_allocated) { |
283 | dc->sar_m32 = tcg_temp_local_new_i32(); |
284 | dc->sar_m32_allocated = true; |
285 | } |
286 | tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f); |
287 | tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32); |
288 | dc->sar_5bit = false; |
289 | dc->sar_m32_5bit = true; |
290 | tcg_temp_free(tmp); |
291 | } |
292 | |
293 | static void gen_exception(DisasContext *dc, int excp) |
294 | { |
295 | TCGv_i32 tmp = tcg_const_i32(excp); |
296 | gen_helper_exception(cpu_env, tmp); |
297 | tcg_temp_free(tmp); |
298 | } |
299 | |
300 | static void gen_exception_cause(DisasContext *dc, uint32_t cause) |
301 | { |
302 | TCGv_i32 tpc = tcg_const_i32(dc->pc); |
303 | TCGv_i32 tcause = tcg_const_i32(cause); |
304 | gen_helper_exception_cause(cpu_env, tpc, tcause); |
305 | tcg_temp_free(tpc); |
306 | tcg_temp_free(tcause); |
307 | if (cause == ILLEGAL_INSTRUCTION_CAUSE || |
308 | cause == SYSCALL_CAUSE) { |
309 | dc->base.is_jmp = DISAS_NORETURN; |
310 | } |
311 | } |
312 | |
313 | static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause, |
314 | TCGv_i32 vaddr) |
315 | { |
316 | TCGv_i32 tpc = tcg_const_i32(dc->pc); |
317 | TCGv_i32 tcause = tcg_const_i32(cause); |
318 | gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr); |
319 | tcg_temp_free(tpc); |
320 | tcg_temp_free(tcause); |
321 | } |
322 | |
323 | static void gen_debug_exception(DisasContext *dc, uint32_t cause) |
324 | { |
325 | TCGv_i32 tpc = tcg_const_i32(dc->pc); |
326 | TCGv_i32 tcause = tcg_const_i32(cause); |
327 | gen_helper_debug_exception(cpu_env, tpc, tcause); |
328 | tcg_temp_free(tpc); |
329 | tcg_temp_free(tcause); |
330 | if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) { |
331 | dc->base.is_jmp = DISAS_NORETURN; |
332 | } |
333 | } |
334 | |
335 | static bool gen_check_privilege(DisasContext *dc) |
336 | { |
337 | #ifndef CONFIG_USER_ONLY |
338 | if (!dc->cring) { |
339 | return true; |
340 | } |
341 | #endif |
342 | gen_exception_cause(dc, PRIVILEGED_CAUSE); |
343 | dc->base.is_jmp = DISAS_NORETURN; |
344 | return false; |
345 | } |
346 | |
347 | static bool gen_check_cpenable(DisasContext *dc, uint32_t cp_mask) |
348 | { |
349 | cp_mask &= ~dc->cpenable; |
350 | |
351 | if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) && cp_mask) { |
352 | gen_exception_cause(dc, COPROCESSOR0_DISABLED + ctz32(cp_mask)); |
353 | dc->base.is_jmp = DISAS_NORETURN; |
354 | return false; |
355 | } |
356 | return true; |
357 | } |
358 | |
359 | static int gen_postprocess(DisasContext *dc, int slot); |
360 | |
361 | static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot) |
362 | { |
363 | tcg_gen_mov_i32(cpu_pc, dest); |
364 | if (dc->icount) { |
365 | tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); |
366 | } |
367 | if (dc->base.singlestep_enabled) { |
368 | gen_exception(dc, EXCP_DEBUG); |
369 | } else { |
370 | if (dc->op_flags & XTENSA_OP_POSTPROCESS) { |
371 | slot = gen_postprocess(dc, slot); |
372 | } |
373 | if (slot >= 0) { |
374 | tcg_gen_goto_tb(slot); |
375 | tcg_gen_exit_tb(dc->base.tb, slot); |
376 | } else { |
377 | tcg_gen_exit_tb(NULL, 0); |
378 | } |
379 | } |
380 | dc->base.is_jmp = DISAS_NORETURN; |
381 | } |
382 | |
383 | static void gen_jump(DisasContext *dc, TCGv dest) |
384 | { |
385 | gen_jump_slot(dc, dest, -1); |
386 | } |
387 | |
388 | static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot) |
389 | { |
390 | if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) { |
391 | return -1; |
392 | } else { |
393 | return slot; |
394 | } |
395 | } |
396 | |
397 | static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot) |
398 | { |
399 | TCGv_i32 tmp = tcg_const_i32(dest); |
400 | gen_jump_slot(dc, tmp, adjust_jump_slot(dc, dest, slot)); |
401 | tcg_temp_free(tmp); |
402 | } |
403 | |
404 | static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest, |
405 | int slot) |
406 | { |
407 | TCGv_i32 tcallinc = tcg_const_i32(callinc); |
408 | |
409 | tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS], |
410 | tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN); |
411 | tcg_temp_free(tcallinc); |
412 | tcg_gen_movi_i32(cpu_R[callinc << 2], |
413 | (callinc << 30) | (dc->base.pc_next & 0x3fffffff)); |
414 | gen_jump_slot(dc, dest, slot); |
415 | } |
416 | |
417 | static bool gen_check_loop_end(DisasContext *dc, int slot) |
418 | { |
419 | if (dc->base.pc_next == dc->lend) { |
420 | TCGLabel *label = gen_new_label(); |
421 | |
422 | tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label); |
423 | tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1); |
424 | if (dc->lbeg_off) { |
425 | gen_jumpi(dc, dc->base.pc_next - dc->lbeg_off, slot); |
426 | } else { |
427 | gen_jump(dc, cpu_SR[LBEG]); |
428 | } |
429 | gen_set_label(label); |
430 | gen_jumpi(dc, dc->base.pc_next, -1); |
431 | return true; |
432 | } |
433 | return false; |
434 | } |
435 | |
436 | static void gen_jumpi_check_loop_end(DisasContext *dc, int slot) |
437 | { |
438 | if (!gen_check_loop_end(dc, slot)) { |
439 | gen_jumpi(dc, dc->base.pc_next, slot); |
440 | } |
441 | } |
442 | |
443 | static void gen_brcond(DisasContext *dc, TCGCond cond, |
444 | TCGv_i32 t0, TCGv_i32 t1, uint32_t addr) |
445 | { |
446 | TCGLabel *label = gen_new_label(); |
447 | |
448 | tcg_gen_brcond_i32(cond, t0, t1, label); |
449 | gen_jumpi_check_loop_end(dc, 0); |
450 | gen_set_label(label); |
451 | gen_jumpi(dc, addr, 1); |
452 | } |
453 | |
454 | static void gen_brcondi(DisasContext *dc, TCGCond cond, |
455 | TCGv_i32 t0, uint32_t t1, uint32_t addr) |
456 | { |
457 | TCGv_i32 tmp = tcg_const_i32(t1); |
458 | gen_brcond(dc, cond, t0, tmp, addr); |
459 | tcg_temp_free(tmp); |
460 | } |
461 | |
462 | static bool test_ill_sr(DisasContext *dc, const OpcodeArg arg[], |
463 | const uint32_t par[]) |
464 | { |
465 | return !xtensa_option_enabled(dc->config, par[1]); |
466 | } |
467 | |
468 | static bool test_ill_ccompare(DisasContext *dc, const OpcodeArg arg[], |
469 | const uint32_t par[]) |
470 | { |
471 | unsigned n = par[0] - CCOMPARE; |
472 | |
473 | return test_ill_sr(dc, arg, par) || n >= dc->config->nccompare; |
474 | } |
475 | |
476 | static bool test_ill_dbreak(DisasContext *dc, const OpcodeArg arg[], |
477 | const uint32_t par[]) |
478 | { |
479 | unsigned n = MAX_NDBREAK; |
480 | |
481 | if (par[0] >= DBREAKA && par[0] < DBREAKA + MAX_NDBREAK) { |
482 | n = par[0] - DBREAKA; |
483 | } |
484 | if (par[0] >= DBREAKC && par[0] < DBREAKC + MAX_NDBREAK) { |
485 | n = par[0] - DBREAKC; |
486 | } |
487 | return test_ill_sr(dc, arg, par) || n >= dc->config->ndbreak; |
488 | } |
489 | |
490 | static bool test_ill_ibreak(DisasContext *dc, const OpcodeArg arg[], |
491 | const uint32_t par[]) |
492 | { |
493 | unsigned n = par[0] - IBREAKA; |
494 | |
495 | return test_ill_sr(dc, arg, par) || n >= dc->config->nibreak; |
496 | } |
497 | |
498 | static bool test_ill_hpi(DisasContext *dc, const OpcodeArg arg[], |
499 | const uint32_t par[]) |
500 | { |
501 | unsigned n = MAX_NLEVEL + 1; |
502 | |
503 | if (par[0] >= EXCSAVE1 && par[0] < EXCSAVE1 + MAX_NLEVEL) { |
504 | n = par[0] - EXCSAVE1 + 1; |
505 | } |
506 | if (par[0] >= EPC1 && par[0] < EPC1 + MAX_NLEVEL) { |
507 | n = par[0] - EPC1 + 1; |
508 | } |
509 | if (par[0] >= EPS2 && par[0] < EPS2 + MAX_NLEVEL - 1) { |
510 | n = par[0] - EPS2 + 2; |
511 | } |
512 | return test_ill_sr(dc, arg, par) || n > dc->config->nlevel; |
513 | } |
514 | |
515 | static void gen_load_store_alignment(DisasContext *dc, int shift, |
516 | TCGv_i32 addr, bool no_hw_alignment) |
517 | { |
518 | if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) { |
519 | tcg_gen_andi_i32(addr, addr, ~0 << shift); |
520 | } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) && |
521 | no_hw_alignment) { |
522 | TCGLabel *label = gen_new_label(); |
523 | TCGv_i32 tmp = tcg_temp_new_i32(); |
524 | tcg_gen_andi_i32(tmp, addr, ~(~0 << shift)); |
525 | tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label); |
526 | gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr); |
527 | gen_set_label(label); |
528 | tcg_temp_free(tmp); |
529 | } |
530 | } |
531 | |
532 | #ifndef CONFIG_USER_ONLY |
533 | static void gen_waiti(DisasContext *dc, uint32_t imm4) |
534 | { |
535 | TCGv_i32 pc = tcg_const_i32(dc->base.pc_next); |
536 | TCGv_i32 intlevel = tcg_const_i32(imm4); |
537 | |
538 | if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { |
539 | gen_io_start(); |
540 | } |
541 | gen_helper_waiti(cpu_env, pc, intlevel); |
542 | tcg_temp_free(pc); |
543 | tcg_temp_free(intlevel); |
544 | } |
545 | #endif |
546 | |
547 | static bool gen_window_check(DisasContext *dc, uint32_t mask) |
548 | { |
549 | unsigned r = 31 - clz32(mask); |
550 | |
551 | if (r / 4 > dc->window) { |
552 | TCGv_i32 pc = tcg_const_i32(dc->pc); |
553 | TCGv_i32 w = tcg_const_i32(r / 4); |
554 | |
555 | gen_helper_window_check(cpu_env, pc, w); |
556 | dc->base.is_jmp = DISAS_NORETURN; |
557 | return false; |
558 | } |
559 | return true; |
560 | } |
561 | |
562 | static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned) |
563 | { |
564 | TCGv_i32 m = tcg_temp_new_i32(); |
565 | |
566 | if (hi) { |
567 | (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16); |
568 | } else { |
569 | (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v); |
570 | } |
571 | return m; |
572 | } |
573 | |
574 | static void gen_zero_check(DisasContext *dc, const OpcodeArg arg[]) |
575 | { |
576 | TCGLabel *label = gen_new_label(); |
577 | |
578 | tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0, label); |
579 | gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE); |
580 | gen_set_label(label); |
581 | } |
582 | |
583 | static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0) |
584 | { |
585 | return xtensa_isa_length_from_chars(dc->config->isa, &op0); |
586 | } |
587 | |
588 | static int gen_postprocess(DisasContext *dc, int slot) |
589 | { |
590 | uint32_t op_flags = dc->op_flags; |
591 | |
592 | #ifndef CONFIG_USER_ONLY |
593 | if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) { |
594 | if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { |
595 | gen_io_start(); |
596 | } |
597 | gen_helper_check_interrupts(cpu_env); |
598 | if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { |
599 | gen_io_end(); |
600 | } |
601 | } |
602 | #endif |
603 | if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) { |
604 | gen_helper_sync_windowbase(cpu_env); |
605 | } |
606 | if (op_flags & XTENSA_OP_EXIT_TB_M1) { |
607 | slot = -1; |
608 | } |
609 | return slot; |
610 | } |
611 | |
612 | struct opcode_arg_copy { |
613 | uint32_t resource; |
614 | void *temp; |
615 | OpcodeArg *arg; |
616 | }; |
617 | |
618 | struct opcode_arg_info { |
619 | uint32_t resource; |
620 | int index; |
621 | }; |
622 | |
623 | struct slot_prop { |
624 | XtensaOpcodeOps *ops; |
625 | OpcodeArg arg[MAX_OPCODE_ARGS]; |
626 | struct opcode_arg_info in[MAX_OPCODE_ARGS]; |
627 | struct opcode_arg_info out[MAX_OPCODE_ARGS]; |
628 | unsigned n_in; |
629 | unsigned n_out; |
630 | uint32_t op_flags; |
631 | }; |
632 | |
633 | enum resource_type { |
634 | RES_REGFILE, |
635 | RES_STATE, |
636 | RES_MAX, |
637 | }; |
638 | |
639 | static uint32_t encode_resource(enum resource_type r, unsigned g, unsigned n) |
640 | { |
641 | assert(r < RES_MAX && g < 256 && n < 65536); |
642 | return (r << 24) | (g << 16) | n; |
643 | } |
644 | |
645 | static enum resource_type get_resource_type(uint32_t resource) |
646 | { |
647 | return resource >> 24; |
648 | } |
649 | |
650 | /* |
651 | * a depends on b if b must be executed before a, |
652 | * because a's side effects will destroy b's inputs. |
653 | */ |
654 | static bool op_depends_on(const struct slot_prop *a, |
655 | const struct slot_prop *b) |
656 | { |
657 | unsigned i = 0; |
658 | unsigned j = 0; |
659 | |
660 | if (a->op_flags & XTENSA_OP_CONTROL_FLOW) { |
661 | return true; |
662 | } |
663 | if ((a->op_flags & XTENSA_OP_LOAD_STORE) < |
664 | (b->op_flags & XTENSA_OP_LOAD_STORE)) { |
665 | return true; |
666 | } |
667 | while (i < a->n_out && j < b->n_in) { |
668 | if (a->out[i].resource < b->in[j].resource) { |
669 | ++i; |
670 | } else if (a->out[i].resource > b->in[j].resource) { |
671 | ++j; |
672 | } else { |
673 | return true; |
674 | } |
675 | } |
676 | return false; |
677 | } |
678 | |
679 | /* |
680 | * Try to break a dependency on b, append temporary register copy records |
681 | * to the end of copy and update n_copy in case of success. |
682 | * This is not always possible: e.g. control flow must always be the last, |
683 | * load/store must be first and state dependencies are not supported yet. |
684 | */ |
685 | static bool break_dependency(struct slot_prop *a, |
686 | struct slot_prop *b, |
687 | struct opcode_arg_copy *copy, |
688 | unsigned *n_copy) |
689 | { |
690 | unsigned i = 0; |
691 | unsigned j = 0; |
692 | unsigned n = *n_copy; |
693 | bool rv = false; |
694 | |
695 | if (a->op_flags & XTENSA_OP_CONTROL_FLOW) { |
696 | return false; |
697 | } |
698 | if ((a->op_flags & XTENSA_OP_LOAD_STORE) < |
699 | (b->op_flags & XTENSA_OP_LOAD_STORE)) { |
700 | return false; |
701 | } |
702 | while (i < a->n_out && j < b->n_in) { |
703 | if (a->out[i].resource < b->in[j].resource) { |
704 | ++i; |
705 | } else if (a->out[i].resource > b->in[j].resource) { |
706 | ++j; |
707 | } else { |
708 | int index = b->in[j].index; |
709 | |
710 | if (get_resource_type(a->out[i].resource) != RES_REGFILE || |
711 | index < 0) { |
712 | return false; |
713 | } |
714 | copy[n].resource = b->in[j].resource; |
715 | copy[n].arg = b->arg + index; |
716 | ++n; |
717 | ++j; |
718 | rv = true; |
719 | } |
720 | } |
721 | *n_copy = n; |
722 | return rv; |
723 | } |
724 | |
725 | /* |
726 | * Calculate evaluation order for slot opcodes. |
727 | * Build opcode order graph and output its nodes in topological sort order. |
728 | * An edge a -> b in the graph means that opcode a must be followed by |
729 | * opcode b. |
730 | */ |
731 | static bool tsort(struct slot_prop *slot, |
732 | struct slot_prop *sorted[], |
733 | unsigned n, |
734 | struct opcode_arg_copy *copy, |
735 | unsigned *n_copy) |
736 | { |
737 | struct tsnode { |
738 | unsigned n_in_edge; |
739 | unsigned n_out_edge; |
740 | unsigned out_edge[MAX_INSN_SLOTS]; |
741 | } node[MAX_INSN_SLOTS]; |
742 | |
743 | unsigned in[MAX_INSN_SLOTS]; |
744 | unsigned i, j; |
745 | unsigned n_in = 0; |
746 | unsigned n_out = 0; |
747 | unsigned n_edge = 0; |
748 | unsigned in_idx = 0; |
749 | unsigned node_idx = 0; |
750 | |
751 | for (i = 0; i < n; ++i) { |
752 | node[i].n_in_edge = 0; |
753 | node[i].n_out_edge = 0; |
754 | } |
755 | |
756 | for (i = 0; i < n; ++i) { |
757 | unsigned n_out_edge = 0; |
758 | |
759 | for (j = 0; j < n; ++j) { |
760 | if (i != j && op_depends_on(slot + j, slot + i)) { |
761 | node[i].out_edge[n_out_edge] = j; |
762 | ++node[j].n_in_edge; |
763 | ++n_out_edge; |
764 | ++n_edge; |
765 | } |
766 | } |
767 | node[i].n_out_edge = n_out_edge; |
768 | } |
769 | |
770 | for (i = 0; i < n; ++i) { |
771 | if (!node[i].n_in_edge) { |
772 | in[n_in] = i; |
773 | ++n_in; |
774 | } |
775 | } |
776 | |
777 | again: |
778 | for (; in_idx < n_in; ++in_idx) { |
779 | i = in[in_idx]; |
780 | sorted[n_out] = slot + i; |
781 | ++n_out; |
782 | for (j = 0; j < node[i].n_out_edge; ++j) { |
783 | --n_edge; |
784 | if (--node[node[i].out_edge[j]].n_in_edge == 0) { |
785 | in[n_in] = node[i].out_edge[j]; |
786 | ++n_in; |
787 | } |
788 | } |
789 | } |
790 | if (n_edge) { |
791 | for (; node_idx < n; ++node_idx) { |
792 | struct tsnode *cnode = node + node_idx; |
793 | |
794 | if (cnode->n_in_edge) { |
795 | for (j = 0; j < cnode->n_out_edge; ++j) { |
796 | unsigned k = cnode->out_edge[j]; |
797 | |
798 | if (break_dependency(slot + k, slot + node_idx, |
799 | copy, n_copy) && |
800 | --node[k].n_in_edge == 0) { |
801 | in[n_in] = k; |
802 | ++n_in; |
803 | --n_edge; |
804 | cnode->out_edge[j] = |
805 | cnode->out_edge[cnode->n_out_edge - 1]; |
806 | --cnode->n_out_edge; |
807 | goto again; |
808 | } |
809 | } |
810 | } |
811 | } |
812 | } |
813 | return n_edge == 0; |
814 | } |
815 | |
816 | static void opcode_add_resource(struct slot_prop *op, |
817 | uint32_t resource, char direction, |
818 | int index) |
819 | { |
820 | switch (direction) { |
821 | case 'm': |
822 | case 'i': |
823 | assert(op->n_in < ARRAY_SIZE(op->in)); |
824 | op->in[op->n_in].resource = resource; |
825 | op->in[op->n_in].index = index; |
826 | ++op->n_in; |
827 | /* fall through */ |
828 | case 'o': |
829 | if (direction == 'm' || direction == 'o') { |
830 | assert(op->n_out < ARRAY_SIZE(op->out)); |
831 | op->out[op->n_out].resource = resource; |
832 | op->out[op->n_out].index = index; |
833 | ++op->n_out; |
834 | } |
835 | break; |
836 | default: |
837 | g_assert_not_reached(); |
838 | } |
839 | } |
840 | |
841 | static int resource_compare(const void *a, const void *b) |
842 | { |
843 | const struct opcode_arg_info *pa = a; |
844 | const struct opcode_arg_info *pb = b; |
845 | |
846 | return pa->resource < pb->resource ? |
847 | -1 : (pa->resource > pb->resource ? 1 : 0); |
848 | } |
849 | |
850 | static int arg_copy_compare(const void *a, const void *b) |
851 | { |
852 | const struct opcode_arg_copy *pa = a; |
853 | const struct opcode_arg_copy *pb = b; |
854 | |
855 | return pa->resource < pb->resource ? |
856 | -1 : (pa->resource > pb->resource ? 1 : 0); |
857 | } |
858 | |
859 | static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) |
860 | { |
861 | xtensa_isa isa = dc->config->isa; |
862 | unsigned char b[MAX_INSN_LENGTH] = {cpu_ldub_code(env, dc->pc)}; |
863 | unsigned len = xtensa_op0_insn_len(dc, b[0]); |
864 | xtensa_format fmt; |
865 | int slot, slots; |
866 | unsigned i; |
867 | uint32_t op_flags = 0; |
868 | struct slot_prop slot_prop[MAX_INSN_SLOTS]; |
869 | struct slot_prop *ordered[MAX_INSN_SLOTS]; |
870 | struct opcode_arg_copy arg_copy[MAX_INSN_SLOTS * MAX_OPCODE_ARGS]; |
871 | unsigned n_arg_copy = 0; |
872 | uint32_t debug_cause = 0; |
873 | uint32_t windowed_register = 0; |
874 | uint32_t coprocessor = 0; |
875 | |
876 | if (len == XTENSA_UNDEFINED) { |
877 | qemu_log_mask(LOG_GUEST_ERROR, |
878 | "unknown instruction length (pc = %08x)\n" , |
879 | dc->pc); |
880 | gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); |
881 | return; |
882 | } |
883 | |
884 | dc->base.pc_next = dc->pc + len; |
885 | for (i = 1; i < len; ++i) { |
886 | b[i] = cpu_ldub_code(env, dc->pc + i); |
887 | } |
888 | xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len); |
889 | fmt = xtensa_format_decode(isa, dc->insnbuf); |
890 | if (fmt == XTENSA_UNDEFINED) { |
891 | qemu_log_mask(LOG_GUEST_ERROR, |
892 | "unrecognized instruction format (pc = %08x)\n" , |
893 | dc->pc); |
894 | gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); |
895 | return; |
896 | } |
897 | slots = xtensa_format_num_slots(isa, fmt); |
898 | for (slot = 0; slot < slots; ++slot) { |
899 | xtensa_opcode opc; |
900 | int opnd, vopnd, opnds; |
901 | OpcodeArg *arg = slot_prop[slot].arg; |
902 | XtensaOpcodeOps *ops; |
903 | |
904 | xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf); |
905 | opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf); |
906 | if (opc == XTENSA_UNDEFINED) { |
907 | qemu_log_mask(LOG_GUEST_ERROR, |
908 | "unrecognized opcode in slot %d (pc = %08x)\n" , |
909 | slot, dc->pc); |
910 | gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); |
911 | return; |
912 | } |
913 | opnds = xtensa_opcode_num_operands(isa, opc); |
914 | |
915 | for (opnd = vopnd = 0; opnd < opnds; ++opnd) { |
916 | void **register_file = NULL; |
917 | |
918 | if (xtensa_operand_is_register(isa, opc, opnd)) { |
919 | xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd); |
920 | |
921 | register_file = dc->config->regfile[rf]; |
922 | |
923 | if (rf == dc->config->a_regfile) { |
924 | uint32_t v; |
925 | |
926 | xtensa_operand_get_field(isa, opc, opnd, fmt, slot, |
927 | dc->slotbuf, &v); |
928 | xtensa_operand_decode(isa, opc, opnd, &v); |
929 | windowed_register |= 1u << v; |
930 | } |
931 | } |
932 | if (xtensa_operand_is_visible(isa, opc, opnd)) { |
933 | uint32_t v; |
934 | |
935 | xtensa_operand_get_field(isa, opc, opnd, fmt, slot, |
936 | dc->slotbuf, &v); |
937 | xtensa_operand_decode(isa, opc, opnd, &v); |
938 | arg[vopnd].raw_imm = v; |
939 | if (xtensa_operand_is_PCrelative(isa, opc, opnd)) { |
940 | xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc); |
941 | } |
942 | arg[vopnd].imm = v; |
943 | if (register_file) { |
944 | arg[vopnd].in = register_file[v]; |
945 | arg[vopnd].out = register_file[v]; |
946 | } |
947 | ++vopnd; |
948 | } |
949 | } |
950 | ops = dc->config->opcode_ops[opc]; |
951 | slot_prop[slot].ops = ops; |
952 | |
953 | if (ops) { |
954 | op_flags |= ops->op_flags; |
955 | } else { |
956 | qemu_log_mask(LOG_UNIMP, |
957 | "unimplemented opcode '%s' in slot %d (pc = %08x)\n" , |
958 | xtensa_opcode_name(isa, opc), slot, dc->pc); |
959 | op_flags |= XTENSA_OP_ILL; |
960 | } |
961 | if ((op_flags & XTENSA_OP_ILL) || |
962 | (ops && ops->test_ill && ops->test_ill(dc, arg, ops->par))) { |
963 | gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); |
964 | return; |
965 | } |
966 | if (ops->op_flags & XTENSA_OP_DEBUG_BREAK) { |
967 | debug_cause |= ops->par[0]; |
968 | } |
969 | if (ops->test_overflow) { |
970 | windowed_register |= ops->test_overflow(dc, arg, ops->par); |
971 | } |
972 | coprocessor |= ops->coprocessor; |
973 | |
974 | if (slots > 1) { |
975 | slot_prop[slot].n_in = 0; |
976 | slot_prop[slot].n_out = 0; |
977 | slot_prop[slot].op_flags = ops->op_flags & XTENSA_OP_LOAD_STORE; |
978 | |
979 | opnds = xtensa_opcode_num_operands(isa, opc); |
980 | |
981 | for (opnd = vopnd = 0; opnd < opnds; ++opnd) { |
982 | bool visible = xtensa_operand_is_visible(isa, opc, opnd); |
983 | |
984 | if (xtensa_operand_is_register(isa, opc, opnd)) { |
985 | xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd); |
986 | uint32_t v = 0; |
987 | |
988 | xtensa_operand_get_field(isa, opc, opnd, fmt, slot, |
989 | dc->slotbuf, &v); |
990 | xtensa_operand_decode(isa, opc, opnd, &v); |
991 | opcode_add_resource(slot_prop + slot, |
992 | encode_resource(RES_REGFILE, rf, v), |
993 | xtensa_operand_inout(isa, opc, opnd), |
994 | visible ? vopnd : -1); |
995 | } |
996 | if (visible) { |
997 | ++vopnd; |
998 | } |
999 | } |
1000 | |
1001 | opnds = xtensa_opcode_num_stateOperands(isa, opc); |
1002 | |
1003 | for (opnd = 0; opnd < opnds; ++opnd) { |
1004 | xtensa_state state = xtensa_stateOperand_state(isa, opc, opnd); |
1005 | |
1006 | opcode_add_resource(slot_prop + slot, |
1007 | encode_resource(RES_STATE, 0, state), |
1008 | xtensa_stateOperand_inout(isa, opc, opnd), |
1009 | -1); |
1010 | } |
1011 | if (xtensa_opcode_is_branch(isa, opc) || |
1012 | xtensa_opcode_is_jump(isa, opc) || |
1013 | xtensa_opcode_is_loop(isa, opc) || |
1014 | xtensa_opcode_is_call(isa, opc)) { |
1015 | slot_prop[slot].op_flags |= XTENSA_OP_CONTROL_FLOW; |
1016 | } |
1017 | |
1018 | qsort(slot_prop[slot].in, slot_prop[slot].n_in, |
1019 | sizeof(slot_prop[slot].in[0]), resource_compare); |
1020 | qsort(slot_prop[slot].out, slot_prop[slot].n_out, |
1021 | sizeof(slot_prop[slot].out[0]), resource_compare); |
1022 | } |
1023 | } |
1024 | |
1025 | if (slots > 1) { |
1026 | if (!tsort(slot_prop, ordered, slots, arg_copy, &n_arg_copy)) { |
1027 | qemu_log_mask(LOG_UNIMP, |
1028 | "Circular resource dependencies (pc = %08x)\n" , |
1029 | dc->pc); |
1030 | gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); |
1031 | return; |
1032 | } |
1033 | } else { |
1034 | ordered[0] = slot_prop + 0; |
1035 | } |
1036 | |
1037 | if ((op_flags & XTENSA_OP_PRIVILEGED) && |
1038 | !gen_check_privilege(dc)) { |
1039 | return; |
1040 | } |
1041 | |
1042 | if (op_flags & XTENSA_OP_SYSCALL) { |
1043 | gen_exception_cause(dc, SYSCALL_CAUSE); |
1044 | return; |
1045 | } |
1046 | |
1047 | if ((op_flags & XTENSA_OP_DEBUG_BREAK) && dc->debug) { |
1048 | gen_debug_exception(dc, debug_cause); |
1049 | return; |
1050 | } |
1051 | |
1052 | if (windowed_register && !gen_window_check(dc, windowed_register)) { |
1053 | return; |
1054 | } |
1055 | |
1056 | if (op_flags & XTENSA_OP_UNDERFLOW) { |
1057 | TCGv_i32 tmp = tcg_const_i32(dc->pc); |
1058 | |
1059 | gen_helper_test_underflow_retw(cpu_env, tmp); |
1060 | tcg_temp_free(tmp); |
1061 | } |
1062 | |
1063 | if (op_flags & XTENSA_OP_ALLOCA) { |
1064 | TCGv_i32 tmp = tcg_const_i32(dc->pc); |
1065 | |
1066 | gen_helper_movsp(cpu_env, tmp); |
1067 | tcg_temp_free(tmp); |
1068 | } |
1069 | |
1070 | if (coprocessor && !gen_check_cpenable(dc, coprocessor)) { |
1071 | return; |
1072 | } |
1073 | |
1074 | if (n_arg_copy) { |
1075 | uint32_t resource; |
1076 | void *temp; |
1077 | unsigned j; |
1078 | |
1079 | qsort(arg_copy, n_arg_copy, sizeof(*arg_copy), arg_copy_compare); |
1080 | for (i = j = 0; i < n_arg_copy; ++i) { |
1081 | if (i == 0 || arg_copy[i].resource != resource) { |
1082 | resource = arg_copy[i].resource; |
1083 | temp = tcg_temp_local_new(); |
1084 | tcg_gen_mov_i32(temp, arg_copy[i].arg->in); |
1085 | arg_copy[i].temp = temp; |
1086 | |
1087 | if (i != j) { |
1088 | arg_copy[j] = arg_copy[i]; |
1089 | } |
1090 | ++j; |
1091 | } |
1092 | arg_copy[i].arg->in = temp; |
1093 | } |
1094 | n_arg_copy = j; |
1095 | } |
1096 | |
1097 | if (op_flags & XTENSA_OP_DIVIDE_BY_ZERO) { |
1098 | for (slot = 0; slot < slots; ++slot) { |
1099 | if (slot_prop[slot].ops->op_flags & XTENSA_OP_DIVIDE_BY_ZERO) { |
1100 | gen_zero_check(dc, slot_prop[slot].arg); |
1101 | } |
1102 | } |
1103 | } |
1104 | |
1105 | dc->op_flags = op_flags; |
1106 | |
1107 | for (slot = 0; slot < slots; ++slot) { |
1108 | struct slot_prop *pslot = ordered[slot]; |
1109 | XtensaOpcodeOps *ops = pslot->ops; |
1110 | |
1111 | ops->translate(dc, pslot->arg, ops->par); |
1112 | } |
1113 | |
1114 | for (i = 0; i < n_arg_copy; ++i) { |
1115 | tcg_temp_free(arg_copy[i].temp); |
1116 | } |
1117 | |
1118 | if (dc->base.is_jmp == DISAS_NEXT) { |
1119 | gen_postprocess(dc, 0); |
1120 | dc->op_flags = 0; |
1121 | if (op_flags & XTENSA_OP_EXIT_TB_M1) { |
1122 | /* Change in mmu index, memory mapping or tb->flags; exit tb */ |
1123 | gen_jumpi_check_loop_end(dc, -1); |
1124 | } else if (op_flags & XTENSA_OP_EXIT_TB_0) { |
1125 | gen_jumpi_check_loop_end(dc, 0); |
1126 | } else { |
1127 | gen_check_loop_end(dc, 0); |
1128 | } |
1129 | } |
1130 | dc->pc = dc->base.pc_next; |
1131 | } |
1132 | |
1133 | static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc) |
1134 | { |
1135 | uint8_t b0 = cpu_ldub_code(env, dc->pc); |
1136 | return xtensa_op0_insn_len(dc, b0); |
1137 | } |
1138 | |
1139 | static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc) |
1140 | { |
1141 | unsigned i; |
1142 | |
1143 | for (i = 0; i < dc->config->nibreak; ++i) { |
1144 | if ((env->sregs[IBREAKENABLE] & (1 << i)) && |
1145 | env->sregs[IBREAKA + i] == dc->pc) { |
1146 | gen_debug_exception(dc, DEBUGCAUSE_IB); |
1147 | break; |
1148 | } |
1149 | } |
1150 | } |
1151 | |
1152 | static void xtensa_tr_init_disas_context(DisasContextBase *dcbase, |
1153 | CPUState *cpu) |
1154 | { |
1155 | DisasContext *dc = container_of(dcbase, DisasContext, base); |
1156 | CPUXtensaState *env = cpu->env_ptr; |
1157 | uint32_t tb_flags = dc->base.tb->flags; |
1158 | |
1159 | dc->config = env->config; |
1160 | dc->pc = dc->base.pc_first; |
1161 | dc->ring = tb_flags & XTENSA_TBFLAG_RING_MASK; |
1162 | dc->cring = (tb_flags & XTENSA_TBFLAG_EXCM) ? 0 : dc->ring; |
1163 | dc->lbeg_off = (dc->base.tb->cs_base & XTENSA_CSBASE_LBEG_OFF_MASK) >> |
1164 | XTENSA_CSBASE_LBEG_OFF_SHIFT; |
1165 | dc->lend = (dc->base.tb->cs_base & XTENSA_CSBASE_LEND_MASK) + |
1166 | (dc->base.pc_first & TARGET_PAGE_MASK); |
1167 | dc->debug = tb_flags & XTENSA_TBFLAG_DEBUG; |
1168 | dc->icount = tb_flags & XTENSA_TBFLAG_ICOUNT; |
1169 | dc->cpenable = (tb_flags & XTENSA_TBFLAG_CPENABLE_MASK) >> |
1170 | XTENSA_TBFLAG_CPENABLE_SHIFT; |
1171 | dc->window = ((tb_flags & XTENSA_TBFLAG_WINDOW_MASK) >> |
1172 | XTENSA_TBFLAG_WINDOW_SHIFT); |
1173 | dc->cwoe = tb_flags & XTENSA_TBFLAG_CWOE; |
1174 | dc->callinc = ((tb_flags & XTENSA_TBFLAG_CALLINC_MASK) >> |
1175 | XTENSA_TBFLAG_CALLINC_SHIFT); |
1176 | |
1177 | if (dc->config->isa) { |
1178 | dc->insnbuf = xtensa_insnbuf_alloc(dc->config->isa); |
1179 | dc->slotbuf = xtensa_insnbuf_alloc(dc->config->isa); |
1180 | } |
1181 | init_sar_tracker(dc); |
1182 | } |
1183 | |
1184 | static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu) |
1185 | { |
1186 | DisasContext *dc = container_of(dcbase, DisasContext, base); |
1187 | |
1188 | if (dc->icount) { |
1189 | dc->next_icount = tcg_temp_local_new_i32(); |
1190 | } |
1191 | } |
1192 | |
1193 | static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) |
1194 | { |
1195 | tcg_gen_insn_start(dcbase->pc_next); |
1196 | } |
1197 | |
1198 | static bool xtensa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, |
1199 | const CPUBreakpoint *bp) |
1200 | { |
1201 | DisasContext *dc = container_of(dcbase, DisasContext, base); |
1202 | |
1203 | tcg_gen_movi_i32(cpu_pc, dc->base.pc_next); |
1204 | gen_exception(dc, EXCP_DEBUG); |
1205 | dc->base.is_jmp = DISAS_NORETURN; |
1206 | /* The address covered by the breakpoint must be included in |
1207 | [tb->pc, tb->pc + tb->size) in order to for it to be |
1208 | properly cleared -- thus we increment the PC here so that |
1209 | the logic setting tb->size below does the right thing. */ |
1210 | dc->base.pc_next += 2; |
1211 | return true; |
1212 | } |
1213 | |
1214 | static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) |
1215 | { |
1216 | DisasContext *dc = container_of(dcbase, DisasContext, base); |
1217 | CPUXtensaState *env = cpu->env_ptr; |
1218 | target_ulong page_start; |
1219 | |
1220 | /* These two conditions only apply to the first insn in the TB, |
1221 | but this is the first TranslateOps hook that allows exiting. */ |
1222 | if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT) |
1223 | && (dc->base.tb->flags & XTENSA_TBFLAG_YIELD)) { |
1224 | gen_exception(dc, EXCP_YIELD); |
1225 | dc->base.is_jmp = DISAS_NORETURN; |
1226 | return; |
1227 | } |
1228 | if (dc->base.tb->flags & XTENSA_TBFLAG_EXCEPTION) { |
1229 | gen_exception(dc, EXCP_DEBUG); |
1230 | dc->base.is_jmp = DISAS_NORETURN; |
1231 | return; |
1232 | } |
1233 | |
1234 | if (dc->icount) { |
1235 | TCGLabel *label = gen_new_label(); |
1236 | |
1237 | tcg_gen_addi_i32(dc->next_icount, cpu_SR[ICOUNT], 1); |
1238 | tcg_gen_brcondi_i32(TCG_COND_NE, dc->next_icount, 0, label); |
1239 | tcg_gen_mov_i32(dc->next_icount, cpu_SR[ICOUNT]); |
1240 | if (dc->debug) { |
1241 | gen_debug_exception(dc, DEBUGCAUSE_IC); |
1242 | } |
1243 | gen_set_label(label); |
1244 | } |
1245 | |
1246 | if (dc->debug) { |
1247 | gen_ibreak_check(env, dc); |
1248 | } |
1249 | |
1250 | disas_xtensa_insn(env, dc); |
1251 | |
1252 | if (dc->icount) { |
1253 | tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount); |
1254 | } |
1255 | |
1256 | /* End the TB if the next insn will cross into the next page. */ |
1257 | page_start = dc->base.pc_first & TARGET_PAGE_MASK; |
1258 | if (dc->base.is_jmp == DISAS_NEXT && |
1259 | (dc->pc - page_start >= TARGET_PAGE_SIZE || |
1260 | dc->pc - page_start + xtensa_insn_len(env, dc) > TARGET_PAGE_SIZE)) { |
1261 | dc->base.is_jmp = DISAS_TOO_MANY; |
1262 | } |
1263 | } |
1264 | |
1265 | static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) |
1266 | { |
1267 | DisasContext *dc = container_of(dcbase, DisasContext, base); |
1268 | |
1269 | reset_sar_tracker(dc); |
1270 | if (dc->config->isa) { |
1271 | xtensa_insnbuf_free(dc->config->isa, dc->insnbuf); |
1272 | xtensa_insnbuf_free(dc->config->isa, dc->slotbuf); |
1273 | } |
1274 | if (dc->icount) { |
1275 | tcg_temp_free(dc->next_icount); |
1276 | } |
1277 | |
1278 | switch (dc->base.is_jmp) { |
1279 | case DISAS_NORETURN: |
1280 | break; |
1281 | case DISAS_TOO_MANY: |
1282 | if (dc->base.singlestep_enabled) { |
1283 | tcg_gen_movi_i32(cpu_pc, dc->pc); |
1284 | gen_exception(dc, EXCP_DEBUG); |
1285 | } else { |
1286 | gen_jumpi(dc, dc->pc, 0); |
1287 | } |
1288 | break; |
1289 | default: |
1290 | g_assert_not_reached(); |
1291 | } |
1292 | } |
1293 | |
1294 | static void xtensa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) |
1295 | { |
1296 | qemu_log("IN: %s\n" , lookup_symbol(dcbase->pc_first)); |
1297 | log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size); |
1298 | } |
1299 | |
1300 | static const TranslatorOps xtensa_translator_ops = { |
1301 | .init_disas_context = xtensa_tr_init_disas_context, |
1302 | .tb_start = xtensa_tr_tb_start, |
1303 | .insn_start = xtensa_tr_insn_start, |
1304 | .breakpoint_check = xtensa_tr_breakpoint_check, |
1305 | .translate_insn = xtensa_tr_translate_insn, |
1306 | .tb_stop = xtensa_tr_tb_stop, |
1307 | .disas_log = xtensa_tr_disas_log, |
1308 | }; |
1309 | |
1310 | void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) |
1311 | { |
1312 | DisasContext dc = {}; |
1313 | translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb, max_insns); |
1314 | } |
1315 | |
1316 | void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags) |
1317 | { |
1318 | XtensaCPU *cpu = XTENSA_CPU(cs); |
1319 | CPUXtensaState *env = &cpu->env; |
1320 | xtensa_isa isa = env->config->isa; |
1321 | int i, j; |
1322 | |
1323 | qemu_fprintf(f, "PC=%08x\n\n" , env->pc); |
1324 | |
1325 | for (i = j = 0; i < xtensa_isa_num_sysregs(isa); ++i) { |
1326 | const uint32_t *reg = |
1327 | xtensa_sysreg_is_user(isa, i) ? env->uregs : env->sregs; |
1328 | int regno = xtensa_sysreg_number(isa, i); |
1329 | |
1330 | if (regno >= 0) { |
1331 | qemu_fprintf(f, "%12s=%08x%c" , |
1332 | xtensa_sysreg_name(isa, i), |
1333 | reg[regno], |
1334 | (j++ % 4) == 3 ? '\n' : ' '); |
1335 | } |
1336 | } |
1337 | |
1338 | qemu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n" ); |
1339 | |
1340 | for (i = 0; i < 16; ++i) { |
1341 | qemu_fprintf(f, " A%02d=%08x%c" , |
1342 | i, env->regs[i], (i % 4) == 3 ? '\n' : ' '); |
1343 | } |
1344 | |
1345 | xtensa_sync_phys_from_window(env); |
1346 | qemu_fprintf(f, "\n" ); |
1347 | |
1348 | for (i = 0; i < env->config->nareg; ++i) { |
1349 | qemu_fprintf(f, "AR%02d=%08x " , i, env->phys_regs[i]); |
1350 | if (i % 4 == 3) { |
1351 | bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0; |
1352 | bool cw = env->sregs[WINDOW_BASE] == i / 4; |
1353 | |
1354 | qemu_fprintf(f, "%c%c\n" , ws ? '<' : ' ', cw ? '=' : ' '); |
1355 | } |
1356 | } |
1357 | |
1358 | if ((flags & CPU_DUMP_FPU) && |
1359 | xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) { |
1360 | qemu_fprintf(f, "\n" ); |
1361 | |
1362 | for (i = 0; i < 16; ++i) { |
1363 | qemu_fprintf(f, "F%02d=%08x (%+10.8e)%c" , i, |
1364 | float32_val(env->fregs[i].f32[FP_F32_LOW]), |
1365 | *(float *)(env->fregs[i].f32 + FP_F32_LOW), |
1366 | (i % 2) == 1 ? '\n' : ' '); |
1367 | } |
1368 | } |
1369 | } |
1370 | |
1371 | void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, |
1372 | target_ulong *data) |
1373 | { |
1374 | env->pc = data[0]; |
1375 | } |
1376 | |
1377 | static void translate_abs(DisasContext *dc, const OpcodeArg arg[], |
1378 | const uint32_t par[]) |
1379 | { |
1380 | tcg_gen_abs_i32(arg[0].out, arg[1].in); |
1381 | } |
1382 | |
1383 | static void translate_add(DisasContext *dc, const OpcodeArg arg[], |
1384 | const uint32_t par[]) |
1385 | { |
1386 | tcg_gen_add_i32(arg[0].out, arg[1].in, arg[2].in); |
1387 | } |
1388 | |
1389 | static void translate_addi(DisasContext *dc, const OpcodeArg arg[], |
1390 | const uint32_t par[]) |
1391 | { |
1392 | tcg_gen_addi_i32(arg[0].out, arg[1].in, arg[2].imm); |
1393 | } |
1394 | |
1395 | static void translate_addx(DisasContext *dc, const OpcodeArg arg[], |
1396 | const uint32_t par[]) |
1397 | { |
1398 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1399 | tcg_gen_shli_i32(tmp, arg[1].in, par[0]); |
1400 | tcg_gen_add_i32(arg[0].out, tmp, arg[2].in); |
1401 | tcg_temp_free(tmp); |
1402 | } |
1403 | |
1404 | static void translate_all(DisasContext *dc, const OpcodeArg arg[], |
1405 | const uint32_t par[]) |
1406 | { |
1407 | uint32_t shift = par[1]; |
1408 | TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1].imm); |
1409 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1410 | |
1411 | tcg_gen_and_i32(tmp, arg[1].in, mask); |
1412 | if (par[0]) { |
1413 | tcg_gen_addi_i32(tmp, tmp, 1 << arg[1].imm); |
1414 | } else { |
1415 | tcg_gen_add_i32(tmp, tmp, mask); |
1416 | } |
1417 | tcg_gen_shri_i32(tmp, tmp, arg[1].imm + shift); |
1418 | tcg_gen_deposit_i32(arg[0].out, arg[0].out, |
1419 | tmp, arg[0].imm, 1); |
1420 | tcg_temp_free(mask); |
1421 | tcg_temp_free(tmp); |
1422 | } |
1423 | |
1424 | static void translate_and(DisasContext *dc, const OpcodeArg arg[], |
1425 | const uint32_t par[]) |
1426 | { |
1427 | tcg_gen_and_i32(arg[0].out, arg[1].in, arg[2].in); |
1428 | } |
1429 | |
1430 | static void translate_ball(DisasContext *dc, const OpcodeArg arg[], |
1431 | const uint32_t par[]) |
1432 | { |
1433 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1434 | tcg_gen_and_i32(tmp, arg[0].in, arg[1].in); |
1435 | gen_brcond(dc, par[0], tmp, arg[1].in, arg[2].imm); |
1436 | tcg_temp_free(tmp); |
1437 | } |
1438 | |
1439 | static void translate_bany(DisasContext *dc, const OpcodeArg arg[], |
1440 | const uint32_t par[]) |
1441 | { |
1442 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1443 | tcg_gen_and_i32(tmp, arg[0].in, arg[1].in); |
1444 | gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); |
1445 | tcg_temp_free(tmp); |
1446 | } |
1447 | |
1448 | static void translate_b(DisasContext *dc, const OpcodeArg arg[], |
1449 | const uint32_t par[]) |
1450 | { |
1451 | gen_brcond(dc, par[0], arg[0].in, arg[1].in, arg[2].imm); |
1452 | } |
1453 | |
1454 | static void translate_bb(DisasContext *dc, const OpcodeArg arg[], |
1455 | const uint32_t par[]) |
1456 | { |
1457 | #ifdef TARGET_WORDS_BIGENDIAN |
1458 | TCGv_i32 bit = tcg_const_i32(0x80000000u); |
1459 | #else |
1460 | TCGv_i32 bit = tcg_const_i32(0x00000001u); |
1461 | #endif |
1462 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1463 | tcg_gen_andi_i32(tmp, arg[1].in, 0x1f); |
1464 | #ifdef TARGET_WORDS_BIGENDIAN |
1465 | tcg_gen_shr_i32(bit, bit, tmp); |
1466 | #else |
1467 | tcg_gen_shl_i32(bit, bit, tmp); |
1468 | #endif |
1469 | tcg_gen_and_i32(tmp, arg[0].in, bit); |
1470 | gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); |
1471 | tcg_temp_free(tmp); |
1472 | tcg_temp_free(bit); |
1473 | } |
1474 | |
1475 | static void translate_bbi(DisasContext *dc, const OpcodeArg arg[], |
1476 | const uint32_t par[]) |
1477 | { |
1478 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1479 | #ifdef TARGET_WORDS_BIGENDIAN |
1480 | tcg_gen_andi_i32(tmp, arg[0].in, 0x80000000u >> arg[1].imm); |
1481 | #else |
1482 | tcg_gen_andi_i32(tmp, arg[0].in, 0x00000001u << arg[1].imm); |
1483 | #endif |
1484 | gen_brcondi(dc, par[0], tmp, 0, arg[2].imm); |
1485 | tcg_temp_free(tmp); |
1486 | } |
1487 | |
1488 | static void translate_bi(DisasContext *dc, const OpcodeArg arg[], |
1489 | const uint32_t par[]) |
1490 | { |
1491 | gen_brcondi(dc, par[0], arg[0].in, arg[1].imm, arg[2].imm); |
1492 | } |
1493 | |
1494 | static void translate_bz(DisasContext *dc, const OpcodeArg arg[], |
1495 | const uint32_t par[]) |
1496 | { |
1497 | gen_brcondi(dc, par[0], arg[0].in, 0, arg[1].imm); |
1498 | } |
1499 | |
1500 | enum { |
1501 | BOOLEAN_AND, |
1502 | BOOLEAN_ANDC, |
1503 | BOOLEAN_OR, |
1504 | BOOLEAN_ORC, |
1505 | BOOLEAN_XOR, |
1506 | }; |
1507 | |
1508 | static void translate_boolean(DisasContext *dc, const OpcodeArg arg[], |
1509 | const uint32_t par[]) |
1510 | { |
1511 | static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = { |
1512 | [BOOLEAN_AND] = tcg_gen_and_i32, |
1513 | [BOOLEAN_ANDC] = tcg_gen_andc_i32, |
1514 | [BOOLEAN_OR] = tcg_gen_or_i32, |
1515 | [BOOLEAN_ORC] = tcg_gen_orc_i32, |
1516 | [BOOLEAN_XOR] = tcg_gen_xor_i32, |
1517 | }; |
1518 | |
1519 | TCGv_i32 tmp1 = tcg_temp_new_i32(); |
1520 | TCGv_i32 tmp2 = tcg_temp_new_i32(); |
1521 | |
1522 | tcg_gen_shri_i32(tmp1, arg[1].in, arg[1].imm); |
1523 | tcg_gen_shri_i32(tmp2, arg[2].in, arg[2].imm); |
1524 | op[par[0]](tmp1, tmp1, tmp2); |
1525 | tcg_gen_deposit_i32(arg[0].out, arg[0].out, tmp1, arg[0].imm, 1); |
1526 | tcg_temp_free(tmp1); |
1527 | tcg_temp_free(tmp2); |
1528 | } |
1529 | |
1530 | static void translate_bp(DisasContext *dc, const OpcodeArg arg[], |
1531 | const uint32_t par[]) |
1532 | { |
1533 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1534 | |
1535 | tcg_gen_andi_i32(tmp, arg[0].in, 1 << arg[0].imm); |
1536 | gen_brcondi(dc, par[0], tmp, 0, arg[1].imm); |
1537 | tcg_temp_free(tmp); |
1538 | } |
1539 | |
1540 | static void translate_call0(DisasContext *dc, const OpcodeArg arg[], |
1541 | const uint32_t par[]) |
1542 | { |
1543 | tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next); |
1544 | gen_jumpi(dc, arg[0].imm, 0); |
1545 | } |
1546 | |
1547 | static void translate_callw(DisasContext *dc, const OpcodeArg arg[], |
1548 | const uint32_t par[]) |
1549 | { |
1550 | TCGv_i32 tmp = tcg_const_i32(arg[0].imm); |
1551 | gen_callw_slot(dc, par[0], tmp, adjust_jump_slot(dc, arg[0].imm, 0)); |
1552 | tcg_temp_free(tmp); |
1553 | } |
1554 | |
1555 | static void translate_callx0(DisasContext *dc, const OpcodeArg arg[], |
1556 | const uint32_t par[]) |
1557 | { |
1558 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1559 | tcg_gen_mov_i32(tmp, arg[0].in); |
1560 | tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next); |
1561 | gen_jump(dc, tmp); |
1562 | tcg_temp_free(tmp); |
1563 | } |
1564 | |
1565 | static void translate_callxw(DisasContext *dc, const OpcodeArg arg[], |
1566 | const uint32_t par[]) |
1567 | { |
1568 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1569 | |
1570 | tcg_gen_mov_i32(tmp, arg[0].in); |
1571 | gen_callw_slot(dc, par[0], tmp, -1); |
1572 | tcg_temp_free(tmp); |
1573 | } |
1574 | |
1575 | static void translate_clamps(DisasContext *dc, const OpcodeArg arg[], |
1576 | const uint32_t par[]) |
1577 | { |
1578 | TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2].imm); |
1579 | TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2].imm) - 1); |
1580 | |
1581 | tcg_gen_smax_i32(tmp1, tmp1, arg[1].in); |
1582 | tcg_gen_smin_i32(arg[0].out, tmp1, tmp2); |
1583 | tcg_temp_free(tmp1); |
1584 | tcg_temp_free(tmp2); |
1585 | } |
1586 | |
1587 | static void translate_clrb_expstate(DisasContext *dc, const OpcodeArg arg[], |
1588 | const uint32_t par[]) |
1589 | { |
1590 | /* TODO: GPIO32 may be a part of coprocessor */ |
1591 | tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0].imm)); |
1592 | } |
1593 | |
1594 | static void translate_clrex(DisasContext *dc, const OpcodeArg arg[], |
1595 | const uint32_t par[]) |
1596 | { |
1597 | tcg_gen_movi_i32(cpu_exclusive_addr, -1); |
1598 | } |
1599 | |
1600 | static void translate_const16(DisasContext *dc, const OpcodeArg arg[], |
1601 | const uint32_t par[]) |
1602 | { |
1603 | TCGv_i32 c = tcg_const_i32(arg[1].imm); |
1604 | |
1605 | tcg_gen_deposit_i32(arg[0].out, c, arg[0].in, 16, 16); |
1606 | tcg_temp_free(c); |
1607 | } |
1608 | |
1609 | static void translate_dcache(DisasContext *dc, const OpcodeArg arg[], |
1610 | const uint32_t par[]) |
1611 | { |
1612 | TCGv_i32 addr = tcg_temp_new_i32(); |
1613 | TCGv_i32 res = tcg_temp_new_i32(); |
1614 | |
1615 | tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm); |
1616 | tcg_gen_qemu_ld8u(res, addr, dc->cring); |
1617 | tcg_temp_free(addr); |
1618 | tcg_temp_free(res); |
1619 | } |
1620 | |
1621 | static void translate_depbits(DisasContext *dc, const OpcodeArg arg[], |
1622 | const uint32_t par[]) |
1623 | { |
1624 | tcg_gen_deposit_i32(arg[1].out, arg[1].in, arg[0].in, |
1625 | arg[2].imm, arg[3].imm); |
1626 | } |
1627 | |
1628 | static void translate_diwbuip(DisasContext *dc, const OpcodeArg arg[], |
1629 | const uint32_t par[]) |
1630 | { |
1631 | tcg_gen_addi_i32(arg[0].out, arg[0].in, dc->config->dcache_line_bytes); |
1632 | } |
1633 | |
1634 | static bool test_ill_entry(DisasContext *dc, const OpcodeArg arg[], |
1635 | const uint32_t par[]) |
1636 | { |
1637 | if (arg[0].imm > 3 || !dc->cwoe) { |
1638 | qemu_log_mask(LOG_GUEST_ERROR, |
1639 | "Illegal entry instruction(pc = %08x)\n" , dc->pc); |
1640 | return true; |
1641 | } else { |
1642 | return false; |
1643 | } |
1644 | } |
1645 | |
1646 | static uint32_t test_overflow_entry(DisasContext *dc, const OpcodeArg arg[], |
1647 | const uint32_t par[]) |
1648 | { |
1649 | return 1 << (dc->callinc * 4); |
1650 | } |
1651 | |
1652 | static void translate_entry(DisasContext *dc, const OpcodeArg arg[], |
1653 | const uint32_t par[]) |
1654 | { |
1655 | TCGv_i32 pc = tcg_const_i32(dc->pc); |
1656 | TCGv_i32 s = tcg_const_i32(arg[0].imm); |
1657 | TCGv_i32 imm = tcg_const_i32(arg[1].imm); |
1658 | gen_helper_entry(cpu_env, pc, s, imm); |
1659 | tcg_temp_free(imm); |
1660 | tcg_temp_free(s); |
1661 | tcg_temp_free(pc); |
1662 | } |
1663 | |
1664 | static void translate_extui(DisasContext *dc, const OpcodeArg arg[], |
1665 | const uint32_t par[]) |
1666 | { |
1667 | int maskimm = (1 << arg[3].imm) - 1; |
1668 | |
1669 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1670 | tcg_gen_shri_i32(tmp, arg[1].in, arg[2].imm); |
1671 | tcg_gen_andi_i32(arg[0].out, tmp, maskimm); |
1672 | tcg_temp_free(tmp); |
1673 | } |
1674 | |
1675 | static void translate_getex(DisasContext *dc, const OpcodeArg arg[], |
1676 | const uint32_t par[]) |
1677 | { |
1678 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1679 | |
1680 | tcg_gen_extract_i32(tmp, cpu_SR[ATOMCTL], 8, 1); |
1681 | tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], arg[0].in, 8, 1); |
1682 | tcg_gen_mov_i32(arg[0].out, tmp); |
1683 | tcg_temp_free(tmp); |
1684 | } |
1685 | |
1686 | static void translate_icache(DisasContext *dc, const OpcodeArg arg[], |
1687 | const uint32_t par[]) |
1688 | { |
1689 | #ifndef CONFIG_USER_ONLY |
1690 | TCGv_i32 addr = tcg_temp_new_i32(); |
1691 | |
1692 | tcg_gen_movi_i32(cpu_pc, dc->pc); |
1693 | tcg_gen_addi_i32(addr, arg[0].in, arg[1].imm); |
1694 | gen_helper_itlb_hit_test(cpu_env, addr); |
1695 | tcg_temp_free(addr); |
1696 | #endif |
1697 | } |
1698 | |
1699 | static void translate_itlb(DisasContext *dc, const OpcodeArg arg[], |
1700 | const uint32_t par[]) |
1701 | { |
1702 | #ifndef CONFIG_USER_ONLY |
1703 | TCGv_i32 dtlb = tcg_const_i32(par[0]); |
1704 | |
1705 | gen_helper_itlb(cpu_env, arg[0].in, dtlb); |
1706 | tcg_temp_free(dtlb); |
1707 | #endif |
1708 | } |
1709 | |
1710 | static void translate_j(DisasContext *dc, const OpcodeArg arg[], |
1711 | const uint32_t par[]) |
1712 | { |
1713 | gen_jumpi(dc, arg[0].imm, 0); |
1714 | } |
1715 | |
1716 | static void translate_jx(DisasContext *dc, const OpcodeArg arg[], |
1717 | const uint32_t par[]) |
1718 | { |
1719 | gen_jump(dc, arg[0].in); |
1720 | } |
1721 | |
1722 | static void translate_l32e(DisasContext *dc, const OpcodeArg arg[], |
1723 | const uint32_t par[]) |
1724 | { |
1725 | TCGv_i32 addr = tcg_temp_new_i32(); |
1726 | |
1727 | tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); |
1728 | gen_load_store_alignment(dc, 2, addr, false); |
1729 | tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->ring, MO_TEUL); |
1730 | tcg_temp_free(addr); |
1731 | } |
1732 | |
1733 | #ifdef CONFIG_USER_ONLY |
1734 | static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write) |
1735 | { |
1736 | } |
1737 | #else |
1738 | static void gen_check_exclusive(DisasContext *dc, TCGv_i32 addr, bool is_write) |
1739 | { |
1740 | if (!option_enabled(dc, XTENSA_OPTION_MPU)) { |
1741 | TCGv_i32 tpc = tcg_const_i32(dc->pc); |
1742 | TCGv_i32 write = tcg_const_i32(is_write); |
1743 | |
1744 | gen_helper_check_exclusive(cpu_env, tpc, addr, write); |
1745 | tcg_temp_free(tpc); |
1746 | tcg_temp_free(write); |
1747 | } |
1748 | } |
1749 | #endif |
1750 | |
1751 | static void translate_l32ex(DisasContext *dc, const OpcodeArg arg[], |
1752 | const uint32_t par[]) |
1753 | { |
1754 | TCGv_i32 addr = tcg_temp_new_i32(); |
1755 | |
1756 | tcg_gen_mov_i32(addr, arg[1].in); |
1757 | gen_load_store_alignment(dc, 2, addr, true); |
1758 | gen_check_exclusive(dc, addr, false); |
1759 | tcg_gen_qemu_ld_i32(arg[0].out, addr, dc->ring, MO_TEUL); |
1760 | tcg_gen_mov_i32(cpu_exclusive_addr, addr); |
1761 | tcg_gen_mov_i32(cpu_exclusive_val, arg[0].out); |
1762 | tcg_temp_free(addr); |
1763 | } |
1764 | |
1765 | static void translate_ldst(DisasContext *dc, const OpcodeArg arg[], |
1766 | const uint32_t par[]) |
1767 | { |
1768 | TCGv_i32 addr = tcg_temp_new_i32(); |
1769 | |
1770 | tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); |
1771 | if (par[0] & MO_SIZE) { |
1772 | gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]); |
1773 | } |
1774 | if (par[2]) { |
1775 | if (par[1]) { |
1776 | tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL); |
1777 | } |
1778 | tcg_gen_qemu_st_tl(arg[0].in, addr, dc->cring, par[0]); |
1779 | } else { |
1780 | tcg_gen_qemu_ld_tl(arg[0].out, addr, dc->cring, par[0]); |
1781 | if (par[1]) { |
1782 | tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL); |
1783 | } |
1784 | } |
1785 | tcg_temp_free(addr); |
1786 | } |
1787 | |
1788 | static void translate_l32r(DisasContext *dc, const OpcodeArg arg[], |
1789 | const uint32_t par[]) |
1790 | { |
1791 | TCGv_i32 tmp; |
1792 | |
1793 | if (dc->base.tb->flags & XTENSA_TBFLAG_LITBASE) { |
1794 | tmp = tcg_const_i32(arg[1].raw_imm - 1); |
1795 | tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp); |
1796 | } else { |
1797 | tmp = tcg_const_i32(arg[1].imm); |
1798 | } |
1799 | tcg_gen_qemu_ld32u(arg[0].out, tmp, dc->cring); |
1800 | tcg_temp_free(tmp); |
1801 | } |
1802 | |
1803 | static void translate_loop(DisasContext *dc, const OpcodeArg arg[], |
1804 | const uint32_t par[]) |
1805 | { |
1806 | uint32_t lend = arg[1].imm; |
1807 | |
1808 | tcg_gen_subi_i32(cpu_SR[LCOUNT], arg[0].in, 1); |
1809 | tcg_gen_movi_i32(cpu_SR[LBEG], dc->base.pc_next); |
1810 | tcg_gen_movi_i32(cpu_SR[LEND], lend); |
1811 | |
1812 | if (par[0] != TCG_COND_NEVER) { |
1813 | TCGLabel *label = gen_new_label(); |
1814 | tcg_gen_brcondi_i32(par[0], arg[0].in, 0, label); |
1815 | gen_jumpi(dc, lend, 1); |
1816 | gen_set_label(label); |
1817 | } |
1818 | |
1819 | gen_jumpi(dc, dc->base.pc_next, 0); |
1820 | } |
1821 | |
1822 | enum { |
1823 | MAC16_UMUL, |
1824 | MAC16_MUL, |
1825 | MAC16_MULA, |
1826 | MAC16_MULS, |
1827 | MAC16_NONE, |
1828 | }; |
1829 | |
1830 | enum { |
1831 | MAC16_LL, |
1832 | MAC16_HL, |
1833 | MAC16_LH, |
1834 | MAC16_HH, |
1835 | |
1836 | MAC16_HX = 0x1, |
1837 | MAC16_XH = 0x2, |
1838 | }; |
1839 | |
1840 | static void translate_mac16(DisasContext *dc, const OpcodeArg arg[], |
1841 | const uint32_t par[]) |
1842 | { |
1843 | int op = par[0]; |
1844 | unsigned half = par[1]; |
1845 | uint32_t ld_offset = par[2]; |
1846 | unsigned off = ld_offset ? 2 : 0; |
1847 | TCGv_i32 vaddr = tcg_temp_new_i32(); |
1848 | TCGv_i32 mem32 = tcg_temp_new_i32(); |
1849 | |
1850 | if (ld_offset) { |
1851 | tcg_gen_addi_i32(vaddr, arg[1].in, ld_offset); |
1852 | gen_load_store_alignment(dc, 2, vaddr, false); |
1853 | tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring); |
1854 | } |
1855 | if (op != MAC16_NONE) { |
1856 | TCGv_i32 m1 = gen_mac16_m(arg[off].in, |
1857 | half & MAC16_HX, op == MAC16_UMUL); |
1858 | TCGv_i32 m2 = gen_mac16_m(arg[off + 1].in, |
1859 | half & MAC16_XH, op == MAC16_UMUL); |
1860 | |
1861 | if (op == MAC16_MUL || op == MAC16_UMUL) { |
1862 | tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2); |
1863 | if (op == MAC16_UMUL) { |
1864 | tcg_gen_movi_i32(cpu_SR[ACCHI], 0); |
1865 | } else { |
1866 | tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31); |
1867 | } |
1868 | } else { |
1869 | TCGv_i32 lo = tcg_temp_new_i32(); |
1870 | TCGv_i32 hi = tcg_temp_new_i32(); |
1871 | |
1872 | tcg_gen_mul_i32(lo, m1, m2); |
1873 | tcg_gen_sari_i32(hi, lo, 31); |
1874 | if (op == MAC16_MULA) { |
1875 | tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], |
1876 | cpu_SR[ACCLO], cpu_SR[ACCHI], |
1877 | lo, hi); |
1878 | } else { |
1879 | tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI], |
1880 | cpu_SR[ACCLO], cpu_SR[ACCHI], |
1881 | lo, hi); |
1882 | } |
1883 | tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]); |
1884 | |
1885 | tcg_temp_free_i32(lo); |
1886 | tcg_temp_free_i32(hi); |
1887 | } |
1888 | tcg_temp_free(m1); |
1889 | tcg_temp_free(m2); |
1890 | } |
1891 | if (ld_offset) { |
1892 | tcg_gen_mov_i32(arg[1].out, vaddr); |
1893 | tcg_gen_mov_i32(cpu_SR[MR + arg[0].imm], mem32); |
1894 | } |
1895 | tcg_temp_free(vaddr); |
1896 | tcg_temp_free(mem32); |
1897 | } |
1898 | |
1899 | static void translate_memw(DisasContext *dc, const OpcodeArg arg[], |
1900 | const uint32_t par[]) |
1901 | { |
1902 | tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL); |
1903 | } |
1904 | |
1905 | static void translate_smin(DisasContext *dc, const OpcodeArg arg[], |
1906 | const uint32_t par[]) |
1907 | { |
1908 | tcg_gen_smin_i32(arg[0].out, arg[1].in, arg[2].in); |
1909 | } |
1910 | |
1911 | static void translate_umin(DisasContext *dc, const OpcodeArg arg[], |
1912 | const uint32_t par[]) |
1913 | { |
1914 | tcg_gen_umin_i32(arg[0].out, arg[1].in, arg[2].in); |
1915 | } |
1916 | |
1917 | static void translate_smax(DisasContext *dc, const OpcodeArg arg[], |
1918 | const uint32_t par[]) |
1919 | { |
1920 | tcg_gen_smax_i32(arg[0].out, arg[1].in, arg[2].in); |
1921 | } |
1922 | |
1923 | static void translate_umax(DisasContext *dc, const OpcodeArg arg[], |
1924 | const uint32_t par[]) |
1925 | { |
1926 | tcg_gen_umax_i32(arg[0].out, arg[1].in, arg[2].in); |
1927 | } |
1928 | |
1929 | static void translate_mov(DisasContext *dc, const OpcodeArg arg[], |
1930 | const uint32_t par[]) |
1931 | { |
1932 | tcg_gen_mov_i32(arg[0].out, arg[1].in); |
1933 | } |
1934 | |
1935 | static void translate_movcond(DisasContext *dc, const OpcodeArg arg[], |
1936 | const uint32_t par[]) |
1937 | { |
1938 | TCGv_i32 zero = tcg_const_i32(0); |
1939 | |
1940 | tcg_gen_movcond_i32(par[0], arg[0].out, |
1941 | arg[2].in, zero, arg[1].in, arg[0].in); |
1942 | tcg_temp_free(zero); |
1943 | } |
1944 | |
1945 | static void translate_movi(DisasContext *dc, const OpcodeArg arg[], |
1946 | const uint32_t par[]) |
1947 | { |
1948 | tcg_gen_movi_i32(arg[0].out, arg[1].imm); |
1949 | } |
1950 | |
1951 | static void translate_movp(DisasContext *dc, const OpcodeArg arg[], |
1952 | const uint32_t par[]) |
1953 | { |
1954 | TCGv_i32 zero = tcg_const_i32(0); |
1955 | TCGv_i32 tmp = tcg_temp_new_i32(); |
1956 | |
1957 | tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm); |
1958 | tcg_gen_movcond_i32(par[0], |
1959 | arg[0].out, tmp, zero, |
1960 | arg[1].in, arg[0].in); |
1961 | tcg_temp_free(tmp); |
1962 | tcg_temp_free(zero); |
1963 | } |
1964 | |
1965 | static void translate_movsp(DisasContext *dc, const OpcodeArg arg[], |
1966 | const uint32_t par[]) |
1967 | { |
1968 | tcg_gen_mov_i32(arg[0].out, arg[1].in); |
1969 | } |
1970 | |
1971 | static void translate_mul16(DisasContext *dc, const OpcodeArg arg[], |
1972 | const uint32_t par[]) |
1973 | { |
1974 | TCGv_i32 v1 = tcg_temp_new_i32(); |
1975 | TCGv_i32 v2 = tcg_temp_new_i32(); |
1976 | |
1977 | if (par[0]) { |
1978 | tcg_gen_ext16s_i32(v1, arg[1].in); |
1979 | tcg_gen_ext16s_i32(v2, arg[2].in); |
1980 | } else { |
1981 | tcg_gen_ext16u_i32(v1, arg[1].in); |
1982 | tcg_gen_ext16u_i32(v2, arg[2].in); |
1983 | } |
1984 | tcg_gen_mul_i32(arg[0].out, v1, v2); |
1985 | tcg_temp_free(v2); |
1986 | tcg_temp_free(v1); |
1987 | } |
1988 | |
1989 | static void translate_mull(DisasContext *dc, const OpcodeArg arg[], |
1990 | const uint32_t par[]) |
1991 | { |
1992 | tcg_gen_mul_i32(arg[0].out, arg[1].in, arg[2].in); |
1993 | } |
1994 | |
1995 | static void translate_mulh(DisasContext *dc, const OpcodeArg arg[], |
1996 | const uint32_t par[]) |
1997 | { |
1998 | TCGv_i32 lo = tcg_temp_new(); |
1999 | |
2000 | if (par[0]) { |
2001 | tcg_gen_muls2_i32(lo, arg[0].out, arg[1].in, arg[2].in); |
2002 | } else { |
2003 | tcg_gen_mulu2_i32(lo, arg[0].out, arg[1].in, arg[2].in); |
2004 | } |
2005 | tcg_temp_free(lo); |
2006 | } |
2007 | |
2008 | static void translate_neg(DisasContext *dc, const OpcodeArg arg[], |
2009 | const uint32_t par[]) |
2010 | { |
2011 | tcg_gen_neg_i32(arg[0].out, arg[1].in); |
2012 | } |
2013 | |
2014 | static void translate_nop(DisasContext *dc, const OpcodeArg arg[], |
2015 | const uint32_t par[]) |
2016 | { |
2017 | } |
2018 | |
2019 | static void translate_nsa(DisasContext *dc, const OpcodeArg arg[], |
2020 | const uint32_t par[]) |
2021 | { |
2022 | tcg_gen_clrsb_i32(arg[0].out, arg[1].in); |
2023 | } |
2024 | |
2025 | static void translate_nsau(DisasContext *dc, const OpcodeArg arg[], |
2026 | const uint32_t par[]) |
2027 | { |
2028 | tcg_gen_clzi_i32(arg[0].out, arg[1].in, 32); |
2029 | } |
2030 | |
2031 | static void translate_or(DisasContext *dc, const OpcodeArg arg[], |
2032 | const uint32_t par[]) |
2033 | { |
2034 | tcg_gen_or_i32(arg[0].out, arg[1].in, arg[2].in); |
2035 | } |
2036 | |
2037 | static void translate_ptlb(DisasContext *dc, const OpcodeArg arg[], |
2038 | const uint32_t par[]) |
2039 | { |
2040 | #ifndef CONFIG_USER_ONLY |
2041 | TCGv_i32 dtlb = tcg_const_i32(par[0]); |
2042 | |
2043 | tcg_gen_movi_i32(cpu_pc, dc->pc); |
2044 | gen_helper_ptlb(arg[0].out, cpu_env, arg[1].in, dtlb); |
2045 | tcg_temp_free(dtlb); |
2046 | #endif |
2047 | } |
2048 | |
2049 | static void translate_pptlb(DisasContext *dc, const OpcodeArg arg[], |
2050 | const uint32_t par[]) |
2051 | { |
2052 | #ifndef CONFIG_USER_ONLY |
2053 | tcg_gen_movi_i32(cpu_pc, dc->pc); |
2054 | gen_helper_pptlb(arg[0].out, cpu_env, arg[1].in); |
2055 | #endif |
2056 | } |
2057 | |
2058 | static void translate_quos(DisasContext *dc, const OpcodeArg arg[], |
2059 | const uint32_t par[]) |
2060 | { |
2061 | TCGLabel *label1 = gen_new_label(); |
2062 | TCGLabel *label2 = gen_new_label(); |
2063 | |
2064 | tcg_gen_brcondi_i32(TCG_COND_NE, arg[1].in, 0x80000000, |
2065 | label1); |
2066 | tcg_gen_brcondi_i32(TCG_COND_NE, arg[2].in, 0xffffffff, |
2067 | label1); |
2068 | tcg_gen_movi_i32(arg[0].out, |
2069 | par[0] ? 0x80000000 : 0); |
2070 | tcg_gen_br(label2); |
2071 | gen_set_label(label1); |
2072 | if (par[0]) { |
2073 | tcg_gen_div_i32(arg[0].out, |
2074 | arg[1].in, arg[2].in); |
2075 | } else { |
2076 | tcg_gen_rem_i32(arg[0].out, |
2077 | arg[1].in, arg[2].in); |
2078 | } |
2079 | gen_set_label(label2); |
2080 | } |
2081 | |
2082 | static void translate_quou(DisasContext *dc, const OpcodeArg arg[], |
2083 | const uint32_t par[]) |
2084 | { |
2085 | tcg_gen_divu_i32(arg[0].out, |
2086 | arg[1].in, arg[2].in); |
2087 | } |
2088 | |
2089 | static void translate_read_impwire(DisasContext *dc, const OpcodeArg arg[], |
2090 | const uint32_t par[]) |
2091 | { |
2092 | /* TODO: GPIO32 may be a part of coprocessor */ |
2093 | tcg_gen_movi_i32(arg[0].out, 0); |
2094 | } |
2095 | |
2096 | static void translate_remu(DisasContext *dc, const OpcodeArg arg[], |
2097 | const uint32_t par[]) |
2098 | { |
2099 | tcg_gen_remu_i32(arg[0].out, |
2100 | arg[1].in, arg[2].in); |
2101 | } |
2102 | |
2103 | static void translate_rer(DisasContext *dc, const OpcodeArg arg[], |
2104 | const uint32_t par[]) |
2105 | { |
2106 | gen_helper_rer(arg[0].out, cpu_env, arg[1].in); |
2107 | } |
2108 | |
2109 | static void translate_ret(DisasContext *dc, const OpcodeArg arg[], |
2110 | const uint32_t par[]) |
2111 | { |
2112 | gen_jump(dc, cpu_R[0]); |
2113 | } |
2114 | |
2115 | static bool test_ill_retw(DisasContext *dc, const OpcodeArg arg[], |
2116 | const uint32_t par[]) |
2117 | { |
2118 | if (!dc->cwoe) { |
2119 | qemu_log_mask(LOG_GUEST_ERROR, |
2120 | "Illegal retw instruction(pc = %08x)\n" , dc->pc); |
2121 | return true; |
2122 | } else { |
2123 | TCGv_i32 tmp = tcg_const_i32(dc->pc); |
2124 | |
2125 | gen_helper_test_ill_retw(cpu_env, tmp); |
2126 | tcg_temp_free(tmp); |
2127 | return false; |
2128 | } |
2129 | } |
2130 | |
2131 | static void translate_retw(DisasContext *dc, const OpcodeArg arg[], |
2132 | const uint32_t par[]) |
2133 | { |
2134 | TCGv_i32 tmp = tcg_const_i32(1); |
2135 | tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); |
2136 | tcg_gen_andc_i32(cpu_SR[WINDOW_START], |
2137 | cpu_SR[WINDOW_START], tmp); |
2138 | tcg_gen_movi_i32(tmp, dc->pc); |
2139 | tcg_gen_deposit_i32(tmp, tmp, cpu_R[0], 0, 30); |
2140 | gen_helper_retw(cpu_env, cpu_R[0]); |
2141 | gen_jump(dc, tmp); |
2142 | tcg_temp_free(tmp); |
2143 | } |
2144 | |
2145 | static void translate_rfde(DisasContext *dc, const OpcodeArg arg[], |
2146 | const uint32_t par[]) |
2147 | { |
2148 | gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]); |
2149 | } |
2150 | |
2151 | static void translate_rfe(DisasContext *dc, const OpcodeArg arg[], |
2152 | const uint32_t par[]) |
2153 | { |
2154 | tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); |
2155 | gen_jump(dc, cpu_SR[EPC1]); |
2156 | } |
2157 | |
2158 | static void translate_rfi(DisasContext *dc, const OpcodeArg arg[], |
2159 | const uint32_t par[]) |
2160 | { |
2161 | tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0].imm - 2]); |
2162 | gen_jump(dc, cpu_SR[EPC1 + arg[0].imm - 1]); |
2163 | } |
2164 | |
2165 | static void translate_rfw(DisasContext *dc, const OpcodeArg arg[], |
2166 | const uint32_t par[]) |
2167 | { |
2168 | TCGv_i32 tmp = tcg_const_i32(1); |
2169 | |
2170 | tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM); |
2171 | tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]); |
2172 | |
2173 | if (par[0]) { |
2174 | tcg_gen_andc_i32(cpu_SR[WINDOW_START], |
2175 | cpu_SR[WINDOW_START], tmp); |
2176 | } else { |
2177 | tcg_gen_or_i32(cpu_SR[WINDOW_START], |
2178 | cpu_SR[WINDOW_START], tmp); |
2179 | } |
2180 | |
2181 | tcg_temp_free(tmp); |
2182 | gen_helper_restore_owb(cpu_env); |
2183 | gen_jump(dc, cpu_SR[EPC1]); |
2184 | } |
2185 | |
2186 | static void translate_rotw(DisasContext *dc, const OpcodeArg arg[], |
2187 | const uint32_t par[]) |
2188 | { |
2189 | tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0].imm); |
2190 | } |
2191 | |
2192 | static void translate_rsil(DisasContext *dc, const OpcodeArg arg[], |
2193 | const uint32_t par[]) |
2194 | { |
2195 | tcg_gen_mov_i32(arg[0].out, cpu_SR[PS]); |
2196 | tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL); |
2197 | tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1].imm); |
2198 | } |
2199 | |
2200 | static void translate_rsr(DisasContext *dc, const OpcodeArg arg[], |
2201 | const uint32_t par[]) |
2202 | { |
2203 | tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); |
2204 | } |
2205 | |
2206 | static void translate_rsr_ccount(DisasContext *dc, const OpcodeArg arg[], |
2207 | const uint32_t par[]) |
2208 | { |
2209 | #ifndef CONFIG_USER_ONLY |
2210 | if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { |
2211 | gen_io_start(); |
2212 | } |
2213 | gen_helper_update_ccount(cpu_env); |
2214 | tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); |
2215 | #endif |
2216 | } |
2217 | |
2218 | static void translate_rsr_ptevaddr(DisasContext *dc, const OpcodeArg arg[], |
2219 | const uint32_t par[]) |
2220 | { |
2221 | #ifndef CONFIG_USER_ONLY |
2222 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2223 | |
2224 | tcg_gen_shri_i32(tmp, cpu_SR[EXCVADDR], 10); |
2225 | tcg_gen_or_i32(tmp, tmp, cpu_SR[PTEVADDR]); |
2226 | tcg_gen_andi_i32(arg[0].out, tmp, 0xfffffffc); |
2227 | tcg_temp_free(tmp); |
2228 | #endif |
2229 | } |
2230 | |
2231 | static void translate_rtlb(DisasContext *dc, const OpcodeArg arg[], |
2232 | const uint32_t par[]) |
2233 | { |
2234 | #ifndef CONFIG_USER_ONLY |
2235 | static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1, |
2236 | TCGv_i32 a2) = { |
2237 | gen_helper_rtlb0, |
2238 | gen_helper_rtlb1, |
2239 | }; |
2240 | TCGv_i32 dtlb = tcg_const_i32(par[0]); |
2241 | |
2242 | helper[par[1]](arg[0].out, cpu_env, arg[1].in, dtlb); |
2243 | tcg_temp_free(dtlb); |
2244 | #endif |
2245 | } |
2246 | |
2247 | static void translate_rptlb0(DisasContext *dc, const OpcodeArg arg[], |
2248 | const uint32_t par[]) |
2249 | { |
2250 | #ifndef CONFIG_USER_ONLY |
2251 | gen_helper_rptlb0(arg[0].out, cpu_env, arg[1].in); |
2252 | #endif |
2253 | } |
2254 | |
2255 | static void translate_rptlb1(DisasContext *dc, const OpcodeArg arg[], |
2256 | const uint32_t par[]) |
2257 | { |
2258 | #ifndef CONFIG_USER_ONLY |
2259 | gen_helper_rptlb1(arg[0].out, cpu_env, arg[1].in); |
2260 | #endif |
2261 | } |
2262 | |
2263 | static void translate_rur(DisasContext *dc, const OpcodeArg arg[], |
2264 | const uint32_t par[]) |
2265 | { |
2266 | tcg_gen_mov_i32(arg[0].out, cpu_UR[par[0]]); |
2267 | } |
2268 | |
2269 | static void translate_setb_expstate(DisasContext *dc, const OpcodeArg arg[], |
2270 | const uint32_t par[]) |
2271 | { |
2272 | /* TODO: GPIO32 may be a part of coprocessor */ |
2273 | tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0].imm); |
2274 | } |
2275 | |
2276 | #ifdef CONFIG_USER_ONLY |
2277 | static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr) |
2278 | { |
2279 | } |
2280 | #else |
2281 | static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr) |
2282 | { |
2283 | TCGv_i32 tpc = tcg_const_i32(dc->pc); |
2284 | |
2285 | gen_helper_check_atomctl(cpu_env, tpc, addr); |
2286 | tcg_temp_free(tpc); |
2287 | } |
2288 | #endif |
2289 | |
2290 | static void translate_s32c1i(DisasContext *dc, const OpcodeArg arg[], |
2291 | const uint32_t par[]) |
2292 | { |
2293 | TCGv_i32 tmp = tcg_temp_local_new_i32(); |
2294 | TCGv_i32 addr = tcg_temp_local_new_i32(); |
2295 | |
2296 | tcg_gen_mov_i32(tmp, arg[0].in); |
2297 | tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); |
2298 | gen_load_store_alignment(dc, 2, addr, true); |
2299 | gen_check_atomctl(dc, addr); |
2300 | tcg_gen_atomic_cmpxchg_i32(arg[0].out, addr, cpu_SR[SCOMPARE1], |
2301 | tmp, dc->cring, MO_TEUL); |
2302 | tcg_temp_free(addr); |
2303 | tcg_temp_free(tmp); |
2304 | } |
2305 | |
2306 | static void translate_s32e(DisasContext *dc, const OpcodeArg arg[], |
2307 | const uint32_t par[]) |
2308 | { |
2309 | TCGv_i32 addr = tcg_temp_new_i32(); |
2310 | |
2311 | tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); |
2312 | gen_load_store_alignment(dc, 2, addr, false); |
2313 | tcg_gen_qemu_st_tl(arg[0].in, addr, dc->ring, MO_TEUL); |
2314 | tcg_temp_free(addr); |
2315 | } |
2316 | |
2317 | static void translate_s32ex(DisasContext *dc, const OpcodeArg arg[], |
2318 | const uint32_t par[]) |
2319 | { |
2320 | TCGv_i32 prev = tcg_temp_new_i32(); |
2321 | TCGv_i32 addr = tcg_temp_local_new_i32(); |
2322 | TCGv_i32 res = tcg_temp_local_new_i32(); |
2323 | TCGLabel *label = gen_new_label(); |
2324 | |
2325 | tcg_gen_movi_i32(res, 0); |
2326 | tcg_gen_mov_i32(addr, arg[1].in); |
2327 | gen_load_store_alignment(dc, 2, addr, true); |
2328 | tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, label); |
2329 | gen_check_exclusive(dc, addr, true); |
2330 | tcg_gen_atomic_cmpxchg_i32(prev, cpu_exclusive_addr, cpu_exclusive_val, |
2331 | arg[0].in, dc->cring, MO_TEUL); |
2332 | tcg_gen_setcond_i32(TCG_COND_EQ, res, prev, cpu_exclusive_val); |
2333 | tcg_gen_movcond_i32(TCG_COND_EQ, cpu_exclusive_val, |
2334 | prev, cpu_exclusive_val, prev, cpu_exclusive_val); |
2335 | tcg_gen_movi_i32(cpu_exclusive_addr, -1); |
2336 | gen_set_label(label); |
2337 | tcg_gen_extract_i32(arg[0].out, cpu_SR[ATOMCTL], 8, 1); |
2338 | tcg_gen_deposit_i32(cpu_SR[ATOMCTL], cpu_SR[ATOMCTL], res, 8, 1); |
2339 | tcg_temp_free(prev); |
2340 | tcg_temp_free(addr); |
2341 | tcg_temp_free(res); |
2342 | } |
2343 | |
2344 | static void translate_salt(DisasContext *dc, const OpcodeArg arg[], |
2345 | const uint32_t par[]) |
2346 | { |
2347 | tcg_gen_setcond_i32(par[0], |
2348 | arg[0].out, |
2349 | arg[1].in, arg[2].in); |
2350 | } |
2351 | |
2352 | static void translate_sext(DisasContext *dc, const OpcodeArg arg[], |
2353 | const uint32_t par[]) |
2354 | { |
2355 | int shift = 31 - arg[2].imm; |
2356 | |
2357 | if (shift == 24) { |
2358 | tcg_gen_ext8s_i32(arg[0].out, arg[1].in); |
2359 | } else if (shift == 16) { |
2360 | tcg_gen_ext16s_i32(arg[0].out, arg[1].in); |
2361 | } else { |
2362 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2363 | tcg_gen_shli_i32(tmp, arg[1].in, shift); |
2364 | tcg_gen_sari_i32(arg[0].out, tmp, shift); |
2365 | tcg_temp_free(tmp); |
2366 | } |
2367 | } |
2368 | |
2369 | static bool test_ill_simcall(DisasContext *dc, const OpcodeArg arg[], |
2370 | const uint32_t par[]) |
2371 | { |
2372 | #ifdef CONFIG_USER_ONLY |
2373 | bool ill = true; |
2374 | #else |
2375 | bool ill = !semihosting_enabled(); |
2376 | #endif |
2377 | if (ill) { |
2378 | qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n" ); |
2379 | } |
2380 | return ill; |
2381 | } |
2382 | |
2383 | static void translate_simcall(DisasContext *dc, const OpcodeArg arg[], |
2384 | const uint32_t par[]) |
2385 | { |
2386 | #ifndef CONFIG_USER_ONLY |
2387 | gen_helper_simcall(cpu_env); |
2388 | #endif |
2389 | } |
2390 | |
2391 | /* |
2392 | * Note: 64 bit ops are used here solely because SAR values |
2393 | * have range 0..63 |
2394 | */ |
2395 | #define gen_shift_reg(cmd, reg) do { \ |
2396 | TCGv_i64 tmp = tcg_temp_new_i64(); \ |
2397 | tcg_gen_extu_i32_i64(tmp, reg); \ |
2398 | tcg_gen_##cmd##_i64(v, v, tmp); \ |
2399 | tcg_gen_extrl_i64_i32(arg[0].out, v); \ |
2400 | tcg_temp_free_i64(v); \ |
2401 | tcg_temp_free_i64(tmp); \ |
2402 | } while (0) |
2403 | |
2404 | #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR]) |
2405 | |
2406 | static void translate_sll(DisasContext *dc, const OpcodeArg arg[], |
2407 | const uint32_t par[]) |
2408 | { |
2409 | if (dc->sar_m32_5bit) { |
2410 | tcg_gen_shl_i32(arg[0].out, arg[1].in, dc->sar_m32); |
2411 | } else { |
2412 | TCGv_i64 v = tcg_temp_new_i64(); |
2413 | TCGv_i32 s = tcg_const_i32(32); |
2414 | tcg_gen_sub_i32(s, s, cpu_SR[SAR]); |
2415 | tcg_gen_andi_i32(s, s, 0x3f); |
2416 | tcg_gen_extu_i32_i64(v, arg[1].in); |
2417 | gen_shift_reg(shl, s); |
2418 | tcg_temp_free(s); |
2419 | } |
2420 | } |
2421 | |
2422 | static void translate_slli(DisasContext *dc, const OpcodeArg arg[], |
2423 | const uint32_t par[]) |
2424 | { |
2425 | if (arg[2].imm == 32) { |
2426 | qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n" , |
2427 | arg[0].imm, arg[1].imm); |
2428 | } |
2429 | tcg_gen_shli_i32(arg[0].out, arg[1].in, arg[2].imm & 0x1f); |
2430 | } |
2431 | |
2432 | static void translate_sra(DisasContext *dc, const OpcodeArg arg[], |
2433 | const uint32_t par[]) |
2434 | { |
2435 | if (dc->sar_m32_5bit) { |
2436 | tcg_gen_sar_i32(arg[0].out, arg[1].in, cpu_SR[SAR]); |
2437 | } else { |
2438 | TCGv_i64 v = tcg_temp_new_i64(); |
2439 | tcg_gen_ext_i32_i64(v, arg[1].in); |
2440 | gen_shift(sar); |
2441 | } |
2442 | } |
2443 | |
2444 | static void translate_srai(DisasContext *dc, const OpcodeArg arg[], |
2445 | const uint32_t par[]) |
2446 | { |
2447 | tcg_gen_sari_i32(arg[0].out, arg[1].in, arg[2].imm); |
2448 | } |
2449 | |
2450 | static void translate_src(DisasContext *dc, const OpcodeArg arg[], |
2451 | const uint32_t par[]) |
2452 | { |
2453 | TCGv_i64 v = tcg_temp_new_i64(); |
2454 | tcg_gen_concat_i32_i64(v, arg[2].in, arg[1].in); |
2455 | gen_shift(shr); |
2456 | } |
2457 | |
2458 | static void translate_srl(DisasContext *dc, const OpcodeArg arg[], |
2459 | const uint32_t par[]) |
2460 | { |
2461 | if (dc->sar_m32_5bit) { |
2462 | tcg_gen_shr_i32(arg[0].out, arg[1].in, cpu_SR[SAR]); |
2463 | } else { |
2464 | TCGv_i64 v = tcg_temp_new_i64(); |
2465 | tcg_gen_extu_i32_i64(v, arg[1].in); |
2466 | gen_shift(shr); |
2467 | } |
2468 | } |
2469 | |
2470 | #undef gen_shift |
2471 | #undef gen_shift_reg |
2472 | |
2473 | static void translate_srli(DisasContext *dc, const OpcodeArg arg[], |
2474 | const uint32_t par[]) |
2475 | { |
2476 | tcg_gen_shri_i32(arg[0].out, arg[1].in, arg[2].imm); |
2477 | } |
2478 | |
2479 | static void translate_ssa8b(DisasContext *dc, const OpcodeArg arg[], |
2480 | const uint32_t par[]) |
2481 | { |
2482 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2483 | tcg_gen_shli_i32(tmp, arg[0].in, 3); |
2484 | gen_left_shift_sar(dc, tmp); |
2485 | tcg_temp_free(tmp); |
2486 | } |
2487 | |
2488 | static void translate_ssa8l(DisasContext *dc, const OpcodeArg arg[], |
2489 | const uint32_t par[]) |
2490 | { |
2491 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2492 | tcg_gen_shli_i32(tmp, arg[0].in, 3); |
2493 | gen_right_shift_sar(dc, tmp); |
2494 | tcg_temp_free(tmp); |
2495 | } |
2496 | |
2497 | static void translate_ssai(DisasContext *dc, const OpcodeArg arg[], |
2498 | const uint32_t par[]) |
2499 | { |
2500 | TCGv_i32 tmp = tcg_const_i32(arg[0].imm); |
2501 | gen_right_shift_sar(dc, tmp); |
2502 | tcg_temp_free(tmp); |
2503 | } |
2504 | |
2505 | static void translate_ssl(DisasContext *dc, const OpcodeArg arg[], |
2506 | const uint32_t par[]) |
2507 | { |
2508 | gen_left_shift_sar(dc, arg[0].in); |
2509 | } |
2510 | |
2511 | static void translate_ssr(DisasContext *dc, const OpcodeArg arg[], |
2512 | const uint32_t par[]) |
2513 | { |
2514 | gen_right_shift_sar(dc, arg[0].in); |
2515 | } |
2516 | |
2517 | static void translate_sub(DisasContext *dc, const OpcodeArg arg[], |
2518 | const uint32_t par[]) |
2519 | { |
2520 | tcg_gen_sub_i32(arg[0].out, arg[1].in, arg[2].in); |
2521 | } |
2522 | |
2523 | static void translate_subx(DisasContext *dc, const OpcodeArg arg[], |
2524 | const uint32_t par[]) |
2525 | { |
2526 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2527 | tcg_gen_shli_i32(tmp, arg[1].in, par[0]); |
2528 | tcg_gen_sub_i32(arg[0].out, tmp, arg[2].in); |
2529 | tcg_temp_free(tmp); |
2530 | } |
2531 | |
2532 | static void translate_waiti(DisasContext *dc, const OpcodeArg arg[], |
2533 | const uint32_t par[]) |
2534 | { |
2535 | #ifndef CONFIG_USER_ONLY |
2536 | gen_waiti(dc, arg[0].imm); |
2537 | #endif |
2538 | } |
2539 | |
2540 | static void translate_wtlb(DisasContext *dc, const OpcodeArg arg[], |
2541 | const uint32_t par[]) |
2542 | { |
2543 | #ifndef CONFIG_USER_ONLY |
2544 | TCGv_i32 dtlb = tcg_const_i32(par[0]); |
2545 | |
2546 | gen_helper_wtlb(cpu_env, arg[0].in, arg[1].in, dtlb); |
2547 | tcg_temp_free(dtlb); |
2548 | #endif |
2549 | } |
2550 | |
2551 | static void translate_wptlb(DisasContext *dc, const OpcodeArg arg[], |
2552 | const uint32_t par[]) |
2553 | { |
2554 | #ifndef CONFIG_USER_ONLY |
2555 | gen_helper_wptlb(cpu_env, arg[0].in, arg[1].in); |
2556 | #endif |
2557 | } |
2558 | |
2559 | static void translate_wer(DisasContext *dc, const OpcodeArg arg[], |
2560 | const uint32_t par[]) |
2561 | { |
2562 | gen_helper_wer(cpu_env, arg[0].in, arg[1].in); |
2563 | } |
2564 | |
2565 | static void translate_wrmsk_expstate(DisasContext *dc, const OpcodeArg arg[], |
2566 | const uint32_t par[]) |
2567 | { |
2568 | /* TODO: GPIO32 may be a part of coprocessor */ |
2569 | tcg_gen_and_i32(cpu_UR[EXPSTATE], arg[0].in, arg[1].in); |
2570 | } |
2571 | |
2572 | static void translate_wsr(DisasContext *dc, const OpcodeArg arg[], |
2573 | const uint32_t par[]) |
2574 | { |
2575 | tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); |
2576 | } |
2577 | |
2578 | static void translate_wsr_mask(DisasContext *dc, const OpcodeArg arg[], |
2579 | const uint32_t par[]) |
2580 | { |
2581 | tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, par[2]); |
2582 | } |
2583 | |
2584 | static void translate_wsr_acchi(DisasContext *dc, const OpcodeArg arg[], |
2585 | const uint32_t par[]) |
2586 | { |
2587 | tcg_gen_ext8s_i32(cpu_SR[par[0]], arg[0].in); |
2588 | } |
2589 | |
2590 | static void translate_wsr_ccompare(DisasContext *dc, const OpcodeArg arg[], |
2591 | const uint32_t par[]) |
2592 | { |
2593 | #ifndef CONFIG_USER_ONLY |
2594 | uint32_t id = par[0] - CCOMPARE; |
2595 | TCGv_i32 tmp = tcg_const_i32(id); |
2596 | |
2597 | assert(id < dc->config->nccompare); |
2598 | if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { |
2599 | gen_io_start(); |
2600 | } |
2601 | tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); |
2602 | gen_helper_update_ccompare(cpu_env, tmp); |
2603 | tcg_temp_free(tmp); |
2604 | #endif |
2605 | } |
2606 | |
2607 | static void translate_wsr_ccount(DisasContext *dc, const OpcodeArg arg[], |
2608 | const uint32_t par[]) |
2609 | { |
2610 | #ifndef CONFIG_USER_ONLY |
2611 | if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { |
2612 | gen_io_start(); |
2613 | } |
2614 | gen_helper_wsr_ccount(cpu_env, arg[0].in); |
2615 | #endif |
2616 | } |
2617 | |
2618 | static void translate_wsr_dbreaka(DisasContext *dc, const OpcodeArg arg[], |
2619 | const uint32_t par[]) |
2620 | { |
2621 | #ifndef CONFIG_USER_ONLY |
2622 | unsigned id = par[0] - DBREAKA; |
2623 | TCGv_i32 tmp = tcg_const_i32(id); |
2624 | |
2625 | assert(id < dc->config->ndbreak); |
2626 | gen_helper_wsr_dbreaka(cpu_env, tmp, arg[0].in); |
2627 | tcg_temp_free(tmp); |
2628 | #endif |
2629 | } |
2630 | |
2631 | static void translate_wsr_dbreakc(DisasContext *dc, const OpcodeArg arg[], |
2632 | const uint32_t par[]) |
2633 | { |
2634 | #ifndef CONFIG_USER_ONLY |
2635 | unsigned id = par[0] - DBREAKC; |
2636 | TCGv_i32 tmp = tcg_const_i32(id); |
2637 | |
2638 | assert(id < dc->config->ndbreak); |
2639 | gen_helper_wsr_dbreakc(cpu_env, tmp, arg[0].in); |
2640 | tcg_temp_free(tmp); |
2641 | #endif |
2642 | } |
2643 | |
2644 | static void translate_wsr_ibreaka(DisasContext *dc, const OpcodeArg arg[], |
2645 | const uint32_t par[]) |
2646 | { |
2647 | #ifndef CONFIG_USER_ONLY |
2648 | unsigned id = par[0] - IBREAKA; |
2649 | TCGv_i32 tmp = tcg_const_i32(id); |
2650 | |
2651 | assert(id < dc->config->nibreak); |
2652 | gen_helper_wsr_ibreaka(cpu_env, tmp, arg[0].in); |
2653 | tcg_temp_free(tmp); |
2654 | #endif |
2655 | } |
2656 | |
2657 | static void translate_wsr_ibreakenable(DisasContext *dc, const OpcodeArg arg[], |
2658 | const uint32_t par[]) |
2659 | { |
2660 | #ifndef CONFIG_USER_ONLY |
2661 | gen_helper_wsr_ibreakenable(cpu_env, arg[0].in); |
2662 | #endif |
2663 | } |
2664 | |
2665 | static void translate_wsr_icount(DisasContext *dc, const OpcodeArg arg[], |
2666 | const uint32_t par[]) |
2667 | { |
2668 | #ifndef CONFIG_USER_ONLY |
2669 | if (dc->icount) { |
2670 | tcg_gen_mov_i32(dc->next_icount, arg[0].in); |
2671 | } else { |
2672 | tcg_gen_mov_i32(cpu_SR[par[0]], arg[0].in); |
2673 | } |
2674 | #endif |
2675 | } |
2676 | |
2677 | static void translate_wsr_intclear(DisasContext *dc, const OpcodeArg arg[], |
2678 | const uint32_t par[]) |
2679 | { |
2680 | #ifndef CONFIG_USER_ONLY |
2681 | gen_helper_intclear(cpu_env, arg[0].in); |
2682 | #endif |
2683 | } |
2684 | |
2685 | static void translate_wsr_intset(DisasContext *dc, const OpcodeArg arg[], |
2686 | const uint32_t par[]) |
2687 | { |
2688 | #ifndef CONFIG_USER_ONLY |
2689 | gen_helper_intset(cpu_env, arg[0].in); |
2690 | #endif |
2691 | } |
2692 | |
2693 | static void translate_wsr_memctl(DisasContext *dc, const OpcodeArg arg[], |
2694 | const uint32_t par[]) |
2695 | { |
2696 | #ifndef CONFIG_USER_ONLY |
2697 | gen_helper_wsr_memctl(cpu_env, arg[0].in); |
2698 | #endif |
2699 | } |
2700 | |
2701 | static void translate_wsr_mpuenb(DisasContext *dc, const OpcodeArg arg[], |
2702 | const uint32_t par[]) |
2703 | { |
2704 | #ifndef CONFIG_USER_ONLY |
2705 | gen_helper_wsr_mpuenb(cpu_env, arg[0].in); |
2706 | #endif |
2707 | } |
2708 | |
2709 | static void translate_wsr_ps(DisasContext *dc, const OpcodeArg arg[], |
2710 | const uint32_t par[]) |
2711 | { |
2712 | #ifndef CONFIG_USER_ONLY |
2713 | uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB | |
2714 | PS_UM | PS_EXCM | PS_INTLEVEL; |
2715 | |
2716 | if (option_enabled(dc, XTENSA_OPTION_MMU)) { |
2717 | mask |= PS_RING; |
2718 | } |
2719 | tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, mask); |
2720 | #endif |
2721 | } |
2722 | |
2723 | static void translate_wsr_rasid(DisasContext *dc, const OpcodeArg arg[], |
2724 | const uint32_t par[]) |
2725 | { |
2726 | #ifndef CONFIG_USER_ONLY |
2727 | gen_helper_wsr_rasid(cpu_env, arg[0].in); |
2728 | #endif |
2729 | } |
2730 | |
2731 | static void translate_wsr_sar(DisasContext *dc, const OpcodeArg arg[], |
2732 | const uint32_t par[]) |
2733 | { |
2734 | tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, 0x3f); |
2735 | if (dc->sar_m32_5bit) { |
2736 | tcg_gen_discard_i32(dc->sar_m32); |
2737 | } |
2738 | dc->sar_5bit = false; |
2739 | dc->sar_m32_5bit = false; |
2740 | } |
2741 | |
2742 | static void translate_wsr_windowbase(DisasContext *dc, const OpcodeArg arg[], |
2743 | const uint32_t par[]) |
2744 | { |
2745 | #ifndef CONFIG_USER_ONLY |
2746 | tcg_gen_mov_i32(cpu_windowbase_next, arg[0].in); |
2747 | #endif |
2748 | } |
2749 | |
2750 | static void translate_wsr_windowstart(DisasContext *dc, const OpcodeArg arg[], |
2751 | const uint32_t par[]) |
2752 | { |
2753 | #ifndef CONFIG_USER_ONLY |
2754 | tcg_gen_andi_i32(cpu_SR[par[0]], arg[0].in, |
2755 | (1 << dc->config->nareg / 4) - 1); |
2756 | #endif |
2757 | } |
2758 | |
2759 | static void translate_wur(DisasContext *dc, const OpcodeArg arg[], |
2760 | const uint32_t par[]) |
2761 | { |
2762 | tcg_gen_mov_i32(cpu_UR[par[0]], arg[0].in); |
2763 | } |
2764 | |
2765 | static void translate_wur_fcr(DisasContext *dc, const OpcodeArg arg[], |
2766 | const uint32_t par[]) |
2767 | { |
2768 | gen_helper_wur_fcr(cpu_env, arg[0].in); |
2769 | } |
2770 | |
2771 | static void translate_wur_fsr(DisasContext *dc, const OpcodeArg arg[], |
2772 | const uint32_t par[]) |
2773 | { |
2774 | tcg_gen_andi_i32(cpu_UR[par[0]], arg[0].in, 0xffffff80); |
2775 | } |
2776 | |
2777 | static void translate_xor(DisasContext *dc, const OpcodeArg arg[], |
2778 | const uint32_t par[]) |
2779 | { |
2780 | tcg_gen_xor_i32(arg[0].out, arg[1].in, arg[2].in); |
2781 | } |
2782 | |
2783 | static void translate_xsr(DisasContext *dc, const OpcodeArg arg[], |
2784 | const uint32_t par[]) |
2785 | { |
2786 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2787 | |
2788 | tcg_gen_mov_i32(tmp, arg[0].in); |
2789 | tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); |
2790 | tcg_gen_mov_i32(cpu_SR[par[0]], tmp); |
2791 | tcg_temp_free(tmp); |
2792 | } |
2793 | |
2794 | static void translate_xsr_mask(DisasContext *dc, const OpcodeArg arg[], |
2795 | const uint32_t par[]) |
2796 | { |
2797 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2798 | |
2799 | tcg_gen_mov_i32(tmp, arg[0].in); |
2800 | tcg_gen_mov_i32(arg[0].out, cpu_SR[par[0]]); |
2801 | tcg_gen_andi_i32(cpu_SR[par[0]], tmp, par[2]); |
2802 | tcg_temp_free(tmp); |
2803 | } |
2804 | |
2805 | static void translate_xsr_ccount(DisasContext *dc, const OpcodeArg arg[], |
2806 | const uint32_t par[]) |
2807 | { |
2808 | #ifndef CONFIG_USER_ONLY |
2809 | TCGv_i32 tmp = tcg_temp_new_i32(); |
2810 | |
2811 | if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) { |
2812 | gen_io_start(); |
2813 | } |
2814 | |
2815 | gen_helper_update_ccount(cpu_env); |
2816 | tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); |
2817 | gen_helper_wsr_ccount(cpu_env, arg[0].in); |
2818 | tcg_gen_mov_i32(arg[0].out, tmp); |
2819 | tcg_temp_free(tmp); |
2820 | |
2821 | #endif |
2822 | } |
2823 | |
2824 | #define gen_translate_xsr(name) \ |
2825 | static void translate_xsr_##name(DisasContext *dc, const OpcodeArg arg[], \ |
2826 | const uint32_t par[]) \ |
2827 | { \ |
2828 | TCGv_i32 tmp = tcg_temp_new_i32(); \ |
2829 | \ |
2830 | tcg_gen_mov_i32(tmp, cpu_SR[par[0]]); \ |
2831 | translate_wsr_##name(dc, arg, par); \ |
2832 | tcg_gen_mov_i32(arg[0].out, tmp); \ |
2833 | tcg_temp_free(tmp); \ |
2834 | } |
2835 | |
2836 | gen_translate_xsr(acchi) |
2837 | gen_translate_xsr(ccompare) |
2838 | gen_translate_xsr(dbreaka) |
2839 | gen_translate_xsr(dbreakc) |
2840 | gen_translate_xsr(ibreaka) |
2841 | gen_translate_xsr(ibreakenable) |
2842 | gen_translate_xsr(icount) |
2843 | gen_translate_xsr(memctl) |
2844 | gen_translate_xsr(mpuenb) |
2845 | gen_translate_xsr(ps) |
2846 | gen_translate_xsr(rasid) |
2847 | gen_translate_xsr(sar) |
2848 | gen_translate_xsr(windowbase) |
2849 | gen_translate_xsr(windowstart) |
2850 | |
2851 | #undef gen_translate_xsr |
2852 | |
2853 | static const XtensaOpcodeOps core_ops[] = { |
2854 | { |
2855 | .name = "abs" , |
2856 | .translate = translate_abs, |
2857 | }, { |
2858 | .name = (const char * const[]) { |
2859 | "add" , "add.n" , NULL, |
2860 | }, |
2861 | .translate = translate_add, |
2862 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2863 | }, { |
2864 | .name = (const char * const[]) { |
2865 | "addi" , "addi.n" , NULL, |
2866 | }, |
2867 | .translate = translate_addi, |
2868 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2869 | }, { |
2870 | .name = "addmi" , |
2871 | .translate = translate_addi, |
2872 | }, { |
2873 | .name = "addx2" , |
2874 | .translate = translate_addx, |
2875 | .par = (const uint32_t[]){1}, |
2876 | }, { |
2877 | .name = "addx4" , |
2878 | .translate = translate_addx, |
2879 | .par = (const uint32_t[]){2}, |
2880 | }, { |
2881 | .name = "addx8" , |
2882 | .translate = translate_addx, |
2883 | .par = (const uint32_t[]){3}, |
2884 | }, { |
2885 | .name = "all4" , |
2886 | .translate = translate_all, |
2887 | .par = (const uint32_t[]){true, 4}, |
2888 | }, { |
2889 | .name = "all8" , |
2890 | .translate = translate_all, |
2891 | .par = (const uint32_t[]){true, 8}, |
2892 | }, { |
2893 | .name = "and" , |
2894 | .translate = translate_and, |
2895 | }, { |
2896 | .name = "andb" , |
2897 | .translate = translate_boolean, |
2898 | .par = (const uint32_t[]){BOOLEAN_AND}, |
2899 | }, { |
2900 | .name = "andbc" , |
2901 | .translate = translate_boolean, |
2902 | .par = (const uint32_t[]){BOOLEAN_ANDC}, |
2903 | }, { |
2904 | .name = "any4" , |
2905 | .translate = translate_all, |
2906 | .par = (const uint32_t[]){false, 4}, |
2907 | }, { |
2908 | .name = "any8" , |
2909 | .translate = translate_all, |
2910 | .par = (const uint32_t[]){false, 8}, |
2911 | }, { |
2912 | .name = (const char * const[]) { |
2913 | "ball" , "ball.w15" , "ball.w18" , NULL, |
2914 | }, |
2915 | .translate = translate_ball, |
2916 | .par = (const uint32_t[]){TCG_COND_EQ}, |
2917 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2918 | }, { |
2919 | .name = (const char * const[]) { |
2920 | "bany" , "bany.w15" , "bany.w18" , NULL, |
2921 | }, |
2922 | .translate = translate_bany, |
2923 | .par = (const uint32_t[]){TCG_COND_NE}, |
2924 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2925 | }, { |
2926 | .name = (const char * const[]) { |
2927 | "bbc" , "bbc.w15" , "bbc.w18" , NULL, |
2928 | }, |
2929 | .translate = translate_bb, |
2930 | .par = (const uint32_t[]){TCG_COND_EQ}, |
2931 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2932 | }, { |
2933 | .name = (const char * const[]) { |
2934 | "bbci" , "bbci.w15" , "bbci.w18" , NULL, |
2935 | }, |
2936 | .translate = translate_bbi, |
2937 | .par = (const uint32_t[]){TCG_COND_EQ}, |
2938 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2939 | }, { |
2940 | .name = (const char * const[]) { |
2941 | "bbs" , "bbs.w15" , "bbs.w18" , NULL, |
2942 | }, |
2943 | .translate = translate_bb, |
2944 | .par = (const uint32_t[]){TCG_COND_NE}, |
2945 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2946 | }, { |
2947 | .name = (const char * const[]) { |
2948 | "bbsi" , "bbsi.w15" , "bbsi.w18" , NULL, |
2949 | }, |
2950 | .translate = translate_bbi, |
2951 | .par = (const uint32_t[]){TCG_COND_NE}, |
2952 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2953 | }, { |
2954 | .name = (const char * const[]) { |
2955 | "beq" , "beq.w15" , "beq.w18" , NULL, |
2956 | }, |
2957 | .translate = translate_b, |
2958 | .par = (const uint32_t[]){TCG_COND_EQ}, |
2959 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2960 | }, { |
2961 | .name = (const char * const[]) { |
2962 | "beqi" , "beqi.w15" , "beqi.w18" , NULL, |
2963 | }, |
2964 | .translate = translate_bi, |
2965 | .par = (const uint32_t[]){TCG_COND_EQ}, |
2966 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2967 | }, { |
2968 | .name = (const char * const[]) { |
2969 | "beqz" , "beqz.n" , "beqz.w15" , "beqz.w18" , NULL, |
2970 | }, |
2971 | .translate = translate_bz, |
2972 | .par = (const uint32_t[]){TCG_COND_EQ}, |
2973 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2974 | }, { |
2975 | .name = "bf" , |
2976 | .translate = translate_bp, |
2977 | .par = (const uint32_t[]){TCG_COND_EQ}, |
2978 | }, { |
2979 | .name = (const char * const[]) { |
2980 | "bge" , "bge.w15" , "bge.w18" , NULL, |
2981 | }, |
2982 | .translate = translate_b, |
2983 | .par = (const uint32_t[]){TCG_COND_GE}, |
2984 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2985 | }, { |
2986 | .name = (const char * const[]) { |
2987 | "bgei" , "bgei.w15" , "bgei.w18" , NULL, |
2988 | }, |
2989 | .translate = translate_bi, |
2990 | .par = (const uint32_t[]){TCG_COND_GE}, |
2991 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2992 | }, { |
2993 | .name = (const char * const[]) { |
2994 | "bgeu" , "bgeu.w15" , "bgeu.w18" , NULL, |
2995 | }, |
2996 | .translate = translate_b, |
2997 | .par = (const uint32_t[]){TCG_COND_GEU}, |
2998 | .op_flags = XTENSA_OP_NAME_ARRAY, |
2999 | }, { |
3000 | .name = (const char * const[]) { |
3001 | "bgeui" , "bgeui.w15" , "bgeui.w18" , NULL, |
3002 | }, |
3003 | .translate = translate_bi, |
3004 | .par = (const uint32_t[]){TCG_COND_GEU}, |
3005 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3006 | }, { |
3007 | .name = (const char * const[]) { |
3008 | "bgez" , "bgez.w15" , "bgez.w18" , NULL, |
3009 | }, |
3010 | .translate = translate_bz, |
3011 | .par = (const uint32_t[]){TCG_COND_GE}, |
3012 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3013 | }, { |
3014 | .name = (const char * const[]) { |
3015 | "blt" , "blt.w15" , "blt.w18" , NULL, |
3016 | }, |
3017 | .translate = translate_b, |
3018 | .par = (const uint32_t[]){TCG_COND_LT}, |
3019 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3020 | }, { |
3021 | .name = (const char * const[]) { |
3022 | "blti" , "blti.w15" , "blti.w18" , NULL, |
3023 | }, |
3024 | .translate = translate_bi, |
3025 | .par = (const uint32_t[]){TCG_COND_LT}, |
3026 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3027 | }, { |
3028 | .name = (const char * const[]) { |
3029 | "bltu" , "bltu.w15" , "bltu.w18" , NULL, |
3030 | }, |
3031 | .translate = translate_b, |
3032 | .par = (const uint32_t[]){TCG_COND_LTU}, |
3033 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3034 | }, { |
3035 | .name = (const char * const[]) { |
3036 | "bltui" , "bltui.w15" , "bltui.w18" , NULL, |
3037 | }, |
3038 | .translate = translate_bi, |
3039 | .par = (const uint32_t[]){TCG_COND_LTU}, |
3040 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3041 | }, { |
3042 | .name = (const char * const[]) { |
3043 | "bltz" , "bltz.w15" , "bltz.w18" , NULL, |
3044 | }, |
3045 | .translate = translate_bz, |
3046 | .par = (const uint32_t[]){TCG_COND_LT}, |
3047 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3048 | }, { |
3049 | .name = (const char * const[]) { |
3050 | "bnall" , "bnall.w15" , "bnall.w18" , NULL, |
3051 | }, |
3052 | .translate = translate_ball, |
3053 | .par = (const uint32_t[]){TCG_COND_NE}, |
3054 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3055 | }, { |
3056 | .name = (const char * const[]) { |
3057 | "bne" , "bne.w15" , "bne.w18" , NULL, |
3058 | }, |
3059 | .translate = translate_b, |
3060 | .par = (const uint32_t[]){TCG_COND_NE}, |
3061 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3062 | }, { |
3063 | .name = (const char * const[]) { |
3064 | "bnei" , "bnei.w15" , "bnei.w18" , NULL, |
3065 | }, |
3066 | .translate = translate_bi, |
3067 | .par = (const uint32_t[]){TCG_COND_NE}, |
3068 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3069 | }, { |
3070 | .name = (const char * const[]) { |
3071 | "bnez" , "bnez.n" , "bnez.w15" , "bnez.w18" , NULL, |
3072 | }, |
3073 | .translate = translate_bz, |
3074 | .par = (const uint32_t[]){TCG_COND_NE}, |
3075 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3076 | }, { |
3077 | .name = (const char * const[]) { |
3078 | "bnone" , "bnone.w15" , "bnone.w18" , NULL, |
3079 | }, |
3080 | .translate = translate_bany, |
3081 | .par = (const uint32_t[]){TCG_COND_EQ}, |
3082 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3083 | }, { |
3084 | .name = "break" , |
3085 | .translate = translate_nop, |
3086 | .par = (const uint32_t[]){DEBUGCAUSE_BI}, |
3087 | .op_flags = XTENSA_OP_DEBUG_BREAK, |
3088 | }, { |
3089 | .name = "break.n" , |
3090 | .translate = translate_nop, |
3091 | .par = (const uint32_t[]){DEBUGCAUSE_BN}, |
3092 | .op_flags = XTENSA_OP_DEBUG_BREAK, |
3093 | }, { |
3094 | .name = "bt" , |
3095 | .translate = translate_bp, |
3096 | .par = (const uint32_t[]){TCG_COND_NE}, |
3097 | }, { |
3098 | .name = "call0" , |
3099 | .translate = translate_call0, |
3100 | }, { |
3101 | .name = "call12" , |
3102 | .translate = translate_callw, |
3103 | .par = (const uint32_t[]){3}, |
3104 | }, { |
3105 | .name = "call4" , |
3106 | .translate = translate_callw, |
3107 | .par = (const uint32_t[]){1}, |
3108 | }, { |
3109 | .name = "call8" , |
3110 | .translate = translate_callw, |
3111 | .par = (const uint32_t[]){2}, |
3112 | }, { |
3113 | .name = "callx0" , |
3114 | .translate = translate_callx0, |
3115 | }, { |
3116 | .name = "callx12" , |
3117 | .translate = translate_callxw, |
3118 | .par = (const uint32_t[]){3}, |
3119 | }, { |
3120 | .name = "callx4" , |
3121 | .translate = translate_callxw, |
3122 | .par = (const uint32_t[]){1}, |
3123 | }, { |
3124 | .name = "callx8" , |
3125 | .translate = translate_callxw, |
3126 | .par = (const uint32_t[]){2}, |
3127 | }, { |
3128 | .name = "clamps" , |
3129 | .translate = translate_clamps, |
3130 | }, { |
3131 | .name = "clrb_expstate" , |
3132 | .translate = translate_clrb_expstate, |
3133 | }, { |
3134 | .name = "clrex" , |
3135 | .translate = translate_clrex, |
3136 | }, { |
3137 | .name = "const16" , |
3138 | .translate = translate_const16, |
3139 | }, { |
3140 | .name = "depbits" , |
3141 | .translate = translate_depbits, |
3142 | }, { |
3143 | .name = "dhi" , |
3144 | .translate = translate_dcache, |
3145 | .op_flags = XTENSA_OP_PRIVILEGED, |
3146 | }, { |
3147 | .name = "dhi.b" , |
3148 | .translate = translate_nop, |
3149 | }, { |
3150 | .name = "dhu" , |
3151 | .translate = translate_dcache, |
3152 | .op_flags = XTENSA_OP_PRIVILEGED, |
3153 | }, { |
3154 | .name = "dhwb" , |
3155 | .translate = translate_dcache, |
3156 | }, { |
3157 | .name = "dhwb.b" , |
3158 | .translate = translate_nop, |
3159 | }, { |
3160 | .name = "dhwbi" , |
3161 | .translate = translate_dcache, |
3162 | }, { |
3163 | .name = "dhwbi.b" , |
3164 | .translate = translate_nop, |
3165 | }, { |
3166 | .name = "dii" , |
3167 | .translate = translate_nop, |
3168 | .op_flags = XTENSA_OP_PRIVILEGED, |
3169 | }, { |
3170 | .name = "diu" , |
3171 | .translate = translate_nop, |
3172 | .op_flags = XTENSA_OP_PRIVILEGED, |
3173 | }, { |
3174 | .name = "diwb" , |
3175 | .translate = translate_nop, |
3176 | .op_flags = XTENSA_OP_PRIVILEGED, |
3177 | }, { |
3178 | .name = "diwbi" , |
3179 | .translate = translate_nop, |
3180 | .op_flags = XTENSA_OP_PRIVILEGED, |
3181 | }, { |
3182 | .name = "diwbui.p" , |
3183 | .translate = translate_diwbuip, |
3184 | .op_flags = XTENSA_OP_PRIVILEGED, |
3185 | }, { |
3186 | .name = "dpfl" , |
3187 | .translate = translate_dcache, |
3188 | .op_flags = XTENSA_OP_PRIVILEGED, |
3189 | }, { |
3190 | .name = "dpfm.b" , |
3191 | .translate = translate_nop, |
3192 | }, { |
3193 | .name = "dpfm.bf" , |
3194 | .translate = translate_nop, |
3195 | }, { |
3196 | .name = "dpfr" , |
3197 | .translate = translate_nop, |
3198 | }, { |
3199 | .name = "dpfr.b" , |
3200 | .translate = translate_nop, |
3201 | }, { |
3202 | .name = "dpfr.bf" , |
3203 | .translate = translate_nop, |
3204 | }, { |
3205 | .name = "dpfro" , |
3206 | .translate = translate_nop, |
3207 | }, { |
3208 | .name = "dpfw" , |
3209 | .translate = translate_nop, |
3210 | }, { |
3211 | .name = "dpfw.b" , |
3212 | .translate = translate_nop, |
3213 | }, { |
3214 | .name = "dpfw.bf" , |
3215 | .translate = translate_nop, |
3216 | }, { |
3217 | .name = "dpfwo" , |
3218 | .translate = translate_nop, |
3219 | }, { |
3220 | .name = "dsync" , |
3221 | .translate = translate_nop, |
3222 | }, { |
3223 | .name = "entry" , |
3224 | .translate = translate_entry, |
3225 | .test_ill = test_ill_entry, |
3226 | .test_overflow = test_overflow_entry, |
3227 | .op_flags = XTENSA_OP_EXIT_TB_M1 | |
3228 | XTENSA_OP_SYNC_REGISTER_WINDOW, |
3229 | }, { |
3230 | .name = "esync" , |
3231 | .translate = translate_nop, |
3232 | }, { |
3233 | .name = "excw" , |
3234 | .translate = translate_nop, |
3235 | }, { |
3236 | .name = "extui" , |
3237 | .translate = translate_extui, |
3238 | }, { |
3239 | .name = "extw" , |
3240 | .translate = translate_memw, |
3241 | }, { |
3242 | .name = "getex" , |
3243 | .translate = translate_getex, |
3244 | }, { |
3245 | .name = "hwwdtlba" , |
3246 | .op_flags = XTENSA_OP_ILL, |
3247 | }, { |
3248 | .name = "hwwitlba" , |
3249 | .op_flags = XTENSA_OP_ILL, |
3250 | }, { |
3251 | .name = "idtlb" , |
3252 | .translate = translate_itlb, |
3253 | .par = (const uint32_t[]){true}, |
3254 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
3255 | }, { |
3256 | .name = "ihi" , |
3257 | .translate = translate_icache, |
3258 | }, { |
3259 | .name = "ihu" , |
3260 | .translate = translate_icache, |
3261 | .op_flags = XTENSA_OP_PRIVILEGED, |
3262 | }, { |
3263 | .name = "iii" , |
3264 | .translate = translate_nop, |
3265 | .op_flags = XTENSA_OP_PRIVILEGED, |
3266 | }, { |
3267 | .name = "iitlb" , |
3268 | .translate = translate_itlb, |
3269 | .par = (const uint32_t[]){false}, |
3270 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
3271 | }, { |
3272 | .name = "iiu" , |
3273 | .translate = translate_nop, |
3274 | .op_flags = XTENSA_OP_PRIVILEGED, |
3275 | }, { |
3276 | .name = (const char * const[]) { |
3277 | "ill" , "ill.n" , NULL, |
3278 | }, |
3279 | .op_flags = XTENSA_OP_ILL | XTENSA_OP_NAME_ARRAY, |
3280 | }, { |
3281 | .name = "ipf" , |
3282 | .translate = translate_nop, |
3283 | }, { |
3284 | .name = "ipfl" , |
3285 | .translate = translate_icache, |
3286 | .op_flags = XTENSA_OP_PRIVILEGED, |
3287 | }, { |
3288 | .name = "isync" , |
3289 | .translate = translate_nop, |
3290 | }, { |
3291 | .name = "j" , |
3292 | .translate = translate_j, |
3293 | }, { |
3294 | .name = "jx" , |
3295 | .translate = translate_jx, |
3296 | }, { |
3297 | .name = "l16si" , |
3298 | .translate = translate_ldst, |
3299 | .par = (const uint32_t[]){MO_TESW, false, false}, |
3300 | .op_flags = XTENSA_OP_LOAD, |
3301 | }, { |
3302 | .name = "l16ui" , |
3303 | .translate = translate_ldst, |
3304 | .par = (const uint32_t[]){MO_TEUW, false, false}, |
3305 | .op_flags = XTENSA_OP_LOAD, |
3306 | }, { |
3307 | .name = "l32ai" , |
3308 | .translate = translate_ldst, |
3309 | .par = (const uint32_t[]){MO_TEUL, true, false}, |
3310 | .op_flags = XTENSA_OP_LOAD, |
3311 | }, { |
3312 | .name = "l32e" , |
3313 | .translate = translate_l32e, |
3314 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_LOAD, |
3315 | }, { |
3316 | .name = "l32ex" , |
3317 | .translate = translate_l32ex, |
3318 | .op_flags = XTENSA_OP_LOAD, |
3319 | }, { |
3320 | .name = (const char * const[]) { |
3321 | "l32i" , "l32i.n" , NULL, |
3322 | }, |
3323 | .translate = translate_ldst, |
3324 | .par = (const uint32_t[]){MO_TEUL, false, false}, |
3325 | .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_LOAD, |
3326 | }, { |
3327 | .name = "l32r" , |
3328 | .translate = translate_l32r, |
3329 | .op_flags = XTENSA_OP_LOAD, |
3330 | }, { |
3331 | .name = "l8ui" , |
3332 | .translate = translate_ldst, |
3333 | .par = (const uint32_t[]){MO_UB, false, false}, |
3334 | .op_flags = XTENSA_OP_LOAD, |
3335 | }, { |
3336 | .name = "lddec" , |
3337 | .translate = translate_mac16, |
3338 | .par = (const uint32_t[]){MAC16_NONE, 0, -4}, |
3339 | .op_flags = XTENSA_OP_LOAD, |
3340 | }, { |
3341 | .name = "ldinc" , |
3342 | .translate = translate_mac16, |
3343 | .par = (const uint32_t[]){MAC16_NONE, 0, 4}, |
3344 | .op_flags = XTENSA_OP_LOAD, |
3345 | }, { |
3346 | .name = "ldpte" , |
3347 | .op_flags = XTENSA_OP_ILL, |
3348 | }, { |
3349 | .name = (const char * const[]) { |
3350 | "loop" , "loop.w15" , NULL, |
3351 | }, |
3352 | .translate = translate_loop, |
3353 | .par = (const uint32_t[]){TCG_COND_NEVER}, |
3354 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3355 | }, { |
3356 | .name = (const char * const[]) { |
3357 | "loopgtz" , "loopgtz.w15" , NULL, |
3358 | }, |
3359 | .translate = translate_loop, |
3360 | .par = (const uint32_t[]){TCG_COND_GT}, |
3361 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3362 | }, { |
3363 | .name = (const char * const[]) { |
3364 | "loopnez" , "loopnez.w15" , NULL, |
3365 | }, |
3366 | .translate = translate_loop, |
3367 | .par = (const uint32_t[]){TCG_COND_NE}, |
3368 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3369 | }, { |
3370 | .name = "max" , |
3371 | .translate = translate_smax, |
3372 | }, { |
3373 | .name = "maxu" , |
3374 | .translate = translate_umax, |
3375 | }, { |
3376 | .name = "memw" , |
3377 | .translate = translate_memw, |
3378 | }, { |
3379 | .name = "min" , |
3380 | .translate = translate_smin, |
3381 | }, { |
3382 | .name = "minu" , |
3383 | .translate = translate_umin, |
3384 | }, { |
3385 | .name = (const char * const[]) { |
3386 | "mov" , "mov.n" , NULL, |
3387 | }, |
3388 | .translate = translate_mov, |
3389 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3390 | }, { |
3391 | .name = "moveqz" , |
3392 | .translate = translate_movcond, |
3393 | .par = (const uint32_t[]){TCG_COND_EQ}, |
3394 | }, { |
3395 | .name = "movf" , |
3396 | .translate = translate_movp, |
3397 | .par = (const uint32_t[]){TCG_COND_EQ}, |
3398 | }, { |
3399 | .name = "movgez" , |
3400 | .translate = translate_movcond, |
3401 | .par = (const uint32_t[]){TCG_COND_GE}, |
3402 | }, { |
3403 | .name = "movi" , |
3404 | .translate = translate_movi, |
3405 | }, { |
3406 | .name = "movi.n" , |
3407 | .translate = translate_movi, |
3408 | }, { |
3409 | .name = "movltz" , |
3410 | .translate = translate_movcond, |
3411 | .par = (const uint32_t[]){TCG_COND_LT}, |
3412 | }, { |
3413 | .name = "movnez" , |
3414 | .translate = translate_movcond, |
3415 | .par = (const uint32_t[]){TCG_COND_NE}, |
3416 | }, { |
3417 | .name = "movsp" , |
3418 | .translate = translate_movsp, |
3419 | .op_flags = XTENSA_OP_ALLOCA, |
3420 | }, { |
3421 | .name = "movt" , |
3422 | .translate = translate_movp, |
3423 | .par = (const uint32_t[]){TCG_COND_NE}, |
3424 | }, { |
3425 | .name = "mul.aa.hh" , |
3426 | .translate = translate_mac16, |
3427 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, |
3428 | }, { |
3429 | .name = "mul.aa.hl" , |
3430 | .translate = translate_mac16, |
3431 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, |
3432 | }, { |
3433 | .name = "mul.aa.lh" , |
3434 | .translate = translate_mac16, |
3435 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, |
3436 | }, { |
3437 | .name = "mul.aa.ll" , |
3438 | .translate = translate_mac16, |
3439 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, |
3440 | }, { |
3441 | .name = "mul.ad.hh" , |
3442 | .translate = translate_mac16, |
3443 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, |
3444 | }, { |
3445 | .name = "mul.ad.hl" , |
3446 | .translate = translate_mac16, |
3447 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, |
3448 | }, { |
3449 | .name = "mul.ad.lh" , |
3450 | .translate = translate_mac16, |
3451 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, |
3452 | }, { |
3453 | .name = "mul.ad.ll" , |
3454 | .translate = translate_mac16, |
3455 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, |
3456 | }, { |
3457 | .name = "mul.da.hh" , |
3458 | .translate = translate_mac16, |
3459 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, |
3460 | }, { |
3461 | .name = "mul.da.hl" , |
3462 | .translate = translate_mac16, |
3463 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, |
3464 | }, { |
3465 | .name = "mul.da.lh" , |
3466 | .translate = translate_mac16, |
3467 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, |
3468 | }, { |
3469 | .name = "mul.da.ll" , |
3470 | .translate = translate_mac16, |
3471 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, |
3472 | }, { |
3473 | .name = "mul.dd.hh" , |
3474 | .translate = translate_mac16, |
3475 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HH, 0}, |
3476 | }, { |
3477 | .name = "mul.dd.hl" , |
3478 | .translate = translate_mac16, |
3479 | .par = (const uint32_t[]){MAC16_MUL, MAC16_HL, 0}, |
3480 | }, { |
3481 | .name = "mul.dd.lh" , |
3482 | .translate = translate_mac16, |
3483 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LH, 0}, |
3484 | }, { |
3485 | .name = "mul.dd.ll" , |
3486 | .translate = translate_mac16, |
3487 | .par = (const uint32_t[]){MAC16_MUL, MAC16_LL, 0}, |
3488 | }, { |
3489 | .name = "mul16s" , |
3490 | .translate = translate_mul16, |
3491 | .par = (const uint32_t[]){true}, |
3492 | }, { |
3493 | .name = "mul16u" , |
3494 | .translate = translate_mul16, |
3495 | .par = (const uint32_t[]){false}, |
3496 | }, { |
3497 | .name = "mula.aa.hh" , |
3498 | .translate = translate_mac16, |
3499 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, |
3500 | }, { |
3501 | .name = "mula.aa.hl" , |
3502 | .translate = translate_mac16, |
3503 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, |
3504 | }, { |
3505 | .name = "mula.aa.lh" , |
3506 | .translate = translate_mac16, |
3507 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, |
3508 | }, { |
3509 | .name = "mula.aa.ll" , |
3510 | .translate = translate_mac16, |
3511 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, |
3512 | }, { |
3513 | .name = "mula.ad.hh" , |
3514 | .translate = translate_mac16, |
3515 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, |
3516 | }, { |
3517 | .name = "mula.ad.hl" , |
3518 | .translate = translate_mac16, |
3519 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, |
3520 | }, { |
3521 | .name = "mula.ad.lh" , |
3522 | .translate = translate_mac16, |
3523 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, |
3524 | }, { |
3525 | .name = "mula.ad.ll" , |
3526 | .translate = translate_mac16, |
3527 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, |
3528 | }, { |
3529 | .name = "mula.da.hh" , |
3530 | .translate = translate_mac16, |
3531 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, |
3532 | }, { |
3533 | .name = "mula.da.hh.lddec" , |
3534 | .translate = translate_mac16, |
3535 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4}, |
3536 | }, { |
3537 | .name = "mula.da.hh.ldinc" , |
3538 | .translate = translate_mac16, |
3539 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4}, |
3540 | }, { |
3541 | .name = "mula.da.hl" , |
3542 | .translate = translate_mac16, |
3543 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, |
3544 | }, { |
3545 | .name = "mula.da.hl.lddec" , |
3546 | .translate = translate_mac16, |
3547 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4}, |
3548 | }, { |
3549 | .name = "mula.da.hl.ldinc" , |
3550 | .translate = translate_mac16, |
3551 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4}, |
3552 | }, { |
3553 | .name = "mula.da.lh" , |
3554 | .translate = translate_mac16, |
3555 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, |
3556 | }, { |
3557 | .name = "mula.da.lh.lddec" , |
3558 | .translate = translate_mac16, |
3559 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4}, |
3560 | }, { |
3561 | .name = "mula.da.lh.ldinc" , |
3562 | .translate = translate_mac16, |
3563 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4}, |
3564 | }, { |
3565 | .name = "mula.da.ll" , |
3566 | .translate = translate_mac16, |
3567 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, |
3568 | }, { |
3569 | .name = "mula.da.ll.lddec" , |
3570 | .translate = translate_mac16, |
3571 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4}, |
3572 | }, { |
3573 | .name = "mula.da.ll.ldinc" , |
3574 | .translate = translate_mac16, |
3575 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4}, |
3576 | }, { |
3577 | .name = "mula.dd.hh" , |
3578 | .translate = translate_mac16, |
3579 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 0}, |
3580 | }, { |
3581 | .name = "mula.dd.hh.lddec" , |
3582 | .translate = translate_mac16, |
3583 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, -4}, |
3584 | }, { |
3585 | .name = "mula.dd.hh.ldinc" , |
3586 | .translate = translate_mac16, |
3587 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HH, 4}, |
3588 | }, { |
3589 | .name = "mula.dd.hl" , |
3590 | .translate = translate_mac16, |
3591 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 0}, |
3592 | }, { |
3593 | .name = "mula.dd.hl.lddec" , |
3594 | .translate = translate_mac16, |
3595 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, -4}, |
3596 | }, { |
3597 | .name = "mula.dd.hl.ldinc" , |
3598 | .translate = translate_mac16, |
3599 | .par = (const uint32_t[]){MAC16_MULA, MAC16_HL, 4}, |
3600 | }, { |
3601 | .name = "mula.dd.lh" , |
3602 | .translate = translate_mac16, |
3603 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 0}, |
3604 | }, { |
3605 | .name = "mula.dd.lh.lddec" , |
3606 | .translate = translate_mac16, |
3607 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, -4}, |
3608 | }, { |
3609 | .name = "mula.dd.lh.ldinc" , |
3610 | .translate = translate_mac16, |
3611 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LH, 4}, |
3612 | }, { |
3613 | .name = "mula.dd.ll" , |
3614 | .translate = translate_mac16, |
3615 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 0}, |
3616 | }, { |
3617 | .name = "mula.dd.ll.lddec" , |
3618 | .translate = translate_mac16, |
3619 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, -4}, |
3620 | }, { |
3621 | .name = "mula.dd.ll.ldinc" , |
3622 | .translate = translate_mac16, |
3623 | .par = (const uint32_t[]){MAC16_MULA, MAC16_LL, 4}, |
3624 | }, { |
3625 | .name = "mull" , |
3626 | .translate = translate_mull, |
3627 | }, { |
3628 | .name = "muls.aa.hh" , |
3629 | .translate = translate_mac16, |
3630 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, |
3631 | }, { |
3632 | .name = "muls.aa.hl" , |
3633 | .translate = translate_mac16, |
3634 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, |
3635 | }, { |
3636 | .name = "muls.aa.lh" , |
3637 | .translate = translate_mac16, |
3638 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, |
3639 | }, { |
3640 | .name = "muls.aa.ll" , |
3641 | .translate = translate_mac16, |
3642 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, |
3643 | }, { |
3644 | .name = "muls.ad.hh" , |
3645 | .translate = translate_mac16, |
3646 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, |
3647 | }, { |
3648 | .name = "muls.ad.hl" , |
3649 | .translate = translate_mac16, |
3650 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, |
3651 | }, { |
3652 | .name = "muls.ad.lh" , |
3653 | .translate = translate_mac16, |
3654 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, |
3655 | }, { |
3656 | .name = "muls.ad.ll" , |
3657 | .translate = translate_mac16, |
3658 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, |
3659 | }, { |
3660 | .name = "muls.da.hh" , |
3661 | .translate = translate_mac16, |
3662 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, |
3663 | }, { |
3664 | .name = "muls.da.hl" , |
3665 | .translate = translate_mac16, |
3666 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, |
3667 | }, { |
3668 | .name = "muls.da.lh" , |
3669 | .translate = translate_mac16, |
3670 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, |
3671 | }, { |
3672 | .name = "muls.da.ll" , |
3673 | .translate = translate_mac16, |
3674 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, |
3675 | }, { |
3676 | .name = "muls.dd.hh" , |
3677 | .translate = translate_mac16, |
3678 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HH, 0}, |
3679 | }, { |
3680 | .name = "muls.dd.hl" , |
3681 | .translate = translate_mac16, |
3682 | .par = (const uint32_t[]){MAC16_MULS, MAC16_HL, 0}, |
3683 | }, { |
3684 | .name = "muls.dd.lh" , |
3685 | .translate = translate_mac16, |
3686 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LH, 0}, |
3687 | }, { |
3688 | .name = "muls.dd.ll" , |
3689 | .translate = translate_mac16, |
3690 | .par = (const uint32_t[]){MAC16_MULS, MAC16_LL, 0}, |
3691 | }, { |
3692 | .name = "mulsh" , |
3693 | .translate = translate_mulh, |
3694 | .par = (const uint32_t[]){true}, |
3695 | }, { |
3696 | .name = "muluh" , |
3697 | .translate = translate_mulh, |
3698 | .par = (const uint32_t[]){false}, |
3699 | }, { |
3700 | .name = "neg" , |
3701 | .translate = translate_neg, |
3702 | }, { |
3703 | .name = (const char * const[]) { |
3704 | "nop" , "nop.n" , NULL, |
3705 | }, |
3706 | .translate = translate_nop, |
3707 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3708 | }, { |
3709 | .name = "nsa" , |
3710 | .translate = translate_nsa, |
3711 | }, { |
3712 | .name = "nsau" , |
3713 | .translate = translate_nsau, |
3714 | }, { |
3715 | .name = "or" , |
3716 | .translate = translate_or, |
3717 | }, { |
3718 | .name = "orb" , |
3719 | .translate = translate_boolean, |
3720 | .par = (const uint32_t[]){BOOLEAN_OR}, |
3721 | }, { |
3722 | .name = "orbc" , |
3723 | .translate = translate_boolean, |
3724 | .par = (const uint32_t[]){BOOLEAN_ORC}, |
3725 | }, { |
3726 | .name = "pdtlb" , |
3727 | .translate = translate_ptlb, |
3728 | .par = (const uint32_t[]){true}, |
3729 | .op_flags = XTENSA_OP_PRIVILEGED, |
3730 | }, { |
3731 | .name = "pfend.a" , |
3732 | .translate = translate_nop, |
3733 | }, { |
3734 | .name = "pfend.o" , |
3735 | .translate = translate_nop, |
3736 | }, { |
3737 | .name = "pfnxt.f" , |
3738 | .translate = translate_nop, |
3739 | }, { |
3740 | .name = "pfwait.a" , |
3741 | .translate = translate_nop, |
3742 | }, { |
3743 | .name = "pfwait.o" , |
3744 | .translate = translate_nop, |
3745 | }, { |
3746 | .name = "pitlb" , |
3747 | .translate = translate_ptlb, |
3748 | .par = (const uint32_t[]){false}, |
3749 | .op_flags = XTENSA_OP_PRIVILEGED, |
3750 | }, { |
3751 | .name = "pptlb" , |
3752 | .translate = translate_pptlb, |
3753 | .op_flags = XTENSA_OP_PRIVILEGED, |
3754 | }, { |
3755 | .name = "quos" , |
3756 | .translate = translate_quos, |
3757 | .par = (const uint32_t[]){true}, |
3758 | .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, |
3759 | }, { |
3760 | .name = "quou" , |
3761 | .translate = translate_quou, |
3762 | .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, |
3763 | }, { |
3764 | .name = "rdtlb0" , |
3765 | .translate = translate_rtlb, |
3766 | .par = (const uint32_t[]){true, 0}, |
3767 | .op_flags = XTENSA_OP_PRIVILEGED, |
3768 | }, { |
3769 | .name = "rdtlb1" , |
3770 | .translate = translate_rtlb, |
3771 | .par = (const uint32_t[]){true, 1}, |
3772 | .op_flags = XTENSA_OP_PRIVILEGED, |
3773 | }, { |
3774 | .name = "read_impwire" , |
3775 | .translate = translate_read_impwire, |
3776 | }, { |
3777 | .name = "rems" , |
3778 | .translate = translate_quos, |
3779 | .par = (const uint32_t[]){false}, |
3780 | .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, |
3781 | }, { |
3782 | .name = "remu" , |
3783 | .translate = translate_remu, |
3784 | .op_flags = XTENSA_OP_DIVIDE_BY_ZERO, |
3785 | }, { |
3786 | .name = "rer" , |
3787 | .translate = translate_rer, |
3788 | .op_flags = XTENSA_OP_PRIVILEGED, |
3789 | }, { |
3790 | .name = (const char * const[]) { |
3791 | "ret" , "ret.n" , NULL, |
3792 | }, |
3793 | .translate = translate_ret, |
3794 | .op_flags = XTENSA_OP_NAME_ARRAY, |
3795 | }, { |
3796 | .name = (const char * const[]) { |
3797 | "retw" , "retw.n" , NULL, |
3798 | }, |
3799 | .translate = translate_retw, |
3800 | .test_ill = test_ill_retw, |
3801 | .op_flags = XTENSA_OP_UNDERFLOW | XTENSA_OP_NAME_ARRAY, |
3802 | }, { |
3803 | .name = "rfdd" , |
3804 | .op_flags = XTENSA_OP_ILL, |
3805 | }, { |
3806 | .name = "rfde" , |
3807 | .translate = translate_rfde, |
3808 | .op_flags = XTENSA_OP_PRIVILEGED, |
3809 | }, { |
3810 | .name = "rfdo" , |
3811 | .op_flags = XTENSA_OP_ILL, |
3812 | }, { |
3813 | .name = "rfe" , |
3814 | .translate = translate_rfe, |
3815 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, |
3816 | }, { |
3817 | .name = "rfi" , |
3818 | .translate = translate_rfi, |
3819 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, |
3820 | }, { |
3821 | .name = "rfwo" , |
3822 | .translate = translate_rfw, |
3823 | .par = (const uint32_t[]){true}, |
3824 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, |
3825 | }, { |
3826 | .name = "rfwu" , |
3827 | .translate = translate_rfw, |
3828 | .par = (const uint32_t[]){false}, |
3829 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_CHECK_INTERRUPTS, |
3830 | }, { |
3831 | .name = "ritlb0" , |
3832 | .translate = translate_rtlb, |
3833 | .par = (const uint32_t[]){false, 0}, |
3834 | .op_flags = XTENSA_OP_PRIVILEGED, |
3835 | }, { |
3836 | .name = "ritlb1" , |
3837 | .translate = translate_rtlb, |
3838 | .par = (const uint32_t[]){false, 1}, |
3839 | .op_flags = XTENSA_OP_PRIVILEGED, |
3840 | }, { |
3841 | .name = "rptlb0" , |
3842 | .translate = translate_rptlb0, |
3843 | .op_flags = XTENSA_OP_PRIVILEGED, |
3844 | }, { |
3845 | .name = "rptlb1" , |
3846 | .translate = translate_rptlb1, |
3847 | .op_flags = XTENSA_OP_PRIVILEGED, |
3848 | }, { |
3849 | .name = "rotw" , |
3850 | .translate = translate_rotw, |
3851 | .op_flags = XTENSA_OP_PRIVILEGED | |
3852 | XTENSA_OP_EXIT_TB_M1 | |
3853 | XTENSA_OP_SYNC_REGISTER_WINDOW, |
3854 | }, { |
3855 | .name = "rsil" , |
3856 | .translate = translate_rsil, |
3857 | .op_flags = |
3858 | XTENSA_OP_PRIVILEGED | |
3859 | XTENSA_OP_EXIT_TB_0 | |
3860 | XTENSA_OP_CHECK_INTERRUPTS, |
3861 | }, { |
3862 | .name = "rsr.176" , |
3863 | .translate = translate_rsr, |
3864 | .par = (const uint32_t[]){176}, |
3865 | .op_flags = XTENSA_OP_PRIVILEGED, |
3866 | }, { |
3867 | .name = "rsr.208" , |
3868 | .translate = translate_rsr, |
3869 | .par = (const uint32_t[]){208}, |
3870 | .op_flags = XTENSA_OP_PRIVILEGED, |
3871 | }, { |
3872 | .name = "rsr.acchi" , |
3873 | .translate = translate_rsr, |
3874 | .test_ill = test_ill_sr, |
3875 | .par = (const uint32_t[]){ |
3876 | ACCHI, |
3877 | XTENSA_OPTION_MAC16, |
3878 | }, |
3879 | }, { |
3880 | .name = "rsr.acclo" , |
3881 | .translate = translate_rsr, |
3882 | .test_ill = test_ill_sr, |
3883 | .par = (const uint32_t[]){ |
3884 | ACCLO, |
3885 | XTENSA_OPTION_MAC16, |
3886 | }, |
3887 | }, { |
3888 | .name = "rsr.atomctl" , |
3889 | .translate = translate_rsr, |
3890 | .test_ill = test_ill_sr, |
3891 | .par = (const uint32_t[]){ |
3892 | ATOMCTL, |
3893 | XTENSA_OPTION_ATOMCTL, |
3894 | }, |
3895 | .op_flags = XTENSA_OP_PRIVILEGED, |
3896 | }, { |
3897 | .name = "rsr.br" , |
3898 | .translate = translate_rsr, |
3899 | .test_ill = test_ill_sr, |
3900 | .par = (const uint32_t[]){ |
3901 | BR, |
3902 | XTENSA_OPTION_BOOLEAN, |
3903 | }, |
3904 | }, { |
3905 | .name = "rsr.cacheadrdis" , |
3906 | .translate = translate_rsr, |
3907 | .test_ill = test_ill_sr, |
3908 | .par = (const uint32_t[]){ |
3909 | CACHEADRDIS, |
3910 | XTENSA_OPTION_MPU, |
3911 | }, |
3912 | .op_flags = XTENSA_OP_PRIVILEGED, |
3913 | }, { |
3914 | .name = "rsr.cacheattr" , |
3915 | .translate = translate_rsr, |
3916 | .test_ill = test_ill_sr, |
3917 | .par = (const uint32_t[]){ |
3918 | CACHEATTR, |
3919 | XTENSA_OPTION_CACHEATTR, |
3920 | }, |
3921 | .op_flags = XTENSA_OP_PRIVILEGED, |
3922 | }, { |
3923 | .name = "rsr.ccompare0" , |
3924 | .translate = translate_rsr, |
3925 | .test_ill = test_ill_ccompare, |
3926 | .par = (const uint32_t[]){ |
3927 | CCOMPARE, |
3928 | XTENSA_OPTION_TIMER_INTERRUPT, |
3929 | }, |
3930 | .op_flags = XTENSA_OP_PRIVILEGED, |
3931 | }, { |
3932 | .name = "rsr.ccompare1" , |
3933 | .translate = translate_rsr, |
3934 | .test_ill = test_ill_ccompare, |
3935 | .par = (const uint32_t[]){ |
3936 | CCOMPARE + 1, |
3937 | XTENSA_OPTION_TIMER_INTERRUPT, |
3938 | }, |
3939 | .op_flags = XTENSA_OP_PRIVILEGED, |
3940 | }, { |
3941 | .name = "rsr.ccompare2" , |
3942 | .translate = translate_rsr, |
3943 | .test_ill = test_ill_ccompare, |
3944 | .par = (const uint32_t[]){ |
3945 | CCOMPARE + 2, |
3946 | XTENSA_OPTION_TIMER_INTERRUPT, |
3947 | }, |
3948 | .op_flags = XTENSA_OP_PRIVILEGED, |
3949 | }, { |
3950 | .name = "rsr.ccount" , |
3951 | .translate = translate_rsr_ccount, |
3952 | .test_ill = test_ill_sr, |
3953 | .par = (const uint32_t[]){ |
3954 | CCOUNT, |
3955 | XTENSA_OPTION_TIMER_INTERRUPT, |
3956 | }, |
3957 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
3958 | }, { |
3959 | .name = "rsr.configid0" , |
3960 | .translate = translate_rsr, |
3961 | .par = (const uint32_t[]){CONFIGID0}, |
3962 | .op_flags = XTENSA_OP_PRIVILEGED, |
3963 | }, { |
3964 | .name = "rsr.configid1" , |
3965 | .translate = translate_rsr, |
3966 | .par = (const uint32_t[]){CONFIGID1}, |
3967 | .op_flags = XTENSA_OP_PRIVILEGED, |
3968 | }, { |
3969 | .name = "rsr.cpenable" , |
3970 | .translate = translate_rsr, |
3971 | .test_ill = test_ill_sr, |
3972 | .par = (const uint32_t[]){ |
3973 | CPENABLE, |
3974 | XTENSA_OPTION_COPROCESSOR, |
3975 | }, |
3976 | .op_flags = XTENSA_OP_PRIVILEGED, |
3977 | }, { |
3978 | .name = "rsr.dbreaka0" , |
3979 | .translate = translate_rsr, |
3980 | .test_ill = test_ill_dbreak, |
3981 | .par = (const uint32_t[]){ |
3982 | DBREAKA, |
3983 | XTENSA_OPTION_DEBUG, |
3984 | }, |
3985 | .op_flags = XTENSA_OP_PRIVILEGED, |
3986 | }, { |
3987 | .name = "rsr.dbreaka1" , |
3988 | .translate = translate_rsr, |
3989 | .test_ill = test_ill_dbreak, |
3990 | .par = (const uint32_t[]){ |
3991 | DBREAKA + 1, |
3992 | XTENSA_OPTION_DEBUG, |
3993 | }, |
3994 | .op_flags = XTENSA_OP_PRIVILEGED, |
3995 | }, { |
3996 | .name = "rsr.dbreakc0" , |
3997 | .translate = translate_rsr, |
3998 | .test_ill = test_ill_dbreak, |
3999 | .par = (const uint32_t[]){ |
4000 | DBREAKC, |
4001 | XTENSA_OPTION_DEBUG, |
4002 | }, |
4003 | .op_flags = XTENSA_OP_PRIVILEGED, |
4004 | }, { |
4005 | .name = "rsr.dbreakc1" , |
4006 | .translate = translate_rsr, |
4007 | .test_ill = test_ill_dbreak, |
4008 | .par = (const uint32_t[]){ |
4009 | DBREAKC + 1, |
4010 | XTENSA_OPTION_DEBUG, |
4011 | }, |
4012 | .op_flags = XTENSA_OP_PRIVILEGED, |
4013 | }, { |
4014 | .name = "rsr.ddr" , |
4015 | .translate = translate_rsr, |
4016 | .test_ill = test_ill_sr, |
4017 | .par = (const uint32_t[]){ |
4018 | DDR, |
4019 | XTENSA_OPTION_DEBUG, |
4020 | }, |
4021 | .op_flags = XTENSA_OP_PRIVILEGED, |
4022 | }, { |
4023 | .name = "rsr.debugcause" , |
4024 | .translate = translate_rsr, |
4025 | .test_ill = test_ill_sr, |
4026 | .par = (const uint32_t[]){ |
4027 | DEBUGCAUSE, |
4028 | XTENSA_OPTION_DEBUG, |
4029 | }, |
4030 | .op_flags = XTENSA_OP_PRIVILEGED, |
4031 | }, { |
4032 | .name = "rsr.depc" , |
4033 | .translate = translate_rsr, |
4034 | .test_ill = test_ill_sr, |
4035 | .par = (const uint32_t[]){ |
4036 | DEPC, |
4037 | XTENSA_OPTION_EXCEPTION, |
4038 | }, |
4039 | .op_flags = XTENSA_OP_PRIVILEGED, |
4040 | }, { |
4041 | .name = "rsr.dtlbcfg" , |
4042 | .translate = translate_rsr, |
4043 | .test_ill = test_ill_sr, |
4044 | .par = (const uint32_t[]){ |
4045 | DTLBCFG, |
4046 | XTENSA_OPTION_MMU, |
4047 | }, |
4048 | .op_flags = XTENSA_OP_PRIVILEGED, |
4049 | }, { |
4050 | .name = "rsr.epc1" , |
4051 | .translate = translate_rsr, |
4052 | .test_ill = test_ill_sr, |
4053 | .par = (const uint32_t[]){ |
4054 | EPC1, |
4055 | XTENSA_OPTION_EXCEPTION, |
4056 | }, |
4057 | .op_flags = XTENSA_OP_PRIVILEGED, |
4058 | }, { |
4059 | .name = "rsr.epc2" , |
4060 | .translate = translate_rsr, |
4061 | .test_ill = test_ill_hpi, |
4062 | .par = (const uint32_t[]){ |
4063 | EPC1 + 1, |
4064 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4065 | }, |
4066 | .op_flags = XTENSA_OP_PRIVILEGED, |
4067 | }, { |
4068 | .name = "rsr.epc3" , |
4069 | .translate = translate_rsr, |
4070 | .test_ill = test_ill_hpi, |
4071 | .par = (const uint32_t[]){ |
4072 | EPC1 + 2, |
4073 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4074 | }, |
4075 | .op_flags = XTENSA_OP_PRIVILEGED, |
4076 | }, { |
4077 | .name = "rsr.epc4" , |
4078 | .translate = translate_rsr, |
4079 | .test_ill = test_ill_hpi, |
4080 | .par = (const uint32_t[]){ |
4081 | EPC1 + 3, |
4082 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4083 | }, |
4084 | .op_flags = XTENSA_OP_PRIVILEGED, |
4085 | }, { |
4086 | .name = "rsr.epc5" , |
4087 | .translate = translate_rsr, |
4088 | .test_ill = test_ill_hpi, |
4089 | .par = (const uint32_t[]){ |
4090 | EPC1 + 4, |
4091 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4092 | }, |
4093 | .op_flags = XTENSA_OP_PRIVILEGED, |
4094 | }, { |
4095 | .name = "rsr.epc6" , |
4096 | .translate = translate_rsr, |
4097 | .test_ill = test_ill_hpi, |
4098 | .par = (const uint32_t[]){ |
4099 | EPC1 + 5, |
4100 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4101 | }, |
4102 | .op_flags = XTENSA_OP_PRIVILEGED, |
4103 | }, { |
4104 | .name = "rsr.epc7" , |
4105 | .translate = translate_rsr, |
4106 | .test_ill = test_ill_hpi, |
4107 | .par = (const uint32_t[]){ |
4108 | EPC1 + 6, |
4109 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4110 | }, |
4111 | .op_flags = XTENSA_OP_PRIVILEGED, |
4112 | }, { |
4113 | .name = "rsr.eps2" , |
4114 | .translate = translate_rsr, |
4115 | .test_ill = test_ill_hpi, |
4116 | .par = (const uint32_t[]){ |
4117 | EPS2, |
4118 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4119 | }, |
4120 | .op_flags = XTENSA_OP_PRIVILEGED, |
4121 | }, { |
4122 | .name = "rsr.eps3" , |
4123 | .translate = translate_rsr, |
4124 | .test_ill = test_ill_hpi, |
4125 | .par = (const uint32_t[]){ |
4126 | EPS2 + 1, |
4127 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4128 | }, |
4129 | .op_flags = XTENSA_OP_PRIVILEGED, |
4130 | }, { |
4131 | .name = "rsr.eps4" , |
4132 | .translate = translate_rsr, |
4133 | .test_ill = test_ill_hpi, |
4134 | .par = (const uint32_t[]){ |
4135 | EPS2 + 2, |
4136 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4137 | }, |
4138 | .op_flags = XTENSA_OP_PRIVILEGED, |
4139 | }, { |
4140 | .name = "rsr.eps5" , |
4141 | .translate = translate_rsr, |
4142 | .test_ill = test_ill_hpi, |
4143 | .par = (const uint32_t[]){ |
4144 | EPS2 + 3, |
4145 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4146 | }, |
4147 | .op_flags = XTENSA_OP_PRIVILEGED, |
4148 | }, { |
4149 | .name = "rsr.eps6" , |
4150 | .translate = translate_rsr, |
4151 | .test_ill = test_ill_hpi, |
4152 | .par = (const uint32_t[]){ |
4153 | EPS2 + 4, |
4154 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4155 | }, |
4156 | .op_flags = XTENSA_OP_PRIVILEGED, |
4157 | }, { |
4158 | .name = "rsr.eps7" , |
4159 | .translate = translate_rsr, |
4160 | .test_ill = test_ill_hpi, |
4161 | .par = (const uint32_t[]){ |
4162 | EPS2 + 5, |
4163 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4164 | }, |
4165 | .op_flags = XTENSA_OP_PRIVILEGED, |
4166 | }, { |
4167 | .name = "rsr.eraccess" , |
4168 | .translate = translate_rsr, |
4169 | .par = (const uint32_t[]){ERACCESS}, |
4170 | .op_flags = XTENSA_OP_PRIVILEGED, |
4171 | }, { |
4172 | .name = "rsr.exccause" , |
4173 | .translate = translate_rsr, |
4174 | .test_ill = test_ill_sr, |
4175 | .par = (const uint32_t[]){ |
4176 | EXCCAUSE, |
4177 | XTENSA_OPTION_EXCEPTION, |
4178 | }, |
4179 | .op_flags = XTENSA_OP_PRIVILEGED, |
4180 | }, { |
4181 | .name = "rsr.excsave1" , |
4182 | .translate = translate_rsr, |
4183 | .test_ill = test_ill_sr, |
4184 | .par = (const uint32_t[]){ |
4185 | EXCSAVE1, |
4186 | XTENSA_OPTION_EXCEPTION, |
4187 | }, |
4188 | .op_flags = XTENSA_OP_PRIVILEGED, |
4189 | }, { |
4190 | .name = "rsr.excsave2" , |
4191 | .translate = translate_rsr, |
4192 | .test_ill = test_ill_hpi, |
4193 | .par = (const uint32_t[]){ |
4194 | EXCSAVE1 + 1, |
4195 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4196 | }, |
4197 | .op_flags = XTENSA_OP_PRIVILEGED, |
4198 | }, { |
4199 | .name = "rsr.excsave3" , |
4200 | .translate = translate_rsr, |
4201 | .test_ill = test_ill_hpi, |
4202 | .par = (const uint32_t[]){ |
4203 | EXCSAVE1 + 2, |
4204 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4205 | }, |
4206 | .op_flags = XTENSA_OP_PRIVILEGED, |
4207 | }, { |
4208 | .name = "rsr.excsave4" , |
4209 | .translate = translate_rsr, |
4210 | .test_ill = test_ill_hpi, |
4211 | .par = (const uint32_t[]){ |
4212 | EXCSAVE1 + 3, |
4213 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4214 | }, |
4215 | .op_flags = XTENSA_OP_PRIVILEGED, |
4216 | }, { |
4217 | .name = "rsr.excsave5" , |
4218 | .translate = translate_rsr, |
4219 | .test_ill = test_ill_hpi, |
4220 | .par = (const uint32_t[]){ |
4221 | EXCSAVE1 + 4, |
4222 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4223 | }, |
4224 | .op_flags = XTENSA_OP_PRIVILEGED, |
4225 | }, { |
4226 | .name = "rsr.excsave6" , |
4227 | .translate = translate_rsr, |
4228 | .test_ill = test_ill_hpi, |
4229 | .par = (const uint32_t[]){ |
4230 | EXCSAVE1 + 5, |
4231 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4232 | }, |
4233 | .op_flags = XTENSA_OP_PRIVILEGED, |
4234 | }, { |
4235 | .name = "rsr.excsave7" , |
4236 | .translate = translate_rsr, |
4237 | .test_ill = test_ill_hpi, |
4238 | .par = (const uint32_t[]){ |
4239 | EXCSAVE1 + 6, |
4240 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4241 | }, |
4242 | .op_flags = XTENSA_OP_PRIVILEGED, |
4243 | }, { |
4244 | .name = "rsr.excvaddr" , |
4245 | .translate = translate_rsr, |
4246 | .test_ill = test_ill_sr, |
4247 | .par = (const uint32_t[]){ |
4248 | EXCVADDR, |
4249 | XTENSA_OPTION_EXCEPTION, |
4250 | }, |
4251 | .op_flags = XTENSA_OP_PRIVILEGED, |
4252 | }, { |
4253 | .name = "rsr.ibreaka0" , |
4254 | .translate = translate_rsr, |
4255 | .test_ill = test_ill_ibreak, |
4256 | .par = (const uint32_t[]){ |
4257 | IBREAKA, |
4258 | XTENSA_OPTION_DEBUG, |
4259 | }, |
4260 | .op_flags = XTENSA_OP_PRIVILEGED, |
4261 | }, { |
4262 | .name = "rsr.ibreaka1" , |
4263 | .translate = translate_rsr, |
4264 | .test_ill = test_ill_ibreak, |
4265 | .par = (const uint32_t[]){ |
4266 | IBREAKA + 1, |
4267 | XTENSA_OPTION_DEBUG, |
4268 | }, |
4269 | .op_flags = XTENSA_OP_PRIVILEGED, |
4270 | }, { |
4271 | .name = "rsr.ibreakenable" , |
4272 | .translate = translate_rsr, |
4273 | .test_ill = test_ill_sr, |
4274 | .par = (const uint32_t[]){ |
4275 | IBREAKENABLE, |
4276 | XTENSA_OPTION_DEBUG, |
4277 | }, |
4278 | .op_flags = XTENSA_OP_PRIVILEGED, |
4279 | }, { |
4280 | .name = "rsr.icount" , |
4281 | .translate = translate_rsr, |
4282 | .test_ill = test_ill_sr, |
4283 | .par = (const uint32_t[]){ |
4284 | ICOUNT, |
4285 | XTENSA_OPTION_DEBUG, |
4286 | }, |
4287 | .op_flags = XTENSA_OP_PRIVILEGED, |
4288 | }, { |
4289 | .name = "rsr.icountlevel" , |
4290 | .translate = translate_rsr, |
4291 | .test_ill = test_ill_sr, |
4292 | .par = (const uint32_t[]){ |
4293 | ICOUNTLEVEL, |
4294 | XTENSA_OPTION_DEBUG, |
4295 | }, |
4296 | .op_flags = XTENSA_OP_PRIVILEGED, |
4297 | }, { |
4298 | .name = "rsr.intclear" , |
4299 | .translate = translate_rsr, |
4300 | .test_ill = test_ill_sr, |
4301 | .par = (const uint32_t[]){ |
4302 | INTCLEAR, |
4303 | XTENSA_OPTION_INTERRUPT, |
4304 | }, |
4305 | .op_flags = XTENSA_OP_PRIVILEGED, |
4306 | }, { |
4307 | .name = "rsr.intenable" , |
4308 | .translate = translate_rsr, |
4309 | .test_ill = test_ill_sr, |
4310 | .par = (const uint32_t[]){ |
4311 | INTENABLE, |
4312 | XTENSA_OPTION_INTERRUPT, |
4313 | }, |
4314 | .op_flags = XTENSA_OP_PRIVILEGED, |
4315 | }, { |
4316 | .name = "rsr.interrupt" , |
4317 | .translate = translate_rsr_ccount, |
4318 | .test_ill = test_ill_sr, |
4319 | .par = (const uint32_t[]){ |
4320 | INTSET, |
4321 | XTENSA_OPTION_INTERRUPT, |
4322 | }, |
4323 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
4324 | }, { |
4325 | .name = "rsr.intset" , |
4326 | .translate = translate_rsr_ccount, |
4327 | .test_ill = test_ill_sr, |
4328 | .par = (const uint32_t[]){ |
4329 | INTSET, |
4330 | XTENSA_OPTION_INTERRUPT, |
4331 | }, |
4332 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
4333 | }, { |
4334 | .name = "rsr.itlbcfg" , |
4335 | .translate = translate_rsr, |
4336 | .test_ill = test_ill_sr, |
4337 | .par = (const uint32_t[]){ |
4338 | ITLBCFG, |
4339 | XTENSA_OPTION_MMU, |
4340 | }, |
4341 | .op_flags = XTENSA_OP_PRIVILEGED, |
4342 | }, { |
4343 | .name = "rsr.lbeg" , |
4344 | .translate = translate_rsr, |
4345 | .test_ill = test_ill_sr, |
4346 | .par = (const uint32_t[]){ |
4347 | LBEG, |
4348 | XTENSA_OPTION_LOOP, |
4349 | }, |
4350 | }, { |
4351 | .name = "rsr.lcount" , |
4352 | .translate = translate_rsr, |
4353 | .test_ill = test_ill_sr, |
4354 | .par = (const uint32_t[]){ |
4355 | LCOUNT, |
4356 | XTENSA_OPTION_LOOP, |
4357 | }, |
4358 | }, { |
4359 | .name = "rsr.lend" , |
4360 | .translate = translate_rsr, |
4361 | .test_ill = test_ill_sr, |
4362 | .par = (const uint32_t[]){ |
4363 | LEND, |
4364 | XTENSA_OPTION_LOOP, |
4365 | }, |
4366 | }, { |
4367 | .name = "rsr.litbase" , |
4368 | .translate = translate_rsr, |
4369 | .test_ill = test_ill_sr, |
4370 | .par = (const uint32_t[]){ |
4371 | LITBASE, |
4372 | XTENSA_OPTION_EXTENDED_L32R, |
4373 | }, |
4374 | }, { |
4375 | .name = "rsr.m0" , |
4376 | .translate = translate_rsr, |
4377 | .test_ill = test_ill_sr, |
4378 | .par = (const uint32_t[]){ |
4379 | MR, |
4380 | XTENSA_OPTION_MAC16, |
4381 | }, |
4382 | }, { |
4383 | .name = "rsr.m1" , |
4384 | .translate = translate_rsr, |
4385 | .test_ill = test_ill_sr, |
4386 | .par = (const uint32_t[]){ |
4387 | MR + 1, |
4388 | XTENSA_OPTION_MAC16, |
4389 | }, |
4390 | }, { |
4391 | .name = "rsr.m2" , |
4392 | .translate = translate_rsr, |
4393 | .test_ill = test_ill_sr, |
4394 | .par = (const uint32_t[]){ |
4395 | MR + 2, |
4396 | XTENSA_OPTION_MAC16, |
4397 | }, |
4398 | }, { |
4399 | .name = "rsr.m3" , |
4400 | .translate = translate_rsr, |
4401 | .test_ill = test_ill_sr, |
4402 | .par = (const uint32_t[]){ |
4403 | MR + 3, |
4404 | XTENSA_OPTION_MAC16, |
4405 | }, |
4406 | }, { |
4407 | .name = "rsr.memctl" , |
4408 | .translate = translate_rsr, |
4409 | .par = (const uint32_t[]){MEMCTL}, |
4410 | .op_flags = XTENSA_OP_PRIVILEGED, |
4411 | }, { |
4412 | .name = "rsr.mecr" , |
4413 | .translate = translate_rsr, |
4414 | .test_ill = test_ill_sr, |
4415 | .par = (const uint32_t[]){ |
4416 | MECR, |
4417 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
4418 | }, |
4419 | .op_flags = XTENSA_OP_PRIVILEGED, |
4420 | }, { |
4421 | .name = "rsr.mepc" , |
4422 | .translate = translate_rsr, |
4423 | .test_ill = test_ill_sr, |
4424 | .par = (const uint32_t[]){ |
4425 | MEPC, |
4426 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
4427 | }, |
4428 | .op_flags = XTENSA_OP_PRIVILEGED, |
4429 | }, { |
4430 | .name = "rsr.meps" , |
4431 | .translate = translate_rsr, |
4432 | .test_ill = test_ill_sr, |
4433 | .par = (const uint32_t[]){ |
4434 | MEPS, |
4435 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
4436 | }, |
4437 | .op_flags = XTENSA_OP_PRIVILEGED, |
4438 | }, { |
4439 | .name = "rsr.mesave" , |
4440 | .translate = translate_rsr, |
4441 | .test_ill = test_ill_sr, |
4442 | .par = (const uint32_t[]){ |
4443 | MESAVE, |
4444 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
4445 | }, |
4446 | .op_flags = XTENSA_OP_PRIVILEGED, |
4447 | }, { |
4448 | .name = "rsr.mesr" , |
4449 | .translate = translate_rsr, |
4450 | .test_ill = test_ill_sr, |
4451 | .par = (const uint32_t[]){ |
4452 | MESR, |
4453 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
4454 | }, |
4455 | .op_flags = XTENSA_OP_PRIVILEGED, |
4456 | }, { |
4457 | .name = "rsr.mevaddr" , |
4458 | .translate = translate_rsr, |
4459 | .test_ill = test_ill_sr, |
4460 | .par = (const uint32_t[]){ |
4461 | MESR, |
4462 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
4463 | }, |
4464 | .op_flags = XTENSA_OP_PRIVILEGED, |
4465 | }, { |
4466 | .name = "rsr.misc0" , |
4467 | .translate = translate_rsr, |
4468 | .test_ill = test_ill_sr, |
4469 | .par = (const uint32_t[]){ |
4470 | MISC, |
4471 | XTENSA_OPTION_MISC_SR, |
4472 | }, |
4473 | .op_flags = XTENSA_OP_PRIVILEGED, |
4474 | }, { |
4475 | .name = "rsr.misc1" , |
4476 | .translate = translate_rsr, |
4477 | .test_ill = test_ill_sr, |
4478 | .par = (const uint32_t[]){ |
4479 | MISC + 1, |
4480 | XTENSA_OPTION_MISC_SR, |
4481 | }, |
4482 | .op_flags = XTENSA_OP_PRIVILEGED, |
4483 | }, { |
4484 | .name = "rsr.misc2" , |
4485 | .translate = translate_rsr, |
4486 | .test_ill = test_ill_sr, |
4487 | .par = (const uint32_t[]){ |
4488 | MISC + 2, |
4489 | XTENSA_OPTION_MISC_SR, |
4490 | }, |
4491 | .op_flags = XTENSA_OP_PRIVILEGED, |
4492 | }, { |
4493 | .name = "rsr.misc3" , |
4494 | .translate = translate_rsr, |
4495 | .test_ill = test_ill_sr, |
4496 | .par = (const uint32_t[]){ |
4497 | MISC + 3, |
4498 | XTENSA_OPTION_MISC_SR, |
4499 | }, |
4500 | .op_flags = XTENSA_OP_PRIVILEGED, |
4501 | }, { |
4502 | .name = "rsr.mpucfg" , |
4503 | .translate = translate_rsr, |
4504 | .test_ill = test_ill_sr, |
4505 | .par = (const uint32_t[]){ |
4506 | MPUCFG, |
4507 | XTENSA_OPTION_MPU, |
4508 | }, |
4509 | .op_flags = XTENSA_OP_PRIVILEGED, |
4510 | }, { |
4511 | .name = "rsr.mpuenb" , |
4512 | .translate = translate_rsr, |
4513 | .test_ill = test_ill_sr, |
4514 | .par = (const uint32_t[]){ |
4515 | MPUENB, |
4516 | XTENSA_OPTION_MPU, |
4517 | }, |
4518 | .op_flags = XTENSA_OP_PRIVILEGED, |
4519 | }, { |
4520 | .name = "rsr.prefctl" , |
4521 | .translate = translate_rsr, |
4522 | .par = (const uint32_t[]){PREFCTL}, |
4523 | }, { |
4524 | .name = "rsr.prid" , |
4525 | .translate = translate_rsr, |
4526 | .test_ill = test_ill_sr, |
4527 | .par = (const uint32_t[]){ |
4528 | PRID, |
4529 | XTENSA_OPTION_PROCESSOR_ID, |
4530 | }, |
4531 | .op_flags = XTENSA_OP_PRIVILEGED, |
4532 | }, { |
4533 | .name = "rsr.ps" , |
4534 | .translate = translate_rsr, |
4535 | .test_ill = test_ill_sr, |
4536 | .par = (const uint32_t[]){ |
4537 | PS, |
4538 | XTENSA_OPTION_EXCEPTION, |
4539 | }, |
4540 | .op_flags = XTENSA_OP_PRIVILEGED, |
4541 | }, { |
4542 | .name = "rsr.ptevaddr" , |
4543 | .translate = translate_rsr_ptevaddr, |
4544 | .test_ill = test_ill_sr, |
4545 | .par = (const uint32_t[]){ |
4546 | PTEVADDR, |
4547 | XTENSA_OPTION_MMU, |
4548 | }, |
4549 | .op_flags = XTENSA_OP_PRIVILEGED, |
4550 | }, { |
4551 | .name = "rsr.rasid" , |
4552 | .translate = translate_rsr, |
4553 | .test_ill = test_ill_sr, |
4554 | .par = (const uint32_t[]){ |
4555 | RASID, |
4556 | XTENSA_OPTION_MMU, |
4557 | }, |
4558 | .op_flags = XTENSA_OP_PRIVILEGED, |
4559 | }, { |
4560 | .name = "rsr.sar" , |
4561 | .translate = translate_rsr, |
4562 | .par = (const uint32_t[]){SAR}, |
4563 | }, { |
4564 | .name = "rsr.scompare1" , |
4565 | .translate = translate_rsr, |
4566 | .test_ill = test_ill_sr, |
4567 | .par = (const uint32_t[]){ |
4568 | SCOMPARE1, |
4569 | XTENSA_OPTION_CONDITIONAL_STORE, |
4570 | }, |
4571 | }, { |
4572 | .name = "rsr.vecbase" , |
4573 | .translate = translate_rsr, |
4574 | .test_ill = test_ill_sr, |
4575 | .par = (const uint32_t[]){ |
4576 | VECBASE, |
4577 | XTENSA_OPTION_RELOCATABLE_VECTOR, |
4578 | }, |
4579 | .op_flags = XTENSA_OP_PRIVILEGED, |
4580 | }, { |
4581 | .name = "rsr.windowbase" , |
4582 | .translate = translate_rsr, |
4583 | .test_ill = test_ill_sr, |
4584 | .par = (const uint32_t[]){ |
4585 | WINDOW_BASE, |
4586 | XTENSA_OPTION_WINDOWED_REGISTER, |
4587 | }, |
4588 | .op_flags = XTENSA_OP_PRIVILEGED, |
4589 | }, { |
4590 | .name = "rsr.windowstart" , |
4591 | .translate = translate_rsr, |
4592 | .test_ill = test_ill_sr, |
4593 | .par = (const uint32_t[]){ |
4594 | WINDOW_START, |
4595 | XTENSA_OPTION_WINDOWED_REGISTER, |
4596 | }, |
4597 | .op_flags = XTENSA_OP_PRIVILEGED, |
4598 | }, { |
4599 | .name = "rsync" , |
4600 | .translate = translate_nop, |
4601 | }, { |
4602 | .name = "rur.expstate" , |
4603 | .translate = translate_rur, |
4604 | .par = (const uint32_t[]){EXPSTATE}, |
4605 | }, { |
4606 | .name = "rur.fcr" , |
4607 | .translate = translate_rur, |
4608 | .par = (const uint32_t[]){FCR}, |
4609 | .coprocessor = 0x1, |
4610 | }, { |
4611 | .name = "rur.fsr" , |
4612 | .translate = translate_rur, |
4613 | .par = (const uint32_t[]){FSR}, |
4614 | .coprocessor = 0x1, |
4615 | }, { |
4616 | .name = "rur.threadptr" , |
4617 | .translate = translate_rur, |
4618 | .par = (const uint32_t[]){THREADPTR}, |
4619 | }, { |
4620 | .name = "s16i" , |
4621 | .translate = translate_ldst, |
4622 | .par = (const uint32_t[]){MO_TEUW, false, true}, |
4623 | .op_flags = XTENSA_OP_STORE, |
4624 | }, { |
4625 | .name = "s32c1i" , |
4626 | .translate = translate_s32c1i, |
4627 | .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE, |
4628 | }, { |
4629 | .name = "s32e" , |
4630 | .translate = translate_s32e, |
4631 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_STORE, |
4632 | }, { |
4633 | .name = "s32ex" , |
4634 | .translate = translate_s32ex, |
4635 | .op_flags = XTENSA_OP_LOAD | XTENSA_OP_STORE, |
4636 | }, { |
4637 | .name = (const char * const[]) { |
4638 | "s32i" , "s32i.n" , "s32nb" , NULL, |
4639 | }, |
4640 | .translate = translate_ldst, |
4641 | .par = (const uint32_t[]){MO_TEUL, false, true}, |
4642 | .op_flags = XTENSA_OP_NAME_ARRAY | XTENSA_OP_STORE, |
4643 | }, { |
4644 | .name = "s32ri" , |
4645 | .translate = translate_ldst, |
4646 | .par = (const uint32_t[]){MO_TEUL, true, true}, |
4647 | .op_flags = XTENSA_OP_STORE, |
4648 | }, { |
4649 | .name = "s8i" , |
4650 | .translate = translate_ldst, |
4651 | .par = (const uint32_t[]){MO_UB, false, true}, |
4652 | .op_flags = XTENSA_OP_STORE, |
4653 | }, { |
4654 | .name = "salt" , |
4655 | .translate = translate_salt, |
4656 | .par = (const uint32_t[]){TCG_COND_LT}, |
4657 | }, { |
4658 | .name = "saltu" , |
4659 | .translate = translate_salt, |
4660 | .par = (const uint32_t[]){TCG_COND_LTU}, |
4661 | }, { |
4662 | .name = "setb_expstate" , |
4663 | .translate = translate_setb_expstate, |
4664 | }, { |
4665 | .name = "sext" , |
4666 | .translate = translate_sext, |
4667 | }, { |
4668 | .name = "simcall" , |
4669 | .translate = translate_simcall, |
4670 | .test_ill = test_ill_simcall, |
4671 | .op_flags = XTENSA_OP_PRIVILEGED, |
4672 | }, { |
4673 | .name = "sll" , |
4674 | .translate = translate_sll, |
4675 | }, { |
4676 | .name = "slli" , |
4677 | .translate = translate_slli, |
4678 | }, { |
4679 | .name = "sra" , |
4680 | .translate = translate_sra, |
4681 | }, { |
4682 | .name = "srai" , |
4683 | .translate = translate_srai, |
4684 | }, { |
4685 | .name = "src" , |
4686 | .translate = translate_src, |
4687 | }, { |
4688 | .name = "srl" , |
4689 | .translate = translate_srl, |
4690 | }, { |
4691 | .name = "srli" , |
4692 | .translate = translate_srli, |
4693 | }, { |
4694 | .name = "ssa8b" , |
4695 | .translate = translate_ssa8b, |
4696 | }, { |
4697 | .name = "ssa8l" , |
4698 | .translate = translate_ssa8l, |
4699 | }, { |
4700 | .name = "ssai" , |
4701 | .translate = translate_ssai, |
4702 | }, { |
4703 | .name = "ssl" , |
4704 | .translate = translate_ssl, |
4705 | }, { |
4706 | .name = "ssr" , |
4707 | .translate = translate_ssr, |
4708 | }, { |
4709 | .name = "sub" , |
4710 | .translate = translate_sub, |
4711 | }, { |
4712 | .name = "subx2" , |
4713 | .translate = translate_subx, |
4714 | .par = (const uint32_t[]){1}, |
4715 | }, { |
4716 | .name = "subx4" , |
4717 | .translate = translate_subx, |
4718 | .par = (const uint32_t[]){2}, |
4719 | }, { |
4720 | .name = "subx8" , |
4721 | .translate = translate_subx, |
4722 | .par = (const uint32_t[]){3}, |
4723 | }, { |
4724 | .name = "syscall" , |
4725 | .op_flags = XTENSA_OP_SYSCALL, |
4726 | }, { |
4727 | .name = "umul.aa.hh" , |
4728 | .translate = translate_mac16, |
4729 | .par = (const uint32_t[]){MAC16_UMUL, MAC16_HH, 0}, |
4730 | }, { |
4731 | .name = "umul.aa.hl" , |
4732 | .translate = translate_mac16, |
4733 | .par = (const uint32_t[]){MAC16_UMUL, MAC16_HL, 0}, |
4734 | }, { |
4735 | .name = "umul.aa.lh" , |
4736 | .translate = translate_mac16, |
4737 | .par = (const uint32_t[]){MAC16_UMUL, MAC16_LH, 0}, |
4738 | }, { |
4739 | .name = "umul.aa.ll" , |
4740 | .translate = translate_mac16, |
4741 | .par = (const uint32_t[]){MAC16_UMUL, MAC16_LL, 0}, |
4742 | }, { |
4743 | .name = "waiti" , |
4744 | .translate = translate_waiti, |
4745 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
4746 | }, { |
4747 | .name = "wdtlb" , |
4748 | .translate = translate_wtlb, |
4749 | .par = (const uint32_t[]){true}, |
4750 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
4751 | }, { |
4752 | .name = "wer" , |
4753 | .translate = translate_wer, |
4754 | .op_flags = XTENSA_OP_PRIVILEGED, |
4755 | }, { |
4756 | .name = "witlb" , |
4757 | .translate = translate_wtlb, |
4758 | .par = (const uint32_t[]){false}, |
4759 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
4760 | }, { |
4761 | .name = "wptlb" , |
4762 | .translate = translate_wptlb, |
4763 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
4764 | }, { |
4765 | .name = "wrmsk_expstate" , |
4766 | .translate = translate_wrmsk_expstate, |
4767 | }, { |
4768 | .name = "wsr.176" , |
4769 | .op_flags = XTENSA_OP_ILL, |
4770 | }, { |
4771 | .name = "wsr.208" , |
4772 | .op_flags = XTENSA_OP_ILL, |
4773 | }, { |
4774 | .name = "wsr.acchi" , |
4775 | .translate = translate_wsr_acchi, |
4776 | .test_ill = test_ill_sr, |
4777 | .par = (const uint32_t[]){ |
4778 | ACCHI, |
4779 | XTENSA_OPTION_MAC16, |
4780 | }, |
4781 | }, { |
4782 | .name = "wsr.acclo" , |
4783 | .translate = translate_wsr, |
4784 | .test_ill = test_ill_sr, |
4785 | .par = (const uint32_t[]){ |
4786 | ACCLO, |
4787 | XTENSA_OPTION_MAC16, |
4788 | }, |
4789 | }, { |
4790 | .name = "wsr.atomctl" , |
4791 | .translate = translate_wsr_mask, |
4792 | .test_ill = test_ill_sr, |
4793 | .par = (const uint32_t[]){ |
4794 | ATOMCTL, |
4795 | XTENSA_OPTION_ATOMCTL, |
4796 | 0x3f, |
4797 | }, |
4798 | .op_flags = XTENSA_OP_PRIVILEGED, |
4799 | }, { |
4800 | .name = "wsr.br" , |
4801 | .translate = translate_wsr_mask, |
4802 | .test_ill = test_ill_sr, |
4803 | .par = (const uint32_t[]){ |
4804 | BR, |
4805 | XTENSA_OPTION_BOOLEAN, |
4806 | 0xffff, |
4807 | }, |
4808 | }, { |
4809 | .name = "wsr.cacheadrdis" , |
4810 | .translate = translate_wsr_mask, |
4811 | .test_ill = test_ill_sr, |
4812 | .par = (const uint32_t[]){ |
4813 | CACHEADRDIS, |
4814 | XTENSA_OPTION_MPU, |
4815 | 0xff, |
4816 | }, |
4817 | .op_flags = XTENSA_OP_PRIVILEGED, |
4818 | }, { |
4819 | .name = "wsr.cacheattr" , |
4820 | .translate = translate_wsr, |
4821 | .test_ill = test_ill_sr, |
4822 | .par = (const uint32_t[]){ |
4823 | CACHEATTR, |
4824 | XTENSA_OPTION_CACHEATTR, |
4825 | }, |
4826 | .op_flags = XTENSA_OP_PRIVILEGED, |
4827 | }, { |
4828 | .name = "wsr.ccompare0" , |
4829 | .translate = translate_wsr_ccompare, |
4830 | .test_ill = test_ill_ccompare, |
4831 | .par = (const uint32_t[]){ |
4832 | CCOMPARE, |
4833 | XTENSA_OPTION_TIMER_INTERRUPT, |
4834 | }, |
4835 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
4836 | }, { |
4837 | .name = "wsr.ccompare1" , |
4838 | .translate = translate_wsr_ccompare, |
4839 | .test_ill = test_ill_ccompare, |
4840 | .par = (const uint32_t[]){ |
4841 | CCOMPARE + 1, |
4842 | XTENSA_OPTION_TIMER_INTERRUPT, |
4843 | }, |
4844 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
4845 | }, { |
4846 | .name = "wsr.ccompare2" , |
4847 | .translate = translate_wsr_ccompare, |
4848 | .test_ill = test_ill_ccompare, |
4849 | .par = (const uint32_t[]){ |
4850 | CCOMPARE + 2, |
4851 | XTENSA_OPTION_TIMER_INTERRUPT, |
4852 | }, |
4853 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
4854 | }, { |
4855 | .name = "wsr.ccount" , |
4856 | .translate = translate_wsr_ccount, |
4857 | .test_ill = test_ill_sr, |
4858 | .par = (const uint32_t[]){ |
4859 | CCOUNT, |
4860 | XTENSA_OPTION_TIMER_INTERRUPT, |
4861 | }, |
4862 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
4863 | }, { |
4864 | .name = "wsr.configid0" , |
4865 | .op_flags = XTENSA_OP_ILL, |
4866 | }, { |
4867 | .name = "wsr.configid1" , |
4868 | .op_flags = XTENSA_OP_ILL, |
4869 | }, { |
4870 | .name = "wsr.cpenable" , |
4871 | .translate = translate_wsr_mask, |
4872 | .test_ill = test_ill_sr, |
4873 | .par = (const uint32_t[]){ |
4874 | CPENABLE, |
4875 | XTENSA_OPTION_COPROCESSOR, |
4876 | 0xff, |
4877 | }, |
4878 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
4879 | }, { |
4880 | .name = "wsr.dbreaka0" , |
4881 | .translate = translate_wsr_dbreaka, |
4882 | .test_ill = test_ill_dbreak, |
4883 | .par = (const uint32_t[]){ |
4884 | DBREAKA, |
4885 | XTENSA_OPTION_DEBUG, |
4886 | }, |
4887 | .op_flags = XTENSA_OP_PRIVILEGED, |
4888 | }, { |
4889 | .name = "wsr.dbreaka1" , |
4890 | .translate = translate_wsr_dbreaka, |
4891 | .test_ill = test_ill_dbreak, |
4892 | .par = (const uint32_t[]){ |
4893 | DBREAKA + 1, |
4894 | XTENSA_OPTION_DEBUG, |
4895 | }, |
4896 | .op_flags = XTENSA_OP_PRIVILEGED, |
4897 | }, { |
4898 | .name = "wsr.dbreakc0" , |
4899 | .translate = translate_wsr_dbreakc, |
4900 | .test_ill = test_ill_dbreak, |
4901 | .par = (const uint32_t[]){ |
4902 | DBREAKC, |
4903 | XTENSA_OPTION_DEBUG, |
4904 | }, |
4905 | .op_flags = XTENSA_OP_PRIVILEGED, |
4906 | }, { |
4907 | .name = "wsr.dbreakc1" , |
4908 | .translate = translate_wsr_dbreakc, |
4909 | .test_ill = test_ill_dbreak, |
4910 | .par = (const uint32_t[]){ |
4911 | DBREAKC + 1, |
4912 | XTENSA_OPTION_DEBUG, |
4913 | }, |
4914 | .op_flags = XTENSA_OP_PRIVILEGED, |
4915 | }, { |
4916 | .name = "wsr.ddr" , |
4917 | .translate = translate_wsr, |
4918 | .test_ill = test_ill_sr, |
4919 | .par = (const uint32_t[]){ |
4920 | DDR, |
4921 | XTENSA_OPTION_DEBUG, |
4922 | }, |
4923 | .op_flags = XTENSA_OP_PRIVILEGED, |
4924 | }, { |
4925 | .name = "wsr.debugcause" , |
4926 | .op_flags = XTENSA_OP_ILL, |
4927 | }, { |
4928 | .name = "wsr.depc" , |
4929 | .translate = translate_wsr, |
4930 | .test_ill = test_ill_sr, |
4931 | .par = (const uint32_t[]){ |
4932 | DEPC, |
4933 | XTENSA_OPTION_EXCEPTION, |
4934 | }, |
4935 | .op_flags = XTENSA_OP_PRIVILEGED, |
4936 | }, { |
4937 | .name = "wsr.dtlbcfg" , |
4938 | .translate = translate_wsr_mask, |
4939 | .test_ill = test_ill_sr, |
4940 | .par = (const uint32_t[]){ |
4941 | DTLBCFG, |
4942 | XTENSA_OPTION_MMU, |
4943 | 0x01130000, |
4944 | }, |
4945 | .op_flags = XTENSA_OP_PRIVILEGED, |
4946 | }, { |
4947 | .name = "wsr.epc1" , |
4948 | .translate = translate_wsr, |
4949 | .test_ill = test_ill_sr, |
4950 | .par = (const uint32_t[]){ |
4951 | EPC1, |
4952 | XTENSA_OPTION_EXCEPTION, |
4953 | }, |
4954 | .op_flags = XTENSA_OP_PRIVILEGED, |
4955 | }, { |
4956 | .name = "wsr.epc2" , |
4957 | .translate = translate_wsr, |
4958 | .test_ill = test_ill_hpi, |
4959 | .par = (const uint32_t[]){ |
4960 | EPC1 + 1, |
4961 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4962 | }, |
4963 | .op_flags = XTENSA_OP_PRIVILEGED, |
4964 | }, { |
4965 | .name = "wsr.epc3" , |
4966 | .translate = translate_wsr, |
4967 | .test_ill = test_ill_hpi, |
4968 | .par = (const uint32_t[]){ |
4969 | EPC1 + 2, |
4970 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4971 | }, |
4972 | .op_flags = XTENSA_OP_PRIVILEGED, |
4973 | }, { |
4974 | .name = "wsr.epc4" , |
4975 | .translate = translate_wsr, |
4976 | .test_ill = test_ill_hpi, |
4977 | .par = (const uint32_t[]){ |
4978 | EPC1 + 3, |
4979 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4980 | }, |
4981 | .op_flags = XTENSA_OP_PRIVILEGED, |
4982 | }, { |
4983 | .name = "wsr.epc5" , |
4984 | .translate = translate_wsr, |
4985 | .test_ill = test_ill_hpi, |
4986 | .par = (const uint32_t[]){ |
4987 | EPC1 + 4, |
4988 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4989 | }, |
4990 | .op_flags = XTENSA_OP_PRIVILEGED, |
4991 | }, { |
4992 | .name = "wsr.epc6" , |
4993 | .translate = translate_wsr, |
4994 | .test_ill = test_ill_hpi, |
4995 | .par = (const uint32_t[]){ |
4996 | EPC1 + 5, |
4997 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
4998 | }, |
4999 | .op_flags = XTENSA_OP_PRIVILEGED, |
5000 | }, { |
5001 | .name = "wsr.epc7" , |
5002 | .translate = translate_wsr, |
5003 | .test_ill = test_ill_hpi, |
5004 | .par = (const uint32_t[]){ |
5005 | EPC1 + 6, |
5006 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5007 | }, |
5008 | .op_flags = XTENSA_OP_PRIVILEGED, |
5009 | }, { |
5010 | .name = "wsr.eps2" , |
5011 | .translate = translate_wsr, |
5012 | .test_ill = test_ill_hpi, |
5013 | .par = (const uint32_t[]){ |
5014 | EPS2, |
5015 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5016 | }, |
5017 | .op_flags = XTENSA_OP_PRIVILEGED, |
5018 | }, { |
5019 | .name = "wsr.eps3" , |
5020 | .translate = translate_wsr, |
5021 | .test_ill = test_ill_hpi, |
5022 | .par = (const uint32_t[]){ |
5023 | EPS2 + 1, |
5024 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5025 | }, |
5026 | .op_flags = XTENSA_OP_PRIVILEGED, |
5027 | }, { |
5028 | .name = "wsr.eps4" , |
5029 | .translate = translate_wsr, |
5030 | .test_ill = test_ill_hpi, |
5031 | .par = (const uint32_t[]){ |
5032 | EPS2 + 2, |
5033 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5034 | }, |
5035 | .op_flags = XTENSA_OP_PRIVILEGED, |
5036 | }, { |
5037 | .name = "wsr.eps5" , |
5038 | .translate = translate_wsr, |
5039 | .test_ill = test_ill_hpi, |
5040 | .par = (const uint32_t[]){ |
5041 | EPS2 + 3, |
5042 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5043 | }, |
5044 | .op_flags = XTENSA_OP_PRIVILEGED, |
5045 | }, { |
5046 | .name = "wsr.eps6" , |
5047 | .translate = translate_wsr, |
5048 | .test_ill = test_ill_hpi, |
5049 | .par = (const uint32_t[]){ |
5050 | EPS2 + 4, |
5051 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5052 | }, |
5053 | .op_flags = XTENSA_OP_PRIVILEGED, |
5054 | }, { |
5055 | .name = "wsr.eps7" , |
5056 | .translate = translate_wsr, |
5057 | .test_ill = test_ill_hpi, |
5058 | .par = (const uint32_t[]){ |
5059 | EPS2 + 5, |
5060 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5061 | }, |
5062 | .op_flags = XTENSA_OP_PRIVILEGED, |
5063 | }, { |
5064 | .name = "wsr.eraccess" , |
5065 | .translate = translate_wsr_mask, |
5066 | .par = (const uint32_t[]){ |
5067 | ERACCESS, |
5068 | 0, |
5069 | 0xffff, |
5070 | }, |
5071 | .op_flags = XTENSA_OP_PRIVILEGED, |
5072 | }, { |
5073 | .name = "wsr.exccause" , |
5074 | .translate = translate_wsr, |
5075 | .test_ill = test_ill_sr, |
5076 | .par = (const uint32_t[]){ |
5077 | EXCCAUSE, |
5078 | XTENSA_OPTION_EXCEPTION, |
5079 | }, |
5080 | .op_flags = XTENSA_OP_PRIVILEGED, |
5081 | }, { |
5082 | .name = "wsr.excsave1" , |
5083 | .translate = translate_wsr, |
5084 | .test_ill = test_ill_sr, |
5085 | .par = (const uint32_t[]){ |
5086 | EXCSAVE1, |
5087 | XTENSA_OPTION_EXCEPTION, |
5088 | }, |
5089 | .op_flags = XTENSA_OP_PRIVILEGED, |
5090 | }, { |
5091 | .name = "wsr.excsave2" , |
5092 | .translate = translate_wsr, |
5093 | .test_ill = test_ill_hpi, |
5094 | .par = (const uint32_t[]){ |
5095 | EXCSAVE1 + 1, |
5096 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5097 | }, |
5098 | .op_flags = XTENSA_OP_PRIVILEGED, |
5099 | }, { |
5100 | .name = "wsr.excsave3" , |
5101 | .translate = translate_wsr, |
5102 | .test_ill = test_ill_hpi, |
5103 | .par = (const uint32_t[]){ |
5104 | EXCSAVE1 + 2, |
5105 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5106 | }, |
5107 | .op_flags = XTENSA_OP_PRIVILEGED, |
5108 | }, { |
5109 | .name = "wsr.excsave4" , |
5110 | .translate = translate_wsr, |
5111 | .test_ill = test_ill_hpi, |
5112 | .par = (const uint32_t[]){ |
5113 | EXCSAVE1 + 3, |
5114 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5115 | }, |
5116 | .op_flags = XTENSA_OP_PRIVILEGED, |
5117 | }, { |
5118 | .name = "wsr.excsave5" , |
5119 | .translate = translate_wsr, |
5120 | .test_ill = test_ill_hpi, |
5121 | .par = (const uint32_t[]){ |
5122 | EXCSAVE1 + 4, |
5123 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5124 | }, |
5125 | .op_flags = XTENSA_OP_PRIVILEGED, |
5126 | }, { |
5127 | .name = "wsr.excsave6" , |
5128 | .translate = translate_wsr, |
5129 | .test_ill = test_ill_hpi, |
5130 | .par = (const uint32_t[]){ |
5131 | EXCSAVE1 + 5, |
5132 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5133 | }, |
5134 | .op_flags = XTENSA_OP_PRIVILEGED, |
5135 | }, { |
5136 | .name = "wsr.excsave7" , |
5137 | .translate = translate_wsr, |
5138 | .test_ill = test_ill_hpi, |
5139 | .par = (const uint32_t[]){ |
5140 | EXCSAVE1 + 6, |
5141 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5142 | }, |
5143 | .op_flags = XTENSA_OP_PRIVILEGED, |
5144 | }, { |
5145 | .name = "wsr.excvaddr" , |
5146 | .translate = translate_wsr, |
5147 | .test_ill = test_ill_sr, |
5148 | .par = (const uint32_t[]){ |
5149 | EXCVADDR, |
5150 | XTENSA_OPTION_EXCEPTION, |
5151 | }, |
5152 | .op_flags = XTENSA_OP_PRIVILEGED, |
5153 | }, { |
5154 | .name = "wsr.ibreaka0" , |
5155 | .translate = translate_wsr_ibreaka, |
5156 | .test_ill = test_ill_ibreak, |
5157 | .par = (const uint32_t[]){ |
5158 | IBREAKA, |
5159 | XTENSA_OPTION_DEBUG, |
5160 | }, |
5161 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5162 | }, { |
5163 | .name = "wsr.ibreaka1" , |
5164 | .translate = translate_wsr_ibreaka, |
5165 | .test_ill = test_ill_ibreak, |
5166 | .par = (const uint32_t[]){ |
5167 | IBREAKA + 1, |
5168 | XTENSA_OPTION_DEBUG, |
5169 | }, |
5170 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5171 | }, { |
5172 | .name = "wsr.ibreakenable" , |
5173 | .translate = translate_wsr_ibreakenable, |
5174 | .test_ill = test_ill_sr, |
5175 | .par = (const uint32_t[]){ |
5176 | IBREAKENABLE, |
5177 | XTENSA_OPTION_DEBUG, |
5178 | }, |
5179 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5180 | }, { |
5181 | .name = "wsr.icount" , |
5182 | .translate = translate_wsr_icount, |
5183 | .test_ill = test_ill_sr, |
5184 | .par = (const uint32_t[]){ |
5185 | ICOUNT, |
5186 | XTENSA_OPTION_DEBUG, |
5187 | }, |
5188 | .op_flags = XTENSA_OP_PRIVILEGED, |
5189 | }, { |
5190 | .name = "wsr.icountlevel" , |
5191 | .translate = translate_wsr_mask, |
5192 | .test_ill = test_ill_sr, |
5193 | .par = (const uint32_t[]){ |
5194 | ICOUNTLEVEL, |
5195 | XTENSA_OPTION_DEBUG, |
5196 | 0xf, |
5197 | }, |
5198 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
5199 | }, { |
5200 | .name = "wsr.intclear" , |
5201 | .translate = translate_wsr_intclear, |
5202 | .test_ill = test_ill_sr, |
5203 | .par = (const uint32_t[]){ |
5204 | INTCLEAR, |
5205 | XTENSA_OPTION_INTERRUPT, |
5206 | }, |
5207 | .op_flags = |
5208 | XTENSA_OP_PRIVILEGED | |
5209 | XTENSA_OP_EXIT_TB_0 | |
5210 | XTENSA_OP_CHECK_INTERRUPTS, |
5211 | }, { |
5212 | .name = "wsr.intenable" , |
5213 | .translate = translate_wsr, |
5214 | .test_ill = test_ill_sr, |
5215 | .par = (const uint32_t[]){ |
5216 | INTENABLE, |
5217 | XTENSA_OPTION_INTERRUPT, |
5218 | }, |
5219 | .op_flags = |
5220 | XTENSA_OP_PRIVILEGED | |
5221 | XTENSA_OP_EXIT_TB_0 | |
5222 | XTENSA_OP_CHECK_INTERRUPTS, |
5223 | }, { |
5224 | .name = "wsr.interrupt" , |
5225 | .translate = translate_wsr, |
5226 | .test_ill = test_ill_sr, |
5227 | .par = (const uint32_t[]){ |
5228 | INTSET, |
5229 | XTENSA_OPTION_INTERRUPT, |
5230 | }, |
5231 | .op_flags = |
5232 | XTENSA_OP_PRIVILEGED | |
5233 | XTENSA_OP_EXIT_TB_0 | |
5234 | XTENSA_OP_CHECK_INTERRUPTS, |
5235 | }, { |
5236 | .name = "wsr.intset" , |
5237 | .translate = translate_wsr_intset, |
5238 | .test_ill = test_ill_sr, |
5239 | .par = (const uint32_t[]){ |
5240 | INTSET, |
5241 | XTENSA_OPTION_INTERRUPT, |
5242 | }, |
5243 | .op_flags = |
5244 | XTENSA_OP_PRIVILEGED | |
5245 | XTENSA_OP_EXIT_TB_0 | |
5246 | XTENSA_OP_CHECK_INTERRUPTS, |
5247 | }, { |
5248 | .name = "wsr.itlbcfg" , |
5249 | .translate = translate_wsr_mask, |
5250 | .test_ill = test_ill_sr, |
5251 | .par = (const uint32_t[]){ |
5252 | ITLBCFG, |
5253 | XTENSA_OPTION_MMU, |
5254 | 0x01130000, |
5255 | }, |
5256 | .op_flags = XTENSA_OP_PRIVILEGED, |
5257 | }, { |
5258 | .name = "wsr.lbeg" , |
5259 | .translate = translate_wsr, |
5260 | .test_ill = test_ill_sr, |
5261 | .par = (const uint32_t[]){ |
5262 | LBEG, |
5263 | XTENSA_OPTION_LOOP, |
5264 | }, |
5265 | .op_flags = XTENSA_OP_EXIT_TB_M1, |
5266 | }, { |
5267 | .name = "wsr.lcount" , |
5268 | .translate = translate_wsr, |
5269 | .test_ill = test_ill_sr, |
5270 | .par = (const uint32_t[]){ |
5271 | LCOUNT, |
5272 | XTENSA_OPTION_LOOP, |
5273 | }, |
5274 | }, { |
5275 | .name = "wsr.lend" , |
5276 | .translate = translate_wsr, |
5277 | .test_ill = test_ill_sr, |
5278 | .par = (const uint32_t[]){ |
5279 | LEND, |
5280 | XTENSA_OPTION_LOOP, |
5281 | }, |
5282 | .op_flags = XTENSA_OP_EXIT_TB_M1, |
5283 | }, { |
5284 | .name = "wsr.litbase" , |
5285 | .translate = translate_wsr_mask, |
5286 | .test_ill = test_ill_sr, |
5287 | .par = (const uint32_t[]){ |
5288 | LITBASE, |
5289 | XTENSA_OPTION_EXTENDED_L32R, |
5290 | 0xfffff001, |
5291 | }, |
5292 | .op_flags = XTENSA_OP_EXIT_TB_M1, |
5293 | }, { |
5294 | .name = "wsr.m0" , |
5295 | .translate = translate_wsr, |
5296 | .test_ill = test_ill_sr, |
5297 | .par = (const uint32_t[]){ |
5298 | MR, |
5299 | XTENSA_OPTION_MAC16, |
5300 | }, |
5301 | }, { |
5302 | .name = "wsr.m1" , |
5303 | .translate = translate_wsr, |
5304 | .test_ill = test_ill_sr, |
5305 | .par = (const uint32_t[]){ |
5306 | MR + 1, |
5307 | XTENSA_OPTION_MAC16, |
5308 | }, |
5309 | }, { |
5310 | .name = "wsr.m2" , |
5311 | .translate = translate_wsr, |
5312 | .test_ill = test_ill_sr, |
5313 | .par = (const uint32_t[]){ |
5314 | MR + 2, |
5315 | XTENSA_OPTION_MAC16, |
5316 | }, |
5317 | }, { |
5318 | .name = "wsr.m3" , |
5319 | .translate = translate_wsr, |
5320 | .test_ill = test_ill_sr, |
5321 | .par = (const uint32_t[]){ |
5322 | MR + 3, |
5323 | XTENSA_OPTION_MAC16, |
5324 | }, |
5325 | }, { |
5326 | .name = "wsr.memctl" , |
5327 | .translate = translate_wsr_memctl, |
5328 | .par = (const uint32_t[]){MEMCTL}, |
5329 | .op_flags = XTENSA_OP_PRIVILEGED, |
5330 | }, { |
5331 | .name = "wsr.mecr" , |
5332 | .translate = translate_wsr, |
5333 | .test_ill = test_ill_sr, |
5334 | .par = (const uint32_t[]){ |
5335 | MECR, |
5336 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
5337 | }, |
5338 | .op_flags = XTENSA_OP_PRIVILEGED, |
5339 | }, { |
5340 | .name = "wsr.mepc" , |
5341 | .translate = translate_wsr, |
5342 | .test_ill = test_ill_sr, |
5343 | .par = (const uint32_t[]){ |
5344 | MEPC, |
5345 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
5346 | }, |
5347 | .op_flags = XTENSA_OP_PRIVILEGED, |
5348 | }, { |
5349 | .name = "wsr.meps" , |
5350 | .translate = translate_wsr, |
5351 | .test_ill = test_ill_sr, |
5352 | .par = (const uint32_t[]){ |
5353 | MEPS, |
5354 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
5355 | }, |
5356 | .op_flags = XTENSA_OP_PRIVILEGED, |
5357 | }, { |
5358 | .name = "wsr.mesave" , |
5359 | .translate = translate_wsr, |
5360 | .test_ill = test_ill_sr, |
5361 | .par = (const uint32_t[]){ |
5362 | MESAVE, |
5363 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
5364 | }, |
5365 | .op_flags = XTENSA_OP_PRIVILEGED, |
5366 | }, { |
5367 | .name = "wsr.mesr" , |
5368 | .translate = translate_wsr, |
5369 | .test_ill = test_ill_sr, |
5370 | .par = (const uint32_t[]){ |
5371 | MESR, |
5372 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
5373 | }, |
5374 | .op_flags = XTENSA_OP_PRIVILEGED, |
5375 | }, { |
5376 | .name = "wsr.mevaddr" , |
5377 | .translate = translate_wsr, |
5378 | .test_ill = test_ill_sr, |
5379 | .par = (const uint32_t[]){ |
5380 | MESR, |
5381 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
5382 | }, |
5383 | .op_flags = XTENSA_OP_PRIVILEGED, |
5384 | }, { |
5385 | .name = "wsr.misc0" , |
5386 | .translate = translate_wsr, |
5387 | .test_ill = test_ill_sr, |
5388 | .par = (const uint32_t[]){ |
5389 | MISC, |
5390 | XTENSA_OPTION_MISC_SR, |
5391 | }, |
5392 | .op_flags = XTENSA_OP_PRIVILEGED, |
5393 | }, { |
5394 | .name = "wsr.misc1" , |
5395 | .translate = translate_wsr, |
5396 | .test_ill = test_ill_sr, |
5397 | .par = (const uint32_t[]){ |
5398 | MISC + 1, |
5399 | XTENSA_OPTION_MISC_SR, |
5400 | }, |
5401 | .op_flags = XTENSA_OP_PRIVILEGED, |
5402 | }, { |
5403 | .name = "wsr.misc2" , |
5404 | .translate = translate_wsr, |
5405 | .test_ill = test_ill_sr, |
5406 | .par = (const uint32_t[]){ |
5407 | MISC + 2, |
5408 | XTENSA_OPTION_MISC_SR, |
5409 | }, |
5410 | .op_flags = XTENSA_OP_PRIVILEGED, |
5411 | }, { |
5412 | .name = "wsr.misc3" , |
5413 | .translate = translate_wsr, |
5414 | .test_ill = test_ill_sr, |
5415 | .par = (const uint32_t[]){ |
5416 | MISC + 3, |
5417 | XTENSA_OPTION_MISC_SR, |
5418 | }, |
5419 | .op_flags = XTENSA_OP_PRIVILEGED, |
5420 | }, { |
5421 | .name = "wsr.mmid" , |
5422 | .translate = translate_wsr, |
5423 | .test_ill = test_ill_sr, |
5424 | .par = (const uint32_t[]){ |
5425 | MMID, |
5426 | XTENSA_OPTION_TRACE_PORT, |
5427 | }, |
5428 | .op_flags = XTENSA_OP_PRIVILEGED, |
5429 | }, { |
5430 | .name = "wsr.mpuenb" , |
5431 | .translate = translate_wsr_mpuenb, |
5432 | .test_ill = test_ill_sr, |
5433 | .par = (const uint32_t[]){ |
5434 | MPUENB, |
5435 | XTENSA_OPTION_MPU, |
5436 | }, |
5437 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
5438 | }, { |
5439 | .name = "wsr.prefctl" , |
5440 | .translate = translate_wsr, |
5441 | .par = (const uint32_t[]){PREFCTL}, |
5442 | }, { |
5443 | .name = "wsr.prid" , |
5444 | .op_flags = XTENSA_OP_ILL, |
5445 | }, { |
5446 | .name = "wsr.ps" , |
5447 | .translate = translate_wsr_ps, |
5448 | .test_ill = test_ill_sr, |
5449 | .par = (const uint32_t[]){ |
5450 | PS, |
5451 | XTENSA_OPTION_EXCEPTION, |
5452 | }, |
5453 | .op_flags = |
5454 | XTENSA_OP_PRIVILEGED | |
5455 | XTENSA_OP_EXIT_TB_M1 | |
5456 | XTENSA_OP_CHECK_INTERRUPTS, |
5457 | }, { |
5458 | .name = "wsr.ptevaddr" , |
5459 | .translate = translate_wsr_mask, |
5460 | .test_ill = test_ill_sr, |
5461 | .par = (const uint32_t[]){ |
5462 | PTEVADDR, |
5463 | XTENSA_OPTION_MMU, |
5464 | 0xffc00000, |
5465 | }, |
5466 | .op_flags = XTENSA_OP_PRIVILEGED, |
5467 | }, { |
5468 | .name = "wsr.rasid" , |
5469 | .translate = translate_wsr_rasid, |
5470 | .test_ill = test_ill_sr, |
5471 | .par = (const uint32_t[]){ |
5472 | RASID, |
5473 | XTENSA_OPTION_MMU, |
5474 | }, |
5475 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
5476 | }, { |
5477 | .name = "wsr.sar" , |
5478 | .translate = translate_wsr_sar, |
5479 | .par = (const uint32_t[]){SAR}, |
5480 | }, { |
5481 | .name = "wsr.scompare1" , |
5482 | .translate = translate_wsr, |
5483 | .test_ill = test_ill_sr, |
5484 | .par = (const uint32_t[]){ |
5485 | SCOMPARE1, |
5486 | XTENSA_OPTION_CONDITIONAL_STORE, |
5487 | }, |
5488 | }, { |
5489 | .name = "wsr.vecbase" , |
5490 | .translate = translate_wsr, |
5491 | .test_ill = test_ill_sr, |
5492 | .par = (const uint32_t[]){ |
5493 | VECBASE, |
5494 | XTENSA_OPTION_RELOCATABLE_VECTOR, |
5495 | }, |
5496 | .op_flags = XTENSA_OP_PRIVILEGED, |
5497 | }, { |
5498 | .name = "wsr.windowbase" , |
5499 | .translate = translate_wsr_windowbase, |
5500 | .test_ill = test_ill_sr, |
5501 | .par = (const uint32_t[]){ |
5502 | WINDOW_BASE, |
5503 | XTENSA_OPTION_WINDOWED_REGISTER, |
5504 | }, |
5505 | .op_flags = XTENSA_OP_PRIVILEGED | |
5506 | XTENSA_OP_EXIT_TB_M1 | |
5507 | XTENSA_OP_SYNC_REGISTER_WINDOW, |
5508 | }, { |
5509 | .name = "wsr.windowstart" , |
5510 | .translate = translate_wsr_windowstart, |
5511 | .test_ill = test_ill_sr, |
5512 | .par = (const uint32_t[]){ |
5513 | WINDOW_START, |
5514 | XTENSA_OPTION_WINDOWED_REGISTER, |
5515 | }, |
5516 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
5517 | }, { |
5518 | .name = "wur.expstate" , |
5519 | .translate = translate_wur, |
5520 | .par = (const uint32_t[]){EXPSTATE}, |
5521 | }, { |
5522 | .name = "wur.fcr" , |
5523 | .translate = translate_wur_fcr, |
5524 | .par = (const uint32_t[]){FCR}, |
5525 | .coprocessor = 0x1, |
5526 | }, { |
5527 | .name = "wur.fsr" , |
5528 | .translate = translate_wur_fsr, |
5529 | .par = (const uint32_t[]){FSR}, |
5530 | .coprocessor = 0x1, |
5531 | }, { |
5532 | .name = "wur.threadptr" , |
5533 | .translate = translate_wur, |
5534 | .par = (const uint32_t[]){THREADPTR}, |
5535 | }, { |
5536 | .name = "xor" , |
5537 | .translate = translate_xor, |
5538 | }, { |
5539 | .name = "xorb" , |
5540 | .translate = translate_boolean, |
5541 | .par = (const uint32_t[]){BOOLEAN_XOR}, |
5542 | }, { |
5543 | .name = "xsr.176" , |
5544 | .op_flags = XTENSA_OP_ILL, |
5545 | }, { |
5546 | .name = "xsr.208" , |
5547 | .op_flags = XTENSA_OP_ILL, |
5548 | }, { |
5549 | .name = "xsr.acchi" , |
5550 | .translate = translate_xsr_acchi, |
5551 | .test_ill = test_ill_sr, |
5552 | .par = (const uint32_t[]){ |
5553 | ACCHI, |
5554 | XTENSA_OPTION_MAC16, |
5555 | }, |
5556 | }, { |
5557 | .name = "xsr.acclo" , |
5558 | .translate = translate_xsr, |
5559 | .test_ill = test_ill_sr, |
5560 | .par = (const uint32_t[]){ |
5561 | ACCLO, |
5562 | XTENSA_OPTION_MAC16, |
5563 | }, |
5564 | }, { |
5565 | .name = "xsr.atomctl" , |
5566 | .translate = translate_xsr_mask, |
5567 | .test_ill = test_ill_sr, |
5568 | .par = (const uint32_t[]){ |
5569 | ATOMCTL, |
5570 | XTENSA_OPTION_ATOMCTL, |
5571 | 0x3f, |
5572 | }, |
5573 | .op_flags = XTENSA_OP_PRIVILEGED, |
5574 | }, { |
5575 | .name = "xsr.br" , |
5576 | .translate = translate_xsr_mask, |
5577 | .test_ill = test_ill_sr, |
5578 | .par = (const uint32_t[]){ |
5579 | BR, |
5580 | XTENSA_OPTION_BOOLEAN, |
5581 | 0xffff, |
5582 | }, |
5583 | }, { |
5584 | .name = "xsr.cacheadrdis" , |
5585 | .translate = translate_xsr_mask, |
5586 | .test_ill = test_ill_sr, |
5587 | .par = (const uint32_t[]){ |
5588 | CACHEADRDIS, |
5589 | XTENSA_OPTION_MPU, |
5590 | 0xff, |
5591 | }, |
5592 | .op_flags = XTENSA_OP_PRIVILEGED, |
5593 | }, { |
5594 | .name = "xsr.cacheattr" , |
5595 | .translate = translate_xsr, |
5596 | .test_ill = test_ill_sr, |
5597 | .par = (const uint32_t[]){ |
5598 | CACHEATTR, |
5599 | XTENSA_OPTION_CACHEATTR, |
5600 | }, |
5601 | .op_flags = XTENSA_OP_PRIVILEGED, |
5602 | }, { |
5603 | .name = "xsr.ccompare0" , |
5604 | .translate = translate_xsr_ccompare, |
5605 | .test_ill = test_ill_ccompare, |
5606 | .par = (const uint32_t[]){ |
5607 | CCOMPARE, |
5608 | XTENSA_OPTION_TIMER_INTERRUPT, |
5609 | }, |
5610 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5611 | }, { |
5612 | .name = "xsr.ccompare1" , |
5613 | .translate = translate_xsr_ccompare, |
5614 | .test_ill = test_ill_ccompare, |
5615 | .par = (const uint32_t[]){ |
5616 | CCOMPARE + 1, |
5617 | XTENSA_OPTION_TIMER_INTERRUPT, |
5618 | }, |
5619 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5620 | }, { |
5621 | .name = "xsr.ccompare2" , |
5622 | .translate = translate_xsr_ccompare, |
5623 | .test_ill = test_ill_ccompare, |
5624 | .par = (const uint32_t[]){ |
5625 | CCOMPARE + 2, |
5626 | XTENSA_OPTION_TIMER_INTERRUPT, |
5627 | }, |
5628 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5629 | }, { |
5630 | .name = "xsr.ccount" , |
5631 | .translate = translate_xsr_ccount, |
5632 | .test_ill = test_ill_sr, |
5633 | .par = (const uint32_t[]){ |
5634 | CCOUNT, |
5635 | XTENSA_OPTION_TIMER_INTERRUPT, |
5636 | }, |
5637 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5638 | }, { |
5639 | .name = "xsr.configid0" , |
5640 | .op_flags = XTENSA_OP_ILL, |
5641 | }, { |
5642 | .name = "xsr.configid1" , |
5643 | .op_flags = XTENSA_OP_ILL, |
5644 | }, { |
5645 | .name = "xsr.cpenable" , |
5646 | .translate = translate_xsr_mask, |
5647 | .test_ill = test_ill_sr, |
5648 | .par = (const uint32_t[]){ |
5649 | CPENABLE, |
5650 | XTENSA_OPTION_COPROCESSOR, |
5651 | 0xff, |
5652 | }, |
5653 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
5654 | }, { |
5655 | .name = "xsr.dbreaka0" , |
5656 | .translate = translate_xsr_dbreaka, |
5657 | .test_ill = test_ill_dbreak, |
5658 | .par = (const uint32_t[]){ |
5659 | DBREAKA, |
5660 | XTENSA_OPTION_DEBUG, |
5661 | }, |
5662 | .op_flags = XTENSA_OP_PRIVILEGED, |
5663 | }, { |
5664 | .name = "xsr.dbreaka1" , |
5665 | .translate = translate_xsr_dbreaka, |
5666 | .test_ill = test_ill_dbreak, |
5667 | .par = (const uint32_t[]){ |
5668 | DBREAKA + 1, |
5669 | XTENSA_OPTION_DEBUG, |
5670 | }, |
5671 | .op_flags = XTENSA_OP_PRIVILEGED, |
5672 | }, { |
5673 | .name = "xsr.dbreakc0" , |
5674 | .translate = translate_xsr_dbreakc, |
5675 | .test_ill = test_ill_dbreak, |
5676 | .par = (const uint32_t[]){ |
5677 | DBREAKC, |
5678 | XTENSA_OPTION_DEBUG, |
5679 | }, |
5680 | .op_flags = XTENSA_OP_PRIVILEGED, |
5681 | }, { |
5682 | .name = "xsr.dbreakc1" , |
5683 | .translate = translate_xsr_dbreakc, |
5684 | .test_ill = test_ill_dbreak, |
5685 | .par = (const uint32_t[]){ |
5686 | DBREAKC + 1, |
5687 | XTENSA_OPTION_DEBUG, |
5688 | }, |
5689 | .op_flags = XTENSA_OP_PRIVILEGED, |
5690 | }, { |
5691 | .name = "xsr.ddr" , |
5692 | .translate = translate_xsr, |
5693 | .test_ill = test_ill_sr, |
5694 | .par = (const uint32_t[]){ |
5695 | DDR, |
5696 | XTENSA_OPTION_DEBUG, |
5697 | }, |
5698 | .op_flags = XTENSA_OP_PRIVILEGED, |
5699 | }, { |
5700 | .name = "xsr.debugcause" , |
5701 | .op_flags = XTENSA_OP_ILL, |
5702 | }, { |
5703 | .name = "xsr.depc" , |
5704 | .translate = translate_xsr, |
5705 | .test_ill = test_ill_sr, |
5706 | .par = (const uint32_t[]){ |
5707 | DEPC, |
5708 | XTENSA_OPTION_EXCEPTION, |
5709 | }, |
5710 | .op_flags = XTENSA_OP_PRIVILEGED, |
5711 | }, { |
5712 | .name = "xsr.dtlbcfg" , |
5713 | .translate = translate_xsr_mask, |
5714 | .test_ill = test_ill_sr, |
5715 | .par = (const uint32_t[]){ |
5716 | DTLBCFG, |
5717 | XTENSA_OPTION_MMU, |
5718 | 0x01130000, |
5719 | }, |
5720 | .op_flags = XTENSA_OP_PRIVILEGED, |
5721 | }, { |
5722 | .name = "xsr.epc1" , |
5723 | .translate = translate_xsr, |
5724 | .test_ill = test_ill_sr, |
5725 | .par = (const uint32_t[]){ |
5726 | EPC1, |
5727 | XTENSA_OPTION_EXCEPTION, |
5728 | }, |
5729 | .op_flags = XTENSA_OP_PRIVILEGED, |
5730 | }, { |
5731 | .name = "xsr.epc2" , |
5732 | .translate = translate_xsr, |
5733 | .test_ill = test_ill_hpi, |
5734 | .par = (const uint32_t[]){ |
5735 | EPC1 + 1, |
5736 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5737 | }, |
5738 | .op_flags = XTENSA_OP_PRIVILEGED, |
5739 | }, { |
5740 | .name = "xsr.epc3" , |
5741 | .translate = translate_xsr, |
5742 | .test_ill = test_ill_hpi, |
5743 | .par = (const uint32_t[]){ |
5744 | EPC1 + 2, |
5745 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5746 | }, |
5747 | .op_flags = XTENSA_OP_PRIVILEGED, |
5748 | }, { |
5749 | .name = "xsr.epc4" , |
5750 | .translate = translate_xsr, |
5751 | .test_ill = test_ill_hpi, |
5752 | .par = (const uint32_t[]){ |
5753 | EPC1 + 3, |
5754 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5755 | }, |
5756 | .op_flags = XTENSA_OP_PRIVILEGED, |
5757 | }, { |
5758 | .name = "xsr.epc5" , |
5759 | .translate = translate_xsr, |
5760 | .test_ill = test_ill_hpi, |
5761 | .par = (const uint32_t[]){ |
5762 | EPC1 + 4, |
5763 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5764 | }, |
5765 | .op_flags = XTENSA_OP_PRIVILEGED, |
5766 | }, { |
5767 | .name = "xsr.epc6" , |
5768 | .translate = translate_xsr, |
5769 | .test_ill = test_ill_hpi, |
5770 | .par = (const uint32_t[]){ |
5771 | EPC1 + 5, |
5772 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5773 | }, |
5774 | .op_flags = XTENSA_OP_PRIVILEGED, |
5775 | }, { |
5776 | .name = "xsr.epc7" , |
5777 | .translate = translate_xsr, |
5778 | .test_ill = test_ill_hpi, |
5779 | .par = (const uint32_t[]){ |
5780 | EPC1 + 6, |
5781 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5782 | }, |
5783 | .op_flags = XTENSA_OP_PRIVILEGED, |
5784 | }, { |
5785 | .name = "xsr.eps2" , |
5786 | .translate = translate_xsr, |
5787 | .test_ill = test_ill_hpi, |
5788 | .par = (const uint32_t[]){ |
5789 | EPS2, |
5790 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5791 | }, |
5792 | .op_flags = XTENSA_OP_PRIVILEGED, |
5793 | }, { |
5794 | .name = "xsr.eps3" , |
5795 | .translate = translate_xsr, |
5796 | .test_ill = test_ill_hpi, |
5797 | .par = (const uint32_t[]){ |
5798 | EPS2 + 1, |
5799 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5800 | }, |
5801 | .op_flags = XTENSA_OP_PRIVILEGED, |
5802 | }, { |
5803 | .name = "xsr.eps4" , |
5804 | .translate = translate_xsr, |
5805 | .test_ill = test_ill_hpi, |
5806 | .par = (const uint32_t[]){ |
5807 | EPS2 + 2, |
5808 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5809 | }, |
5810 | .op_flags = XTENSA_OP_PRIVILEGED, |
5811 | }, { |
5812 | .name = "xsr.eps5" , |
5813 | .translate = translate_xsr, |
5814 | .test_ill = test_ill_hpi, |
5815 | .par = (const uint32_t[]){ |
5816 | EPS2 + 3, |
5817 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5818 | }, |
5819 | .op_flags = XTENSA_OP_PRIVILEGED, |
5820 | }, { |
5821 | .name = "xsr.eps6" , |
5822 | .translate = translate_xsr, |
5823 | .test_ill = test_ill_hpi, |
5824 | .par = (const uint32_t[]){ |
5825 | EPS2 + 4, |
5826 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5827 | }, |
5828 | .op_flags = XTENSA_OP_PRIVILEGED, |
5829 | }, { |
5830 | .name = "xsr.eps7" , |
5831 | .translate = translate_xsr, |
5832 | .test_ill = test_ill_hpi, |
5833 | .par = (const uint32_t[]){ |
5834 | EPS2 + 5, |
5835 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5836 | }, |
5837 | .op_flags = XTENSA_OP_PRIVILEGED, |
5838 | }, { |
5839 | .name = "xsr.eraccess" , |
5840 | .translate = translate_xsr_mask, |
5841 | .par = (const uint32_t[]){ |
5842 | ERACCESS, |
5843 | 0, |
5844 | 0xffff, |
5845 | }, |
5846 | .op_flags = XTENSA_OP_PRIVILEGED, |
5847 | }, { |
5848 | .name = "xsr.exccause" , |
5849 | .translate = translate_xsr, |
5850 | .test_ill = test_ill_sr, |
5851 | .par = (const uint32_t[]){ |
5852 | EXCCAUSE, |
5853 | XTENSA_OPTION_EXCEPTION, |
5854 | }, |
5855 | .op_flags = XTENSA_OP_PRIVILEGED, |
5856 | }, { |
5857 | .name = "xsr.excsave1" , |
5858 | .translate = translate_xsr, |
5859 | .test_ill = test_ill_sr, |
5860 | .par = (const uint32_t[]){ |
5861 | EXCSAVE1, |
5862 | XTENSA_OPTION_EXCEPTION, |
5863 | }, |
5864 | .op_flags = XTENSA_OP_PRIVILEGED, |
5865 | }, { |
5866 | .name = "xsr.excsave2" , |
5867 | .translate = translate_xsr, |
5868 | .test_ill = test_ill_hpi, |
5869 | .par = (const uint32_t[]){ |
5870 | EXCSAVE1 + 1, |
5871 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5872 | }, |
5873 | .op_flags = XTENSA_OP_PRIVILEGED, |
5874 | }, { |
5875 | .name = "xsr.excsave3" , |
5876 | .translate = translate_xsr, |
5877 | .test_ill = test_ill_hpi, |
5878 | .par = (const uint32_t[]){ |
5879 | EXCSAVE1 + 2, |
5880 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5881 | }, |
5882 | .op_flags = XTENSA_OP_PRIVILEGED, |
5883 | }, { |
5884 | .name = "xsr.excsave4" , |
5885 | .translate = translate_xsr, |
5886 | .test_ill = test_ill_hpi, |
5887 | .par = (const uint32_t[]){ |
5888 | EXCSAVE1 + 3, |
5889 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5890 | }, |
5891 | .op_flags = XTENSA_OP_PRIVILEGED, |
5892 | }, { |
5893 | .name = "xsr.excsave5" , |
5894 | .translate = translate_xsr, |
5895 | .test_ill = test_ill_hpi, |
5896 | .par = (const uint32_t[]){ |
5897 | EXCSAVE1 + 4, |
5898 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5899 | }, |
5900 | .op_flags = XTENSA_OP_PRIVILEGED, |
5901 | }, { |
5902 | .name = "xsr.excsave6" , |
5903 | .translate = translate_xsr, |
5904 | .test_ill = test_ill_hpi, |
5905 | .par = (const uint32_t[]){ |
5906 | EXCSAVE1 + 5, |
5907 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5908 | }, |
5909 | .op_flags = XTENSA_OP_PRIVILEGED, |
5910 | }, { |
5911 | .name = "xsr.excsave7" , |
5912 | .translate = translate_xsr, |
5913 | .test_ill = test_ill_hpi, |
5914 | .par = (const uint32_t[]){ |
5915 | EXCSAVE1 + 6, |
5916 | XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, |
5917 | }, |
5918 | .op_flags = XTENSA_OP_PRIVILEGED, |
5919 | }, { |
5920 | .name = "xsr.excvaddr" , |
5921 | .translate = translate_xsr, |
5922 | .test_ill = test_ill_sr, |
5923 | .par = (const uint32_t[]){ |
5924 | EXCVADDR, |
5925 | XTENSA_OPTION_EXCEPTION, |
5926 | }, |
5927 | .op_flags = XTENSA_OP_PRIVILEGED, |
5928 | }, { |
5929 | .name = "xsr.ibreaka0" , |
5930 | .translate = translate_xsr_ibreaka, |
5931 | .test_ill = test_ill_ibreak, |
5932 | .par = (const uint32_t[]){ |
5933 | IBREAKA, |
5934 | XTENSA_OPTION_DEBUG, |
5935 | }, |
5936 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5937 | }, { |
5938 | .name = "xsr.ibreaka1" , |
5939 | .translate = translate_xsr_ibreaka, |
5940 | .test_ill = test_ill_ibreak, |
5941 | .par = (const uint32_t[]){ |
5942 | IBREAKA + 1, |
5943 | XTENSA_OPTION_DEBUG, |
5944 | }, |
5945 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5946 | }, { |
5947 | .name = "xsr.ibreakenable" , |
5948 | .translate = translate_xsr_ibreakenable, |
5949 | .test_ill = test_ill_sr, |
5950 | .par = (const uint32_t[]){ |
5951 | IBREAKENABLE, |
5952 | XTENSA_OPTION_DEBUG, |
5953 | }, |
5954 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_0, |
5955 | }, { |
5956 | .name = "xsr.icount" , |
5957 | .translate = translate_xsr_icount, |
5958 | .test_ill = test_ill_sr, |
5959 | .par = (const uint32_t[]){ |
5960 | ICOUNT, |
5961 | XTENSA_OPTION_DEBUG, |
5962 | }, |
5963 | .op_flags = XTENSA_OP_PRIVILEGED, |
5964 | }, { |
5965 | .name = "xsr.icountlevel" , |
5966 | .translate = translate_xsr_mask, |
5967 | .test_ill = test_ill_sr, |
5968 | .par = (const uint32_t[]){ |
5969 | ICOUNTLEVEL, |
5970 | XTENSA_OPTION_DEBUG, |
5971 | 0xf, |
5972 | }, |
5973 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
5974 | }, { |
5975 | .name = "xsr.intclear" , |
5976 | .op_flags = XTENSA_OP_ILL, |
5977 | }, { |
5978 | .name = "xsr.intenable" , |
5979 | .translate = translate_xsr, |
5980 | .test_ill = test_ill_sr, |
5981 | .par = (const uint32_t[]){ |
5982 | INTENABLE, |
5983 | XTENSA_OPTION_INTERRUPT, |
5984 | }, |
5985 | .op_flags = |
5986 | XTENSA_OP_PRIVILEGED | |
5987 | XTENSA_OP_EXIT_TB_0 | |
5988 | XTENSA_OP_CHECK_INTERRUPTS, |
5989 | }, { |
5990 | .name = "xsr.interrupt" , |
5991 | .op_flags = XTENSA_OP_ILL, |
5992 | }, { |
5993 | .name = "xsr.intset" , |
5994 | .op_flags = XTENSA_OP_ILL, |
5995 | }, { |
5996 | .name = "xsr.itlbcfg" , |
5997 | .translate = translate_xsr_mask, |
5998 | .test_ill = test_ill_sr, |
5999 | .par = (const uint32_t[]){ |
6000 | ITLBCFG, |
6001 | XTENSA_OPTION_MMU, |
6002 | 0x01130000, |
6003 | }, |
6004 | .op_flags = XTENSA_OP_PRIVILEGED, |
6005 | }, { |
6006 | .name = "xsr.lbeg" , |
6007 | .translate = translate_xsr, |
6008 | .test_ill = test_ill_sr, |
6009 | .par = (const uint32_t[]){ |
6010 | LBEG, |
6011 | XTENSA_OPTION_LOOP, |
6012 | }, |
6013 | .op_flags = XTENSA_OP_EXIT_TB_M1, |
6014 | }, { |
6015 | .name = "xsr.lcount" , |
6016 | .translate = translate_xsr, |
6017 | .test_ill = test_ill_sr, |
6018 | .par = (const uint32_t[]){ |
6019 | LCOUNT, |
6020 | XTENSA_OPTION_LOOP, |
6021 | }, |
6022 | }, { |
6023 | .name = "xsr.lend" , |
6024 | .translate = translate_xsr, |
6025 | .test_ill = test_ill_sr, |
6026 | .par = (const uint32_t[]){ |
6027 | LEND, |
6028 | XTENSA_OPTION_LOOP, |
6029 | }, |
6030 | .op_flags = XTENSA_OP_EXIT_TB_M1, |
6031 | }, { |
6032 | .name = "xsr.litbase" , |
6033 | .translate = translate_xsr_mask, |
6034 | .test_ill = test_ill_sr, |
6035 | .par = (const uint32_t[]){ |
6036 | LITBASE, |
6037 | XTENSA_OPTION_EXTENDED_L32R, |
6038 | 0xfffff001, |
6039 | }, |
6040 | .op_flags = XTENSA_OP_EXIT_TB_M1, |
6041 | }, { |
6042 | .name = "xsr.m0" , |
6043 | .translate = translate_xsr, |
6044 | .test_ill = test_ill_sr, |
6045 | .par = (const uint32_t[]){ |
6046 | MR, |
6047 | XTENSA_OPTION_MAC16, |
6048 | }, |
6049 | }, { |
6050 | .name = "xsr.m1" , |
6051 | .translate = translate_xsr, |
6052 | .test_ill = test_ill_sr, |
6053 | .par = (const uint32_t[]){ |
6054 | MR + 1, |
6055 | XTENSA_OPTION_MAC16, |
6056 | }, |
6057 | }, { |
6058 | .name = "xsr.m2" , |
6059 | .translate = translate_xsr, |
6060 | .test_ill = test_ill_sr, |
6061 | .par = (const uint32_t[]){ |
6062 | MR + 2, |
6063 | XTENSA_OPTION_MAC16, |
6064 | }, |
6065 | }, { |
6066 | .name = "xsr.m3" , |
6067 | .translate = translate_xsr, |
6068 | .test_ill = test_ill_sr, |
6069 | .par = (const uint32_t[]){ |
6070 | MR + 3, |
6071 | XTENSA_OPTION_MAC16, |
6072 | }, |
6073 | }, { |
6074 | .name = "xsr.memctl" , |
6075 | .translate = translate_xsr_memctl, |
6076 | .par = (const uint32_t[]){MEMCTL}, |
6077 | .op_flags = XTENSA_OP_PRIVILEGED, |
6078 | }, { |
6079 | .name = "xsr.mecr" , |
6080 | .translate = translate_xsr, |
6081 | .test_ill = test_ill_sr, |
6082 | .par = (const uint32_t[]){ |
6083 | MECR, |
6084 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
6085 | }, |
6086 | .op_flags = XTENSA_OP_PRIVILEGED, |
6087 | }, { |
6088 | .name = "xsr.mepc" , |
6089 | .translate = translate_xsr, |
6090 | .test_ill = test_ill_sr, |
6091 | .par = (const uint32_t[]){ |
6092 | MEPC, |
6093 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
6094 | }, |
6095 | .op_flags = XTENSA_OP_PRIVILEGED, |
6096 | }, { |
6097 | .name = "xsr.meps" , |
6098 | .translate = translate_xsr, |
6099 | .test_ill = test_ill_sr, |
6100 | .par = (const uint32_t[]){ |
6101 | MEPS, |
6102 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
6103 | }, |
6104 | .op_flags = XTENSA_OP_PRIVILEGED, |
6105 | }, { |
6106 | .name = "xsr.mesave" , |
6107 | .translate = translate_xsr, |
6108 | .test_ill = test_ill_sr, |
6109 | .par = (const uint32_t[]){ |
6110 | MESAVE, |
6111 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
6112 | }, |
6113 | .op_flags = XTENSA_OP_PRIVILEGED, |
6114 | }, { |
6115 | .name = "xsr.mesr" , |
6116 | .translate = translate_xsr, |
6117 | .test_ill = test_ill_sr, |
6118 | .par = (const uint32_t[]){ |
6119 | MESR, |
6120 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
6121 | }, |
6122 | .op_flags = XTENSA_OP_PRIVILEGED, |
6123 | }, { |
6124 | .name = "xsr.mevaddr" , |
6125 | .translate = translate_xsr, |
6126 | .test_ill = test_ill_sr, |
6127 | .par = (const uint32_t[]){ |
6128 | MESR, |
6129 | XTENSA_OPTION_MEMORY_ECC_PARITY, |
6130 | }, |
6131 | .op_flags = XTENSA_OP_PRIVILEGED, |
6132 | }, { |
6133 | .name = "xsr.misc0" , |
6134 | .translate = translate_xsr, |
6135 | .test_ill = test_ill_sr, |
6136 | .par = (const uint32_t[]){ |
6137 | MISC, |
6138 | XTENSA_OPTION_MISC_SR, |
6139 | }, |
6140 | .op_flags = XTENSA_OP_PRIVILEGED, |
6141 | }, { |
6142 | .name = "xsr.misc1" , |
6143 | .translate = translate_xsr, |
6144 | .test_ill = test_ill_sr, |
6145 | .par = (const uint32_t[]){ |
6146 | MISC + 1, |
6147 | XTENSA_OPTION_MISC_SR, |
6148 | }, |
6149 | .op_flags = XTENSA_OP_PRIVILEGED, |
6150 | }, { |
6151 | .name = "xsr.misc2" , |
6152 | .translate = translate_xsr, |
6153 | .test_ill = test_ill_sr, |
6154 | .par = (const uint32_t[]){ |
6155 | MISC + 2, |
6156 | XTENSA_OPTION_MISC_SR, |
6157 | }, |
6158 | .op_flags = XTENSA_OP_PRIVILEGED, |
6159 | }, { |
6160 | .name = "xsr.misc3" , |
6161 | .translate = translate_xsr, |
6162 | .test_ill = test_ill_sr, |
6163 | .par = (const uint32_t[]){ |
6164 | MISC + 3, |
6165 | XTENSA_OPTION_MISC_SR, |
6166 | }, |
6167 | .op_flags = XTENSA_OP_PRIVILEGED, |
6168 | }, { |
6169 | .name = "xsr.mpuenb" , |
6170 | .translate = translate_xsr_mpuenb, |
6171 | .test_ill = test_ill_sr, |
6172 | .par = (const uint32_t[]){ |
6173 | MPUENB, |
6174 | XTENSA_OPTION_MPU, |
6175 | }, |
6176 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
6177 | }, { |
6178 | .name = "xsr.prefctl" , |
6179 | .translate = translate_xsr, |
6180 | .par = (const uint32_t[]){PREFCTL}, |
6181 | }, { |
6182 | .name = "xsr.prid" , |
6183 | .op_flags = XTENSA_OP_ILL, |
6184 | }, { |
6185 | .name = "xsr.ps" , |
6186 | .translate = translate_xsr_ps, |
6187 | .test_ill = test_ill_sr, |
6188 | .par = (const uint32_t[]){ |
6189 | PS, |
6190 | XTENSA_OPTION_EXCEPTION, |
6191 | }, |
6192 | .op_flags = |
6193 | XTENSA_OP_PRIVILEGED | |
6194 | XTENSA_OP_EXIT_TB_M1 | |
6195 | XTENSA_OP_CHECK_INTERRUPTS, |
6196 | }, { |
6197 | .name = "xsr.ptevaddr" , |
6198 | .translate = translate_xsr_mask, |
6199 | .test_ill = test_ill_sr, |
6200 | .par = (const uint32_t[]){ |
6201 | PTEVADDR, |
6202 | XTENSA_OPTION_MMU, |
6203 | 0xffc00000, |
6204 | }, |
6205 | .op_flags = XTENSA_OP_PRIVILEGED, |
6206 | }, { |
6207 | .name = "xsr.rasid" , |
6208 | .translate = translate_xsr_rasid, |
6209 | .test_ill = test_ill_sr, |
6210 | .par = (const uint32_t[]){ |
6211 | RASID, |
6212 | XTENSA_OPTION_MMU, |
6213 | }, |
6214 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
6215 | }, { |
6216 | .name = "xsr.sar" , |
6217 | .translate = translate_xsr_sar, |
6218 | .par = (const uint32_t[]){SAR}, |
6219 | }, { |
6220 | .name = "xsr.scompare1" , |
6221 | .translate = translate_xsr, |
6222 | .test_ill = test_ill_sr, |
6223 | .par = (const uint32_t[]){ |
6224 | SCOMPARE1, |
6225 | XTENSA_OPTION_CONDITIONAL_STORE, |
6226 | }, |
6227 | }, { |
6228 | .name = "xsr.vecbase" , |
6229 | .translate = translate_xsr, |
6230 | .test_ill = test_ill_sr, |
6231 | .par = (const uint32_t[]){ |
6232 | VECBASE, |
6233 | XTENSA_OPTION_RELOCATABLE_VECTOR, |
6234 | }, |
6235 | .op_flags = XTENSA_OP_PRIVILEGED, |
6236 | }, { |
6237 | .name = "xsr.windowbase" , |
6238 | .translate = translate_xsr_windowbase, |
6239 | .test_ill = test_ill_sr, |
6240 | .par = (const uint32_t[]){ |
6241 | WINDOW_BASE, |
6242 | XTENSA_OPTION_WINDOWED_REGISTER, |
6243 | }, |
6244 | .op_flags = XTENSA_OP_PRIVILEGED | |
6245 | XTENSA_OP_EXIT_TB_M1 | |
6246 | XTENSA_OP_SYNC_REGISTER_WINDOW, |
6247 | }, { |
6248 | .name = "xsr.windowstart" , |
6249 | .translate = translate_xsr_windowstart, |
6250 | .test_ill = test_ill_sr, |
6251 | .par = (const uint32_t[]){ |
6252 | WINDOW_START, |
6253 | XTENSA_OPTION_WINDOWED_REGISTER, |
6254 | }, |
6255 | .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1, |
6256 | }, |
6257 | }; |
6258 | |
6259 | const XtensaOpcodeTranslators xtensa_core_opcodes = { |
6260 | .num_opcodes = ARRAY_SIZE(core_ops), |
6261 | .opcode = core_ops, |
6262 | }; |
6263 | |
6264 | |
6265 | static void translate_abs_s(DisasContext *dc, const OpcodeArg arg[], |
6266 | const uint32_t par[]) |
6267 | { |
6268 | gen_helper_abs_s(arg[0].out, arg[1].in); |
6269 | } |
6270 | |
6271 | static void translate_add_s(DisasContext *dc, const OpcodeArg arg[], |
6272 | const uint32_t par[]) |
6273 | { |
6274 | gen_helper_add_s(arg[0].out, cpu_env, |
6275 | arg[1].in, arg[2].in); |
6276 | } |
6277 | |
6278 | enum { |
6279 | COMPARE_UN, |
6280 | COMPARE_OEQ, |
6281 | COMPARE_UEQ, |
6282 | COMPARE_OLT, |
6283 | COMPARE_ULT, |
6284 | COMPARE_OLE, |
6285 | COMPARE_ULE, |
6286 | }; |
6287 | |
6288 | static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[], |
6289 | const uint32_t par[]) |
6290 | { |
6291 | static void (* const helper[])(TCGv_env env, TCGv_i32 bit, |
6292 | TCGv_i32 s, TCGv_i32 t) = { |
6293 | [COMPARE_UN] = gen_helper_un_s, |
6294 | [COMPARE_OEQ] = gen_helper_oeq_s, |
6295 | [COMPARE_UEQ] = gen_helper_ueq_s, |
6296 | [COMPARE_OLT] = gen_helper_olt_s, |
6297 | [COMPARE_ULT] = gen_helper_ult_s, |
6298 | [COMPARE_OLE] = gen_helper_ole_s, |
6299 | [COMPARE_ULE] = gen_helper_ule_s, |
6300 | }; |
6301 | TCGv_i32 bit = tcg_const_i32(1 << arg[0].imm); |
6302 | |
6303 | helper[par[0]](cpu_env, bit, arg[1].in, arg[2].in); |
6304 | tcg_temp_free(bit); |
6305 | } |
6306 | |
6307 | static void translate_float_s(DisasContext *dc, const OpcodeArg arg[], |
6308 | const uint32_t par[]) |
6309 | { |
6310 | TCGv_i32 scale = tcg_const_i32(-arg[2].imm); |
6311 | |
6312 | if (par[0]) { |
6313 | gen_helper_uitof(arg[0].out, cpu_env, arg[1].in, scale); |
6314 | } else { |
6315 | gen_helper_itof(arg[0].out, cpu_env, arg[1].in, scale); |
6316 | } |
6317 | tcg_temp_free(scale); |
6318 | } |
6319 | |
6320 | static void translate_ftoi_s(DisasContext *dc, const OpcodeArg arg[], |
6321 | const uint32_t par[]) |
6322 | { |
6323 | TCGv_i32 rounding_mode = tcg_const_i32(par[0]); |
6324 | TCGv_i32 scale = tcg_const_i32(arg[2].imm); |
6325 | |
6326 | if (par[1]) { |
6327 | gen_helper_ftoui(arg[0].out, arg[1].in, |
6328 | rounding_mode, scale); |
6329 | } else { |
6330 | gen_helper_ftoi(arg[0].out, arg[1].in, |
6331 | rounding_mode, scale); |
6332 | } |
6333 | tcg_temp_free(rounding_mode); |
6334 | tcg_temp_free(scale); |
6335 | } |
6336 | |
6337 | static void translate_ldsti(DisasContext *dc, const OpcodeArg arg[], |
6338 | const uint32_t par[]) |
6339 | { |
6340 | TCGv_i32 addr = tcg_temp_new_i32(); |
6341 | |
6342 | tcg_gen_addi_i32(addr, arg[1].in, arg[2].imm); |
6343 | gen_load_store_alignment(dc, 2, addr, false); |
6344 | if (par[0]) { |
6345 | tcg_gen_qemu_st32(arg[0].in, addr, dc->cring); |
6346 | } else { |
6347 | tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring); |
6348 | } |
6349 | if (par[1]) { |
6350 | tcg_gen_mov_i32(arg[1].out, addr); |
6351 | } |
6352 | tcg_temp_free(addr); |
6353 | } |
6354 | |
6355 | static void translate_ldstx(DisasContext *dc, const OpcodeArg arg[], |
6356 | const uint32_t par[]) |
6357 | { |
6358 | TCGv_i32 addr = tcg_temp_new_i32(); |
6359 | |
6360 | tcg_gen_add_i32(addr, arg[1].in, arg[2].in); |
6361 | gen_load_store_alignment(dc, 2, addr, false); |
6362 | if (par[0]) { |
6363 | tcg_gen_qemu_st32(arg[0].in, addr, dc->cring); |
6364 | } else { |
6365 | tcg_gen_qemu_ld32u(arg[0].out, addr, dc->cring); |
6366 | } |
6367 | if (par[1]) { |
6368 | tcg_gen_mov_i32(arg[1].out, addr); |
6369 | } |
6370 | tcg_temp_free(addr); |
6371 | } |
6372 | |
6373 | static void translate_madd_s(DisasContext *dc, const OpcodeArg arg[], |
6374 | const uint32_t par[]) |
6375 | { |
6376 | gen_helper_madd_s(arg[0].out, cpu_env, |
6377 | arg[0].in, arg[1].in, arg[2].in); |
6378 | } |
6379 | |
6380 | static void translate_mov_s(DisasContext *dc, const OpcodeArg arg[], |
6381 | const uint32_t par[]) |
6382 | { |
6383 | tcg_gen_mov_i32(arg[0].out, arg[1].in); |
6384 | } |
6385 | |
6386 | static void translate_movcond_s(DisasContext *dc, const OpcodeArg arg[], |
6387 | const uint32_t par[]) |
6388 | { |
6389 | TCGv_i32 zero = tcg_const_i32(0); |
6390 | |
6391 | tcg_gen_movcond_i32(par[0], arg[0].out, |
6392 | arg[2].in, zero, |
6393 | arg[1].in, arg[0].in); |
6394 | tcg_temp_free(zero); |
6395 | } |
6396 | |
6397 | static void translate_movp_s(DisasContext *dc, const OpcodeArg arg[], |
6398 | const uint32_t par[]) |
6399 | { |
6400 | TCGv_i32 zero = tcg_const_i32(0); |
6401 | TCGv_i32 tmp = tcg_temp_new_i32(); |
6402 | |
6403 | tcg_gen_andi_i32(tmp, arg[2].in, 1 << arg[2].imm); |
6404 | tcg_gen_movcond_i32(par[0], |
6405 | arg[0].out, tmp, zero, |
6406 | arg[1].in, arg[0].in); |
6407 | tcg_temp_free(tmp); |
6408 | tcg_temp_free(zero); |
6409 | } |
6410 | |
6411 | static void translate_mul_s(DisasContext *dc, const OpcodeArg arg[], |
6412 | const uint32_t par[]) |
6413 | { |
6414 | gen_helper_mul_s(arg[0].out, cpu_env, |
6415 | arg[1].in, arg[2].in); |
6416 | } |
6417 | |
6418 | static void translate_msub_s(DisasContext *dc, const OpcodeArg arg[], |
6419 | const uint32_t par[]) |
6420 | { |
6421 | gen_helper_msub_s(arg[0].out, cpu_env, |
6422 | arg[0].in, arg[1].in, arg[2].in); |
6423 | } |
6424 | |
6425 | static void translate_neg_s(DisasContext *dc, const OpcodeArg arg[], |
6426 | const uint32_t par[]) |
6427 | { |
6428 | gen_helper_neg_s(arg[0].out, arg[1].in); |
6429 | } |
6430 | |
6431 | static void translate_rfr_s(DisasContext *dc, const OpcodeArg arg[], |
6432 | const uint32_t par[]) |
6433 | { |
6434 | tcg_gen_mov_i32(arg[0].out, arg[1].in); |
6435 | } |
6436 | |
6437 | static void translate_sub_s(DisasContext *dc, const OpcodeArg arg[], |
6438 | const uint32_t par[]) |
6439 | { |
6440 | gen_helper_sub_s(arg[0].out, cpu_env, |
6441 | arg[1].in, arg[2].in); |
6442 | } |
6443 | |
6444 | static void translate_wfr_s(DisasContext *dc, const OpcodeArg arg[], |
6445 | const uint32_t par[]) |
6446 | { |
6447 | tcg_gen_mov_i32(arg[0].out, arg[1].in); |
6448 | } |
6449 | |
6450 | static const XtensaOpcodeOps fpu2000_ops[] = { |
6451 | { |
6452 | .name = "abs.s" , |
6453 | .translate = translate_abs_s, |
6454 | .coprocessor = 0x1, |
6455 | }, { |
6456 | .name = "add.s" , |
6457 | .translate = translate_add_s, |
6458 | .coprocessor = 0x1, |
6459 | }, { |
6460 | .name = "ceil.s" , |
6461 | .translate = translate_ftoi_s, |
6462 | .par = (const uint32_t[]){float_round_up, false}, |
6463 | .coprocessor = 0x1, |
6464 | }, { |
6465 | .name = "float.s" , |
6466 | .translate = translate_float_s, |
6467 | .par = (const uint32_t[]){false}, |
6468 | .coprocessor = 0x1, |
6469 | }, { |
6470 | .name = "floor.s" , |
6471 | .translate = translate_ftoi_s, |
6472 | .par = (const uint32_t[]){float_round_down, false}, |
6473 | .coprocessor = 0x1, |
6474 | }, { |
6475 | .name = "lsi" , |
6476 | .translate = translate_ldsti, |
6477 | .par = (const uint32_t[]){false, false}, |
6478 | .op_flags = XTENSA_OP_LOAD, |
6479 | .coprocessor = 0x1, |
6480 | }, { |
6481 | .name = "lsiu" , |
6482 | .translate = translate_ldsti, |
6483 | .par = (const uint32_t[]){false, true}, |
6484 | .op_flags = XTENSA_OP_LOAD, |
6485 | .coprocessor = 0x1, |
6486 | }, { |
6487 | .name = "lsx" , |
6488 | .translate = translate_ldstx, |
6489 | .par = (const uint32_t[]){false, false}, |
6490 | .op_flags = XTENSA_OP_LOAD, |
6491 | .coprocessor = 0x1, |
6492 | }, { |
6493 | .name = "lsxu" , |
6494 | .translate = translate_ldstx, |
6495 | .par = (const uint32_t[]){false, true}, |
6496 | .op_flags = XTENSA_OP_LOAD, |
6497 | .coprocessor = 0x1, |
6498 | }, { |
6499 | .name = "madd.s" , |
6500 | .translate = translate_madd_s, |
6501 | .coprocessor = 0x1, |
6502 | }, { |
6503 | .name = "mov.s" , |
6504 | .translate = translate_mov_s, |
6505 | .coprocessor = 0x1, |
6506 | }, { |
6507 | .name = "moveqz.s" , |
6508 | .translate = translate_movcond_s, |
6509 | .par = (const uint32_t[]){TCG_COND_EQ}, |
6510 | .coprocessor = 0x1, |
6511 | }, { |
6512 | .name = "movf.s" , |
6513 | .translate = translate_movp_s, |
6514 | .par = (const uint32_t[]){TCG_COND_EQ}, |
6515 | .coprocessor = 0x1, |
6516 | }, { |
6517 | .name = "movgez.s" , |
6518 | .translate = translate_movcond_s, |
6519 | .par = (const uint32_t[]){TCG_COND_GE}, |
6520 | .coprocessor = 0x1, |
6521 | }, { |
6522 | .name = "movltz.s" , |
6523 | .translate = translate_movcond_s, |
6524 | .par = (const uint32_t[]){TCG_COND_LT}, |
6525 | .coprocessor = 0x1, |
6526 | }, { |
6527 | .name = "movnez.s" , |
6528 | .translate = translate_movcond_s, |
6529 | .par = (const uint32_t[]){TCG_COND_NE}, |
6530 | .coprocessor = 0x1, |
6531 | }, { |
6532 | .name = "movt.s" , |
6533 | .translate = translate_movp_s, |
6534 | .par = (const uint32_t[]){TCG_COND_NE}, |
6535 | .coprocessor = 0x1, |
6536 | }, { |
6537 | .name = "msub.s" , |
6538 | .translate = translate_msub_s, |
6539 | .coprocessor = 0x1, |
6540 | }, { |
6541 | .name = "mul.s" , |
6542 | .translate = translate_mul_s, |
6543 | .coprocessor = 0x1, |
6544 | }, { |
6545 | .name = "neg.s" , |
6546 | .translate = translate_neg_s, |
6547 | .coprocessor = 0x1, |
6548 | }, { |
6549 | .name = "oeq.s" , |
6550 | .translate = translate_compare_s, |
6551 | .par = (const uint32_t[]){COMPARE_OEQ}, |
6552 | .coprocessor = 0x1, |
6553 | }, { |
6554 | .name = "ole.s" , |
6555 | .translate = translate_compare_s, |
6556 | .par = (const uint32_t[]){COMPARE_OLE}, |
6557 | .coprocessor = 0x1, |
6558 | }, { |
6559 | .name = "olt.s" , |
6560 | .translate = translate_compare_s, |
6561 | .par = (const uint32_t[]){COMPARE_OLT}, |
6562 | .coprocessor = 0x1, |
6563 | }, { |
6564 | .name = "rfr" , |
6565 | .translate = translate_rfr_s, |
6566 | .coprocessor = 0x1, |
6567 | }, { |
6568 | .name = "round.s" , |
6569 | .translate = translate_ftoi_s, |
6570 | .par = (const uint32_t[]){float_round_nearest_even, false}, |
6571 | .coprocessor = 0x1, |
6572 | }, { |
6573 | .name = "ssi" , |
6574 | .translate = translate_ldsti, |
6575 | .par = (const uint32_t[]){true, false}, |
6576 | .op_flags = XTENSA_OP_STORE, |
6577 | .coprocessor = 0x1, |
6578 | }, { |
6579 | .name = "ssiu" , |
6580 | .translate = translate_ldsti, |
6581 | .par = (const uint32_t[]){true, true}, |
6582 | .op_flags = XTENSA_OP_STORE, |
6583 | .coprocessor = 0x1, |
6584 | }, { |
6585 | .name = "ssx" , |
6586 | .translate = translate_ldstx, |
6587 | .par = (const uint32_t[]){true, false}, |
6588 | .op_flags = XTENSA_OP_STORE, |
6589 | .coprocessor = 0x1, |
6590 | }, { |
6591 | .name = "ssxu" , |
6592 | .translate = translate_ldstx, |
6593 | .par = (const uint32_t[]){true, true}, |
6594 | .op_flags = XTENSA_OP_STORE, |
6595 | .coprocessor = 0x1, |
6596 | }, { |
6597 | .name = "sub.s" , |
6598 | .translate = translate_sub_s, |
6599 | .coprocessor = 0x1, |
6600 | }, { |
6601 | .name = "trunc.s" , |
6602 | .translate = translate_ftoi_s, |
6603 | .par = (const uint32_t[]){float_round_to_zero, false}, |
6604 | .coprocessor = 0x1, |
6605 | }, { |
6606 | .name = "ueq.s" , |
6607 | .translate = translate_compare_s, |
6608 | .par = (const uint32_t[]){COMPARE_UEQ}, |
6609 | .coprocessor = 0x1, |
6610 | }, { |
6611 | .name = "ufloat.s" , |
6612 | .translate = translate_float_s, |
6613 | .par = (const uint32_t[]){true}, |
6614 | .coprocessor = 0x1, |
6615 | }, { |
6616 | .name = "ule.s" , |
6617 | .translate = translate_compare_s, |
6618 | .par = (const uint32_t[]){COMPARE_ULE}, |
6619 | .coprocessor = 0x1, |
6620 | }, { |
6621 | .name = "ult.s" , |
6622 | .translate = translate_compare_s, |
6623 | .par = (const uint32_t[]){COMPARE_ULT}, |
6624 | .coprocessor = 0x1, |
6625 | }, { |
6626 | .name = "un.s" , |
6627 | .translate = translate_compare_s, |
6628 | .par = (const uint32_t[]){COMPARE_UN}, |
6629 | .coprocessor = 0x1, |
6630 | }, { |
6631 | .name = "utrunc.s" , |
6632 | .translate = translate_ftoi_s, |
6633 | .par = (const uint32_t[]){float_round_to_zero, true}, |
6634 | .coprocessor = 0x1, |
6635 | }, { |
6636 | .name = "wfr" , |
6637 | .translate = translate_wfr_s, |
6638 | .coprocessor = 0x1, |
6639 | }, |
6640 | }; |
6641 | |
6642 | const XtensaOpcodeTranslators xtensa_fpu2000_opcodes = { |
6643 | .num_opcodes = ARRAY_SIZE(fpu2000_ops), |
6644 | .opcode = fpu2000_ops, |
6645 | }; |
6646 | |