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