Statistics
| Branch: | Revision:

root / target-xtensa / translate.c @ dd519cbe

History | View | Annotate | Download (85.7 kB)

1 2328826b Max Filippov
/*
2 2328826b Max Filippov
 * Xtensa ISA:
3 2328826b Max Filippov
 * http://www.tensilica.com/products/literature-docs/documentation/xtensa-isa-databook.htm
4 2328826b Max Filippov
 *
5 2328826b Max Filippov
 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
6 2328826b Max Filippov
 * All rights reserved.
7 2328826b Max Filippov
 *
8 2328826b Max Filippov
 * Redistribution and use in source and binary forms, with or without
9 2328826b Max Filippov
 * modification, are permitted provided that the following conditions are met:
10 2328826b Max Filippov
 *     * Redistributions of source code must retain the above copyright
11 2328826b Max Filippov
 *       notice, this list of conditions and the following disclaimer.
12 2328826b Max Filippov
 *     * Redistributions in binary form must reproduce the above copyright
13 2328826b Max Filippov
 *       notice, this list of conditions and the following disclaimer in the
14 2328826b Max Filippov
 *       documentation and/or other materials provided with the distribution.
15 2328826b Max Filippov
 *     * Neither the name of the Open Source and Linux Lab nor the
16 2328826b Max Filippov
 *       names of its contributors may be used to endorse or promote products
17 2328826b Max Filippov
 *       derived from this software without specific prior written permission.
18 2328826b Max Filippov
 *
19 2328826b Max Filippov
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 2328826b Max Filippov
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 2328826b Max Filippov
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 2328826b Max Filippov
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 2328826b Max Filippov
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 2328826b Max Filippov
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 2328826b Max Filippov
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 2328826b Max Filippov
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 2328826b Max Filippov
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 2328826b Max Filippov
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 2328826b Max Filippov
 */
30 2328826b Max Filippov
31 2328826b Max Filippov
#include <stdio.h>
32 2328826b Max Filippov
33 2328826b Max Filippov
#include "cpu.h"
34 2328826b Max Filippov
#include "exec-all.h"
35 2328826b Max Filippov
#include "disas.h"
36 2328826b Max Filippov
#include "tcg-op.h"
37 2328826b Max Filippov
#include "qemu-log.h"
38 1ddeaa5d Max Filippov
#include "sysemu.h"
39 2328826b Max Filippov
40 16c1deae Lluís Vilanova
#include "helper.h"
41 dedc5eae Max Filippov
#define GEN_HELPER 1
42 16c1deae Lluís Vilanova
#include "helper.h"
43 dedc5eae Max Filippov
44 dedc5eae Max Filippov
typedef struct DisasContext {
45 dedc5eae Max Filippov
    const XtensaConfig *config;
46 dedc5eae Max Filippov
    TranslationBlock *tb;
47 dedc5eae Max Filippov
    uint32_t pc;
48 dedc5eae Max Filippov
    uint32_t next_pc;
49 f0a548b9 Max Filippov
    int cring;
50 f0a548b9 Max Filippov
    int ring;
51 797d780b Max Filippov
    uint32_t lbeg;
52 797d780b Max Filippov
    uint32_t lend;
53 6ad6dbf7 Max Filippov
    TCGv_i32 litbase;
54 dedc5eae Max Filippov
    int is_jmp;
55 dedc5eae Max Filippov
    int singlestep_enabled;
56 3580ecad Max Filippov
57 3580ecad Max Filippov
    bool sar_5bit;
58 3580ecad Max Filippov
    bool sar_m32_5bit;
59 3580ecad Max Filippov
    bool sar_m32_allocated;
60 3580ecad Max Filippov
    TCGv_i32 sar_m32;
61 b994e91b Max Filippov
62 b994e91b Max Filippov
    uint32_t ccount_delta;
63 772177c1 Max Filippov
    unsigned used_window;
64 e61dc8f7 Max Filippov
65 e61dc8f7 Max Filippov
    bool debug;
66 35b5c044 Max Filippov
    bool icount;
67 35b5c044 Max Filippov
    TCGv_i32 next_icount;
68 dedc5eae Max Filippov
} DisasContext;
69 dedc5eae Max Filippov
70 dedc5eae Max Filippov
static TCGv_ptr cpu_env;
71 dedc5eae Max Filippov
static TCGv_i32 cpu_pc;
72 dedc5eae Max Filippov
static TCGv_i32 cpu_R[16];
73 dd519cbe Max Filippov
static TCGv_i32 cpu_FR[16];
74 2af3da91 Max Filippov
static TCGv_i32 cpu_SR[256];
75 2af3da91 Max Filippov
static TCGv_i32 cpu_UR[256];
76 dedc5eae Max Filippov
77 dedc5eae Max Filippov
#include "gen-icount.h"
78 2328826b Max Filippov
79 2af3da91 Max Filippov
static const char * const sregnames[256] = {
80 797d780b Max Filippov
    [LBEG] = "LBEG",
81 797d780b Max Filippov
    [LEND] = "LEND",
82 797d780b Max Filippov
    [LCOUNT] = "LCOUNT",
83 3580ecad Max Filippov
    [SAR] = "SAR",
84 4dd85b6b Max Filippov
    [BR] = "BR",
85 6ad6dbf7 Max Filippov
    [LITBASE] = "LITBASE",
86 809377aa Max Filippov
    [SCOMPARE1] = "SCOMPARE1",
87 6825b6c3 Max Filippov
    [ACCLO] = "ACCLO",
88 6825b6c3 Max Filippov
    [ACCHI] = "ACCHI",
89 6825b6c3 Max Filippov
    [MR] = "MR0",
90 6825b6c3 Max Filippov
    [MR + 1] = "MR1",
91 6825b6c3 Max Filippov
    [MR + 2] = "MR2",
92 6825b6c3 Max Filippov
    [MR + 3] = "MR3",
93 553e44f9 Max Filippov
    [WINDOW_BASE] = "WINDOW_BASE",
94 553e44f9 Max Filippov
    [WINDOW_START] = "WINDOW_START",
95 b67ea0cd Max Filippov
    [PTEVADDR] = "PTEVADDR",
96 b67ea0cd Max Filippov
    [RASID] = "RASID",
97 b67ea0cd Max Filippov
    [ITLBCFG] = "ITLBCFG",
98 b67ea0cd Max Filippov
    [DTLBCFG] = "DTLBCFG",
99 e61dc8f7 Max Filippov
    [IBREAKENABLE] = "IBREAKENABLE",
100 e61dc8f7 Max Filippov
    [IBREAKA] = "IBREAKA0",
101 e61dc8f7 Max Filippov
    [IBREAKA + 1] = "IBREAKA1",
102 f14c4b5f Max Filippov
    [DBREAKA] = "DBREAKA0",
103 f14c4b5f Max Filippov
    [DBREAKA + 1] = "DBREAKA1",
104 f14c4b5f Max Filippov
    [DBREAKC] = "DBREAKC0",
105 f14c4b5f Max Filippov
    [DBREAKC + 1] = "DBREAKC1",
106 40643d7c Max Filippov
    [EPC1] = "EPC1",
107 b994e91b Max Filippov
    [EPC1 + 1] = "EPC2",
108 b994e91b Max Filippov
    [EPC1 + 2] = "EPC3",
109 b994e91b Max Filippov
    [EPC1 + 3] = "EPC4",
110 b994e91b Max Filippov
    [EPC1 + 4] = "EPC5",
111 b994e91b Max Filippov
    [EPC1 + 5] = "EPC6",
112 b994e91b Max Filippov
    [EPC1 + 6] = "EPC7",
113 40643d7c Max Filippov
    [DEPC] = "DEPC",
114 b994e91b Max Filippov
    [EPS2] = "EPS2",
115 b994e91b Max Filippov
    [EPS2 + 1] = "EPS3",
116 b994e91b Max Filippov
    [EPS2 + 2] = "EPS4",
117 b994e91b Max Filippov
    [EPS2 + 3] = "EPS5",
118 b994e91b Max Filippov
    [EPS2 + 4] = "EPS6",
119 b994e91b Max Filippov
    [EPS2 + 5] = "EPS7",
120 40643d7c Max Filippov
    [EXCSAVE1] = "EXCSAVE1",
121 b994e91b Max Filippov
    [EXCSAVE1 + 1] = "EXCSAVE2",
122 b994e91b Max Filippov
    [EXCSAVE1 + 2] = "EXCSAVE3",
123 b994e91b Max Filippov
    [EXCSAVE1 + 3] = "EXCSAVE4",
124 b994e91b Max Filippov
    [EXCSAVE1 + 4] = "EXCSAVE5",
125 b994e91b Max Filippov
    [EXCSAVE1 + 5] = "EXCSAVE6",
126 b994e91b Max Filippov
    [EXCSAVE1 + 6] = "EXCSAVE7",
127 f3df4c04 Max Filippov
    [CPENABLE] = "CPENABLE",
128 b994e91b Max Filippov
    [INTSET] = "INTSET",
129 b994e91b Max Filippov
    [INTCLEAR] = "INTCLEAR",
130 b994e91b Max Filippov
    [INTENABLE] = "INTENABLE",
131 f0a548b9 Max Filippov
    [PS] = "PS",
132 97836cee Max Filippov
    [VECBASE] = "VECBASE",
133 40643d7c Max Filippov
    [EXCCAUSE] = "EXCCAUSE",
134 ab58c5b4 Max Filippov
    [DEBUGCAUSE] = "DEBUGCAUSE",
135 b994e91b Max Filippov
    [CCOUNT] = "CCOUNT",
136 f3df4c04 Max Filippov
    [PRID] = "PRID",
137 35b5c044 Max Filippov
    [ICOUNT] = "ICOUNT",
138 35b5c044 Max Filippov
    [ICOUNTLEVEL] = "ICOUNTLEVEL",
139 40643d7c Max Filippov
    [EXCVADDR] = "EXCVADDR",
140 b994e91b Max Filippov
    [CCOMPARE] = "CCOMPARE0",
141 b994e91b Max Filippov
    [CCOMPARE + 1] = "CCOMPARE1",
142 b994e91b Max Filippov
    [CCOMPARE + 2] = "CCOMPARE2",
143 2af3da91 Max Filippov
};
144 2af3da91 Max Filippov
145 2af3da91 Max Filippov
static const char * const uregnames[256] = {
146 2af3da91 Max Filippov
    [THREADPTR] = "THREADPTR",
147 2af3da91 Max Filippov
    [FCR] = "FCR",
148 2af3da91 Max Filippov
    [FSR] = "FSR",
149 2af3da91 Max Filippov
};
150 2af3da91 Max Filippov
151 2328826b Max Filippov
void xtensa_translate_init(void)
152 2328826b Max Filippov
{
153 dedc5eae Max Filippov
    static const char * const regnames[] = {
154 dedc5eae Max Filippov
        "ar0", "ar1", "ar2", "ar3",
155 dedc5eae Max Filippov
        "ar4", "ar5", "ar6", "ar7",
156 dedc5eae Max Filippov
        "ar8", "ar9", "ar10", "ar11",
157 dedc5eae Max Filippov
        "ar12", "ar13", "ar14", "ar15",
158 dedc5eae Max Filippov
    };
159 dd519cbe Max Filippov
    static const char * const fregnames[] = {
160 dd519cbe Max Filippov
        "f0", "f1", "f2", "f3",
161 dd519cbe Max Filippov
        "f4", "f5", "f6", "f7",
162 dd519cbe Max Filippov
        "f8", "f9", "f10", "f11",
163 dd519cbe Max Filippov
        "f12", "f13", "f14", "f15",
164 dd519cbe Max Filippov
    };
165 dedc5eae Max Filippov
    int i;
166 dedc5eae Max Filippov
167 dedc5eae Max Filippov
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
168 dedc5eae Max Filippov
    cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
169 97129ac8 Andreas Färber
            offsetof(CPUXtensaState, pc), "pc");
170 dedc5eae Max Filippov
171 dedc5eae Max Filippov
    for (i = 0; i < 16; i++) {
172 dedc5eae Max Filippov
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
173 97129ac8 Andreas Färber
                offsetof(CPUXtensaState, regs[i]),
174 dedc5eae Max Filippov
                regnames[i]);
175 dedc5eae Max Filippov
    }
176 2af3da91 Max Filippov
177 dd519cbe Max Filippov
    for (i = 0; i < 16; i++) {
178 dd519cbe Max Filippov
        cpu_FR[i] = tcg_global_mem_new_i32(TCG_AREG0,
179 dd519cbe Max Filippov
                offsetof(CPUXtensaState, fregs[i]),
180 dd519cbe Max Filippov
                fregnames[i]);
181 dd519cbe Max Filippov
    }
182 dd519cbe Max Filippov
183 2af3da91 Max Filippov
    for (i = 0; i < 256; ++i) {
184 2af3da91 Max Filippov
        if (sregnames[i]) {
185 2af3da91 Max Filippov
            cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
186 97129ac8 Andreas Färber
                    offsetof(CPUXtensaState, sregs[i]),
187 2af3da91 Max Filippov
                    sregnames[i]);
188 2af3da91 Max Filippov
        }
189 2af3da91 Max Filippov
    }
190 2af3da91 Max Filippov
191 2af3da91 Max Filippov
    for (i = 0; i < 256; ++i) {
192 2af3da91 Max Filippov
        if (uregnames[i]) {
193 2af3da91 Max Filippov
            cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
194 97129ac8 Andreas Färber
                    offsetof(CPUXtensaState, uregs[i]),
195 2af3da91 Max Filippov
                    uregnames[i]);
196 2af3da91 Max Filippov
        }
197 2af3da91 Max Filippov
    }
198 dedc5eae Max Filippov
#define GEN_HELPER 2
199 16c1deae Lluís Vilanova
#include "helper.h"
200 dedc5eae Max Filippov
}
201 dedc5eae Max Filippov
202 b67ea0cd Max Filippov
static inline bool option_bits_enabled(DisasContext *dc, uint64_t opt)
203 b67ea0cd Max Filippov
{
204 b67ea0cd Max Filippov
    return xtensa_option_bits_enabled(dc->config, opt);
205 b67ea0cd Max Filippov
}
206 b67ea0cd Max Filippov
207 dedc5eae Max Filippov
static inline bool option_enabled(DisasContext *dc, int opt)
208 dedc5eae Max Filippov
{
209 dedc5eae Max Filippov
    return xtensa_option_enabled(dc->config, opt);
210 dedc5eae Max Filippov
}
211 dedc5eae Max Filippov
212 6ad6dbf7 Max Filippov
static void init_litbase(DisasContext *dc)
213 6ad6dbf7 Max Filippov
{
214 6ad6dbf7 Max Filippov
    if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
215 6ad6dbf7 Max Filippov
        dc->litbase = tcg_temp_local_new_i32();
216 6ad6dbf7 Max Filippov
        tcg_gen_andi_i32(dc->litbase, cpu_SR[LITBASE], 0xfffff000);
217 6ad6dbf7 Max Filippov
    }
218 6ad6dbf7 Max Filippov
}
219 6ad6dbf7 Max Filippov
220 6ad6dbf7 Max Filippov
static void reset_litbase(DisasContext *dc)
221 6ad6dbf7 Max Filippov
{
222 6ad6dbf7 Max Filippov
    if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
223 6ad6dbf7 Max Filippov
        tcg_temp_free(dc->litbase);
224 6ad6dbf7 Max Filippov
    }
225 6ad6dbf7 Max Filippov
}
226 6ad6dbf7 Max Filippov
227 3580ecad Max Filippov
static void init_sar_tracker(DisasContext *dc)
228 3580ecad Max Filippov
{
229 3580ecad Max Filippov
    dc->sar_5bit = false;
230 3580ecad Max Filippov
    dc->sar_m32_5bit = false;
231 3580ecad Max Filippov
    dc->sar_m32_allocated = false;
232 3580ecad Max Filippov
}
233 3580ecad Max Filippov
234 3580ecad Max Filippov
static void reset_sar_tracker(DisasContext *dc)
235 3580ecad Max Filippov
{
236 3580ecad Max Filippov
    if (dc->sar_m32_allocated) {
237 3580ecad Max Filippov
        tcg_temp_free(dc->sar_m32);
238 3580ecad Max Filippov
    }
239 3580ecad Max Filippov
}
240 3580ecad Max Filippov
241 3580ecad Max Filippov
static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
242 3580ecad Max Filippov
{
243 3580ecad Max Filippov
    tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
244 3580ecad Max Filippov
    if (dc->sar_m32_5bit) {
245 3580ecad Max Filippov
        tcg_gen_discard_i32(dc->sar_m32);
246 3580ecad Max Filippov
    }
247 3580ecad Max Filippov
    dc->sar_5bit = true;
248 3580ecad Max Filippov
    dc->sar_m32_5bit = false;
249 3580ecad Max Filippov
}
250 3580ecad Max Filippov
251 3580ecad Max Filippov
static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
252 3580ecad Max Filippov
{
253 3580ecad Max Filippov
    TCGv_i32 tmp = tcg_const_i32(32);
254 3580ecad Max Filippov
    if (!dc->sar_m32_allocated) {
255 3580ecad Max Filippov
        dc->sar_m32 = tcg_temp_local_new_i32();
256 3580ecad Max Filippov
        dc->sar_m32_allocated = true;
257 3580ecad Max Filippov
    }
258 3580ecad Max Filippov
    tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
259 3580ecad Max Filippov
    tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
260 3580ecad Max Filippov
    dc->sar_5bit = false;
261 3580ecad Max Filippov
    dc->sar_m32_5bit = true;
262 3580ecad Max Filippov
    tcg_temp_free(tmp);
263 3580ecad Max Filippov
}
264 3580ecad Max Filippov
265 b994e91b Max Filippov
static void gen_advance_ccount(DisasContext *dc)
266 b994e91b Max Filippov
{
267 b994e91b Max Filippov
    if (dc->ccount_delta > 0) {
268 b994e91b Max Filippov
        TCGv_i32 tmp = tcg_const_i32(dc->ccount_delta);
269 b994e91b Max Filippov
        dc->ccount_delta = 0;
270 f492b82d Max Filippov
        gen_helper_advance_ccount(cpu_env, tmp);
271 b994e91b Max Filippov
        tcg_temp_free(tmp);
272 b994e91b Max Filippov
    }
273 b994e91b Max Filippov
}
274 b994e91b Max Filippov
275 772177c1 Max Filippov
static void reset_used_window(DisasContext *dc)
276 772177c1 Max Filippov
{
277 772177c1 Max Filippov
    dc->used_window = 0;
278 772177c1 Max Filippov
}
279 772177c1 Max Filippov
280 b994e91b Max Filippov
static void gen_exception(DisasContext *dc, int excp)
281 dedc5eae Max Filippov
{
282 dedc5eae Max Filippov
    TCGv_i32 tmp = tcg_const_i32(excp);
283 b994e91b Max Filippov
    gen_advance_ccount(dc);
284 f492b82d Max Filippov
    gen_helper_exception(cpu_env, tmp);
285 dedc5eae Max Filippov
    tcg_temp_free(tmp);
286 dedc5eae Max Filippov
}
287 dedc5eae Max Filippov
288 40643d7c Max Filippov
static void gen_exception_cause(DisasContext *dc, uint32_t cause)
289 40643d7c Max Filippov
{
290 40643d7c Max Filippov
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
291 40643d7c Max Filippov
    TCGv_i32 tcause = tcg_const_i32(cause);
292 b994e91b Max Filippov
    gen_advance_ccount(dc);
293 f492b82d Max Filippov
    gen_helper_exception_cause(cpu_env, tpc, tcause);
294 40643d7c Max Filippov
    tcg_temp_free(tpc);
295 40643d7c Max Filippov
    tcg_temp_free(tcause);
296 6b814719 Max Filippov
    if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
297 6b814719 Max Filippov
            cause == SYSCALL_CAUSE) {
298 6b814719 Max Filippov
        dc->is_jmp = DISAS_UPDATE;
299 6b814719 Max Filippov
    }
300 40643d7c Max Filippov
}
301 40643d7c Max Filippov
302 5b4e481b Max Filippov
static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
303 5b4e481b Max Filippov
        TCGv_i32 vaddr)
304 5b4e481b Max Filippov
{
305 5b4e481b Max Filippov
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
306 5b4e481b Max Filippov
    TCGv_i32 tcause = tcg_const_i32(cause);
307 b994e91b Max Filippov
    gen_advance_ccount(dc);
308 f492b82d Max Filippov
    gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr);
309 5b4e481b Max Filippov
    tcg_temp_free(tpc);
310 5b4e481b Max Filippov
    tcg_temp_free(tcause);
311 5b4e481b Max Filippov
}
312 5b4e481b Max Filippov
313 e61dc8f7 Max Filippov
static void gen_debug_exception(DisasContext *dc, uint32_t cause)
314 e61dc8f7 Max Filippov
{
315 e61dc8f7 Max Filippov
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
316 e61dc8f7 Max Filippov
    TCGv_i32 tcause = tcg_const_i32(cause);
317 e61dc8f7 Max Filippov
    gen_advance_ccount(dc);
318 f492b82d Max Filippov
    gen_helper_debug_exception(cpu_env, tpc, tcause);
319 e61dc8f7 Max Filippov
    tcg_temp_free(tpc);
320 e61dc8f7 Max Filippov
    tcg_temp_free(tcause);
321 e61dc8f7 Max Filippov
    if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
322 e61dc8f7 Max Filippov
        dc->is_jmp = DISAS_UPDATE;
323 e61dc8f7 Max Filippov
    }
