~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to target-alpha/translate.c

  • Committer: pbrook
  • Date: 2006-10-22 00:18:54 UTC
  • Revision ID: git-v1:e6e5906b6e0a81718066ca43aef57515026c6624
ColdFire target.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2196 c046a42c-6fe2-441c-8c8c-71466251a162

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
 
#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
 
}