~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to target-alpha/translate.c

Tags: upstream-0.9.0+20070816
ImportĀ upstreamĀ versionĀ 0.9.0+20070816

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 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 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 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 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 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 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##_user, /* executive */                                 \
 
194
    &gen_op_ld##width##_data, /* supervisor */                                \
 
195
    &gen_op_ld##width##_data, /* 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##_user, /* executive */                                 \
 
201
    &gen_op_st##width##_data, /* supervisor */                                \
 
202
    &gen_op_st##width##_data, /* user */                                      \
 
203
}
 
204
#endif
 
205
 
 
206
#define GEN_LD(width)                                                         \
 
207
OP_LD_TABLE(width);                                                           \
 
208
static 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 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 inline void gen_op_set_s16_T0 (int16_t imm)
 
248
{
 
249
    gen_op_set_s32_T0((int32_t)imm);
 
250
}
 
251
 
 
252
static inline void gen_op_set_s16_T1 (int16_t imm)
 
253
{
 
254
    gen_op_set_s32_T1((int32_t)imm);
 
255
}
 
256
 
 
257
static inline void gen_op_set_u16_T0 (uint16_t imm)
 
258
{
 
259
    gen_op_set_s32_T0((uint32_t)imm);
 
260
}
 
261
 
 
262
static 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 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 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 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 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 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 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 inline void gen_excp (DisasContext *ctx, int exception, int error_code)
 
383
{
 
384
    gen_update_pc(ctx);
 
385
    gen_op_excp(exception, error_code);
 
386
}
 
387
 
 
388
static inline void gen_invalid (DisasContext *ctx)
 
389
{
 
390
    gen_excp(ctx, EXCP_OPCDEC, 0);
 
391
}
 
392
 
 
393
static void gen_load_mem (DisasContext *ctx,
 
394
                          void (*gen_load_op)(DisasContext *ctx),
 
395
                          int ra, int rb, int32_t disp16, int clear)
 
396
{
 
397
    if (ra == 31 && disp16 == 0) {
 
398
        /* UNOP */
 
399
        gen_op_nop();
 
400
    } else {
 
401
        gen_load_ir(ctx, rb, 0);
 
402
        if (disp16 != 0) {
 
403
            gen_set_sT1(ctx, disp16);
 
404
            gen_op_addq();
 
405
        }
 
406
        if (clear)
 
407
            gen_op_n7();
 
408
        (*gen_load_op)(ctx);
 
409
        gen_store_ir(ctx, ra, 1);
 
410
    }
 
411
}
 
412
 
 
413
static void gen_store_mem (DisasContext *ctx,
 
414
                           void (*gen_store_op)(DisasContext *ctx),
 
415
                           int ra, int rb, int32_t disp16, int clear)
 
416
{
 
417
    gen_load_ir(ctx, rb, 0);
 
418
    if (disp16 != 0) {
 
419
        gen_set_sT1(ctx, disp16);
 
420
        gen_op_addq();
 
421
    }
 
422
    if (clear)
 
423
        gen_op_n7();
 
424
    gen_load_ir(ctx, ra, 1);
 
425
    (*gen_store_op)(ctx);
 
426
}
 
427
 
 
428
static void gen_load_fmem (DisasContext *ctx,
 
429
                           void (*gen_load_fop)(DisasContext *ctx),
 
430
                          int ra, int rb, int32_t disp16)
 
431
{
 
432
    gen_load_ir(ctx, rb, 0);
 
433
    if (disp16 != 0) {
 
434
        gen_set_sT1(ctx, disp16);
 
435
        gen_op_addq();
 
436
    }
 
437
    (*gen_load_fop)(ctx);
 
438
    gen_store_fir(ctx, ra, 1);
 
439
}
 
440
 
 
441
static void gen_store_fmem (DisasContext *ctx,
 
442
                            void (*gen_store_fop)(DisasContext *ctx),
 
443
                            int ra, int rb, int32_t disp16)
 
444
{
 
445
    gen_load_ir(ctx, rb, 0);
 
446
    if (disp16 != 0) {
 
447
        gen_set_sT1(ctx, disp16);
 
448
        gen_op_addq();
 
449
    }
 
450
    gen_load_fir(ctx, ra, 1);
 
451
    (*gen_store_fop)(ctx);
 
452
}
 
453
 
 
454
static void gen_bcond (DisasContext *ctx, void (*gen_test_op)(void),
 
455
                       int ra, int32_t disp16)
 
456
{
 
457
    if (disp16 != 0) {
 
458
        gen_set_uT0(ctx, ctx->pc);
 
459
        gen_set_sT1(ctx, disp16 << 2);
 
460
        gen_op_addq1();
 
461
    } else {
 
462
        gen_set_uT1(ctx, ctx->pc);
 
463
    }
 
464
    gen_load_ir(ctx, ra, 0);
 
465
    (*gen_test_op)();
 
466
    _gen_op_bcond(ctx);
 
467
}
 
468
 
 
469
static void gen_fbcond (DisasContext *ctx, void (*gen_test_op)(void),
 
470
                        int ra, int32_t disp16)
 
471
{
 
472
    if (disp16 != 0) {
 
473
        gen_set_uT0(ctx, ctx->pc);
 
474
        gen_set_sT1(ctx, disp16 << 2);
 
475
        gen_op_addq1();
 
476
    } else {
 
477
        gen_set_uT1(ctx, ctx->pc);
 
478
    }
 
479
    gen_load_fir(ctx, ra, 0);
 
480
    (*gen_test_op)();
 
481
    _gen_op_bcond(ctx);
 
482
}
 
483
 
 
484
static void gen_arith2 (DisasContext *ctx, void (*gen_arith_op)(void),
 
485
                        int rb, int rc, int islit, int8_t lit)
 
486
{
 
487
    if (islit)
 
488
        gen_set_sT0(ctx, lit);
 
489
    else
 
490
        gen_load_ir(ctx, rb, 0);
 
491
    (*gen_arith_op)();
 
492
    gen_store_ir(ctx, rc, 0);
 
493
}
 
494
 
 
495
static void gen_arith3 (DisasContext *ctx, void (*gen_arith_op)(void),
 
496
                        int ra, int rb, int rc, int islit, int8_t lit)
 
497
{
 
498
    gen_load_ir(ctx, ra, 0);
 
499
    if (islit)
 
500
        gen_set_sT1(ctx, lit);
 
501
    else
 
502
        gen_load_ir(ctx, rb, 1);
 
503
    (*gen_arith_op)();
 
504
    gen_store_ir(ctx, rc, 0);
 
505
}
 
506
 
 
507
static void gen_cmov (DisasContext *ctx, void (*gen_test_op)(void),
 
508
                      int ra, int rb, int rc, int islit, int8_t lit)
 
509
{
 
510
    gen_load_ir(ctx, ra, 1);
 
511
    if (islit)
 
512
        gen_set_sT0(ctx, lit);
 
513
    else
 
514
        gen_load_ir(ctx, rb, 0);
 
515
    (*gen_test_op)();
 
516
    gen_op_cmov_ir(rc);
 
517
}
 
518
 
 
519
static void gen_farith2 (DisasContext *ctx, void (*gen_arith_fop)(void),
 
520
                         int rb, int rc)
 
521
{
 
522
    gen_load_fir(ctx, rb, 0);
 
523
    (*gen_arith_fop)();
 
524
    gen_store_fir(ctx, rc, 0);
 
525
}
 
526
 
 
527
static void gen_farith3 (DisasContext *ctx, void (*gen_arith_fop)(void),
 
528
                         int ra, int rb, int rc)
 
529
{
 
530
    gen_load_fir(ctx, ra, 0);
 
531
    gen_load_fir(ctx, rb, 1);
 
532
    (*gen_arith_fop)();
 
533
    gen_store_fir(ctx, rc, 0);
 
534
}
 
535
 
 
536
static void gen_fcmov (DisasContext *ctx, void (*gen_test_fop)(void),
 
537
                       int ra, int rb, int rc)
 
538
{
 
539
    gen_load_fir(ctx, ra, 0);
 
540
    gen_load_fir(ctx, rb, 1);
 
541
    (*gen_test_fop)();
 
542
    gen_op_cmov_fir(rc);
 
543
}
 
544
 
 
545
static void gen_fti (DisasContext *ctx, void (*gen_move_fop)(void),
 
546
                     int ra, int rc)
 
547
{
 
548
    gen_load_fir(ctx, rc, 0);
 
549
    (*gen_move_fop)();
 
550
    gen_store_ir(ctx, ra, 0);
 
551
}
 
552
 
 
553
static void gen_itf (DisasContext *ctx, void (*gen_move_fop)(void),
 
554
                     int ra, int rc)
 
555
{
 
556
    gen_load_ir(ctx, ra, 0);
 
557
    (*gen_move_fop)();
 
558
    gen_store_fir(ctx, rc, 0);
 
559
}
 
560
 
 
561
static void gen_s4addl (void)
 
