Statistics
| Branch: | Revision:

root / target-xtensa / translate.c @ 6825b6c3

History | View | Annotate | Download (79.1 kB)

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
}
270

    
271
static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
272
        TCGv_i32 vaddr)
273
{
274
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
275
    TCGv_i32 tcause = tcg_const_i32(cause);
276
    gen_advance_ccount(dc);
277
    gen_helper_exception_cause_vaddr(tpc, tcause, vaddr);
278
    tcg_temp_free(tpc);
279
    tcg_temp_free(tcause);
280
}
281

    
282
static void gen_check_privilege(DisasContext *dc)
283
{
284
    if (dc->cring) {
285
        gen_exception_cause(dc, PRIVILEGED_CAUSE);
286
    }
287
}
288

    
289
static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
290
{
291
    tcg_gen_mov_i32(cpu_pc, dest);
292
    if (dc->singlestep_enabled) {
293
        gen_exception(dc, EXCP_DEBUG);
294
    } else {
295
        gen_advance_ccount(dc);
296
        if (slot >= 0) {
297
            tcg_gen_goto_tb(slot);
298
            tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
299
        } else {
300
            tcg_gen_exit_tb(0);
301
        }
302
    }
303
    dc->is_jmp = DISAS_UPDATE;
304
}
305

    
306
static void gen_jump(DisasContext *dc, TCGv dest)
307
{
308
    gen_jump_slot(dc, dest, -1);
309
}
310

    
311
static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
312
{
313
    TCGv_i32 tmp = tcg_const_i32(dest);
314
    if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
315
        slot = -1;
316
    }
317
    gen_jump_slot(dc, tmp, slot);
318
    tcg_temp_free(tmp);
319
}
320

    
321
static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
322
        int slot)
323
{
324
    TCGv_i32 tcallinc = tcg_const_i32(callinc);
325

    
326
    tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
327
            tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
328
    tcg_temp_free(tcallinc);
329
    tcg_gen_movi_i32(cpu_R[callinc << 2],
330
            (callinc << 30) | (dc->next_pc & 0x3fffffff));
331
    gen_jump_slot(dc, dest, slot);
332
}
333

    
334
static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
335
{
336
    gen_callw_slot(dc, callinc, dest, -1);
337
}
338

    
339
static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
340
{
341
    TCGv_i32 tmp = tcg_const_i32(dest);
342
    if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
343
        slot = -1;
344
    }
345
    gen_callw_slot(dc, callinc, tmp, slot);
346
    tcg_temp_free(tmp);
347
}
348

    
349
static bool gen_check_loop_end(DisasContext *dc, int slot)
350
{
351
    if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
352
            !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&
353
            dc->next_pc == dc->lend) {
354
        int label = gen_new_label();
355

    
356
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
357
        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
358
        gen_jumpi(dc, dc->lbeg, slot);
359
        gen_set_label(label);
360
        gen_jumpi(dc, dc->next_pc, -1);
361
        return true;
362
    }
363
    return false;
364
}
365

    
366
static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
367
{
368
    if (!gen_check_loop_end(dc, slot)) {
369
        gen_jumpi(dc, dc->next_pc, slot);
370
    }
371
}
372

    
373
static void gen_brcond(DisasContext *dc, TCGCond cond,
374
        TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)
375
{
376
    int label = gen_new_label();
377

    
378
    tcg_gen_brcond_i32(cond, t0, t1, label);
379
    gen_jumpi_check_loop_end(dc, 0);
380
    gen_set_label(label);
381
    gen_jumpi(dc, dc->pc + offset, 1);
382
}
383

    
384
static void gen_brcondi(DisasContext *dc, TCGCond cond,
385
        TCGv_i32 t0, uint32_t t1, uint32_t offset)
386
{
387
    TCGv_i32 tmp = tcg_const_i32(t1);
388
    gen_brcond(dc, cond, t0, tmp, offset);
389
    tcg_temp_free(tmp);
390
}
391

    
392
static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
393
{
394
    gen_advance_ccount(dc);
395
    tcg_gen_mov_i32(d, cpu_SR[sr]);
396
}
397

    
398
static void gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
399
{
400
    tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10);
401
    tcg_gen_or_i32(d, d, cpu_SR[sr]);
402
    tcg_gen_andi_i32(d, d, 0xfffffffc);
403
}
404

    
405
static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
406
{
407
    static void (* const rsr_handler[256])(DisasContext *dc,
408
            TCGv_i32 d, uint32_t sr) = {
409
        [CCOUNT] = gen_rsr_ccount,
410
        [PTEVADDR] = gen_rsr_ptevaddr,
411
    };
412

    
413
    if (sregnames[sr]) {
414
        if (rsr_handler[sr]) {
415
            rsr_handler[sr](dc, d, sr);
416
        } else {
417
            tcg_gen_mov_i32(d, cpu_SR[sr]);
418
        }
419
    } else {
420
        qemu_log("RSR %d not implemented, ", sr);
421
    }
422
}
423

    
424
static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
425
{
426
    gen_helper_wsr_lbeg(s);
427
}
428

    
429
static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
430
{
431
    gen_helper_wsr_lend(s);
432
}
433

    
434
static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
435
{
436
    tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
437
    if (dc->sar_m32_5bit) {
438
        tcg_gen_discard_i32(dc->sar_m32);
439
    }
440
    dc->sar_5bit = false;
441
    dc->sar_m32_5bit = false;
442
}
443

    
444
static void gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
445
{
446
    tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
447
}
448

    
449
static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
450
{
451
    tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
452
    /* This can change tb->flags, so exit tb */
453
    gen_jumpi_check_loop_end(dc, -1);
454
}
455

    
456
static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
457
{
458
    tcg_gen_ext8s_i32(cpu_SR[sr], s);
459
}
460

    
461
static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
462
{
463
    gen_helper_wsr_windowbase(v);
464
    reset_used_window(dc);
465
}
466

    
467
static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
468
{
469
    tcg_gen_mov_i32(cpu_SR[sr], v);
470
    reset_used_window(dc);
471
}
472

    
473
static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
474
{
475
    tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
476
}
477

    
478
static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
479
{
480
    gen_helper_wsr_rasid(v);
481
    /* This can change tb->flags, so exit tb */
482
    gen_jumpi_check_loop_end(dc, -1);
483
}
484

    
485
static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
486
{
487
    tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
488
}
489

    
490
static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
491
{
492
    tcg_gen_andi_i32(cpu_SR[sr], v,
493
            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
494
    gen_helper_check_interrupts(cpu_env);
495
    gen_jumpi_check_loop_end(dc, 0);
496
}
497

    
498
static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
499
{
500
    TCGv_i32 tmp = tcg_temp_new_i32();
501

    
502
    tcg_gen_andi_i32(tmp, v,
503
            dc->config->inttype_mask[INTTYPE_EDGE] |
504
            dc->config->inttype_mask[INTTYPE_NMI] |
505
            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
506
    tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp);
507
    tcg_temp_free(tmp);
508
    gen_helper_check_interrupts(cpu_env);
509
}
510

    
511
static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
512
{
513
    tcg_gen_mov_i32(cpu_SR[sr], v);
514
    gen_helper_check_interrupts(cpu_env);
515
    gen_jumpi_check_loop_end(dc, 0);
516
}
517

    
518
static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
519
{
520
    uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
521
        PS_UM | PS_EXCM | PS_INTLEVEL;
522

    
523
    if (option_enabled(dc, XTENSA_OPTION_MMU)) {
524
        mask |= PS_RING;
525
    }
526
    tcg_gen_andi_i32(cpu_SR[sr], v, mask);
527
    reset_used_window(dc);
528
    gen_helper_check_interrupts(cpu_env);
529
    /* This can change mmu index and tb->flags, so exit tb */
530
    gen_jumpi_check_loop_end(dc, -1);
531
}
532

    
533
static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
534
{
535
}
536

    
537
static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
538
{
539
    uint32_t id = sr - CCOMPARE;
540
    if (id < dc->config->nccompare) {
541
        uint32_t int_bit = 1 << dc->config->timerint[id];
542
        gen_advance_ccount(dc);
543
        tcg_gen_mov_i32(cpu_SR[sr], v);
544
        tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);
545
        gen_helper_check_interrupts(cpu_env);
546
    }
547
}
548

    
549
static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
550
{
551
    static void (* const wsr_handler[256])(DisasContext *dc,
552
            uint32_t sr, TCGv_i32 v) = {
553
        [LBEG] = gen_wsr_lbeg,
554
        [LEND] = gen_wsr_lend,
555
        [SAR] = gen_wsr_sar,
556
        [BR] = gen_wsr_br,
557
        [LITBASE] = gen_wsr_litbase,
558
        [ACCHI] = gen_wsr_acchi,
559
        [WINDOW_BASE] = gen_wsr_windowbase,
560
        [WINDOW_START] = gen_wsr_windowstart,
561
        [PTEVADDR] = gen_wsr_ptevaddr,
562
        [RASID] = gen_wsr_rasid,
563
        [ITLBCFG] = gen_wsr_tlbcfg,
564
        [DTLBCFG] = gen_wsr_tlbcfg,
565
        [INTSET] = gen_wsr_intset,
566
        [INTCLEAR] = gen_wsr_intclear,
567
        [INTENABLE] = gen_wsr_intenable,
568
        [PS] = gen_wsr_ps,
569
        [PRID] = gen_wsr_prid,
570
        [CCOMPARE] = gen_wsr_ccompare,
571
        [CCOMPARE + 1] = gen_wsr_ccompare,
572
        [CCOMPARE + 2] = gen_wsr_ccompare,
573
    };
574

    
575
    if (sregnames[sr]) {
576
        if (wsr_handler[sr]) {
577
            wsr_handler[sr](dc, sr, s);
578
        } else {
579
            tcg_gen_mov_i32(cpu_SR[sr], s);
580
        }
581
    } else {
582
        qemu_log("WSR %d not implemented, ", sr);
583
    }
584
}
585

    
586
static void gen_load_store_alignment(DisasContext *dc, int shift,
587
        TCGv_i32 addr, bool no_hw_alignment)
