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