Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ c0ce998e

History | View | Annotate | Download (74.8 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 "tcg-op.h"
30
#include "qemu-common.h"
31

    
32
#include "helper.h"
33
#define GEN_HELPER 1
34
#include "helper.h"
35

    
36
/* #define DO_SINGLE_STEP */
37
#define ALPHA_DEBUG_DISAS
38
/* #define DO_TB_FLUSH */
39

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

    
50
/* global register indexes */
51
static TCGv_ptr cpu_env;
52
static TCGv cpu_ir[31];
53
static TCGv cpu_fir[31];
54
static TCGv cpu_pc;
55
static TCGv cpu_lock;
56

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

    
60
#include "gen-icount.h"
61

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

    
68
    if (done_init)
69
        return;
70

    
71
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
72

    
73
    p = cpu_reg_names;
74
    for (i = 0; i < 31; i++) {
75
        sprintf(p, "ir%d", i);
76
        cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
77
                                           offsetof(CPUState, ir[i]), p);
78
        p += (i < 10) ? 4 : 5;
79

    
80
        sprintf(p, "fir%d", i);
81
        cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
82
                                            offsetof(CPUState, fir[i]), p);
83
        p += (i < 10) ? 5 : 6;
84
    }
85

    
86
    cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
87
                                    offsetof(CPUState, pc), "pc");
88

    
89
    cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
90
                                      offsetof(CPUState, lock), "lock");
91

    
92
    /* register helpers */
93
#define GEN_HELPER 2
94
#include "helper.h"
95

    
96
    done_init = 1;
97
}
98

    
99
static always_inline void gen_excp (DisasContext *ctx,
100
                                    int exception, int error_code)
101
{
102
    TCGv_i32 tmp1, tmp2;
103

    
104
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
105
    tmp1 = tcg_const_i32(exception);
106
    tmp2 = tcg_const_i32(error_code);
107
    gen_helper_excp(tmp1, tmp2);
108
    tcg_temp_free_i32(tmp2);
109
    tcg_temp_free_i32(tmp1);
110
}
111

    
112
static always_inline void gen_invalid (DisasContext *ctx)
113
{
114
    gen_excp(ctx, EXCP_OPCDEC, 0);
115
}
116

    
117
static always_inline void gen_qemu_ldf (TCGv t0, TCGv t1, int flags)
118
{
119
    TCGv tmp = tcg_temp_new();
120
    TCGv_i32 tmp32 = tcg_temp_new_i32();
121
    tcg_gen_qemu_ld32u(tmp, t1, flags);
122
    tcg_gen_trunc_i64_i32(tmp32, tmp);
123
    gen_helper_memory_to_f(t0, tmp32);
124
    tcg_temp_free_i32(tmp32);
125
    tcg_temp_free(tmp);
126
}
127

    
128
static always_inline void gen_qemu_ldg (TCGv t0, TCGv t1, int flags)
129
{
130
    TCGv tmp = tcg_temp_new();
131
    tcg_gen_qemu_ld64(tmp, t1, flags);
132
    gen_helper_memory_to_g(t0, tmp);
133
    tcg_temp_free(tmp);
134
}
135

    
136
static always_inline void gen_qemu_lds (TCGv t0, TCGv t1, int flags)
137
{
138
    TCGv tmp = tcg_temp_new();
139
    TCGv_i32 tmp32 = tcg_temp_new_i32();
140
    tcg_gen_qemu_ld32u(tmp, t1, flags);
141
    tcg_gen_trunc_i64_i32(tmp32, tmp);
142
    gen_helper_memory_to_s(t0, tmp32);
143
    tcg_temp_free_i32(tmp32);
144
    tcg_temp_free(tmp);
145
}
146

    
147
static always_inline void gen_qemu_ldl_l (TCGv t0, TCGv t1, int flags)
148
{
149
    tcg_gen_mov_i64(cpu_lock, t1);
150
    tcg_gen_qemu_ld32s(t0, t1, flags);
151
}
152

    
153
static always_inline void gen_qemu_ldq_l (TCGv t0, TCGv t1, int flags)
154
{
155
    tcg_gen_mov_i64(cpu_lock, t1);
156
    tcg_gen_qemu_ld64(t0, t1, flags);
157
}
158

    
159
static always_inline void gen_load_mem (DisasContext *ctx,
160
                                        void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1, int flags),
161
                                        int ra, int rb, int32_t disp16,
162
                                        int fp, int clear)
163
{
164
    TCGv addr;
165

    
166
    if (unlikely(ra == 31))
167
        return;
168

    
169
    addr = tcg_temp_new();
170
    if (rb != 31) {
171
        tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
172
        if (clear)
173
            tcg_gen_andi_i64(addr, addr, ~0x7);
174
    } else {
175
        if (clear)
176
            disp16 &= ~0x7;
177
        tcg_gen_movi_i64(addr, disp16);
178
    }
179
    if (fp)
180
        tcg_gen_qemu_load(cpu_fir[ra], addr, ctx->mem_idx);
181
    else
182
        tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx);
183
    tcg_temp_free(addr);
184
}
185

    
186
static always_inline void gen_qemu_stf (TCGv t0, TCGv t1, int flags)
187
{
188
    TCGv_i32 tmp32 = tcg_temp_new_i32();
189
    TCGv tmp = tcg_temp_new();
190
    gen_helper_f_to_memory(tmp32, t0);
191
    tcg_gen_extu_i32_i64(tmp, tmp32);
192
    tcg_gen_qemu_st32(tmp, t1, flags);
193
    tcg_temp_free(tmp);
194
    tcg_temp_free_i32(tmp32);
195
}
196

    
197
static always_inline void gen_qemu_stg (TCGv t0, TCGv t1, int flags)
198
{
199
    TCGv tmp = tcg_temp_new();
200
    gen_helper_g_to_memory(tmp, t0);
201
    tcg_gen_qemu_st64(tmp, t1, flags);
202
    tcg_temp_free(tmp);
203
}
204

    
205
static always_inline void gen_qemu_sts (TCGv t0, TCGv t1, int flags)
206
{
207
    TCGv_i32 tmp32 = tcg_temp_new_i32();
208
    TCGv tmp = tcg_temp_new();
209
    gen_helper_s_to_memory(tmp32, t0);
210
    tcg_gen_extu_i32_i64(tmp, tmp32);
211
    tcg_gen_qemu_st32(tmp, t1, flags);
212
    tcg_temp_free(tmp);
213
    tcg_temp_free_i32(tmp32);
214
}
215

    
216
static always_inline void gen_qemu_stl_c (TCGv t0, TCGv t1, int flags)
217
{
218
    int l1, l2;
219

    
220
    l1 = gen_new_label();
221
    l2 = gen_new_label();
222
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
223
    tcg_gen_qemu_st32(t0, t1, flags);
224
    tcg_gen_movi_i64(t0, 1);
225
    tcg_gen_br(l2);
226
    gen_set_label(l1);
227
    tcg_gen_movi_i64(t0, 0);
228
    gen_set_label(l2);
229
    tcg_gen_movi_i64(cpu_lock, -1);
230
}
231

    
232
static always_inline void gen_qemu_stq_c (TCGv t0, TCGv t1, int flags)
233
{
234
    int l1, l2;
235

    
236
    l1 = gen_new_label();
237
    l2 = gen_new_label();
238
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
239
    tcg_gen_qemu_st64(t0, t1, flags);
240
    tcg_gen_movi_i64(t0, 1);
241
    tcg_gen_br(l2);
242
    gen_set_label(l1);
243
    tcg_gen_movi_i64(t0, 0);
244
    gen_set_label(l2);
245
    tcg_gen_movi_i64(cpu_lock, -1);
246
}
247

    
248
static always_inline void gen_store_mem (DisasContext *ctx,
249
                                         void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1, int flags),
250
                                         int ra, int rb, int32_t disp16,
251
                                         int fp, int clear, int local)
252
{
253
    TCGv addr;
254
    if (local)
255
        addr = tcg_temp_local_new();
256
    else
257
        addr = tcg_temp_new();
258
    if (rb != 31) {
259
        tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
260
        if (clear)
261
            tcg_gen_andi_i64(addr, addr, ~0x7);
262
    } else {
263
        if (clear)
264
            disp16 &= ~0x7;
265
        tcg_gen_movi_i64(addr, disp16);
266
    }
267
    if (ra != 31) {
268
        if (fp)
269
            tcg_gen_qemu_store(cpu_fir[ra], addr, ctx->mem_idx);
270
        else
271
            tcg_gen_qemu_store(cpu_ir[ra], addr, ctx->mem_idx);
272
    } else {
273
        TCGv zero;
274
        if (local)
275
            zero = tcg_const_local_i64(0);
276
        else
277
            zero = tcg_const_i64(0);
278
        tcg_gen_qemu_store(zero, addr, ctx->mem_idx);
279
        tcg_temp_free(zero);
280
    }
281
    tcg_temp_free(addr);
282
}
283

    
284
static always_inline void gen_bcond (DisasContext *ctx,
285
                                     TCGCond cond,
286
                                     int ra, int32_t disp16, int mask)
287
{
288
    int l1, l2;
289

    
290
    l1 = gen_new_label();
291
    l2 = gen_new_label();
292
    if (likely(ra != 31)) {
293
        if (mask) {
294
            TCGv tmp = tcg_temp_new();
295
            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
296
            tcg_gen_brcondi_i64(cond, tmp, 0, l1);
297
            tcg_temp_free(tmp);
298
        } else
299
            tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
300
    } else {
301
        /* Very uncommon case - Do not bother to optimize.  */
302
        TCGv tmp = tcg_const_i64(0);
303
        tcg_gen_brcondi_i64(cond, tmp, 0, l1);
304
        tcg_temp_free(tmp);
305
    }
306
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
307
    tcg_gen_br(l2);
308
    gen_set_label(l1);
309
    tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
310
    gen_set_label(l2);
311
}
312

    
313
static always_inline void gen_fbcond (DisasContext *ctx, int opc,
314
                                      int ra, int32_t disp16)
