Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ f071b4d3

History | View | Annotate | Download (57.9 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

    
29
#define DO_SINGLE_STEP
30
#define GENERATE_NOP
31
#define ALPHA_DEBUG_DISAS
32
#define DO_TB_FLUSH
33

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

    
44
#ifdef USE_DIRECT_JUMP
45
#define TBPARAM(x)
46
#else
47
#define TBPARAM(x) (long)(x)
48
#endif
49

    
50
enum {
51
#define DEF(s, n, copy_size) INDEX_op_ ## s,
52
#include "opc.h"
53
#undef DEF
54
    NB_OPS,
55
};
56

    
57
static uint16_t *gen_opc_ptr;
58
static uint32_t *gen_opparam_ptr;
59

    
60
#include "gen-op.h"
61

    
62
static always_inline void gen_op_nop (void)
63
{
64
#if defined(GENERATE_NOP)
65
    gen_op_no_op();
66
#endif
67
}
68

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

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

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

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

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

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

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

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

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

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

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

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

    
246
#if defined(__i386__) || defined(__x86_64__)
247
static always_inline void gen_op_set_s16_T0 (int16_t imm)
248
{
249
    gen_op_set_s32_T0((int32_t)imm);
250
}
251

    
252
static always_inline void gen_op_set_s16_T1 (int16_t imm)
253
{
254
    gen_op_set_s32_T1((int32_t)imm);
255
}
256

    
257
static always_inline void gen_op_set_u16_T0 (uint16_t imm)
258
{
259
    gen_op_set_s32_T0((uint32_t)imm);
260
}
261

    
262
static always_inline void gen_op_set_u16_T1 (uint16_t imm)
263
{
264
    gen_op_set_s32_T1((uint32_t)imm);
265
}
266
#endif
267

    
268
static always_inline void gen_set_sT0 (DisasContext *ctx, int64_t imm)
269
{
270
    int32_t imm32;
271
    int16_t imm16;
272

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

    
294
static always_inline void gen_set_sT1 (DisasContext *ctx, int64_t imm)
295
{
296
    int32_t imm32;
297
    int16_t imm16;
298

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

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

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

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

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

    
382
static always_inline void gen_excp (DisasContext *ctx,
383
                                    int exception, int error_code)
384
{
385
    gen_update_pc(ctx);
386
    gen_op_excp(exception, error_code);
387
}
388

    
389
static always_inline void gen_invalid (DisasContext *ctx)
390
{
391
    gen_excp(ctx, EXCP_OPCDEC, 0);
392
}
393

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
576
static always_inline void gen_s4addl (void)
577
{
578
    gen_op_s4();
579
    gen_op_addl();
580
}
581

    
582
static always_inline void gen_s4subl (void)
583
{
584
    gen_op_s4();
585
    gen_op_subl();
586
}
587

    
588
static always_inline void gen_s8addl (void)
589
{
590
    gen_op_s8();
591
    gen_op_addl();
592
}
593

    
594
static always_inline void gen_s8subl (void)
595
{
596
    gen_op_s8();
597
    gen_op_subl();
598
}
599

    
600
static always_inline void gen_s4addq (void)
601
{
602
    gen_op_s4();
603
    gen_op_addq();
604
}
605

    
606
static always_inline void gen_s4subq (void)
607
{
608
    gen_op_s4();
609
    gen_op_subq();
610
}
611

    
612
static always_inline void gen_s8addq (void)
613
{
614
    gen_op_s8();
615
    gen_op_addq();
616
}
617

    
618
static always_inline void gen_s8subq (void)
619
{
620
    gen_op_s8();
621
    gen_op_subq();
622
}
623

    
624
static always_inline void gen_amask (void)
625
{
626
    gen_op_load_amask();
627
    gen_op_bic();
628
}
629

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

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

    
1973
    return ret;
1974
}
1975

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

    
1990
    pc_start = tb->pc;
1991
    gen_opc_ptr = gen_opc_buf;
1992
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1993
    gen_opparam_ptr = gen_opparam_buf;
1994
    nb_gen_labels = 0;
1995
    ctx.pc = pc_start;
1996
    ctx.amask = env->amask;
1997
#if defined (CONFIG_USER_ONLY)
1998
    ctx.mem_idx = 0;
1999
#else
2000
    ctx.mem_idx = ((env->ps >> 3) & 3);
2001
    ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
2002
#endif
2003
    for (ret = 0; ret == 0;) {
2004
        if (env->nb_breakpoints > 0) {
2005
            for(j = 0; j < env->nb_breakpoints; j++) {
2006
                if (env->breakpoints[j] == ctx.pc) {
2007
                    gen_excp(&ctx, EXCP_DEBUG, 0);
2008
                    break;
2009
                }
2010
            }
2011
        }
2012
        if (search_pc) {
2013
            j = gen_opc_ptr - gen_opc_buf;
2014
            if (lj < j) {
2015
                lj++;
2016
                while (lj < j)
2017
                    gen_opc_instr_start[lj++] = 0;
2018
                gen_opc_pc[lj] = ctx.pc;
2019
                gen_opc_instr_start[lj] = 1;
2020
            }
2021
        }
2022
#if defined ALPHA_DEBUG_DISAS
2023
        insn_count++;
2024
        if (logfile != NULL) {
2025
            fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2026
                    ctx.pc, ctx.mem_idx);
2027
        }
2028
#endif
2029
        insn = ldl_code(ctx.pc);
2030
#if defined ALPHA_DEBUG_DISAS
2031
        insn_count++;
2032
        if (logfile != NULL) {
2033
            fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2034
        }
2035
#endif
2036
        ctx.pc += 4;
2037
        ret = translate_one(ctxp, insn);
2038
        if (ret != 0)
2039
            break;
2040
        /* if we reach a page boundary or are single stepping, stop
2041
         * generation
2042
         */
2043
        if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2044
            (env->singlestep_enabled)) {
2045
            break;
2046
        }
2047
#if defined (DO_SINGLE_STEP)
2048
        break;
2049
#endif
2050
    }
