Statistics
| Branch: | Revision:

root / target-xtensa / translate.c @ ab1103de

History | View | Annotate | Download (94.5 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 "helper.h"
41
#define GEN_HELPER 1
42
#include "helper.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

    
65
    bool debug;
66
    bool icount;
67
    TCGv_i32 next_icount;
68

    
69
    unsigned cpenable;
70
} DisasContext;
71

    
72
static TCGv_ptr cpu_env;
73
static TCGv_i32 cpu_pc;
74
static TCGv_i32 cpu_R[16];
75
static TCGv_i32 cpu_FR[16];
76
static TCGv_i32 cpu_SR[256];
77
static TCGv_i32 cpu_UR[256];
78

    
79
#include "gen-icount.h"
80

    
81
static const char * const sregnames[256] = {
82
    [LBEG] = "LBEG",
83
    [LEND] = "LEND",
84
    [LCOUNT] = "LCOUNT",
85
    [SAR] = "SAR",
86
    [BR] = "BR",
87
    [LITBASE] = "LITBASE",
88
    [SCOMPARE1] = "SCOMPARE1",
89
    [ACCLO] = "ACCLO",
90
    [ACCHI] = "ACCHI",
91
    [MR] = "MR0",
92
    [MR + 1] = "MR1",
93
    [MR + 2] = "MR2",
94
    [MR + 3] = "MR3",
95
    [WINDOW_BASE] = "WINDOW_BASE",
96
    [WINDOW_START] = "WINDOW_START",
97
    [PTEVADDR] = "PTEVADDR",
98
    [RASID] = "RASID",
99
    [ITLBCFG] = "ITLBCFG",
100
    [DTLBCFG] = "DTLBCFG",
101
    [IBREAKENABLE] = "IBREAKENABLE",
102
    [IBREAKA] = "IBREAKA0",
103
    [IBREAKA + 1] = "IBREAKA1",
104
    [DBREAKA] = "DBREAKA0",
105
    [DBREAKA + 1] = "DBREAKA1",
106
    [DBREAKC] = "DBREAKC0",
107
    [DBREAKC + 1] = "DBREAKC1",
108
    [EPC1] = "EPC1",
109
    [EPC1 + 1] = "EPC2",
110
    [EPC1 + 2] = "EPC3",
111
    [EPC1 + 3] = "EPC4",
112
    [EPC1 + 4] = "EPC5",
113
    [EPC1 + 5] = "EPC6",
114
    [EPC1 + 6] = "EPC7",
115
    [DEPC] = "DEPC",
116
    [EPS2] = "EPS2",
117
    [EPS2 + 1] = "EPS3",
118
    [EPS2 + 2] = "EPS4",
119
    [EPS2 + 3] = "EPS5",
120
    [EPS2 + 4] = "EPS6",
121
    [EPS2 + 5] = "EPS7",
122
    [EXCSAVE1] = "EXCSAVE1",
123
    [EXCSAVE1 + 1] = "EXCSAVE2",
124
    [EXCSAVE1 + 2] = "EXCSAVE3",
125
    [EXCSAVE1 + 3] = "EXCSAVE4",
126
    [EXCSAVE1 + 4] = "EXCSAVE5",
127
    [EXCSAVE1 + 5] = "EXCSAVE6",
128
    [EXCSAVE1 + 6] = "EXCSAVE7",
129
    [CPENABLE] = "CPENABLE",
130
    [INTSET] = "INTSET",
131
    [INTCLEAR] = "INTCLEAR",
132
    [INTENABLE] = "INTENABLE",
133
    [PS] = "PS",
134
    [VECBASE] = "VECBASE",
135
    [EXCCAUSE] = "EXCCAUSE",
136
    [DEBUGCAUSE] = "DEBUGCAUSE",
137
    [CCOUNT] = "CCOUNT",
138
    [PRID] = "PRID",
139
    [ICOUNT] = "ICOUNT",
140
    [ICOUNTLEVEL] = "ICOUNTLEVEL",
141
    [EXCVADDR] = "EXCVADDR",
142
    [CCOMPARE] = "CCOMPARE0",
143
    [CCOMPARE + 1] = "CCOMPARE1",
144
    [CCOMPARE + 2] = "CCOMPARE2",
145
};
146

    
147
static const char * const uregnames[256] = {
148
    [THREADPTR] = "THREADPTR",
149
    [FCR] = "FCR",
150
    [FSR] = "FSR",
151
};
152

    
153
void xtensa_translate_init(void)
154
{
155
    static const char * const regnames[] = {
156
        "ar0", "ar1", "ar2", "ar3",
157
        "ar4", "ar5", "ar6", "ar7",
158
        "ar8", "ar9", "ar10", "ar11",
159
        "ar12", "ar13", "ar14", "ar15",
160
    };
161
    static const char * const fregnames[] = {
162
        "f0", "f1", "f2", "f3",
163
        "f4", "f5", "f6", "f7",
164
        "f8", "f9", "f10", "f11",
165
        "f12", "f13", "f14", "f15",
166
    };
167
    int i;
168

    
169
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
170
    cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
171
            offsetof(CPUXtensaState, pc), "pc");
172

    
173
    for (i = 0; i < 16; i++) {
174
        cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
175
                offsetof(CPUXtensaState, regs[i]),
176
                regnames[i]);
177
    }
178

    
179
    for (i = 0; i < 16; i++) {
180
        cpu_FR[i] = tcg_global_mem_new_i32(TCG_AREG0,
181
                offsetof(CPUXtensaState, fregs[i]),
182
                fregnames[i]);
183
    }
184

    
185
    for (i = 0; i < 256; ++i) {
186
        if (sregnames[i]) {
187
            cpu_SR[i] = tcg_global_mem_new_i32(TCG_AREG0,
188
                    offsetof(CPUXtensaState, sregs[i]),
189
                    sregnames[i]);
190
        }
191
    }
192

    
193
    for (i = 0; i < 256; ++i) {
194
        if (uregnames[i]) {
195
            cpu_UR[i] = tcg_global_mem_new_i32(TCG_AREG0,
196
                    offsetof(CPUXtensaState, uregs[i]),
197
                    uregnames[i]);
198
        }
199
    }
200
#define GEN_HELPER 2
201
#include "helper.h"
202
}
203

    
204
static inline bool option_bits_enabled(DisasContext *dc, uint64_t opt)
205
{
206
    return xtensa_option_bits_enabled(dc->config, opt);
207
}
208

    
209
static inline bool option_enabled(DisasContext *dc, int opt)
210
{
211
    return xtensa_option_enabled(dc->config, opt);
212
}
213

    
214
static void init_litbase(DisasContext *dc)
215
{
216
    if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
217
        dc->litbase = tcg_temp_local_new_i32();
218
        tcg_gen_andi_i32(dc->litbase, cpu_SR[LITBASE], 0xfffff000);
219
    }
220
}
221

    
222
static void reset_litbase(DisasContext *dc)
223
{
224
    if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
225
        tcg_temp_free(dc->litbase);
226
    }
227
}
228

    
229
static void init_sar_tracker(DisasContext *dc)
230
{
231
    dc->sar_5bit = false;
232
    dc->sar_m32_5bit = false;
233
    dc->sar_m32_allocated = false;
234
}
235

    
236
static void reset_sar_tracker(DisasContext *dc)
237
{
238
    if (dc->sar_m32_allocated) {
239
        tcg_temp_free(dc->sar_m32);
240
    }
241
}
242

    
243
static void gen_right_shift_sar(DisasContext *dc, TCGv_i32 sa)
244
{
245
    tcg_gen_andi_i32(cpu_SR[SAR], sa, 0x1f);
246
    if (dc->sar_m32_5bit) {
247
        tcg_gen_discard_i32(dc->sar_m32);
248
    }
249
    dc->sar_5bit = true;
250
    dc->sar_m32_5bit = false;
251
}
252

    
253
static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
254
{
255
    TCGv_i32 tmp = tcg_const_i32(32);
256
    if (!dc->sar_m32_allocated) {
257
        dc->sar_m32 = tcg_temp_local_new_i32();
258
        dc->sar_m32_allocated = true;
259
    }
260
    tcg_gen_andi_i32(dc->sar_m32, sa, 0x1f);
261
    tcg_gen_sub_i32(cpu_SR[SAR], tmp, dc->sar_m32);
262
    dc->sar_5bit = false;
263
    dc->sar_m32_5bit = true;
264
    tcg_temp_free(tmp);
265
}
266

    
267
static void gen_advance_ccount(DisasContext *dc)
268
{
269
    if (dc->ccount_delta > 0) {
270
        TCGv_i32 tmp = tcg_const_i32(dc->ccount_delta);
271
        dc->ccount_delta = 0;
272
        gen_helper_advance_ccount(cpu_env, tmp);
273
        tcg_temp_free(tmp);
274
    }
275
}
276

    
277
static void reset_used_window(DisasContext *dc)
278
{
279
    dc->used_window = 0;
280
}
281

    
282
static void gen_exception(DisasContext *dc, int excp)
283
{
284
    TCGv_i32 tmp = tcg_const_i32(excp);
285
    gen_advance_ccount(dc);
286
    gen_helper_exception(cpu_env, tmp);
287
    tcg_temp_free(tmp);
288
}
289

    
290
static void gen_exception_cause(DisasContext *dc, uint32_t cause)
291
{
292
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
293
    TCGv_i32 tcause = tcg_const_i32(cause);
294
    gen_advance_ccount(dc);
295
    gen_helper_exception_cause(cpu_env, tpc, tcause);
296
    tcg_temp_free(tpc);
297
    tcg_temp_free(tcause);
298
    if (cause == ILLEGAL_INSTRUCTION_CAUSE ||
299
            cause == SYSCALL_CAUSE) {
300
        dc->is_jmp = DISAS_UPDATE;
301
    }
302
}
303

    
304
static void gen_exception_cause_vaddr(DisasContext *dc, uint32_t cause,
305
        TCGv_i32 vaddr)
306
{
307
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
308
    TCGv_i32 tcause = tcg_const_i32(cause);
309
    gen_advance_ccount(dc);
310
    gen_helper_exception_cause_vaddr(cpu_env, tpc, tcause, vaddr);
311
    tcg_temp_free(tpc);
312
    tcg_temp_free(tcause);
313
}
314

    
315
static void gen_debug_exception(DisasContext *dc, uint32_t cause)
316
{
317
    TCGv_i32 tpc = tcg_const_i32(dc->pc);
318
    TCGv_i32 tcause = tcg_const_i32(cause);
319
    gen_advance_ccount(dc);
320
    gen_helper_debug_exception(cpu_env, tpc, tcause);
321
    tcg_temp_free(tpc);
322
    tcg_temp_free(tcause);
323
    if (cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BI | DEBUGCAUSE_BN)) {
324
        dc->is_jmp = DISAS_UPDATE;
325
    }
326
}
327

    
328
static void gen_check_privilege(DisasContext *dc)
329
{
330
    if (dc->cring) {
331
        gen_exception_cause(dc, PRIVILEGED_CAUSE);
332
        dc->is_jmp = DISAS_UPDATE;
333
    }
334
}
335

    
336
static void gen_check_cpenable(DisasContext *dc, unsigned cp)
337
{
338
    if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) &&
339
            !(dc->cpenable & (1 << cp))) {
340
        gen_exception_cause(dc, COPROCESSOR0_DISABLED + cp);
341
        dc->is_jmp = DISAS_UPDATE;
342
    }
343
}
344

    
345
static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
346
{
347
    tcg_gen_mov_i32(cpu_pc, dest);
348
    gen_advance_ccount(dc);
349
    if (dc->icount) {
350
        tcg_gen_mov_i32(cpu_SR[ICOUNT], dc->next_icount);
351
    }
352
    if (dc->singlestep_enabled) {
353
        gen_exception(dc, EXCP_DEBUG);
354
    } else {
355
        if (slot >= 0) {
356
            tcg_gen_goto_tb(slot);
357
            tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
358
        } else {
359
            tcg_gen_exit_tb(0);
360
        }
361
    }
362
    dc->is_jmp = DISAS_UPDATE;
363
}
364

    
365
static void gen_jump(DisasContext *dc, TCGv dest)
366
{
367
    gen_jump_slot(dc, dest, -1);
368
}
369

    
370
static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot)
371
{
372
    TCGv_i32 tmp = tcg_const_i32(dest);
373
    if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
374
        slot = -1;
375
    }
376
    gen_jump_slot(dc, tmp, slot);
377
    tcg_temp_free(tmp);
378
}
379

    
380
static void gen_callw_slot(DisasContext *dc, int callinc, TCGv_i32 dest,
381
        int slot)
382
{
383
    TCGv_i32 tcallinc = tcg_const_i32(callinc);
384

    
385
    tcg_gen_deposit_i32(cpu_SR[PS], cpu_SR[PS],
386
            tcallinc, PS_CALLINC_SHIFT, PS_CALLINC_LEN);
387
    tcg_temp_free(tcallinc);
388
    tcg_gen_movi_i32(cpu_R[callinc << 2],
389
            (callinc << 30) | (dc->next_pc & 0x3fffffff));
390
    gen_jump_slot(dc, dest, slot);
391
}
392

    
393
static void gen_callw(DisasContext *dc, int callinc, TCGv_i32 dest)
394
{
395
    gen_callw_slot(dc, callinc, dest, -1);
396
}
397

    
398
static void gen_callwi(DisasContext *dc, int callinc, uint32_t dest, int slot)
399
{
400
    TCGv_i32 tmp = tcg_const_i32(dest);
401
    if (((dc->pc ^ dest) & TARGET_PAGE_MASK) != 0) {
402
        slot = -1;
403
    }
404
    gen_callw_slot(dc, callinc, tmp, slot);
405
    tcg_temp_free(tmp);
406
}
407

    
408
static bool gen_check_loop_end(DisasContext *dc, int slot)
409
{
410
    if (option_enabled(dc, XTENSA_OPTION_LOOP) &&
411
            !(dc->tb->flags & XTENSA_TBFLAG_EXCM) &&
412
            dc->next_pc == dc->lend) {
413
        int label = gen_new_label();
414

    
415
        gen_advance_ccount(dc);
416
        tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_SR[LCOUNT], 0, label);
417
        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_SR[LCOUNT], 1);