315
{
316
    int l1, l2;
317
    TCGv tmp;
318
    TCGv src;
319

    
320
    l1 = gen_new_label();
321
    l2 = gen_new_label();
322
    if (ra != 31) {
323
        tmp = tcg_temp_new();
324
        src = cpu_fir[ra];
325
    } else  {
326
        tmp = tcg_const_i64(0);
327
        src = tmp;
328
    }
329
    switch (opc) {
330
    case 0x31: /* FBEQ */
331
        gen_helper_cmpfeq(tmp, src);
332
        break;
333
    case 0x32: /* FBLT */
334
        gen_helper_cmpflt(tmp, src);
335
        break;
336
    case 0x33: /* FBLE */
337
        gen_helper_cmpfle(tmp, src);
338
        break;
339
    case 0x35: /* FBNE */
340
        gen_helper_cmpfne(tmp, src);
341
        break;
342
    case 0x36: /* FBGE */
343
        gen_helper_cmpfge(tmp, src);
344
        break;
345
    case 0x37: /* FBGT */
346
        gen_helper_cmpfgt(tmp, src);
347
        break;
348
    default:
349
        abort();
350
    }
351
    tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);
352
    tcg_gen_movi_i64(cpu_pc, ctx->pc);
353
    tcg_gen_br(l2);
354
    gen_set_label(l1);
355
    tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
356
    gen_set_label(l2);
357
}
358

    
359
static always_inline void gen_cmov (TCGCond inv_cond,
360
                                    int ra, int rb, int rc,
361
                                    int islit, uint8_t lit, int mask)
362
{
363
    int l1;
364

    
365
    if (unlikely(rc == 31))
366
        return;
367

    
368
    l1 = gen_new_label();
369

    
370
    if (ra != 31) {
371
        if (mask) {
372
            TCGv tmp = tcg_temp_new();
373
            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
374
            tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
375
            tcg_temp_free(tmp);
376
        } else
377
            tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
378
    } else {
379
        /* Very uncommon case - Do not bother to optimize.  */
380
        TCGv tmp = tcg_const_i64(0);
381
        tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
382
        tcg_temp_free(tmp);
383
    }
384

    
385
    if (islit)
386
        tcg_gen_movi_i64(cpu_ir[rc], lit);
387
    else
388
        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
389
    gen_set_label(l1);
390
}
391

    
392
#define FARITH2(name)                                       \
393
static always_inline void glue(gen_f, name)(int rb, int rc) \
394
{                                                           \
395
    if (unlikely(rc == 31))                                 \
396
      return;                                               \
397
                                                            \
398
    if (rb != 31)                                           \
399
        gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]);    \
400
    else {                                                  \
401
        TCGv tmp = tcg_const_i64(0);                        \
402
        gen_helper_ ## name (cpu_fir[rc], tmp);            \
403
        tcg_temp_free(tmp);                                 \
404
    }                                                       \
405
}
406
FARITH2(sqrts)
407
FARITH2(sqrtf)
408
FARITH2(sqrtg)
409
FARITH2(sqrtt)
410
FARITH2(cvtgf)
411
FARITH2(cvtgq)
412
FARITH2(cvtqf)
413
FARITH2(cvtqg)
414
FARITH2(cvtst)
415
FARITH2(cvtts)
416
FARITH2(cvttq)
417
FARITH2(cvtqs)
418
FARITH2(cvtqt)
419
FARITH2(cvtlq)
420
FARITH2(cvtql)
421
FARITH2(cvtqlv)
422
FARITH2(cvtqlsv)
423

    
424
#define FARITH3(name)                                                     \
425
static always_inline void glue(gen_f, name) (int ra, int rb, int rc)      \
426
{                                                                         \
427
    if (unlikely(rc == 31))                                               \
428
        return;                                                           \
429
                                                                          \
430
    if (ra != 31) {                                                       \
431
        if (rb != 31)                                                     \
432
            gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], cpu_fir[rb]);  \
433
        else {                                                            \
434
            TCGv tmp = tcg_const_i64(0);                                  \
435
            gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], tmp);          \
436
            tcg_temp_free(tmp);                                           \
437
        }                                                                 \
438
    } else {                                                              \
439
        TCGv tmp = tcg_const_i64(0);                                      \
440
        if (rb != 31)                                                     \
441
            gen_helper_ ## name (cpu_fir[rc], tmp, cpu_fir[rb]);          \
442
        else                                                              \
443
            gen_helper_ ## name (cpu_fir[rc], tmp, tmp);                   \
444
        tcg_temp_free(tmp);                                               \
445
    }                                                                     \
446
}
447

    
448
FARITH3(addf)
449
FARITH3(subf)
450
FARITH3(mulf)
451
FARITH3(divf)
452
FARITH3(addg)
453
FARITH3(subg)
454
FARITH3(mulg)
455
FARITH3(divg)
456
FARITH3(cmpgeq)
457
FARITH3(cmpglt)
458
FARITH3(cmpgle)
459
FARITH3(adds)
460
FARITH3(subs)
461
FARITH3(muls)
462
FARITH3(divs)
463
FARITH3(addt)
464
FARITH3(subt)
465
FARITH3(mult)
466
FARITH3(divt)
467
FARITH3(cmptun)
468
FARITH3(cmpteq)
469
FARITH3(cmptlt)
470
FARITH3(cmptle)
471
FARITH3(cpys)
472
FARITH3(cpysn)
473
FARITH3(cpyse)
474

    
475
#define FCMOV(name)                                                   \
476
static always_inline void glue(gen_f, name) (int ra, int rb, int rc)  \
477
{                                                                     \
478
    int l1;                                                           \
479
    TCGv tmp;                                                         \
480
                                                                      \
481
    if (unlikely(rc == 31))                                           \
482
        return;                                                       \
483
                                                                      \
484
    l1 = gen_new_label();                                             \
485
    tmp = tcg_temp_new();                                 \
486
    if (ra != 31) {                                                   \
487
        tmp = tcg_temp_new();                             \
488
        gen_helper_ ## name (tmp, cpu_fir[ra]);                       \
489
    } else  {                                                         \
490
        tmp = tcg_const_i64(0);                                       \
491
        gen_helper_ ## name (tmp, tmp);                               \
492
    }                                                                 \
493
    tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1);                     \
494
    if (rb != 31)                                                     \
495
        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);                    \
496
    else                                                              \
497
        tcg_gen_movi_i64(cpu_fir[rc], 0);                             \
498
    gen_set_label(l1);                                                \
499
}
500
FCMOV(cmpfeq)
501
FCMOV(cmpfne)
502
FCMOV(cmpflt)
503
FCMOV(cmpfge)
504
FCMOV(cmpfle)
505
FCMOV(cmpfgt)
506

    
507
/* EXTWH, EXTWH, EXTLH, EXTQH */
508
static always_inline void gen_ext_h(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
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
            if (lit != 0)
518
                tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 64 - ((lit & 7) * 8));
519
            else
520
                tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
521
        } else {
522
            TCGv tmp1, tmp2;
523
            tmp1 = tcg_temp_new();
524
            tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
525
            tcg_gen_shli_i64(tmp1, tmp1, 3);
526
            tmp2 = tcg_const_i64(64);
527
            tcg_gen_sub_i64(tmp1, tmp2, tmp1);
528
            tcg_temp_free(tmp2);
529
            tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
530
            tcg_temp_free(tmp1);
531
        }
532
        if (tcg_gen_ext_i64)
533
            tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
534
    } else
535
        tcg_gen_movi_i64(cpu_ir[rc], 0);
536
}
537

    
538
/* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */
539
static always_inline void gen_ext_l(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
540
                                    int ra, int rb, int rc,
541
                                    int islit, uint8_t lit)
542
{
543
    if (unlikely(rc == 31))
544
        return;
545

    
546
    if (ra != 31) {
547
        if (islit) {
548
                tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
549
        } else {
550
            TCGv tmp = tcg_temp_new();
551
            tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
552
            tcg_gen_shli_i64(tmp, tmp, 3);
553
            tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
554
            tcg_temp_free(tmp);
555
        }
556
        if (tcg_gen_ext_i64)
557
            tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
558
    } else
559
        tcg_gen_movi_i64(cpu_ir[rc], 0);
560
}
561

    
562
/* Code to call arith3 helpers */
563
#define ARITH3(name)                                                  \
564
static always_inline void glue(gen_, name) (int ra, int rb, int rc,   \
565
                                            int islit, uint8_t lit)   \
566
{                                                                     \
567
    if (unlikely(rc == 31))                                           \
568
        return;                                                       \
569
                                                                      \
570
    if (ra != 31) {                                                   \
571
        if (islit) {                                                  \
572
            TCGv tmp = tcg_const_i64(lit);                            \
573
            gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp);         \
574
            tcg_temp_free(tmp);                                       \
575
        } else                                                        \
576
            gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
577
    } else {                                                          \
578
        TCGv tmp1 = tcg_const_i64(0);                                 \
579
        if (islit) {                                                  \
580
            TCGv tmp2 = tcg_const_i64(lit);                           \
581
            gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2);             \
582
            tcg_temp_free(tmp2);                                      \
583
        } else                                                        \
584
            gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]);       \
585
        tcg_temp_free(tmp1);                                          \
586
    }                                                                 \
