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