]> git.proxmox.com Git - qemu.git/blame - target-xtensa/translate.c
target-xtensa: implement CACHE group
[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*/
28067b22
MF
432 switch (RRR_T) {
433 case 0: /*ISYNC*/
434 break;
435
436 case 1: /*RSYNC*/
437 break;
438
439 case 2: /*ESYNC*/
440 break;
441
442 case 3: /*DSYNC*/
443 break;
444
445 case 8: /*EXCW*/
446 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
447 break;
448
449 case 12: /*MEMW*/
450 break;
451
452 case 13: /*EXTW*/
453 break;
454
455 case 15: /*NOP*/
456 break;
457
458 default: /*reserved*/
459 RESERVED();
460 break;
461 }
91a5bb76
MF
462 break;
463
464 case 3: /*RFEIx*/
465 TBD();
466 break;
467
468 case 4: /*BREAKx*/
469 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
470 TBD();
471 break;
472
473 case 5: /*SYSCALLx*/
474 HAS_OPTION(XTENSA_OPTION_EXCEPTION);
475 TBD();
476 break;
477
478 case 6: /*RSILx*/
479 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
480 TBD();
481 break;
482
483 case 7: /*WAITIx*/
484 HAS_OPTION(XTENSA_OPTION_INTERRUPT);
485 TBD();
486 break;
487
488 case 8: /*ANY4p*/
489 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
490 TBD();
491 break;
492
493 case 9: /*ALL4p*/
494 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
495 TBD();
dedc5eae
MF
496 break;
497
91a5bb76
MF
498 case 10: /*ANY8p*/
499 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
500 TBD();
501 break;
502
503 case 11: /*ALL8p*/
504 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
505 TBD();
506 break;
507
508 default: /*reserved*/
509 RESERVED();
dedc5eae
MF
510 break;
511
512 }
513 break;
514
515 case 1: /*AND*/
516 tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
517 break;
518
519 case 2: /*OR*/
520 tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
521 break;
522
523 case 3: /*XOR*/
524 tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
525 break;
526
527 case 4: /*ST1*/
3580ecad
MF
528 switch (RRR_R) {
529 case 0: /*SSR*/
530 gen_right_shift_sar(dc, cpu_R[RRR_S]);
531 break;
532
533 case 1: /*SSL*/
534 gen_left_shift_sar(dc, cpu_R[RRR_S]);
535 break;
536
537 case 2: /*SSA8L*/
538 {
539 TCGv_i32 tmp = tcg_temp_new_i32();
540 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
541 gen_right_shift_sar(dc, tmp);
542 tcg_temp_free(tmp);
543 }
544 break;
545
546 case 3: /*SSA8B*/
547 {
548 TCGv_i32 tmp = tcg_temp_new_i32();
549 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
550 gen_left_shift_sar(dc, tmp);
551 tcg_temp_free(tmp);
552 }
553 break;
554
555 case 4: /*SSAI*/
556 {
557 TCGv_i32 tmp = tcg_const_i32(
558 RRR_S | ((RRR_T & 1) << 4));
559 gen_right_shift_sar(dc, tmp);
560 tcg_temp_free(tmp);
561 }
562 break;
563
564 case 6: /*RER*/
91a5bb76 565 TBD();
3580ecad
MF
566 break;
567
568 case 7: /*WER*/
91a5bb76 569 TBD();
3580ecad
MF
570 break;
571
572 case 8: /*ROTWw*/
573 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 574 TBD();
3580ecad
MF
575 break;
576
577 case 14: /*NSAu*/
578 HAS_OPTION(XTENSA_OPTION_MISC_OP);
579 gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);
580 break;
581
582 case 15: /*NSAUu*/
583 HAS_OPTION(XTENSA_OPTION_MISC_OP);
584 gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);
585 break;
586
587 default: /*reserved*/
91a5bb76 588 RESERVED();
3580ecad
MF
589 break;
590 }
dedc5eae
MF
591 break;
592
593 case 5: /*TLB*/
91a5bb76 594 TBD();
dedc5eae
MF
595 break;
596
597 case 6: /*RT0*/
f331fe5e
MF
598 switch (RRR_S) {
599 case 0: /*NEG*/
600 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
601 break;
602
603 case 1: /*ABS*/
604 {
605 int label = gen_new_label();
606 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
607 tcg_gen_brcondi_i32(
608 TCG_COND_GE, cpu_R[RRR_R], 0, label);
609 tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
610 gen_set_label(label);
611 }
612 break;
613
614 default: /*reserved*/
91a5bb76 615 RESERVED();
f331fe5e
MF
616 break;
617 }
dedc5eae
MF
618 break;
619
620 case 7: /*reserved*/
91a5bb76 621 RESERVED();
dedc5eae
MF
622 break;
623
624 case 8: /*ADD*/
625 tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
626 break;
627
628 case 9: /*ADD**/
629 case 10:
630 case 11:
631 {
632 TCGv_i32 tmp = tcg_temp_new_i32();
633 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);
634 tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
635 tcg_temp_free(tmp);
636 }
637 break;
638
639 case 12: /*SUB*/
640 tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
641 break;
642
643 case 13: /*SUB**/
644 case 14:
645 case 15:
646 {
647 TCGv_i32 tmp = tcg_temp_new_i32();
648 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);
649 tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
650 tcg_temp_free(tmp);
651 }
652 break;
653 }
654 break;
655
656 case 1: /*RST1*/
3580ecad
MF
657 switch (OP2) {
658 case 0: /*SLLI*/
659 case 1:
660 tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],
661 32 - (RRR_T | ((OP2 & 1) << 4)));
662 break;
663
664 case 2: /*SRAI*/
665 case 3:
666 tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],
667 RRR_S | ((OP2 & 1) << 4));
668 break;
669
670 case 4: /*SRLI*/
671 tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);
672 break;
673
674 case 6: /*XSR*/
675 {
676 TCGv_i32 tmp = tcg_temp_new_i32();
677 tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
678 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
679 gen_wsr(dc, RSR_SR, tmp);
680 tcg_temp_free(tmp);
91a5bb76
MF
681 if (!sregnames[RSR_SR]) {
682 TBD();
683 }
3580ecad
MF
684 }
685 break;
686
687 /*
688 * Note: 64 bit ops are used here solely because SAR values
689 * have range 0..63
690 */
691#define gen_shift_reg(cmd, reg) do { \
692 TCGv_i64 tmp = tcg_temp_new_i64(); \
693 tcg_gen_extu_i32_i64(tmp, reg); \
694 tcg_gen_##cmd##_i64(v, v, tmp); \
695 tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
696 tcg_temp_free_i64(v); \
697 tcg_temp_free_i64(tmp); \
698 } while (0)
699
700#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
701
702 case 8: /*SRC*/
703 {
704 TCGv_i64 v = tcg_temp_new_i64();
705 tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);
706 gen_shift(shr);
707 }
708 break;
709
710 case 9: /*SRL*/
711 if (dc->sar_5bit) {
712 tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
713 } else {
714 TCGv_i64 v = tcg_temp_new_i64();
715 tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);
716 gen_shift(shr);
717 }
718 break;
719
720 case 10: /*SLL*/
721 if (dc->sar_m32_5bit) {
722 tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);
723 } else {
724 TCGv_i64 v = tcg_temp_new_i64();
725 TCGv_i32 s = tcg_const_i32(32);
726 tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
727 tcg_gen_andi_i32(s, s, 0x3f);
728 tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);
729 gen_shift_reg(shl, s);
730 tcg_temp_free(s);
731 }
732 break;
733
734 case 11: /*SRA*/
735 if (dc->sar_5bit) {
736 tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
737 } else {
738 TCGv_i64 v = tcg_temp_new_i64();
739 tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);
740 gen_shift(sar);
741 }
742 break;
743#undef gen_shift
744#undef gen_shift_reg
745
746 case 12: /*MUL16U*/
747 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
748 {
749 TCGv_i32 v1 = tcg_temp_new_i32();
750 TCGv_i32 v2 = tcg_temp_new_i32();
751 tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);
752 tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);
753 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
754 tcg_temp_free(v2);
755 tcg_temp_free(v1);
756 }
757 break;
758
759 case 13: /*MUL16S*/
760 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
761 {
762 TCGv_i32 v1 = tcg_temp_new_i32();
763 TCGv_i32 v2 = tcg_temp_new_i32();
764 tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);
765 tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);
766 tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
767 tcg_temp_free(v2);
768 tcg_temp_free(v1);
769 }
770 break;
771
772 default: /*reserved*/
91a5bb76 773 RESERVED();
3580ecad
MF
774 break;
775 }
dedc5eae
MF
776 break;
777
778 case 2: /*RST2*/
91a5bb76 779 TBD();
dedc5eae
MF
780 break;
781
782 case 3: /*RST3*/
b8132eff
MF
783 switch (OP2) {
784 case 0: /*RSR*/
785 gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
91a5bb76
MF
786 if (!sregnames[RSR_SR]) {
787 TBD();
788 }
b8132eff
MF
789 break;
790
791 case 1: /*WSR*/
792 gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
91a5bb76
MF
793 if (!sregnames[RSR_SR]) {
794 TBD();
795 }
b8132eff
MF
796 break;
797
798 case 2: /*SEXTu*/
799 HAS_OPTION(XTENSA_OPTION_MISC_OP);
800 {
801 int shift = 24 - RRR_T;
802
803 if (shift == 24) {
804 tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
805 } else if (shift == 16) {
806 tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
807 } else {
808 TCGv_i32 tmp = tcg_temp_new_i32();
809 tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);
810 tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);
811 tcg_temp_free(tmp);
812 }
813 }
814 break;
815
816 case 3: /*CLAMPSu*/
817 HAS_OPTION(XTENSA_OPTION_MISC_OP);
818 {
819 TCGv_i32 tmp1 = tcg_temp_new_i32();
820 TCGv_i32 tmp2 = tcg_temp_new_i32();
821 int label = gen_new_label();
822
823 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
824 tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
825 tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
826 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
827 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
828
829 tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
830 tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
831 0xffffffff >> (25 - RRR_T));
832
833 gen_set_label(label);
834
835 tcg_temp_free(tmp1);
836 tcg_temp_free(tmp2);
837 }
838 break;
839
840 case 4: /*MINu*/
841 case 5: /*MAXu*/
842 case 6: /*MINUu*/
843 case 7: /*MAXUu*/
844 HAS_OPTION(XTENSA_OPTION_MISC_OP);
845 {
846 static const TCGCond cond[] = {
847 TCG_COND_LE,
848 TCG_COND_GE,
849 TCG_COND_LEU,
850 TCG_COND_GEU
851 };
852 int label = gen_new_label();
853
854 if (RRR_R != RRR_T) {
855 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
856 tcg_gen_brcond_i32(cond[OP2 - 4],
857 cpu_R[RRR_S], cpu_R[RRR_T], label);
858 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
859 } else {
860 tcg_gen_brcond_i32(cond[OP2 - 4],
861 cpu_R[RRR_T], cpu_R[RRR_S], label);
862 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
863 }
864 gen_set_label(label);
865 }
866 break;
867
868 case 8: /*MOVEQZ*/
869 case 9: /*MOVNEZ*/
870 case 10: /*MOVLTZ*/
871 case 11: /*MOVGEZ*/
872 {
873 static const TCGCond cond[] = {
874 TCG_COND_NE,
875 TCG_COND_EQ,
876 TCG_COND_GE,
877 TCG_COND_LT
878 };
879 int label = gen_new_label();
880 tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
881 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
882 gen_set_label(label);
883 }
884 break;
885
886 case 12: /*MOVFp*/
887 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 888 TBD();
b8132eff
MF
889 break;
890
891 case 13: /*MOVTp*/
892 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 893 TBD();
b8132eff
MF
894 break;
895
896 case 14: /*RUR*/
897 {
898 int st = (RRR_S << 4) + RRR_T;
899 if (uregnames[st]) {
900 tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
901 } else {
902 qemu_log("RUR %d not implemented, ", st);
91a5bb76 903 TBD();
b8132eff
MF
904 }
905 }
906 break;
907
908 case 15: /*WUR*/
909 {
910 if (uregnames[RSR_SR]) {
911 tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);
912 } else {
913 qemu_log("WUR %d not implemented, ", RSR_SR);
91a5bb76 914 TBD();
b8132eff
MF
915 }
916 }
917 break;
918
919 }
dedc5eae
MF
920 break;
921
922 case 4: /*EXTUI*/
923 case 5:
3580ecad
MF
924 {
925 int shiftimm = RRR_S | (OP1 << 4);
926 int maskimm = (1 << (OP2 + 1)) - 1;
927
928 TCGv_i32 tmp = tcg_temp_new_i32();
929 tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
930 tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
931 tcg_temp_free(tmp);
932 }
dedc5eae
MF
933 break;
934
935 case 6: /*CUST0*/
91a5bb76 936 RESERVED();
dedc5eae
MF
937 break;
938
939 case 7: /*CUST1*/
91a5bb76 940 RESERVED();
dedc5eae
MF
941 break;
942
943 case 8: /*LSCXp*/
944 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
91a5bb76 945 TBD();
dedc5eae
MF
946 break;
947
948 case 9: /*LSC4*/
91a5bb76 949 TBD();
dedc5eae
MF
950 break;
951
952 case 10: /*FP0*/
953 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
91a5bb76 954 TBD();
dedc5eae
MF
955 break;
956
957 case 11: /*FP1*/
958 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
91a5bb76 959 TBD();
dedc5eae
MF
960 break;
961
962 default: /*reserved*/
91a5bb76 963 RESERVED();
dedc5eae
MF
964 break;
965 }
966 break;
967
968 case 1: /*L32R*/
969 {
970 TCGv_i32 tmp = tcg_const_i32(
971 (0xfffc0000 | (RI16_IMM16 << 2)) +
972 ((dc->pc + 3) & ~3));
973
974 /* no ext L32R */
975
976 tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, 0);
977 tcg_temp_free(tmp);
978 }
979 break;
980
981 case 2: /*LSAI*/
809377aa
MF
982#define gen_load_store(type, shift) do { \
983 TCGv_i32 addr = tcg_temp_new_i32(); \
984 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
985 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, 0); \
986 tcg_temp_free(addr); \
987 } while (0)
988
989 switch (RRI8_R) {
990 case 0: /*L8UI*/
991 gen_load_store(ld8u, 0);
992 break;
993
994 case 1: /*L16UI*/
995 gen_load_store(ld16u, 1);
996 break;
997
998 case 2: /*L32I*/
999 gen_load_store(ld32u, 2);
1000 break;
1001
1002 case 4: /*S8I*/
1003 gen_load_store(st8, 0);
1004 break;
1005
1006 case 5: /*S16I*/
1007 gen_load_store(st16, 1);
1008 break;
1009
1010 case 6: /*S32I*/
1011 gen_load_store(st32, 2);
1012 break;
1013
1014 case 7: /*CACHEc*/
8ffc2d0d
MF
1015 if (RRI8_T < 8) {
1016 HAS_OPTION(XTENSA_OPTION_DCACHE);
1017 }
1018
1019 switch (RRI8_T) {
1020 case 0: /*DPFRc*/
1021 break;
1022
1023 case 1: /*DPFWc*/
1024 break;
1025
1026 case 2: /*DPFROc*/
1027 break;
1028
1029 case 3: /*DPFWOc*/
1030 break;
1031
1032 case 4: /*DHWBc*/
1033 break;
1034
1035 case 5: /*DHWBIc*/
1036 break;
1037
1038 case 6: /*DHIc*/
1039 break;
1040
1041 case 7: /*DIIc*/
1042 break;
1043
1044 case 8: /*DCEc*/
1045 switch (OP1) {
1046 case 0: /*DPFLl*/
1047 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1048 break;
1049
1050 case 2: /*DHUl*/
1051 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1052 break;
1053
1054 case 3: /*DIUl*/
1055 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1056 break;
1057
1058 case 4: /*DIWBc*/
1059 HAS_OPTION(XTENSA_OPTION_DCACHE);
1060 break;
1061
1062 case 5: /*DIWBIc*/
1063 HAS_OPTION(XTENSA_OPTION_DCACHE);
1064 break;
1065
1066 default: /*reserved*/
1067 RESERVED();
1068 break;
1069
1070 }
1071 break;
1072
1073 case 12: /*IPFc*/
1074 HAS_OPTION(XTENSA_OPTION_ICACHE);
1075 break;
1076
1077 case 13: /*ICEc*/
1078 switch (OP1) {
1079 case 0: /*IPFLl*/
1080 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1081 break;
1082
1083 case 2: /*IHUl*/
1084 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1085 break;
1086
1087 case 3: /*IIUl*/
1088 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1089 break;
1090
1091 default: /*reserved*/
1092 RESERVED();
1093 break;
1094 }
1095 break;
1096
1097 case 14: /*IHIc*/
1098 HAS_OPTION(XTENSA_OPTION_ICACHE);
1099 break;
1100
1101 case 15: /*IIIc*/
1102 HAS_OPTION(XTENSA_OPTION_ICACHE);
1103 break;
1104
1105 default: /*reserved*/
1106 RESERVED();
1107 break;
1108 }
809377aa
MF
1109 break;
1110
1111 case 9: /*L16SI*/
1112 gen_load_store(ld16s, 1);
1113 break;
1114
1115 case 10: /*MOVI*/
1116 tcg_gen_movi_i32(cpu_R[RRI8_T],
1117 RRI8_IMM8 | (RRI8_S << 8) |
1118 ((RRI8_S & 0x8) ? 0xfffff000 : 0));
1119 break;
1120
1121 case 11: /*L32AIy*/
1122 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1123 gen_load_store(ld32u, 2); /*TODO acquire?*/
1124 break;
1125
1126 case 12: /*ADDI*/
1127 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);
1128 break;
1129
1130 case 13: /*ADDMI*/
1131 tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);
1132 break;
1133
1134 case 14: /*S32C1Iy*/
1135 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1136 {
1137 int label = gen_new_label();
1138 TCGv_i32 tmp = tcg_temp_local_new_i32();
1139 TCGv_i32 addr = tcg_temp_local_new_i32();
1140
1141 tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
1142 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
1143 tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, 0);
1144 tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
1145 cpu_SR[SCOMPARE1], label);
1146
1147 tcg_gen_qemu_st32(tmp, addr, 0);
1148
1149 gen_set_label(label);
1150 tcg_temp_free(addr);
1151 tcg_temp_free(tmp);
1152 }
1153 break;
1154
1155 case 15: /*S32RIy*/
1156 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1157 gen_load_store(st32, 2); /*TODO release?*/
1158 break;
1159
1160 default: /*reserved*/
91a5bb76 1161 RESERVED();
809377aa
MF
1162 break;
1163 }
dedc5eae 1164 break;
809377aa 1165#undef gen_load_store
dedc5eae
MF
1166
1167 case 3: /*LSCIp*/
1168 HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
91a5bb76 1169 TBD();
dedc5eae
MF
1170 break;
1171
1172 case 4: /*MAC16d*/
1173 HAS_OPTION(XTENSA_OPTION_MAC16);
91a5bb76 1174 TBD();
dedc5eae
MF
1175 break;
1176
1177 case 5: /*CALLN*/
1178 switch (CALL_N) {
1179 case 0: /*CALL0*/
1180 tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
1181 gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
1182 break;
1183
1184 case 1: /*CALL4w*/
1185 case 2: /*CALL8w*/
1186 case 3: /*CALL12w*/
1187 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 1188 TBD();
dedc5eae
MF
1189 break;
1190 }
1191 break;
1192
1193 case 6: /*SI*/
1194 switch (CALL_N) {
1195 case 0: /*J*/
1196 gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);
1197 break;
1198
bd57fb91
MF
1199 case 1: /*BZ*/
1200 {
1201 static const TCGCond cond[] = {
1202 TCG_COND_EQ, /*BEQZ*/
1203 TCG_COND_NE, /*BNEZ*/
1204 TCG_COND_LT, /*BLTZ*/
1205 TCG_COND_GE, /*BGEZ*/
1206 };
1207
1208 gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,
1209 4 + BRI12_IMM12_SE);
1210 }
1211 break;
1212
1213 case 2: /*BI0*/
1214 {
1215 static const TCGCond cond[] = {
1216 TCG_COND_EQ, /*BEQI*/
1217 TCG_COND_NE, /*BNEI*/
1218 TCG_COND_LT, /*BLTI*/
1219 TCG_COND_GE, /*BGEI*/
1220 };
1221
1222 gen_brcondi(dc, cond[BRI8_M & 3],
1223 cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);
1224 }
1225 break;
1226
1227 case 3: /*BI1*/
1228 switch (BRI8_M) {
1229 case 0: /*ENTRYw*/
1230 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
91a5bb76 1231 TBD();
bd57fb91
MF
1232 break;
1233
1234 case 1: /*B1*/
1235 switch (BRI8_R) {
1236 case 0: /*BFp*/
1237 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1238 TBD();
bd57fb91
MF
1239 break;
1240
1241 case 1: /*BTp*/
1242 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
91a5bb76 1243 TBD();
bd57fb91
MF
1244 break;
1245
1246 case 8: /*LOOP*/
91a5bb76 1247 TBD();
bd57fb91
MF
1248 break;
1249
1250 case 9: /*LOOPNEZ*/
91a5bb76 1251 TBD();
bd57fb91
MF
1252 break;
1253
1254 case 10: /*LOOPGTZ*/
91a5bb76 1255 TBD();
bd57fb91
MF
1256 break;
1257
1258 default: /*reserved*/
91a5bb76 1259 RESERVED();
bd57fb91
MF
1260 break;
1261
1262 }
1263 break;
1264
1265 case 2: /*BLTUI*/
1266 case 3: /*BGEUI*/
1267 gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,
1268 cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);
1269 break;
1270 }
1271 break;
1272
dedc5eae
MF
1273 }
1274 break;
1275
1276 case 7: /*B*/
bd57fb91
MF
1277 {
1278 TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;
1279
1280 switch (RRI8_R & 7) {
1281 case 0: /*BNONE*/ /*BANY*/
1282 {
1283 TCGv_i32 tmp = tcg_temp_new_i32();
1284 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
1285 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1286 tcg_temp_free(tmp);
1287 }
1288 break;
1289
1290 case 1: /*BEQ*/ /*BNE*/
1291 case 2: /*BLT*/ /*BGE*/
1292 case 3: /*BLTU*/ /*BGEU*/
1293 {
1294 static const TCGCond cond[] = {
1295 [1] = TCG_COND_EQ,
1296 [2] = TCG_COND_LT,
1297 [3] = TCG_COND_LTU,
1298 [9] = TCG_COND_NE,
1299 [10] = TCG_COND_GE,
1300 [11] = TCG_COND_GEU,
1301 };
1302 gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],
1303 4 + RRI8_IMM8_SE);
1304 }
1305 break;
1306
1307 case 4: /*BALL*/ /*BNALL*/
1308 {
1309 TCGv_i32 tmp = tcg_temp_new_i32();
1310 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
1311 gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],
1312 4 + RRI8_IMM8_SE);
1313 tcg_temp_free(tmp);
1314 }
1315 break;
1316
1317 case 5: /*BBC*/ /*BBS*/
1318 {
1319 TCGv_i32 bit = tcg_const_i32(1);
1320 TCGv_i32 tmp = tcg_temp_new_i32();
1321 tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);
1322 tcg_gen_shl_i32(bit, bit, tmp);
1323 tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);
1324 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1325 tcg_temp_free(tmp);
1326 tcg_temp_free(bit);
1327 }
1328 break;
1329
1330 case 6: /*BBCI*/ /*BBSI*/
1331 case 7:
1332 {
1333 TCGv_i32 tmp = tcg_temp_new_i32();
1334 tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],
1335 1 << (((RRI8_R & 1) << 4) | RRI8_T));
1336 gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
1337 tcg_temp_free(tmp);
1338 }
1339 break;
1340
1341 }
1342 }
dedc5eae
MF
1343 break;
1344
67882fd1
MF
1345#define gen_narrow_load_store(type) do { \
1346 TCGv_i32 addr = tcg_temp_new_i32(); \
1347 tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
1348 tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, 0); \
1349 tcg_temp_free(addr); \
1350 } while (0)
1351
dedc5eae 1352 case 8: /*L32I.Nn*/
67882fd1 1353 gen_narrow_load_store(ld32u);
dedc5eae
MF
1354 break;
1355
1356 case 9: /*S32I.Nn*/
67882fd1 1357 gen_narrow_load_store(st32);
dedc5eae 1358 break;
67882fd1 1359#undef gen_narrow_load_store
dedc5eae
MF
1360
1361 case 10: /*ADD.Nn*/
67882fd1 1362 tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);
dedc5eae
MF
1363 break;
1364
1365 case 11: /*ADDI.Nn*/
67882fd1 1366 tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);
dedc5eae
MF
1367 break;
1368
1369 case 12: /*ST2n*/
67882fd1
MF
1370 if (RRRN_T < 8) { /*MOVI.Nn*/
1371 tcg_gen_movi_i32(cpu_R[RRRN_S],
1372 RRRN_R | (RRRN_T << 4) |
1373 ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));
1374 } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
bd57fb91
MF
1375 TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;
1376
1377 gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,
1378 4 + (RRRN_R | ((RRRN_T & 3) << 4)));
67882fd1 1379 }
dedc5eae
MF
1380 break;
1381
1382 case 13: /*ST3n*/
67882fd1
MF
1383 switch (RRRN_R) {
1384 case 0: /*MOV.Nn*/
1385 tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);
1386 break;
1387
1388 case 15: /*S3*/
1389 switch (RRRN_T) {
1390 case 0: /*RET.Nn*/
1391 gen_jump(dc, cpu_R[0]);
1392 break;
1393
1394 case 1: /*RETW.Nn*/
91a5bb76
MF
1395 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1396 TBD();
67882fd1
MF
1397 break;
1398
1399 case 2: /*BREAK.Nn*/
91a5bb76 1400 TBD();
67882fd1
MF
1401 break;
1402
1403 case 3: /*NOP.Nn*/
1404 break;
1405
1406 case 6: /*ILL.Nn*/
91a5bb76 1407 TBD();
67882fd1
MF
1408 break;
1409
1410 default: /*reserved*/
91a5bb76 1411 RESERVED();
67882fd1
MF
1412 break;
1413 }
1414 break;
1415
1416 default: /*reserved*/
91a5bb76 1417 RESERVED();
67882fd1
MF
1418 break;
1419 }
dedc5eae
MF
1420 break;
1421
1422 default: /*reserved*/
91a5bb76 1423 RESERVED();
dedc5eae
MF
1424 break;
1425 }
1426
1427 dc->pc = dc->next_pc;
1428 return;
1429
1430invalid_opcode:
1431 qemu_log("INVALID(pc = %08x)\n", dc->pc);
1432 dc->pc = dc->next_pc;
1433#undef HAS_OPTION
1434}
1435
1436static void check_breakpoint(CPUState *env, DisasContext *dc)
1437{
1438 CPUBreakpoint *bp;
1439
1440 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
1441 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1442 if (bp->pc == dc->pc) {
1443 tcg_gen_movi_i32(cpu_pc, dc->pc);
1444 gen_exception(EXCP_DEBUG);
1445 dc->is_jmp = DISAS_UPDATE;
1446 }
1447 }
1448 }
1449}
1450
1451static void gen_intermediate_code_internal(
1452 CPUState *env, TranslationBlock *tb, int search_pc)
1453{
1454 DisasContext dc;
1455 int insn_count = 0;
1456 int j, lj = -1;
1457 uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1458 int max_insns = tb->cflags & CF_COUNT_MASK;
1459 uint32_t pc_start = tb->pc;
1460 uint32_t next_page_start =
1461 (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
1462
1463 if (max_insns == 0) {
1464 max_insns = CF_COUNT_MASK;
1465 }
1466
1467 dc.config = env->config;
1468 dc.singlestep_enabled = env->singlestep_enabled;
1469 dc.tb = tb;
1470 dc.pc = pc_start;
1471 dc.is_jmp = DISAS_NEXT;
1472
3580ecad
MF
1473 init_sar_tracker(&dc);
1474
dedc5eae
MF
1475 gen_icount_start();
1476
1477 do {
1478 check_breakpoint(env, &dc);
1479
1480 if (search_pc) {
1481 j = gen_opc_ptr - gen_opc_buf;
1482 if (lj < j) {
1483 lj++;
1484 while (lj < j) {
1485 gen_opc_instr_start[lj++] = 0;
1486 }
1487 }
1488 gen_opc_pc[lj] = dc.pc;
1489 gen_opc_instr_start[lj] = 1;
1490 gen_opc_icount[lj] = insn_count;
1491 }
1492
1493 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
1494 tcg_gen_debug_insn_start(dc.pc);
1495 }
1496
1497 disas_xtensa_insn(&dc);
1498 ++insn_count;
1499 if (env->singlestep_enabled) {
1500 tcg_gen_movi_i32(cpu_pc, dc.pc);
1501 gen_exception(EXCP_DEBUG);
1502 break;
1503 }
1504 } while (dc.is_jmp == DISAS_NEXT &&
1505 insn_count < max_insns &&
1506 dc.pc < next_page_start &&
1507 gen_opc_ptr < gen_opc_end);
1508
3580ecad
MF
1509 reset_sar_tracker(&dc);
1510
dedc5eae
MF
1511 if (dc.is_jmp == DISAS_NEXT) {
1512 gen_jumpi(&dc, dc.pc, 0);
1513 }
1514 gen_icount_end(tb, insn_count);
1515 *gen_opc_ptr = INDEX_op_end;
1516
1517 if (!search_pc) {
1518 tb->size = dc.pc - pc_start;
1519 tb->icount = insn_count;
1520 }
2328826b
MF
1521}
1522
1523void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
1524{
dedc5eae 1525 gen_intermediate_code_internal(env, tb, 0);
2328826b
MF
1526}
1527
1528void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
1529{
dedc5eae 1530 gen_intermediate_code_internal(env, tb, 1);
2328826b
MF
1531}
1532
1533void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1534 int flags)
1535{
2af3da91
MF
1536 int i, j;
1537
1538 cpu_fprintf(f, "PC=%08x\n\n", env->pc);
1539
1540 for (i = j = 0; i < 256; ++i) {
1541 if (sregnames[i]) {
1542 cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
1543 (j++ % 4) == 3 ? '\n' : ' ');
1544 }
1545 }
1546
1547 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
1548
1549 for (i = j = 0; i < 256; ++i) {
1550 if (uregnames[i]) {
1551 cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
1552 (j++ % 4) == 3 ? '\n' : ' ');
1553 }
1554 }
2328826b 1555
2af3da91 1556 cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2328826b
MF
1557
1558 for (i = 0; i < 16; ++i) {
1559 cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
1560 (i % 4) == 3 ? '\n' : ' ');
1561 }
1562}
1563
1564void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
1565{
1566 env->pc = gen_opc_pc[pc_pos];
1567}