Statistics
| Branch: | Revision:

root / target-alpha / translate.c @ f8ed7070

History | View | Annotate | Download (57.6 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
static always_inline void gen_op_nop (void)
47
{
48
#if defined(GENERATE_NOP)
49
    gen_op_no_op();
50
#endif
51
}
52

    
53
#define GEN32(func, NAME) \
54
static GenOpFunc *NAME ## _table [32] = {                                     \
55
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
56
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
57
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
58
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
59
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
60
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
61
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
62
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
63
};                                                                            \
64
static always_inline void func (int n)                                        \
65
{                                                                             \
66
    NAME ## _table[n]();                                                      \
67
}
68

    
69
/* IR moves */
70
/* Special hacks for ir31 */
71
#define gen_op_load_T0_ir31 gen_op_reset_T0
72
#define gen_op_load_T1_ir31 gen_op_reset_T1
73
#define gen_op_load_T2_ir31 gen_op_reset_T2
74
#define gen_op_store_T0_ir31 gen_op_nop
75
#define gen_op_store_T1_ir31 gen_op_nop
76
#define gen_op_store_T2_ir31 gen_op_nop
77
#define gen_op_cmov_ir31 gen_op_nop
78
GEN32(gen_op_load_T0_ir, gen_op_load_T0_ir);
79
GEN32(gen_op_load_T1_ir, gen_op_load_T1_ir);
80
GEN32(gen_op_load_T2_ir, gen_op_load_T2_ir);
81
GEN32(gen_op_store_T0_ir, gen_op_store_T0_ir);
82
GEN32(gen_op_store_T1_ir, gen_op_store_T1_ir);
83
GEN32(gen_op_store_T2_ir, gen_op_store_T2_ir);
84
GEN32(gen_op_cmov_ir, gen_op_cmov_ir);
85

    
86
static always_inline void gen_load_ir (DisasContext *ctx, int irn, int Tn)
87
{
88
    switch (Tn) {
89
    case 0:
90
        gen_op_load_T0_ir(irn);
91
        break;
92
    case 1:
93
        gen_op_load_T1_ir(irn);
94
        break;
95
    case 2:
96
        gen_op_load_T2_ir(irn);
97
        break;
98
    }
99
}
100

    
101
static always_inline void gen_store_ir (DisasContext *ctx, int irn, int Tn)
102
{
103
    switch (Tn) {
104
    case 0:
105
        gen_op_store_T0_ir(irn);
106
        break;
107
    case 1:
108
        gen_op_store_T1_ir(irn);
109
        break;
110
    case 2:
111
        gen_op_store_T2_ir(irn);
112
        break;
113
    }
114
}
115

    
116
/* FIR moves */
117
/* Special hacks for fir31 */
118
#define gen_op_load_FT0_fir31 gen_op_reset_FT0
119
#define gen_op_load_FT1_fir31 gen_op_reset_FT1
120
#define gen_op_load_FT2_fir31 gen_op_reset_FT2
121
#define gen_op_store_FT0_fir31 gen_op_nop
122
#define gen_op_store_FT1_fir31 gen_op_nop
123
#define gen_op_store_FT2_fir31 gen_op_nop
124
#define gen_op_cmov_fir31 gen_op_nop
125
GEN32(gen_op_load_FT0_fir, gen_op_load_FT0_fir);
126
GEN32(gen_op_load_FT1_fir, gen_op_load_FT1_fir);
127
GEN32(gen_op_load_FT2_fir, gen_op_load_FT2_fir);
128
GEN32(gen_op_store_FT0_fir, gen_op_store_FT0_fir);
129
GEN32(gen_op_store_FT1_fir, gen_op_store_FT1_fir);
130
GEN32(gen_op_store_FT2_fir, gen_op_store_FT2_fir);
131
GEN32(gen_op_cmov_fir, gen_op_cmov_fir);
132

    
133
static always_inline void gen_load_fir (DisasContext *ctx, int firn, int Tn)
134
{
135
    switch (Tn) {
136
    case 0:
137
        gen_op_load_FT0_fir(firn);
138
        break;
139
    case 1:
140
        gen_op_load_FT1_fir(firn);
141
        break;
142
    case 2:
143
        gen_op_load_FT2_fir(firn);
144
        break;
145
    }
146
}
147

    
148
static always_inline void gen_store_fir (DisasContext *ctx, int firn, int Tn)
149
{
150
    switch (Tn) {
151
    case 0:
152
        gen_op_store_FT0_fir(firn);
153
        break;
154
    case 1:
155
        gen_op_store_FT1_fir(firn);
156
        break;
157
    case 2:
158
        gen_op_store_FT2_fir(firn);
159
        break;
160
    }
161
}
162

    
163
/* Memory moves */
164
#if defined(CONFIG_USER_ONLY)
165
#define OP_LD_TABLE(width)                                                    \
166
static GenOpFunc *gen_op_ld##width[] = {                                      \
167
    &gen_op_ld##width##_raw,                                                  \