588
{
589
    if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
590
        tcg_gen_andi_i32(addr, addr, ~0 << shift);
591
    } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
592
            no_hw_alignment) {
593
        int label = gen_new_label();
594
        TCGv_i32 tmp = tcg_temp_new_i32();
595
        tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
596
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
597
        gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
598
        gen_set_label(label);
599
        tcg_temp_free(tmp);
600
    }
601
}
602

    
603
static void gen_waiti(DisasContext *dc, uint32_t imm4)
604
{
605
    TCGv_i32 pc = tcg_const_i32(dc->next_pc);
606
    TCGv_i32 intlevel = tcg_const_i32(imm4);
607
    gen_advance_ccount(dc);
608
    gen_helper_waiti(pc, intlevel);
609
    tcg_temp_free(pc);
610
    tcg_temp_free(intlevel);
611
}
612

    
613
static void gen_window_check1(DisasContext *dc, unsigned r1)
614
{
615
    if (dc->tb->flags & XTENSA_TBFLAG_EXCM) {
616
        return;
617
    }
618
    if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&
619
            r1 / 4 > dc->used_window) {
620
        TCGv_i32 pc = tcg_const_i32(dc->pc);
621
        TCGv_i32 w = tcg_const_i32(r1 / 4);
622

    
623
        dc->used_window = r1 / 4;
624
        gen_advance_ccount(dc);
625
        gen_helper_window_check(pc, w);
626

    
627
        tcg_temp_free(w);
628
        tcg_temp_free(pc);
629
    }
630
}
631

    
632
static void gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)
633
{
634
    gen_window_check1(dc, r1 > r2 ? r1 : r2);
635
}
636

    
637
static void gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2,
638
        unsigned r3)
639
{
640
    gen_window_check2(dc, r1, r2 > r3 ? r2 : r3);
641
}
642

    
643
static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
644
{
645
    TCGv_i32 m = tcg_temp_new_i32();
646

    
647
    if (hi) {
648
        (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
649
    } else {
650
        (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
651
    }
652
    return m;
653
}
654

    
655
static void disas_xtensa_insn(DisasContext *dc)
656
{
657
#define HAS_OPTION_BITS(opt) do { \
658
        if (!option_bits_enabled(dc, opt)) { \
659
            qemu_log("Option is not enabled %s:%d\n", \
660
                    __FILE__, __LINE__); \
661
            goto invalid_opcode; \
662
        } \
663
    } while (0)
664

    
665
#define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt))
666

    
667
#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
668
#define RESERVED() do { \
669
        qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
670
                dc->pc, b0, b1, b2, __FILE__, __LINE__); \
671
        goto invalid_opcode; \
672
    } while (0)
673

    
674

    
675
#ifdef TARGET_WORDS_BIGENDIAN
676
#define OP0 (((b0) & 0xf0) >> 4)
677
#define OP1 (((b2) & 0xf0) >> 4)
678
#define OP2 ((b2) & 0xf)
679
#define RRR_R ((b1) & 0xf)
680
#define RRR_S (((b1) & 0xf0) >> 4)
681
#define RRR_T ((b0) & 0xf)
682
#else
683
#define OP0 (((b0) & 0xf))
684
#define OP1 (((b2) & 0xf))
685
#define OP2 (((b2) & 0xf0) >> 4)
686
#define RRR_R (((b1) & 0xf0) >> 4)
687
#define RRR_S (((b1) & 0xf))
688
#define RRR_T (((b0) & 0xf0) >> 4)
689
#endif
690
#define RRR_X ((RRR_R & 0x4) >> 2)
691
#define RRR_Y ((RRR_T & 0x4) >> 2)
692
#define RRR_W (RRR_R & 0x3)
693

    
694
#define RRRN_R RRR_R
695
#define RRRN_S RRR_S
696
#define RRRN_T RRR_T
697

    
698
#define RRI8_R RRR_R
699
#define RRI8_S RRR_S
700
#define RRI8_T RRR_T
701
#define RRI8_IMM8 (b2)
702
#define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)
703

    
704
#ifdef TARGET_WORDS_BIGENDIAN
705
#define RI16_IMM16 (((b1) << 8) | (b2))
706
#else
707
#define RI16_IMM16 (((b2) << 8) | (b1))
708
#endif
709

    
710
#ifdef TARGET_WORDS_BIGENDIAN
711
#define CALL_N (((b0) & 0xc) >> 2)
712
#define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))
713
#else
714
#define CALL_N (((b0) & 0x30) >> 4)
715
#define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))
716
#endif
717
#define CALL_OFFSET_SE \
718
    (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)
719

    
720
#define CALLX_N CALL_N
721
#ifdef TARGET_WORDS_BIGENDIAN
722
#define CALLX_M ((b0) & 0x3)
723
#else
724
#define CALLX_M (((b0) & 0xc0) >> 6)
725
#endif
726
#define CALLX_S RRR_S
727

    
728
#define BRI12_M CALLX_M
729
#define BRI12_S RRR_S
730
#ifdef TARGET_WORDS_BIGENDIAN
731
#define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))
732
#else
733
#define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))
734
#endif
735
#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)
736

    
737
#define BRI8_M BRI12_M
738
#define BRI8_R RRI8_R
739
#define BRI8_S RRI8_S
740
#define BRI8_IMM8 RRI8_IMM8
741
#define BRI8_IMM8_SE RRI8_IMM8_SE
742

    
743
#define RSR_SR (b1)
744

    
745
    uint8_t b0 = ldub_code(dc->pc);
746
    uint8_t b1 = ldub_code(dc->pc + 1);
747
    uint8_t b2 = ldub_code(dc->pc + 2);
748

    
749
    static const uint32_t B4CONST[] = {
750
        0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
751
    };
752

    
753
    static const uint32_t B4CONSTU[] = {
754
        32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
755
    };
756

    
757
    if (OP0 >= 8) {
758
        dc->next_pc = dc->pc + 2;
759
        HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
760
    } else {
761
        dc->next_pc = dc->pc + 3;
762
    }
763

    
764
    switch (OP0) {
765
    case 0: /*QRST*/
766
        switch (OP1) {
767
        case 0: /*RST0*/
768
            switch (OP2) {
769
            case 0: /*ST0*/
770
                if ((RRR_R & 0xc) == 0x8) {
771
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
772
                }
773

    
774
                switch (RRR_R) {
775
                case 0: /*SNM0*/
776
                    switch (CALLX_M) {
777
                    case 0: /*ILL*/
778
                        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
779
                        break;
780

    
781
                    case 1: /*reserved*/
782
                        RESERVED();
783
                        break;
784

    
785
                    case 2: /*JR*/
786
                        switch (CALLX_N) {
787
                        case 0: /*RET*/
788
                        case 2: /*JX*/
789
                            gen_window_check1(dc, CALLX_S);
790
                            gen_jump(dc, cpu_R[CALLX_S]);
791
                            break;
792

    
793
                        case 1: /*RETWw*/
794
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
795
                            {
796
                                TCGv_i32 tmp = tcg_const_i32(dc->pc);
797
                                gen_advance_ccount(dc);
798
                                gen_helper_retw(tmp, tmp);
799
                                gen_jump(dc, tmp);
800
                                tcg_temp_free(tmp);
801
                            }
802
                            break;
803

    
804
                        case 3: /*reserved*/
805
                            RESERVED();
806
                            break;
807
                        }
808
                        break;
809

    
810
                    case 3: /*CALLX*/
811
                        gen_window_check2(dc, CALLX_S, CALLX_N << 2);
812
                        switch (CALLX_N) {
813
                        case 0: /*CALLX0*/
814
                            {
815
                                TCGv_i32 tmp = tcg_temp_new_i32();
816
                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
817
                                tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
818
                                gen_jump(dc, tmp);
819
                                tcg_temp_free(tmp);
820
                            }
821
                            break;
822

    
823
                        case 1: /*CALLX4w*/
824
                        case 2: /*CALLX8w*/
825
                        case 3: /*CALLX12w*/
826
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
827
                            {
828
                                TCGv_i32 tmp = tcg_temp_new_i32();
829

    
830
                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
831
                                gen_callw(dc, CALLX_N, tmp);
832
                                tcg_temp_free(tmp);
833
                            }
834
                            break;
835
                        }
836
                        break;
837
                    }
838
                    break;
839

    
840
                case 1: /*MOVSPw*/
841
                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
842
                    gen_window_check2(dc, RRR_T, RRR_S);
843
                    {
844
                        TCGv_i32 pc = tcg_const_i32(dc->pc);
845
                        gen_advance_ccount(dc);
846
                        gen_helper_movsp(pc);
847
                        tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]);
848
                        tcg_temp_free(pc);
849
                    }
850
                    break;
851

    
852
                case 2: /*SYNC*/
853
                    switch (RRR_T) {
854
                    case 0: /*ISYNC*/
855
                        break;
856

    
857
                    case 1: /*RSYNC*/
858
                        break;
859

    
860
                    case 2: /*ESYNC*/
861
                        break;
862

    
863
                    case 3: /*DSYNC*/
864
                        break;
865

    
866
                    case 8: /*EXCW*/
867
                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);
868
                        break;
869

    
870
                    case 12: /*MEMW*/
871
                        break;
872

    
873
                    case 13: /*EXTW*/
874
                        break;
875

    
876
                    case 15: /*NOP*/
877
                        break;
878

    
879
                    default: /*reserved*/
880
                        RESERVED();
881
                        break;
882
                    }
883
                    break;
884

    
885
                case 3: /*RFEIx*/
886
                    switch (RRR_T) {
887
                    case 0: /*RFETx*/
888
                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);
889
                        switch (RRR_S) {
890
                        case 0: /*RFEx*/
891
                            gen_check_privilege(dc);
892
                            tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
893
                            gen_helper_check_interrupts(cpu_env);
894
                            gen_jump(dc, cpu_SR[EPC1]);
895
                            break;
896

    
897
                        case 1: /*RFUEx*/
898
                            RESERVED();
899
                            break;
900

    
901
                        case 2: /*RFDEx*/
902
                            gen_check_privilege(dc);
903
                            gen_jump(dc, cpu_SR[
904
                                    dc->config->ndepc ? DEPC : EPC1]);
905
                            break;
906

    
907
                        case 4: /*RFWOw*/
908
                        case 5: /*RFWUw*/
909
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
910
                            gen_check_privilege(dc);
911
                            {
912
                                TCGv_i32 tmp = tcg_const_i32(1);
913

    
914
                                tcg_gen_andi_i32(
915
                                        cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
916
                                tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
917

    
918
                                if (RRR_S == 4) {
919
                                    tcg_gen_andc_i32(cpu_SR[WINDOW_START],
920
                                            cpu_SR[WINDOW_START], tmp);
921
                                } else {
922
                                    tcg_gen_or_i32(cpu_SR[WINDOW_START],
923
                                            cpu_SR[WINDOW_START], tmp);
924
                                }
925

    
926
                                gen_helper_restore_owb();
927
                                gen_helper_check_interrupts(cpu_env);
928
                                gen_jump(dc, cpu_SR[EPC1]);
929

    
930
                                tcg_temp_free(tmp);
931
                            }
932
                            break;
933

    
934
                        default: /*reserved*/
935
                            RESERVED();
936
                            break;
937
                        }
938
                        break;
939

    
940
                    case 1: /*RFIx*/
941
                        HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT);
942
                        if (RRR_S >= 2 && RRR_S <= dc->config->nlevel) {
943
                            gen_check_privilege(dc);
944
                            tcg_gen_mov_i32(cpu_SR[PS],
945
                                    cpu_SR[EPS2 + RRR_S - 2]);
946
                            gen_helper_check_interrupts(cpu_env);
947
                            gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]);