587
}
588
ARITH3(cmpbge)
589
ARITH3(addlv)
590
ARITH3(sublv)
591
ARITH3(addqv)
592
ARITH3(subqv)
593
ARITH3(mskbl)
594
ARITH3(insbl)
595
ARITH3(mskwl)
596
ARITH3(inswl)
597
ARITH3(mskll)
598
ARITH3(insll)
599
ARITH3(zap)
600
ARITH3(zapnot)
601
ARITH3(mskql)
602
ARITH3(insql)
603
ARITH3(mskwh)
604
ARITH3(inswh)
605
ARITH3(msklh)
606
ARITH3(inslh)
607
ARITH3(mskqh)
608
ARITH3(insqh)
609
ARITH3(umulh)
610
ARITH3(mullv)
611
ARITH3(mulqv)
612

    
613
static always_inline void gen_cmp(TCGCond cond,
614
                                  int ra, int rb, int rc,
615
                                  int islit, uint8_t lit)
616
{
617
    int l1, l2;
618
    TCGv tmp;
619

    
620
    if (unlikely(rc == 31))
621
    return;
622

    
623
    l1 = gen_new_label();
624
    l2 = gen_new_label();
625

    
626
    if (ra != 31) {
627
        tmp = tcg_temp_new();
628
        tcg_gen_mov_i64(tmp, cpu_ir[ra]);
629
    } else
630
        tmp = tcg_const_i64(0);
631
    if (islit)
632
        tcg_gen_brcondi_i64(cond, tmp, lit, l1);
633
    else
634
        tcg_gen_brcond_i64(cond, tmp, cpu_ir[rb], l1);
635

    
636
    tcg_gen_movi_i64(cpu_ir[rc], 0);
637
    tcg_gen_br(l2);
638
    gen_set_label(l1);
639
    tcg_gen_movi_i64(cpu_ir[rc], 1);
640
    gen_set_label(l2);
641
}
642

    
643
static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
644
{
645
    uint32_t palcode;
646
    int32_t disp21, disp16, disp12;
647
    uint16_t fn11, fn16;
648
    uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
649
    uint8_t lit;
650
    int ret;
651

    
652
    /* Decode all instruction fields */
653
    opc = insn >> 26;
654
    ra = (insn >> 21) & 0x1F;
655
    rb = (insn >> 16) & 0x1F;
656
    rc = insn & 0x1F;
657
    sbz = (insn >> 13) & 0x07;
658
    islit = (insn >> 12) & 1;
659
    if (rb == 31 && !islit) {
660
        islit = 1;
661
        lit = 0;
662
    } else
663
        lit = (insn >> 13) & 0xFF;
664
    palcode = insn & 0x03FFFFFF;
665
    disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
666
    disp16 = (int16_t)(insn & 0x0000FFFF);
667
    disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
668
    fn16 = insn & 0x0000FFFF;
669
    fn11 = (insn >> 5) & 0x000007FF;
670
    fpfn = fn11 & 0x3F;
671
    fn7 = (insn >> 5) & 0x0000007F;
672
    fn2 = (insn >> 5) & 0x00000003;
673
    ret = 0;
674
#if defined ALPHA_DEBUG_DISAS
675
    if (logfile != NULL) {
676
        fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n",
677
                opc, ra, rb, rc, disp16);
678
    }
679
#endif
680
    switch (opc) {
681
    case 0x00:
682
        /* CALL_PAL */
683
        if (palcode >= 0x80 && palcode < 0xC0) {
684
            /* Unprivileged PAL call */
685
            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);
686
#if !defined (CONFIG_USER_ONLY)
687
        } else if (palcode < 0x40) {
688
            /* Privileged PAL code */
689
            if (ctx->mem_idx & 1)
690
                goto invalid_opc;
691
            else
692
                gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0);
693
#endif
694
        } else {
695
            /* Invalid PAL call */
696
            goto invalid_opc;
697
        }
698
        ret = 3;
699
        break;
700
    case 0x01:
701
        /* OPC01 */
702
        goto invalid_opc;
703
    case 0x02:
704
        /* OPC02 */
705
        goto invalid_opc;
706
    case 0x03:
707
        /* OPC03 */
708
        goto invalid_opc;
709
    case 0x04:
710
        /* OPC04 */
711
        goto invalid_opc;
712
    case 0x05:
713
        /* OPC05 */
714
        goto invalid_opc;
715
    case 0x06:
716
        /* OPC06 */
717
        goto invalid_opc;
718
    case 0x07:
719
        /* OPC07 */
720
        goto invalid_opc;
721
    case 0x08:
722
        /* LDA */
723
        if (likely(ra != 31)) {
724
            if (rb != 31)
725
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
726
            else
727
                tcg_gen_movi_i64(cpu_ir[ra], disp16);
728
        }
729
        break;
730
    case 0x09:
731
        /* LDAH */
732
        if (likely(ra != 31)) {
733
            if (rb != 31)
734
                tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
735
            else
736
                tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
737
        }
738
        break;
739
    case 0x0A:
740
        /* LDBU */
741
        if (!(ctx->amask & AMASK_BWX))
742
            goto invalid_opc;
743
        gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
744
        break;
745
    case 0x0B:
746
        /* LDQ_U */
747
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
748
        break;
749
    case 0x0C:
750
        /* LDWU */
751
        if (!(ctx->amask & AMASK_BWX))
752
            goto invalid_opc;
753
        gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 1);
754
        break;
755
    case 0x0D:
756
        /* STW */
757
        gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0, 0);
758
        break;
759
    case 0x0E:
760
        /* STB */
761
        gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0, 0);
762
        break;
763
    case 0x0F:
764
        /* STQ_U */
765
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1, 0);
766
        break;
767
    case 0x10:
768
        switch (fn7) {
769
        case 0x00:
770
            /* ADDL */
771
            if (likely(rc != 31)) {
772
                if (ra != 31) {
773
                    if (islit) {
774
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
775
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
776
                    } else {
777
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
778
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
779
                    }
780
                } else {
781
                    if (islit)
782
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
783
                    else
784
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
785
                }
786
            }
787
            break;
788
        case 0x02:
789
            /* S4ADDL */
790
            if (likely(rc != 31)) {
791
                if (ra != 31) {
792
                    TCGv tmp = tcg_temp_new();
793
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
794
                    if (islit)
795
                        tcg_gen_addi_i64(tmp, tmp, lit);
796
                    else
797
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
798
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
799
                    tcg_temp_free(tmp);
800
                } else {
801
                    if (islit)
802
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
803
                    else
804
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
805
                }
806
            }
807
            break;
808
        case 0x09:
809
            /* SUBL */
810
            if (likely(rc != 31)) {
811
                if (ra != 31) {
812
                    if (islit)
813
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
814
                    else
815
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
816
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
817
                } else {
818
                    if (islit)
819
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
820
                    else {
821
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
822
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
823
                }
824
            }
825
            break;
826
        case 0x0B:
827
            /* S4SUBL */
828
            if (likely(rc != 31)) {
829
                if (ra != 31) {
830
                    TCGv tmp = tcg_temp_new();
831
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
832
                    if (islit)
833
                        tcg_gen_subi_i64(tmp, tmp, lit);
834
                    else
835
                        tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
836
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
837
                    tcg_temp_free(tmp);
838
                } else {
839
                    if (islit)
840
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
841
                    else {
842
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
843
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
844
                    }
845
                }
846
            }
847
            break;
848
        case 0x0F:
849
            /* CMPBGE */
850
            gen_cmpbge(ra, rb, rc, islit, lit);
851
            break;
852
        case 0x12:
853
            /* S8ADDL */
854
            if (likely(rc != 31)) {
855
                if (ra != 31) {
856
                    TCGv tmp = tcg_temp_new();
857
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
858
                    if (islit)
859
                        tcg_gen_addi_i64(tmp, tmp, lit);
860
                    else
861
                        tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
862
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
863
                    tcg_temp_free(tmp);
864
                } else {
865
                    if (islit)
866
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
867
                    else
868
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
869
                }
870
            }
871
            break;
872
        case 0x1B:
873
            /* S8SUBL */
874
            if (likely(rc != 31)) {
875
                if (ra != 31) {
876
                    TCGv tmp = tcg_temp_new();
877
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
878
                    if (islit)
879
                        tcg_gen_subi_i64(tmp, tmp, lit);
880
                    else
881
                       tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
882
                    tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
883
                    tcg_temp_free(tmp);
884
                } else {
885
                    if (islit)
886
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
887
                    else
888
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
889
                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
890
                    }
891
                }
892
            }
893
            break;
894
        case 0x1D:
895
            /* CMPULT */
896
            gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
897
            break;
898
        case 0x20:
899
            /* ADDQ */
900
            if (likely(rc != 31)) {
901
                if (ra != 31) {
902
                    if (islit)
903
                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
904
                    else
905
                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
906
                } else {
907
                    if (islit)
908
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
909
                    else
910
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
911
                }
912
            }
913
            break;
914
        case 0x22:
915
            /* S4ADDQ */
916
            if (likely(rc != 31)) {
917
                if (ra != 31) {
918
                    TCGv tmp = tcg_temp_new();
919
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
920
                    if (islit)
921
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
922
                    else
923
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
924
                    tcg_temp_free(tmp);
925
                } else {
926
                    if (islit)
927
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
928
                    else
929
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
930
                }
931
            }
932
            break;
933
        case 0x29:
934
            /* SUBQ */
935
            if (likely(rc != 31)) {
936
                if (ra != 31) {
937
                    if (islit)
938
                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
939
                    else
940
                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
941
                } else {
942
                    if (islit)
943
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
944
                    else
945
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
946
                }
947
            }
948
            break;
949
        case 0x2B:
950
            /* S4SUBQ */
951
            if (likely(rc != 31)) {
952
                if (ra != 31) {
953
                    TCGv tmp = tcg_temp_new();
954
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
955
                    if (islit)
956
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
957
                    else
958
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
959
                    tcg_temp_free(tmp);
960
                } else {
961
                    if (islit)
962
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
963
                    else
964
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
965
                }
966
            }
967
            break;
968
        case 0x2D:
969
            /* CMPEQ */
970
            gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
971
            break;
972
        case 0x32:
973
            /* S8ADDQ */
974
            if (likely(rc != 31)) {
975
                if (ra != 31) {
976
                    TCGv tmp = tcg_temp_new();
977
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
978
                    if (islit)
979
                        tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
980
                    else
981
                        tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
982
                    tcg_temp_free(tmp);
983
                } else {
984
                    if (islit)
985
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
986
                    else
987
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
988
                }
989
            }
990
            break;
991
        case 0x3B:
992
            /* S8SUBQ */
993
            if (likely(rc != 31)) {
994
                if (ra != 31) {
995
                    TCGv tmp = tcg_temp_new();
996
                    tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
997
                    if (islit)
998
                        tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
999
                    else
1000
                        tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1001
                    tcg_temp_free(tmp);
1002
                } else {
1003
                    if (islit)
1004
                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
1005
                    else
1006
                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1007
                }
1008
            }
1009
            break;
1010
        case 0x3D:
1011
            /* CMPULE */
1012
            gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
1013
            break;
1014
        case 0x40:
1015
            /* ADDL/V */
1016
            gen_addlv(ra, rb, rc, islit, lit);
1017
            break;
1018
        case 0x49:
1019
            /* SUBL/V */
1020
            gen_sublv(ra, rb, rc, islit, lit);
1021
            break;
1022
        case 0x4D:
1023
            /* CMPLT */
1024
            gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
1025
            break;
1026
        case 0x60:
1027
            /* ADDQ/V */
1028
            gen_addqv(ra, rb, rc, islit, lit);
1029
            break;
1030
        case 0x69:
1031
            /* SUBQ/V */
1032
            gen_subqv(ra, rb, rc, islit, lit);
1033
            break;
1034
        case 0x6D:
1035
            /* CMPLE */
1036
            gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
1037
            break;
1038
        default:
1039
            goto invalid_opc;
1040
        }