324 e61dc8f7 Max Filippov
}
325 e61dc8f7 Max Filippov
326 40643d7c Max Filippov
static void gen_check_privilege(DisasContext *dc)
327 40643d7c Max Filippov
{
328 40643d7c Max Filippov
    if (dc->cring) {
329 40643d7c Max Filippov
        gen_exception_cause(dc, PRIVILEGED_CAUSE);
330 6b814719 Max Filippov
        dc->is_jmp = DISAS_UPDATE;
331 40643d7c Max Filippov
    }
332 40643d7c Max Filippov
}
333 40643d7c Max Filippov
334 dedc5eae Max Filippov
static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
335 dedc5eae Max Filippov
{
336 dedc5eae Max Filippov
    tcg_gen_mov_i32(cpu_pc, dest);
337 35b5c044 Max Filippov
    gen_advance_ccount(dc);
338 35b5c044 Max Filippov
    if (dc->icount) {
339 35b5c044 Max Filippov
        tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
340 35b5c044 Max Filippov
    }
341 dedc5eae Max Filippov
    if (dc->singlestep_enabled) {
342 b994e91b Max Filippov
        gen_exception(dc, EXCP_DEBUG);
343 dedc5eae Max Filippov
    } else {
344 dedc5eae Max Filippov
        if (slot >= 0) {
345 dedc5eae Max Filippov
            tcg_gen_goto_tb(slot);
346 dedc5eae Max Filippov
            tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
347 dedc5eae Max Filippov
        } else {
348 dedc5eae Max Filippov
            tcg_gen_exit_tb(0);
349 dedc5eae Max Filippov
        }
350 dedc5eae Max Filippov
    }
351 dedc5eae Max Filippov
    dc->is_jmp = DISAS_UPDATE;
352 dedc5eae Max Filippov
}
353 dedc5eae Max Filippov
354 67882fd1 Max Filippov
static void gen_jump(DisasContext *dc, TCGv dest)
355 67882fd1 Max Filippov
{
356 67882fd1 Max Filippov
    gen_jump_slot(dc, dest, -1);
357 67882fd1 Max Filippov
}
358 67882fd1 Max Filippov
359 dedc5eae Max Filippov
static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
360 dedc5eae Max Filippov
{
361 dedc5eae Max Filippov
    TCGv_i32 tmp = tcg_const_i32(dest);
362 dedc5eae Max Filippov
    if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
363 dedc5eae Max Filippov
        slot = -1;
364 dedc5eae Max Filippov
    }
365 dedc5eae Max Filippov
    gen_jump_slot(dc, tmp, slot);
366 dedc5eae Max Filippov
    tcg_temp_free(tmp);
367 dedc5eae Max Filippov
}
368 dedc5eae Max Filippov
369 553e44f9 Max Filippov
static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
370 553e44f9 Max Filippov
        int slot)
371 553e44f9 Max Filippov
{
372 553e44f9 Max Filippov
    TCGv_i32 tcallinc = tcg_const_i32(callinc);
373 553e44f9 Max Filippov
374 553e44f9 Max Filippov
    tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
375 553e44f9 Max Filippov
            tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
376 553e44f9 Max Filippov
    tcg_temp_free(tcallinc);
377 553e44f9 Max Filippov
    tcg_gen_movi_i32(cpu_R[callinc << 2],
378 553e44f9 Max Filippov
            (callinc << 30) | (dc->next_pc & 0x3fffffff));
379 553e44f9 Max Filippov
    gen_jump_slot(dc, dest, slot);
380 553e44f9 Max Filippov
}
381 553e44f9 Max Filippov
382 553e44f9 Max Filippov
static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
383 553e44f9 Max Filippov
{
384 553e44f9 Max Filippov
    gen_callw_slot(dc, callinc, dest, -1);
385 553e44f9 Max Filippov
}
386 553e44f9 Max Filippov
387 553e44f9 Max Filippov
static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
388 553e44f9 Max Filippov
{
389 553e44f9 Max Filippov
    TCGv_i32 tmp = tcg_const_i32(dest);
390 553e44f9 Max Filippov
    if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
391 553e44f9 Max Filippov
        slot = -1;
392 553e44f9 Max Filippov
    }
393 553e44f9 Max Filippov
    gen_callw_slot(dc, callinc, tmp, slot);
394 553e44f9 Max Filippov
    tcg_temp_free(tmp);
395 553e44f9 Max Filippov
}
396 553e44f9 Max Filippov
397 797d780b Max Filippov
static bool gen_check_loop_end(DisasContext *dc, int slot)
398 797d780b Max Filippov
{
399 797d780b Max Filippov
    if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
400 797d780b Max Filippov
            !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&
401 797d780b Max Filippov
            dc->next_pc == dc->lend) {
402 797d780b Max Filippov
        int label = gen_new_label();
403 797d780b Max Filippov
404 d865f307 Max Filippov
        gen_advance_ccount(dc);
405 797d780b Max Filippov
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
406 797d780b Max Filippov
        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
407 797d780b Max Filippov
        gen_jumpi(dc, dc->lbeg, slot);
408 797d780b Max Filippov
        gen_set_label(label);
409 797d780b Max Filippov
        gen_jumpi(dc, dc->next_pc, -1);
410 797d780b Max Filippov
        return true;
411 797d780b Max Filippov
    }
412 797d780b Max Filippov
    return false;
413 797d780b Max Filippov
}
414 797d780b Max Filippov
415 797d780b Max Filippov
static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
416 797d780b Max Filippov
{
417 797d780b Max Filippov
    if (!gen_check_loop_end(dc, slot)) {
418 797d780b Max Filippov
        gen_jumpi(dc, dc->next_pc, slot);
419 797d780b Max Filippov
    }
420 797d780b Max Filippov
}
421 797d780b Max Filippov
422 bd57fb91 Max Filippov
static void gen_brcond(DisasContext *dc, TCGCond cond,
423 bd57fb91 Max Filippov
        TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)
424 bd57fb91 Max Filippov
{
425 bd57fb91 Max Filippov
    int label = gen_new_label();
426 bd57fb91 Max Filippov
427 d865f307 Max Filippov
    gen_advance_ccount(dc);
428 bd57fb91 Max Filippov
    tcg_gen_brcond_i32(cond, t0, t1, label);
429 797d780b Max Filippov
    gen_jumpi_check_loop_end(dc, 0);
430 bd57fb91 Max Filippov
    gen_set_label(label);
431 bd57fb91 Max Filippov
    gen_jumpi(dc, dc->pc + offset, 1);
432 bd57fb91 Max Filippov
}
433 bd57fb91 Max Filippov
434 bd57fb91 Max Filippov
static void gen_brcondi(DisasContext *dc, TCGCond cond,
435 bd57fb91 Max Filippov
        TCGv_i32 t0, uint32_t t1, uint32_t offset)
436 bd57fb91 Max Filippov
{
437 bd57fb91 Max Filippov
    TCGv_i32 tmp = tcg_const_i32(t1);
438 bd57fb91 Max Filippov
    gen_brcond(dc, cond, t0, tmp, offset);
439 bd57fb91 Max Filippov
    tcg_temp_free(tmp);
440 bd57fb91 Max Filippov
}
441 bd57fb91 Max Filippov
442 b994e91b Max Filippov
static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
443 b994e91b Max Filippov
{
444 b994e91b Max Filippov
    gen_advance_ccount(dc);
445 b994e91b Max Filippov
    tcg_gen_mov_i32(d, cpu_SR[sr]);
446 b994e91b Max Filippov
}
447 b994e91b Max Filippov
448 b67ea0cd Max Filippov
static void gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
449 b67ea0cd Max Filippov
{
450 b67ea0cd Max Filippov
    tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10);
451 b67ea0cd Max Filippov
    tcg_gen_or_i32(d, d, cpu_SR[sr]);
452 b67ea0cd Max Filippov
    tcg_gen_andi_i32(d, d, 0xfffffffc);
453 b67ea0cd Max Filippov
}
454 b67ea0cd Max Filippov
455 b8132eff Max Filippov
static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
456 b8132eff Max Filippov
{
457 b8132eff Max Filippov
    static void (* const rsr_handler[256])(DisasContext *dc,
458 b8132eff Max Filippov
            TCGv_i32 d, uint32_t sr) = {
459 b994e91b Max Filippov
        [CCOUNT] = gen_rsr_ccount,
460 b67ea0cd Max Filippov
        [PTEVADDR] = gen_rsr_ptevaddr,
461 b8132eff Max Filippov
    };
462 b8132eff Max Filippov
463 b8132eff Max Filippov
    if (sregnames[sr]) {
464 b8132eff Max Filippov
        if (rsr_handler[sr]) {
465 b8132eff Max Filippov
            rsr_handler[sr](dc, d, sr);
466 b8132eff Max Filippov
        } else {
467 b8132eff Max Filippov
            tcg_gen_mov_i32(d, cpu_SR[sr]);
468 b8132eff Max Filippov
        }
469 b8132eff Max Filippov
    } else {
470 b8132eff Max Filippov
        qemu_log("RSR %d not implemented, ", sr);
471 b8132eff Max Filippov
    }
472 b8132eff Max Filippov
}
473 b8132eff Max Filippov
474 797d780b Max Filippov
static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
475 797d780b Max Filippov
{
476 f492b82d Max Filippov
    gen_helper_wsr_lbeg(cpu_env, s);
477 3d0be8a5 Max Filippov
    gen_jumpi_check_loop_end(dc, 0);
478 797d780b Max Filippov
}
479 797d780b Max Filippov
480 797d780b Max Filippov
static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
481 797d780b Max Filippov
{
482 f492b82d Max Filippov
    gen_helper_wsr_lend(cpu_env, s);
483 3d0be8a5 Max Filippov
    gen_jumpi_check_loop_end(dc, 0);
484 797d780b Max Filippov
}
485 797d780b Max Filippov
486 3580ecad Max Filippov
static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
487 3580ecad Max Filippov
{
488 3580ecad Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
489 3580ecad Max Filippov
    if (dc->sar_m32_5bit) {
490 3580ecad Max Filippov
        tcg_gen_discard_i32(dc->sar_m32);
491 3580ecad Max Filippov
    }
492 3580ecad Max Filippov
    dc->sar_5bit = false;
493 3580ecad Max Filippov
    dc->sar_m32_5bit = false;
494 3580ecad Max Filippov
}
495 3580ecad Max Filippov
496 4dd85b6b Max Filippov
static void gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
497 4dd85b6b Max Filippov
{
498 4dd85b6b Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
499 4dd85b6b Max Filippov
}
500 4dd85b6b Max Filippov
501 6ad6dbf7 Max Filippov
static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
502 6ad6dbf7 Max Filippov
{
503 6ad6dbf7 Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
504 6ad6dbf7 Max Filippov
    /* This can change tb->flags, so exit tb */
505 6ad6dbf7 Max Filippov
    gen_jumpi_check_loop_end(dc, -1);
506 6ad6dbf7 Max Filippov
}
507 6ad6dbf7 Max Filippov
508 6825b6c3 Max Filippov
static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
509 6825b6c3 Max Filippov
{
510 6825b6c3 Max Filippov
    tcg_gen_ext8s_i32(cpu_SR[sr], s);
511 6825b6c3 Max Filippov
}
512 6825b6c3 Max Filippov
513 553e44f9 Max Filippov
static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
514 553e44f9 Max Filippov
{
515 f492b82d Max Filippov
    gen_helper_wsr_windowbase(cpu_env, v);
516 772177c1 Max Filippov
    reset_used_window(dc);
517 772177c1 Max Filippov
}
518 772177c1 Max Filippov
519 772177c1 Max Filippov
static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
520 772177c1 Max Filippov
{
521 53a72dfd Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1);
522 772177c1 Max Filippov
    reset_used_window(dc);
523 553e44f9 Max Filippov
}
524 553e44f9 Max Filippov
525 b67ea0cd Max Filippov
static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
526 b67ea0cd Max Filippov
{
527 b67ea0cd Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
528 b67ea0cd Max Filippov
}
529 b67ea0cd Max Filippov
530 b67ea0cd Max Filippov
static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
531 b67ea0cd Max Filippov
{
532 f492b82d Max Filippov
    gen_helper_wsr_rasid(cpu_env, v);
533 b67ea0cd Max Filippov
    /* This can change tb->flags, so exit tb */
534 b67ea0cd Max Filippov
    gen_jumpi_check_loop_end(dc, -1);
535 b67ea0cd Max Filippov
}
536 b67ea0cd Max Filippov
537 b67ea0cd Max Filippov
static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
538 b67ea0cd Max Filippov
{
539 b67ea0cd Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
540 b67ea0cd Max Filippov
}
541 b67ea0cd Max Filippov
542 e61dc8f7 Max Filippov
static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
543 e61dc8f7 Max Filippov
{
544 f492b82d Max Filippov
    gen_helper_wsr_ibreakenable(cpu_env, v);
545 e61dc8f7 Max Filippov
    gen_jumpi_check_loop_end(dc, 0);
546 e61dc8f7 Max Filippov
}
547 e61dc8f7 Max Filippov
548 e61dc8f7 Max Filippov
static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
549 e61dc8f7 Max Filippov
{
550 e61dc8f7 Max Filippov
    unsigned id = sr - IBREAKA;
551 e61dc8f7 Max Filippov
552 e61dc8f7 Max Filippov
    if (id < dc->config->nibreak) {
553 e61dc8f7 Max Filippov
        TCGv_i32 tmp = tcg_const_i32(id);
554 f492b82d Max Filippov
        gen_helper_wsr_ibreaka(cpu_env, tmp, v);
555 e61dc8f7 Max Filippov
        tcg_temp_free(tmp);
556 e61dc8f7 Max Filippov
        gen_jumpi_check_loop_end(dc, 0);
557 e61dc8f7 Max Filippov
    }
558 e61dc8f7 Max Filippov
}
559 e61dc8f7 Max Filippov
560 f14c4b5f Max Filippov
static void gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
561 f14c4b5f Max Filippov
{
562 f14c4b5f Max Filippov
    unsigned id = sr - DBREAKA;
563 f14c4b5f Max Filippov
564 f14c4b5f Max Filippov
    if (id < dc->config->ndbreak) {
565 f14c4b5f Max Filippov
        TCGv_i32 tmp = tcg_const_i32(id);
566 f492b82d Max Filippov
        gen_helper_wsr_dbreaka(cpu_env, tmp, v);
567 f14c4b5f Max Filippov
        tcg_temp_free(tmp);
568 f14c4b5f Max Filippov
    }
569 f14c4b5f Max Filippov
}
570 f14c4b5f Max Filippov
571 f14c4b5f Max Filippov
static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
572 f14c4b5f Max Filippov
{
573 f14c4b5f Max Filippov
    unsigned id = sr - DBREAKC;
574 f14c4b5f Max Filippov
575 f14c4b5f Max Filippov
    if (id < dc->config->ndbreak) {
576 f14c4b5f Max Filippov
        TCGv_i32 tmp = tcg_const_i32(id);
577 f492b82d Max Filippov
        gen_helper_wsr_dbreakc(cpu_env, tmp, v);
578 f14c4b5f Max Filippov
        tcg_temp_free(tmp);
579 f14c4b5f Max Filippov
    }
580 f14c4b5f Max Filippov
}
581 f14c4b5f Max Filippov
582 b994e91b Max Filippov
static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
583 b994e91b Max Filippov
{
584 b994e91b Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], v,
585 b994e91b Max Filippov
            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
586 b994e91b Max Filippov
    gen_helper_check_interrupts(cpu_env);
587 b994e91b Max Filippov
    gen_jumpi_check_loop_end(dc, 0);
588 b994e91b Max Filippov
}
589 b994e91b Max Filippov
590 b994e91b Max Filippov
static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
591 b994e91b Max Filippov
{
592 b994e91b Max Filippov
    TCGv_i32 tmp = tcg_temp_new_i32();
593 b994e91b Max Filippov
594 b994e91b Max Filippov
    tcg_gen_andi_i32(tmp, v,
595 b994e91b Max Filippov
            dc->config->inttype_mask[INTTYPE_EDGE] |
596 b994e91b Max Filippov
            dc->config->inttype_mask[INTTYPE_NMI] |
597 b994e91b Max Filippov
            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
598 b994e91b Max Filippov
    tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp);
599 b994e91b Max Filippov
    tcg_temp_free(tmp);
600 b994e91b Max Filippov
    gen_helper_check_interrupts(cpu_env);
601 b994e91b Max Filippov
}
602 b994e91b Max Filippov
603 b994e91b Max Filippov
static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
604 b994e91b Max Filippov
{
605 b994e91b Max Filippov
    tcg_gen_mov_i32(cpu_SR[sr], v);
606 b994e91b Max Filippov
    gen_helper_check_interrupts(cpu_env);
607 b994e91b Max Filippov
    gen_jumpi_check_loop_end(dc, 0);
608 b994e91b Max Filippov
}
609 b994e91b Max Filippov
610 f0a548b9 Max Filippov
static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
611 f0a548b9 Max Filippov
{
612 f0a548b9 Max Filippov
    uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
613 f0a548b9 Max Filippov
        PS_UM | PS_EXCM | PS_INTLEVEL;
614 f0a548b9 Max Filippov
615 f0a548b9 Max Filippov
    if (option_enabled(dc, XTENSA_OPTION_MMU)) {
616 f0a548b9 Max Filippov
        mask |= PS_RING;
617 f0a548b9 Max Filippov
    }
618 f0a548b9 Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], v, mask);
619 772177c1 Max Filippov
    reset_used_window(dc);
620 b994e91b Max Filippov
    gen_helper_check_interrupts(cpu_env);
621 b994e91b Max Filippov
    /* This can change mmu index and tb->flags, so exit tb */
622 797d780b Max Filippov
    gen_jumpi_check_loop_end(dc, -1);
623 f0a548b9 Max Filippov
}
624 f0a548b9 Max Filippov
625 ab58c5b4 Max Filippov
static void gen_wsr_debugcause(DisasContext *dc, uint32_t sr, TCGv_i32 v)
626 ab58c5b4 Max Filippov
{
627 ab58c5b4 Max Filippov
}
628 ab58c5b4 Max Filippov
629 f3df4c04 Max Filippov
static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
630 f3df4c04 Max Filippov
{
631 f3df4c04 Max Filippov
}
632 f3df4c04 Max Filippov
633 35b5c044 Max Filippov
static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
634 35b5c044 Max Filippov
{
635 35b5c044 Max Filippov
    if (dc->icount) {
636 35b5c044 Max Filippov
        tcg_gen_mov_i32(dc->next_icount, v);
637 35b5c044 Max Filippov
    } else {
638 35b5c044 Max Filippov
        tcg_gen_mov_i32(cpu_SR[sr], v);
639 35b5c044 Max Filippov
    }
640 35b5c044 Max Filippov
}
641 35b5c044 Max Filippov
642 35b5c044 Max Filippov
static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
643 35b5c044 Max Filippov
{
644 35b5c044 Max Filippov
    tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
645 35b5c044 Max Filippov
    /* This can change tb->flags, so exit tb */
646 35b5c044 Max Filippov
    gen_jumpi_check_loop_end(dc, -1);
647 35b5c044 Max Filippov
}
648 35b5c044 Max Filippov
649 b994e91b Max Filippov
static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
650 b994e91b Max Filippov
{
651 b994e91b Max Filippov
    uint32_t id = sr - CCOMPARE;
652 b994e91b Max Filippov
    if (id < dc->config->nccompare) {
653 b994e91b Max Filippov
        uint32_t int_bit = 1 << dc->config->timerint[id];
654 b994e91b Max Filippov
        gen_advance_ccount(dc);
655 b994e91b Max Filippov
        tcg_gen_mov_i32(cpu_SR[sr], v);
656 b994e91b Max Filippov
        tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);
657 b994e91b Max Filippov
        gen_helper_check_interrupts(cpu_env);
658 b994e91b Max Filippov
    }
659 b994e91b Max Filippov
}
660 b994e91b Max Filippov
661 b8132eff Max Filippov
static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
662 b8132eff Max Filippov
{
663 b8132eff Max Filippov
    static void (* const wsr_handler[256])(DisasContext *dc,
664 b8132eff Max Filippov
            uint32_t sr, TCGv_i32 v) = {
665 797d780b Max Filippov
        [LBEG] = gen_wsr_lbeg,
666 797d780b Max Filippov
        [LEND] = gen_wsr_lend,
667 3580ecad Max Filippov
        [SAR] = gen_wsr_sar,
668 4dd85b6b Max Filippov
        [BR] = gen_wsr_br,
669 6ad6dbf7 Max Filippov
        [LITBASE] = gen_wsr_litbase,
670 6825b6c3 Max Filippov
        [ACCHI] = gen_wsr_acchi,
671 553e44f9 Max Filippov
        [WINDOW_BASE] = gen_wsr_windowbase,
672 772177c1 Max Filippov
        [WINDOW_START] = gen_wsr_windowstart,
673 b67ea0cd Max Filippov
        [PTEVADDR] = gen_wsr_ptevaddr,
674 b67ea0cd Max Filippov
        [RASID] = gen_wsr_rasid,
675 b67ea0cd Max Filippov
        [ITLBCFG] = gen_wsr_tlbcfg,
676 b67ea0cd Max Filippov
        [DTLBCFG] = gen_wsr_tlbcfg,
677 e61dc8f7 Max Filippov
        [IBREAKENABLE] = gen_wsr_ibreakenable,
678 e61dc8f7 Max Filippov
        [IBREAKA] = gen_wsr_ibreaka,
679 e61dc8f7 Max Filippov
        [IBREAKA + 1] = gen_wsr_ibreaka,
680 f14c4b5f Max Filippov
        [DBREAKA] = gen_wsr_dbreaka,
681 f14c4b5f Max Filippov
        [DBREAKA + 1] = gen_wsr_dbreaka,
682 f14c4b5f Max Filippov
        [DBREAKC] = gen_wsr_dbreakc,
683 f14c4b5f Max Filippov
        [DBREAKC + 1] = gen_wsr_dbreakc,
684 b994e91b Max Filippov
        [INTSET] = gen_wsr_intset,
685 b994e91b Max Filippov
        [INTCLEAR] = gen_wsr_intclear,
686 b994e91b Max Filippov
        [INTENABLE] = gen_wsr_intenable,
687 f0a548b9 Max Filippov
        [PS] = gen_wsr_ps,
688 ab58c5b4 Max Filippov
        [DEBUGCAUSE] = gen_wsr_debugcause,
689 f3df4c04 Max Filippov
        [PRID] = gen_wsr_prid,
690 35b5c044 Max Filippov
        [ICOUNT] = gen_wsr_icount,
691 35b5c044 Max Filippov
        [ICOUNTLEVEL] = gen_wsr_icountlevel,
692 b994e91b Max Filippov
        [CCOMPARE] = gen_wsr_ccompare,
693 b994e91b Max Filippov
        [CCOMPARE + 1] = gen_wsr_ccompare,
694 b994e91b Max Filippov
        [CCOMPARE + 2] = gen_wsr_ccompare,
695 b8132eff Max Filippov
    };
696 b8132eff Max Filippov
697 b8132eff Max Filippov
    if (sregnames[sr]) {
698 b8132eff Max Filippov
        if (wsr_handler[sr]) {
699 b8132eff Max Filippov
            wsr_handler[sr](dc, sr, s);
700 b8132eff Max Filippov
        } else {
701 b8132eff Max Filippov
            tcg_gen_mov_i32(cpu_SR[sr], s);
702 b8132eff Max Filippov
        }
703 b8132eff Max Filippov
    } else {
704 b8132eff Max Filippov
        qemu_log("WSR %d not implemented, ", sr);
705 b8132eff Max Filippov
    }
706 b8132eff Max Filippov
}
707 b8132eff Max Filippov
708 dd519cbe Max Filippov
static void gen_wur(uint32_t ur, TCGv_i32 s)
709 dd519cbe Max Filippov
{
710 dd519cbe Max Filippov
    switch (ur) {
711 dd519cbe Max Filippov
    case FCR:
712 dd519cbe Max Filippov
        gen_helper_wur_fcr(cpu_env, s);
713 dd519cbe Max Filippov
        break;
714 dd519cbe Max Filippov
715 dd519cbe Max Filippov
    case FSR:
716 dd519cbe Max Filippov
        tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80);
717 dd519cbe Max Filippov
        break;
718 dd519cbe Max Filippov
719 dd519cbe Max Filippov
    default:
720 dd519cbe Max Filippov
        tcg_gen_mov_i32(cpu_UR[ur], s);
721 dd519cbe Max Filippov
        break;
722 dd519cbe Max Filippov
    }