562
{
 
563
    gen_op_s4();
 
564
    gen_op_addl();
 
565
 
566
 
 
567
static void gen_s4subl (void)
 
568
{
 
569
    gen_op_s4();
 
570
    gen_op_subl();
 
571
 
572
 
 
573
static void gen_s8addl (void)
 
574
{
 
575
    gen_op_s8();
 
576
    gen_op_addl();
 
577
 
578
 
 
579
static void gen_s8subl (void)
 
580
{
 
581
    gen_op_s8();
 
582
    gen_op_subl();
 
583
 
584
 
 
585
static void gen_s4addq (void)
 
586
{
 
587
    gen_op_s4();
 
588
    gen_op_addq();
 
589
 
590
 
 
591
static void gen_s4subq (void)
 
592
{
 
593
    gen_op_s4();
 
594
    gen_op_subq();
 
595
 
596
 
 
597
static void gen_s8addq (void)
 
598
{
 
599
    gen_op_s8();
 
600
    gen_op_addq();
 
601
 
602
 
 
603
static void gen_s8subq (void)
 
604
{
 
605
    gen_op_s8();
 
606
    gen_op_subq();
 
607
 
608
 
 
609
static void gen_amask (void)
 
610
{
 
611
    gen_op_load_amask();
 
612
    gen_op_bic();
 
613
}
 
614
 
 
615
static int translate_one (DisasContext *ctx, uint32_t insn)
 
616
{
 
617
    uint32_t palcode;
 
618
    int32_t disp21, disp16, disp12;
 
619
    uint16_t fn11, fn16;
 
620
    uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
 
621
    int8_t lit;
 
622
    int ret;
 
623
 
 
624
    /* Decode all instruction fields */
 
625
    opc = insn >> 26;
 
626
    ra = (insn >> 21) & 0x1F;
 
627
    rb = (insn >> 16) & 0x1F;
 
628
    rc = insn & 0x1F;
 
629
    sbz = (insn >> 13) & 0x07;
 
630
    islit = (insn >> 12) & 1;
 
631
    lit = (insn >> 13) & 0xFF;
 
632
    palcode = insn & 0x03FFFFFF;
 
633
    disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
 
634
    disp16 = (int16_t)(insn & 0x0000FFFF);
 
635
    disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
 
636
    fn16 = insn & 0x0000FFFF;
 
637
    fn11 = (insn >> 5) & 0x000007FF;
 
638
    fpfn = fn11 & 0x3F;
 
639
    fn7 = (insn >> 5) & 0x0000007F;
 
640
    fn2 = (insn >> 5) & 0x00000003;
 
641
    ret = 0;
 
642
#if defined ALPHA_DEBUG_DISAS
 
643
    if (logfile != NULL) {
 
644
        fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n",
 
645
                opc, ra, rb, rc, disp16);
 
646
    }
 
647
#endif
 
648
    switch (opc) {
 
649
    case 0x00:
 
650
        /* CALL_PAL */
 
651
        if (palcode >= 0x80 && palcode < 0xC0) {
 
652
            /* Unprivileged PAL call */
 
653
            gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);
 
654
#if !defined (CONFIG_USER_ONLY)
 
655
        } else if (palcode < 0x40) {
 
656
            /* Privileged PAL code */
 
657
            if (ctx->mem_idx & 1)
 
658
                goto invalid_opc;
 
659
            else
 
660
                gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0);
 
661
#endif
 
662
        } else {
 
663
            /* Invalid PAL call */
 
664
            goto invalid_opc;
 
665
        }
 
666
        ret = 3;
 
667
        break;
 
668
    case 0x01:
 
669
        /* OPC01 */
 
670
        goto invalid_opc;
 
671
    case 0x02:
 
672
        /* OPC02 */
 
673
        goto invalid_opc;
 
674
    case 0x03:
 
675
        /* OPC03 */
 
676
        goto invalid_opc;
 
677
    case 0x04:
 
678
        /* OPC04 */
 
679
        goto invalid_opc;
 
680
    case 0x05:
 
681
        /* OPC05 */
 
682
        goto invalid_opc;
 
683
    case 0x06:
 
684
        /* OPC06 */
 
685
        goto invalid_opc;
 
686
    case 0x07:
 
687
        /* OPC07 */
 
688
        goto invalid_opc;
 
689
    case 0x08:
 
690
        /* LDA */
 
691
        gen_load_ir(ctx, rb, 0);
 
692
        gen_set_sT1(ctx, disp16);
 
693
        gen_op_addq();
 
694
        gen_store_ir(ctx, ra, 0);
 
695
        break;
 
696
    case 0x09:
 
697
        /* LDAH */
 
698
        gen_load_ir(ctx, rb, 0);
 
699
        gen_set_sT1(ctx, disp16 << 16);
 
700
        gen_op_addq();
 
701
        gen_store_ir(ctx, ra, 0);
 
702
        break;
 
703
    case 0x0A:
 
704
        /* LDBU */
 
705
        if (!(ctx->amask & AMASK_BWX))
 
706
            goto invalid_opc;
 
707
        gen_load_mem(ctx, &gen_ldbu, ra, rb, disp16, 0);
 
708
        break;
 
709
    case 0x0B:
 
710
        /* LDQ_U */
 
711
        gen_load_mem(ctx, &gen_ldq_u, ra, rb, disp16, 1);
 
712
        break;
 
713
    case 0x0C:
 
714
        /* LDWU */
 
715
        if (!(ctx->amask & AMASK_BWX))
 
716
            goto invalid_opc;
 
717
        gen_load_mem(ctx, &gen_ldwu, ra, rb, disp16, 0);
 
718
        break;
 
719
    case 0x0D:
 
720
        /* STW */
 
721
        if (!(ctx->amask & AMASK_BWX))
 
722
            goto invalid_opc;
 
723
        gen_store_mem(ctx, &gen_stw, ra, rb, disp16, 0);
 
724
        break;
 
725
    case 0x0E:
 
726
        /* STB */
 
727
        if (!(ctx->amask & AMASK_BWX))
 
728
            goto invalid_opc;
 
729
        gen_store_mem(ctx, &gen_stb, ra, rb, disp16, 0);
 
730
        break;
 
731
    case 0x0F:
 
732
        /* STQ_U */
 
733
        gen_store_mem(ctx, &gen_stq_u, ra, rb, disp16, 1);
 
734
        break;
 
735
    case 0x10:
 
736
        switch (fn7) {
 
737
        case 0x00:
 
738
            /* ADDL */
 
739
            gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit);
 
740
            break;
 
741
        case 0x02:
 
742
            /* S4ADDL */
 
743
            gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit);
 
744
            break;
 
745
        case 0x09:
 
746
            /* SUBL */
 
747
            gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit);
 
748
            break;
 
749
        case 0x0B:
 
750
            /* S4SUBL */
 
751
            gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit);
 
752
            break;
 
753
        case 0x0F:
 
754
            /* CMPBGE */
 
755
            gen_arith3(ctx, &gen_op_cmpbge, ra, rb, rc, islit, lit);
 
756
            break;
 
757
        case 0x12:
 
758
            /* S8ADDL */
 
759
            gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit);
 
760
            break;
 
761
        case 0x1B:
 
762
            /* S8SUBL */
 
763
            gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit);
 
764
            break;
 
765
        case 0x1D:
 
766
            /* CMPULT */
 
767
            gen_arith3(ctx, &gen_op_cmpult, ra, rb, rc, islit, lit);
 
768
            break;
 
769
        case 0x20:
 
770
            /* ADDQ */
 
771
            gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit);
 
772
            break;
 
773
        case 0x22:
 
774
            /* S4ADDQ */
 
775
            gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit);
 
776
            break;
 
777
        case 0x29:
 
778
            /* SUBQ */
 
779
            gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit);
 
780
            break;
 
781
        case 0x2B:
 
782
            /* S4SUBQ */
 
783
            gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit);
 
784
            break;
 
785
        case 0x2D:
 
786
            /* CMPEQ */
 
787
            gen_arith3(ctx, &gen_op_cmpeq, ra, rb, rc, islit, lit);
 
788
            break;
 
789
        case 0x32:
 
790
            /* S8ADDQ */
 
791
            gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit);
 
792
            break;
 
793
        case 0x3B:
 
794
            /* S8SUBQ */
 
795
            gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit);
 
796
            break;
 
797
        case 0x3D:
 
798
            /* CMPULE */
 
799
            gen_arith3(ctx, &gen_op_cmpule, ra, rb, rc, islit, lit);
 
800
            break;
 
801
        case 0x40:
 
802
            /* ADDL/V */
 
803
            gen_arith3(ctx, &gen_op_addlv, ra, rb, rc, islit, lit);
 
804
            break;
 
805
        case 0x49:
 
806
            /* SUBL/V */
 
807
            gen_arith3(ctx, &gen_op_sublv, ra, rb, rc, islit, lit);
 
808
            break;
 
809
        case 0x4D:
 
810
            /* CMPLT */
 
811
            gen_arith3(ctx, &gen_op_cmplt, ra, rb, rc, islit, lit);
 
