Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ 2e70f6ef

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

    
31
#define DO_SINGLE_STEP
32
#define GENERATE_NOP
33
#define ALPHA_DEBUG_DISAS
34
#define DO_TB_FLUSH
35

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

    
46
TCGv cpu_env;
47

    
48
#include "gen-icount.h"
49

    
50
void alpha_translate_init()
51
{
52
    static int done_init = 0;
53
    if (done_init)
54
        return;
55
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
56
    done_init = 1;
57
}
58

    
59
static always_inline void gen_op_nop (void)
60
{
61
#if defined(GENERATE_NOP)
62
    gen_op_no_op();
63
#endif
64
}
65

    
66
#define GEN32(func, NAME) \
67
static GenOpFunc *NAME ## _table [32] = {                                     \
68
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
69
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
70
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
71
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
72
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
73
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
74
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
75
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
76
};                                                                            \
77
static always_inline void func (int n)                                        \
78
{                                                                             \
79
    NAME ## _table[n]();                                                      \
80
}
81

    
82
/* IR moves */
83
/* Special hacks for ir31 */
84
#define gen_op_load_T0_ir31 gen_op_reset_T0
85
#define gen_op_load_T1_ir31 gen_op_reset_T1
86
#define gen_op_load_T2_ir31 gen_op_reset_T2
87
#define gen_op_store_T0_ir31 gen_op_nop
88
#define gen_op_store_T1_ir31 gen_op_nop
89
#define gen_op_store_T2_ir31 gen_op_nop
90
#define gen_op_cmov_ir31 gen_op_nop
91
GEN32(gen_op_load_T0_ir, gen_op_load_T0_ir);
92
GEN32(gen_op_load_T1_ir, gen_op_load_T1_ir);
93
GEN32(gen_op_load_T2_ir, gen_op_load_T2_ir);
94
GEN32(gen_op_store_T0_ir, gen_op_store_T0_ir);
95
GEN32(gen_op_store_T1_ir, gen_op_store_T1_ir);
96
GEN32(gen_op_store_T2_ir, gen_op_store_T2_ir);
97
GEN32(gen_op_cmov_ir, gen_op_cmov_ir);
98

    
99
static always_inline void gen_load_ir (DisasContext *ctx, int irn, int Tn)
100
{
101
    switch (Tn) {
102
    case 0:
103
        gen_op_load_T0_ir(irn);
104
        break;
105
    case 1:
106
        gen_op_load_T1_ir(irn);
107
        break;
108
    case 2:
109
        gen_op_load_T2_ir(irn);
110
        break;
111
    }
112
}
113

    
114
static always_inline void gen_store_ir (DisasContext *ctx, int irn, int Tn)
115
{
116
    switch (Tn) {
117
    case 0:
118
        gen_op_store_T0_ir(irn);
119
        break;
120
    case 1:
121
        gen_op_store_T1_ir(irn);
122
        break;
123
    case 2:
124
        gen_op_store_T2_ir(irn);
125
        break;
126
    }
127
}
128

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

    
146
static always_inline void gen_load_fir (DisasContext *ctx, int firn, int Tn)
147
{
148
    switch (Tn) {
149
    case 0:
150
        gen_op_load_FT0_fir(firn);
151
        break;
152
    case 1:
153
        gen_op_load_FT1_fir(firn);
154
        break;
155
    case 2:
156
        gen_op_load_FT2_fir(firn);
157
        break;
158
    }
159
}
160

    
161
static always_inline void gen_store_fir (DisasContext *ctx, int firn, int Tn)
162
{
163
    switch (Tn) {
164
    case 0:
165
        gen_op_store_FT0_fir(firn);
166
        break;
167
    case 1:
168
        gen_op_store_FT1_fir(firn);
169
        break;
170
    case 2:
171
        gen_op_store_FT2_fir(firn);
172
        break;
173
    }
174
}
175

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

    
203
#define GEN_LD(width)                                                         \
204
OP_LD_TABLE(width);                                                           \
205
static always_inline void gen_ld##width (DisasContext *ctx)                   \
206
{                                                                             \
207
    (*gen_op_ld##width[ctx->mem_idx])();                                      \
208
}
209

    
210
#define GEN_ST(width)                                                         \
211
OP_ST_TABLE(width);                                                           \
212
static always_inline void gen_st##width (DisasContext *ctx)                   \
213
{                                                                             \
214
    (*gen_op_st##width[ctx->mem_idx])();                                      \
215
}
216

    
217
GEN_LD(bu);
218
GEN_ST(b);
219
GEN_LD(wu);
220
GEN_ST(w);
221
GEN_LD(l);
222
GEN_ST(l);
223
GEN_LD(q);
224
GEN_ST(q);
225
GEN_LD(q_u);
226
GEN_ST(q_u);
227
GEN_LD(l_l);
228
GEN_ST(l_c);
229
GEN_LD(q_l);
230
GEN_ST(q_c);
231

    
232
#if 0 /* currently unused */
233
GEN_LD(f);
234
GEN_ST(f);
235
GEN_LD(g);
236
GEN_ST(g);
237
#endif /* 0 */
238
GEN_LD(s);
239
GEN_ST(s);
240
GEN_LD(t);
241
GEN_ST(t);
242

    
243
#if defined(__i386__) || defined(__x86_64__)
244
static always_inline void gen_op_set_s16_T0 (int16_t imm)
245
{
246
    gen_op_set_s32_T0((int32_t)imm);
247
}
248

    
249
static always_inline void gen_op_set_s16_T1 (int16_t imm)
250
{
251
    gen_op_set_s32_T1((int32_t)imm);
252
}
253

    
254
static always_inline void gen_op_set_u16_T0 (uint16_t imm)
255
{
256
    gen_op_set_s32_T0((uint32_t)imm);
257
}
258

    
259
static always_inline void gen_op_set_u16_T1 (uint16_t imm)
260
{
261
    gen_op_set_s32_T1((uint32_t)imm);
262
}
263
#endif
264

    
265
static always_inline void gen_set_sT0 (DisasContext *ctx, int64_t imm)
266
{
267
    int32_t imm32;
268
    int16_t imm16;
269

    
270
    imm32 = imm;
271
    if (imm32 == imm) {
272
        imm16 = imm;
273
        if (imm16 == imm) {
274
            if (imm == 0) {
275
                gen_op_reset_T0();
276
            } else {
277
                gen_op_set_s16_T0(imm16);
278
            }
279
        } else {
280
            gen_op_set_s32_T0(imm32);
281
        }
282
    } else {
283
#if 0 // Qemu does not know how to do this...
284
        gen_op_set_64_T0(imm);
285
#else
286
        gen_op_set_64_T0(imm >> 32, imm);
287
#endif
288
    }
289
}
290

    
291
static always_inline void gen_set_sT1 (DisasContext *ctx, int64_t imm)
292
{
293
    int32_t imm32;
294
    int16_t imm16;
295

    
296
    imm32 = imm;
297
    if (imm32 == imm) {
298
        imm16 = imm;
299
        if (imm16 == imm) {
300
            if (imm == 0) {
301
                gen_op_reset_T1();
302
            } else {
303
                gen_op_set_s16_T1(imm16);
304
            }
305
        } else {
306
            gen_op_set_s32_T1(imm32);
307
        }
308
    } else {
309
#if 0 // Qemu does not know how to do this...
310
        gen_op_set_64_T1(imm);
311
#else
312
        gen_op_set_64_T1(imm >> 32, imm);
313
#endif
314
    }
315
}
316

    
317
static always_inline void gen_set_uT0 (DisasContext *ctx, uint64_t imm)
318
{
319
    if (!(imm >> 32)) {
320
        if ((!imm >> 16)) {
321
            if (imm == 0)
322
                gen_op_reset_T0();
323
            else
324
                gen_op_set_u16_T0(imm);
325
        } else {
326
            gen_op_set_u32_T0(imm);
327
        }
328
    } else {
329
#if 0 // Qemu does not know how to do this...
330
        gen_op_set_64_T0(imm);
331
#else
332
        gen_op_set_64_T0(imm >> 32, imm);
333
#endif
334
    }
335
}
336

    
337
static always_inline void gen_set_uT1 (DisasContext *ctx, uint64_t imm)
338
{
339
    if (!(imm >> 32)) {
340
        if ((!imm >> 16)) {
341
            if (imm == 0)
342
                gen_op_reset_T1();
343
            else
344
                gen_op_set_u16_T1(imm);
345
        } else {
346
            gen_op_set_u32_T1(imm);
347
        }
348
    } else {
349
#if 0 // Qemu does not know how to do this...
350
        gen_op_set_64_T1(imm);
351
#else
352
        gen_op_set_64_T1(imm >> 32, imm);
353
#endif
354
    }
355
}
356

    
357
static always_inline void gen_update_pc (DisasContext *ctx)
358
{
359
    if (!(ctx->pc >> 32)) {
360
        gen_op_update_pc32(ctx->pc);
361
    } else {
362
#if 0 // Qemu does not know how to do this...
363
        gen_op_update_pc(ctx->pc);
364
#else
365
        gen_op_update_pc(ctx->pc >> 32, ctx->pc);
366
#endif
367
    }
368
}
369

    
370
static always_inline void _gen_op_bcond (DisasContext *ctx)
371
{
372
#if 0 // Qemu does not know how to do this...
373
    gen_op_bcond(ctx->pc);
374
#else
375
    gen_op_bcond(ctx->pc >> 32, ctx->pc);
376
#endif
377
}
378

    
379
static always_inline void gen_excp (DisasContext *ctx,
380
                                    int exception, int error_code)
381
{
382
    gen_update_pc(ctx);
383
    gen_op_excp(exception, error_code);
384
}
385

    
386
static always_inline void gen_invalid (DisasContext *ctx)
387
{
388
    gen_excp(ctx, EXCP_OPCDEC, 0);
389
}
390

    
391
static always_inline void gen_load_mem (DisasContext *ctx,
392
                                        void (*gen_load_op)(DisasContext *ctx),
393
                                        int ra, int rb, int32_t disp16,
394
                                        int clear)
395
{
396
    if (ra == 31 && disp16 == 0) {
397
        /* UNOP */
398
        gen_op_nop();
399
    } else {
400
        gen_load_ir(ctx, rb, 0);
401
        if (disp16 != 0) {
402
            gen_set_sT1(ctx, disp16);
403
            gen_op_addq();
404
        }
405
        if (clear)
406
            gen_op_n7();
407
        (*gen_load_op)(ctx);
408
        gen_store_ir(ctx, ra, 1);
409
    }
410
}
411

    
412
static always_inline void gen_store_mem (DisasContext *ctx,
413
                                         void (*gen_store_op)(DisasContext *ctx),
414
                                         int ra, int rb, int32_t disp16,
415
                                         int clear)
416
{
417
    gen_load_ir(ctx, rb, 0);
418
    if (disp16 != 0) {
419
        gen_set_sT1(ctx, disp16);
420
        gen_op_addq();
421
    }
422
    if (clear)
423
        gen_op_n7();
424
    gen_load_ir(ctx, ra, 1);
425
    (*gen_store_op)(ctx);
426
}
427

    
428
static always_inline void gen_load_fmem (DisasContext *ctx,
429
                                         void (*gen_load_fop)(DisasContext *ctx),
430
                                         int ra, int rb, int32_t disp16)
431
{
432
    gen_load_ir(ctx, rb, 0);
433
    if (disp16 != 0) {
434
        gen_set_sT1(ctx, disp16);
435
        gen_op_addq();
436
    }
437
    (*gen_load_fop)(ctx);
438
    gen_store_fir(ctx, ra, 1);
439
}
440

    
441
static always_inline void gen_store_fmem (DisasContext *ctx,
442
                                          void (*gen_store_fop)(DisasContext *ctx),
443
                                          int ra, int rb, int32_t disp16)
444
{
445
    gen_load_ir(ctx, rb, 0);
446
    if (disp16 != 0) {
447
        gen_set_sT1(ctx, disp16);
448
        gen_op_addq();
449
    }
450
    gen_load_fir(ctx, ra, 1);
451
    (*gen_store_fop)(ctx);
452
}
453

    
454
static always_inline void gen_bcond (DisasContext *ctx,
455
                                     void (*gen_test_op)(void),
456
                                     int ra, int32_t disp16)
457
{
458
    if (disp16 != 0) {
459
        gen_set_uT0(ctx, ctx->pc);
460
        gen_set_sT1(ctx, disp16 << 2);
461
        gen_op_addq1();
462
    } else {
463
        gen_set_uT1(ctx, ctx->pc);
464
    }
465
    gen_load_ir(ctx, ra, 0);
466
    (*gen_test_op)();
467
    _gen_op_bcond(ctx);
468
}
469

    
470
static always_inline void gen_fbcond (DisasContext *ctx,
471
                                      void (*gen_test_op)(void),
472
                                      int ra, int32_t disp16)
473
{
474
    if (disp16 != 0) {
475
        gen_set_uT0(ctx, ctx->pc);
476
        gen_set_sT1(ctx, disp16 << 2);
477
        gen_op_addq1();
478
    } else {
479
        gen_set_uT1(ctx, ctx->pc);
480
    }
481
    gen_load_fir(ctx, ra, 0);
482
    (*gen_test_op)();
483
    _gen_op_bcond(ctx);
484
}
485

    
486
static always_inline void gen_arith2 (DisasContext *ctx,
487
                                      void (*gen_arith_op)(void),
488
                                      int rb, int rc, int islit, int8_t lit)
489
{
490
    if (islit)
491
        gen_set_sT0(ctx, lit);
492
    else
493
        gen_load_ir(ctx, rb, 0);
494
    (*gen_arith_op)();
495
    gen_store_ir(ctx, rc, 0);
496
}
497

    
498
static always_inline void gen_arith3 (DisasContext *ctx,
499
                                      void (*gen_arith_op)(void),
500
                                      int ra, int rb, int rc,
501
                                      int islit, int8_t lit)
502
{
503
    gen_load_ir(ctx, ra, 0);
504
    if (islit)
505
        gen_set_sT1(ctx, lit);
506
    else
507
        gen_load_ir(ctx, rb, 1);
508
    (*gen_arith_op)();
509
    gen_store_ir(ctx, rc, 0);
510
}
511

    
512
static always_inline void gen_cmov (DisasContext *ctx,
513
                                    void (*gen_test_op)(void),
514
                                    int ra, int rb, int rc,
515
                                    int islit, int8_t lit)
516
{
517
    gen_load_ir(ctx, ra, 1);
518
    if (islit)
519
        gen_set_sT0(ctx, lit);
520
    else
521
        gen_load_ir(ctx, rb, 0);
522
    (*gen_test_op)();
523
    gen_op_cmov_ir(rc);
524
}
525

    
526
static always_inline void gen_farith2 (DisasContext *ctx,
527
                                       void (*gen_arith_fop)(void),
528
                                       int rb, int rc)
529
{
530
    gen_load_fir(ctx, rb, 0);
531
    (*gen_arith_fop)();
532
    gen_store_fir(ctx, rc, 0);
533
}
534

    
535
static always_inline void gen_farith3 (DisasContext *ctx,
536
                                       void (*gen_arith_fop)(void),
537
                                       int ra, int rb, int rc)
538
{
539
    gen_load_fir(ctx, ra, 0);
540
    gen_load_fir(ctx, rb, 1);
541
    (*gen_arith_fop)();
542
    gen_store_fir(ctx, rc, 0);
543
}
544

    
545
static always_inline void gen_fcmov (DisasContext *ctx,
546
                                     void (*gen_test_fop)(void),
547
                                     int ra, int rb, int rc)
548
{
549
    gen_load_fir(ctx, ra, 0);
550
    gen_load_fir(ctx, rb, 1);
551
    (*gen_test_fop)();
552
    gen_op_cmov_fir(rc);
553
}
554

    
555
static always_inline void gen_fti (DisasContext *ctx,
556
                                   void (*gen_move_fop)(void),
557
                                   int ra, int rc)
558
{
559
    gen_load_fir(ctx, rc, 0);
560
    (*gen_move_fop)();
561
    gen_store_ir(ctx, ra, 0);
562
}
563

    
564
static always_inline void gen_itf (DisasContext *ctx,
565
                                   void (*gen_move_fop)(void),
566
                                   int ra, int rc)
567
{
568
    gen_load_ir(ctx, ra, 0);
569
    (*gen_move_fop)();
570
    gen_store_fir(ctx, rc, 0);
571
}
572

    
573
static always_inline void gen_s4addl (void)
574
{
575
    gen_op_s4();
576
    gen_op_addl();
577
}
578

    
579
static always_inline void gen_s4subl (void)
580
{
581
    gen_op_s4();
582
    gen_op_subl();
583
}
584

    
585
static always_inline void gen_s8addl (void)
586
{
587
    gen_op_s8();
588
    gen_op_addl();
589
}
590

    
591
static always_inline void gen_s8subl (void)
592
{
593
    gen_op_s8();
594
    gen_op_subl();
595
}
596

    
597
static always_inline void gen_s4addq (void)
598
{
599
    gen_op_s4();
600
    gen_op_addq();
601
}
602

    
603
static always_inline void gen_s4subq (void)
604
{
605
    gen_op_s4();
606
    gen_op_subq();
607
}
608

    
609
static always_inline void gen_s8addq (void)
610
{
611
    gen_op_s8();
612
    gen_op_addq();
613
}
614

    
615
static always_inline void gen_s8subq (void)
616
{
617
    gen_op_s8();
618
    gen_op_subq();
619
}
620

    
621
static always_inline void gen_amask (void)
622
{
623
    gen_op_load_amask();
624
    gen_op_bic();
625
}
626

    
627
static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
628
{
629
    uint32_t palcode;
630
    int32_t disp21, disp16, disp12;
631
    uint16_t fn11, fn16;
632
    uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
633
    int8_t lit;
634
    int ret;
635

    
636
    /* Decode all instruction fields */
637
    opc = insn >> 26;
638
    ra = (insn >> 21) & 0x1F;
639
    rb = (insn >> 16) & 0x1F;
640
    rc = insn & 0x1F;
641
    sbz = (insn >> 13) & 0x07;
642
    islit = (insn >> 12) & 1;
643
    lit = (insn >> 13) & 0xFF;
644
    palcode = insn & 0x03FFFFFF;
645
    disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
646
    disp16 = (int16_t)(insn & 0x0000FFFF);
647
    disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
648
    fn16 = insn & 0x0000FFFF;
649
    fn11 = (insn >> 5) & 0x000007FF;
650
    fpfn = fn11 & 0x3F;
651
    fn7 = (insn >> 5) & 0x0000007F;
652
    fn2 = (insn >> 5) & 0x00000003;
653
    ret = 0;
654
#if defined ALPHA_DEBUG_DISAS
655
    if (logfile != NULL) {
656
        fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n",
657
                opc, ra, rb, rc, disp16);
658
    }
659
#endif
660
    switch (opc) {
661
    case 0x00:
662
        /* CALL_PAL */
663
        if (palcode >= 0x80 && palcode < 0xC0) {
664
            /* Unprivileged PAL call */
665
            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);
666
#if !defined (CONFIG_USER_ONLY)
667
        } else if (palcode < 0x40) {
668
            /* Privileged PAL code */
669
            if (ctx->mem_idx & 1)
670
                goto invalid_opc;
671
            else
672
                gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0);
673
#endif
674
        } else {
675
            /* Invalid PAL call */
676
            goto invalid_opc;
677
        }
678
        ret = 3;
679
        break;
680
    case 0x01:
681
        /* OPC01 */
682
        goto invalid_opc;
683
    case 0x02:
684
        /* OPC02 */
685
        goto invalid_opc;
686
    case 0x03:
687
        /* OPC03 */
688
        goto invalid_opc;
689
    case 0x04:
690
        /* OPC04 */
691
        goto invalid_opc;
692
    case 0x05:
693
        /* OPC05 */
694
        goto invalid_opc;
695
    case 0x06:
696
        /* OPC06 */
697
        goto invalid_opc;
698
    case 0x07:
699
        /* OPC07 */
700
        goto invalid_opc;
701
    case 0x08:
702
        /* LDA */
703
        gen_load_ir(ctx, rb, 0);
704
        gen_set_sT1(ctx, disp16);
705
        gen_op_addq();
706
        gen_store_ir(ctx, ra, 0);
707
        break;
708
    case 0x09:
709
        /* LDAH */
710
        gen_load_ir(ctx, rb, 0);
711
        gen_set_sT1(ctx, disp16 << 16);
712
        gen_op_addq();
713
        gen_store_ir(ctx, ra, 0);
714
        break;
715
    case 0x0A:
716
        /* LDBU */
717
        if (!(ctx->amask & AMASK_BWX))
718
            goto invalid_opc;
719
        gen_load_mem(ctx, &gen_ldbu, ra, rb, disp16, 0);
720
        break;
721
    case 0x0B:
722
        /* LDQ_U */
723
        gen_load_mem(ctx, &gen_ldq_u, ra, rb, disp16, 1);
724
        break;
725
    case 0x0C:
726
        /* LDWU */
727
        if (!(ctx->amask & AMASK_BWX))
728
            goto invalid_opc;
729
        gen_load_mem(ctx, &gen_ldwu, ra, rb, disp16, 0);
730
        break;
731
    case 0x0D:
732
        /* STW */
733
        if (!(ctx->amask & AMASK_BWX))
734
            goto invalid_opc;
735
        gen_store_mem(ctx, &gen_stw, ra, rb, disp16, 0);
736
        break;
737
    case 0x0E:
738
        /* STB */
739
        if (!(ctx->amask & AMASK_BWX))
740
            goto invalid_opc;
741
        gen_store_mem(ctx, &gen_stb, ra, rb, disp16, 0);
742
        break;
743
    case 0x0F:
744
        /* STQ_U */
745
        gen_store_mem(ctx, &gen_stq_u, ra, rb, disp16, 1);
746
        break;
747
    case 0x10:
748
        switch (fn7) {
749
        case 0x00:
750
            /* ADDL */
751
            gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit);
752
            break;
753
        case 0x02:
754
            /* S4ADDL */
755
            gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit);
