]> git.proxmox.com Git - qemu.git/blob - target-xtensa/translate.c
Version 1.0.1
[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 <stdio.h>
32
33 #include "cpu.h"
34 #include "exec-all.h"
35 #include "disas.h"
36 #include "tcg-op.h"
37 #include "qemu-log.h"
38 #include "sysemu.h"
39
40 #include "helpers.h"
41 #define GEN_HELPER 1
42 #include "helpers.h"
43
44 typedef struct DisasContext {
45 const XtensaConfig *config;
46 TranslationBlock *tb;
47 uint32_t pc;
48 uint32_t next_pc;
49 int cring;
50 int ring;
51 uint32_t lbeg;
52 uint32_t lend;
53 TCGv_i32 litbase;
54 int is_jmp;
55 int singlestep_enabled;
56
57 bool sar_5bit;
58 bool sar_m32_5bit;
59 bool sar_m32_allocated;
60 TCGv_i32 sar_m32;
61
62 uint32_t ccount_delta;
63 unsigned used_window;
64 } DisasContext;
65
66 static TCGv_ptr cpu_env;
67 static TCGv_i32 cpu_pc;
68 static TCGv_i32 cpu_R[16];
69 static TCGv_i32 cpu_SR[256];
70 static TCGv_i32 cpu_UR[256];
71
72 #include "gen-icount.h"
73
74 static const char * const sregnames[256] = {
75 [LBEG] = "LBEG",
76 [LEND] = "LEND",
77 [LCOUNT] = "LCOUNT",
78 [SAR] = "SAR",
79 [BR] = "BR",
80 [LITBASE] = "LITBASE",
81 [SCOMPARE1] = "SCOMPARE1",
82 [ACCLO] = "ACCLO",
83 [ACCHI] = "ACCHI",
84 [MR] = "MR0",
85 [MR + 1] = "MR1",
86 [MR + 2] = "MR2",
87 [MR + 3] = "MR3",
88 [WINDOW_BASE] = "WINDOW_BASE",
89 [WINDOW_START] = "WINDOW_START",
90 [PTEVADDR] = "PTEVADDR",
91 [RASID] = "RASID",
92 [ITLBCFG] = "ITLBCFG",
93 [DTLBCFG] = "DTLBCFG",
94 [EPC1] = "EPC1",
95 [EPC1 + 1] = "EPC2",
96 [EPC1 + 2] = "EPC3",
97 [EPC1 + 3] = "EPC4",
98 [EPC1 + 4] = "EPC5",
99 [EPC1 + 5] = "EPC6",
100 [EPC1 + 6] = "EPC7",
101 [DEPC] = "DEPC",
102 [EPS2] = "EPS2",
103 [EPS2 + 1] = "EPS3",
104 [EPS2 + 2] = "EPS4",
105 [EPS2 + 3] = "EPS5",
106 [EPS2 + 4] = "EPS6",
107 [EPS2 + 5] = "EPS7",
108 [EXCSAVE1] = "EXCSAVE1",
109 [EXCSAVE1 + 1] = "EXCSAVE2",
110 [EXCSAVE1 + 2] = "EXCSAVE3",
111 [EXCSAVE1 + 3] = "EXCSAVE4",
112 [EXCSAVE1 + 4] = "EXCSAVE5",
113 [EXCSAVE1 + 5] = "EXCSAVE6",
114 [EXCSAVE1 + 6] = "EXCSAVE7",
115 [CPENABLE] = "CPENABLE",
116 [INTSET] = "INTSET",
117 [INTCLEAR] = "INTCLEAR",
118 [INTENABLE] = "INTENABLE",
119 [PS] = "PS",
120 [VECBASE] = "VECBASE",
121 [EXCCAUSE] = "EXCCAUSE",
122 [CCOUNT] = "CCOUNT",
123 [PRID] = "PRID",
124 [EXCVADDR] = "EXCVADDR",
125 [CCOMPARE] = "CCOMPARE0",
126 [CCOMPARE + 1] = "CCOMPARE1",
127 [CCOMPARE + 2] = "CCOMPARE2",
128 };
129
130 static const char * const uregnames[256] = {
131 [THREADPTR] = "THREADPTR",
132 [FCR] = "FCR",
133 [FSR] = "FSR",
134 };
135
136 void xtensa_translate_init(void)
137 {
138 static const char * const regnames[] = {
139 "ar0", "ar1", "ar2", "ar3",
140 "ar4", "ar5", "ar6", "ar7",
141 "ar8", "ar9", "ar10", "ar11",
142 "ar12", "ar13", "ar14", "ar15",
143 };
144 int i;
145
146 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
147 cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
148 offsetof(CPUState, pc), "pc");
149
150 for (i = 0; i < 16; i++) {
151 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
152 offsetof(CPUState, regs[i]),
153 regnames[i]);
154 }
155
156 for (i = 0; i < 256; ++i) {
157 if (sregnames[i]) {
158 cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
159 offsetof(CPUState, sregs[i]),
160 sregnames[i]);
161 }
162 }
163
164 for (i = 0; i < 256; ++i) {
165 if (uregnames[i]) {
166 cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
167 offsetof(CPUState, uregs[i]),
168 uregnames[i]);
169 }
170 }
171 #define GEN_HELPER 2
172 #include "helpers.h"
173 }
174
175 static inline bool option_bits_enabled(DisasContext *dc, uint64_t opt)
176 {
177 return xtensa_option_bits_enabled(dc->config, opt);
178 }
179
180 static inline bool option_enabled(DisasContext *dc, int opt)
181 {
182 return xtensa_option_enabled(dc->config, opt);
183 }
184
185 static void init_litbase(DisasContext *dc)
186 {
187 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
188 dc->litbase = tcg_temp_local_new_i32();
189 tcg_gen_andi_i32(dc->litbase, cpu_SR[LITBASE], 0xfffff000);
190 }
191 }
192
193 static void reset_litbase(DisasContext *dc)
194 {
195 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
196 tcg_temp_free(dc->litbase);
197 }
198 }
199
200 static void init_sar_tracker(DisasContext *dc)
201 {
202 dc->sar_5bit = false;
203 dc->sar_m32_5bit = false;
204 dc->sar_m32_allocated = false;
205 }
206
207 static void reset_sar_tracker(DisasContext *dc)
208 {
209 if (dc->sar_m32_allocated) {
210 tcg_temp_free(dc->sar_m32);
211 }
212 }
213
214 static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
215 {
216 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
217 if (dc->sar_m32_5bit) {
218 tcg_gen_discard_i32(dc->sar_m32);
219 }
220 dc->sar_5bit = true;
221 dc->sar_m32_5bit = false;
222 }
223
224 static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
225 {
226 TCGv_i32 tmp = tcg_const_i32(32);
227 if (!dc->sar_m32_allocated) {
228 dc->sar_m32 = tcg_temp_local_new_i32();
229 dc->sar_m32_allocated = true;
230 }
231 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
232 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
233 dc->sar_5bit = false;
234 dc->sar_m32_5bit = true;
235 tcg_temp_free(tmp);
236 }
237
238 static void gen_advance_ccount(DisasContext *dc)
239 {
240 if (dc->ccount_delta > 0) {
241 TCGv_i32 tmp = tcg_const_i32(dc->ccount_delta);
242 dc->ccount_delta = 0;
243 gen_helper_advance_ccount(tmp);
244 tcg_temp_free(tmp);
245 }
246 }
247
248 static void reset_used_window(DisasContext *dc)
249 {
250 dc->used_window = 0;
251 }
252
253 static void gen_exception(DisasContext *dc, int excp)
254 {
255 TCGv_i32 tmp = tcg_const_i32(excp);
256 gen_advance_ccount(dc);
257 gen_helper_exception(tmp);
258 tcg_temp_free(tmp);
259 }
260
261 static void gen_exception_cause(DisasContext *dc, uint32_t cause)
262 {
263 TCGv_i32 tpc = tcg_const_i32(dc->pc);
264 TCGv_i32 tcause = tcg_const_i32(cause);
265 gen_advance_ccount(dc);
266 gen_helper_exception_cause(tpc, tcause);
267 tcg_temp_free(tpc);
268 tcg_temp_free(tcause);
269 if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
270 cause == SYSCALL_CAUSE) {
271 dc->is_jmp = DISAS_UPDATE;
272 }
273 }
274
275 static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
276 TCGv_i32 vaddr)
277 {
278 TCGv_i32 tpc = tcg_const_i32(dc->pc);
279 TCGv_i32 tcause = tcg_const_i32(cause);
280 gen_advance_ccount(dc);
281 gen_helper_exception_cause_vaddr(tpc, tcause, vaddr);
282 tcg_temp_free(tpc);
283 tcg_temp_free(tcause);
284 }
285
286 static void gen_check_privilege(DisasContext *dc)
287 {
288 if (dc->cring) {
289 gen_exception_cause(dc, PRIVILEGED_CAUSE);
290 dc->is_jmp = DISAS_UPDATE;
291 }
292 }
293
294 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
295 {
296 tcg_gen_mov_i32(cpu_pc, dest);
297 if (dc->singlestep_enabled) {
298 gen_exception(dc, EXCP_DEBUG);
299 } else {
300 gen_advance_ccount(dc);
301 if (slot >= 0) {
302 tcg_gen_goto_tb(slot);
303 tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
304 } else {
305 tcg_gen_exit_tb(0);
306 }
307 }
308 dc->is_jmp = DISAS_UPDATE;
309 }
310
311 static void gen_jump(DisasContext *dc, TCGv dest)
312 {
313 gen_jump_slot(dc, dest, -1);
314 }
315
316 static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
317 {
318 TCGv_i32 tmp = tcg_const_i32(dest);
319 if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
320 slot = -1;
321 }
322 gen_jump_slot(dc, tmp, slot);
323 tcg_temp_free(tmp);
324 }
325
326 static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
327 int slot)
328 {
329 TCGv_i32 tcallinc = tcg_const_i32(callinc);
330
331 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
332 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
333 tcg_temp_free(tcallinc);
334 tcg_gen_movi_i32(cpu_R[callinc << 2],
335 (callinc << 30) | (dc->next_pc & 0x3fffffff));
336 gen_jump_slot(dc, dest, slot);
337 }
338
339 static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
340 {
341 gen_callw_slot(dc, callinc, dest, -1);
342 }
343
344 static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
345 {
346 TCGv_i32 tmp = tcg_const_i32(dest);
347 if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
348 slot = -1;
349 }
350 gen_callw_slot(dc, callinc, tmp, slot);
351 tcg_temp_free(tmp);
352 }
353
354 static bool gen_check_loop_end(DisasContext *dc, int slot)
355 {
356 if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
357 !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&
358 dc->next_pc == dc->lend) {
359 int label = gen_new_label();
360
361 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
362 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
363 gen_jumpi(dc, dc->lbeg, slot);
364 gen_set_label(label);
365 gen_jumpi(dc, dc->next_pc, -1);
366 return true;
367 }
368 return false;
369 }
370
371 static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
372 {
373 if (!gen_check_loop_end(dc, slot)) {
374 gen_jumpi(dc, dc->next_pc, slot);
375 }
376 }
377
378 static void gen_brcond(DisasContext *dc, TCGCond cond,
379 TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)
380 {
381 int label = gen_new_label();
382
383 tcg_gen_brcond_i32(cond, t0, t1, label);
384 gen_jumpi_check_loop_end(dc, 0);
385 gen_set_label(label);
386 gen_jumpi(dc, dc->pc + offset, 1);
387 }
388
389 static void gen_brcondi(DisasContext *dc, TCGCond cond,
390 TCGv_i32 t0, uint32_t t1, uint32_t offset)
391 {
392 TCGv_i32 tmp = tcg_const_i32(t1);
393 gen_brcond(dc, cond, t0, tmp, offset);
394 tcg_temp_free(tmp);
395 }
396
397 static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
398 {
399 gen_advance_ccount(dc);
400 tcg_gen_mov_i32(d, cpu_SR[sr]);
401 }
402
403 static void gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
404 {
405 tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10);
406 tcg_gen_or_i32(d, d, cpu_SR[sr]);
407 tcg_gen_andi_i32(d, d, 0xfffffffc);
408 }
409
410 static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
411 {
412 static void (* const rsr_handler[256])(DisasContext *dc,
413 TCGv_i32 d, uint32_t sr) = {
414 [CCOUNT] = gen_rsr_ccount,
415 [PTEVADDR] = gen_rsr_ptevaddr,
416 };
417
418 if (sregnames[sr]) {
419 if (rsr_handler[sr]) {
420 rsr_handler[sr](dc, d, sr);
421 } else {
422 tcg_gen_mov_i32(d, cpu_SR[sr]);
423 }
424 } else {
425 qemu_log("RSR %d not implemented, ", sr);
426 }
427 }
428
429 static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
430 {
431 gen_helper_wsr_lbeg(s);
432 }
433
434 static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
435 {
436 gen_helper_wsr_lend(s);
437 }
438
439 static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
440 {
441 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
442 if (dc->sar_m32_5bit) {
443 tcg_gen_discard_i32(dc->sar_m32);
444 }
445 dc->sar_5bit = false;
446 dc->sar_m32_5bit = false;
447 }
448
449 static void gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
450 {
451 tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
452 }
453
454 static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
455 {
456 tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
457 /* This can change tb->flags, so exit tb */
458 gen_jumpi_check_loop_end(dc, -1);
459 }
460
461 static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
462 {
463 tcg_gen_ext8s_i32(cpu_SR[sr], s);
464 }
465
466 static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
467 {
468 gen_helper_wsr_windowbase(v);
469 reset_used_window(dc);
470 }
471
472 static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
473 {
474 tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1);
475 reset_used_window(dc);
476 }
477
478 static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
479 {
480 tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
481 }
482
483 static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
484 {
485 gen_helper_wsr_rasid(v);
486 /* This can change tb->flags, so exit tb */
487 gen_jumpi_check_loop_end(dc, -1);
488 }
489
490 static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
491 {
492 tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
493 }
494
495 static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
496 {
497 tcg_gen_andi_i32(cpu_SR[sr], v,
498 dc->config->inttype_mask[INTTYPE_SOFTWARE]);
499 gen_helper_check_interrupts(cpu_env);
500 gen_jumpi_check_loop_end(dc, 0);
501 }
502
503 static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
504 {
505 TCGv_i32 tmp = tcg_temp_new_i32();
506
507 tcg_gen_andi_i32(tmp, v,
508 dc->config->inttype_mask[INTTYPE_EDGE] |
509 dc->config->inttype_mask[INTTYPE_NMI] |
510 dc->config->inttype_mask[INTTYPE_SOFTWARE]);
511 tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp);
512 tcg_temp_free(tmp);
513 gen_helper_check_interrupts(cpu_env);
514 }
515
516 static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
517 {
518 tcg_gen_mov_i32(cpu_SR[sr], v);
519 gen_helper_check_interrupts(cpu_env);
520 gen_jumpi_check_loop_end(dc, 0);
521 }
522
523 static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
524 {
525 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
526 PS_UM | PS_EXCM | PS_INTLEVEL;
527
528 if (option_enabled(dc, XTENSA_OPTION_MMU)) {
529 mask |= PS_RING;
530 }
531 tcg_gen_andi_i32(cpu_SR[sr], v, mask);
532 reset_used_window(dc);
533 gen_helper_check_interrupts(cpu_env);
534 /* This can change mmu index and tb->flags, so exit tb */
535 gen_jumpi_check_loop_end(dc, -1);
536 }
537
538 static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
539 {
540 }
541
542 static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
543 {
544 uint32_t id = sr - CCOMPARE;
545 if (id < dc->config->nccompare) {
546 uint32_t int_bit = 1 << dc->config->timerint[id];
547 gen_advance_ccount(dc);
548 tcg_gen_mov_i32(cpu_SR[sr], v);
549 tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);
550 gen_helper_check_interrupts(cpu_env);
551 }
552 }
553
554 static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
555 {
556 static void (* const wsr_handler[256])(DisasContext *dc,
557 uint32_t sr, TCGv_i32 v) = {
558 [LBEG] = gen_wsr_lbeg,
559 [LEND] = gen_wsr_lend,
560 [SAR] = gen_wsr_sar,
561 [BR] = gen_wsr_br,
562 [LITBASE] = gen_wsr_litbase,
563 [ACCHI] = gen_wsr_acchi,
564 [WINDOW_BASE] = gen_wsr_windowbase,
565 [WINDOW_START] = gen_wsr_windowstart,
566 [PTEVADDR] = gen_wsr_ptevaddr,
567 [RASID] = gen_wsr_rasid,
568 [ITLBCFG] = gen_wsr_tlbcfg,
569 [DTLBCFG] = gen_wsr_tlbcfg,
570 [INTSET] = gen_wsr_intset,
571 [INTCLEAR] = gen_wsr_intclear,
572 [INTENABLE] = gen_wsr_intenable,
573 [PS] = gen_wsr_ps,
574 [PRID] = gen_wsr_prid,
575 [CCOMPARE] = gen_wsr_ccompare,
576 [CCOMPARE + 1] = gen_wsr_ccompare,
577 [CCOMPARE + 2] = gen_wsr_ccompare,
578 };
579
580 if (sregnames[sr]) {
581 if (wsr_handler[sr]) {
582 wsr_handler[sr](dc, sr, s);
583 } else {
584 tcg_gen_mov_i32(cpu_SR[sr], s);
585 }
586 } else {
587 qemu_log("WSR %d not implemented, ", sr);
588 }
589 }
590
591 static void gen_load_store_alignment(DisasContext *dc, int shift,
592 TCGv_i32 addr, bool no_hw_alignment)
593 {
594 if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
595 tcg_gen_andi_i32(addr, addr, ~0 << shift);
596 } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
597 no_hw_alignment) {
598 int label = gen_new_label();
599 TCGv_i32 tmp = tcg_temp_new_i32();
600 tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
601 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
602 gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
603 gen_set_label(label);
604 tcg_temp_free(tmp);
605 }
606 }
607
608 static void gen_waiti(DisasContext *dc, uint32_t imm4)
609 {
610 TCGv_i32 pc = tcg_const_i32(dc->next_pc);
611 TCGv_i32 intlevel = tcg_const_i32(imm4);
612 gen_advance_ccount(dc);
613 gen_helper_waiti(pc, intlevel);
614 tcg_temp_free(pc);
615 tcg_temp_free(intlevel);
616 }
617
618 static void gen_window_check1(DisasContext *dc, unsigned r1)
619 {
620 if (dc->tb->flags & XTENSA_TBFLAG_EXCM) {
621 return;
622 }
623 if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&
624 r1 / 4 > dc->used_window) {
625 TCGv_i32 pc = tcg_const_i32(dc->pc);
626 TCGv_i32 w = tcg_const_i32(r1 / 4);
627
628 dc->used_window = r1 / 4;
629 gen_advance_ccount(dc);
630 gen_helper_window_check(pc, w);
631
632 tcg_temp_free(w);
633 tcg_temp_free(pc);
634 }
635 }
636
637 static void gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)
638 {
639 gen_window_check1(dc, r1 > r2 ? r1 : r2);
640 }
641
642 static void gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2,
643 unsigned r3)
644 {
645 gen_window_check2(dc, r1, r2 > r3 ? r2 : r3);
646 }
647
648 static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
649 {
650 TCGv_i32 m = tcg_temp_new_i32();
651
652 if (hi) {
653 (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
654 } else {
655 (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
656 }
657 return m;
658 }
659
660 static void disas_xtensa_insn(DisasContext *dc)
661 {
662 #define HAS_OPTION_BITS(opt) do { \
663 if (!option_bits_enabled(dc, opt)) { \
664 qemu_log("Option is not enabled %s:%d\n", \
665 __FILE__, __LINE__); \
666 goto invalid_opcode; \
667 } \
668 } while (0)
669
670 #define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt))
671
672 #define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
673 #define RESERVED() do { \
674 qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
675 dc->pc, b0, b1, b2, __FILE__, __LINE__); \
676 goto invalid_opcode; \
677 } while (0)
678
679
680 #ifdef TARGET_WORDS_BIGENDIAN
681 #define OP0 (((b0) & 0xf0) >> 4)
682 #define OP1 (((b2) & 0xf0) >> 4)
683 #define OP2 ((b2) & 0xf)
684 #define RRR_R ((b1) & 0xf)
685 #define RRR_S (((b1) & 0xf0) >> 4)
686 #define RRR_T ((b0) & 0xf)
687 #else
688 #define OP0 (((b0) & 0xf))
689 #define OP1 (((b2) & 0xf))
690 #define OP2 (((b2) & 0xf0) >> 4)
691 #define RRR_R (((b1) & 0xf0) >> 4)
692 #define RRR_S (((b1) & 0xf))
693 #define RRR_T (((b0) & 0xf0) >> 4)
694 #endif
695 #define RRR_X ((RRR_R & 0x4) >> 2)
696 #define RRR_Y ((RRR_T & 0x4) >> 2)
697 #define RRR_W (RRR_R & 0x3)
698
699 #define RRRN_R RRR_R
700 #define RRRN_S RRR_S
701 #define RRRN_T RRR_T
702
703 #define RRI8_R RRR_R
704 #define RRI8_S RRR_S
705 #define RRI8_T RRR_T
706 #define RRI8_IMM8 (b2)
707 #define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)
708
709 #ifdef TARGET_WORDS_BIGENDIAN
710 #define RI16_IMM16 (((b1) << 8) | (b2))
711 #else
712 #define RI16_IMM16 (((b2) << 8) | (b1))
713 #endif
714
715 #ifdef TARGET_WORDS_BIGENDIAN
716 #define CALL_N (((b0) & 0xc) >> 2)
717 #define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))
718 #else
719 #define CALL_N (((b0) & 0x30) >> 4)
720 #define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))
721 #endif
722 #define CALL_OFFSET_SE \
723 (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)
724
725 #define CALLX_N CALL_N
726 #ifdef TARGET_WORDS_BIGENDIAN
727 #define CALLX_M ((b0) & 0x3)
728 #else
729 #define CALLX_M (((b0) & 0xc0) >> 6)
730 #endif
731 #define CALLX_S RRR_S
732
733 #define BRI12_M CALLX_M
734 #define BRI12_S RRR_S
735 #ifdef TARGET_WORDS_BIGENDIAN
736 #define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))
737 #else
738 #define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))
739 #endif
740 #define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)
741
742 #define BRI8_M BRI12_M
743 #define BRI8_R RRI8_R
744 #define BRI8_S RRI8_S
745 #define BRI8_IMM8 RRI8_IMM8
746 #define BRI8_IMM8_SE RRI8_IMM8_SE
747
748 #define RSR_SR (b1)
749
750 uint8_t b0 = ldub_code(dc->pc);
751 uint8_t b1 = ldub_code(dc->pc + 1);
752 uint8_t b2 = ldub_code(dc->pc + 2);
753
754 static const uint32_t B4CONST[] = {
755 0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
756 };
757
758 static const uint32_t B4CONSTU[] = {
759 32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
760 };
761
762 if (OP0 >= 8) {
763 dc->next_pc = dc->pc + 2;
764 HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
765 } else {
766 dc->next_pc = dc->pc + 3;
767 }
768
769 switch (OP0) {
770 case 0: /*QRST*/
771 switch (OP1) {
772 case 0: /*RST0*/
773 switch (OP2) {
774 case 0: /*ST0*/
775 if ((RRR_R & 0xc) == 0x8) {
776 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
777 }
778
779 switch (RRR_R) {
780 case 0: /*SNM0*/
781 switch (CALLX_M) {
782 case 0: /*ILL*/
783 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
784 break;
785
786 case 1: /*reserved*/
787 RESERVED();
788 break;
789
790 case 2: /*JR*/
791 switch (CALLX_N) {
792 case 0: /*RET*/
793 case 2: /*JX*/
794 gen_window_check1(dc, CALLX_S);
795 gen_jump(dc, cpu_R[CALLX_S]);
796 break;
797
798 case 1: /*RETWw*/
799 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
800 {
801 TCGv_i32 tmp = tcg_const_i32(dc->pc);
802 gen_advance_ccount(dc);
803 gen_helper_retw(tmp, tmp);
804 gen_jump(dc, tmp);
805 tcg_temp_free(tmp);
806 }
807 break;
808
809 case 3: /*reserved*/
810 RESERVED();
811 break;
812 }
813 break;
814
815 case 3: /*CALLX*/
816 gen_window_check2(dc, CALLX_S, CALLX_N << 2);
817 switch (CALLX_N) {
818 case 0: /*CALLX0*/
819 {
820 TCGv_i32 tmp = tcg_temp_new_i32();
821 tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
822 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
823 gen_jump(dc, tmp);
824 tcg_temp_free(tmp);
825 }
826 break;
827
828 case 1: /*CALLX4w*/
829 case 2: /*CALLX8w*/
830 case 3: /*CALLX12w*/
831 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
832 {
833 TCGv_i32 tmp = tcg_temp_new_i32();
834
835 tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
836 gen_callw(dc, CALLX_N, tmp);
837 tcg_temp_free(tmp);
838 }
839 break;
840 }
841 break;
842 }
843 break;
844
845 case 1: /*MOVSPw*/
846 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
847 gen_window_check2(dc, RRR_T, RRR_S);
848 {
849 TCGv_i32 pc = tcg_const_i32(dc->pc);
850 gen_advance_ccount(dc);
851 gen_helper_movsp(pc);
852 tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]);
853 tcg_temp_free(pc);
854 }
855 break;
856
857 case 2: /*SYNC*/
858 switch (RRR_T) {
859 case 0: /*ISYNC*/
860 break;
861
862 case 1: /*RSYNC*/
863 break;
864
865 case 2: /*ESYNC*/
866 break;
867
868 case 3: /*DSYNC*/
869 break;
870
871 case 8: /*EXCW*/
872 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
873 break;
874
875 case 12: /*MEMW*/
876 break;
877
878 case 13: /*EXTW*/
879 break;
880
881 case 15: /*NOP*/
882 break;
883
884 default: /*reserved*/
885 RESERVED();
886 break;
887 }
888 break;
889
890 case 3: /*RFEIx*/
891 switch (RRR_T) {
892 case 0: /*RFETx*/
893 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
894 switch (RRR_S) {
895 case 0: /*RFEx*/
896 gen_check_privilege(dc);
897 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
898 gen_helper_check_interrupts(cpu_env);
899 gen_jump(dc, cpu_SR[EPC1]);
900 break;
901
902 case 1: /*RFUEx*/
903 RESERVED();
904 break;
905
906 case 2: /*RFDEx*/
907 gen_check_privilege(dc);
908 gen_jump(dc, cpu_SR[
909 dc->config->ndepc ? DEPC : EPC1]);
910 break;
911
912 case 4: /*RFWOw*/
913 case 5: /*RFWUw*/
914 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
915 gen_check_privilege(dc);
916 {
917 TCGv_i32 tmp = tcg_const_i32(1);
918
919 tcg_gen_andi_i32(
920 cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
921 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
922
923 if (RRR_S == 4) {
924 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
925 cpu_SR[WINDOW_START], tmp);
926 } else {
927 tcg_gen_or_i32(cpu_SR[WINDOW_START],
928 cpu_SR[WINDOW_START], tmp);
929 }
930
931 gen_helper_restore_owb();
932 gen_helper_check_interrupts(cpu_env);
933 gen_jump(dc, cpu_SR[EPC1]);
934
935 tcg_temp_free(tmp);
936 }
937 break;
938
939 default: /*reserved*/
940 RESERVED();
941 break;
942 }
943 break;
944
945 case 1: /*RFIx*/
946 HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT);
947 if (RRR_S >= 2 && RRR_S <= dc->config->nlevel) {
948 gen_check_privilege(dc);
949 tcg_gen_mov_i32(cpu_SR[PS],
950 cpu_SR[EPS2 + RRR_S - 2]);
951 gen_helper_check_interrupts(cpu_env);
952 gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]);
953 } else {
954 qemu_log("RFI %d is illegal\n", RRR_S);
955 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
956 }
957 break;
958
959 case 2: /*RFME*/
960 TBD();
961 break;
962
963 default: /*reserved*/
964 RESERVED();
965 break;
966
967 }
968 break;
969
970 case 4: /*BREAKx*/
971 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
972 TBD();
973 break;
974
975 case 5: /*SYSCALLx*/
976 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
977 switch (RRR_S) {
978 case 0: /*SYSCALLx*/
979 gen_exception_cause(dc, SYSCALL_CAUSE);
980 break;
981
982 case 1: /*SIMCALL*/
983 if (semihosting_enabled) {
984 gen_check_privilege(dc);
985 gen_helper_simcall(cpu_env);
986 } else {
987 qemu_log("SIMCALL but semihosting is disabled\n");
988 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
989 }
990 break;
991
992 default:
993 RESERVED();
994 break;
995 }
996 break;
997
998 case 6: /*RSILx*/
999 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
1000 gen_check_privilege(dc);
1001 gen_window_check1(dc, RRR_T);
1002 tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]);
1003 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
1004 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S);
1005 gen_helper_check_interrupts(cpu_env);
1006 gen_jumpi_check_loop_end(dc, 0);
1007 break;
1008
1009 case 7: /*WAITIx*/
1010 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
1011 gen_check_privilege(dc);
1012 gen_waiti(dc, RRR_S);
1013 break;
1014
1015 case 8: /*ANY4p*/
1016 case 9: /*ALL4p*/
1017 case 10: /*ANY8p*/
1018 case 11: /*ALL8p*/
1019 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1020 {
1021 const unsigned shift = (RRR_R & 2) ? 8 : 4;
1022 TCGv_i32 mask = tcg_const_i32(
1023 ((1 << shift) - 1) << RRR_S);
1024 TCGv_i32 tmp = tcg_temp_new_i32();
1025
1026 tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
1027 if (RRR_R & 1) { /*ALL*/
1028 tcg_gen_addi_i32(tmp, tmp, 1 << RRR_S);
1029 } else { /*ANY*/
1030 tcg_gen_add_i32(tmp, tmp, mask);
1031 }
1032 tcg_gen_shri_i32(tmp, tmp, RRR_S + shift);
1033 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
1034 tmp, RRR_T, 1);
1035 tcg_temp_free(mask);
1036 tcg_temp_free(tmp);
1037 }
1038 break;
1039
1040 default: /*reserved*/
1041 RESERVED();
1042 break;
1043
1044 }
1045 break;
1046
1047 case 1: /*AND*/
1048 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1049 tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1050 break;
1051
1052 case 2: /*OR*/
1053 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1054 tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1055 break;
1056
1057 case 3: /*XOR*/
1058 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1059 tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1060 break;
1061
1062 case 4: /*ST1*/
1063 switch (RRR_R) {
1064 case 0: /*SSR*/
1065 gen_window_check1(dc, RRR_S);
1066 gen_right_shift_sar(dc, cpu_R[RRR_S]);
1067 break;
1068
1069 case 1: /*SSL*/
1070 gen_window_check1(dc, RRR_S);
1071 gen_left_shift_sar(dc, cpu_R[RRR_S]);
1072 break;
1073
1074 case 2: /*SSA8L*/
1075 gen_window_check1(dc, RRR_S);
1076 {
1077 TCGv_i32 tmp = tcg_temp_new_i32();
1078 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1079 gen_right_shift_sar(dc, tmp);
1080 tcg_temp_free(tmp);
1081 }
1082 break;
1083
1084 case 3: /*SSA8B*/
1085 gen_window_check1(dc, RRR_S);
1086 {
1087 TCGv_i32 tmp = tcg_temp_new_i32();
1088 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1089 gen_left_shift_sar(dc, tmp);
1090 tcg_temp_free(tmp);
1091 }
1092 break;
1093
1094 case 4: /*SSAI*/
1095 {
1096 TCGv_i32 tmp = tcg_const_i32(
1097 RRR_S | ((RRR_T & 1) << 4));
1098 gen_right_shift_sar(dc, tmp);
1099 tcg_temp_free(tmp);
1100 }
1101 break;
1102
1103 case 6: /*RER*/
1104 TBD();
1105 break;
1106
1107 case 7: /*WER*/
1108 TBD();
1109 break;
1110
1111 case 8: /*ROTWw*/
1112 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1113 gen_check_privilege(dc);
1114 {
1115 TCGv_i32 tmp = tcg_const_i32(
1116 RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0));
1117 gen_helper_rotw(tmp);
1118 tcg_temp_free(tmp);
1119 reset_used_window(dc);
1120 }
1121 break;
1122
1123 case 14: /*NSAu*/
1124 HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);
1125 gen_window_check2(dc, RRR_S, RRR_T);
1126 gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);
1127 break;
1128
1129 case 15: /*NSAUu*/
1130 HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);
1131 gen_window_check2(dc, RRR_S, RRR_T);
1132 gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);
1133 break;
1134
1135 default: /*reserved*/
1136 RESERVED();
1137 break;
1138 }
1139 break;
1140
1141 case 5: /*TLB*/
1142 HAS_OPTION_BITS(
1143 XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
1144 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
1145 XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION));
1146 gen_check_privilege(dc);
1147 gen_window_check2(dc, RRR_S, RRR_T);
1148 {
1149 TCGv_i32 dtlb = tcg_const_i32((RRR_R & 8) != 0);
1150
1151 switch (RRR_R & 7) {
1152 case 3: /*RITLB0*/ /*RDTLB0*/
1153 gen_helper_rtlb0(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1154 break;
1155
1156 case 4: /*IITLB*/ /*IDTLB*/
1157 gen_helper_itlb(cpu_R[RRR_S], dtlb);
1158 /* This could change memory mapping, so exit tb */
1159 gen_jumpi_check_loop_end(dc, -1);
1160 break;
1161
1162 case 5: /*PITLB*/ /*PDTLB*/
1163 tcg_gen_movi_i32(cpu_pc, dc->pc);
1164 gen_helper_ptlb(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1165 break;
1166
1167 case 6: /*WITLB*/ /*WDTLB*/
1168 gen_helper_wtlb(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1169 /* This could change memory mapping, so exit tb */
1170 gen_jumpi_check_loop_end(dc, -1);
1171 break;
1172
1173 case 7: /*RITLB1*/ /*RDTLB1*/
1174 gen_helper_rtlb1(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1175 break;
1176
1177 default:
1178 tcg_temp_free(dtlb);
1179 RESERVED();
1180 break;
1181 }
1182 tcg_temp_free(dtlb);
1183 }
1184 break;
1185
1186 case 6: /*RT0*/
1187 gen_window_check2(dc, RRR_R, RRR_T);
1188 switch (RRR_S) {
1189 case 0: /*NEG*/
1190 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1191 break;
1192
1193 case 1: /*ABS*/
1194 {
1195 int label = gen_new_label();
1196 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1197 tcg_gen_brcondi_i32(
1198 TCG_COND_GE, cpu_R[RRR_R], 0, label);
1199 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1200 gen_set_label(label);
1201 }
1202 break;
1203
1204 default: /*reserved*/
1205 RESERVED();
1206 break;
1207 }
1208 break;
1209
1210 case 7: /*reserved*/
1211 RESERVED();
1212 break;
1213
1214 case 8: /*ADD*/
1215 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1216 tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1217 break;
1218
1219 case 9: /*ADD**/
1220 case 10:
1221 case 11:
1222 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1223 {
1224 TCGv_i32 tmp = tcg_temp_new_i32();
1225 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);
1226 tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1227 tcg_temp_free(tmp);
1228 }
1229 break;
1230
1231 case 12: /*SUB*/
1232 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1233 tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1234 break;
1235
1236 case 13: /*SUB**/
1237 case 14:
1238 case 15:
1239 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1240 {
1241 TCGv_i32 tmp = tcg_temp_new_i32();
1242 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);
1243 tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1244 tcg_temp_free(tmp);
1245 }
1246 break;
1247 }
1248 break;
1249
1250 case 1: /*RST1*/
1251 switch (OP2) {
1252 case 0: /*SLLI*/
1253 case 1:
1254 gen_window_check2(dc, RRR_R, RRR_S);
1255 tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],
1256 32 - (RRR_T | ((OP2 & 1) << 4)));
1257 break;
1258
1259 case 2: /*SRAI*/
1260 case 3:
1261 gen_window_check2(dc, RRR_R, RRR_T);
1262 tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],
1263 RRR_S | ((OP2 & 1) << 4));
1264 break;
1265
1266 case 4: /*SRLI*/
1267 gen_window_check2(dc, RRR_R, RRR_T);
1268 tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);
1269 break;
1270
1271 case 6: /*XSR*/
1272 {
1273 TCGv_i32 tmp = tcg_temp_new_i32();
1274 if (RSR_SR >= 64) {
1275 gen_check_privilege(dc);
1276 }
1277 gen_window_check1(dc, RRR_T);
1278 tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
1279 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1280 gen_wsr(dc, RSR_SR, tmp);
1281 tcg_temp_free(tmp);
1282 if (!sregnames[RSR_SR]) {
1283 TBD();
1284 }
1285 }
1286 break;
1287
1288 /*
1289 * Note: 64 bit ops are used here solely because SAR values
1290 * have range 0..63
1291 */
1292 #define gen_shift_reg(cmd, reg) do { \
1293 TCGv_i64 tmp = tcg_temp_new_i64(); \
1294 tcg_gen_extu_i32_i64(tmp, reg); \
1295 tcg_gen_##cmd##_i64(v, v, tmp); \
1296 tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
1297 tcg_temp_free_i64(v); \
1298 tcg_temp_free_i64(tmp); \
1299 } while (0)
1300
1301 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
1302
1303 case 8: /*SRC*/
1304 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1305 {
1306 TCGv_i64 v = tcg_temp_new_i64();
1307 tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);
1308 gen_shift(shr);
1309 }
1310 break;
1311
1312 case 9: /*SRL*/
1313 gen_window_check2(dc, RRR_R, RRR_T);
1314 if (dc->sar_5bit) {
1315 tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1316 } else {
1317 TCGv_i64 v = tcg_temp_new_i64();
1318 tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);
1319 gen_shift(shr);
1320 }
1321 break;
1322
1323 case 10: /*SLL*/
1324 gen_window_check2(dc, RRR_R, RRR_S);
1325 if (dc->sar_m32_5bit) {
1326 tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);
1327 } else {
1328 TCGv_i64 v = tcg_temp_new_i64();
1329 TCGv_i32 s = tcg_const_i32(32);
1330 tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
1331 tcg_gen_andi_i32(s, s, 0x3f);
1332 tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);
1333 gen_shift_reg(shl, s);
1334 tcg_temp_free(s);
1335 }
1336 break;
1337
1338 case 11: /*SRA*/
1339 gen_window_check2(dc, RRR_R, RRR_T);
1340 if (dc->sar_5bit) {
1341 tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1342 } else {
1343 TCGv_i64 v = tcg_temp_new_i64();
1344 tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);
1345 gen_shift(sar);
1346 }
1347 break;
1348 #undef gen_shift
1349 #undef gen_shift_reg
1350
1351 case 12: /*MUL16U*/
1352 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1353 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1354 {
1355 TCGv_i32 v1 = tcg_temp_new_i32();
1356 TCGv_i32 v2 = tcg_temp_new_i32();
1357 tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);
1358 tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);
1359 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1360 tcg_temp_free(v2);
1361 tcg_temp_free(v1);
1362 }
1363 break;
1364
1365 case 13: /*MUL16S*/
1366 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1367 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1368 {
1369 TCGv_i32 v1 = tcg_temp_new_i32();
1370 TCGv_i32 v2 = tcg_temp_new_i32();
1371 tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);
1372 tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);
1373 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1374 tcg_temp_free(v2);
1375 tcg_temp_free(v1);
1376 }
1377 break;
1378
1379 default: /*reserved*/
1380 RESERVED();
1381 break;
1382 }
1383 break;
1384
1385 case 2: /*RST2*/
1386 if (OP2 >= 8) {
1387 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1388 }
1389
1390 if (OP2 >= 12) {
1391 HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV);
1392 int label = gen_new_label();
1393 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label);
1394 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
1395 gen_set_label(label);
1396 }
1397
1398 switch (OP2) {
1399 #define BOOLEAN_LOGIC(fn, r, s, t) \
1400 do { \
1401 HAS_OPTION(XTENSA_OPTION_BOOLEAN); \
1402 TCGv_i32 tmp1 = tcg_temp_new_i32(); \
1403 TCGv_i32 tmp2 = tcg_temp_new_i32(); \
1404 \
1405 tcg_gen_shri_i32(tmp1, cpu_SR[BR], s); \
1406 tcg_gen_shri_i32(tmp2, cpu_SR[BR], t); \
1407 tcg_gen_##fn##_i32(tmp1, tmp1, tmp2); \
1408 tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, r, 1); \
1409 tcg_temp_free(tmp1); \
1410 tcg_temp_free(tmp2); \
1411 } while (0)
1412
1413 case 0: /*ANDBp*/
1414 BOOLEAN_LOGIC(and, RRR_R, RRR_S, RRR_T);
1415 break;
1416
1417 case 1: /*ANDBCp*/
1418 BOOLEAN_LOGIC(andc, RRR_R, RRR_S, RRR_T);
1419 break;
1420
1421 case 2: /*ORBp*/
1422 BOOLEAN_LOGIC(or, RRR_R, RRR_S, RRR_T);
1423 break;
1424
1425 case 3: /*ORBCp*/
1426 BOOLEAN_LOGIC(orc, RRR_R, RRR_S, RRR_T);
1427 break;
1428
1429 case 4: /*XORBp*/
1430 BOOLEAN_LOGIC(xor, RRR_R, RRR_S, RRR_T);
1431 break;
1432
1433 #undef BOOLEAN_LOGIC
1434
1435 case 8: /*MULLi*/
1436 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
1437 tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1438 break;
1439
1440 case 10: /*MULUHi*/
1441 case 11: /*MULSHi*/
1442 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL_HIGH);
1443 {
1444 TCGv_i64 r = tcg_temp_new_i64();
1445 TCGv_i64 s = tcg_temp_new_i64();
1446 TCGv_i64 t = tcg_temp_new_i64();
1447
1448 if (OP2 == 10) {
1449 tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);
1450 tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);
1451 } else {
1452 tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);
1453 tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);
1454 }
1455 tcg_gen_mul_i64(r, s, t);
1456 tcg_gen_shri_i64(r, r, 32);
1457 tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);
1458
1459 tcg_temp_free_i64(r);
1460 tcg_temp_free_i64(s);
1461 tcg_temp_free_i64(t);
1462 }
1463 break;
1464
1465 case 12: /*QUOUi*/
1466 tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1467 break;
1468
1469 case 13: /*QUOSi*/
1470 case 15: /*REMSi*/
1471 {
1472 int label1 = gen_new_label();
1473 int label2 = gen_new_label();
1474
1475 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000,
1476 label1);
1477 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff,
1478 label1);
1479 tcg_gen_movi_i32(cpu_R[RRR_R],
1480 OP2 == 13 ? 0x80000000 : 0);
1481 tcg_gen_br(label2);
1482 gen_set_label(label1);
1483 if (OP2 == 13) {
1484 tcg_gen_div_i32(cpu_R[RRR_R],
1485 cpu_R[RRR_S], cpu_R[RRR_T]);
1486 } else {
1487 tcg_gen_rem_i32(cpu_R[RRR_R],
1488 cpu_R[RRR_S], cpu_R[RRR_T]);
1489 }
1490 gen_set_label(label2);
1491 }
1492 break;
1493
1494 case 14: /*REMUi*/
1495 tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1496 break;
1497
1498 default: /*reserved*/
1499 RESERVED();
1500 break;
1501 }
1502 break;
1503
1504 case 3: /*RST3*/
1505 switch (OP2) {
1506 case 0: /*RSR*/
1507 if (RSR_SR >= 64) {
1508 gen_check_privilege(dc);
1509 }
1510 gen_window_check1(dc, RRR_T);
1511 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1512 if (!sregnames[RSR_SR]) {
1513 TBD();
1514 }
1515 break;
1516
1517 case 1: /*WSR*/
1518 if (RSR_SR >= 64) {
1519 gen_check_privilege(dc);
1520 }
1521 gen_window_check1(dc, RRR_T);
1522 gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
1523 if (!sregnames[RSR_SR]) {
1524 TBD();
1525 }
1526 break;
1527
1528 case 2: /*SEXTu*/
1529 HAS_OPTION(XTENSA_OPTION_MISC_OP_SEXT);
1530 gen_window_check2(dc, RRR_R, RRR_S);
1531 {
1532 int shift = 24 - RRR_T;
1533
1534 if (shift == 24) {
1535 tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1536 } else if (shift == 16) {
1537 tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1538 } else {
1539 TCGv_i32 tmp = tcg_temp_new_i32();
1540 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);
1541 tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);
1542 tcg_temp_free(tmp);
1543 }
1544 }
1545 break;
1546
1547 case 3: /*CLAMPSu*/
1548 HAS_OPTION(XTENSA_OPTION_MISC_OP_CLAMPS);
1549 gen_window_check2(dc, RRR_R, RRR_S);
1550 {
1551 TCGv_i32 tmp1 = tcg_temp_new_i32();
1552 TCGv_i32 tmp2 = tcg_temp_new_i32();
1553 int label = gen_new_label();
1554
1555 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
1556 tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
1557 tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
1558 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1559 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
1560
1561 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
1562 tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
1563 0xffffffff >> (25 - RRR_T));
1564
1565 gen_set_label(label);
1566
1567 tcg_temp_free(tmp1);
1568 tcg_temp_free(tmp2);
1569 }
1570 break;
1571
1572 case 4: /*MINu*/
1573 case 5: /*MAXu*/
1574 case 6: /*MINUu*/
1575 case 7: /*MAXUu*/
1576 HAS_OPTION(XTENSA_OPTION_MISC_OP_MINMAX);
1577 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1578 {
1579 static const TCGCond cond[] = {
1580 TCG_COND_LE,
1581 TCG_COND_GE,
1582 TCG_COND_LEU,
1583 TCG_COND_GEU
1584 };
1585 int label = gen_new_label();
1586
1587 if (RRR_R != RRR_T) {
1588 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1589 tcg_gen_brcond_i32(cond[OP2 - 4],
1590 cpu_R[RRR_S], cpu_R[RRR_T], label);
1591 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1592 } else {
1593 tcg_gen_brcond_i32(cond[OP2 - 4],
1594 cpu_R[RRR_T], cpu_R[RRR_S], label);
1595 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1596 }
1597 gen_set_label(label);
1598 }
1599 break;
1600
1601 case 8: /*MOVEQZ*/
1602 case 9: /*MOVNEZ*/
1603 case 10: /*MOVLTZ*/
1604 case 11: /*MOVGEZ*/
1605 gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1606 {
1607 static const TCGCond cond[] = {
1608 TCG_COND_NE,
1609 TCG_COND_EQ,
1610 TCG_COND_GE,
1611 TCG_COND_LT
1612 };
1613 int label = gen_new_label();
1614 tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
1615 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1616 gen_set_label(label);
1617 }
1618 break;
1619
1620 case 12: /*MOVFp*/
1621 case 13: /*MOVTp*/
1622 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1623 gen_window_check2(dc, RRR_R, RRR_S);
1624 {
1625 int label = gen_new_label();
1626 TCGv_i32 tmp = tcg_temp_new_i32();
1627
1628 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
1629 tcg_gen_brcondi_i32(
1630 OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
1631 tmp, 0, label);
1632 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1633 gen_set_label(label);
1634 tcg_temp_free(tmp);
1635 }
1636 break;
1637
1638 case 14: /*RUR*/
1639 gen_window_check1(dc, RRR_R);
1640 {
1641 int st = (RRR_S << 4) + RRR_T;
1642 if (uregnames[st]) {
1643 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
1644 } else {
1645 qemu_log("RUR %d not implemented, ", st);
1646 TBD();
1647 }
1648 }
1649 break;
1650
1651 case 15: /*WUR*/
1652 gen_window_check1(dc, RRR_T);
1653 {
1654 if (uregnames[RSR_SR]) {
1655 tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);
1656 } else {
1657 qemu_log("WUR %d not implemented, ", RSR_SR);
1658 TBD();
1659 }
1660 }
1661 break;
1662
1663 }
1664 break;
1665
1666 case 4: /*EXTUI*/
1667 case 5:
1668 gen_window_check2(dc, RRR_R, RRR_T);
1669 {
1670 int shiftimm = RRR_S | (OP1 << 4);
1671 int maskimm = (1 << (OP2 + 1)) - 1;
1672
1673 TCGv_i32 tmp = tcg_temp_new_i32();
1674 tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
1675 tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
1676 tcg_temp_free(tmp);
1677 }
1678 break;
1679
1680 case 6: /*CUST0*/
1681 RESERVED();
1682 break;
1683
1684 case 7: /*CUST1*/
1685 RESERVED();
1686 break;
1687
1688 case 8: /*LSCXp*/
1689 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
1690 TBD();
1691 break;
1692
1693 case 9: /*LSC4*/
1694 gen_window_check2(dc, RRR_S, RRR_T);
1695 switch (OP2) {
1696 case 0: /*L32E*/
1697 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1698 gen_check_privilege(dc);
1699 {
1700 TCGv_i32 addr = tcg_temp_new_i32();
1701 tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1702 (0xffffffc0 | (RRR_R << 2)));
1703 tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring);
1704 tcg_temp_free(addr);
1705 }
1706 break;
1707
1708 case 4: /*S32E*/
1709 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1710 gen_check_privilege(dc);
1711 {
1712 TCGv_i32 addr = tcg_temp_new_i32();
1713 tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1714 (0xffffffc0 | (RRR_R << 2)));
1715 tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring);
1716 tcg_temp_free(addr);
1717 }
1718 break;
1719
1720 default:
1721 RESERVED();
1722 break;
1723 }
1724 break;
1725
1726 case 10: /*FP0*/
1727 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1728 TBD();
1729 break;
1730
1731 case 11: /*FP1*/
1732 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1733 TBD();
1734 break;
1735
1736 default: /*reserved*/
1737 RESERVED();
1738 break;
1739 }
1740 break;
1741
1742 case 1: /*L32R*/
1743 gen_window_check1(dc, RRR_T);
1744 {
1745 TCGv_i32 tmp = tcg_const_i32(
1746 ((dc->tb->flags & XTENSA_TBFLAG_LITBASE) ?
1747 0 : ((dc->pc + 3) & ~3)) +
1748 (0xfffc0000 | (RI16_IMM16 << 2)));
1749
1750 if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
1751 tcg_gen_add_i32(tmp, tmp, dc->litbase);
1752 }
1753 tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring);
1754 tcg_temp_free(tmp);
1755 }
1756 break;
1757
1758 case 2: /*LSAI*/
1759 #define gen_load_store(type, shift) do { \
1760 TCGv_i32 addr = tcg_temp_new_i32(); \
1761 gen_window_check2(dc, RRI8_S, RRI8_T); \
1762 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
1763 if (shift) { \
1764 gen_load_store_alignment(dc, shift, addr, false); \
1765 } \
1766 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1767 tcg_temp_free(addr); \
1768 } while (0)
1769
1770 switch (RRI8_R) {
1771 case 0: /*L8UI*/
1772 gen_load_store(ld8u, 0);
1773 break;
1774
1775 case 1: /*L16UI*/
1776 gen_load_store(ld16u, 1);
1777 break;
1778
1779 case 2: /*L32I*/
1780 gen_load_store(ld32u, 2);
1781 break;
1782
1783 case 4: /*S8I*/
1784 gen_load_store(st8, 0);
1785 break;
1786
1787 case 5: /*S16I*/
1788 gen_load_store(st16, 1);
1789 break;
1790
1791 case 6: /*S32I*/
1792 gen_load_store(st32, 2);
1793 break;
1794
1795 case 7: /*CACHEc*/
1796 if (RRI8_T < 8) {
1797 HAS_OPTION(XTENSA_OPTION_DCACHE);
1798 }
1799
1800 switch (RRI8_T) {
1801 case 0: /*DPFRc*/
1802 break;
1803
1804 case 1: /*DPFWc*/
1805 break;
1806
1807 case 2: /*DPFROc*/
1808 break;
1809
1810 case 3: /*DPFWOc*/
1811 break;
1812
1813 case 4: /*DHWBc*/
1814 break;
1815
1816 case 5: /*DHWBIc*/
1817 break;
1818
1819 case 6: /*DHIc*/
1820 break;
1821
1822 case 7: /*DIIc*/
1823 break;
1824
1825 case 8: /*DCEc*/
1826 switch (OP1) {
1827 case 0: /*DPFLl*/
1828 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1829 break;
1830
1831 case 2: /*DHUl*/
1832 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1833 break;
1834
1835 case 3: /*DIUl*/
1836 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1837 break;
1838
1839 case 4: /*DIWBc*/
1840 HAS_OPTION(XTENSA_OPTION_DCACHE);
1841 break;
1842
1843 case 5: /*DIWBIc*/
1844 HAS_OPTION(XTENSA_OPTION_DCACHE);
1845 break;
1846
1847 default: /*reserved*/
1848 RESERVED();
1849 break;
1850
1851 }
1852 break;
1853
1854 case 12: /*IPFc*/
1855 HAS_OPTION(XTENSA_OPTION_ICACHE);
1856 break;
1857
1858 case 13: /*ICEc*/
1859 switch (OP1) {
1860 case 0: /*IPFLl*/
1861 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1862 break;
1863
1864 case 2: /*IHUl*/
1865 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1866 break;
1867
1868 case 3: /*IIUl*/
1869 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1870 break;
1871
1872 default: /*reserved*/
1873 RESERVED();
1874 break;
1875 }
1876 break;
1877
1878 case 14: /*IHIc*/
1879 HAS_OPTION(XTENSA_OPTION_ICACHE);
1880 break;
1881
1882 case 15: /*IIIc*/
1883 HAS_OPTION(XTENSA_OPTION_ICACHE);
1884 break;
1885
1886 default: /*reserved*/
1887 RESERVED();
1888 break;
1889 }
1890 break;
1891
1892 case 9: /*L16SI*/
1893 gen_load_store(ld16s, 1);
1894 break;
1895 #undef gen_load_store
1896
1897 case 10: /*MOVI*/
1898 gen_window_check1(dc, RRI8_T);
1899 tcg_gen_movi_i32(cpu_R[RRI8_T],
1900 RRI8_IMM8 | (RRI8_S << 8) |
1901 ((RRI8_S & 0x8) ? 0xfffff000 : 0));
1902 break;
1903
1904 #define gen_load_store_no_hw_align(type) do { \
1905 TCGv_i32 addr = tcg_temp_local_new_i32(); \
1906 gen_window_check2(dc, RRI8_S, RRI8_T); \
1907 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \
1908 gen_load_store_alignment(dc, 2, addr, true); \
1909 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1910 tcg_temp_free(addr); \
1911 } while (0)
1912
1913 case 11: /*L32AIy*/
1914 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1915 gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/
1916 break;
1917
1918 case 12: /*ADDI*/
1919 gen_window_check2(dc, RRI8_S, RRI8_T);
1920 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);
1921 break;
1922
1923 case 13: /*ADDMI*/
1924 gen_window_check2(dc, RRI8_S, RRI8_T);
1925 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);
1926 break;
1927
1928 case 14: /*S32C1Iy*/
1929 HAS_OPTION(XTENSA_OPTION_CONDITIONAL_STORE);
1930 gen_window_check2(dc, RRI8_S, RRI8_T);
1931 {
1932 int label = gen_new_label();
1933 TCGv_i32 tmp = tcg_temp_local_new_i32();
1934 TCGv_i32 addr = tcg_temp_local_new_i32();
1935
1936 tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
1937 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
1938 gen_load_store_alignment(dc, 2, addr, true);
1939 tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);
1940 tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
1941 cpu_SR[SCOMPARE1], label);
1942
1943 tcg_gen_qemu_st32(tmp, addr, dc->cring);
1944
1945 gen_set_label(label);
1946 tcg_temp_free(addr);
1947 tcg_temp_free(tmp);
1948 }
1949 break;
1950
1951 case 15: /*S32RIy*/
1952 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1953 gen_load_store_no_hw_align(st32); /*TODO release?*/
1954 break;
1955 #undef gen_load_store_no_hw_align
1956
1957 default: /*reserved*/
1958 RESERVED();
1959 break;
1960 }
1961 break;
1962
1963 case 3: /*LSCIp*/
1964 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
1965 TBD();
1966 break;
1967
1968 case 4: /*MAC16d*/
1969 HAS_OPTION(XTENSA_OPTION_MAC16);
1970 {
1971 enum {
1972 MAC16_UMUL = 0x0,
1973 MAC16_MUL = 0x4,
1974 MAC16_MULA = 0x8,
1975 MAC16_MULS = 0xc,
1976 MAC16_NONE = 0xf,
1977 } op = OP1 & 0xc;
1978 bool is_m1_sr = (OP2 & 0x3) == 2;
1979 bool is_m2_sr = (OP2 & 0xc) == 0;
1980 uint32_t ld_offset = 0;
1981
1982 if (OP2 > 9) {
1983 RESERVED();
1984 }
1985
1986 switch (OP2 & 2) {
1987 case 0: /*MACI?/MACC?*/
1988 is_m1_sr = true;
1989 ld_offset = (OP2 & 1) ? -4 : 4;
1990
1991 if (OP2 >= 8) { /*MACI/MACC*/
1992 if (OP1 == 0) { /*LDINC/LDDEC*/
1993 op = MAC16_NONE;
1994 } else {
1995 RESERVED();
1996 }
1997 } else if (op != MAC16_MULA) { /*MULA.*.*.LDINC/LDDEC*/
1998 RESERVED();
1999 }
2000 break;
2001
2002 case 2: /*MACD?/MACA?*/
2003 if (op == MAC16_UMUL && OP2 != 7) { /*UMUL only in MACAA*/
2004 RESERVED();
2005 }
2006 break;
2007 }
2008
2009 if (op != MAC16_NONE) {
2010 if (!is_m1_sr) {
2011 gen_window_check1(dc, RRR_S);
2012 }
2013 if (!is_m2_sr) {
2014 gen_window_check1(dc, RRR_T);
2015 }
2016 }
2017
2018 {
2019 TCGv_i32 vaddr = tcg_temp_new_i32();
2020 TCGv_i32 mem32 = tcg_temp_new_i32();
2021
2022 if (ld_offset) {
2023 gen_window_check1(dc, RRR_S);
2024 tcg_gen_addi_i32(vaddr, cpu_R[RRR_S], ld_offset);
2025 gen_load_store_alignment(dc, 2, vaddr, false);
2026 tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
2027 }
2028 if (op != MAC16_NONE) {
2029 TCGv_i32 m1 = gen_mac16_m(
2030 is_m1_sr ? cpu_SR[MR + RRR_X] : cpu_R[RRR_S],
2031 OP1 & 1, op == MAC16_UMUL);
2032 TCGv_i32 m2 = gen_mac16_m(
2033 is_m2_sr ? cpu_SR[MR + 2 + RRR_Y] : cpu_R[RRR_T],
2034 OP1 & 2, op == MAC16_UMUL);
2035
2036 if (op == MAC16_MUL || op == MAC16_UMUL) {
2037 tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
2038 if (op == MAC16_UMUL) {
2039 tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
2040 } else {
2041 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
2042 }
2043 } else {
2044 TCGv_i32 res = tcg_temp_new_i32();
2045 TCGv_i64 res64 = tcg_temp_new_i64();
2046 TCGv_i64 tmp = tcg_temp_new_i64();
2047
2048 tcg_gen_mul_i32(res, m1, m2);
2049 tcg_gen_ext_i32_i64(res64, res);
2050 tcg_gen_concat_i32_i64(tmp,
2051 cpu_SR[ACCLO], cpu_SR[ACCHI]);
2052 if (op == MAC16_MULA) {
2053 tcg_gen_add_i64(tmp, tmp, res64);
2054 } else {
2055 tcg_gen_sub_i64(tmp, tmp, res64);
2056 }
2057 tcg_gen_trunc_i64_i32(cpu_SR[ACCLO], tmp);
2058 tcg_gen_shri_i64(tmp, tmp, 32);
2059 tcg_gen_trunc_i64_i32(cpu_SR[ACCHI], tmp);
2060 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
2061
2062 tcg_temp_free(res);
2063 tcg_temp_free_i64(res64);
2064 tcg_temp_free_i64(tmp);
2065 }
2066 tcg_temp_free(m1);
2067 tcg_temp_free(m2);
2068 }
2069 if (ld_offset) {
2070 tcg_gen_mov_i32(cpu_R[RRR_S], vaddr);
2071 tcg_gen_mov_i32(cpu_SR[MR + RRR_W], mem32);
2072 }
2073 tcg_temp_free(vaddr);
2074 tcg_temp_free(mem32);
2075 }
2076 }
2077 break;
2078
2079 case 5: /*CALLN*/
2080 switch (CALL_N) {
2081 case 0: /*CALL0*/
2082 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
2083 gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2084 break;
2085
2086 case 1: /*CALL4w*/
2087 case 2: /*CALL8w*/
2088 case 3: /*CALL12w*/
2089 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2090 gen_window_check1(dc, CALL_N << 2);
2091 gen_callwi(dc, CALL_N,
2092 (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2093 break;
2094 }
2095 break;
2096
2097 case 6: /*SI*/
2098 switch (CALL_N) {
2099 case 0: /*J*/
2100 gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);
2101 break;
2102
2103 case 1: /*BZ*/
2104 gen_window_check1(dc, BRI12_S);
2105 {
2106 static const TCGCond cond[] = {
2107 TCG_COND_EQ, /*BEQZ*/
2108 TCG_COND_NE, /*BNEZ*/
2109 TCG_COND_LT, /*BLTZ*/
2110 TCG_COND_GE, /*BGEZ*/
2111 };
2112
2113 gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,
2114 4 + BRI12_IMM12_SE);
2115 }
2116 break;
2117
2118 case 2: /*BI0*/
2119 gen_window_check1(dc, BRI8_S);
2120 {
2121 static const TCGCond cond[] = {
2122 TCG_COND_EQ, /*BEQI*/
2123 TCG_COND_NE, /*BNEI*/
2124 TCG_COND_LT, /*BLTI*/
2125 TCG_COND_GE, /*BGEI*/
2126 };
2127
2128 gen_brcondi(dc, cond[BRI8_M & 3],
2129 cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);
2130 }
2131 break;
2132
2133 case 3: /*BI1*/
2134 switch (BRI8_M) {
2135 case 0: /*ENTRYw*/
2136 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2137 {
2138 TCGv_i32 pc = tcg_const_i32(dc->pc);
2139 TCGv_i32 s = tcg_const_i32(BRI12_S);
2140 TCGv_i32 imm = tcg_const_i32(BRI12_IMM12);
2141 gen_advance_ccount(dc);
2142 gen_helper_entry(pc, s, imm);
2143 tcg_temp_free(imm);
2144 tcg_temp_free(s);
2145 tcg_temp_free(pc);
2146 reset_used_window(dc);
2147 }
2148 break;
2149
2150 case 1: /*B1*/
2151 switch (BRI8_R) {
2152 case 0: /*BFp*/
2153 case 1: /*BTp*/
2154 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
2155 {
2156 TCGv_i32 tmp = tcg_temp_new_i32();
2157 tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRI8_S);
2158 gen_brcondi(dc,
2159 BRI8_R == 1 ? TCG_COND_NE : TCG_COND_EQ,
2160 tmp, 0, 4 + RRI8_IMM8_SE);
2161 tcg_temp_free(tmp);
2162 }
2163 break;
2164
2165 case 8: /*LOOP*/
2166 case 9: /*LOOPNEZ*/
2167 case 10: /*LOOPGTZ*/
2168 HAS_OPTION(XTENSA_OPTION_LOOP);
2169 gen_window_check1(dc, RRI8_S);
2170 {
2171 uint32_t lend = dc->pc + RRI8_IMM8 + 4;
2172 TCGv_i32 tmp = tcg_const_i32(lend);
2173
2174 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);
2175 tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
2176 gen_wsr_lend(dc, LEND, tmp);
2177 tcg_temp_free(tmp);
2178
2179 if (BRI8_R > 8) {
2180 int label = gen_new_label();
2181 tcg_gen_brcondi_i32(
2182 BRI8_R == 9 ? TCG_COND_NE : TCG_COND_GT,
2183 cpu_R[RRI8_S], 0, label);
2184 gen_jumpi(dc, lend, 1);
2185 gen_set_label(label);
2186 }
2187
2188 gen_jumpi(dc, dc->next_pc, 0);
2189 }
2190 break;
2191
2192 default: /*reserved*/
2193 RESERVED();
2194 break;
2195
2196 }
2197 break;
2198
2199 case 2: /*BLTUI*/
2200 case 3: /*BGEUI*/
2201 gen_window_check1(dc, BRI8_S);
2202 gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,
2203 cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);
2204 break;
2205 }
2206 break;
2207
2208 }
2209 break;
2210
2211 case 7: /*B*/
2212 {
2213 TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;
2214
2215 switch (RRI8_R & 7) {
2216 case 0: /*BNONE*/ /*BANY*/
2217 gen_window_check2(dc, RRI8_S, RRI8_T);
2218 {
2219 TCGv_i32 tmp = tcg_temp_new_i32();
2220 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2221 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2222 tcg_temp_free(tmp);
2223 }
2224 break;
2225
2226 case 1: /*BEQ*/ /*BNE*/
2227 case 2: /*BLT*/ /*BGE*/
2228 case 3: /*BLTU*/ /*BGEU*/
2229 gen_window_check2(dc, RRI8_S, RRI8_T);
2230 {
2231 static const TCGCond cond[] = {
2232 [1] = TCG_COND_EQ,
2233 [2] = TCG_COND_LT,
2234 [3] = TCG_COND_LTU,
2235 [9] = TCG_COND_NE,
2236 [10] = TCG_COND_GE,
2237 [11] = TCG_COND_GEU,
2238 };
2239 gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],
2240 4 + RRI8_IMM8_SE);
2241 }
2242 break;
2243
2244 case 4: /*BALL*/ /*BNALL*/
2245 gen_window_check2(dc, RRI8_S, RRI8_T);
2246 {
2247 TCGv_i32 tmp = tcg_temp_new_i32();
2248 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2249 gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],
2250 4 + RRI8_IMM8_SE);
2251 tcg_temp_free(tmp);
2252 }
2253 break;
2254
2255 case 5: /*BBC*/ /*BBS*/
2256 gen_window_check2(dc, RRI8_S, RRI8_T);
2257 {
2258 TCGv_i32 bit = tcg_const_i32(1);
2259 TCGv_i32 tmp = tcg_temp_new_i32();
2260 tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);
2261 tcg_gen_shl_i32(bit, bit, tmp);
2262 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);
2263 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2264 tcg_temp_free(tmp);
2265 tcg_temp_free(bit);
2266 }
2267 break;
2268
2269 case 6: /*BBCI*/ /*BBSI*/
2270 case 7:
2271 gen_window_check1(dc, RRI8_S);
2272 {
2273 TCGv_i32 tmp = tcg_temp_new_i32();
2274 tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],
2275 1 << (((RRI8_R & 1) << 4) | RRI8_T));
2276 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2277 tcg_temp_free(tmp);
2278 }
2279 break;
2280
2281 }
2282 }
2283 break;
2284
2285 #define gen_narrow_load_store(type) do { \
2286 TCGv_i32 addr = tcg_temp_new_i32(); \
2287 gen_window_check2(dc, RRRN_S, RRRN_T); \
2288 tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
2289 gen_load_store_alignment(dc, 2, addr, false); \
2290 tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \
2291 tcg_temp_free(addr); \
2292 } while (0)
2293
2294 case 8: /*L32I.Nn*/
2295 gen_narrow_load_store(ld32u);
2296 break;
2297
2298 case 9: /*S32I.Nn*/
2299 gen_narrow_load_store(st32);
2300 break;
2301 #undef gen_narrow_load_store
2302
2303 case 10: /*ADD.Nn*/
2304 gen_window_check3(dc, RRRN_R, RRRN_S, RRRN_T);
2305 tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);
2306 break;
2307
2308 case 11: /*ADDI.Nn*/
2309 gen_window_check2(dc, RRRN_R, RRRN_S);
2310 tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);
2311 break;
2312
2313 case 12: /*ST2n*/
2314 gen_window_check1(dc, RRRN_S);
2315 if (RRRN_T < 8) { /*MOVI.Nn*/
2316 tcg_gen_movi_i32(cpu_R[RRRN_S],
2317 RRRN_R | (RRRN_T << 4) |
2318 ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));
2319 } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
2320 TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;
2321
2322 gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,
2323 4 + (RRRN_R | ((RRRN_T & 3) << 4)));
2324 }
2325 break;
2326
2327 case 13: /*ST3n*/
2328 switch (RRRN_R) {
2329 case 0: /*MOV.Nn*/
2330 gen_window_check2(dc, RRRN_S, RRRN_T);
2331 tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);
2332 break;
2333
2334 case 15: /*S3*/
2335 switch (RRRN_T) {
2336 case 0: /*RET.Nn*/
2337 gen_jump(dc, cpu_R[0]);
2338 break;
2339
2340 case 1: /*RETW.Nn*/
2341 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2342 {
2343 TCGv_i32 tmp = tcg_const_i32(dc->pc);
2344 gen_advance_ccount(dc);
2345 gen_helper_retw(tmp, tmp);
2346 gen_jump(dc, tmp);
2347 tcg_temp_free(tmp);
2348 }
2349 break;
2350
2351 case 2: /*BREAK.Nn*/
2352 TBD();
2353 break;
2354
2355 case 3: /*NOP.Nn*/
2356 break;
2357
2358 case 6: /*ILL.Nn*/
2359 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2360 break;
2361
2362 default: /*reserved*/
2363 RESERVED();
2364 break;
2365 }
2366 break;
2367
2368 default: /*reserved*/
2369 RESERVED();
2370 break;
2371 }
2372 break;
2373
2374 default: /*reserved*/
2375 RESERVED();
2376 break;
2377 }
2378
2379 gen_check_loop_end(dc, 0);
2380 dc->pc = dc->next_pc;
2381
2382 return;
2383
2384 invalid_opcode:
2385 qemu_log("INVALID(pc = %08x)\n", dc->pc);
2386 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2387 #undef HAS_OPTION
2388 }
2389
2390 static void check_breakpoint(CPUState *env, DisasContext *dc)
2391 {
2392 CPUBreakpoint *bp;
2393
2394 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
2395 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
2396 if (bp->pc == dc->pc) {
2397 tcg_gen_movi_i32(cpu_pc, dc->pc);
2398 gen_exception(dc, EXCP_DEBUG);
2399 dc->is_jmp = DISAS_UPDATE;
2400 }
2401 }
2402 }
2403 }
2404
2405 static void gen_intermediate_code_internal(
2406 CPUState *env, TranslationBlock *tb, int search_pc)
2407 {
2408 DisasContext dc;
2409 int insn_count = 0;
2410 int j, lj = -1;
2411 uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2412 int max_insns = tb->cflags & CF_COUNT_MASK;
2413 uint32_t pc_start = tb->pc;
2414 uint32_t next_page_start =
2415 (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2416
2417 if (max_insns == 0) {
2418 max_insns = CF_COUNT_MASK;
2419 }
2420
2421 dc.config = env->config;
2422 dc.singlestep_enabled = env->singlestep_enabled;
2423 dc.tb = tb;
2424 dc.pc = pc_start;
2425 dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
2426 dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;
2427 dc.lbeg = env->sregs[LBEG];
2428 dc.lend = env->sregs[LEND];
2429 dc.is_jmp = DISAS_NEXT;
2430 dc.ccount_delta = 0;
2431
2432 init_litbase(&dc);
2433 init_sar_tracker(&dc);
2434 reset_used_window(&dc);
2435
2436 gen_icount_start();
2437
2438 if (env->singlestep_enabled && env->exception_taken) {
2439 env->exception_taken = 0;
2440 tcg_gen_movi_i32(cpu_pc, dc.pc);
2441 gen_exception(&dc, EXCP_DEBUG);
2442 }
2443
2444 do {
2445 check_breakpoint(env, &dc);
2446
2447 if (search_pc) {
2448 j = gen_opc_ptr - gen_opc_buf;
2449 if (lj < j) {
2450 lj++;
2451 while (lj < j) {
2452 gen_opc_instr_start[lj++] = 0;
2453 }
2454 }
2455 gen_opc_pc[lj] = dc.pc;
2456 gen_opc_instr_start[lj] = 1;
2457 gen_opc_icount[lj] = insn_count;
2458 }
2459
2460 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2461 tcg_gen_debug_insn_start(dc.pc);
2462 }
2463
2464 ++dc.ccount_delta;
2465
2466 if (insn_count + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
2467 gen_io_start();
2468 }
2469
2470 disas_xtensa_insn(&dc);
2471 ++insn_count;
2472 if (env->singlestep_enabled) {
2473 tcg_gen_movi_i32(cpu_pc, dc.pc);
2474 gen_exception(&dc, EXCP_DEBUG);
2475 break;
2476 }
2477 } while (dc.is_jmp == DISAS_NEXT &&
2478 insn_count < max_insns &&
2479 dc.pc < next_page_start &&
2480 gen_opc_ptr < gen_opc_end);
2481
2482 reset_litbase(&dc);
2483 reset_sar_tracker(&dc);
2484
2485 if (tb->cflags & CF_LAST_IO) {
2486 gen_io_end();
2487 }
2488
2489 if (dc.is_jmp == DISAS_NEXT) {
2490 gen_jumpi(&dc, dc.pc, 0);
2491 }
2492 gen_icount_end(tb, insn_count);
2493 *gen_opc_ptr = INDEX_op_end;
2494
2495 if (!search_pc) {
2496 tb->size = dc.pc - pc_start;
2497 tb->icount = insn_count;
2498 }
2499 }
2500
2501 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
2502 {
2503 gen_intermediate_code_internal(env, tb, 0);
2504 }
2505
2506 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
2507 {
2508 gen_intermediate_code_internal(env, tb, 1);
2509 }
2510
2511 void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
2512 int flags)
2513 {
2514 int i, j;
2515
2516 cpu_fprintf(f, "PC=%08x\n\n", env->pc);
2517
2518 for (i = j = 0; i < 256; ++i) {
2519 if (sregnames[i]) {
2520 cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
2521 (j++ % 4) == 3 ? '\n' : ' ');
2522 }
2523 }
2524
2525 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2526
2527 for (i = j = 0; i < 256; ++i) {
2528 if (uregnames[i]) {
2529 cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
2530 (j++ % 4) == 3 ? '\n' : ' ');
2531 }
2532 }
2533
2534 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2535
2536 for (i = 0; i < 16; ++i) {
2537 cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
2538 (i % 4) == 3 ? '\n' : ' ');
2539 }
2540
2541 cpu_fprintf(f, "\n");
2542
2543 for (i = 0; i < env->config->nareg; ++i) {
2544 cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
2545 (i % 4) == 3 ? '\n' : ' ');
2546 }
2547 }
2548
2549 void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
2550 {
2551 env->pc = gen_opc_pc[pc_pos];
2552 }