418
        gen_jumpi(dc, dc->lbeg, slot);
419
        gen_set_label(label);
420
        gen_jumpi(dc, dc->next_pc, -1);
421
        return true;
422
    }
423
    return false;
424
}
425

    
426
static void gen_jumpi_check_loop_end(DisasContext *dc, int slot)
427
{
428
    if (!gen_check_loop_end(dc, slot)) {
429
        gen_jumpi(dc, dc->next_pc, slot);
430
    }
431
}
432

    
433
static void gen_brcond(DisasContext *dc, TCGCond cond,
434
        TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)
435
{
436
    int label = gen_new_label();
437

    
438
    gen_advance_ccount(dc);
439
    tcg_gen_brcond_i32(cond, t0, t1, label);
440
    gen_jumpi_check_loop_end(dc, 0);
441
    gen_set_label(label);
442
    gen_jumpi(dc, dc->pc + offset, 1);
443
}
444

    
445
static void gen_brcondi(DisasContext *dc, TCGCond cond,
446
        TCGv_i32 t0, uint32_t t1, uint32_t offset)
447
{
448
    TCGv_i32 tmp = tcg_const_i32(t1);
449
    gen_brcond(dc, cond, t0, tmp, offset);
450
    tcg_temp_free(tmp);
451
}
452

    
453
static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
454
{
455
    gen_advance_ccount(dc);
456
    tcg_gen_mov_i32(d, cpu_SR[sr]);
457
}
458

    
459
static void gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
460
{
461
    tcg_gen_shri_i32(d, cpu_SR[EXCVADDR], 10);
462
    tcg_gen_or_i32(d, d, cpu_SR[sr]);
463
    tcg_gen_andi_i32(d, d, 0xfffffffc);
464
}
465

    
466
static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
467
{
468
    static void (* const rsr_handler[256])(DisasContext *dc,
469
            TCGv_i32 d, uint32_t sr) = {
470
        [CCOUNT] = gen_rsr_ccount,
471
        [PTEVADDR] = gen_rsr_ptevaddr,
472
    };
473

    
474
    if (sregnames[sr]) {
475
        if (rsr_handler[sr]) {
476
            rsr_handler[sr](dc, d, sr);
477
        } else {
478
            tcg_gen_mov_i32(d, cpu_SR[sr]);
479
        }
480
    } else {
481
        qemu_log("RSR %d not implemented, ", sr);
482
    }
483
}
484

    
485
static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
486
{
487
    gen_helper_wsr_lbeg(cpu_env, s);
488
    gen_jumpi_check_loop_end(dc, 0);
489
}
490

    
491
static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
492
{
493
    gen_helper_wsr_lend(cpu_env, s);
494
    gen_jumpi_check_loop_end(dc, 0);
495
}
496

    
497
static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
498
{
499
    tcg_gen_andi_i32(cpu_SR[sr], s, 0x3f);
500
    if (dc->sar_m32_5bit) {
501
        tcg_gen_discard_i32(dc->sar_m32);
502
    }
503
    dc->sar_5bit = false;
504
    dc->sar_m32_5bit = false;
505
}
506

    
507
static void gen_wsr_br(DisasContext *dc, uint32_t sr, TCGv_i32 s)
508
{
509
    tcg_gen_andi_i32(cpu_SR[sr], s, 0xffff);
510
}
511

    
512
static void gen_wsr_litbase(DisasContext *dc, uint32_t sr, TCGv_i32 s)
513
{
514
    tcg_gen_andi_i32(cpu_SR[sr], s, 0xfffff001);
515
    /* This can change tb->flags, so exit tb */
516
    gen_jumpi_check_loop_end(dc, -1);
517
}
518

    
519
static void gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s)
520
{
521
    tcg_gen_ext8s_i32(cpu_SR[sr], s);
522
}
523

    
524
static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
525
{
526
    gen_helper_wsr_windowbase(cpu_env, v);
527
    reset_used_window(dc);
528
}
529

    
530
static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
531
{
532
    tcg_gen_andi_i32(cpu_SR[sr], v, (1 << dc->config->nareg / 4) - 1);
533
    reset_used_window(dc);
534
}
535

    
536
static void gen_wsr_ptevaddr(DisasContext *dc, uint32_t sr, TCGv_i32 v)
537
{
538
    tcg_gen_andi_i32(cpu_SR[sr], v, 0xffc00000);
539
}
540

    
541
static void gen_wsr_rasid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
542
{
543
    gen_helper_wsr_rasid(cpu_env, v);
544
    /* This can change tb->flags, so exit tb */
545
    gen_jumpi_check_loop_end(dc, -1);
546
}
547

    
548
static void gen_wsr_tlbcfg(DisasContext *dc, uint32_t sr, TCGv_i32 v)
549
{
550
    tcg_gen_andi_i32(cpu_SR[sr], v, 0x01130000);
551
}
552

    
553
static void gen_wsr_ibreakenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
554
{
555
    gen_helper_wsr_ibreakenable(cpu_env, v);
556
    gen_jumpi_check_loop_end(dc, 0);
557
}
558

    
559
static void gen_wsr_ibreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
560
{
561
    unsigned id = sr - IBREAKA;
562

    
563
    if (id < dc->config->nibreak) {
564
        TCGv_i32 tmp = tcg_const_i32(id);
565
        gen_helper_wsr_ibreaka(cpu_env, tmp, v);
566
        tcg_temp_free(tmp);
567
        gen_jumpi_check_loop_end(dc, 0);
568
    }
569
}
570

    
571
static void gen_wsr_dbreaka(DisasContext *dc, uint32_t sr, TCGv_i32 v)
572
{
573
    unsigned id = sr - DBREAKA;
574

    
575
    if (id < dc->config->ndbreak) {
576
        TCGv_i32 tmp = tcg_const_i32(id);
577
        gen_helper_wsr_dbreaka(cpu_env, tmp, v);
578
        tcg_temp_free(tmp);
579
    }
580
}
581

    
582
static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
583
{
584
    unsigned id = sr - DBREAKC;
585

    
586
    if (id < dc->config->ndbreak) {
587
        TCGv_i32 tmp = tcg_const_i32(id);
588
        gen_helper_wsr_dbreakc(cpu_env, tmp, v);
589
        tcg_temp_free(tmp);
590
    }
591
}
592

    
593
static void gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
594
{
595
    tcg_gen_andi_i32(cpu_SR[sr], v, 0xff);
596
    /* This can change tb->flags, so exit tb */
597
    gen_jumpi_check_loop_end(dc, -1);
598
}
599

    
600
static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
601
{
602
    tcg_gen_andi_i32(cpu_SR[sr], v,
603
            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
604
    gen_helper_check_interrupts(cpu_env);
605
    gen_jumpi_check_loop_end(dc, 0);
606
}
607

    
608
static void gen_wsr_intclear(DisasContext *dc, uint32_t sr, TCGv_i32 v)
609
{
610
    TCGv_i32 tmp = tcg_temp_new_i32();
611

    
612
    tcg_gen_andi_i32(tmp, v,
613
            dc->config->inttype_mask[INTTYPE_EDGE] |
614
            dc->config->inttype_mask[INTTYPE_NMI] |
615
            dc->config->inttype_mask[INTTYPE_SOFTWARE]);
616
    tcg_gen_andc_i32(cpu_SR[INTSET], cpu_SR[INTSET], tmp);
617
    tcg_temp_free(tmp);
618
    gen_helper_check_interrupts(cpu_env);
619
}
620

    
621
static void gen_wsr_intenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
622
{
623
    tcg_gen_mov_i32(cpu_SR[sr], v);
624
    gen_helper_check_interrupts(cpu_env);
625
    gen_jumpi_check_loop_end(dc, 0);
626
}
627

    
628
static void gen_wsr_ps(DisasContext *dc, uint32_t sr, TCGv_i32 v)
629
{
630
    uint32_t mask = PS_WOE | PS_CALLINC | PS_OWB |
631
        PS_UM | PS_EXCM | PS_INTLEVEL;
632

    
633
    if (option_enabled(dc, XTENSA_OPTION_MMU)) {
634
        mask |= PS_RING;
635
    }
636
    tcg_gen_andi_i32(cpu_SR[sr], v, mask);
637
    reset_used_window(dc);
638
    gen_helper_check_interrupts(cpu_env);
639
    /* This can change mmu index and tb->flags, so exit tb */
640
    gen_jumpi_check_loop_end(dc, -1);
641
}
642

    
643
static void gen_wsr_debugcause(DisasContext *dc, uint32_t sr, TCGv_i32 v)
644
{
645
}
646

    
647
static void gen_wsr_prid(DisasContext *dc, uint32_t sr, TCGv_i32 v)
648
{
649
}
650

    
651
static void gen_wsr_icount(DisasContext *dc, uint32_t sr, TCGv_i32 v)
652
{
653
    if (dc->icount) {
654
        tcg_gen_mov_i32(dc->next_icount, v);
655
    } else {
656
        tcg_gen_mov_i32(cpu_SR[sr], v);
657
    }
658
}
659

    
660
static void gen_wsr_icountlevel(DisasContext *dc, uint32_t sr, TCGv_i32 v)
661
{
662
    tcg_gen_andi_i32(cpu_SR[sr], v, 0xf);
663
    /* This can change tb->flags, so exit tb */
664
    gen_jumpi_check_loop_end(dc, -1);
665
}
666

    
667
static void gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)
668
{
669
    uint32_t id = sr - CCOMPARE;
670
    if (id < dc->config->nccompare) {
671
        uint32_t int_bit = 1 << dc->config->timerint[id];
672
        gen_advance_ccount(dc);
673
        tcg_gen_mov_i32(cpu_SR[sr], v);
674
        tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);
675
        gen_helper_check_interrupts(cpu_env);
676
    }
677
}
678

    
679
static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
680
{
681
    static void (* const wsr_handler[256])(DisasContext *dc,
682
            uint32_t sr, TCGv_i32 v) = {
683
        [LBEG] = gen_wsr_lbeg,
684
        [LEND] = gen_wsr_lend,
685
        [SAR] = gen_wsr_sar,
686
        [BR] = gen_wsr_br,
687
        [LITBASE] = gen_wsr_litbase,
688
        [ACCHI] = gen_wsr_acchi,
689
        [WINDOW_BASE] = gen_wsr_windowbase,
690
        [WINDOW_START] = gen_wsr_windowstart,
691
        [PTEVADDR] = gen_wsr_ptevaddr,
692
        [RASID] = gen_wsr_rasid,
693
        [ITLBCFG] = gen_wsr_tlbcfg,
694
        [DTLBCFG] = gen_wsr_tlbcfg,
695
        [IBREAKENABLE] = gen_wsr_ibreakenable,
696
        [IBREAKA] = gen_wsr_ibreaka,
697
        [IBREAKA + 1] = gen_wsr_ibreaka,
698
        [DBREAKA] = gen_wsr_dbreaka,
699
        [DBREAKA + 1] = gen_wsr_dbreaka,
700
        [DBREAKC] = gen_wsr_dbreakc,
701
        [DBREAKC + 1] = gen_wsr_dbreakc,
702
        [CPENABLE] = gen_wsr_cpenable,
703
        [INTSET] = gen_wsr_intset,
704
        [INTCLEAR] = gen_wsr_intclear,
705
        [INTENABLE] = gen_wsr_intenable,
706
        [PS] = gen_wsr_ps,
707
        [DEBUGCAUSE] = gen_wsr_debugcause,
708
        [PRID] = gen_wsr_prid,
709
        [ICOUNT] = gen_wsr_icount,
710
        [ICOUNTLEVEL] = gen_wsr_icountlevel,
711
        [CCOMPARE] = gen_wsr_ccompare,
712
        [CCOMPARE + 1] = gen_wsr_ccompare,
713
        [CCOMPARE + 2] = gen_wsr_ccompare,
714
    };
715

    
716
    if (sregnames[sr]) {
717
        if (wsr_handler[sr]) {
718
            wsr_handler[sr](dc, sr, s);
719
        } else {
720
            tcg_gen_mov_i32(cpu_SR[sr], s);
721
        }
722
    } else {
723
        qemu_log("WSR %d not implemented, ", sr);
724
    }
725
}
726

    
727
static void gen_wur(uint32_t ur, TCGv_i32 s)
728
{
729
    switch (ur) {
730
    case FCR:
731
        gen_helper_wur_fcr(cpu_env, s);
732
        break;
733

    
734
    case FSR:
735
        tcg_gen_andi_i32(cpu_UR[ur], s, 0xffffff80);
736
        break;
737

    
738
    default:
739
        tcg_gen_mov_i32(cpu_UR[ur], s);
740
        break;
741
    }
742
}
743

    
744
static void gen_load_store_alignment(DisasContext *dc, int shift,
745
        TCGv_i32 addr, bool no_hw_alignment)