812
            break;
 
813
        case 0x60:
 
814
            /* ADDQ/V */
 
815
            gen_arith3(ctx, &gen_op_addqv, ra, rb, rc, islit, lit);
 
816
            break;
 
817
        case 0x69:
 
818
            /* SUBQ/V */
 
819
            gen_arith3(ctx, &gen_op_subqv, ra, rb, rc, islit, lit);
 
820
            break;
 
821
        case 0x6D:
 
822
            /* CMPLE */
 
823
            gen_arith3(ctx, &gen_op_cmple, ra, rb, rc, islit, lit);
 
824
            break;
 
825
        default:
 
826
            goto invalid_opc;
 
827
        }
 
828
        break;
 
829
    case 0x11:
 
830
        switch (fn7) {
 
831
        case 0x00:
 
832
            /* AND */
 
833
            gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit);
 
834
            break;
 
835
        case 0x08:
 
836
            /* BIC */
 
837
            gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit);
 
838
            break;
 
839
        case 0x14:
 
840
            /* CMOVLBS */
 
841
            gen_cmov(ctx, &gen_op_cmplbs, ra, rb, rc, islit, lit);
 
842
            break;
 
843
        case 0x16:
 
844
            /* CMOVLBC */
 
845
            gen_cmov(ctx, &gen_op_cmplbc, ra, rb, rc, islit, lit);
 
846
            break;
 
847
        case 0x20:
 
848
            /* BIS */
 
849
            if (ra == rb || ra == 31 || rb == 31) {
 
850
                if (ra == 31 && rc == 31) {
 
851
                    /* NOP */
 
852
                    gen_op_nop();
 
853
                } else {
 
854
                    /* MOV */
 
855
                    gen_load_ir(ctx, rb, 0);
 
856
                    gen_store_ir(ctx, rc, 0);
 
857
                }
 
858
            } else {
 
859
                gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
 
860
            }
 
861
            break;
 
862
        case 0x24:
 
863
            /* CMOVEQ */
 
864
            gen_cmov(ctx, &gen_op_cmpeqz, ra, rb, rc, islit, lit);
 
865
            break;
 
866
        case 0x26:
 
867
            /* CMOVNE */
 
868
            gen_cmov(ctx, &gen_op_cmpnez, ra, rb, rc, islit, lit);
 
869
            break;
 
870
        case 0x28:
 
871
            /* ORNOT */
 
872
            gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit);
 
873
            break;
 
874
        case 0x40:
 
875
            /* XOR */
 
876
            gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit);
 
877
            break;
 
878
        case 0x44:
 
879
            /* CMOVLT */
 
880
            gen_cmov(ctx, &gen_op_cmpltz, ra, rb, rc, islit, lit);
 
881
            break;
 
882
        case 0x46:
 
883
            /* CMOVGE */
 
884
            gen_cmov(ctx, &gen_op_cmpgez, ra, rb, rc, islit, lit);
 
885
            break;
 
886
        case 0x48:
 
887
            /* EQV */
 
888
            gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit);
 
889
            break;
 
890
        case 0x61:
 
891
            /* AMASK */
 
892
            gen_arith2(ctx, &gen_amask, rb, rc, islit, lit);
 
893
            break;
 
894
        case 0x64:
 
895
            /* CMOVLE */
 
896
            gen_cmov(ctx, &gen_op_cmplez, ra, rb, rc, islit, lit);
 
897
            break;
 
898
        case 0x66:
 
899
            /* CMOVGT */
 
900
            gen_cmov(ctx, &gen_op_cmpgtz, ra, rb, rc, islit, lit);
 
901
            break;
 
902
        case 0x6C:
 
903
            /* IMPLVER */
 
904
            gen_op_load_implver();
 
905
            gen_store_ir(ctx, rc, 0);
 
906
            break;
 
907
        default:
 
908
            goto invalid_opc;
 
909
        }
 
910
        break;
 
911
    case 0x12:
 
912
        switch (fn7) {
 
913
        case 0x02:
 
914
            /* MSKBL */
 
915
            gen_arith3(ctx, &gen_op_mskbl, ra, rb, rc, islit, lit);
 
916
            break;
 
917
        case 0x06:
 
918
            /* EXTBL */
 
919
            gen_arith3(ctx, &gen_op_extbl, ra, rb, rc, islit, lit);
 
920
            break;
 
921
        case 0x0B:
 
922
            /* INSBL */
 
923
            gen_arith3(ctx, &gen_op_insbl, ra, rb, rc, islit, lit);
 
924
            break;
 
925
        case 0x12:
 
926
            /* MSKWL */
 
927
            gen_arith3(ctx, &gen_op_mskwl, ra, rb, rc, islit, lit);
 
928
            break;
 
929
        case 0x16:
 
930
            /* EXTWL */
 
931
            gen_arith3(ctx, &gen_op_extwl, ra, rb, rc, islit, lit);
 
932
            break;
 
933
        case 0x1B:
 
934
            /* INSWL */
 
935
            gen_arith3(ctx, &gen_op_inswl, ra, rb, rc, islit, lit);
 
936
            break;
 
937
        case 0x22:
 
938
            /* MSKLL */
 
939
            gen_arith3(ctx, &gen_op_mskll, ra, rb, rc, islit, lit);
 
940
            break;
 
941
        case 0x26:
 
942
            /* EXTLL */
 
943
            gen_arith3(ctx, &gen_op_extll, ra, rb, rc, islit, lit);
 
944
            break;
 
945
        case 0x2B:
 
946
            /* INSLL */
 
947
            gen_arith3(ctx, &gen_op_insll, ra, rb, rc, islit, lit);
 
948
            break;
 
949
        case 0x30:
 
950
            /* ZAP */
 
951
            gen_arith3(ctx, &gen_op_zap, ra, rb, rc, islit, lit);
 
952
            break;
 
953
        case 0x31:
 
954
            /* ZAPNOT */
 
955
            gen_arith3(ctx, &gen_op_zapnot, ra, rb, rc, islit, lit);
 
956
            break;
 
957
        case 0x32:
 
958
            /* MSKQL */
 
959
            gen_arith3(ctx, &gen_op_mskql, ra, rb, rc, islit, lit);
 
960
            break;
 
961
        case 0x34:
 
962
            /* SRL */
 
963
            gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit);
 
964
            break;
 
965
        case 0x36:
 
966
            /* EXTQL */
 
967
            gen_arith3(ctx, &gen_op_extql, ra, rb, rc, islit, lit);
 
968
            break;
 
969
        case 0x39:
 
970
            /* SLL */
 
971
            gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit);
 
972
            break;
 
973
        case 0x3B:
 
974
            /* INSQL */
 
975
            gen_arith3(ctx, &gen_op_insql, ra, rb, rc, islit, lit);
 
976
            break;
 
977
        case 0x3C:
 
978
            /* SRA */
 
979
            gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit);
 
980
            break;
 
981
        case 0x52:
 
982
            /* MSKWH */
 
983
            gen_arith3(ctx, &gen_op_mskwh, ra, rb, rc, islit, lit);
 
984
            break;
 
985
        case 0x57:
 
986
            /* INSWH */
 
987
            gen_arith3(ctx, &gen_op_inswh, ra, rb, rc, islit, lit);
 
988
            break;
 
989
        case 0x5A:
 
990
            /* EXTWH */
 
991
            gen_arith3(ctx, &gen_op_extwh, ra, rb, rc, islit, lit);
 
992
            break;
 
993
        case 0x62:
 
994
            /* MSKLH */
 
995
            gen_arith3(ctx, &gen_op_msklh, ra, rb, rc, islit, lit);
 
996
            break;
 
997
        case 0x67:
 
998
            /* INSLH */
 
999
            gen_arith3(ctx, &gen_op_inslh, ra, rb, rc, islit, lit);
 
1000
            break;
 
1001
        case 0x6A:
 
1002
            /* EXTLH */
 
1003
            gen_arith3(ctx, &gen_op_extlh, ra, rb, rc, islit, lit);
 
1004
            break;
 
1005
        case 0x72:
 
1006
            /* MSKQH */
 
1007
            gen_arith3(ctx, &gen_op_mskqh, ra, rb, rc, islit, lit);
 
1008
            break;
 
1009
        case 0x77:
 
1010
            /* INSQH */
 
1011
            gen_arith3(ctx, &gen_op_insqh, ra, rb, rc, islit, lit);
 
1012
            break;
 
1013
        case 0x7A:
 
1014
            /* EXTQH */
 
1015
            gen_arith3(ctx, &gen_op_extqh, ra, rb, rc, islit, lit);
 
1016
            break;
 
1017
        default:
 
1018
            goto invalid_opc;
 
1019
        }
 
1020
        break;
 
1021
    case 0x13:
 
1022
        switch (fn7) {
 
1023
        case 0x00:
 
1024
            /* MULL */
 
1025
            gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit);
 
1026
            break;
 
1027
        case 0x20:
 
1028
            /* MULQ */
 