1041
        break;
1042
    case 0x11:
1043
        switch (fn7) {
1044
        case 0x00:
1045
            /* AND */
1046
            if (likely(rc != 31)) {
1047
                if (ra == 31)
1048
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1049
                else if (islit)
1050
                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1051
                else
1052
                    tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1053
            }
1054
            break;
1055
        case 0x08:
1056
            /* BIC */
1057
            if (likely(rc != 31)) {
1058
                if (ra != 31) {
1059
                    if (islit)
1060
                        tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1061
                    else
1062
                        tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1063
                } else
1064
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1065
            }
1066
            break;
1067
        case 0x14:
1068
            /* CMOVLBS */
1069
            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
1070
            break;
1071
        case 0x16:
1072
            /* CMOVLBC */
1073
            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
1074
            break;
1075
        case 0x20:
1076
            /* BIS */
1077
            if (likely(rc != 31)) {
1078
                if (ra != 31) {
1079
                    if (islit)
1080
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
1081
                    else
1082
                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1083
                } else {
1084
                    if (islit)
1085
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1086
                    else
1087
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1088
                }
1089
            }
1090
            break;
1091
        case 0x24:
1092
            /* CMOVEQ */
1093
            gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
1094
            break;
1095
        case 0x26:
1096
            /* CMOVNE */
1097
            gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
1098
            break;
1099
        case 0x28:
1100
            /* ORNOT */
1101
            if (likely(rc != 31)) {
1102
                if (ra != 31) {
1103
                    if (islit)
1104
                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1105
                    else
1106
                        tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1107
                } else {
1108
                    if (islit)
1109
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
1110
                    else
1111
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
1112
                }
1113
            }
1114
            break;
1115
        case 0x40:
1116
            /* XOR */
1117
            if (likely(rc != 31)) {
1118
                if (ra != 31) {
1119
                    if (islit)
1120
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
1121
                    else
1122
                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1123
                } else {
1124
                    if (islit)
1125
                        tcg_gen_movi_i64(cpu_ir[rc], lit);
1126
                    else
1127
                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1128
                }
1129
            }
1130
            break;
1131
        case 0x44:
1132
            /* CMOVLT */
1133
            gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
1134
            break;
1135
        case 0x46:
1136
            /* CMOVGE */
1137
            gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
1138
            break;
1139
        case 0x48:
1140
            /* EQV */
1141
            if (likely(rc != 31)) {
1142
                if (ra != 31) {
1143
                    if (islit)
1144
                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1145
                    else
1146
                        tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1147
                } else {
1148
                    if (islit)
1149
                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
1150
                    else
1151
                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
1152
                }
1153
            }
1154
            break;
1155
        case 0x61:
1156
            /* AMASK */
1157
            if (likely(rc != 31)) {
1158
                if (islit)
1159
                    tcg_gen_movi_i64(cpu_ir[rc], helper_amask(lit));
1160
                else
1161
                    gen_helper_amask(cpu_ir[rc], cpu_ir[rb]);
1162
            }
1163
            break;
1164
        case 0x64:
1165
            /* CMOVLE */
1166
            gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
1167
            break;
1168
        case 0x66:
1169
            /* CMOVGT */
1170
            gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
1171
            break;
1172
        case 0x6C:
1173
            /* IMPLVER */
1174
            if (rc != 31)
1175
                gen_helper_load_implver(cpu_ir[rc]);
1176
            break;
1177
        default:
1178
            goto invalid_opc;
1179
        }
1180
        break;
1181
    case 0x12:
1182
        switch (fn7) {
1183
        case 0x02:
1184
            /* MSKBL */
1185
            gen_mskbl(ra, rb, rc, islit, lit);
1186
            break;
1187
        case 0x06:
1188
            /* EXTBL */
1189
            gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit);
1190
            break;
1191
        case 0x0B:
1192
            /* INSBL */
1193
            gen_insbl(ra, rb, rc, islit, lit);
1194
            break;
1195
        case 0x12:
1196
            /* MSKWL */
1197
            gen_mskwl(ra, rb, rc, islit, lit);
1198
            break;
1199
        case 0x16:
1200
            /* EXTWL */
1201
            gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1202
            break;
1203
        case 0x1B:
1204
            /* INSWL */
1205
            gen_inswl(ra, rb, rc, islit, lit);
1206
            break;
1207
        case 0x22:
1208
            /* MSKLL */
1209
            gen_mskll(ra, rb, rc, islit, lit);
1210
            break;
1211
        case 0x26:
1212
            /* EXTLL */
1213
            gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
1214
            break;
1215
        case 0x2B:
1216
            /* INSLL */
1217
            gen_insll(ra, rb, rc, islit, lit);
1218
            break;
1219
        case 0x30:
1220
            /* ZAP */
1221
            gen_zap(ra, rb, rc, islit, lit);
1222
            break;
1223
        case 0x31:
1224
            /* ZAPNOT */
1225
            gen_zapnot(ra, rb, rc, islit, lit);
1226
            break;
1227
        case 0x32:
1228
            /* MSKQL */
1229
            gen_mskql(ra, rb, rc, islit, lit);
1230
            break;
1231
        case 0x34:
1232
            /* SRL */
1233
            if (likely(rc != 31)) {
1234
                if (ra != 31) {
1235
                    if (islit)
1236
                        tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
1237
                    else {
1238
                        TCGv shift = tcg_temp_new();
1239
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1240
                        tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
1241
                        tcg_temp_free(shift);
1242
                    }
1243
                } else
1244
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1245
            }
1246
            break;
1247
        case 0x36:
1248
            /* EXTQL */
1249
            gen_ext_l(NULL, ra, rb, rc, islit, lit);
1250
            break;
1251
        case 0x39:
1252
            /* SLL */
1253
            if (likely(rc != 31)) {
1254
                if (ra != 31) {
1255
                    if (islit)
1256
                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
1257
                    else {
1258
                        TCGv shift = tcg_temp_new();
1259
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1260
                        tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
1261
                        tcg_temp_free(shift);
1262
                    }
1263
                } else
1264
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1265
            }
1266
            break;
1267
        case 0x3B:
1268
            /* INSQL */
1269
            gen_insql(ra, rb, rc, islit, lit);
1270
            break;
1271
        case 0x3C:
1272
            /* SRA */
1273
            if (likely(rc != 31)) {
1274
                if (ra != 31) {
1275
                    if (islit)
1276
                        tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
1277
                    else {
1278
                        TCGv shift = tcg_temp_new();
1279
                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1280
                        tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
1281
                        tcg_temp_free(shift);
1282
                    }
1283
                } else
1284
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1285
            }
1286
            break;
1287
        case 0x52:
1288
            /* MSKWH */
1289
            gen_mskwh(ra, rb, rc, islit, lit);
1290
            break;
1291
        case 0x57:
1292
            /* INSWH */
1293
            gen_inswh(ra, rb, rc, islit, lit);
1294
            break;
1295
        case 0x5A:
1296
            /* EXTWH */
1297
            gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1298
            break;
1299
        case 0x62:
1300
            /* MSKLH */
1301
            gen_msklh(ra, rb, rc, islit, lit);
1302
            break;
1303
        case 0x67:
1304
            /* INSLH */
1305
            gen_inslh(ra, rb, rc, islit, lit);
1306
            break;
1307
        case 0x6A:
1308
            /* EXTLH */
1309
            gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1310
            break;
1311
        case 0x72:
1312
            /* MSKQH */
1313
            gen_mskqh(ra, rb, rc, islit, lit);
1314
            break;
1315
        case 0x77:
1316
            /* INSQH */
1317
            gen_insqh(ra, rb, rc, islit, lit);
1318
            break;
1319
        case 0x7A:
1320
            /* EXTQH */
1321
            gen_ext_h(NULL, ra, rb, rc, islit, lit);
1322
            break;
1323
        default:
1324
            goto invalid_opc;
1325
        }
1326
        break;
1327
    case 0x13:
1328
        switch (fn7) {
1329
        case 0x00:
1330
            /* MULL */
1331
            if (likely(rc != 31)) {
1332
                if (ra == 31)
1333
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1334
                else {
1335
                    if (islit)
1336
                        tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1337
                    else
1338
                        tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1339
                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1340
                }
1341
            }
1342
            break;
1343
        case 0x20:
1344
            /* MULQ */
1345
            if (likely(rc != 31)) {
1346
                if (ra == 31)
1347
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
1348
                else if (islit)
1349
                    tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1350
                else
1351
                    tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1352
            }
1353
            break;
1354
        case 0x30:
1355
            /* UMULH */
1356
            gen_umulh(ra, rb, rc, islit, lit);
1357
            break;
1358
        case 0x40:
1359
            /* MULL/V */
1360
            gen_mullv(ra, rb, rc, islit, lit);
1361
            break;
1362
        case 0x60:
1363
            /* MULQ/V */
1364
            gen_mulqv(ra, rb, rc, islit, lit);
1365
            break;
1366
        default:
1367
            goto invalid_opc;
1368
        }
1369
        break;
1370
    case 0x14:
1371
        switch (fpfn) { /* f11 & 0x3F */
1372
        case 0x04:
1373
            /* ITOFS */
1374
            if (!(ctx->amask & AMASK_FIX))
1375
                goto invalid_opc;
1376
            if (likely(rc != 31)) {
1377
                if (ra != 31) {
1378
                    TCGv_i32 tmp = tcg_temp_new_i32();
1379
                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
1380
                    gen_helper_memory_to_s(cpu_fir[rc], tmp);
1381
                    tcg_temp_free_i32(tmp);
1382
                } else
1383
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
1384
            }
1385
            break;
1386
        case 0x0A:
1387
            /* SQRTF */
1388
            if (!(ctx->amask & AMASK_FIX))
1389
                goto invalid_opc;
1390
            gen_fsqrtf(rb, rc);
1391
            break;
1392
        case 0x0B:
1393
            /* SQRTS */
1394
            if (!(ctx->amask & AMASK_FIX))
1395
                goto invalid_opc;
1396
            gen_fsqrts(rb, rc);
1397
            break;
1398
        case 0x14:
1399
            /* ITOFF */
1400
            if (!(ctx->amask & AMASK_FIX))
1401
                goto invalid_opc;
1402
            if (likely(rc != 31)) {
1403
                if (ra != 31) {
1404
                    TCGv_i32 tmp = tcg_temp_new_i32();
1405
                    tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
1406
                    gen_helper_memory_to_f(cpu_fir[rc], tmp);
1407
                    tcg_temp_free_i32(tmp);
1408
                } else
1409
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
1410
            }
1411
            break;
1412
        case 0x24:
1413
            /* ITOFT */
1414
            if (!(ctx->amask & AMASK_FIX))
1415
                goto invalid_opc;
1416
            if (likely(rc != 31)) {
1417
                if (ra != 31)
1418
                    tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
1419
                else
1420
                    tcg_gen_movi_i64(cpu_fir[rc], 0);
1421
            }
1422
            break;
1423
        case 0x2A:
1424
            /* SQRTG */
1425
            if (!(ctx->amask & AMASK_FIX))
1426
                goto invalid_opc;
1427
            gen_fsqrtg(rb, rc);
1428
            break;
1429
        case 0x02B:
1430
            /* SQRTT */
1431
            if (!(ctx->amask & AMASK_FIX))
1432
                goto invalid_opc;
1433
            gen_fsqrtt(rb, rc);
1434
            break;
1435
        default:
1436
            goto invalid_opc;
1437
        }
1438
        break;
1439
    case 0x15:
1440
        /* VAX floating point */
1441
        /* XXX: rounding mode and trap are ignored (!) */
1442
        switch (fpfn) { /* f11 & 0x3F */
1443
        case 0x00:
1444
            /* ADDF */
1445
            gen_faddf(ra, rb, rc);
1446
            break;
1447
        case 0x01:
1448
            /* SUBF */
1449
            gen_fsubf(ra, rb, rc);
1450
            break;
1451
        case 0x02:
1452
            /* MULF */
1453
            gen_fmulf(ra, rb, rc);
1454
            break;
1455
        case 0x03:
1456
            /* DIVF */
1457
            gen_fdivf(ra, rb, rc);
1458
            break;
1459
        case 0x1E:
1460
            /* CVTDG */
1461
#if 0 // TODO
1462
            gen_fcvtdg(rb, rc);
1463
#else
1464
            goto invalid_opc;
1465
#endif
1466
            break;
1467
        case 0x20:
1468
            /* ADDG */
1469
            gen_faddg(ra, rb, rc);
1470
            break;
1471
        case 0x21:
1472
            /* SUBG */
1473
            gen_fsubg(ra, rb, rc);
1474
            break;
1475
        case 0x22:
1476
            /* MULG */
1477
            gen_fmulg(ra, rb, rc);
1478
            break;
1479
        case 0x23:
1480
            /* DIVG */
1481
            gen_fdivg(ra, rb, rc);
1482
            break;
1483
        case 0x25:
1484
            /* CMPGEQ */
1485
            gen_fcmpgeq(ra, rb, rc);
1486
            break;
1487
        case 0x26:
1488
            /* CMPGLT */
1489
            gen_fcmpglt(ra, rb, rc);
1490
            break;
1491
        case 0x27:
1492
            /* CMPGLE */
1493
            gen_fcmpgle(ra, rb, rc);
1494
            break;
1495
        case 0x2C:
1496
            /* CVTGF */
1497
            gen_fcvtgf(rb, rc);
1498
            break;
1499
        case 0x2D:
1500
            /* CVTGD */
1501
#if 0 // TODO
1502
            gen_fcvtgd(rb, rc);
1503
#else
1504
            goto invalid_opc;
1505
#endif
1506
            break;
1507
        case 0x2F:
1508
            /* CVTGQ */
1509
            gen_fcvtgq(rb, rc);
1510
            break;
1511
        case 0x3C:
1512
            /* CVTQF */
1513
            gen_fcvtqf(rb, rc);
1514
            break;
1515
        case 0x3E:
1516
            /* CVTQG */
1517
            gen_fcvtqg(rb, rc);
1518
            break;
1519
        default:
1520
            goto invalid_opc;
1521
        }
1522
        break;
1523
    case 0x16:
1524
        /* IEEE floating-point */
1525
        /* XXX: rounding mode and traps are ignored (!) */
1526
        switch (fpfn) { /* f11 & 0x3F */
1527
        case 0x00:
1528
            /* ADDS */
1529
            gen_fadds(ra, rb, rc);
1530
            break;
1531
        case 0x01:
1532
            /* SUBS */
1533
            gen_fsubs(ra, rb, rc);
1534
            break;
1535
        case 0x02:
1536
            /* MULS */
1537
            gen_fmuls(ra, rb, rc);
1538
            break;
1539
        case 0x03:
1540
            /* DIVS */
1541
            gen_fdivs(ra, rb, rc);
1542
            break;
1543
        case 0x20:
1544
            /* ADDT */
1545
            gen_faddt(ra, rb, rc);
1546
            break;
1547
        case 0x21:
1548
            /* SUBT */
1549
            gen_fsubt(ra, rb, rc);
1550
            break;
1551
        case 0x22:
1552
            /* MULT */
1553
            gen_fmult(ra, rb, rc);
1554
            break;
1555
        case 0x23:
1556
            /* DIVT */
1557
            gen_fdivt(ra, rb, rc);
1558
            break;
1559
        case 0x24:
1560
            /* CMPTUN */
1561
            gen_fcmptun(ra, rb, rc);
1562
            break;
1563
        case 0x25:
1564
            /* CMPTEQ */
1565
            gen_fcmpteq(ra, rb, rc);
1566
            break;
1567
        case 0x26:
1568
            /* CMPTLT */
1569
            gen_fcmptlt(ra, rb, rc);
1570
            break;
1571
        case 0x27:
1572
            /* CMPTLE */
1573
            gen_fcmptle(ra, rb, rc);
1574
            break;
1575
        case 0x2C:
1576
            /* XXX: incorrect */
1577
            if (fn11 == 0x2AC || fn11 == 0x6AC) {
1578
                /* CVTST */
1579
                gen_fcvtst(rb, rc);
1580
            } else {
1581
                /* CVTTS */
1582
                gen_fcvtts(rb, rc);
1583
            }
1584
            break;
1585
        case 0x2F:
1586
            /* CVTTQ */
1587
            gen_fcvttq(rb, rc);
1588
            break;
1589
        case 0x3C:
1590
            /* CVTQS */
1591
            gen_fcvtqs(rb, rc);
1592
            break;
1593
        case 0x3E:
1594
            /* CVTQT */
1595
            gen_fcvtqt(rb, rc);
1596
            break;
1597
        default:
1598
            goto invalid_opc;
1599
        }
1600
        break;
1601
    case 0x17:
1602
        switch (fn11) {
1603
        case 0x010:
1604
            /* CVTLQ */
1605
            gen_fcvtlq(rb, rc);
1606
            break;
1607
        case 0x020:
1608
            if (likely(rc != 31)) {
1609
                if (ra == rb)
1610
                    /* FMOV */
1611
                    tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
1612
                else
1613
                    /* CPYS */
1614
                    gen_fcpys(ra, rb, rc);
1615
            }
1616
            break;
1617
        case 0x021:
1618
            /* CPYSN */
1619
            gen_fcpysn(ra, rb, rc);
1620
            break;
1621
        case 0x022:
1622
            /* CPYSE */
1623
            gen_fcpyse(ra, rb, rc);
1624
            break;
1625
        case 0x024:
1626
            /* MT_FPCR */
1627
            if (likely(ra != 31))
1628
                gen_helper_store_fpcr(cpu_fir[ra]);
1629
            else {
1630
                TCGv tmp = tcg_const_i64(0);
1631
                gen_helper_store_fpcr(tmp);
1632
                tcg_temp_free(tmp);
1633
            }
1634
            break;
1635
        case 0x025:
1636
            /* MF_FPCR */
1637
            if (likely(ra != 31))
1638
                gen_helper_load_fpcr(cpu_fir[ra]);
1639
            break;
1640
        case 0x02A:
1641
            /* FCMOVEQ */
1642
            gen_fcmpfeq(ra, rb, rc);
1643
            break;
1644
        case 0x02B:
1645
            /* FCMOVNE */
1646
            gen_fcmpfne(ra, rb, rc);
1647
            break;
1648
        case 0x02C:
1649
            /* FCMOVLT */
1650
            gen_fcmpflt(ra, rb, rc);
1651
            break;
1652
        case 0x02D:
1653
            /* FCMOVGE */
1654
            gen_fcmpfge(ra, rb, rc);
1655
            break;
1656
        case 0x02E:
1657
            /* FCMOVLE */
1658
            gen_fcmpfle(ra, rb, rc);
1659
            break;
1660
        case 0x02F:
1661
            /* FCMOVGT */
1662
            gen_fcmpfgt(ra, rb, rc);
1663
            break;
1664
        case 0x030:
1665
            /* CVTQL */
1666
            gen_fcvtql(rb, rc);
1667
            break;
1668
        case 0x130:
1669
            /* CVTQL/V */
1670
            gen_fcvtqlv(rb, rc);
1671
            break;
1672
        case 0x530:
1673
            /* CVTQL/SV */
1674
            gen_fcvtqlsv(rb, rc);
1675
            break;
1676
        default:
1677
            goto invalid_opc;
1678
        }
1679
        break;
1680
    case 0x18:
1681
        switch ((uint16_t)disp16) {
1682
        case 0x0000:
1683
            /* TRAPB */
1684
            /* No-op. Just exit from the current tb */
1685
            ret = 2;
1686
            break;
1687
        case 0x0400:
1688
            /* EXCB */
1689
            /* No-op. Just exit from the current tb */
1690
            ret = 2;
1691
            break;
1692
        case 0x4000:
1693
            /* MB */
1694
            /* No-op */
1695
            break;
1696
        case 0x4400:
1697
            /* WMB */
1698
            /* No-op */
1699
            break;
1700
        case 0x8000:
1701
            /* FETCH */
1702
            /* No-op */
1703
            break;
1704
        case 0xA000:
1705
            /* FETCH_M */
1706
            /* No-op */
1707
            break;
1708
        case 0xC000:
1709
            /* RPCC */
1710
            if (ra != 31)
1711
                gen_helper_load_pcc(cpu_ir[ra]);
1712
            break;
1713
        case 0xE000:
1714
            /* RC */
1715
            if (ra != 31)
1716
                gen_helper_rc(cpu_ir[ra]);
1717
            break;
1718
        case 0xE800:
1719
            /* ECB */
1720
            /* XXX: TODO: evict tb cache at address rb */
1721
#if 0
1722
            ret = 2;
1723
#else
1724
            goto invalid_opc;
1725
#endif
1726
            break;
1727
        case 0xF000:
1728
            /* RS */
1729
            if (ra != 31)
1730
                gen_helper_rs(cpu_ir[ra]);
1731
            break;
1732
        case 0xF800:
1733
            /* WH64 */
1734
            /* No-op */
1735
            break;
1736
        default:
1737
            goto invalid_opc;
1738
        }
1739
        break;
1740
    case 0x19:
1741
        /* HW_MFPR (PALcode) */
1742
#if defined (CONFIG_USER_ONLY)
1743
        goto invalid_opc;
1744
#else
1745
        if (!ctx->pal_mode)
1746
            goto invalid_opc;
1747
        if (ra != 31) {
1748
            TCGv tmp = tcg_const_i32(insn & 0xFF);
1749
            gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]);
1750
            tcg_temp_free(tmp);
1751
        }
1752
        break;
1753
#endif
1754
    case 0x1A:
1755
        if (rb != 31)
1756
            tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
1757
        else
1758
            tcg_gen_movi_i64(cpu_pc, 0);
1759
        if (ra != 31)
1760
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
1761
        /* Those four jumps only differ by the branch prediction hint */
1762
        switch (fn2) {
1763
        case 0x0:
1764
            /* JMP */
1765
            break;
1766
        case 0x1:
1767
            /* JSR */
1768
            break;
1769
        case 0x2:
1770
            /* RET */
1771
            break;
1772
        case 0x3:
1773
            /* JSR_COROUTINE */
1774
            break;
1775
        }
1776
        ret = 1;
1777
        break;
1778
    case 0x1B:
1779
        /* HW_LD (PALcode) */
1780
#if defined (CONFIG_USER_ONLY)
1781
        goto invalid_opc;
1782
#else
1783
        if (!ctx->pal_mode)
1784
            goto invalid_opc;
1785
        if (ra != 31) {
1786
            TCGv addr = tcg_temp_new();
1787
            if (rb != 31)
1788
                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
1789
            else
1790
                tcg_gen_movi_i64(addr, disp12);
1791
            switch ((insn >> 12) & 0xF) {
1792
            case 0x0:
1793
                /* Longword physical access */
1794
                gen_helper_ldl_raw(cpu_ir[ra], addr);
1795
                break;
1796
            case 0x1:
1797
                /* Quadword physical access */
1798
                gen_helper_ldq_raw(cpu_ir[ra], addr);
1799
                break;
1800
            case 0x2:
1801
                /* Longword physical access with lock */
1802
                gen_helper_ldl_l_raw(cpu_ir[ra], addr);
1803
                break;
1804
            case 0x3:
1805
                /* Quadword physical access with lock */
1806
                gen_helper_ldq_l_raw(cpu_ir[ra], addr);
1807
                break;
1808
            case 0x4:
1809
                /* Longword virtual PTE fetch */
1810
                gen_helper_ldl_kernel(cpu_ir[ra], addr);
1811
                break;
1812
            case 0x5:
1813
                /* Quadword virtual PTE fetch */
1814
                gen_helper_ldq_kernel(cpu_ir[ra], addr);
1815
                break;
1816
            case 0x6:
1817
                /* Incpu_ir[ra]id */
1818
                goto incpu_ir[ra]id_opc;
1819
            case 0x7:
1820
                /* Incpu_ir[ra]id */
1821
                goto incpu_ir[ra]id_opc;
1822
            case 0x8:
1823
                /* Longword virtual access */
1824
                gen_helper_st_virt_to_phys(addr, addr);
1825
                gen_helper_ldl_raw(cpu_ir[ra], addr);
1826
                break;
1827
            case 0x9:
1828
                /* Quadword virtual access */
1829
                gen_helper_st_virt_to_phys(addr, addr);
1830
                gen_helper_ldq_raw(cpu_ir[ra], addr);
1831
                break;
1832
            case 0xA:
1833
                /* Longword virtual access with protection check */
1834
                tcg_gen_qemu_ld32s(cpu_ir[ra], addr, ctx->flags);
1835
                break;
1836
            case 0xB:
1837
                /* Quadword virtual access with protection check */
1838
                tcg_gen_qemu_ld64(cpu_ir[ra], addr, ctx->flags);
1839
                break;
1840
            case 0xC:
1841
                /* Longword virtual access with altenate access mode */
1842
                gen_helper_set_alt_mode();
1843
                gen_helper_st_virt_to_phys(addr, addr);
1844
                gen_helper_ldl_raw(cpu_ir[ra], addr);
1845
                gen_helper_restore_mode();
1846
                break;
1847
            case 0xD:
1848
                /* Quadword virtual access with altenate access mode */
1849
                gen_helper_set_alt_mode();
1850
                gen_helper_st_virt_to_phys(addr, addr);
1851
                gen_helper_ldq_raw(cpu_ir[ra], addr);
1852
                gen_helper_restore_mode();
1853
                break;
1854
            case 0xE:
1855
                /* Longword virtual access with alternate access mode and
1856
                 * protection checks
1857
                 */
1858
                gen_helper_set_alt_mode();
1859
                gen_helper_ldl_data(cpu_ir[ra], addr);
1860
                gen_helper_restore_mode();
1861
                break;
1862
            case 0xF:
1863
                /* Quadword virtual access with alternate access mode and
1864
                 * protection checks
1865
                 */
1866
                gen_helper_set_alt_mode();
1867
                gen_helper_ldq_data(cpu_ir[ra], addr);
1868
                gen_helper_restore_mode();
1869
                break;
1870
            }
1871
            tcg_temp_free(addr);
1872
        }
1873
        break;
1874
#endif
1875
    case 0x1C:
1876
        switch (fn7) {
1877
        case 0x00:
1878
            /* SEXTB */
1879
            if (!(ctx->amask & AMASK_BWX))
1880
                goto invalid_opc;
1881
            if (likely(rc != 31)) {
1882
                if (islit)
1883
                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
1884
                else
1885
                    tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
1886
            }
1887
            break;
1888
        case 0x01:
1889
            /* SEXTW */
1890
            if (!(ctx->amask & AMASK_BWX))
1891
                goto invalid_opc;
1892
            if (likely(rc != 31)) {
1893
                if (islit)
1894
                    tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
1895
                else
1896
                    tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
1897
            }
1898
            break;
1899
        case 0x30:
1900
            /* CTPOP */
1901
            if (!(ctx->amask & AMASK_CIX))
1902
                goto invalid_opc;
1903
            if (likely(rc != 31)) {
1904
                if (islit)
1905
                    tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
1906
                else
1907
                    gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
1908
            }
1909
            break;
1910
        case 0x31:
1911
            /* PERR */
1912
            if (!(ctx->amask & AMASK_MVI))
1913
                goto invalid_opc;
1914
            /* XXX: TODO */
1915
            goto invalid_opc;
1916
            break;
1917
        case 0x32:
1918
            /* CTLZ */
1919
            if (!(ctx->amask & AMASK_CIX))
1920
                goto invalid_opc;
1921
            if (likely(rc != 31)) {
1922
                if (islit)
1923
                    tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
1924
                else
1925
                    gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
1926
            }
1927
            break;
1928
        case 0x33:
1929
            /* CTTZ */
1930
            if (!(ctx->amask & AMASK_CIX))
1931
                goto invalid_opc;
1932
            if (likely(rc != 31)) {
1933
                if (islit)
1934
                    tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
1935
                else
1936
                    gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
1937
            }
1938
            break;
1939
        case 0x34:
1940
            /* UNPKBW */
1941
            if (!(ctx->amask & AMASK_MVI))
1942
                goto invalid_opc;
1943
            /* XXX: TODO */
1944
            goto invalid_opc;
1945
            break;
1946
        case 0x35:
1947
            /* UNPKWL */
1948
            if (!(ctx->amask & AMASK_MVI))
1949
                goto invalid_opc;
1950
            /* XXX: TODO */
1951
            goto invalid_opc;
1952
            break;
1953
        case 0x36:
1954
            /* PKWB */
1955
            if (!(ctx->amask & AMASK_MVI))
1956
                goto invalid_opc;
1957
            /* XXX: TODO */
1958
            goto invalid_opc;
1959
            break;
1960
        case 0x37:
1961
            /* PKLB */
1962
            if (!(ctx->amask & AMASK_MVI))
1963
                goto invalid_opc;
1964
            /* XXX: TODO */
1965
            goto invalid_opc;
1966
            break;
1967
        case 0x38:
1968
            /* MINSB8 */
1969
            if (!(ctx->amask & AMASK_MVI))
1970
                goto invalid_opc;
1971
            /* XXX: TODO */
1972
            goto invalid_opc;
1973
            break;
1974
        case 0x39:
1975
            /* MINSW4 */
1976
            if (!(ctx->amask & AMASK_MVI))
1977
                goto invalid_opc;
1978
            /* XXX: TODO */
1979
            goto invalid_opc;
1980
            break;
1981
        case 0x3A:
1982
            /* MINUB8 */
1983
            if (!(ctx->amask & AMASK_MVI))
1984
                goto invalid_opc;
1985
            /* XXX: TODO */
1986
            goto invalid_opc;
1987
            break;
1988
        case 0x3B:
1989
            /* MINUW4 */
1990
            if (!(ctx->amask & AMASK_MVI))
1991
                goto invalid_opc;
1992
            /* XXX: TODO */
1993
            goto invalid_opc;
1994
            break;
1995
        case 0x3C:
1996
            /* MAXUB8 */
1997
            if (!(ctx->amask & AMASK_MVI))
1998
                goto invalid_opc;
1999
            /* XXX: TODO */
2000
            goto invalid_opc;
2001
            break;
2002
        case 0x3D:
2003
            /* MAXUW4 */
2004
            if (!(ctx->amask & AMASK_MVI))
2005
                goto invalid_opc;
2006
            /* XXX: TODO */
2007
            goto invalid_opc;
2008
            break;
2009
        case 0x3E:
2010
            /* MAXSB8 */
2011
            if (!(ctx->amask & AMASK_MVI))
2012
                goto invalid_opc;
2013
            /* XXX: TODO */
2014
            goto invalid_opc;
2015
            break;
2016
        case 0x3F:
2017
            /* MAXSW4 */
2018
            if (!(ctx->amask & AMASK_MVI))
2019
                goto invalid_opc;
2020
            /* XXX: TODO */
2021
            goto invalid_opc;
2022
            break;
2023
        case 0x70:
2024
            /* FTOIT */
2025
            if (!(ctx->amask & AMASK_FIX))
2026
                goto invalid_opc;
2027
            if (likely(rc != 31)) {
2028
                if (ra != 31)
2029
                    tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
2030
                else
2031
                    tcg_gen_movi_i64(cpu_ir[rc], 0);
2032
            }
2033
            break;
2034
        case 0x78:
2035
            /* FTOIS */
2036
            if (!(ctx->amask & AMASK_FIX))
2037
                goto invalid_opc;
2038
            if (rc != 31) {
2039
                TCGv_i32 tmp1 = tcg_temp_new_i32();
2040
                if (ra != 31)
2041
                    gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
2042
                else {
2043
                    TCGv tmp2 = tcg_const_i64(0);
2044
                    gen_helper_s_to_memory(tmp1, tmp2);
2045
                    tcg_temp_free(tmp2);
2046
                }
2047
                tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
2048
                tcg_temp_free_i32(tmp1);
2049
            }
2050
            break;
2051
        default:
2052
            goto invalid_opc;
2053
        }
2054
        break;
2055
    case 0x1D:
2056
        /* HW_MTPR (PALcode) */
2057
#if defined (CONFIG_USER_ONLY)
2058
        goto invalid_opc;
2059
#else
2060
        if (!ctx->pal_mode)
2061
            goto invalid_opc;
2062
        else {
2063
            TCGv tmp1 = tcg_const_i32(insn & 0xFF);
2064
            if (ra != 31)
2065
                gen_helper_mtpr(tmp1, cpu_ir[ra]);
2066
            else {
2067
                TCGv tmp2 = tcg_const_i64(0);
2068
                gen_helper_mtpr(tmp1, tmp2);
2069
                tcg_temp_free(tmp2);
2070
            }
2071
            tcg_temp_free(tmp1);
2072
            ret = 2;
2073
        }
2074
        break;
2075
#endif
2076
    case 0x1E:
2077
        /* HW_REI (PALcode) */
2078
#if defined (CONFIG_USER_ONLY)
2079
        goto invalid_opc;
2080
#else
2081
        if (!ctx->pal_mode)
2082
            goto invalid_opc;
2083
        if (rb == 31) {
2084
            /* "Old" alpha */
2085
            gen_helper_hw_rei();
2086
        } else {
2087
            TCGv tmp;
2088

    
2089
            if (ra != 31) {
2090
                tmp = tcg_temp_new();
2091
                tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51));
2092
            } else
2093
                tmp = tcg_const_i64(((int64_t)insn << 51) >> 51);
2094
            gen_helper_hw_ret(tmp);
2095
            tcg_temp_free(tmp);
2096
        }
2097
        ret = 2;
2098
        break;
2099
#endif
2100
    case 0x1F:
2101
        /* HW_ST (PALcode) */
2102
#if defined (CONFIG_USER_ONLY)
2103
        goto invalid_opc;
2104
#else
2105
        if (!ctx->pal_mode)
2106
            goto invalid_opc;
2107
        else {
2108
            TCGv addr, val;
2109
            addr = tcg_temp_new();
2110
            if (rb != 31)
2111
                tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2112
            else
2113
                tcg_gen_movi_i64(addr, disp12);
2114
            if (ra != 31)
2115
                val = cpu_ir[ra];
2116
            else {
2117
                val = tcg_temp_new();
2118
                tcg_gen_movi_i64(val, 0);
2119
            }
2120
            switch ((insn >> 12) & 0xF) {
2121
            case 0x0:
2122
                /* Longword physical access */
2123
                gen_helper_stl_raw(val, addr);
2124
                break;
2125
            case 0x1:
2126
                /* Quadword physical access */
2127
                gen_helper_stq_raw(val, addr);
2128
                break;
2129
            case 0x2:
2130
                /* Longword physical access with lock */
2131
                gen_helper_stl_c_raw(val, val, addr);
2132
                break;
2133
            case 0x3:
2134
                /* Quadword physical access with lock */
2135
                gen_helper_stq_c_raw(val, val, addr);
2136
                break;
2137
            case 0x4:
2138
                /* Longword virtual access */
2139
                gen_helper_st_virt_to_phys(addr, addr);
2140
                gen_helper_stl_raw(val, addr);
2141
                break;
2142
            case 0x5:
2143
                /* Quadword virtual access */
2144
                gen_helper_st_virt_to_phys(addr, addr);
2145
                gen_helper_stq_raw(val, addr);
2146
                break;
2147
            case 0x6:
2148
                /* Invalid */
2149
                goto invalid_opc;
2150
            case 0x7:
2151
                /* Invalid */
2152
                goto invalid_opc;
2153
            case 0x8:
2154
                /* Invalid */
2155
                goto invalid_opc;
2156
            case 0x9:
2157
                /* Invalid */
2158
                goto invalid_opc;
2159
            case 0xA:
2160
                /* Invalid */
2161
                goto invalid_opc;
2162
            case 0xB:
2163
                /* Invalid */
2164
                goto invalid_opc;
2165
            case 0xC:
2166
                /* Longword virtual access with alternate access mode */
2167
                gen_helper_set_alt_mode();
2168
                gen_helper_st_virt_to_phys(addr, addr);
2169
                gen_helper_stl_raw(val, addr);
2170
                gen_helper_restore_mode();
2171
                break;
2172
            case 0xD:
2173
                /* Quadword virtual access with alternate access mode */
2174
                gen_helper_set_alt_mode();
2175
                gen_helper_st_virt_to_phys(addr, addr);
2176
                gen_helper_stl_raw(val, addr);
2177
                gen_helper_restore_mode();
2178
                break;
2179
            case 0xE:
2180
                /* Invalid */
2181
                goto invalid_opc;
2182
            case 0xF:
2183
                /* Invalid */
2184
                goto invalid_opc;
2185
            }
2186
            if (ra != 31)
2187
                tcg_temp_free(val);
2188
            tcg_temp_free(addr);
2189
        }
2190
        ret = 2;
2191
        break;
2192
#endif
2193
    case 0x20:
2194
        /* LDF */
2195
        gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
2196
        break;
2197
    case 0x21:
2198
        /* LDG */
2199
        gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
2200
        break;
2201
    case 0x22:
2202
        /* LDS */
2203
        gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
2204
        break;
2205
    case 0x23:
2206
        /* LDT */
2207
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
2208
        break;
2209
    case 0x24:
2210
        /* STF */