746
{
747
    if (!option_enabled(dc, XTENSA_OPTION_UNALIGNED_EXCEPTION)) {
748
        tcg_gen_andi_i32(addr, addr, ~0 << shift);
749
    } else if (option_enabled(dc, XTENSA_OPTION_HW_ALIGNMENT) &&
750
            no_hw_alignment) {
751
        int label = gen_new_label();
752
        TCGv_i32 tmp = tcg_temp_new_i32();
753
        tcg_gen_andi_i32(tmp, addr, ~(~0 << shift));
754
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
755
        gen_exception_cause_vaddr(dc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
756
        gen_set_label(label);
757
        tcg_temp_free(tmp);
758
    }
759
}
760

    
761
static void gen_waiti(DisasContext *dc, uint32_t imm4)
762
{
763
    TCGv_i32 pc = tcg_const_i32(dc->next_pc);
764
    TCGv_i32 intlevel = tcg_const_i32(imm4);
765
    gen_advance_ccount(dc);
766
    gen_helper_waiti(cpu_env, pc, intlevel);
767
    tcg_temp_free(pc);
768
    tcg_temp_free(intlevel);
769
}
770

    
771
static void gen_window_check1(DisasContext *dc, unsigned r1)
772
{
773
    if (dc->tb->flags & XTENSA_TBFLAG_EXCM) {
774
        return;
775
    }
776
    if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&
777
            r1 / 4 > dc->used_window) {
778
        TCGv_i32 pc = tcg_const_i32(dc->pc);
779
        TCGv_i32 w = tcg_const_i32(r1 / 4);
780

    
781
        dc->used_window = r1 / 4;
782
        gen_advance_ccount(dc);
783
        gen_helper_window_check(cpu_env, pc, w);
784

    
785
        tcg_temp_free(w);
786
        tcg_temp_free(pc);
787
    }
788
}
789

    
790
static void gen_window_check2(DisasContext *dc, unsigned r1, unsigned r2)
791
{
792
    gen_window_check1(dc, r1 > r2 ? r1 : r2);
793
}
794

    
795
static void gen_window_check3(DisasContext *dc, unsigned r1, unsigned r2,
796
        unsigned r3)
797
{
798
    gen_window_check2(dc, r1, r2 > r3 ? r2 : r3);
799
}
800

    
801
static TCGv_i32 gen_mac16_m(TCGv_i32 v, bool hi, bool is_unsigned)
802
{
803
    TCGv_i32 m = tcg_temp_new_i32();
804

    
805
    if (hi) {
806
        (is_unsigned ? tcg_gen_shri_i32 : tcg_gen_sari_i32)(m, v, 16);
807
    } else {
808
        (is_unsigned ? tcg_gen_ext16u_i32 : tcg_gen_ext16s_i32)(m, v);
809
    }
810
    return m;
811
}
812

    
813
static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
814
{
815
#define HAS_OPTION_BITS(opt) do { \
816
        if (!option_bits_enabled(dc, opt)) { \
817
            qemu_log("Option is not enabled %s:%d\n", \
818
                    __FILE__, __LINE__); \
819
            goto invalid_opcode; \
820
        } \
821
    } while (0)
822

    
823
#define HAS_OPTION(opt) HAS_OPTION_BITS(XTENSA_OPTION_BIT(opt))
824

    
825
#define TBD() qemu_log("TBD(pc = %08x): %s:%d\n", dc->pc, __FILE__, __LINE__)
826
#define RESERVED() do { \
827
        qemu_log("RESERVED(pc = %08x, %02x%02x%02x): %s:%d\n", \
828
                dc->pc, b0, b1, b2, __FILE__, __LINE__); \
829
        goto invalid_opcode; \
830
    } while (0)
831

    
832

    
833
#ifdef TARGET_WORDS_BIGENDIAN
834
#define OP0 (((b0) & 0xf0) >> 4)
835
#define OP1 (((b2) & 0xf0) >> 4)
836
#define OP2 ((b2) & 0xf)
837
#define RRR_R ((b1) & 0xf)
838
#define RRR_S (((b1) & 0xf0) >> 4)
839
#define RRR_T ((b0) & 0xf)
840
#else
841
#define OP0 (((b0) & 0xf))
842
#define OP1 (((b2) & 0xf))
843
#define OP2 (((b2) & 0xf0) >> 4)
844
#define RRR_R (((b1) & 0xf0) >> 4)
845
#define RRR_S (((b1) & 0xf))
846
#define RRR_T (((b0) & 0xf0) >> 4)
847
#endif
848
#define RRR_X ((RRR_R & 0x4) >> 2)
849
#define RRR_Y ((RRR_T & 0x4) >> 2)
850
#define RRR_W (RRR_R & 0x3)
851

    
852
#define RRRN_R RRR_R
853
#define RRRN_S RRR_S
854
#define RRRN_T RRR_T
855

    
856
#define RRI8_R RRR_R
857
#define RRI8_S RRR_S
858
#define RRI8_T RRR_T
859
#define RRI8_IMM8 (b2)
860
#define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)
861

    
862
#ifdef TARGET_WORDS_BIGENDIAN
863
#define RI16_IMM16 (((b1) << 8) | (b2))
864
#else
865
#define RI16_IMM16 (((b2) << 8) | (b1))
866
#endif
867

    
868
#ifdef TARGET_WORDS_BIGENDIAN
869
#define CALL_N (((b0) & 0xc) >> 2)
870
#define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))
871
#else
872
#define CALL_N (((b0) & 0x30) >> 4)
873
#define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))
874
#endif
875
#define CALL_OFFSET_SE \
876
    (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)
877

    
878
#define CALLX_N CALL_N
879
#ifdef TARGET_WORDS_BIGENDIAN
880
#define CALLX_M ((b0) & 0x3)
881
#else
882
#define CALLX_M (((b0) & 0xc0) >> 6)
883
#endif
884
#define CALLX_S RRR_S
885

    
886
#define BRI12_M CALLX_M
887
#define BRI12_S RRR_S
888
#ifdef TARGET_WORDS_BIGENDIAN
889
#define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))
890
#else
891
#define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))
892
#endif
893
#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)
894

    
895
#define BRI8_M BRI12_M
896
#define BRI8_R RRI8_R
897
#define BRI8_S RRI8_S
898
#define BRI8_IMM8 RRI8_IMM8
899
#define BRI8_IMM8_SE RRI8_IMM8_SE
900

    
901
#define RSR_SR (b1)
902

    
903
    uint8_t b0 = cpu_ldub_code(env, dc->pc);
904
    uint8_t b1 = cpu_ldub_code(env, dc->pc + 1);
905
    uint8_t b2 = 0;
906

    
907
    static const uint32_t B4CONST[] = {
908
        0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
909
    };
910

    
911
    static const uint32_t B4CONSTU[] = {
912
        32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256
913
    };
914

    
915
    if (OP0 >= 8) {
916
        dc->next_pc = dc->pc + 2;
917
        HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);
918
    } else {
919
        dc->next_pc = dc->pc + 3;
920
        b2 = cpu_ldub_code(env, dc->pc + 2);
921
    }
922

    
923
    switch (OP0) {
924
    case 0: /*QRST*/
925
        switch (OP1) {
926
        case 0: /*RST0*/
927
            switch (OP2) {
928
            case 0: /*ST0*/
929
                if ((RRR_R & 0xc) == 0x8) {
930
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
931
                }
932

    
933
                switch (RRR_R) {
934
                case 0: /*SNM0*/
935
                    switch (CALLX_M) {
936
                    case 0: /*ILL*/
937
                        gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
938
                        break;
939

    
940
                    case 1: /*reserved*/
941
                        RESERVED();
942
                        break;
943

    
944
                    case 2: /*JR*/
945
                        switch (CALLX_N) {
946
                        case 0: /*RET*/
947
                        case 2: /*JX*/
948
                            gen_window_check1(dc, CALLX_S);
949
                            gen_jump(dc, cpu_R[CALLX_S]);
950
                            break;
951

    
952
                        case 1: /*RETWw*/
953
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
954
                            {
955
                                TCGv_i32 tmp = tcg_const_i32(dc->pc);
956
                                gen_advance_ccount(dc);
957
                                gen_helper_retw(tmp, cpu_env, tmp);
958
                                gen_jump(dc, tmp);
959
                                tcg_temp_free(tmp);
960
                            }
961
                            break;
962

    
963
                        case 3: /*reserved*/
964
                            RESERVED();
965
                            break;
966
                        }
967
                        break;
968

    
969
                    case 3: /*CALLX*/
970
                        gen_window_check2(dc, CALLX_S, CALLX_N << 2);
971
                        switch (CALLX_N) {
972
                        case 0: /*CALLX0*/
973
                            {
974
                                TCGv_i32 tmp = tcg_temp_new_i32();
975
                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
976
                                tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
977
                                gen_jump(dc, tmp);
978
                                tcg_temp_free(tmp);
979
                            }
980
                            break;
981

    
982
                        case 1: /*CALLX4w*/
983
                        case 2: /*CALLX8w*/
984
                        case 3: /*CALLX12w*/
985
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
986
                            {
987
                                TCGv_i32 tmp = tcg_temp_new_i32();
988

    
989
                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);
990
                                gen_callw(dc, CALLX_N, tmp);
991
                                tcg_temp_free(tmp);
992
                            }
993
                            break;
994
                        }
995
                        break;
996
                    }
997
                    break;
998

    
999
                case 1: /*MOVSPw*/
1000
                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1001
                    gen_window_check2(dc, RRR_T, RRR_S);
1002
                    {
1003
                        TCGv_i32 pc = tcg_const_i32(dc->pc);
1004
                        gen_advance_ccount(dc);
1005
                        gen_helper_movsp(cpu_env, pc);
1006
                        tcg_gen_mov_i32(cpu_R[RRR_T], cpu_R[RRR_S]);
1007
                        tcg_temp_free(pc);
1008
                    }
1009
                    break;
1010

    
1011
                case 2: /*SYNC*/
1012
                    switch (RRR_T) {
1013
                    case 0: /*ISYNC*/
1014
                        break;
1015

    
1016
                    case 1: /*RSYNC*/
1017
                        break;
1018

    
1019
                    case 2: /*ESYNC*/
1020
                        break;
1021

    
1022
                    case 3: /*DSYNC*/
1023
                        break;
1024

    
1025
                    case 8: /*EXCW*/
1026
                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);
1027
                        break;
1028

    
1029
                    case 12: /*MEMW*/
1030
                        break;
1031

    
1032
                    case 13: /*EXTW*/
1033
                        break;
1034

    
1035
                    case 15: /*NOP*/
1036
                        break;
1037

    
1038
                    default: /*reserved*/
1039
                        RESERVED();
1040
                        break;
1041
                    }
1042
                    break;
1043

    
1044
                case 3: /*RFEIx*/
1045
                    switch (RRR_T) {
1046
                    case 0: /*RFETx*/
1047
                        HAS_OPTION(XTENSA_OPTION_EXCEPTION);
1048
                        switch (RRR_S) {
1049
                        case 0: /*RFEx*/
1050
                            gen_check_privilege(dc);
1051
                            tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
1052
                            gen_helper_check_interrupts(cpu_env);
1053
                            gen_jump(dc, cpu_SR[EPC1]);
1054
                            break;
1055

    
1056
                        case 1: /*RFUEx*/
1057
                            RESERVED();
1058
                            break;
1059

    
1060
                        case 2: /*RFDEx*/
1061
                            gen_check_privilege(dc);
1062
                            gen_jump(dc, cpu_SR[
1063
                                    dc->config->ndepc ? DEPC : EPC1]);
1064
                            break;
1065

    
1066
                        case 4: /*RFWOw*/
1067
                        case 5: /*RFWUw*/
1068
                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1069
                            gen_check_privilege(dc);
1070
                            {
1071
                                TCGv_i32 tmp = tcg_const_i32(1);
1072

    
1073
                                tcg_gen_andi_i32(
1074
                                        cpu_SR[PS], cpu_SR[PS], ~PS_EXCM);
1075
                                tcg_gen_shl_i32(tmp, tmp, cpu_SR[WINDOW_BASE]);
1076

    
1077
                                if (RRR_S == 4) {
1078
                                    tcg_gen_andc_i32(cpu_SR[WINDOW_START],
1079
                                            cpu_SR[WINDOW_START], tmp);
1080
                                } else {
1081
                                    tcg_gen_or_i32(cpu_SR[WINDOW_START],
1082
                                            cpu_SR[WINDOW_START], tmp);
1083
                                }
1084

    
1085
                                gen_helper_restore_owb(cpu_env);
1086
                                gen_helper_check_interrupts(cpu_env);
1087
                                gen_jump(dc, cpu_SR[EPC1]);
1088

    
1089
                                tcg_temp_free(tmp);
1090
                            }
1091
                            break;
1092

    
1093
                        default: /*reserved*/
1094
                            RESERVED();
1095
                            break;
1096
                        }
1097
                        break;
1098

    
1099
                    case 1: /*RFIx*/
1100
                        HAS_OPTION(XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT);
1101
                        if (RRR_S >= 2 && RRR_S <= dc->config->nlevel) {
1102
                            gen_check_privilege(dc);
1103
                            tcg_gen_mov_i32(cpu_SR[PS],
1104
                                    cpu_SR[EPS2 + RRR_S - 2]);
1105
                            gen_helper_check_interrupts(cpu_env);
1106
                            gen_jump(dc, cpu_SR[EPC1 + RRR_S - 1]);
1107
                        } else {
1108
                            qemu_log("RFI %d is illegal\n", RRR_S);
1109
                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1110
                        }
1111
                        break;
1112

    
1113
                    case 2: /*RFME*/
1114
                        TBD();
1115
                        break;
1116

    
1117
                    default: /*reserved*/
1118
                        RESERVED();
1119
                        break;
1120

    
1121
                    }
1122
                    break;
1123

    
1124
                case 4: /*BREAKx*/
1125
                    HAS_OPTION(XTENSA_OPTION_DEBUG);
1126
                    if (dc->debug) {
1127
                        gen_debug_exception(dc, DEBUGCAUSE_BI);
1128
                    }
1129
                    break;
1130

    
1131
                case 5: /*SYSCALLx*/
1132
                    HAS_OPTION(XTENSA_OPTION_EXCEPTION);
1133
                    switch (RRR_S) {
1134
                    case 0: /*SYSCALLx*/
1135
                        gen_exception_cause(dc, SYSCALL_CAUSE);
1136
                        break;
1137

    
1138
                    case 1: /*SIMCALL*/
1139
                        if (semihosting_enabled) {
1140
                            gen_check_privilege(dc);
1141
                            gen_helper_simcall(cpu_env);
1142
                        } else {
1143
                            qemu_log("SIMCALL but semihosting is disabled\n");
1144
                            gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
1145
                        }
1146
                        break;
1147

    
1148
                    default:
1149
                        RESERVED();
1150
                        break;
1151
                    }
1152
                    break;
1153

    
1154
                case 6: /*RSILx*/
1155
                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);
1156
                    gen_check_privilege(dc);
1157
                    gen_window_check1(dc, RRR_T);
1158
                    tcg_gen_mov_i32(cpu_R[RRR_T], cpu_SR[PS]);
1159
                    tcg_gen_andi_i32(cpu_SR[PS], cpu_SR[PS], ~PS_INTLEVEL);
1160
                    tcg_gen_ori_i32(cpu_SR[PS], cpu_SR[PS], RRR_S);
1161
                    gen_helper_check_interrupts(cpu_env);
1162
                    gen_jumpi_check_loop_end(dc, 0);
1163
                    break;
1164

    
1165
                case 7: /*WAITIx*/
1166
                    HAS_OPTION(XTENSA_OPTION_INTERRUPT);
1167
                    gen_check_privilege(dc);
1168
                    gen_waiti(dc, RRR_S);
1169
                    break;
1170

    
1171
                case 8: /*ANY4p*/
1172
                case 9: /*ALL4p*/
1173
                case 10: /*ANY8p*/
1174
                case 11: /*ALL8p*/
1175
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1176
                    {
1177
                        const unsigned shift = (RRR_R & 2) ? 8 : 4;
1178
                        TCGv_i32 mask = tcg_const_i32(
1179
                                ((1 << shift) - 1) << RRR_S);
1180
                        TCGv_i32 tmp = tcg_temp_new_i32();
1181

    
1182
                        tcg_gen_and_i32(tmp, cpu_SR[BR], mask);
1183
                        if (RRR_R & 1) { /*ALL*/
1184
                            tcg_gen_addi_i32(tmp, tmp, 1 << RRR_S);
1185
                        } else { /*ANY*/
1186
                            tcg_gen_add_i32(tmp, tmp, mask);
1187
                        }
1188
                        tcg_gen_shri_i32(tmp, tmp, RRR_S + shift);
1189
                        tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR],
1190
                                tmp, RRR_T, 1);
