~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to target-xtensa/translate.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

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