Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ 04acd307

History | View | Annotate | Download (72.1 kB)

1
/*
2
 *  Alpha emulation cpu translation for qemu.
3
 *
4
 *  Copyright (c) 2007 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

    
21
#include <stdint.h>
22
#include <stdlib.h>
23
#include <stdio.h>
24

    
25
#include "cpu.h"
26
#include "exec-all.h"
27
#include "disas.h"
28
#include "host-utils.h"
29
#include "helper.h"
30
#include "tcg-op.h"
31
#include "qemu-common.h"
32

    
33
#define DO_SINGLE_STEP
34
#define GENERATE_NOP
35
#define ALPHA_DEBUG_DISAS
36
#define DO_TB_FLUSH
37

    
38
typedef struct DisasContext DisasContext;
39
struct DisasContext {
40
    uint64_t pc;
41
    int mem_idx;
42
#if !defined (CONFIG_USER_ONLY)
43
    int pal_mode;
44
#endif
45
    uint32_t amask;
46
};
47

    
48
/* global register indexes */
49
static TCGv cpu_env;
50
static TCGv cpu_ir[31];
51
static TCGv cpu_pc;
52

    
53
/* dyngen register indexes */
54
static TCGv cpu_T[2];
55

    
56
/* register names */
57
static char cpu_reg_names[10*4+21*5];
58

    
59
#include "gen-icount.h"
60

    
61
static void alpha_translate_init(void)
62
{
63
    int i;
64
    char *p;
65
    static int done_init = 0;
66

    
67
    if (done_init)
68
        return;
69

    
70
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
71

    
72
#if TARGET_LONG_BITS > HOST_LONG_BITS
73
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
74
                                  offsetof(CPUState, t0), "T0");
75
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
76
                                  offsetof(CPUState, t1), "T1");
77
#else
78
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I64, TCG_AREG1, "T0");
79
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I64, TCG_AREG2, "T1");
80
#endif
81

    
82
    p = cpu_reg_names;
83
    for (i = 0; i < 31; i++) {
84
        sprintf(p, "ir%d", i);
85
        cpu_ir[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
86
                                       offsetof(CPUState, ir[i]), p);
87
        p += (i < 10) ? 4 : 5;
88
    }
89

    
90
    cpu_pc = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
91
                                offsetof(CPUState, pc), "pc");
92

    
93
    /* register helpers */
94
#undef DEF_HELPER
95
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
96
#include "helper.h"
97

    
98
    done_init = 1;
99
}
100

    
101
static always_inline void gen_op_nop (void)
102
{
103
#if defined(GENERATE_NOP)
104
    gen_op_no_op();
105
#endif
106
}
107

    
108
#define GEN32(func, NAME) \
109
static GenOpFunc *NAME ## _table [32] = {                                     \
110
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
111
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
112
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
113
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
114
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
115
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
116
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
117
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
118
};                                                                            \
119
static always_inline void func (int n)                                        \
120
{                                                                             \
121
    NAME ## _table[n]();                                                      \
122
}
123

    
124
/* FIR moves */
125
/* Special hacks for fir31 */
126
#define gen_op_load_FT0_fir31 gen_op_reset_FT0
127
#define gen_op_load_FT1_fir31 gen_op_reset_FT1
128
#define gen_op_load_FT2_fir31 gen_op_reset_FT2
129
#define gen_op_store_FT0_fir31 gen_op_nop
130
#define gen_op_store_FT1_fir31 gen_op_nop
131
#define gen_op_store_FT2_fir31 gen_op_nop
132
#define gen_op_cmov_fir31 gen_op_nop
133
GEN32(gen_op_load_FT0_fir, gen_op_load_FT0_fir);
134
GEN32(gen_op_load_FT1_fir, gen_op_load_FT1_fir);
135
GEN32(gen_op_load_FT2_fir, gen_op_load_FT2_fir);
136
GEN32(gen_op_store_FT0_fir, gen_op_store_FT0_fir);
137
GEN32(gen_op_store_FT1_fir, gen_op_store_FT1_fir);
138
GEN32(gen_op_store_FT2_fir, gen_op_store_FT2_fir);
139
GEN32(gen_op_cmov_fir, gen_op_cmov_fir);
140

    
141
static always_inline void gen_load_fir (DisasContext *ctx, int firn, int Tn)
142
{
143
    switch (Tn) {
144
    case 0:
145
        gen_op_load_FT0_fir(firn);
146
        break;
147
    case 1:
148
        gen_op_load_FT1_fir(firn);
149
        break;
150
    case 2:
151
        gen_op_load_FT2_fir(firn);
152
        break;
153
    }
154
}
155

    
156
static always_inline void gen_store_fir (DisasContext *ctx, int firn, int Tn)
157
{
158
    switch (Tn) {
159
    case 0:
160
        gen_op_store_FT0_fir(firn);
161
        break;
162
    case 1:
163
        gen_op_store_FT1_fir(firn);
164
        break;
165
    case 2:
166
        gen_op_store_FT2_fir(firn);
167
        break;
168
    }
169
}
170

    
171
/* Memory moves */
172
#if defined(CONFIG_USER_ONLY)
173
#define OP_LD_TABLE(width)                                                    \
174
static GenOpFunc *gen_op_ld##width[] = {                                      \
175
    &gen_op_ld##width##_raw,                                                  \
176
}
177
#define OP_ST_TABLE(width)                                                    \
178
static GenOpFunc *gen_op_st##width[] = {                                      \
179
    &gen_op_st##width##_raw,                                                  \
180
}
181
#else
182
#define OP_LD_TABLE(width)                                                    \
183
static GenOpFunc *gen_op_ld##width[] = {                                      \
184
    &gen_op_ld##width##_kernel,                                               \
185
    &gen_op_ld##width##_executive,                                            \
186
    &gen_op_ld##width##_supervisor,                                           \
187
    &gen_op_ld##width##_user,                                                 \
188
}
189
#define OP_ST_TABLE(width)                                                    \
190
static GenOpFunc *gen_op_st##width[] = {                                      \
191
    &gen_op_st##width##_kernel,                                               \
192
    &gen_op_st##width##_executive,                                            \
193
    &gen_op_st##width##_supervisor,                                           \
194
    &gen_op_st##width##_user,                                                 \
195
}
196
#endif
197

    
198
#define GEN_LD(width)                                                         \
199
OP_LD_TABLE(width);                                                           \
200
static always_inline void gen_ld##width (DisasContext *ctx)                   \
201
{                                                                             \
202
    (*gen_op_ld##width[ctx->mem_idx])();                                      \
203
}
204

    
205
#define GEN_ST(width)                                                         \
206
OP_ST_TABLE(width);                                                           \
207
static always_inline void gen_st##width (DisasContext *ctx)                   \
208
{                                                                             \
209
    (*gen_op_st##width[ctx->mem_idx])();                                      \
210
}
211

    
212
GEN_LD(bu);
213
GEN_ST(b);
214
GEN_LD(wu);
215
GEN_ST(w);
216
GEN_LD(l);
217
GEN_ST(l);
218
GEN_LD(q);
219
GEN_ST(q);
220
GEN_LD(q_u);
221
GEN_ST(q_u);
222
GEN_LD(l_l);
223
GEN_ST(l_c);
224
GEN_LD(q_l);
225
GEN_ST(q_c);
226

    
227
#if 0 /* currently unused */
228
GEN_LD(f);
229
GEN_ST(f);
230
GEN_LD(g);
231
GEN_ST(g);
232
#endif /* 0 */
233
GEN_LD(s);
234
GEN_ST(s);
235
GEN_LD(t);
236
GEN_ST(t);
237

    
238
static always_inline void _gen_op_bcond (DisasContext *ctx)
239
{
240
#if 0 // Qemu does not know how to do this...
241
    gen_op_bcond(ctx->pc);
242
#else
243
    gen_op_bcond(ctx->pc >> 32, ctx->pc);
244
#endif
245
}
246

    
247
static always_inline void gen_excp (DisasContext *ctx,
248
                                    int exception, int error_code)
249
{
250
    TCGv tmp1, tmp2;
251

    
252
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
253
    tmp1 = tcg_const_i32(exception);
254
    tmp2 = tcg_const_i32(error_code);
255
    tcg_gen_helper_0_2(helper_excp, tmp1, tmp2);
256
    tcg_temp_free(tmp2);
257
    tcg_temp_free(tmp1);
258
}
259

    
260
static always_inline void gen_invalid (DisasContext *ctx)
261
{
262
    gen_excp(ctx, EXCP_OPCDEC, 0);
263
}
264

    
265
static always_inline void gen_load_mem (DisasContext *ctx,
266
                                        void (*gen_load_op)(DisasContext *ctx),
267
                                        int ra, int rb, int32_t disp16,
268
                                        int clear)
269
{
270
    if (ra == 31 && disp16 == 0) {
271
        /* UNOP */
272
        gen_op_nop();
273
    } else {
274
        if (rb != 31)
275
            tcg_gen_addi_i64(cpu_T[0], cpu_ir[rb], disp16);
276
        else
277
            tcg_gen_movi_i64(cpu_T[0], disp16);
278
        if (clear)
279
            tcg_gen_andi_i64(cpu_T[0], cpu_T[0], ~0x7);
280
        (*gen_load_op)(ctx);
281
        if (ra != 31)
282
            tcg_gen_mov_i64(cpu_ir[ra], cpu_T[1]);
283
    }
284
}
285

    
286
static always_inline void gen_store_mem (DisasContext *ctx,
287
                                         void (*gen_store_op)(DisasContext *ctx),
288
                                         int ra, int rb, int32_t disp16,
289
                                         int clear)
290
{
291
    if (rb != 31)
292
        tcg_gen_addi_i64(cpu_T[0], cpu_ir[rb], disp16);
293
    else
294
        tcg_gen_movi_i64(cpu_T[0], disp16);
295
    if (clear)
296
        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], ~0x7);
297
    if (ra != 31)
298
        tcg_gen_mov_i64(cpu_T[1], cpu_ir[ra]);
299
    else
300
        tcg_gen_movi_i64(cpu_T[1], 0);
301
    (*gen_store_op)(ctx);
302
}
303

    
304
static always_inline void gen_load_fmem (DisasContext *ctx,
305
                                         void (*gen_load_fop)(DisasContext *ctx),
306
                                         int ra, int rb, int32_t disp16)