948
                        } else {
949
                            qemu_log("RFI %d is illegal\n", RRR_S);
950
                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
951
                        }
952
                        break;
953

    
954
                    case 2: /*RFME*/
955
                        TBD();
956
                        break;
957

    
958
                    default: /*reserved*/
959
                        RESERVED();
960
                        break;
961

    
962
                    }
963
                    break;
964

    
965
                case 4: /*BREAKx*/
966
                    HAS_OPTION(XTENSA_OPTION_EXCEPTION);
967
                    TBD();
968
                    break;
969

    
970
                case 5: /*SYSCALLx*/
971
                    HAS_OPTION(XTENSA_OPTION_EXCEPTION);
972
                    switch (RRR_S) {
973
                    case 0: /*SYSCALLx*/
974
                        gen_exception_cause(dc, SYSCALL_CAUSE);
975
                        break;
976

    
977
                    case 1: /*SIMCALL*/
978
                        if (semihosting_enabled) {
979
                            gen_check_privilege(dc);
980
                            gen_helper_simcall(cpu_env);
981
                        } else {
982
                            qemu_log("SIMCALL but semihosting is disabled\n");
983
                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
984
                        }
985
                        break;
986

    
987
                    default:
988
                        RESERVED();
989
                        break;
990
                    }
991
                    break;
992

    
993
                case 6: /*RSILx*/
994
                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);
995
                    gen_check_privilege(dc);
996
                    gen_window_check1(dc, RRR_T);
997
                    tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]);
998
                    tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
999
                    tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S);
1000
                    gen_helper_check_interrupts(cpu_env);
1001
                    gen_jumpi_check_loop_end(dc, 0);
1002
                    break;
1003

    
1004
                case 7: /*WAITIx*/
1005
                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);
1006
                    gen_check_privilege(dc);
1007
                    gen_waiti(dc, RRR_S);
1008
                    break;
1009

    
1010
                case 8: /*ANY4p*/
1011
                case 9: /*ALL4p*/
1012
                case 10: /*ANY8p*/
1013
                case 11: /*ALL8p*/
1014
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1015
                    {
1016
                        const unsigned shift = (RRR_R & 2) ? 8 : 4;
1017
                        TCGv_i32 mask = tcg_const_i32(
1018
                                ((1 << shift) - 1) << RRR_S);
1019
                        TCGv_i32 tmp = tcg_temp_new_i32();
1020

    
1021
                        tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
1022
                        if (RRR_R & 1) { /*ALL*/
1023
                            tcg_gen_addi_i32(tmp, tmp, 1 << RRR_S);
1024
                        } else { /*ANY*/
1025
                            tcg_gen_add_i32(tmp, tmp, mask);
1026
                        }
1027
                        tcg_gen_shri_i32(tmp, tmp, RRR_S + shift);
1028
                        tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
1029
                                tmp, RRR_T, 1);
1030
                        tcg_temp_free(mask);
1031
                        tcg_temp_free(tmp);
1032
                    }
1033
                    break;
1034

    
1035
                default: /*reserved*/
1036
                    RESERVED();
1037
                    break;
1038

    
1039
                }
1040
                break;
1041

    
1042
            case 1: /*AND*/
1043
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1044
                tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1045
                break;
1046

    
1047
            case 2: /*OR*/
1048
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1049
                tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1050
                break;
1051

    
1052
            case 3: /*XOR*/
1053
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1054
                tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1055
                break;
1056

    
1057
            case 4: /*ST1*/
1058
                switch (RRR_R) {
1059
                case 0: /*SSR*/
1060
                    gen_window_check1(dc, RRR_S);
1061
                    gen_right_shift_sar(dc, cpu_R[RRR_S]);
1062
                    break;
1063

    
1064
                case 1: /*SSL*/
1065
                    gen_window_check1(dc, RRR_S);
1066
                    gen_left_shift_sar(dc, cpu_R[RRR_S]);
1067
                    break;
1068

    
1069
                case 2: /*SSA8L*/
1070
                    gen_window_check1(dc, RRR_S);
1071
                    {
1072
                        TCGv_i32 tmp = tcg_temp_new_i32();
1073
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1074
                        gen_right_shift_sar(dc, tmp);
1075
                        tcg_temp_free(tmp);
1076
                    }
1077
                    break;
1078

    
1079
                case 3: /*SSA8B*/
1080
                    gen_window_check1(dc, RRR_S);
1081
                    {
1082
                        TCGv_i32 tmp = tcg_temp_new_i32();
1083
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1084
                        gen_left_shift_sar(dc, tmp);
1085
                        tcg_temp_free(tmp);
1086
                    }
1087
                    break;
1088

    
1089
                case 4: /*SSAI*/
1090
                    {
1091
                        TCGv_i32 tmp = tcg_const_i32(
1092
                                RRR_S | ((RRR_T & 1) << 4));
1093
                        gen_right_shift_sar(dc, tmp);
1094
                        tcg_temp_free(tmp);
1095
                    }
1096
                    break;
1097

    
1098
                case 6: /*RER*/
1099
                    TBD();
1100
                    break;
1101

    
1102
                case 7: /*WER*/
1103
                    TBD();
1104
                    break;
1105

    
1106
                case 8: /*ROTWw*/
1107
                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1108
                    gen_check_privilege(dc);
1109
                    {
1110
                        TCGv_i32 tmp = tcg_const_i32(
1111
                                RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0));
1112
                        gen_helper_rotw(tmp);
1113
                        tcg_temp_free(tmp);
1114
                        reset_used_window(dc);
1115
                    }
1116
                    break;
1117

    
1118
                case 14: /*NSAu*/
1119
                    HAS_OPTION(XTENSA_OPTION_MISC_OP);
1120
                    gen_window_check2(dc, RRR_S, RRR_T);
1121
                    gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);
1122
                    break;
1123

    
1124
                case 15: /*NSAUu*/
1125
                    HAS_OPTION(XTENSA_OPTION_MISC_OP);
1126
                    gen_window_check2(dc, RRR_S, RRR_T);
1127
                    gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);
1128
                    break;
1129

    
1130
                default: /*reserved*/
1131
                    RESERVED();
1132
                    break;
1133
                }
1134
                break;
1135

    
1136
            case 5: /*TLB*/
1137
                HAS_OPTION_BITS(
1138
                        XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
1139
                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
1140
                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION));
1141
                gen_check_privilege(dc);
1142
                gen_window_check2(dc, RRR_S, RRR_T);