756
            break;
757
        case 0x09:
758
            /* SUBL */
759
            gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit);
760
            break;
761
        case 0x0B:
762
            /* S4SUBL */
763
            gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit);
764
            break;
765
        case 0x0F:
766
            /* CMPBGE */
767
            gen_arith3(ctx, &gen_op_cmpbge, ra, rb, rc, islit, lit);
768
            break;
769
        case 0x12:
770
            /* S8ADDL */
771
            gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit);
772
            break;
773
        case 0x1B:
774
            /* S8SUBL */
775
            gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit);
776
            break;
777
        case 0x1D:
778
            /* CMPULT */
779
            gen_arith3(ctx, &gen_op_cmpult, ra, rb, rc, islit, lit);
780
            break;
781
        case 0x20:
782
            /* ADDQ */
783
            gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit);
784
            break;
785
        case 0x22:
786
            /* S4ADDQ */
787
            gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit);
788
            break;
789
        case 0x29:
790
            /* SUBQ */
791
            gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit);
792
            break;
793
        case 0x2B:
794
            /* S4SUBQ */
795
            gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit);
796
            break;
797
        case 0x2D:
798
            /* CMPEQ */
799
            gen_arith3(ctx, &gen_op_cmpeq, ra, rb, rc, islit, lit);
800
            break;