307
{
308
    if (rb != 31)
309
        tcg_gen_addi_i64(cpu_T[0], cpu_ir[rb], disp16);
310
    else
311
        tcg_gen_movi_i64(cpu_T[0], disp16);
312
    (*gen_load_fop)(ctx);
313
    gen_store_fir(ctx, ra, 1);
314
}
315

    
316
static always_inline void gen_store_fmem (DisasContext *ctx,
317
                                          void (*gen_store_fop)(DisasContext *ctx),
318
                                          int ra, int rb, int32_t disp16)
319
{
320
    if (rb != 31)
321
        tcg_gen_addi_i64(cpu_T[0], cpu_ir[rb], disp16);
322
    else
323
        tcg_gen_movi_i64(cpu_T[0], disp16);
324
    gen_load_fir(ctx, ra, 1);
325
    (*gen_store_fop)(ctx);
326
}
327

    
328
static always_inline void gen_bcond (DisasContext *ctx,
329
                                     TCGCond cond,
330
                                     int ra, int32_t disp16, int mask)
331
{
332
    int l1, l2;
333

    
334
    l1 = gen_new_label();
335
    l2 = gen_new_label();
336
    if (likely(ra != 31)) {
337
        if (mask) {
338
            TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
339
            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
340
            tcg_gen_brcondi_i64(cond, tmp, 0, l1);
341
            tcg_temp_free(tmp);
342
        } else
343
            tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
344
    } else {
345
        /* Very uncommon case - Do not bother to optimize.  */
346
        TCGv tmp = tcg_const_i64(0);
347
        tcg_gen_brcondi_i64(cond, tmp, 0, l1);
348
        tcg_temp_free(tmp);
349
    }
350
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
351
    tcg_gen_br(l2);
352
    gen_set_label(l1);
353
    tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
354
    gen_set_label(l2);
355
}
356

    
357
static always_inline void gen_fbcond (DisasContext *ctx,
358
                                      void (*gen_test_op)(void),
359
                                      int ra, int32_t disp16)
360
{
361
    tcg_gen_movi_i64(cpu_T[1], ctx->pc + (int64_t)(disp16 << 2));
362
    gen_load_fir(ctx, ra, 0);
363
    (*gen_test_op)();
364
    _gen_op_bcond(ctx);
365
}
366

    
367
static always_inline void gen_cmov (DisasContext *ctx,
368
                                    TCGCond inv_cond,
369
                                    int ra, int rb, int rc,
370
                                    int islit, uint8_t lit, int mask)
371
{
372
    int l1;
373

    
374
    if (unlikely(rc == 31))
375
        return;
376

    
377
    l1 = gen_new_label();
378

    
379
    if (ra != 31) {
380
        if (mask) {
381
            TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
382
            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
383
            tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
384
            tcg_temp_free(tmp);
385
        } else
386
            tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
387
    } else {
388
        /* Very uncommon case - Do not bother to optimize.  */
389
        TCGv tmp = tcg_const_i64(0);
390
        tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
391
        tcg_temp_free(tmp);
392
    }
393

    
394
    if (islit)
395
        tcg_gen_movi_i64(cpu_ir[rc], lit);
396
    else
397
        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
398
    gen_set_label(l1);
399
}
400

    
401
static always_inline void gen_farith2 (DisasContext *ctx,
402
                                       void (*gen_arith_fop)(void),
403
                                       int rb, int rc)
404
{
405
    gen_load_fir(ctx, rb, 0);
406
    (*gen_arith_fop)();
407
    gen_store_fir(ctx, rc, 0);
408
}
409

    
410
static always_inline void gen_farith3 (DisasContext *ctx,
411
                                       void (*gen_arith_fop)(void),
412
                                       int ra, int rb, int rc)
413
{
414
    gen_load_fir(ctx, ra, 0);
415
    gen_load_fir(ctx, rb, 1);
416
    (*gen_arith_fop)();
417
    gen_store_fir(ctx, rc, 0);
418
}
419

    
420
static always_inline void gen_fcmov (DisasContext *ctx,
421
                                     void (*gen_test_fop)(void),
422
                                     int ra, int rb, int rc)
423
{
424
    gen_load_fir(ctx, ra, 0);
425
    gen_load_fir(ctx, rb, 1);
426
    (*gen_test_fop)();
427
    gen_op_cmov_fir(rc);
428
}
429

    
430
static always_inline void gen_fti (DisasContext *ctx,
431
                                   void (*gen_move_fop)(void),
432
                                   int ra, int rc)
433
{
434
    gen_load_fir(ctx, rc, 0);
435
    (*gen_move_fop)();
436
    if (ra != 31)
437
        tcg_gen_mov_i64(cpu_ir[ra], cpu_T[0]);
438
}
439

    
440
static always_inline void gen_itf (DisasContext *ctx,
441
                                   void (*gen_move_fop)(void),
442
                                   int ra, int rc)
443
{
444
    if (ra != 31)
445
        tcg_gen_mov_i64(cpu_T[0], cpu_ir[ra]);
446
    else
447
        tcg_gen_movi_i64(cpu_T[0], 0);
448
    (*gen_move_fop)();
449
    gen_store_fir(ctx, rc, 0);
450
}
451

    
452
/* EXTWH, EXTWH, EXTLH, EXTQH */
453
static always_inline void gen_ext_h(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
454
                                    int ra, int rb, int rc,
455
                                    int islit, uint8_t lit)
456
{
457
    if (unlikely(rc == 31))
458
        return;
459

    
460
    if (ra != 31) {
461
        if (islit) {
462
            if (lit != 0)
463
                tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 64 - ((lit & 7) * 8));
464
            else
465
                tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
466
        } else {
467
            TCGv tmp1, tmp2;
468
            tmp1 = tcg_temp_new(TCG_TYPE_I64);
469
            tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
470
            tcg_gen_shli_i64(tmp1, tmp1, 3);
471
            tmp2 = tcg_const_i64(64);
472
            tcg_gen_sub_i64(tmp1, tmp2, tmp1);
473
            tcg_temp_free(tmp2);
474
            tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
475
            tcg_temp_free(tmp1);
476
        }
477
        if (tcg_gen_ext_i64)
478
            tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
479
    } else
480
        tcg_gen_movi_i64(cpu_ir[rc], 0);
481
}
482

    
483
/* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */
484
static always_inline void gen_ext_l(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
485
                                    int ra, int rb, int rc,
486
                                    int islit, uint8_t lit)
487
{
488
    if (unlikely(rc == 31))
489
        return;
490

    
491
    if (ra != 31) {
492
        if (islit) {
493
                tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
494
        } else {
495
            TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
496
            tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
497
            tcg_gen_shli_i64(tmp, tmp, 3);
498
            tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
499
            tcg_temp_free(tmp);
500
        }
501
        if (tcg_gen_ext_i64)
502
            tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
503
    } else
504
        tcg_gen_movi_i64(cpu_ir[rc], 0);
505
}
506

    
507
/* Code to call arith3 helpers */
508
static always_inline void gen_arith3_helper(void *helper,
509
                                            int ra, int rb, int rc,
510
                                            int islit, uint8_t lit)
511
{
512
    if (unlikely(rc == 31))
513
        return;
514

    
515
    if (ra != 31) {
516
        if (islit) {
517
            TCGv tmp = tcg_const_i64(lit);
518
            tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], tmp);
519
            tcg_temp_free(tmp);
520
        } else
521
            tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
522
    } else {
523
        TCGv tmp1 = tcg_const_i64(0);
524
        if (islit) {
525
            TCGv tmp2 = tcg_const_i64(lit);
526
            tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, tmp2);
527
            tcg_temp_free(tmp2);
528
        } else
529
            tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, cpu_ir[rb]);
530
        tcg_temp_free(tmp1);
531
    }
532
}
533

    
534
static always_inline void gen_cmp(TCGCond cond,
535
                                  int ra, int rb, int rc,
536
                                  int islit, uint8_t lit)
537
{
538
    int l1, l2;
539
    TCGv tmp;
540

    
541
    if (unlikely(rc == 31))
542
    return;
543

    
544
    l1 = gen_new_label();
545
    l2 = gen_new_label();
546

    
547
    if (ra != 31) {
548
        tmp = tcg_temp_new(TCG_TYPE_I64);
549
        tcg_gen_mov_i64(tmp, cpu_ir[ra]);
550
    } else
551
        tmp = tcg_const_i64(0);
552
    if (islit)
553
        tcg_gen_brcondi_i64(cond, tmp, lit, l1);
554
    else
555
        tcg_gen_brcond_i64(cond, tmp, cpu_ir[rb], l1);
556

    
557
    tcg_gen_movi_i64(cpu_ir[rc], 0);
558
    tcg_gen_br(l2);
559
    gen_set_label(l1);
560
    tcg_gen_movi_i64(cpu_ir[rc], 1);
561
    gen_set_label(l2);
562
}
563

    
564
static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
565
{
566
    uint32_t palcode;
567
    int32_t disp21, disp16, disp12;
568
    uint16_t fn11, fn16;
569
    uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
570
    uint8_t lit;
571
    int ret;
572

    
573
    /* Decode all instruction fields */
574
    opc = insn >> 26;
575
    ra = (insn >> 21) & 0x1F;
576
    rb = (insn >> 16) & 0x1F;
577
    rc = insn & 0x1F;
578
    sbz = (insn >> 13) & 0x07;
579
    islit = (insn >> 12) & 1;
580
    if (rb == 31 && !islit) {
581
        islit = 1;
582
        lit = 0;
583
    } else
584
        lit = (insn >> 13) & 0xFF;
585
    palcode = insn & 0x03FFFFFF;
586
    disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
587
    disp16 = (int16_t)(insn & 0x0000FFFF);
588
    disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
589
    fn16 = insn & 0x0000FFFF;
590
    fn11 = (insn >> 5) & 0x000007FF;
591
    fpfn = fn11 & 0x3F;
592
    fn7 = (insn >> 5) & 0x0000007F;
593
    fn2 = (insn >> 5) & 0x00000003;
594
    ret = 0;
595
#if defined ALPHA_DEBUG_DISAS
596
    if (logfile != NULL) {
597
        fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n",
598
                opc, ra, rb, rc, disp16);
599
    }