1143
                {
1144
                    TCGv_i32 dtlb = tcg_const_i32((RRR_R & 8) != 0);
1145

    
1146
                    switch (RRR_R & 7) {
1147
                    case 3: /*RITLB0*/ /*RDTLB0*/
1148
                        gen_helper_rtlb0(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1149
                        break;
1150

    
1151
                    case 4: /*IITLB*/ /*IDTLB*/
1152
                        gen_helper_itlb(cpu_R[RRR_S], dtlb);
1153
                        /* This could change memory mapping, so exit tb */
1154
                        gen_jumpi_check_loop_end(dc, -1);
1155
                        break;
1156

    
1157
                    case 5: /*PITLB*/ /*PDTLB*/
1158
                        tcg_gen_movi_i32(cpu_pc, dc->pc);
1159
                        gen_helper_ptlb(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1160
                        break;
1161

    
1162
                    case 6: /*WITLB*/ /*WDTLB*/
1163
                        gen_helper_wtlb(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1164
                        /* This could change memory mapping, so exit tb */
1165
                        gen_jumpi_check_loop_end(dc, -1);
1166
                        break;
1167

    
1168
                    case 7: /*RITLB1*/ /*RDTLB1*/
1169
                        gen_helper_rtlb1(cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1170
                        break;
1171

    
1172
                    default:
1173
                        tcg_temp_free(dtlb);
1174
                        RESERVED();
1175
                        break;
1176
                    }
1177
                    tcg_temp_free(dtlb);
1178
                }
1179
                break;
1180

    
1181
            case 6: /*RT0*/
1182
                gen_window_check2(dc, RRR_R, RRR_T);
1183
                switch (RRR_S) {
1184
                case 0: /*NEG*/
1185
                    tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1186
                    break;
1187

    
1188
                case 1: /*ABS*/
1189
                    {
1190
                        int label = gen_new_label();
1191
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1192
                        tcg_gen_brcondi_i32(
1193
                                TCG_COND_GE, cpu_R[RRR_R], 0, label);
1194
                        tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1195
                        gen_set_label(label);
1196
                    }
1197
                    break;
1198

    
1199
                default: /*reserved*/
1200
                    RESERVED();
1201
                    break;
1202
                }
1203
                break;
1204

    
1205
            case 7: /*reserved*/
1206
                RESERVED();
1207
                break;
1208

    
1209
            case 8: /*ADD*/
1210
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1211
                tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1212
                break;
1213

    
1214
            case 9: /*ADD**/
1215
            case 10:
1216
            case 11:
1217
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1218
                {
1219
                    TCGv_i32 tmp = tcg_temp_new_i32();
1220
                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);
1221
                    tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1222
                    tcg_temp_free(tmp);
1223
                }
1224
                break;
1225

    
1226
            case 12: /*SUB*/
1227
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1228
                tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1229
                break;
1230

    
1231
            case 13: /*SUB**/
1232
            case 14:
1233
            case 15:
1234
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1235
                {
1236
                    TCGv_i32 tmp = tcg_temp_new_i32();
1237
                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);
1238
                    tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1239
                    tcg_temp_free(tmp);
1240
                }
1241
                break;
1242
            }
1243
            break;
1244

    
1245
        case 1: /*RST1*/
1246
            switch (OP2) {
1247
            case 0: /*SLLI*/
1248
            case 1:
1249
                gen_window_check2(dc, RRR_R, RRR_S);
1250
                tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],
1251
                        32 - (RRR_T | ((OP2 & 1) << 4)));
1252
                break;
1253

    
1254
            case 2: /*SRAI*/
1255
            case 3:
1256
                gen_window_check2(dc, RRR_R, RRR_T);
1257
                tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],
1258
                        RRR_S | ((OP2 & 1) << 4));
1259
                break;
1260

    
1261
            case 4: /*SRLI*/
1262
                gen_window_check2(dc, RRR_R, RRR_T);
1263
                tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);
1264
                break;
1265

    
1266
            case 6: /*XSR*/
1267
                {
1268
                    TCGv_i32 tmp = tcg_temp_new_i32();
1269
                    if (RSR_SR >= 64) {
1270
                        gen_check_privilege(dc);
1271
                    }
1272
                    gen_window_check1(dc, RRR_T);
1273
                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
1274
                    gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1275
                    gen_wsr(dc, RSR_SR, tmp);
1276
                    tcg_temp_free(tmp);
1277
                    if (!sregnames[RSR_SR]) {
1278
                        TBD();
1279
                    }
1280
                }
1281
                break;
1282

    
1283
                /*
1284
                 * Note: 64 bit ops are used here solely because SAR values
1285
                 * have range 0..63
1286
                 */
1287
#define gen_shift_reg(cmd, reg) do { \
1288
                    TCGv_i64 tmp = tcg_temp_new_i64(); \
1289
                    tcg_gen_extu_i32_i64(tmp, reg); \
1290
                    tcg_gen_##cmd##_i64(v, v, tmp); \
1291
                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
1292
                    tcg_temp_free_i64(v); \
1293
                    tcg_temp_free_i64(tmp); \
1294
                } while (0)
1295

    
1296
#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
1297

    
1298
            case 8: /*SRC*/
1299
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1300
                {
1301
                    TCGv_i64 v = tcg_temp_new_i64();
1302
                    tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);
1303
                    gen_shift(shr);
1304
                }
1305
                break;
1306

    
1307
            case 9: /*SRL*/
1308
                gen_window_check2(dc, RRR_R, RRR_T);
1309
                if (dc->sar_5bit) {
1310
                    tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1311
                } else {
1312
                    TCGv_i64 v = tcg_temp_new_i64();
1313
                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);
1314
                    gen_shift(shr);
1315
                }
1316
                break;
1317

    
1318
            case 10: /*SLL*/
1319
                gen_window_check2(dc, RRR_R, RRR_S);
1320
                if (dc->sar_m32_5bit) {
1321
                    tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);
1322
                } else {
1323
                    TCGv_i64 v = tcg_temp_new_i64();
1324
                    TCGv_i32 s = tcg_const_i32(32);
1325
                    tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
1326
                    tcg_gen_andi_i32(s, s, 0x3f);
1327
                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);
1328
                    gen_shift_reg(shl, s);
1329
                    tcg_temp_free(s);
1330
                }
1331
                break;
1332

    
1333
            case 11: /*SRA*/
1334
                gen_window_check2(dc, RRR_R, RRR_T);
1335
                if (dc->sar_5bit) {
1336
                    tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1337
                } else {
1338
                    TCGv_i64 v = tcg_temp_new_i64();
1339
                    tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);
1340
                    gen_shift(sar);
1341
                }
1342
                break;
1343
#undef gen_shift
1344
#undef gen_shift_reg
1345

    
1346
            case 12: /*MUL16U*/
1347
                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1348
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1349
                {
1350
                    TCGv_i32 v1 = tcg_temp_new_i32();
1351
                    TCGv_i32 v2 = tcg_temp_new_i32();
1352
                    tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);
1353
                    tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);
1354
                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1355
                    tcg_temp_free(v2);
1356
                    tcg_temp_free(v1);
1357
                }
1358
                break;
1359

    
1360
            case 13: /*MUL16S*/
1361
                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1362
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1363
                {
1364
                    TCGv_i32 v1 = tcg_temp_new_i32();
1365
                    TCGv_i32 v2 = tcg_temp_new_i32();
1366
                    tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);
1367
                    tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);
1368
                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1369
                    tcg_temp_free(v2);
1370
                    tcg_temp_free(v1);
1371
                }
1372
                break;
1373

    
1374
            default: /*reserved*/
1375
                RESERVED();
1376
                break;
1377
            }
1378
            break;
1379

    
1380
        case 2: /*RST2*/
1381
            if (OP2 >= 8) {
1382
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1383
            }
1384

    
1385
            if (OP2 >= 12) {
1386
                HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV);
1387
                int label = gen_new_label();
1388
                tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label);
1389
                gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
1390
                gen_set_label(label);
1391
            }
1392

    
1393
            switch (OP2) {
1394
#define BOOLEAN_LOGIC(fn, r, s, t) \
1395
                do { \
1396
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN); \
1397
                    TCGv_i32 tmp1 = tcg_temp_new_i32(); \
1398
                    TCGv_i32 tmp2 = tcg_temp_new_i32(); \
1399
                    \
1400
                    tcg_gen_shri_i32(tmp1, cpu_SR[BR], s); \
1401
                    tcg_gen_shri_i32(tmp2, cpu_SR[BR], t); \
1402
                    tcg_gen_##fn##_i32(tmp1, tmp1, tmp2); \
1403
                    tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, r, 1); \
1404
                    tcg_temp_free(tmp1); \
1405
                    tcg_temp_free(tmp2); \
1406
                } while (0)
1407

    
1408
            case 0: /*ANDBp*/
1409
                BOOLEAN_LOGIC(and, RRR_R, RRR_S, RRR_T);
1410
                break;
1411

    
1412
            case 1: /*ANDBCp*/
1413
                BOOLEAN_LOGIC(andc, RRR_R, RRR_S, RRR_T);
1414
                break;
1415

    
1416
            case 2: /*ORBp*/
1417
                BOOLEAN_LOGIC(or, RRR_R, RRR_S, RRR_T);
1418
                break;
1419

    
1420
            case 3: /*ORBCp*/
1421
                BOOLEAN_LOGIC(orc, RRR_R, RRR_S, RRR_T);
1422
                break;
1423

    
1424
            case 4: /*XORBp*/
1425
                BOOLEAN_LOGIC(xor, RRR_R, RRR_S, RRR_T);
1426
                break;
1427

    
1428
#undef BOOLEAN_LOGIC
1429

    
1430
            case 8: /*MULLi*/