723 dd519cbe Max Filippov
}
724 dd519cbe Max Filippov
725 5b4e481b Max Filippov
static void gen_load_store_alignment(DisasContext *dc, int shift,
726 5b4e481b Max Filippov
        TCGv_i32 addr, bool no_hw_alignment)
727 5b4e481b Max Filippov
{
728 5b4e481b Max Filippov
    if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
729 5b4e481b Max Filippov
        tcg_gen_andi_i32(addr, addr, ~0 << shift);
730 5b4e481b Max Filippov
    } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
731 5b4e481b Max Filippov
            no_hw_alignment) {
732 5b4e481b Max Filippov
        int label = gen_new_label();
733 5b4e481b Max Filippov
        TCGv_i32 tmp = tcg_temp_new_i32();
734 5b4e481b Max Filippov
        tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
735 5b4e481b Max Filippov
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
736 5b4e481b Max Filippov
        gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
737 5b4e481b Max Filippov
        gen_set_label(label);
738 5b4e481b Max Filippov
        tcg_temp_free(tmp);
739 5b4e481b Max Filippov
    }
740 5b4e481b Max Filippov
}
741 5b4e481b Max Filippov
742 b994e91b Max Filippov
static void gen_waiti(DisasContext *dc, uint32_t imm4)
743 b994e91b Max Filippov
{
744 b994e91b Max Filippov
    TCGv_i32 pc = tcg_const_i32(dc->next_pc);
745 b994e91b Max Filippov
    TCGv_i32 intlevel = tcg_const_i32(imm4);
746 b994e91b Max Filippov
    gen_advance_ccount(dc);
747 f492b82d Max Filippov
    gen_helper_waiti(cpu_env, pc, intlevel);
748 b994e91b Max Filippov
    tcg_temp_free(pc);
749 b994e91b Max Filippov
    tcg_temp_free(intlevel);
750 b994e91b Max Filippov
}
751 b994e91b Max Filippov
752 772177c1 Max Filippov
static void gen_window_check1(DisasContext *dc, unsigned r1)
753 772177c1 Max Filippov
{
754 772177c1 Max Filippov
    if (dc->tb->flags & XTENSA_TBFLAG_EXCM) {
755 772177c1 Max Filippov
        return;
756 772177c1 Max Filippov
    }
757 772177c1 Max Filippov
    if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&
758 772177c1 Max Filippov
            r1 / 4 > dc->used_window) {
759 772177c1 Max Filippov
        TCGv_i32 pc = tcg_const_i32(dc->pc);
760 772177c1 Max Filippov
        TCGv_i32 w = tcg_const_i32(r1 / 4);
761 772177c1 Max Filippov
762 772177c1 Max Filippov
        dc->used_window = r1 / 4;
763 772177c1 Max Filippov
        gen_advance_ccount(dc);
764 f492b82d Max Filippov
        gen_helper_window_check(cpu_env, pc, w);
765 772177c1 Max Filippov
766 772177c1 Max Filippov
        tcg_temp_free(w);
767 772177c1 Max Filippov
        tcg_temp_free(pc);
768 772177c1 Max Filippov
    }
769 772177c1 Max Filippov
}
770 772177c1 Max Filippov
771 772177c1 Max Filippov
static void gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)
772 772177c1 Max Filippov
{
773 772177c1 Max Filippov
    gen_window_check1(dc, r1 > r2 ? r1 : r2);
774 772177c1 Max Filippov
}
775 772177c1 Max Filippov
776 772177c1 Max Filippov
static void gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2,
777 772177c1 Max Filippov
        unsigned r3)
778 772177c1 Max Filippov
{
779 772177c1 Max Filippov
    gen_window_check2(dc, r1, r2 > r3 ? r2 : r3);
780 772177c1 Max Filippov
}
781 772177c1 Max Filippov
782 6825b6c3 Max Filippov
static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
783 6825b6c3 Max Filippov
{
784 6825b6c3 Max Filippov
    TCGv_i32 m = tcg_temp_new_i32();
785 6825b6c3 Max Filippov
786 6825b6c3 Max Filippov
    if (hi) {
787 6825b6c3 Max Filippov
        (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
788 6825b6c3 Max Filippov
    } else {
789 6825b6c3 Max Filippov
        (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
790 6825b6c3 Max Filippov
    }
791 6825b6c3 Max Filippov
    return m;
792 6825b6c3 Max Filippov
}
793 6825b6c3 Max Filippov
794 dedc5eae Max Filippov
static void disas_xtensa_insn(DisasContext *dc)
795 dedc5eae Max Filippov
{
796 b67ea0cd Max Filippov
#define HAS_OPTION_BITS(opt) do { \
797 b67ea0cd Max Filippov
        if (!option_bits_enabled(dc, opt)) { \
798 b67ea0cd Max Filippov
            qemu_log("Option is not enabled %s:%d\n", \
799 b67ea0cd Max Filippov
                    __FILE__, __LINE__); \
800 dedc5eae Max Filippov
            goto invalid_opcode; \
801 dedc5eae Max Filippov
        } \
802 dedc5eae Max Filippov
    } while (0)
803 dedc5eae Max Filippov
804 b67ea0cd Max Filippov
#define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt))
805 b67ea0cd Max Filippov
806 91a5bb76 Max Filippov
#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
807 91a5bb76 Max Filippov
#define RESERVED() do { \
808 91a5bb76 Max Filippov
        qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
809 91a5bb76 Max Filippov
                dc->pc, b0, b1, b2, __FILE__, __LINE__); \
810 91a5bb76 Max Filippov
        goto invalid_opcode; \
811 91a5bb76 Max Filippov
    } while (0)
812 91a5bb76 Max Filippov
813 91a5bb76 Max Filippov
814 dedc5eae Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
815 dedc5eae Max Filippov
#define OP0 (((b0) & 0xf0) >> 4)
816 dedc5eae Max Filippov
#define OP1 (((b2) & 0xf0) >> 4)
817 dedc5eae Max Filippov
#define OP2 ((b2) & 0xf)
818 dedc5eae Max Filippov
#define RRR_R ((b1) & 0xf)
819 dedc5eae Max Filippov
#define RRR_S (((b1) & 0xf0) >> 4)
820 dedc5eae Max Filippov
#define RRR_T ((b0) & 0xf)
821 dedc5eae Max Filippov
#else
822 dedc5eae Max Filippov
#define OP0 (((b0) & 0xf))
823 dedc5eae Max Filippov
#define OP1 (((b2) & 0xf))
824 dedc5eae Max Filippov
#define OP2 (((b2) & 0xf0) >> 4)
825 dedc5eae Max Filippov
#define RRR_R (((b1) & 0xf0) >> 4)
826 dedc5eae Max Filippov
#define RRR_S (((b1) & 0xf))
827 dedc5eae Max Filippov
#define RRR_T (((b0) & 0xf0) >> 4)
828 dedc5eae Max Filippov
#endif
829 6825b6c3 Max Filippov
#define RRR_X ((RRR_R & 0x4) >> 2)
830 6825b6c3 Max Filippov
#define RRR_Y ((RRR_T & 0x4) >> 2)
831 6825b6c3 Max Filippov
#define RRR_W (RRR_R & 0x3)
832 dedc5eae Max Filippov
833 dedc5eae Max Filippov
#define RRRN_R RRR_R
834 dedc5eae Max Filippov
#define RRRN_S RRR_S
835 dedc5eae Max Filippov
#define RRRN_T RRR_T
836 dedc5eae Max Filippov
837 dedc5eae Max Filippov
#define RRI8_R RRR_R
838 dedc5eae Max Filippov
#define RRI8_S RRR_S
839 dedc5eae Max Filippov
#define RRI8_T RRR_T
840 dedc5eae Max Filippov
#define RRI8_IMM8 (b2)
841 dedc5eae Max Filippov
#define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)
842 dedc5eae Max Filippov
843 dedc5eae Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
844 dedc5eae Max Filippov
#define RI16_IMM16 (((b1) << 8) | (b2))
845 dedc5eae Max Filippov
#else
846 dedc5eae Max Filippov
#define RI16_IMM16 (((b2) << 8) | (b1))
847 dedc5eae Max Filippov
#endif
848 dedc5eae Max Filippov
849 dedc5eae Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
850 dedc5eae Max Filippov
#define CALL_N (((b0) & 0xc) >> 2)
851 dedc5eae Max Filippov
#define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))
852 dedc5eae Max Filippov
#else
853 dedc5eae Max Filippov
#define CALL_N (((b0) & 0x30) >> 4)
854 dedc5eae Max Filippov
#define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))
855 dedc5eae Max Filippov
#endif
856 dedc5eae Max Filippov
#define CALL_OFFSET_SE \
857 dedc5eae Max Filippov
    (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)
858 dedc5eae Max Filippov
859 dedc5eae Max Filippov
#define CALLX_N CALL_N
860 dedc5eae Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
861 dedc5eae Max Filippov
#define CALLX_M ((b0) & 0x3)
862 dedc5eae Max Filippov
#else
863 dedc5eae Max Filippov
#define CALLX_M (((b0) & 0xc0) >> 6)
864 dedc5eae Max Filippov
#endif
865 dedc5eae Max Filippov
#define CALLX_S RRR_S
866 dedc5eae Max Filippov
867 dedc5eae Max Filippov
#define BRI12_M CALLX_M
868 dedc5eae Max Filippov
#define BRI12_S RRR_S
869 dedc5eae Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
870 dedc5eae Max Filippov
#define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))
871 dedc5eae Max Filippov
#else
872 dedc5eae Max Filippov
#define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))
873 dedc5eae Max Filippov
#endif
874 dedc5eae Max Filippov
#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)
875 dedc5eae Max Filippov
876 dedc5eae Max Filippov
#define BRI8_M BRI12_M
877 dedc5eae Max Filippov
#define BRI8_R RRI8_R
878 dedc5eae Max Filippov
#define BRI8_S RRI8_S
879 dedc5eae Max Filippov
#define BRI8_IMM8 RRI8_IMM8
880 dedc5eae Max Filippov
#define BRI8_IMM8_SE RRI8_IMM8_SE
881 dedc5eae Max Filippov
882 dedc5eae Max Filippov
#define RSR_SR (b1)
883 dedc5eae Max Filippov
884 f492b82d Max Filippov
    uint8_t b0 = cpu_ldub_code(cpu_single_env, dc->pc);
885 f492b82d Max Filippov
    uint8_t b1 = cpu_ldub_code(cpu_single_env, dc->pc + 1);
886 a044ec2a Max Filippov
    uint8_t b2 = 0;
887 dedc5eae Max Filippov
888 bd57fb91 Max Filippov
    static const uint32_t B4CONST[] = {
889 bd57fb91 Max Filippov
        0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
890 bd57fb91 Max Filippov
    };
891 bd57fb91 Max Filippov
892 bd57fb91 Max Filippov
    static const uint32_t B4CONSTU[] = {
893 bd57fb91 Max Filippov
        32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
894 bd57fb91 Max Filippov
    };
895 bd57fb91 Max Filippov
896 dedc5eae Max Filippov
    if (OP0 >= 8) {
897 dedc5eae Max Filippov
        dc->next_pc = dc->pc + 2;
898 dedc5eae Max Filippov
        HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
899 dedc5eae Max Filippov
    } else {
900 dedc5eae Max Filippov
        dc->next_pc = dc->pc + 3;
901 f492b82d Max Filippov
        b2 = cpu_ldub_code(cpu_single_env, dc->pc + 2);
902 dedc5eae Max Filippov
    }
903 dedc5eae Max Filippov
904 dedc5eae Max Filippov
    switch (OP0) {
905 dedc5eae Max Filippov
    case 0: /*QRST*/
906 dedc5eae Max Filippov
        switch (OP1) {
907 dedc5eae Max Filippov
        case 0: /*RST0*/
908 dedc5eae Max Filippov
            switch (OP2) {
909 dedc5eae Max Filippov
            case 0: /*ST0*/
910 dedc5eae Max Filippov
                if ((RRR_R & 0xc) == 0x8) {
911 dedc5eae Max Filippov
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
912 dedc5eae Max Filippov
                }
913 dedc5eae Max Filippov
914 dedc5eae Max Filippov
                switch (RRR_R) {
915 dedc5eae Max Filippov
                case 0: /*SNM0*/
916 5da4a6a8 Max Filippov
                    switch (CALLX_M) {
917 5da4a6a8 Max Filippov
                    case 0: /*ILL*/
918 40643d7c Max Filippov
                        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
919 5da4a6a8 Max Filippov
                        break;
920 5da4a6a8 Max Filippov
921 5da4a6a8 Max Filippov
                    case 1: /*reserved*/
922 91a5bb76 Max Filippov
                        RESERVED();
923 5da4a6a8 Max Filippov
                        break;
924 5da4a6a8 Max Filippov
925 5da4a6a8 Max Filippov
                    case 2: /*JR*/
926 5da4a6a8 Max Filippov
                        switch (CALLX_N) {
927 5da4a6a8 Max Filippov
                        case 0: /*RET*/
928 5da4a6a8 Max Filippov
                        case 2: /*JX*/
929 772177c1 Max Filippov
                            gen_window_check1(dc, CALLX_S);
930 5da4a6a8 Max Filippov
                            gen_jump(dc, cpu_R[CALLX_S]);
931 5da4a6a8 Max Filippov
                            break;
932 5da4a6a8 Max Filippov
933 5da4a6a8 Max Filippov
                        case 1: /*RETWw*/
934 5da4a6a8 Max Filippov
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
935 553e44f9 Max Filippov
                            {
936 553e44f9 Max Filippov
                                TCGv_i32 tmp = tcg_const_i32(dc->pc);
937 b994e91b Max Filippov
                                gen_advance_ccount(dc);
938 f492b82d Max Filippov
                                gen_helper_retw(tmp, cpu_env, tmp);
939 553e44f9 Max Filippov
                                gen_jump(dc, tmp);
940 553e44f9 Max Filippov
                                tcg_temp_free(tmp);
941 553e44f9 Max Filippov
                            }
942 5da4a6a8 Max Filippov
                            break;
943 5da4a6a8 Max Filippov
944 5da4a6a8 Max Filippov
                        case 3: /*reserved*/
945 91a5bb76 Max Filippov
                            RESERVED();
946 5da4a6a8 Max Filippov
                            break;
947 5da4a6a8 Max Filippov
                        }
948 5da4a6a8 Max Filippov
                        break;
949 5da4a6a8 Max Filippov
950 5da4a6a8 Max Filippov
                    case 3: /*CALLX*/
951 772177c1 Max Filippov
                        gen_window_check2(dc, CALLX_S, CALLX_N << 2);
952 5da4a6a8 Max Filippov
                        switch (CALLX_N) {
953 5da4a6a8 Max Filippov
                        case 0: /*CALLX0*/
954 5da4a6a8 Max Filippov
                            {
955 5da4a6a8 Max Filippov
                                TCGv_i32 tmp = tcg_temp_new_i32();
956 5da4a6a8 Max Filippov
                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
957 5da4a6a8 Max Filippov
                                tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
958 5da4a6a8 Max Filippov
                                gen_jump(dc, tmp);
959 5da4a6a8 Max Filippov
                                tcg_temp_free(tmp);
960 5da4a6a8 Max Filippov
                            }
961 5da4a6a8 Max Filippov
                            break;
962 5da4a6a8 Max Filippov
963 5da4a6a8 Max Filippov
                        case 1: /*CALLX4w*/
964 5da4a6a8 Max Filippov
                        case 2: /*CALLX8w*/
965 5da4a6a8 Max Filippov
                        case 3: /*CALLX12w*/
966 5da4a6a8 Max Filippov
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
967 553e44f9 Max Filippov
                            {
968 553e44f9 Max Filippov
                                TCGv_i32 tmp = tcg_temp_new_i32();
969 553e44f9 Max Filippov
970 553e44f9 Max Filippov
                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
971 553e44f9 Max Filippov
                                gen_callw(dc, CALLX_N, tmp);
972 553e44f9 Max Filippov
                                tcg_temp_free(tmp);
973 553e44f9 Max Filippov
                            }
974 5da4a6a8 Max Filippov
                            break;
975 5da4a6a8 Max Filippov
                        }
976 5da4a6a8 Max Filippov
                        break;
977 5da4a6a8 Max Filippov
                    }
978 dedc5eae Max Filippov
                    break;
979 dedc5eae Max Filippov
980 dedc5eae Max Filippov
                case 1: /*MOVSPw*/
981 dedc5eae Max Filippov
                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
982 772177c1 Max Filippov
                    gen_window_check2(dc, RRR_T, RRR_S);
983 553e44f9 Max Filippov
                    {
984 553e44f9 Max Filippov
                        TCGv_i32 pc = tcg_const_i32(dc->pc);
985 b994e91b Max Filippov
                        gen_advance_ccount(dc);
986 f492b82d Max Filippov
                        gen_helper_movsp(cpu_env, pc);
987 553e44f9 Max Filippov
                        tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]);
988 553e44f9 Max Filippov
                        tcg_temp_free(pc);
989 553e44f9 Max Filippov
                    }
990 dedc5eae Max Filippov
                    break;
991 dedc5eae Max Filippov
992 dedc5eae Max Filippov
                case 2: /*SYNC*/
993 28067b22 Max Filippov
                    switch (RRR_T) {
994 28067b22 Max Filippov
                    case 0: /*ISYNC*/
995 28067b22 Max Filippov
                        break;
996 28067b22 Max Filippov
997 28067b22 Max Filippov
                    case 1: /*RSYNC*/
998 28067b22 Max Filippov
                        break;
999 28067b22 Max Filippov
1000 28067b22 Max Filippov
                    case 2: /*ESYNC*/
1001 28067b22 Max Filippov
                        break;
1002 28067b22 Max Filippov
1003 28067b22 Max Filippov
                    case 3: /*DSYNC*/
1004 28067b22 Max Filippov
                        break;
1005 28067b22 Max Filippov
1006 28067b22 Max Filippov
                    case 8: /*EXCW*/
1007 28067b22 Max Filippov
                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);
1008 28067b22 Max Filippov
                        break;
1009 28067b22 Max Filippov
1010 28067b22 Max Filippov
                    case 12: /*MEMW*/
1011 28067b22 Max Filippov
                        break;
1012 28067b22 Max Filippov
1013 28067b22 Max Filippov
                    case 13: /*EXTW*/
1014 28067b22 Max Filippov
                        break;
1015 28067b22 Max Filippov
1016 28067b22 Max Filippov
                    case 15: /*NOP*/
1017 28067b22 Max Filippov
                        break;
1018 28067b22 Max Filippov
1019 28067b22 Max Filippov
                    default: /*reserved*/
1020 28067b22 Max Filippov
                        RESERVED();
1021 28067b22 Max Filippov
                        break;
1022 28067b22 Max Filippov
                    }
1023 91a5bb76 Max Filippov
                    break;
1024 91a5bb76 Max Filippov
1025 91a5bb76 Max Filippov
                case 3: /*RFEIx*/
1026 40643d7c Max Filippov
                    switch (RRR_T) {
1027 40643d7c Max Filippov
                    case 0: /*RFETx*/
1028 40643d7c Max Filippov
                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);
1029 40643d7c Max Filippov
                        switch (RRR_S) {
1030 40643d7c Max Filippov
                        case 0: /*RFEx*/
1031 40643d7c Max Filippov
                            gen_check_privilege(dc);
1032 40643d7c Max Filippov
                            tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
1033 b994e91b Max Filippov
                            gen_helper_check_interrupts(cpu_env);
1034 40643d7c Max Filippov
                            gen_jump(dc, cpu_SR[EPC1]);
1035 40643d7c Max Filippov
                            break;
1036 40643d7c Max Filippov
1037 40643d7c Max Filippov
                        case 1: /*RFUEx*/
1038 40643d7c Max Filippov
                            RESERVED();
1039 40643d7c Max Filippov
                            break;
1040 40643d7c Max Filippov
1041 40643d7c Max Filippov
                        case 2: /*RFDEx*/
1042 40643d7c Max Filippov
                            gen_check_privilege(dc);
1043 40643d7c Max Filippov
                            gen_jump(dc, cpu_SR[
1044 40643d7c Max Filippov
                                    dc->config->ndepc ? DEPC : EPC1]);
1045 40643d7c Max Filippov
                            break;
1046 40643d7c Max Filippov
1047 40643d7c Max Filippov
                        case 4: /*RFWOw*/
1048 40643d7c Max Filippov
                        case 5: /*RFWUw*/
1049 40643d7c Max Filippov
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1050 553e44f9 Max Filippov
                            gen_check_privilege(dc);
1051 553e44f9 Max Filippov
                            {
1052 553e44f9 Max Filippov
                                TCGv_i32 tmp = tcg_const_i32(1);
1053 553e44f9 Max Filippov
1054 553e44f9 Max Filippov
                                tcg_gen_andi_i32(
1055 553e44f9 Max Filippov
                                        cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
1056 553e44f9 Max Filippov
                                tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
1057 553e44f9 Max Filippov
1058 553e44f9 Max Filippov
                                if (RRR_S == 4) {
1059 553e44f9 Max Filippov
                                    tcg_gen_andc_i32(cpu_SR[WINDOW_START],
1060 553e44f9 Max Filippov
                                            cpu_SR[WINDOW_START], tmp);
1061 553e44f9 Max Filippov
                                } else {
1062 553e44f9 Max Filippov
                                    tcg_gen_or_i32(cpu_SR[WINDOW_START],
1063 553e44f9 Max Filippov
                                            cpu_SR[WINDOW_START], tmp);
1064 553e44f9 Max Filippov
                                }
1065 553e44f9 Max Filippov
1066 f492b82d Max Filippov
                                gen_helper_restore_owb(cpu_env);
1067 b994e91b Max Filippov
                                gen_helper_check_interrupts(cpu_env);
1068 553e44f9 Max Filippov
                                gen_jump(dc, cpu_SR[EPC1]);
1069 553e44f9 Max Filippov
1070 553e44f9 Max Filippov
                                tcg_temp_free(tmp);
1071 553e44f9 Max Filippov
                            }
1072 40643d7c Max Filippov
                            break;
1073 40643d7c Max Filippov
1074 40643d7c Max Filippov
                        default: /*reserved*/
1075 40643d7c Max Filippov
                            RESERVED();
1076 40643d7c Max Filippov
                            break;
1077 40643d7c Max Filippov
                        }
1078 40643d7c Max Filippov
                        break;
1079 40643d7c Max Filippov
1080 40643d7c Max Filippov
                    case 1: /*RFIx*/
1081 40643d7c Max Filippov
                        HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT);
1082 b994e91b Max Filippov
                        if (RRR_S >= 2 && RRR_S <= dc->config->nlevel) {
1083 b994e91b Max Filippov
                            gen_check_privilege(dc);
1084 b994e91b Max Filippov
                            tcg_gen_mov_i32(cpu_SR[PS],
1085 b994e91b Max Filippov
                                    cpu_SR[EPS2 + RRR_S - 2]);
1086 b994e91b Max Filippov
                            gen_helper_check_interrupts(cpu_env);
1087 b994e91b Max Filippov
                            gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]);