600
#endif
601
    switch (opc) {
602
    case 0x00:
603
        /* CALL_PAL */
604
        if (palcode >= 0x80 && palcode < 0xC0) {
605
            /* Unprivileged PAL call */
606
            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);
607
#if !defined (CONFIG_USER_ONLY)
608
        } else if (palcode < 0x40) {
609
            /* Privileged PAL code */
610
            if (ctx->mem_idx & 1)
611
                goto invalid_opc;
612
            else
613
                gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0);
614
#endif
615
        } else {
616
            /* Invalid PAL call */
617
            goto invalid_opc;
618
        }
619
        ret = 3;
620
        break;
621
    case 0x01:
622
        /* OPC01 */
623
        goto invalid_opc;
624
    case 0x02:
625
        /* OPC02 */
626
        goto invalid_opc;
627
    case 0x03:
628
        /* OPC03 */
629
        goto invalid_opc;
630
    case 0x04:
631
        /* OPC04 */
632
        goto invalid_opc;
633
    case 0x05:
634
        /* OPC05 */
635
        goto invalid_opc;
636
    case 0x06:
637
        /* OPC06 */
638
        goto invalid_opc;
639
    case 0x07:
640
        /* OPC07 */
641
        goto invalid_opc;
642
    case 0x08:
643
        /* LDA */
644
        if (likely(ra != 31)) {
645
            if (rb != 31)
646
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
647
            else
648
                tcg_gen_movi_i64(cpu_ir[ra], disp16);
649
        }
650
        break;
651
    case 0x09:
652
        /* LDAH */
653
        if (likely(ra != 31)) {
654
            if (rb != 31)
655
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
656
            else
657
                tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
658
        }
659
        break;
660
    case 0x0A:
661
        /* LDBU */
662
        if (!(ctx->amask & AMASK_BWX))
663
            goto invalid_opc;
664
        gen_load_mem(ctx, &gen_ldbu, ra, rb, disp16, 0);
665
        break;
666
    case 0x0B:
667
        /* LDQ_U */
668
        gen_load_mem(ctx, &gen_ldq_u, ra, rb, disp16, 1);
669
        break;
670
    case 0x0C:
671
        /* LDWU */
672
        if (!(ctx->amask & AMASK_BWX))
673
            goto invalid_opc;
674
        gen_load_mem(ctx, &gen_ldwu, ra, rb, disp16, 0);
675
        break;
676
    case 0x0D:
677
        /* STW */
678
        if (!(ctx->amask & AMASK_BWX))
679
            goto invalid_opc;
680
        gen_store_mem(ctx, &gen_stw, ra, rb, disp16, 0);
681
        break;
682
    case 0x0E:
683
        /* STB */
684
        if (!(ctx->amask & AMASK_BWX))
685
            goto invalid_opc;
686
        gen_store_mem(ctx, &gen_stb, ra, rb, disp16, 0);
687
        break;
688
    case 0x0F:
689
        /* STQ_U */
690
        gen_store_mem(ctx, &gen_stq_u, ra, rb, disp16, 1);
691
        break;
692
    case 0x10:
693
        switch (fn7) {
694
        case 0x00:
695
            /* ADDL */
696
            if (likely(rc != 31)) {
697
                if (ra != 31) {
698
                    if (islit) {
699
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
700
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
701
                    } else {
702
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
703
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
704
                    }
705
                } else {
706
                    if (islit)
707
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
708
                    else
709
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
710
                }
711
            }
712
            break;
713
        case 0x02:
714
            /* S4ADDL */
715
            if (likely(rc != 31)) {
716
                if (ra != 31) {
717
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
718
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
719
                    if (islit)
720
                        tcg_gen_addi_i64(tmp, tmp, lit);
721
                    else
722
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
723
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
724
                    tcg_temp_free(tmp);
725
                } else {
726
                    if (islit)
727
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
728
                    else
729
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
730
                }
731
            }
732
            break;
733
        case 0x09:
734
            /* SUBL */
735
            if (likely(rc != 31)) {
736
                if (ra != 31) {
737
                    if (islit)
738
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
739
                    else
740
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
741
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
742
                } else {
743
                    if (islit)
744
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
745
                    else {
746
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
747
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
748
                }
749
            }
750
            break;
751
        case 0x0B:
752
            /* S4SUBL */
753
            if (likely(rc != 31)) {
754
                if (ra != 31) {
755
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
756
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
757
                    if (islit)
758
                        tcg_gen_subi_i64(tmp, tmp, lit);
759
                    else
760
                        tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
761
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
762
                    tcg_temp_free(tmp);
763
                } else {
764
                    if (islit)
765
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
766
                    else {
767
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
768
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
769
                    }
770
                }
771
            }
772
            break;
773
        case 0x0F:
774
            /* CMPBGE */
775
            gen_arith3_helper(helper_cmpbge, ra, rb, rc, islit, lit);
776
            break;
777
        case 0x12:
778
            /* S8ADDL */
779
            if (likely(rc != 31)) {
780
                if (ra != 31) {
781
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
782
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
783
                    if (islit)
784
                        tcg_gen_addi_i64(tmp, tmp, lit);
785
                    else
786
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
787
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
788
                    tcg_temp_free(tmp);
789
                } else {
790
                    if (islit)
791
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
792
                    else
793
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
794
                }
795
            }
796
            break;
797
        case 0x1B:
798
            /* S8SUBL */
799
            if (likely(rc != 31)) {
800
                if (ra != 31) {
801
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
802
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
803
                    if (islit)
804
                        tcg_gen_subi_i64(tmp, tmp, lit);
805
                    else
806
                       tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
807
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
808
                    tcg_temp_free(tmp);
809
                } else {
810
                    if (islit)
811
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
812
                    else
813
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
814
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
815
                    }
816
                }
817
            }
818
            break;
819
        case 0x1D:
820
            /* CMPULT */
821
            gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
822
            break;
823
        case 0x20:
824
            /* ADDQ */
825
            if (likely(rc != 31)) {
826
                if (ra != 31) {
827
                    if (islit)
828
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
829
                    else
830
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
831
                } else {
832
                    if (islit)
833
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
834
                    else
835
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
836
                }
837
            }
838
            break;
839
        case 0x22:
840
            /* S4ADDQ */
841
            if (likely(rc != 31)) {
842
                if (ra != 31) {
843
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
844
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
845
                    if (islit)
846
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
847
                    else
848
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
849
                    tcg_temp_free(tmp);
850
                } else {
851
                    if (islit)
852
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
853
                    else
854
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
855
                }
856
            }
857
            break;
858
        case 0x29:
859
            /* SUBQ */
860
            if (likely(rc != 31)) {
861
                if (ra != 31) {
862
                    if (islit)
863
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
864
                    else
865
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
866
                } else {
867
                    if (islit)
868
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
869
                    else
870
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
871
                }
872
            }
873
            break;
874
        case 0x2B:
875
            /* S4SUBQ */
876
            if (likely(rc != 31)) {
877
                if (ra != 31) {
878
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
879
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
880
                    if (islit)
881
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
882
                    else
883
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
884
                    tcg_temp_free(tmp);
885
                } else {
886
                    if (islit)
887
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
888
                    else
889
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
890
                }
891
            }
892
            break;
893
        case 0x2D:
894
            /* CMPEQ */
895
            gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
896
            break;
897
        case 0x32:
898
            /* S8ADDQ */
899
            if (likely(rc != 31)) {
900
                if (ra != 31) {
901
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
902
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
903
                    if (islit)
904
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
905
                    else
906
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
907
                    tcg_temp_free(tmp);
908
                } else {
909
                    if (islit)
910
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
911
                    else
912
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
913
                }
914
            }
915
            break;
916
        case 0x3B:
917
            /* S8SUBQ */
918
            if (likely(rc != 31)) {
919
                if (ra != 31) {
920
                    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
921
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
922
                    if (islit)
923
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
924
                    else
925
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
926
                    tcg_temp_free(tmp);
927
                } else {
928
                    if (islit)
929
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
930
                    else
931
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
932
                }
933
            }
934
            break;
935
        case 0x3D:
936
            /* CMPULE */
937
            gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
938
            break;
939
        case 0x40:
940
            /* ADDL/V */
941
            gen_arith3_helper(helper_addlv, ra, rb, rc, islit, lit);
942
            break;
943
        case 0x49:
944
            /* SUBL/V */
945
            gen_arith3_helper(helper_sublv, ra, rb, rc, islit, lit);
946
            break;
947
        case 0x4D:
948
            /* CMPLT */
949
            gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
950
            break;
951
        case 0x60:
952
            /* ADDQ/V */
953
            gen_arith3_helper(helper_addqv, ra, rb, rc, islit, lit);
954
            break;
955
        case 0x69:
956
            /* SUBQ/V */
957
            gen_arith3_helper(helper_subqv, ra, rb, rc, islit, lit);
958
            break;
959
        case 0x6D:
960
            /* CMPLE */
961
            gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
962
            break;
963
        default:
964
            goto invalid_opc;
965
        }
966
        break;
967
    case 0x11:
968
        switch (fn7) {
969
        case 0x00:
970
            /* AND */
971
            if (likely(rc != 31)) {
972
                if (ra == 31)
973
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
974
                else if (islit)
975
                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
976
                else
977
                    tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
978
            }
979
            break;
980
        case 0x08:
981
            /* BIC */
982
            if (likely(rc != 31)) {
983
                if (ra != 31) {
984
                    if (islit)
985
                        tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
986
                    else {
987
                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
988
                        tcg_gen_not_i64(tmp, cpu_ir[rb]);
989
                        tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], tmp);
990
                        tcg_temp_free(tmp);
991
                    }
992
                } else