168
}
169
#define OP_ST_TABLE(width)                                                    \
170
static GenOpFunc *gen_op_st##width[] = {                                      \
171
    &gen_op_st##width##_raw,                                                  \
172
}
173
#else
174
#define OP_LD_TABLE(width)                                                    \
175
static GenOpFunc *gen_op_ld##width[] = {                                      \
176
    &gen_op_ld##width##_kernel,                                               \
177
    &gen_op_ld##width##_executive,                                            \
178
    &gen_op_ld##width##_supervisor,                                           \
179
    &gen_op_ld##width##_user,                                                 \
180
}
181
#define OP_ST_TABLE(width)                                                    \
182
static GenOpFunc *gen_op_st##width[] = {                                      \
183
    &gen_op_st##width##_kernel,                                               \
184
    &gen_op_st##width##_executive,                                            \
185
    &gen_op_st##width##_supervisor,                                           \
186
    &gen_op_st##width##_user,                                                 \
187
}
188
#endif
189

    
190
#define GEN_LD(width)                                                         \
191
OP_LD_TABLE(width);                                                           \
192
static always_inline void gen_ld##width (DisasContext *ctx)                   \
193
{                                                                             \
194
    (*gen_op_ld##width[ctx->mem_idx])();                                      \
195
}
196

    
197
#define GEN_ST(width)                                                         \
198
OP_ST_TABLE(width);                                                           \
199
static always_inline void gen_st##width (DisasContext *ctx)                   \
200
{                                                                             \
201
    (*gen_op_st##width[ctx->mem_idx])();                                      \
202
}
203

    
204
GEN_LD(bu);
205
GEN_ST(b);
206
GEN_LD(wu);
207
GEN_ST(w);
208
GEN_LD(l);
209
GEN_ST(l);
210
GEN_LD(q);
211
GEN_ST(q);
212
GEN_LD(q_u);
213
GEN_ST(q_u);
214
GEN_LD(l_l);
215
GEN_ST(l_c);
216
GEN_LD(q_l);
217
GEN_ST(q_c);
218

    
219
#if 0 /* currently unused */
220
GEN_LD(f);
221
GEN_ST(f);
222
GEN_LD(g);
223
GEN_ST(g);
224
#endif /* 0 */
225
GEN_LD(s);
226
GEN_ST(s);
227
GEN_LD(t);
228
GEN_ST(t);
229

    
230
#if defined(__i386__) || defined(__x86_64__)
231
static always_inline void gen_op_set_s16_T0 (int16_t imm)
232
{
233
    gen_op_set_s32_T0((int32_t)imm);
234
}
235

    
236
static always_inline void gen_op_set_s16_T1 (int16_t imm)
237
{
238
    gen_op_set_s32_T1((int32_t)imm);
239
}
240

    
241
static always_inline void gen_op_set_u16_T0 (uint16_t imm)
242
{
243
    gen_op_set_s32_T0((uint32_t)imm);
244
}
245

    
246
static always_inline void gen_op_set_u16_T1 (uint16_t imm)
247
{
248
    gen_op_set_s32_T1((uint32_t)imm);
249
}
250
#endif
251

    
252
static always_inline void gen_set_sT0 (DisasContext *ctx, int64_t imm)
253
{
254
    int32_t imm32;
255
    int16_t imm16;
256

    
257
    imm32 = imm;
258
    if (imm32 == imm) {
259
        imm16 = imm;
260
        if (imm16 == imm) {
261
            if (imm == 0) {
262
                gen_op_reset_T0();
263
            } else {
264
                gen_op_set_s16_T0(imm16);
265
            }
266
        } else {
267
            gen_op_set_s32_T0(imm32);
268
        }
269
    } else {
270
#if 0 // Qemu does not know how to do this...
271
        gen_op_set_64_T0(imm);
272
#else
273
        gen_op_set_64_T0(imm >> 32, imm);
274
#endif
275
    }
276
}
277

    
278
static always_inline void gen_set_sT1 (DisasContext *ctx, int64_t imm)
279
{
280
    int32_t imm32;
281
    int16_t imm16;
282

    
283
    imm32 = imm;
284
    if (imm32 == imm) {
285
        imm16 = imm;
286
        if (imm16 == imm) {
287
            if (imm == 0) {
288
                gen_op_reset_T1();
289
            } else {
290
                gen_op_set_s16_T1(imm16);
291
            }
292
        } else {
293
            gen_op_set_s32_T1(imm32);
294
        }
295
    } else {
296
#if 0 // Qemu does not know how to do this...
297
        gen_op_set_64_T1(imm);
298
#else
299
        gen_op_set_64_T1(imm >> 32, imm);
300
#endif
301
    }
302
}
303

    
304
static always_inline void gen_set_uT0 (DisasContext *ctx, uint64_t imm)
305
{
306
    if (!(imm >> 32)) {
307
        if ((!imm >> 16)) {
308
            if (imm == 0)
309
                gen_op_reset_T0();
310
            else
311
                gen_op_set_u16_T0(imm);
312
        } else {
313
            gen_op_set_u32_T0(imm);
314
        }
315
    } else {
316
#if 0 // Qemu does not know how to do this...
317
        gen_op_set_64_T0(imm);
318
#else
319
        gen_op_set_64_T0(imm >> 32, imm);
320
#endif
321
    }
322
}
323

    
324
static always_inline void gen_set_uT1 (DisasContext *ctx, uint64_t imm)
325
{
326
    if (!(imm >> 32)) {
327
        if ((!imm >> 16)) {
328
            if (imm == 0)
329
                gen_op_reset_T1();
330
            else
331
                gen_op_set_u16_T1(imm);
332
        } else {
333
            gen_op_set_u32_T1(imm);
334
        }
335
    } else {
336
#if 0 // Qemu does not know how to do this...
337
        gen_op_set_64_T1(imm);
338
#else
339
        gen_op_set_64_T1(imm >> 32, imm);
340
#endif
341
    }
342
}
343

    
344
static always_inline void gen_update_pc (DisasContext *ctx)
345
{
346
    if (!(ctx->pc >> 32)) {
347
        gen_op_update_pc32(ctx->pc);
348
    } else {
349
#if 0 // Qemu does not know how to do this...
350
        gen_op_update_pc(ctx->pc);
351
#else
352
        gen_op_update_pc(ctx->pc >> 32, ctx->pc);
353
#endif
354
    }
355
}
356

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

    
366
static always_inline void gen_excp (DisasContext *ctx,
367
                                    int exception, int error_code)
368
{
369
    gen_update_pc(ctx);
370
    gen_op_excp(exception, error_code);
371
}
372

    
373
static always_inline void gen_invalid (DisasContext *ctx)
374
{
375
    gen_excp(ctx, EXCP_OPCDEC, 0);
376
}
377

    
378
static always_inline void gen_load_mem (DisasContext *ctx,
379
                                        void (*gen_load_op)(DisasContext *ctx),
380
                                        int ra, int rb, int32_t disp16,
381
                                        int clear)
382
{
383
    if (ra == 31 && disp16 == 0) {
384
        /* UNOP */
385
        gen_op_nop();
386
    } else {
387
        gen_load_ir(ctx, rb, 0);
388
        if (disp16 != 0) {
389
            gen_set_sT1(ctx, disp16);
390
            gen_op_addq();
391
        }
392
        if (clear)
393
            gen_op_n7();
394
        (*gen_load_op)(ctx);
395
        gen_store_ir(ctx, ra, 1);
396
    }
397
}
398

    
399
static always_inline void gen_store_mem (DisasContext *ctx,
400
                                         void (*gen_store_op)(DisasContext *ctx),
401
                                         int ra, int rb, int32_t disp16,
402
                                         int clear)
403
{
404
    gen_load_ir(ctx, rb, 0);
405
    if (disp16 != 0) {
406
        gen_set_sT1(ctx, disp16);
407
        gen_op_addq();
408
    }
409
    if (clear)
410
        gen_op_n7();
411
    gen_load_ir(ctx, ra, 1);
412
    (*gen_store_op)(ctx);
413
}
414

    
415
static always_inline void gen_load_fmem (DisasContext *ctx,
416
                                         void (*gen_load_fop)(DisasContext *ctx),
417
                                         int ra, int rb, int32_t disp16)
418
{
419
    gen_load_ir(ctx, rb, 0);
420
    if (disp16 != 0) {
421
        gen_set_sT1(ctx, disp16);
422
        gen_op_addq();
423
    }
424
    (*gen_load_fop)(ctx);
425
    gen_store_fir(ctx, ra, 1);
426
}
427

    
428
static always_inline void gen_store_fmem (DisasContext *ctx,
429
                                          void (*gen_store_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_fir(ctx, ra, 1);
438
    (*gen_store_fop)(ctx);
439
}
440

    
441
static always_inline void gen_bcond (DisasContext *ctx,
442
                                     void (*gen_test_op)(void),
443
                                     int ra, int32_t disp16)
444
{
445
    if (disp16 != 0) {
446
        gen_set_uT0(ctx, ctx->pc);
447
        gen_set_sT1(ctx, disp16 << 2);
448
        gen_op_addq1();
449
    } else {
450
        gen_set_uT1(ctx, ctx->pc);
451
    }
452
    gen_load_ir(ctx, ra, 0);
453
    (*gen_test_op)();
454
    _gen_op_bcond(ctx);
455
}
456

    
457
static always_inline void gen_fbcond (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_fir(ctx, ra, 0);
469
    (*gen_test_op)();
470
    _gen_op_bcond(ctx);
471
}
472

    
473
static always_inline void gen_arith2 (DisasContext *ctx,
474
                                      void (*gen_arith_op)(void),
475
                                      int rb, int rc, int islit, int8_t lit)
476
{
477
    if (islit)
478
        gen_set_sT0(ctx, lit);
479
    else
480
        gen_load_ir(ctx, rb, 0);
481
    (*gen_arith_op)();
482
    gen_store_ir(ctx, rc, 0);
483
}
484

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

    
499
static always_inline void gen_cmov (DisasContext *ctx,
500
                                    void (*gen_test_op)(void),
501
                                    int ra, int rb, int rc,
502
                                    int islit, int8_t lit)
503
{
504
    gen_load_ir(ctx, ra, 1);
505
    if (islit)
506
        gen_set_sT0(ctx, lit);
507
    else
508
        gen_load_ir(ctx, rb, 0);
509
    (*gen_test_op)();
510
    gen_op_cmov_ir(rc);
511
}
512

    
513
static always_inline void gen_farith2 (DisasContext *ctx,
514
                                       void (*gen_arith_fop)(void),
515
                                       int rb, int rc)
516
{
517
    gen_load_fir(ctx, rb, 0);
518
    (*gen_arith_fop)();
519
    gen_store_fir(ctx, rc, 0);
520
}
521

    
522
static always_inline void gen_farith3 (DisasContext *ctx,
523
                                       void (*gen_arith_fop)(void),
524
                                       int ra, int rb, int rc)
525
{
526
    gen_load_fir(ctx, ra, 0);
527
    gen_load_fir(ctx, rb, 1);
528
    (*gen_arith_fop)();
529
    gen_store_fir(ctx, rc, 0);
530
}
531

    
532
static always_inline void gen_fcmov (DisasContext *ctx,
533
                                     void (*gen_test_fop)(void),
534
                                     int ra, int rb, int rc)
535
{
536
    gen_load_fir(ctx, ra, 0);
537
    gen_load_fir(ctx, rb, 1);
538
    (*gen_test_fop)();
539
    gen_op_cmov_fir(rc);
540
}
541

    
542
static always_inline void gen_fti (DisasContext *ctx,
543
                                   void (*gen_move_fop)(void),
544
                                   int ra, int rc)
545
{
546
    gen_load_fir(ctx, rc, 0);
547
    (*gen_move_fop)();
548
    gen_store_ir(ctx, ra, 0);
549
}
550

    
551
static always_inline void gen_itf (DisasContext *ctx,
552
                                   void (*gen_move_fop)(void),
553
                                   int ra, int rc)
554
{
555
    gen_load_ir(ctx, ra, 0);
556
    (*gen_move_fop)();
557
    gen_store_fir(ctx, rc, 0);
558
}
559

    
560
static always_inline void gen_s4addl (void)
561
{
562
    gen_op_s4();
563
    gen_op_addl();
564
}
565

    
566
static always_inline void gen_s4subl (void)
567
{
568
    gen_op_s4();
569
    gen_op_subl();
570
}
571

    
572
static always_inline void gen_s8addl (void)
573
{
574
    gen_op_s8();
575
    gen_op_addl();
576
}
577

    
578
static always_inline void gen_s8subl (void)
579
{
580
    gen_op_s8();
581
    gen_op_subl();
582
}
583

    
584
static always_inline void gen_s4addq (void)
585
{
586
    gen_op_s4();
587
    gen_op_addq();
588
}
589

    
590
static always_inline void gen_s4subq (void)
591
{
592
    gen_op_s4();
593
    gen_op_subq();
594
}
595

    
596
static always_inline void gen_s8addq (void)
597
{
598
    gen_op_s8();
599
    gen_op_addq();
600
}
601

    
602
static always_inline void gen_s8subq (void)
603
{
604
    gen_op_s8();
605
    gen_op_subq();
606
}
607

    
608
static always_inline void gen_amask (void)
609
{
610
    gen_op_load_amask();
611
    gen_op_bic();
612
}
613

    
614
static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
615
{
616
    uint32_t palcode;
617
    int32_t disp21, disp16, disp12;
618
    uint16_t fn11, fn16;
619
    uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
620
    int8_t lit;
621
    int ret;
622

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

    
1957
    return ret;
1958
}
1959

    
1960
static always_inline int gen_intermediate_code_internal (CPUState *env,
1961
                                                         TranslationBlock *tb,
1962
                                                         int search_pc)
1963
{
1964
#if defined ALPHA_DEBUG_DISAS
1965
    static int insn_count;
1966
#endif
1967
    DisasContext ctx, *ctxp = &ctx;
1968
    target_ulong pc_start;
1969
    uint32_t insn;
1970
    uint16_t *gen_opc_end;
1971
    int j, lj = -1;
1972
    int ret;
1973

    
1974
    pc_start = tb->pc;
1975
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1976
    ctx.pc = pc_start;
1977
    ctx.amask = env->amask;
1978
#if defined (CONFIG_USER_ONLY)
1979
    ctx.mem_idx = 0;
1980
#else
1981
    ctx.mem_idx = ((env->ps >> 3) & 3);
1982
    ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
1983
#endif
1984
    for (ret = 0; ret == 0;) {
1985
        if (env->nb_breakpoints > 0) {
1986
            for(j = 0; j < env->nb_breakpoints; j++) {
1987
                if (env->breakpoints[j] == ctx.pc) {
1988
                    gen_excp(&ctx, EXCP_DEBUG, 0);
1989
                    break;
1990
                }
1991
            }
1992
        }
1993
        if (search_pc) {
1994
            j = gen_opc_ptr - gen_opc_buf;
1995
            if (lj < j) {
1996
                lj++;
1997
                while (lj < j)
1998
                    gen_opc_instr_start[lj++] = 0;
1999
                gen_opc_pc[lj] = ctx.pc;
2000
                gen_opc_instr_start[lj] = 1;
2001
            }
2002
        }
2003
#if defined ALPHA_DEBUG_DISAS
2004
        insn_count++;
2005
        if (logfile != NULL) {
2006
            fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2007
                    ctx.pc, ctx.mem_idx);
2008
        }
2009
#endif
2010
        insn = ldl_code(ctx.pc);
2011
#if defined ALPHA_DEBUG_DISAS
2012
        insn_count++;
2013
        if (logfile != NULL) {
2014
            fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2015
        }
2016
#endif
2017
        ctx.pc += 4;
2018
        ret = translate_one(ctxp, insn);
2019
        if (ret != 0)
2020
            break;
2021
        /* if we reach a page boundary or are single stepping, stop
2022
         * generation
2023
         */
2024
        if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2025
            (env->singlestep_enabled)) {
2026
            break;
2027
        }
2028
#if defined (DO_SINGLE_STEP)
2029
        break;
2030
#endif
2031
    }
2032
    if (ret != 1 && ret != 3) {
2033
        gen_update_pc(&ctx);
2034
    }
2035
#if defined (DO_TB_FLUSH)
2036
    gen_op_tb_flush();
2037
#endif
2038
    /* Generate the return instruction */
2039
    tcg_gen_exit_tb(0);
2040
    *gen_opc_ptr = INDEX_op_end;
2041
    if (search_pc) {
2042
        j = gen_opc_ptr - gen_opc_buf;
2043
        lj++;
2044
        while (lj <= j)
2045
            gen_opc_instr_start[lj++] = 0;
2046
    } else {
2047
        tb->size = ctx.pc - pc_start;
2048
    }
2049
#if defined ALPHA_DEBUG_DISAS
2050
    if (loglevel & CPU_LOG_TB_CPU) {
2051
        cpu_dump_state(env, logfile, fprintf, 0);
2052
    }
2053
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2054
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2055
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
2056
        fprintf(logfile, "\n");
2057
    }
2058
#endif
2059

    
2060
    return 0;
2061
}
2062

    
2063
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
2064
{
2065
    return gen_intermediate_code_internal(env, tb, 0);
2066
}
2067

    
2068
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2069
{
2070
    return gen_intermediate_code_internal(env, tb, 1);
2071
}
2072

    
2073
CPUAlphaState * cpu_alpha_init (const char *cpu_model)
2074
{
2075
    CPUAlphaState *env;
2076
    uint64_t hwpcb;
2077

    
2078
    env = qemu_mallocz(sizeof(CPUAlphaState));
2079
    if (!env)
2080
        return NULL;
2081
    cpu_exec_init(env);
2082
    tlb_flush(env, 1);
2083
    /* XXX: should not be hardcoded */
2084
    env->implver = IMPLVER_2106x;
2085
    env->ps = 0x1F00;
2086
#if defined (CONFIG_USER_ONLY)
2087
    env->ps |= 1 << 3;
2088
#endif
2089
    pal_init(env);
2090
    /* Initialize IPR */
2091
    hwpcb = env->ipr[IPR_PCBB];
2092
    env->ipr[IPR_ASN] = 0;
2093
    env->ipr[IPR_ASTEN] = 0;
2094
    env->ipr[IPR_ASTSR] = 0;
2095
    env->ipr[IPR_DATFX] = 0;
2096
    /* XXX: fix this */
2097
    //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2098
    //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2099
    //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2100
    //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2101
    env->ipr[IPR_FEN] = 0;
2102
    env->ipr[IPR_IPL] = 31;
2103
    env->ipr[IPR_MCES] = 0;
2104
    env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2105
    //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2106
    env->ipr[IPR_SISR] = 0;
2107
    env->ipr[IPR_VIRBND] = -1ULL;
2108

    
2109
    return env;
2110
}
2111

    
2112
void gen_pc_load(CPUState *env, TranslationBlock *tb,
2113
                unsigned long searched_pc, int pc_pos, void *puc)
2114
{
2115
    env->pc = gen_opc_pc[pc_pos];
2116
}