1088 b994e91b Max Filippov
                        } else {
1089 b994e91b Max Filippov
                            qemu_log("RFI %d is illegal\n", RRR_S);
1090 b994e91b Max Filippov
                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1091 b994e91b Max Filippov
                        }
1092 40643d7c Max Filippov
                        break;
1093 40643d7c Max Filippov
1094 40643d7c Max Filippov
                    case 2: /*RFME*/
1095 40643d7c Max Filippov
                        TBD();
1096 40643d7c Max Filippov
                        break;
1097 40643d7c Max Filippov
1098 40643d7c Max Filippov
                    default: /*reserved*/
1099 40643d7c Max Filippov
                        RESERVED();
1100 40643d7c Max Filippov
                        break;
1101 40643d7c Max Filippov
1102 40643d7c Max Filippov
                    }
1103 91a5bb76 Max Filippov
                    break;
1104 91a5bb76 Max Filippov
1105 91a5bb76 Max Filippov
                case 4: /*BREAKx*/
1106 e61dc8f7 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_DEBUG);
1107 e61dc8f7 Max Filippov
                    if (dc->debug) {
1108 e61dc8f7 Max Filippov
                        gen_debug_exception(dc, DEBUGCAUSE_BI);
1109 e61dc8f7 Max Filippov
                    }
1110 91a5bb76 Max Filippov
                    break;
1111 91a5bb76 Max Filippov
1112 91a5bb76 Max Filippov
                case 5: /*SYSCALLx*/
1113 91a5bb76 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_EXCEPTION);
1114 40643d7c Max Filippov
                    switch (RRR_S) {
1115 40643d7c Max Filippov
                    case 0: /*SYSCALLx*/
1116 40643d7c Max Filippov
                        gen_exception_cause(dc, SYSCALL_CAUSE);
1117 40643d7c Max Filippov
                        break;
1118 40643d7c Max Filippov
1119 40643d7c Max Filippov
                    case 1: /*SIMCALL*/
1120 1ddeaa5d Max Filippov
                        if (semihosting_enabled) {
1121 1ddeaa5d Max Filippov
                            gen_check_privilege(dc);
1122 1ddeaa5d Max Filippov
                            gen_helper_simcall(cpu_env);
1123 1ddeaa5d Max Filippov
                        } else {
1124 1ddeaa5d Max Filippov
                            qemu_log("SIMCALL but semihosting is disabled\n");
1125 1ddeaa5d Max Filippov
                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1126 1ddeaa5d Max Filippov
                        }
1127 40643d7c Max Filippov
                        break;
1128 40643d7c Max Filippov
1129 40643d7c Max Filippov
                    default:
1130 40643d7c Max Filippov
                        RESERVED();
1131 40643d7c Max Filippov
                        break;
1132 40643d7c Max Filippov
                    }
1133 91a5bb76 Max Filippov
                    break;
1134 91a5bb76 Max Filippov
1135 91a5bb76 Max Filippov
                case 6: /*RSILx*/
1136 91a5bb76 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);
1137 40643d7c Max Filippov
                    gen_check_privilege(dc);
1138 772177c1 Max Filippov
                    gen_window_check1(dc, RRR_T);
1139 40643d7c Max Filippov
                    tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]);
1140 b994e91b Max Filippov
                    tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
1141 40643d7c Max Filippov
                    tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S);
1142 b994e91b Max Filippov
                    gen_helper_check_interrupts(cpu_env);
1143 b994e91b Max Filippov
                    gen_jumpi_check_loop_end(dc, 0);
1144 91a5bb76 Max Filippov
                    break;
1145 91a5bb76 Max Filippov
1146 91a5bb76 Max Filippov
                case 7: /*WAITIx*/
1147 91a5bb76 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);
1148 b994e91b Max Filippov
                    gen_check_privilege(dc);
1149 b994e91b Max Filippov
                    gen_waiti(dc, RRR_S);
1150 91a5bb76 Max Filippov
                    break;
1151 91a5bb76 Max Filippov
1152 91a5bb76 Max Filippov
                case 8: /*ANY4p*/
1153 91a5bb76 Max Filippov
                case 9: /*ALL4p*/
1154 91a5bb76 Max Filippov
                case 10: /*ANY8p*/
1155 91a5bb76 Max Filippov
                case 11: /*ALL8p*/
1156 91a5bb76 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1157 4dd85b6b Max Filippov
                    {
1158 4dd85b6b Max Filippov
                        const unsigned shift = (RRR_R & 2) ? 8 : 4;
1159 4dd85b6b Max Filippov
                        TCGv_i32 mask = tcg_const_i32(
1160 4dd85b6b Max Filippov
                                ((1 << shift) - 1) << RRR_S);
1161 4dd85b6b Max Filippov
                        TCGv_i32 tmp = tcg_temp_new_i32();
1162 4dd85b6b Max Filippov
1163 4dd85b6b Max Filippov
                        tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
1164 4dd85b6b Max Filippov
                        if (RRR_R & 1) { /*ALL*/
1165 4dd85b6b Max Filippov
                            tcg_gen_addi_i32(tmp, tmp, 1 << RRR_S);
1166 4dd85b6b Max Filippov
                        } else { /*ANY*/
1167 4dd85b6b Max Filippov
                            tcg_gen_add_i32(tmp, tmp, mask);
1168 4dd85b6b Max Filippov
                        }
1169 4dd85b6b Max Filippov
                        tcg_gen_shri_i32(tmp, tmp, RRR_S + shift);
1170 4dd85b6b Max Filippov
                        tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
1171 4dd85b6b Max Filippov
                                tmp, RRR_T, 1);
1172 4dd85b6b Max Filippov
                        tcg_temp_free(mask);
1173 4dd85b6b Max Filippov
                        tcg_temp_free(tmp);
1174 4dd85b6b Max Filippov
                    }
1175 91a5bb76 Max Filippov
                    break;
1176 91a5bb76 Max Filippov
1177 91a5bb76 Max Filippov
                default: /*reserved*/
1178 91a5bb76 Max Filippov
                    RESERVED();
1179 dedc5eae Max Filippov
                    break;
1180 dedc5eae Max Filippov
1181 dedc5eae Max Filippov
                }
1182 dedc5eae Max Filippov
                break;
1183 dedc5eae Max Filippov
1184 dedc5eae Max Filippov
            case 1: /*AND*/
1185 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1186 dedc5eae Max Filippov
                tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1187 dedc5eae Max Filippov
                break;
1188 dedc5eae Max Filippov
1189 dedc5eae Max Filippov
            case 2: /*OR*/
1190 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1191 dedc5eae Max Filippov
                tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1192 dedc5eae Max Filippov
                break;
1193 dedc5eae Max Filippov
1194 dedc5eae Max Filippov
            case 3: /*XOR*/
1195 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1196 dedc5eae Max Filippov
                tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1197 dedc5eae Max Filippov
                break;
1198 dedc5eae Max Filippov
1199 dedc5eae Max Filippov
            case 4: /*ST1*/
1200 3580ecad Max Filippov
                switch (RRR_R) {
1201 3580ecad Max Filippov
                case 0: /*SSR*/
1202 772177c1 Max Filippov
                    gen_window_check1(dc, RRR_S);
1203 3580ecad Max Filippov
                    gen_right_shift_sar(dc, cpu_R[RRR_S]);
1204 3580ecad Max Filippov
                    break;
1205 3580ecad Max Filippov
1206 3580ecad Max Filippov
                case 1: /*SSL*/
1207 772177c1 Max Filippov
                    gen_window_check1(dc, RRR_S);
1208 3580ecad Max Filippov
                    gen_left_shift_sar(dc, cpu_R[RRR_S]);
1209 3580ecad Max Filippov
                    break;
1210 3580ecad Max Filippov
1211 3580ecad Max Filippov
                case 2: /*SSA8L*/
1212 772177c1 Max Filippov
                    gen_window_check1(dc, RRR_S);
1213 3580ecad Max Filippov
                    {
1214 3580ecad Max Filippov
                        TCGv_i32 tmp = tcg_temp_new_i32();
1215 3580ecad Max Filippov
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1216 3580ecad Max Filippov
                        gen_right_shift_sar(dc, tmp);
1217 3580ecad Max Filippov
                        tcg_temp_free(tmp);
1218 3580ecad Max Filippov
                    }
1219 3580ecad Max Filippov
                    break;
1220 3580ecad Max Filippov
1221 3580ecad Max Filippov
                case 3: /*SSA8B*/
1222 772177c1 Max Filippov
                    gen_window_check1(dc, RRR_S);
1223 3580ecad Max Filippov
                    {
1224 3580ecad Max Filippov
                        TCGv_i32 tmp = tcg_temp_new_i32();
1225 3580ecad Max Filippov
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1226 3580ecad Max Filippov
                        gen_left_shift_sar(dc, tmp);
1227 3580ecad Max Filippov
                        tcg_temp_free(tmp);
1228 3580ecad Max Filippov
                    }
1229 3580ecad Max Filippov
                    break;
1230 3580ecad Max Filippov
1231 3580ecad Max Filippov
                case 4: /*SSAI*/
1232 3580ecad Max Filippov
                    {
1233 3580ecad Max Filippov
                        TCGv_i32 tmp = tcg_const_i32(
1234 3580ecad Max Filippov
                                RRR_S | ((RRR_T & 1) << 4));
1235 3580ecad Max Filippov
                        gen_right_shift_sar(dc, tmp);
1236 3580ecad Max Filippov
                        tcg_temp_free(tmp);
1237 3580ecad Max Filippov
                    }
1238 3580ecad Max Filippov
                    break;
1239 3580ecad Max Filippov
1240 3580ecad Max Filippov
                case 6: /*RER*/
1241 91a5bb76 Max Filippov
                    TBD();
1242 3580ecad Max Filippov
                    break;
1243 3580ecad Max Filippov
1244 3580ecad Max Filippov
                case 7: /*WER*/
1245 91a5bb76 Max Filippov
                    TBD();
1246 3580ecad Max Filippov
                    break;
1247 3580ecad Max Filippov
1248 3580ecad Max Filippov
                case 8: /*ROTWw*/
1249 3580ecad Max Filippov
                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1250 553e44f9 Max Filippov
                    gen_check_privilege(dc);
1251 553e44f9 Max Filippov
                    {
1252 553e44f9 Max Filippov
                        TCGv_i32 tmp = tcg_const_i32(
1253 553e44f9 Max Filippov
                                RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0));
1254 f492b82d Max Filippov
                        gen_helper_rotw(cpu_env, tmp);
1255 553e44f9 Max Filippov
                        tcg_temp_free(tmp);
1256 772177c1 Max Filippov
                        reset_used_window(dc);
1257 553e44f9 Max Filippov
                    }
1258 3580ecad Max Filippov
                    break;
1259 3580ecad Max Filippov
1260 3580ecad Max Filippov
                case 14: /*NSAu*/
1261 7f65f4b0 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);
1262 772177c1 Max Filippov
                    gen_window_check2(dc, RRR_S, RRR_T);
1263 3580ecad Max Filippov
                    gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);
1264 3580ecad Max Filippov
                    break;
1265 3580ecad Max Filippov
1266 3580ecad Max Filippov
                case 15: /*NSAUu*/
1267 7f65f4b0 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);
1268 772177c1 Max Filippov
                    gen_window_check2(dc, RRR_S, RRR_T);
1269 3580ecad Max Filippov
                    gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);
1270 3580ecad Max Filippov
                    break;
1271 3580ecad Max Filippov
1272 3580ecad Max Filippov
                default: /*reserved*/
1273 91a5bb76 Max Filippov
                    RESERVED();
1274 3580ecad Max Filippov
                    break;
1275 3580ecad Max Filippov
                }
1276 dedc5eae Max Filippov
                break;
1277 dedc5eae Max Filippov
1278 dedc5eae Max Filippov
            case 5: /*TLB*/
1279 b67ea0cd Max Filippov
                HAS_OPTION_BITS(
1280 b67ea0cd Max Filippov
                        XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
1281 b67ea0cd Max Filippov
                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
1282 b67ea0cd Max Filippov
                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION));
1283 b67ea0cd Max Filippov
                gen_check_privilege(dc);
1284 b67ea0cd Max Filippov
                gen_window_check2(dc, RRR_S, RRR_T);
1285 b67ea0cd Max Filippov
                {
1286 b67ea0cd Max Filippov
                    TCGv_i32 dtlb = tcg_const_i32((RRR_R & 8) != 0);
1287 b67ea0cd Max Filippov
1288 b67ea0cd Max Filippov
                    switch (RRR_R & 7) {
1289 b67ea0cd Max Filippov
                    case 3: /*RITLB0*/ /*RDTLB0*/
1290 f492b82d Max Filippov
                        gen_helper_rtlb0(cpu_R[RRR_T],
1291 f492b82d Max Filippov
                                cpu_env, cpu_R[RRR_S], dtlb);
1292 b67ea0cd Max Filippov
                        break;
1293 b67ea0cd Max Filippov
1294 b67ea0cd Max Filippov
                    case 4: /*IITLB*/ /*IDTLB*/
1295 f492b82d Max Filippov
                        gen_helper_itlb(cpu_env, cpu_R[RRR_S], dtlb);
1296 b67ea0cd Max Filippov
                        /* This could change memory mapping, so exit tb */
1297 b67ea0cd Max Filippov
                        gen_jumpi_check_loop_end(dc, -1);
1298 b67ea0cd Max Filippov
                        break;
1299 b67ea0cd Max Filippov
1300 b67ea0cd Max Filippov
                    case 5: /*PITLB*/ /*PDTLB*/
1301 b67ea0cd Max Filippov
                        tcg_gen_movi_i32(cpu_pc, dc->pc);
1302 f492b82d Max Filippov
                        gen_helper_ptlb(cpu_R[RRR_T],
1303 f492b82d Max Filippov
                                cpu_env, cpu_R[RRR_S], dtlb);
1304 b67ea0cd Max Filippov
                        break;
1305 b67ea0cd Max Filippov
1306 b67ea0cd Max Filippov
                    case 6: /*WITLB*/ /*WDTLB*/
1307 f492b82d Max Filippov
                        gen_helper_wtlb(
1308 f492b82d Max Filippov
                                cpu_env, cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1309 b67ea0cd Max Filippov
                        /* This could change memory mapping, so exit tb */
1310 b67ea0cd Max Filippov
                        gen_jumpi_check_loop_end(dc, -1);
1311 b67ea0cd Max Filippov
                        break;
1312 b67ea0cd Max Filippov
1313 b67ea0cd Max Filippov
                    case 7: /*RITLB1*/ /*RDTLB1*/
1314 f492b82d Max Filippov
                        gen_helper_rtlb1(cpu_R[RRR_T],
1315 f492b82d Max Filippov
                                cpu_env, cpu_R[RRR_S], dtlb);
1316 b67ea0cd Max Filippov
                        break;
1317 b67ea0cd Max Filippov
1318 b67ea0cd Max Filippov
                    default:
1319 b67ea0cd Max Filippov
                        tcg_temp_free(dtlb);
1320 b67ea0cd Max Filippov
                        RESERVED();
1321 b67ea0cd Max Filippov
                        break;
1322 b67ea0cd Max Filippov
                    }
1323 b67ea0cd Max Filippov
                    tcg_temp_free(dtlb);
1324 b67ea0cd Max Filippov
                }
1325 dedc5eae Max Filippov
                break;
1326 dedc5eae Max Filippov
1327 dedc5eae Max Filippov
            case 6: /*RT0*/
1328 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_T);
1329 f331fe5e Max Filippov
                switch (RRR_S) {
1330 f331fe5e Max Filippov
                case 0: /*NEG*/
1331 f331fe5e Max Filippov
                    tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1332 f331fe5e Max Filippov
                    break;
1333 f331fe5e Max Filippov
1334 f331fe5e Max Filippov
                case 1: /*ABS*/
1335 f331fe5e Max Filippov
                    {
1336 f331fe5e Max Filippov
                        int label = gen_new_label();
1337 f331fe5e Max Filippov
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1338 f331fe5e Max Filippov
                        tcg_gen_brcondi_i32(
1339 f331fe5e Max Filippov
                                TCG_COND_GE, cpu_R[RRR_R], 0, label);
1340 f331fe5e Max Filippov
                        tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1341 f331fe5e Max Filippov
                        gen_set_label(label);
1342 f331fe5e Max Filippov
                    }
1343 f331fe5e Max Filippov
                    break;
1344 f331fe5e Max Filippov
1345 f331fe5e Max Filippov
                default: /*reserved*/
1346 91a5bb76 Max Filippov
                    RESERVED();
1347 f331fe5e Max Filippov
                    break;
1348 f331fe5e Max Filippov
                }
1349 dedc5eae Max Filippov
                break;
1350 dedc5eae Max Filippov
1351 dedc5eae Max Filippov
            case 7: /*reserved*/
1352 91a5bb76 Max Filippov
                RESERVED();
1353 dedc5eae Max Filippov
                break;
1354 dedc5eae Max Filippov
1355 dedc5eae Max Filippov
            case 8: /*ADD*/
1356 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1357 dedc5eae Max Filippov
                tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1358 dedc5eae Max Filippov
                break;
1359 dedc5eae Max Filippov
1360 dedc5eae Max Filippov
            case 9: /*ADD**/
1361 dedc5eae Max Filippov
            case 10:
1362 dedc5eae Max Filippov
            case 11:
1363 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1364 dedc5eae Max Filippov
                {
1365 dedc5eae Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
1366 dedc5eae Max Filippov
                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);
1367 dedc5eae Max Filippov
                    tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1368 dedc5eae Max Filippov
                    tcg_temp_free(tmp);
1369 dedc5eae Max Filippov
                }
1370 dedc5eae Max Filippov
                break;
1371 dedc5eae Max Filippov
1372 dedc5eae Max Filippov
            case 12: /*SUB*/
1373 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1374 dedc5eae Max Filippov
                tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1375 dedc5eae Max Filippov
                break;
1376 dedc5eae Max Filippov
1377 dedc5eae Max Filippov
            case 13: /*SUB**/
1378 dedc5eae Max Filippov
            case 14:
1379 dedc5eae Max Filippov
            case 15:
1380 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1381 dedc5eae Max Filippov
                {
1382 dedc5eae Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
1383 dedc5eae Max Filippov
                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);
1384 dedc5eae Max Filippov
                    tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1385 dedc5eae Max Filippov
                    tcg_temp_free(tmp);
1386 dedc5eae Max Filippov
                }
1387 dedc5eae Max Filippov
                break;
1388 dedc5eae Max Filippov
            }
1389 dedc5eae Max Filippov
            break;
1390 dedc5eae Max Filippov
1391 dedc5eae Max Filippov
        case 1: /*RST1*/
1392 3580ecad Max Filippov
            switch (OP2) {
1393 3580ecad Max Filippov
            case 0: /*SLLI*/
1394 3580ecad Max Filippov
            case 1:
1395 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_S);
1396 3580ecad Max Filippov
                tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],