2051
    if (ret != 1 && ret != 3) {
2052
        gen_update_pc(&ctx);
2053
    }
2054
    gen_op_reset_T0();
2055
#if defined (DO_TB_FLUSH)
2056
    gen_op_tb_flush();
2057
#endif
2058
    /* Generate the return instruction */
2059
    gen_op_exit_tb();
2060
    *gen_opc_ptr = INDEX_op_end;
2061
    if (search_pc) {
2062
        j = gen_opc_ptr - gen_opc_buf;
2063
        lj++;
2064
        while (lj <= j)
2065
            gen_opc_instr_start[lj++] = 0;
2066
    } else {
2067
        tb->size = ctx.pc - pc_start;
2068
    }
2069
#if defined ALPHA_DEBUG_DISAS
2070
    if (loglevel & CPU_LOG_TB_CPU) {
2071
        cpu_dump_state(env, logfile, fprintf, 0);
2072
    }
2073
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2074
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2075
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
2076
        fprintf(logfile, "\n");
2077
    }
2078
    if (loglevel & CPU_LOG_TB_OP) {
2079
        fprintf(logfile, "OP:\n");
2080
        dump_ops(gen_opc_buf, gen_opparam_buf);
2081
        fprintf(logfile, "\n");
2082
    }
2083
#endif
2084

    
2085
    return 0;
2086
}
2087

    
2088
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2089
{
2090
    return gen_intermediate_code_internal(env, tb, 0);
2091
}
2092

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

    
2098
CPUAlphaState * cpu_alpha_init (void)
2099
{
2100
    CPUAlphaState *env;
2101
    uint64_t hwpcb;
2102

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

    
2134
    return env;
2135
}