]> git.proxmox.com Git - qemu.git/blame - target-xtensa/translate.c
target-xtensa: mark reserved and TBD opcodes
[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;
48 int is_jmp;
49 int singlestep_enabled;
3580ecad
MF
50
51 bool sar_5bit;
52 bool sar_m32_5bit;
53 bool sar_m32_allocated;
54 TCGv_i32 sar_m32;
dedc5eae
MF
55} DisasContext;
56
57static TCGv_ptr cpu_env;
58static TCGv_i32 cpu_pc;
59static TCGv_i32 cpu_R[16];
2af3da91
MF
60static TCGv_i32 cpu_SR[256];
61static TCGv_i32 cpu_UR[256];
dedc5eae
MF
62
63#include "gen-icount.h"
2328826b 64
2af3da91 65static const char * const sregnames[256] = {
3580ecad 66 [SAR] = "SAR",
809377aa 67 [SCOMPARE1] = "SCOMPARE1",
2af3da91
MF
68};
69
70static const char * const uregnames[256] = {
71 [THREADPTR] = "THREADPTR",
72 [FCR] = "FCR",
73 [FSR] = "FSR",
74};
75
2328826b
MF
76void xtensa_translate_init(void)
77{
dedc5eae
MF
78 static const char * const regnames[] = {
79 "ar0", "ar1", "ar2", "ar3",
80 "ar4", "ar5", "ar6", "ar7",
81 "ar8", "ar9", "ar10", "ar11",
82 "ar12", "ar13", "ar14", "ar15",
83 };
84 int i;
85
86 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
87 cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
88 offsetof(CPUState, pc), "pc");
89
90 for (i = 0; i < 16; i++) {
91 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
92 offsetof(CPUState, regs[i]),
93 regnames[i]);
94 }
2af3da91
MF
95
96 for (i = 0; i < 256; ++i) {
97 if (sregnames[i]) {
98 cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
99 offsetof(CPUState, sregs[i]),
100 sregnames[i]);
101 }
102 }
103
104 for (i = 0; i < 256; ++i) {
105 if (uregnames[i]) {
106 cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
107 offsetof(CPUState, uregs[i]),
108 uregnames[i]);
109 }
110 }
dedc5eae
MF
111#define GEN_HELPER 2
112#include "helpers.h"
113}
114
115static inline bool option_enabled(DisasContext *dc, int opt)
116{
117 return xtensa_option_enabled(dc->config, opt);
118}
119
3580ecad
MF
120static void init_sar_tracker(DisasContext *dc)
121{
122 dc->sar_5bit = false;
123 dc->sar_m32_5bit = false;
124 dc->sar_m32_allocated = false;
125}
126
127static void reset_sar_tracker(DisasContext *dc)
128{
129 if (dc->sar_m32_allocated) {
130 tcg_temp_free(dc->sar_m32);
131 }
132}
133
134static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
135{
136 tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
137 if (dc->sar_m32_5bit) {
138 tcg_gen_discard_i32(dc->sar_m32);
139 }
140 dc->sar_5bit = true;
141 dc->sar_m32_5bit = false;
142}
143
144static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
145{
146 TCGv_i32 tmp = tcg_const_i32(32);
147 if (!dc->sar_m32_allocated) {
148 dc->sar_m32 = tcg_temp_local_new_i32();
149 dc->sar_m32_allocated = true;
150 }
151 tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
152 tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
153 dc->sar_5bit = false;
154 dc->sar_m32_5bit = true;
155 tcg_temp_free(tmp);
156}
157
dedc5eae
MF
158static void gen_exception(int excp)
159{
160 TCGv_i32 tmp = tcg_const_i32(excp);
161 gen_helper_exception(tmp);
162 tcg_temp_free(tmp);
163}
164
165static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
166{
167 tcg_gen_mov_i32(cpu_pc, dest);
168 if (dc->singlestep_enabled) {
169 gen_exception(EXCP_DEBUG);
170 } else {
171 if (slot >= 0) {
172 tcg_gen_goto_tb(slot);
173 tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
174 } else {
175 tcg_gen_exit_tb(0);
176 }
177 }
178 dc->is_jmp = DISAS_UPDATE;
179}
180
67882fd1
MF
181static void gen_jump(DisasContext *dc, TCGv dest)
182{
183 gen_jump_slot(dc, dest, -1);
184}
185
dedc5eae
MF
186static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
187{
188 TCGv_i32 tmp = tcg_const_i32(dest);
189 if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
190 slot = -1;
191 }
192 gen_jump_slot(dc, tmp, slot);
193 tcg_temp_free(tmp);
194}
195
bd57fb91
MF
196static void gen_brcond(DisasContext *dc, TCGCond cond,
197 TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)
198{
199 int label = gen_new_label();
200
201 tcg_gen_brcond_i32(cond, t0, t1, label);
202 gen_jumpi(dc, dc->next_pc, 0);
203 gen_set_label(label);
204 gen_jumpi(dc, dc->pc + offset, 1);
205}
206
207static void gen_brcondi(DisasContext *dc, TCGCond cond,
208 TCGv_i32 t0, uint32_t t1, uint32_t offset)
209{
210 TCGv_i32 tmp = tcg_const_i32(t1);
211 gen_brcond(dc, cond, t0, tmp, offset);
212 tcg_temp_free(tmp);
213}
214
b8132eff
MF
215static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
216{
217 static void (* const rsr_handler[256])(DisasContext *dc,
218 TCGv_i32 d, uint32_t sr) = {
219 };
220
221 if (sregnames[sr]) {
222 if (rsr_handler[sr]) {
223 rsr_handler[sr](dc, d, sr);
224 } else {
225 tcg_gen_mov_i32(d, cpu_SR[sr]);
226 }
227 } else {
228 qemu_log("RSR %d not implemented, ", sr);
229 }
230}
231
3580ecad
MF
232static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
233{
234 tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
235 if (dc->sar_m32_5bit) {
236 tcg_gen_discard_i32(dc->sar_m32);
237 }
238 dc->sar_5bit = false;
239 dc->sar_m32_5bit = false;
240}
241
b8132eff
MF
242static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
243{
244 static void (* const wsr_handler[256])(DisasContext *dc,
245 uint32_t sr, TCGv_i32 v) = {
3580ecad 246 [SAR] = gen_wsr_sar,
b8132eff
MF
247 };
248
249 if (sregnames[sr]) {
250 if (wsr_handler[sr]) {
251 wsr_handler[sr](dc, sr, s);
252 } else {
253 tcg_gen_mov_i32(cpu_SR[sr], s);
254 }
255 } else {
256 qemu_log("WSR %d not implemented, ", sr);
257 }
258}
259
dedc5eae
MF
260static void disas_xtensa_insn(DisasContext *dc)
261{
262#define HAS_OPTION(opt) do { \
263 if (!option_enabled(dc, opt)) { \
264 qemu_log("Option %d is not enabled %s:%d\n", \
265 (opt), __FILE__, __LINE__); \
266 goto invalid_opcode; \
267 } \
268 } while (0)
269
91a5bb76
MF
270#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
271#define RESERVED() do { \
272 qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
273 dc->pc, b0, b1, b2, __FILE__, __LINE__); \
274 goto invalid_opcode; \
275 } while (0)
276
277
dedc5eae
MF
278#ifdef TARGET_WORDS_BIGENDIAN
279#define OP0 (((b0) & 0xf0) >> 4)
280#define OP1 (((b2) & 0xf0) >> 4)
281#define OP2 ((b2) & 0xf)
282#define RRR_R ((b1) & 0xf)
283#define RRR_S (((b1) & 0xf0) >> 4)
284#define RRR_T ((b0) & 0xf)
285#else
286#define OP0 (((b0) & 0xf))
287#define OP1 (((b2) & 0xf))
288#define OP2 (((b2) & 0xf0) >> 4)
289#define RRR_R (((b1) & 0xf0) >> 4)
290#define RRR_S (((b1) & 0xf))
291#define RRR_T (((b0) & 0xf0) >> 4)
292#endif
293
294#define RRRN_R RRR_R
295#define RRRN_S RRR_S
296#define RRRN_T RRR_T
297
298#define RRI8_R RRR_R
299#define RRI8_S RRR_S
300#define RRI8_T RRR_T
301#define RRI8_IMM8 (b2)
302#define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)
303
304#ifdef TARGET_WORDS_BIGENDIAN
305#define RI16_IMM16 (((b1) << 8) | (b2))
306#else
307#define RI16_IMM16 (((b2) << 8) | (b1))
308#endif
309
310#ifdef TARGET_WORDS_BIGENDIAN
311#define CALL_N (((b0) & 0xc) >> 2)
312#define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))
313#else
314#define CALL_N (((b0) & 0x30) >> 4)
315#define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))
316#endif
317#define CALL_OFFSET_SE \
318 (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)
319
320#define CALLX_N CALL_N
321#ifdef TARGET_WORDS_BIGENDIAN
322#define CALLX_M ((b0) & 0x3)
323#else
324#define CALLX_M (((b0) & 0xc0) >> 6)
325#endif
326#define CALLX_S RRR_S
327
328#define BRI12_M CALLX_M
329#define BRI12_S RRR_S
330#ifdef TARGET_WORDS_BIGENDIAN
331#define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))
332#else
333#define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))
334#endif
335#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)
336
337#define BRI8_M BRI12_M
338#define BRI8_R RRI8_R
339#define BRI8_S RRI8_S
340#define BRI8_IMM8 RRI8_IMM8
341#define BRI8_IMM8_SE RRI8_IMM8_SE
342
343#define RSR_SR (b1)
344
345 uint8_t b0 = ldub_code(dc->pc);
346 uint8_t b1 = ldub_code(dc->pc + 1);
347 uint8_t b2 = ldub_code(dc->pc + 2);
348
bd57fb91
MF
349 static const uint32_t B4CONST[] = {
350 0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
351 };
352
353 static const uint32_t B4CONSTU[] = {
354 32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
355 };
356
dedc5eae
MF
357 if (OP0 >= 8) {
358 dc->next_pc = dc->pc + 2;
359 HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
360 } else {
361 dc->next_pc = dc->pc + 3;
362 }
363
364 switch (OP0) {
365 case 0: /*QRST*/
366 switch (OP1) {
367 case 0: /*RST0*/
368 switch (OP2) {
369 case 0: /*ST0*/
370 if ((RRR_R & 0xc) == 0x8) {
371 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
372 }
373
374 switch (RRR_R) {
375 case 0: /*SNM0*/
5da4a6a8
MF
376 switch (CALLX_M) {
377 case 0: /*ILL*/
91a5bb76 378 TBD();
5da4a6a8
MF
379 break;
380
381 case 1: /*reserved*/
91a5bb76 382 RESERVED();
5da4a6a8
MF
383 break;
384
385 case 2: /*JR*/
386 switch (CALLX_N) {
387 case 0: /*RET*/
388 case 2: /*JX*/
389 gen_jump(dc, cpu_R[CALLX_S]);
390 break;
391
392 case 1: /*RETWw*/
393 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 394 TBD();
5da4a6a8
MF
395 break;
396
397 case 3: /*reserved*/
91a5bb76 398 RESERVED();
5da4a6a8
MF
399 break;
400 }
401 break;
402
403 case 3: /*CALLX*/
404 switch (CALLX_N) {
405 case 0: /*CALLX0*/
406 {
407 TCGv_i32 tmp = tcg_temp_new_i32();
408 tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
409 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
410 gen_jump(dc, tmp);
411 tcg_temp_free(tmp);
412 }
413 break;
414
415 case 1: /*CALLX4w*/
416 case 2: /*CALLX8w*/
417 case 3: /*CALLX12w*/
418 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 419 TBD();
5da4a6a8
MF
420 break;
421 }
422 break;
423 }
dedc5eae
MF
424 break;
425
426 case 1: /*MOVSPw*/
427 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 428 TBD();
dedc5eae
MF
429 break;
430
431 case 2: /*SYNC*/
91a5bb76
MF
432 TBD();
433 break;
434
435 case 3: /*RFEIx*/
436 TBD();
437 break;
438
439 case 4: /*BREAKx*/
440 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
441 TBD();
442 break;
443
444 case 5: /*SYSCALLx*/
445 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
446 TBD();
447 break;
448
449 case 6: /*RSILx*/
450 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
451 TBD();
452 break;
453
454 case 7: /*WAITIx*/
455 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
456 TBD();
457 break;
458
459 case 8: /*ANY4p*/
460 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
461 TBD();
462 break;
463
464 case 9: /*ALL4p*/
465 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
466 TBD();
dedc5eae
MF
467 break;
468
91a5bb76
MF
469 case 10: /*ANY8p*/
470 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
471 TBD();
472 break;
473
474 case 11: /*ALL8p*/
475 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
476 TBD();
477 break;
478
479 default: /*reserved*/
480 RESERVED();
dedc5eae
MF
481 break;
482
483 }
484 break;
485
486 case 1: /*AND*/
487 tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
488 break;
489
490 case 2: /*OR*/
491 tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
492 break;
493
494 case 3: /*XOR*/
495 tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
496 break;
497
498 case 4: /*ST1*/
3580ecad
MF
499 switch (RRR_R) {
500 case 0: /*SSR*/
501 gen_right_shift_sar(dc, cpu_R[RRR_S]);
502 break;
503
504 case 1: /*SSL*/
505 gen_left_shift_sar(dc, cpu_R[RRR_S]);
506 break;
507
508 case 2: /*SSA8L*/
509 {
510 TCGv_i32 tmp = tcg_temp_new_i32();
511 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
512 gen_right_shift_sar(dc, tmp);
513 tcg_temp_free(tmp);
514 }
515 break;
516
517 case 3: /*SSA8B*/
518 {
519 TCGv_i32 tmp = tcg_temp_new_i32();
520 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
521 gen_left_shift_sar(dc, tmp);
522 tcg_temp_free(tmp);
523 }
524 break;
525
526 case 4: /*SSAI*/
527 {
528 TCGv_i32 tmp = tcg_const_i32(
529 RRR_S | ((RRR_T & 1) << 4));
530 gen_right_shift_sar(dc, tmp);
531 tcg_temp_free(tmp);
532 }
533 break;
534
535 case 6: /*RER*/
91a5bb76 536 TBD();
3580ecad
MF
537 break;
538
539 case 7: /*WER*/
91a5bb76 540 TBD();
3580ecad
MF
541 break;
542
543 case 8: /*ROTWw*/
544 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 545 TBD();
3580ecad
MF
546 break;
547
548 case 14: /*NSAu*/
549 HAS_OPTION(XTENSA_OPTION_MISC_OP);
550 gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);
551 break;
552
553 case 15: /*NSAUu*/
554 HAS_OPTION(XTENSA_OPTION_MISC_OP);
555 gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);
556 break;
557
558 default: /*reserved*/
91a5bb76 559 RESERVED();
3580ecad
MF
560 break;
561 }
dedc5eae
MF
562 break;
563
564 case 5: /*TLB*/
91a5bb76 565 TBD();
dedc5eae
MF
566 break;
567
568 case 6: /*RT0*/
f331fe5e
MF
569 switch (RRR_S) {
570 case 0: /*NEG*/
571 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
572 break;
573
574 case 1: /*ABS*/
575 {
576 int label = gen_new_label();
577 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
578 tcg_gen_brcondi_i32(
579 TCG_COND_GE, cpu_R[RRR_R], 0, label);
580 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
581 gen_set_label(label);
582 }
583 break;
584
585 default: /*reserved*/
91a5bb76 586 RESERVED();
f331fe5e
MF
587 break;
588 }
dedc5eae
MF
589 break;
590
591 case 7: /*reserved*/
91a5bb76 592 RESERVED();
dedc5eae
MF
593 break;
594
595 case 8: /*ADD*/
596 tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
597 break;
598
599 case 9: /*ADD**/
600 case 10:
601 case 11:
602 {
603 TCGv_i32 tmp = tcg_temp_new_i32();
604 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);
605 tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
606 tcg_temp_free(tmp);
607 }
608 break;
609
610 case 12: /*SUB*/
611 tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
612 break;
613
614 case 13: /*SUB**/
615 case 14:
616 case 15:
617 {
618 TCGv_i32 tmp = tcg_temp_new_i32();
619 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);
620 tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
621 tcg_temp_free(tmp);
622 }
623 break;
624 }
625 break;
626
627 case 1: /*RST1*/
3580ecad
MF
628 switch (OP2) {
629 case 0: /*SLLI*/
630 case 1:
631 tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],
632 32 - (RRR_T | ((OP2 & 1) << 4)));
633 break;
634
635 case 2: /*SRAI*/
636 case 3:
637 tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],
638 RRR_S | ((OP2 & 1) << 4));
639 break;
640
641 case 4: /*SRLI*/
642 tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);
643 break;
644
645 case 6: /*XSR*/
646 {
647 TCGv_i32 tmp = tcg_temp_new_i32();
648 tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
649 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
650 gen_wsr(dc, RSR_SR, tmp);
651 tcg_temp_free(tmp);
91a5bb76
MF
652 if (!sregnames[RSR_SR]) {
653 TBD();
654 }
3580ecad
MF
655 }
656 break;
657
658 /*
659 * Note: 64 bit ops are used here solely because SAR values
660 * have range 0..63
661 */
662#define gen_shift_reg(cmd, reg) do { \
663 TCGv_i64 tmp = tcg_temp_new_i64(); \
664 tcg_gen_extu_i32_i64(tmp, reg); \
665 tcg_gen_##cmd##_i64(v, v, tmp); \
666 tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
667 tcg_temp_free_i64(v); \
668 tcg_temp_free_i64(tmp); \
669 } while (0)
670
671#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
672
673 case 8: /*SRC*/
674 {
675 TCGv_i64 v = tcg_temp_new_i64();
676 tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);
677 gen_shift(shr);
678 }
679 break;
680
681 case 9: /*SRL*/
682 if (dc->sar_5bit) {
683 tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
684 } else {
685 TCGv_i64 v = tcg_temp_new_i64();
686 tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);
687 gen_shift(shr);
688 }
689 break;
690
691 case 10: /*SLL*/
692 if (dc->sar_m32_5bit) {
693 tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);
694 } else {
695 TCGv_i64 v = tcg_temp_new_i64();
696 TCGv_i32 s = tcg_const_i32(32);
697 tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
698 tcg_gen_andi_i32(s, s, 0x3f);
699 tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);
700 gen_shift_reg(shl, s);
701 tcg_temp_free(s);
702 }
703 break;
704
705 case 11: /*SRA*/
706 if (dc->sar_5bit) {
707 tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
708 } else {
709 TCGv_i64 v = tcg_temp_new_i64();
710 tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);
711 gen_shift(sar);
712 }
713 break;
714#undef gen_shift
715#undef gen_shift_reg
716
717 case 12: /*MUL16U*/
718 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
719 {
720 TCGv_i32 v1 = tcg_temp_new_i32();
721 TCGv_i32 v2 = tcg_temp_new_i32();
722 tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);
723 tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);
724 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
725 tcg_temp_free(v2);
726 tcg_temp_free(v1);
727 }
728 break;
729
730 case 13: /*MUL16S*/
731 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
732 {
733 TCGv_i32 v1 = tcg_temp_new_i32();
734 TCGv_i32 v2 = tcg_temp_new_i32();
735 tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);
736 tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);
737 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
738 tcg_temp_free(v2);
739 tcg_temp_free(v1);
740 }
741 break;
742
743 default: /*reserved*/
91a5bb76 744 RESERVED();
3580ecad
MF
745 break;
746 }
dedc5eae
MF
747 break;
748
749 case 2: /*RST2*/
91a5bb76 750 TBD();
dedc5eae
MF
751 break;
752
753 case 3: /*RST3*/
b8132eff
MF
754 switch (OP2) {
755 case 0: /*RSR*/
756 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
91a5bb76
MF
757 if (!sregnames[RSR_SR]) {
758 TBD();
759 }
b8132eff
MF
760 break;
761
762 case 1: /*WSR*/
763 gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
91a5bb76
MF
764 if (!sregnames[RSR_SR]) {
765 TBD();
766 }
b8132eff
MF
767 break;
768
769 case 2: /*SEXTu*/
770 HAS_OPTION(XTENSA_OPTION_MISC_OP);
771 {
772 int shift = 24 - RRR_T;
773
774 if (shift == 24) {
775 tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
776 } else if (shift == 16) {
777 tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
778 } else {
779 TCGv_i32 tmp = tcg_temp_new_i32();
780 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);
781 tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);
782 tcg_temp_free(tmp);
783 }
784 }
785 break;
786
787 case 3: /*CLAMPSu*/
788 HAS_OPTION(XTENSA_OPTION_MISC_OP);
789 {
790 TCGv_i32 tmp1 = tcg_temp_new_i32();
791 TCGv_i32 tmp2 = tcg_temp_new_i32();
792 int label = gen_new_label();
793
794 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
795 tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
796 tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
797 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
798 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
799
800 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
801 tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
802 0xffffffff >> (25 - RRR_T));
803
804 gen_set_label(label);
805
806 tcg_temp_free(tmp1);
807 tcg_temp_free(tmp2);
808 }
809 break;
810
811 case 4: /*MINu*/
812 case 5: /*MAXu*/
813 case 6: /*MINUu*/
814 case 7: /*MAXUu*/
815 HAS_OPTION(XTENSA_OPTION_MISC_OP);
816 {
817 static const TCGCond cond[] = {
818 TCG_COND_LE,
819 TCG_COND_GE,
820 TCG_COND_LEU,
821 TCG_COND_GEU
822 };
823 int label = gen_new_label();
824
825 if (RRR_R != RRR_T) {
826 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
827 tcg_gen_brcond_i32(cond[OP2 - 4],
828 cpu_R[RRR_S], cpu_R[RRR_T], label);
829 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
830 } else {
831 tcg_gen_brcond_i32(cond[OP2 - 4],
832 cpu_R[RRR_T], cpu_R[RRR_S], label);
833 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
834 }
835 gen_set_label(label);
836 }
837 break;
838
839 case 8: /*MOVEQZ*/
840 case 9: /*MOVNEZ*/
841 case 10: /*MOVLTZ*/
842 case 11: /*MOVGEZ*/
843 {
844 static const TCGCond cond[] = {
845 TCG_COND_NE,
846 TCG_COND_EQ,
847 TCG_COND_GE,
848 TCG_COND_LT
849 };
850 int label = gen_new_label();
851 tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
852 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
853 gen_set_label(label);
854 }
855 break;
856
857 case 12: /*MOVFp*/
858 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 859 TBD();
b8132eff
MF
860 break;
861
862 case 13: /*MOVTp*/
863 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 864 TBD();
b8132eff
MF
865 break;
866
867 case 14: /*RUR*/
868 {
869 int st = (RRR_S << 4) + RRR_T;
870 if (uregnames[st]) {
871 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
872 } else {
873 qemu_log("RUR %d not implemented, ", st);
91a5bb76 874 TBD();
b8132eff
MF
875 }
876 }
877 break;
878
879 case 15: /*WUR*/
880 {
881 if (uregnames[RSR_SR]) {
882 tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);
883 } else {
884 qemu_log("WUR %d not implemented, ", RSR_SR);
91a5bb76 885 TBD();
b8132eff
MF
886 }
887 }
888 break;
889
890 }
dedc5eae
MF
891 break;
892
893 case 4: /*EXTUI*/
894 case 5:
3580ecad
MF
895 {
896 int shiftimm = RRR_S | (OP1 << 4);
897 int maskimm = (1 << (OP2 + 1)) - 1;
898
899 TCGv_i32 tmp = tcg_temp_new_i32();
900 tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
901 tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
902 tcg_temp_free(tmp);
903 }
dedc5eae
MF
904 break;
905
906 case 6: /*CUST0*/
91a5bb76 907 RESERVED();
dedc5eae
MF
908 break;
909
910 case 7: /*CUST1*/
91a5bb76 911 RESERVED();
dedc5eae
MF
912 break;
913
914 case 8: /*LSCXp*/
915 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
91a5bb76 916 TBD();
dedc5eae
MF
917 break;
918
919 case 9: /*LSC4*/
91a5bb76 920 TBD();
dedc5eae
MF
921 break;
922
923 case 10: /*FP0*/
924 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
91a5bb76 925 TBD();
dedc5eae
MF
926 break;
927
928 case 11: /*FP1*/
929 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
91a5bb76 930 TBD();
dedc5eae
MF
931 break;
932
933 default: /*reserved*/
91a5bb76 934 RESERVED();
dedc5eae
MF
935 break;
936 }
937 break;
938
939 case 1: /*L32R*/
940 {
941 TCGv_i32 tmp = tcg_const_i32(
942 (0xfffc0000 | (RI16_IMM16 << 2)) +
943 ((dc->pc + 3) & ~3));
944
945 /* no ext L32R */
946
947 tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, 0);
948 tcg_temp_free(tmp);
949 }
950 break;
951
952 case 2: /*LSAI*/
809377aa
MF
953#define gen_load_store(type, shift) do { \
954 TCGv_i32 addr = tcg_temp_new_i32(); \
955 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
956 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, 0); \
957 tcg_temp_free(addr); \
958 } while (0)
959
960 switch (RRI8_R) {
961 case 0: /*L8UI*/
962 gen_load_store(ld8u, 0);
963 break;
964
965 case 1: /*L16UI*/
966 gen_load_store(ld16u, 1);
967 break;
968
969 case 2: /*L32I*/
970 gen_load_store(ld32u, 2);
971 break;
972
973 case 4: /*S8I*/
974 gen_load_store(st8, 0);
975 break;
976
977 case 5: /*S16I*/
978 gen_load_store(st16, 1);
979 break;
980
981 case 6: /*S32I*/
982 gen_load_store(st32, 2);
983 break;
984
985 case 7: /*CACHEc*/
91a5bb76 986 TBD();
809377aa
MF
987 break;
988
989 case 9: /*L16SI*/
990 gen_load_store(ld16s, 1);
991 break;
992
993 case 10: /*MOVI*/
994 tcg_gen_movi_i32(cpu_R[RRI8_T],
995 RRI8_IMM8 | (RRI8_S << 8) |
996 ((RRI8_S & 0x8) ? 0xfffff000 : 0));
997 break;
998
999 case 11: /*L32AIy*/
1000 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1001 gen_load_store(ld32u, 2); /*TODO acquire?*/
1002 break;
1003
1004 case 12: /*ADDI*/
1005 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);
1006 break;
1007
1008 case 13: /*ADDMI*/
1009 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);
1010 break;
1011
1012 case 14: /*S32C1Iy*/
1013 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1014 {
1015 int label = gen_new_label();
1016 TCGv_i32 tmp = tcg_temp_local_new_i32();
1017 TCGv_i32 addr = tcg_temp_local_new_i32();
1018
1019 tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
1020 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
1021 tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, 0);
1022 tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
1023 cpu_SR[SCOMPARE1], label);
1024
1025 tcg_gen_qemu_st32(tmp, addr, 0);
1026
1027 gen_set_label(label);
1028 tcg_temp_free(addr);
1029 tcg_temp_free(tmp);
1030 }
1031 break;
1032
1033 case 15: /*S32RIy*/
1034 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1035 gen_load_store(st32, 2); /*TODO release?*/
1036 break;
1037
1038 default: /*reserved*/
91a5bb76 1039 RESERVED();
809377aa
MF
1040 break;
1041 }
dedc5eae 1042 break;
809377aa 1043#undef gen_load_store
dedc5eae
MF
1044
1045 case 3: /*LSCIp*/
1046 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
91a5bb76 1047 TBD();
dedc5eae
MF
1048 break;
1049
1050 case 4: /*MAC16d*/
1051 HAS_OPTION(XTENSA_OPTION_MAC16);
91a5bb76 1052 TBD();
dedc5eae
MF
1053 break;
1054
1055 case 5: /*CALLN*/
1056 switch (CALL_N) {
1057 case 0: /*CALL0*/
1058 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
1059 gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
1060 break;
1061
1062 case 1: /*CALL4w*/
1063 case 2: /*CALL8w*/
1064 case 3: /*CALL12w*/
1065 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 1066 TBD();
dedc5eae
MF
1067 break;
1068 }
1069 break;
1070
1071 case 6: /*SI*/
1072 switch (CALL_N) {
1073 case 0: /*J*/
1074 gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);
1075 break;
1076
bd57fb91
MF
1077 case 1: /*BZ*/
1078 {
1079 static const TCGCond cond[] = {
1080 TCG_COND_EQ, /*BEQZ*/
1081 TCG_COND_NE, /*BNEZ*/
1082 TCG_COND_LT, /*BLTZ*/
1083 TCG_COND_GE, /*BGEZ*/
1084 };
1085
1086 gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,
1087 4 + BRI12_IMM12_SE);
1088 }
1089 break;
1090
1091 case 2: /*BI0*/
1092 {
1093 static const TCGCond cond[] = {
1094 TCG_COND_EQ, /*BEQI*/
1095 TCG_COND_NE, /*BNEI*/
1096 TCG_COND_LT, /*BLTI*/
1097 TCG_COND_GE, /*BGEI*/
1098 };
1099
1100 gen_brcondi(dc, cond[BRI8_M & 3],
1101 cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);
1102 }
1103 break;
1104
1105 case 3: /*BI1*/
1106 switch (BRI8_M) {
1107 case 0: /*ENTRYw*/
1108 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 1109 TBD();
bd57fb91
MF
1110 break;
1111
1112 case 1: /*B1*/
1113 switch (BRI8_R) {
1114 case 0: /*BFp*/
1115 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1116 TBD();
bd57fb91
MF
1117 break;
1118
1119 case 1: /*BTp*/
1120 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1121 TBD();
bd57fb91
MF
1122 break;
1123
1124 case 8: /*LOOP*/
91a5bb76 1125 TBD();
bd57fb91
MF
1126 break;
1127
1128 case 9: /*LOOPNEZ*/
91a5bb76 1129 TBD();
bd57fb91
MF
1130 break;
1131
1132 case 10: /*LOOPGTZ*/
91a5bb76 1133 TBD();
bd57fb91
MF
1134 break;
1135
1136 default: /*reserved*/
91a5bb76 1137 RESERVED();
bd57fb91
MF
1138 break;
1139
1140 }
1141 break;
1142
1143 case 2: /*BLTUI*/
1144 case 3: /*BGEUI*/
1145 gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,
1146 cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);
1147 break;
1148 }
1149 break;
1150
dedc5eae
MF
1151 }
1152 break;
1153
1154 case 7: /*B*/
bd57fb91
MF
1155 {
1156 TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;
1157
1158 switch (RRI8_R & 7) {
1159 case 0: /*BNONE*/ /*BANY*/
1160 {
1161 TCGv_i32 tmp = tcg_temp_new_i32();
1162 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
1163 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1164 tcg_temp_free(tmp);
1165 }
1166 break;
1167
1168 case 1: /*BEQ*/ /*BNE*/
1169 case 2: /*BLT*/ /*BGE*/
1170 case 3: /*BLTU*/ /*BGEU*/
1171 {
1172 static const TCGCond cond[] = {
1173 [1] = TCG_COND_EQ,
1174 [2] = TCG_COND_LT,
1175 [3] = TCG_COND_LTU,
1176 [9] = TCG_COND_NE,
1177 [10] = TCG_COND_GE,
1178 [11] = TCG_COND_GEU,
1179 };
1180 gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],
1181 4 + RRI8_IMM8_SE);
1182 }
1183 break;
1184
1185 case 4: /*BALL*/ /*BNALL*/
1186 {
1187 TCGv_i32 tmp = tcg_temp_new_i32();
1188 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
1189 gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],
1190 4 + RRI8_IMM8_SE);
1191 tcg_temp_free(tmp);
1192 }
1193 break;
1194
1195 case 5: /*BBC*/ /*BBS*/
1196 {
1197 TCGv_i32 bit = tcg_const_i32(1);
1198 TCGv_i32 tmp = tcg_temp_new_i32();
1199 tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);
1200 tcg_gen_shl_i32(bit, bit, tmp);
1201 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);
1202 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1203 tcg_temp_free(tmp);
1204 tcg_temp_free(bit);
1205 }
1206 break;
1207
1208 case 6: /*BBCI*/ /*BBSI*/
1209 case 7:
1210 {
1211 TCGv_i32 tmp = tcg_temp_new_i32();
1212 tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],
1213 1 << (((RRI8_R & 1) << 4) | RRI8_T));
1214 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1215 tcg_temp_free(tmp);
1216 }
1217 break;
1218
1219 }
1220 }
dedc5eae
MF
1221 break;
1222
67882fd1
MF
1223#define gen_narrow_load_store(type) do { \
1224 TCGv_i32 addr = tcg_temp_new_i32(); \
1225 tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
1226 tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, 0); \
1227 tcg_temp_free(addr); \
1228 } while (0)
1229
dedc5eae 1230 case 8: /*L32I.Nn*/
67882fd1 1231 gen_narrow_load_store(ld32u);
dedc5eae
MF
1232 break;
1233
1234 case 9: /*S32I.Nn*/
67882fd1 1235 gen_narrow_load_store(st32);
dedc5eae 1236 break;
67882fd1 1237#undef gen_narrow_load_store
dedc5eae
MF
1238
1239 case 10: /*ADD.Nn*/
67882fd1 1240 tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);
dedc5eae
MF
1241 break;
1242
1243 case 11: /*ADDI.Nn*/
67882fd1 1244 tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);
dedc5eae
MF
1245 break;
1246
1247 case 12: /*ST2n*/
67882fd1
MF
1248 if (RRRN_T < 8) { /*MOVI.Nn*/
1249 tcg_gen_movi_i32(cpu_R[RRRN_S],
1250 RRRN_R | (RRRN_T << 4) |
1251 ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));
1252 } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
bd57fb91
MF
1253 TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;
1254
1255 gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,
1256 4 + (RRRN_R | ((RRRN_T & 3) << 4)));
67882fd1 1257 }
dedc5eae
MF
1258 break;
1259
1260 case 13: /*ST3n*/
67882fd1
MF
1261 switch (RRRN_R) {
1262 case 0: /*MOV.Nn*/
1263 tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);
1264 break;
1265
1266 case 15: /*S3*/
1267 switch (RRRN_T) {
1268 case 0: /*RET.Nn*/
1269 gen_jump(dc, cpu_R[0]);
1270 break;
1271
1272 case 1: /*RETW.Nn*/
91a5bb76
MF
1273 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1274 TBD();
67882fd1
MF
1275 break;
1276
1277 case 2: /*BREAK.Nn*/
91a5bb76 1278 TBD();
67882fd1
MF
1279 break;
1280
1281 case 3: /*NOP.Nn*/
1282 break;
1283
1284 case 6: /*ILL.Nn*/
91a5bb76 1285 TBD();
67882fd1
MF
1286 break;
1287
1288 default: /*reserved*/
91a5bb76 1289 RESERVED();
67882fd1
MF
1290 break;
1291 }
1292 break;
1293
1294 default: /*reserved*/
91a5bb76 1295 RESERVED();
67882fd1
MF
1296 break;
1297 }
dedc5eae
MF
1298 break;
1299
1300 default: /*reserved*/
91a5bb76 1301 RESERVED();
dedc5eae
MF
1302 break;
1303 }
1304
1305 dc->pc = dc->next_pc;
1306 return;
1307
1308invalid_opcode:
1309 qemu_log("INVALID(pc = %08x)\n", dc->pc);
1310 dc->pc = dc->next_pc;
1311#undef HAS_OPTION
1312}
1313
1314static void check_breakpoint(CPUState *env, DisasContext *dc)
1315{
1316 CPUBreakpoint *bp;
1317
1318 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
1319 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1320 if (bp->pc == dc->pc) {
1321 tcg_gen_movi_i32(cpu_pc, dc->pc);
1322 gen_exception(EXCP_DEBUG);
1323 dc->is_jmp = DISAS_UPDATE;
1324 }
1325 }
1326 }
1327}
1328
1329static void gen_intermediate_code_internal(
1330 CPUState *env, TranslationBlock *tb, int search_pc)
1331{
1332 DisasContext dc;
1333 int insn_count = 0;
1334 int j, lj = -1;
1335 uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1336 int max_insns = tb->cflags & CF_COUNT_MASK;
1337 uint32_t pc_start = tb->pc;
1338 uint32_t next_page_start =
1339 (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1340
1341 if (max_insns == 0) {
1342 max_insns = CF_COUNT_MASK;
1343 }
1344
1345 dc.config = env->config;
1346 dc.singlestep_enabled = env->singlestep_enabled;
1347 dc.tb = tb;
1348 dc.pc = pc_start;
1349 dc.is_jmp = DISAS_NEXT;
1350
3580ecad
MF
1351 init_sar_tracker(&dc);
1352
dedc5eae
MF
1353 gen_icount_start();
1354
1355 do {
1356 check_breakpoint(env, &dc);
1357
1358 if (search_pc) {
1359 j = gen_opc_ptr - gen_opc_buf;
1360 if (lj < j) {
1361 lj++;
1362 while (lj < j) {
1363 gen_opc_instr_start[lj++] = 0;
1364 }
1365 }
1366 gen_opc_pc[lj] = dc.pc;
1367 gen_opc_instr_start[lj] = 1;
1368 gen_opc_icount[lj] = insn_count;
1369 }
1370
1371 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
1372 tcg_gen_debug_insn_start(dc.pc);
1373 }
1374
1375 disas_xtensa_insn(&dc);
1376 ++insn_count;
1377 if (env->singlestep_enabled) {
1378 tcg_gen_movi_i32(cpu_pc, dc.pc);
1379 gen_exception(EXCP_DEBUG);
1380 break;
1381 }
1382 } while (dc.is_jmp == DISAS_NEXT &&
1383 insn_count < max_insns &&
1384 dc.pc < next_page_start &&
1385 gen_opc_ptr < gen_opc_end);
1386
3580ecad
MF
1387 reset_sar_tracker(&dc);
1388
dedc5eae
MF
1389 if (dc.is_jmp == DISAS_NEXT) {
1390 gen_jumpi(&dc, dc.pc, 0);
1391 }
1392 gen_icount_end(tb, insn_count);
1393 *gen_opc_ptr = INDEX_op_end;
1394
1395 if (!search_pc) {
1396 tb->size = dc.pc - pc_start;
1397 tb->icount = insn_count;
1398 }
2328826b
MF
1399}
1400
1401void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
1402{
dedc5eae 1403 gen_intermediate_code_internal(env, tb, 0);
2328826b
MF
1404}
1405
1406void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
1407{
dedc5eae 1408 gen_intermediate_code_internal(env, tb, 1);
2328826b
MF
1409}
1410
1411void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1412 int flags)
1413{
2af3da91
MF
1414 int i, j;
1415
1416 cpu_fprintf(f, "PC=%08x\n\n", env->pc);
1417
1418 for (i = j = 0; i < 256; ++i) {
1419 if (sregnames[i]) {
1420 cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
1421 (j++ % 4) == 3 ? '\n' : ' ');
1422 }
1423 }
1424
1425 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1426
1427 for (i = j = 0; i < 256; ++i) {
1428 if (uregnames[i]) {
1429 cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
1430 (j++ % 4) == 3 ? '\n' : ' ');
1431 }
1432 }
2328826b 1433
2af3da91 1434 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2328826b
MF
1435
1436 for (i = 0; i < 16; ++i) {
1437 cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
1438 (i % 4) == 3 ? '\n' : ' ');
1439 }
1440}
1441
1442void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
1443{
1444 env->pc = gen_opc_pc[pc_pos];
1445}