1397 3580ecad Max Filippov
                        32 - (RRR_T | ((OP2 & 1) << 4)));
1398 3580ecad Max Filippov
                break;
1399 3580ecad Max Filippov
1400 3580ecad Max Filippov
            case 2: /*SRAI*/
1401 3580ecad Max Filippov
            case 3:
1402 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_T);
1403 3580ecad Max Filippov
                tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],
1404 3580ecad Max Filippov
                        RRR_S | ((OP2 & 1) << 4));
1405 3580ecad Max Filippov
                break;
1406 3580ecad Max Filippov
1407 3580ecad Max Filippov
            case 4: /*SRLI*/
1408 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_T);
1409 3580ecad Max Filippov
                tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);
1410 3580ecad Max Filippov
                break;
1411 3580ecad Max Filippov
1412 3580ecad Max Filippov
            case 6: /*XSR*/
1413 3580ecad Max Filippov
                {
1414 3580ecad Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
1415 40643d7c Max Filippov
                    if (RSR_SR >= 64) {
1416 40643d7c Max Filippov
                        gen_check_privilege(dc);
1417 40643d7c Max Filippov
                    }
1418 772177c1 Max Filippov
                    gen_window_check1(dc, RRR_T);
1419 3580ecad Max Filippov
                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
1420 3580ecad Max Filippov
                    gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1421 3580ecad Max Filippov
                    gen_wsr(dc, RSR_SR, tmp);
1422 3580ecad Max Filippov
                    tcg_temp_free(tmp);
1423 91a5bb76 Max Filippov
                    if (!sregnames[RSR_SR]) {
1424 91a5bb76 Max Filippov
                        TBD();
1425 91a5bb76 Max Filippov
                    }
1426 3580ecad Max Filippov
                }
1427 3580ecad Max Filippov
                break;
1428 3580ecad Max Filippov
1429 3580ecad Max Filippov
                /*
1430 3580ecad Max Filippov
                 * Note: 64 bit ops are used here solely because SAR values
1431 3580ecad Max Filippov
                 * have range 0..63
1432 3580ecad Max Filippov
                 */
1433 3580ecad Max Filippov
#define gen_shift_reg(cmd, reg) do { \
1434 3580ecad Max Filippov
                    TCGv_i64 tmp = tcg_temp_new_i64(); \
1435 3580ecad Max Filippov
                    tcg_gen_extu_i32_i64(tmp, reg); \
1436 3580ecad Max Filippov
                    tcg_gen_##cmd##_i64(v, v, tmp); \
1437 3580ecad Max Filippov
                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
1438 3580ecad Max Filippov
                    tcg_temp_free_i64(v); \
1439 3580ecad Max Filippov
                    tcg_temp_free_i64(tmp); \
1440 3580ecad Max Filippov
                } while (0)
1441 3580ecad Max Filippov
1442 3580ecad Max Filippov
#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
1443 3580ecad Max Filippov
1444 3580ecad Max Filippov
            case 8: /*SRC*/
1445 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1446 3580ecad Max Filippov
                {
1447 3580ecad Max Filippov
                    TCGv_i64 v = tcg_temp_new_i64();
1448 3580ecad Max Filippov
                    tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);
1449 3580ecad Max Filippov
                    gen_shift(shr);
1450 3580ecad Max Filippov
                }
1451 3580ecad Max Filippov
                break;
1452 3580ecad Max Filippov
1453 3580ecad Max Filippov
            case 9: /*SRL*/
1454 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_T);
1455 3580ecad Max Filippov
                if (dc->sar_5bit) {
1456 3580ecad Max Filippov
                    tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1457 3580ecad Max Filippov
                } else {
1458 3580ecad Max Filippov
                    TCGv_i64 v = tcg_temp_new_i64();
1459 3580ecad Max Filippov
                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);
1460 3580ecad Max Filippov
                    gen_shift(shr);
1461 3580ecad Max Filippov
                }
1462 3580ecad Max Filippov
                break;
1463 3580ecad Max Filippov
1464 3580ecad Max Filippov
            case 10: /*SLL*/
1465 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_S);
1466 3580ecad Max Filippov
                if (dc->sar_m32_5bit) {
1467 3580ecad Max Filippov
                    tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);
1468 3580ecad Max Filippov
                } else {
1469 3580ecad Max Filippov
                    TCGv_i64 v = tcg_temp_new_i64();
1470 3580ecad Max Filippov
                    TCGv_i32 s = tcg_const_i32(32);
1471 3580ecad Max Filippov
                    tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
1472 3580ecad Max Filippov
                    tcg_gen_andi_i32(s, s, 0x3f);
1473 3580ecad Max Filippov
                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);
1474 3580ecad Max Filippov
                    gen_shift_reg(shl, s);
1475 3580ecad Max Filippov
                    tcg_temp_free(s);
1476 3580ecad Max Filippov
                }
1477 3580ecad Max Filippov
                break;
1478 3580ecad Max Filippov
1479 3580ecad Max Filippov
            case 11: /*SRA*/
1480 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_T);
1481 3580ecad Max Filippov
                if (dc->sar_5bit) {
1482 3580ecad Max Filippov
                    tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1483 3580ecad Max Filippov
                } else {
1484 3580ecad Max Filippov
                    TCGv_i64 v = tcg_temp_new_i64();
1485 3580ecad Max Filippov
                    tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);
1486 3580ecad Max Filippov
                    gen_shift(sar);
1487 3580ecad Max Filippov
                }
1488 3580ecad Max Filippov
                break;
1489 3580ecad Max Filippov
#undef gen_shift
1490 3580ecad Max Filippov
#undef gen_shift_reg
1491 3580ecad Max Filippov
1492 3580ecad Max Filippov
            case 12: /*MUL16U*/
1493 3580ecad Max Filippov
                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1494 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1495 3580ecad Max Filippov
                {
1496 3580ecad Max Filippov
                    TCGv_i32 v1 = tcg_temp_new_i32();
1497 3580ecad Max Filippov
                    TCGv_i32 v2 = tcg_temp_new_i32();
1498 3580ecad Max Filippov
                    tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);
1499 3580ecad Max Filippov
                    tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);
1500 3580ecad Max Filippov
                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1501 3580ecad Max Filippov
                    tcg_temp_free(v2);
1502 3580ecad Max Filippov
                    tcg_temp_free(v1);
1503 3580ecad Max Filippov
                }
1504 3580ecad Max Filippov
                break;
1505 3580ecad Max Filippov
1506 3580ecad Max Filippov
            case 13: /*MUL16S*/
1507 3580ecad Max Filippov
                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1508 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1509 3580ecad Max Filippov
                {
1510 3580ecad Max Filippov
                    TCGv_i32 v1 = tcg_temp_new_i32();
1511 3580ecad Max Filippov
                    TCGv_i32 v2 = tcg_temp_new_i32();
1512 3580ecad Max Filippov
                    tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);
1513 3580ecad Max Filippov
                    tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);
1514 3580ecad Max Filippov
                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1515 3580ecad Max Filippov
                    tcg_temp_free(v2);
1516 3580ecad Max Filippov
                    tcg_temp_free(v1);
1517 3580ecad Max Filippov
                }
1518 3580ecad Max Filippov
                break;
1519 3580ecad Max Filippov
1520 3580ecad Max Filippov
            default: /*reserved*/
1521 91a5bb76 Max Filippov
                RESERVED();
1522 3580ecad Max Filippov
                break;
1523 3580ecad Max Filippov
            }
1524 dedc5eae Max Filippov
            break;
1525 dedc5eae Max Filippov
1526 dedc5eae Max Filippov
        case 2: /*RST2*/
1527 4dd85b6b Max Filippov
            if (OP2 >= 8) {
1528 4dd85b6b Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1529 4dd85b6b Max Filippov
            }
1530 772177c1 Max Filippov
1531 f76ebf55 Max Filippov
            if (OP2 >= 12) {
1532 f76ebf55 Max Filippov
                HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV);
1533 f76ebf55 Max Filippov
                int label = gen_new_label();
1534 f76ebf55 Max Filippov
                tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label);
1535 f76ebf55 Max Filippov
                gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
1536 f76ebf55 Max Filippov
                gen_set_label(label);
1537 f76ebf55 Max Filippov
            }
1538 f76ebf55 Max Filippov
1539 f76ebf55 Max Filippov
            switch (OP2) {
1540 4dd85b6b Max Filippov
#define BOOLEAN_LOGIC(fn, r, s, t) \
1541 4dd85b6b Max Filippov
                do { \
1542 4dd85b6b Max Filippov
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN); \
1543 4dd85b6b Max Filippov
                    TCGv_i32 tmp1 = tcg_temp_new_i32(); \
1544 4dd85b6b Max Filippov
                    TCGv_i32 tmp2 = tcg_temp_new_i32(); \
1545 4dd85b6b Max Filippov
                    \
1546 4dd85b6b Max Filippov
                    tcg_gen_shri_i32(tmp1, cpu_SR[BR], s); \
1547 4dd85b6b Max Filippov
                    tcg_gen_shri_i32(tmp2, cpu_SR[BR], t); \
1548 4dd85b6b Max Filippov
                    tcg_gen_##fn##_i32(tmp1, tmp1, tmp2); \
1549 4dd85b6b Max Filippov
                    tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, r, 1); \
1550 4dd85b6b Max Filippov
                    tcg_temp_free(tmp1); \
1551 4dd85b6b Max Filippov
                    tcg_temp_free(tmp2); \
1552 4dd85b6b Max Filippov
                } while (0)
1553 4dd85b6b Max Filippov
1554 4dd85b6b Max Filippov
            case 0: /*ANDBp*/
1555 4dd85b6b Max Filippov
                BOOLEAN_LOGIC(and, RRR_R, RRR_S, RRR_T);
1556 4dd85b6b Max Filippov
                break;
1557 4dd85b6b Max Filippov
1558 4dd85b6b Max Filippov
            case 1: /*ANDBCp*/
1559 4dd85b6b Max Filippov
                BOOLEAN_LOGIC(andc, RRR_R, RRR_S, RRR_T);
1560 4dd85b6b Max Filippov
                break;
1561 4dd85b6b Max Filippov
1562 4dd85b6b Max Filippov
            case 2: /*ORBp*/
1563 4dd85b6b Max Filippov
                BOOLEAN_LOGIC(or, RRR_R, RRR_S, RRR_T);
1564 4dd85b6b Max Filippov
                break;
1565 4dd85b6b Max Filippov
1566 4dd85b6b Max Filippov
            case 3: /*ORBCp*/
1567 4dd85b6b Max Filippov
                BOOLEAN_LOGIC(orc, RRR_R, RRR_S, RRR_T);
1568 4dd85b6b Max Filippov
                break;
1569 4dd85b6b Max Filippov
1570 4dd85b6b Max Filippov
            case 4: /*XORBp*/
1571 4dd85b6b Max Filippov
                BOOLEAN_LOGIC(xor, RRR_R, RRR_S, RRR_T);
1572 4dd85b6b Max Filippov
                break;
1573 4dd85b6b Max Filippov
1574 4dd85b6b Max Filippov
#undef BOOLEAN_LOGIC
1575 4dd85b6b Max Filippov
1576 f76ebf55 Max Filippov
            case 8: /*MULLi*/
1577 f76ebf55 Max Filippov
                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
1578 f76ebf55 Max Filippov
                tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1579 f76ebf55 Max Filippov
                break;
1580 f76ebf55 Max Filippov
1581 f76ebf55 Max Filippov
            case 10: /*MULUHi*/
1582 f76ebf55 Max Filippov
            case 11: /*MULSHi*/
1583 7f65f4b0 Max Filippov
                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL_HIGH);
1584 f76ebf55 Max Filippov
                {
1585 f76ebf55 Max Filippov
                    TCGv_i64 r = tcg_temp_new_i64();
1586 f76ebf55 Max Filippov
                    TCGv_i64 s = tcg_temp_new_i64();
1587 f76ebf55 Max Filippov
                    TCGv_i64 t = tcg_temp_new_i64();
1588 f76ebf55 Max Filippov
1589 f76ebf55 Max Filippov
                    if (OP2 == 10) {
1590 f76ebf55 Max Filippov
                        tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);
1591 f76ebf55 Max Filippov
                        tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);
1592 f76ebf55 Max Filippov
                    } else {
1593 f76ebf55 Max Filippov
                        tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);
1594 f76ebf55 Max Filippov
                        tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);
1595 f76ebf55 Max Filippov
                    }
1596 f76ebf55 Max Filippov
                    tcg_gen_mul_i64(r, s, t);
1597 f76ebf55 Max Filippov
                    tcg_gen_shri_i64(r, r, 32);
1598 f76ebf55 Max Filippov
                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);
1599 f76ebf55 Max Filippov
1600 f76ebf55 Max Filippov
                    tcg_temp_free_i64(r);
1601 f76ebf55 Max Filippov
                    tcg_temp_free_i64(s);
1602 f76ebf55 Max Filippov
                    tcg_temp_free_i64(t);
1603 f76ebf55 Max Filippov
                }
1604 f76ebf55 Max Filippov
                break;
1605 f76ebf55 Max Filippov
1606 f76ebf55 Max Filippov
            case 12: /*QUOUi*/
1607 f76ebf55 Max Filippov
                tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1608 f76ebf55 Max Filippov
                break;
1609 f76ebf55 Max Filippov
1610 f76ebf55 Max Filippov
            case 13: /*QUOSi*/
1611 f76ebf55 Max Filippov
            case 15: /*REMSi*/
1612 f76ebf55 Max Filippov
                {
1613 f76ebf55 Max Filippov
                    int label1 = gen_new_label();
1614 f76ebf55 Max Filippov
                    int label2 = gen_new_label();
1615 f76ebf55 Max Filippov
1616 f76ebf55 Max Filippov
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000,
1617 f76ebf55 Max Filippov
                            label1);
1618 f76ebf55 Max Filippov
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff,
1619 f76ebf55 Max Filippov
                            label1);
1620 f76ebf55 Max Filippov
                    tcg_gen_movi_i32(cpu_R[RRR_R],
1621 f76ebf55 Max Filippov
                            OP2 == 13 ? 0x80000000 : 0);
1622 f76ebf55 Max Filippov
                    tcg_gen_br(label2);
1623 f76ebf55 Max Filippov
                    gen_set_label(label1);
1624 f76ebf55 Max Filippov
                    if (OP2 == 13) {
1625 f76ebf55 Max Filippov
                        tcg_gen_div_i32(cpu_R[RRR_R],
1626 f76ebf55 Max Filippov
                                cpu_R[RRR_S], cpu_R[RRR_T]);
1627 f76ebf55 Max Filippov
                    } else {
1628 f76ebf55 Max Filippov
                        tcg_gen_rem_i32(cpu_R[RRR_R],
1629 f76ebf55 Max Filippov
                                cpu_R[RRR_S], cpu_R[RRR_T]);
1630 f76ebf55 Max Filippov
                    }
1631 f76ebf55 Max Filippov
                    gen_set_label(label2);
1632 f76ebf55 Max Filippov
                }
1633 f76ebf55 Max Filippov
                break;
1634 f76ebf55 Max Filippov
1635 f76ebf55 Max Filippov
            case 14: /*REMUi*/
1636 f76ebf55 Max Filippov
                tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1637 f76ebf55 Max Filippov
                break;
1638 f76ebf55 Max Filippov
1639 f76ebf55 Max Filippov
            default: /*reserved*/
1640 f76ebf55 Max Filippov
                RESERVED();
1641 f76ebf55 Max Filippov
                break;
1642 f76ebf55 Max Filippov
            }
1643 dedc5eae Max Filippov
            break;
1644 dedc5eae Max Filippov
1645 dedc5eae Max Filippov
        case 3: /*RST3*/
1646 b8132eff Max Filippov
            switch (OP2) {
1647 b8132eff Max Filippov
            case 0: /*RSR*/
1648 40643d7c Max Filippov
                if (RSR_SR >= 64) {
1649 40643d7c Max Filippov
                    gen_check_privilege(dc);
1650 40643d7c Max Filippov
                }
1651 772177c1 Max Filippov
                gen_window_check1(dc, RRR_T);
1652 b8132eff Max Filippov
                gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1653 91a5bb76 Max Filippov
                if (!sregnames[RSR_SR]) {
1654 91a5bb76 Max Filippov
                    TBD();
1655 91a5bb76 Max Filippov
                }
1656 b8132eff Max Filippov
                break;
1657 b8132eff Max Filippov
1658 b8132eff Max Filippov
            case 1: /*WSR*/
1659 40643d7c Max Filippov
                if (RSR_SR >= 64) {
1660 40643d7c Max Filippov
                    gen_check_privilege(dc);
1661 40643d7c Max Filippov
                }
1662 772177c1 Max Filippov
                gen_window_check1(dc, RRR_T);
1663 b8132eff Max Filippov
                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
1664 91a5bb76 Max Filippov
                if (!sregnames[RSR_SR]) {
1665 91a5bb76 Max Filippov
                    TBD();
1666 91a5bb76 Max Filippov
                }
1667 b8132eff Max Filippov
                break;
1668 b8132eff Max Filippov
1669 b8132eff Max Filippov
            case 2: /*SEXTu*/
1670 7f65f4b0 Max Filippov
                HAS_OPTION(XTENSA_OPTION_MISC_OP_SEXT);
1671 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_S);
1672 b8132eff Max Filippov
                {
1673 b8132eff Max Filippov
                    int shift = 24 - RRR_T;
1674 b8132eff Max Filippov
1675 b8132eff Max Filippov
                    if (shift == 24) {
1676 b8132eff Max Filippov
                        tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1677 b8132eff Max Filippov
                    } else if (shift == 16) {
1678 b8132eff Max Filippov
                        tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1679 b8132eff Max Filippov
                    } else {
1680 b8132eff Max Filippov
                        TCGv_i32 tmp = tcg_temp_new_i32();
1681 b8132eff Max Filippov
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);
1682 b8132eff Max Filippov
                        tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);
1683 b8132eff Max Filippov
                        tcg_temp_free(tmp);
1684 b8132eff Max Filippov
                    }
1685 b8132eff Max Filippov
                }
1686 b8132eff Max Filippov
                break;
1687 b8132eff Max Filippov
1688 b8132eff Max Filippov
            case 3: /*CLAMPSu*/
1689 7f65f4b0 Max Filippov
                HAS_OPTION(XTENSA_OPTION_MISC_OP_CLAMPS);
1690 772177c1 Max Filippov
                gen_window_check2(dc, RRR_R, RRR_S);
1691 b8132eff Max Filippov
                {
1692 b8132eff Max Filippov
                    TCGv_i32 tmp1 = tcg_temp_new_i32();
1693 b8132eff Max Filippov
                    TCGv_i32 tmp2 = tcg_temp_new_i32();
1694 b8132eff Max Filippov
                    int label = gen_new_label();
1695 b8132eff Max Filippov
1696 b8132eff Max Filippov
                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
1697 b8132eff Max Filippov
                    tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
1698 b8132eff Max Filippov
                    tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
1699 b8132eff Max Filippov
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1700 b8132eff Max Filippov
                    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
1701 b8132eff Max Filippov
1702 b8132eff Max Filippov
                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
1703 b8132eff Max Filippov
                    tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
1704 b8132eff Max Filippov
                            0xffffffff >> (25 - RRR_T));
1705 b8132eff Max Filippov
1706 b8132eff Max Filippov
                    gen_set_label(label);
1707 b8132eff Max Filippov
1708 b8132eff Max Filippov
                    tcg_temp_free(tmp1);
1709 b8132eff Max Filippov
                    tcg_temp_free(tmp2);
1710 b8132eff Max Filippov
                }
1711 b8132eff Max Filippov
                break;
1712 b8132eff Max Filippov
1713 b8132eff Max Filippov
            case 4: /*MINu*/
1714 b8132eff Max Filippov
            case 5: /*MAXu*/
1715 b8132eff Max Filippov
            case 6: /*MINUu*/
1716 b8132eff Max Filippov
            case 7: /*MAXUu*/
1717 7f65f4b0 Max Filippov
                HAS_OPTION(XTENSA_OPTION_MISC_OP_MINMAX);
1718 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1719 b8132eff Max Filippov
                {
1720 b8132eff Max Filippov
                    static const TCGCond cond[] = {
1721 b8132eff Max Filippov
                        TCG_COND_LE,
1722 b8132eff Max Filippov
                        TCG_COND_GE,
1723 b8132eff Max Filippov
                        TCG_COND_LEU,
1724 b8132eff Max Filippov
                        TCG_COND_GEU
1725 b8132eff Max Filippov
                    };
1726 b8132eff Max Filippov
                    int label = gen_new_label();
1727 b8132eff Max Filippov
1728 b8132eff Max Filippov
                    if (RRR_R != RRR_T) {
1729 b8132eff Max Filippov
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1730 b8132eff Max Filippov
                        tcg_gen_brcond_i32(cond[OP2 - 4],
1731 b8132eff Max Filippov
                                cpu_R[RRR_S], cpu_R[RRR_T], label);
1732 b8132eff Max Filippov
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1733 b8132eff Max Filippov
                    } else {
1734 b8132eff Max Filippov
                        tcg_gen_brcond_i32(cond[OP2 - 4],
1735 b8132eff Max Filippov
                                cpu_R[RRR_T], cpu_R[RRR_S], label);
1736 b8132eff Max Filippov
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1737 b8132eff Max Filippov
                    }
1738 b8132eff Max Filippov
                    gen_set_label(label);
1739 b8132eff Max Filippov
                }
1740 b8132eff Max Filippov
                break;
1741 b8132eff Max Filippov
1742 b8132eff Max Filippov
            case 8: /*MOVEQZ*/
1743 b8132eff Max Filippov
            case 9: /*MOVNEZ*/
1744 b8132eff Max Filippov
            case 10: /*MOVLTZ*/
1745 b8132eff Max Filippov
            case 11: /*MOVGEZ*/