993
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
994
            }
995
            break;
996
        case 0x14:
997
            /* CMOVLBS */
998
            gen_cmov(ctx, TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
999
            break;
1000
        case 0x16:
1001
            /* CMOVLBC */
1002
            gen_cmov(ctx, TCG_COND_NE, ra, rb, rc, islit, lit, 1);
1003
            break;
1004
        case 0x20:
1005
            /* BIS */
1006
            if (likely(rc != 31)) {
1007
                if (ra != 31) {
1008
                    if (islit)
1009
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
1010
                    else
1011
                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1012
                } else {
1013
                    if (islit)
1014
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1015
                    else
1016
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1017
                }
1018
            }
1019
            break;
1020
        case 0x24:
1021
            /* CMOVEQ */
1022
            gen_cmov(ctx, TCG_COND_NE, ra, rb, rc, islit, lit, 0);
1023
            break;
1024
        case 0x26:
1025
            /* CMOVNE */
1026
            gen_cmov(ctx, TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
1027
            break;
1028
        case 0x28:
1029
            /* ORNOT */
1030
            if (likely(rc != 31)) {
1031
                if (ra != 31) {
1032
                    if (islit)
1033
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1034
                    else {
1035
                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
1036
                        tcg_gen_not_i64(tmp, cpu_ir[rb]);
1037
                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], tmp);
1038
                        tcg_temp_free(tmp);
1039
                    }
1040
                } else {
1041
                    if (islit)
1042
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
1043
                    else
1044
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
1045
                }
1046
            }
1047
            break;
1048
        case 0x40:
1049
            /* XOR */
1050
            if (likely(rc != 31)) {
1051
                if (ra != 31) {
1052
                    if (islit)
1053
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
1054
                    else
1055
                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1056
                } else {
1057
                    if (islit)
1058
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1059
                    else
1060
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1061
                }
1062
            }
1063
            break;
1064
        case 0x44:
1065
            /* CMOVLT */
1066
            gen_cmov(ctx, TCG_COND_GE, ra, rb, rc, islit, lit, 0);
1067
            break;
1068
        case 0x46:
1069
            /* CMOVGE */
1070
            gen_cmov(ctx, TCG_COND_LT, ra, rb, rc, islit, lit, 0);
1071
            break;
1072
        case 0x48:
1073
            /* EQV */
1074
            if (likely(rc != 31)) {
1075
                if (ra != 31) {
1076
                    if (islit)
1077
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1078
                    else {
1079
                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
1080
                        tcg_gen_not_i64(tmp, cpu_ir[rb]);
1081
                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], tmp);
1082
                        tcg_temp_free(tmp);
1083
                    }
1084
                } else {
1085
                    if (islit)
1086
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
1087
                    else
1088
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
1089
                }
1090
            }
1091
            break;
1092
        case 0x61:
1093
            /* AMASK */
1094
            if (likely(rc != 31)) {
1095
                if (islit)
1096
                    tcg_gen_movi_i64(cpu_ir[rc], helper_amask(lit));
1097
                else
1098
                    tcg_gen_helper_1_1(helper_amask, cpu_ir[rc], cpu_ir[rb]);
1099
            }
1100
            break;
1101
        case 0x64:
1102
            /* CMOVLE */
1103
            gen_cmov(ctx, TCG_COND_GT, ra, rb, rc, islit, lit, 0);
1104
            break;
1105
        case 0x66:
1106
            /* CMOVGT */
1107
            gen_cmov(ctx, TCG_COND_LE, ra, rb, rc, islit, lit, 0);
1108
            break;
1109
        case 0x6C:
1110
            /* IMPLVER */
1111
            if (rc != 31)
1112
                tcg_gen_helper_1_0(helper_load_implver, cpu_ir[rc]);
1113
            break;
1114
        default:
1115
            goto invalid_opc;
1116
        }
1117
        break;
1118
    case 0x12:
1119
        switch (fn7) {
1120
        case 0x02:
1121
            /* MSKBL */
1122
            gen_arith3_helper(helper_mskbl, ra, rb, rc, islit, lit);
1123
            break;
1124
        case 0x06:
1125
            /* EXTBL */
1126
            gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit);
1127
            break;
1128
        case 0x0B:
1129
            /* INSBL */
1130
            gen_arith3_helper(helper_insbl, ra, rb, rc, islit, lit);
1131
            break;
1132
        case 0x12:
1133
            /* MSKWL */
1134
            gen_arith3_helper(helper_mskwl, ra, rb, rc, islit, lit);
1135
            break;
1136
        case 0x16:
1137
            /* EXTWL */
1138
            gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1139
            break;
1140
        case 0x1B:
1141
            /* INSWL */
1142
            gen_arith3_helper(helper_inswl, ra, rb, rc, islit, lit);
1143
            break;
1144
        case 0x22:
1145
            /* MSKLL */
1146
            gen_arith3_helper(helper_mskll, ra, rb, rc, islit, lit);
1147
            break;
1148
        case 0x26:
1149
            /* EXTLL */
1150
            gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
1151
            break;
1152
        case 0x2B:
1153
            /* INSLL */
1154
            gen_arith3_helper(helper_insll, ra, rb, rc, islit, lit);
1155
            break;
1156
        case 0x30:
1157
            /* ZAP */
1158
            gen_arith3_helper(helper_zap, ra, rb, rc, islit, lit);
1159
            break;
1160
        case 0x31:
1161
            /* ZAPNOT */
1162
            gen_arith3_helper(helper_zapnot, ra, rb, rc, islit, lit);
1163
            break;
1164
        case 0x32:
1165
            /* MSKQL */
1166
            gen_arith3_helper(helper_mskql, ra, rb, rc, islit, lit);
1167
            break;
1168
        case 0x34:
1169
            /* SRL */
1170
            if (likely(rc != 31)) {
1171
                if (ra != 31) {
1172
                    if (islit)
1173
                        tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
1174
                    else {
1175
                        TCGv shift = tcg_temp_new(TCG_TYPE_I64);
1176
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1177
                        tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
1178
                        tcg_temp_free(shift);
1179
                    }
1180
                } else
1181
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1182
            }
1183
            break;
1184
        case 0x36:
1185
            /* EXTQL */
1186
            gen_ext_l(NULL, ra, rb, rc, islit, lit);
1187
            break;
1188
        case 0x39:
1189
            /* SLL */
1190
            if (likely(rc != 31)) {
1191
                if (ra != 31) {
1192
                    if (islit)
1193
                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
1194
                    else {
1195
                        TCGv shift = tcg_temp_new(TCG_TYPE_I64);
1196
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1197
                        tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
1198
                        tcg_temp_free(shift);
1199
                    }
1200
                } else
1201
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1202
            }
1203
            break;
1204
        case 0x3B:
1205
            /* INSQL */
1206
            gen_arith3_helper(helper_insql, ra, rb, rc, islit, lit);
1207
            break;
1208
        case 0x3C:
1209
            /* SRA */
1210
            if (likely(rc != 31)) {
1211
                if (ra != 31) {
1212
                    if (islit)
1213
                        tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
1214
                    else {
1215
                        TCGv shift = tcg_temp_new(TCG_TYPE_I64);
1216
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1217
                        tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
1218
                        tcg_temp_free(shift);
1219
                    }
1220
                } else
1221
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1222
            }
1223
            break;
1224
        case 0x52:
1225
            /* MSKWH */
1226
            gen_arith3_helper(helper_mskwh, ra, rb, rc, islit, lit);
1227
            break;
1228
        case 0x57:
1229
            /* INSWH */
1230
            gen_arith3_helper(helper_inswh, ra, rb, rc, islit, lit);
1231
            break;
1232
        case 0x5A:
1233
            /* EXTWH */
1234
            gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1235
            break;
1236
        case 0x62:
1237
            /* MSKLH */
1238
            gen_arith3_helper(helper_msklh, ra, rb, rc, islit, lit);
1239
            break;
1240
        case 0x67:
1241
            /* INSLH */
1242
            gen_arith3_helper(helper_inslh, ra, rb, rc, islit, lit);
1243
            break;
1244
        case 0x6A:
1245
            /* EXTLH */
1246
            gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1247
            break;
1248
        case 0x72:
1249
            /* MSKQH */
1250
            gen_arith3_helper(helper_mskqh, ra, rb, rc, islit, lit);
1251
            break;
1252
        case 0x77:
1253
            /* INSQH */
1254
            gen_arith3_helper(helper_insqh, ra, rb, rc, islit, lit);
1255
            break;
1256
        case 0x7A:
1257
            /* EXTQH */
1258
            gen_ext_h(NULL, ra, rb, rc, islit, lit);
1259
            break;
1260
        default:
1261
            goto invalid_opc;
1262
        }
1263
        break;
1264
    case 0x13:
1265
        switch (fn7) {
1266
        case 0x00:
1267
            /* MULL */
1268
            if (likely(rc != 31)) {
1269
                if (ra == 31)
1270
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1271
                else {
1272
                    if (islit)
1273
                        tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1274
                    else
1275
                        tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1276
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1277
                }
1278
            }
1279
            break;
1280
        case 0x20:
1281
            /* MULQ */
1282
            if (likely(rc != 31)) {
1283
                if (ra == 31)
1284
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1285
                else if (islit)
1286
                    tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1287
                else
1288
                    tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1289
            }
1290
            break;
1291
        case 0x30:
1292
            /* UMULH */
1293
            gen_arith3_helper(helper_umulh, ra, rb, rc, islit, lit);
1294
            break;
1295
        case 0x40:
1296
            /* MULL/V */
1297
            gen_arith3_helper(helper_mullv, ra, rb, rc, islit, lit);
1298
            break;
1299
        case 0x60:
1300
            /* MULQ/V */
1301
            gen_arith3_helper(helper_mulqv, ra, rb, rc, islit, lit);
1302
            break;
1303
        default:
1304
            goto invalid_opc;
1305
        }
1306
        break;
1307
    case 0x14:
1308
        switch (fpfn) { /* f11 & 0x3F */
1309
        case 0x04:
1310
            /* ITOFS */
1311
            if (!(ctx->amask & AMASK_FIX))
1312
                goto invalid_opc;
1313
            gen_itf(ctx, &gen_op_itofs, ra, rc);
1314
            break;
1315
        case 0x0A:
1316
            /* SQRTF */
1317
            if (!(ctx->amask & AMASK_FIX))
1318
                goto invalid_opc;
1319
            gen_farith2(ctx, &gen_op_sqrtf, rb, rc);
1320
            break;
1321
        case 0x0B:
1322
            /* SQRTS */
1323
            if (!(ctx->amask & AMASK_FIX))
1324
                goto invalid_opc;
1325
            gen_farith2(ctx, &gen_op_sqrts, rb, rc);
1326
            break;
1327
        case 0x14:
1328
            /* ITOFF */
1329
            if (!(ctx->amask & AMASK_FIX))
1330
                goto invalid_opc;
1331
#if 0 // TODO
1332
            gen_itf(ctx, &gen_op_itoff, ra, rc);
1333
#else
1334
            goto invalid_opc;
1335
#endif
1336
            break;
1337
        case 0x24:
1338
            /* ITOFT */
1339
            if (!(ctx->amask & AMASK_FIX))
1340
                goto invalid_opc;
1341
            gen_itf(ctx, &gen_op_itoft, ra, rc);
1342
            break;
1343
        case 0x2A:
1344
            /* SQRTG */
1345
            if (!(ctx->amask & AMASK_FIX))
1346
                goto invalid_opc;
1347
            gen_farith2(ctx, &gen_op_sqrtg, rb, rc);
1348
            break;
1349
        case 0x02B:
1350
            /* SQRTT */
1351
            if (!(ctx->amask & AMASK_FIX))
1352
                goto invalid_opc;
1353
            gen_farith2(ctx, &gen_op_sqrtt, rb, rc);
1354
            break;
1355
        default:
1356
            goto invalid_opc;
1357
        }
1358
        break;
1359
    case 0x15:
1360
        /* VAX floating point */
1361
        /* XXX: rounding mode and trap are ignored (!) */
1362
        switch (fpfn) { /* f11 & 0x3F */
1363
        case 0x00:
1364
            /* ADDF */
1365
            gen_farith3(ctx, &gen_op_addf, ra, rb, rc);
1366
            break;
1367
        case 0x01:
1368
            /* SUBF */
1369
            gen_farith3(ctx, &gen_op_subf, ra, rb, rc);
1370
            break;
1371
        case 0x02:
1372
            /* MULF */
1373
            gen_farith3(ctx, &gen_op_mulf, ra, rb, rc);
1374
            break;
1375
        case 0x03:
1376
            /* DIVF */
1377
            gen_farith3(ctx, &gen_op_divf, ra, rb, rc);
1378
            break;
1379
        case 0x1E:
1380
            /* CVTDG */
1381
#if 0 // TODO
1382
            gen_farith2(ctx, &gen_op_cvtdg, rb, rc);
1383
#else
1384
            goto invalid_opc;
1385
#endif
1386
            break;
1387
        case 0x20:
1388
            /* ADDG */
1389
            gen_farith3(ctx, &gen_op_addg, ra, rb, rc);
1390
            break;
1391
        case 0x21:
1392
            /* SUBG */
1393
            gen_farith3(ctx, &gen_op_subg, ra, rb, rc);
1394
            break;
1395
        case 0x22:
1396
            /* MULG */
1397
            gen_farith3(ctx, &gen_op_mulg, ra, rb, rc);
1398
            break;
1399
        case 0x23:
1400
            /* DIVG */
1401
            gen_farith3(ctx, &gen_op_divg, ra, rb, rc);
1402
            break;
1403
        case 0x25:
1404
            /* CMPGEQ */
1405
            gen_farith3(ctx, &gen_op_cmpgeq, ra, rb, rc);
1406
            break;
1407
        case 0x26:
1408
            /* CMPGLT */
1409
            gen_farith3(ctx, &gen_op_cmpglt, ra, rb, rc);
1410
            break;
1411
        case 0x27:
1412
            /* CMPGLE */
1413
            gen_farith3(ctx, &gen_op_cmpgle, ra, rb, rc);
1414
            break;
1415
        case 0x2C:
1416
            /* CVTGF */
1417
            gen_farith2(ctx, &gen_op_cvtgf, rb, rc);
1418
            break;
1419
        case 0x2D:
1420
            /* CVTGD */
1421
#if 0 // TODO
1422
            gen_farith2(ctx, &gen_op_cvtgd, rb, rc);
1423
#else
1424
            goto invalid_opc;
1425
#endif
1426
            break;
1427
        case 0x2F:
1428
            /* CVTGQ */
1429
            gen_farith2(ctx, &gen_op_cvtgq, rb, rc);
1430
            break;
1431
        case 0x3C:
1432
            /* CVTQF */
1433
            gen_farith2(ctx, &gen_op_cvtqf, rb, rc);
1434
            break;
1435
        case 0x3E:
1436
            /* CVTQG */
1437
            gen_farith2(ctx, &gen_op_cvtqg, rb, rc);
1438
            break;
1439
        default:
1440
            goto invalid_opc;
1441
        }
1442
        break;
1443
    case 0x16:
1444
        /* IEEE floating-point */
1445
        /* XXX: rounding mode and traps are ignored (!) */
1446
        switch (fpfn) { /* f11 & 0x3F */
1447
        case 0x00:
1448
            /* ADDS */
1449
            gen_farith3(ctx, &gen_op_adds, ra, rb, rc);
1450
            break;
1451
        case 0x01:
1452
            /* SUBS */
1453
            gen_farith3(ctx, &gen_op_subs, ra, rb, rc);
1454
            break;
1455
        case 0x02:
1456
            /* MULS */
1457
            gen_farith3(ctx, &gen_op_muls, ra, rb, rc);
1458
            break;
1459
        case 0x03:
1460
            /* DIVS */
1461
            gen_farith3(ctx, &gen_op_divs, ra, rb, rc);
1462
            break;
1463
        case 0x20:
1464
            /* ADDT */
1465
            gen_farith3(ctx, &gen_op_addt, ra, rb, rc);
1466
            break;
1467
        case 0x21:
1468
            /* SUBT */
1469
            gen_farith3(ctx, &gen_op_subt, ra, rb, rc);
1470
            break;
1471
        case 0x22:
1472
            /* MULT */
1473
            gen_farith3(ctx, &gen_op_mult, ra, rb, rc);
1474
            break;
1475
        case 0x23:
1476
            /* DIVT */
1477
            gen_farith3(ctx, &gen_op_divt, ra, rb, rc);
1478
            break;
1479
        case 0x24:
1480
            /* CMPTUN */
1481
            gen_farith3(ctx, &gen_op_cmptun, ra, rb, rc);
1482
            break;
1483
        case 0x25:
1484
            /* CMPTEQ */
1485
            gen_farith3(ctx, &gen_op_cmpteq, ra, rb, rc);
1486
            break;
1487
        case 0x26:
1488
            /* CMPTLT */
1489
            gen_farith3(ctx, &gen_op_cmptlt, ra, rb, rc);
1490
            break;
1491
        case 0x27:
1492
            /* CMPTLE */
1493
            gen_farith3(ctx, &gen_op_cmptle, ra, rb, rc);
1494
            break;
1495
        case 0x2C:
1496
            /* XXX: incorrect */
1497
            if (fn11 == 0x2AC) {
1498
                /* CVTST */
1499
                gen_farith2(ctx, &gen_op_cvtst, rb, rc);
1500
            } else {
1501
                /* CVTTS */
1502
                gen_farith2(ctx, &gen_op_cvtts, rb, rc);
1503
            }
1504
            break;
1505
        case 0x2F:
1506
            /* CVTTQ */
1507
            gen_farith2(ctx, &gen_op_cvttq, rb, rc);
1508
            break;
1509
        case 0x3C:
1510
            /* CVTQS */
1511
            gen_farith2(ctx, &gen_op_cvtqs, rb, rc);
1512
            break;
1513
        case 0x3E:
1514
            /* CVTQT */
1515
            gen_farith2(ctx, &gen_op_cvtqt, rb, rc);
1516
            break;
1517
        default:
1518
            goto invalid_opc;
1519
        }
1520
        break;
1521
    case 0x17:
1522
        switch (fn11) {
1523
        case 0x010:
1524
            /* CVTLQ */
1525
            gen_farith2(ctx, &gen_op_cvtlq, rb, rc);
1526
            break;
1527
        case 0x020:
1528
            /* CPYS */
1529
            if (ra == rb) {
1530
                if (ra == 31 && rc == 31) {
1531
                    /* FNOP */
1532
                    gen_op_nop();
1533
                } else {
1534
                    /* FMOV */
1535
                    gen_load_fir(ctx, rb, 0);
1536
                    gen_store_fir(ctx, rc, 0);
1537
                }
1538
            } else {
1539
                gen_farith3(ctx, &gen_op_cpys, ra, rb, rc);
1540
            }
1541
            break;
1542
        case 0x021:
1543
            /* CPYSN */
1544
            gen_farith2(ctx, &gen_op_cpysn, rb, rc);
1545
            break;
1546
        case 0x022:
1547
            /* CPYSE */
1548
            gen_farith2(ctx, &gen_op_cpyse, rb, rc);
1549
            break;
1550
        case 0x024:
1551
            /* MT_FPCR */
1552
            gen_load_fir(ctx, ra, 0);
1553
            gen_op_store_fpcr();
1554
            break;
1555
        case 0x025:
1556
            /* MF_FPCR */
1557
            gen_op_load_fpcr();
1558
            gen_store_fir(ctx, ra, 0);
1559
            break;
1560
        case 0x02A:
1561
            /* FCMOVEQ */
1562
            gen_fcmov(ctx, &gen_op_cmpfeq, ra, rb, rc);
1563
            break;
1564
        case 0x02B:
1565
            /* FCMOVNE */
1566
            gen_fcmov(ctx, &gen_op_cmpfne, ra, rb, rc);
1567
            break;
1568
        case 0x02C:
1569
            /* FCMOVLT */
1570
            gen_fcmov(ctx, &gen_op_cmpflt, ra, rb, rc);
1571
            break;
1572
        case 0x02D:
1573
            /* FCMOVGE */
1574
            gen_fcmov(ctx, &gen_op_cmpfge, ra, rb, rc);
1575
            break;
1576
        case 0x02E:
1577
            /* FCMOVLE */
1578
            gen_fcmov(ctx, &gen_op_cmpfle, ra, rb, rc);
1579
            break;
1580
        case 0x02F:
1581
            /* FCMOVGT */
1582
            gen_fcmov(ctx, &gen_op_cmpfgt, ra, rb, rc);
1583
            break;
1584
        case 0x030:
1585
            /* CVTQL */
1586
            gen_farith2(ctx, &gen_op_cvtql, rb, rc);
1587
            break;
1588
        case 0x130:
1589
            /* CVTQL/V */
1590
            gen_farith2(ctx, &gen_op_cvtqlv, rb, rc);
1591
            break;
1592
        case 0x530:
1593
            /* CVTQL/SV */
1594
            gen_farith2(ctx, &gen_op_cvtqlsv, rb, rc);
1595
            break;
1596
        default:
1597
            goto invalid_opc;
1598
        }