1191
                        tcg_temp_free(mask);
1192
                        tcg_temp_free(tmp);
1193
                    }
1194
                    break;
1195

    
1196
                default: /*reserved*/
1197
                    RESERVED();
1198
                    break;
1199

    
1200
                }
1201
                break;
1202

    
1203
            case 1: /*AND*/
1204
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1205
                tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1206
                break;
1207

    
1208
            case 2: /*OR*/
1209
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1210
                tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1211
                break;
1212

    
1213
            case 3: /*XOR*/
1214
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1215
                tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1216
                break;
1217

    
1218
            case 4: /*ST1*/
1219
                switch (RRR_R) {
1220
                case 0: /*SSR*/
1221
                    gen_window_check1(dc, RRR_S);
1222
                    gen_right_shift_sar(dc, cpu_R[RRR_S]);
1223
                    break;
1224

    
1225
                case 1: /*SSL*/
1226
                    gen_window_check1(dc, RRR_S);
1227
                    gen_left_shift_sar(dc, cpu_R[RRR_S]);
1228
                    break;
1229

    
1230
                case 2: /*SSA8L*/
1231
                    gen_window_check1(dc, RRR_S);
1232
                    {
1233
                        TCGv_i32 tmp = tcg_temp_new_i32();
1234
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1235
                        gen_right_shift_sar(dc, tmp);
1236
                        tcg_temp_free(tmp);
1237
                    }
1238
                    break;
1239

    
1240
                case 3: /*SSA8B*/
1241
                    gen_window_check1(dc, RRR_S);
1242
                    {
1243
                        TCGv_i32 tmp = tcg_temp_new_i32();
1244
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);
1245
                        gen_left_shift_sar(dc, tmp);
1246
                        tcg_temp_free(tmp);
1247
                    }
1248
                    break;
1249

    
1250
                case 4: /*SSAI*/
1251
                    {
1252
                        TCGv_i32 tmp = tcg_const_i32(
1253
                                RRR_S | ((RRR_T & 1) << 4));
1254
                        gen_right_shift_sar(dc, tmp);
1255
                        tcg_temp_free(tmp);
1256
                    }
1257
                    break;
1258

    
1259
                case 6: /*RER*/
1260
                    TBD();
1261
                    break;
1262

    
1263
                case 7: /*WER*/
1264
                    TBD();
1265
                    break;
1266

    
1267
                case 8: /*ROTWw*/
1268
                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1269
                    gen_check_privilege(dc);
1270
                    {
1271
                        TCGv_i32 tmp = tcg_const_i32(
1272
                                RRR_T | ((RRR_T & 8) ? 0xfffffff0 : 0));
1273
                        gen_helper_rotw(cpu_env, tmp);
1274
                        tcg_temp_free(tmp);
1275
                        reset_used_window(dc);
1276
                    }
1277
                    break;
1278

    
1279
                case 14: /*NSAu*/
1280
                    HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);
1281
                    gen_window_check2(dc, RRR_S, RRR_T);
1282
                    gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);
1283
                    break;
1284

    
1285
                case 15: /*NSAUu*/
1286
                    HAS_OPTION(XTENSA_OPTION_MISC_OP_NSA);
1287
                    gen_window_check2(dc, RRR_S, RRR_T);
1288
                    gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);
1289
                    break;
1290

    
1291
                default: /*reserved*/
1292
                    RESERVED();
1293
                    break;
1294
                }
1295
                break;
1296

    
1297
            case 5: /*TLB*/
1298
                HAS_OPTION_BITS(
1299
                        XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
1300
                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
1301
                        XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION));
1302
                gen_check_privilege(dc);
1303
                gen_window_check2(dc, RRR_S, RRR_T);
1304
                {
1305
                    TCGv_i32 dtlb = tcg_const_i32((RRR_R & 8) != 0);
1306

    
1307
                    switch (RRR_R & 7) {
1308
                    case 3: /*RITLB0*/ /*RDTLB0*/
1309
                        gen_helper_rtlb0(cpu_R[RRR_T],
1310
                                cpu_env, cpu_R[RRR_S], dtlb);
1311
                        break;
1312

    
1313
                    case 4: /*IITLB*/ /*IDTLB*/
1314
                        gen_helper_itlb(cpu_env, cpu_R[RRR_S], dtlb);
1315
                        /* This could change memory mapping, so exit tb */
1316
                        gen_jumpi_check_loop_end(dc, -1);
1317
                        break;
1318

    
1319
                    case 5: /*PITLB*/ /*PDTLB*/
1320
                        tcg_gen_movi_i32(cpu_pc, dc->pc);
1321
                        gen_helper_ptlb(cpu_R[RRR_T],
1322
                                cpu_env, cpu_R[RRR_S], dtlb);
1323
                        break;
1324

    
1325
                    case 6: /*WITLB*/ /*WDTLB*/
1326
                        gen_helper_wtlb(
1327
                                cpu_env, cpu_R[RRR_T], cpu_R[RRR_S], dtlb);
1328
                        /* This could change memory mapping, so exit tb */
1329
                        gen_jumpi_check_loop_end(dc, -1);
1330
                        break;
1331

    
1332
                    case 7: /*RITLB1*/ /*RDTLB1*/
1333
                        gen_helper_rtlb1(cpu_R[RRR_T],
1334
                                cpu_env, cpu_R[RRR_S], dtlb);
1335
                        break;
1336

    
1337
                    default:
1338
                        tcg_temp_free(dtlb);
1339
                        RESERVED();
1340
                        break;
1341
                    }
1342
                    tcg_temp_free(dtlb);
1343
                }
1344
                break;
1345

    
1346
            case 6: /*RT0*/
1347
                gen_window_check2(dc, RRR_R, RRR_T);
1348
                switch (RRR_S) {
1349
                case 0: /*NEG*/
1350
                    tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1351
                    break;
1352

    
1353
                case 1: /*ABS*/
1354
                    {
1355
                        int label = gen_new_label();
1356
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1357
                        tcg_gen_brcondi_i32(
1358
                                TCG_COND_GE, cpu_R[RRR_R], 0, label);
1359
                        tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1360
                        gen_set_label(label);
1361
                    }
1362
                    break;
1363

    
1364
                default: /*reserved*/
1365
                    RESERVED();
1366
                    break;
1367
                }
1368
                break;
1369

    
1370
            case 7: /*reserved*/
1371
                RESERVED();
1372
                break;
1373

    
1374
            case 8: /*ADD*/
1375
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1376
                tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1377
                break;
1378

    
1379
            case 9: /*ADD**/
1380
            case 10:
1381
            case 11:
1382
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1383
                {
1384
                    TCGv_i32 tmp = tcg_temp_new_i32();
1385
                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);
1386
                    tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1387
                    tcg_temp_free(tmp);
1388
                }
1389
                break;
1390

    
1391
            case 12: /*SUB*/
1392
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1393
                tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1394
                break;
1395

    
1396
            case 13: /*SUB**/
1397
            case 14:
1398
            case 15:
1399
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1400
                {
1401
                    TCGv_i32 tmp = tcg_temp_new_i32();
1402
                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);
1403
                    tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);
1404
                    tcg_temp_free(tmp);
1405
                }
1406
                break;
1407
            }
1408
            break;
1409

    
1410
        case 1: /*RST1*/
1411
            switch (OP2) {
1412
            case 0: /*SLLI*/
1413
            case 1:
1414
                gen_window_check2(dc, RRR_R, RRR_S);
1415
                tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],
1416
                        32 - (RRR_T | ((OP2 & 1) << 4)));
1417
                break;
1418

    
1419
            case 2: /*SRAI*/
1420
            case 3:
1421
                gen_window_check2(dc, RRR_R, RRR_T);
1422
                tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],
1423
                        RRR_S | ((OP2 & 1) << 4));
1424
                break;
1425

    
1426
            case 4: /*SRLI*/
1427
                gen_window_check2(dc, RRR_R, RRR_T);
1428
                tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);
1429
                break;
1430

    
1431
            case 6: /*XSR*/
1432
                {
1433
                    TCGv_i32 tmp = tcg_temp_new_i32();
1434
                    if (RSR_SR >= 64) {
1435
                        gen_check_privilege(dc);
1436
                    }
1437
                    gen_window_check1(dc, RRR_T);
1438
                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
1439
                    gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1440
                    gen_wsr(dc, RSR_SR, tmp);
1441
                    tcg_temp_free(tmp);
1442
                    if (!sregnames[RSR_SR]) {
1443
                        TBD();
1444
                    }
1445
                }
1446
                break;
1447

    
1448
                /*
1449
                 * Note: 64 bit ops are used here solely because SAR values
1450
                 * have range 0..63
1451
                 */
1452
#define gen_shift_reg(cmd, reg) do { \
1453
                    TCGv_i64 tmp = tcg_temp_new_i64(); \
1454
                    tcg_gen_extu_i32_i64(tmp, reg); \
1455
                    tcg_gen_##cmd##_i64(v, v, tmp); \
1456
                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \
1457
                    tcg_temp_free_i64(v); \
1458
                    tcg_temp_free_i64(tmp); \
1459
                } while (0)
1460

    
1461
#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])
1462

    
1463
            case 8: /*SRC*/
1464
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1465
                {
1466
                    TCGv_i64 v = tcg_temp_new_i64();
1467
                    tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);
1468
                    gen_shift(shr);
1469
                }
1470
                break;
1471

    
1472
            case 9: /*SRL*/
1473
                gen_window_check2(dc, RRR_R, RRR_T);
1474
                if (dc->sar_5bit) {
1475
                    tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1476
                } else {
1477
                    TCGv_i64 v = tcg_temp_new_i64();
1478
                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);
1479
                    gen_shift(shr);
1480
                }
1481
                break;
1482

    
1483
            case 10: /*SLL*/
1484
                gen_window_check2(dc, RRR_R, RRR_S);
1485
                if (dc->sar_m32_5bit) {
1486
                    tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);
1487
                } else {
1488
                    TCGv_i64 v = tcg_temp_new_i64();
1489
                    TCGv_i32 s = tcg_const_i32(32);
1490
                    tcg_gen_sub_i32(s, s, cpu_SR[SAR]);
1491
                    tcg_gen_andi_i32(s, s, 0x3f);
1492
                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);
1493
                    gen_shift_reg(shl, s);
1494
                    tcg_temp_free(s);
1495
                }
1496
                break;
1497

    
1498
            case 11: /*SRA*/
1499
                gen_window_check2(dc, RRR_R, RRR_T);
1500
                if (dc->sar_5bit) {
1501
                    tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);
1502
                } else {
1503
                    TCGv_i64 v = tcg_temp_new_i64();
1504
                    tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);
1505
                    gen_shift(sar);
1506
                }
1507
                break;
1508
#undef gen_shift
1509
#undef gen_shift_reg
1510

    
1511
            case 12: /*MUL16U*/
1512
                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1513
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1514
                {
1515
                    TCGv_i32 v1 = tcg_temp_new_i32();
1516
                    TCGv_i32 v2 = tcg_temp_new_i32();
1517
                    tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);
1518
                    tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);
1519
                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1520
                    tcg_temp_free(v2);
1521
                    tcg_temp_free(v1);
1522
                }
1523
                break;