1746 772177c1 Max Filippov
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1747 b8132eff Max Filippov
                {
1748 b8132eff Max Filippov
                    static const TCGCond cond[] = {
1749 b8132eff Max Filippov
                        TCG_COND_NE,
1750 b8132eff Max Filippov
                        TCG_COND_EQ,
1751 b8132eff Max Filippov
                        TCG_COND_GE,
1752 b8132eff Max Filippov
                        TCG_COND_LT
1753 b8132eff Max Filippov
                    };
1754 b8132eff Max Filippov
                    int label = gen_new_label();
1755 b8132eff Max Filippov
                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
1756 b8132eff Max Filippov
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1757 b8132eff Max Filippov
                    gen_set_label(label);
1758 b8132eff Max Filippov
                }
1759 b8132eff Max Filippov
                break;
1760 b8132eff Max Filippov
1761 b8132eff Max Filippov
            case 12: /*MOVFp*/
1762 b8132eff Max Filippov
            case 13: /*MOVTp*/
1763 b8132eff Max Filippov
                HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1764 4dd85b6b Max Filippov
                gen_window_check2(dc, RRR_R, RRR_S);
1765 4dd85b6b Max Filippov
                {
1766 4dd85b6b Max Filippov
                    int label = gen_new_label();
1767 4dd85b6b Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
1768 4dd85b6b Max Filippov
1769 4dd85b6b Max Filippov
                    tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
1770 4dd85b6b Max Filippov
                    tcg_gen_brcondi_i32(
1771 4dd85b6b Max Filippov
                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
1772 4dd85b6b Max Filippov
                            tmp, 0, label);
1773 4dd85b6b Max Filippov
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1774 4dd85b6b Max Filippov
                    gen_set_label(label);
1775 4dd85b6b Max Filippov
                    tcg_temp_free(tmp);
1776 4dd85b6b Max Filippov
                }
1777 b8132eff Max Filippov
                break;
1778 b8132eff Max Filippov
1779 b8132eff Max Filippov
            case 14: /*RUR*/
1780 772177c1 Max Filippov
                gen_window_check1(dc, RRR_R);
1781 b8132eff Max Filippov
                {
1782 b8132eff Max Filippov
                    int st = (RRR_S << 4) + RRR_T;
1783 b8132eff Max Filippov
                    if (uregnames[st]) {
1784 b8132eff Max Filippov
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
1785 b8132eff Max Filippov
                    } else {
1786 b8132eff Max Filippov
                        qemu_log("RUR %d not implemented, ", st);
1787 91a5bb76 Max Filippov
                        TBD();
1788 b8132eff Max Filippov
                    }
1789 b8132eff Max Filippov
                }
1790 b8132eff Max Filippov
                break;
1791 b8132eff Max Filippov
1792 b8132eff Max Filippov
            case 15: /*WUR*/
1793 772177c1 Max Filippov
                gen_window_check1(dc, RRR_T);
1794 dd519cbe Max Filippov
                if (uregnames[RSR_SR]) {
1795 dd519cbe Max Filippov
                    gen_wur(RSR_SR, cpu_R[RRR_T]);
1796 dd519cbe Max Filippov
                } else {
1797 dd519cbe Max Filippov
                    qemu_log("WUR %d not implemented, ", RSR_SR);
1798 dd519cbe Max Filippov
                    TBD();
1799 b8132eff Max Filippov
                }
1800 b8132eff Max Filippov
                break;
1801 b8132eff Max Filippov
1802 b8132eff Max Filippov
            }
1803 dedc5eae Max Filippov
            break;
1804 dedc5eae Max Filippov
1805 dedc5eae Max Filippov
        case 4: /*EXTUI*/
1806 dedc5eae Max Filippov
        case 5:
1807 772177c1 Max Filippov
            gen_window_check2(dc, RRR_R, RRR_T);
1808 3580ecad Max Filippov
            {
1809 f9cb5045 Max Filippov
                int shiftimm = RRR_S | ((OP1 & 1) << 4);
1810 3580ecad Max Filippov
                int maskimm = (1 << (OP2 + 1)) - 1;
1811 3580ecad Max Filippov
1812 3580ecad Max Filippov
                TCGv_i32 tmp = tcg_temp_new_i32();
1813 f9cb5045 Max Filippov
1814 f9cb5045 Max Filippov
                if (shiftimm) {
1815 f9cb5045 Max Filippov
                    tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
1816 f9cb5045 Max Filippov
                } else {
1817 f9cb5045 Max Filippov
                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
1818 f9cb5045 Max Filippov
                }
1819 f9cb5045 Max Filippov
1820 f9cb5045 Max Filippov
                switch (maskimm) {
1821 f9cb5045 Max Filippov
                case 0xff:
1822 f9cb5045 Max Filippov
                    tcg_gen_ext8u_i32(cpu_R[RRR_R], tmp);
1823 f9cb5045 Max Filippov
                    break;
1824 f9cb5045 Max Filippov
1825 f9cb5045 Max Filippov
                case 0xffff:
1826 f9cb5045 Max Filippov
                    tcg_gen_ext16u_i32(cpu_R[RRR_R], tmp);
1827 f9cb5045 Max Filippov
                    break;
1828 f9cb5045 Max Filippov
1829 f9cb5045 Max Filippov
                default:
1830 f9cb5045 Max Filippov
                    tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
1831 f9cb5045 Max Filippov
                    break;
1832 f9cb5045 Max Filippov
                }
1833 3580ecad Max Filippov
                tcg_temp_free(tmp);
1834 3580ecad Max Filippov
            }
1835 dedc5eae Max Filippov
            break;
1836 dedc5eae Max Filippov
1837 dedc5eae Max Filippov
        case 6: /*CUST0*/
1838 91a5bb76 Max Filippov
            RESERVED();
1839 dedc5eae Max Filippov
            break;
1840 dedc5eae Max Filippov
1841 dedc5eae Max Filippov
        case 7: /*CUST1*/
1842 91a5bb76 Max Filippov
            RESERVED();
1843 dedc5eae Max Filippov
            break;
1844 dedc5eae Max Filippov
1845 dedc5eae Max Filippov
        case 8: /*LSCXp*/
1846 dedc5eae Max Filippov
            HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
1847 91a5bb76 Max Filippov
            TBD();
1848 dedc5eae Max Filippov
            break;
1849 dedc5eae Max Filippov
1850 dedc5eae Max Filippov
        case 9: /*LSC4*/
1851 772177c1 Max Filippov
            gen_window_check2(dc, RRR_S, RRR_T);
1852 553e44f9 Max Filippov
            switch (OP2) {
1853 553e44f9 Max Filippov
            case 0: /*L32E*/
1854 553e44f9 Max Filippov
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1855 553e44f9 Max Filippov
                gen_check_privilege(dc);
1856 553e44f9 Max Filippov
                {
1857 553e44f9 Max Filippov
                    TCGv_i32 addr = tcg_temp_new_i32();
1858 553e44f9 Max Filippov
                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1859 553e44f9 Max Filippov
                            (0xffffffc0 | (RRR_R << 2)));
1860 553e44f9 Max Filippov
                    tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring);
1861 553e44f9 Max Filippov
                    tcg_temp_free(addr);
1862 553e44f9 Max Filippov
                }
1863 553e44f9 Max Filippov
                break;
1864 553e44f9 Max Filippov
1865 553e44f9 Max Filippov
            case 4: /*S32E*/
1866 553e44f9 Max Filippov
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1867 553e44f9 Max Filippov
                gen_check_privilege(dc);
1868 553e44f9 Max Filippov
                {
1869 553e44f9 Max Filippov
                    TCGv_i32 addr = tcg_temp_new_i32();
1870 553e44f9 Max Filippov
                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1871 553e44f9 Max Filippov
                            (0xffffffc0 | (RRR_R << 2)));
1872 553e44f9 Max Filippov
                    tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring);
1873 553e44f9 Max Filippov
                    tcg_temp_free(addr);
1874 553e44f9 Max Filippov
                }
1875 553e44f9 Max Filippov
                break;
1876 553e44f9 Max Filippov
1877 553e44f9 Max Filippov
            default:
1878 553e44f9 Max Filippov
                RESERVED();
1879 553e44f9 Max Filippov
                break;
1880 553e44f9 Max Filippov
            }
1881 dedc5eae Max Filippov
            break;
1882 dedc5eae Max Filippov
1883 dedc5eae Max Filippov
        case 10: /*FP0*/
1884 dedc5eae Max Filippov
            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1885 91a5bb76 Max Filippov
            TBD();
1886 dedc5eae Max Filippov
            break;
1887 dedc5eae Max Filippov
1888 dedc5eae Max Filippov
        case 11: /*FP1*/
1889 dedc5eae Max Filippov
            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1890 91a5bb76 Max Filippov
            TBD();
1891 dedc5eae Max Filippov
            break;
1892 dedc5eae Max Filippov
1893 dedc5eae Max Filippov
        default: /*reserved*/
1894 91a5bb76 Max Filippov
            RESERVED();
1895 dedc5eae Max Filippov
            break;
1896 dedc5eae Max Filippov
        }
1897 dedc5eae Max Filippov
        break;
1898 dedc5eae Max Filippov
1899 dedc5eae Max Filippov
    case 1: /*L32R*/
1900 772177c1 Max Filippov
        gen_window_check1(dc, RRR_T);
1901 dedc5eae Max Filippov
        {
1902 dedc5eae Max Filippov
            TCGv_i32 tmp = tcg_const_i32(
1903 6ad6dbf7 Max Filippov
                    ((dc->tb->flags & XTENSA_TBFLAG_LITBASE) ?
1904 6ad6dbf7 Max Filippov
                     0 : ((dc->pc + 3) & ~3)) +
1905 6ad6dbf7 Max Filippov
                    (0xfffc0000 | (RI16_IMM16 << 2)));
1906 dedc5eae Max Filippov
1907 6ad6dbf7 Max Filippov
            if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
1908 6ad6dbf7 Max Filippov
                tcg_gen_add_i32(tmp, tmp, dc->litbase);
1909 6ad6dbf7 Max Filippov
            }
1910 f0a548b9 Max Filippov
            tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring);
1911 dedc5eae Max Filippov
            tcg_temp_free(tmp);
1912 dedc5eae Max Filippov
        }
1913 dedc5eae Max Filippov
        break;
1914 dedc5eae Max Filippov
1915 dedc5eae Max Filippov
    case 2: /*LSAI*/
1916 809377aa Max Filippov
#define gen_load_store(type, shift) do { \
1917 809377aa Max Filippov
            TCGv_i32 addr = tcg_temp_new_i32(); \
1918 772177c1 Max Filippov
            gen_window_check2(dc, RRI8_S, RRI8_T); \
1919 809377aa Max Filippov
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
1920 5b4e481b Max Filippov
            if (shift) { \
1921 5b4e481b Max Filippov
                gen_load_store_alignment(dc, shift, addr, false); \
1922 5b4e481b Max Filippov
            } \
1923 f0a548b9 Max Filippov
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1924 809377aa Max Filippov
            tcg_temp_free(addr); \
1925 809377aa Max Filippov
        } while (0)
1926 809377aa Max Filippov
1927 809377aa Max Filippov
        switch (RRI8_R) {
1928 809377aa Max Filippov
        case 0: /*L8UI*/
1929 809377aa Max Filippov
            gen_load_store(ld8u, 0);
1930 809377aa Max Filippov
            break;
1931 809377aa Max Filippov
1932 809377aa Max Filippov
        case 1: /*L16UI*/
1933 809377aa Max Filippov
            gen_load_store(ld16u, 1);
1934 809377aa Max Filippov
            break;
1935 809377aa Max Filippov
1936 809377aa Max Filippov
        case 2: /*L32I*/
1937 809377aa Max Filippov
            gen_load_store(ld32u, 2);
1938 809377aa Max Filippov
            break;
1939 809377aa Max Filippov
1940 809377aa Max Filippov
        case 4: /*S8I*/
1941 809377aa Max Filippov
            gen_load_store(st8, 0);
1942 809377aa Max Filippov
            break;
1943 809377aa Max Filippov
1944 809377aa Max Filippov
        case 5: /*S16I*/
1945 809377aa Max Filippov
            gen_load_store(st16, 1);
1946 809377aa Max Filippov
            break;
1947 809377aa Max Filippov
1948 809377aa Max Filippov
        case 6: /*S32I*/
1949 809377aa Max Filippov
            gen_load_store(st32, 2);
1950 809377aa Max Filippov
            break;
1951 809377aa Max Filippov
1952 809377aa Max Filippov
        case 7: /*CACHEc*/
1953 8ffc2d0d Max Filippov
            if (RRI8_T < 8) {
1954 8ffc2d0d Max Filippov
                HAS_OPTION(XTENSA_OPTION_DCACHE);
1955 8ffc2d0d Max Filippov
            }
1956 8ffc2d0d Max Filippov
1957 8ffc2d0d Max Filippov
            switch (RRI8_T) {
1958 8ffc2d0d Max Filippov
            case 0: /*DPFRc*/
1959 8ffc2d0d Max Filippov
                break;
1960 8ffc2d0d Max Filippov
1961 8ffc2d0d Max Filippov
            case 1: /*DPFWc*/
1962 8ffc2d0d Max Filippov
                break;
1963 8ffc2d0d Max Filippov
1964 8ffc2d0d Max Filippov
            case 2: /*DPFROc*/
1965 8ffc2d0d Max Filippov
                break;
1966 8ffc2d0d Max Filippov
1967 8ffc2d0d Max Filippov
            case 3: /*DPFWOc*/
1968 8ffc2d0d Max Filippov
                break;
1969 8ffc2d0d Max Filippov
1970 8ffc2d0d Max Filippov
            case 4: /*DHWBc*/
1971 8ffc2d0d Max Filippov
                break;
1972 8ffc2d0d Max Filippov
1973 8ffc2d0d Max Filippov
            case 5: /*DHWBIc*/
1974 8ffc2d0d Max Filippov
                break;
1975 8ffc2d0d Max Filippov
1976 8ffc2d0d Max Filippov
            case 6: /*DHIc*/
1977 8ffc2d0d Max Filippov
                break;
1978 8ffc2d0d Max Filippov
1979 8ffc2d0d Max Filippov
            case 7: /*DIIc*/
1980 8ffc2d0d Max Filippov
                break;
1981 8ffc2d0d Max Filippov
1982 8ffc2d0d Max Filippov
            case 8: /*DCEc*/
1983 8ffc2d0d Max Filippov
                switch (OP1) {
1984 8ffc2d0d Max Filippov
                case 0: /*DPFLl*/
1985 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1986 8ffc2d0d Max Filippov
                    break;
1987 8ffc2d0d Max Filippov
1988 8ffc2d0d Max Filippov
                case 2: /*DHUl*/
1989 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1990 8ffc2d0d Max Filippov
                    break;
1991 8ffc2d0d Max Filippov
1992 8ffc2d0d Max Filippov
                case 3: /*DIUl*/
1993 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1994 8ffc2d0d Max Filippov
                    break;
1995 8ffc2d0d Max Filippov
1996 8ffc2d0d Max Filippov
                case 4: /*DIWBc*/
1997 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_DCACHE);
1998 8ffc2d0d Max Filippov
                    break;
1999 8ffc2d0d Max Filippov
2000 8ffc2d0d Max Filippov
                case 5: /*DIWBIc*/
2001 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_DCACHE);
2002 8ffc2d0d Max Filippov
                    break;
2003 8ffc2d0d Max Filippov
2004 8ffc2d0d Max Filippov
                default: /*reserved*/
2005 8ffc2d0d Max Filippov
                    RESERVED();
2006 8ffc2d0d Max Filippov
                    break;
2007 8ffc2d0d Max Filippov
2008 8ffc2d0d Max Filippov
                }
2009 8ffc2d0d Max Filippov
                break;
2010 8ffc2d0d Max Filippov
2011 8ffc2d0d Max Filippov
            case 12: /*IPFc*/
2012 8ffc2d0d Max Filippov
                HAS_OPTION(XTENSA_OPTION_ICACHE);
2013 8ffc2d0d Max Filippov
                break;
2014 8ffc2d0d Max Filippov
2015 8ffc2d0d Max Filippov
            case 13: /*ICEc*/
2016 8ffc2d0d Max Filippov
                switch (OP1) {
2017 8ffc2d0d Max Filippov
                case 0: /*IPFLl*/
2018 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
2019 8ffc2d0d Max Filippov
                    break;
2020 8ffc2d0d Max Filippov
2021 8ffc2d0d Max Filippov
                case 2: /*IHUl*/
2022 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
2023 8ffc2d0d Max Filippov
                    break;
2024 8ffc2d0d Max Filippov
2025 8ffc2d0d Max Filippov
                case 3: /*IIUl*/
2026 8ffc2d0d Max Filippov
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
2027 8ffc2d0d Max Filippov
                    break;
2028 8ffc2d0d Max Filippov
2029 8ffc2d0d Max Filippov
                default: /*reserved*/
2030 8ffc2d0d Max Filippov
                    RESERVED();
2031 8ffc2d0d Max Filippov
                    break;
2032 8ffc2d0d Max Filippov
                }
2033 8ffc2d0d Max Filippov
                break;
2034 8ffc2d0d Max Filippov
2035 8ffc2d0d Max Filippov
            case 14: /*IHIc*/
2036 8ffc2d0d Max Filippov
                HAS_OPTION(XTENSA_OPTION_ICACHE);
2037 8ffc2d0d Max Filippov
                break;
2038 8ffc2d0d Max Filippov
2039 8ffc2d0d Max Filippov
            case 15: /*IIIc*/
2040 8ffc2d0d Max Filippov
                HAS_OPTION(XTENSA_OPTION_ICACHE);
2041 8ffc2d0d Max Filippov
                break;
2042 8ffc2d0d Max Filippov
2043 8ffc2d0d Max Filippov
            default: /*reserved*/
2044 8ffc2d0d Max Filippov
                RESERVED();
2045 8ffc2d0d Max Filippov
                break;
2046 8ffc2d0d Max Filippov
            }
2047 809377aa Max Filippov
            break;
2048 809377aa Max Filippov
2049 809377aa Max Filippov
        case 9: /*L16SI*/
2050 809377aa Max Filippov
            gen_load_store(ld16s, 1);
2051 809377aa Max Filippov
            break;
2052 5b4e481b Max Filippov
#undef gen_load_store
2053 809377aa Max Filippov
2054 809377aa Max Filippov
        case 10: /*MOVI*/
2055 772177c1 Max Filippov
            gen_window_check1(dc, RRI8_T);
2056 809377aa Max Filippov
            tcg_gen_movi_i32(cpu_R[RRI8_T],
2057 809377aa Max Filippov
                    RRI8_IMM8 | (RRI8_S << 8) |
2058 809377aa Max Filippov
                    ((RRI8_S & 0x8) ? 0xfffff000 : 0));
2059 809377aa Max Filippov
            break;
2060 809377aa Max Filippov
2061 5b4e481b Max Filippov
#define gen_load_store_no_hw_align(type) do { \
2062 5b4e481b Max Filippov
            TCGv_i32 addr = tcg_temp_local_new_i32(); \
2063 772177c1 Max Filippov
            gen_window_check2(dc, RRI8_S, RRI8_T); \
2064 5b4e481b Max Filippov
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \
2065 5b4e481b Max Filippov
            gen_load_store_alignment(dc, 2, addr, true); \
2066 5b4e481b Max Filippov
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
2067 5b4e481b Max Filippov
            tcg_temp_free(addr); \
2068 5b4e481b Max Filippov
        } while (0)
2069 5b4e481b Max Filippov
2070 809377aa Max Filippov
        case 11: /*L32AIy*/
2071 809377aa Max Filippov
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
2072 5b4e481b Max Filippov
            gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/
2073 809377aa Max Filippov
            break;
2074 809377aa Max Filippov
2075 809377aa Max Filippov
        case 12: /*ADDI*/
2076 772177c1 Max Filippov
            gen_window_check2(dc, RRI8_S, RRI8_T);
2077 809377aa Max Filippov
            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);
2078 809377aa Max Filippov
            break;
2079 809377aa Max Filippov
2080 809377aa Max Filippov
        case 13: /*ADDMI*/
2081 772177c1 Max Filippov
            gen_window_check2(dc, RRI8_S, RRI8_T);
2082 809377aa Max Filippov
            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);
2083 809377aa Max Filippov
            break;
2084 809377aa Max Filippov
2085 809377aa Max Filippov
        case 14: /*S32C1Iy*/
2086 7f65f4b0 Max Filippov
            HAS_OPTION(XTENSA_OPTION_CONDITIONAL_STORE);
2087 772177c1 Max Filippov
            gen_window_check2(dc, RRI8_S, RRI8_T);
2088 809377aa Max Filippov
            {
2089 809377aa Max Filippov
                int label = gen_new_label();
2090 809377aa Max Filippov
                TCGv_i32 tmp = tcg_temp_local_new_i32();
2091 809377aa Max Filippov
                TCGv_i32 addr = tcg_temp_local_new_i32();
2092 809377aa Max Filippov
2093 809377aa Max Filippov
                tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
2094 809377aa Max Filippov
                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
2095 5b4e481b Max Filippov
                gen_load_store_alignment(dc, 2, addr, true);
2096 f0a548b9 Max Filippov
                tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);
2097 809377aa Max Filippov
                tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
2098 809377aa Max Filippov
                        cpu_SR[SCOMPARE1], label);
2099 809377aa Max Filippov
2100 f0a548b9 Max Filippov
                tcg_gen_qemu_st32(tmp, addr, dc->cring);
2101 809377aa Max Filippov
2102 809377aa Max Filippov
                gen_set_label(label);
2103 809377aa Max Filippov
                tcg_temp_free(addr);
2104 809377aa Max Filippov
                tcg_temp_free(tmp);
2105 809377aa Max Filippov
            }
2106 809377aa Max Filippov
            break;
2107 809377aa Max Filippov
2108 809377aa Max Filippov
        case 15: /*S32RIy*/
2109 809377aa Max Filippov
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
2110 5b4e481b Max Filippov
            gen_load_store_no_hw_align(st32); /*TODO release?*/
2111 809377aa Max Filippov
            break;