801
        case 0x32:
802
            /* S8ADDQ */
803
            gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit);
804
            break;
805
        case 0x3B:
806
            /* S8SUBQ */
807
            gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit);
808
            break;
809
        case 0x3D:
810
            /* CMPULE */
811
            gen_arith3(ctx, &gen_op_cmpule, ra, rb, rc, islit, lit);
812
            break;
813
        case 0x40:
814
            /* ADDL/V */
815
            gen_arith3(ctx, &gen_op_addlv, ra, rb, rc, islit, lit);
816
            break;
817
        case 0x49:
818
            /* SUBL/V */
819
            gen_arith3(ctx, &gen_op_sublv, ra, rb, rc, islit, lit);
820
            break;
821
        case 0x4D:
822
            /* CMPLT */
823
            gen_arith3(ctx, &gen_op_cmplt, ra, rb, rc, islit, lit);
824
            break;
825
        case 0x60:
826
            /* ADDQ/V */
827
            gen_arith3(ctx, &gen_op_addqv, ra, rb, rc, islit, lit);
828
            break;
829
        case 0x69:
830
            /* SUBQ/V */
831
            gen_arith3(ctx, &gen_op_subqv, ra, rb, rc, islit, lit);
832
            break;
833
        case 0x6D:
834
            /* CMPLE */
835
            gen_arith3(ctx, &gen_op_cmple, ra, rb, rc, islit, lit);
836
            break;
837
        default:
838
            goto invalid_opc;
839
        }
840
        break;
841
    case 0x11:
842
        switch (fn7) {
843
        case 0x00:
844
            /* AND */
845
            gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit);
846
            break;
847
        case 0x08:
848
            /* BIC */
849
            gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit);
850
            break;
851
        case 0x14:
852
            /* CMOVLBS */
853
            gen_cmov(ctx, &gen_op_cmplbs, ra, rb, rc, islit, lit);
854
            break;
855
        case 0x16:
856
            /* CMOVLBC */
857
            gen_cmov(ctx, &gen_op_cmplbc, ra, rb, rc, islit, lit);
858
            break;
859
        case 0x20:
860
            /* BIS */
861
            if (ra == rb || ra == 31 || rb == 31) {
862
                if (ra == 31 && rc == 31) {
863
                    /* NOP */
864
                    gen_op_nop();
865
                } else {
866
                    /* MOV */
867
                    gen_load_ir(ctx, rb, 0);
868
                    gen_store_ir(ctx, rc, 0);
869
                }
870
            } else {
871
                gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
872
            }
873
            break;
874
        case 0x24:
875
            /* CMOVEQ */
876
            gen_cmov(ctx, &gen_op_cmpeqz, ra, rb, rc, islit, lit);
877
            break;
878
        case 0x26:
879
            /* CMOVNE */
880
            gen_cmov(ctx, &gen_op_cmpnez, ra, rb, rc, islit, lit);
881
            break;
882
        case 0x28:
883
            /* ORNOT */
884
            gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit);
885
            break;
886
        case 0x40:
887
            /* XOR */
888
            gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit);
889
            break;
890
        case 0x44:
891
            /* CMOVLT */
892
            gen_cmov(ctx, &gen_op_cmpltz, ra, rb, rc, islit, lit);
893
            break;
894
        case 0x46:
895
            /* CMOVGE */
896
            gen_cmov(ctx, &gen_op_cmpgez, ra, rb, rc, islit, lit);
897
            break;
898
        case 0x48:
899
            /* EQV */
900
            gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit);
901
            break;
902
        case 0x61:
903
            /* AMASK */
904
            gen_arith2(ctx, &gen_amask, rb, rc, islit, lit);
905
            break;
906
        case 0x64:
907
            /* CMOVLE */
908
            gen_cmov(ctx, &gen_op_cmplez, ra, rb, rc, islit, lit);
909
            break;
910
        case 0x66:
911
            /* CMOVGT */
912
            gen_cmov(ctx, &gen_op_cmpgtz, ra, rb, rc, islit, lit);
913
            break;
914
        case 0x6C:
915
            /* IMPLVER */
916
            gen_op_load_implver();
917
            gen_store_ir(ctx, rc, 0);
918
            break;
919
        default:
920
            goto invalid_opc;
921
        }
922
        break;
923
    case 0x12:
924
        switch (fn7) {
925
        case 0x02:
926
            /* MSKBL */
927
            gen_arith3(ctx, &gen_op_mskbl, ra, rb, rc, islit, lit);
928
            break;
929
        case 0x06:
930
            /* EXTBL */
931
            gen_arith3(ctx, &gen_op_extbl, ra, rb, rc, islit, lit);
932
            break;
933
        case 0x0B:
934
            /* INSBL */
935
            gen_arith3(ctx, &gen_op_insbl, ra, rb, rc, islit, lit);
936
            break;
937
        case 0x12:
938
            /* MSKWL */
939
            gen_arith3(ctx, &gen_op_mskwl, ra, rb, rc, islit, lit);
940
            break;
941
        case 0x16:
942
            /* EXTWL */
943
            gen_arith3(ctx, &gen_op_extwl, ra, rb, rc, islit, lit);
944
            break;
945
        case 0x1B:
946
            /* INSWL */
947
            gen_arith3(ctx, &gen_op_inswl, ra, rb, rc, islit, lit);
948
            break;
949
        case 0x22:
950
            /* MSKLL */
951
            gen_arith3(ctx, &gen_op_mskll, ra, rb, rc, islit, lit);
952
            break;
953
        case 0x26:
954
            /* EXTLL */
955
            gen_arith3(ctx, &gen_op_extll, ra, rb, rc, islit, lit);
956
            break;
957
        case 0x2B:
958
            /* INSLL */
959
            gen_arith3(ctx, &gen_op_insll, ra, rb, rc, islit, lit);
960
            break;
961
        case 0x30:
962
            /* ZAP */
963
            gen_arith3(ctx, &gen_op_zap, ra, rb, rc, islit, lit);
964
            break;
965
        case 0x31:
966
            /* ZAPNOT */
967
            gen_arith3(ctx, &gen_op_zapnot, ra, rb, rc, islit, lit);
968
            break;
969
        case 0x32:
970
            /* MSKQL */
971
            gen_arith3(ctx, &gen_op_mskql, ra, rb, rc, islit, lit);
972
            break;
973
        case 0x34:
974
            /* SRL */
975
            gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit);
976
            break;
977
        case 0x36:
978
            /* EXTQL */
979
            gen_arith3(ctx, &gen_op_extql, ra, rb, rc, islit, lit);
980
            break;
981
        case 0x39:
982
            /* SLL */
983
            gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit);
984
            break;
985
        case 0x3B:
986
            /* INSQL */
987
            gen_arith3(ctx, &gen_op_insql, ra, rb, rc, islit, lit);
988
            break;
989
        case 0x3C:
990
            /* SRA */
991
            gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit);
992
            break;
993
        case 0x52:
994
            /* MSKWH */
995
            gen_arith3(ctx, &gen_op_mskwh, ra, rb, rc, islit, lit);
996
            break;
997
        case 0x57:
998
            /* INSWH */
999
            gen_arith3(ctx, &gen_op_inswh, ra, rb, rc, islit, lit);
1000
            break;
1001
        case 0x5A:
1002
            /* EXTWH */
1003
            gen_arith3(ctx, &gen_op_extwh, ra, rb, rc, islit, lit);
1004
            break;
1005
        case 0x62:
1006
            /* MSKLH */
1007
            gen_arith3(ctx, &gen_op_msklh, ra, rb, rc, islit, lit);
1008
            break;
1009
        case 0x67:
1010
            /* INSLH */
1011
            gen_arith3(ctx, &gen_op_inslh, ra, rb, rc, islit, lit);
1012
            break;
1013
        case 0x6A:
1014
            /* EXTLH */
1015
            gen_arith3(ctx, &gen_op_extlh, ra, rb, rc, islit, lit);
1016
            break;
1017
        case 0x72:
1018
            /* MSKQH */
1019
            gen_arith3(ctx, &gen_op_mskqh, ra, rb, rc, islit, lit);
1020
            break;
1021
        case 0x77:
1022
            /* INSQH */
1023
            gen_arith3(ctx, &gen_op_insqh, ra, rb, rc, islit, lit);
1024
            break;
1025
        case 0x7A:
1026
            /* EXTQH */
1027
            gen_arith3(ctx, &gen_op_extqh, ra, rb, rc, islit, lit);
1028
            break;
1029
        default:
1030
            goto invalid_opc;
1031
        }
1032
        break;
1033
    case 0x13:
1034
        switch (fn7) {
1035
        case 0x00:
1036
            /* MULL */
1037
            gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit);
1038
            break;
1039
        case 0x20:
1040
            /* MULQ */
1041
            gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit);
1042
            break;
1043
        case 0x30:
1044
            /* UMULH */
1045
            gen_arith3(ctx, &gen_op_umulh, ra, rb, rc, islit, lit);
1046
            break;
1047
        case 0x40:
1048
            /* MULL/V */
1049
            gen_arith3(ctx, &gen_op_mullv, ra, rb, rc, islit, lit);
1050
            break;
1051
        case 0x60:
1052
            /* MULQ/V */
1053
            gen_arith3(ctx, &gen_op_mulqv, ra, rb, rc, islit, lit);
1054
            break;
1055
        default:
1056
            goto invalid_opc;
1057
        }
1058
        break;
1059
    case 0x14:
1060
        switch (fpfn) { /* f11 & 0x3F */
1061
        case 0x04:
1062
            /* ITOFS */
1063
            if (!(ctx->amask & AMASK_FIX))
1064
                goto invalid_opc;
1065
            gen_itf(ctx, &gen_op_itofs, ra, rc);
1066
            break;
1067
        case 0x0A:
1068
            /* SQRTF */
1069
            if (!(ctx->amask & AMASK_FIX))
1070
                goto invalid_opc;
1071
            gen_farith2(ctx, &gen_op_sqrtf, rb, rc);
1072
            break;
1073
        case 0x0B:
1074
            /* SQRTS */
1075
            if (!(ctx->amask & AMASK_FIX))
1076
                goto invalid_opc;
1077
            gen_farith2(ctx, &gen_op_sqrts, rb, rc);
1078
            break;
1079
        case 0x14:
1080
            /* ITOFF */
1081
            if (!(ctx->amask & AMASK_FIX))
1082
                goto invalid_opc;
1083
#if 0 // TODO
1084
            gen_itf(ctx, &gen_op_itoff, ra, rc);
1085
#else
1086
            goto invalid_opc;
1087
#endif
1088
            break;
1089
        case 0x24:
1090
            /* ITOFT */
1091
            if (!(ctx->amask & AMASK_FIX))
1092
                goto invalid_opc;
1093
            gen_itf(ctx, &gen_op_itoft, ra, rc);
1094
            break;
1095
        case 0x2A:
1096
            /* SQRTG */
1097
            if (!(ctx->amask & AMASK_FIX))
1098
                goto invalid_opc;
1099
            gen_farith2(ctx, &gen_op_sqrtg, rb, rc);
1100
            break;
1101
        case 0x02B:
1102
            /* SQRTT */
1103
            if (!(ctx->amask & AMASK_FIX))
1104
                goto invalid_opc;
1105
            gen_farith2(ctx, &gen_op_sqrtt, rb, rc);
1106
            break;
1107
        default:
1108
            goto invalid_opc;
1109
        }
1110
        break;
1111
    case 0x15:
1112
        /* VAX floating point */
1113
        /* XXX: rounding mode and trap are ignored (!) */
