3 * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm
5 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
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.
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.
43 typedef struct DisasContext
{
44 const XtensaConfig
*config
;
54 int singlestep_enabled
;
58 bool sar_m32_allocated
;
62 static TCGv_ptr cpu_env
;
63 static TCGv_i32 cpu_pc
;
64 static TCGv_i32 cpu_R
[16];
65 static TCGv_i32 cpu_SR
[256];
66 static TCGv_i32 cpu_UR
[256];
68 #include "gen-icount.h"
70 static const char * const sregnames
[256] = {
75 [LITBASE
] = "LITBASE",
76 [SCOMPARE1
] = "SCOMPARE1",
77 [WINDOW_BASE
] = "WINDOW_BASE",
78 [WINDOW_START
] = "WINDOW_START",
81 [EXCSAVE1
] = "EXCSAVE1",
83 [EXCCAUSE
] = "EXCCAUSE",
84 [EXCVADDR
] = "EXCVADDR",
87 static const char * const uregnames
[256] = {
88 [THREADPTR
] = "THREADPTR",
93 void xtensa_translate_init(void)
95 static const char * const regnames
[] = {
96 "ar0", "ar1", "ar2", "ar3",
97 "ar4", "ar5", "ar6", "ar7",
98 "ar8", "ar9", "ar10", "ar11",
99 "ar12", "ar13", "ar14", "ar15",
103 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
104 cpu_pc
= tcg_global_mem_new_i32(TCG_AREG0
,
105 offsetof(CPUState
, pc
), "pc");
107 for (i
= 0; i
< 16; i
++) {
108 cpu_R
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
109 offsetof(CPUState
, regs
[i
]),
113 for (i
= 0; i
< 256; ++i
) {
115 cpu_SR
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
116 offsetof(CPUState
, sregs
[i
]),
121 for (i
= 0; i
< 256; ++i
) {
123 cpu_UR
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
124 offsetof(CPUState
, uregs
[i
]),
132 static inline bool option_enabled(DisasContext
*dc
, int opt
)
134 return xtensa_option_enabled(dc
->config
, opt
);
137 static void init_litbase(DisasContext
*dc
)
139 if (dc
->tb
->flags
& XTENSA_TBFLAG_LITBASE
) {
140 dc
->litbase
= tcg_temp_local_new_i32();
141 tcg_gen_andi_i32(dc
->litbase
, cpu_SR
[LITBASE
], 0xfffff000);
145 static void reset_litbase(DisasContext
*dc
)
147 if (dc
->tb
->flags
& XTENSA_TBFLAG_LITBASE
) {
148 tcg_temp_free(dc
->litbase
);
152 static void init_sar_tracker(DisasContext
*dc
)
154 dc
->sar_5bit
= false;
155 dc
->sar_m32_5bit
= false;
156 dc
->sar_m32_allocated
= false;
159 static void reset_sar_tracker(DisasContext
*dc
)
161 if (dc
->sar_m32_allocated
) {
162 tcg_temp_free(dc
->sar_m32
);
166 static void gen_right_shift_sar(DisasContext
*dc
, TCGv_i32 sa
)
168 tcg_gen_andi_i32(cpu_SR
[SAR
], sa
, 0x1f);
169 if (dc
->sar_m32_5bit
) {
170 tcg_gen_discard_i32(dc
->sar_m32
);
173 dc
->sar_m32_5bit
= false;
176 static void gen_left_shift_sar(DisasContext
*dc
, TCGv_i32 sa
)
178 TCGv_i32 tmp
= tcg_const_i32(32);
179 if (!dc
->sar_m32_allocated
) {
180 dc
->sar_m32
= tcg_temp_local_new_i32();
181 dc
->sar_m32_allocated
= true;
183 tcg_gen_andi_i32(dc
->sar_m32
, sa
, 0x1f);
184 tcg_gen_sub_i32(cpu_SR
[SAR
], tmp
, dc
->sar_m32
);
185 dc
->sar_5bit
= false;
186 dc
->sar_m32_5bit
= true;
190 static void gen_exception(int excp
)
192 TCGv_i32 tmp
= tcg_const_i32(excp
);
193 gen_helper_exception(tmp
);
197 static void gen_exception_cause(DisasContext
*dc
, uint32_t cause
)
199 TCGv_i32 tpc
= tcg_const_i32(dc
->pc
);
200 TCGv_i32 tcause
= tcg_const_i32(cause
);
201 gen_helper_exception_cause(tpc
, tcause
);
203 tcg_temp_free(tcause
);
206 static void gen_check_privilege(DisasContext
*dc
)
209 gen_exception_cause(dc
, PRIVILEGED_CAUSE
);
213 static void gen_jump_slot(DisasContext
*dc
, TCGv dest
, int slot
)
215 tcg_gen_mov_i32(cpu_pc
, dest
);
216 if (dc
->singlestep_enabled
) {
217 gen_exception(EXCP_DEBUG
);
220 tcg_gen_goto_tb(slot
);
221 tcg_gen_exit_tb((tcg_target_long
)dc
->tb
+ slot
);
226 dc
->is_jmp
= DISAS_UPDATE
;
229 static void gen_jump(DisasContext
*dc
, TCGv dest
)
231 gen_jump_slot(dc
, dest
, -1);
234 static void gen_jumpi(DisasContext
*dc
, uint32_t dest
, int slot
)
236 TCGv_i32 tmp
= tcg_const_i32(dest
);
237 if (((dc
->pc
^ dest
) & TARGET_PAGE_MASK
) != 0) {
240 gen_jump_slot(dc
, tmp
, slot
);
244 static void gen_callw_slot(DisasContext
*dc
, int callinc
, TCGv_i32 dest
,
247 TCGv_i32 tcallinc
= tcg_const_i32(callinc
);
249 tcg_gen_deposit_i32(cpu_SR
[PS
], cpu_SR
[PS
],
250 tcallinc
, PS_CALLINC_SHIFT
, PS_CALLINC_LEN
);
251 tcg_temp_free(tcallinc
);
252 tcg_gen_movi_i32(cpu_R
[callinc
<< 2],
253 (callinc
<< 30) | (dc
->next_pc
& 0x3fffffff));
254 gen_jump_slot(dc
, dest
, slot
);
257 static void gen_callw(DisasContext
*dc
, int callinc
, TCGv_i32 dest
)
259 gen_callw_slot(dc
, callinc
, dest
, -1);
262 static void gen_callwi(DisasContext
*dc
, int callinc
, uint32_t dest
, int slot
)
264 TCGv_i32 tmp
= tcg_const_i32(dest
);
265 if (((dc
->pc
^ dest
) & TARGET_PAGE_MASK
) != 0) {
268 gen_callw_slot(dc
, callinc
, tmp
, slot
);
272 static bool gen_check_loop_end(DisasContext
*dc
, int slot
)
274 if (option_enabled(dc
, XTENSA_OPTION_LOOP
) &&
275 !(dc
->tb
->flags
& XTENSA_TBFLAG_EXCM
) &&
276 dc
->next_pc
== dc
->lend
) {
277 int label
= gen_new_label();
279 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_SR
[LCOUNT
], 0, label
);
280 tcg_gen_subi_i32(cpu_SR
[LCOUNT
], cpu_SR
[LCOUNT
], 1);
281 gen_jumpi(dc
, dc
->lbeg
, slot
);
282 gen_set_label(label
);
283 gen_jumpi(dc
, dc
->next_pc
, -1);
289 static void gen_jumpi_check_loop_end(DisasContext
*dc
, int slot
)
291 if (!gen_check_loop_end(dc
, slot
)) {
292 gen_jumpi(dc
, dc
->next_pc
, slot
);
296 static void gen_brcond(DisasContext
*dc
, TCGCond cond
,
297 TCGv_i32 t0
, TCGv_i32 t1
, uint32_t offset
)
299 int label
= gen_new_label();
301 tcg_gen_brcond_i32(cond
, t0
, t1
, label
);
302 gen_jumpi_check_loop_end(dc
, 0);
303 gen_set_label(label
);
304 gen_jumpi(dc
, dc
->pc
+ offset
, 1);
307 static void gen_brcondi(DisasContext
*dc
, TCGCond cond
,
308 TCGv_i32 t0
, uint32_t t1
, uint32_t offset
)
310 TCGv_i32 tmp
= tcg_const_i32(t1
);
311 gen_brcond(dc
, cond
, t0
, tmp
, offset
);
315 static void gen_rsr(DisasContext
*dc
, TCGv_i32 d
, uint32_t sr
)
317 static void (* const rsr_handler
[256])(DisasContext
*dc
,
318 TCGv_i32 d
, uint32_t sr
) = {
322 if (rsr_handler
[sr
]) {
323 rsr_handler
[sr
](dc
, d
, sr
);
325 tcg_gen_mov_i32(d
, cpu_SR
[sr
]);
328 qemu_log("RSR %d not implemented, ", sr
);
332 static void gen_wsr_lbeg(DisasContext
*dc
, uint32_t sr
, TCGv_i32 s
)
334 gen_helper_wsr_lbeg(s
);
337 static void gen_wsr_lend(DisasContext
*dc
, uint32_t sr
, TCGv_i32 s
)
339 gen_helper_wsr_lend(s
);
342 static void gen_wsr_sar(DisasContext
*dc
, uint32_t sr
, TCGv_i32 s
)
344 tcg_gen_andi_i32(cpu_SR
[sr
], s
, 0x3f);
345 if (dc
->sar_m32_5bit
) {
346 tcg_gen_discard_i32(dc
->sar_m32
);
348 dc
->sar_5bit
= false;
349 dc
->sar_m32_5bit
= false;
352 static void gen_wsr_litbase(DisasContext
*dc
, uint32_t sr
, TCGv_i32 s
)
354 tcg_gen_andi_i32(cpu_SR
[sr
], s
, 0xfffff001);
355 /* This can change tb->flags, so exit tb */
356 gen_jumpi_check_loop_end(dc
, -1);
359 static void gen_wsr_windowbase(DisasContext
*dc
, uint32_t sr
, TCGv_i32 v
)
361 gen_helper_wsr_windowbase(v
);
364 static void gen_wsr_ps(DisasContext
*dc
, uint32_t sr
, TCGv_i32 v
)
366 uint32_t mask
= PS_WOE
| PS_CALLINC
| PS_OWB
|
367 PS_UM
| PS_EXCM
| PS_INTLEVEL
;
369 if (option_enabled(dc
, XTENSA_OPTION_MMU
)) {
372 tcg_gen_andi_i32(cpu_SR
[sr
], v
, mask
);
373 /* This can change mmu index, so exit tb */
374 gen_jumpi_check_loop_end(dc
, -1);
377 static void gen_wsr(DisasContext
*dc
, uint32_t sr
, TCGv_i32 s
)
379 static void (* const wsr_handler
[256])(DisasContext
*dc
,
380 uint32_t sr
, TCGv_i32 v
) = {
381 [LBEG
] = gen_wsr_lbeg
,
382 [LEND
] = gen_wsr_lend
,
384 [LITBASE
] = gen_wsr_litbase
,
385 [WINDOW_BASE
] = gen_wsr_windowbase
,
390 if (wsr_handler
[sr
]) {
391 wsr_handler
[sr
](dc
, sr
, s
);
393 tcg_gen_mov_i32(cpu_SR
[sr
], s
);
396 qemu_log("WSR %d not implemented, ", sr
);
400 static void disas_xtensa_insn(DisasContext
*dc
)
402 #define HAS_OPTION(opt) do { \
403 if (!option_enabled(dc, opt)) { \
404 qemu_log("Option %d is not enabled %s:%d\n", \
405 (opt), __FILE__, __LINE__); \
406 goto invalid_opcode; \
410 #define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
411 #define RESERVED() do { \
412 qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
413 dc->pc, b0, b1, b2, __FILE__, __LINE__); \
414 goto invalid_opcode; \
418 #ifdef TARGET_WORDS_BIGENDIAN
419 #define OP0 (((b0) & 0xf0) >> 4)
420 #define OP1 (((b2) & 0xf0) >> 4)
421 #define OP2 ((b2) & 0xf)
422 #define RRR_R ((b1) & 0xf)
423 #define RRR_S (((b1) & 0xf0) >> 4)
424 #define RRR_T ((b0) & 0xf)
426 #define OP0 (((b0) & 0xf))
427 #define OP1 (((b2) & 0xf))
428 #define OP2 (((b2) & 0xf0) >> 4)
429 #define RRR_R (((b1) & 0xf0) >> 4)
430 #define RRR_S (((b1) & 0xf))
431 #define RRR_T (((b0) & 0xf0) >> 4)
441 #define RRI8_IMM8 (b2)
442 #define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)
444 #ifdef TARGET_WORDS_BIGENDIAN
445 #define RI16_IMM16 (((b1) << 8) | (b2))
447 #define RI16_IMM16 (((b2) << 8) | (b1))
450 #ifdef TARGET_WORDS_BIGENDIAN
451 #define CALL_N (((b0) & 0xc) >> 2)
452 #define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))
454 #define CALL_N (((b0) & 0x30) >> 4)
455 #define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))
457 #define CALL_OFFSET_SE \
458 (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)
460 #define CALLX_N CALL_N
461 #ifdef TARGET_WORDS_BIGENDIAN
462 #define CALLX_M ((b0) & 0x3)
464 #define CALLX_M (((b0) & 0xc0) >> 6)
466 #define CALLX_S RRR_S
468 #define BRI12_M CALLX_M
469 #define BRI12_S RRR_S
470 #ifdef TARGET_WORDS_BIGENDIAN
471 #define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))
473 #define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))
475 #define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)
477 #define BRI8_M BRI12_M
478 #define BRI8_R RRI8_R
479 #define BRI8_S RRI8_S
480 #define BRI8_IMM8 RRI8_IMM8
481 #define BRI8_IMM8_SE RRI8_IMM8_SE
485 uint8_t b0
= ldub_code(dc
->pc
);
486 uint8_t b1
= ldub_code(dc
->pc
+ 1);
487 uint8_t b2
= ldub_code(dc
->pc
+ 2);
489 static const uint32_t B4CONST
[] = {
490 0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
493 static const uint32_t B4CONSTU
[] = {
494 32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
498 dc
->next_pc
= dc
->pc
+ 2;
499 HAS_OPTION(XTENSA_OPTION_CODE_DENSITY
);
501 dc
->next_pc
= dc
->pc
+ 3;
510 if ((RRR_R
& 0xc) == 0x8) {
511 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
518 gen_exception_cause(dc
, ILLEGAL_INSTRUCTION_CAUSE
);
529 gen_jump(dc
, cpu_R
[CALLX_S
]);
533 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
535 TCGv_i32 tmp
= tcg_const_i32(dc
->pc
);
536 gen_helper_retw(tmp
, tmp
);
552 TCGv_i32 tmp
= tcg_temp_new_i32();
553 tcg_gen_mov_i32(tmp
, cpu_R
[CALLX_S
]);
554 tcg_gen_movi_i32(cpu_R
[0], dc
->next_pc
);
563 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
565 TCGv_i32 tmp
= tcg_temp_new_i32();
567 tcg_gen_mov_i32(tmp
, cpu_R
[CALLX_S
]);
568 gen_callw(dc
, CALLX_N
, tmp
);
578 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
580 TCGv_i32 pc
= tcg_const_i32(dc
->pc
);
581 gen_helper_movsp(pc
);
582 tcg_gen_mov_i32(cpu_R
[RRR_T
], cpu_R
[RRR_S
]);
602 HAS_OPTION(XTENSA_OPTION_EXCEPTION
);
614 default: /*reserved*/
623 HAS_OPTION(XTENSA_OPTION_EXCEPTION
);
626 gen_check_privilege(dc
);
627 tcg_gen_andi_i32(cpu_SR
[PS
], cpu_SR
[PS
], ~PS_EXCM
);
628 gen_jump(dc
, cpu_SR
[EPC1
]);
636 gen_check_privilege(dc
);
638 dc
->config
->ndepc
? DEPC
: EPC1
]);
643 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
644 gen_check_privilege(dc
);
646 TCGv_i32 tmp
= tcg_const_i32(1);
649 cpu_SR
[PS
], cpu_SR
[PS
], ~PS_EXCM
);
650 tcg_gen_shl_i32(tmp
, tmp
, cpu_SR
[WINDOW_BASE
]);
653 tcg_gen_andc_i32(cpu_SR
[WINDOW_START
],
654 cpu_SR
[WINDOW_START
], tmp
);
656 tcg_gen_or_i32(cpu_SR
[WINDOW_START
],
657 cpu_SR
[WINDOW_START
], tmp
);
660 gen_helper_restore_owb();
661 gen_jump(dc
, cpu_SR
[EPC1
]);
667 default: /*reserved*/
674 HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT
);
682 default: /*reserved*/
690 HAS_OPTION(XTENSA_OPTION_EXCEPTION
);
695 HAS_OPTION(XTENSA_OPTION_EXCEPTION
);
698 gen_exception_cause(dc
, SYSCALL_CAUSE
);
712 HAS_OPTION(XTENSA_OPTION_INTERRUPT
);
713 gen_check_privilege(dc
);
714 tcg_gen_mov_i32(cpu_R
[RRR_T
], cpu_SR
[PS
]);
715 tcg_gen_ori_i32(cpu_SR
[PS
], cpu_SR
[PS
], RRR_S
);
716 tcg_gen_andi_i32(cpu_SR
[PS
], cpu_SR
[PS
],
717 RRR_S
| ~PS_INTLEVEL
);
721 HAS_OPTION(XTENSA_OPTION_INTERRUPT
);
726 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
731 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
736 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
741 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
745 default: /*reserved*/
753 tcg_gen_and_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
757 tcg_gen_or_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
761 tcg_gen_xor_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
767 gen_right_shift_sar(dc
, cpu_R
[RRR_S
]);
771 gen_left_shift_sar(dc
, cpu_R
[RRR_S
]);
776 TCGv_i32 tmp
= tcg_temp_new_i32();
777 tcg_gen_shli_i32(tmp
, cpu_R
[RRR_S
], 3);
778 gen_right_shift_sar(dc
, tmp
);
785 TCGv_i32 tmp
= tcg_temp_new_i32();
786 tcg_gen_shli_i32(tmp
, cpu_R
[RRR_S
], 3);
787 gen_left_shift_sar(dc
, tmp
);
794 TCGv_i32 tmp
= tcg_const_i32(
795 RRR_S
| ((RRR_T
& 1) << 4));
796 gen_right_shift_sar(dc
, tmp
);
810 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
811 gen_check_privilege(dc
);
813 TCGv_i32 tmp
= tcg_const_i32(
814 RRR_T
| ((RRR_T
& 8) ? 0xfffffff0 : 0));
815 gen_helper_rotw(tmp
);
821 HAS_OPTION(XTENSA_OPTION_MISC_OP
);
822 gen_helper_nsa(cpu_R
[RRR_T
], cpu_R
[RRR_S
]);
826 HAS_OPTION(XTENSA_OPTION_MISC_OP
);
827 gen_helper_nsau(cpu_R
[RRR_T
], cpu_R
[RRR_S
]);
830 default: /*reserved*/
843 tcg_gen_neg_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
]);
848 int label
= gen_new_label();
849 tcg_gen_mov_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
]);
851 TCG_COND_GE
, cpu_R
[RRR_R
], 0, label
);
852 tcg_gen_neg_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
]);
853 gen_set_label(label
);
857 default: /*reserved*/
868 tcg_gen_add_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
875 TCGv_i32 tmp
= tcg_temp_new_i32();
876 tcg_gen_shli_i32(tmp
, cpu_R
[RRR_S
], OP2
- 8);
877 tcg_gen_add_i32(cpu_R
[RRR_R
], tmp
, cpu_R
[RRR_T
]);
883 tcg_gen_sub_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
890 TCGv_i32 tmp
= tcg_temp_new_i32();
891 tcg_gen_shli_i32(tmp
, cpu_R
[RRR_S
], OP2
- 12);
892 tcg_gen_sub_i32(cpu_R
[RRR_R
], tmp
, cpu_R
[RRR_T
]);
903 tcg_gen_shli_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
],
904 32 - (RRR_T
| ((OP2
& 1) << 4)));
909 tcg_gen_sari_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
],
910 RRR_S
| ((OP2
& 1) << 4));
914 tcg_gen_shri_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
], RRR_S
);
919 TCGv_i32 tmp
= tcg_temp_new_i32();
921 gen_check_privilege(dc
);
923 tcg_gen_mov_i32(tmp
, cpu_R
[RRR_T
]);
924 gen_rsr(dc
, cpu_R
[RRR_T
], RSR_SR
);
925 gen_wsr(dc
, RSR_SR
, tmp
);
927 if (!sregnames
[RSR_SR
]) {
934 * Note: 64 bit ops are used here solely because SAR values
937 #define gen_shift_reg(cmd, reg) do { \
938 TCGv_i64 tmp = tcg_temp_new_i64(); \
939 tcg_gen_extu_i32_i64(tmp, reg); \
940 tcg_gen_##cmd##_i64(v, v, tmp); \
941 tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
942 tcg_temp_free_i64(v); \
943 tcg_temp_free_i64(tmp); \
946 #define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
950 TCGv_i64 v
= tcg_temp_new_i64();
951 tcg_gen_concat_i32_i64(v
, cpu_R
[RRR_T
], cpu_R
[RRR_S
]);
958 tcg_gen_shr_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
], cpu_SR
[SAR
]);
960 TCGv_i64 v
= tcg_temp_new_i64();
961 tcg_gen_extu_i32_i64(v
, cpu_R
[RRR_T
]);
967 if (dc
->sar_m32_5bit
) {
968 tcg_gen_shl_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], dc
->sar_m32
);
970 TCGv_i64 v
= tcg_temp_new_i64();
971 TCGv_i32 s
= tcg_const_i32(32);
972 tcg_gen_sub_i32(s
, s
, cpu_SR
[SAR
]);
973 tcg_gen_andi_i32(s
, s
, 0x3f);
974 tcg_gen_extu_i32_i64(v
, cpu_R
[RRR_S
]);
975 gen_shift_reg(shl
, s
);
982 tcg_gen_sar_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
], cpu_SR
[SAR
]);
984 TCGv_i64 v
= tcg_temp_new_i64();
985 tcg_gen_ext_i32_i64(v
, cpu_R
[RRR_T
]);
993 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL
);
995 TCGv_i32 v1
= tcg_temp_new_i32();
996 TCGv_i32 v2
= tcg_temp_new_i32();
997 tcg_gen_ext16u_i32(v1
, cpu_R
[RRR_S
]);
998 tcg_gen_ext16u_i32(v2
, cpu_R
[RRR_T
]);
999 tcg_gen_mul_i32(cpu_R
[RRR_R
], v1
, v2
);
1006 HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL
);
1008 TCGv_i32 v1
= tcg_temp_new_i32();
1009 TCGv_i32 v2
= tcg_temp_new_i32();
1010 tcg_gen_ext16s_i32(v1
, cpu_R
[RRR_S
]);
1011 tcg_gen_ext16s_i32(v2
, cpu_R
[RRR_T
]);
1012 tcg_gen_mul_i32(cpu_R
[RRR_R
], v1
, v2
);
1018 default: /*reserved*/
1026 HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV
);
1027 int label
= gen_new_label();
1028 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_R
[RRR_T
], 0, label
);
1029 gen_exception_cause(dc
, INTEGER_DIVIDE_BY_ZERO_CAUSE
);
1030 gen_set_label(label
);
1035 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL
);
1036 tcg_gen_mul_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
1041 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL
);
1043 TCGv_i64 r
= tcg_temp_new_i64();
1044 TCGv_i64 s
= tcg_temp_new_i64();
1045 TCGv_i64 t
= tcg_temp_new_i64();
1048 tcg_gen_extu_i32_i64(s
, cpu_R
[RRR_S
]);
1049 tcg_gen_extu_i32_i64(t
, cpu_R
[RRR_T
]);
1051 tcg_gen_ext_i32_i64(s
, cpu_R
[RRR_S
]);
1052 tcg_gen_ext_i32_i64(t
, cpu_R
[RRR_T
]);
1054 tcg_gen_mul_i64(r
, s
, t
);
1055 tcg_gen_shri_i64(r
, r
, 32);
1056 tcg_gen_trunc_i64_i32(cpu_R
[RRR_R
], r
);
1058 tcg_temp_free_i64(r
);
1059 tcg_temp_free_i64(s
);
1060 tcg_temp_free_i64(t
);
1065 tcg_gen_divu_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
1071 int label1
= gen_new_label();
1072 int label2
= gen_new_label();
1074 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_R
[RRR_S
], 0x80000000,
1076 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_R
[RRR_T
], 0xffffffff,
1078 tcg_gen_movi_i32(cpu_R
[RRR_R
],
1079 OP2
== 13 ? 0x80000000 : 0);
1081 gen_set_label(label1
);
1083 tcg_gen_div_i32(cpu_R
[RRR_R
],
1084 cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
1086 tcg_gen_rem_i32(cpu_R
[RRR_R
],
1087 cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
1089 gen_set_label(label2
);
1094 tcg_gen_remu_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
], cpu_R
[RRR_T
]);
1097 default: /*reserved*/
1107 gen_check_privilege(dc
);
1109 gen_rsr(dc
, cpu_R
[RRR_T
], RSR_SR
);
1110 if (!sregnames
[RSR_SR
]) {
1117 gen_check_privilege(dc
);
1119 gen_wsr(dc
, RSR_SR
, cpu_R
[RRR_T
]);
1120 if (!sregnames
[RSR_SR
]) {
1126 HAS_OPTION(XTENSA_OPTION_MISC_OP
);
1128 int shift
= 24 - RRR_T
;
1131 tcg_gen_ext8s_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
]);
1132 } else if (shift
== 16) {
1133 tcg_gen_ext16s_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
]);
1135 TCGv_i32 tmp
= tcg_temp_new_i32();
1136 tcg_gen_shli_i32(tmp
, cpu_R
[RRR_S
], shift
);
1137 tcg_gen_sari_i32(cpu_R
[RRR_R
], tmp
, shift
);
1144 HAS_OPTION(XTENSA_OPTION_MISC_OP
);
1146 TCGv_i32 tmp1
= tcg_temp_new_i32();
1147 TCGv_i32 tmp2
= tcg_temp_new_i32();
1148 int label
= gen_new_label();
1150 tcg_gen_sari_i32(tmp1
, cpu_R
[RRR_S
], 24 - RRR_T
);
1151 tcg_gen_xor_i32(tmp2
, tmp1
, cpu_R
[RRR_S
]);
1152 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffffffff << (RRR_T
+ 7));
1153 tcg_gen_mov_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
]);
1154 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp2
, 0, label
);
1156 tcg_gen_sari_i32(tmp1
, cpu_R
[RRR_S
], 31);
1157 tcg_gen_xori_i32(cpu_R
[RRR_R
], tmp1
,
1158 0xffffffff >> (25 - RRR_T
));
1160 gen_set_label(label
);
1162 tcg_temp_free(tmp1
);
1163 tcg_temp_free(tmp2
);
1171 HAS_OPTION(XTENSA_OPTION_MISC_OP
);
1173 static const TCGCond cond
[] = {
1179 int label
= gen_new_label();
1181 if (RRR_R
!= RRR_T
) {
1182 tcg_gen_mov_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
]);
1183 tcg_gen_brcond_i32(cond
[OP2
- 4],
1184 cpu_R
[RRR_S
], cpu_R
[RRR_T
], label
);
1185 tcg_gen_mov_i32(cpu_R
[RRR_R
], cpu_R
[RRR_T
]);
1187 tcg_gen_brcond_i32(cond
[OP2
- 4],
1188 cpu_R
[RRR_T
], cpu_R
[RRR_S
], label
);
1189 tcg_gen_mov_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
]);
1191 gen_set_label(label
);
1200 static const TCGCond cond
[] = {
1206 int label
= gen_new_label();
1207 tcg_gen_brcondi_i32(cond
[OP2
- 8], cpu_R
[RRR_T
], 0, label
);
1208 tcg_gen_mov_i32(cpu_R
[RRR_R
], cpu_R
[RRR_S
]);
1209 gen_set_label(label
);
1214 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
1219 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
1225 int st
= (RRR_S
<< 4) + RRR_T
;
1226 if (uregnames
[st
]) {
1227 tcg_gen_mov_i32(cpu_R
[RRR_R
], cpu_UR
[st
]);
1229 qemu_log("RUR %d not implemented, ", st
);
1237 if (uregnames
[RSR_SR
]) {
1238 tcg_gen_mov_i32(cpu_UR
[RSR_SR
], cpu_R
[RRR_T
]);
1240 qemu_log("WUR %d not implemented, ", RSR_SR
);
1252 int shiftimm
= RRR_S
| (OP1
<< 4);
1253 int maskimm
= (1 << (OP2
+ 1)) - 1;
1255 TCGv_i32 tmp
= tcg_temp_new_i32();
1256 tcg_gen_shri_i32(tmp
, cpu_R
[RRR_T
], shiftimm
);
1257 tcg_gen_andi_i32(cpu_R
[RRR_R
], tmp
, maskimm
);
1271 HAS_OPTION(XTENSA_OPTION_COPROCESSOR
);
1278 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
1279 gen_check_privilege(dc
);
1281 TCGv_i32 addr
= tcg_temp_new_i32();
1282 tcg_gen_addi_i32(addr
, cpu_R
[RRR_S
],
1283 (0xffffffc0 | (RRR_R
<< 2)));
1284 tcg_gen_qemu_ld32u(cpu_R
[RRR_T
], addr
, dc
->ring
);
1285 tcg_temp_free(addr
);
1290 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
1291 gen_check_privilege(dc
);
1293 TCGv_i32 addr
= tcg_temp_new_i32();
1294 tcg_gen_addi_i32(addr
, cpu_R
[RRR_S
],
1295 (0xffffffc0 | (RRR_R
<< 2)));
1296 tcg_gen_qemu_st32(cpu_R
[RRR_T
], addr
, dc
->ring
);
1297 tcg_temp_free(addr
);
1308 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR
);
1313 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR
);
1317 default: /*reserved*/
1325 TCGv_i32 tmp
= tcg_const_i32(
1326 ((dc
->tb
->flags
& XTENSA_TBFLAG_LITBASE
) ?
1327 0 : ((dc
->pc
+ 3) & ~3)) +
1328 (0xfffc0000 | (RI16_IMM16
<< 2)));
1330 if (dc
->tb
->flags
& XTENSA_TBFLAG_LITBASE
) {
1331 tcg_gen_add_i32(tmp
, tmp
, dc
->litbase
);
1333 tcg_gen_qemu_ld32u(cpu_R
[RRR_T
], tmp
, dc
->cring
);
1339 #define gen_load_store(type, shift) do { \
1340 TCGv_i32 addr = tcg_temp_new_i32(); \
1341 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
1342 tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1343 tcg_temp_free(addr); \
1348 gen_load_store(ld8u
, 0);
1352 gen_load_store(ld16u
, 1);
1356 gen_load_store(ld32u
, 2);
1360 gen_load_store(st8
, 0);
1364 gen_load_store(st16
, 1);
1368 gen_load_store(st32
, 2);
1373 HAS_OPTION(XTENSA_OPTION_DCACHE
);
1404 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK
);
1408 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK
);
1412 HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK
);
1416 HAS_OPTION(XTENSA_OPTION_DCACHE
);
1420 HAS_OPTION(XTENSA_OPTION_DCACHE
);
1423 default: /*reserved*/
1431 HAS_OPTION(XTENSA_OPTION_ICACHE
);
1437 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK
);
1441 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK
);
1445 HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK
);
1448 default: /*reserved*/
1455 HAS_OPTION(XTENSA_OPTION_ICACHE
);
1459 HAS_OPTION(XTENSA_OPTION_ICACHE
);
1462 default: /*reserved*/
1469 gen_load_store(ld16s
, 1);
1473 tcg_gen_movi_i32(cpu_R
[RRI8_T
],
1474 RRI8_IMM8
| (RRI8_S
<< 8) |
1475 ((RRI8_S
& 0x8) ? 0xfffff000 : 0));
1479 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO
);
1480 gen_load_store(ld32u
, 2); /*TODO acquire?*/
1484 tcg_gen_addi_i32(cpu_R
[RRI8_T
], cpu_R
[RRI8_S
], RRI8_IMM8_SE
);
1488 tcg_gen_addi_i32(cpu_R
[RRI8_T
], cpu_R
[RRI8_S
], RRI8_IMM8_SE
<< 8);
1491 case 14: /*S32C1Iy*/
1492 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO
);
1494 int label
= gen_new_label();
1495 TCGv_i32 tmp
= tcg_temp_local_new_i32();
1496 TCGv_i32 addr
= tcg_temp_local_new_i32();
1498 tcg_gen_mov_i32(tmp
, cpu_R
[RRI8_T
]);
1499 tcg_gen_addi_i32(addr
, cpu_R
[RRI8_S
], RRI8_IMM8
<< 2);
1500 tcg_gen_qemu_ld32u(cpu_R
[RRI8_T
], addr
, dc
->cring
);
1501 tcg_gen_brcond_i32(TCG_COND_NE
, cpu_R
[RRI8_T
],
1502 cpu_SR
[SCOMPARE1
], label
);
1504 tcg_gen_qemu_st32(tmp
, addr
, dc
->cring
);
1506 gen_set_label(label
);
1507 tcg_temp_free(addr
);
1513 HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO
);
1514 gen_load_store(st32
, 2); /*TODO release?*/
1517 default: /*reserved*/
1522 #undef gen_load_store
1525 HAS_OPTION(XTENSA_OPTION_COPROCESSOR
);
1530 HAS_OPTION(XTENSA_OPTION_MAC16
);
1537 tcg_gen_movi_i32(cpu_R
[0], dc
->next_pc
);
1538 gen_jumpi(dc
, (dc
->pc
& ~3) + (CALL_OFFSET_SE
<< 2) + 4, 0);
1544 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
1545 gen_callwi(dc
, CALL_N
,
1546 (dc
->pc
& ~3) + (CALL_OFFSET_SE
<< 2) + 4, 0);
1554 gen_jumpi(dc
, dc
->pc
+ 4 + CALL_OFFSET_SE
, 0);
1559 static const TCGCond cond
[] = {
1560 TCG_COND_EQ
, /*BEQZ*/
1561 TCG_COND_NE
, /*BNEZ*/
1562 TCG_COND_LT
, /*BLTZ*/
1563 TCG_COND_GE
, /*BGEZ*/
1566 gen_brcondi(dc
, cond
[BRI12_M
& 3], cpu_R
[BRI12_S
], 0,
1567 4 + BRI12_IMM12_SE
);
1573 static const TCGCond cond
[] = {
1574 TCG_COND_EQ
, /*BEQI*/
1575 TCG_COND_NE
, /*BNEI*/
1576 TCG_COND_LT
, /*BLTI*/
1577 TCG_COND_GE
, /*BGEI*/
1580 gen_brcondi(dc
, cond
[BRI8_M
& 3],
1581 cpu_R
[BRI8_S
], B4CONST
[BRI8_R
], 4 + BRI8_IMM8_SE
);
1588 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
1590 TCGv_i32 pc
= tcg_const_i32(dc
->pc
);
1591 TCGv_i32 s
= tcg_const_i32(BRI12_S
);
1592 TCGv_i32 imm
= tcg_const_i32(BRI12_IMM12
);
1593 gen_helper_entry(pc
, s
, imm
);
1603 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
1608 HAS_OPTION(XTENSA_OPTION_BOOLEAN
);
1614 case 10: /*LOOPGTZ*/
1615 HAS_OPTION(XTENSA_OPTION_LOOP
);
1617 uint32_t lend
= dc
->pc
+ RRI8_IMM8
+ 4;
1618 TCGv_i32 tmp
= tcg_const_i32(lend
);
1620 tcg_gen_subi_i32(cpu_SR
[LCOUNT
], cpu_R
[RRI8_S
], 1);
1621 tcg_gen_movi_i32(cpu_SR
[LBEG
], dc
->next_pc
);
1622 gen_wsr_lend(dc
, LEND
, tmp
);
1626 int label
= gen_new_label();
1627 tcg_gen_brcondi_i32(
1628 BRI8_R
== 9 ? TCG_COND_NE
: TCG_COND_GT
,
1629 cpu_R
[RRI8_S
], 0, label
);
1630 gen_jumpi(dc
, lend
, 1);
1631 gen_set_label(label
);
1634 gen_jumpi(dc
, dc
->next_pc
, 0);
1638 default: /*reserved*/
1647 gen_brcondi(dc
, BRI8_M
== 2 ? TCG_COND_LTU
: TCG_COND_GEU
,
1648 cpu_R
[BRI8_S
], B4CONSTU
[BRI8_R
], 4 + BRI8_IMM8_SE
);
1658 TCGCond eq_ne
= (RRI8_R
& 8) ? TCG_COND_NE
: TCG_COND_EQ
;
1660 switch (RRI8_R
& 7) {
1661 case 0: /*BNONE*/ /*BANY*/
1663 TCGv_i32 tmp
= tcg_temp_new_i32();
1664 tcg_gen_and_i32(tmp
, cpu_R
[RRI8_S
], cpu_R
[RRI8_T
]);
1665 gen_brcondi(dc
, eq_ne
, tmp
, 0, 4 + RRI8_IMM8_SE
);
1670 case 1: /*BEQ*/ /*BNE*/
1671 case 2: /*BLT*/ /*BGE*/
1672 case 3: /*BLTU*/ /*BGEU*/
1674 static const TCGCond cond
[] = {
1680 [11] = TCG_COND_GEU
,
1682 gen_brcond(dc
, cond
[RRI8_R
], cpu_R
[RRI8_S
], cpu_R
[RRI8_T
],
1687 case 4: /*BALL*/ /*BNALL*/
1689 TCGv_i32 tmp
= tcg_temp_new_i32();
1690 tcg_gen_and_i32(tmp
, cpu_R
[RRI8_S
], cpu_R
[RRI8_T
]);
1691 gen_brcond(dc
, eq_ne
, tmp
, cpu_R
[RRI8_T
],
1697 case 5: /*BBC*/ /*BBS*/
1699 TCGv_i32 bit
= tcg_const_i32(1);
1700 TCGv_i32 tmp
= tcg_temp_new_i32();
1701 tcg_gen_andi_i32(tmp
, cpu_R
[RRI8_T
], 0x1f);
1702 tcg_gen_shl_i32(bit
, bit
, tmp
);
1703 tcg_gen_and_i32(tmp
, cpu_R
[RRI8_S
], bit
);
1704 gen_brcondi(dc
, eq_ne
, tmp
, 0, 4 + RRI8_IMM8_SE
);
1710 case 6: /*BBCI*/ /*BBSI*/
1713 TCGv_i32 tmp
= tcg_temp_new_i32();
1714 tcg_gen_andi_i32(tmp
, cpu_R
[RRI8_S
],
1715 1 << (((RRI8_R
& 1) << 4) | RRI8_T
));
1716 gen_brcondi(dc
, eq_ne
, tmp
, 0, 4 + RRI8_IMM8_SE
);
1725 #define gen_narrow_load_store(type) do { \
1726 TCGv_i32 addr = tcg_temp_new_i32(); \
1727 tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
1728 tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \
1729 tcg_temp_free(addr); \
1733 gen_narrow_load_store(ld32u
);
1737 gen_narrow_load_store(st32
);
1739 #undef gen_narrow_load_store
1742 tcg_gen_add_i32(cpu_R
[RRRN_R
], cpu_R
[RRRN_S
], cpu_R
[RRRN_T
]);
1745 case 11: /*ADDI.Nn*/
1746 tcg_gen_addi_i32(cpu_R
[RRRN_R
], cpu_R
[RRRN_S
], RRRN_T
? RRRN_T
: -1);
1750 if (RRRN_T
< 8) { /*MOVI.Nn*/
1751 tcg_gen_movi_i32(cpu_R
[RRRN_S
],
1752 RRRN_R
| (RRRN_T
<< 4) |
1753 ((RRRN_T
& 6) == 6 ? 0xffffff80 : 0));
1754 } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
1755 TCGCond eq_ne
= (RRRN_T
& 4) ? TCG_COND_NE
: TCG_COND_EQ
;
1757 gen_brcondi(dc
, eq_ne
, cpu_R
[RRRN_S
], 0,
1758 4 + (RRRN_R
| ((RRRN_T
& 3) << 4)));
1765 tcg_gen_mov_i32(cpu_R
[RRRN_T
], cpu_R
[RRRN_S
]);
1771 gen_jump(dc
, cpu_R
[0]);
1775 HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER
);
1777 TCGv_i32 tmp
= tcg_const_i32(dc
->pc
);
1778 gen_helper_retw(tmp
, tmp
);
1784 case 2: /*BREAK.Nn*/
1792 gen_exception_cause(dc
, ILLEGAL_INSTRUCTION_CAUSE
);
1795 default: /*reserved*/
1801 default: /*reserved*/
1807 default: /*reserved*/
1812 gen_check_loop_end(dc
, 0);
1813 dc
->pc
= dc
->next_pc
;
1818 qemu_log("INVALID(pc = %08x)\n", dc
->pc
);
1819 dc
->pc
= dc
->next_pc
;
1823 static void check_breakpoint(CPUState
*env
, DisasContext
*dc
)
1827 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
1828 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
1829 if (bp
->pc
== dc
->pc
) {
1830 tcg_gen_movi_i32(cpu_pc
, dc
->pc
);
1831 gen_exception(EXCP_DEBUG
);
1832 dc
->is_jmp
= DISAS_UPDATE
;
1838 static void gen_intermediate_code_internal(
1839 CPUState
*env
, TranslationBlock
*tb
, int search_pc
)
1844 uint16_t *gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
1845 int max_insns
= tb
->cflags
& CF_COUNT_MASK
;
1846 uint32_t pc_start
= tb
->pc
;
1847 uint32_t next_page_start
=
1848 (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
1850 if (max_insns
== 0) {
1851 max_insns
= CF_COUNT_MASK
;
1854 dc
.config
= env
->config
;
1855 dc
.singlestep_enabled
= env
->singlestep_enabled
;
1858 dc
.ring
= tb
->flags
& XTENSA_TBFLAG_RING_MASK
;
1859 dc
.cring
= (tb
->flags
& XTENSA_TBFLAG_EXCM
) ? 0 : dc
.ring
;
1860 dc
.lbeg
= env
->sregs
[LBEG
];
1861 dc
.lend
= env
->sregs
[LEND
];
1862 dc
.is_jmp
= DISAS_NEXT
;
1865 init_sar_tracker(&dc
);
1869 if (env
->singlestep_enabled
&& env
->exception_taken
) {
1870 env
->exception_taken
= 0;
1871 tcg_gen_movi_i32(cpu_pc
, dc
.pc
);
1872 gen_exception(EXCP_DEBUG
);
1876 check_breakpoint(env
, &dc
);
1879 j
= gen_opc_ptr
- gen_opc_buf
;
1883 gen_opc_instr_start
[lj
++] = 0;
1886 gen_opc_pc
[lj
] = dc
.pc
;
1887 gen_opc_instr_start
[lj
] = 1;
1888 gen_opc_icount
[lj
] = insn_count
;
1891 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
))) {
1892 tcg_gen_debug_insn_start(dc
.pc
);
1895 disas_xtensa_insn(&dc
);
1897 if (env
->singlestep_enabled
) {
1898 tcg_gen_movi_i32(cpu_pc
, dc
.pc
);
1899 gen_exception(EXCP_DEBUG
);
1902 } while (dc
.is_jmp
== DISAS_NEXT
&&
1903 insn_count
< max_insns
&&
1904 dc
.pc
< next_page_start
&&
1905 gen_opc_ptr
< gen_opc_end
);
1908 reset_sar_tracker(&dc
);
1910 if (dc
.is_jmp
== DISAS_NEXT
) {
1911 gen_jumpi(&dc
, dc
.pc
, 0);
1913 gen_icount_end(tb
, insn_count
);
1914 *gen_opc_ptr
= INDEX_op_end
;
1917 tb
->size
= dc
.pc
- pc_start
;
1918 tb
->icount
= insn_count
;
1922 void gen_intermediate_code(CPUState
*env
, TranslationBlock
*tb
)
1924 gen_intermediate_code_internal(env
, tb
, 0);
1927 void gen_intermediate_code_pc(CPUState
*env
, TranslationBlock
*tb
)
1929 gen_intermediate_code_internal(env
, tb
, 1);
1932 void cpu_dump_state(CPUState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
1937 cpu_fprintf(f
, "PC=%08x\n\n", env
->pc
);
1939 for (i
= j
= 0; i
< 256; ++i
) {
1941 cpu_fprintf(f
, "%s=%08x%c", sregnames
[i
], env
->sregs
[i
],
1942 (j
++ % 4) == 3 ? '\n' : ' ');
1946 cpu_fprintf(f
, (j
% 4) == 0 ? "\n" : "\n\n");
1948 for (i
= j
= 0; i
< 256; ++i
) {
1950 cpu_fprintf(f
, "%s=%08x%c", uregnames
[i
], env
->uregs
[i
],
1951 (j
++ % 4) == 3 ? '\n' : ' ');
1955 cpu_fprintf(f
, (j
% 4) == 0 ? "\n" : "\n\n");
1957 for (i
= 0; i
< 16; ++i
) {
1958 cpu_fprintf(f
, "A%02d=%08x%c", i
, env
->regs
[i
],
1959 (i
% 4) == 3 ? '\n' : ' ');
1962 cpu_fprintf(f
, "\n");
1964 for (i
= 0; i
< env
->config
->nareg
; ++i
) {
1965 cpu_fprintf(f
, "AR%02d=%08x%c", i
, env
->phys_regs
[i
],
1966 (i
% 4) == 3 ? '\n' : ' ');
1970 void restore_state_to_opc(CPUState
*env
, TranslationBlock
*tb
, int pc_pos
)
1972 env
->pc
= gen_opc_pc
[pc_pos
];