Statistics
| Branch: | Revision:

root / target-xtensa / translate.c @ 797d780b

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