1431
                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
1432
                tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1433
                break;
1434

    
1435
            case 10: /*MULUHi*/
1436
            case 11: /*MULSHi*/
1437
                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
1438
                {
1439
                    TCGv_i64 r = tcg_temp_new_i64();
1440
                    TCGv_i64 s = tcg_temp_new_i64();
1441
                    TCGv_i64 t = tcg_temp_new_i64();
1442

    
1443
                    if (OP2 == 10) {
1444
                        tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);
1445
                        tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);
1446
                    } else {
1447
                        tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);
1448
                        tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);
1449
                    }
1450
                    tcg_gen_mul_i64(r, s, t);
1451
                    tcg_gen_shri_i64(r, r, 32);
1452
                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);
1453

    
1454
                    tcg_temp_free_i64(r);
1455
                    tcg_temp_free_i64(s);
1456
                    tcg_temp_free_i64(t);
1457
                }
1458
                break;
1459

    
1460
            case 12: /*QUOUi*/
1461
                tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1462
                break;
1463

    
1464
            case 13: /*QUOSi*/
1465
            case 15: /*REMSi*/
1466
                {
1467
                    int label1 = gen_new_label();
1468
                    int label2 = gen_new_label();
1469

    
1470
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000,
1471
                            label1);
1472
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff,
1473
                            label1);
1474
                    tcg_gen_movi_i32(cpu_R[RRR_R],
1475
                            OP2 == 13 ? 0x80000000 : 0);
1476
                    tcg_gen_br(label2);
1477
                    gen_set_label(label1);
1478
                    if (OP2 == 13) {
1479
                        tcg_gen_div_i32(cpu_R[RRR_R],
1480
                                cpu_R[RRR_S], cpu_R[RRR_T]);
1481
                    } else {
1482
                        tcg_gen_rem_i32(cpu_R[RRR_R],
1483
                                cpu_R[RRR_S], cpu_R[RRR_T]);
1484
                    }
1485
                    gen_set_label(label2);
1486
                }
1487
                break;
1488

    
1489
            case 14: /*REMUi*/
1490
                tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1491
                break;
1492

    
1493
            default: /*reserved*/
1494
                RESERVED();
1495
                break;
1496
            }
1497
            break;
1498

    
1499
        case 3: /*RST3*/
1500
            switch (OP2) {
1501
            case 0: /*RSR*/
1502
                if (RSR_SR >= 64) {
1503
                    gen_check_privilege(dc);
1504
                }
1505
                gen_window_check1(dc, RRR_T);
1506
                gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1507
                if (!sregnames[RSR_SR]) {
1508
                    TBD();
1509
                }
1510
                break;
1511

    
1512
            case 1: /*WSR*/
1513
                if (RSR_SR >= 64) {
1514
                    gen_check_privilege(dc);
1515
                }
1516
                gen_window_check1(dc, RRR_T);
1517
                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
1518
                if (!sregnames[RSR_SR]) {
1519
                    TBD();
1520
                }
1521
                break;
1522

    
1523
            case 2: /*SEXTu*/
1524
                HAS_OPTION(XTENSA_OPTION_MISC_OP);
1525
                gen_window_check2(dc, RRR_R, RRR_S);
1526
                {
1527
                    int shift = 24 - RRR_T;
1528

    
1529
                    if (shift == 24) {
1530
                        tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1531
                    } else if (shift == 16) {
1532
                        tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1533
                    } else {
1534
                        TCGv_i32 tmp = tcg_temp_new_i32();
1535
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);
1536
                        tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);
1537
                        tcg_temp_free(tmp);
1538
                    }
1539
                }
1540
                break;
1541

    
1542
            case 3: /*CLAMPSu*/
1543
                HAS_OPTION(XTENSA_OPTION_MISC_OP);
1544
                gen_window_check2(dc, RRR_R, RRR_S);
1545
                {
1546
                    TCGv_i32 tmp1 = tcg_temp_new_i32();
1547
                    TCGv_i32 tmp2 = tcg_temp_new_i32();
1548
                    int label = gen_new_label();
1549

    
1550
                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
1551
                    tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
1552
                    tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
1553
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1554
                    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
1555

    
1556
                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
1557
                    tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
1558
                            0xffffffff >> (25 - RRR_T));
1559

    
1560
                    gen_set_label(label);
1561

    
1562
                    tcg_temp_free(tmp1);
1563
                    tcg_temp_free(tmp2);
1564
                }
1565
                break;
1566

    
1567
            case 4: /*MINu*/
1568
            case 5: /*MAXu*/
1569
            case 6: /*MINUu*/
1570
            case 7: /*MAXUu*/
1571
                HAS_OPTION(XTENSA_OPTION_MISC_OP);
1572
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1573
                {
1574
                    static const TCGCond cond[] = {
1575
                        TCG_COND_LE,
1576
                        TCG_COND_GE,
1577
                        TCG_COND_LEU,
1578
                        TCG_COND_GEU
1579
                    };
1580
                    int label = gen_new_label();
1581

    
1582
                    if (RRR_R != RRR_T) {
1583
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1584
                        tcg_gen_brcond_i32(cond[OP2 - 4],
1585
                                cpu_R[RRR_S], cpu_R[RRR_T], label);
1586
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1587
                    } else {
1588
                        tcg_gen_brcond_i32(cond[OP2 - 4],
1589
                                cpu_R[RRR_T], cpu_R[RRR_S], label);
1590
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1591
                    }
1592
                    gen_set_label(label);
1593
                }
1594
                break;
1595

    
1596
            case 8: /*MOVEQZ*/
1597
            case 9: /*MOVNEZ*/
1598
            case 10: /*MOVLTZ*/
1599
            case 11: /*MOVGEZ*/
1600
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1601
                {
1602
                    static const TCGCond cond[] = {
1603
                        TCG_COND_NE,
1604
                        TCG_COND_EQ,
1605
                        TCG_COND_GE,
1606
                        TCG_COND_LT
1607
                    };
1608
                    int label = gen_new_label();
1609
                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
1610
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1611
                    gen_set_label(label);
1612
                }
1613
                break;
1614

    
1615
            case 12: /*MOVFp*/
1616
            case 13: /*MOVTp*/
1617
                HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1618
                gen_window_check2(dc, RRR_R, RRR_S);
1619
                {
1620
                    int label = gen_new_label();
1621
                    TCGv_i32 tmp = tcg_temp_new_i32();
1622

    
1623
                    tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
1624
                    tcg_gen_brcondi_i32(
1625
                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
1626
                            tmp, 0, label);
1627
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1628
                    gen_set_label(label);
1629
                    tcg_temp_free(tmp);
1630
                }
1631
                break;
1632

    
1633
            case 14: /*RUR*/
1634
                gen_window_check1(dc, RRR_R);
1635
                {
1636
                    int st = (RRR_S << 4) + RRR_T;
1637
                    if (uregnames[st]) {
1638
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
1639
                    } else {
1640
                        qemu_log("RUR %d not implemented, ", st);
1641
                        TBD();
1642
                    }
1643
                }
1644
                break;
1645

    
1646
            case 15: /*WUR*/
1647
                gen_window_check1(dc, RRR_T);
1648
                {
1649
                    if (uregnames[RSR_SR]) {
1650
                        tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);
1651
                    } else {
1652
                        qemu_log("WUR %d not implemented, ", RSR_SR);
1653
                        TBD();
1654
                    }
1655
                }
1656
                break;
1657

    
1658
            }
1659
            break;
1660

    
1661
        case 4: /*EXTUI*/
1662
        case 5:
1663
            gen_window_check2(dc, RRR_R, RRR_T);
1664
            {
1665
                int shiftimm = RRR_S | (OP1 << 4);
1666
                int maskimm = (1 << (OP2 + 1)) - 1;
1667

    
1668
                TCGv_i32 tmp = tcg_temp_new_i32();
1669
                tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
1670
                tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
1671
                tcg_temp_free(tmp);
1672
            }
1673
            break;
1674

    
1675
        case 6: /*CUST0*/
1676
            RESERVED();
1677
            break;
1678

    
1679
        case 7: /*CUST1*/
1680
            RESERVED();
1681
            break;
1682

    
1683
        case 8: /*LSCXp*/
1684
            HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
1685
            TBD();
1686
            break;
1687

    
1688
        case 9: /*LSC4*/
1689
            gen_window_check2(dc, RRR_S, RRR_T);
1690
            switch (OP2) {
1691
            case 0: /*L32E*/
1692
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1693
                gen_check_privilege(dc);
1694
                {
1695
                    TCGv_i32 addr = tcg_temp_new_i32();
1696
                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1697
                            (0xffffffc0 | (RRR_R << 2)));
1698
                    tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring);
1699
                    tcg_temp_free(addr);
1700
                }
1701
                break;
1702

    
1703
            case 4: /*S32E*/
1704
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1705
                gen_check_privilege(dc);
1706
                {
1707
                    TCGv_i32 addr = tcg_temp_new_i32();
1708
                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1709
                            (0xffffffc0 | (RRR_R << 2)));
1710
                    tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring);
1711
                    tcg_temp_free(addr);
1712
                }
1713
                break;
1714

    
1715
            default:
1716
                RESERVED();
1717
                break;
1718
            }
1719
            break;
1720

    
1721
        case 10: /*FP0*/
1722
            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1723
            TBD();
1724
            break;
1725

    
1726
        case 11: /*FP1*/
1727
            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1728
            TBD();
1729
            break;