1599
        break;
1600
    case 0x18:
1601
        switch ((uint16_t)disp16) {
1602
        case 0x0000:
1603
            /* TRAPB */
1604
            /* No-op. Just exit from the current tb */
1605
            ret = 2;
1606
            break;
1607
        case 0x0400:
1608
            /* EXCB */
1609
            /* No-op. Just exit from the current tb */
1610
            ret = 2;
1611
            break;
1612
        case 0x4000:
1613
            /* MB */
1614
            /* No-op */
1615
            break;
1616
        case 0x4400:
1617
            /* WMB */
1618
            /* No-op */
1619
            break;
1620
        case 0x8000:
1621
            /* FETCH */
1622
            /* No-op */
1623
            break;
1624
        case 0xA000:
1625
            /* FETCH_M */
1626
            /* No-op */
1627
            break;
1628
        case 0xC000:
1629
            /* RPCC */
1630
            if (ra != 31)
1631
                tcg_gen_helper_1_0(helper_load_pcc, cpu_ir[ra]);
1632
            break;
1633
        case 0xE000:
1634
            /* RC */
1635
            if (ra != 31)
1636
                tcg_gen_helper_1_0(helper_rc, cpu_ir[ra]);
1637
            break;
1638
        case 0xE800:
1639
            /* ECB */
1640
            /* XXX: TODO: evict tb cache at address rb */
1641
#if 0
1642
            ret = 2;
1643
#else
1644
            goto invalid_opc;
1645
#endif
1646
            break;
1647
        case 0xF000:
1648
            /* RS */
1649
            if (ra != 31)
1650
                tcg_gen_helper_1_0(helper_rs, cpu_ir[ra]);
1651
            break;
1652
        case 0xF800:
1653
            /* WH64 */
1654
            /* No-op */
1655
            break;
1656
        default:
1657
            goto invalid_opc;
1658
        }
1659
        break;
1660
    case 0x19:
1661
        /* HW_MFPR (PALcode) */
1662
#if defined (CONFIG_USER_ONLY)
1663
        goto invalid_opc;
1664
#else
1665
        if (!ctx->pal_mode)
1666
            goto invalid_opc;
1667
        gen_op_mfpr(insn & 0xFF);
1668
        if (ra != 31)
1669
            tcg_gen_mov_i64(cpu_ir[ra], cpu_T[0]);
1670
        break;
1671
#endif
1672
    case 0x1A:
1673
        if (ra != 31)
1674
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
1675
        if (rb != 31)
1676
            tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
1677
        else
1678
            tcg_gen_movi_i64(cpu_pc, 0);
1679
        /* Those four jumps only differ by the branch prediction hint */
1680
        switch (fn2) {
1681
        case 0x0:
1682
            /* JMP */
1683
            break;
1684
        case 0x1:
1685
            /* JSR */
1686
            break;
1687
        case 0x2:
1688
            /* RET */
1689
            break;
1690
        case 0x3:
1691
            /* JSR_COROUTINE */
1692
            break;
1693
        }
1694
        ret = 1;
1695
        break;
1696
    case 0x1B:
1697
        /* HW_LD (PALcode) */
1698
#if defined (CONFIG_USER_ONLY)
1699
        goto invalid_opc;
1700
#else
1701
        if (!ctx->pal_mode)
1702
            goto invalid_opc;
1703
        if (rb != 31)
1704
            tcg_gen_mov_i64(cpu_T[0], cpu_ir[rb]);
1705
        else
1706
            tcg_gen_movi_i64(cpu_T[0], 0);
1707
        tcg_gen_movi_i64(cpu_T[1], disp12);
1708
        tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1709
        switch ((insn >> 12) & 0xF) {
1710
        case 0x0:
1711
            /* Longword physical access */
1712
            gen_op_ldl_raw();
1713
            break;
1714
        case 0x1:
1715
            /* Quadword physical access */
1716
            gen_op_ldq_raw();
1717
            break;
1718
        case 0x2:
1719
            /* Longword physical access with lock */
1720
            gen_op_ldl_l_raw();
1721
            break;
1722
        case 0x3:
1723
            /* Quadword physical access with lock */
1724
            gen_op_ldq_l_raw();
1725
            break;
1726
        case 0x4:
1727
            /* Longword virtual PTE fetch */
1728
            gen_op_ldl_kernel();
1729
            break;
1730
        case 0x5:
1731
            /* Quadword virtual PTE fetch */
1732
            gen_op_ldq_kernel();
1733
            break;
1734
        case 0x6:
1735
            /* Invalid */
1736
            goto invalid_opc;
1737
        case 0x7:
1738
            /* Invalid */
1739
            goto invalid_opc;
1740
        case 0x8:
1741
            /* Longword virtual access */
1742
            gen_op_ld_phys_to_virt();
1743
            gen_op_ldl_raw();
1744
            break;
1745
        case 0x9:
1746
            /* Quadword virtual access */
1747
            gen_op_ld_phys_to_virt();
1748
            gen_op_ldq_raw();
1749
            break;
1750
        case 0xA:
1751
            /* Longword virtual access with protection check */
1752
            gen_ldl(ctx);
1753
            break;
1754
        case 0xB:
1755
            /* Quadword virtual access with protection check */
1756
            gen_ldq(ctx);
1757
            break;
1758
        case 0xC:
1759
            /* Longword virtual access with altenate access mode */
1760
            gen_op_set_alt_mode();
1761
            gen_op_ld_phys_to_virt();
1762
            gen_op_ldl_raw();
1763
            gen_op_restore_mode();
1764
            break;
1765
        case 0xD:
1766
            /* Quadword virtual access with altenate access mode */
1767
            gen_op_set_alt_mode();
1768
            gen_op_ld_phys_to_virt();
1769
            gen_op_ldq_raw();
1770
            gen_op_restore_mode();
1771
            break;
1772
        case 0xE:
1773
            /* Longword virtual access with alternate access mode and
1774
             * protection checks
1775
             */
1776
            gen_op_set_alt_mode();
1777
            gen_op_ldl_data();
1778
            gen_op_restore_mode();
1779
            break;
1780
        case 0xF:
1781
            /* Quadword virtual access with alternate access mode and
1782
             * protection checks
1783
             */
1784
            gen_op_set_alt_mode();
1785
            gen_op_ldq_data();
1786
            gen_op_restore_mode();
1787
            break;
1788
        }
1789
        if (ra != 31)
1790
            tcg_gen_mov_i64(cpu_ir[ra], cpu_T[1]);
1791
        break;
1792
#endif
1793
    case 0x1C:
1794
        switch (fn7) {
1795
        case 0x00:
1796
            /* SEXTB */
1797
            if (!(ctx->amask & AMASK_BWX))
1798
                goto invalid_opc;
1799
            if (likely(rc != 31)) {
1800
                if (islit)
1801
                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
1802
                else
1803
                    tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
1804
            }
1805
            break;
1806
        case 0x01:
1807
            /* SEXTW */
1808
            if (!(ctx->amask & AMASK_BWX))
1809
                goto invalid_opc;
1810
            if (likely(rc != 31)) {
1811
                if (islit)
1812
                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
1813
                else
1814
                    tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
1815
            }
1816
            break;
1817
        case 0x30:
1818
            /* CTPOP */
1819
            if (!(ctx->amask & AMASK_CIX))
1820
                goto invalid_opc;
1821
            if (likely(rc != 31)) {
1822
                if (islit)
1823
                    tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
1824
                else
1825
                    tcg_gen_helper_1_1(helper_ctpop, cpu_ir[rc], cpu_ir[rb]);
1826
            }
1827
            break;
1828
        case 0x31:
1829
            /* PERR */
1830
            if (!(ctx->amask & AMASK_MVI))
1831
                goto invalid_opc;
1832
            /* XXX: TODO */
1833
            goto invalid_opc;
1834
            break;
1835
        case 0x32:
1836
            /* CTLZ */
1837
            if (!(ctx->amask & AMASK_CIX))
1838
                goto invalid_opc;
1839
            if (likely(rc != 31)) {
1840
                if (islit)
1841
                    tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
1842
                else
1843
                    tcg_gen_helper_1_1(helper_ctlz, cpu_ir[rc], cpu_ir[rb]);
1844
            }
1845
            break;
1846
        case 0x33:
1847
            /* CTTZ */
1848
            if (!(ctx->amask & AMASK_CIX))
1849
                goto invalid_opc;
1850
            if (likely(rc != 31)) {
1851
                if (islit)
1852
                    tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
1853
                else
1854
                    tcg_gen_helper_1_1(helper_cttz, cpu_ir[rc], cpu_ir[rb]);
1855
            }
1856
            break;
1857
        case 0x34:
1858
            /* UNPKBW */
1859
            if (!(ctx->amask & AMASK_MVI))
1860
                goto invalid_opc;
1861
            /* XXX: TODO */
1862
            goto invalid_opc;
1863
            break;
1864
        case 0x35:
1865
            /* UNPKWL */
1866
            if (!(ctx->amask & AMASK_MVI))
1867
                goto invalid_opc;
1868
            /* XXX: TODO */
1869
            goto invalid_opc;
1870
            break;
1871
        case 0x36:
1872
            /* PKWB */
1873
            if (!(ctx->amask & AMASK_MVI))
1874
                goto invalid_opc;
1875
            /* XXX: TODO */
1876
            goto invalid_opc;
1877
            break;
1878
        case 0x37:
1879
            /* PKLB */
1880
            if (!(ctx->amask & AMASK_MVI))
1881
                goto invalid_opc;
1882
            /* XXX: TODO */
1883
            goto invalid_opc;
1884
            break;
1885
        case 0x38:
1886
            /* MINSB8 */
1887
            if (!(ctx->amask & AMASK_MVI))
1888
                goto invalid_opc;
1889
            /* XXX: TODO */
1890
            goto invalid_opc;
1891
            break;
1892
        case 0x39:
1893
            /* MINSW4 */
1894
            if (!(ctx->amask & AMASK_MVI))
1895
                goto invalid_opc;
1896
            /* XXX: TODO */
1897
            goto invalid_opc;
1898
            break;
1899
        case 0x3A:
1900
            /* MINUB8 */
1901
            if (!(ctx->amask & AMASK_MVI))
1902
                goto invalid_opc;
1903
            /* XXX: TODO */
1904
            goto invalid_opc;
1905
            break;
1906
        case 0x3B:
1907
            /* MINUW4 */
1908
            if (!(ctx->amask & AMASK_MVI))
1909
                goto invalid_opc;
1910
            /* XXX: TODO */
1911
            goto invalid_opc;
1912
            break;
1913
        case 0x3C:
1914
            /* MAXUB8 */
1915
            if (!(ctx->amask & AMASK_MVI))
1916
                goto invalid_opc;
1917
            /* XXX: TODO */
1918
            goto invalid_opc;
1919
            break;
1920
        case 0x3D:
1921
            /* MAXUW4 */
1922
            if (!(ctx->amask & AMASK_MVI))
1923
                goto invalid_opc;
1924
            /* XXX: TODO */
1925
            goto invalid_opc;
1926
            break;
1927
        case 0x3E:
1928
            /* MAXSB8 */
1929
            if (!(ctx->amask & AMASK_MVI))
1930
                goto invalid_opc;
1931
            /* XXX: TODO */
1932
            goto invalid_opc;
1933
            break;
1934
        case 0x3F:
1935
            /* MAXSW4 */
1936
            if (!(ctx->amask & AMASK_MVI))
1937
                goto invalid_opc;
1938
            /* XXX: TODO */
1939
            goto invalid_opc;
1940
            break;
1941
        case 0x70:
1942
            /* FTOIT */
1943
            if (!(ctx->amask & AMASK_FIX))
1944
                goto invalid_opc;
1945
            gen_fti(ctx, &gen_op_ftoit, ra, rb);
1946
            break;
1947
        case 0x78:
1948
            /* FTOIS */
1949
            if (!(ctx->amask & AMASK_FIX))
1950
                goto invalid_opc;
1951
            gen_fti(ctx, &gen_op_ftois, ra, rb);
1952
            break;
1953
        default:
1954
            goto invalid_opc;
1955
        }
1956
        break;
1957
    case 0x1D:
1958
        /* HW_MTPR (PALcode) */
1959
#if defined (CONFIG_USER_ONLY)
1960
        goto invalid_opc;
1961
#else
1962
        if (!ctx->pal_mode)
1963
            goto invalid_opc;
1964
        if (ra != 31)
1965
            tcg_gen_mov_i64(cpu_T[0], cpu_ir[ra]);
1966
        else
1967
            tcg_gen_movi_i64(cpu_T[0], 0);
1968
        gen_op_mtpr(insn & 0xFF);
1969
        ret = 2;
1970
        break;
1971
#endif
1972
    case 0x1E:
1973
        /* HW_REI (PALcode) */
1974
#if defined (CONFIG_USER_ONLY)
1975
        goto invalid_opc;
1976
#else
1977
        if (!ctx->pal_mode)
1978
            goto invalid_opc;
1979
        if (rb == 31) {
1980
            /* "Old" alpha */
1981
            gen_op_hw_rei();
1982
        } else {
1983
            if (ra != 31)
1984
                tcg_gen_mov_i64(cpu_T[0], cpu_ir[rb]);
1985
            else
1986
                tcg_gen_movi_i64(cpu_T[0], 0);
1987
            tcg_gen_movi_i64(cpu_T[1], (((int64_t)insn << 51) >> 51));
1988
            tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1989
            gen_op_hw_ret();
1990
        }
1991
        ret = 2;
1992
        break;
1993
#endif
1994
    case 0x1F:
1995
        /* HW_ST (PALcode) */
1996
#if defined (CONFIG_USER_ONLY)
1997
        goto invalid_opc;
1998
#else
1999
        if (!ctx->pal_mode)
2000
            goto invalid_opc;
2001
        if (ra != 31)
2002
            tcg_gen_addi_i64(cpu_T[0], cpu_ir[rb], disp12);
2003
        else
2004
            tcg_gen_movi_i64(cpu_T[0], disp12);
2005
        if (ra != 31)
2006
            tcg_gen_mov_i64(cpu_T[1], cpu_ir[ra]);
2007
        else
2008
            tcg_gen_movi_i64(cpu_T[1], 0);
2009
        switch ((insn >> 12) & 0xF) {
2010
        case 0x0:
2011
            /* Longword physical access */
2012
            gen_op_stl_raw();
2013
            break;
2014
        case 0x1:
2015
            /* Quadword physical access */
2016
            gen_op_stq_raw();
2017
            break;
2018
        case 0x2:
2019
            /* Longword physical access with lock */
2020
            gen_op_stl_c_raw();
2021
            break;
2022
        case 0x3:
2023
            /* Quadword physical access with lock */
2024
            gen_op_stq_c_raw();
2025
            break;
2026
        case 0x4:
2027
            /* Longword virtual access */
2028
            gen_op_st_phys_to_virt();
2029
            gen_op_stl_raw();
2030
            break;
2031
        case 0x5:
2032
            /* Quadword virtual access */
2033
            gen_op_st_phys_to_virt();
2034
            gen_op_stq_raw();
2035
            break;
2036
        case 0x6:
2037
            /* Invalid */
2038
            goto invalid_opc;
2039
        case 0x7:
2040
            /* Invalid */
2041
            goto invalid_opc;
2042
        case 0x8:
2043
            /* Invalid */
2044
            goto invalid_opc;
2045
        case 0x9:
2046
            /* Invalid */
2047
            goto invalid_opc;
2048
        case 0xA:
2049
            /* Invalid */
2050
            goto invalid_opc;
2051
        case 0xB:
2052
            /* Invalid */
2053
            goto invalid_opc;
2054
        case 0xC:
2055
            /* Longword virtual access with alternate access mode */
2056
            gen_op_set_alt_mode();
2057
            gen_op_st_phys_to_virt();
2058
            gen_op_ldl_raw();
2059
            gen_op_restore_mode();
2060
            break;
2061
        case 0xD:
2062
            /* Quadword virtual access with alternate access mode */
2063
            gen_op_set_alt_mode();
2064
            gen_op_st_phys_to_virt();
2065
            gen_op_ldq_raw();
2066
            gen_op_restore_mode();
2067
            break;
2068
        case 0xE:
2069
            /* Invalid */
2070
            goto invalid_opc;
2071
        case 0xF:
2072
            /* Invalid */
2073
            goto invalid_opc;
2074
        }
2075
        ret = 2;
2076
        break;
2077
#endif
2078
    case 0x20:
2079
        /* LDF */
2080
#if 0 // TODO
2081
        gen_load_fmem(ctx, &gen_ldf, ra, rb, disp16);
2082
#else
2083
        goto invalid_opc;
2084
#endif
2085
        break;
2086
    case 0x21:
2087
        /* LDG */
2088
#if 0 // TODO
2089
        gen_load_fmem(ctx, &gen_ldg, ra, rb, disp16);
2090
#else
2091
        goto invalid_opc;
2092
#endif
2093
        break;
2094
    case 0x22:
2095
        /* LDS */
2096
        gen_load_fmem(ctx, &gen_lds, ra, rb, disp16);
2097
        break;
2098
    case 0x23:
2099
        /* LDT */
2100
        gen_load_fmem(ctx, &gen_ldt, ra, rb, disp16);
2101
        break;
2102
    case 0x24:
2103
        /* STF */
2104
#if 0 // TODO
2105
        gen_store_fmem(ctx, &gen_stf, ra, rb, disp16);
2106
#else
2107
        goto invalid_opc;
2108
#endif
2109
        break;
2110
    case 0x25:
2111
        /* STG */
2112
#if 0 // TODO
2113
        gen_store_fmem(ctx, &gen_stg, ra, rb, disp16);
2114
#else
2115
        goto invalid_opc;
2116
#endif
2117
        break;
2118
    case 0x26:
2119
        /* STS */
2120
        gen_store_fmem(ctx, &gen_sts, ra, rb, disp16);
2121
        break;
2122
    case 0x27:
2123
        /* STT */
2124
        gen_store_fmem(ctx, &gen_stt, ra, rb, disp16);
2125
        break;
2126
    case 0x28:
2127
        /* LDL */
2128
        gen_load_mem(ctx, &gen_ldl, ra, rb, disp16, 0);
2129
        break;
2130
    case 0x29:
2131
        /* LDQ */
2132
        gen_load_mem(ctx, &gen_ldq, ra, rb, disp16, 0);
2133
        break;
2134
    case 0x2A:
2135
        /* LDL_L */
2136
        gen_load_mem(ctx, &gen_ldl_l, ra, rb, disp16, 0);
2137
        break;
2138
    case 0x2B:
2139
        /* LDQ_L */