1029
            gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit);
 
1030
            break;
 
1031
        case 0x30:
 
1032
            /* UMULH */
 
1033
            gen_arith3(ctx, &gen_op_umulh, ra, rb, rc, islit, lit);
 
1034
            break;
 
1035
        case 0x40:
 
1036
            /* MULL/V */
 
1037
            gen_arith3(ctx, &gen_op_mullv, ra, rb, rc, islit, lit);
 
1038
            break;
 
1039
        case 0x60:
 
1040
            /* MULQ/V */
 
1041
            gen_arith3(ctx, &gen_op_mulqv, ra, rb, rc, islit, lit);
 
1042
            break;
 
1043
        default:
 
1044
            goto invalid_opc;
 
1045
        }
 
1046
        break;
 
1047
    case 0x14:
 
1048
        switch (fpfn) { /* f11 & 0x3F */
 
1049
        case 0x04:
 
1050
            /* ITOFS */
 
1051
            if (!(ctx->amask & AMASK_FIX))
 
1052
                goto invalid_opc;
 
1053
            gen_itf(ctx, &gen_op_itofs, ra, rc);
 
1054
            break;
 
1055
        case 0x0A:
 
1056
            /* SQRTF */
 
1057
            if (!(ctx->amask & AMASK_FIX))
 
1058
                goto invalid_opc;
 
1059
            gen_farith2(ctx, &gen_op_sqrtf, rb, rc);
 
1060
            break;
 
1061
        case 0x0B:
 
1062
            /* SQRTS */
 
1063
            if (!(ctx->amask & AMASK_FIX))
 
1064
                goto invalid_opc;
 
1065
            gen_farith2(ctx, &gen_op_sqrts, rb, rc);
 
1066
            break;
 
1067
        case 0x14:
 
1068
            /* ITOFF */
 
1069
            if (!(ctx->amask & AMASK_FIX))
 
1070
                goto invalid_opc;
 
1071
#if 0 // TODO
 
1072
            gen_itf(ctx, &gen_op_itoff, ra, rc);
 
1073
#else
 
1074
            goto invalid_opc;
 
1075
#endif
 
1076
            break;
 
1077
        case 0x24:
 
1078
            /* ITOFT */
 
1079
            if (!(ctx->amask & AMASK_FIX))
 
1080
                goto invalid_opc;
 
1081
            gen_itf(ctx, &gen_op_itoft, ra, rc);
 
1082
            break;
 
1083
        case 0x2A:
 
1084
            /* SQRTG */
 
1085
            if (!(ctx->amask & AMASK_FIX))
 
1086
                goto invalid_opc;
 
1087
            gen_farith2(ctx, &gen_op_sqrtg, rb, rc);
 
1088
            break;
 
1089
        case 0x02B:
 
1090
            /* SQRTT */
 
1091
            if (!(ctx->amask & AMASK_FIX))
 
1092
                goto invalid_opc;
 
1093
            gen_farith2(ctx, &gen_op_sqrtt, rb, rc);
 
1094
            break;
 
1095
        default:
 
1096
            goto invalid_opc;
 
1097
        }
 
1098
        break;
 
1099
    case 0x15:
 
1100
        /* VAX floating point */
 
1101
        /* XXX: rounding mode and trap are ignored (!) */
 
1102
        switch (fpfn) { /* f11 & 0x3F */
 
1103
        case 0x00:
 
1104
            /* ADDF */
 
1105
            gen_farith3(ctx, &gen_op_addf, ra, rb, rc);
 
1106
            break;
 
1107
        case 0x01:
 
1108
            /* SUBF */
 
1109
            gen_farith3(ctx, &gen_op_subf, ra, rb, rc);
 
1110
            break;
 
1111
        case 0x02:
 
1112
            /* MULF */
 
1113
            gen_farith3(ctx, &gen_op_mulf, ra, rb, rc);
 
1114
            break;
 
1115
        case 0x03:
 
1116
            /* DIVF */
 
1117
            gen_farith3(ctx, &gen_op_divf, ra, rb, rc);
 
1118
            break;
 
1119
        case 0x1E:
 
1120
            /* CVTDG */
 
1121
#if 0 // TODO
 
1122
            gen_farith2(ctx, &gen_op_cvtdg, rb, rc);
 
1123
#else
 
1124
            goto invalid_opc;
 
1125
#endif
 
1126
            break;
 
1127
        case 0x20:
 
1128
            /* ADDG */
 
1129
            gen_farith3(ctx, &gen_op_addg, ra, rb, rc);
 
1130
            break;
 
1131
        case 0x21:
 
1132
            /* SUBG */
 
1133
            gen_farith3(ctx, &gen_op_subg, ra, rb, rc);
 
1134
            break;
 
1135
        case 0x22:
 
1136
            /* MULG */
 
1137
            gen_farith3(ctx, &gen_op_mulg, ra, rb, rc);
 
1138
            break;
 
1139
        case 0x23:
 
1140
            /* DIVG */
 
1141
            gen_farith3(ctx, &gen_op_divg, ra, rb, rc);
 
1142
            break;
 
1143
        case 0x25:
 
1144
            /* CMPGEQ */
 
1145
            gen_farith3(ctx, &gen_op_cmpgeq, ra, rb, rc);
 
1146
            break;
 
1147
        case 0x26:
 
1148
            /* CMPGLT */
 
1149
            gen_farith3(ctx, &gen_op_cmpglt, ra, rb, rc);
 
1150
            break;
 
1151
        case 0x27:
 
1152
            /* CMPGLE */
 
1153
            gen_farith3(ctx, &gen_op_cmpgle, ra, rb, rc);
 
1154
            break;
 
1155
        case 0x2C:
 
1156
            /* CVTGF */
 
1157
            gen_farith2(ctx, &gen_op_cvtgf, rb, rc);
 
1158
            break;
 
1159
        case 0x2D:
 
1160
            /* CVTGD */
 
1161
#if 0 // TODO
 
1162
            gen_farith2(ctx, &gen_op_cvtgd, rb, rc);
 
1163
#else
 
1164
            goto invalid_opc;
 
1165
#endif
 
1166
            break;
 
1167
        case 0x2F:
 
1168
            /* CVTGQ */
 
1169
            gen_farith2(ctx, &gen_op_cvtgq, rb, rc);
 
1170
            break;
 
1171
        case 0x3C:
 
1172
            /* CVTQF */
 
1173
            gen_farith2(ctx, &gen_op_cvtqf, rb, rc);
 
1174
            break;
 
1175
        case 0x3E:
 
1176
            /* CVTQG */
 
1177
            gen_farith2(ctx, &gen_op_cvtqg, rb, rc);
 
1178
            break;
 
1179
        default:
 
1180
            goto invalid_opc;
 
1181
        }
 
1182
        break;
 
1183
    case 0x16:
 
1184
        /* IEEE floating-point */
 
1185
        /* XXX: rounding mode and traps are ignored (!) */
 
1186
        switch (fpfn) { /* f11 & 0x3F */
 
1187
        case 0x00:
 
1188
            /* ADDS */
 
1189
            gen_farith3(ctx, &gen_op_adds, ra, rb, rc);
 
1190
            break;
 
1191
        case 0x01:
 
1192
            /* SUBS */
 
1193
            gen_farith3(ctx, &gen_op_subs, ra, rb, rc);
 
1194
            break;
 
1195
        case 0x02:
 
1196
            /* MULS */
 
1197
            gen_farith3(ctx, &gen_op_muls, ra, rb, rc);
 
1198
            break;
 
1199
        case 0x03:
 
1200
            /* DIVS */
 
1201
            gen_farith3(ctx, &gen_op_divs, ra, rb, rc);
 
1202
            break;
 
1203
        case 0x20:
 
1204
            /* ADDT */
 
1205
            gen_farith3(ctx, &gen_op_addt, ra, rb, rc);
 
1206
            break;
 
1207
        case 0x21:
 
1208
            /* SUBT */
 
1209
            gen_farith3(ctx, &gen_op_subt, ra, rb, rc);
 
1210
            break;
 
1211
        case 0x22:
 
1212
            /* MULT */
 
1213
            gen_farith3(ctx, &gen_op_mult, ra, rb, rc);
 
1214
            break;
 
1215
        case 0x23:
 
1216
            /* DIVT */
 
1217
            gen_farith3(ctx, &gen_op_divt, ra, rb, rc);
 
1218
            break;
 
1219
        case 0x24:
 
1220
            /* CMPTUN */
 
1221
            gen_farith3(ctx, &gen_op_cmptun, ra, rb, rc);
 
1222
            break;
 
1223
        case 0x25:
 
1224
            /* CMPTEQ */
 
1225
            gen_farith3(ctx, &gen_op_cmpteq, ra, rb, rc);
 
1226
            break;
 
1227
        case 0x26:
 
1228
            /* CMPTLT */
 
1229
            gen_farith3(ctx, &gen_op_cmptlt, ra, rb, rc);
 
1230
            break;
 
1231
        case 0x27:
 
1232
            /* CMPTLE */
 
1233
            gen_farith3(ctx, &gen_op_cmptle, ra, rb, rc);
 
1234
            break;
 
1235
        case 0x2C:
 
1236
            /* XXX: incorrect */
 
1237
            if (fn11 == 0x2AC) {
 
1238
                /* CVTST */
 
1239
                gen_farith2(ctx, &gen_op_cvtst, rb, rc);
 
1240
            } else {
 
1241
                /* CVTTS */
 
1242
                gen_farith2(ctx, &gen_op_cvtts, rb, rc);
 
1243
            }
 
1244
            break;
 
1245
        case 0x2F:
 
1246
            /* CVTTQ */
 
1247
            gen_farith2(ctx, &gen_op_cvttq, rb, rc);
 
1248
            break;
 
1249
        case 0x3C:
 
1250
            /* CVTQS */
 
1251
            gen_farith2(ctx, &gen_op_cvtqs, rb, rc);
 
1252
            break;
 
1253
        case 0x3E:
 
1254
            /* CVTQT */
 
1255
            gen_farith2(ctx, &gen_op_cvtqt, rb, rc);
 
1256
            break;
 
1257
        default:
 
1258
            goto invalid_opc;
 
1259
        }
 