1730

    
1731
        default: /*reserved*/
1732
            RESERVED();
1733
            break;
1734
        }
1735
        break;
1736

    
1737
    case 1: /*L32R*/
1738
        gen_window_check1(dc, RRR_T);
1739
        {
1740
            TCGv_i32 tmp = tcg_const_i32(
1741
                    ((dc->tb->flags & XTENSA_TBFLAG_LITBASE) ?
1742
                     0 : ((dc->pc + 3) & ~3)) +
1743
                    (0xfffc0000 | (RI16_IMM16 << 2)));
1744

    
1745
            if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
1746
                tcg_gen_add_i32(tmp, tmp, dc->litbase);
1747
            }
1748
            tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring);
1749
            tcg_temp_free(tmp);
1750
        }
1751
        break;
1752

    
1753
    case 2: /*LSAI*/
1754
#define gen_load_store(type, shift) do { \
1755
            TCGv_i32 addr = tcg_temp_new_i32(); \
1756
            gen_window_check2(dc, RRI8_S, RRI8_T); \
1757
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
1758
            if (shift) { \
1759
                gen_load_store_alignment(dc, shift, addr, false); \
1760
            } \
1761
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1762
            tcg_temp_free(addr); \
1763
        } while (0)
1764

    
1765
        switch (RRI8_R) {
1766
        case 0: /*L8UI*/
1767
            gen_load_store(ld8u, 0);
1768
            break;
1769

    
1770
        case 1: /*L16UI*/
1771
            gen_load_store(ld16u, 1);
1772
            break;
1773

    
1774
        case 2: /*L32I*/
1775
            gen_load_store(ld32u, 2);
1776
            break;
1777

    
1778
        case 4: /*S8I*/
1779
            gen_load_store(st8, 0);
1780
            break;
1781

    
1782
        case 5: /*S16I*/
1783
            gen_load_store(st16, 1);
1784
            break;
1785

    
1786
        case 6: /*S32I*/
1787
            gen_load_store(st32, 2);
1788
            break;
1789

    
1790
        case 7: /*CACHEc*/
1791
            if (RRI8_T < 8) {
1792
                HAS_OPTION(XTENSA_OPTION_DCACHE);
1793
            }
1794

    
1795
            switch (RRI8_T) {
1796
            case 0: /*DPFRc*/
1797
                break;
1798

    
1799
            case 1: /*DPFWc*/
1800
                break;
1801

    
1802
            case 2: /*DPFROc*/
1803
                break;
1804

    
1805
            case 3: /*DPFWOc*/
1806
                break;
1807

    
1808
            case 4: /*DHWBc*/
1809
                break;
1810

    
1811
            case 5: /*DHWBIc*/
1812
                break;
1813

    
1814
            case 6: /*DHIc*/
1815
                break;
1816

    
1817
            case 7: /*DIIc*/
1818
                break;
1819

    
1820
            case 8: /*DCEc*/
1821
                switch (OP1) {
1822
                case 0: /*DPFLl*/
1823
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1824
                    break;
1825

    
1826
                case 2: /*DHUl*/
1827
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1828
                    break;
1829

    
1830
                case 3: /*DIUl*/
1831
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
1832
                    break;
1833

    
1834
                case 4: /*DIWBc*/
1835
                    HAS_OPTION(XTENSA_OPTION_DCACHE);
1836
                    break;
1837

    
1838
                case 5: /*DIWBIc*/
1839
                    HAS_OPTION(XTENSA_OPTION_DCACHE);
1840
                    break;
1841

    
1842
                default: /*reserved*/
1843
                    RESERVED();
1844
                    break;
1845

    
1846
                }
1847
                break;
1848

    
1849
            case 12: /*IPFc*/
1850
                HAS_OPTION(XTENSA_OPTION_ICACHE);
1851
                break;
1852

    
1853
            case 13: /*ICEc*/
1854
                switch (OP1) {
1855
                case 0: /*IPFLl*/
1856
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1857
                    break;
1858

    
1859
                case 2: /*IHUl*/
1860
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1861
                    break;
1862

    
1863
                case 3: /*IIUl*/
1864
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
1865
                    break;
1866

    
1867
                default: /*reserved*/
1868
                    RESERVED();
1869
                    break;
1870
                }
1871
                break;
1872

    
1873
            case 14: /*IHIc*/
1874
                HAS_OPTION(XTENSA_OPTION_ICACHE);
1875
                break;
1876

    
1877
            case 15: /*IIIc*/
1878
                HAS_OPTION(XTENSA_OPTION_ICACHE);
1879
                break;
1880

    
1881
            default: /*reserved*/
1882
                RESERVED();
1883
                break;
1884
            }
1885
            break;
1886

    
1887
        case 9: /*L16SI*/
1888
            gen_load_store(ld16s, 1);
1889
            break;
1890
#undef gen_load_store
1891

    
1892
        case 10: /*MOVI*/
1893
            gen_window_check1(dc, RRI8_T);
1894
            tcg_gen_movi_i32(cpu_R[RRI8_T],
1895
                    RRI8_IMM8 | (RRI8_S << 8) |
1896
                    ((RRI8_S & 0x8) ? 0xfffff000 : 0));
1897
            break;
1898

    
1899
#define gen_load_store_no_hw_align(type) do { \
1900
            TCGv_i32 addr = tcg_temp_local_new_i32(); \
1901
            gen_window_check2(dc, RRI8_S, RRI8_T); \
1902
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \
1903
            gen_load_store_alignment(dc, 2, addr, true); \
1904
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
1905
            tcg_temp_free(addr); \
1906
        } while (0)
1907

    
1908
        case 11: /*L32AIy*/
1909
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1910
            gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/
1911
            break;
1912

    
1913
        case 12: /*ADDI*/
1914
            gen_window_check2(dc, RRI8_S, RRI8_T);
1915
            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);
1916
            break;
1917

    
1918
        case 13: /*ADDMI*/
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 << 8);
1921
            break;
1922

    
1923
        case 14: /*S32C1Iy*/
1924
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1925
            gen_window_check2(dc, RRI8_S, RRI8_T);
1926
            {
1927
                int label = gen_new_label();
1928
                TCGv_i32 tmp = tcg_temp_local_new_i32();
1929
                TCGv_i32 addr = tcg_temp_local_new_i32();
1930

    
1931
                tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
1932
                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
1933
                gen_load_store_alignment(dc, 2, addr, true);
1934
                tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);
1935
                tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
1936
                        cpu_SR[SCOMPARE1], label);
1937

    
1938
                tcg_gen_qemu_st32(tmp, addr, dc->cring);
1939

    
1940
                gen_set_label(label);
1941
                tcg_temp_free(addr);
1942
                tcg_temp_free(tmp);
1943
            }
1944
            break;
1945

    
1946
        case 15: /*S32RIy*/
1947
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
1948
            gen_load_store_no_hw_align(st32); /*TODO release?*/
1949
            break;
1950
#undef gen_load_store_no_hw_align
1951

    
1952
        default: /*reserved*/
1953
            RESERVED();
1954
            break;
1955
        }
1956
        break;
1957

    
1958
    case 3: /*LSCIp*/
1959
        HAS_OPTION(XTENSA_OPTION_COPROCESSOR);
1960
        TBD();
1961
        break;
1962

    
1963
    case 4: /*MAC16d*/
1964
        HAS_OPTION(XTENSA_OPTION_MAC16);