1114
        switch (fpfn) { /* f11 & 0x3F */
1115
        case 0x00:
1116
            /* ADDF */
1117
            gen_farith3(ctx, &gen_op_addf, ra, rb, rc);
1118
            break;
1119
        case 0x01:
1120
            /* SUBF */
1121
            gen_farith3(ctx, &gen_op_subf, ra, rb, rc);
1122
            break;
1123
        case 0x02:
1124
            /* MULF */
1125
            gen_farith3(ctx, &gen_op_mulf, ra, rb, rc);
1126
            break;
1127
        case 0x03:
1128
            /* DIVF */
1129
            gen_farith3(ctx, &gen_op_divf, ra, rb, rc);
1130
            break;
1131
        case 0x1E:
1132
            /* CVTDG */
1133
#if 0 // TODO
1134
            gen_farith2(ctx, &gen_op_cvtdg, rb, rc);
1135
#else
1136
            goto invalid_opc;
1137
#endif
1138
            break;
1139
        case 0x20:
1140
            /* ADDG */
1141
            gen_farith3(ctx, &gen_op_addg, ra, rb, rc);
1142
            break;
1143
        case 0x21:
1144
            /* SUBG */
1145
            gen_farith3(ctx, &gen_op_subg, ra, rb, rc);
1146
            break;
1147
        case 0x22:
1148
            /* MULG */
1149
            gen_farith3(ctx, &gen_op_mulg, ra, rb, rc);
1150
            break;
1151
        case 0x23:
1152
            /* DIVG */
1153
            gen_farith3(ctx, &gen_op_divg, ra, rb, rc);
1154
            break;
1155
        case 0x25:
1156
            /* CMPGEQ */
1157
            gen_farith3(ctx, &gen_op_cmpgeq, ra, rb, rc);
1158
            break;
1159
        case 0x26:
1160
            /* CMPGLT */
1161
            gen_farith3(ctx, &gen_op_cmpglt, ra, rb, rc);
1162
            break;
1163
        case 0x27:
1164
            /* CMPGLE */
1165
            gen_farith3(ctx, &gen_op_cmpgle, ra, rb, rc);
1166
            break;
1167
        case 0x2C:
1168
            /* CVTGF */
1169
            gen_farith2(ctx, &gen_op_cvtgf, rb, rc);
1170
            break;
1171
        case 0x2D:
1172
            /* CVTGD */
1173
#if 0 // TODO
1174
            gen_farith2(ctx, &gen_op_cvtgd, rb, rc);
1175
#else
1176
            goto invalid_opc;
1177
#endif
1178
            break;
1179
        case 0x2F:
1180
            /* CVTGQ */
1181
            gen_farith2(ctx, &gen_op_cvtgq, rb, rc);
1182
            break;
1183
        case 0x3C:
1184
            /* CVTQF */
1185
            gen_farith2(ctx, &gen_op_cvtqf, rb, rc);
1186
            break;
1187
        case 0x3E:
1188
            /* CVTQG */
1189
            gen_farith2(ctx, &gen_op_cvtqg, rb, rc);
1190
            break;
1191
        default:
1192
            goto invalid_opc;
1193
        }
1194
        break;
1195
    case 0x16:
1196
        /* IEEE floating-point */
1197
        /* XXX: rounding mode and traps are ignored (!) */
1198
        switch (fpfn) { /* f11 & 0x3F */
1199
        case 0x00:
1200
            /* ADDS */
1201
            gen_farith3(ctx, &gen_op_adds, ra, rb, rc);
1202
            break;
1203
        case 0x01:
1204
            /* SUBS */
1205
            gen_farith3(ctx, &gen_op_subs, ra, rb, rc);
1206
            break;
1207
        case 0x02:
1208
            /* MULS */
1209
            gen_farith3(ctx, &gen_op_muls, ra, rb, rc);
1210
            break;
1211
        case 0x03:
1212
            /* DIVS */
1213
            gen_farith3(ctx, &gen_op_divs, ra, rb, rc);
1214
            break;
1215
        case 0x20:
1216
            /* ADDT */
1217
            gen_farith3(ctx, &gen_op_addt, ra, rb, rc);
1218
            break;
1219
        case 0x21:
1220
            /* SUBT */
1221
            gen_farith3(ctx, &gen_op_subt, ra, rb, rc);
1222
            break;
1223
        case 0x22:
1224
            /* MULT */
1225
            gen_farith3(ctx, &gen_op_mult, ra, rb, rc);
1226
            break;
1227
        case 0x23:
1228
            /* DIVT */
1229
            gen_farith3(ctx, &gen_op_divt, ra, rb, rc);
1230
            break;
1231
        case 0x24:
1232
            /* CMPTUN */
1233
            gen_farith3(ctx, &gen_op_cmptun, ra, rb, rc);
1234
            break;
1235
        case 0x25:
1236
            /* CMPTEQ */
1237
            gen_farith3(ctx, &gen_op_cmpteq, ra, rb, rc);
1238
            break;
1239
        case 0x26:
1240
            /* CMPTLT */
1241
            gen_farith3(ctx, &gen_op_cmptlt, ra, rb, rc);
1242
            break;
1243
        case 0x27:
1244
            /* CMPTLE */
1245
            gen_farith3(ctx, &gen_op_cmptle, ra, rb, rc);
1246
            break;
1247
        case 0x2C:
1248
            /* XXX: incorrect */
1249
            if (fn11 == 0x2AC) {
1250
                /* CVTST */
1251
                gen_farith2(ctx, &gen_op_cvtst, rb, rc);
1252
            } else {
1253
                /* CVTTS */
1254
                gen_farith2(ctx, &gen_op_cvtts, rb, rc);
1255
            }
1256
            break;
1257
        case 0x2F:
1258
            /* CVTTQ */
1259
            gen_farith2(ctx, &gen_op_cvttq, rb, rc);
1260
            break;
1261
        case 0x3C:
1262
            /* CVTQS */
1263
            gen_farith2(ctx, &gen_op_cvtqs, rb, rc);
1264
            break;
1265
        case 0x3E:
1266
            /* CVTQT */
1267
            gen_farith2(ctx, &gen_op_cvtqt, rb, rc);
1268
            break;
1269
        default:
1270
            goto invalid_opc;
1271
        }
1272
        break;
1273
    case 0x17:
1274
        switch (fn11) {
1275
        case 0x010:
1276
            /* CVTLQ */
1277
            gen_farith2(ctx, &gen_op_cvtlq, rb, rc);
1278
            break;
1279
        case 0x020:
1280
            /* CPYS */
1281
            if (ra == rb) {
1282
                if (ra == 31 && rc == 31) {
1283
                    /* FNOP */
1284
                    gen_op_nop();
1285
                } else {
1286
                    /* FMOV */
1287
                    gen_load_fir(ctx, rb, 0);
1288
                    gen_store_fir(ctx, rc, 0);
1289
                }
1290
            } else {
1291
                gen_farith3(ctx, &gen_op_cpys, ra, rb, rc);
1292
            }
1293
            break;
1294
        case 0x021:
1295
            /* CPYSN */
1296
            gen_farith2(ctx, &gen_op_cpysn, rb, rc);
1297
            break;
1298
        case 0x022:
1299
            /* CPYSE */
1300
            gen_farith2(ctx, &gen_op_cpyse, rb, rc);
1301
            break;
1302
        case 0x024:
1303
            /* MT_FPCR */
1304
            gen_load_fir(ctx, ra, 0);
1305
            gen_op_store_fpcr();
1306
            break;
1307
        case 0x025:
1308
            /* MF_FPCR */
1309
            gen_op_load_fpcr();
1310
            gen_store_fir(ctx, ra, 0);
1311
            break;
1312
        case 0x02A:
1313
            /* FCMOVEQ */
1314
            gen_fcmov(ctx, &gen_op_cmpfeq, ra, rb, rc);
1315
            break;
1316
        case 0x02B:
1317
            /* FCMOVNE */
1318
            gen_fcmov(ctx, &gen_op_cmpfne, ra, rb, rc);
1319
            break;
1320
        case 0x02C:
1321
            /* FCMOVLT */
1322
            gen_fcmov(ctx, &gen_op_cmpflt, ra, rb, rc);
1323
            break;
1324
        case 0x02D:
1325
            /* FCMOVGE */
1326
            gen_fcmov(ctx, &gen_op_cmpfge, ra, rb, rc);
1327
            break;
1328
        case 0x02E:
1329
            /* FCMOVLE */
1330
            gen_fcmov(ctx, &gen_op_cmpfle, ra, rb, rc);
1331
            break;
1332
        case 0x02F:
1333
            /* FCMOVGT */
1334
            gen_fcmov(ctx, &gen_op_cmpfgt, ra, rb, rc);
1335
            break;
1336
        case 0x030:
1337
            /* CVTQL */
1338
            gen_farith2(ctx, &gen_op_cvtql, rb, rc);
1339
            break;
1340
        case 0x130:
1341
            /* CVTQL/V */
1342
            gen_farith2(ctx, &gen_op_cvtqlv, rb, rc);
1343
            break;
1344
        case 0x530:
1345
            /* CVTQL/SV */
1346
            gen_farith2(ctx, &gen_op_cvtqlsv, rb, rc);
1347
            break;
1348
        default:
1349
            goto invalid_opc;
1350
        }
1351
        break;
1352
    case 0x18:
1353
        switch ((uint16_t)disp16) {
1354
        case 0x0000:
1355
            /* TRAPB */
1356
            /* No-op. Just exit from the current tb */
1357
            ret = 2;
1358
            break;
1359
        case 0x0400:
1360
            /* EXCB */
1361
            /* No-op. Just exit from the current tb */
1362
            ret = 2;
1363
            break;
1364
        case 0x4000:
1365
            /* MB */
1366
            /* No-op */
1367
            break;
1368
        case 0x4400:
1369
            /* WMB */
1370
            /* No-op */
1371
            break;
1372
        case 0x8000:
1373
            /* FETCH */
1374
            /* No-op */
1375
            break;
1376
        case 0xA000:
1377
            /* FETCH_M */
1378
            /* No-op */
1379
            break;
1380
        case 0xC000:
1381
            /* RPCC */
1382
            gen_op_load_pcc();
1383
            gen_store_ir(ctx, ra, 0);
1384
            break;
1385
        case 0xE000:
1386
            /* RC */
1387
            gen_op_load_irf();
1388
            gen_store_ir(ctx, ra, 0);
1389
            gen_op_clear_irf();
1390
            break;
1391
        case 0xE800:
1392
            /* ECB */
1393
            /* XXX: TODO: evict tb cache at address rb */
1394
#if 0
1395
            ret = 2;
1396
#else
1397
            goto invalid_opc;
1398
#endif
1399
            break;
1400
        case 0xF000:
1401
            /* RS */
1402
            gen_op_load_irf();
1403
            gen_store_ir(ctx, ra, 0);
1404
            gen_op_set_irf();
1405
            break;
1406
        case 0xF800:
1407
            /* WH64 */
1408
            /* No-op */
1409
            break;
1410
        default:
1411
            goto invalid_opc;
1412
        }