1260
        break;
 
1261
    case 0x17:
 
1262
        switch (fn11) {
 
1263
        case 0x010:
 
1264
            /* CVTLQ */
 
1265
            gen_farith2(ctx, &gen_op_cvtlq, rb, rc);
 
1266
            break;
 
1267
        case 0x020:
 
1268
            /* CPYS */
 
1269
            if (ra == rb) {
 
1270
                if (ra == 31 && rc == 31) {
 
1271
                    /* FNOP */
 
1272
                    gen_op_nop();
 
1273
                } else {
 
1274
                    /* FMOV */
 
1275
                    gen_load_fir(ctx, rb, 0);
 
1276
                    gen_store_fir(ctx, rc, 0);
 
1277
                }
 
1278
            } else {
 
1279
                gen_farith3(ctx, &gen_op_cpys, ra, rb, rc);
 
1280
            }
 
1281
            break;
 
1282
        case 0x021:
 
1283
            /* CPYSN */
 
1284
            gen_farith2(ctx, &gen_op_cpysn, rb, rc);
 
1285
            break;
 
1286
        case 0x022:
 
1287
            /* CPYSE */
 
1288
            gen_farith2(ctx, &gen_op_cpyse, rb, rc);
 
1289
            break;
 
1290
        case 0x024:
 
1291
            /* MT_FPCR */
 
1292
            gen_load_fir(ctx, ra, 0);
 
1293
            gen_op_store_fpcr();
 
1294
            break;
 
1295
        case 0x025:
 
1296
            /* MF_FPCR */
 
1297
            gen_op_load_fpcr();
 
1298
            gen_store_fir(ctx, ra, 0);
 
1299
            break;
 
1300
        case 0x02A:
 
1301
            /* FCMOVEQ */
 
1302
            gen_fcmov(ctx, &gen_op_cmpfeq, ra, rb, rc);
 
1303
            break;
 
1304
        case 0x02B:
 
1305
            /* FCMOVNE */
 
1306
            gen_fcmov(ctx, &gen_op_cmpfne, ra, rb, rc);
 
1307
            break;
 
1308
        case 0x02C:
 
1309
            /* FCMOVLT */
 
1310
            gen_fcmov(ctx, &gen_op_cmpflt, ra, rb, rc);
 
1311
            break;
 
1312
        case 0x02D:
 
1313
            /* FCMOVGE */
 
1314
            gen_fcmov(ctx, &gen_op_cmpfge, ra, rb, rc);
 
1315
            break;
 
1316
        case 0x02E:
 
1317
            /* FCMOVLE */
 
1318
            gen_fcmov(ctx, &gen_op_cmpfle, ra, rb, rc);
 
1319
            break;
 
1320
        case 0x02F:
 
1321
            /* FCMOVGT */
 
1322
            gen_fcmov(ctx, &gen_op_cmpfgt, ra, rb, rc);
 
1323
            break;
 
1324
        case 0x030:
 
1325
            /* CVTQL */
 
1326
            gen_farith2(ctx, &gen_op_cvtql, rb, rc);
 
1327
            break;
 
1328
        case 0x130:
 
1329
            /* CVTQL/V */
 
1330
            gen_farith2(ctx, &gen_op_cvtqlv, rb, rc);
 
1331
            break;
 
1332
        case 0x530:
 
1333
            /* CVTQL/SV */
 
1334
            gen_farith2(ctx, &gen_op_cvtqlsv, rb, rc);
 
1335
            break;
 
1336
        default:
 
1337
            goto invalid_opc;
 
1338
        }
 
1339
        break;
 
1340
    case 0x18:
 
1341
        switch ((uint16_t)disp16) {
 
1342
        case 0x0000:
 
1343
            /* TRAPB */
 
1344
            /* No-op. Just exit from the current tb */
 
1345
            ret = 2;
 
1346
            break;
 
1347
        case 0x0400:
 
1348
            /* EXCB */
 
1349
            /* No-op. Just exit from the current tb */
 
1350
            ret = 2;
 
1351
            break;
 
1352
        case 0x4000:
 
1353
            /* MB */
 
1354
            /* No-op */
 
1355
            break;
 
1356
        case 0x4400:
 
1357
            /* WMB */
 
1358
            /* No-op */
 
1359
            break;
 
1360
        case 0x8000:
 
1361
            /* FETCH */
 
1362
            /* No-op */
 
1363
            break;
 
1364
        case 0xA000:
 
1365
            /* FETCH_M */
 
1366
            /* No-op */
 
1367
            break;
 
1368
        case 0xC000:
 
1369
            /* RPCC */
 
1370
            gen_op_load_pcc();
 
1371
            gen_store_ir(ctx, ra, 0);
 
1372
            break;
 
1373
        case 0xE000:
 
1374
            /* RC */
 
1375
            gen_op_load_irf();
 
1376
            gen_store_ir(ctx, ra, 0);
 
1377
            gen_op_clear_irf();
 
1378
            break;
 
1379
        case 0xE800:
 
1380
            /* ECB */
 
1381
            /* XXX: TODO: evict tb cache at address rb */
 
1382
#if 0
 
1383
            ret = 2;
 
1384
#else
 
1385
            goto invalid_opc;
 
1386
#endif
 
1387
            break;
 
1388
        case 0xF000:
 
1389
            /* RS */
 
1390
            gen_op_load_irf();
 
1391
            gen_store_ir(ctx, ra, 0);
 
1392
            gen_op_set_irf();
 
1393
            break;
 
1394
        case 0xF800:
 
1395
            /* WH64 */
 
1396
            /* No-op */
 
1397
            break;
 
1398
        default:
 
1399
            goto invalid_opc;
 
1400
        }
 
1401
        break;
 
1402
    case 0x19:
 
1403
        /* HW_MFPR (PALcode) */
 
1404
#if defined (CONFIG_USER_ONLY)
 
1405
        goto invalid_opc;
 
1406
#else
 
1407
        if (!ctx->pal_mode)
 
1408
            goto invalid_opc;
 
1409
        gen_op_mfpr(insn & 0xFF);
 
1410
        gen_store_ir(ctx, ra, 0);
 
1411
        break;
 
1412
#endif
 
1413
    case 0x1A:
 
1414
        gen_load_ir(ctx, rb, 0);
 
1415
        if (ra != 31) {
 
1416
            gen_set_uT1(ctx, ctx->pc);
 
1417
            gen_store_ir(ctx, ra, 1);
 
1418
        }
 
1419
        gen_op_branch();
 
1420
        /* Those four jumps only differ by the branch prediction hint */
 
1421
        switch (fn2) {
 
1422
        case 0x0:
 
1423
            /* JMP */
 
1424
            break;
 
1425
        case 0x1:
 
1426
            /* JSR */
 
1427
            break;
 
1428
        case 0x2:
 
1429
            /* RET */
 
1430
            break;
 
1431
        case 0x3:
 
1432
            /* JSR_COROUTINE */
 
1433
            break;
 
1434
        }
 
1435
        ret = 1;
 
1436
        break;
 
1437
    case 0x1B:
 
1438
        /* HW_LD (PALcode) */
 
1439
#if defined (CONFIG_USER_ONLY)
 
1440
        goto invalid_opc;
 
1441
#else
 
1442
        if (!ctx->pal_mode)
 
1443
            goto invalid_opc;
 
1444
        gen_load_ir(ctx, rb, 0);
 
1445
        gen_set_sT1(ctx, disp12);
 
1446
        gen_op_addq();
 
