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