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