1447
        switch ((insn >> 12) & 0xF) {
 
1448
        case 0x0:
 
1449
            /* Longword physical access */
 
1450
            gen_op_ldl_raw();
 
1451
            break;
 
1452
        case 0x1:
 
1453
            /* Quadword physical access */
 
1454
            gen_op_ldq_raw();
 
1455
            break;
 
1456
        case 0x2:
 
1457
            /* Longword physical access with lock */
 
1458
            gen_op_ldl_l_raw();
 
1459
            break;
 
1460
        case 0x3:
 
1461
            /* Quadword physical access with lock */
 
1462
            gen_op_ldq_l_raw();
 
1463
            break;
 
1464
        case 0x4:
 
1465
            /* Longword virtual PTE fetch */
 
1466
            gen_op_ldl_kernel();
 
1467
            break;
 
1468
        case 0x5:
 
1469
            /* Quadword virtual PTE fetch */
 
1470
            gen_op_ldq_kernel();
 
1471
            break;
 
1472
        case 0x6:
 
1473
            /* Invalid */
 
1474
            goto invalid_opc;
 
1475
        case 0x7:
 
1476
            /* Invalid */
 
1477
            goto invalid_opc;
 
1478
        case 0x8:
 
1479
            /* Longword virtual access */
 
1480
            gen_op_ld_phys_to_virt();
 
1481
            gen_op_ldl_raw();
 
1482
            break;
 
1483
        case 0x9:
 
1484
            /* Quadword virtual access */
 
1485
            gen_op_ld_phys_to_virt();
 
1486
            gen_op_ldq_raw();
 
1487
            break;
 
1488
        case 0xA:
 
1489
            /* Longword virtual access with protection check */
 
1490
            gen_ldl(ctx);
 
1491
            break;
 
1492
        case 0xB:
 
1493
            /* Quadword virtual access with protection check */
 
1494
            gen_ldq(ctx);
 
1495
            break;
 
1496
        case 0xC:
 
1497
            /* Longword virtual access with altenate access mode */
 
1498
            gen_op_set_alt_mode();
 
1499
            gen_op_ld_phys_to_virt();
 
1500
            gen_op_ldl_raw();
 
1501
            gen_op_restore_mode();
 
1502
            break;
 
1503
        case 0xD:
 
1504
            /* Quadword virtual access with altenate access mode */
 
1505
            gen_op_set_alt_mode();
 
1506
            gen_op_ld_phys_to_virt();
 
1507
            gen_op_ldq_raw();
 
1508
            gen_op_restore_mode();
 
1509
            break;
 
1510
        case 0xE:
 
1511
            /* Longword virtual access with alternate access mode and
 
1512
             * protection checks
 
1513
             */
 
1514
            gen_op_set_alt_mode();
 
1515
            gen_op_ldl_data();
 
1516
            gen_op_restore_mode();
 
1517
            break;
 
1518
        case 0xF:
 
1519
            /* Quadword virtual access with alternate access mode and
 
1520
             * protection checks
 
1521
             */
 
1522
            gen_op_set_alt_mode();
 
1523
            gen_op_ldq_data();
 
1524
            gen_op_restore_mode();
 
1525
            break;
 
1526
        }
 
1527
        gen_store_ir(ctx, ra, 1);
 
1528
        break;
 
1529
#endif
 
1530
    case 0x1C:
 
1531
        switch (fn7) {
 
1532
        case 0x00:
 
1533
            /* SEXTB */
 
1534
            if (!(ctx->amask & AMASK_BWX))
 
1535
                goto invalid_opc;
 
1536
            gen_arith2(ctx, &gen_op_sextb, rb, rc, islit, lit);
 
1537
            break;
 
1538
        case 0x01:
 
1539
            /* SEXTW */
 
1540
            if (!(ctx->amask & AMASK_BWX))
 
1541
                goto invalid_opc;
 
1542
            gen_arith2(ctx, &gen_op_sextw, rb, rc, islit, lit);
 
1543
            break;
 
1544
        case 0x30:
 
1545
            /* CTPOP */
 
1546
            if (!(ctx->amask & AMASK_CIX))
 
1547
                goto invalid_opc;
 
1548
            gen_arith2(ctx, &gen_op_ctpop, rb, rc, 0, 0);
 
1549
            break;
 
1550
        case 0x31:
 
1551
            /* PERR */
 
1552
            if (!(ctx->amask & AMASK_MVI))
 
1553
                goto invalid_opc;
 
1554
            /* XXX: TODO */
 
1555
            goto invalid_opc;
 
1556
            break;
 
1557
        case 0x32:
 
1558
            /* CTLZ */
 
1559
            if (!(ctx->amask & AMASK_CIX))
 
1560
                goto invalid_opc;
 
1561
            gen_arith2(ctx, &gen_op_ctlz, rb, rc, 0, 0);
 
1562
            break;
 
1563
        case 0x33:
 
1564
            /* CTTZ */
 
1565
            if (!(ctx->amask & AMASK_CIX))
 
1566
                goto invalid_opc;
 
1567
            gen_arith2(ctx, &gen_op_cttz, rb, rc, 0, 0);
 
1568
            break;
 
1569
        case 0x34:
 
1570
            /* UNPKBW */
 
1571
            if (!(ctx->amask & AMASK_MVI))
 
1572
                goto invalid_opc;
 
1573
            /* XXX: TODO */
 
1574
            goto invalid_opc;
 
1575
            break;
 
1576
        case 0x35:
 
1577
            /* UNPKWL */
 
1578
            if (!(ctx->amask & AMASK_MVI))
 
1579
                goto invalid_opc;
 
1580
            /* XXX: TODO */
 
1581
            goto invalid_opc;
 
1582
            break;
 
1583
        case 0x36:
 
1584
            /* PKWB */
 
1585
            if (!(ctx->amask & AMASK_MVI))
 
1586
                goto invalid_opc;
 
1587
            /* XXX: TODO */
 
1588
            goto invalid_opc;
 
1589
            break;
 
1590
        case 0x37:
 
1591
            /* PKLB */
 
1592
            if (!(ctx->amask & AMASK_MVI))
 
1593
                goto invalid_opc;
 
1594
            /* XXX: TODO */
 
1595
            goto invalid_opc;
 
1596
            break;
 
1597
        case 0x38:
 
1598
            /* MINSB8 */
 
1599
            if (!(ctx->amask & AMASK_MVI))
 
1600
                goto invalid_opc;
 
1601
            /* XXX: TODO */
 
1602
            goto invalid_opc;
 
1603
            break;
 
1604
        case 0x39:
 
1605
            /* MINSW4 */
 
1606
            if (!(ctx->amask & AMASK_MVI))
 
1607
                goto invalid_opc;
 
1608
            /* XXX: TODO */
 
1609
            goto invalid_opc;
 
1610
            break;
 
1611
        case 0x3A:
 
1612
            /* MINUB8 */
 
1613
            if (!(ctx->amask & AMASK_MVI))
 
1614
                goto invalid_opc;
 
1615
            /* XXX: TODO */
 
1616
            goto invalid_opc;
 
1617
            break;
 
1618
        case 0x3B:
 
1619
            /* MINUW4 */
 
1620
            if (!(ctx->amask & AMASK_MVI))
 
1621
                goto invalid_opc;
 
1622
            /* XXX: TODO */
 
1623
            goto invalid_opc;
 
1624
            break;
 
1625
        case 0x3C:
 
1626
            /* MAXUB8 */
 
1627
            if (!(ctx->amask & AMASK_MVI))
 
1628
                goto invalid_opc;
 
1629
            /* XXX: TODO */
 
1630
            goto invalid_opc;
 
1631
            break;
 
1632
        case 0x3D:
 
1633
            /* MAXUW4 */
 
1634
            if (!(ctx->amask & AMASK_MVI))
 
1635
                goto invalid_opc;
 
1636
            /* XXX: TODO */
 
1637
            goto invalid_opc;
 
1638
            break;
 
1639
        case 0x3E:
 
1640
            /* MAXSB8 */
 
1641
            if (!(ctx->amask & AMASK_MVI))
 
1642
                goto invalid_opc;
 
1643
            /* XXX: TODO */
 
1644
            goto invalid_opc;
 
1645
            break;
 
1646
        case 0x3F:
 
1647
            /* MAXSW4 */
 
1648
            if (!(ctx->amask & AMASK_MVI))
 
1649
                goto invalid_opc;
 
1650
            /* XXX: TODO */
 
1651
            goto invalid_opc;
 
1652
            break;
 
1653
        case 0x70:
 
1654
            /* FTOIT */
 
1655
            if (!(ctx->amask & AMASK_FIX))
 
1656
                goto invalid_opc;
 
1657
            gen_fti(ctx, &gen_op_ftoit, ra, rb);
 
1658
            break;
 
1659
        case 0x78:
 
1660
            /* FTOIS */
 
1661
            if (!(ctx->amask & AMASK_FIX))
 
1662
                goto invalid_opc;
 
1663
            gen_fti(ctx, &gen_op_ftois, ra, rb);
 
1664
            break;
 
1665
        default:
 
1666
            goto invalid_opc;
 
1667
        }
 
1668
        break;
 
1669
    case 0x1D:
 
1670
        /* HW_MTPR (PALcode) */
 
1671
#if defined (CONFIG_USER_ONLY)
 