1413
        break;
1414
    case 0x19:
1415
        /* HW_MFPR (PALcode) */
1416
#if defined (CONFIG_USER_ONLY)
1417
        goto invalid_opc;
1418
#else
1419
        if (!ctx->pal_mode)
1420
            goto invalid_opc;
1421
        gen_op_mfpr(insn & 0xFF);
1422
        gen_store_ir(ctx, ra, 0);
1423
        break;
1424
#endif
1425
    case 0x1A:
1426
        gen_load_ir(ctx, rb, 0);
1427
        if (ra != 31) {
1428
            gen_set_uT1(ctx, ctx->pc);
1429
            gen_store_ir(ctx, ra, 1);
1430
        }
1431
        gen_op_branch();
1432
        /* Those four jumps only differ by the branch prediction hint */
1433
        switch (fn2) {
1434
        case 0x0:
1435
            /* JMP */
1436
            break;
1437
        case 0x1:
1438
            /* JSR */
1439
            break;
1440
        case 0x2:
1441
            /* RET */
1442
            break;
1443
        case 0x3:
1444
            /* JSR_COROUTINE */
1445
            break;
1446
        }
1447
        ret = 1;
1448
        break;
1449
    case 0x1B:
1450
        /* HW_LD (PALcode) */
1451
#if defined (CONFIG_USER_ONLY)
1452
        goto invalid_opc;
1453
#else
1454
        if (!ctx->pal_mode)
1455
            goto invalid_opc;
1456
        gen_load_ir(ctx, rb, 0);
1457
        gen_set_sT1(ctx, disp12);
1458
        gen_op_addq();
1459
        switch ((insn >> 12) & 0xF) {
1460
        case 0x0:
1461
            /* Longword physical access */
1462
            gen_op_ldl_raw();
1463
            break;
1464
        case 0x1:
1465
            /* Quadword physical access */
1466
            gen_op_ldq_raw();
1467
            break;
1468
        case 0x2:
1469
            /* Longword physical access with lock */
1470
            gen_op_ldl_l_raw();
1471
            break;
1472
        case 0x3:
1473
            /* Quadword physical access with lock */
1474
            gen_op_ldq_l_raw();
1475
            break;
1476
        case 0x4:
1477
            /* Longword virtual PTE fetch */
1478
            gen_op_ldl_kernel();
1479
            break;
1480
        case 0x5:
1481
            /* Quadword virtual PTE fetch */
1482
            gen_op_ldq_kernel();
1483
            break;
1484
        case 0x6:
1485
            /* Invalid */
1486
            goto invalid_opc;
1487
        case 0x7:
1488
            /* Invalid */
1489
            goto invalid_opc;
1490
        case 0x8:
1491
            /* Longword virtual access */
1492
            gen_op_ld_phys_to_virt();
1493
            gen_op_ldl_raw();
1494
            break;
1495
        case 0x9:
1496
            /* Quadword virtual access */
1497
            gen_op_ld_phys_to_virt();
1498
            gen_op_ldq_raw();
1499
            break;
1500
        case 0xA:
1501
            /* Longword virtual access with protection check */
1502
            gen_ldl(ctx);
1503
            break;
1504
        case 0xB:
1505
            /* Quadword virtual access with protection check */
1506
            gen_ldq(ctx);
1507
            break;
1508
        case 0xC:
1509
            /* Longword virtual access with altenate access mode */
1510
            gen_op_set_alt_mode();
1511
            gen_op_ld_phys_to_virt();
1512
            gen_op_ldl_raw();
1513
            gen_op_restore_mode();
1514
            break;
1515
        case 0xD:
1516
            /* Quadword virtual access with altenate access mode */
1517
            gen_op_set_alt_mode();
1518
            gen_op_ld_phys_to_virt();
1519
            gen_op_ldq_raw();
1520
            gen_op_restore_mode();
1521
            break;
1522
        case 0xE:
1523
            /* Longword virtual access with alternate access mode and
1524
             * protection checks
1525
             */
1526
            gen_op_set_alt_mode();
1527
            gen_op_ldl_data();
1528
            gen_op_restore_mode();
1529
            break;
1530
        case 0xF:
1531
            /* Quadword virtual access with alternate access mode and
1532
             * protection checks
1533
             */
1534
            gen_op_set_alt_mode();
1535
            gen_op_ldq_data();
1536
            gen_op_restore_mode();
1537
            break;
1538
        }
1539
        gen_store_ir(ctx, ra, 1);
1540
        break;
1541
#endif
1542
    case 0x1C:
1543
        switch (fn7) {
1544
        case 0x00:
1545
            /* SEXTB */
1546
            if (!(ctx->amask & AMASK_BWX))
1547
                goto invalid_opc;
1548
            gen_arith2(ctx, &gen_op_sextb, rb, rc, islit, lit);
1549
            break;
1550
        case 0x01:
1551
            /* SEXTW */
1552
            if (!(ctx->amask & AMASK_BWX))
1553
                goto invalid_opc;
1554
            gen_arith2(ctx, &gen_op_sextw, rb, rc, islit, lit);
1555
            break;
1556
        case 0x30:
1557
            /* CTPOP */
1558
            if (!(ctx->amask & AMASK_CIX))
1559
                goto invalid_opc;
1560
            gen_arith2(ctx, &gen_op_ctpop, rb, rc, 0, 0);
1561
            break;
1562
        case 0x31:
1563
            /* PERR */
1564
            if (!(ctx->amask & AMASK_MVI))
1565
                goto invalid_opc;
1566
            /* XXX: TODO */
1567
            goto invalid_opc;
1568
            break;
1569
        case 0x32:
1570
            /* CTLZ */
1571
            if (!(ctx->amask & AMASK_CIX))
1572
                goto invalid_opc;
1573
            gen_arith2(ctx, &gen_op_ctlz, rb, rc, 0, 0);
1574
            break;
1575
        case 0x33:
1576
            /* CTTZ */
1577
            if (!(ctx->amask & AMASK_CIX))
1578
                goto invalid_opc;
1579
            gen_arith2(ctx, &gen_op_cttz, rb, rc, 0, 0);
1580
            break;
1581
        case 0x34:
1582
            /* UNPKBW */
1583
            if (!(ctx->amask & AMASK_MVI))
1584
                goto invalid_opc;
1585
            /* XXX: TODO */
1586
            goto invalid_opc;
1587
            break;
1588
        case 0x35:
1589
            /* UNPKWL */
1590
            if (!(ctx->amask & AMASK_MVI))
1591
                goto invalid_opc;
1592
            /* XXX: TODO */
1593
            goto invalid_opc;
1594
            break;
1595
        case 0x36:
1596
            /* PKWB */
1597
            if (!(ctx->amask & AMASK_MVI))
1598
                goto invalid_opc;
1599
            /* XXX: TODO */
1600
            goto invalid_opc;
1601
            break;
1602
        case 0x37:
1603
            /* PKLB */
1604
            if (!(ctx->amask & AMASK_MVI))
1605
                goto invalid_opc;
1606
            /* XXX: TODO */
1607
            goto invalid_opc;
1608
            break;
1609
        case 0x38:
1610
            /* MINSB8 */
1611
            if (!(ctx->amask & AMASK_MVI))
1612
                goto invalid_opc;
1613
            /* XXX: TODO */
1614
            goto invalid_opc;
1615
            break;
1616
        case 0x39:
1617
            /* MINSW4 */
1618
            if (!(ctx->amask & AMASK_MVI))
1619
                goto invalid_opc;
1620
            /* XXX: TODO */
1621
            goto invalid_opc;
1622
            break;
1623
        case 0x3A:
1624
            /* MINUB8 */
1625
            if (!(ctx->amask & AMASK_MVI))
1626
                goto invalid_opc;
1627
            /* XXX: TODO */
1628
            goto invalid_opc;
1629
            break;
1630
        case 0x3B:
1631
            /* MINUW4 */
1632
            if (!(ctx->amask & AMASK_MVI))
1633
                goto invalid_opc;
1634
            /* XXX: TODO */
1635
            goto invalid_opc;
1636
            break;
1637
        case 0x3C:
1638
            /* MAXUB8 */
1639
            if (!(ctx->amask & AMASK_MVI))
1640
                goto invalid_opc;
1641
            /* XXX: TODO */
1642
            goto invalid_opc;
1643
            break;
1644
        case 0x3D:
1645
            /* MAXUW4 */
1646
            if (!(ctx->amask & AMASK_MVI))
1647
                goto invalid_opc;
1648
            /* XXX: TODO */
1649
            goto invalid_opc;
1650
            break;
1651
        case 0x3E:
1652
            /* MAXSB8 */
1653
            if (!(ctx->amask & AMASK_MVI))
1654
                goto invalid_opc;
1655
            /* XXX: TODO */
1656
            goto invalid_opc;
1657
            break;
1658
        case 0x3F:
1659
            /* MAXSW4 */
1660
            if (!(ctx->amask & AMASK_MVI))
1661
                goto invalid_opc;
1662
            /* XXX: TODO */
1663
            goto invalid_opc;
1664
            break;
1665
        case 0x70:
1666
            /* FTOIT */
1667
            if (!(ctx->amask & AMASK_FIX))
1668
                goto invalid_opc;
1669
            gen_fti(ctx, &gen_op_ftoit, ra, rb);
1670
            break;
1671
        case 0x78:
1672
            /* FTOIS */
1673
            if (!(ctx->amask & AMASK_FIX))
1674
                goto invalid_opc;
1675
            gen_fti(ctx, &gen_op_ftois, ra, rb);
1676
            break;
1677
        default:
1678
            goto invalid_opc;
1679
        }
