]> git.proxmox.com Git - qemu.git/blame - target-alpha/translate.c
Fix alignment problem with some 64bit load/store instructions
[qemu.git] / target-alpha / translate.c
CommitLineData
4c9649a9
JM
1/*
2 * Alpha emulation cpu translation for qemu.
5fafdf24 3 *
4c9649a9
JM
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"
ae8ecd42 28#include "host-utils.h"
496cb5b9 29#include "helper.h"
57fec1fe 30#include "tcg-op.h"
ca10f867 31#include "qemu-common.h"
4c9649a9
JM
32
33#define DO_SINGLE_STEP
4c9649a9
JM
34#define ALPHA_DEBUG_DISAS
35#define DO_TB_FLUSH
36
37typedef struct DisasContext DisasContext;
38struct DisasContext {
39 uint64_t pc;
40 int mem_idx;
41#if !defined (CONFIG_USER_ONLY)
42 int pal_mode;
43#endif
44 uint32_t amask;
45};
46
3761035f 47/* global register indexes */
b2437bf2 48static TCGv cpu_env;
496cb5b9 49static TCGv cpu_ir[31];
f18cd223 50static TCGv cpu_fir[31];
496cb5b9 51static TCGv cpu_pc;
f4ed8679 52static TCGv cpu_lock;
496cb5b9 53
3761035f 54/* register names */
f18cd223 55static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
2e70f6ef
PB
56
57#include "gen-icount.h"
58
a5f1b965 59static void alpha_translate_init(void)
2e70f6ef 60{
496cb5b9
AJ
61 int i;
62 char *p;
2e70f6ef 63 static int done_init = 0;
496cb5b9 64
2e70f6ef
PB
65 if (done_init)
66 return;
496cb5b9 67
2e70f6ef 68 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
496cb5b9
AJ
69
70 p = cpu_reg_names;
71 for (i = 0; i < 31; i++) {
72 sprintf(p, "ir%d", i);
73 cpu_ir[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
74 offsetof(CPUState, ir[i]), p);
6ba8dcd7 75 p += (i < 10) ? 4 : 5;
f18cd223
AJ
76
77 sprintf(p, "fir%d", i);
78 cpu_fir[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
79 offsetof(CPUState, fir[i]), p);
80 p += (i < 10) ? 5 : 6;
496cb5b9
AJ
81 }
82
83 cpu_pc = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
84 offsetof(CPUState, pc), "pc");
85
f4ed8679
AJ
86 cpu_lock = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
87 offsetof(CPUState, lock), "lock");
88
496cb5b9
AJ
89 /* register helpers */
90#undef DEF_HELPER
91#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
92#include "helper.h"
93
2e70f6ef
PB
94 done_init = 1;
95}
96
f071b4d3
JM
97static always_inline void gen_excp (DisasContext *ctx,
98 int exception, int error_code)
4c9649a9 99{
6ad02592
AJ
100 TCGv tmp1, tmp2;
101
496cb5b9 102 tcg_gen_movi_i64(cpu_pc, ctx->pc);
6ad02592
AJ
103 tmp1 = tcg_const_i32(exception);
104 tmp2 = tcg_const_i32(error_code);
105 tcg_gen_helper_0_2(helper_excp, tmp1, tmp2);
106 tcg_temp_free(tmp2);
107 tcg_temp_free(tmp1);
4c9649a9
JM
108}
109
f071b4d3 110static always_inline void gen_invalid (DisasContext *ctx)
4c9649a9
JM
111{
112 gen_excp(ctx, EXCP_OPCDEC, 0);
113}
114
f18cd223
AJ
115static always_inline void gen_qemu_ldf (TCGv t0, TCGv t1, int flags)
116{
117 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
118 tcg_gen_qemu_ld32u(tmp, t1, flags);
119 tcg_gen_helper_1_1(helper_memory_to_f, t0, tmp);
120 tcg_temp_free(tmp);
121}
122
123static always_inline void gen_qemu_ldg (TCGv t0, TCGv t1, int flags)
124{
125 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
126 tcg_gen_qemu_ld64(tmp, t1, flags);
127 tcg_gen_helper_1_1(helper_memory_to_g, t0, tmp);
128 tcg_temp_free(tmp);
129}
130
131static always_inline void gen_qemu_lds (TCGv t0, TCGv t1, int flags)
132{
133 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
134 tcg_gen_qemu_ld32u(tmp, t1, flags);
135 tcg_gen_helper_1_1(helper_memory_to_s, t0, tmp);
136 tcg_temp_free(tmp);
137}
138
f4ed8679
AJ
139static always_inline void gen_qemu_ldl_l (TCGv t0, TCGv t1, int flags)
140{
141 tcg_gen_mov_i64(cpu_lock, t1);
142 tcg_gen_qemu_ld32s(t0, t1, flags);
143}
144
145static always_inline void gen_qemu_ldq_l (TCGv t0, TCGv t1, int flags)
146{
147 tcg_gen_mov_i64(cpu_lock, t1);
148 tcg_gen_qemu_ld64(t0, t1, flags);
149}
150
023d8ca2
AJ
151static always_inline void gen_load_mem (DisasContext *ctx,
152 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1, int flags),
153 int ra, int rb, int32_t disp16,
f18cd223 154 int fp, int clear)
023d8ca2
AJ
155{
156 TCGv addr;
157
158 if (unlikely(ra == 31))
159 return;
160
161 addr = tcg_temp_new(TCG_TYPE_I64);
162 if (rb != 31) {
163 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
164 if (clear)
165 tcg_gen_andi_i64(addr, addr, ~0x7);
166 } else {
167 if (clear)
168 disp16 &= ~0x7;
169 tcg_gen_movi_i64(addr, disp16);
170 }
f18cd223
AJ
171 if (fp)
172 tcg_gen_qemu_load(cpu_fir[ra], addr, ctx->mem_idx);
173 else
174 tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx);
023d8ca2
AJ
175 tcg_temp_free(addr);
176}
177
f18cd223
AJ
178static always_inline void gen_qemu_stf (TCGv t0, TCGv t1, int flags)
179{
180 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
181 tcg_gen_helper_1_1(helper_f_to_memory, tmp, t0);
182 tcg_gen_qemu_st32(tmp, t1, flags);
183 tcg_temp_free(tmp);
184}
185
186static always_inline void gen_qemu_stg (TCGv t0, TCGv t1, int flags)
187{
188 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
189 tcg_gen_helper_1_1(helper_g_to_memory, tmp, t0);
190 tcg_gen_qemu_st64(tmp, t1, flags);
191 tcg_temp_free(tmp);
192}
193
194static always_inline void gen_qemu_sts (TCGv t0, TCGv t1, int flags)
195{
196 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
197 tcg_gen_helper_1_1(helper_s_to_memory, tmp, t0);
198 tcg_gen_qemu_st32(tmp, t1, flags);
199 tcg_temp_free(tmp);
200}
201
f4ed8679
AJ
202static always_inline void gen_qemu_stl_c (TCGv t0, TCGv t1, int flags)
203{
204 int l1, l2;
205
206 l1 = gen_new_label();
207 l2 = gen_new_label();
208 tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
209 tcg_gen_qemu_st32(t0, t1, flags);
6223246a 210 tcg_gen_movi_i64(t0, 1);
f4ed8679
AJ
211 tcg_gen_br(l2);
212 gen_set_label(l1);
6223246a 213 tcg_gen_movi_i64(t0, 0);
f4ed8679
AJ
214 gen_set_label(l2);
215 tcg_gen_movi_i64(cpu_lock, -1);
216}
217
218static always_inline void gen_qemu_stq_c (TCGv t0, TCGv t1, int flags)
219{
220 int l1, l2;
221
222 l1 = gen_new_label();
223 l2 = gen_new_label();
224 tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
225 tcg_gen_qemu_st64(t0, t1, flags);
6223246a 226 tcg_gen_movi_i64(t0, 1);
f4ed8679
AJ
227 tcg_gen_br(l2);
228 gen_set_label(l1);
6223246a 229 tcg_gen_movi_i64(t0, 0);
f4ed8679
AJ
230 gen_set_label(l2);
231 tcg_gen_movi_i64(cpu_lock, -1);
232}
233
023d8ca2
AJ
234static always_inline void gen_store_mem (DisasContext *ctx,
235 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1, int flags),
236 int ra, int rb, int32_t disp16,
57a92c8e 237 int fp, int clear, int local)
023d8ca2
AJ
238{
239 TCGv addr = tcg_temp_new(TCG_TYPE_I64);
57a92c8e
AJ
240 if (local)
241 addr = tcg_temp_local_new(TCG_TYPE_I64);
242 else
243 addr = tcg_temp_new(TCG_TYPE_I64);
023d8ca2
AJ
244 if (rb != 31) {
245 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
246 if (clear)
247 tcg_gen_andi_i64(addr, addr, ~0x7);
248 } else {
249 if (clear)
250 disp16 &= ~0x7;
251 tcg_gen_movi_i64(addr, disp16);
252 }
f18cd223
AJ
253 if (ra != 31) {
254 if (fp)
255 tcg_gen_qemu_store(cpu_fir[ra], addr, ctx->mem_idx);
256 else
257 tcg_gen_qemu_store(cpu_ir[ra], addr, ctx->mem_idx);
258 } else {
57a92c8e
AJ
259 TCGv zero;
260 if (local)
261 zero = tcg_const_local_i64(0);
262 else
263 zero = tcg_const_i64(0);
023d8ca2
AJ
264 tcg_gen_qemu_store(zero, addr, ctx->mem_idx);
265 tcg_temp_free(zero);
266 }
267 tcg_temp_free(addr);
268}
269
f071b4d3 270static always_inline void gen_bcond (DisasContext *ctx,
9c29504e
AJ
271 TCGCond cond,
272 int ra, int32_t disp16, int mask)
4c9649a9 273{
9c29504e
AJ
274 int l1, l2;
275
276 l1 = gen_new_label();
277 l2 = gen_new_label();
278 if (likely(ra != 31)) {
279 if (mask) {
280 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
281 tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
282 tcg_gen_brcondi_i64(cond, tmp, 0, l1);
283 tcg_temp_free(tmp);
284 } else
285 tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
286 } else {
287 /* Very uncommon case - Do not bother to optimize. */
288 TCGv tmp = tcg_const_i64(0);
289 tcg_gen_brcondi_i64(cond, tmp, 0, l1);
290 tcg_temp_free(tmp);
291 }
292 tcg_gen_movi_i64(cpu_pc, ctx->pc);
293 tcg_gen_br(l2);
294 gen_set_label(l1);
295 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
296 gen_set_label(l2);
4c9649a9
JM
297}
298
f071b4d3 299static always_inline void gen_fbcond (DisasContext *ctx,
f18cd223 300 void* func,
f071b4d3 301 int ra, int32_t disp16)
4c9649a9 302{
f18cd223
AJ
303 int l1, l2;
304 TCGv tmp;
305
306 l1 = gen_new_label();
307 l2 = gen_new_label();
308 if (ra != 31) {
309 tmp = tcg_temp_new(TCG_TYPE_I64);
310 tcg_gen_helper_1_1(func, tmp, cpu_fir[ra]);
311 } else {
312 tmp = tcg_const_i64(0);
313 tcg_gen_helper_1_1(func, tmp, tmp);
314 }
315 tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);
316 tcg_gen_movi_i64(cpu_pc, ctx->pc);
317 tcg_gen_br(l2);
318 gen_set_label(l1);
319 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
320 gen_set_label(l2);
4c9649a9
JM
321}
322
fe2b269a 323static always_inline void gen_cmov (TCGCond inv_cond,
f071b4d3 324 int ra, int rb, int rc,
adf3c8b6 325 int islit, uint8_t lit, int mask)
4c9649a9 326{
9c29504e
AJ
327 int l1;
328
329 if (unlikely(rc == 31))
330 return;
331
332 l1 = gen_new_label();
333
334 if (ra != 31) {
335 if (mask) {
336 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
337 tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
338 tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
339 tcg_temp_free(tmp);
340 } else
341 tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
342 } else {
343 /* Very uncommon case - Do not bother to optimize. */
344 TCGv tmp = tcg_const_i64(0);
345 tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
346 tcg_temp_free(tmp);
347 }
348
4c9649a9 349 if (islit)
9c29504e 350 tcg_gen_movi_i64(cpu_ir[rc], lit);
4c9649a9 351 else
dfaa8583 352 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
9c29504e 353 gen_set_label(l1);
4c9649a9
JM
354}
355
f18cd223 356static always_inline void gen_farith2 (void *helper,
f071b4d3 357 int rb, int rc)
4c9649a9 358{
f18cd223
AJ
359 if (unlikely(rc == 31))
360 return;
361
362 if (rb != 31)
363 tcg_gen_helper_1_1(helper, cpu_fir[rc], cpu_fir[rb]);
364 else {
365 TCGv tmp = tcg_const_i64(0);
366 tcg_gen_helper_1_1(helper, cpu_fir[rc], tmp);
367 tcg_temp_free(tmp);
368 }
4c9649a9
JM
369}
370
f18cd223 371static always_inline void gen_farith3 (void *helper,
f071b4d3 372 int ra, int rb, int rc)
4c9649a9 373{
f18cd223
AJ
374 if (unlikely(rc == 31))
375 return;
376
377 if (ra != 31) {
378 if (rb != 31)
379 tcg_gen_helper_1_2(helper, cpu_fir[rc], cpu_fir[ra], cpu_fir[rb]);
380 else {
381 TCGv tmp = tcg_const_i64(0);
382 tcg_gen_helper_1_2(helper, cpu_fir[rc], cpu_fir[ra], tmp);
383 tcg_temp_free(tmp);
384 }
385 } else {
386 TCGv tmp = tcg_const_i64(0);
387 if (rb != 31)
388 tcg_gen_helper_1_2(helper, cpu_fir[rc], tmp, cpu_fir[rb]);
389 else
390 tcg_gen_helper_1_2(helper, cpu_fir[rc], tmp, tmp);
391 tcg_temp_free(tmp);
392 }
4c9649a9
JM
393}
394
f18cd223 395static always_inline void gen_fcmov (void *func,
f071b4d3 396 int ra, int rb, int rc)
4c9649a9 397{
f18cd223
AJ
398 int l1;
399 TCGv tmp;
4c9649a9 400
f18cd223
AJ
401 if (unlikely(rc == 31))
402 return;
4c9649a9 403
f18cd223
AJ
404 l1 = gen_new_label();
405 tmp = tcg_temp_new(TCG_TYPE_I64);
406 if (ra != 31) {
407 tmp = tcg_temp_new(TCG_TYPE_I64);
408 tcg_gen_helper_1_1(func, tmp, cpu_fir[ra]);
409 } else {
410 tmp = tcg_const_i64(0);
411 tcg_gen_helper_1_1(func, tmp, tmp);
412 }
413 tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1);
414 if (rb != 31)
415 tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
3761035f 416 else
f18cd223
AJ
417 tcg_gen_movi_i64(cpu_fir[rc], 0);
418 gen_set_label(l1);
4c9649a9
JM
419}
420
b3249f63
AJ
421/* EXTWH, EXTWH, EXTLH, EXTQH */
422static always_inline void gen_ext_h(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
423 int ra, int rb, int rc,
adf3c8b6 424 int islit, uint8_t lit)
b3249f63
AJ
425{
426 if (unlikely(rc == 31))
427 return;
428
429 if (ra != 31) {
dfaa8583
AJ
430 if (islit) {
431 if (lit != 0)
432 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 64 - ((lit & 7) * 8));
433 else
434 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
fe2b269a 435 } else {
b3249f63
AJ
436 TCGv tmp1, tmp2;
437 tmp1 = tcg_temp_new(TCG_TYPE_I64);
438 tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
439 tcg_gen_shli_i64(tmp1, tmp1, 3);
440 tmp2 = tcg_const_i64(64);
441 tcg_gen_sub_i64(tmp1, tmp2, tmp1);
442 tcg_temp_free(tmp2);
dfaa8583 443 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
b3249f63 444 tcg_temp_free(tmp1);
dfaa8583
AJ
445 }
446 if (tcg_gen_ext_i64)
447 tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
b3249f63
AJ
448 } else
449 tcg_gen_movi_i64(cpu_ir[rc], 0);
450}
451
452/* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */
453static always_inline void gen_ext_l(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
454 int ra, int rb, int rc,
adf3c8b6 455 int islit, uint8_t lit)
b3249f63
AJ
456{
457 if (unlikely(rc == 31))
458 return;
459
460 if (ra != 31) {
dfaa8583
AJ
461 if (islit) {
462 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
463 } else {
b3249f63
AJ
464 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
465 tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
466 tcg_gen_shli_i64(tmp, tmp, 3);
dfaa8583 467 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
b3249f63 468 tcg_temp_free(tmp);
fe2b269a 469 }
dfaa8583
AJ
470 if (tcg_gen_ext_i64)
471 tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
b3249f63
AJ
472 } else
473 tcg_gen_movi_i64(cpu_ir[rc], 0);
474}
475
04acd307 476/* Code to call arith3 helpers */
fe2b269a
AJ
477static always_inline void gen_arith3 (void *helper,
478 int ra, int rb, int rc,
479 int islit, uint8_t lit)
b3249f63
AJ
480{
481 if (unlikely(rc == 31))
482 return;
483
484 if (ra != 31) {
dfaa8583
AJ
485 if (islit) {
486 TCGv tmp = tcg_const_i64(lit);
b3249f63
AJ
487 tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], tmp);
488 tcg_temp_free(tmp);
489 } else
490 tcg_gen_helper_1_2(helper, cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
04acd307
AJ
491 } else {
492 TCGv tmp1 = tcg_const_i64(0);
493 if (islit) {
494 TCGv tmp2 = tcg_const_i64(lit);
495 tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, tmp2);
496 tcg_temp_free(tmp2);
497 } else
498 tcg_gen_helper_1_2(helper, cpu_ir[rc], tmp1, cpu_ir[rb]);
499 tcg_temp_free(tmp1);
500 }
b3249f63
AJ
501}
502
01ff9cc8
AJ
503static always_inline void gen_cmp(TCGCond cond,
504 int ra, int rb, int rc,
a1cf28f4 505 int islit, uint8_t lit)
01ff9cc8
AJ
506{
507 int l1, l2;
508 TCGv tmp;
509
510 if (unlikely(rc == 31))
511 return;
512
513 l1 = gen_new_label();
514 l2 = gen_new_label();
515
516 if (ra != 31) {
517 tmp = tcg_temp_new(TCG_TYPE_I64);
518 tcg_gen_mov_i64(tmp, cpu_ir[ra]);
519 } else
520 tmp = tcg_const_i64(0);
521 if (islit)
522 tcg_gen_brcondi_i64(cond, tmp, lit, l1);
01ff9cc8 523 else
dfaa8583 524 tcg_gen_brcond_i64(cond, tmp, cpu_ir[rb], l1);
01ff9cc8
AJ
525
526 tcg_gen_movi_i64(cpu_ir[rc], 0);
527 tcg_gen_br(l2);
528 gen_set_label(l1);
529 tcg_gen_movi_i64(cpu_ir[rc], 1);
530 gen_set_label(l2);
531}
532
f071b4d3 533static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
4c9649a9
JM
534{
535 uint32_t palcode;
536 int32_t disp21, disp16, disp12;
537 uint16_t fn11, fn16;
538 uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit;
adf3c8b6 539 uint8_t lit;
4c9649a9
JM
540 int ret;
541
542 /* Decode all instruction fields */
543 opc = insn >> 26;
544 ra = (insn >> 21) & 0x1F;
545 rb = (insn >> 16) & 0x1F;
546 rc = insn & 0x1F;
547 sbz = (insn >> 13) & 0x07;
548 islit = (insn >> 12) & 1;
dfaa8583
AJ
549 if (rb == 31 && !islit) {
550 islit = 1;
551 lit = 0;
552 } else
553 lit = (insn >> 13) & 0xFF;
4c9649a9
JM
554 palcode = insn & 0x03FFFFFF;
555 disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
556 disp16 = (int16_t)(insn & 0x0000FFFF);
557 disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
558 fn16 = insn & 0x0000FFFF;
559 fn11 = (insn >> 5) & 0x000007FF;
560 fpfn = fn11 & 0x3F;
561 fn7 = (insn >> 5) & 0x0000007F;
562 fn2 = (insn >> 5) & 0x00000003;
563 ret = 0;
564#if defined ALPHA_DEBUG_DISAS
565 if (logfile != NULL) {
566 fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n",
567 opc, ra, rb, rc, disp16);
568 }
569#endif
570 switch (opc) {
571 case 0x00:
572 /* CALL_PAL */
573 if (palcode >= 0x80 && palcode < 0xC0) {
574 /* Unprivileged PAL call */
575 gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0);
576#if !defined (CONFIG_USER_ONLY)
577 } else if (palcode < 0x40) {
578 /* Privileged PAL code */
579 if (ctx->mem_idx & 1)
580 goto invalid_opc;
581 else
582 gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0);
583#endif
584 } else {
585 /* Invalid PAL call */
586 goto invalid_opc;
587 }
588 ret = 3;
589 break;
590 case 0x01:
591 /* OPC01 */
592 goto invalid_opc;
593 case 0x02:
594 /* OPC02 */
595 goto invalid_opc;
596 case 0x03:
597 /* OPC03 */
598 goto invalid_opc;
599 case 0x04:
600 /* OPC04 */
601 goto invalid_opc;
602 case 0x05:
603 /* OPC05 */
604 goto invalid_opc;
605 case 0x06:
606 /* OPC06 */
607 goto invalid_opc;
608 case 0x07:
609 /* OPC07 */
610 goto invalid_opc;
611 case 0x08:
612 /* LDA */
1ef4ef4e 613 if (likely(ra != 31)) {
496cb5b9 614 if (rb != 31)
3761035f
AJ
615 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
616 else
617 tcg_gen_movi_i64(cpu_ir[ra], disp16);
496cb5b9 618 }
4c9649a9
JM
619 break;
620 case 0x09:
621 /* LDAH */
1ef4ef4e 622 if (likely(ra != 31)) {
496cb5b9 623 if (rb != 31)
3761035f
AJ
624 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
625 else
626 tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
496cb5b9 627 }
4c9649a9
JM
628 break;
629 case 0x0A:
630 /* LDBU */
631 if (!(ctx->amask & AMASK_BWX))
632 goto invalid_opc;
f18cd223 633 gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
4c9649a9
JM
634 break;
635 case 0x0B:
636 /* LDQ_U */
f18cd223 637 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
4c9649a9
JM
638 break;
639 case 0x0C:
640 /* LDWU */
641 if (!(ctx->amask & AMASK_BWX))
642 goto invalid_opc;
f18cd223 643 gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 1);
4c9649a9
JM
644 break;
645 case 0x0D:
646 /* STW */
57a92c8e 647 gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
648 break;
649 case 0x0E:
650 /* STB */
57a92c8e 651 gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
652 break;
653 case 0x0F:
654 /* STQ_U */
57a92c8e 655 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1, 0);
4c9649a9
JM
656 break;
657 case 0x10:
658 switch (fn7) {
659 case 0x00:
660 /* ADDL */
30c7183b
AJ
661 if (likely(rc != 31)) {
662 if (ra != 31) {
663 if (islit) {
664 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
665 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 666 } else {
30c7183b
AJ
667 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
668 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 669 }
30c7183b
AJ
670 } else {
671 if (islit)
dfaa8583 672 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 673 else
dfaa8583 674 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
675 }
676 }
4c9649a9
JM
677 break;
678 case 0x02:
679 /* S4ADDL */
30c7183b
AJ
680 if (likely(rc != 31)) {
681 if (ra != 31) {
dfaa8583
AJ
682 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
683 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
684 if (islit)
685 tcg_gen_addi_i64(tmp, tmp, lit);
686 else
687 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
688 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
689 tcg_temp_free(tmp);
30c7183b
AJ
690 } else {
691 if (islit)
692 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 693 else
dfaa8583 694 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
695 }
696 }
4c9649a9
JM
697 break;
698 case 0x09:
699 /* SUBL */
30c7183b
AJ
700 if (likely(rc != 31)) {
701 if (ra != 31) {
dfaa8583 702 if (islit)
30c7183b 703 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
dfaa8583 704 else
30c7183b 705 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
dfaa8583 706 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
30c7183b
AJ
707 } else {
708 if (islit)
709 tcg_gen_movi_i64(cpu_ir[rc], -lit);
dfaa8583 710 else {
30c7183b
AJ
711 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
712 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
30c7183b
AJ
713 }
714 }
4c9649a9
JM
715 break;
716 case 0x0B:
717 /* S4SUBL */
30c7183b
AJ
718 if (likely(rc != 31)) {
719 if (ra != 31) {
dfaa8583
AJ
720 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
721 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
722 if (islit)
723 tcg_gen_subi_i64(tmp, tmp, lit);
724 else
725 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
726 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
727 tcg_temp_free(tmp);
30c7183b
AJ
728 } else {
729 if (islit)
730 tcg_gen_movi_i64(cpu_ir[rc], -lit);
dfaa8583 731 else {
30c7183b
AJ
732 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
733 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 734 }
30c7183b
AJ
735 }
736 }
4c9649a9
JM
737 break;
738 case 0x0F:
739 /* CMPBGE */
fe2b269a 740 gen_arith3(helper_cmpbge, ra, rb, rc, islit, lit);
4c9649a9
JM
741 break;
742 case 0x12:
743 /* S8ADDL */
30c7183b
AJ
744 if (likely(rc != 31)) {
745 if (ra != 31) {
dfaa8583
AJ
746 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
747 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
748 if (islit)
749 tcg_gen_addi_i64(tmp, tmp, lit);
750 else
751 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
752 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
753 tcg_temp_free(tmp);
30c7183b
AJ
754 } else {
755 if (islit)
756 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 757 else
dfaa8583 758 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
759 }
760 }
4c9649a9
JM
761 break;
762 case 0x1B:
763 /* S8SUBL */
30c7183b
AJ
764 if (likely(rc != 31)) {
765 if (ra != 31) {
dfaa8583
AJ
766 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
767 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
768 if (islit)
769 tcg_gen_subi_i64(tmp, tmp, lit);
770 else
771 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
772 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
773 tcg_temp_free(tmp);
30c7183b
AJ
774 } else {
775 if (islit)
776 tcg_gen_movi_i64(cpu_ir[rc], -lit);
dfaa8583 777 else
30c7183b
AJ
778 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
779 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 780 }
30c7183b
AJ
781 }
782 }
4c9649a9
JM
783 break;
784 case 0x1D:
785 /* CMPULT */
01ff9cc8 786 gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
4c9649a9
JM
787 break;
788 case 0x20:
789 /* ADDQ */
30c7183b
AJ
790 if (likely(rc != 31)) {
791 if (ra != 31) {
792 if (islit)
793 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
30c7183b 794 else
dfaa8583 795 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
796 } else {
797 if (islit)
798 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 799 else
dfaa8583 800 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
801 }
802 }
4c9649a9
JM
803 break;
804 case 0x22:
805 /* S4ADDQ */
30c7183b
AJ
806 if (likely(rc != 31)) {
807 if (ra != 31) {
dfaa8583
AJ
808 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
809 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
810 if (islit)
811 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
812 else
813 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
814 tcg_temp_free(tmp);
30c7183b
AJ
815 } else {
816 if (islit)
817 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 818 else
dfaa8583 819 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
820 }
821 }
4c9649a9
JM
822 break;
823 case 0x29:
824 /* SUBQ */
30c7183b
AJ
825 if (likely(rc != 31)) {
826 if (ra != 31) {
827 if (islit)
828 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
30c7183b 829 else
dfaa8583 830 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
831 } else {
832 if (islit)
833 tcg_gen_movi_i64(cpu_ir[rc], -lit);
30c7183b 834 else
dfaa8583 835 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
836 }
837 }
4c9649a9
JM
838 break;
839 case 0x2B:
840 /* S4SUBQ */
30c7183b
AJ
841 if (likely(rc != 31)) {
842 if (ra != 31) {
dfaa8583
AJ
843 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
844 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
845 if (islit)
846 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
847 else
848 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
849 tcg_temp_free(tmp);
30c7183b
AJ
850 } else {
851 if (islit)
852 tcg_gen_movi_i64(cpu_ir[rc], -lit);
30c7183b 853 else
dfaa8583 854 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
855 }
856 }
4c9649a9
JM
857 break;
858 case 0x2D:
859 /* CMPEQ */
01ff9cc8 860 gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
4c9649a9
JM
861 break;
862 case 0x32:
863 /* S8ADDQ */
30c7183b
AJ
864 if (likely(rc != 31)) {
865 if (ra != 31) {
dfaa8583
AJ
866 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
867 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
868 if (islit)
869 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
870 else
871 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
872 tcg_temp_free(tmp);
30c7183b
AJ
873 } else {
874 if (islit)
875 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 876 else
dfaa8583 877 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
878 }
879 }
4c9649a9
JM
880 break;
881 case 0x3B:
882 /* S8SUBQ */
30c7183b
AJ
883 if (likely(rc != 31)) {
884 if (ra != 31) {
dfaa8583
AJ
885 TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
886 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
887 if (islit)
888 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
889 else
890 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
891 tcg_temp_free(tmp);
30c7183b
AJ
892 } else {
893 if (islit)
894 tcg_gen_movi_i64(cpu_ir[rc], -lit);
30c7183b 895 else
dfaa8583 896 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
897 }
898 }
4c9649a9
JM
899 break;
900 case 0x3D:
901 /* CMPULE */
01ff9cc8 902 gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
4c9649a9
JM
903 break;
904 case 0x40:
905 /* ADDL/V */
fe2b269a 906 gen_arith3(helper_addlv, ra, rb, rc, islit, lit);
4c9649a9
JM
907 break;
908 case 0x49:
909 /* SUBL/V */
fe2b269a 910 gen_arith3(helper_sublv, ra, rb, rc, islit, lit);
4c9649a9
JM
911 break;
912 case 0x4D:
913 /* CMPLT */
01ff9cc8 914 gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
4c9649a9
JM
915 break;
916 case 0x60:
917 /* ADDQ/V */
fe2b269a 918 gen_arith3(helper_addqv, ra, rb, rc, islit, lit);
4c9649a9
JM
919 break;
920 case 0x69:
921 /* SUBQ/V */
fe2b269a 922 gen_arith3(helper_subqv, ra, rb, rc, islit, lit);
4c9649a9
JM
923 break;
924 case 0x6D:
925 /* CMPLE */
01ff9cc8 926 gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
4c9649a9
JM
927 break;
928 default:
929 goto invalid_opc;
930 }
931 break;
932 case 0x11:
933 switch (fn7) {
934 case 0x00:
935 /* AND */
30c7183b 936 if (likely(rc != 31)) {
dfaa8583 937 if (ra == 31)
30c7183b
AJ
938 tcg_gen_movi_i64(cpu_ir[rc], 0);
939 else if (islit)
940 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
941 else
942 tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
943 }
4c9649a9
JM
944 break;
945 case 0x08:
946 /* BIC */
30c7183b
AJ
947 if (likely(rc != 31)) {
948 if (ra != 31) {
949 if (islit)
950 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1b581c44
AJ
951 else
952 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
953 } else
954 tcg_gen_movi_i64(cpu_ir[rc], 0);
955 }
4c9649a9
JM
956 break;
957 case 0x14:
958 /* CMOVLBS */
fe2b269a 959 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
4c9649a9
JM
960 break;
961 case 0x16:
962 /* CMOVLBC */
fe2b269a 963 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
4c9649a9
JM
964 break;
965 case 0x20:
966 /* BIS */
30c7183b
AJ
967 if (likely(rc != 31)) {
968 if (ra != 31) {
969 if (islit)
970 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
8bb6e981 971 else
30c7183b 972 tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
4c9649a9 973 } else {
30c7183b
AJ
974 if (islit)
975 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 976 else
dfaa8583 977 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
4c9649a9 978 }
4c9649a9
JM
979 }
980 break;
981 case 0x24:
982 /* CMOVEQ */
fe2b269a 983 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
984 break;
985 case 0x26:
986 /* CMOVNE */
fe2b269a 987 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
988 break;
989 case 0x28:
990 /* ORNOT */
30c7183b 991 if (likely(rc != 31)) {
dfaa8583 992 if (ra != 31) {
30c7183b
AJ
993 if (islit)
994 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1b581c44
AJ
995 else
996 tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
997 } else {
998 if (islit)
999 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
1000 else
1001 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
1002 }
1003 }
4c9649a9
JM
1004 break;
1005 case 0x40:
1006 /* XOR */
30c7183b
AJ
1007 if (likely(rc != 31)) {
1008 if (ra != 31) {
1009 if (islit)
1010 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
30c7183b 1011 else
dfaa8583 1012 tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1013 } else {
1014 if (islit)
1015 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1016 else
dfaa8583 1017 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1018 }
1019 }
4c9649a9
JM
1020 break;
1021 case 0x44:
1022 /* CMOVLT */
fe2b269a 1023 gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1024 break;
1025 case 0x46:
1026 /* CMOVGE */
fe2b269a 1027 gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1028 break;
1029 case 0x48:
1030 /* EQV */
30c7183b
AJ
1031 if (likely(rc != 31)) {
1032 if (ra != 31) {
1033 if (islit)
1034 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1b581c44
AJ
1035 else
1036 tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1037 } else {
1038 if (islit)
1039 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
30c7183b 1040 else
dfaa8583 1041 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1042 }
1043 }
4c9649a9
JM
1044 break;
1045 case 0x61:
1046 /* AMASK */
ae8ecd42
AJ
1047 if (likely(rc != 31)) {
1048 if (islit)
1049 tcg_gen_movi_i64(cpu_ir[rc], helper_amask(lit));
ae8ecd42 1050 else
dfaa8583 1051 tcg_gen_helper_1_1(helper_amask, cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 1052 }
4c9649a9
JM
1053 break;
1054 case 0x64:
1055 /* CMOVLE */
fe2b269a 1056 gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1057 break;
1058 case 0x66:
1059 /* CMOVGT */
fe2b269a 1060 gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1061 break;
1062 case 0x6C:
1063 /* IMPLVER */
3761035f 1064 if (rc != 31)
6ad02592 1065 tcg_gen_helper_1_0(helper_load_implver, cpu_ir[rc]);
4c9649a9
JM
1066 break;
1067 default:
1068 goto invalid_opc;
1069 }
1070 break;
1071 case 0x12:
1072 switch (fn7) {
1073 case 0x02:
1074 /* MSKBL */
fe2b269a 1075 gen_arith3(helper_mskbl, ra, rb, rc, islit, lit);
4c9649a9
JM
1076 break;
1077 case 0x06:
1078 /* EXTBL */
b3249f63 1079 gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit);
4c9649a9
JM
1080 break;
1081 case 0x0B:
1082 /* INSBL */
fe2b269a 1083 gen_arith3(helper_insbl, ra, rb, rc, islit, lit);
4c9649a9
JM
1084 break;
1085 case 0x12:
1086 /* MSKWL */
fe2b269a 1087 gen_arith3(helper_mskwl, ra, rb, rc, islit, lit);
4c9649a9
JM
1088 break;
1089 case 0x16:
1090 /* EXTWL */
b3249f63 1091 gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
4c9649a9
JM
1092 break;
1093 case 0x1B:
1094 /* INSWL */
fe2b269a 1095 gen_arith3(helper_inswl, ra, rb, rc, islit, lit);
4c9649a9
JM
1096 break;
1097 case 0x22:
1098 /* MSKLL */
fe2b269a 1099 gen_arith3(helper_mskll, ra, rb, rc, islit, lit);
4c9649a9
JM
1100 break;
1101 case 0x26:
1102 /* EXTLL */
b3249f63 1103 gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
4c9649a9
JM
1104 break;
1105 case 0x2B:
1106 /* INSLL */
fe2b269a 1107 gen_arith3(helper_insll, ra, rb, rc, islit, lit);
4c9649a9
JM
1108 break;
1109 case 0x30:
1110 /* ZAP */
fe2b269a 1111 gen_arith3(helper_zap, ra, rb, rc, islit, lit);
4c9649a9
JM
1112 break;
1113 case 0x31:
1114 /* ZAPNOT */
fe2b269a 1115 gen_arith3(helper_zapnot, ra, rb, rc, islit, lit);
4c9649a9
JM
1116 break;
1117 case 0x32:
1118 /* MSKQL */
fe2b269a 1119 gen_arith3(helper_mskql, ra, rb, rc, islit, lit);
4c9649a9
JM
1120 break;
1121 case 0x34:
1122 /* SRL */
30c7183b
AJ
1123 if (likely(rc != 31)) {
1124 if (ra != 31) {
1125 if (islit)
1126 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
dfaa8583 1127 else {
30c7183b
AJ
1128 TCGv shift = tcg_temp_new(TCG_TYPE_I64);
1129 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1130 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
1131 tcg_temp_free(shift);
dfaa8583 1132 }
30c7183b
AJ
1133 } else
1134 tcg_gen_movi_i64(cpu_ir[rc], 0);
1135 }
4c9649a9
JM
1136 break;
1137 case 0x36:
1138 /* EXTQL */
b3249f63 1139 gen_ext_l(NULL, ra, rb, rc, islit, lit);
4c9649a9
JM
1140 break;
1141 case 0x39:
1142 /* SLL */
30c7183b
AJ
1143 if (likely(rc != 31)) {
1144 if (ra != 31) {
1145 if (islit)
1146 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
dfaa8583 1147 else {
30c7183b
AJ
1148 TCGv shift = tcg_temp_new(TCG_TYPE_I64);
1149 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1150 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
1151 tcg_temp_free(shift);
dfaa8583 1152 }
30c7183b
AJ
1153 } else
1154 tcg_gen_movi_i64(cpu_ir[rc], 0);
1155 }
4c9649a9
JM
1156 break;
1157 case 0x3B:
1158 /* INSQL */
fe2b269a 1159 gen_arith3(helper_insql, ra, rb, rc, islit, lit);
4c9649a9
JM
1160 break;
1161 case 0x3C:
1162 /* SRA */
30c7183b
AJ
1163 if (likely(rc != 31)) {
1164 if (ra != 31) {
1165 if (islit)
1166 tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
dfaa8583 1167 else {
30c7183b
AJ
1168 TCGv shift = tcg_temp_new(TCG_TYPE_I64);
1169 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1170 tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
1171 tcg_temp_free(shift);
dfaa8583 1172 }
30c7183b
AJ
1173 } else
1174 tcg_gen_movi_i64(cpu_ir[rc], 0);
1175 }
4c9649a9
JM
1176 break;
1177 case 0x52:
1178 /* MSKWH */
fe2b269a 1179 gen_arith3(helper_mskwh, ra, rb, rc, islit, lit);
4c9649a9
JM
1180 break;
1181 case 0x57:
1182 /* INSWH */
fe2b269a 1183 gen_arith3(helper_inswh, ra, rb, rc, islit, lit);
4c9649a9
JM
1184 break;
1185 case 0x5A:
1186 /* EXTWH */
b3249f63 1187 gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
4c9649a9
JM
1188 break;
1189 case 0x62:
1190 /* MSKLH */
fe2b269a 1191 gen_arith3(helper_msklh, ra, rb, rc, islit, lit);
4c9649a9
JM
1192 break;
1193 case 0x67:
1194 /* INSLH */
fe2b269a 1195 gen_arith3(helper_inslh, ra, rb, rc, islit, lit);
4c9649a9
JM
1196 break;
1197 case 0x6A:
1198 /* EXTLH */
b3249f63 1199 gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
4c9649a9
JM
1200 break;
1201 case 0x72:
1202 /* MSKQH */
fe2b269a 1203 gen_arith3(helper_mskqh, ra, rb, rc, islit, lit);
4c9649a9
JM
1204 break;
1205 case 0x77:
1206 /* INSQH */
fe2b269a 1207 gen_arith3(helper_insqh, ra, rb, rc, islit, lit);
4c9649a9
JM
1208 break;
1209 case 0x7A:
1210 /* EXTQH */
b3249f63 1211 gen_ext_h(NULL, ra, rb, rc, islit, lit);
4c9649a9
JM
1212 break;
1213 default:
1214 goto invalid_opc;
1215 }
1216 break;
1217 case 0x13:
1218 switch (fn7) {
1219 case 0x00:
1220 /* MULL */
30c7183b 1221 if (likely(rc != 31)) {
dfaa8583 1222 if (ra == 31)
30c7183b
AJ
1223 tcg_gen_movi_i64(cpu_ir[rc], 0);
1224 else {
1225 if (islit)
1226 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1227 else
1228 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1229 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1230 }
1231 }
4c9649a9
JM
1232 break;
1233 case 0x20:
1234 /* MULQ */
30c7183b 1235 if (likely(rc != 31)) {
dfaa8583 1236 if (ra == 31)
30c7183b
AJ
1237 tcg_gen_movi_i64(cpu_ir[rc], 0);
1238 else if (islit)
1239 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1240 else
1241 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1242 }
4c9649a9
JM
1243 break;
1244 case 0x30:
1245 /* UMULH */
fe2b269a 1246 gen_arith3(helper_umulh, ra, rb, rc, islit, lit);
4c9649a9
JM
1247 break;
1248 case 0x40:
1249 /* MULL/V */
fe2b269a 1250 gen_arith3(helper_mullv, ra, rb, rc, islit, lit);
4c9649a9
JM
1251 break;
1252 case 0x60:
1253 /* MULQ/V */
fe2b269a 1254 gen_arith3(helper_mulqv, ra, rb, rc, islit, lit);
4c9649a9
JM
1255 break;
1256 default:
1257 goto invalid_opc;
1258 }
1259 break;
1260 case 0x14:
1261 switch (fpfn) { /* f11 & 0x3F */
1262 case 0x04:
1263 /* ITOFS */
1264 if (!(ctx->amask & AMASK_FIX))
1265 goto invalid_opc;
f18cd223
AJ
1266 if (likely(rc != 31)) {
1267 if (ra != 31) {
1268 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1269 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
1270 tcg_gen_helper_1_1(helper_memory_to_s, cpu_fir[rc], tmp);
1271 tcg_temp_free(tmp);
1272 } else
1273 tcg_gen_movi_i64(cpu_fir[rc], 0);
1274 }
4c9649a9
JM
1275 break;
1276 case 0x0A:
1277 /* SQRTF */
1278 if (!(ctx->amask & AMASK_FIX))
1279 goto invalid_opc;
f18cd223 1280 gen_farith2(&helper_sqrtf, rb, rc);
4c9649a9
JM
1281 break;
1282 case 0x0B:
1283 /* SQRTS */
1284 if (!(ctx->amask & AMASK_FIX))
1285 goto invalid_opc;
f18cd223 1286 gen_farith2(&helper_sqrts, rb, rc);
4c9649a9
JM
1287 break;
1288 case 0x14:
1289 /* ITOFF */
1290 if (!(ctx->amask & AMASK_FIX))
1291 goto invalid_opc;
f18cd223
AJ
1292 if (likely(rc != 31)) {
1293 if (ra != 31) {
1294 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1295 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
1296 tcg_gen_helper_1_1(helper_memory_to_f, cpu_fir[rc], tmp);
1297 tcg_temp_free(tmp);
1298 } else
1299 tcg_gen_movi_i64(cpu_fir[rc], 0);
1300 }
4c9649a9
JM
1301 break;
1302 case 0x24:
1303 /* ITOFT */
1304 if (!(ctx->amask & AMASK_FIX))
1305 goto invalid_opc;
f18cd223
AJ
1306 if (likely(rc != 31)) {
1307 if (ra != 31)
1308 tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
1309 else
1310 tcg_gen_movi_i64(cpu_fir[rc], 0);
1311 }
4c9649a9
JM
1312 break;
1313 case 0x2A:
1314 /* SQRTG */
1315 if (!(ctx->amask & AMASK_FIX))
1316 goto invalid_opc;
f18cd223 1317 gen_farith2(&helper_sqrtg, rb, rc);
4c9649a9
JM
1318 break;
1319 case 0x02B:
1320 /* SQRTT */
1321 if (!(ctx->amask & AMASK_FIX))
1322 goto invalid_opc;
f18cd223 1323 gen_farith2(&helper_sqrtt, rb, rc);
4c9649a9
JM
1324 break;
1325 default:
1326 goto invalid_opc;
1327 }
1328 break;
1329 case 0x15:
1330 /* VAX floating point */
1331 /* XXX: rounding mode and trap are ignored (!) */
1332 switch (fpfn) { /* f11 & 0x3F */
1333 case 0x00:
1334 /* ADDF */
f18cd223 1335 gen_farith3(&helper_addf, ra, rb, rc);
4c9649a9
JM
1336 break;
1337 case 0x01:
1338 /* SUBF */
f18cd223 1339 gen_farith3(&helper_subf, ra, rb, rc);
4c9649a9
JM
1340 break;
1341 case 0x02:
1342 /* MULF */
f18cd223 1343 gen_farith3(&helper_mulf, ra, rb, rc);
4c9649a9
JM
1344 break;
1345 case 0x03:
1346 /* DIVF */
f18cd223 1347 gen_farith3(&helper_divf, ra, rb, rc);
4c9649a9
JM
1348 break;
1349 case 0x1E:
1350 /* CVTDG */
1351#if 0 // TODO
f18cd223 1352 gen_farith2(&helper_cvtdg, rb, rc);
4c9649a9
JM
1353#else
1354 goto invalid_opc;
1355#endif
1356 break;
1357 case 0x20:
1358 /* ADDG */
f18cd223 1359 gen_farith3(&helper_addg, ra, rb, rc);
4c9649a9
JM
1360 break;
1361 case 0x21:
1362 /* SUBG */
f18cd223 1363 gen_farith3(&helper_subg, ra, rb, rc);
4c9649a9
JM
1364 break;
1365 case 0x22:
1366 /* MULG */
f18cd223 1367 gen_farith3(&helper_mulg, ra, rb, rc);
4c9649a9
JM
1368 break;
1369 case 0x23:
1370 /* DIVG */
f18cd223 1371 gen_farith3(&helper_divg, ra, rb, rc);
4c9649a9
JM
1372 break;
1373 case 0x25:
1374 /* CMPGEQ */
f18cd223 1375 gen_farith3(&helper_cmpgeq, ra, rb, rc);
4c9649a9
JM
1376 break;
1377 case 0x26:
1378 /* CMPGLT */
f18cd223 1379 gen_farith3(&helper_cmpglt, ra, rb, rc);
4c9649a9
JM
1380 break;
1381 case 0x27:
1382 /* CMPGLE */
f18cd223 1383 gen_farith3(&helper_cmpgle, ra, rb, rc);
4c9649a9
JM
1384 break;
1385 case 0x2C:
1386 /* CVTGF */
f18cd223 1387 gen_farith2(&helper_cvtgf, rb, rc);
4c9649a9
JM
1388 break;
1389 case 0x2D:
1390 /* CVTGD */
1391#if 0 // TODO
f18cd223 1392 gen_farith2(ctx, &helper_cvtgd, rb, rc);
4c9649a9
JM
1393#else
1394 goto invalid_opc;
1395#endif
1396 break;
1397 case 0x2F:
1398 /* CVTGQ */
f18cd223 1399 gen_farith2(&helper_cvtgq, rb, rc);
4c9649a9
JM
1400 break;
1401 case 0x3C:
1402 /* CVTQF */
f18cd223 1403 gen_farith2(&helper_cvtqf, rb, rc);
4c9649a9
JM
1404 break;
1405 case 0x3E:
1406 /* CVTQG */
f18cd223 1407 gen_farith2(&helper_cvtqg, rb, rc);
4c9649a9
JM
1408 break;
1409 default:
1410 goto invalid_opc;
1411 }
1412 break;
1413 case 0x16:
1414 /* IEEE floating-point */
1415 /* XXX: rounding mode and traps are ignored (!) */
1416 switch (fpfn) { /* f11 & 0x3F */
1417 case 0x00:
1418 /* ADDS */
f18cd223 1419 gen_farith3(&helper_adds, ra, rb, rc);
4c9649a9
JM
1420 break;
1421 case 0x01:
1422 /* SUBS */
f18cd223 1423 gen_farith3(&helper_subs, ra, rb, rc);
4c9649a9
JM
1424 break;
1425 case 0x02:
1426 /* MULS */
f18cd223 1427 gen_farith3(&helper_muls, ra, rb, rc);
4c9649a9
JM
1428 break;
1429 case 0x03:
1430 /* DIVS */
f18cd223 1431 gen_farith3(&helper_divs, ra, rb, rc);
4c9649a9
JM
1432 break;
1433 case 0x20:
1434 /* ADDT */
f18cd223 1435 gen_farith3(&helper_addt, ra, rb, rc);
4c9649a9
JM
1436 break;
1437 case 0x21:
1438 /* SUBT */
f18cd223 1439 gen_farith3(&helper_subt, ra, rb, rc);
4c9649a9
JM
1440 break;
1441 case 0x22:
1442 /* MULT */
f18cd223 1443 gen_farith3(&helper_mult, ra, rb, rc);
4c9649a9
JM
1444 break;
1445 case 0x23:
1446 /* DIVT */
f18cd223 1447 gen_farith3(&helper_divt, ra, rb, rc);
4c9649a9
JM
1448 break;
1449 case 0x24:
1450 /* CMPTUN */
f18cd223 1451 gen_farith3(&helper_cmptun, ra, rb, rc);
4c9649a9
JM
1452 break;
1453 case 0x25:
1454 /* CMPTEQ */
f18cd223 1455 gen_farith3(&helper_cmpteq, ra, rb, rc);
4c9649a9
JM
1456 break;
1457 case 0x26:
1458 /* CMPTLT */
f18cd223 1459 gen_farith3(&helper_cmptlt, ra, rb, rc);
4c9649a9
JM
1460 break;
1461 case 0x27:
1462 /* CMPTLE */
f18cd223 1463 gen_farith3(&helper_cmptle, ra, rb, rc);
4c9649a9
JM
1464 break;
1465 case 0x2C:
1466 /* XXX: incorrect */
1467 if (fn11 == 0x2AC) {
1468 /* CVTST */
f18cd223 1469 gen_farith2(&helper_cvtst, rb, rc);
4c9649a9
JM
1470 } else {
1471 /* CVTTS */
f18cd223 1472 gen_farith2(&helper_cvtts, rb, rc);
4c9649a9
JM
1473 }
1474 break;
1475 case 0x2F:
1476 /* CVTTQ */
f18cd223 1477 gen_farith2(&helper_cvttq, rb, rc);
4c9649a9
JM
1478 break;
1479 case 0x3C:
1480 /* CVTQS */
f18cd223 1481 gen_farith2(&helper_cvtqs, rb, rc);
4c9649a9
JM
1482 break;
1483 case 0x3E:
1484 /* CVTQT */
f18cd223 1485 gen_farith2(&helper_cvtqt, rb, rc);
4c9649a9
JM
1486 break;
1487 default:
1488 goto invalid_opc;
1489 }
1490 break;
1491 case 0x17:
1492 switch (fn11) {
1493 case 0x010:
1494 /* CVTLQ */
f18cd223 1495 gen_farith2(&helper_cvtlq, rb, rc);
4c9649a9
JM
1496 break;
1497 case 0x020:
f18cd223
AJ
1498 if (likely(rc != 31)) {
1499 if (ra == rb)
4c9649a9 1500 /* FMOV */
f18cd223
AJ
1501 tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
1502 else
1503 /* CPYS */
1504 gen_farith3(&helper_cpys, ra, rb, rc);
4c9649a9
JM
1505 }
1506 break;
1507 case 0x021:
1508 /* CPYSN */
f18cd223 1509 gen_farith3(&helper_cpysn, ra, rb, rc);
4c9649a9
JM
1510 break;
1511 case 0x022:
1512 /* CPYSE */
f18cd223 1513 gen_farith3(&helper_cpyse, ra, rb, rc);
4c9649a9
JM
1514 break;
1515 case 0x024:
1516 /* MT_FPCR */
f18cd223
AJ
1517 if (likely(ra != 31))
1518 tcg_gen_helper_0_1(helper_store_fpcr, cpu_fir[ra]);
1519 else {
1520 TCGv tmp = tcg_const_i64(0);
1521 tcg_gen_helper_0_1(helper_store_fpcr, tmp);
1522 tcg_temp_free(tmp);
1523 }
4c9649a9
JM
1524 break;
1525 case 0x025:
1526 /* MF_FPCR */
f18cd223
AJ
1527 if (likely(ra != 31))
1528 tcg_gen_helper_1_0(helper_load_fpcr, cpu_fir[ra]);
4c9649a9
JM
1529 break;
1530 case 0x02A:
1531 /* FCMOVEQ */
f18cd223 1532 gen_fcmov(&helper_cmpfeq, ra, rb, rc);
4c9649a9
JM
1533 break;
1534 case 0x02B:
1535 /* FCMOVNE */
f18cd223 1536 gen_fcmov(&helper_cmpfne, ra, rb, rc);
4c9649a9
JM
1537 break;
1538 case 0x02C:
1539 /* FCMOVLT */
f18cd223 1540 gen_fcmov(&helper_cmpflt, ra, rb, rc);
4c9649a9
JM
1541 break;
1542 case 0x02D:
1543 /* FCMOVGE */
f18cd223 1544 gen_fcmov(&helper_cmpfge, ra, rb, rc);
4c9649a9
JM
1545 break;
1546 case 0x02E:
1547 /* FCMOVLE */
f18cd223 1548 gen_fcmov(&helper_cmpfle, ra, rb, rc);
4c9649a9
JM
1549 break;
1550 case 0x02F:
1551 /* FCMOVGT */
f18cd223 1552 gen_fcmov(&helper_cmpfgt, ra, rb, rc);
4c9649a9
JM
1553 break;
1554 case 0x030:
1555 /* CVTQL */
f18cd223 1556 gen_farith2(&helper_cvtql, rb, rc);
4c9649a9
JM
1557 break;
1558 case 0x130:
1559 /* CVTQL/V */
f18cd223 1560 gen_farith2(&helper_cvtqlv, rb, rc);
4c9649a9
JM
1561 break;
1562 case 0x530:
1563 /* CVTQL/SV */
f18cd223 1564 gen_farith2(&helper_cvtqlsv, rb, rc);
4c9649a9
JM
1565 break;
1566 default:
1567 goto invalid_opc;
1568 }
1569 break;
1570 case 0x18:
1571 switch ((uint16_t)disp16) {
1572 case 0x0000:
1573 /* TRAPB */
1574 /* No-op. Just exit from the current tb */
1575 ret = 2;
1576 break;
1577 case 0x0400:
1578 /* EXCB */
1579 /* No-op. Just exit from the current tb */
1580 ret = 2;
1581 break;
1582 case 0x4000:
1583 /* MB */
1584 /* No-op */
1585 break;
1586 case 0x4400:
1587 /* WMB */
1588 /* No-op */
1589 break;
1590 case 0x8000:
1591 /* FETCH */
1592 /* No-op */
1593 break;
1594 case 0xA000:
1595 /* FETCH_M */
1596 /* No-op */
1597 break;
1598 case 0xC000:
1599 /* RPCC */
3761035f 1600 if (ra != 31)
6ad02592 1601 tcg_gen_helper_1_0(helper_load_pcc, cpu_ir[ra]);
4c9649a9
JM
1602 break;
1603 case 0xE000:
1604 /* RC */
3761035f 1605 if (ra != 31)
6ad02592 1606 tcg_gen_helper_1_0(helper_rc, cpu_ir[ra]);
4c9649a9
JM
1607 break;
1608 case 0xE800:
1609 /* ECB */
1610 /* XXX: TODO: evict tb cache at address rb */
1611#if 0
1612 ret = 2;
1613#else
1614 goto invalid_opc;
1615#endif
1616 break;
1617 case 0xF000:
1618 /* RS */
3761035f 1619 if (ra != 31)
6ad02592 1620 tcg_gen_helper_1_0(helper_rs, cpu_ir[ra]);
4c9649a9
JM
1621 break;
1622 case 0xF800:
1623 /* WH64 */
1624 /* No-op */
1625 break;
1626 default:
1627 goto invalid_opc;
1628 }
1629 break;
1630 case 0x19:
1631 /* HW_MFPR (PALcode) */
1632#if defined (CONFIG_USER_ONLY)
1633 goto invalid_opc;
1634#else
1635 if (!ctx->pal_mode)
1636 goto invalid_opc;
8bb6e981
AJ
1637 if (ra != 31) {
1638 TCGv tmp = tcg_const_i32(insn & 0xFF);
1639 tcg_gen_helper_1_2(helper_mfpr, cpu_ir[ra], tmp, cpu_ir[ra]);
1640 tcg_temp_free(tmp);
1641 }
4c9649a9
JM
1642 break;
1643#endif
1644 case 0x1A:
3761035f
AJ
1645 if (rb != 31)
1646 tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
1647 else
1648 tcg_gen_movi_i64(cpu_pc, 0);
1304ca87
AJ
1649 if (ra != 31)
1650 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
4c9649a9
JM
1651 /* Those four jumps only differ by the branch prediction hint */
1652 switch (fn2) {
1653 case 0x0:
1654 /* JMP */
1655 break;
1656 case 0x1:
1657 /* JSR */
1658 break;
1659 case 0x2:
1660 /* RET */
1661 break;
1662 case 0x3:
1663 /* JSR_COROUTINE */
1664 break;
1665 }
1666 ret = 1;
1667 break;
1668 case 0x1B:
1669 /* HW_LD (PALcode) */
1670#if defined (CONFIG_USER_ONLY)
1671 goto invalid_opc;
1672#else
1673 if (!ctx->pal_mode)
1674 goto invalid_opc;
8bb6e981
AJ
1675 if (ra != 31) {
1676 TCGv addr = tcg_temp_new(TCG_TYPE_I64);
1677 if (rb != 31)
1678 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
1679 else
1680 tcg_gen_movi_i64(addr, disp12);
1681 switch ((insn >> 12) & 0xF) {
1682 case 0x0:
1683 /* Longword physical access */
1684 tcg_gen_helper_0_2(helper_ldl_raw, cpu_ir[ra], addr);
1685 break;
1686 case 0x1:
1687 /* Quadword physical access */
1688 tcg_gen_helper_0_2(helper_ldq_raw, cpu_ir[ra], addr);
1689 break;
1690 case 0x2:
1691 /* Longword physical access with lock */
1692 tcg_gen_helper_0_2(helper_ldl_l_raw, cpu_ir[ra], addr);
1693 break;
1694 case 0x3:
1695 /* Quadword physical access with lock */
1696 tcg_gen_helper_0_2(helper_ldq_l_raw, cpu_ir[ra], addr);
1697 break;
1698 case 0x4:
1699 /* Longword virtual PTE fetch */
1700 tcg_gen_helper_0_2(helper_ldl_kernel, cpu_ir[ra], addr);
1701 break;
1702 case 0x5:
1703 /* Quadword virtual PTE fetch */
1704 tcg_gen_helper_0_2(helper_ldq_kernel, cpu_ir[ra], addr);
1705 break;
1706 case 0x6:
1707 /* Incpu_ir[ra]id */
1708 goto incpu_ir[ra]id_opc;
1709 case 0x7:
1710 /* Incpu_ir[ra]id */
1711 goto incpu_ir[ra]id_opc;
1712 case 0x8:
1713 /* Longword virtual access */
1714 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
1715 tcg_gen_helper_0_2(helper_ldl_raw, cpu_ir[ra], addr);
1716 break;
1717 case 0x9:
1718 /* Quadword virtual access */
1719 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
1720 tcg_gen_helper_0_2(helper_ldq_raw, cpu_ir[ra], addr);
1721 break;
1722 case 0xA:
1723 /* Longword virtual access with protection check */
1724 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, ctx->flags);
1725 break;
1726 case 0xB:
1727 /* Quadword virtual access with protection check */
1728 tcg_gen_qemu_ld64(cpu_ir[ra], addr, ctx->flags);
1729 break;
1730 case 0xC:
1731 /* Longword virtual access with altenate access mode */
1732 tcg_gen_helper_0_0(helper_set_alt_mode);
1733 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
1734 tcg_gen_helper_0_2(helper_ldl_raw, cpu_ir[ra], addr);
1735 tcg_gen_helper_0_0(helper_restore_mode);
1736 break;
1737 case 0xD:
1738 /* Quadword virtual access with altenate access mode */
1739 tcg_gen_helper_0_0(helper_set_alt_mode);
1740 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
1741 tcg_gen_helper_0_2(helper_ldq_raw, cpu_ir[ra], addr);
1742 tcg_gen_helper_0_0(helper_restore_mode);
1743 break;
1744 case 0xE:
1745 /* Longword virtual access with alternate access mode and
1746 * protection checks
1747 */
1748 tcg_gen_helper_0_0(helper_set_alt_mode);
1749 tcg_gen_helper_0_2(helper_ldl_data, cpu_ir[ra], addr);
1750 tcg_gen_helper_0_0(helper_restore_mode);
1751 break;
1752 case 0xF:
1753 /* Quadword virtual access with alternate access mode and
1754 * protection checks
1755 */
1756 tcg_gen_helper_0_0(helper_set_alt_mode);
1757 tcg_gen_helper_0_2(helper_ldq_data, cpu_ir[ra], addr);
1758 tcg_gen_helper_0_0(helper_restore_mode);
1759 break;
1760 }
1761 tcg_temp_free(addr);
4c9649a9 1762 }
4c9649a9
JM
1763 break;
1764#endif
1765 case 0x1C:
1766 switch (fn7) {
1767 case 0x00:
1768 /* SEXTB */
1769 if (!(ctx->amask & AMASK_BWX))
1770 goto invalid_opc;
ae8ecd42
AJ
1771 if (likely(rc != 31)) {
1772 if (islit)
1773 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
ae8ecd42 1774 else
dfaa8583 1775 tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 1776 }
4c9649a9
JM
1777 break;
1778 case 0x01:
1779 /* SEXTW */
1780 if (!(ctx->amask & AMASK_BWX))
1781 goto invalid_opc;
ae8ecd42
AJ
1782 if (likely(rc != 31)) {
1783 if (islit)
1784 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
ae8ecd42 1785 else
dfaa8583 1786 tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 1787 }
4c9649a9
JM
1788 break;
1789 case 0x30:
1790 /* CTPOP */
1791 if (!(ctx->amask & AMASK_CIX))
1792 goto invalid_opc;
ae8ecd42
AJ
1793 if (likely(rc != 31)) {
1794 if (islit)
1795 tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
ae8ecd42 1796 else
dfaa8583 1797 tcg_gen_helper_1_1(helper_ctpop, cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 1798 }
4c9649a9
JM
1799 break;
1800 case 0x31:
1801 /* PERR */
1802 if (!(ctx->amask & AMASK_MVI))
1803 goto invalid_opc;
1804 /* XXX: TODO */
1805 goto invalid_opc;
1806 break;
1807 case 0x32:
1808 /* CTLZ */
1809 if (!(ctx->amask & AMASK_CIX))
1810 goto invalid_opc;
ae8ecd42
AJ
1811 if (likely(rc != 31)) {
1812 if (islit)
1813 tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
ae8ecd42 1814 else
dfaa8583 1815 tcg_gen_helper_1_1(helper_ctlz, cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 1816 }
4c9649a9
JM
1817 break;
1818 case 0x33:
1819 /* CTTZ */
1820 if (!(ctx->amask & AMASK_CIX))
1821 goto invalid_opc;
ae8ecd42
AJ
1822 if (likely(rc != 31)) {
1823 if (islit)
1824 tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
ae8ecd42 1825 else
dfaa8583 1826 tcg_gen_helper_1_1(helper_cttz, cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 1827 }
4c9649a9
JM
1828 break;
1829 case 0x34:
1830 /* UNPKBW */
1831 if (!(ctx->amask & AMASK_MVI))
1832 goto invalid_opc;
1833 /* XXX: TODO */
1834 goto invalid_opc;
1835 break;
1836 case 0x35:
1837 /* UNPKWL */
1838 if (!(ctx->amask & AMASK_MVI))
1839 goto invalid_opc;
1840 /* XXX: TODO */
1841 goto invalid_opc;
1842 break;
1843 case 0x36:
1844 /* PKWB */
1845 if (!(ctx->amask & AMASK_MVI))
1846 goto invalid_opc;
1847 /* XXX: TODO */
1848 goto invalid_opc;
1849 break;
1850 case 0x37:
1851 /* PKLB */
1852 if (!(ctx->amask & AMASK_MVI))
1853 goto invalid_opc;
1854 /* XXX: TODO */
1855 goto invalid_opc;
1856 break;
1857 case 0x38:
1858 /* MINSB8 */
1859 if (!(ctx->amask & AMASK_MVI))
1860 goto invalid_opc;
1861 /* XXX: TODO */
1862 goto invalid_opc;
1863 break;
1864 case 0x39:
1865 /* MINSW4 */
1866 if (!(ctx->amask & AMASK_MVI))
1867 goto invalid_opc;
1868 /* XXX: TODO */
1869 goto invalid_opc;
1870 break;
1871 case 0x3A:
1872 /* MINUB8 */
1873 if (!(ctx->amask & AMASK_MVI))
1874 goto invalid_opc;
1875 /* XXX: TODO */
1876 goto invalid_opc;
1877 break;
1878 case 0x3B:
1879 /* MINUW4 */
1880 if (!(ctx->amask & AMASK_MVI))
1881 goto invalid_opc;
1882 /* XXX: TODO */
1883 goto invalid_opc;
1884 break;
1885 case 0x3C:
1886 /* MAXUB8 */
1887 if (!(ctx->amask & AMASK_MVI))
1888 goto invalid_opc;
1889 /* XXX: TODO */
1890 goto invalid_opc;
1891 break;
1892 case 0x3D:
1893 /* MAXUW4 */
1894 if (!(ctx->amask & AMASK_MVI))
1895 goto invalid_opc;
1896 /* XXX: TODO */
1897 goto invalid_opc;
1898 break;
1899 case 0x3E:
1900 /* MAXSB8 */
1901 if (!(ctx->amask & AMASK_MVI))
1902 goto invalid_opc;
1903 /* XXX: TODO */
1904 goto invalid_opc;
1905 break;
1906 case 0x3F:
1907 /* MAXSW4 */
1908 if (!(ctx->amask & AMASK_MVI))
1909 goto invalid_opc;
1910 /* XXX: TODO */
1911 goto invalid_opc;
1912 break;
1913 case 0x70:
1914 /* FTOIT */
1915 if (!(ctx->amask & AMASK_FIX))
1916 goto invalid_opc;
f18cd223
AJ
1917 if (likely(rc != 31)) {
1918 if (ra != 31)
1919 tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
1920 else
1921 tcg_gen_movi_i64(cpu_ir[rc], 0);
1922 }
4c9649a9
JM
1923 break;
1924 case 0x78:
1925 /* FTOIS */
1926 if (!(ctx->amask & AMASK_FIX))
1927 goto invalid_opc;
f18cd223
AJ
1928 if (rc != 31) {
1929 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
1930 if (ra != 31)
1931 tcg_gen_helper_1_1(helper_s_to_memory, tmp1, cpu_fir[ra]);
1932 else {
1933 TCGv tmp2 = tcg_const_i64(0);
1934 tcg_gen_helper_1_1(helper_s_to_memory, tmp1, tmp2);
1935 tcg_temp_free(tmp2);
1936 }
1937 tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
1938 tcg_temp_free(tmp1);
1939 }
4c9649a9
JM
1940 break;
1941 default:
1942 goto invalid_opc;
1943 }
1944 break;
1945 case 0x1D:
1946 /* HW_MTPR (PALcode) */
1947#if defined (CONFIG_USER_ONLY)
1948 goto invalid_opc;
1949#else
1950 if (!ctx->pal_mode)
1951 goto invalid_opc;
8bb6e981
AJ
1952 else {
1953 TCGv tmp1 = tcg_const_i32(insn & 0xFF);
1954 if (ra != 31)
1955 tcg_gen_helper(helper_mtpr, tmp1, cpu_ir[ra]);
1956 else {
1957 TCGv tmp2 = tcg_const_i64(0);
1958 tcg_gen_helper(helper_mtpr, tmp1, tmp2);
1959 tcg_temp_free(tmp2);
1960 }
1961 tcg_temp_free(tmp1);
1962 ret = 2;
1963 }
4c9649a9
JM
1964 break;
1965#endif
1966 case 0x1E:
1967 /* HW_REI (PALcode) */
1968#if defined (CONFIG_USER_ONLY)
1969 goto invalid_opc;
1970#else
1971 if (!ctx->pal_mode)
1972 goto invalid_opc;
1973 if (rb == 31) {
1974 /* "Old" alpha */
8bb6e981 1975 tcg_gen_helper_0_0(helper_hw_rei);
4c9649a9 1976 } else {
8bb6e981
AJ
1977 TCGv tmp;
1978
1979 if (ra != 31) {
1980 tmp = tcg_temp_new(TCG_TYPE_I64);
1981 tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51));
1982 } else
1983 tmp = tcg_const_i64(((int64_t)insn << 51) >> 51);
1984 tcg_gen_helper_0_1(helper_hw_ret, tmp);
1985 tcg_temp_free(tmp);
4c9649a9
JM
1986 }
1987 ret = 2;
1988 break;
1989#endif
1990 case 0x1F:
1991 /* HW_ST (PALcode) */
1992#if defined (CONFIG_USER_ONLY)
1993 goto invalid_opc;
1994#else
1995 if (!ctx->pal_mode)
1996 goto invalid_opc;
8bb6e981
AJ
1997 else {
1998 TCGv addr, val;
1999 addr = tcg_temp_new(TCG_TYPE_I64);
2000 if (rb != 31)
2001 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2002 else
2003 tcg_gen_movi_i64(addr, disp12);
2004 if (ra != 31)
2005 val = cpu_ir[ra];
2006 else {
2007 val = tcg_temp_new(TCG_TYPE_I64);
2008 tcg_gen_movi_i64(val, 0);
2009 }
2010 switch ((insn >> 12) & 0xF) {
2011 case 0x0:
2012 /* Longword physical access */
2013 tcg_gen_helper_0_2(helper_stl_raw, val, addr);
2014 break;
2015 case 0x1:
2016 /* Quadword physical access */
2017 tcg_gen_helper_0_2(helper_stq_raw, val, addr);
2018 break;
2019 case 0x2:
2020 /* Longword physical access with lock */
2021 tcg_gen_helper_1_2(helper_stl_c_raw, val, val, addr);
2022 break;
2023 case 0x3:
2024 /* Quadword physical access with lock */
2025 tcg_gen_helper_1_2(helper_stq_c_raw, val, val, addr);
2026 break;
2027 case 0x4:
2028 /* Longword virtual access */
2029 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
2030 tcg_gen_helper_0_2(helper_stl_raw, val, addr);
2031 break;
2032 case 0x5:
2033 /* Quadword virtual access */
2034 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
2035 tcg_gen_helper_0_2(helper_stq_raw, val, addr);
2036 break;
2037 case 0x6:
2038 /* Invalid */
2039 goto invalid_opc;
2040 case 0x7:
2041 /* Invalid */
2042 goto invalid_opc;
2043 case 0x8:
2044 /* Invalid */
2045 goto invalid_opc;
2046 case 0x9:
2047 /* Invalid */
2048 goto invalid_opc;
2049 case 0xA:
2050 /* Invalid */
2051 goto invalid_opc;
2052 case 0xB:
2053 /* Invalid */
2054 goto invalid_opc;
2055 case 0xC:
2056 /* Longword virtual access with alternate access mode */
2057 tcg_gen_helper_0_0(helper_set_alt_mode);
2058 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
2059 tcg_gen_helper_0_2(helper_stl_raw, val, addr);
2060 tcg_gen_helper_0_0(helper_restore_mode);
2061 break;
2062 case 0xD:
2063 /* Quadword virtual access with alternate access mode */
2064 tcg_gen_helper_0_0(helper_set_alt_mode);
2065 tcg_gen_helper_1_1(helper_st_virt_to_phys, addr, addr);
2066 tcg_gen_helper_0_2(helper_stl_raw, val, addr);
2067 tcg_gen_helper_0_0(helper_restore_mode);
2068 break;
2069 case 0xE:
2070 /* Invalid */
2071 goto invalid_opc;
2072 case 0xF:
2073 /* Invalid */
2074 goto invalid_opc;
2075 }
2076 if (ra != 31)
2077 tcg_temp_free(val);
2078 tcg_temp_free(addr);
4c9649a9
JM
2079 }
2080 ret = 2;
2081 break;
2082#endif
2083 case 0x20:
2084 /* LDF */
f18cd223 2085 gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
4c9649a9
JM
2086 break;
2087 case 0x21:
2088 /* LDG */
f18cd223 2089 gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
4c9649a9
JM
2090 break;
2091 case 0x22:
2092 /* LDS */
f18cd223 2093 gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
4c9649a9
JM
2094 break;
2095 case 0x23:
2096 /* LDT */
f18cd223 2097 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
4c9649a9
JM
2098 break;
2099 case 0x24:
2100 /* STF */
57a92c8e 2101 gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2102 break;
2103 case 0x25:
2104 /* STG */
57a92c8e 2105 gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2106 break;
2107 case 0x26:
2108 /* STS */
57a92c8e 2109 gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2110 break;
2111 case 0x27:
2112 /* STT */
57a92c8e 2113 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2114 break;
2115 case 0x28:
2116 /* LDL */
f18cd223 2117 gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
4c9649a9
JM
2118 break;
2119 case 0x29:
2120 /* LDQ */
f18cd223 2121 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
4c9649a9
JM
2122 break;
2123 case 0x2A:
2124 /* LDL_L */
f4ed8679 2125 gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
4c9649a9
JM
2126 break;
2127 case 0x2B:
2128 /* LDQ_L */
f4ed8679 2129 gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
4c9649a9
JM
2130 break;
2131 case 0x2C:
2132 /* STL */
57a92c8e 2133 gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
2134 break;
2135 case 0x2D:
2136 /* STQ */
57a92c8e 2137 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
2138 break;
2139 case 0x2E:
2140 /* STL_C */
57a92c8e 2141 gen_store_mem(ctx, &gen_qemu_stl_c, ra, rb, disp16, 0, 0, 1);
4c9649a9
JM
2142 break;
2143 case 0x2F:
2144 /* STQ_C */
57a92c8e 2145 gen_store_mem(ctx, &gen_qemu_stq_c, ra, rb, disp16, 0, 0, 1);
4c9649a9
JM
2146 break;
2147 case 0x30:
2148 /* BR */
3761035f
AJ
2149 if (ra != 31)
2150 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2151 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
4c9649a9
JM
2152 ret = 1;
2153 break;
2154 case 0x31:
2155 /* FBEQ */
f18cd223 2156 gen_fbcond(ctx, &helper_cmpfeq, ra, disp16);
4c9649a9
JM
2157 ret = 1;
2158 break;
2159 case 0x32:
2160 /* FBLT */
f18cd223 2161 gen_fbcond(ctx, &helper_cmpflt, ra, disp16);
4c9649a9
JM
2162 ret = 1;
2163 break;
2164 case 0x33:
2165 /* FBLE */
f18cd223 2166 gen_fbcond(ctx, &helper_cmpfle, ra, disp16);
4c9649a9
JM
2167 ret = 1;
2168 break;
2169 case 0x34:
2170 /* BSR */
3761035f
AJ
2171 if (ra != 31)
2172 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2173 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
4c9649a9
JM
2174 ret = 1;
2175 break;
2176 case 0x35:
2177 /* FBNE */
f18cd223 2178 gen_fbcond(ctx, &helper_cmpfne, ra, disp16);
4c9649a9
JM
2179 ret = 1;
2180 break;
2181 case 0x36:
2182 /* FBGE */
f18cd223 2183 gen_fbcond(ctx, &helper_cmpfge, ra, disp16);
4c9649a9
JM
2184 ret = 1;
2185 break;
2186 case 0x37:
2187 /* FBGT */
f18cd223 2188 gen_fbcond(ctx, &helper_cmpfgt, ra, disp16);
4c9649a9
JM
2189 ret = 1;
2190 break;
2191 case 0x38:
2192 /* BLBC */
9c29504e 2193 gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 1);
4c9649a9
JM
2194 ret = 1;
2195 break;
2196 case 0x39:
2197 /* BEQ */
9c29504e 2198 gen_bcond(ctx, TCG_COND_EQ, ra, disp16, 0);
4c9649a9
JM
2199 ret = 1;
2200 break;
2201 case 0x3A:
2202 /* BLT */
9c29504e 2203 gen_bcond(ctx, TCG_COND_LT, ra, disp16, 0);
4c9649a9
JM
2204 ret = 1;
2205 break;
2206 case 0x3B:
2207 /* BLE */
9c29504e 2208 gen_bcond(ctx, TCG_COND_LE, ra, disp16, 0);
4c9649a9
JM
2209 ret = 1;
2210 break;
2211 case 0x3C:
2212 /* BLBS */
9c29504e 2213 gen_bcond(ctx, TCG_COND_NE, ra, disp16, 1);
4c9649a9
JM
2214 ret = 1;
2215 break;
2216 case 0x3D:
2217 /* BNE */
9c29504e 2218 gen_bcond(ctx, TCG_COND_NE, ra, disp16, 0);
4c9649a9
JM
2219 ret = 1;
2220 break;
2221 case 0x3E:
2222 /* BGE */
9c29504e 2223 gen_bcond(ctx, TCG_COND_GE, ra, disp16, 0);
4c9649a9
JM
2224 ret = 1;
2225 break;
2226 case 0x3F:
2227 /* BGT */
9c29504e 2228 gen_bcond(ctx, TCG_COND_GT, ra, disp16, 0);
4c9649a9
JM
2229 ret = 1;
2230 break;
2231 invalid_opc:
2232 gen_invalid(ctx);
2233 ret = 3;
2234 break;
2235 }
2236
2237 return ret;
2238}
2239
2cfc5f17
TS
2240static always_inline void gen_intermediate_code_internal (CPUState *env,
2241 TranslationBlock *tb,
2242 int search_pc)
4c9649a9
JM
2243{
2244#if defined ALPHA_DEBUG_DISAS
2245 static int insn_count;
2246#endif
2247 DisasContext ctx, *ctxp = &ctx;
2248 target_ulong pc_start;
2249 uint32_t insn;
2250 uint16_t *gen_opc_end;
2251 int j, lj = -1;
2252 int ret;
2e70f6ef
PB
2253 int num_insns;
2254 int max_insns;
4c9649a9
JM
2255
2256 pc_start = tb->pc;
4c9649a9 2257 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4c9649a9
JM
2258 ctx.pc = pc_start;
2259 ctx.amask = env->amask;
2260#if defined (CONFIG_USER_ONLY)
2261 ctx.mem_idx = 0;
2262#else
2263 ctx.mem_idx = ((env->ps >> 3) & 3);
2264 ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
2265#endif
2e70f6ef
PB
2266 num_insns = 0;
2267 max_insns = tb->cflags & CF_COUNT_MASK;
2268 if (max_insns == 0)
2269 max_insns = CF_COUNT_MASK;
2270
2271 gen_icount_start();
4c9649a9
JM
2272 for (ret = 0; ret == 0;) {
2273 if (env->nb_breakpoints > 0) {
2274 for(j = 0; j < env->nb_breakpoints; j++) {
2275 if (env->breakpoints[j] == ctx.pc) {
2276 gen_excp(&ctx, EXCP_DEBUG, 0);
2277 break;
2278 }
2279 }
2280 }
2281 if (search_pc) {
2282 j = gen_opc_ptr - gen_opc_buf;
2283 if (lj < j) {
2284 lj++;
2285 while (lj < j)
2286 gen_opc_instr_start[lj++] = 0;
2287 gen_opc_pc[lj] = ctx.pc;
2288 gen_opc_instr_start[lj] = 1;
2e70f6ef 2289 gen_opc_icount[lj] = num_insns;
4c9649a9
JM
2290 }
2291 }
2e70f6ef
PB
2292 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
2293 gen_io_start();
4c9649a9
JM
2294#if defined ALPHA_DEBUG_DISAS
2295 insn_count++;
2296 if (logfile != NULL) {
e96efcfc
JM
2297 fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n",
2298 ctx.pc, ctx.mem_idx);
4c9649a9
JM
2299 }
2300#endif
2301 insn = ldl_code(ctx.pc);
2302#if defined ALPHA_DEBUG_DISAS
2303 insn_count++;
2304 if (logfile != NULL) {
2305 fprintf(logfile, "opcode %08x %d\n", insn, insn_count);
2306 }
2307#endif
2e70f6ef 2308 num_insns++;
4c9649a9
JM
2309 ctx.pc += 4;
2310 ret = translate_one(ctxp, insn);
2311 if (ret != 0)
2312 break;
2313 /* if we reach a page boundary or are single stepping, stop
2314 * generation
2315 */
2316 if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) ||
2e70f6ef
PB
2317 (env->singlestep_enabled) ||
2318 num_insns >= max_insns) {
4c9649a9
JM
2319 break;
2320 }
2321#if defined (DO_SINGLE_STEP)
2322 break;
2323#endif
2324 }
2325 if (ret != 1 && ret != 3) {
496cb5b9 2326 tcg_gen_movi_i64(cpu_pc, ctx.pc);
4c9649a9 2327 }
4c9649a9 2328#if defined (DO_TB_FLUSH)
496cb5b9 2329 tcg_gen_helper_0_0(helper_tb_flush);
4c9649a9 2330#endif
2e70f6ef
PB
2331 if (tb->cflags & CF_LAST_IO)
2332 gen_io_end();
4c9649a9 2333 /* Generate the return instruction */
57fec1fe 2334 tcg_gen_exit_tb(0);
2e70f6ef 2335 gen_icount_end(tb, num_insns);
4c9649a9
JM
2336 *gen_opc_ptr = INDEX_op_end;
2337 if (search_pc) {
2338 j = gen_opc_ptr - gen_opc_buf;
2339 lj++;
2340 while (lj <= j)
2341 gen_opc_instr_start[lj++] = 0;
4c9649a9
JM
2342 } else {
2343 tb->size = ctx.pc - pc_start;
2e70f6ef 2344 tb->icount = num_insns;
4c9649a9
JM
2345 }
2346#if defined ALPHA_DEBUG_DISAS
2347 if (loglevel & CPU_LOG_TB_CPU) {
2348 cpu_dump_state(env, logfile, fprintf, 0);
2349 }
2350 if (loglevel & CPU_LOG_TB_IN_ASM) {
2351 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
fe2b269a 2352 target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
4c9649a9
JM
2353 fprintf(logfile, "\n");
2354 }
4c9649a9 2355#endif
4c9649a9
JM
2356}
2357
2cfc5f17 2358void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
4c9649a9 2359{
2cfc5f17 2360 gen_intermediate_code_internal(env, tb, 0);
4c9649a9
JM
2361}
2362
2cfc5f17 2363void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
4c9649a9 2364{
2cfc5f17 2365 gen_intermediate_code_internal(env, tb, 1);
4c9649a9
JM
2366}
2367
aaed909a 2368CPUAlphaState * cpu_alpha_init (const char *cpu_model)
4c9649a9
JM
2369{
2370 CPUAlphaState *env;
2371 uint64_t hwpcb;
2372
2373 env = qemu_mallocz(sizeof(CPUAlphaState));
2374 if (!env)
2375 return NULL;
2376 cpu_exec_init(env);
2e70f6ef 2377 alpha_translate_init();
4c9649a9
JM
2378 tlb_flush(env, 1);
2379 /* XXX: should not be hardcoded */
2380 env->implver = IMPLVER_2106x;
2381 env->ps = 0x1F00;
2382#if defined (CONFIG_USER_ONLY)
2383 env->ps |= 1 << 3;
2384#endif
2385 pal_init(env);
2386 /* Initialize IPR */
2387 hwpcb = env->ipr[IPR_PCBB];
2388 env->ipr[IPR_ASN] = 0;
2389 env->ipr[IPR_ASTEN] = 0;
2390 env->ipr[IPR_ASTSR] = 0;
2391 env->ipr[IPR_DATFX] = 0;
2392 /* XXX: fix this */
2393 // env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2394 // env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2395 // env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2396 // env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2397 env->ipr[IPR_FEN] = 0;
2398 env->ipr[IPR_IPL] = 31;
2399 env->ipr[IPR_MCES] = 0;
2400 env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2401 // env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2402 env->ipr[IPR_SISR] = 0;
2403 env->ipr[IPR_VIRBND] = -1ULL;
2404
2405 return env;
2406}
aaed909a 2407
d2856f1a
AJ
2408void gen_pc_load(CPUState *env, TranslationBlock *tb,
2409 unsigned long searched_pc, int pc_pos, void *puc)
2410{
2411 env->pc = gen_opc_pc[pc_pos];
2412}