2140
        gen_load_mem(ctx, &gen_ldq_l, ra, rb, disp16, 0);
2141
        break;
2142
    case 0x2C:
2143
        /* STL */
2144
        gen_store_mem(ctx, &gen_stl, ra, rb, disp16, 0);
2145
        break;
2146
    case 0x2D:
2147
        /* STQ */
2148
        gen_store_mem(ctx, &gen_stq, ra, rb, disp16, 0);
2149
        break;
2150
    case 0x2E:
2151
        /* STL_C */
2152
        gen_store_mem(ctx, &gen_stl_c, ra, rb, disp16, 0);
2153
        break;
2154
    case 0x2F:
2155
        /* STQ_C */
2156
        gen_store_mem(ctx, &gen_stq_c, ra, rb, disp16, 0);
2157
        break;
2158
    case 0x30:
2159
        /* BR */
2160
        if (ra != 31)
2161
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2162
        tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
2163
        ret = 1;
2164
        break;
2165
    case 0x31:
2166
        /* FBEQ */
2167
        gen_fbcond(ctx, &gen_op_cmpfeq, ra, disp16);
2168
        ret = 1;
2169
        break;
2170
    case 0x32:
2171
        /* FBLT */
2172
        gen_fbcond(ctx, &gen_op_cmpflt, ra, disp16);
2173
        ret = 1;
2174
        break;
2175
    case 0x33:
2176
        /* FBLE */
2177
        gen_fbcond(ctx, &gen_op_cmpfle, ra, disp16);
2178
        ret = 1;
2179
        break;
2180
    case 0x34:
2181
        /* BSR */
2182
        if (ra != 31)
2183
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2184
        tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
2185
        ret = 1;
2186
        break;
2187
    case 0x35:
2188
        /* FBNE */
2189
        gen_fbcond(ctx, &gen_op_cmpfne, ra, disp16);
2190
        ret = 1;
2191
        break;
2192
    case 0x36:
2193
        /* FBGE */
2194
        gen_fbcond(ctx, &gen_op_cmpfge, ra, disp16);
2195
        ret = 1;
2196
        break;
2197
    case 0x37:
2198
        /* FBGT */
2199
        gen_fbcond(ctx, &gen_op_cmpfgt, ra, disp16);
2200
        ret = 1;
2201
        break;
2202
    case 0x38:
2203
        /* BLBC */
2204
        gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 1);
2205
        ret = 1;
2206
        break;
2207
    case 0x39:
2208
        /* BEQ */
2209
        gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 0);
2210
        ret = 1;
2211
        break;
2212
    case 0x3A:
2213
        /* BLT */
2214
        gen_bcond(ctx, TCG_COND_LT, ra, disp16, 0);
2215
        ret = 1;
2216
        break;
2217
    case 0x3B:
2218
        /* BLE */
2219
        gen_bcond(ctx, TCG_COND_LE, ra, disp16, 0);
2220
        ret = 1;
2221
        break;
2222
    case 0x3C:
2223
        /* BLBS */
2224
        gen_bcond(ctx, TCG_COND_NE, ra, disp16, 1);
2225
        ret = 1;
2226
        break;
2227
    case 0x3D:
2228
        /* BNE */
2229
        gen_bcond(ctx, TCG_COND_NE, ra, disp16, 0);
2230
        ret = 1;
2231
        break;
2232
    case 0x3E:
2233
        /* BGE */
2234
        gen_bcond(ctx, TCG_COND_GE, ra, disp16, 0);
2235
        ret = 1;
2236
        break;
2237
    case 0x3F:
2238
        /* BGT */
2239
        gen_bcond(ctx, TCG_COND_GT, ra, disp16, 0);
2240
        ret = 1;
2241
        break;
2242
    invalid_opc:
2243
        gen_invalid(ctx);
2244
        ret = 3;
2245
        break;
2246
    }
2247

    
2248
    return ret;
2249
}
2250

    
2251
static always_inline void gen_intermediate_code_internal (CPUState *env,
2252
                                                          TranslationBlock *tb,
2253
                                                          int search_pc)
2254
{
2255
#if defined ALPHA_DEBUG_DISAS
2256
    static int insn_count;
2257
#endif
2258
    DisasContext ctx, *ctxp = &ctx;
2259
    target_ulong pc_start;
2260
    uint32_t insn;
2261
    uint16_t *gen_opc_end;
2262
    int j, lj = -1;
2263
    int ret;
2264
    int num_insns;
2265
    int max_insns;
2266

    
2267
    pc_start = tb->pc;
2268
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2269
    ctx.pc = pc_start;
2270
    ctx.amask = env->amask;
2271
#if defined (CONFIG_USER_ONLY)
2272
    ctx.mem_idx = 0;
2273
#else
2274
    ctx.mem_idx = ((env->ps >> 3) & 3);
2275
    ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
2276
#endif
2277
    num_insns = 0;
2278
    max_insns = tb->cflags & CF_COUNT_MASK;
2279
    if (max_insns == 0)
2280
        max_insns = CF_COUNT_MASK;
2281

    
2282
    gen_icount_start();
2283
    for (ret = 0; ret == 0;) {
2284
        if (env->nb_breakpoints > 0) {
2285
            for(j = 0; j < env->nb_breakpoints; j++) {
2286
                if (env->breakpoints[j] == ctx.pc) {
2287
                    gen_excp(&ctx, EXCP_DEBUG, 0);
2288
                    break;
2289
                }
2290
            }
2291
        }
2292
        if (search_pc) {
2293
            j = gen_opc_ptr - gen_opc_buf;
2294
            if (lj < j) {
2295
                lj++;
2296
                while (lj < j)
2297
                    gen_opc_instr_start[lj++] = 0;
2298
                gen_opc_pc[lj] = ctx.pc;
2299
                gen_opc_instr_start[lj] = 1;
2300
                gen_opc_icount[lj] = num_insns;
2301
            }
2302
        }
2303
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
2304
            gen_io_start();
2305
#if defined ALPHA_DEBUG_DISAS
2306
        insn_count++;
2307
        if (logfile != NULL) {
2308
            fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2309
                    ctx.pc, ctx.mem_idx);
2310
        }
2311
#endif
2312
        insn = ldl_code(ctx.pc);
2313
#if defined ALPHA_DEBUG_DISAS
2314
        insn_count++;
2315
        if (logfile != NULL) {
2316
            fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2317
        }
2318
#endif
2319
        num_insns++;
2320
        ctx.pc += 4;
2321
        ret = translate_one(ctxp, insn);
2322
        if (ret != 0)
2323
            break;
2324
        /* if we reach a page boundary or are single stepping, stop
2325
         * generation
2326
         */
2327
        if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2328
            (env->singlestep_enabled) ||
2329
            num_insns >= max_insns) {
2330
            break;
2331
        }
2332
#if defined (DO_SINGLE_STEP)
2333
        break;
2334
#endif
2335
    }
2336
    if (ret != 1 && ret != 3) {
2337
        tcg_gen_movi_i64(cpu_pc, ctx.pc);
2338
    }
2339
#if defined (DO_TB_FLUSH)
2340
    tcg_gen_helper_0_0(helper_tb_flush);
2341
#endif
2342
    if (tb->cflags & CF_LAST_IO)
2343
        gen_io_end();
2344
    /* Generate the return instruction */
2345
    tcg_gen_exit_tb(0);
2346
    gen_icount_end(tb, num_insns);
2347
    *gen_opc_ptr = INDEX_op_end;
2348
    if (search_pc) {
2349
        j = gen_opc_ptr - gen_opc_buf;
2350
        lj++;
2351
        while (lj <= j)
2352
            gen_opc_instr_start[lj++] = 0;
2353
    } else {
2354
        tb->size = ctx.pc - pc_start;
2355
        tb->icount = num_insns;
2356
    }
2357
#if defined ALPHA_DEBUG_DISAS
2358
    if (loglevel & CPU_LOG_TB_CPU) {
2359
        cpu_dump_state(env, logfile, fprintf, 0);
2360
    }
2361
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2362
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2363
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
2364
        fprintf(logfile, "\n");
2365
    }
2366
#endif
2367
}
2368

    
2369
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2370
{
2371
    gen_intermediate_code_internal(env, tb, 0);
2372
}
2373

    
2374
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2375
{
2376
    gen_intermediate_code_internal(env, tb, 1);
2377
}
2378

    
2379
CPUAlphaState * cpu_alpha_init (const char *cpu_model)
2380
{
2381
    CPUAlphaState *env;
2382
    uint64_t hwpcb;
2383

    
2384
    env = qemu_mallocz(sizeof(CPUAlphaState));
2385
    if (!env)
2386
        return NULL;
2387
    cpu_exec_init(env);
2388
    alpha_translate_init();
2389
    tlb_flush(env, 1);
2390
    /* XXX: should not be hardcoded */
2391
    env->implver = IMPLVER_2106x;
2392
    env->ps = 0x1F00;
2393
#if defined (CONFIG_USER_ONLY)
2394
    env->ps |= 1 << 3;
2395
#endif
2396
    pal_init(env);
2397
    /* Initialize IPR */
2398
    hwpcb = env->ipr[IPR_PCBB];
2399
    env->ipr[IPR_ASN] = 0;
2400
    env->ipr[IPR_ASTEN] = 0;
2401
    env->ipr[IPR_ASTSR] = 0;
2402
    env->ipr[IPR_DATFX] = 0;
2403
    /* XXX: fix this */
2404
    //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2405
    //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2406
    //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2407
    //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2408
    env->ipr[IPR_FEN] = 0;
2409
    env->ipr[IPR_IPL] = 31;
2410
    env->ipr[IPR_MCES] = 0;
2411
    env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2412
    //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2413
    env->ipr[IPR_SISR] = 0;
2414
    env->ipr[IPR_VIRBND] = -1ULL;
2415

    
2416
    return env;
2417
}
2418

    
2419
void gen_pc_load(CPUState *env, TranslationBlock *tb,
2420
                unsigned long searched_pc, int pc_pos, void *puc)
2421
{
2422
    env->pc = gen_opc_pc[pc_pos];
2423
}