1680
        break;
1681
    case 0x1D:
1682
        /* HW_MTPR (PALcode) */
1683
#if defined (CONFIG_USER_ONLY)
1684
        goto invalid_opc;
1685
#else
1686
        if (!ctx->pal_mode)
1687
            goto invalid_opc;
1688
        gen_load_ir(ctx, ra, 0);
1689
        gen_op_mtpr(insn & 0xFF);
1690
        ret = 2;
1691
        break;
1692
#endif
1693
    case 0x1E:
1694
        /* HW_REI (PALcode) */
1695
#if defined (CONFIG_USER_ONLY)
1696
        goto invalid_opc;
1697
#else
1698
        if (!ctx->pal_mode)
1699
            goto invalid_opc;
1700
        if (rb == 31) {
1701
            /* "Old" alpha */
1702
            gen_op_hw_rei();
1703
        } else {
1704
            gen_load_ir(ctx, rb, 0);
1705
            gen_set_uT1(ctx, (((int64_t)insn << 51) >> 51));
1706
            gen_op_addq();
1707
            gen_op_hw_ret();
1708
        }
1709
        ret = 2;
1710
        break;
1711
#endif
1712
    case 0x1F:
1713
        /* HW_ST (PALcode) */
1714
#if defined (CONFIG_USER_ONLY)
1715
        goto invalid_opc;
1716
#else
1717
        if (!ctx->pal_mode)
1718
            goto invalid_opc;
1719
        gen_load_ir(ctx, rb, 0);
1720
        gen_set_sT1(ctx, disp12);
1721
        gen_op_addq();
1722
        gen_load_ir(ctx, ra, 1);
1723
        switch ((insn >> 12) & 0xF) {
1724
        case 0x0:
1725
            /* Longword physical access */
1726
            gen_op_stl_raw();
1727
            break;
1728
        case 0x1:
1729
            /* Quadword physical access */
1730
            gen_op_stq_raw();
1731
            break;
1732
        case 0x2:
1733
            /* Longword physical access with lock */
1734
            gen_op_stl_c_raw();
1735
            break;
1736
        case 0x3:
1737
            /* Quadword physical access with lock */
1738
            gen_op_stq_c_raw();
1739
            break;
1740
        case 0x4:
1741
            /* Longword virtual access */
1742
            gen_op_st_phys_to_virt();
1743
            gen_op_stl_raw();
1744
            break;
1745
        case 0x5:
1746
            /* Quadword virtual access */
1747
            gen_op_st_phys_to_virt();
1748
            gen_op_stq_raw();
1749
            break;
1750
        case 0x6:
1751
            /* Invalid */
1752
            goto invalid_opc;
1753
        case 0x7:
1754
            /* Invalid */
1755
            goto invalid_opc;
1756
        case 0x8:
1757
            /* Invalid */
1758
            goto invalid_opc;
1759
        case 0x9:
1760
            /* Invalid */
1761
            goto invalid_opc;
1762
        case 0xA:
1763
            /* Invalid */
1764
            goto invalid_opc;
1765
        case 0xB:
1766
            /* Invalid */
1767
            goto invalid_opc;
1768
        case 0xC:
1769
            /* Longword virtual access with alternate access mode */
1770
            gen_op_set_alt_mode();
1771
            gen_op_st_phys_to_virt();
1772
            gen_op_ldl_raw();
1773
            gen_op_restore_mode();
1774
            break;
1775
        case 0xD:
1776
            /* Quadword virtual access with alternate access mode */
1777
            gen_op_set_alt_mode();
1778
            gen_op_st_phys_to_virt();
1779
            gen_op_ldq_raw();
1780
            gen_op_restore_mode();
1781
            break;
1782
        case 0xE:
1783
            /* Invalid */
1784
            goto invalid_opc;
1785
        case 0xF:
1786
            /* Invalid */
1787
            goto invalid_opc;
1788
        }
1789
        ret = 2;
1790
        break;
1791
#endif
1792
    case 0x20:
1793
        /* LDF */
1794
#if 0 // TODO
1795
        gen_load_fmem(ctx, &gen_ldf, ra, rb, disp16);
1796
#else
1797
        goto invalid_opc;
1798
#endif
1799
        break;
1800
    case 0x21:
1801
        /* LDG */
1802
#if 0 // TODO
1803
        gen_load_fmem(ctx, &gen_ldg, ra, rb, disp16);
1804
#else
1805
        goto invalid_opc;
1806
#endif
1807
        break;
1808
    case 0x22:
1809
        /* LDS */
1810
        gen_load_fmem(ctx, &gen_lds, ra, rb, disp16);
1811
        break;
1812
    case 0x23:
1813
        /* LDT */
1814
        gen_load_fmem(ctx, &gen_ldt, ra, rb, disp16);
1815
        break;
1816
    case 0x24:
1817
        /* STF */
1818
#if 0 // TODO
1819
        gen_store_fmem(ctx, &gen_stf, ra, rb, disp16);
1820
#else
1821
        goto invalid_opc;
1822
#endif
1823
        break;
1824
    case 0x25:
1825
        /* STG */
1826
#if 0 // TODO
1827
        gen_store_fmem(ctx, &gen_stg, ra, rb, disp16);
1828
#else
1829
        goto invalid_opc;
1830
#endif
1831
        break;
1832
    case 0x26:
1833
        /* STS */
1834
        gen_store_fmem(ctx, &gen_sts, ra, rb, disp16);
1835
        break;
1836
    case 0x27:
1837
        /* STT */
1838
        gen_store_fmem(ctx, &gen_stt, ra, rb, disp16);
1839
        break;
1840
    case 0x28:
1841
        /* LDL */
1842
        gen_load_mem(ctx, &gen_ldl, ra, rb, disp16, 0);
1843
        break;
1844
    case 0x29:
1845
        /* LDQ */
1846
        gen_load_mem(ctx, &gen_ldq, ra, rb, disp16, 0);
1847
        break;
1848
    case 0x2A:
1849
        /* LDL_L */
1850
        gen_load_mem(ctx, &gen_ldl_l, ra, rb, disp16, 0);
1851
        break;
1852
    case 0x2B:
1853
        /* LDQ_L */
1854
        gen_load_mem(ctx, &gen_ldq_l, ra, rb, disp16, 0);
1855
        break;
1856
    case 0x2C:
1857
        /* STL */
1858
        gen_store_mem(ctx, &gen_stl, ra, rb, disp16, 0);
1859
        break;
1860
    case 0x2D:
1861
        /* STQ */
1862
        gen_store_mem(ctx, &gen_stq, ra, rb, disp16, 0);
1863
        break;
1864
    case 0x2E:
1865
        /* STL_C */
1866
        gen_store_mem(ctx, &gen_stl_c, ra, rb, disp16, 0);
1867
        break;
1868
    case 0x2F:
1869
        /* STQ_C */
1870
        gen_store_mem(ctx, &gen_stq_c, ra, rb, disp16, 0);
1871
        break;
1872
    case 0x30:
1873
        /* BR */
1874
        gen_set_uT0(ctx, ctx->pc);
1875
        gen_store_ir(ctx, ra, 0);
1876
        if (disp21 != 0) {
1877
            gen_set_sT1(ctx, disp21 << 2);
1878
            gen_op_addq();
1879
        }
1880
        gen_op_branch();
1881
        ret = 1;
1882
        break;
1883
    case 0x31:
1884
        /* FBEQ */
1885
        gen_fbcond(ctx, &gen_op_cmpfeq, ra, disp16);
1886
        ret = 1;
1887
        break;
1888
    case 0x32:
1889
        /* FBLT */
1890
        gen_fbcond(ctx, &gen_op_cmpflt, ra, disp16);
1891
        ret = 1;
1892
        break;