1672
        goto invalid_opc;
 
1673
#else
 
1674
        if (!ctx->pal_mode)
 
1675
            goto invalid_opc;
 
1676
        gen_load_ir(ctx, ra, 0);
 
1677
        gen_op_mtpr(insn & 0xFF);
 
1678
        ret = 2;
 
1679
        break;
 
1680
#endif
 
1681
    case 0x1E:
 
1682
        /* HW_REI (PALcode) */
 
1683
#if defined (CONFIG_USER_ONLY)
 
1684
        goto invalid_opc;
 
1685
#else
 
1686
        if (!ctx->pal_mode)
 
1687
            goto invalid_opc;
 
1688
        if (rb == 31) {
 
1689
            /* "Old" alpha */
 
1690
            gen_op_hw_rei();
 
1691
        } else {
 
1692
            gen_load_ir(ctx, rb, 0);
 
1693
            gen_set_uT1(ctx, (((int64_t)insn << 51) >> 51));
 
1694
            gen_op_addq();
 
1695
            gen_op_hw_ret();
 
1696
        }
 
1697
        ret = 2;
 
1698
        break;
 
1699
#endif
 
1700
    case 0x1F:
 
1701
        /* HW_ST (PALcode) */
 
1702
#if defined (CONFIG_USER_ONLY)
 
1703
        goto invalid_opc;
 
1704
#else
 
1705
        if (!ctx->pal_mode)
 
1706
            goto invalid_opc;
 
1707
        gen_load_ir(ctx, rb, 0);
 
1708
        gen_set_sT1(ctx, disp12);
 
1709
        gen_op_addq();
 
1710
        gen_load_ir(ctx, ra, 1);
 
1711
        switch ((insn >> 12) & 0xF) {
 
1712
        case 0x0:
 
1713
            /* Longword physical access */
 
1714
            gen_op_stl_raw();
 
1715
            break;
 
1716
        case 0x1:
 
1717
            /* Quadword physical access */
 
1718
            gen_op_stq_raw();
 
1719
            break;
 
1720
        case 0x2:
 
1721
            /* Longword physical access with lock */
 
1722
            gen_op_stl_c_raw();
 
1723
            break;
 
1724
        case 0x3:
 
1725
            /* Quadword physical access with lock */
 
1726
            gen_op_stq_c_raw();
 
1727
            break;
 
1728
        case 0x4:
 
1729
            /* Longword virtual access */
 
1730
            gen_op_st_phys_to_virt();
 
1731
            gen_op_stl_raw();
 
1732
            break;
 
1733
        case 0x5:
 
1734
            /* Quadword virtual access */
 
1735
            gen_op_st_phys_to_virt();
 
1736
            gen_op_stq_raw();
 
1737
            break;
 
1738
        case 0x6:
 
1739
            /* Invalid */
 
1740
            goto invalid_opc;
 
1741
        case 0x7:
 
1742
            /* Invalid */
 
1743
            goto invalid_opc;
 
1744
        case 0x8:
 
1745
            /* Invalid */
 
1746
            goto invalid_opc;
 
1747
        case 0x9:
 
1748
            /* Invalid */
 
1749
            goto invalid_opc;
 
1750
        case 0xA:
 
1751
            /* Invalid */
 
1752
            goto invalid_opc;
 
1753
        case 0xB:
 
1754
            /* Invalid */
 
1755
            goto invalid_opc;
 
1756
        case 0xC:
 
1757
            /* Longword virtual access with alternate access mode */
 
1758
            gen_op_set_alt_mode();
 
1759
            gen_op_st_phys_to_virt();
 
1760
            gen_op_ldl_raw();
 
1761
            gen_op_restore_mode();
 
1762
            break;
 
1763
        case 0xD:
 
1764
            /* Quadword virtual access with alternate access mode */
 
1765
            gen_op_set_alt_mode();
 
1766
            gen_op_st_phys_to_virt();
 
1767
            gen_op_ldq_raw();
 
1768
            gen_op_restore_mode();
 
1769
            break;
 
1770
        case 0xE:
 
1771
            /* Invalid */
 
1772
            goto invalid_opc;
 
1773
        case 0xF:
 
1774
            /* Invalid */
 
1775
            goto invalid_opc;
 
1776
        }
 
1777
        ret = 2;
 
1778
        break;
 
1779
#endif
 
1780
    case 0x20:
 
1781
        /* LDF */
 
1782
#if 0 // TODO
 
1783
        gen_load_fmem(ctx, &gen_ldf, ra, rb, disp16);
 
1784
#else
 
1785
        goto invalid_opc;
 
1786
#endif
 
1787
        break;
 
1788
    case 0x21:
 
1789
        /* LDG */
 
1790
#if 0 // TODO
 
1791
        gen_load_fmem(ctx, &gen_ldg, ra, rb, disp16);
 
1792
#else
 
1793
        goto invalid_opc;
 
1794
#endif
 
1795
        break;
 
1796
    case 0x22:
 
1797
        /* LDS */
 
1798
        gen_load_fmem(ctx, &gen_lds, ra, rb, disp16);
 
1799
        break;
 
1800
    case 0x23:
 
1801
        /* LDT */
 
1802
        gen_load_fmem(ctx, &gen_ldt, ra, rb, disp16);
 
1803
        break;
 
1804
    case 0x24:
 
1805
        /* STF */
 
1806
#if 0 // TODO
 
1807
        gen_store_fmem(ctx, &gen_stf, ra, rb, disp16);
 
1808
#else
 
1809
        goto invalid_opc;
 
1810
#endif
 
1811
        break;
 
1812
    case 0x25:
 
1813
        /* STG */
 
1814
#if 0 // TODO
 
1815
        gen_store_fmem(ctx, &gen_stg, ra, rb, disp16);
 
1816
#else
 
1817
        goto invalid_opc;
 
1818
#endif
 
1819
        break;
 
1820
    case 0x26:
 
1821
        /* STS */
 
1822
        gen_store_fmem(ctx, &gen_sts, ra, rb, disp16);
 
1823
        break;
 
1824
    case 0x27:
 
1825
        /* STT */
 
1826
        gen_store_fmem(ctx, &gen_stt, ra, rb, disp16);
 
1827
        break;
 
1828
    case 0x28:
 
1829
        /* LDL */
 
1830
        gen_load_mem(ctx, &gen_ldl, ra, rb, disp16, 0);
 
1831
        break;
 
1832
    case 0x29:
 
1833
        /* LDQ */
 
1834
        gen_load_mem(ctx, &gen_ldq, ra, rb, disp16, 0);
 
1835
        break;
 
1836
    case 0x2A:
 
1837
        /* LDL_L */
 
1838
        gen_load_mem(ctx, &gen_ldl_l, ra, rb, disp16, 0);
 
1839
        break;
 
1840
    case 0x2B:
 
1841
        /* LDQ_L */
 
1842
        gen_load_mem(ctx, &gen_ldq_l, ra, rb, disp16, 0);
 
1843
        break;
 
1844
    case 0x2C:
 
1845
        /* STL */
 
1846
        gen_store_mem(ctx, &gen_stl, ra, rb, disp16, 0);
 
1847
        break;
 
1848
    case 0x2D:
 
1849
        /* STQ */
 
1850
        gen_store_mem(ctx, &gen_stq, ra, rb, disp16, 0);
 
1851
        break;
 
1852
    case 0x2E:
 
1853
        /* STL_C */
 
1854
        gen_store_mem(ctx, &gen_stl_c, ra, rb, disp16, 0);
 
1855
        break;
 
1856
    case 0x2F:
 
1857
        /* STQ_C */
 
1858
        gen_store_mem(ctx, &gen_stq_c, ra, rb, disp16, 0);
 
1859
        break;
 
1860
    case 0x30:
 
1861
        /* BR */
 
1862
        gen_set_uT0(ctx, ctx->pc);
 
1863
        gen_store_ir(ctx, ra, 0);
 
1864
        if (disp21 != 0) {
 
1865
            gen_set_sT1(ctx, disp21 << 2);
 
1866
            gen_op_addq();
 
1867
        }
 
1868
        gen_op_branch();
 
1869
        ret = 1;
 
1870
        break;
 
1871
    case 0x31:
 
1872
        /* FBEQ */
 
1873
        gen_fbcond(ctx, &gen_op_cmpfeq, ra, disp16);
 
1874
        ret = 1;
 
1875
        break;
 
1876
    case 0x32:
 
1877
        /* FBLT */
 
1878
        gen_fbcond(ctx, &gen_op_cmpflt, ra, disp16);
 
1879
        ret = 1;
 
1880
        break;
 
1881
    case 0x33:
 
1882
        /* FBLE */
 
1883
        gen_fbcond(ctx, &gen_op_cmpfle, ra, disp16);
 
1884
        ret = 1;
 
1885
        break;
 
1886
    case 0x34:
 
1887
        /* BSR */
 
1888
        gen_set_uT0(ctx, ctx->pc);
 
1889
        gen_store_ir(ctx, ra, 0);
 