2112 5b4e481b Max Filippov
#undef gen_load_store_no_hw_align
2113 809377aa Max Filippov
2114 809377aa Max Filippov
        default: /*reserved*/
2115 91a5bb76 Max Filippov
            RESERVED();
2116 809377aa Max Filippov
            break;
2117 809377aa Max Filippov
        }
2118 dedc5eae Max Filippov
        break;
2119 dedc5eae Max Filippov
2120 dedc5eae Max Filippov
    case 3: /*LSCIp*/
2121 dedc5eae Max Filippov
        HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
2122 91a5bb76 Max Filippov
        TBD();
2123 dedc5eae Max Filippov
        break;
2124 dedc5eae Max Filippov
2125 dedc5eae Max Filippov
    case 4: /*MAC16d*/
2126 dedc5eae Max Filippov
        HAS_OPTION(XTENSA_OPTION_MAC16);
2127 6825b6c3 Max Filippov
        {
2128 6825b6c3 Max Filippov
            enum {
2129 6825b6c3 Max Filippov
                MAC16_UMUL = 0x0,
2130 6825b6c3 Max Filippov
                MAC16_MUL  = 0x4,
2131 6825b6c3 Max Filippov
                MAC16_MULA = 0x8,
2132 6825b6c3 Max Filippov
                MAC16_MULS = 0xc,
2133 6825b6c3 Max Filippov
                MAC16_NONE = 0xf,
2134 6825b6c3 Max Filippov
            } op = OP1 & 0xc;
2135 6825b6c3 Max Filippov
            bool is_m1_sr = (OP2 & 0x3) == 2;
2136 6825b6c3 Max Filippov
            bool is_m2_sr = (OP2 & 0xc) == 0;
2137 6825b6c3 Max Filippov
            uint32_t ld_offset = 0;
2138 6825b6c3 Max Filippov
2139 6825b6c3 Max Filippov
            if (OP2 > 9) {
2140 6825b6c3 Max Filippov
                RESERVED();
2141 6825b6c3 Max Filippov
            }
2142 6825b6c3 Max Filippov
2143 6825b6c3 Max Filippov
            switch (OP2 & 2) {
2144 6825b6c3 Max Filippov
            case 0: /*MACI?/MACC?*/
2145 6825b6c3 Max Filippov
                is_m1_sr = true;
2146 6825b6c3 Max Filippov
                ld_offset = (OP2 & 1) ? -4 : 4;
2147 6825b6c3 Max Filippov
2148 6825b6c3 Max Filippov
                if (OP2 >= 8) { /*MACI/MACC*/
2149 6825b6c3 Max Filippov
                    if (OP1 == 0) { /*LDINC/LDDEC*/
2150 6825b6c3 Max Filippov
                        op = MAC16_NONE;
2151 6825b6c3 Max Filippov
                    } else {
2152 6825b6c3 Max Filippov
                        RESERVED();
2153 6825b6c3 Max Filippov
                    }
2154 6825b6c3 Max Filippov
                } else if (op != MAC16_MULA) { /*MULA.*.*.LDINC/LDDEC*/
2155 6825b6c3 Max Filippov
                    RESERVED();
2156 6825b6c3 Max Filippov
                }
2157 6825b6c3 Max Filippov
                break;
2158 6825b6c3 Max Filippov
2159 6825b6c3 Max Filippov
            case 2: /*MACD?/MACA?*/
2160 6825b6c3 Max Filippov
                if (op == MAC16_UMUL && OP2 != 7) { /*UMUL only in MACAA*/
2161 6825b6c3 Max Filippov
                    RESERVED();
2162 6825b6c3 Max Filippov
                }
2163 6825b6c3 Max Filippov
                break;
2164 6825b6c3 Max Filippov
            }
2165 6825b6c3 Max Filippov
2166 6825b6c3 Max Filippov
            if (op != MAC16_NONE) {
2167 6825b6c3 Max Filippov
                if (!is_m1_sr) {
2168 6825b6c3 Max Filippov
                    gen_window_check1(dc, RRR_S);
2169 6825b6c3 Max Filippov
                }
2170 6825b6c3 Max Filippov
                if (!is_m2_sr) {
2171 6825b6c3 Max Filippov
                    gen_window_check1(dc, RRR_T);
2172 6825b6c3 Max Filippov
                }
2173 6825b6c3 Max Filippov
            }
2174 6825b6c3 Max Filippov
2175 6825b6c3 Max Filippov
            {
2176 6825b6c3 Max Filippov
                TCGv_i32 vaddr = tcg_temp_new_i32();
2177 6825b6c3 Max Filippov
                TCGv_i32 mem32 = tcg_temp_new_i32();
2178 6825b6c3 Max Filippov
2179 6825b6c3 Max Filippov
                if (ld_offset) {
2180 6825b6c3 Max Filippov
                    gen_window_check1(dc, RRR_S);
2181 6825b6c3 Max Filippov
                    tcg_gen_addi_i32(vaddr, cpu_R[RRR_S], ld_offset);
2182 6825b6c3 Max Filippov
                    gen_load_store_alignment(dc, 2, vaddr, false);
2183 6825b6c3 Max Filippov
                    tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
2184 6825b6c3 Max Filippov
                }
2185 6825b6c3 Max Filippov
                if (op != MAC16_NONE) {
2186 6825b6c3 Max Filippov
                    TCGv_i32 m1 = gen_mac16_m(
2187 6825b6c3 Max Filippov
                            is_m1_sr ? cpu_SR[MR + RRR_X] : cpu_R[RRR_S],
2188 6825b6c3 Max Filippov
                            OP1 & 1, op == MAC16_UMUL);
2189 6825b6c3 Max Filippov
                    TCGv_i32 m2 = gen_mac16_m(
2190 6825b6c3 Max Filippov
                            is_m2_sr ? cpu_SR[MR + 2 + RRR_Y] : cpu_R[RRR_T],
2191 6825b6c3 Max Filippov
                            OP1 & 2, op == MAC16_UMUL);
2192 6825b6c3 Max Filippov
2193 6825b6c3 Max Filippov
                    if (op == MAC16_MUL || op == MAC16_UMUL) {
2194 6825b6c3 Max Filippov
                        tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
2195 6825b6c3 Max Filippov
                        if (op == MAC16_UMUL) {
2196 6825b6c3 Max Filippov
                            tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
2197 6825b6c3 Max Filippov
                        } else {
2198 6825b6c3 Max Filippov
                            tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
2199 6825b6c3 Max Filippov
                        }
2200 6825b6c3 Max Filippov
                    } else {
2201 6825b6c3 Max Filippov
                        TCGv_i32 res = tcg_temp_new_i32();
2202 6825b6c3 Max Filippov
                        TCGv_i64 res64 = tcg_temp_new_i64();
2203 6825b6c3 Max Filippov
                        TCGv_i64 tmp = tcg_temp_new_i64();
2204 6825b6c3 Max Filippov
2205 6825b6c3 Max Filippov
                        tcg_gen_mul_i32(res, m1, m2);
2206 6825b6c3 Max Filippov
                        tcg_gen_ext_i32_i64(res64, res);
2207 6825b6c3 Max Filippov
                        tcg_gen_concat_i32_i64(tmp,
2208 6825b6c3 Max Filippov
                                cpu_SR[ACCLO], cpu_SR[ACCHI]);
2209 6825b6c3 Max Filippov
                        if (op == MAC16_MULA) {
2210 6825b6c3 Max Filippov
                            tcg_gen_add_i64(tmp, tmp, res64);
2211 6825b6c3 Max Filippov
                        } else {
2212 6825b6c3 Max Filippov
                            tcg_gen_sub_i64(tmp, tmp, res64);
2213 6825b6c3 Max Filippov
                        }
2214 6825b6c3 Max Filippov
                        tcg_gen_trunc_i64_i32(cpu_SR[ACCLO], tmp);
2215 6825b6c3 Max Filippov
                        tcg_gen_shri_i64(tmp, tmp, 32);
2216 6825b6c3 Max Filippov
                        tcg_gen_trunc_i64_i32(cpu_SR[ACCHI], tmp);
2217 6825b6c3 Max Filippov
                        tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
2218 6825b6c3 Max Filippov
2219 6825b6c3 Max Filippov
                        tcg_temp_free(res);
2220 6825b6c3 Max Filippov
                        tcg_temp_free_i64(res64);
2221 6825b6c3 Max Filippov
                        tcg_temp_free_i64(tmp);
2222 6825b6c3 Max Filippov
                    }
2223 6825b6c3 Max Filippov
                    tcg_temp_free(m1);
2224 6825b6c3 Max Filippov
                    tcg_temp_free(m2);
2225 6825b6c3 Max Filippov
                }
2226 6825b6c3 Max Filippov
                if (ld_offset) {
2227 6825b6c3 Max Filippov
                    tcg_gen_mov_i32(cpu_R[RRR_S], vaddr);
2228 6825b6c3 Max Filippov
                    tcg_gen_mov_i32(cpu_SR[MR + RRR_W], mem32);
2229 6825b6c3 Max Filippov
                }
2230 6825b6c3 Max Filippov
                tcg_temp_free(vaddr);
2231 6825b6c3 Max Filippov
                tcg_temp_free(mem32);
2232 6825b6c3 Max Filippov
            }
2233 6825b6c3 Max Filippov
        }
2234 dedc5eae Max Filippov
        break;
2235 dedc5eae Max Filippov
2236 dedc5eae Max Filippov
    case 5: /*CALLN*/
2237 dedc5eae Max Filippov
        switch (CALL_N) {
2238 dedc5eae Max Filippov
        case 0: /*CALL0*/
2239 dedc5eae Max Filippov
            tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
2240 dedc5eae Max Filippov
            gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2241 dedc5eae Max Filippov
            break;
2242 dedc5eae Max Filippov
2243 dedc5eae Max Filippov
        case 1: /*CALL4w*/
2244 dedc5eae Max Filippov
        case 2: /*CALL8w*/
2245 dedc5eae Max Filippov
        case 3: /*CALL12w*/
2246 dedc5eae Max Filippov
            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2247 772177c1 Max Filippov
            gen_window_check1(dc, CALL_N << 2);
2248 553e44f9 Max Filippov
            gen_callwi(dc, CALL_N,
2249 553e44f9 Max Filippov
                    (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2250 dedc5eae Max Filippov
            break;
2251 dedc5eae Max Filippov
        }
2252 dedc5eae Max Filippov
        break;
2253 dedc5eae Max Filippov
2254 dedc5eae Max Filippov
    case 6: /*SI*/
2255 dedc5eae Max Filippov
        switch (CALL_N) {
2256 dedc5eae Max Filippov
        case 0: /*J*/
2257 dedc5eae Max Filippov
            gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);
2258 dedc5eae Max Filippov
            break;
2259 dedc5eae Max Filippov
2260 bd57fb91 Max Filippov
        case 1: /*BZ*/
2261 772177c1 Max Filippov
            gen_window_check1(dc, BRI12_S);
2262 bd57fb91 Max Filippov
            {
2263 bd57fb91 Max Filippov
                static const TCGCond cond[] = {
2264 bd57fb91 Max Filippov
                    TCG_COND_EQ, /*BEQZ*/
2265 bd57fb91 Max Filippov
                    TCG_COND_NE, /*BNEZ*/
2266 bd57fb91 Max Filippov
                    TCG_COND_LT, /*BLTZ*/
2267 bd57fb91 Max Filippov
                    TCG_COND_GE, /*BGEZ*/
2268 bd57fb91 Max Filippov
                };
2269 bd57fb91 Max Filippov
2270 bd57fb91 Max Filippov
                gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,
2271 bd57fb91 Max Filippov
                        4 + BRI12_IMM12_SE);
2272 bd57fb91 Max Filippov
            }
2273 bd57fb91 Max Filippov
            break;
2274 bd57fb91 Max Filippov
2275 bd57fb91 Max Filippov
        case 2: /*BI0*/
2276 772177c1 Max Filippov
            gen_window_check1(dc, BRI8_S);
2277 bd57fb91 Max Filippov
            {
2278 bd57fb91 Max Filippov
                static const TCGCond cond[] = {
2279 bd57fb91 Max Filippov
                    TCG_COND_EQ, /*BEQI*/
2280 bd57fb91 Max Filippov
                    TCG_COND_NE, /*BNEI*/
2281 bd57fb91 Max Filippov
                    TCG_COND_LT, /*BLTI*/
2282 bd57fb91 Max Filippov
                    TCG_COND_GE, /*BGEI*/
2283 bd57fb91 Max Filippov
                };
2284 bd57fb91 Max Filippov
2285 bd57fb91 Max Filippov
                gen_brcondi(dc, cond[BRI8_M & 3],
2286 bd57fb91 Max Filippov
                        cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);
2287 bd57fb91 Max Filippov
            }
2288 bd57fb91 Max Filippov
            break;
2289 bd57fb91 Max Filippov
2290 bd57fb91 Max Filippov
        case 3: /*BI1*/
2291 bd57fb91 Max Filippov
            switch (BRI8_M) {
2292 bd57fb91 Max Filippov
            case 0: /*ENTRYw*/
2293 bd57fb91 Max Filippov
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2294 553e44f9 Max Filippov
                {
2295 553e44f9 Max Filippov
                    TCGv_i32 pc = tcg_const_i32(dc->pc);
2296 553e44f9 Max Filippov
                    TCGv_i32 s = tcg_const_i32(BRI12_S);
2297 553e44f9 Max Filippov
                    TCGv_i32 imm = tcg_const_i32(BRI12_IMM12);
2298 b994e91b Max Filippov
                    gen_advance_ccount(dc);
2299 f492b82d Max Filippov
                    gen_helper_entry(cpu_env, pc, s, imm);
2300 553e44f9 Max Filippov
                    tcg_temp_free(imm);
2301 553e44f9 Max Filippov
                    tcg_temp_free(s);
2302 553e44f9 Max Filippov
                    tcg_temp_free(pc);
2303 772177c1 Max Filippov
                    reset_used_window(dc);
2304 553e44f9 Max Filippov
                }
2305 bd57fb91 Max Filippov
                break;
2306 bd57fb91 Max Filippov
2307 bd57fb91 Max Filippov
            case 1: /*B1*/
2308 bd57fb91 Max Filippov
                switch (BRI8_R) {
2309 bd57fb91 Max Filippov
                case 0: /*BFp*/
2310 bd57fb91 Max Filippov
                case 1: /*BTp*/
2311 bd57fb91 Max Filippov
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
2312 4dd85b6b Max Filippov
                    {
2313 4dd85b6b Max Filippov
                        TCGv_i32 tmp = tcg_temp_new_i32();
2314 4dd85b6b Max Filippov
                        tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRI8_S);
2315 4dd85b6b Max Filippov
                        gen_brcondi(dc,
2316 4dd85b6b Max Filippov
                                BRI8_R == 1 ? TCG_COND_NE : TCG_COND_EQ,
2317 4dd85b6b Max Filippov
                                tmp, 0, 4 + RRI8_IMM8_SE);
2318 4dd85b6b Max Filippov
                        tcg_temp_free(tmp);
2319 4dd85b6b Max Filippov
                    }
2320 bd57fb91 Max Filippov
                    break;
2321 bd57fb91 Max Filippov
2322 bd57fb91 Max Filippov
                case 8: /*LOOP*/
2323 bd57fb91 Max Filippov
                case 9: /*LOOPNEZ*/
2324 bd57fb91 Max Filippov
                case 10: /*LOOPGTZ*/
2325 797d780b Max Filippov
                    HAS_OPTION(XTENSA_OPTION_LOOP);
2326 772177c1 Max Filippov
                    gen_window_check1(dc, RRI8_S);
2327 797d780b Max Filippov
                    {
2328 797d780b Max Filippov
                        uint32_t lend = dc->pc + RRI8_IMM8 + 4;
2329 797d780b Max Filippov
                        TCGv_i32 tmp = tcg_const_i32(lend);
2330 797d780b Max Filippov
2331 797d780b Max Filippov
                        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);
2332 797d780b Max Filippov
                        tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
2333 f492b82d Max Filippov
                        gen_helper_wsr_lend(cpu_env, tmp);
2334 797d780b Max Filippov
                        tcg_temp_free(tmp);
2335 797d780b Max Filippov
2336 797d780b Max Filippov
                        if (BRI8_R > 8) {
2337 797d780b Max Filippov
                            int label = gen_new_label();
2338 797d780b Max Filippov
                            tcg_gen_brcondi_i32(
2339 797d780b Max Filippov
                                    BRI8_R == 9 ? TCG_COND_NE : TCG_COND_GT,
2340 797d780b Max Filippov
                                    cpu_R[RRI8_S], 0, label);
2341 797d780b Max Filippov
                            gen_jumpi(dc, lend, 1);
2342 797d780b Max Filippov
                            gen_set_label(label);
2343 797d780b Max Filippov
                        }
2344 797d780b Max Filippov
2345 797d780b Max Filippov
                        gen_jumpi(dc, dc->next_pc, 0);
2346 797d780b Max Filippov
                    }
2347 bd57fb91 Max Filippov
                    break;
2348 bd57fb91 Max Filippov
2349 bd57fb91 Max Filippov
                default: /*reserved*/
2350 91a5bb76 Max Filippov
                    RESERVED();
2351 bd57fb91 Max Filippov
                    break;
2352 bd57fb91 Max Filippov
2353 bd57fb91 Max Filippov
                }
2354 bd57fb91 Max Filippov
                break;
2355 bd57fb91 Max Filippov
2356 bd57fb91 Max Filippov
            case 2: /*BLTUI*/
2357 bd57fb91 Max Filippov
            case 3: /*BGEUI*/
2358 772177c1 Max Filippov
                gen_window_check1(dc, BRI8_S);
2359 bd57fb91 Max Filippov
                gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,
2360 bd57fb91 Max Filippov
                        cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);
2361 bd57fb91 Max Filippov
                break;
2362 bd57fb91 Max Filippov
            }
2363 bd57fb91 Max Filippov
            break;
2364 bd57fb91 Max Filippov
2365 dedc5eae Max Filippov
        }
2366 dedc5eae Max Filippov
        break;
2367 dedc5eae Max Filippov
2368 dedc5eae Max Filippov
    case 7: /*B*/
2369 bd57fb91 Max Filippov
        {
2370 bd57fb91 Max Filippov
            TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;
2371 bd57fb91 Max Filippov
2372 bd57fb91 Max Filippov
            switch (RRI8_R & 7) {
2373 bd57fb91 Max Filippov
            case 0: /*BNONE*/ /*BANY*/
2374 772177c1 Max Filippov
                gen_window_check2(dc, RRI8_S, RRI8_T);
2375 bd57fb91 Max Filippov
                {
2376 bd57fb91 Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
2377 bd57fb91 Max Filippov
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2378 bd57fb91 Max Filippov
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2379 bd57fb91 Max Filippov
                    tcg_temp_free(tmp);
2380 bd57fb91 Max Filippov
                }
2381 bd57fb91 Max Filippov
                break;
2382 bd57fb91 Max Filippov
2383 bd57fb91 Max Filippov
            case 1: /*BEQ*/ /*BNE*/
2384 bd57fb91 Max Filippov
            case 2: /*BLT*/ /*BGE*/
2385 bd57fb91 Max Filippov
            case 3: /*BLTU*/ /*BGEU*/
2386 772177c1 Max Filippov
                gen_window_check2(dc, RRI8_S, RRI8_T);
2387 bd57fb91 Max Filippov
                {
2388 bd57fb91 Max Filippov
                    static const TCGCond cond[] = {
2389 bd57fb91 Max Filippov
                        [1] = TCG_COND_EQ,
2390 bd57fb91 Max Filippov
                        [2] = TCG_COND_LT,
2391 bd57fb91 Max Filippov
                        [3] = TCG_COND_LTU,
2392 bd57fb91 Max Filippov
                        [9] = TCG_COND_NE,
2393 bd57fb91 Max Filippov
                        [10] = TCG_COND_GE,
2394 bd57fb91 Max Filippov
                        [11] = TCG_COND_GEU,
2395 bd57fb91 Max Filippov
                    };
2396 bd57fb91 Max Filippov
                    gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],
2397 bd57fb91 Max Filippov
                            4 + RRI8_IMM8_SE);
2398 bd57fb91 Max Filippov
                }
2399 bd57fb91 Max Filippov
                break;
2400 bd57fb91 Max Filippov
2401 bd57fb91 Max Filippov
            case 4: /*BALL*/ /*BNALL*/
2402 772177c1 Max Filippov
                gen_window_check2(dc, RRI8_S, RRI8_T);
2403 bd57fb91 Max Filippov
                {
2404 bd57fb91 Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
2405 bd57fb91 Max Filippov
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2406 bd57fb91 Max Filippov
                    gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],
2407 bd57fb91 Max Filippov
                            4 + RRI8_IMM8_SE);
2408 bd57fb91 Max Filippov
                    tcg_temp_free(tmp);
2409 bd57fb91 Max Filippov
                }
2410 bd57fb91 Max Filippov
                break;
2411 bd57fb91 Max Filippov
2412 bd57fb91 Max Filippov
            case 5: /*BBC*/ /*BBS*/
2413 772177c1 Max Filippov
                gen_window_check2(dc, RRI8_S, RRI8_T);
2414 bd57fb91 Max Filippov
                {
2415 7ff7563f Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
2416 7ff7563f Max Filippov
                    TCGv_i32 bit = tcg_const_i32(0x80000000);
2417 7ff7563f Max Filippov
#else
2418 7ff7563f Max Filippov
                    TCGv_i32 bit = tcg_const_i32(0x00000001);
2419 7ff7563f Max Filippov
#endif
2420 bd57fb91 Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
2421 bd57fb91 Max Filippov
                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);
2422 7ff7563f Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
2423 7ff7563f Max Filippov
                    tcg_gen_shr_i32(bit, bit, tmp);
2424 7ff7563f Max Filippov
#else
2425 bd57fb91 Max Filippov
                    tcg_gen_shl_i32(bit, bit, tmp);
2426 7ff7563f Max Filippov
#endif
2427 bd57fb91 Max Filippov
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);
2428 bd57fb91 Max Filippov
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2429 bd57fb91 Max Filippov
                    tcg_temp_free(tmp);