1524

    
1525
            case 13: /*MUL16S*/
1526
                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);
1527
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1528
                {
1529
                    TCGv_i32 v1 = tcg_temp_new_i32();
1530
                    TCGv_i32 v2 = tcg_temp_new_i32();
1531
                    tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);
1532
                    tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);
1533
                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);
1534
                    tcg_temp_free(v2);
1535
                    tcg_temp_free(v1);
1536
                }
1537
                break;
1538

    
1539
            default: /*reserved*/
1540
                RESERVED();
1541
                break;
1542
            }
1543
            break;
1544

    
1545
        case 2: /*RST2*/
1546
            if (OP2 >= 8) {
1547
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1548
            }
1549

    
1550
            if (OP2 >= 12) {
1551
                HAS_OPTION(XTENSA_OPTION_32_BIT_IDIV);
1552
                int label = gen_new_label();
1553
                tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0, label);
1554
                gen_exception_cause(dc, INTEGER_DIVIDE_BY_ZERO_CAUSE);
1555
                gen_set_label(label);
1556
            }
1557

    
1558
            switch (OP2) {
1559
#define BOOLEAN_LOGIC(fn, r, s, t) \
1560
                do { \
1561
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN); \
1562
                    TCGv_i32 tmp1 = tcg_temp_new_i32(); \
1563
                    TCGv_i32 tmp2 = tcg_temp_new_i32(); \
1564
                    \
1565
                    tcg_gen_shri_i32(tmp1, cpu_SR[BR], s); \
1566
                    tcg_gen_shri_i32(tmp2, cpu_SR[BR], t); \
1567
                    tcg_gen_##fn##_i32(tmp1, tmp1, tmp2); \
1568
                    tcg_gen_deposit_i32(cpu_SR[BR], cpu_SR[BR], tmp1, r, 1); \
1569
                    tcg_temp_free(tmp1); \
1570
                    tcg_temp_free(tmp2); \
1571
                } while (0)
1572

    
1573
            case 0: /*ANDBp*/
1574
                BOOLEAN_LOGIC(and, RRR_R, RRR_S, RRR_T);
1575
                break;
1576

    
1577
            case 1: /*ANDBCp*/
1578
                BOOLEAN_LOGIC(andc, RRR_R, RRR_S, RRR_T);
1579
                break;
1580

    
1581
            case 2: /*ORBp*/
1582
                BOOLEAN_LOGIC(or, RRR_R, RRR_S, RRR_T);
1583
                break;
1584

    
1585
            case 3: /*ORBCp*/
1586
                BOOLEAN_LOGIC(orc, RRR_R, RRR_S, RRR_T);
1587
                break;
1588

    
1589
            case 4: /*XORBp*/
1590
                BOOLEAN_LOGIC(xor, RRR_R, RRR_S, RRR_T);
1591
                break;
1592

    
1593
#undef BOOLEAN_LOGIC
1594

    
1595
            case 8: /*MULLi*/
1596
                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL);
1597
                tcg_gen_mul_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1598
                break;
1599

    
1600
            case 10: /*MULUHi*/
1601
            case 11: /*MULSHi*/
1602
                HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL_HIGH);
1603
                {
1604
                    TCGv_i64 r = tcg_temp_new_i64();
1605
                    TCGv_i64 s = tcg_temp_new_i64();
1606
                    TCGv_i64 t = tcg_temp_new_i64();
1607

    
1608
                    if (OP2 == 10) {
1609
                        tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);
1610
                        tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);
1611
                    } else {
1612
                        tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);
1613
                        tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);
1614
                    }
1615
                    tcg_gen_mul_i64(r, s, t);
1616
                    tcg_gen_shri_i64(r, r, 32);
1617
                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);
1618

    
1619
                    tcg_temp_free_i64(r);
1620
                    tcg_temp_free_i64(s);
1621
                    tcg_temp_free_i64(t);
1622
                }
1623
                break;
1624

    
1625
            case 12: /*QUOUi*/
1626
                tcg_gen_divu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1627
                break;
1628

    
1629
            case 13: /*QUOSi*/
1630
            case 15: /*REMSi*/
1631
                {
1632
                    int label1 = gen_new_label();
1633
                    int label2 = gen_new_label();
1634

    
1635
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_S], 0x80000000,
1636
                            label1);
1637
                    tcg_gen_brcondi_i32(TCG_COND_NE, cpu_R[RRR_T], 0xffffffff,
1638
                            label1);
1639
                    tcg_gen_movi_i32(cpu_R[RRR_R],
1640
                            OP2 == 13 ? 0x80000000 : 0);
1641
                    tcg_gen_br(label2);
1642
                    gen_set_label(label1);
1643
                    if (OP2 == 13) {
1644
                        tcg_gen_div_i32(cpu_R[RRR_R],
1645
                                cpu_R[RRR_S], cpu_R[RRR_T]);
1646
                    } else {
1647
                        tcg_gen_rem_i32(cpu_R[RRR_R],
1648
                                cpu_R[RRR_S], cpu_R[RRR_T]);
1649
                    }
1650
                    gen_set_label(label2);
1651
                }
1652
                break;
1653

    
1654
            case 14: /*REMUi*/
1655
                tcg_gen_remu_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);
1656
                break;
1657

    
1658
            default: /*reserved*/
1659
                RESERVED();
1660
                break;
1661
            }
1662
            break;
1663

    
1664
        case 3: /*RST3*/
1665
            switch (OP2) {
1666
            case 0: /*RSR*/
1667
                if (RSR_SR >= 64) {
1668
                    gen_check_privilege(dc);
1669
                }
1670
                gen_window_check1(dc, RRR_T);
1671
                gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
1672
                if (!sregnames[RSR_SR]) {
1673
                    TBD();
1674
                }
1675
                break;
1676

    
1677
            case 1: /*WSR*/
1678
                if (RSR_SR >= 64) {
1679
                    gen_check_privilege(dc);
1680
                }
1681
                gen_window_check1(dc, RRR_T);
1682
                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
1683
                if (!sregnames[RSR_SR]) {
1684
                    TBD();
1685
                }
1686
                break;
1687

    
1688
            case 2: /*SEXTu*/
1689
                HAS_OPTION(XTENSA_OPTION_MISC_OP_SEXT);
1690
                gen_window_check2(dc, RRR_R, RRR_S);
1691
                {
1692
                    int shift = 24 - RRR_T;
1693

    
1694
                    if (shift == 24) {
1695
                        tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1696
                    } else if (shift == 16) {
1697
                        tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1698
                    } else {
1699
                        TCGv_i32 tmp = tcg_temp_new_i32();
1700
                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);
1701
                        tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);
1702
                        tcg_temp_free(tmp);
1703
                    }
1704
                }
1705
                break;
1706

    
1707
            case 3: /*CLAMPSu*/
1708
                HAS_OPTION(XTENSA_OPTION_MISC_OP_CLAMPS);
1709
                gen_window_check2(dc, RRR_R, RRR_S);
1710
                {
1711
                    TCGv_i32 tmp1 = tcg_temp_new_i32();
1712
                    TCGv_i32 tmp2 = tcg_temp_new_i32();
1713
                    int label = gen_new_label();
1714

    
1715
                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);
1716
                    tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);
1717
                    tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));
1718
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1719
                    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);
1720

    
1721
                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);
1722
                    tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,
1723
                            0xffffffff >> (25 - RRR_T));
1724

    
1725
                    gen_set_label(label);
1726

    
1727
                    tcg_temp_free(tmp1);
1728
                    tcg_temp_free(tmp2);
1729
                }
1730
                break;
1731

    
1732
            case 4: /*MINu*/
1733
            case 5: /*MAXu*/
1734
            case 6: /*MINUu*/
1735
            case 7: /*MAXUu*/
1736
                HAS_OPTION(XTENSA_OPTION_MISC_OP_MINMAX);
1737
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1738
                {
1739
                    static const TCGCond cond[] = {
1740
                        TCG_COND_LE,
1741
                        TCG_COND_GE,
1742
                        TCG_COND_LEU,
1743
                        TCG_COND_GEU
1744
                    };
1745
                    int label = gen_new_label();
1746

    
1747
                    if (RRR_R != RRR_T) {
1748
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1749
                        tcg_gen_brcond_i32(cond[OP2 - 4],
1750
                                cpu_R[RRR_S], cpu_R[RRR_T], label);
1751
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);
1752
                    } else {
1753
                        tcg_gen_brcond_i32(cond[OP2 - 4],
1754
                                cpu_R[RRR_T], cpu_R[RRR_S], label);
1755
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1756
                    }
1757
                    gen_set_label(label);
1758
                }
1759
                break;
1760

    
1761
            case 8: /*MOVEQZ*/
1762
            case 9: /*MOVNEZ*/
1763
            case 10: /*MOVLTZ*/
1764
            case 11: /*MOVGEZ*/
1765
                gen_window_check3(dc, RRR_R, RRR_S, RRR_T);
1766
                {
1767
                    static const TCGCond cond[] = {
1768
                        TCG_COND_NE,
1769
                        TCG_COND_EQ,
1770
                        TCG_COND_GE,
1771
                        TCG_COND_LT
1772
                    };
1773
                    int label = gen_new_label();
1774
                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
1775
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1776
                    gen_set_label(label);
1777
                }
1778
                break;
1779

    
1780
            case 12: /*MOVFp*/
1781
            case 13: /*MOVTp*/
1782
                HAS_OPTION(XTENSA_OPTION_BOOLEAN);
1783
                gen_window_check2(dc, RRR_R, RRR_S);
1784
                {
1785
                    int label = gen_new_label();
1786
                    TCGv_i32 tmp = tcg_temp_new_i32();
1787

    
1788
                    tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
1789
                    tcg_gen_brcondi_i32(
1790
                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
1791
                            tmp, 0, label);
1792
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);
1793
                    gen_set_label(label);
1794
                    tcg_temp_free(tmp);
1795
                }
1796
                break;
1797

    
1798
            case 14: /*RUR*/
1799
                gen_window_check1(dc, RRR_R);
1800
                {
1801
                    int st = (RRR_S << 4) + RRR_T;
1802
                    if (uregnames[st]) {
1803
                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);
1804
                    } else {
1805
                        qemu_log("RUR %d not implemented, ", st);
1806
                        TBD();
1807
                    }
1808
                }
1809
                break;
1810

    
1811
            case 15: /*WUR*/
1812
                gen_window_check1(dc, RRR_T);
1813
                if (uregnames[RSR_SR]) {
1814
                    gen_wur(RSR_SR, cpu_R[RRR_T]);
1815
                } else {
1816
                    qemu_log("WUR %d not implemented, ", RSR_SR);
1817
                    TBD();
1818
                }
1819
                break;
1820

    
1821
            }
1822
            break;
1823

    
1824
        case 4: /*EXTUI*/
1825
        case 5:
1826
            gen_window_check2(dc, RRR_R, RRR_T);
1827
            {
1828
                int shiftimm = RRR_S | ((OP1 & 1) << 4);
1829
                int maskimm = (1 << (OP2 + 1)) - 1;
1830

    
1831
                TCGv_i32 tmp = tcg_temp_new_i32();
1832
                tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
1833
                tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
1834
                tcg_temp_free(tmp);
1835
            }
1836
            break;
1837

    
1838
        case 6: /*CUST0*/
1839
            RESERVED();
1840
            break;
1841

    
1842
        case 7: /*CUST1*/
1843
            RESERVED();
1844
            break;
1845

    
1846
        case 8: /*LSCXp*/
1847
            switch (OP2) {
1848
            case 0: /*LSXf*/
1849
            case 1: /*LSXUf*/
1850
            case 4: /*SSXf*/
1851
            case 5: /*SSXUf*/
1852
                HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1853
                gen_window_check2(dc, RRR_S, RRR_T);
1854
                gen_check_cpenable(dc, 0);
1855
                {
1856
                    TCGv_i32 addr = tcg_temp_new_i32();
1857
                    tcg_gen_add_i32(addr, cpu_R[RRR_S], cpu_R[RRR_T]);
1858
                    gen_load_store_alignment(dc, 2, addr, false);
1859
                    if (OP2 & 0x4) {
1860
                        tcg_gen_qemu_st32(cpu_FR[RRR_R], addr, dc->cring);
1861
                    } else {
1862
                        tcg_gen_qemu_ld32u(cpu_FR[RRR_R], addr, dc->cring);
1863
                    }
1864
                    if (OP2 & 0x1) {
1865
                        tcg_gen_mov_i32(cpu_R[RRR_S], addr);
1866
                    }
1867
                    tcg_temp_free(addr);
1868
                }
1869
                break;
1870

    
1871
            default: /*reserved*/
1872
                RESERVED();
1873
                break;
1874
            }
1875
            break;
1876

    
1877
        case 9: /*LSC4*/
1878
            gen_window_check2(dc, RRR_S, RRR_T);
1879
            switch (OP2) {
1880
            case 0: /*L32E*/
1881
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1882
                gen_check_privilege(dc);
1883
                {
1884
                    TCGv_i32 addr = tcg_temp_new_i32();
1885
                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1886
                            (0xffffffc0 | (RRR_R << 2)));
1887
                    tcg_gen_qemu_ld32u(cpu_R[RRR_T], addr, dc->ring);
1888
                    tcg_temp_free(addr);
1889
                }
1890
                break;
1891

    
1892
            case 4: /*S32E*/
1893
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
1894
                gen_check_privilege(dc);
1895
                {
1896
                    TCGv_i32 addr = tcg_temp_new_i32();
1897
                    tcg_gen_addi_i32(addr, cpu_R[RRR_S],
1898
                            (0xffffffc0 | (RRR_R << 2)));
1899
                    tcg_gen_qemu_st32(cpu_R[RRR_T], addr, dc->ring);
1900
                    tcg_temp_free(addr);
1901
                }