1890
        if (disp21 != 0) {
 
1891
            gen_set_sT1(ctx, disp21 << 2);
 
1892
            gen_op_addq();
 
1893
        }
 
1894
        gen_op_branch();
 
1895
        ret = 1;
 
1896
        break;
 
1897
    case 0x35:
 
1898
        /* FBNE */
 
1899
        gen_fbcond(ctx, &gen_op_cmpfne, ra, disp16);
 
1900
        ret = 1;
 
1901
        break;
 
1902
    case 0x36:
 
1903
        /* FBGE */
 
1904
        gen_fbcond(ctx, &gen_op_cmpfge, ra, disp16);
 
1905
        ret = 1;
 
1906
        break;
 
1907
    case 0x37:
 
1908
        /* FBGT */
 
1909
        gen_fbcond(ctx, &gen_op_cmpfgt, ra, disp16);
 
1910
        ret = 1;
 
1911
        break;
 
1912
    case 0x38:
 
1913
        /* BLBC */
 
1914
        gen_bcond(ctx, &gen_op_cmplbc, ra, disp16);
 
1915
        ret = 1;
 
1916
        break;
 
1917
    case 0x39:
 
1918
        /* BEQ */
 
1919
        gen_bcond(ctx, &gen_op_cmpeqz, ra, disp16);
 
1920
        ret = 1;
 
1921
        break;
 
1922
    case 0x3A:
 
1923
        /* BLT */
 
1924
        gen_bcond(ctx, &gen_op_cmpltz, ra, disp16);
 
1925
        ret = 1;
 
1926
        break;
 
1927
    case 0x3B:
 
1928
        /* BLE */
 
1929
        gen_bcond(ctx, &gen_op_cmplez, ra, disp16);
 
1930
        ret = 1;
 
1931
        break;
 
1932
    case 0x3C:
 
1933
        /* BLBS */
 
1934
        gen_bcond(ctx, &gen_op_cmplbs, ra, disp16);
 
1935
        ret = 1;
 
1936
        break;
 
1937
    case 0x3D:
 
1938
        /* BNE */
 
1939
        gen_bcond(ctx, &gen_op_cmpnez, ra, disp16);
 
1940
        ret = 1;
 
1941
        break;
 
1942
    case 0x3E:
 
1943
        /* BGE */
 
1944
        gen_bcond(ctx, &gen_op_cmpgez, ra, disp16);
 
1945
        ret = 1;
 
1946
        break;
 
1947
    case 0x3F:
 
1948
        /* BGT */
 
1949
        gen_bcond(ctx, &gen_op_cmpgtz, ra, disp16);
 
1950
        ret = 1;
 
1951
        break;
 
1952
    invalid_opc:
 
1953
        gen_invalid(ctx);
 
1954
        ret = 3;
 
1955
        break;
 
1956
    }
 
1957
 
 
1958
    return ret;
 
1959
}
 
1960
 
 
1961
int gen_intermediate_code_internal (CPUState *env, 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_ptr = gen_opc_buf;
 
1976
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
 
1977
    gen_opparam_ptr = gen_opparam_buf;
 
1978
    nb_gen_labels = 0;
 
1979
    ctx.pc = pc_start;
 
1980
    ctx.amask = env->amask;
 
1981
#if defined (CONFIG_USER_ONLY)
 
1982
    ctx.mem_idx = 0;
 
1983
#else
 
1984
    ctx.mem_idx = ((env->ps >> 3) & 3);
 
1985
    ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
 
1986
#endif
 
1987
    for (ret = 0; ret == 0;) {
 
1988
        if (env->nb_breakpoints > 0) {
 
1989
            for(j = 0; j < env->nb_breakpoints; j++) {
 
1990
                if (env->breakpoints[j] == ctx.pc) {
 
1991
                    gen_excp(&ctx, EXCP_DEBUG, 0);
 
1992
                    break;
 
1993
                }
 
1994
            }
 
1995
        }
 
1996
        if (search_pc) {
 
1997
            j = gen_opc_ptr - gen_opc_buf;
 
1998
            if (lj < j) {
 
1999
                lj++;
 
2000
                while (lj < j)
 
2001
                    gen_opc_instr_start[lj++] = 0;
 
2002
                gen_opc_pc[lj] = ctx.pc;
 
2003
                gen_opc_instr_start[lj] = 1;
 
2004
            }
 
2005
        }
 
2006
#if defined ALPHA_DEBUG_DISAS
 
2007
        insn_count++;
 
2008
        if (logfile != NULL) {
 
2009
            fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
 
2010
                    ctx.pc, ctx.mem_idx);
 
2011
        }
 
2012
#endif
 
2013
        insn = ldl_code(ctx.pc);
 
2014
#if defined ALPHA_DEBUG_DISAS
 
2015
        insn_count++;
 
2016
        if (logfile != NULL) {
 
2017
            fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
 
2018
        }
 
2019
#endif
 
2020
        ctx.pc += 4;
 
2021
        ret = translate_one(ctxp, insn);
 
2022
        if (ret != 0)
 
2023
            break;
 
2024
        /* if we reach a page boundary or are single stepping, stop
 
2025
         * generation
 
2026
         */
 
2027
        if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
 
2028
            (env->singlestep_enabled)) {
 
2029
            break;
 
2030
        }
 
2031
#if defined (DO_SINGLE_STEP)
 
2032
        break;
 
2033
#endif
 
2034
    }
 
2035
    if (ret != 1 && ret != 3) {
 
2036
        gen_update_pc(&ctx);
 
2037
    }
 
2038
    gen_op_reset_T0();
 
2039
#if defined (DO_TB_FLUSH)
 
2040
    gen_op_tb_flush();
 
2041
#endif
 
2042
    /* Generate the return instruction */
 
2043
    gen_op_exit_tb();
 
2044
    *gen_opc_ptr = INDEX_op_end;
 
2045
    if (search_pc) {
 
2046
        j = gen_opc_ptr - gen_opc_buf;
 
2047
        lj++;
 
2048
        while (lj <= j)
 
2049
            gen_opc_instr_start[lj++] = 0;
 
2050
        tb->size = 0;
 
2051
    } else {
 
2052
        tb->size = ctx.pc - pc_start;
 
2053
    }
 
2054
#if defined ALPHA_DEBUG_DISAS
 
2055
    if (loglevel & CPU_LOG_TB_CPU) {
 
2056
        cpu_dump_state(env, logfile, fprintf, 0);
 
2057
    }
 
2058
    if (loglevel & CPU_LOG_TB_IN_ASM) {
 
2059
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
 
2060
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
 
2061
        fprintf(logfile, "\n");
 
2062
    }
 
2063
    if (loglevel & CPU_LOG_TB_OP) {
 
2064
        fprintf(logfile, "OP:\n");
 
2065
        dump_ops(gen_opc_buf, gen_opparam_buf);
 
2066
        fprintf(logfile, "\n");
 
2067
    }
 
2068
#endif
 
2069
 
 
2070
    return 0;
 
2071
}
 
2072
 
 
2073
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
 
2074
{
 
2075
    return gen_intermediate_code_internal(env, tb, 0);
 
2076
}
 
2077
 
 
2078
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
 
2079
{
 
2080
    return gen_intermediate_code_internal(env, tb, 1);
 
2081
}
 
2082
 
 
2083
CPUAlphaState * cpu_alpha_init (void)
 
2084
{
 
2085
    CPUAlphaState *env;
 
2086
    uint64_t hwpcb;
 
2087
 
 
2088
    env = qemu_mallocz(sizeof(CPUAlphaState));
 
2089
    if (!env)
 
2090
        return NULL;
 
2091
    cpu_exec_init(env);
 
2092
    tlb_flush(env, 1);
 
2093
    /* XXX: should not be hardcoded */
 
2094
    env->implver = IMPLVER_2106x;
 
2095
    env->ps = 0x1F00;
 
2096
#if defined (CONFIG_USER_ONLY)
 
2097
    env->ps |= 1 << 3;
 
2098
#endif
 
2099
    pal_init(env);
 
2100
    /* Initialize IPR */
 
2101
    hwpcb = env->ipr[IPR_PCBB];
 
2102
    env->ipr[IPR_ASN] = 0;
 
2103
    env->ipr[IPR_ASTEN] = 0;
 
2104
    env->ipr[IPR_ASTSR] = 0;
 
2105
    env->ipr[IPR_DATFX] = 0;
 
2106
    /* XXX: fix this */
 
2107
    //    env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
 
2108
    //    env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
 
2109
    //    env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
 
2110
    //    env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
 
2111
    env->ipr[IPR_FEN] = 0;
 
2112
    env->ipr[IPR_IPL] = 31;
 
2113
    env->ipr[IPR_MCES] = 0;
 
2114
    env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
 
2115
    //    env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
 
2116
    env->ipr[IPR_SISR] = 0;
 
2117
    env->ipr[IPR_VIRBND] = -1ULL;
 
2118
 
 
2119
    return env;
 
2120
}