2430 bd57fb91 Max Filippov
                    tcg_temp_free(bit);
2431 bd57fb91 Max Filippov
                }
2432 bd57fb91 Max Filippov
                break;
2433 bd57fb91 Max Filippov
2434 bd57fb91 Max Filippov
            case 6: /*BBCI*/ /*BBSI*/
2435 bd57fb91 Max Filippov
            case 7:
2436 772177c1 Max Filippov
                gen_window_check1(dc, RRI8_S);
2437 bd57fb91 Max Filippov
                {
2438 bd57fb91 Max Filippov
                    TCGv_i32 tmp = tcg_temp_new_i32();
2439 bd57fb91 Max Filippov
                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],
2440 7ff7563f Max Filippov
#ifdef TARGET_WORDS_BIGENDIAN
2441 7ff7563f Max Filippov
                            0x80000000 >> (((RRI8_R & 1) << 4) | RRI8_T));
2442 7ff7563f Max Filippov
#else
2443 7ff7563f Max Filippov
                            0x00000001 << (((RRI8_R & 1) << 4) | RRI8_T));
2444 7ff7563f Max Filippov
#endif
2445 bd57fb91 Max Filippov
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2446 bd57fb91 Max Filippov
                    tcg_temp_free(tmp);
2447 bd57fb91 Max Filippov
                }
2448 bd57fb91 Max Filippov
                break;
2449 bd57fb91 Max Filippov
2450 bd57fb91 Max Filippov
            }
2451 bd57fb91 Max Filippov
        }
2452 dedc5eae Max Filippov
        break;
2453 dedc5eae Max Filippov
2454 67882fd1 Max Filippov
#define gen_narrow_load_store(type) do { \
2455 67882fd1 Max Filippov
            TCGv_i32 addr = tcg_temp_new_i32(); \
2456 772177c1 Max Filippov
            gen_window_check2(dc, RRRN_S, RRRN_T); \
2457 67882fd1 Max Filippov
            tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
2458 5b4e481b Max Filippov
            gen_load_store_alignment(dc, 2, addr, false); \
2459 f0a548b9 Max Filippov
            tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \
2460 67882fd1 Max Filippov
            tcg_temp_free(addr); \
2461 67882fd1 Max Filippov
        } while (0)
2462 67882fd1 Max Filippov
2463 dedc5eae Max Filippov
    case 8: /*L32I.Nn*/
2464 67882fd1 Max Filippov
        gen_narrow_load_store(ld32u);
2465 dedc5eae Max Filippov
        break;
2466 dedc5eae Max Filippov
2467 dedc5eae Max Filippov
    case 9: /*S32I.Nn*/
2468 67882fd1 Max Filippov
        gen_narrow_load_store(st32);
2469 dedc5eae Max Filippov
        break;
2470 67882fd1 Max Filippov
#undef gen_narrow_load_store
2471 dedc5eae Max Filippov
2472 dedc5eae Max Filippov
    case 10: /*ADD.Nn*/
2473 772177c1 Max Filippov
        gen_window_check3(dc, RRRN_R, RRRN_S, RRRN_T);
2474 67882fd1 Max Filippov
        tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);
2475 dedc5eae Max Filippov
        break;
2476 dedc5eae Max Filippov
2477 dedc5eae Max Filippov
    case 11: /*ADDI.Nn*/
2478 772177c1 Max Filippov
        gen_window_check2(dc, RRRN_R, RRRN_S);
2479 67882fd1 Max Filippov
        tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);
2480 dedc5eae Max Filippov
        break;
2481 dedc5eae Max Filippov
2482 dedc5eae Max Filippov
    case 12: /*ST2n*/
2483 772177c1 Max Filippov
        gen_window_check1(dc, RRRN_S);
2484 67882fd1 Max Filippov
        if (RRRN_T < 8) { /*MOVI.Nn*/
2485 67882fd1 Max Filippov
            tcg_gen_movi_i32(cpu_R[RRRN_S],
2486 67882fd1 Max Filippov
                    RRRN_R | (RRRN_T << 4) |
2487 67882fd1 Max Filippov
                    ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));
2488 67882fd1 Max Filippov
        } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
2489 bd57fb91 Max Filippov
            TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;
2490 bd57fb91 Max Filippov
2491 bd57fb91 Max Filippov
            gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,
2492 bd57fb91 Max Filippov
                    4 + (RRRN_R | ((RRRN_T & 3) << 4)));
2493 67882fd1 Max Filippov
        }
2494 dedc5eae Max Filippov
        break;
2495 dedc5eae Max Filippov
2496 dedc5eae Max Filippov
    case 13: /*ST3n*/
2497 67882fd1 Max Filippov
        switch (RRRN_R) {
2498 67882fd1 Max Filippov
        case 0: /*MOV.Nn*/
2499 772177c1 Max Filippov
            gen_window_check2(dc, RRRN_S, RRRN_T);
2500 67882fd1 Max Filippov
            tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);
2501 67882fd1 Max Filippov
            break;
2502 67882fd1 Max Filippov
2503 67882fd1 Max Filippov
        case 15: /*S3*/
2504 67882fd1 Max Filippov
            switch (RRRN_T) {
2505 67882fd1 Max Filippov
            case 0: /*RET.Nn*/
2506 67882fd1 Max Filippov
                gen_jump(dc, cpu_R[0]);
2507 67882fd1 Max Filippov
                break;
2508 67882fd1 Max Filippov
2509 67882fd1 Max Filippov
            case 1: /*RETW.Nn*/
2510 91a5bb76 Max Filippov
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2511 553e44f9 Max Filippov
                {
2512 553e44f9 Max Filippov
                    TCGv_i32 tmp = tcg_const_i32(dc->pc);
2513 b994e91b Max Filippov
                    gen_advance_ccount(dc);
2514 f492b82d Max Filippov
                    gen_helper_retw(tmp, cpu_env, tmp);
2515 553e44f9 Max Filippov
                    gen_jump(dc, tmp);
2516 553e44f9 Max Filippov
                    tcg_temp_free(tmp);
2517 553e44f9 Max Filippov
                }
2518 67882fd1 Max Filippov
                break;
2519 67882fd1 Max Filippov
2520 67882fd1 Max Filippov
            case 2: /*BREAK.Nn*/
2521 e61dc8f7 Max Filippov
                HAS_OPTION(XTENSA_OPTION_DEBUG);
2522 e61dc8f7 Max Filippov
                if (dc->debug) {
2523 e61dc8f7 Max Filippov
                    gen_debug_exception(dc, DEBUGCAUSE_BN);
2524 e61dc8f7 Max Filippov
                }
2525 67882fd1 Max Filippov
                break;
2526 67882fd1 Max Filippov
2527 67882fd1 Max Filippov
            case 3: /*NOP.Nn*/
2528 67882fd1 Max Filippov
                break;
2529 67882fd1 Max Filippov
2530 67882fd1 Max Filippov
            case 6: /*ILL.Nn*/
2531 40643d7c Max Filippov
                gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2532 67882fd1 Max Filippov
                break;
2533 67882fd1 Max Filippov
2534 67882fd1 Max Filippov
            default: /*reserved*/
2535 91a5bb76 Max Filippov
                RESERVED();
2536 67882fd1 Max Filippov
                break;
2537 67882fd1 Max Filippov
            }
2538 67882fd1 Max Filippov
            break;
2539 67882fd1 Max Filippov
2540 67882fd1 Max Filippov
        default: /*reserved*/
2541 91a5bb76 Max Filippov
            RESERVED();
2542 67882fd1 Max Filippov
            break;
2543 67882fd1 Max Filippov
        }
2544 dedc5eae Max Filippov
        break;
2545 dedc5eae Max Filippov
2546 dedc5eae Max Filippov
    default: /*reserved*/
2547 91a5bb76 Max Filippov
        RESERVED();
2548 dedc5eae Max Filippov
        break;
2549 dedc5eae Max Filippov
    }
2550 dedc5eae Max Filippov
2551 c26032b2 Max Filippov
    if (dc->is_jmp == DISAS_NEXT) {
2552 c26032b2 Max Filippov
        gen_check_loop_end(dc, 0);
2553 c26032b2 Max Filippov
    }
2554 dedc5eae Max Filippov
    dc->pc = dc->next_pc;
2555 797d780b Max Filippov
2556 dedc5eae Max Filippov
    return;
2557 dedc5eae Max Filippov
2558 dedc5eae Max Filippov
invalid_opcode:
2559 dedc5eae Max Filippov
    qemu_log("INVALID(pc = %08x)\n", dc->pc);
2560 6b814719 Max Filippov
    gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2561 dedc5eae Max Filippov
#undef HAS_OPTION
2562 dedc5eae Max Filippov
}
2563 dedc5eae Max Filippov
2564 97129ac8 Andreas Färber
static void check_breakpoint(CPUXtensaState *env, DisasContext *dc)
2565 dedc5eae Max Filippov
{
2566 dedc5eae Max Filippov
    CPUBreakpoint *bp;
2567 dedc5eae Max Filippov
2568 dedc5eae Max Filippov
    if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
2569 dedc5eae Max Filippov
        QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
2570 dedc5eae Max Filippov
            if (bp->pc == dc->pc) {
2571 dedc5eae Max Filippov
                tcg_gen_movi_i32(cpu_pc, dc->pc);
2572 b994e91b Max Filippov
                gen_exception(dc, EXCP_DEBUG);
2573 dedc5eae Max Filippov
                dc->is_jmp = DISAS_UPDATE;
2574 dedc5eae Max Filippov
             }
2575 dedc5eae Max Filippov
        }
2576 dedc5eae Max Filippov
    }
2577 dedc5eae Max Filippov
}
2578 dedc5eae Max Filippov
2579 97129ac8 Andreas Färber
static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
2580 e61dc8f7 Max Filippov
{
2581 e61dc8f7 Max Filippov
    unsigned i;
2582 e61dc8f7 Max Filippov
2583 e61dc8f7 Max Filippov
    for (i = 0; i < dc->config->nibreak; ++i) {
2584 e61dc8f7 Max Filippov
        if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
2585 e61dc8f7 Max Filippov
                env->sregs[IBREAKA + i] == dc->pc) {
2586 e61dc8f7 Max Filippov
            gen_debug_exception(dc, DEBUGCAUSE_IB);
2587 e61dc8f7 Max Filippov
            break;
2588 e61dc8f7 Max Filippov
        }
2589 e61dc8f7 Max Filippov
    }
2590 e61dc8f7 Max Filippov
}
2591 e61dc8f7 Max Filippov
2592 dedc5eae Max Filippov
static void gen_intermediate_code_internal(
2593 97129ac8 Andreas Färber
        CPUXtensaState *env, TranslationBlock *tb, int search_pc)
2594 dedc5eae Max Filippov
{
2595 dedc5eae Max Filippov
    DisasContext dc;
2596 dedc5eae Max Filippov
    int insn_count = 0;
2597 dedc5eae Max Filippov
    int j, lj = -1;
2598 dedc5eae Max Filippov
    uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2599 dedc5eae Max Filippov
    int max_insns = tb->cflags & CF_COUNT_MASK;
2600 dedc5eae Max Filippov
    uint32_t pc_start = tb->pc;
2601 dedc5eae Max Filippov
    uint32_t next_page_start =
2602 dedc5eae Max Filippov
        (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2603 dedc5eae Max Filippov
2604 dedc5eae Max Filippov
    if (max_insns == 0) {
2605 dedc5eae Max Filippov
        max_insns = CF_COUNT_MASK;
2606 dedc5eae Max Filippov
    }
2607 dedc5eae Max Filippov
2608 dedc5eae Max Filippov
    dc.config = env->config;
2609 dedc5eae Max Filippov
    dc.singlestep_enabled = env->singlestep_enabled;
2610 dedc5eae Max Filippov
    dc.tb = tb;
2611 dedc5eae Max Filippov
    dc.pc = pc_start;
2612 f0a548b9 Max Filippov
    dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
2613 f0a548b9 Max Filippov
    dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;
2614 797d780b Max Filippov
    dc.lbeg = env->sregs[LBEG];
2615 797d780b Max Filippov
    dc.lend = env->sregs[LEND];
2616 dedc5eae Max Filippov
    dc.is_jmp = DISAS_NEXT;
2617 b994e91b Max Filippov
    dc.ccount_delta = 0;
2618 e61dc8f7 Max Filippov
    dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
2619 35b5c044 Max Filippov
    dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
2620 dedc5eae Max Filippov
2621 6ad6dbf7 Max Filippov
    init_litbase(&dc);
2622 3580ecad Max Filippov
    init_sar_tracker(&dc);
2623 772177c1 Max Filippov
    reset_used_window(&dc);
2624 35b5c044 Max Filippov
    if (dc.icount) {
2625 35b5c044 Max Filippov
        dc.next_icount = tcg_temp_local_new_i32();
2626 35b5c044 Max Filippov
    }
2627 3580ecad Max Filippov
2628 dedc5eae Max Filippov
    gen_icount_start();
2629 dedc5eae Max Filippov
2630 40643d7c Max Filippov
    if (env->singlestep_enabled && env->exception_taken) {
2631 40643d7c Max Filippov
        env->exception_taken = 0;
2632 40643d7c Max Filippov
        tcg_gen_movi_i32(cpu_pc, dc.pc);
2633 b994e91b Max Filippov
        gen_exception(&dc, EXCP_DEBUG);
2634 40643d7c Max Filippov
    }
2635 40643d7c Max Filippov
2636 dedc5eae Max Filippov
    do {
2637 dedc5eae Max Filippov
        check_breakpoint(env, &dc);
2638 dedc5eae Max Filippov
2639 dedc5eae Max Filippov
        if (search_pc) {
2640 dedc5eae Max Filippov
            j = gen_opc_ptr - gen_opc_buf;
2641 dedc5eae Max Filippov
            if (lj < j) {
2642 dedc5eae Max Filippov
                lj++;
2643 dedc5eae Max Filippov
                while (lj < j) {
2644 dedc5eae Max Filippov
                    gen_opc_instr_start[lj++] = 0;
2645 dedc5eae Max Filippov
                }
2646 dedc5eae Max Filippov
            }
2647 dedc5eae Max Filippov
            gen_opc_pc[lj] = dc.pc;
2648 dedc5eae Max Filippov
            gen_opc_instr_start[lj] = 1;
2649 dedc5eae Max Filippov
            gen_opc_icount[lj] = insn_count;
2650 dedc5eae Max Filippov
        }
2651 dedc5eae Max Filippov
2652 dedc5eae Max Filippov
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2653 dedc5eae Max Filippov
            tcg_gen_debug_insn_start(dc.pc);
2654 dedc5eae Max Filippov
        }
2655 dedc5eae Max Filippov
2656 b994e91b Max Filippov
        ++dc.ccount_delta;
2657 b994e91b Max Filippov
2658 b994e91b Max Filippov
        if (insn_count + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
2659 b994e91b Max Filippov
            gen_io_start();
2660 b994e91b Max Filippov
        }
2661 b994e91b Max Filippov
2662 35b5c044 Max Filippov
        if (dc.icount) {
2663 35b5c044 Max Filippov
            int label = gen_new_label();
2664 35b5c044 Max Filippov
2665 35b5c044 Max Filippov
            tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1);
2666 35b5c044 Max Filippov
            tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label);
2667 35b5c044 Max Filippov
            tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]);
2668 35b5c044 Max Filippov
            if (dc.debug) {
2669 35b5c044 Max Filippov
                gen_debug_exception(&dc, DEBUGCAUSE_IC);
2670 35b5c044 Max Filippov
            }
2671 35b5c044 Max Filippov
            gen_set_label(label);
2672 35b5c044 Max Filippov
        }
2673 35b5c044 Max Filippov
2674 e61dc8f7 Max Filippov
        if (dc.debug) {
2675 e61dc8f7 Max Filippov
            gen_ibreak_check(env, &dc);
2676 e61dc8f7 Max Filippov
        }
2677 e61dc8f7 Max Filippov
2678 dedc5eae Max Filippov
        disas_xtensa_insn(&dc);
2679 dedc5eae Max Filippov
        ++insn_count;
2680 35b5c044 Max Filippov
        if (dc.icount) {
2681 35b5c044 Max Filippov
            tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
2682 35b5c044 Max Filippov
        }
2683 dedc5eae Max Filippov
        if (env->singlestep_enabled) {
2684 dedc5eae Max Filippov
            tcg_gen_movi_i32(cpu_pc, dc.pc);
2685 b994e91b Max Filippov
            gen_exception(&dc, EXCP_DEBUG);
2686 dedc5eae Max Filippov
            break;
2687 dedc5eae Max Filippov
        }
2688 dedc5eae Max Filippov
    } while (dc.is_jmp == DISAS_NEXT &&
2689 dedc5eae Max Filippov
            insn_count < max_insns &&
2690 dedc5eae Max Filippov
            dc.pc < next_page_start &&
2691 dedc5eae Max Filippov
            gen_opc_ptr < gen_opc_end);
2692 dedc5eae Max Filippov
2693 6ad6dbf7 Max Filippov
    reset_litbase(&dc);
2694 3580ecad Max Filippov
    reset_sar_tracker(&dc);
2695 35b5c044 Max Filippov
    if (dc.icount) {
2696 35b5c044 Max Filippov
        tcg_temp_free(dc.next_icount);
2697 35b5c044 Max Filippov
    }
2698 3580ecad Max Filippov
2699 b994e91b Max Filippov
    if (tb->cflags & CF_LAST_IO) {
2700 b994e91b Max Filippov
        gen_io_end();
2701 b994e91b Max Filippov
    }
2702 b994e91b Max Filippov
2703 dedc5eae Max Filippov
    if (dc.is_jmp == DISAS_NEXT) {
2704 dedc5eae Max Filippov
        gen_jumpi(&dc, dc.pc, 0);
2705 dedc5eae Max Filippov
    }
2706 dedc5eae Max Filippov
    gen_icount_end(tb, insn_count);
2707 dedc5eae Max Filippov
    *gen_opc_ptr = INDEX_op_end;
2708 dedc5eae Max Filippov
2709 dedc5eae Max Filippov
    if (!search_pc) {
2710 dedc5eae Max Filippov
        tb->size = dc.pc - pc_start;
2711 dedc5eae Max Filippov
        tb->icount = insn_count;
2712 dedc5eae Max Filippov
    }
2713 2328826b Max Filippov
}
2714 2328826b Max Filippov
2715 97129ac8 Andreas Färber
void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
2716 2328826b Max Filippov
{
2717 dedc5eae Max Filippov
    gen_intermediate_code_internal(env, tb, 0);
2718 2328826b Max Filippov
}
2719 2328826b Max Filippov
2720 97129ac8 Andreas Färber
void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
2721 2328826b Max Filippov
{
2722 dedc5eae Max Filippov
    gen_intermediate_code_internal(env, tb, 1);
2723 2328826b Max Filippov
}
2724 2328826b Max Filippov
2725 97129ac8 Andreas Färber
void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
2726 2328826b Max Filippov
        int flags)
2727 2328826b Max Filippov
{
2728 2af3da91 Max Filippov
    int i, j;
2729 2af3da91 Max Filippov
2730 2af3da91 Max Filippov
    cpu_fprintf(f, "PC=%08x\n\n", env->pc);
2731 2af3da91 Max Filippov
2732 2af3da91 Max Filippov
    for (i = j = 0; i < 256; ++i) {
2733 2af3da91 Max Filippov
        if (sregnames[i]) {
2734 2af3da91 Max Filippov
            cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
2735 2af3da91 Max Filippov
                    (j++ % 4) == 3 ? '\n' : ' ');
2736 2af3da91 Max Filippov
        }
2737 2af3da91 Max Filippov
    }
2738 2af3da91 Max Filippov
2739 2af3da91 Max Filippov
    cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2740 2af3da91 Max Filippov
2741 2af3da91 Max Filippov
    for (i = j = 0; i < 256; ++i) {
2742 2af3da91 Max Filippov
        if (uregnames[i]) {
2743 2af3da91 Max Filippov
            cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
2744 2af3da91 Max Filippov
                    (j++ % 4) == 3 ? '\n' : ' ');
2745 2af3da91 Max Filippov
        }
2746 2af3da91 Max Filippov
    }
2747 2328826b Max Filippov
2748 2af3da91 Max Filippov
    cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2749 2328826b Max Filippov
2750 2328826b Max Filippov
    for (i = 0; i < 16; ++i) {
2751 2328826b Max Filippov
        cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
2752 2328826b Max Filippov
                (i % 4) == 3 ? '\n' : ' ');
2753 2328826b Max Filippov
    }
2754 553e44f9 Max Filippov
2755 553e44f9 Max Filippov
    cpu_fprintf(f, "\n");
2756 553e44f9 Max Filippov
2757 553e44f9 Max Filippov
    for (i = 0; i < env->config->nareg; ++i) {
2758 553e44f9 Max Filippov
        cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
2759 553e44f9 Max Filippov
                (i % 4) == 3 ? '\n' : ' ');
2760 553e44f9 Max Filippov
    }
2761 dd519cbe Max Filippov
2762 dd519cbe Max Filippov
    if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
2763 dd519cbe Max Filippov
        cpu_fprintf(f, "\n");
2764 dd519cbe Max Filippov
2765 dd519cbe Max Filippov
        for (i = 0; i < 16; ++i) {
2766 dd519cbe Max Filippov
            cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
2767 dd519cbe Max Filippov
                    float32_val(env->fregs[i]),
2768 dd519cbe Max Filippov
                    *(float *)&env->fregs[i], (i % 2) == 1 ? '\n' : ' ');
2769 dd519cbe Max Filippov
        }
2770 dd519cbe Max Filippov
    }
2771 2328826b Max Filippov
}
2772 2328826b Max Filippov
2773 97129ac8 Andreas Färber
void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, int pc_pos)
2774 2328826b Max Filippov
{
2775 2328826b Max Filippov
    env->pc = gen_opc_pc[pc_pos];
2776 2328826b Max Filippov
}