1902
                break;
1903

    
1904
            default:
1905
                RESERVED();
1906
                break;
1907
            }
1908
            break;
1909

    
1910
        case 10: /*FP0*/
1911
            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
1912
            switch (OP2) {
1913
            case 0: /*ADD.Sf*/
1914
                gen_check_cpenable(dc, 0);
1915
                gen_helper_add_s(cpu_FR[RRR_R], cpu_env,
1916
                        cpu_FR[RRR_S], cpu_FR[RRR_T]);
1917
                break;
1918

    
1919
            case 1: /*SUB.Sf*/
1920
                gen_check_cpenable(dc, 0);
1921
                gen_helper_sub_s(cpu_FR[RRR_R], cpu_env,
1922
                        cpu_FR[RRR_S], cpu_FR[RRR_T]);
1923
                break;
1924

    
1925
            case 2: /*MUL.Sf*/
1926
                gen_check_cpenable(dc, 0);
1927
                gen_helper_mul_s(cpu_FR[RRR_R], cpu_env,
1928
                        cpu_FR[RRR_S], cpu_FR[RRR_T]);
1929
                break;
1930

    
1931
            case 4: /*MADD.Sf*/
1932
                gen_check_cpenable(dc, 0);
1933
                gen_helper_madd_s(cpu_FR[RRR_R], cpu_env,
1934
                        cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
1935
                break;
1936

    
1937
            case 5: /*MSUB.Sf*/
1938
                gen_check_cpenable(dc, 0);
1939
                gen_helper_msub_s(cpu_FR[RRR_R], cpu_env,
1940
                        cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
1941
                break;
1942

    
1943
            case 8: /*ROUND.Sf*/
1944
            case 9: /*TRUNC.Sf*/
1945
            case 10: /*FLOOR.Sf*/
1946
            case 11: /*CEIL.Sf*/
1947
            case 14: /*UTRUNC.Sf*/
1948
                gen_window_check1(dc, RRR_R);
1949
                gen_check_cpenable(dc, 0);
1950
                {
1951
                    static const unsigned rounding_mode_const[] = {
1952
                        float_round_nearest_even,
1953
                        float_round_to_zero,
1954
                        float_round_down,
1955
                        float_round_up,
1956
                        [6] = float_round_to_zero,
1957
                    };
1958
                    TCGv_i32 rounding_mode = tcg_const_i32(
1959
                            rounding_mode_const[OP2 & 7]);
1960
                    TCGv_i32 scale = tcg_const_i32(RRR_T);
1961

    
1962
                    if (OP2 == 14) {
1963
                        gen_helper_ftoui(cpu_R[RRR_R], cpu_FR[RRR_S],
1964
                                rounding_mode, scale);
1965
                    } else {
1966
                        gen_helper_ftoi(cpu_R[RRR_R], cpu_FR[RRR_S],
1967
                                rounding_mode, scale);
1968
                    }
1969

    
1970
                    tcg_temp_free(rounding_mode);
1971
                    tcg_temp_free(scale);
1972
                }
1973
                break;
1974

    
1975
            case 12: /*FLOAT.Sf*/
1976
            case 13: /*UFLOAT.Sf*/
1977
                gen_window_check1(dc, RRR_S);
1978
                gen_check_cpenable(dc, 0);
1979
                {
1980
                    TCGv_i32 scale = tcg_const_i32(-RRR_T);
1981

    
1982
                    if (OP2 == 13) {
1983
                        gen_helper_uitof(cpu_FR[RRR_R], cpu_env,
1984
                                cpu_R[RRR_S], scale);
1985
                    } else {
1986
                        gen_helper_itof(cpu_FR[RRR_R], cpu_env,
1987
                                cpu_R[RRR_S], scale);
1988
                    }
1989
                    tcg_temp_free(scale);
1990
                }
1991
                break;
1992

    
1993
            case 15: /*FP1OP*/
1994
                switch (RRR_T) {
1995
                case 0: /*MOV.Sf*/
1996
                    gen_check_cpenable(dc, 0);
1997
                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
1998
                    break;
1999

    
2000
                case 1: /*ABS.Sf*/
2001
                    gen_check_cpenable(dc, 0);
2002
                    gen_helper_abs_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
2003
                    break;
2004

    
2005
                case 4: /*RFRf*/
2006
                    gen_window_check1(dc, RRR_R);
2007
                    gen_check_cpenable(dc, 0);
2008
                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_FR[RRR_S]);
2009
                    break;
2010

    
2011
                case 5: /*WFRf*/
2012
                    gen_window_check1(dc, RRR_S);
2013
                    gen_check_cpenable(dc, 0);
2014
                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_R[RRR_S]);
2015
                    break;
2016

    
2017
                case 6: /*NEG.Sf*/
2018
                    gen_check_cpenable(dc, 0);
2019
                    gen_helper_neg_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
2020
                    break;
2021

    
2022
                default: /*reserved*/
2023
                    RESERVED();
2024
                    break;
2025
                }
2026
                break;
2027

    
2028
            default: /*reserved*/
2029
                RESERVED();
2030
                break;
2031
            }
2032
            break;
2033

    
2034
        case 11: /*FP1*/
2035
            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
2036

    
2037
#define gen_compare(rel, br, a, b) \
2038
    do { \
2039
        TCGv_i32 bit = tcg_const_i32(1 << br); \
2040
        \
2041
        gen_check_cpenable(dc, 0); \
2042
        gen_helper_##rel(cpu_env, bit, cpu_FR[a], cpu_FR[b]); \
2043
        tcg_temp_free(bit); \
2044
    } while (0)
2045

    
2046
            switch (OP2) {
2047
            case 1: /*UN.Sf*/
2048
                gen_compare(un_s, RRR_R, RRR_S, RRR_T);
2049
                break;
2050

    
2051
            case 2: /*OEQ.Sf*/
2052
                gen_compare(oeq_s, RRR_R, RRR_S, RRR_T);
2053
                break;
2054

    
2055
            case 3: /*UEQ.Sf*/
2056
                gen_compare(ueq_s, RRR_R, RRR_S, RRR_T);
2057
                break;
2058

    
2059
            case 4: /*OLT.Sf*/
2060
                gen_compare(olt_s, RRR_R, RRR_S, RRR_T);
2061
                break;
2062

    
2063
            case 5: /*ULT.Sf*/
2064
                gen_compare(ult_s, RRR_R, RRR_S, RRR_T);
2065
                break;
2066

    
2067
            case 6: /*OLE.Sf*/
2068
                gen_compare(ole_s, RRR_R, RRR_S, RRR_T);
2069
                break;
2070

    
2071
            case 7: /*ULE.Sf*/
2072
                gen_compare(ule_s, RRR_R, RRR_S, RRR_T);
2073
                break;
2074

    
2075
#undef gen_compare
2076

    
2077
            case 8: /*MOVEQZ.Sf*/
2078
            case 9: /*MOVNEZ.Sf*/
2079
            case 10: /*MOVLTZ.Sf*/
2080
            case 11: /*MOVGEZ.Sf*/
2081
                gen_window_check1(dc, RRR_T);
2082
                gen_check_cpenable(dc, 0);
2083
                {
2084
                    static const TCGCond cond[] = {
2085
                        TCG_COND_NE,
2086
                        TCG_COND_EQ,
2087
                        TCG_COND_GE,
2088
                        TCG_COND_LT
2089
                    };
2090
                    int label = gen_new_label();
2091
                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);
2092
                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
2093
                    gen_set_label(label);
2094
                }
2095
                break;
2096

    
2097
            case 12: /*MOVF.Sf*/
2098
            case 13: /*MOVT.Sf*/
2099
                HAS_OPTION(XTENSA_OPTION_BOOLEAN);
2100
                gen_check_cpenable(dc, 0);
2101
                {
2102
                    int label = gen_new_label();
2103
                    TCGv_i32 tmp = tcg_temp_new_i32();
2104

    
2105
                    tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRR_T);
2106
                    tcg_gen_brcondi_i32(
2107
                            OP2 & 1 ? TCG_COND_EQ : TCG_COND_NE,
2108
                            tmp, 0, label);
2109
                    tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
2110
                    gen_set_label(label);
2111
                    tcg_temp_free(tmp);
2112
                }
2113
                break;
2114

    
2115
            default: /*reserved*/
2116
                RESERVED();
2117
                break;
2118
            }
2119
            break;
2120

    
2121
        default: /*reserved*/
2122
            RESERVED();
2123
            break;
2124
        }
2125
        break;
2126

    
2127
    case 1: /*L32R*/
2128
        gen_window_check1(dc, RRR_T);
2129
        {
2130
            TCGv_i32 tmp = tcg_const_i32(
2131
                    ((dc->tb->flags & XTENSA_TBFLAG_LITBASE) ?
2132
                     0 : ((dc->pc + 3) & ~3)) +
2133
                    (0xfffc0000 | (RI16_IMM16 << 2)));
2134

    
2135
            if (dc->tb->flags & XTENSA_TBFLAG_LITBASE) {
2136
                tcg_gen_add_i32(tmp, tmp, dc->litbase);
2137
            }
2138
            tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, dc->cring);
2139
            tcg_temp_free(tmp);
2140
        }
2141
        break;
2142

    
2143
    case 2: /*LSAI*/
2144
#define gen_load_store(type, shift) do { \
2145
            TCGv_i32 addr = tcg_temp_new_i32(); \
2146
            gen_window_check2(dc, RRI8_S, RRI8_T); \
2147
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \
2148
            if (shift) { \
2149
                gen_load_store_alignment(dc, shift, addr, false); \
2150
            } \
2151
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
2152
            tcg_temp_free(addr); \
2153
        } while (0)
2154

    
2155
        switch (RRI8_R) {
2156
        case 0: /*L8UI*/
2157
            gen_load_store(ld8u, 0);
2158
            break;
2159

    
2160
        case 1: /*L16UI*/
2161
            gen_load_store(ld16u, 1);
2162
            break;
2163

    
2164
        case 2: /*L32I*/
2165
            gen_load_store(ld32u, 2);
2166
            break;
2167

    
2168
        case 4: /*S8I*/
2169
            gen_load_store(st8, 0);
2170
            break;
2171

    
2172
        case 5: /*S16I*/
2173
            gen_load_store(st16, 1);
2174
            break;
2175

    
2176
        case 6: /*S32I*/
2177
            gen_load_store(st32, 2);
2178
            break;
2179

    
2180
        case 7: /*CACHEc*/
2181
            if (RRI8_T < 8) {
2182
                HAS_OPTION(XTENSA_OPTION_DCACHE);
2183
            }
2184

    
2185
            switch (RRI8_T) {
2186
            case 0: /*DPFRc*/
2187
                break;
2188

    
2189
            case 1: /*DPFWc*/
2190
                break;
2191

    
2192
            case 2: /*DPFROc*/
2193
                break;
2194

    
2195
            case 3: /*DPFWOc*/
2196
                break;
2197

    
2198
            case 4: /*DHWBc*/
2199
                break;
2200

    
2201
            case 5: /*DHWBIc*/
2202
                break;
2203

    
2204
            case 6: /*DHIc*/
2205
                break;
2206

    
2207
            case 7: /*DIIc*/
2208
                break;
2209

    
2210
            case 8: /*DCEc*/
2211
                switch (OP1) {
2212
                case 0: /*DPFLl*/
2213
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
2214
                    break;
2215

    
2216
                case 2: /*DHUl*/
2217
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
2218
                    break;
2219

    
2220
                case 3: /*DIUl*/
2221
                    HAS_OPTION(XTENSA_OPTION_DCACHE_INDEX_LOCK);
2222
                    break;
2223

    
2224
                case 4: /*DIWBc*/
2225
                    HAS_OPTION(XTENSA_OPTION_DCACHE);
2226
                    break;
2227

    
2228
                case 5: /*DIWBIc*/
2229
                    HAS_OPTION(XTENSA_OPTION_DCACHE);
2230
                    break;
2231

    
2232
                default: /*reserved*/
2233
                    RESERVED();
2234
                    break;
2235

    
2236
                }
2237
                break;
2238

    
2239
            case 12: /*IPFc*/
2240
                HAS_OPTION(XTENSA_OPTION_ICACHE);
2241
                break;
2242

    
2243
            case 13: /*ICEc*/
2244
                switch (OP1) {
2245
                case 0: /*IPFLl*/
2246
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
2247
                    break;
2248

    
2249
                case 2: /*IHUl*/
2250
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
2251
                    break;
2252

    
2253
                case 3: /*IIUl*/
2254
                    HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
2255
                    break;
2256

    
2257
                default: /*reserved*/
2258
                    RESERVED();
2259
                    break;
2260
                }
2261
                break;
2262

    
2263
            case 14: /*IHIc*/
2264
                HAS_OPTION(XTENSA_OPTION_ICACHE);
2265
                break;
2266

    
2267
            case 15: /*IIIc*/
2268
                HAS_OPTION(XTENSA_OPTION_ICACHE);
2269
                break;
2270

    
2271
            default: /*reserved*/
2272
                RESERVED();
2273
                break;
2274
            }
2275
            break;
2276

    
2277
        case 9: /*L16SI*/
2278
            gen_load_store(ld16s, 1);
2279
            break;
2280
#undef gen_load_store
2281

    
2282
        case 10: /*MOVI*/
2283
            gen_window_check1(dc, RRI8_T);
2284
            tcg_gen_movi_i32(cpu_R[RRI8_T],
2285
                    RRI8_IMM8 | (RRI8_S << 8) |
2286
                    ((RRI8_S & 0x8) ? 0xfffff000 : 0));
2287
            break;
2288

    
2289
#define gen_load_store_no_hw_align(type) do { \
2290
            TCGv_i32 addr = tcg_temp_local_new_i32(); \
2291
            gen_window_check2(dc, RRI8_S, RRI8_T); \
2292
            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2); \