1893
    case 0x33:
1894
        /* FBLE */
1895
        gen_fbcond(ctx, &gen_op_cmpfle, ra, disp16);
1896
        ret = 1;
1897
        break;
1898
    case 0x34:
1899
        /* BSR */
1900
        gen_set_uT0(ctx, ctx->pc);
1901
        gen_store_ir(ctx, ra, 0);
1902
        if (disp21 != 0) {
1903
            gen_set_sT1(ctx, disp21 << 2);
1904
            gen_op_addq();
1905
        }
1906
        gen_op_branch();
1907
        ret = 1;
1908
        break;
1909
    case 0x35:
1910
        /* FBNE */
1911
        gen_fbcond(ctx, &gen_op_cmpfne, ra, disp16);
1912
        ret = 1;
1913
        break;
1914
    case 0x36:
1915
        /* FBGE */
1916
        gen_fbcond(ctx, &gen_op_cmpfge, ra, disp16);
1917
        ret = 1;
1918
        break;
1919
    case 0x37:
1920
        /* FBGT */
1921
        gen_fbcond(ctx, &gen_op_cmpfgt, ra, disp16);
1922
        ret = 1;
1923
        break;
1924
    case 0x38:
1925
        /* BLBC */
1926
        gen_bcond(ctx, &gen_op_cmplbc, ra, disp16);
1927
        ret = 1;
1928
        break;
1929
    case 0x39:
1930
        /* BEQ */
1931
        gen_bcond(ctx, &gen_op_cmpeqz, ra, disp16);
1932
        ret = 1;
1933
        break;
1934
    case 0x3A:
1935
        /* BLT */
1936
        gen_bcond(ctx, &gen_op_cmpltz, ra, disp16);
1937
        ret = 1;
1938
        break;
1939
    case 0x3B:
1940
        /* BLE */
1941
        gen_bcond(ctx, &gen_op_cmplez, ra, disp16);
1942
        ret = 1;
1943
        break;
1944
    case 0x3C:
1945
        /* BLBS */
1946
        gen_bcond(ctx, &gen_op_cmplbs, ra, disp16);
1947
        ret = 1;
1948
        break;
1949
    case 0x3D:
1950
        /* BNE */
1951
        gen_bcond(ctx, &gen_op_cmpnez, ra, disp16);
1952
        ret = 1;
1953
        break;
1954
    case 0x3E:
1955
        /* BGE */
1956
        gen_bcond(ctx, &gen_op_cmpgez, ra, disp16);
1957
        ret = 1;
1958
        break;
1959
    case 0x3F:
1960
        /* BGT */
1961
        gen_bcond(ctx, &gen_op_cmpgtz, ra, disp16);
1962
        ret = 1;
1963
        break;
1964
    invalid_opc:
1965
        gen_invalid(ctx);
1966
        ret = 3;
1967
        break;
1968
    }
1969

    
1970
    return ret;
1971
}
1972

    
1973
static always_inline int gen_intermediate_code_internal (CPUState *env,
1974
                                                         TranslationBlock *tb,
1975
                                                         int search_pc)
1976
{
1977
#if defined ALPHA_DEBUG_DISAS
1978
    static int insn_count;
1979
#endif
1980
    DisasContext ctx, *ctxp = &ctx;
1981
    target_ulong pc_start;
1982
    uint32_t insn;
1983
    uint16_t *gen_opc_end;
1984
    int j, lj = -1;
1985
    int ret;
1986
    int num_insns;
1987
    int max_insns;
1988

    
1989
    pc_start = tb->pc;
1990
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1991
    ctx.pc = pc_start;
1992
    ctx.amask = env->amask;
1993
#if defined (CONFIG_USER_ONLY)
1994
    ctx.mem_idx = 0;
1995
#else
1996
    ctx.mem_idx = ((env->ps >> 3) & 3);
1997
    ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
1998
#endif
1999
    num_insns = 0;
2000
    max_insns = tb->cflags & CF_COUNT_MASK;
2001
    if (max_insns == 0)
2002
        max_insns = CF_COUNT_MASK;
2003

    
2004
    gen_icount_start();
2005
    for (ret = 0; ret == 0;) {
2006
        if (env->nb_breakpoints > 0) {
2007
            for(j = 0; j < env->nb_breakpoints; j++) {
2008
                if (env->breakpoints[j] == ctx.pc) {
2009
                    gen_excp(&ctx, EXCP_DEBUG, 0);
2010
                    break;
2011
                }
2012
            }
2013
        }
2014
        if (search_pc) {
2015
            j = gen_opc_ptr - gen_opc_buf;
2016
            if (lj < j) {
2017
                lj++;
2018
                while (lj < j)
2019
                    gen_opc_instr_start[lj++] = 0;
2020
                gen_opc_pc[lj] = ctx.pc;
2021
                gen_opc_instr_start[lj] = 1;
2022
                gen_opc_icount[lj] = num_insns;
2023
            }
2024
        }
2025
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
2026
            gen_io_start();
2027
#if defined ALPHA_DEBUG_DISAS
2028
        insn_count++;
2029
        if (logfile != NULL) {
2030
            fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2031
                    ctx.pc, ctx.mem_idx);
2032
        }
2033
#endif
2034
        insn = ldl_code(ctx.pc);
2035
#if defined ALPHA_DEBUG_DISAS
2036
        insn_count++;
2037
        if (logfile != NULL) {
2038
            fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2039
        }
2040
#endif
2041
        num_insns++;
2042
        ctx.pc += 4;
2043
        ret = translate_one(ctxp, insn);
2044
        if (ret != 0)
2045
            break;
2046
        /* if we reach a page boundary or are single stepping, stop
2047
         * generation
2048
         */
2049
        if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2050
            (env->singlestep_enabled) ||
2051
            num_insns >= max_insns) {
2052
            break;
2053
        }
2054
#if defined (DO_SINGLE_STEP)
2055
        break;
2056
#endif
2057
    }
2058
    if (ret != 1 && ret != 3) {
2059
        gen_update_pc(&ctx);
2060
    }
2061
#if defined (DO_TB_FLUSH)
2062
    gen_op_tb_flush();
2063
#endif
2064
    if (tb->cflags & CF_LAST_IO)
2065
        gen_io_end();
2066
    /* Generate the return instruction */
2067
    tcg_gen_exit_tb(0);
2068
    gen_icount_end(tb, num_insns);
2069
    *gen_opc_ptr = INDEX_op_end;
2070
    if (search_pc) {
2071
        j = gen_opc_ptr - gen_opc_buf;
2072
        lj++;
2073
        while (lj <= j)
2074
            gen_opc_instr_start[lj++] = 0;
2075
    } else {
2076
        tb->size = ctx.pc - pc_start;
2077
        tb->icount = num_insns;
2078
    }
2079
#if defined ALPHA_DEBUG_DISAS
2080
    if (loglevel & CPU_LOG_TB_CPU) {
2081
        cpu_dump_state(env, logfile, fprintf, 0);
2082
    }
2083
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2084
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2085
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
2086
        fprintf(logfile, "\n");
2087
    }
2088
#endif
2089

    
2090
    return 0;
2091
}
2092

    
2093
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2094
{
2095
    return gen_intermediate_code_internal(env, tb, 0);
2096
}
2097

    
2098
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2099
{
2100
    return gen_intermediate_code_internal(env, tb, 1);
2101
}
2102

    
2103
CPUAlphaState * cpu_alpha_init (const char *cpu_model)
2104
{
2105
    CPUAlphaState *env;
2106
    uint64_t hwpcb;
2107

    
2108
    env = qemu_mallocz(sizeof(CPUAlphaState));
2109
    if (!env)
2110
        return NULL;
2111
    cpu_exec_init(env);
2112
    alpha_translate_init();
2113
    tlb_flush(env, 1);
2114
    /* XXX: should not be hardcoded */
2115
    env->implver = IMPLVER_2106x;
2116
    env->ps = 0x1F00;
2117
#if defined (CONFIG_USER_ONLY)
2118
    env->ps |= 1 << 3;
2119
#endif
2120
    pal_init(env);
2121
    /* Initialize IPR */
2122
    hwpcb = env->ipr[IPR_PCBB];
2123
    env->ipr[IPR_ASN] = 0;
2124
    env->ipr[IPR_ASTEN] = 0;
2125
    env->ipr[IPR_ASTSR] = 0;
2126
    env->ipr[IPR_DATFX] = 0;
2127
    /* XXX: fix this */
2128
    //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2129
    //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2130
    //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2131
    //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2132
    env->ipr[IPR_FEN] = 0;
2133
    env->ipr[IPR_IPL] = 31;
2134
    env->ipr[IPR_MCES] = 0;
2135
    env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2136
    //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2137
    env->ipr[IPR_SISR] = 0;
2138
    env->ipr[IPR_VIRBND] = -1ULL;
2139

    
2140
    return env;
2141
}
2142

    
2143
void gen_pc_load(CPUState *env, TranslationBlock *tb,
2144
                unsigned long searched_pc, int pc_pos, void *puc)
2145
{
2146
    env->pc = gen_opc_pc[pc_pos];
2147
}