1965
        {
1966
            enum {
1967
                MAC16_UMUL = 0x0,
1968
                MAC16_MUL  = 0x4,
1969
                MAC16_MULA = 0x8,
1970
                MAC16_MULS = 0xc,
1971
                MAC16_NONE = 0xf,
1972
            } op = OP1 & 0xc;
1973
            bool is_m1_sr = (OP2 & 0x3) == 2;
1974
            bool is_m2_sr = (OP2 & 0xc) == 0;
1975
            uint32_t ld_offset = 0;
1976

    
1977
            if (OP2 > 9) {
1978
                RESERVED();
1979
            }
1980

    
1981
            switch (OP2 & 2) {
1982
            case 0: /*MACI?/MACC?*/
1983
                is_m1_sr = true;
1984
                ld_offset = (OP2 & 1) ? -4 : 4;
1985

    
1986
                if (OP2 >= 8) { /*MACI/MACC*/
1987
                    if (OP1 == 0) { /*LDINC/LDDEC*/
1988
                        op = MAC16_NONE;
1989
                    } else {
1990
                        RESERVED();
1991
                    }
1992
                } else if (op != MAC16_MULA) { /*MULA.*.*.LDINC/LDDEC*/
1993
                    RESERVED();
1994
                }
1995
                break;
1996

    
1997
            case 2: /*MACD?/MACA?*/
1998
                if (op == MAC16_UMUL && OP2 != 7) { /*UMUL only in MACAA*/
1999
                    RESERVED();
2000
                }
2001
                break;
2002
            }
2003

    
2004
            if (op != MAC16_NONE) {
2005
                if (!is_m1_sr) {
2006
                    gen_window_check1(dc, RRR_S);
2007
                }
2008
                if (!is_m2_sr) {
2009
                    gen_window_check1(dc, RRR_T);
2010
                }
2011
            }
2012

    
2013
            {
2014
                TCGv_i32 vaddr = tcg_temp_new_i32();
2015
                TCGv_i32 mem32 = tcg_temp_new_i32();
2016

    
2017
                if (ld_offset) {
2018
                    gen_window_check1(dc, RRR_S);
2019
                    tcg_gen_addi_i32(vaddr, cpu_R[RRR_S], ld_offset);
2020
                    gen_load_store_alignment(dc, 2, vaddr, false);
2021
                    tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
2022
                }
2023
                if (op != MAC16_NONE) {
2024
                    TCGv_i32 m1 = gen_mac16_m(
2025
                            is_m1_sr ? cpu_SR[MR + RRR_X] : cpu_R[RRR_S],
2026
                            OP1 & 1, op == MAC16_UMUL);
2027
                    TCGv_i32 m2 = gen_mac16_m(
2028
                            is_m2_sr ? cpu_SR[MR + 2 + RRR_Y] : cpu_R[RRR_T],
2029
                            OP1 & 2, op == MAC16_UMUL);
2030

    
2031
                    if (op == MAC16_MUL || op == MAC16_UMUL) {
2032
                        tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
2033
                        if (op == MAC16_UMUL) {
2034
                            tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
2035
                        } else {
2036
                            tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
2037
                        }
2038
                    } else {
2039
                        TCGv_i32 res = tcg_temp_new_i32();
2040
                        TCGv_i64 res64 = tcg_temp_new_i64();
2041
                        TCGv_i64 tmp = tcg_temp_new_i64();
2042

    
2043
                        tcg_gen_mul_i32(res, m1, m2);
2044
                        tcg_gen_ext_i32_i64(res64, res);
2045
                        tcg_gen_concat_i32_i64(tmp,
2046
                                cpu_SR[ACCLO], cpu_SR[ACCHI]);
2047
                        if (op == MAC16_MULA) {
2048
                            tcg_gen_add_i64(tmp, tmp, res64);
2049
                        } else {
2050
                            tcg_gen_sub_i64(tmp, tmp, res64);
2051
                        }
2052
                        tcg_gen_trunc_i64_i32(cpu_SR[ACCLO], tmp);
2053
                        tcg_gen_shri_i64(tmp, tmp, 32);
2054
                        tcg_gen_trunc_i64_i32(cpu_SR[ACCHI], tmp);
2055
                        tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
2056

    
2057
                        tcg_temp_free(res);
2058
                        tcg_temp_free_i64(res64);
2059
                        tcg_temp_free_i64(tmp);
2060
                    }
2061
                    tcg_temp_free(m1);
2062
                    tcg_temp_free(m2);
2063
                }
2064
                if (ld_offset) {
2065
                    tcg_gen_mov_i32(cpu_R[RRR_S], vaddr);
2066
                    tcg_gen_mov_i32(cpu_SR[MR + RRR_W], mem32);
2067
                }
2068
                tcg_temp_free(vaddr);
2069
                tcg_temp_free(mem32);
2070
            }
2071
        }
2072
        break;
2073

    
2074
    case 5: /*CALLN*/
2075
        switch (CALL_N) {
2076
        case 0: /*CALL0*/
2077
            tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
2078
            gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2079
            break;
2080

    
2081
        case 1: /*CALL4w*/
2082
        case 2: /*CALL8w*/
2083
        case 3: /*CALL12w*/
2084
            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2085
            gen_window_check1(dc, CALL_N << 2);
2086
            gen_callwi(dc, CALL_N,
2087
                    (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2088
            break;
2089
        }
2090
        break;
2091

    
2092
    case 6: /*SI*/
2093
        switch (CALL_N) {
2094
        case 0: /*J*/
2095
            gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);
2096
            break;
2097

    
2098
        case 1: /*BZ*/
2099
            gen_window_check1(dc, BRI12_S);
2100
            {
2101
                static const TCGCond cond[] = {
2102
                    TCG_COND_EQ, /*BEQZ*/
2103
                    TCG_COND_NE, /*BNEZ*/
2104
                    TCG_COND_LT, /*BLTZ*/
2105
                    TCG_COND_GE, /*BGEZ*/
2106
                };
2107

    
2108
                gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,
2109
                        4 + BRI12_IMM12_SE);
2110
            }
2111
            break;
2112

    
2113
        case 2: /*BI0*/
2114
            gen_window_check1(dc, BRI8_S);
2115
            {
2116
                static const TCGCond cond[] = {
2117
                    TCG_COND_EQ, /*BEQI*/
2118
                    TCG_COND_NE, /*BNEI*/
2119
                    TCG_COND_LT, /*BLTI*/
2120
                    TCG_COND_GE, /*BGEI*/
2121
                };
2122

    
2123
                gen_brcondi(dc, cond[BRI8_M & 3],
2124
                        cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);
2125
            }
2126
            break;
2127

    
2128
        case 3: /*BI1*/
2129
            switch (BRI8_M) {
2130
            case 0: /*ENTRYw*/
2131
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2132
                {
2133
                    TCGv_i32 pc = tcg_const_i32(dc->pc);
2134
                    TCGv_i32 s = tcg_const_i32(BRI12_S);
2135
                    TCGv_i32 imm = tcg_const_i32(BRI12_IMM12);
2136
                    gen_advance_ccount(dc);
2137
                    gen_helper_entry(pc, s, imm);
2138
                    tcg_temp_free(imm);
2139
                    tcg_temp_free(s);
2140
                    tcg_temp_free(pc);
2141
                    reset_used_window(dc);
2142
                }
2143
                break;
2144

    
2145
            case 1: /*B1*/
2146
                switch (BRI8_R) {
2147
                case 0: /*BFp*/
2148
                case 1: /*BTp*/
2149
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
2150
                    {
2151
                        TCGv_i32 tmp = tcg_temp_new_i32();
2152
                        tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRI8_S);
2153
                        gen_brcondi(dc,
2154
                                BRI8_R == 1 ? TCG_COND_NE : TCG_COND_EQ,
2155
                                tmp, 0, 4 + RRI8_IMM8_SE);
2156
                        tcg_temp_free(tmp);
2157
                    }
2158
                    break;
2159

    
2160
                case 8: /*LOOP*/
2161
                case 9: /*LOOPNEZ*/
2162
                case 10: /*LOOPGTZ*/
2163
                    HAS_OPTION(XTENSA_OPTION_LOOP);
2164
                    gen_window_check1(dc, RRI8_S);
2165
                    {
2166
                        uint32_t lend = dc->pc + RRI8_IMM8 + 4;
2167
                        TCGv_i32 tmp = tcg_const_i32(lend);
2168

    
2169
                        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);
2170
                        tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
2171
                        gen_wsr_lend(dc, LEND, tmp);
2172
                        tcg_temp_free(tmp);
2173

    
2174
                        if (BRI8_R > 8) {
2175
                            int label = gen_new_label();
2176
                            tcg_gen_brcondi_i32(
2177
                                    BRI8_R == 9 ? TCG_COND_NE : TCG_COND_GT,
2178
                                    cpu_R[RRI8_S], 0, label);
2179
                            gen_jumpi(dc, lend, 1);
2180
                            gen_set_label(label);
2181
                        }
2182

    
2183
                        gen_jumpi(dc, dc->next_pc, 0);
2184
                    }
2185
                    break;
2186

    
2187
                default: /*reserved*/
2188
                    RESERVED();
2189
                    break;
2190

    
2191
                }
2192
                break;
2193

    
2194
            case 2: /*BLTUI*/
2195
            case 3: /*BGEUI*/
2196
                gen_window_check1(dc, BRI8_S);
2197
                gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,
2198
                        cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);
2199
                break;
2200
            }
2201
            break;
2202

    
2203
        }
2204
        break;
2205

    
2206
    case 7: /*B*/
2207
        {
2208
            TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;
2209

    
2210
            switch (RRI8_R & 7) {
2211
            case 0: /*BNONE*/ /*BANY*/
2212
                gen_window_check2(dc, RRI8_S, RRI8_T);
2213
                {
2214
                    TCGv_i32 tmp = tcg_temp_new_i32();
2215
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2216
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2217
                    tcg_temp_free(tmp);
2218
                }
2219
                break;
2220

    
2221
            case 1: /*BEQ*/ /*BNE*/
2222
            case 2: /*BLT*/ /*BGE*/
2223
            case 3: /*BLTU*/ /*BGEU*/
2224
                gen_window_check2(dc, RRI8_S, RRI8_T);
2225
                {
2226
                    static const TCGCond cond[] = {
2227
                        [1] = TCG_COND_EQ,
2228
                        [2] = TCG_COND_LT,
2229
                        [3] = TCG_COND_LTU,
2230
                        [9] = TCG_COND_NE,
2231
                        [10] = TCG_COND_GE,
2232
                        [11] = TCG_COND_GEU,
2233
                    };
2234
                    gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],
2235
                            4 + RRI8_IMM8_SE);
2236
                }
2237
                break;
2238

    
2239
            case 4: /*BALL*/ /*BNALL*/
2240
                gen_window_check2(dc, RRI8_S, RRI8_T);
2241
                {
2242
                    TCGv_i32 tmp = tcg_temp_new_i32();
2243
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2244
                    gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],
2245
                            4 + RRI8_IMM8_SE);
2246
                    tcg_temp_free(tmp);
2247
                }
2248
                break;
2249

    
2250
            case 5: /*BBC*/ /*BBS*/
2251
                gen_window_check2(dc, RRI8_S, RRI8_T);
2252
                {
2253
                    TCGv_i32 bit = tcg_const_i32(1);
2254
                    TCGv_i32 tmp = tcg_temp_new_i32();
2255
                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);
2256
                    tcg_gen_shl_i32(bit, bit, tmp);
2257
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);
2258
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2259
                    tcg_temp_free(tmp);