2293
            gen_load_store_alignment(dc, 2, addr, true); \
2294
            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, dc->cring); \
2295
            tcg_temp_free(addr); \
2296
        } while (0)
2297

    
2298
        case 11: /*L32AIy*/
2299
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
2300
            gen_load_store_no_hw_align(ld32u); /*TODO acquire?*/
2301
            break;
2302

    
2303
        case 12: /*ADDI*/
2304
            gen_window_check2(dc, RRI8_S, RRI8_T);
2305
            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);
2306
            break;
2307

    
2308
        case 13: /*ADDMI*/
2309
            gen_window_check2(dc, RRI8_S, RRI8_T);
2310
            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);
2311
            break;
2312

    
2313
        case 14: /*S32C1Iy*/
2314
            HAS_OPTION(XTENSA_OPTION_CONDITIONAL_STORE);
2315
            gen_window_check2(dc, RRI8_S, RRI8_T);
2316
            {
2317
                int label = gen_new_label();
2318
                TCGv_i32 tmp = tcg_temp_local_new_i32();
2319
                TCGv_i32 addr = tcg_temp_local_new_i32();
2320

    
2321
                tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);
2322
                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
2323
                gen_load_store_alignment(dc, 2, addr, true);
2324
                tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, dc->cring);
2325
                tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],
2326
                        cpu_SR[SCOMPARE1], label);
2327

    
2328
                tcg_gen_qemu_st32(tmp, addr, dc->cring);
2329

    
2330
                gen_set_label(label);
2331
                tcg_temp_free(addr);
2332
                tcg_temp_free(tmp);
2333
            }
2334
            break;
2335

    
2336
        case 15: /*S32RIy*/
2337
            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);
2338
            gen_load_store_no_hw_align(st32); /*TODO release?*/
2339
            break;
2340
#undef gen_load_store_no_hw_align
2341

    
2342
        default: /*reserved*/
2343
            RESERVED();
2344
            break;
2345
        }
2346
        break;
2347

    
2348
    case 3: /*LSCIp*/
2349
        switch (RRI8_R) {
2350
        case 0: /*LSIf*/
2351
        case 4: /*SSIf*/
2352
        case 8: /*LSIUf*/
2353
        case 12: /*SSIUf*/
2354
            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
2355
            gen_window_check1(dc, RRI8_S);
2356
            gen_check_cpenable(dc, 0);
2357
            {
2358
                TCGv_i32 addr = tcg_temp_new_i32();
2359
                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
2360
                gen_load_store_alignment(dc, 2, addr, false);
2361
                if (RRI8_R & 0x4) {
2362
                    tcg_gen_qemu_st32(cpu_FR[RRI8_T], addr, dc->cring);
2363
                } else {
2364
                    tcg_gen_qemu_ld32u(cpu_FR[RRI8_T], addr, dc->cring);
2365
                }
2366
                if (RRI8_R & 0x8) {
2367
                    tcg_gen_mov_i32(cpu_R[RRI8_S], addr);
2368
                }
2369
                tcg_temp_free(addr);
2370
            }
2371
            break;
2372

    
2373
        default: /*reserved*/
2374
            RESERVED();
2375
            break;
2376
        }
2377
        break;
2378

    
2379
    case 4: /*MAC16d*/
2380
        HAS_OPTION(XTENSA_OPTION_MAC16);
2381
        {
2382
            enum {
2383
                MAC16_UMUL = 0x0,
2384
                MAC16_MUL  = 0x4,
2385
                MAC16_MULA = 0x8,
2386
                MAC16_MULS = 0xc,
2387
                MAC16_NONE = 0xf,
2388
            } op = OP1 & 0xc;
2389
            bool is_m1_sr = (OP2 & 0x3) == 2;
2390
            bool is_m2_sr = (OP2 & 0xc) == 0;
2391
            uint32_t ld_offset = 0;
2392

    
2393
            if (OP2 > 9) {
2394
                RESERVED();
2395
            }
2396

    
2397
            switch (OP2 & 2) {
2398
            case 0: /*MACI?/MACC?*/
2399
                is_m1_sr = true;
2400
                ld_offset = (OP2 & 1) ? -4 : 4;
2401

    
2402
                if (OP2 >= 8) { /*MACI/MACC*/
2403
                    if (OP1 == 0) { /*LDINC/LDDEC*/
2404
                        op = MAC16_NONE;
2405
                    } else {
2406
                        RESERVED();
2407
                    }
2408
                } else if (op != MAC16_MULA) { /*MULA.*.*.LDINC/LDDEC*/
2409
                    RESERVED();
2410
                }
2411
                break;
2412

    
2413
            case 2: /*MACD?/MACA?*/
2414
                if (op == MAC16_UMUL && OP2 != 7) { /*UMUL only in MACAA*/
2415
                    RESERVED();
2416
                }
2417
                break;
2418
            }
2419

    
2420
            if (op != MAC16_NONE) {
2421
                if (!is_m1_sr) {
2422
                    gen_window_check1(dc, RRR_S);
2423
                }
2424
                if (!is_m2_sr) {
2425
                    gen_window_check1(dc, RRR_T);
2426
                }
2427
            }
2428

    
2429
            {
2430
                TCGv_i32 vaddr = tcg_temp_new_i32();
2431
                TCGv_i32 mem32 = tcg_temp_new_i32();
2432

    
2433
                if (ld_offset) {
2434
                    gen_window_check1(dc, RRR_S);
2435
                    tcg_gen_addi_i32(vaddr, cpu_R[RRR_S], ld_offset);
2436
                    gen_load_store_alignment(dc, 2, vaddr, false);
2437
                    tcg_gen_qemu_ld32u(mem32, vaddr, dc->cring);
2438
                }
2439
                if (op != MAC16_NONE) {
2440
                    TCGv_i32 m1 = gen_mac16_m(
2441
                            is_m1_sr ? cpu_SR[MR + RRR_X] : cpu_R[RRR_S],
2442
                            OP1 & 1, op == MAC16_UMUL);
2443
                    TCGv_i32 m2 = gen_mac16_m(
2444
                            is_m2_sr ? cpu_SR[MR + 2 + RRR_Y] : cpu_R[RRR_T],
2445
                            OP1 & 2, op == MAC16_UMUL);
2446

    
2447
                    if (op == MAC16_MUL || op == MAC16_UMUL) {
2448
                        tcg_gen_mul_i32(cpu_SR[ACCLO], m1, m2);
2449
                        if (op == MAC16_UMUL) {
2450
                            tcg_gen_movi_i32(cpu_SR[ACCHI], 0);
2451
                        } else {
2452
                            tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
2453
                        }
2454
                    } else {
2455
                        TCGv_i32 res = tcg_temp_new_i32();
2456
                        TCGv_i64 res64 = tcg_temp_new_i64();
2457
                        TCGv_i64 tmp = tcg_temp_new_i64();
2458

    
2459
                        tcg_gen_mul_i32(res, m1, m2);
2460
                        tcg_gen_ext_i32_i64(res64, res);
2461
                        tcg_gen_concat_i32_i64(tmp,
2462
                                cpu_SR[ACCLO], cpu_SR[ACCHI]);
2463
                        if (op == MAC16_MULA) {
2464
                            tcg_gen_add_i64(tmp, tmp, res64);
2465
                        } else {
2466
                            tcg_gen_sub_i64(tmp, tmp, res64);
2467
                        }
2468
                        tcg_gen_trunc_i64_i32(cpu_SR[ACCLO], tmp);
2469
                        tcg_gen_shri_i64(tmp, tmp, 32);
2470
                        tcg_gen_trunc_i64_i32(cpu_SR[ACCHI], tmp);
2471
                        tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
2472

    
2473
                        tcg_temp_free(res);
2474
                        tcg_temp_free_i64(res64);
2475
                        tcg_temp_free_i64(tmp);
2476
                    }
2477
                    tcg_temp_free(m1);
2478
                    tcg_temp_free(m2);
2479
                }
2480
                if (ld_offset) {
2481
                    tcg_gen_mov_i32(cpu_R[RRR_S], vaddr);
2482
                    tcg_gen_mov_i32(cpu_SR[MR + RRR_W], mem32);
2483
                }
2484
                tcg_temp_free(vaddr);
2485
                tcg_temp_free(mem32);
2486
            }
2487
        }
2488
        break;
2489

    
2490
    case 5: /*CALLN*/
2491
        switch (CALL_N) {
2492
        case 0: /*CALL0*/
2493
            tcg_gen_movi_i32(cpu_R[0], dc->next_pc);
2494
            gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2495
            break;
2496

    
2497
        case 1: /*CALL4w*/
2498
        case 2: /*CALL8w*/
2499
        case 3: /*CALL12w*/
2500
            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2501
            gen_window_check1(dc, CALL_N << 2);
2502
            gen_callwi(dc, CALL_N,
2503
                    (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);
2504
            break;
2505
        }
2506
        break;
2507

    
2508
    case 6: /*SI*/
2509
        switch (CALL_N) {
2510
        case 0: /*J*/
2511
            gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);
2512
            break;
2513

    
2514
        case 1: /*BZ*/
2515
            gen_window_check1(dc, BRI12_S);
2516
            {
2517
                static const TCGCond cond[] = {
2518
                    TCG_COND_EQ, /*BEQZ*/
2519
                    TCG_COND_NE, /*BNEZ*/
2520
                    TCG_COND_LT, /*BLTZ*/
2521
                    TCG_COND_GE, /*BGEZ*/
2522
                };
2523

    
2524
                gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,
2525
                        4 + BRI12_IMM12_SE);
2526
            }
2527
            break;
2528

    
2529
        case 2: /*BI0*/
2530
            gen_window_check1(dc, BRI8_S);
2531
            {
2532
                static const TCGCond cond[] = {
2533
                    TCG_COND_EQ, /*BEQI*/
2534
                    TCG_COND_NE, /*BNEI*/
2535
                    TCG_COND_LT, /*BLTI*/
2536
                    TCG_COND_GE, /*BGEI*/
2537
                };
2538

    
2539
                gen_brcondi(dc, cond[BRI8_M & 3],
2540
                        cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);
2541
            }
2542
            break;
2543

    
2544
        case 3: /*BI1*/
2545
            switch (BRI8_M) {
2546
            case 0: /*ENTRYw*/
2547
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2548
                {
2549
                    TCGv_i32 pc = tcg_const_i32(dc->pc);
2550
                    TCGv_i32 s = tcg_const_i32(BRI12_S);
2551
                    TCGv_i32 imm = tcg_const_i32(BRI12_IMM12);
2552
                    gen_advance_ccount(dc);
2553
                    gen_helper_entry(cpu_env, pc, s, imm);
2554
                    tcg_temp_free(imm);
2555
                    tcg_temp_free(s);
2556
                    tcg_temp_free(pc);
2557
                    reset_used_window(dc);
2558
                }
2559
                break;
2560

    
2561
            case 1: /*B1*/
2562
                switch (BRI8_R) {
2563
                case 0: /*BFp*/
2564
                case 1: /*BTp*/
2565
                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);
2566
                    {
2567
                        TCGv_i32 tmp = tcg_temp_new_i32();
2568
                        tcg_gen_andi_i32(tmp, cpu_SR[BR], 1 << RRI8_S);
2569
                        gen_brcondi(dc,
2570
                                BRI8_R == 1 ? TCG_COND_NE : TCG_COND_EQ,
2571
                                tmp, 0, 4 + RRI8_IMM8_SE);
2572
                        tcg_temp_free(tmp);
2573
                    }
2574
                    break;
2575

    
2576
                case 8: /*LOOP*/
2577
                case 9: /*LOOPNEZ*/
2578
                case 10: /*LOOPGTZ*/
2579
                    HAS_OPTION(XTENSA_OPTION_LOOP);
2580
                    gen_window_check1(dc, RRI8_S);
2581
                    {
2582
                        uint32_t lend = dc->pc + RRI8_IMM8 + 4;
2583
                        TCGv_i32 tmp = tcg_const_i32(lend);
2584

    
2585
                        tcg_gen_subi_i32(cpu_SR[LCOUNT], cpu_R[RRI8_S], 1);
2586
                        tcg_gen_movi_i32(cpu_SR[LBEG], dc->next_pc);
2587
                        gen_helper_wsr_lend(cpu_env, tmp);
2588
                        tcg_temp_free(tmp);
2589

    
2590
                        if (BRI8_R > 8) {
2591
                            int label = gen_new_label();
2592
                            tcg_gen_brcondi_i32(
2593
                                    BRI8_R == 9 ? TCG_COND_NE : TCG_COND_GT,
2594
                                    cpu_R[RRI8_S], 0, label);
2595
                            gen_jumpi(dc, lend, 1);
2596
                            gen_set_label(label);
2597
                        }
2598

    
2599
                        gen_jumpi(dc, dc->next_pc, 0);
2600
                    }
2601
                    break;
2602

    
2603
                default: /*reserved*/
2604
                    RESERVED();
2605
                    break;
2606

    
2607
                }
2608
                break;
2609

    
2610
            case 2: /*BLTUI*/
2611
            case 3: /*BGEUI*/
2612
                gen_window_check1(dc, BRI8_S);
2613
                gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,
2614
                        cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);
2615
                break;
2616
            }
2617
            break;
2618

    
2619
        }
2620
        break;
2621

    
2622
    case 7: /*B*/
