target/xtensa: Convert to TranslatorOps
[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 "sysemu/sysemu.h"
39 #include "exec/cpu_ldst.h"
40 #include "exec/semihost.h"
41 #include "exec/translator.h"
42
43 #include "exec/helper-proto.h"
44 #include "exec/helper-gen.h"
45
46 #include "trace-tcg.h"
47 #include "exec/log.h"
48
49
50 struct DisasContext {
51 DisasContextBase base;
52 const XtensaConfig *config;
53 uint32_t pc;
54 int cring;
55 int ring;
56 uint32_t lbeg;
57 uint32_t lend;
58
59 bool sar_5bit;
60 bool sar_m32_5bit;
61 bool sar_m32_allocated;
62 TCGv_i32 sar_m32;
63
64 unsigned window;
65
66 bool debug;
67 bool icount;
68 TCGv_i32 next_icount;
69
70 unsigned cpenable;
71
72 uint32_t *raw_arg;
73 xtensa_insnbuf insnbuf;
74 xtensa_insnbuf slotbuf;
75 };
76
77 static TCGv_i32 cpu_pc;
78 static TCGv_i32 cpu_R[16];
79 static TCGv_i32 cpu_FR[16];
80 static TCGv_i32 cpu_SR[256];
81 static TCGv_i32 cpu_UR[256];
82
83 #include "exec/gen-icount.h"
84
85 typedef struct XtensaReg {
86 const char *name;
87 uint64_t opt_bits;
88 enum {
89 SR_R = 1,
90 SR_W = 2,
91 SR_X = 4,
92 SR_RW = 3,
93 SR_RWX = 7,
94 } access;
95 } XtensaReg;
96
97 #define XTENSA_REG_ACCESS(regname, opt, acc) { \
98 .name = (regname), \
99 .opt_bits = XTENSA_OPTION_BIT(opt), \
100 .access = (acc), \
101 }
102
103 #define XTENSA_REG(regname, opt) XTENSA_REG_ACCESS(regname, opt, SR_RWX)
104
105 #define XTENSA_REG_BITS_ACCESS(regname, opt, acc) { \
106 .name = (regname), \
107 .opt_bits = (opt), \
108 .access = (acc), \
109 }
110
111 #define XTENSA_REG_BITS(regname, opt) \
112 XTENSA_REG_BITS_ACCESS(regname, opt, SR_RWX)
113
114 static const XtensaReg sregnames[256] = {
115 [LBEG] = XTENSA_REG("LBEG", XTENSA_OPTION_LOOP),
116 [LEND] = XTENSA_REG("LEND", XTENSA_OPTION_LOOP),
117 [LCOUNT] = XTENSA_REG("LCOUNT", XTENSA_OPTION_LOOP),
118 [SAR] = XTENSA_REG_BITS("SAR", XTENSA_OPTION_ALL),
119 [BR] = XTENSA_REG("BR", XTENSA_OPTION_BOOLEAN),
120 [LITBASE] = XTENSA_REG("LITBASE", XTENSA_OPTION_EXTENDED_L32R),
121 [SCOMPARE1] = XTENSA_REG("SCOMPARE1", XTENSA_OPTION_CONDITIONAL_STORE),
122 [ACCLO] = XTENSA_REG("ACCLO", XTENSA_OPTION_MAC16),
123 [ACCHI] = XTENSA_REG("ACCHI", XTENSA_OPTION_MAC16),
124 [MR] = XTENSA_REG("MR0", XTENSA_OPTION_MAC16),
125 [MR + 1] = XTENSA_REG("MR1", XTENSA_OPTION_MAC16),
126 [MR + 2] = XTENSA_REG("MR2", XTENSA_OPTION_MAC16),
127 [MR + 3] = XTENSA_REG("MR3", XTENSA_OPTION_MAC16),
128 [WINDOW_BASE] = XTENSA_REG("WINDOW_BASE", XTENSA_OPTION_WINDOWED_REGISTER),
129 [WINDOW_START] = XTENSA_REG("WINDOW_START",
130 XTENSA_OPTION_WINDOWED_REGISTER),
131 [PTEVADDR] = XTENSA_REG("PTEVADDR", XTENSA_OPTION_MMU),
132 [MMID] = XTENSA_REG_BITS("MMID", XTENSA_OPTION_ALL),
133 [RASID] = XTENSA_REG("RASID", XTENSA_OPTION_MMU),
134 [ITLBCFG] = XTENSA_REG("ITLBCFG", XTENSA_OPTION_MMU),
135 [DTLBCFG] = XTENSA_REG("DTLBCFG", XTENSA_OPTION_MMU),
136 [IBREAKENABLE] = XTENSA_REG("IBREAKENABLE", XTENSA_OPTION_DEBUG),
137 [MEMCTL] = XTENSA_REG_BITS("MEMCTL", XTENSA_OPTION_ALL),
138 [CACHEATTR] = XTENSA_REG("CACHEATTR", XTENSA_OPTION_CACHEATTR),
139 [ATOMCTL] = XTENSA_REG("ATOMCTL", XTENSA_OPTION_ATOMCTL),
140 [DDR] = XTENSA_REG("DDR", XTENSA_OPTION_DEBUG),
141 [IBREAKA] = XTENSA_REG("IBREAKA0", XTENSA_OPTION_DEBUG),
142 [IBREAKA + 1] = XTENSA_REG("IBREAKA1", XTENSA_OPTION_DEBUG),
143 [DBREAKA] = XTENSA_REG("DBREAKA0", XTENSA_OPTION_DEBUG),
144 [DBREAKA + 1] = XTENSA_REG("DBREAKA1", XTENSA_OPTION_DEBUG),
145 [DBREAKC] = XTENSA_REG("DBREAKC0", XTENSA_OPTION_DEBUG),
146 [DBREAKC + 1] = XTENSA_REG("DBREAKC1", XTENSA_OPTION_DEBUG),
147 [CONFIGID0] = XTENSA_REG_BITS_ACCESS("CONFIGID0", XTENSA_OPTION_ALL, SR_R),
148 [EPC1] = XTENSA_REG("EPC1", XTENSA_OPTION_EXCEPTION),
149 [EPC1 + 1] = XTENSA_REG("EPC2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
150 [EPC1 + 2] = XTENSA_REG("EPC3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
151 [EPC1 + 3] = XTENSA_REG("EPC4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
152 [EPC1 + 4] = XTENSA_REG("EPC5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
153 [EPC1 + 5] = XTENSA_REG("EPC6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
154 [EPC1 + 6] = XTENSA_REG("EPC7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
155 [DEPC] = XTENSA_REG("DEPC", XTENSA_OPTION_EXCEPTION),
156 [EPS2] = XTENSA_REG("EPS2", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
157 [EPS2 + 1] = XTENSA_REG("EPS3", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
158 [EPS2 + 2] = XTENSA_REG("EPS4", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
159 [EPS2 + 3] = XTENSA_REG("EPS5", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
160 [EPS2 + 4] = XTENSA_REG("EPS6", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
161 [EPS2 + 5] = XTENSA_REG("EPS7", XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
162 [CONFIGID1] = XTENSA_REG_BITS_ACCESS("CONFIGID1", XTENSA_OPTION_ALL, SR_R),
163 [EXCSAVE1] = XTENSA_REG("EXCSAVE1", XTENSA_OPTION_EXCEPTION),
164 [EXCSAVE1 + 1] = XTENSA_REG("EXCSAVE2",
165 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
166 [EXCSAVE1 + 2] = XTENSA_REG("EXCSAVE3",
167 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
168 [EXCSAVE1 + 3] = XTENSA_REG("EXCSAVE4",
169 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
170 [EXCSAVE1 + 4] = XTENSA_REG("EXCSAVE5",
171 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
172 [EXCSAVE1 + 5] = XTENSA_REG("EXCSAVE6",
173 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
174 [EXCSAVE1 + 6] = XTENSA_REG("EXCSAVE7",
175 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT),
176 [CPENABLE] = XTENSA_REG("CPENABLE", XTENSA_OPTION_COPROCESSOR),
177 [INTSET] = XTENSA_REG_ACCESS("INTSET", XTENSA_OPTION_INTERRUPT, SR_RW),
178 [INTCLEAR] = XTENSA_REG_ACCESS("INTCLEAR", XTENSA_OPTION_INTERRUPT, SR_W),
179 [INTENABLE] = XTENSA_REG("INTENABLE", XTENSA_OPTION_INTERRUPT),
180 [PS] = XTENSA_REG_BITS("PS", XTENSA_OPTION_ALL),
181 [VECBASE] = XTENSA_REG("VECBASE", XTENSA_OPTION_RELOCATABLE_VECTOR),
182 [EXCCAUSE] = XTENSA_REG("EXCCAUSE", XTENSA_OPTION_EXCEPTION),
183 [DEBUGCAUSE] = XTENSA_REG_ACCESS("DEBUGCAUSE", XTENSA_OPTION_DEBUG, SR_R),
184 [CCOUNT] = XTENSA_REG("CCOUNT", XTENSA_OPTION_TIMER_INTERRUPT),
185 [PRID] = XTENSA_REG_ACCESS("PRID", XTENSA_OPTION_PROCESSOR_ID, SR_R),
186 [ICOUNT] = XTENSA_REG("ICOUNT", XTENSA_OPTION_DEBUG),
187 [ICOUNTLEVEL] = XTENSA_REG("ICOUNTLEVEL", XTENSA_OPTION_DEBUG),
188 [EXCVADDR] = XTENSA_REG("EXCVADDR", XTENSA_OPTION_EXCEPTION),
189 [CCOMPARE] = XTENSA_REG("CCOMPARE0", XTENSA_OPTION_TIMER_INTERRUPT),
190 [CCOMPARE + 1] = XTENSA_REG("CCOMPARE1",
191 XTENSA_OPTION_TIMER_INTERRUPT),
192 [CCOMPARE + 2] = XTENSA_REG("CCOMPARE2",
193 XTENSA_OPTION_TIMER_INTERRUPT),
194 [MISC] = XTENSA_REG("MISC0", XTENSA_OPTION_MISC_SR),
195 [MISC + 1] = XTENSA_REG("MISC1", XTENSA_OPTION_MISC_SR),
196 [MISC + 2] = XTENSA_REG("MISC2", XTENSA_OPTION_MISC_SR),
197 [MISC + 3] = XTENSA_REG("MISC3", XTENSA_OPTION_MISC_SR),
198 };
199
200 static const XtensaReg uregnames[256] = {
201 [EXPSTATE] = XTENSA_REG_BITS("EXPSTATE", XTENSA_OPTION_ALL),
202 [THREADPTR] = XTENSA_REG("THREADPTR", XTENSA_OPTION_THREAD_POINTER),
203 [FCR] = XTENSA_REG("FCR", XTENSA_OPTION_FP_COPROCESSOR),
204 [FSR] = XTENSA_REG("FSR", XTENSA_OPTION_FP_COPROCESSOR),
205 };
206
207 void xtensa_translate_init(void)
208 {
209 static const char * const regnames[] = {
210 "ar0", "ar1", "ar2", "ar3",
211 "ar4", "ar5", "ar6", "ar7",
212 "ar8", "ar9", "ar10", "ar11",
213 "ar12", "ar13", "ar14", "ar15",
214 };
215 static const char * const fregnames[] = {
216 "f0", "f1", "f2", "f3",
217 "f4", "f5", "f6", "f7",
218 "f8", "f9", "f10", "f11",
219 "f12", "f13", "f14", "f15",
220 };
221 int i;
222
223 cpu_pc = tcg_global_mem_new_i32(cpu_env,
224 offsetof(CPUXtensaState, pc), "pc");
225
226 for (i = 0; i < 16; i++) {
227 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
228 offsetof(CPUXtensaState, regs[i]),
229 regnames[i]);
230 }
231
232 for (i = 0; i < 16; i++) {
233 cpu_FR[i] = tcg_global_mem_new_i32(cpu_env,
234 offsetof(CPUXtensaState, fregs[i].f32[FP_F32_LOW]),
235 fregnames[i]);
236 }
237
238 for (i = 0; i < 256; ++i) {
239 if (sregnames[i].name) {
240 cpu_SR[i] = tcg_global_mem_new_i32(cpu_env,
241 offsetof(CPUXtensaState, sregs[i]),
242 sregnames[i].name);
243 }
244 }
245
246 for (i = 0; i < 256; ++i) {
247 if (uregnames[i].name) {
248 cpu_UR[i] = tcg_global_mem_new_i32(cpu_env,
249 offsetof(CPUXtensaState, uregs[i]),
250 uregnames[i].name);
251 }
252 }
253 }
254
255 static inline bool option_enabled(DisasContext *dc, int opt)
256 {
257 return xtensa_option_enabled(dc->config, opt);
258 }
259
260 static void init_sar_tracker(DisasContext *dc)
261 {
262 dc->sar_5bit = false;
263 dc->sar_m32_5bit = false;
264 dc->sar_m32_allocated = false;
265 }
266
267 static void reset_sar_tracker(DisasContext *dc)
268 {
269 if (dc->sar_m32_allocated) {
270 tcg_temp_free(dc->sar_m32);
271 }
272 }
273
274 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
275 {
276 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
277 if (dc->sar_m32_5bit) {
278 tcg_gen_discard_i32(dc->sar_m32);
279 }
280 dc->sar_5bit = true;
281 dc->sar_m32_5bit = false;
282 }
283
284 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
285 {
286 TCGv_i32 tmp = tcg_const_i32(32);
287 if (!dc->sar_m32_allocated) {
288 dc->sar_m32 = tcg_temp_local_new_i32();
289 dc->sar_m32_allocated = true;
290 }
291 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
292 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
293 dc->sar_5bit = false;
294 dc->sar_m32_5bit = true;
295 tcg_temp_free(tmp);
296 }
297
298 static void gen_exception(DisasContext *dc, int excp)
299 {
300 TCGv_i32 tmp = tcg_const_i32(excp);
301 gen_helper_exception(cpu_env, tmp);
302 tcg_temp_free(tmp);
303 }
304
305 static void gen_exception_cause(DisasContext *dc, uint32_t cause)
306 {
307 TCGv_i32 tpc = tcg_const_i32(dc->pc);
308 TCGv_i32 tcause = tcg_const_i32(cause);
309 gen_helper_exception_cause(cpu_env, tpc, tcause);
310 tcg_temp_free(tpc);
311 tcg_temp_free(tcause);
312 if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
313 cause == SYSCALL_CAUSE) {
314 dc->base.is_jmp = DISAS_NORETURN;
315 }
316 }
317
318 static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
319 TCGv_i32 vaddr)
320 {
321 TCGv_i32 tpc = tcg_const_i32(dc->pc);
322 TCGv_i32 tcause = tcg_const_i32(cause);
323 gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr);
324 tcg_temp_free(tpc);
325 tcg_temp_free(tcause);
326 }
327
328 static void gen_debug_exception(DisasContext *dc, uint32_t cause)
329 {
330 TCGv_i32 tpc = tcg_const_i32(dc->pc);
331 TCGv_i32 tcause = tcg_const_i32(cause);
332 gen_helper_debug_exception(cpu_env, tpc, tcause);
333 tcg_temp_free(tpc);
334 tcg_temp_free(tcause);
335 if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
336 dc->base.is_jmp = DISAS_NORETURN;
337 }
338 }
339
340 static bool gen_check_privilege(DisasContext *dc)
341 {
342 #ifndef CONFIG_USER_ONLY
343 if (!dc->cring) {
344 return true;
345 }
346 #endif
347 gen_exception_cause(dc, PRIVILEGED_CAUSE);
348 dc->base.is_jmp = DISAS_NORETURN;
349 return false;
350 }
351
352 static bool gen_check_cpenable(DisasContext *dc, unsigned cp)
353 {
354 if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) &&
355 !(dc->cpenable & (1 << cp))) {
356 gen_exception_cause(dc, COPROCESSOR0_DISABLED + cp);
357 dc->base.is_jmp = DISAS_NORETURN;
358 return false;
359 }
360 return true;
361 }
362
363 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
364 {
365 tcg_gen_mov_i32(cpu_pc, dest);
366 if (dc->icount) {
367 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
368 }
369 if (dc->base.singlestep_enabled) {
370 gen_exception(dc, EXCP_DEBUG);
371 } else {
372 if (slot >= 0) {
373 tcg_gen_goto_tb(slot);
374 tcg_gen_exit_tb(dc->base.tb, slot);
375 } else {
376 tcg_gen_exit_tb(NULL, 0);
377 }
378 }
379 dc->base.is_jmp = DISAS_NORETURN;
380 }
381
382 static void gen_jump(DisasContext *dc, TCGv dest)
383 {
384 gen_jump_slot(dc, dest, -1);
385 }
386
387 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
388 {
389 TCGv_i32 tmp = tcg_const_i32(dest);
390 #ifndef CONFIG_USER_ONLY
391 if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) {
392 slot = -1;
393 }
394 #endif
395 gen_jump_slot(dc, tmp, slot);
396 tcg_temp_free(tmp);
397 }
398
399 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
400 int slot)
401 {
402 TCGv_i32 tcallinc = tcg_const_i32(callinc);
403
404 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
405 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
406 tcg_temp_free(tcallinc);
407 tcg_gen_movi_i32(cpu_R[callinc << 2],
408 (callinc << 30) | (dc->base.pc_next & 0x3fffffff));
409 gen_jump_slot(dc, dest, slot);
410 }
411
412 static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
413 {
414 gen_callw_slot(dc, callinc, dest, -1);
415 }
416
417 static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
418 {
419 TCGv_i32 tmp = tcg_const_i32(dest);
420 #ifndef CONFIG_USER_ONLY
421 if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) {
422 slot = -1;
423 }
424 #endif
425 gen_callw_slot(dc, callinc, tmp, slot);
426 tcg_temp_free(tmp);
427 }
428
429 static bool gen_check_loop_end(DisasContext *dc, int slot)
430 {
431 if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
432 !(dc->base.tb->flags & XTENSA_TBFLAG_EXCM) &&
433 dc->base.pc_next == dc->lend) {
434 TCGLabel *label = gen_new_label();
435
436 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
437 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
438 gen_jumpi(dc, dc->lbeg, slot);
439 gen_set_label(label);
440 gen_jumpi(dc, dc->base.pc_next, -1);
441 return true;
442 }
443 return false;
444 }
445
446 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
447 {
448 if (!gen_check_loop_end(dc, slot)) {
449 gen_jumpi(dc, dc->base.pc_next, slot);
450 }
451 }
452
453 static void gen_brcond(DisasContext *dc, TCGCond cond,
454 TCGv_i32 t0, TCGv_i32 t1, uint32_t addr)
455 {
456 TCGLabel *label = gen_new_label();
457
458 tcg_gen_brcond_i32(cond, t0, t1, label);
459 gen_jumpi_check_loop_end(dc, 0);
460 gen_set_label(label);
461 gen_jumpi(dc, addr, 1);
462 }
463
464 static void gen_brcondi(DisasContext *dc, TCGCond cond,
465 TCGv_i32 t0, uint32_t t1, uint32_t addr)
466 {
467 TCGv_i32 tmp = tcg_const_i32(t1);
468 gen_brcond(dc, cond, t0, tmp, addr);
469 tcg_temp_free(tmp);
470 }
471
472 static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
473 {
474 if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
475 if (sregnames[sr].name) {
476 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not configured\n", sregnames[sr].name);
477 } else {
478 qemu_log_mask(LOG_UNIMP, "SR %d is not implemented\n", sr);
479 }
480 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
481 return false;
482 } else if (!(sregnames[sr].access & access)) {
483 static const char * const access_text[] = {
484 [SR_R] = "rsr",
485 [SR_W] = "wsr",
486 [SR_X] = "xsr",
487 };
488 assert(access < ARRAY_SIZE(access_text) && access_text[access]);
489 qemu_log_mask(LOG_GUEST_ERROR, "SR %s is not available for %s\n", sregnames[sr].name,
490 access_text[access]);
491 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
492 return false;
493 }
494 return true;
495 }
496
497 #ifndef CONFIG_USER_ONLY
498 static bool gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
499 {
500 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
501 gen_io_start();
502 }
503 gen_helper_update_ccount(cpu_env);
504 tcg_gen_mov_i32(d, cpu_SR[sr]);
505 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
506 gen_io_end();
507 return true;
508 }
509 return false;
510 }
511
512 static bool gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
513 {
514 tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10);
515 tcg_gen_or_i32(d, d, cpu_SR[sr]);
516 tcg_gen_andi_i32(d, d, 0xfffffffc);
517 return false;
518 }
519 #endif
520
521 static bool gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
522 {
523 static bool (* const rsr_handler[256])(DisasContext *dc,
524 TCGv_i32 d, uint32_t sr) = {
525 #ifndef CONFIG_USER_ONLY
526 [CCOUNT] = gen_rsr_ccount,
527 [INTSET] = gen_rsr_ccount,
528 [PTEVADDR] = gen_rsr_ptevaddr,
529 #endif
530 };
531
532 if (rsr_handler[sr]) {
533 return rsr_handler[sr](dc, d, sr);
534 } else {
535 tcg_gen_mov_i32(d, cpu_SR[sr]);
536 return false;
537 }
538 }
539
540 static bool gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
541 {
542 gen_helper_wsr_lbeg(cpu_env, s);
543 gen_jumpi_check_loop_end(dc, 0);
544 return false;
545 }
546
547 static bool gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
548 {
549 gen_helper_wsr_lend(cpu_env, s);
550 gen_jumpi_check_loop_end(dc, 0);
551 return false;
552 }
553
554 static bool gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
555 {
556 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
557 if (dc->sar_m32_5bit) {
558 tcg_gen_discard_i32(dc->sar_m32);
559 }
560 dc->sar_5bit = false;
561 dc->sar_m32_5bit = false;
562 return false;
563 }
564
565 static bool gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
566 {
567 tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
568 return false;
569 }
570
571 static bool gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
572 {
573 tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
574 /* This can change tb->flags, so exit tb */
575 gen_jumpi_check_loop_end(dc, -1);
576 return true;
577 }
578
579 static bool gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
580 {
581 tcg_gen_ext8s_i32(cpu_SR[sr], s);
582 return false;
583 }
584
585 #ifndef CONFIG_USER_ONLY
586 static bool gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
587 {
588 gen_helper_wsr_windowbase(cpu_env, v);
589 /* This can change tb->flags, so exit tb */
590 gen_jumpi_check_loop_end(dc, -1);
591 return true;
592 }
593
594 static bool gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
595 {
596 tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1);
597 /* This can change tb->flags, so exit tb */
598 gen_jumpi_check_loop_end(dc, -1);
599 return true;
600 }
601
602 static bool gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
603 {
604 tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
605 return false;
606 }
607
608 static bool gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
609 {
610 gen_helper_wsr_rasid(cpu_env, v);
611 /* This can change tb->flags, so exit tb */
612 gen_jumpi_check_loop_end(dc, -1);
613 return true;
614 }
615
616 static bool gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
617 {
618 tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
619 return false;
620 }
621
622 static bool gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
623 {
624 gen_helper_wsr_ibreakenable(cpu_env, v);
625 gen_jumpi_check_loop_end(dc, 0);
626 return true;
627 }
628
629 static bool gen_wsr_memctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
630 {
631 gen_helper_wsr_memctl(cpu_env, v);
632 return false;
633 }
634
635 static bool gen_wsr_atomctl(DisasContext *dc, uint32_t sr, TCGv_i32 v)
636 {
637 tcg_gen_andi_i32(cpu_SR[sr], v, 0x3f);
638 return false;
639 }
640
641 static bool gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
642 {
643 unsigned id = sr - IBREAKA;
644
645 if (id < dc->config->nibreak) {
646 TCGv_i32 tmp = tcg_const_i32(id);
647 gen_helper_wsr_ibreaka(cpu_env, tmp, v);
648 tcg_temp_free(tmp);
649 gen_jumpi_check_loop_end(dc, 0);
650 return true;
651 }
652 return false;
653 }
654
655 static bool gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
656 {
657 unsigned id = sr - DBREAKA;
658
659 if (id < dc->config->ndbreak) {
660 TCGv_i32 tmp = tcg_const_i32(id);
661 gen_helper_wsr_dbreaka(cpu_env, tmp, v);
662 tcg_temp_free(tmp);
663 }
664 return false;
665 }
666
667 static bool gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
668 {
669 unsigned id = sr - DBREAKC;
670
671 if (id < dc->config->ndbreak) {
672 TCGv_i32 tmp = tcg_const_i32(id);
673 gen_helper_wsr_dbreakc(cpu_env, tmp, v);
674 tcg_temp_free(tmp);
675 }
676 return false;
677 }
678
679 static bool gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
680 {
681 tcg_gen_andi_i32(cpu_SR[sr], v, 0xff);
682 /* This can change tb->flags, so exit tb */
683 gen_jumpi_check_loop_end(dc, -1);
684 return true;
685 }
686
687 static void gen_check_interrupts(DisasContext *dc)
688 {
689 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
690 gen_io_start();
691 }
692 gen_helper_check_interrupts(cpu_env);
693 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
694 gen_io_end();
695 }
696 }
697
698 static bool gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
699 {
700 tcg_gen_andi_i32(cpu_SR[sr], v,
701 dc->config->inttype_mask[INTTYPE_SOFTWARE]);
702 gen_check_interrupts(dc);
703 gen_jumpi_check_loop_end(dc, 0);
704 return true;
705 }
706
707 static bool gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
708 {
709 TCGv_i32 tmp = tcg_temp_new_i32();
710
711 tcg_gen_andi_i32(tmp, v,
712 dc->config->inttype_mask[INTTYPE_EDGE] |
713 dc->config->inttype_mask[INTTYPE_NMI] |
714 dc->config->inttype_mask[INTTYPE_SOFTWARE]);
715 tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp);
716 tcg_temp_free(tmp);
717 gen_check_interrupts(dc);
718 gen_jumpi_check_loop_end(dc, 0);
719 return true;
720 }
721
722 static bool gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
723 {
724 tcg_gen_mov_i32(cpu_SR[sr], v);
725 gen_check_interrupts(dc);
726 gen_jumpi_check_loop_end(dc, 0);
727 return true;
728 }
729
730 static bool gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
731 {
732 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
733 PS_UM | PS_EXCM | PS_INTLEVEL;
734
735 if (option_enabled(dc, XTENSA_OPTION_MMU)) {
736 mask |= PS_RING;
737 }
738 tcg_gen_andi_i32(cpu_SR[sr], v, mask);
739 gen_check_interrupts(dc);
740 /* This can change mmu index and tb->flags, so exit tb */
741 gen_jumpi_check_loop_end(dc, -1);
742 return true;
743 }
744
745 static bool gen_wsr_ccount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
746 {
747 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
748 gen_io_start();
749 }
750 gen_helper_wsr_ccount(cpu_env, v);
751 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
752 gen_io_end();
753 gen_jumpi_check_loop_end(dc, 0);
754 return true;
755 }
756 return false;
757 }
758
759 static bool gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
760 {
761 if (dc->icount) {
762 tcg_gen_mov_i32(dc->next_icount, v);
763 } else {
764 tcg_gen_mov_i32(cpu_SR[sr], v);
765 }
766 return false;
767 }
768
769 static bool gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
770 {
771 tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
772 /* This can change tb->flags, so exit tb */
773 gen_jumpi_check_loop_end(dc, -1);
774 return true;
775 }
776
777 static bool gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
778 {
779 uint32_t id = sr - CCOMPARE;
780 bool ret = false;
781
782 if (id < dc->config->nccompare) {
783 uint32_t int_bit = 1 << dc->config->timerint[id];
784 TCGv_i32 tmp = tcg_const_i32(id);
785
786 tcg_gen_mov_i32(cpu_SR[sr], v);
787 tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);
788 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
789 gen_io_start();
790 }
791 gen_helper_update_ccompare(cpu_env, tmp);
792 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
793 gen_io_end();
794 gen_jumpi_check_loop_end(dc, 0);
795 ret = true;
796 }
797 tcg_temp_free(tmp);
798 }
799 return ret;
800 }
801 #else
802 static void gen_check_interrupts(DisasContext *dc)
803 {
804 }
805 #endif
806
807 static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
808 {
809 static bool (* const wsr_handler[256])(DisasContext *dc,
810 uint32_t sr, TCGv_i32 v) = {
811 [LBEG] = gen_wsr_lbeg,
812 [LEND] = gen_wsr_lend,
813 [SAR] = gen_wsr_sar,
814 [BR] = gen_wsr_br,
815 [LITBASE] = gen_wsr_litbase,
816 [ACCHI] = gen_wsr_acchi,
817 #ifndef CONFIG_USER_ONLY
818 [WINDOW_BASE] = gen_wsr_windowbase,
819 [WINDOW_START] = gen_wsr_windowstart,
820 [PTEVADDR] = gen_wsr_ptevaddr,
821 [RASID] = gen_wsr_rasid,
822 [ITLBCFG] = gen_wsr_tlbcfg,
823 [DTLBCFG] = gen_wsr_tlbcfg,
824 [IBREAKENABLE] = gen_wsr_ibreakenable,
825 [MEMCTL] = gen_wsr_memctl,
826 [ATOMCTL] = gen_wsr_atomctl,
827 [IBREAKA] = gen_wsr_ibreaka,
828 [IBREAKA + 1] = gen_wsr_ibreaka,
829 [DBREAKA] = gen_wsr_dbreaka,
830 [DBREAKA + 1] = gen_wsr_dbreaka,
831 [DBREAKC] = gen_wsr_dbreakc,
832 [DBREAKC + 1] = gen_wsr_dbreakc,
833 [CPENABLE] = gen_wsr_cpenable,
834 [INTSET] = gen_wsr_intset,
835 [INTCLEAR] = gen_wsr_intclear,
836 [INTENABLE] = gen_wsr_intenable,
837 [PS] = gen_wsr_ps,
838 [CCOUNT] = gen_wsr_ccount,
839 [ICOUNT] = gen_wsr_icount,
840 [ICOUNTLEVEL] = gen_wsr_icountlevel,
841 [CCOMPARE] = gen_wsr_ccompare,
842 [CCOMPARE + 1] = gen_wsr_ccompare,
843 [CCOMPARE + 2] = gen_wsr_ccompare,
844 #endif
845 };
846
847 if (wsr_handler[sr]) {
848 return wsr_handler[sr](dc, sr, s);
849 } else {
850 tcg_gen_mov_i32(cpu_SR[sr], s);
851 return false;
852 }
853 }
854
855 static void gen_wur(uint32_t ur, TCGv_i32 s)
856 {
857 switch (ur) {
858 case FCR:
859 gen_helper_wur_fcr(cpu_env, s);
860 break;
861
862 case FSR:
863 tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80);
864 break;
865
866 default:
867 tcg_gen_mov_i32(cpu_UR[ur], s);
868 break;
869 }
870 }
871
872 static void gen_load_store_alignment(DisasContext *dc, int shift,
873 TCGv_i32 addr, bool no_hw_alignment)
874 {
875 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
876 tcg_gen_andi_i32(addr, addr, ~0 << shift);
877 } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
878 no_hw_alignment) {
879 TCGLabel *label = gen_new_label();
880 TCGv_i32 tmp = tcg_temp_new_i32();
881 tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
882 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
883 gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
884 gen_set_label(label);
885 tcg_temp_free(tmp);
886 }
887 }
888
889 #ifndef CONFIG_USER_ONLY
890 static void gen_waiti(DisasContext *dc, uint32_t imm4)
891 {
892 TCGv_i32 pc = tcg_const_i32(dc->base.pc_next);
893 TCGv_i32 intlevel = tcg_const_i32(imm4);
894
895 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
896 gen_io_start();
897 }
898 gen_helper_waiti(cpu_env, pc, intlevel);
899 if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
900 gen_io_end();
901 }
902 tcg_temp_free(pc);
903 tcg_temp_free(intlevel);
904 gen_jumpi_check_loop_end(dc, 0);
905 }
906 #endif
907
908 static bool gen_window_check1(DisasContext *dc, unsigned r1)
909 {
910 if (r1 / 4 > dc->window) {
911 TCGv_i32 pc = tcg_const_i32(dc->pc);
912 TCGv_i32 w = tcg_const_i32(r1 / 4);
913
914 gen_helper_window_check(cpu_env, pc, w);
915 dc->base.is_jmp = DISAS_NORETURN;
916 return false;
917 }
918 return true;
919 }
920
921 static bool gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)
922 {
923 return gen_window_check1(dc, r1 > r2 ? r1 : r2);
924 }
925
926 static bool gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2,
927 unsigned r3)
928 {
929 return gen_window_check2(dc, r1, r2 > r3 ? r2 : r3);
930 }
931
932 static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
933 {
934 TCGv_i32 m = tcg_temp_new_i32();
935
936 if (hi) {
937 (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
938 } else {
939 (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
940 }
941 return m;
942 }
943
944 static inline unsigned xtensa_op0_insn_len(DisasContext *dc, uint8_t op0)
945 {
946 return xtensa_isa_length_from_chars(dc->config->isa, &op0);
947 }
948
949 static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
950 {
951 xtensa_isa isa = dc->config->isa;
952 unsigned char b[MAX_INSN_LENGTH] = {cpu_ldub_code(env, dc->pc)};
953 unsigned len = xtensa_op0_insn_len(dc, b[0]);
954 xtensa_format fmt;
955 int slot, slots;
956 unsigned i;
957
958 if (len == XTENSA_UNDEFINED) {
959 qemu_log_mask(LOG_GUEST_ERROR,
960 "unknown instruction length (pc = %08x)\n",
961 dc->pc);
962 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
963 return;
964 }
965
966 dc->base.pc_next = dc->pc + len;
967 if (xtensa_option_enabled(dc->config, XTENSA_OPTION_LOOP) &&
968 dc->lbeg == dc->pc &&
969 ((dc->pc ^ (dc->base.pc_next - 1)) & -dc->config->inst_fetch_width)) {
970 qemu_log_mask(LOG_GUEST_ERROR,
971 "unaligned first instruction of a loop (pc = %08x)\n",
972 dc->pc);
973 }
974 for (i = 1; i < len; ++i) {
975 b[i] = cpu_ldub_code(env, dc->pc + i);
976 }
977 xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len);
978 fmt = xtensa_format_decode(isa, dc->insnbuf);
979 if (fmt == XTENSA_UNDEFINED) {
980 qemu_log_mask(LOG_GUEST_ERROR,
981 "unrecognized instruction format (pc = %08x)\n",
982 dc->pc);
983 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
984 return;
985 }
986 slots = xtensa_format_num_slots(isa, fmt);
987 for (slot = 0; slot < slots; ++slot) {
988 xtensa_opcode opc;
989 int opnd, vopnd, opnds;
990 uint32_t raw_arg[MAX_OPCODE_ARGS];
991 uint32_t arg[MAX_OPCODE_ARGS];
992 XtensaOpcodeOps *ops;
993
994 dc->raw_arg = raw_arg;
995
996 xtensa_format_get_slot(isa, fmt, slot, dc->insnbuf, dc->slotbuf);
997 opc = xtensa_opcode_decode(isa, fmt, slot, dc->slotbuf);
998 if (opc == XTENSA_UNDEFINED) {
999 qemu_log_mask(LOG_GUEST_ERROR,
1000 "unrecognized opcode in slot %d (pc = %08x)\n",
1001 slot, dc->pc);
1002 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1003 return;
1004 }
1005 opnds = xtensa_opcode_num_operands(isa, opc);
1006
1007 for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
1008 if (xtensa_operand_is_visible(isa, opc, opnd)) {
1009 uint32_t v;
1010
1011 xtensa_operand_get_field(isa, opc, opnd, fmt, slot,
1012 dc->slotbuf, &v);
1013 xtensa_operand_decode(isa, opc, opnd, &v);
1014 raw_arg[vopnd] = v;
1015 if (xtensa_operand_is_PCrelative(isa, opc, opnd)) {
1016 xtensa_operand_undo_reloc(isa, opc, opnd, &v, dc->pc);
1017 }
1018 arg[vopnd] = v;
1019 ++vopnd;
1020 }
1021 }
1022 ops = dc->config->opcode_ops[opc];
1023 if (ops) {
1024 ops->translate(dc, arg, ops->par);
1025 } else {
1026 qemu_log_mask(LOG_GUEST_ERROR,
1027 "unimplemented opcode '%s' in slot %d (pc = %08x)\n",
1028 xtensa_opcode_name(isa, opc), slot, dc->pc);
1029 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1030 return;
1031 }
1032 }
1033 if (dc->base.is_jmp == DISAS_NEXT) {
1034 gen_check_loop_end(dc, 0);
1035 }
1036 dc->pc = dc->base.pc_next;
1037 }
1038
1039 static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
1040 {
1041 uint8_t b0 = cpu_ldub_code(env, dc->pc);
1042 return xtensa_op0_insn_len(dc, b0);
1043 }
1044
1045 static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
1046 {
1047 unsigned i;
1048
1049 for (i = 0; i < dc->config->nibreak; ++i) {
1050 if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
1051 env->sregs[IBREAKA + i] == dc->pc) {
1052 gen_debug_exception(dc, DEBUGCAUSE_IB);
1053 break;
1054 }
1055 }
1056 }
1057
1058 static void xtensa_tr_init_disas_context(DisasContextBase *dcbase,
1059 CPUState *cpu)
1060 {
1061 DisasContext *dc = container_of(dcbase, DisasContext, base);
1062 CPUXtensaState *env = cpu->env_ptr;
1063 uint32_t tb_flags = dc->base.tb->flags;
1064
1065 dc->config = env->config;
1066 dc->pc = dc->base.pc_first;
1067 dc->ring = tb_flags & XTENSA_TBFLAG_RING_MASK;
1068 dc->cring = (tb_flags & XTENSA_TBFLAG_EXCM) ? 0 : dc->ring;
1069 dc->lbeg = env->sregs[LBEG];
1070 dc->lend = env->sregs[LEND];
1071 dc->debug = tb_flags & XTENSA_TBFLAG_DEBUG;
1072 dc->icount = tb_flags & XTENSA_TBFLAG_ICOUNT;
1073 dc->cpenable = (tb_flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
1074 XTENSA_TBFLAG_CPENABLE_SHIFT;
1075 dc->window = ((tb_flags & XTENSA_TBFLAG_WINDOW_MASK) >>
1076 XTENSA_TBFLAG_WINDOW_SHIFT);
1077
1078 if (dc->config->isa) {
1079 dc->insnbuf = xtensa_insnbuf_alloc(dc->config->isa);
1080 dc->slotbuf = xtensa_insnbuf_alloc(dc->config->isa);
1081 }
1082 init_sar_tracker(dc);
1083 }
1084
1085 static void xtensa_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
1086 {
1087 DisasContext *dc = container_of(dcbase, DisasContext, base);
1088
1089 if (dc->icount) {
1090 dc->next_icount = tcg_temp_local_new_i32();
1091 }
1092 }
1093
1094 static void xtensa_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1095 {
1096 tcg_gen_insn_start(dcbase->pc_next);
1097 }
1098
1099 static bool xtensa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
1100 const CPUBreakpoint *bp)
1101 {
1102 DisasContext *dc = container_of(dcbase, DisasContext, base);
1103
1104 tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
1105 gen_exception(dc, EXCP_DEBUG);
1106 dc->base.is_jmp = DISAS_NORETURN;
1107 /* The address covered by the breakpoint must be included in
1108 [tb->pc, tb->pc + tb->size) in order to for it to be
1109 properly cleared -- thus we increment the PC here so that
1110 the logic setting tb->size below does the right thing. */
1111 dc->base.pc_next += 2;
1112 return true;
1113 }
1114
1115 static void xtensa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1116 {
1117 DisasContext *dc = container_of(dcbase, DisasContext, base);
1118 CPUXtensaState *env = cpu->env_ptr;
1119 target_ulong page_start;
1120
1121 /* These two conditions only apply to the first insn in the TB,
1122 but this is the first TranslateOps hook that allows exiting. */
1123 if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
1124 && (dc->base.tb->flags & XTENSA_TBFLAG_YIELD)) {
1125 gen_exception(dc, EXCP_YIELD);
1126 dc->base.is_jmp = DISAS_NORETURN;
1127 return;
1128 }
1129 if (dc->base.tb->flags & XTENSA_TBFLAG_EXCEPTION) {
1130 gen_exception(dc, EXCP_DEBUG);
1131 dc->base.is_jmp = DISAS_NORETURN;
1132 return;
1133 }
1134
1135 if (dc->icount) {
1136 TCGLabel *label = gen_new_label();
1137
1138 tcg_gen_addi_i32(dc->next_icount, cpu_SR[ICOUNT], 1);
1139 tcg_gen_brcondi_i32(TCG_COND_NE, dc->next_icount, 0, label);
1140 tcg_gen_mov_i32(dc->next_icount, cpu_SR[ICOUNT]);
1141 if (dc->debug) {
1142 gen_debug_exception(dc, DEBUGCAUSE_IC);
1143 }
1144 gen_set_label(label);
1145 }
1146
1147 if (dc->debug) {
1148 gen_ibreak_check(env, dc);
1149 }
1150
1151 disas_xtensa_insn(env, dc);
1152
1153 if (dc->icount) {
1154 tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
1155 }
1156
1157 /* End the TB if the next insn will cross into the next page. */
1158 page_start = dc->base.pc_first & TARGET_PAGE_MASK;
1159 if (dc->base.is_jmp == DISAS_NEXT &&
1160 (dc->pc - page_start >= TARGET_PAGE_SIZE ||
1161 dc->pc - page_start + xtensa_insn_len(env, dc) > TARGET_PAGE_SIZE)) {
1162 dc->base.is_jmp = DISAS_TOO_MANY;
1163 }
1164 }
1165
1166 static void xtensa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1167 {
1168 DisasContext *dc = container_of(dcbase, DisasContext, base);
1169
1170 reset_sar_tracker(dc);
1171 if (dc->config->isa) {
1172 xtensa_insnbuf_free(dc->config->isa, dc->insnbuf);
1173 xtensa_insnbuf_free(dc->config->isa, dc->slotbuf);
1174 }
1175 if (dc->icount) {
1176 tcg_temp_free(dc->next_icount);
1177 }
1178
1179 switch (dc->base.is_jmp) {
1180 case DISAS_NORETURN:
1181 break;
1182 case DISAS_TOO_MANY:
1183 if (dc->base.singlestep_enabled) {
1184 tcg_gen_movi_i32(cpu_pc, dc->pc);
1185 gen_exception(dc, EXCP_DEBUG);
1186 } else {
1187 gen_jumpi(dc, dc->pc, 0);
1188 }
1189 break;
1190 default:
1191 g_assert_not_reached();
1192 }
1193 }
1194
1195 static void xtensa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
1196 {
1197 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
1198 log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
1199 }
1200
1201 static const TranslatorOps xtensa_translator_ops = {
1202 .init_disas_context = xtensa_tr_init_disas_context,
1203 .tb_start = xtensa_tr_tb_start,
1204 .insn_start = xtensa_tr_insn_start,
1205 .breakpoint_check = xtensa_tr_breakpoint_check,
1206 .translate_insn = xtensa_tr_translate_insn,
1207 .tb_stop = xtensa_tr_tb_stop,
1208 .disas_log = xtensa_tr_disas_log,
1209 };
1210
1211 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
1212 {
1213 DisasContext dc = {};
1214 translator_loop(&xtensa_translator_ops, &dc.base, cpu, tb);
1215 }
1216
1217 void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
1218 fprintf_function cpu_fprintf, int flags)
1219 {
1220 XtensaCPU *cpu = XTENSA_CPU(cs);
1221 CPUXtensaState *env = &cpu->env;
1222 int i, j;
1223
1224 cpu_fprintf(f, "PC=%08x\n\n", env->pc);
1225
1226 for (i = j = 0; i < 256; ++i) {
1227 if (xtensa_option_bits_enabled(env->config, sregnames[i].opt_bits)) {
1228 cpu_fprintf(f, "%12s=%08x%c", sregnames[i].name, env->sregs[i],
1229 (j++ % 4) == 3 ? '\n' : ' ');
1230 }
1231 }
1232
1233 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1234
1235 for (i = j = 0; i < 256; ++i) {
1236 if (xtensa_option_bits_enabled(env->config, uregnames[i].opt_bits)) {
1237 cpu_fprintf(f, "%s=%08x%c", uregnames[i].name, env->uregs[i],
1238 (j++ % 4) == 3 ? '\n' : ' ');
1239 }
1240 }
1241
1242 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1243
1244 for (i = 0; i < 16; ++i) {
1245 cpu_fprintf(f, " A%02d=%08x%c", i, env->regs[i],
1246 (i % 4) == 3 ? '\n' : ' ');
1247 }
1248
1249 xtensa_sync_phys_from_window(env);
1250 cpu_fprintf(f, "\n");
1251
1252 for (i = 0; i < env->config->nareg; ++i) {
1253 cpu_fprintf(f, "AR%02d=%08x ", i, env->phys_regs[i]);
1254 if (i % 4 == 3) {
1255 bool ws = (env->sregs[WINDOW_START] & (1 << (i / 4))) != 0;
1256 bool cw = env->sregs[WINDOW_BASE] == i / 4;
1257
1258 cpu_fprintf(f, "%c%c\n", ws ? '<' : ' ', cw ? '=' : ' ');
1259 }
1260 }
1261
1262 if ((flags & CPU_DUMP_FPU) &&
1263 xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
1264 cpu_fprintf(f, "\n");
1265
1266 for (i = 0; i < 16; ++i) {
1267 cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
1268 float32_val(env->fregs[i].f32[FP_F32_LOW]),
1269 *(float *)(env->fregs[i].f32 + FP_F32_LOW),
1270 (i % 2) == 1 ? '\n' : ' ');
1271 }
1272 }
1273 }
1274
1275 void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
1276 target_ulong *data)
1277 {
1278 env->pc = data[0];
1279 }
1280
1281 static int compare_opcode_ops(const void *a, const void *b)
1282 {
1283 return strcmp((const char *)a,
1284 ((const XtensaOpcodeOps *)b)->name);
1285 }
1286
1287 XtensaOpcodeOps *
1288 xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
1289 const char *name)
1290 {
1291 return bsearch(name, t->opcode, t->num_opcodes,
1292 sizeof(XtensaOpcodeOps), compare_opcode_ops);
1293 }
1294
1295 static void translate_abs(DisasContext *dc, const uint32_t arg[],
1296 const uint32_t par[])
1297 {
1298 if (gen_window_check2(dc, arg[0], arg[1])) {
1299 TCGv_i32 zero = tcg_const_i32(0);
1300 TCGv_i32 neg = tcg_temp_new_i32();
1301
1302 tcg_gen_neg_i32(neg, cpu_R[arg[1]]);
1303 tcg_gen_movcond_i32(TCG_COND_GE, cpu_R[arg[0]],
1304 cpu_R[arg[1]], zero, cpu_R[arg[1]], neg);
1305 tcg_temp_free(neg);
1306 tcg_temp_free(zero);
1307 }
1308 }
1309
1310 static void translate_add(DisasContext *dc, const uint32_t arg[],
1311 const uint32_t par[])
1312 {
1313 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1314 tcg_gen_add_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1315 }
1316 }
1317
1318 static void translate_addi(DisasContext *dc, const uint32_t arg[],
1319 const uint32_t par[])
1320 {
1321 if (gen_window_check2(dc, arg[0], arg[1])) {
1322 tcg_gen_addi_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
1323 }
1324 }
1325
1326 static void translate_addx(DisasContext *dc, const uint32_t arg[],
1327 const uint32_t par[])
1328 {
1329 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1330 TCGv_i32 tmp = tcg_temp_new_i32();
1331 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
1332 tcg_gen_add_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
1333 tcg_temp_free(tmp);
1334 }
1335 }
1336
1337 static void translate_all(DisasContext *dc, const uint32_t arg[],
1338 const uint32_t par[])
1339 {
1340 uint32_t shift = par[1];
1341 TCGv_i32 mask = tcg_const_i32(((1 << shift) - 1) << arg[1]);
1342 TCGv_i32 tmp = tcg_temp_new_i32();
1343
1344 tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
1345 if (par[0]) {
1346 tcg_gen_addi_i32(tmp, tmp, 1 << arg[1]);
1347 } else {
1348 tcg_gen_add_i32(tmp, tmp, mask);
1349 }
1350 tcg_gen_shri_i32(tmp, tmp, arg[1] + shift);
1351 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
1352 tmp, arg[0], 1);
1353 tcg_temp_free(mask);
1354 tcg_temp_free(tmp);
1355 }
1356
1357 static void translate_and(DisasContext *dc, const uint32_t arg[],
1358 const uint32_t par[])
1359 {
1360 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1361 tcg_gen_and_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1362 }
1363 }
1364
1365 static void translate_ball(DisasContext *dc, const uint32_t arg[],
1366 const uint32_t par[])
1367 {
1368 if (gen_window_check2(dc, arg[0], arg[1])) {
1369 TCGv_i32 tmp = tcg_temp_new_i32();
1370 tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
1371 gen_brcond(dc, par[0], tmp, cpu_R[arg[1]], arg[2]);
1372 tcg_temp_free(tmp);
1373 }
1374 }
1375
1376 static void translate_bany(DisasContext *dc, const uint32_t arg[],
1377 const uint32_t par[])
1378 {
1379 if (gen_window_check2(dc, arg[0], arg[1])) {
1380 TCGv_i32 tmp = tcg_temp_new_i32();
1381 tcg_gen_and_i32(tmp, cpu_R[arg[0]], cpu_R[arg[1]]);
1382 gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1383 tcg_temp_free(tmp);
1384 }
1385 }
1386
1387 static void translate_b(DisasContext *dc, const uint32_t arg[],
1388 const uint32_t par[])
1389 {
1390 if (gen_window_check2(dc, arg[0], arg[1])) {
1391 gen_brcond(dc, par[0], cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
1392 }
1393 }
1394
1395 static void translate_bb(DisasContext *dc, const uint32_t arg[],
1396 const uint32_t par[])
1397 {
1398 if (gen_window_check2(dc, arg[0], arg[1])) {
1399 #ifdef TARGET_WORDS_BIGENDIAN
1400 TCGv_i32 bit = tcg_const_i32(0x80000000u);
1401 #else
1402 TCGv_i32 bit = tcg_const_i32(0x00000001u);
1403 #endif
1404 TCGv_i32 tmp = tcg_temp_new_i32();
1405 tcg_gen_andi_i32(tmp, cpu_R[arg[1]], 0x1f);
1406 #ifdef TARGET_WORDS_BIGENDIAN
1407 tcg_gen_shr_i32(bit, bit, tmp);
1408 #else
1409 tcg_gen_shl_i32(bit, bit, tmp);
1410 #endif
1411 tcg_gen_and_i32(tmp, cpu_R[arg[0]], bit);
1412 gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1413 tcg_temp_free(tmp);
1414 tcg_temp_free(bit);
1415 }
1416 }
1417
1418 static void translate_bbi(DisasContext *dc, const uint32_t arg[],
1419 const uint32_t par[])
1420 {
1421 if (gen_window_check1(dc, arg[0])) {
1422 TCGv_i32 tmp = tcg_temp_new_i32();
1423 #ifdef TARGET_WORDS_BIGENDIAN
1424 tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x80000000u >> arg[1]);
1425 #else
1426 tcg_gen_andi_i32(tmp, cpu_R[arg[0]], 0x00000001u << arg[1]);
1427 #endif
1428 gen_brcondi(dc, par[0], tmp, 0, arg[2]);
1429 tcg_temp_free(tmp);
1430 }
1431 }
1432
1433 static void translate_bi(DisasContext *dc, const uint32_t arg[],
1434 const uint32_t par[])
1435 {
1436 if (gen_window_check1(dc, arg[0])) {
1437 gen_brcondi(dc, par[0], cpu_R[arg[0]], arg[1], arg[2]);
1438 }
1439 }
1440
1441 static void translate_bz(DisasContext *dc, const uint32_t arg[],
1442 const uint32_t par[])
1443 {
1444 if (gen_window_check1(dc, arg[0])) {
1445 gen_brcondi(dc, par[0], cpu_R[arg[0]], 0, arg[1]);
1446 }
1447 }
1448
1449 enum {
1450 BOOLEAN_AND,
1451 BOOLEAN_ANDC,
1452 BOOLEAN_OR,
1453 BOOLEAN_ORC,
1454 BOOLEAN_XOR,
1455 };
1456
1457 static void translate_boolean(DisasContext *dc, const uint32_t arg[],
1458 const uint32_t par[])
1459 {
1460 static void (* const op[])(TCGv_i32, TCGv_i32, TCGv_i32) = {
1461 [BOOLEAN_AND] = tcg_gen_and_i32,
1462 [BOOLEAN_ANDC] = tcg_gen_andc_i32,
1463 [BOOLEAN_OR] = tcg_gen_or_i32,
1464 [BOOLEAN_ORC] = tcg_gen_orc_i32,
1465 [BOOLEAN_XOR] = tcg_gen_xor_i32,
1466 };
1467
1468 TCGv_i32 tmp1 = tcg_temp_new_i32();
1469 TCGv_i32 tmp2 = tcg_temp_new_i32();
1470
1471 tcg_gen_shri_i32(tmp1, cpu_SR[BR], arg[1]);
1472 tcg_gen_shri_i32(tmp2, cpu_SR[BR], arg[2]);
1473 op[par[0]](tmp1, tmp1, tmp2);
1474 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, arg[0], 1);
1475 tcg_temp_free(tmp1);
1476 tcg_temp_free(tmp2);
1477 }
1478
1479 static void translate_bp(DisasContext *dc, const uint32_t arg[],
1480 const uint32_t par[])
1481 {
1482 TCGv_i32 tmp = tcg_temp_new_i32();
1483
1484 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[0]);
1485 gen_brcondi(dc, par[0], tmp, 0, arg[1]);
1486 tcg_temp_free(tmp);
1487 }
1488
1489 static void translate_break(DisasContext *dc, const uint32_t arg[],
1490 const uint32_t par[])
1491 {
1492 if (dc->debug) {
1493 gen_debug_exception(dc, par[0]);
1494 }
1495 }
1496
1497 static void translate_call0(DisasContext *dc, const uint32_t arg[],
1498 const uint32_t par[])
1499 {
1500 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1501 gen_jumpi(dc, arg[0], 0);
1502 }
1503
1504 static void translate_callw(DisasContext *dc, const uint32_t arg[],
1505 const uint32_t par[])
1506 {
1507 if (gen_window_check1(dc, par[0] << 2)) {
1508 gen_callwi(dc, par[0], arg[0], 0);
1509 }
1510 }
1511
1512 static void translate_callx0(DisasContext *dc, const uint32_t arg[],
1513 const uint32_t par[])
1514 {
1515 if (gen_window_check1(dc, arg[0])) {
1516 TCGv_i32 tmp = tcg_temp_new_i32();
1517 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
1518 tcg_gen_movi_i32(cpu_R[0], dc->base.pc_next);
1519 gen_jump(dc, tmp);
1520 tcg_temp_free(tmp);
1521 }
1522 }
1523
1524 static void translate_callxw(DisasContext *dc, const uint32_t arg[],
1525 const uint32_t par[])
1526 {
1527 if (gen_window_check2(dc, arg[0], par[0] << 2)) {
1528 TCGv_i32 tmp = tcg_temp_new_i32();
1529
1530 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
1531 gen_callw(dc, par[0], tmp);
1532 tcg_temp_free(tmp);
1533 }
1534 }
1535
1536 static void translate_clamps(DisasContext *dc, const uint32_t arg[],
1537 const uint32_t par[])
1538 {
1539 if (gen_window_check2(dc, arg[0], arg[1])) {
1540 TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2]);
1541 TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2]) - 1);
1542
1543 tcg_gen_smax_i32(tmp1, tmp1, cpu_R[arg[1]]);
1544 tcg_gen_smin_i32(cpu_R[arg[0]], tmp1, tmp2);
1545 tcg_temp_free(tmp1);
1546 tcg_temp_free(tmp2);
1547 }
1548 }
1549
1550 static void translate_clrb_expstate(DisasContext *dc, const uint32_t arg[],
1551 const uint32_t par[])
1552 {
1553 /* TODO: GPIO32 may be a part of coprocessor */
1554 tcg_gen_andi_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], ~(1u << arg[0]));
1555 }
1556
1557 static void translate_const16(DisasContext *dc, const uint32_t arg[],
1558 const uint32_t par[])
1559 {
1560 if (gen_window_check1(dc, arg[0])) {
1561 TCGv_i32 c = tcg_const_i32(arg[1]);
1562
1563 tcg_gen_deposit_i32(cpu_R[arg[0]], c, cpu_R[arg[0]], 16, 16);
1564 tcg_temp_free(c);
1565 }
1566 }
1567
1568 /* par[0]: privileged, par[1]: check memory access */
1569 static void translate_dcache(DisasContext *dc, const uint32_t arg[],
1570 const uint32_t par[])
1571 {
1572 if ((!par[0] || gen_check_privilege(dc)) &&
1573 gen_window_check1(dc, arg[0]) && par[1]) {
1574 TCGv_i32 addr = tcg_temp_new_i32();
1575 TCGv_i32 res = tcg_temp_new_i32();
1576
1577 tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
1578 tcg_gen_qemu_ld8u(res, addr, dc->cring);
1579 tcg_temp_free(addr);
1580 tcg_temp_free(res);
1581 }
1582 }
1583
1584 static void translate_depbits(DisasContext *dc, const uint32_t arg[],
1585 const uint32_t par[])
1586 {
1587 if (gen_window_check2(dc, arg[0], arg[1])) {
1588 tcg_gen_deposit_i32(cpu_R[arg[1]], cpu_R[arg[1]], cpu_R[arg[0]],
1589 arg[2], arg[3]);
1590 }
1591 }
1592
1593 static void translate_entry(DisasContext *dc, const uint32_t arg[],
1594 const uint32_t par[])
1595 {
1596 TCGv_i32 pc = tcg_const_i32(dc->pc);
1597 TCGv_i32 s = tcg_const_i32(arg[0]);
1598 TCGv_i32 imm = tcg_const_i32(arg[1]);
1599 gen_helper_entry(cpu_env, pc, s, imm);
1600 tcg_temp_free(imm);
1601 tcg_temp_free(s);
1602 tcg_temp_free(pc);
1603 /* This can change tb->flags, so exit tb */
1604 gen_jumpi_check_loop_end(dc, -1);
1605 }
1606
1607 static void translate_extui(DisasContext *dc, const uint32_t arg[],
1608 const uint32_t par[])
1609 {
1610 if (gen_window_check2(dc, arg[0], arg[1])) {
1611 int maskimm = (1 << arg[3]) - 1;
1612
1613 TCGv_i32 tmp = tcg_temp_new_i32();
1614 tcg_gen_shri_i32(tmp, cpu_R[arg[1]], arg[2]);
1615 tcg_gen_andi_i32(cpu_R[arg[0]], tmp, maskimm);
1616 tcg_temp_free(tmp);
1617 }
1618 }
1619
1620 /* par[0]: privileged, par[1]: check memory access */
1621 static void translate_icache(DisasContext *dc, const uint32_t arg[],
1622 const uint32_t par[])
1623 {
1624 if ((!par[0] || gen_check_privilege(dc)) &&
1625 gen_window_check1(dc, arg[0]) && par[1]) {
1626 #ifndef CONFIG_USER_ONLY
1627 TCGv_i32 addr = tcg_temp_new_i32();
1628
1629 tcg_gen_movi_i32(cpu_pc, dc->pc);
1630 tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]);
1631 gen_helper_itlb_hit_test(cpu_env, addr);
1632 tcg_temp_free(addr);
1633 #endif
1634 }
1635 }
1636
1637 static void translate_itlb(DisasContext *dc, const uint32_t arg[],
1638 const uint32_t par[])
1639 {
1640 if (gen_check_privilege(dc) &&
1641 gen_window_check1(dc, arg[0])) {
1642 #ifndef CONFIG_USER_ONLY
1643 TCGv_i32 dtlb = tcg_const_i32(par[0]);
1644
1645 gen_helper_itlb(cpu_env, cpu_R[arg[0]], dtlb);
1646 /* This could change memory mapping, so exit tb */
1647 gen_jumpi_check_loop_end(dc, -1);
1648 tcg_temp_free(dtlb);
1649 #endif
1650 }
1651 }
1652
1653 static void translate_ill(DisasContext *dc, const uint32_t arg[],
1654 const uint32_t par[])
1655 {
1656 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1657 }
1658
1659 static void translate_j(DisasContext *dc, const uint32_t arg[],
1660 const uint32_t par[])
1661 {
1662 gen_jumpi(dc, arg[0], 0);
1663 }
1664
1665 static void translate_jx(DisasContext *dc, const uint32_t arg[],
1666 const uint32_t par[])
1667 {
1668 if (gen_window_check1(dc, arg[0])) {
1669 gen_jump(dc, cpu_R[arg[0]]);
1670 }
1671 }
1672
1673 static void translate_l32e(DisasContext *dc, const uint32_t arg[],
1674 const uint32_t par[])
1675 {
1676 if (gen_check_privilege(dc) &&
1677 gen_window_check2(dc, arg[0], arg[1])) {
1678 TCGv_i32 addr = tcg_temp_new_i32();
1679
1680 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
1681 gen_load_store_alignment(dc, 2, addr, false);
1682 tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
1683 tcg_temp_free(addr);
1684 }
1685 }
1686
1687 static void translate_ldst(DisasContext *dc, const uint32_t arg[],
1688 const uint32_t par[])
1689 {
1690 if (gen_window_check2(dc, arg[0], arg[1])) {
1691 TCGv_i32 addr = tcg_temp_new_i32();
1692
1693 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
1694 if (par[0] & MO_SIZE) {
1695 gen_load_store_alignment(dc, par[0] & MO_SIZE, addr, par[1]);
1696 }
1697 if (par[2]) {
1698 if (par[1]) {
1699 tcg_gen_mb(TCG_BAR_STRL | TCG_MO_ALL);
1700 }
1701 tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
1702 } else {
1703 tcg_gen_qemu_ld_tl(cpu_R[arg[0]], addr, dc->cring, par[0]);
1704 if (par[1]) {
1705 tcg_gen_mb(TCG_BAR_LDAQ | TCG_MO_ALL);
1706 }
1707 }
1708 tcg_temp_free(addr);
1709 }
1710 }
1711
1712 static void translate_l32r(DisasContext *dc, const uint32_t arg[],
1713 const uint32_t par[])
1714 {
1715 if (gen_window_check1(dc, arg[0])) {
1716 TCGv_i32 tmp;
1717
1718 if (dc->base.tb->flags & XTENSA_TBFLAG_LITBASE) {
1719 tmp = tcg_const_i32(dc->raw_arg[1] - 1);
1720 tcg_gen_add_i32(tmp, cpu_SR[LITBASE], tmp);
1721 } else {
1722 tmp = tcg_const_i32(arg[1]);
1723 }
1724 tcg_gen_qemu_ld32u(cpu_R[arg[0]], tmp, dc->cring);
1725 tcg_temp_free(tmp);
1726 }
1727 }
1728
1729 static void translate_loop(DisasContext *dc, const uint32_t arg[],
1730 const uint32_t par[])
1731 {
1732 if (gen_window_check1(dc, arg[0])) {
1733 uint32_t lend = arg[1];
1734 TCGv_i32 tmp = tcg_const_i32(lend);
1735
1736 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[arg[0]], 1);
1737 tcg_gen_movi_i32(cpu_SR[LBEG], dc->base.pc_next);
1738 gen_helper_wsr_lend(cpu_env, tmp);
1739 tcg_temp_free(tmp);
1740
1741 if (par[0] != TCG_COND_NEVER) {
1742 TCGLabel *label = gen_new_label();
1743 tcg_gen_brcondi_i32(par[0], cpu_R[arg[0]], 0, label);
1744 gen_jumpi(dc, lend, 1);
1745 gen_set_label(label);
1746 }
1747
1748 gen_jumpi(dc, dc->base.pc_next, 0);
1749 }
1750 }
1751
1752 enum {
1753 MAC16_UMUL,
1754 MAC16_MUL,
1755 MAC16_MULA,
1756 MAC16_MULS,
1757 MAC16_NONE,
1758 };
1759
1760 enum {
1761 MAC16_LL,
1762 MAC16_HL,
1763 MAC16_LH,
1764 MAC16_HH,
1765
1766 MAC16_HX = 0x1,
1767 MAC16_XH = 0x2,
1768 };
1769
1770 enum {
1771 MAC16_AA,
1772 MAC16_AD,
1773 MAC16_DA,
1774 MAC16_DD,
1775
1776 MAC16_XD = 0x1,
1777 MAC16_DX = 0x2,
1778 };
1779
1780 static void translate_mac16(DisasContext *dc, const uint32_t arg[],
1781 const uint32_t par[])
1782 {
1783 int op = par[0];
1784 bool is_m1_sr = par[1] & MAC16_DX;
1785 bool is_m2_sr = par[1] & MAC16_XD;
1786 unsigned half = par[2];
1787 uint32_t ld_offset = par[3];
1788 unsigned off = ld_offset ? 2 : 0;
1789 uint32_t ar[3] = {0};
1790 unsigned n_ar = 0;
1791
1792 if (op != MAC16_NONE) {
1793 if (!is_m1_sr) {
1794 ar[n_ar++] = arg[off];
1795 }
1796 if (!is_m2_sr) {
1797 ar[n_ar++] = arg[off + 1];
1798 }
1799 }
1800
1801 if (ld_offset) {
1802 ar[n_ar++] = arg[1];
1803 }
1804
1805 if (gen_window_check3(dc, ar[0], ar[1], ar[2])) {
1806 TCGv_i32 vaddr = tcg_temp_new_i32();
1807 TCGv_i32 mem32 = tcg_temp_new_i32();
1808
1809 if (ld_offset) {
1810 tcg_gen_addi_i32(vaddr, cpu_R[arg[1]], ld_offset);
1811 gen_load_store_alignment(dc, 2, vaddr, false);
1812 tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
1813 }
1814 if (op != MAC16_NONE) {
1815 TCGv_i32 m1 = gen_mac16_m(is_m1_sr ?
1816 cpu_SR[MR + arg[off]] :
1817 cpu_R[arg[off]],
1818 half & MAC16_HX, op == MAC16_UMUL);
1819 TCGv_i32 m2 = gen_mac16_m(is_m2_sr ?
1820 cpu_SR[MR + arg[off + 1]] :
1821 cpu_R[arg[off + 1]],
1822 half & MAC16_XH, op == MAC16_UMUL);
1823
1824 if (op == MAC16_MUL || op == MAC16_UMUL) {
1825 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
1826 if (op == MAC16_UMUL) {
1827 tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
1828 } else {
1829 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
1830 }
1831 } else {
1832 TCGv_i32 lo = tcg_temp_new_i32();
1833 TCGv_i32 hi = tcg_temp_new_i32();
1834
1835 tcg_gen_mul_i32(lo, m1, m2);
1836 tcg_gen_sari_i32(hi, lo, 31);
1837 if (op == MAC16_MULA) {
1838 tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1839 cpu_SR[ACCLO], cpu_SR[ACCHI],
1840 lo, hi);
1841 } else {
1842 tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
1843 cpu_SR[ACCLO], cpu_SR[ACCHI],
1844 lo, hi);
1845 }
1846 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
1847
1848 tcg_temp_free_i32(lo);
1849 tcg_temp_free_i32(hi);
1850 }
1851 tcg_temp_free(m1);
1852 tcg_temp_free(m2);
1853 }
1854 if (ld_offset) {
1855 tcg_gen_mov_i32(cpu_R[arg[1]], vaddr);
1856 tcg_gen_mov_i32(cpu_SR[MR + arg[0]], mem32);
1857 }
1858 tcg_temp_free(vaddr);
1859 tcg_temp_free(mem32);
1860 }
1861 }
1862
1863 static void translate_memw(DisasContext *dc, const uint32_t arg[],
1864 const uint32_t par[])
1865 {
1866 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
1867 }
1868
1869 static void translate_smin(DisasContext *dc, const uint32_t arg[],
1870 const uint32_t par[])
1871 {
1872 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1873 tcg_gen_smin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1874 }
1875 }
1876
1877 static void translate_umin(DisasContext *dc, const uint32_t arg[],
1878 const uint32_t par[])
1879 {
1880 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1881 tcg_gen_umin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1882 }
1883 }
1884
1885 static void translate_smax(DisasContext *dc, const uint32_t arg[],
1886 const uint32_t par[])
1887 {
1888 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1889 tcg_gen_smax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1890 }
1891 }
1892
1893 static void translate_umax(DisasContext *dc, const uint32_t arg[],
1894 const uint32_t par[])
1895 {
1896 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1897 tcg_gen_umax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1898 }
1899 }
1900
1901 static void translate_mov(DisasContext *dc, const uint32_t arg[],
1902 const uint32_t par[])
1903 {
1904 if (gen_window_check2(dc, arg[0], arg[1])) {
1905 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1906 }
1907 }
1908
1909 static void translate_movcond(DisasContext *dc, const uint32_t arg[],
1910 const uint32_t par[])
1911 {
1912 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1913 TCGv_i32 zero = tcg_const_i32(0);
1914
1915 tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
1916 cpu_R[arg[2]], zero, cpu_R[arg[1]], cpu_R[arg[0]]);
1917 tcg_temp_free(zero);
1918 }
1919 }
1920
1921 static void translate_movi(DisasContext *dc, const uint32_t arg[],
1922 const uint32_t par[])
1923 {
1924 if (gen_window_check1(dc, arg[0])) {
1925 tcg_gen_movi_i32(cpu_R[arg[0]], arg[1]);
1926 }
1927 }
1928
1929 static void translate_movp(DisasContext *dc, const uint32_t arg[],
1930 const uint32_t par[])
1931 {
1932 if (gen_window_check2(dc, arg[0], arg[1])) {
1933 TCGv_i32 zero = tcg_const_i32(0);
1934 TCGv_i32 tmp = tcg_temp_new_i32();
1935
1936 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << arg[2]);
1937 tcg_gen_movcond_i32(par[0],
1938 cpu_R[arg[0]], tmp, zero,
1939 cpu_R[arg[1]], cpu_R[arg[0]]);
1940 tcg_temp_free(tmp);
1941 tcg_temp_free(zero);
1942 }
1943 }
1944
1945 static void translate_movsp(DisasContext *dc, const uint32_t arg[],
1946 const uint32_t par[])
1947 {
1948 if (gen_window_check2(dc, arg[0], arg[1])) {
1949 TCGv_i32 pc = tcg_const_i32(dc->pc);
1950 gen_helper_movsp(cpu_env, pc);
1951 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
1952 tcg_temp_free(pc);
1953 }
1954 }
1955
1956 static void translate_mul16(DisasContext *dc, const uint32_t arg[],
1957 const uint32_t par[])
1958 {
1959 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1960 TCGv_i32 v1 = tcg_temp_new_i32();
1961 TCGv_i32 v2 = tcg_temp_new_i32();
1962
1963 if (par[0]) {
1964 tcg_gen_ext16s_i32(v1, cpu_R[arg[1]]);
1965 tcg_gen_ext16s_i32(v2, cpu_R[arg[2]]);
1966 } else {
1967 tcg_gen_ext16u_i32(v1, cpu_R[arg[1]]);
1968 tcg_gen_ext16u_i32(v2, cpu_R[arg[2]]);
1969 }
1970 tcg_gen_mul_i32(cpu_R[arg[0]], v1, v2);
1971 tcg_temp_free(v2);
1972 tcg_temp_free(v1);
1973 }
1974 }
1975
1976 static void translate_mull(DisasContext *dc, const uint32_t arg[],
1977 const uint32_t par[])
1978 {
1979 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1980 tcg_gen_mul_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1981 }
1982 }
1983
1984 static void translate_mulh(DisasContext *dc, const uint32_t arg[],
1985 const uint32_t par[])
1986 {
1987 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
1988 TCGv_i32 lo = tcg_temp_new();
1989
1990 if (par[0]) {
1991 tcg_gen_muls2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1992 } else {
1993 tcg_gen_mulu2_i32(lo, cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
1994 }
1995 tcg_temp_free(lo);
1996 }
1997 }
1998
1999 static void translate_neg(DisasContext *dc, const uint32_t arg[],
2000 const uint32_t par[])
2001 {
2002 if (gen_window_check2(dc, arg[0], arg[1])) {
2003 tcg_gen_neg_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2004 }
2005 }
2006
2007 static void translate_nop(DisasContext *dc, const uint32_t arg[],
2008 const uint32_t par[])
2009 {
2010 }
2011
2012 static void translate_nsa(DisasContext *dc, const uint32_t arg[],
2013 const uint32_t par[])
2014 {
2015 if (gen_window_check2(dc, arg[0], arg[1])) {
2016 tcg_gen_clrsb_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2017 }
2018 }
2019
2020 static void translate_nsau(DisasContext *dc, const uint32_t arg[],
2021 const uint32_t par[])
2022 {
2023 if (gen_window_check2(dc, arg[0], arg[1])) {
2024 tcg_gen_clzi_i32(cpu_R[arg[0]], cpu_R[arg[1]], 32);
2025 }
2026 }
2027
2028 static void translate_or(DisasContext *dc, const uint32_t arg[],
2029 const uint32_t par[])
2030 {
2031 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2032 tcg_gen_or_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2033 }
2034 }
2035
2036 static void translate_ptlb(DisasContext *dc, const uint32_t arg[],
2037 const uint32_t par[])
2038 {
2039 if (gen_check_privilege(dc) &&
2040 gen_window_check2(dc, arg[0], arg[1])) {
2041 #ifndef CONFIG_USER_ONLY
2042 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2043
2044 tcg_gen_movi_i32(cpu_pc, dc->pc);
2045 gen_helper_ptlb(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
2046 tcg_temp_free(dtlb);
2047 #endif
2048 }
2049 }
2050
2051 static void gen_zero_check(DisasContext *dc, const uint32_t arg[])
2052 {
2053 TCGLabel *label = gen_new_label();
2054
2055 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0, label);
2056 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
2057 gen_set_label(label);
2058 }
2059
2060 static void translate_quos(DisasContext *dc, const uint32_t arg[],
2061 const uint32_t par[])
2062 {
2063 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2064 TCGLabel *label1 = gen_new_label();
2065 TCGLabel *label2 = gen_new_label();
2066
2067 gen_zero_check(dc, arg);
2068
2069 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[1]], 0x80000000,
2070 label1);
2071 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[arg[2]], 0xffffffff,
2072 label1);
2073 tcg_gen_movi_i32(cpu_R[arg[0]],
2074 par[0] ? 0x80000000 : 0);
2075 tcg_gen_br(label2);
2076 gen_set_label(label1);
2077 if (par[0]) {
2078 tcg_gen_div_i32(cpu_R[arg[0]],
2079 cpu_R[arg[1]], cpu_R[arg[2]]);
2080 } else {
2081 tcg_gen_rem_i32(cpu_R[arg[0]],
2082 cpu_R[arg[1]], cpu_R[arg[2]]);
2083 }
2084 gen_set_label(label2);
2085 }
2086 }
2087
2088 static void translate_quou(DisasContext *dc, const uint32_t arg[],
2089 const uint32_t par[])
2090 {
2091 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2092 gen_zero_check(dc, arg);
2093 if (par[0]) {
2094 tcg_gen_divu_i32(cpu_R[arg[0]],
2095 cpu_R[arg[1]], cpu_R[arg[2]]);
2096 } else {
2097 tcg_gen_remu_i32(cpu_R[arg[0]],
2098 cpu_R[arg[1]], cpu_R[arg[2]]);
2099 }
2100 }
2101 }
2102
2103 static void translate_read_impwire(DisasContext *dc, const uint32_t arg[],
2104 const uint32_t par[])
2105 {
2106 if (gen_window_check1(dc, arg[0])) {
2107 /* TODO: GPIO32 may be a part of coprocessor */
2108 tcg_gen_movi_i32(cpu_R[arg[0]], 0);
2109 }
2110 }
2111
2112 static void translate_rer(DisasContext *dc, const uint32_t arg[],
2113 const uint32_t par[])
2114 {
2115 if (gen_check_privilege(dc) &&
2116 gen_window_check2(dc, arg[0], arg[1])) {
2117 gen_helper_rer(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]]);
2118 }
2119 }
2120
2121 static void translate_ret(DisasContext *dc, const uint32_t arg[],
2122 const uint32_t par[])
2123 {
2124 gen_jump(dc, cpu_R[0]);
2125 }
2126
2127 static void translate_retw(DisasContext *dc, const uint32_t arg[],
2128 const uint32_t par[])
2129 {
2130 TCGv_i32 tmp = tcg_const_i32(dc->pc);
2131 gen_helper_retw(tmp, cpu_env, tmp);
2132 gen_jump(dc, tmp);
2133 tcg_temp_free(tmp);
2134 }
2135
2136 static void translate_rfde(DisasContext *dc, const uint32_t arg[],
2137 const uint32_t par[])
2138 {
2139 if (gen_check_privilege(dc)) {
2140 gen_jump(dc, cpu_SR[dc->config->ndepc ? DEPC : EPC1]);
2141 }
2142 }
2143
2144 static void translate_rfe(DisasContext *dc, const uint32_t arg[],
2145 const uint32_t par[])
2146 {
2147 if (gen_check_privilege(dc)) {
2148 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2149 gen_check_interrupts(dc);
2150 gen_jump(dc, cpu_SR[EPC1]);
2151 }
2152 }
2153
2154 static void translate_rfi(DisasContext *dc, const uint32_t arg[],
2155 const uint32_t par[])
2156 {
2157 if (gen_check_privilege(dc)) {
2158 tcg_gen_mov_i32(cpu_SR[PS], cpu_SR[EPS2 + arg[0] - 2]);
2159 gen_check_interrupts(dc);
2160 gen_jump(dc, cpu_SR[EPC1 + arg[0] - 1]);
2161 }
2162 }
2163
2164 static void translate_rfw(DisasContext *dc, const uint32_t arg[],
2165 const uint32_t par[])
2166 {
2167 if (gen_check_privilege(dc)) {
2168 TCGv_i32 tmp = tcg_const_i32(1);
2169
2170 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
2171 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
2172
2173 if (par[0]) {
2174 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
2175 cpu_SR[WINDOW_START], tmp);
2176 } else {
2177 tcg_gen_or_i32(cpu_SR[WINDOW_START],
2178 cpu_SR[WINDOW_START], tmp);
2179 }
2180
2181 gen_helper_restore_owb(cpu_env);
2182 gen_check_interrupts(dc);
2183 gen_jump(dc, cpu_SR[EPC1]);
2184
2185 tcg_temp_free(tmp);
2186 }
2187 }
2188
2189 static void translate_rotw(DisasContext *dc, const uint32_t arg[],
2190 const uint32_t par[])
2191 {
2192 if (gen_check_privilege(dc)) {
2193 TCGv_i32 tmp = tcg_const_i32(arg[0]);
2194 gen_helper_rotw(cpu_env, tmp);
2195 tcg_temp_free(tmp);
2196 /* This can change tb->flags, so exit tb */
2197 gen_jumpi_check_loop_end(dc, -1);
2198 }
2199 }
2200
2201 static void translate_rsil(DisasContext *dc, const uint32_t arg[],
2202 const uint32_t par[])
2203 {
2204 if (gen_check_privilege(dc) &&
2205 gen_window_check1(dc, arg[0])) {
2206 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_SR[PS]);
2207 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
2208 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], arg[1]);
2209 gen_check_interrupts(dc);
2210 gen_jumpi_check_loop_end(dc, 0);
2211 }
2212 }
2213
2214 static void translate_rsr(DisasContext *dc, const uint32_t arg[],
2215 const uint32_t par[])
2216 {
2217 if (gen_check_sr(dc, par[0], SR_R) &&
2218 (par[0] < 64 || gen_check_privilege(dc)) &&
2219 gen_window_check1(dc, arg[0])) {
2220 if (gen_rsr(dc, cpu_R[arg[0]], par[0])) {
2221 gen_jumpi_check_loop_end(dc, 0);
2222 }
2223 }
2224 }
2225
2226 static void translate_rtlb(DisasContext *dc, const uint32_t arg[],
2227 const uint32_t par[])
2228 {
2229 static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1,
2230 TCGv_i32 a2) = {
2231 #ifndef CONFIG_USER_ONLY
2232 gen_helper_rtlb0,
2233 gen_helper_rtlb1,
2234 #endif
2235 };
2236
2237 if (gen_check_privilege(dc) &&
2238 gen_window_check2(dc, arg[0], arg[1])) {
2239 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2240
2241 helper[par[1]](cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb);
2242 tcg_temp_free(dtlb);
2243 }
2244 }
2245
2246 static void translate_rur(DisasContext *dc, const uint32_t arg[],
2247 const uint32_t par[])
2248 {
2249 if (gen_window_check1(dc, arg[0])) {
2250 if (uregnames[par[0]].name) {
2251 tcg_gen_mov_i32(cpu_R[arg[0]], cpu_UR[par[0]]);
2252 } else {
2253 qemu_log_mask(LOG_UNIMP, "RUR %d not implemented\n", par[0]);
2254 }
2255 }
2256 }
2257
2258 static void translate_setb_expstate(DisasContext *dc, const uint32_t arg[],
2259 const uint32_t par[])
2260 {
2261 /* TODO: GPIO32 may be a part of coprocessor */
2262 tcg_gen_ori_i32(cpu_UR[EXPSTATE], cpu_UR[EXPSTATE], 1u << arg[0]);
2263 }
2264
2265 #ifdef CONFIG_USER_ONLY
2266 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2267 {
2268 }
2269 #else
2270 static void gen_check_atomctl(DisasContext *dc, TCGv_i32 addr)
2271 {
2272 TCGv_i32 tpc = tcg_const_i32(dc->pc);
2273
2274 gen_helper_check_atomctl(cpu_env, tpc, addr);
2275 tcg_temp_free(tpc);
2276 }
2277 #endif
2278
2279 static void translate_s32c1i(DisasContext *dc, const uint32_t arg[],
2280 const uint32_t par[])
2281 {
2282 if (gen_window_check2(dc, arg[0], arg[1])) {
2283 TCGv_i32 tmp = tcg_temp_local_new_i32();
2284 TCGv_i32 addr = tcg_temp_local_new_i32();
2285
2286 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
2287 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
2288 gen_load_store_alignment(dc, 2, addr, true);
2289 gen_check_atomctl(dc, addr);
2290 tcg_gen_atomic_cmpxchg_i32(cpu_R[arg[0]], addr, cpu_SR[SCOMPARE1],
2291 tmp, dc->cring, MO_32);
2292 tcg_temp_free(addr);
2293 tcg_temp_free(tmp);
2294 }
2295 }
2296
2297 static void translate_s32e(DisasContext *dc, const uint32_t arg[],
2298 const uint32_t par[])
2299 {
2300 if (gen_check_privilege(dc) &&
2301 gen_window_check2(dc, arg[0], arg[1])) {
2302 TCGv_i32 addr = tcg_temp_new_i32();
2303
2304 tcg_gen_addi_i32(addr, cpu_R[arg[1]], arg[2]);
2305 gen_load_store_alignment(dc, 2, addr, false);
2306 tcg_gen_qemu_st_tl(cpu_R[arg[0]], addr, dc->ring, MO_TEUL);
2307 tcg_temp_free(addr);
2308 }
2309 }
2310
2311 static void translate_salt(DisasContext *dc, const uint32_t arg[],
2312 const uint32_t par[])
2313 {
2314 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2315 tcg_gen_setcond_i32(par[0],
2316 cpu_R[arg[0]],
2317 cpu_R[arg[1]], cpu_R[arg[2]]);
2318 }
2319 }
2320
2321 static void translate_sext(DisasContext *dc, const uint32_t arg[],
2322 const uint32_t par[])
2323 {
2324 if (gen_window_check2(dc, arg[0], arg[1])) {
2325 int shift = 31 - arg[2];
2326
2327 if (shift == 24) {
2328 tcg_gen_ext8s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2329 } else if (shift == 16) {
2330 tcg_gen_ext16s_i32(cpu_R[arg[0]], cpu_R[arg[1]]);
2331 } else {
2332 TCGv_i32 tmp = tcg_temp_new_i32();
2333 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], shift);
2334 tcg_gen_sari_i32(cpu_R[arg[0]], tmp, shift);
2335 tcg_temp_free(tmp);
2336 }
2337 }
2338 }
2339
2340 static void translate_simcall(DisasContext *dc, const uint32_t arg[],
2341 const uint32_t par[])
2342 {
2343 #ifndef CONFIG_USER_ONLY
2344 if (semihosting_enabled()) {
2345 if (gen_check_privilege(dc)) {
2346 gen_helper_simcall(cpu_env);
2347 }
2348 } else
2349 #endif
2350 {
2351 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n");
2352 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2353 }
2354 }
2355
2356 /*
2357 * Note: 64 bit ops are used here solely because SAR values
2358 * have range 0..63
2359 */
2360 #define gen_shift_reg(cmd, reg) do { \
2361 TCGv_i64 tmp = tcg_temp_new_i64(); \
2362 tcg_gen_extu_i32_i64(tmp, reg); \
2363 tcg_gen_##cmd##_i64(v, v, tmp); \
2364 tcg_gen_extrl_i64_i32(cpu_R[arg[0]], v); \
2365 tcg_temp_free_i64(v); \
2366 tcg_temp_free_i64(tmp); \
2367 } while (0)
2368
2369 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
2370
2371 static void translate_sll(DisasContext *dc, const uint32_t arg[],
2372 const uint32_t par[])
2373 {
2374 if (gen_window_check2(dc, arg[0], arg[1])) {
2375 if (dc->sar_m32_5bit) {
2376 tcg_gen_shl_i32(cpu_R[arg[0]], cpu_R[arg[1]], dc->sar_m32);
2377 } else {
2378 TCGv_i64 v = tcg_temp_new_i64();
2379 TCGv_i32 s = tcg_const_i32(32);
2380 tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
2381 tcg_gen_andi_i32(s, s, 0x3f);
2382 tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
2383 gen_shift_reg(shl, s);
2384 tcg_temp_free(s);
2385 }
2386 }
2387 }
2388
2389 static void translate_slli(DisasContext *dc, const uint32_t arg[],
2390 const uint32_t par[])
2391 {
2392 if (gen_window_check2(dc, arg[0], arg[1])) {
2393 if (arg[2] == 32) {
2394 qemu_log_mask(LOG_GUEST_ERROR, "slli a%d, a%d, 32 is undefined\n",
2395 arg[0], arg[1]);
2396 }
2397 tcg_gen_shli_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2] & 0x1f);
2398 }
2399 }
2400
2401 static void translate_sra(DisasContext *dc, const uint32_t arg[],
2402 const uint32_t par[])
2403 {
2404 if (gen_window_check2(dc, arg[0], arg[1])) {
2405 if (dc->sar_m32_5bit) {
2406 tcg_gen_sar_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
2407 } else {
2408 TCGv_i64 v = tcg_temp_new_i64();
2409 tcg_gen_ext_i32_i64(v, cpu_R[arg[1]]);
2410 gen_shift(sar);
2411 }
2412 }
2413 }
2414
2415 static void translate_srai(DisasContext *dc, const uint32_t arg[],
2416 const uint32_t par[])
2417 {
2418 if (gen_window_check2(dc, arg[0], arg[1])) {
2419 tcg_gen_sari_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
2420 }
2421 }
2422
2423 static void translate_src(DisasContext *dc, const uint32_t arg[],
2424 const uint32_t par[])
2425 {
2426 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2427 TCGv_i64 v = tcg_temp_new_i64();
2428 tcg_gen_concat_i32_i64(v, cpu_R[arg[2]], cpu_R[arg[1]]);
2429 gen_shift(shr);
2430 }
2431 }
2432
2433 static void translate_srl(DisasContext *dc, const uint32_t arg[],
2434 const uint32_t par[])
2435 {
2436 if (gen_window_check2(dc, arg[0], arg[1])) {
2437 if (dc->sar_m32_5bit) {
2438 tcg_gen_shr_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_SR[SAR]);
2439 } else {
2440 TCGv_i64 v = tcg_temp_new_i64();
2441 tcg_gen_extu_i32_i64(v, cpu_R[arg[1]]);
2442 gen_shift(shr);
2443 }
2444 }
2445 }
2446
2447 #undef gen_shift
2448 #undef gen_shift_reg
2449
2450 static void translate_srli(DisasContext *dc, const uint32_t arg[],
2451 const uint32_t par[])
2452 {
2453 if (gen_window_check2(dc, arg[0], arg[1])) {
2454 tcg_gen_shri_i32(cpu_R[arg[0]], cpu_R[arg[1]], arg[2]);
2455 }
2456 }
2457
2458 static void translate_ssa8b(DisasContext *dc, const uint32_t arg[],
2459 const uint32_t par[])
2460 {
2461 if (gen_window_check1(dc, arg[0])) {
2462 TCGv_i32 tmp = tcg_temp_new_i32();
2463 tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
2464 gen_left_shift_sar(dc, tmp);
2465 tcg_temp_free(tmp);
2466 }
2467 }
2468
2469 static void translate_ssa8l(DisasContext *dc, const uint32_t arg[],
2470 const uint32_t par[])
2471 {
2472 if (gen_window_check1(dc, arg[0])) {
2473 TCGv_i32 tmp = tcg_temp_new_i32();
2474 tcg_gen_shli_i32(tmp, cpu_R[arg[0]], 3);
2475 gen_right_shift_sar(dc, tmp);
2476 tcg_temp_free(tmp);
2477 }
2478 }
2479
2480 static void translate_ssai(DisasContext *dc, const uint32_t arg[],
2481 const uint32_t par[])
2482 {
2483 TCGv_i32 tmp = tcg_const_i32(arg[0]);
2484 gen_right_shift_sar(dc, tmp);
2485 tcg_temp_free(tmp);
2486 }
2487
2488 static void translate_ssl(DisasContext *dc, const uint32_t arg[],
2489 const uint32_t par[])
2490 {
2491 if (gen_window_check1(dc, arg[0])) {
2492 gen_left_shift_sar(dc, cpu_R[arg[0]]);
2493 }
2494 }
2495
2496 static void translate_ssr(DisasContext *dc, const uint32_t arg[],
2497 const uint32_t par[])
2498 {
2499 if (gen_window_check1(dc, arg[0])) {
2500 gen_right_shift_sar(dc, cpu_R[arg[0]]);
2501 }
2502 }
2503
2504 static void translate_sub(DisasContext *dc, const uint32_t arg[],
2505 const uint32_t par[])
2506 {
2507 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2508 tcg_gen_sub_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2509 }
2510 }
2511
2512 static void translate_subx(DisasContext *dc, const uint32_t arg[],
2513 const uint32_t par[])
2514 {
2515 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2516 TCGv_i32 tmp = tcg_temp_new_i32();
2517 tcg_gen_shli_i32(tmp, cpu_R[arg[1]], par[0]);
2518 tcg_gen_sub_i32(cpu_R[arg[0]], tmp, cpu_R[arg[2]]);
2519 tcg_temp_free(tmp);
2520 }
2521 }
2522
2523 static void translate_syscall(DisasContext *dc, const uint32_t arg[],
2524 const uint32_t par[])
2525 {
2526 gen_exception_cause(dc, SYSCALL_CAUSE);
2527 }
2528
2529 static void translate_waiti(DisasContext *dc, const uint32_t arg[],
2530 const uint32_t par[])
2531 {
2532 if (gen_check_privilege(dc)) {
2533 #ifndef CONFIG_USER_ONLY
2534 gen_waiti(dc, arg[0]);
2535 #endif
2536 }
2537 }
2538
2539 static void translate_wtlb(DisasContext *dc, const uint32_t arg[],
2540 const uint32_t par[])
2541 {
2542 if (gen_check_privilege(dc) &&
2543 gen_window_check2(dc, arg[0], arg[1])) {
2544 #ifndef CONFIG_USER_ONLY
2545 TCGv_i32 dtlb = tcg_const_i32(par[0]);
2546
2547 gen_helper_wtlb(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]], dtlb);
2548 /* This could change memory mapping, so exit tb */
2549 gen_jumpi_check_loop_end(dc, -1);
2550 tcg_temp_free(dtlb);
2551 #endif
2552 }
2553 }
2554
2555 static void translate_wer(DisasContext *dc, const uint32_t arg[],
2556 const uint32_t par[])
2557 {
2558 if (gen_check_privilege(dc) &&
2559 gen_window_check2(dc, arg[0], arg[1])) {
2560 gen_helper_wer(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]]);
2561 }
2562 }
2563
2564 static void translate_wrmsk_expstate(DisasContext *dc, const uint32_t arg[],
2565 const uint32_t par[])
2566 {
2567 if (gen_window_check2(dc, arg[0], arg[1])) {
2568 /* TODO: GPIO32 may be a part of coprocessor */
2569 tcg_gen_and_i32(cpu_UR[EXPSTATE], cpu_R[arg[0]], cpu_R[arg[1]]);
2570 }
2571 }
2572
2573 static void translate_wsr(DisasContext *dc, const uint32_t arg[],
2574 const uint32_t par[])
2575 {
2576 if (gen_check_sr(dc, par[0], SR_W) &&
2577 (par[0] < 64 || gen_check_privilege(dc)) &&
2578 gen_window_check1(dc, arg[0])) {
2579 gen_wsr(dc, par[0], cpu_R[arg[0]]);
2580 }
2581 }
2582
2583 static void translate_wur(DisasContext *dc, const uint32_t arg[],
2584 const uint32_t par[])
2585 {
2586 if (gen_window_check1(dc, arg[0])) {
2587 if (uregnames[par[0]].name) {
2588 gen_wur(par[0], cpu_R[arg[0]]);
2589 } else {
2590 qemu_log_mask(LOG_UNIMP, "WUR %d not implemented\n", par[0]);
2591 }
2592 }
2593 }
2594
2595 static void translate_xor(DisasContext *dc, const uint32_t arg[],
2596 const uint32_t par[])
2597 {
2598 if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
2599 tcg_gen_xor_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
2600 }
2601 }
2602
2603 static void translate_xsr(DisasContext *dc, const uint32_t arg[],
2604 const uint32_t par[])
2605 {
2606 if (gen_check_sr(dc, par[0], SR_X) &&
2607 (par[0] < 64 || gen_check_privilege(dc)) &&
2608 gen_window_check1(dc, arg[0])) {
2609 TCGv_i32 tmp = tcg_temp_new_i32();
2610 bool rsr_end, wsr_end;
2611
2612 tcg_gen_mov_i32(tmp, cpu_R[arg[0]]);
2613 rsr_end = gen_rsr(dc, cpu_R[arg[0]], par[0]);
2614 wsr_end = gen_wsr(dc, par[0], tmp);
2615 tcg_temp_free(tmp);
2616 if (rsr_end && !wsr_end) {
2617 gen_jumpi_check_loop_end(dc, 0);
2618 }
2619 }
2620 }
2621
2622 static const XtensaOpcodeOps core_ops[] = {
2623 {
2624 .name = "abs",
2625 .translate = translate_abs,
2626 }, {
2627 .name = "add",
2628 .translate = translate_add,
2629 }, {
2630 .name = "add.n",
2631 .translate = translate_add,
2632 }, {
2633 .name = "addi",
2634 .translate = translate_addi,
2635 }, {
2636 .name = "addi.n",
2637 .translate = translate_addi,
2638 }, {
2639 .name = "addmi",
2640 .translate = translate_addi,
2641 }, {
2642 .name = "addx2",
2643 .translate = translate_addx,
2644 .par = (const uint32_t[]){1},
2645 }, {
2646 .name = "addx4",
2647 .translate = translate_addx,
2648 .par = (const uint32_t[]){2},
2649 }, {
2650 .name = "addx8",
2651 .translate = translate_addx,
2652 .par = (const uint32_t[]){3},
2653 }, {
2654 .name = "all4",
2655 .translate = translate_all,
2656 .par = (const uint32_t[]){true, 4},
2657 }, {
2658 .name = "all8",
2659 .translate = translate_all,
2660 .par = (const uint32_t[]){true, 8},
2661 }, {
2662 .name = "and",
2663 .translate = translate_and,
2664 }, {
2665 .name = "andb",
2666 .translate = translate_boolean,
2667 .par = (const uint32_t[]){BOOLEAN_AND},
2668 }, {
2669 .name = "andbc",
2670 .translate = translate_boolean,
2671 .par = (const uint32_t[]){BOOLEAN_ANDC},
2672 }, {
2673 .name = "any4",
2674 .translate = translate_all,
2675 .par = (const uint32_t[]){false, 4},
2676 }, {
2677 .name = "any8",
2678 .translate = translate_all,
2679 .par = (const uint32_t[]){false, 8},
2680 }, {
2681 .name = "ball",
2682 .translate = translate_ball,
2683 .par = (const uint32_t[]){TCG_COND_EQ},
2684 }, {
2685 .name = "bany",
2686 .translate = translate_bany,
2687 .par = (const uint32_t[]){TCG_COND_NE},
2688 }, {
2689 .name = "bbc",
2690 .translate = translate_bb,
2691 .par = (const uint32_t[]){TCG_COND_EQ},
2692 }, {
2693 .name = "bbci",
2694 .translate = translate_bbi,
2695 .par = (const uint32_t[]){TCG_COND_EQ},
2696 }, {
2697 .name = "bbs",
2698 .translate = translate_bb,
2699 .par = (const uint32_t[]){TCG_COND_NE},
2700 }, {
2701 .name = "bbsi",
2702 .translate = translate_bbi,
2703 .par = (const uint32_t[]){TCG_COND_NE},
2704 }, {
2705 .name = "beq",
2706 .translate = translate_b,
2707 .par = (const uint32_t[]){TCG_COND_EQ},
2708 }, {
2709 .name = "beqi",
2710 .translate = translate_bi,
2711 .par = (const uint32_t[]){TCG_COND_EQ},
2712 }, {
2713 .name = "beqz",
2714 .translate = translate_bz,
2715 .par = (const uint32_t[]){TCG_COND_EQ},
2716 }, {
2717 .name = "beqz.n",
2718 .translate = translate_bz,
2719 .par = (const uint32_t[]){TCG_COND_EQ},
2720 }, {
2721 .name = "bf",
2722 .translate = translate_bp,
2723 .par = (const uint32_t[]){TCG_COND_EQ},
2724 }, {
2725 .name = "bge",
2726 .translate = translate_b,
2727 .par = (const uint32_t[]){TCG_COND_GE},
2728 }, {
2729 .name = "bgei",
2730 .translate = translate_bi,
2731 .par = (const uint32_t[]){TCG_COND_GE},
2732 }, {
2733 .name = "bgeu",
2734 .translate = translate_b,
2735 .par = (const uint32_t[]){TCG_COND_GEU},
2736 }, {
2737 .name = "bgeui",
2738 .translate = translate_bi,
2739 .par = (const uint32_t[]){TCG_COND_GEU},
2740 }, {
2741 .name = "bgez",
2742 .translate = translate_bz,
2743 .par = (const uint32_t[]){TCG_COND_GE},
2744 }, {
2745 .name = "blt",
2746 .translate = translate_b,
2747 .par = (const uint32_t[]){TCG_COND_LT},
2748 }, {
2749 .name = "blti",
2750 .translate = translate_bi,
2751 .par = (const uint32_t[]){TCG_COND_LT},
2752 }, {
2753 .name = "bltu",
2754 .translate = translate_b,
2755 .par = (const uint32_t[]){TCG_COND_LTU},
2756 }, {
2757 .name = "bltui",
2758 .translate = translate_bi,
2759 .par = (const uint32_t[]){TCG_COND_LTU},
2760 }, {
2761 .name = "bltz",
2762 .translate = translate_bz,
2763 .par = (const uint32_t[]){TCG_COND_LT},
2764 }, {
2765 .name = "bnall",
2766 .translate = translate_ball,
2767 .par = (const uint32_t[]){TCG_COND_NE},
2768 }, {
2769 .name = "bne",
2770 .translate = translate_b,
2771 .par = (const uint32_t[]){TCG_COND_NE},
2772 }, {
2773 .name = "bnei",
2774 .translate = translate_bi,
2775 .par = (const uint32_t[]){TCG_COND_NE},
2776 }, {
2777 .name = "bnez",
2778 .translate = translate_bz,
2779 .par = (const uint32_t[]){TCG_COND_NE},
2780 }, {
2781 .name = "bnez.n",
2782 .translate = translate_bz,
2783 .par = (const uint32_t[]){TCG_COND_NE},
2784 }, {
2785 .name = "bnone",
2786 .translate = translate_bany,
2787 .par = (const uint32_t[]){TCG_COND_EQ},
2788 }, {
2789 .name = "break",
2790 .translate = translate_break,
2791 .par = (const uint32_t[]){DEBUGCAUSE_BI},
2792 }, {
2793 .name = "break.n",
2794 .translate = translate_break,
2795 .par = (const uint32_t[]){DEBUGCAUSE_BN},
2796 }, {
2797 .name = "bt",
2798 .translate = translate_bp,
2799 .par = (const uint32_t[]){TCG_COND_NE},
2800 }, {
2801 .name = "call0",
2802 .translate = translate_call0,
2803 }, {
2804 .name = "call12",
2805 .translate = translate_callw,
2806 .par = (const uint32_t[]){3},
2807 }, {
2808 .name = "call4",
2809 .translate = translate_callw,
2810 .par = (const uint32_t[]){1},
2811 }, {
2812 .name = "call8",
2813 .translate = translate_callw,
2814 .par = (const uint32_t[]){2},
2815 }, {
2816 .name = "callx0",
2817 .translate = translate_callx0,
2818 }, {
2819 .name = "callx12",
2820 .translate = translate_callxw,
2821 .par = (const uint32_t[]){3},
2822 }, {
2823 .name = "callx4",
2824 .translate = translate_callxw,
2825 .par = (const uint32_t[]){1},
2826 }, {
2827 .name = "callx8",
2828 .translate = translate_callxw,
2829 .par = (const uint32_t[]){2},
2830 }, {
2831 .name = "clamps",
2832 .translate = translate_clamps,
2833 }, {
2834 .name = "clrb_expstate",
2835 .translate = translate_clrb_expstate,
2836 }, {
2837 .name = "const16",
2838 .translate = translate_const16,
2839 }, {
2840 .name = "depbits",
2841 .translate = translate_depbits,
2842 }, {
2843 .name = "dhi",
2844 .translate = translate_dcache,
2845 .par = (const uint32_t[]){true, true},
2846 }, {
2847 .name = "dhu",
2848 .translate = translate_dcache,
2849 .par = (const uint32_t[]){true, true},
2850 }, {
2851 .name = "dhwb",
2852 .translate = translate_dcache,
2853 .par = (const uint32_t[]){false, true},
2854 }, {
2855 .name = "dhwbi",
2856 .translate = translate_dcache,
2857 .par = (const uint32_t[]){false, true},
2858 }, {
2859 .name = "dii",
2860 .translate = translate_dcache,
2861 .par = (const uint32_t[]){true, false},
2862 }, {
2863 .name = "diu",
2864 .translate = translate_dcache,
2865 .par = (const uint32_t[]){true, false},
2866 }, {
2867 .name = "diwb",
2868 .translate = translate_dcache,
2869 .par = (const uint32_t[]){true, false},
2870 }, {
2871 .name = "diwbi",
2872 .translate = translate_dcache,
2873 .par = (const uint32_t[]){true, false},
2874 }, {
2875 .name = "dpfl",
2876 .translate = translate_dcache,
2877 .par = (const uint32_t[]){true, true},
2878 }, {
2879 .name = "dpfr",
2880 .translate = translate_dcache,
2881 .par = (const uint32_t[]){false, false},
2882 }, {
2883 .name = "dpfro",
2884 .translate = translate_dcache,
2885 .par = (const uint32_t[]){false, false},
2886 }, {
2887 .name = "dpfw",
2888 .translate = translate_dcache,
2889 .par = (const uint32_t[]){false, false},
2890 }, {
2891 .name = "dpfwo",
2892 .translate = translate_dcache,
2893 .par = (const uint32_t[]){false, false},
2894 }, {
2895 .name = "dsync",
2896 .translate = translate_nop,
2897 }, {
2898 .name = "entry",
2899 .translate = translate_entry,
2900 }, {
2901 .name = "esync",
2902 .translate = translate_nop,
2903 }, {
2904 .name = "excw",
2905 .translate = translate_nop,
2906 }, {
2907 .name = "extui",
2908 .translate = translate_extui,
2909 }, {
2910 .name = "extw",
2911 .translate = translate_memw,
2912 }, {
2913 .name = "hwwdtlba",
2914 .translate = translate_ill,
2915 }, {
2916 .name = "hwwitlba",
2917 .translate = translate_ill,
2918 }, {
2919 .name = "idtlb",
2920 .translate = translate_itlb,
2921 .par = (const uint32_t[]){true},
2922 }, {
2923 .name = "ihi",
2924 .translate = translate_icache,
2925 .par = (const uint32_t[]){false, true},
2926 }, {
2927 .name = "ihu",
2928 .translate = translate_icache,
2929 .par = (const uint32_t[]){true, true},
2930 }, {
2931 .name = "iii",
2932 .translate = translate_icache,
2933 .par = (const uint32_t[]){true, false},
2934 }, {
2935 .name = "iitlb",
2936 .translate = translate_itlb,
2937 .par = (const uint32_t[]){false},
2938 }, {
2939 .name = "iiu",
2940 .translate = translate_icache,
2941 .par = (const uint32_t[]){true, false},
2942 }, {
2943 .name = "ill",
2944 .translate = translate_ill,
2945 }, {
2946 .name = "ill.n",
2947 .translate = translate_ill,
2948 }, {
2949 .name = "ipf",
2950 .translate = translate_icache,
2951 .par = (const uint32_t[]){false, false},
2952 }, {
2953 .name = "ipfl",
2954 .translate = translate_icache,
2955 .par = (const uint32_t[]){true, true},
2956 }, {
2957 .name = "isync",
2958 .translate = translate_nop,
2959 }, {
2960 .name = "j",
2961 .translate = translate_j,
2962 }, {
2963 .name = "jx",
2964 .translate = translate_jx,
2965 }, {
2966 .name = "l16si",
2967 .translate = translate_ldst,
2968 .par = (const uint32_t[]){MO_TESW, false, false},
2969 }, {
2970 .name = "l16ui",
2971 .translate = translate_ldst,
2972 .par = (const uint32_t[]){MO_TEUW, false, false},
2973 }, {
2974 .name = "l32ai",
2975 .translate = translate_ldst,
2976 .par = (const uint32_t[]){MO_TEUL, true, false},
2977 }, {
2978 .name = "l32e",
2979 .translate = translate_l32e,
2980 }, {
2981 .name = "l32i",
2982 .translate = translate_ldst,
2983 .par = (const uint32_t[]){MO_TEUL, false, false},
2984 }, {
2985 .name = "l32i.n",
2986 .translate = translate_ldst,
2987 .par = (const uint32_t[]){MO_TEUL, false, false},
2988 }, {
2989 .name = "l32r",
2990 .translate = translate_l32r,
2991 }, {
2992 .name = "l8ui",
2993 .translate = translate_ldst,
2994 .par = (const uint32_t[]){MO_UB, false, false},
2995 }, {
2996 .name = "lddec",
2997 .translate = translate_mac16,
2998 .par = (const uint32_t[]){MAC16_NONE, 0, 0, -4},
2999 }, {
3000 .name = "ldinc",
3001 .translate = translate_mac16,
3002 .par = (const uint32_t[]){MAC16_NONE, 0, 0, 4},
3003 }, {
3004 .name = "ldpte",
3005 .translate = translate_ill,
3006 }, {
3007 .name = "loop",
3008 .translate = translate_loop,
3009 .par = (const uint32_t[]){TCG_COND_NEVER},
3010 }, {
3011 .name = "loopgtz",
3012 .translate = translate_loop,
3013 .par = (const uint32_t[]){TCG_COND_GT},
3014 }, {
3015 .name = "loopnez",
3016 .translate = translate_loop,
3017 .par = (const uint32_t[]){TCG_COND_NE},
3018 }, {
3019 .name = "max",
3020 .translate = translate_smax,
3021 }, {
3022 .name = "maxu",
3023 .translate = translate_umax,
3024 }, {
3025 .name = "memw",
3026 .translate = translate_memw,
3027 }, {
3028 .name = "min",
3029 .translate = translate_smin,
3030 }, {
3031 .name = "minu",
3032 .translate = translate_umin,
3033 }, {
3034 .name = "mov",
3035 .translate = translate_mov,
3036 }, {
3037 .name = "mov.n",
3038 .translate = translate_mov,
3039 }, {
3040 .name = "moveqz",
3041 .translate = translate_movcond,
3042 .par = (const uint32_t[]){TCG_COND_EQ},
3043 }, {
3044 .name = "movf",
3045 .translate = translate_movp,
3046 .par = (const uint32_t[]){TCG_COND_EQ},
3047 }, {
3048 .name = "movgez",
3049 .translate = translate_movcond,
3050 .par = (const uint32_t[]){TCG_COND_GE},
3051 }, {
3052 .name = "movi",
3053 .translate = translate_movi,
3054 }, {
3055 .name = "movi.n",
3056 .translate = translate_movi,
3057 }, {
3058 .name = "movltz",
3059 .translate = translate_movcond,
3060 .par = (const uint32_t[]){TCG_COND_LT},
3061 }, {
3062 .name = "movnez",
3063 .translate = translate_movcond,