2211
        gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0, 0);
2212
        break;
2213
    case 0x25:
2214
        /* STG */
2215
        gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0, 0);
2216
        break;
2217
    case 0x26:
2218
        /* STS */
2219
        gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0, 0);
2220
        break;
2221
    case 0x27:
2222
        /* STT */
2223
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0, 0);
2224
        break;
2225
    case 0x28:
2226
        /* LDL */
2227
        gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
2228
        break;
2229
    case 0x29:
2230
        /* LDQ */
2231
        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
2232
        break;
2233
    case 0x2A:
2234
        /* LDL_L */
2235
        gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
2236
        break;
2237
    case 0x2B:
2238
        /* LDQ_L */
2239
        gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
2240
        break;
2241
    case 0x2C:
2242
        /* STL */
2243
        gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0, 0);
2244
        break;
2245
    case 0x2D:
2246
        /* STQ */
2247
        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0, 0);
2248
        break;
2249
    case 0x2E:
2250
        /* STL_C */
2251
        gen_store_mem(ctx, &gen_qemu_stl_c, ra, rb, disp16, 0, 0, 1);
2252
        break;
2253
    case 0x2F:
2254
        /* STQ_C */
2255
        gen_store_mem(ctx, &gen_qemu_stq_c, ra, rb, disp16, 0, 0, 1);
2256
        break;
2257
    case 0x30:
2258
        /* BR */
2259
        if (ra != 31)
2260
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2261
        tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
2262
        ret = 1;
2263
        break;
2264
    case 0x31: /* FBEQ */
2265
    case 0x32: /* FBLT */
2266
    case 0x33: /* FBLE */
2267
        gen_fbcond(ctx, opc, ra, disp16);
2268
        ret = 1;
2269
        break;
2270
    case 0x34:
2271
        /* BSR */
2272
        if (ra != 31)
2273
            tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2274
        tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
2275
        ret = 1;
2276
        break;
2277
    case 0x35: /* FBNE */
2278
    case 0x36: /* FBGE */
2279
    case 0x37: /* FBGT */
2280
        gen_fbcond(ctx, opc, ra, disp16);
2281
        ret = 1;
2282
        break;
2283
    case 0x38:
2284
        /* BLBC */
2285
        gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 1);
2286
        ret = 1;
2287
        break;
2288
    case 0x39:
2289
        /* BEQ */
2290
        gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 0);
2291
        ret = 1;
2292
        break;
2293
    case 0x3A:
2294
        /* BLT */
2295
        gen_bcond(ctx, TCG_COND_LT, ra, disp16, 0);
2296
        ret = 1;
2297
        break;
2298
    case 0x3B:
2299
        /* BLE */
2300
        gen_bcond(ctx, TCG_COND_LE, ra, disp16, 0);
2301
        ret = 1;
2302
        break;
2303
    case 0x3C:
2304
        /* BLBS */
2305
        gen_bcond(ctx, TCG_COND_NE, ra, disp16, 1);
2306
        ret = 1;
2307
        break;
2308
    case 0x3D:
2309
        /* BNE */
2310
        gen_bcond(ctx, TCG_COND_NE, ra, disp16, 0);
2311
        ret = 1;
2312
        break;
2313
    case 0x3E:
2314
        /* BGE */
2315
        gen_bcond(ctx, TCG_COND_GE, ra, disp16, 0);
2316
        ret = 1;
2317
        break;
2318
    case 0x3F:
2319
        /* BGT */
2320
        gen_bcond(ctx, TCG_COND_GT, ra, disp16, 0);
2321
        ret = 1;
2322
        break;
2323
    invalid_opc:
2324
        gen_invalid(ctx);
2325
        ret = 3;
2326
        break;
2327
    }
2328

    
2329
    return ret;
2330
}
2331

    
2332
static always_inline void gen_intermediate_code_internal (CPUState *env,
2333
                                                          TranslationBlock *tb,
2334
                                                          int search_pc)
2335
{
2336
#if defined ALPHA_DEBUG_DISAS
2337
    static int insn_count;
2338
#endif
2339
    DisasContext ctx, *ctxp = &ctx;
2340
    target_ulong pc_start;
2341
    uint32_t insn;
2342
    uint16_t *gen_opc_end;
2343
    CPUBreakpoint *bp;
2344
    int j, lj = -1;
2345
    int ret;
2346
    int num_insns;
2347
    int max_insns;
2348

    
2349
    pc_start = tb->pc;
2350
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2351
    ctx.pc = pc_start;
2352
    ctx.amask = env->amask;
2353
#if defined (CONFIG_USER_ONLY)
2354
    ctx.mem_idx = 0;
2355
#else
2356
    ctx.mem_idx = ((env->ps >> 3) & 3);
2357
    ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
2358
#endif
2359
    num_insns = 0;
2360
    max_insns = tb->cflags & CF_COUNT_MASK;
2361
    if (max_insns == 0)
2362
        max_insns = CF_COUNT_MASK;
2363

    
2364
    gen_icount_start();
2365
    for (ret = 0; ret == 0;) {
2366
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
2367
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
2368
                if (bp->pc == ctx.pc) {
2369
                    gen_excp(&ctx, EXCP_DEBUG, 0);
2370
                    break;
2371
                }
2372
            }
2373
        }
2374
        if (search_pc) {
2375
            j = gen_opc_ptr - gen_opc_buf;
2376
            if (lj < j) {
2377
                lj++;
2378
                while (lj < j)
2379
                    gen_opc_instr_start[lj++] = 0;
2380
                gen_opc_pc[lj] = ctx.pc;
2381
                gen_opc_instr_start[lj] = 1;
2382
                gen_opc_icount[lj] = num_insns;
2383
            }
2384
        }
2385
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
2386
            gen_io_start();
2387
#if defined ALPHA_DEBUG_DISAS
2388
        insn_count++;
2389
        if (logfile != NULL) {
2390
            fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2391
                    ctx.pc, ctx.mem_idx);
2392
        }
2393
#endif
2394
        insn = ldl_code(ctx.pc);
2395
#if defined ALPHA_DEBUG_DISAS
2396
        insn_count++;
2397
        if (logfile != NULL) {
2398
            fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2399
        }
2400
#endif
2401
        num_insns++;
2402
        ctx.pc += 4;
2403
        ret = translate_one(ctxp, insn);
2404
        if (ret != 0)
2405
            break;
2406
        /* if we reach a page boundary or are single stepping, stop
2407
         * generation
2408
         */
2409
        if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2410
            (env->singlestep_enabled) ||
2411
            num_insns >= max_insns) {
2412
            break;
2413
        }
2414
#if defined (DO_SINGLE_STEP)
2415
        break;
2416
#endif
2417
    }
2418
    if (ret != 1 && ret != 3) {
2419
        tcg_gen_movi_i64(cpu_pc, ctx.pc);
2420
    }
2421
#if defined (DO_TB_FLUSH)
2422
    gen_helper_tb_flush();
2423
#endif
2424
    if (tb->cflags & CF_LAST_IO)
2425
        gen_io_end();
2426
    /* Generate the return instruction */
2427
    tcg_gen_exit_tb(0);
2428
    gen_icount_end(tb, num_insns);
2429
    *gen_opc_ptr = INDEX_op_end;
2430
    if (search_pc) {
2431
        j = gen_opc_ptr - gen_opc_buf;
2432
        lj++;
2433
        while (lj <= j)
2434
            gen_opc_instr_start[lj++] = 0;
2435
    } else {
2436
        tb->size = ctx.pc - pc_start;
2437
        tb->icount = num_insns;
2438
    }
2439
#if defined ALPHA_DEBUG_DISAS
2440
    if (loglevel & CPU_LOG_TB_CPU) {
2441
        cpu_dump_state(env, logfile, fprintf, 0);
2442
    }
2443
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2444
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2445
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
2446
        fprintf(logfile, "\n");
2447
    }
2448
#endif
2449
}
2450

    
2451
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2452
{
2453
    gen_intermediate_code_internal(env, tb, 0);
2454
}
2455

    
2456
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2457
{
2458
    gen_intermediate_code_internal(env, tb, 1);
2459
}
2460

    
2461
CPUAlphaState * cpu_alpha_init (const char *cpu_model)
2462
{
2463
    CPUAlphaState *env;
2464
    uint64_t hwpcb;
2465

    
2466
    env = qemu_mallocz(sizeof(CPUAlphaState));
2467
    if (!env)
2468
        return NULL;
2469
    cpu_exec_init(env);
2470
    alpha_translate_init();
2471
    tlb_flush(env, 1);
2472
    /* XXX: should not be hardcoded */
2473
    env->implver = IMPLVER_2106x;
2474
    env->ps = 0x1F00;
2475
#if defined (CONFIG_USER_ONLY)
2476
    env->ps |= 1 << 3;
2477
#endif
2478
    pal_init(env);
2479
    /* Initialize IPR */
2480
    hwpcb = env->ipr[IPR_PCBB];
2481
    env->ipr[IPR_ASN] = 0;
2482
    env->ipr[IPR_ASTEN] = 0;
2483
    env->ipr[IPR_ASTSR] = 0;
2484
    env->ipr[IPR_DATFX] = 0;
2485
    /* XXX: fix this */
2486
    //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2487
    //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2488
    //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2489
    //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2490
    env->ipr[IPR_FEN] = 0;
2491
    env->ipr[IPR_IPL] = 31;
2492
    env->ipr[IPR_MCES] = 0;
2493
    env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2494
    //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2495
    env->ipr[IPR_SISR] = 0;
2496
    env->ipr[IPR_VIRBND] = -1ULL;
2497

    
2498
    return env;
2499
}
2500

    
2501
void gen_pc_load(CPUState *env, TranslationBlock *tb,
2502
                unsigned long searched_pc, int pc_pos, void *puc)
2503
{
2504
    env->pc = gen_opc_pc[pc_pos];
2505
}