2623
        {
2624
            TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;
2625

    
2626
            switch (RRI8_R & 7) {
2627
            case 0: /*BNONE*/ /*BANY*/
2628
                gen_window_check2(dc, RRI8_S, RRI8_T);
2629
                {
2630
                    TCGv_i32 tmp = tcg_temp_new_i32();
2631
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2632
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2633
                    tcg_temp_free(tmp);
2634
                }
2635
                break;
2636

    
2637
            case 1: /*BEQ*/ /*BNE*/
2638
            case 2: /*BLT*/ /*BGE*/
2639
            case 3: /*BLTU*/ /*BGEU*/
2640
                gen_window_check2(dc, RRI8_S, RRI8_T);
2641
                {
2642
                    static const TCGCond cond[] = {
2643
                        [1] = TCG_COND_EQ,
2644
                        [2] = TCG_COND_LT,
2645
                        [3] = TCG_COND_LTU,
2646
                        [9] = TCG_COND_NE,
2647
                        [10] = TCG_COND_GE,
2648
                        [11] = TCG_COND_GEU,
2649
                    };
2650
                    gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],
2651
                            4 + RRI8_IMM8_SE);
2652
                }
2653
                break;
2654

    
2655
            case 4: /*BALL*/ /*BNALL*/
2656
                gen_window_check2(dc, RRI8_S, RRI8_T);
2657
                {
2658
                    TCGv_i32 tmp = tcg_temp_new_i32();
2659
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);
2660
                    gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],
2661
                            4 + RRI8_IMM8_SE);
2662
                    tcg_temp_free(tmp);
2663
                }
2664
                break;
2665

    
2666
            case 5: /*BBC*/ /*BBS*/
2667
                gen_window_check2(dc, RRI8_S, RRI8_T);
2668
                {
2669
#ifdef TARGET_WORDS_BIGENDIAN
2670
                    TCGv_i32 bit = tcg_const_i32(0x80000000);
2671
#else
2672
                    TCGv_i32 bit = tcg_const_i32(0x00000001);
2673
#endif
2674
                    TCGv_i32 tmp = tcg_temp_new_i32();
2675
                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);
2676
#ifdef TARGET_WORDS_BIGENDIAN
2677
                    tcg_gen_shr_i32(bit, bit, tmp);
2678
#else
2679
                    tcg_gen_shl_i32(bit, bit, tmp);
2680
#endif
2681
                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);
2682
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2683
                    tcg_temp_free(tmp);
2684
                    tcg_temp_free(bit);
2685
                }
2686
                break;
2687

    
2688
            case 6: /*BBCI*/ /*BBSI*/
2689
            case 7:
2690
                gen_window_check1(dc, RRI8_S);
2691
                {
2692
                    TCGv_i32 tmp = tcg_temp_new_i32();
2693
                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],
2694
#ifdef TARGET_WORDS_BIGENDIAN
2695
                            0x80000000 >> (((RRI8_R & 1) << 4) | RRI8_T));
2696
#else
2697
                            0x00000001 << (((RRI8_R & 1) << 4) | RRI8_T));
2698
#endif
2699
                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);
2700
                    tcg_temp_free(tmp);
2701
                }
2702
                break;
2703

    
2704
            }
2705
        }
2706
        break;
2707

    
2708
#define gen_narrow_load_store(type) do { \
2709
            TCGv_i32 addr = tcg_temp_new_i32(); \
2710
            gen_window_check2(dc, RRRN_S, RRRN_T); \
2711
            tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \
2712
            gen_load_store_alignment(dc, 2, addr, false); \
2713
            tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, dc->cring); \
2714
            tcg_temp_free(addr); \
2715
        } while (0)
2716

    
2717
    case 8: /*L32I.Nn*/
2718
        gen_narrow_load_store(ld32u);
2719
        break;
2720

    
2721
    case 9: /*S32I.Nn*/
2722
        gen_narrow_load_store(st32);
2723
        break;
2724
#undef gen_narrow_load_store
2725

    
2726
    case 10: /*ADD.Nn*/
2727
        gen_window_check3(dc, RRRN_R, RRRN_S, RRRN_T);
2728
        tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);
2729
        break;
2730

    
2731
    case 11: /*ADDI.Nn*/
2732
        gen_window_check2(dc, RRRN_R, RRRN_S);
2733
        tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);
2734
        break;
2735

    
2736
    case 12: /*ST2n*/
2737
        gen_window_check1(dc, RRRN_S);
2738
        if (RRRN_T < 8) { /*MOVI.Nn*/
2739
            tcg_gen_movi_i32(cpu_R[RRRN_S],
2740
                    RRRN_R | (RRRN_T << 4) |
2741
                    ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));
2742
        } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/
2743
            TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;
2744

    
2745
            gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,
2746
                    4 + (RRRN_R | ((RRRN_T & 3) << 4)));
2747
        }
2748
        break;
2749

    
2750
    case 13: /*ST3n*/
2751
        switch (RRRN_R) {
2752
        case 0: /*MOV.Nn*/
2753
            gen_window_check2(dc, RRRN_S, RRRN_T);
2754
            tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);
2755
            break;
2756

    
2757
        case 15: /*S3*/
2758
            switch (RRRN_T) {
2759
            case 0: /*RET.Nn*/
2760
                gen_jump(dc, cpu_R[0]);
2761
                break;
2762

    
2763
            case 1: /*RETW.Nn*/
2764
                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
2765
                {
2766
                    TCGv_i32 tmp = tcg_const_i32(dc->pc);
2767
                    gen_advance_ccount(dc);
2768
                    gen_helper_retw(tmp, cpu_env, tmp);
2769
                    gen_jump(dc, tmp);
2770
                    tcg_temp_free(tmp);
2771
                }
2772
                break;
2773

    
2774
            case 2: /*BREAK.Nn*/
2775
                HAS_OPTION(XTENSA_OPTION_DEBUG);
2776
                if (dc->debug) {
2777
                    gen_debug_exception(dc, DEBUGCAUSE_BN);
2778
                }
2779
                break;
2780

    
2781
            case 3: /*NOP.Nn*/
2782
                break;
2783

    
2784
            case 6: /*ILL.Nn*/
2785
                gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2786
                break;
2787

    
2788
            default: /*reserved*/
2789
                RESERVED();
2790
                break;
2791
            }
2792
            break;
2793

    
2794
        default: /*reserved*/
2795
            RESERVED();
2796
            break;
2797
        }
2798
        break;
2799

    
2800
    default: /*reserved*/
2801
        RESERVED();
2802
        break;
2803
    }
2804

    
2805
    if (dc->is_jmp == DISAS_NEXT) {
2806
        gen_check_loop_end(dc, 0);
2807
    }
2808
    dc->pc = dc->next_pc;
2809

    
2810
    return;
2811

    
2812
invalid_opcode:
2813
    qemu_log("INVALID(pc = %08x)\n", dc->pc);
2814
    gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
2815
#undef HAS_OPTION
2816
}
2817

    
2818
static void check_breakpoint(CPUXtensaState *env, DisasContext *dc)
2819
{
2820
    CPUBreakpoint *bp;
2821

    
2822
    if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
2823
        QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
2824
            if (bp->pc == dc->pc) {
2825
                tcg_gen_movi_i32(cpu_pc, dc->pc);
2826
                gen_exception(dc, EXCP_DEBUG);
2827
                dc->is_jmp = DISAS_UPDATE;
2828
             }
2829
        }
2830
    }
2831
}
2832

    
2833
static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
2834
{
2835
    unsigned i;
2836

    
2837
    for (i = 0; i < dc->config->nibreak; ++i) {
2838
        if ((env->sregs[IBREAKENABLE] & (1 << i)) &&
2839
                env->sregs[IBREAKA + i] == dc->pc) {
2840
            gen_debug_exception(dc, DEBUGCAUSE_IB);
2841
            break;
2842
        }
2843
    }
2844
}
2845

    
2846
static void gen_intermediate_code_internal(
2847
        CPUXtensaState *env, TranslationBlock *tb, int search_pc)
2848
{
2849
    DisasContext dc;
2850
    int insn_count = 0;
2851
    int j, lj = -1;
2852
    uint16_t *gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
2853
    int max_insns = tb->cflags & CF_COUNT_MASK;
2854
    uint32_t pc_start = tb->pc;
2855
    uint32_t next_page_start =
2856
        (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
2857

    
2858
    if (max_insns == 0) {
2859
        max_insns = CF_COUNT_MASK;
2860
    }
2861

    
2862
    dc.config = env->config;
2863
    dc.singlestep_enabled = env->singlestep_enabled;
2864
    dc.tb = tb;
2865
    dc.pc = pc_start;
2866
    dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
2867
    dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;
2868
    dc.lbeg = env->sregs[LBEG];
2869
    dc.lend = env->sregs[LEND];
2870
    dc.is_jmp = DISAS_NEXT;
2871
    dc.ccount_delta = 0;
2872
    dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
2873
    dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
2874
    dc.cpenable = (tb->flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
2875
        XTENSA_TBFLAG_CPENABLE_SHIFT;
2876

    
2877
    init_litbase(&dc);
2878
    init_sar_tracker(&dc);
2879
    reset_used_window(&dc);
2880
    if (dc.icount) {
2881
        dc.next_icount = tcg_temp_local_new_i32();
2882
    }
2883

    
2884
    gen_icount_start();
2885

    
2886
    if (env->singlestep_enabled && env->exception_taken) {
2887
        env->exception_taken = 0;
2888
        tcg_gen_movi_i32(cpu_pc, dc.pc);
2889
        gen_exception(&dc, EXCP_DEBUG);
2890
    }
2891

    
2892
    do {
2893
        check_breakpoint(env, &dc);
2894

    
2895
        if (search_pc) {
2896
            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
2897
            if (lj < j) {
2898
                lj++;
2899
                while (lj < j) {
2900
                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
2901
                }
2902
            }
2903
            tcg_ctx.gen_opc_pc[lj] = dc.pc;
2904
            tcg_ctx.gen_opc_instr_start[lj] = 1;
2905
            tcg_ctx.gen_opc_icount[lj] = insn_count;
2906
        }
2907

    
2908
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
2909
            tcg_gen_debug_insn_start(dc.pc);
2910
        }
2911

    
2912
        ++dc.ccount_delta;
2913

    
2914
        if (insn_count + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
2915
            gen_io_start();
2916
        }
2917

    
2918
        if (dc.icount) {
2919
            int label = gen_new_label();
2920

    
2921
            tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1);
2922
            tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label);
2923
            tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]);
2924
            if (dc.debug) {
2925
                gen_debug_exception(&dc, DEBUGCAUSE_IC);
2926
            }
2927
            gen_set_label(label);
2928
        }
2929

    
2930
        if (dc.debug) {
2931
            gen_ibreak_check(env, &dc);
2932
        }
2933

    
2934
        disas_xtensa_insn(env, &dc);
2935
        ++insn_count;
2936
        if (dc.icount) {
2937
            tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
2938
        }
2939
        if (env->singlestep_enabled) {
2940
            tcg_gen_movi_i32(cpu_pc, dc.pc);
2941
            gen_exception(&dc, EXCP_DEBUG);
2942
            break;
2943
        }
2944
    } while (dc.is_jmp == DISAS_NEXT &&
2945
            insn_count < max_insns &&
2946
            dc.pc < next_page_start &&
2947
            tcg_ctx.gen_opc_ptr < gen_opc_end);
2948

    
2949
    reset_litbase(&dc);
2950
    reset_sar_tracker(&dc);
2951
    if (dc.icount) {
2952
        tcg_temp_free(dc.next_icount);
2953
    }
2954

    
2955
    if (tb->cflags & CF_LAST_IO) {
2956
        gen_io_end();
2957
    }
2958

    
2959
    if (dc.is_jmp == DISAS_NEXT) {
2960
        gen_jumpi(&dc, dc.pc, 0);
2961
    }
2962
    gen_icount_end(tb, insn_count);
2963
    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
2964

    
2965
    if (!search_pc) {
2966
        tb->size = dc.pc - pc_start;
2967
        tb->icount = insn_count;
2968
    }
2969
}
2970

    
2971
void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
2972
{
2973
    gen_intermediate_code_internal(env, tb, 0);
2974
}
2975

    
2976
void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
2977
{
2978
    gen_intermediate_code_internal(env, tb, 1);
2979
}
2980

    
2981
void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
2982
        int flags)
2983
{
2984
    int i, j;
2985

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

    
2988
    for (i = j = 0; i < 256; ++i) {
2989
        if (sregnames[i]) {
2990
            cpu_fprintf(f, "%s=%08x%c", sregnames[i], env->sregs[i],
2991
                    (j++ % 4) == 3 ? '\n' : ' ');
2992
        }
2993
    }
2994

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

    
2997
    for (i = j = 0; i < 256; ++i) {
2998
        if (uregnames[i]) {
2999
            cpu_fprintf(f, "%s=%08x%c", uregnames[i], env->uregs[i],
3000
                    (j++ % 4) == 3 ? '\n' : ' ');
3001
        }
3002
    }
3003

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

    
3006
    for (i = 0; i < 16; ++i) {
3007
        cpu_fprintf(f, "A%02d=%08x%c", i, env->regs[i],
3008
                (i % 4) == 3 ? '\n' : ' ');
3009
    }
3010

    
3011
    cpu_fprintf(f, "\n");
3012

    
3013
    for (i = 0; i < env->config->nareg; ++i) {
3014
        cpu_fprintf(f, "AR%02d=%08x%c", i, env->phys_regs[i],
3015
                (i % 4) == 3 ? '\n' : ' ');
3016
    }
3017

    
3018
    if (xtensa_option_enabled(env->config, XTENSA_OPTION_FP_COPROCESSOR)) {
3019
        cpu_fprintf(f, "\n");
3020

    
3021
        for (i = 0; i < 16; ++i) {
3022
            cpu_fprintf(f, "F%02d=%08x (%+10.8e)%c", i,
3023
                    float32_val(env->fregs[i]),
3024
                    *(float *)&env->fregs[i], (i % 2) == 1 ? '\n' : ' ');
3025
        }
3026
    }
3027
}
3028

    
3029
void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, int pc_pos)
3030
{
3031
    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
3032
}