2260
                    tcg_temp_free(bit);
2261
                }
2262
                break;
2263

    
2264
            case 6: /*BBCI*/ /*BBSI*/
2265
            case 7:
2266
                gen_window_check1(dc, RRI8_S);
2267
                {
2268
                    TCGv_i32 tmp = tcg_temp_new_i32();
2269
                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],
2270
                            1 << (((RRI8_R & 1) << 4) | RRI8_T));
2271
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2272
                    tcg_temp_free(tmp);
2273
                }
2274
                break;
2275

    
2276
            }
2277
        }
2278
        break;
2279

    
2280
#define gen_narrow_load_store(type) do { \
2281
            TCGv_i32 addr = tcg_temp_new_i32(); \
2282
            gen_window_check2(dc, RRRN_S, RRRN_T); \
2283
            tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
2284
            gen_load_store_alignment(dc, 2, addr, false); \
2285
            tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \
2286
            tcg_temp_free(addr); \
2287
        } while (0)
2288

    
2289
    case 8: /*L32I.Nn*/
2290
        gen_narrow_load_store(ld32u);
2291
        break;
2292

    
2293
    case 9: /*S32I.Nn*/
2294
        gen_narrow_load_store(st32);
2295
        break;
2296
#undef gen_narrow_load_store
2297

    
2298
    case 10: /*ADD.Nn*/
2299
        gen_window_check3(dc, RRRN_R, RRRN_S, RRRN_T);
2300
        tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);
2301
        break;
2302

    
2303
    case 11: /*ADDI.Nn*/
2304
        gen_window_check2(dc, RRRN_R, RRRN_S);
2305
        tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);
2306
        break;
2307

    
2308
    case 12: /*ST2n*/
2309
        gen_window_check1(dc, RRRN_S);
2310
        if (RRRN_T < 8) { /*MOVI.Nn*/
2311
            tcg_gen_movi_i32(cpu_R[RRRN_S],
2312
                    RRRN_R | (RRRN_T << 4) |
2313
                    ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));
2314
        } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
2315
            TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;
2316

    
2317
            gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,
2318
                    4 + (RRRN_R | ((RRRN_T & 3) << 4)));
2319
        }
2320
        break;
2321

    
2322
    case 13: /*ST3n*/
2323
        switch (RRRN_R) {
2324
        case 0: /*MOV.Nn*/
2325
            gen_window_check2(dc, RRRN_S, RRRN_T);
2326
            tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);
2327
            break;
2328

    
2329
        case 15: /*S3*/
2330
            switch (RRRN_T) {
2331
            case 0: /*RET.Nn*/
2332
                gen_jump(dc, cpu_R[0]);
2333
                break;
2334

    
2335
            case 1: /*RETW.Nn*/
2336
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2337
                {
2338
                    TCGv_i32 tmp = tcg_const_i32(dc->pc);
2339
                    gen_advance_ccount(dc);
2340
                    gen_helper_retw(tmp, tmp);
2341
                    gen_jump(dc, tmp);
2342
                    tcg_temp_free(tmp);
2343
                }
2344
                break;
2345

    
2346
            case 2: /*BREAK.Nn*/
2347
                TBD();
2348
                break;
2349

    
2350
            case 3: /*NOP.Nn*/
2351
                break;
2352

    
2353
            case 6: /*ILL.Nn*/
2354
                gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2355
                break;
2356

    
2357
            default: /*reserved*/
2358
                RESERVED();
2359
                break;
2360
            }
2361
            break;
2362

    
2363
        default: /*reserved*/
2364
            RESERVED();
2365
            break;
2366
        }
2367
        break;
2368

    
2369
    default: /*reserved*/
2370
        RESERVED();
2371
        break;
2372
    }
2373

    
2374
    gen_check_loop_end(dc, 0);
2375
    dc->pc = dc->next_pc;
2376

    
2377
    return;
2378

    
2379
invalid_opcode:
2380
    qemu_log("INVALID(pc = %08x)\n", dc->pc);
2381
    dc->pc = dc->next_pc;
2382
#undef HAS_OPTION
2383
}
2384

    
2385
static void check_breakpoint(CPUState *env, DisasContext *dc)
2386
{
2387
    CPUBreakpoint *bp;
2388

    
2389
    if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
2390
        QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
2391
            if (bp->pc == dc->pc) {
2392
                tcg_gen_movi_i32(cpu_pc, dc->pc);
2393
                gen_exception(dc, EXCP_DEBUG);
2394
                dc->is_jmp = DISAS_UPDATE;
2395
             }
2396
        }
2397
    }
2398
}
2399

    
2400
static void gen_intermediate_code_internal(
2401
        CPUState *env, TranslationBlock *tb, int search_pc)
2402
{
2403
    DisasContext dc;
2404
    int insn_count = 0;
2405
    int j, lj = -1;
2406
    uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2407
    int max_insns = tb->cflags & CF_COUNT_MASK;
2408
    uint32_t pc_start = tb->pc;
2409
    uint32_t next_page_start =
2410
        (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2411

    
2412
    if (max_insns == 0) {
2413
        max_insns = CF_COUNT_MASK;
2414
    }
2415

    
2416
    dc.config = env->config;
2417
    dc.singlestep_enabled = env->singlestep_enabled;
2418
    dc.tb = tb;
2419
    dc.pc = pc_start;
2420
    dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
2421
    dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;
2422
    dc.lbeg = env->sregs[LBEG];
2423
    dc.lend = env->sregs[LEND];
2424
    dc.is_jmp = DISAS_NEXT;
2425
    dc.ccount_delta = 0;
2426

    
2427
    init_litbase(&dc);
2428
    init_sar_tracker(&dc);
2429
    reset_used_window(&dc);
2430

    
2431
    gen_icount_start();
2432

    
2433
    if (env->singlestep_enabled && env->exception_taken) {
2434
        env->exception_taken = 0;
2435
        tcg_gen_movi_i32(cpu_pc, dc.pc);
2436
        gen_exception(&dc, EXCP_DEBUG);
2437
    }
2438

    
2439
    do {
2440
        check_breakpoint(env, &dc);
2441

    
2442
        if (search_pc) {
2443
            j = gen_opc_ptr - gen_opc_buf;
2444
            if (lj < j) {
2445
                lj++;
2446
                while (lj < j) {
2447
                    gen_opc_instr_start[lj++] = 0;
2448
                }
2449
            }
2450
            gen_opc_pc[lj] = dc.pc;
2451
            gen_opc_instr_start[lj] = 1;
2452
            gen_opc_icount[lj] = insn_count;
2453
        }
2454

    
2455
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
2456
            tcg_gen_debug_insn_start(dc.pc);
2457
        }
2458

    
2459
        ++dc.ccount_delta;
2460

    
2461
        if (insn_count + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
2462
            gen_io_start();
2463
        }
2464

    
2465
        disas_xtensa_insn(&dc);
2466
        ++insn_count;
2467
        if (env->singlestep_enabled) {
2468
            tcg_gen_movi_i32(cpu_pc, dc.pc);
2469
            gen_exception(&dc, EXCP_DEBUG);
2470
            break;
2471
        }
2472
    } while (dc.is_jmp == DISAS_NEXT &&
2473
            insn_count < max_insns &&
2474
            dc.pc < next_page_start &&
2475
            gen_opc_ptr < gen_opc_end);
2476

    
2477
    reset_litbase(&dc);
2478
    reset_sar_tracker(&dc);
2479

    
2480
    if (tb->cflags & CF_LAST_IO) {
2481
        gen_io_end();
2482
    }
2483

    
2484
    if (dc.is_jmp == DISAS_NEXT) {
2485
        gen_jumpi(&dc, dc.pc, 0);
2486
    }
2487
    gen_icount_end(tb, insn_count);
2488
    *gen_opc_ptr = INDEX_op_end;
2489

    
2490
    if (!search_pc) {
2491
        tb->size = dc.pc - pc_start;
2492
        tb->icount = insn_count;
2493
    }
2494
}
2495

    
2496
void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
2497
{
2498
    gen_intermediate_code_internal(env, tb, 0);
2499
}
2500

    
2501
void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
2502
{
2503
    gen_intermediate_code_internal(env, tb, 1);
2504
}
2505

    
2506
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
2507
        int flags)
2508
{
2509
    int i, j;
2510

    
2511
    cpu_fprintf(f, "PC=%08x\n\n", env->pc);
2512

    
2513
    for (i = j = 0; i < 256; ++i) {
2514
        if (sregnames[i]) {
2515
            cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
2516
                    (j++ % 4) == 3 ? '\n' : ' ');
2517
        }
2518
    }
2519

    
2520
    cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2521

    
2522
    for (i = j = 0; i < 256; ++i) {
2523
        if (uregnames[i]) {
2524
            cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
2525
                    (j++ % 4) == 3 ? '\n' : ' ');
2526
        }
2527
    }
2528

    
2529
    cpu_fprintf(f, (j % 4) == 0 ? "\n" : "\n\n");
2530

    
2531
    for (i = 0; i < 16; ++i) {
2532
        cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
2533
                (i % 4) == 3 ? '\n' : ' ');
2534
    }
2535

    
2536
    cpu_fprintf(f, "\n");
2537

    
2538
    for (i = 0; i < env->config->nareg; ++i) {
2539
        cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
2540
                (i % 4) == 3 ? '\n' : ' ');
2541
    }
2542
}
2543

    
2544
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
2545
{
2546
    env->pc = gen_opc_pc[pc_pos];
2547
}