]> git.proxmox.com Git - qemu.git/blame - target-xtensa/translate.c
target-xtensa: implement loop option
[qemu.git] / target-xtensa / translate.c
CommitLineData
2328826b
MF
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
dedc5eae
MF
39#include "helpers.h"
40#define GEN_HELPER 1
41#include "helpers.h"
42
43typedef struct DisasContext {
44 const XtensaConfig *config;
45 TranslationBlock *tb;
46 uint32_t pc;
47 uint32_t next_pc;
f0a548b9
MF
48 int cring;
49 int ring;
797d780b
MF
50 uint32_t lbeg;
51 uint32_t lend;
dedc5eae
MF
52 int is_jmp;
53 int singlestep_enabled;
3580ecad
MF
54
55 bool sar_5bit;
56 bool sar_m32_5bit;
57 bool sar_m32_allocated;
58 TCGv_i32 sar_m32;
dedc5eae
MF
59} DisasContext;
60
61static TCGv_ptr cpu_env;
62static TCGv_i32 cpu_pc;
63static TCGv_i32 cpu_R[16];
2af3da91
MF
64static TCGv_i32 cpu_SR[256];
65static TCGv_i32 cpu_UR[256];
dedc5eae
MF
66
67#include "gen-icount.h"
2328826b 68
2af3da91 69static const char * const sregnames[256] = {
797d780b
MF
70 [LBEG] = "LBEG",
71 [LEND] = "LEND",
72 [LCOUNT] = "LCOUNT",
3580ecad 73 [SAR] = "SAR",
809377aa 74 [SCOMPARE1] = "SCOMPARE1",
553e44f9
MF
75 [WINDOW_BASE] = "WINDOW_BASE",
76 [WINDOW_START] = "WINDOW_START",
40643d7c
MF
77 [EPC1] = "EPC1",
78 [DEPC] = "DEPC",
79 [EXCSAVE1] = "EXCSAVE1",
f0a548b9 80 [PS] = "PS",
40643d7c
MF
81 [EXCCAUSE] = "EXCCAUSE",
82 [EXCVADDR] = "EXCVADDR",
2af3da91
MF
83};
84
85static const char * const uregnames[256] = {
86 [THREADPTR] = "THREADPTR",
87 [FCR] = "FCR",
88 [FSR] = "FSR",
89};
90
2328826b
MF
91void xtensa_translate_init(void)
92{
dedc5eae
MF
93 static const char * const regnames[] = {
94 "ar0", "ar1", "ar2", "ar3",
95 "ar4", "ar5", "ar6", "ar7",
96 "ar8", "ar9", "ar10", "ar11",
97 "ar12", "ar13", "ar14", "ar15",
98 };
99 int i;
100
101 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
102 cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
103 offsetof(CPUState, pc), "pc");
104
105 for (i = 0; i < 16; i++) {
106 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
107 offsetof(CPUState, regs[i]),
108 regnames[i]);
109 }
2af3da91
MF
110
111 for (i = 0; i < 256; ++i) {
112 if (sregnames[i]) {
113 cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
114 offsetof(CPUState, sregs[i]),
115 sregnames[i]);
116 }
117 }
118
119 for (i = 0; i < 256; ++i) {
120 if (uregnames[i]) {
121 cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
122 offsetof(CPUState, uregs[i]),
123 uregnames[i]);
124 }
125 }
dedc5eae
MF
126#define GEN_HELPER 2
127#include "helpers.h"
128}
129
130static inline bool option_enabled(DisasContext *dc, int opt)
131{
132 return xtensa_option_enabled(dc->config, opt);
133}
134
3580ecad
MF
135static void init_sar_tracker(DisasContext *dc)
136{
137 dc->sar_5bit = false;
138 dc->sar_m32_5bit = false;
139 dc->sar_m32_allocated = false;
140}
141
142static void reset_sar_tracker(DisasContext *dc)
143{
144 if (dc->sar_m32_allocated) {
145 tcg_temp_free(dc->sar_m32);
146 }
147}
148
149static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
150{
151 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
152 if (dc->sar_m32_5bit) {
153 tcg_gen_discard_i32(dc->sar_m32);
154 }
155 dc->sar_5bit = true;
156 dc->sar_m32_5bit = false;
157}
158
159static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
160{
161 TCGv_i32 tmp = tcg_const_i32(32);
162 if (!dc->sar_m32_allocated) {
163 dc->sar_m32 = tcg_temp_local_new_i32();
164 dc->sar_m32_allocated = true;
165 }
166 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
167 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
168 dc->sar_5bit = false;
169 dc->sar_m32_5bit = true;
170 tcg_temp_free(tmp);
171}
172
dedc5eae
MF
173static void gen_exception(int excp)
174{
175 TCGv_i32 tmp = tcg_const_i32(excp);
176 gen_helper_exception(tmp);
177 tcg_temp_free(tmp);
178}
179
40643d7c
MF
180static void gen_exception_cause(DisasContext *dc, uint32_t cause)
181{
182 TCGv_i32 tpc = tcg_const_i32(dc->pc);
183 TCGv_i32 tcause = tcg_const_i32(cause);
184 gen_helper_exception_cause(tpc, tcause);
185 tcg_temp_free(tpc);
186 tcg_temp_free(tcause);
187}
188
189static void gen_check_privilege(DisasContext *dc)
190{
191 if (dc->cring) {
192 gen_exception_cause(dc, PRIVILEGED_CAUSE);
193 }
194}
195
dedc5eae
MF
196static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
197{
198 tcg_gen_mov_i32(cpu_pc, dest);
199 if (dc->singlestep_enabled) {
200 gen_exception(EXCP_DEBUG);
201 } else {
202 if (slot >= 0) {
203 tcg_gen_goto_tb(slot);
204 tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
205 } else {
206 tcg_gen_exit_tb(0);
207 }
208 }
209 dc->is_jmp = DISAS_UPDATE;
210}
211
67882fd1
MF
212static void gen_jump(DisasContext *dc, TCGv dest)
213{
214 gen_jump_slot(dc, dest, -1);
215}
216
dedc5eae
MF
217static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
218{
219 TCGv_i32 tmp = tcg_const_i32(dest);
220 if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
221 slot = -1;
222 }
223 gen_jump_slot(dc, tmp, slot);
224 tcg_temp_free(tmp);
225}
226
553e44f9
MF
227static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
228 int slot)
229{
230 TCGv_i32 tcallinc = tcg_const_i32(callinc);
231
232 tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
233 tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
234 tcg_temp_free(tcallinc);
235 tcg_gen_movi_i32(cpu_R[callinc << 2],
236 (callinc << 30) | (dc->next_pc & 0x3fffffff));
237 gen_jump_slot(dc, dest, slot);
238}
239
240static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
241{
242 gen_callw_slot(dc, callinc, dest, -1);
243}
244
245static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
246{
247 TCGv_i32 tmp = tcg_const_i32(dest);
248 if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
249 slot = -1;
250 }
251 gen_callw_slot(dc, callinc, tmp, slot);
252 tcg_temp_free(tmp);
253}
254
797d780b
MF
255static bool gen_check_loop_end(DisasContext *dc, int slot)
256{
257 if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
258 !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&
259 dc->next_pc == dc->lend) {
260 int label = gen_new_label();
261
262 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
263 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
264 gen_jumpi(dc, dc->lbeg, slot);
265 gen_set_label(label);
266 gen_jumpi(dc, dc->next_pc, -1);
267 return true;
268 }
269 return false;
270}
271
272static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
273{
274 if (!gen_check_loop_end(dc, slot)) {
275 gen_jumpi(dc, dc->next_pc, slot);
276 }
277}
278
bd57fb91
MF
279static void gen_brcond(DisasContext *dc, TCGCond cond,
280 TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)
281{
282 int label = gen_new_label();
283
284 tcg_gen_brcond_i32(cond, t0, t1, label);
797d780b 285 gen_jumpi_check_loop_end(dc, 0);
bd57fb91
MF
286 gen_set_label(label);
287 gen_jumpi(dc, dc->pc + offset, 1);
288}
289
290static void gen_brcondi(DisasContext *dc, TCGCond cond,
291 TCGv_i32 t0, uint32_t t1, uint32_t offset)
292{
293 TCGv_i32 tmp = tcg_const_i32(t1);
294 gen_brcond(dc, cond, t0, tmp, offset);
295 tcg_temp_free(tmp);
296}
297
b8132eff
MF
298static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
299{
300 static void (* const rsr_handler[256])(DisasContext *dc,
301 TCGv_i32 d, uint32_t sr) = {
302 };
303
304 if (sregnames[sr]) {
305 if (rsr_handler[sr]) {
306 rsr_handler[sr](dc, d, sr);
307 } else {
308 tcg_gen_mov_i32(d, cpu_SR[sr]);
309 }
310 } else {
311 qemu_log("RSR %d not implemented, ", sr);
312 }
313}
314
797d780b
MF
315static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
316{
317 gen_helper_wsr_lbeg(s);
318}
319
320static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
321{
322 gen_helper_wsr_lend(s);
323}
324
3580ecad
MF
325static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
326{
327 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
328 if (dc->sar_m32_5bit) {
329 tcg_gen_discard_i32(dc->sar_m32);
330 }
331 dc->sar_5bit = false;
332 dc->sar_m32_5bit = false;
333}
334
553e44f9
MF
335static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
336{
337 gen_helper_wsr_windowbase(v);
338}
339
f0a548b9
MF
340static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
341{
342 uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
343 PS_UM | PS_EXCM | PS_INTLEVEL;
344
345 if (option_enabled(dc, XTENSA_OPTION_MMU)) {
346 mask |= PS_RING;
347 }
348 tcg_gen_andi_i32(cpu_SR[sr], v, mask);
349 /* This can change mmu index, so exit tb */
797d780b 350 gen_jumpi_check_loop_end(dc, -1);
f0a548b9
MF
351}
352
b8132eff
MF
353static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
354{
355 static void (* const wsr_handler[256])(DisasContext *dc,
356 uint32_t sr, TCGv_i32 v) = {
797d780b
MF
357 [LBEG] = gen_wsr_lbeg,
358 [LEND] = gen_wsr_lend,
3580ecad 359 [SAR] = gen_wsr_sar,
553e44f9 360 [WINDOW_BASE] = gen_wsr_windowbase,
f0a548b9 361 [PS] = gen_wsr_ps,
b8132eff
MF
362 };
363
364 if (sregnames[sr]) {
365 if (wsr_handler[sr]) {
366 wsr_handler[sr](dc, sr, s);
367 } else {
368 tcg_gen_mov_i32(cpu_SR[sr], s);
369 }
370 } else {
371 qemu_log("WSR %d not implemented, ", sr);
372 }
373}
374
dedc5eae
MF
375static void disas_xtensa_insn(DisasContext *dc)
376{
377#define HAS_OPTION(opt) do { \
378 if (!option_enabled(dc, opt)) { \
379 qemu_log("Option %d is not enabled %s:%d\n", \
380 (opt), __FILE__, __LINE__); \
381 goto invalid_opcode; \
382 } \
383 } while (0)
384
91a5bb76
MF
385#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
386#define RESERVED() do { \
387 qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
388 dc->pc, b0, b1, b2, __FILE__, __LINE__); \
389 goto invalid_opcode; \
390 } while (0)
391
392
dedc5eae
MF
393#ifdef TARGET_WORDS_BIGENDIAN
394#define OP0 (((b0) & 0xf0) >> 4)
395#define OP1 (((b2) & 0xf0) >> 4)
396#define OP2 ((b2) & 0xf)
397#define RRR_R ((b1) & 0xf)
398#define RRR_S (((b1) & 0xf0) >> 4)
399#define RRR_T ((b0) & 0xf)
400#else
401#define OP0 (((b0) & 0xf))
402#define OP1 (((b2) & 0xf))
403#define OP2 (((b2) & 0xf0) >> 4)
404#define RRR_R (((b1) & 0xf0) >> 4)
405#define RRR_S (((b1) & 0xf))
406#define RRR_T (((b0) & 0xf0) >> 4)
407#endif
408
409#define RRRN_R RRR_R
410#define RRRN_S RRR_S
411#define RRRN_T RRR_T
412
413#define RRI8_R RRR_R
414#define RRI8_S RRR_S
415#define RRI8_T RRR_T
416#define RRI8_IMM8 (b2)
417#define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)
418
419#ifdef TARGET_WORDS_BIGENDIAN
420#define RI16_IMM16 (((b1) << 8) | (b2))
421#else
422#define RI16_IMM16 (((b2) << 8) | (b1))
423#endif
424
425#ifdef TARGET_WORDS_BIGENDIAN
426#define CALL_N (((b0) & 0xc) >> 2)
427#define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))
428#else
429#define CALL_N (((b0) & 0x30) >> 4)
430#define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))
431#endif
432#define CALL_OFFSET_SE \
433 (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)
434
435#define CALLX_N CALL_N
436#ifdef TARGET_WORDS_BIGENDIAN
437#define CALLX_M ((b0) & 0x3)
438#else
439#define CALLX_M (((b0) & 0xc0) >> 6)
440#endif
441#define CALLX_S RRR_S
442
443#define BRI12_M CALLX_M
444#define BRI12_S RRR_S
445#ifdef TARGET_WORDS_BIGENDIAN
446#define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))
447#else
448#define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))
449#endif
450#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)
451
452#define BRI8_M BRI12_M
453#define BRI8_R RRI8_R
454#define BRI8_S RRI8_S
455#define BRI8_IMM8 RRI8_IMM8
456#define BRI8_IMM8_SE RRI8_IMM8_SE
457
458#define RSR_SR (b1)
459
460 uint8_t b0 = ldub_code(dc->pc);
461 uint8_t b1 = ldub_code(dc->pc + 1);
462 uint8_t b2 = ldub_code(dc->pc + 2);
463
bd57fb91
MF
464 static const uint32_t B4CONST[] = {
465 0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
466 };
467
468 static const uint32_t B4CONSTU[] = {
469 32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
470 };
471
dedc5eae
MF
472 if (OP0 >= 8) {
473 dc->next_pc = dc->pc + 2;
474 HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
475 } else {
476 dc->next_pc = dc->pc + 3;
477 }
478
479 switch (OP0) {
480 case 0: /*QRST*/
481 switch (OP1) {
482 case 0: /*RST0*/
483 switch (OP2) {
484 case 0: /*ST0*/
485 if ((RRR_R & 0xc) == 0x8) {
486 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
487 }
488
489 switch (RRR_R) {
490 case 0: /*SNM0*/
5da4a6a8
MF
491 switch (CALLX_M) {
492 case 0: /*ILL*/
40643d7c 493 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
5da4a6a8
MF
494 break;
495
496 case 1: /*reserved*/
91a5bb76 497 RESERVED();
5da4a6a8
MF
498 break;
499
500 case 2: /*JR*/
501 switch (CALLX_N) {
502 case 0: /*RET*/
503 case 2: /*JX*/
504 gen_jump(dc, cpu_R[CALLX_S]);
505 break;
506
507 case 1: /*RETWw*/
508 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
509 {
510 TCGv_i32 tmp = tcg_const_i32(dc->pc);
511 gen_helper_retw(tmp, tmp);
512 gen_jump(dc, tmp);
513 tcg_temp_free(tmp);
514 }
5da4a6a8
MF
515 break;
516
517 case 3: /*reserved*/
91a5bb76 518 RESERVED();
5da4a6a8
MF
519 break;
520 }
521 break;
522
523 case 3: /*CALLX*/
524 switch (CALLX_N) {
525 case 0: /*CALLX0*/
526 {
527 TCGv_i32 tmp = tcg_temp_new_i32();
528 tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
529 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
530 gen_jump(dc, tmp);
531 tcg_temp_free(tmp);
532 }
533 break;
534
535 case 1: /*CALLX4w*/
536 case 2: /*CALLX8w*/
537 case 3: /*CALLX12w*/
538 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
539 {
540 TCGv_i32 tmp = tcg_temp_new_i32();
541
542 tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
543 gen_callw(dc, CALLX_N, tmp);
544 tcg_temp_free(tmp);
545 }
5da4a6a8
MF
546 break;
547 }
548 break;
549 }
dedc5eae
MF
550 break;
551
552 case 1: /*MOVSPw*/
553 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
554 {
555 TCGv_i32 pc = tcg_const_i32(dc->pc);
556 gen_helper_movsp(pc);
557 tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]);
558 tcg_temp_free(pc);
559 }
dedc5eae
MF
560 break;
561
562 case 2: /*SYNC*/
28067b22
MF
563 switch (RRR_T) {
564 case 0: /*ISYNC*/
565 break;
566
567 case 1: /*RSYNC*/
568 break;
569
570 case 2: /*ESYNC*/
571 break;
572
573 case 3: /*DSYNC*/
574 break;
575
576 case 8: /*EXCW*/
577 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
578 break;
579
580 case 12: /*MEMW*/
581 break;
582
583 case 13: /*EXTW*/
584 break;
585
586 case 15: /*NOP*/
587 break;
588
589 default: /*reserved*/
590 RESERVED();
591 break;
592 }
91a5bb76
MF
593 break;
594
595 case 3: /*RFEIx*/
40643d7c
MF
596 switch (RRR_T) {
597 case 0: /*RFETx*/
598 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
599 switch (RRR_S) {
600 case 0: /*RFEx*/
601 gen_check_privilege(dc);
602 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
603 gen_jump(dc, cpu_SR[EPC1]);
604 break;
605
606 case 1: /*RFUEx*/
607 RESERVED();
608 break;
609
610 case 2: /*RFDEx*/
611 gen_check_privilege(dc);
612 gen_jump(dc, cpu_SR[
613 dc->config->ndepc ? DEPC : EPC1]);
614 break;
615
616 case 4: /*RFWOw*/
617 case 5: /*RFWUw*/
618 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
619 gen_check_privilege(dc);
620 {
621 TCGv_i32 tmp = tcg_const_i32(1);
622
623 tcg_gen_andi_i32(
624 cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
625 tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
626
627 if (RRR_S == 4) {
628 tcg_gen_andc_i32(cpu_SR[WINDOW_START],
629 cpu_SR[WINDOW_START], tmp);
630 } else {
631 tcg_gen_or_i32(cpu_SR[WINDOW_START],
632 cpu_SR[WINDOW_START], tmp);
633 }
634
635 gen_helper_restore_owb();
636 gen_jump(dc, cpu_SR[EPC1]);
637
638 tcg_temp_free(tmp);
639 }
40643d7c
MF
640 break;
641
642 default: /*reserved*/
643 RESERVED();
644 break;
645 }
646 break;
647
648 case 1: /*RFIx*/
649 HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT);
650 TBD();
651 break;
652
653 case 2: /*RFME*/
654 TBD();
655 break;
656
657 default: /*reserved*/
658 RESERVED();
659 break;
660
661 }
91a5bb76
MF
662 break;
663
664 case 4: /*BREAKx*/
665 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
666 TBD();
667 break;
668
669 case 5: /*SYSCALLx*/
670 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
40643d7c
MF
671 switch (RRR_S) {
672 case 0: /*SYSCALLx*/
673 gen_exception_cause(dc, SYSCALL_CAUSE);
674 break;
675
676 case 1: /*SIMCALL*/
677 TBD();
678 break;
679
680 default:
681 RESERVED();
682 break;
683 }
91a5bb76
MF
684 break;
685
686 case 6: /*RSILx*/
687 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
40643d7c
MF
688 gen_check_privilege(dc);
689 tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]);
690 tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S);
691 tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS],
692 RRR_S | ~PS_INTLEVEL);
91a5bb76
MF
693 break;
694
695 case 7: /*WAITIx*/
696 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
697 TBD();
698 break;
699
700 case 8: /*ANY4p*/
701 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
702 TBD();
703 break;
704
705 case 9: /*ALL4p*/
706 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
707 TBD();
dedc5eae
MF
708 break;
709
91a5bb76
MF
710 case 10: /*ANY8p*/
711 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
712 TBD();
713 break;
714
715 case 11: /*ALL8p*/
716 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
717 TBD();
718 break;
719
720 default: /*reserved*/
721 RESERVED();
dedc5eae
MF
722 break;
723
724 }
725 break;
726
727 case 1: /*AND*/
728 tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
729 break;
730
731 case 2: /*OR*/
732 tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
733 break;
734
735 case 3: /*XOR*/
736 tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
737 break;
738
739 case 4: /*ST1*/
3580ecad
MF
740 switch (RRR_R) {
741 case 0: /*SSR*/
742 gen_right_shift_sar(dc, cpu_R[RRR_S]);
743 break;
744
745 case 1: /*SSL*/
746 gen_left_shift_sar(dc, cpu_R[RRR_S]);
747 break;
748
749 case 2: /*SSA8L*/
750 {
751 TCGv_i32 tmp = tcg_temp_new_i32();
752 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
753 gen_right_shift_sar(dc, tmp);
754 tcg_temp_free(tmp);
755 }
756 break;
757
758 case 3: /*SSA8B*/
759 {
760 TCGv_i32 tmp = tcg_temp_new_i32();
761 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
762 gen_left_shift_sar(dc, tmp);
763 tcg_temp_free(tmp);
764 }
765 break;
766
767 case 4: /*SSAI*/
768 {
769 TCGv_i32 tmp = tcg_const_i32(
770 RRR_S | ((RRR_T & 1) << 4));
771 gen_right_shift_sar(dc, tmp);
772 tcg_temp_free(tmp);
773 }
774 break;
775
776 case 6: /*RER*/
91a5bb76 777 TBD();
3580ecad
MF
778 break;
779
780 case 7: /*WER*/
91a5bb76 781 TBD();
3580ecad
MF
782 break;
783
784 case 8: /*ROTWw*/
785 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
786 gen_check_privilege(dc);
787 {
788 TCGv_i32 tmp = tcg_const_i32(
789 RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0));
790 gen_helper_rotw(tmp);
791 tcg_temp_free(tmp);
792 }
3580ecad
MF
793 break;
794
795 case 14: /*NSAu*/
796 HAS_OPTION(XTENSA_OPTION_MISC_OP);
797 gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);
798 break;
799
800 case 15: /*NSAUu*/
801 HAS_OPTION(XTENSA_OPTION_MISC_OP);
802 gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);
803 break;
804
805 default: /*reserved*/
91a5bb76 806 RESERVED();
3580ecad
MF
807 break;
808 }
dedc5eae
MF
809 break;
810
811 case 5: /*TLB*/
91a5bb76 812 TBD();
dedc5eae
MF
813 break;
814
815 case 6: /*RT0*/
f331fe5e
MF
816 switch (RRR_S) {
817 case 0: /*NEG*/
818 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
819 break;
820
821 case 1: /*ABS*/
822 {
823 int label = gen_new_label();
824 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
825 tcg_gen_brcondi_i32(
826 TCG_COND_GE, cpu_R[RRR_R], 0, label);
827 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
828 gen_set_label(label);
829 }
830 break;
831
832 default: /*reserved*/
91a5bb76 833 RESERVED();
f331fe5e
MF
834 break;
835 }
dedc5eae
MF
836 break;
837
838 case 7: /*reserved*/
91a5bb76 839 RESERVED();
dedc5eae
MF
840 break;
841
842 case 8: /*ADD*/
843 tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
844 break;
845
846 case 9: /*ADD**/
847 case 10:
848 case 11:
849 {
850 TCGv_i32 tmp = tcg_temp_new_i32();
851 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);
852 tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
853 tcg_temp_free(tmp);
854 }
855 break;
856
857 case 12: /*SUB*/
858 tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
859 break;
860
861 case 13: /*SUB**/
862 case 14:
863 case 15:
864 {
865 TCGv_i32 tmp = tcg_temp_new_i32();
866 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);
867 tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
868 tcg_temp_free(tmp);
869 }
870 break;
871 }
872 break;
873
874 case 1: /*RST1*/
3580ecad
MF
875 switch (OP2) {
876 case 0: /*SLLI*/
877 case 1:
878 tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],
879 32 - (RRR_T | ((OP2 & 1) << 4)));
880 break;
881
882 case 2: /*SRAI*/
883 case 3:
884 tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],
885 RRR_S | ((OP2 & 1) << 4));
886 break;
887
888 case 4: /*SRLI*/
889 tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);
890 break;
891
892 case 6: /*XSR*/
893 {
894 TCGv_i32 tmp = tcg_temp_new_i32();
40643d7c
MF
895 if (RSR_SR >= 64) {
896 gen_check_privilege(dc);
897 }
3580ecad
MF
898 tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
899 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
900 gen_wsr(dc, RSR_SR, tmp);
901 tcg_temp_free(tmp);
91a5bb76
MF
902 if (!sregnames[RSR_SR]) {
903 TBD();
904 }
3580ecad
MF
905 }
906 break;
907
908 /*
909 * Note: 64 bit ops are used here solely because SAR values
910 * have range 0..63
911 */
912#define gen_shift_reg(cmd, reg) do { \
913 TCGv_i64 tmp = tcg_temp_new_i64(); \
914 tcg_gen_extu_i32_i64(tmp, reg); \
915 tcg_gen_##cmd##_i64(v, v, tmp); \
916 tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
917 tcg_temp_free_i64(v); \
918 tcg_temp_free_i64(tmp); \
919 } while (0)
920
921#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
922
923 case 8: /*SRC*/
924 {
925 TCGv_i64 v = tcg_temp_new_i64();
926 tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);
927 gen_shift(shr);
928 }
929 break;
930
931 case 9: /*SRL*/
932 if (dc->sar_5bit) {
933 tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
934 } else {
935 TCGv_i64 v = tcg_temp_new_i64();
936 tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);
937 gen_shift(shr);
938 }
939 break;
940
941 case 10: /*SLL*/
942 if (dc->sar_m32_5bit) {
943 tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);
944 } else {
945 TCGv_i64 v = tcg_temp_new_i64();
946 TCGv_i32 s = tcg_const_i32(32);
947 tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
948 tcg_gen_andi_i32(s, s, 0x3f);
949 tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);
950 gen_shift_reg(shl, s);
951 tcg_temp_free(s);
952 }
953 break;
954
955 case 11: /*SRA*/
956 if (dc->sar_5bit) {
957 tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
958 } else {
959 TCGv_i64 v = tcg_temp_new_i64();
960 tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);
961 gen_shift(sar);
962 }
963 break;
964#undef gen_shift
965#undef gen_shift_reg
966
967 case 12: /*MUL16U*/
968 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
969 {
970 TCGv_i32 v1 = tcg_temp_new_i32();
971 TCGv_i32 v2 = tcg_temp_new_i32();
972 tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);
973 tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);
974 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
975 tcg_temp_free(v2);
976 tcg_temp_free(v1);
977 }
978 break;
979
980 case 13: /*MUL16S*/
981 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
982 {
983 TCGv_i32 v1 = tcg_temp_new_i32();
984 TCGv_i32 v2 = tcg_temp_new_i32();
985 tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);
986 tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);
987 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
988 tcg_temp_free(v2);
989 tcg_temp_free(v1);
990 }
991 break;
992
993 default: /*reserved*/
91a5bb76 994 RESERVED();
3580ecad
MF
995 break;
996 }
dedc5eae
MF
997 break;
998
999 case 2: /*RST2*/
f76ebf55
MF
1000 if (OP2 >= 12) {
1001 HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV);
1002 int label = gen_new_label();
1003 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label);
1004 gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
1005 gen_set_label(label);
1006 }
1007
1008 switch (OP2) {
1009 case 8: /*MULLi*/
1010 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
1011 tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1012 break;
1013
1014 case 10: /*MULUHi*/
1015 case 11: /*MULSHi*/
1016 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
1017 {
1018 TCGv_i64 r = tcg_temp_new_i64();
1019 TCGv_i64 s = tcg_temp_new_i64();
1020 TCGv_i64 t = tcg_temp_new_i64();
1021
1022 if (OP2 == 10) {
1023 tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);
1024 tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);
1025 } else {
1026 tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);
1027 tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);
1028 }
1029 tcg_gen_mul_i64(r, s, t);
1030 tcg_gen_shri_i64(r, r, 32);
1031 tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);
1032
1033 tcg_temp_free_i64(r);
1034 tcg_temp_free_i64(s);
1035 tcg_temp_free_i64(t);
1036 }
1037 break;
1038
1039 case 12: /*QUOUi*/
1040 tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1041 break;
1042
1043 case 13: /*QUOSi*/
1044 case 15: /*REMSi*/
1045 {
1046 int label1 = gen_new_label();
1047 int label2 = gen_new_label();
1048
1049 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000,
1050 label1);
1051 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff,
1052 label1);
1053 tcg_gen_movi_i32(cpu_R[RRR_R],
1054 OP2 == 13 ? 0x80000000 : 0);
1055 tcg_gen_br(label2);
1056 gen_set_label(label1);
1057 if (OP2 == 13) {
1058 tcg_gen_div_i32(cpu_R[RRR_R],
1059 cpu_R[RRR_S], cpu_R[RRR_T]);
1060 } else {
1061 tcg_gen_rem_i32(cpu_R[RRR_R],
1062 cpu_R[RRR_S], cpu_R[RRR_T]);
1063 }
1064 gen_set_label(label2);
1065 }
1066 break;
1067
1068 case 14: /*REMUi*/
1069 tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1070 break;
1071
1072 default: /*reserved*/
1073 RESERVED();
1074 break;
1075 }
dedc5eae
MF
1076 break;
1077
1078 case 3: /*RST3*/
b8132eff
MF
1079 switch (OP2) {
1080 case 0: /*RSR*/
40643d7c
MF
1081 if (RSR_SR >= 64) {
1082 gen_check_privilege(dc);
1083 }
b8132eff 1084 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
91a5bb76
MF
1085 if (!sregnames[RSR_SR]) {
1086 TBD();
1087 }
b8132eff
MF
1088 break;
1089
1090 case 1: /*WSR*/
40643d7c
MF
1091 if (RSR_SR >= 64) {
1092 gen_check_privilege(dc);
1093 }
b8132eff 1094 gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
91a5bb76
MF
1095 if (!sregnames[RSR_SR]) {
1096 TBD();
1097 }
b8132eff
MF
1098 break;
1099
1100 case 2: /*SEXTu*/
1101 HAS_OPTION(XTENSA_OPTION_MISC_OP);
1102 {
1103 int shift = 24 - RRR_T;
1104
1105 if (shift == 24) {
1106 tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1107 } else if (shift == 16) {
1108 tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1109 } else {
1110 TCGv_i32 tmp = tcg_temp_new_i32();
1111 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);
1112 tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);
1113 tcg_temp_free(tmp);
1114 }
1115 }
1116 break;
1117
1118 case 3: /*CLAMPSu*/
1119 HAS_OPTION(XTENSA_OPTION_MISC_OP);
1120 {
1121 TCGv_i32 tmp1 = tcg_temp_new_i32();
1122 TCGv_i32 tmp2 = tcg_temp_new_i32();
1123 int label = gen_new_label();
1124
1125 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
1126 tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
1127 tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
1128 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1129 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
1130
1131 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
1132 tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
1133 0xffffffff >> (25 - RRR_T));
1134
1135 gen_set_label(label);
1136
1137 tcg_temp_free(tmp1);
1138 tcg_temp_free(tmp2);
1139 }
1140 break;
1141
1142 case 4: /*MINu*/
1143 case 5: /*MAXu*/
1144 case 6: /*MINUu*/
1145 case 7: /*MAXUu*/
1146 HAS_OPTION(XTENSA_OPTION_MISC_OP);
1147 {
1148 static const TCGCond cond[] = {
1149 TCG_COND_LE,
1150 TCG_COND_GE,
1151 TCG_COND_LEU,
1152 TCG_COND_GEU
1153 };
1154 int label = gen_new_label();
1155
1156 if (RRR_R != RRR_T) {
1157 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1158 tcg_gen_brcond_i32(cond[OP2 - 4],
1159 cpu_R[RRR_S], cpu_R[RRR_T], label);
1160 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1161 } else {
1162 tcg_gen_brcond_i32(cond[OP2 - 4],
1163 cpu_R[RRR_T], cpu_R[RRR_S], label);
1164 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1165 }
1166 gen_set_label(label);
1167 }
1168 break;
1169
1170 case 8: /*MOVEQZ*/
1171 case 9: /*MOVNEZ*/
1172 case 10: /*MOVLTZ*/
1173 case 11: /*MOVGEZ*/
1174 {
1175 static const TCGCond cond[] = {
1176 TCG_COND_NE,
1177 TCG_COND_EQ,
1178 TCG_COND_GE,
1179 TCG_COND_LT
1180 };
1181 int label = gen_new_label();
1182 tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
1183 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1184 gen_set_label(label);
1185 }
1186 break;
1187
1188 case 12: /*MOVFp*/
1189 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1190 TBD();
b8132eff
MF
1191 break;
1192
1193 case 13: /*MOVTp*/
1194 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1195 TBD();
b8132eff
MF
1196 break;
1197
1198 case 14: /*RUR*/
1199 {
1200 int st = (RRR_S << 4) + RRR_T;
1201 if (uregnames[st]) {
1202 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
1203 } else {
1204 qemu_log("RUR %d not implemented, ", st);
91a5bb76 1205 TBD();
b8132eff
MF
1206 }
1207 }
1208 break;
1209
1210 case 15: /*WUR*/
1211 {
1212 if (uregnames[RSR_SR]) {
1213 tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);
1214 } else {
1215 qemu_log("WUR %d not implemented, ", RSR_SR);
91a5bb76 1216 TBD();
b8132eff
MF
1217 }
1218 }
1219 break;
1220
1221 }
dedc5eae
MF
1222 break;
1223
1224 case 4: /*EXTUI*/
1225 case 5:
3580ecad
MF
1226 {
1227 int shiftimm = RRR_S | (OP1 << 4);
1228 int maskimm = (1 << (OP2 + 1)) - 1;
1229
1230 TCGv_i32 tmp = tcg_temp_new_i32();
1231 tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
1232 tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
1233 tcg_temp_free(tmp);
1234 }
dedc5eae
MF
1235 break;
1236
1237 case 6: /*CUST0*/
91a5bb76 1238 RESERVED();
dedc5eae
MF
1239 break;
1240
1241 case 7: /*CUST1*/
91a5bb76 1242 RESERVED();
dedc5eae
MF
1243 break;
1244
1245 case 8: /*LSCXp*/
1246 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
91a5bb76 1247 TBD();
dedc5eae
MF
1248 break;
1249
1250 case 9: /*LSC4*/
553e44f9
MF
1251 switch (OP2) {
1252 case 0: /*L32E*/
1253 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1254 gen_check_privilege(dc);
1255 {
1256 TCGv_i32 addr = tcg_temp_new_i32();
1257 tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1258 (0xffffffc0 | (RRR_R << 2)));
1259 tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring);
1260 tcg_temp_free(addr);
1261 }
1262 break;
1263
1264 case 4: /*S32E*/
1265 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1266 gen_check_privilege(dc);
1267 {
1268 TCGv_i32 addr = tcg_temp_new_i32();
1269 tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1270 (0xffffffc0 | (RRR_R << 2)));
1271 tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring);
1272 tcg_temp_free(addr);
1273 }
1274 break;
1275
1276 default:
1277 RESERVED();
1278 break;
1279 }
dedc5eae
MF
1280 break;
1281
1282 case 10: /*FP0*/
1283 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
91a5bb76 1284 TBD();
dedc5eae
MF
1285 break;
1286
1287 case 11: /*FP1*/
1288 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
91a5bb76 1289 TBD();
dedc5eae
MF
1290 break;
1291
1292 default: /*reserved*/
91a5bb76 1293 RESERVED();
dedc5eae
MF
1294 break;
1295 }
1296 break;
1297
1298 case 1: /*L32R*/
1299 {
1300 TCGv_i32 tmp = tcg_const_i32(
1301 (0xfffc0000 | (RI16_IMM16 << 2)) +
1302 ((dc->pc + 3) & ~3));
1303
1304 /* no ext L32R */
1305
f0a548b9 1306 tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring);
dedc5eae
MF
1307 tcg_temp_free(tmp);
1308 }
1309 break;
1310
1311 case 2: /*LSAI*/
809377aa
MF
1312#define gen_load_store(type, shift) do { \
1313 TCGv_i32 addr = tcg_temp_new_i32(); \
1314 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
f0a548b9 1315 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
809377aa
MF
1316 tcg_temp_free(addr); \
1317 } while (0)
1318
1319 switch (RRI8_R) {
1320 case 0: /*L8UI*/
1321 gen_load_store(ld8u, 0);
1322 break;
1323
1324 case 1: /*L16UI*/
1325 gen_load_store(ld16u, 1);
1326 break;
1327
1328 case 2: /*L32I*/
1329 gen_load_store(ld32u, 2);
1330 break;
1331
1332 case 4: /*S8I*/
1333 gen_load_store(st8, 0);
1334 break;
1335
1336 case 5: /*S16I*/
1337 gen_load_store(st16, 1);
1338 break;
1339
1340 case 6: /*S32I*/
1341 gen_load_store(st32, 2);
1342 break;
1343
1344 case 7: /*CACHEc*/
8ffc2d0d
MF
1345 if (RRI8_T < 8) {
1346 HAS_OPTION(XTENSA_OPTION_DCACHE);
1347 }
1348
1349 switch (RRI8_T) {
1350 case 0: /*DPFRc*/
1351 break;
1352
1353 case 1: /*DPFWc*/
1354 break;
1355
1356 case 2: /*DPFROc*/
1357 break;
1358
1359 case 3: /*DPFWOc*/
1360 break;
1361
1362 case 4: /*DHWBc*/
1363 break;
1364
1365 case 5: /*DHWBIc*/
1366 break;
1367
1368 case 6: /*DHIc*/
1369 break;
1370
1371 case 7: /*DIIc*/
1372 break;
1373
1374 case 8: /*DCEc*/
1375 switch (OP1) {
1376 case 0: /*DPFLl*/
1377 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1378 break;
1379
1380 case 2: /*DHUl*/
1381 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1382 break;
1383
1384 case 3: /*DIUl*/
1385 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1386 break;
1387
1388 case 4: /*DIWBc*/
1389 HAS_OPTION(XTENSA_OPTION_DCACHE);
1390 break;
1391
1392 case 5: /*DIWBIc*/
1393 HAS_OPTION(XTENSA_OPTION_DCACHE);
1394 break;
1395
1396 default: /*reserved*/
1397 RESERVED();
1398 break;
1399
1400 }
1401 break;
1402
1403 case 12: /*IPFc*/
1404 HAS_OPTION(XTENSA_OPTION_ICACHE);
1405 break;
1406
1407 case 13: /*ICEc*/
1408 switch (OP1) {
1409 case 0: /*IPFLl*/
1410 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1411 break;
1412
1413 case 2: /*IHUl*/
1414 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1415 break;
1416
1417 case 3: /*IIUl*/
1418 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1419 break;
1420
1421 default: /*reserved*/
1422 RESERVED();
1423 break;
1424 }
1425 break;
1426
1427 case 14: /*IHIc*/
1428 HAS_OPTION(XTENSA_OPTION_ICACHE);
1429 break;
1430
1431 case 15: /*IIIc*/
1432 HAS_OPTION(XTENSA_OPTION_ICACHE);
1433 break;
1434
1435 default: /*reserved*/
1436 RESERVED();
1437 break;
1438 }
809377aa
MF
1439 break;
1440
1441 case 9: /*L16SI*/
1442 gen_load_store(ld16s, 1);
1443 break;
1444
1445 case 10: /*MOVI*/
1446 tcg_gen_movi_i32(cpu_R[RRI8_T],
1447 RRI8_IMM8 | (RRI8_S << 8) |
1448 ((RRI8_S & 0x8) ? 0xfffff000 : 0));
1449 break;
1450
1451 case 11: /*L32AIy*/
1452 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1453 gen_load_store(ld32u, 2); /*TODO acquire?*/
1454 break;
1455
1456 case 12: /*ADDI*/
1457 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);
1458 break;
1459
1460 case 13: /*ADDMI*/
1461 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);
1462 break;
1463
1464 case 14: /*S32C1Iy*/
1465 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1466 {
1467 int label = gen_new_label();
1468 TCGv_i32 tmp = tcg_temp_local_new_i32();
1469 TCGv_i32 addr = tcg_temp_local_new_i32();
1470
1471 tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
1472 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
f0a548b9 1473 tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);
809377aa
MF
1474 tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
1475 cpu_SR[SCOMPARE1], label);
1476
f0a548b9 1477 tcg_gen_qemu_st32(tmp, addr, dc->cring);
809377aa
MF
1478
1479 gen_set_label(label);
1480 tcg_temp_free(addr);
1481 tcg_temp_free(tmp);
1482 }
1483 break;
1484
1485 case 15: /*S32RIy*/
1486 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1487 gen_load_store(st32, 2); /*TODO release?*/
1488 break;
1489
1490 default: /*reserved*/
91a5bb76 1491 RESERVED();
809377aa
MF
1492 break;
1493 }
dedc5eae 1494 break;
809377aa 1495#undef gen_load_store
dedc5eae
MF
1496
1497 case 3: /*LSCIp*/
1498 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
91a5bb76 1499 TBD();
dedc5eae
MF
1500 break;
1501
1502 case 4: /*MAC16d*/
1503 HAS_OPTION(XTENSA_OPTION_MAC16);
91a5bb76 1504 TBD();
dedc5eae
MF
1505 break;
1506
1507 case 5: /*CALLN*/
1508 switch (CALL_N) {
1509 case 0: /*CALL0*/
1510 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
1511 gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
1512 break;
1513
1514 case 1: /*CALL4w*/
1515 case 2: /*CALL8w*/
1516 case 3: /*CALL12w*/
1517 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
1518 gen_callwi(dc, CALL_N,
1519 (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
dedc5eae
MF
1520 break;
1521 }
1522 break;
1523
1524 case 6: /*SI*/
1525 switch (CALL_N) {
1526 case 0: /*J*/
1527 gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);
1528 break;
1529
bd57fb91
MF
1530 case 1: /*BZ*/
1531 {
1532 static const TCGCond cond[] = {
1533 TCG_COND_EQ, /*BEQZ*/
1534 TCG_COND_NE, /*BNEZ*/
1535 TCG_COND_LT, /*BLTZ*/
1536 TCG_COND_GE, /*BGEZ*/
1537 };
1538
1539 gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,
1540 4 + BRI12_IMM12_SE);
1541 }
1542 break;
1543
1544 case 2: /*BI0*/
1545 {
1546 static const TCGCond cond[] = {
1547 TCG_COND_EQ, /*BEQI*/
1548 TCG_COND_NE, /*BNEI*/
1549 TCG_COND_LT, /*BLTI*/
1550 TCG_COND_GE, /*BGEI*/
1551 };
1552
1553 gen_brcondi(dc, cond[BRI8_M & 3],
1554 cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);
1555 }
1556 break;
1557
1558 case 3: /*BI1*/
1559 switch (BRI8_M) {
1560 case 0: /*ENTRYw*/
1561 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
1562 {
1563 TCGv_i32 pc = tcg_const_i32(dc->pc);
1564 TCGv_i32 s = tcg_const_i32(BRI12_S);
1565 TCGv_i32 imm = tcg_const_i32(BRI12_IMM12);
1566 gen_helper_entry(pc, s, imm);
1567 tcg_temp_free(imm);
1568 tcg_temp_free(s);
1569 tcg_temp_free(pc);
1570 }
bd57fb91
MF
1571 break;
1572
1573 case 1: /*B1*/
1574 switch (BRI8_R) {
1575 case 0: /*BFp*/
1576 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1577 TBD();
bd57fb91
MF
1578 break;
1579
1580 case 1: /*BTp*/
1581 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1582 TBD();
bd57fb91
MF
1583 break;
1584
1585 case 8: /*LOOP*/
bd57fb91 1586 case 9: /*LOOPNEZ*/
bd57fb91 1587 case 10: /*LOOPGTZ*/
797d780b
MF
1588 HAS_OPTION(XTENSA_OPTION_LOOP);
1589 {
1590 uint32_t lend = dc->pc + RRI8_IMM8 + 4;
1591 TCGv_i32 tmp = tcg_const_i32(lend);
1592
1593 tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);
1594 tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
1595 gen_wsr_lend(dc, LEND, tmp);
1596 tcg_temp_free(tmp);
1597
1598 if (BRI8_R > 8) {
1599 int label = gen_new_label();
1600 tcg_gen_brcondi_i32(
1601 BRI8_R == 9 ? TCG_COND_NE : TCG_COND_GT,
1602 cpu_R[RRI8_S], 0, label);
1603 gen_jumpi(dc, lend, 1);
1604 gen_set_label(label);
1605 }
1606
1607 gen_jumpi(dc, dc->next_pc, 0);
1608 }
bd57fb91
MF
1609 break;
1610
1611 default: /*reserved*/
91a5bb76 1612 RESERVED();
bd57fb91
MF
1613 break;
1614
1615 }
1616 break;
1617
1618 case 2: /*BLTUI*/
1619 case 3: /*BGEUI*/
1620 gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,
1621 cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);
1622 break;
1623 }
1624 break;
1625
dedc5eae
MF
1626 }
1627 break;
1628
1629 case 7: /*B*/
bd57fb91
MF
1630 {
1631 TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;
1632
1633 switch (RRI8_R & 7) {
1634 case 0: /*BNONE*/ /*BANY*/
1635 {
1636 TCGv_i32 tmp = tcg_temp_new_i32();
1637 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
1638 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1639 tcg_temp_free(tmp);
1640 }
1641 break;
1642
1643 case 1: /*BEQ*/ /*BNE*/
1644 case 2: /*BLT*/ /*BGE*/
1645 case 3: /*BLTU*/ /*BGEU*/
1646 {
1647 static const TCGCond cond[] = {
1648 [1] = TCG_COND_EQ,
1649 [2] = TCG_COND_LT,
1650 [3] = TCG_COND_LTU,
1651 [9] = TCG_COND_NE,
1652 [10] = TCG_COND_GE,
1653 [11] = TCG_COND_GEU,
1654 };
1655 gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],
1656 4 + RRI8_IMM8_SE);
1657 }
1658 break;
1659
1660 case 4: /*BALL*/ /*BNALL*/
1661 {
1662 TCGv_i32 tmp = tcg_temp_new_i32();
1663 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
1664 gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],
1665 4 + RRI8_IMM8_SE);
1666 tcg_temp_free(tmp);
1667 }
1668 break;
1669
1670 case 5: /*BBC*/ /*BBS*/
1671 {
1672 TCGv_i32 bit = tcg_const_i32(1);
1673 TCGv_i32 tmp = tcg_temp_new_i32();
1674 tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);
1675 tcg_gen_shl_i32(bit, bit, tmp);
1676 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);
1677 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1678 tcg_temp_free(tmp);
1679 tcg_temp_free(bit);
1680 }
1681 break;
1682
1683 case 6: /*BBCI*/ /*BBSI*/
1684 case 7:
1685 {
1686 TCGv_i32 tmp = tcg_temp_new_i32();
1687 tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],
1688 1 << (((RRI8_R & 1) << 4) | RRI8_T));
1689 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1690 tcg_temp_free(tmp);
1691 }
1692 break;
1693
1694 }
1695 }
dedc5eae
MF
1696 break;
1697
67882fd1
MF
1698#define gen_narrow_load_store(type) do { \
1699 TCGv_i32 addr = tcg_temp_new_i32(); \
1700 tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
f0a548b9 1701 tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \
67882fd1
MF
1702 tcg_temp_free(addr); \
1703 } while (0)
1704
dedc5eae 1705 case 8: /*L32I.Nn*/
67882fd1 1706 gen_narrow_load_store(ld32u);
dedc5eae
MF
1707 break;
1708
1709 case 9: /*S32I.Nn*/
67882fd1 1710 gen_narrow_load_store(st32);
dedc5eae 1711 break;
67882fd1 1712#undef gen_narrow_load_store
dedc5eae
MF
1713
1714 case 10: /*ADD.Nn*/
67882fd1 1715 tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);
dedc5eae
MF
1716 break;
1717
1718 case 11: /*ADDI.Nn*/
67882fd1 1719 tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);
dedc5eae
MF
1720 break;
1721
1722 case 12: /*ST2n*/
67882fd1
MF
1723 if (RRRN_T < 8) { /*MOVI.Nn*/
1724 tcg_gen_movi_i32(cpu_R[RRRN_S],
1725 RRRN_R | (RRRN_T << 4) |
1726 ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));
1727 } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
bd57fb91
MF
1728 TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;
1729
1730 gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,
1731 4 + (RRRN_R | ((RRRN_T & 3) << 4)));
67882fd1 1732 }
dedc5eae
MF
1733 break;
1734
1735 case 13: /*ST3n*/
67882fd1
MF
1736 switch (RRRN_R) {
1737 case 0: /*MOV.Nn*/
1738 tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);
1739 break;
1740
1741 case 15: /*S3*/
1742 switch (RRRN_T) {
1743 case 0: /*RET.Nn*/
1744 gen_jump(dc, cpu_R[0]);
1745 break;
1746
1747 case 1: /*RETW.Nn*/
91a5bb76 1748 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
553e44f9
MF
1749 {
1750 TCGv_i32 tmp = tcg_const_i32(dc->pc);
1751 gen_helper_retw(tmp, tmp);
1752 gen_jump(dc, tmp);
1753 tcg_temp_free(tmp);
1754 }
67882fd1
MF
1755 break;
1756
1757 case 2: /*BREAK.Nn*/
91a5bb76 1758 TBD();
67882fd1
MF
1759 break;
1760
1761 case 3: /*NOP.Nn*/
1762 break;
1763
1764 case 6: /*ILL.Nn*/
40643d7c 1765 gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
67882fd1
MF
1766 break;
1767
1768 default: /*reserved*/
91a5bb76 1769 RESERVED();
67882fd1
MF
1770 break;
1771 }
1772 break;
1773
1774 default: /*reserved*/
91a5bb76 1775 RESERVED();
67882fd1
MF
1776 break;
1777 }
dedc5eae
MF
1778 break;
1779
1780 default: /*reserved*/
91a5bb76 1781 RESERVED();
dedc5eae
MF
1782 break;
1783 }
1784
797d780b 1785 gen_check_loop_end(dc, 0);
dedc5eae 1786 dc->pc = dc->next_pc;
797d780b 1787
dedc5eae
MF
1788 return;
1789
1790invalid_opcode:
1791 qemu_log("INVALID(pc = %08x)\n", dc->pc);
1792 dc->pc = dc->next_pc;
1793#undef HAS_OPTION
1794}
1795
1796static void check_breakpoint(CPUState *env, DisasContext *dc)
1797{
1798 CPUBreakpoint *bp;
1799
1800 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
1801 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1802 if (bp->pc == dc->pc) {
1803 tcg_gen_movi_i32(cpu_pc, dc->pc);
1804 gen_exception(EXCP_DEBUG);
1805 dc->is_jmp = DISAS_UPDATE;
1806 }
1807 }
1808 }
1809}
1810
1811static void gen_intermediate_code_internal(
1812 CPUState *env, TranslationBlock *tb, int search_pc)
1813{
1814 DisasContext dc;
1815 int insn_count = 0;
1816 int j, lj = -1;
1817 uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1818 int max_insns = tb->cflags & CF_COUNT_MASK;
1819 uint32_t pc_start = tb->pc;
1820 uint32_t next_page_start =
1821 (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1822
1823 if (max_insns == 0) {
1824 max_insns = CF_COUNT_MASK;
1825 }
1826
1827 dc.config = env->config;
1828 dc.singlestep_enabled = env->singlestep_enabled;
1829 dc.tb = tb;
1830 dc.pc = pc_start;
f0a548b9
MF
1831 dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
1832 dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;
797d780b
MF
1833 dc.lbeg = env->sregs[LBEG];
1834 dc.lend = env->sregs[LEND];
dedc5eae
MF
1835 dc.is_jmp = DISAS_NEXT;
1836
3580ecad
MF
1837 init_sar_tracker(&dc);
1838
dedc5eae
MF
1839 gen_icount_start();
1840
40643d7c
MF
1841 if (env->singlestep_enabled && env->exception_taken) {
1842 env->exception_taken = 0;
1843 tcg_gen_movi_i32(cpu_pc, dc.pc);
1844 gen_exception(EXCP_DEBUG);
1845 }
1846
dedc5eae
MF
1847 do {
1848 check_breakpoint(env, &dc);
1849
1850 if (search_pc) {
1851 j = gen_opc_ptr - gen_opc_buf;
1852 if (lj < j) {
1853 lj++;
1854 while (lj < j) {
1855 gen_opc_instr_start[lj++] = 0;
1856 }
1857 }
1858 gen_opc_pc[lj] = dc.pc;
1859 gen_opc_instr_start[lj] = 1;
1860 gen_opc_icount[lj] = insn_count;
1861 }
1862
1863 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
1864 tcg_gen_debug_insn_start(dc.pc);
1865 }
1866
1867 disas_xtensa_insn(&dc);
1868 ++insn_count;
1869 if (env->singlestep_enabled) {
1870 tcg_gen_movi_i32(cpu_pc, dc.pc);
1871 gen_exception(EXCP_DEBUG);
1872 break;
1873 }
1874 } while (dc.is_jmp == DISAS_NEXT &&
1875 insn_count < max_insns &&
1876 dc.pc < next_page_start &&
1877 gen_opc_ptr < gen_opc_end);
1878
3580ecad
MF
1879 reset_sar_tracker(&dc);
1880
dedc5eae
MF
1881 if (dc.is_jmp == DISAS_NEXT) {
1882 gen_jumpi(&dc, dc.pc, 0);
1883 }
1884 gen_icount_end(tb, insn_count);
1885 *gen_opc_ptr = INDEX_op_end;
1886
1887 if (!search_pc) {
1888 tb->size = dc.pc - pc_start;
1889 tb->icount = insn_count;
1890 }
2328826b
MF
1891}
1892
1893void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
1894{
dedc5eae 1895 gen_intermediate_code_internal(env, tb, 0);
2328826b
MF
1896}
1897
1898void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
1899{
dedc5eae 1900 gen_intermediate_code_internal(env, tb, 1);
2328826b
MF
1901}
1902
1903void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1904 int flags)
1905{
2af3da91
MF
1906 int i, j;
1907
1908 cpu_fprintf(f, "PC=%08x\n\n", env->pc);
1909
1910 for (i = j = 0; i < 256; ++i) {
1911 if (sregnames[i]) {
1912 cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
1913 (j++ % 4) == 3 ? '\n' : ' ');
1914 }
1915 }
1916
1917 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1918
1919 for (i = j = 0; i < 256; ++i) {
1920 if (uregnames[i]) {
1921 cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
1922 (j++ % 4) == 3 ? '\n' : ' ');
1923 }
1924 }
2328826b 1925
2af3da91 1926 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2328826b
MF
1927
1928 for (i = 0; i < 16; ++i) {
1929 cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
1930 (i % 4) == 3 ? '\n' : ' ');
1931 }
553e44f9
MF
1932
1933 cpu_fprintf(f, "\n");
1934
1935 for (i = 0; i < env->config->nareg; ++i) {
1936 cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
1937 (i % 4) == 3 ? '\n' : ' ');
1938 }
2328826b
MF
1939}
1940
1941void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
1942{
1943 env->pc = gen_opc_pc[pc_pos];
1944}