]> git.proxmox.com Git - mirror_qemu.git/blame - target-alpha/translate.c
target-alpha: Introduce functions for source/sink
[mirror_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
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
4c9649a9
JM
18 */
19
4c9649a9 20#include "cpu.h"
76cad711 21#include "disas/disas.h"
1de7afc9 22#include "qemu/host-utils.h"
57fec1fe 23#include "tcg-op.h"
4c9649a9 24
a7812ae4
PB
25#include "helper.h"
26#define GEN_HELPER 1
27#include "helper.h"
28
19188121 29#undef ALPHA_DEBUG_DISAS
f24518b5 30#define CONFIG_SOFTFLOAT_INLINE
d12d51d5
AL
31
32#ifdef ALPHA_DEBUG_DISAS
806991da 33# define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
d12d51d5
AL
34#else
35# define LOG_DISAS(...) do { } while (0)
36#endif
37
4c9649a9
JM
38typedef struct DisasContext DisasContext;
39struct DisasContext {
4af70374 40 struct TranslationBlock *tb;
4c9649a9
JM
41 uint64_t pc;
42 int mem_idx;
f24518b5
RH
43
44 /* Current rounding mode for this TB. */
45 int tb_rm;
46 /* Current flush-to-zero setting for this TB. */
47 int tb_ftz;
ca6862a6 48
801c4c28
RH
49 /* implver value for this CPU. */
50 int implver;
51
194cfb43
RH
52 /* Temporaries for $31 and $f31 as source and destination. */
53 TCGv zero;
54 TCGv sink;
55 /* Temporary for immediate constants. */
56 TCGv lit;
57
ca6862a6 58 bool singlestep_enabled;
4c9649a9
JM
59};
60
4af70374
RH
61/* Return values from translate_one, indicating the state of the TB.
62 Note that zero indicates that we are not exiting the TB. */
63
64typedef enum {
65 NO_EXIT,
66
67 /* We have emitted one or more goto_tb. No fixup required. */
68 EXIT_GOTO_TB,
69
70 /* We are not using a goto_tb (for whatever reason), but have updated
71 the PC (for whatever reason), so there's no need to do it again on
72 exiting the TB. */
73 EXIT_PC_UPDATED,
74
75 /* We are exiting the TB, but have neither emitted a goto_tb, nor
76 updated the PC for the next instruction to be executed. */
8aa3fa20
RH
77 EXIT_PC_STALE,
78
79 /* We are ending the TB with a noreturn function call, e.g. longjmp.
80 No following code will be executed. */
81 EXIT_NORETURN,
4af70374
RH
82} ExitStatus;
83
3761035f 84/* global register indexes */
a7812ae4 85static TCGv_ptr cpu_env;
496cb5b9 86static TCGv cpu_ir[31];
f18cd223 87static TCGv cpu_fir[31];
496cb5b9 88static TCGv cpu_pc;
6910b8f6
RH
89static TCGv cpu_lock_addr;
90static TCGv cpu_lock_st_addr;
91static TCGv cpu_lock_value;
2ace7e55
RH
92static TCGv cpu_unique;
93#ifndef CONFIG_USER_ONLY
94static TCGv cpu_sysval;
95static TCGv cpu_usp;
ab471ade 96#endif
496cb5b9 97
3761035f 98/* register names */
f18cd223 99static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
2e70f6ef 100
022c62cb 101#include "exec/gen-icount.h"
2e70f6ef 102
0c28246f 103void alpha_translate_init(void)
2e70f6ef 104{
496cb5b9
AJ
105 int i;
106 char *p;
2e70f6ef 107 static int done_init = 0;
496cb5b9 108
67debe3a 109 if (done_init) {
2e70f6ef 110 return;
67debe3a 111 }
496cb5b9 112
a7812ae4 113 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
496cb5b9
AJ
114
115 p = cpu_reg_names;
116 for (i = 0; i < 31; i++) {
117 sprintf(p, "ir%d", i);
a7812ae4 118 cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 119 offsetof(CPUAlphaState, ir[i]), p);
6ba8dcd7 120 p += (i < 10) ? 4 : 5;
f18cd223
AJ
121
122 sprintf(p, "fir%d", i);
a7812ae4 123 cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 124 offsetof(CPUAlphaState, fir[i]), p);
f18cd223 125 p += (i < 10) ? 5 : 6;
496cb5b9
AJ
126 }
127
a7812ae4 128 cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 129 offsetof(CPUAlphaState, pc), "pc");
496cb5b9 130
6910b8f6 131 cpu_lock_addr = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 132 offsetof(CPUAlphaState, lock_addr),
6910b8f6
RH
133 "lock_addr");
134 cpu_lock_st_addr = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 135 offsetof(CPUAlphaState, lock_st_addr),
6910b8f6
RH
136 "lock_st_addr");
137 cpu_lock_value = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 138 offsetof(CPUAlphaState, lock_value),
6910b8f6 139 "lock_value");
f4ed8679 140
2ace7e55 141 cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 142 offsetof(CPUAlphaState, unique), "unique");
2ace7e55
RH
143#ifndef CONFIG_USER_ONLY
144 cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 145 offsetof(CPUAlphaState, sysval), "sysval");
2ace7e55 146 cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
4d5712f1 147 offsetof(CPUAlphaState, usp), "usp");
ab471ade
RH
148#endif
149
2e70f6ef
PB
150 done_init = 1;
151}
152
194cfb43
RH
153static TCGv load_zero(DisasContext *ctx)
154{
155 if (TCGV_IS_UNUSED_I64(ctx->zero)) {
156 ctx->zero = tcg_const_local_i64(0);
157 }
158 return ctx->zero;
159}
160
161static TCGv dest_sink(DisasContext *ctx)
162{
163 if (TCGV_IS_UNUSED_I64(ctx->sink)) {
164 ctx->sink = tcg_temp_local_new();
165 }
166 return ctx->sink;
167}
168
169static TCGv load_gpr(DisasContext *ctx, unsigned reg)
170{
171 if (likely(reg < 31)) {
172 return cpu_ir[reg];
173 } else {
174 return load_zero(ctx);
175 }
176}
177
178static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg,
179 uint8_t lit, bool islit)
180{
181 if (islit) {
182 ctx->lit = tcg_const_i64(lit);
183 return ctx->lit;
184 } else if (likely(reg < 31)) {
185 return cpu_ir[reg];
186 } else {
187 return load_zero(ctx);
188 }
189}
190
191static TCGv dest_gpr(DisasContext *ctx, unsigned reg)
192{
193 if (likely(reg < 31)) {
194 return cpu_ir[reg];
195 } else {
196 return dest_sink(ctx);
197 }
198}
199
200static TCGv __attribute__((unused)) load_fpr(DisasContext *ctx, unsigned reg)
201{
202 if (likely(reg < 31)) {
203 return cpu_fir[reg];
204 } else {
205 return load_zero(ctx);
206 }
207}
208
209static TCGv __attribute__((unused)) dest_fpr(DisasContext *ctx, unsigned reg)
210{
211 if (likely(reg < 31)) {
212 return cpu_fir[reg];
213 } else {
214 return dest_sink(ctx);
215 }
216}
217
bf1b03fe 218static void gen_excp_1(int exception, int error_code)
4c9649a9 219{
a7812ae4 220 TCGv_i32 tmp1, tmp2;
6ad02592 221
6ad02592
AJ
222 tmp1 = tcg_const_i32(exception);
223 tmp2 = tcg_const_i32(error_code);
b9f0923e 224 gen_helper_excp(cpu_env, tmp1, tmp2);
a7812ae4
PB
225 tcg_temp_free_i32(tmp2);
226 tcg_temp_free_i32(tmp1);
bf1b03fe 227}
8aa3fa20 228
bf1b03fe
RH
229static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
230{
231 tcg_gen_movi_i64(cpu_pc, ctx->pc);
232 gen_excp_1(exception, error_code);
8aa3fa20 233 return EXIT_NORETURN;
4c9649a9
JM
234}
235
8aa3fa20 236static inline ExitStatus gen_invalid(DisasContext *ctx)
4c9649a9 237{
8aa3fa20 238 return gen_excp(ctx, EXCP_OPCDEC, 0);
4c9649a9
JM
239}
240
636aa200 241static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
f18cd223 242{
a7812ae4 243 TCGv_i32 tmp32 = tcg_temp_new_i32();
f8da40ae 244 tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
a7812ae4
PB
245 gen_helper_memory_to_f(t0, tmp32);
246 tcg_temp_free_i32(tmp32);
f18cd223
AJ
247}
248
636aa200 249static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
f18cd223 250{
a7812ae4 251 TCGv tmp = tcg_temp_new();
f8da40ae 252 tcg_gen_qemu_ld_i64(tmp, t1, flags, MO_LEQ);
a7812ae4 253 gen_helper_memory_to_g(t0, tmp);
f18cd223
AJ
254 tcg_temp_free(tmp);
255}
256
636aa200 257static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
f18cd223 258{
a7812ae4 259 TCGv_i32 tmp32 = tcg_temp_new_i32();
f8da40ae 260 tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
a7812ae4
PB
261 gen_helper_memory_to_s(t0, tmp32);
262 tcg_temp_free_i32(tmp32);
f18cd223
AJ
263}
264
636aa200 265static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
f4ed8679 266{
f8da40ae 267 tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LESL);
6910b8f6
RH
268 tcg_gen_mov_i64(cpu_lock_addr, t1);
269 tcg_gen_mov_i64(cpu_lock_value, t0);
f4ed8679
AJ
270}
271
636aa200 272static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
f4ed8679 273{
f8da40ae 274 tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LEQ);
6910b8f6
RH
275 tcg_gen_mov_i64(cpu_lock_addr, t1);
276 tcg_gen_mov_i64(cpu_lock_value, t0);
f4ed8679
AJ
277}
278
636aa200
BS
279static inline void gen_load_mem(DisasContext *ctx,
280 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
281 int flags),
282 int ra, int rb, int32_t disp16, int fp,
283 int clear)
023d8ca2 284{
6910b8f6 285 TCGv addr, va;
023d8ca2 286
6910b8f6
RH
287 /* LDQ_U with ra $31 is UNOP. Other various loads are forms of
288 prefetches, which we can treat as nops. No worries about
289 missed exceptions here. */
290 if (unlikely(ra == 31)) {
023d8ca2 291 return;
6910b8f6 292 }
023d8ca2 293
a7812ae4 294 addr = tcg_temp_new();
023d8ca2
AJ
295 if (rb != 31) {
296 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
6910b8f6 297 if (clear) {
023d8ca2 298 tcg_gen_andi_i64(addr, addr, ~0x7);
6910b8f6 299 }
023d8ca2 300 } else {
6910b8f6 301 if (clear) {
023d8ca2 302 disp16 &= ~0x7;
6910b8f6 303 }
023d8ca2
AJ
304 tcg_gen_movi_i64(addr, disp16);
305 }
6910b8f6
RH
306
307 va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
308 tcg_gen_qemu_load(va, addr, ctx->mem_idx);
309
023d8ca2
AJ
310 tcg_temp_free(addr);
311}
312
636aa200 313static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
f18cd223 314{
a7812ae4 315 TCGv_i32 tmp32 = tcg_temp_new_i32();
a7812ae4 316 gen_helper_f_to_memory(tmp32, t0);
f8da40ae 317 tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
a7812ae4 318 tcg_temp_free_i32(tmp32);
f18cd223
AJ
319}
320
636aa200 321static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
f18cd223 322{
a7812ae4
PB
323 TCGv tmp = tcg_temp_new();
324 gen_helper_g_to_memory(tmp, t0);
f8da40ae 325 tcg_gen_qemu_st_i64(tmp, t1, flags, MO_LEQ);
f18cd223
AJ
326 tcg_temp_free(tmp);
327}
328
636aa200 329static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
f18cd223 330{
a7812ae4 331 TCGv_i32 tmp32 = tcg_temp_new_i32();
a7812ae4 332 gen_helper_s_to_memory(tmp32, t0);
f8da40ae 333 tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
a7812ae4 334 tcg_temp_free_i32(tmp32);
f18cd223
AJ
335}
336
636aa200
BS
337static inline void gen_store_mem(DisasContext *ctx,
338 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
339 int flags),
340 int ra, int rb, int32_t disp16, int fp,
6910b8f6 341 int clear)
023d8ca2 342{
6910b8f6
RH
343 TCGv addr, va;
344
345 addr = tcg_temp_new();
023d8ca2
AJ
346 if (rb != 31) {
347 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
6910b8f6 348 if (clear) {
023d8ca2 349 tcg_gen_andi_i64(addr, addr, ~0x7);
6910b8f6 350 }
023d8ca2 351 } else {
6910b8f6 352 if (clear) {
023d8ca2 353 disp16 &= ~0x7;
6910b8f6 354 }
023d8ca2
AJ
355 tcg_gen_movi_i64(addr, disp16);
356 }
6910b8f6
RH
357
358 if (ra == 31) {
359 va = tcg_const_i64(0);
f18cd223 360 } else {
6910b8f6 361 va = (fp ? cpu_fir[ra] : cpu_ir[ra]);
023d8ca2 362 }
6910b8f6
RH
363 tcg_gen_qemu_store(va, addr, ctx->mem_idx);
364
023d8ca2 365 tcg_temp_free(addr);
6910b8f6
RH
366 if (ra == 31) {
367 tcg_temp_free(va);
368 }
369}
370
371static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
372 int32_t disp16, int quad)
373{
374 TCGv addr;
375
376 if (ra == 31) {
377 /* ??? Don't bother storing anything. The user can't tell
378 the difference, since the zero register always reads zero. */
379 return NO_EXIT;
380 }
381
382#if defined(CONFIG_USER_ONLY)
383 addr = cpu_lock_st_addr;
384#else
e52458fe 385 addr = tcg_temp_local_new();
6910b8f6
RH
386#endif
387
388 if (rb != 31) {
389 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
390 } else {
391 tcg_gen_movi_i64(addr, disp16);
392 }
393
394#if defined(CONFIG_USER_ONLY)
395 /* ??? This is handled via a complicated version of compare-and-swap
396 in the cpu_loop. Hopefully one day we'll have a real CAS opcode
397 in TCG so that this isn't necessary. */
398 return gen_excp(ctx, quad ? EXCP_STQ_C : EXCP_STL_C, ra);
399#else
400 /* ??? In system mode we are never multi-threaded, so CAS can be
401 implemented via a non-atomic load-compare-store sequence. */
402 {
403 int lab_fail, lab_done;
404 TCGv val;
405
406 lab_fail = gen_new_label();
407 lab_done = gen_new_label();
e52458fe 408 tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
6910b8f6
RH
409
410 val = tcg_temp_new();
f8da40ae 411 tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, quad ? MO_LEQ : MO_LESL);
e52458fe 412 tcg_gen_brcond_i64(TCG_COND_NE, val, cpu_lock_value, lab_fail);
6910b8f6 413
f8da40ae
RH
414 tcg_gen_qemu_st_i64(cpu_ir[ra], addr, ctx->mem_idx,
415 quad ? MO_LEQ : MO_LEUL);
6910b8f6
RH
416 tcg_gen_movi_i64(cpu_ir[ra], 1);
417 tcg_gen_br(lab_done);
418
419 gen_set_label(lab_fail);
420 tcg_gen_movi_i64(cpu_ir[ra], 0);
421
422 gen_set_label(lab_done);
423 tcg_gen_movi_i64(cpu_lock_addr, -1);
424
425 tcg_temp_free(addr);
426 return NO_EXIT;
427 }
428#endif
023d8ca2
AJ
429}
430
b114b68a 431static bool in_superpage(DisasContext *ctx, int64_t addr)
4c9649a9 432{
b114b68a
RH
433 return ((ctx->tb->flags & TB_FLAGS_USER_MODE) == 0
434 && addr < 0
435 && ((addr >> 41) & 3) == 2
436 && addr >> TARGET_VIRT_ADDR_SPACE_BITS == addr >> 63);
437}
438
439static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
440{
441 /* Suppress goto_tb in the case of single-steping and IO. */
442 if (ctx->singlestep_enabled || (ctx->tb->cflags & CF_LAST_IO)) {
443 return false;
444 }
445 /* If the destination is in the superpage, the page perms can't change. */
446 if (in_superpage(ctx, dest)) {
447 return true;
448 }
449 /* Check for the dest on the same page as the start of the TB. */
450 return ((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
4af70374 451}
dbb30fe6 452
4af70374
RH
453static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
454{
455 uint64_t dest = ctx->pc + (disp << 2);
456
457 if (ra != 31) {
458 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
459 }
460
461 /* Notice branch-to-next; used to initialize RA with the PC. */
462 if (disp == 0) {
463 return 0;
464 } else if (use_goto_tb(ctx, dest)) {
465 tcg_gen_goto_tb(0);
466 tcg_gen_movi_i64(cpu_pc, dest);
8cfd0495 467 tcg_gen_exit_tb((uintptr_t)ctx->tb);
4af70374
RH
468 return EXIT_GOTO_TB;
469 } else {
470 tcg_gen_movi_i64(cpu_pc, dest);
471 return EXIT_PC_UPDATED;
472 }
dbb30fe6
RH
473}
474
4af70374
RH
475static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
476 TCGv cmp, int32_t disp)
dbb30fe6 477{
4af70374 478 uint64_t dest = ctx->pc + (disp << 2);
dbb30fe6 479 int lab_true = gen_new_label();
9c29504e 480
4af70374
RH
481 if (use_goto_tb(ctx, dest)) {
482 tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
483
484 tcg_gen_goto_tb(0);
485 tcg_gen_movi_i64(cpu_pc, ctx->pc);
8cfd0495 486 tcg_gen_exit_tb((uintptr_t)ctx->tb);
4af70374
RH
487
488 gen_set_label(lab_true);
489 tcg_gen_goto_tb(1);
490 tcg_gen_movi_i64(cpu_pc, dest);
8cfd0495 491 tcg_gen_exit_tb((uintptr_t)ctx->tb + 1);
4af70374
RH
492
493 return EXIT_GOTO_TB;
494 } else {
57e289de
RH
495 TCGv_i64 z = tcg_const_i64(0);
496 TCGv_i64 d = tcg_const_i64(dest);
497 TCGv_i64 p = tcg_const_i64(ctx->pc);
4af70374 498
57e289de 499 tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
4af70374 500
57e289de
RH
501 tcg_temp_free_i64(z);
502 tcg_temp_free_i64(d);
503 tcg_temp_free_i64(p);
4af70374
RH
504 return EXIT_PC_UPDATED;
505 }
506}
507
508static ExitStatus gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
509 int32_t disp, int mask)
510{
511 TCGv cmp_tmp;
512
513 if (unlikely(ra == 31)) {
514 cmp_tmp = tcg_const_i64(0);
515 } else {
516 cmp_tmp = tcg_temp_new();
9c29504e 517 if (mask) {
4af70374 518 tcg_gen_andi_i64(cmp_tmp, cpu_ir[ra], 1);
dbb30fe6 519 } else {
4af70374 520 tcg_gen_mov_i64(cmp_tmp, cpu_ir[ra]);
dbb30fe6 521 }
9c29504e 522 }
4af70374
RH
523
524 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
4c9649a9
JM
525}
526
4af70374 527/* Fold -0.0 for comparison with COND. */
dbb30fe6 528
4af70374 529static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
4c9649a9 530{
dbb30fe6 531 uint64_t mzero = 1ull << 63;
f18cd223 532
dbb30fe6
RH
533 switch (cond) {
534 case TCG_COND_LE:
535 case TCG_COND_GT:
536 /* For <= or >, the -0.0 value directly compares the way we want. */
4af70374 537 tcg_gen_mov_i64(dest, src);
a7812ae4 538 break;
dbb30fe6
RH
539
540 case TCG_COND_EQ:
541 case TCG_COND_NE:
542 /* For == or !=, we can simply mask off the sign bit and compare. */
4af70374 543 tcg_gen_andi_i64(dest, src, mzero - 1);
a7812ae4 544 break;
dbb30fe6
RH
545
546 case TCG_COND_GE:
dbb30fe6 547 case TCG_COND_LT:
4af70374
RH
548 /* For >= or <, map -0.0 to +0.0 via comparison and mask. */
549 tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
550 tcg_gen_neg_i64(dest, dest);
551 tcg_gen_and_i64(dest, dest, src);
a7812ae4 552 break;
dbb30fe6 553
a7812ae4
PB
554 default:
555 abort();
f18cd223 556 }
dbb30fe6
RH
557}
558
4af70374
RH
559static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
560 int32_t disp)
dbb30fe6 561{
4af70374 562 TCGv cmp_tmp;
dbb30fe6
RH
563
564 if (unlikely(ra == 31)) {
565 /* Very uncommon case, but easier to optimize it to an integer
566 comparison than continuing with the floating point comparison. */
4af70374 567 return gen_bcond(ctx, cond, ra, disp, 0);
dbb30fe6
RH
568 }
569
4af70374
RH
570 cmp_tmp = tcg_temp_new();
571 gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
572 return gen_bcond_internal(ctx, cond, cmp_tmp, disp);
4c9649a9
JM
573}
574
bbe1dab4 575static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
4af70374 576 int islit, uint8_t lit, int mask)
4c9649a9 577{
57e289de 578 TCGv_i64 c1, z, v1;
9c29504e 579
57e289de 580 if (unlikely(rc == 31)) {
9c29504e 581 return;
57e289de 582 }
9c29504e 583
57e289de 584 if (ra == 31) {
9c29504e 585 /* Very uncommon case - Do not bother to optimize. */
57e289de
RH
586 c1 = tcg_const_i64(0);
587 } else if (mask) {
588 c1 = tcg_const_i64(1);
589 tcg_gen_and_i64(c1, c1, cpu_ir[ra]);
590 } else {
591 c1 = cpu_ir[ra];
592 }
593 if (islit) {
594 v1 = tcg_const_i64(lit);
595 } else {
596 v1 = cpu_ir[rb];
9c29504e 597 }
57e289de 598 z = tcg_const_i64(0);
9c29504e 599
57e289de
RH
600 tcg_gen_movcond_i64(cond, cpu_ir[rc], c1, z, v1, cpu_ir[rc]);
601
602 tcg_temp_free_i64(z);
603 if (ra == 31 || mask) {
604 tcg_temp_free_i64(c1);
605 }
606 if (islit) {
607 tcg_temp_free_i64(v1);
608 }
4c9649a9
JM
609}
610
bbe1dab4 611static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
dbb30fe6 612{
57e289de 613 TCGv_i64 c1, z, v1;
dbb30fe6 614
4af70374 615 if (unlikely(rc == 31)) {
dbb30fe6 616 return;
4af70374
RH
617 }
618
57e289de 619 c1 = tcg_temp_new_i64();
dbb30fe6 620 if (unlikely(ra == 31)) {
57e289de 621 tcg_gen_movi_i64(c1, 0);
4af70374 622 } else {
57e289de 623 gen_fold_mzero(cond, c1, cpu_fir[ra]);
dbb30fe6 624 }
57e289de
RH
625 if (rb == 31) {
626 v1 = tcg_const_i64(0);
627 } else {
628 v1 = cpu_fir[rb];
629 }
630 z = tcg_const_i64(0);
dbb30fe6 631
57e289de 632 tcg_gen_movcond_i64(cond, cpu_fir[rc], c1, z, v1, cpu_fir[rc]);
dbb30fe6 633
57e289de
RH
634 tcg_temp_free_i64(z);
635 tcg_temp_free_i64(c1);
636 if (rb == 31) {
637 tcg_temp_free_i64(v1);
638 }
dbb30fe6
RH
639}
640
f24518b5
RH
641#define QUAL_RM_N 0x080 /* Round mode nearest even */
642#define QUAL_RM_C 0x000 /* Round mode chopped */
643#define QUAL_RM_M 0x040 /* Round mode minus infinity */
644#define QUAL_RM_D 0x0c0 /* Round mode dynamic */
645#define QUAL_RM_MASK 0x0c0
646
647#define QUAL_U 0x100 /* Underflow enable (fp output) */
648#define QUAL_V 0x100 /* Overflow enable (int output) */
649#define QUAL_S 0x400 /* Software completion enable */
650#define QUAL_I 0x200 /* Inexact detection enable */
651
652static void gen_qual_roundmode(DisasContext *ctx, int fn11)
653{
654 TCGv_i32 tmp;
655
656 fn11 &= QUAL_RM_MASK;
657 if (fn11 == ctx->tb_rm) {
658 return;
659 }
660 ctx->tb_rm = fn11;
661
662 tmp = tcg_temp_new_i32();
663 switch (fn11) {
664 case QUAL_RM_N:
665 tcg_gen_movi_i32(tmp, float_round_nearest_even);
666 break;
667 case QUAL_RM_C:
668 tcg_gen_movi_i32(tmp, float_round_to_zero);
669 break;
670 case QUAL_RM_M:
671 tcg_gen_movi_i32(tmp, float_round_down);
672 break;
673 case QUAL_RM_D:
4a58aedf
RH
674 tcg_gen_ld8u_i32(tmp, cpu_env,
675 offsetof(CPUAlphaState, fpcr_dyn_round));
f24518b5
RH
676 break;
677 }
678
679#if defined(CONFIG_SOFTFLOAT_INLINE)
6b4c305c 680 /* ??? The "fpu/softfloat.h" interface is to call set_float_rounding_mode.
f24518b5
RH
681 With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
682 sets the one field. */
683 tcg_gen_st8_i32(tmp, cpu_env,
4d5712f1 684 offsetof(CPUAlphaState, fp_status.float_rounding_mode));
f24518b5
RH
685#else
686 gen_helper_setroundmode(tmp);
687#endif
688
689 tcg_temp_free_i32(tmp);
690}
691
692static void gen_qual_flushzero(DisasContext *ctx, int fn11)
693{
694 TCGv_i32 tmp;
695
696 fn11 &= QUAL_U;
697 if (fn11 == ctx->tb_ftz) {
698 return;
699 }
700 ctx->tb_ftz = fn11;
701
702 tmp = tcg_temp_new_i32();
703 if (fn11) {
704 /* Underflow is enabled, use the FPCR setting. */
4a58aedf
RH
705 tcg_gen_ld8u_i32(tmp, cpu_env,
706 offsetof(CPUAlphaState, fpcr_flush_to_zero));
f24518b5
RH
707 } else {
708 /* Underflow is disabled, force flush-to-zero. */
709 tcg_gen_movi_i32(tmp, 1);
710 }
711
712#if defined(CONFIG_SOFTFLOAT_INLINE)
713 tcg_gen_st8_i32(tmp, cpu_env,
4d5712f1 714 offsetof(CPUAlphaState, fp_status.flush_to_zero));
f24518b5
RH
715#else
716 gen_helper_setflushzero(tmp);
717#endif
718
719 tcg_temp_free_i32(tmp);
720}
721
722static TCGv gen_ieee_input(int reg, int fn11, int is_cmp)
723{
74343409 724 TCGv val;
f24518b5 725 if (reg == 31) {
74343409 726 val = tcg_const_i64(0);
f24518b5 727 } else {
74343409
RH
728 if ((fn11 & QUAL_S) == 0) {
729 if (is_cmp) {
730 gen_helper_ieee_input_cmp(cpu_env, cpu_fir[reg]);
731 } else {
732 gen_helper_ieee_input(cpu_env, cpu_fir[reg]);
733 }
734 }
735 val = tcg_temp_new();
736 tcg_gen_mov_i64(val, cpu_fir[reg]);
f24518b5
RH
737 }
738 return val;
739}
740
741static void gen_fp_exc_clear(void)
742{
743#if defined(CONFIG_SOFTFLOAT_INLINE)
744 TCGv_i32 zero = tcg_const_i32(0);
745 tcg_gen_st8_i32(zero, cpu_env,
4d5712f1 746 offsetof(CPUAlphaState, fp_status.float_exception_flags));
f24518b5
RH
747 tcg_temp_free_i32(zero);
748#else
4a58aedf 749 gen_helper_fp_exc_clear(cpu_env);
f24518b5
RH
750#endif
751}
752
753static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
754{
755 /* ??? We ought to be able to do something with imprecise exceptions.
756 E.g. notice we're still in the trap shadow of something within the
757 TB and do not generate the code to signal the exception; end the TB
758 when an exception is forced to arrive, either by consumption of a
759 register value or TRAPB or EXCB. */
760 TCGv_i32 exc = tcg_temp_new_i32();
761 TCGv_i32 reg;
762
763#if defined(CONFIG_SOFTFLOAT_INLINE)
764 tcg_gen_ld8u_i32(exc, cpu_env,
4d5712f1 765 offsetof(CPUAlphaState, fp_status.float_exception_flags));
f24518b5 766#else
4a58aedf 767 gen_helper_fp_exc_get(exc, cpu_env);
f24518b5
RH
768#endif
769
770 if (ignore) {
771 tcg_gen_andi_i32(exc, exc, ~ignore);
772 }
773
774 /* ??? Pass in the regno of the destination so that the helper can
775 set EXC_MASK, which contains a bitmask of destination registers
776 that have caused arithmetic traps. A simple userspace emulation
777 does not require this. We do need it for a guest kernel's entArith,
778 or if we were to do something clever with imprecise exceptions. */
779 reg = tcg_const_i32(rc + 32);
780
781 if (fn11 & QUAL_S) {
4a58aedf 782 gen_helper_fp_exc_raise_s(cpu_env, exc, reg);
f24518b5 783 } else {
4a58aedf 784 gen_helper_fp_exc_raise(cpu_env, exc, reg);
f24518b5
RH
785 }
786
787 tcg_temp_free_i32(reg);
788 tcg_temp_free_i32(exc);
789}
790
791static inline void gen_fp_exc_raise(int rc, int fn11)
792{
793 gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : float_flag_inexact);
4c9649a9 794}
f24518b5 795
593f17e5
RH
796static void gen_fcvtlq(int rb, int rc)
797{
798 if (unlikely(rc == 31)) {
799 return;
800 }
801 if (unlikely(rb == 31)) {
802 tcg_gen_movi_i64(cpu_fir[rc], 0);
803 } else {
804 TCGv tmp = tcg_temp_new();
805
806 /* The arithmetic right shift here, plus the sign-extended mask below
807 yields a sign-extended result without an explicit ext32s_i64. */
808 tcg_gen_sari_i64(tmp, cpu_fir[rb], 32);
809 tcg_gen_shri_i64(cpu_fir[rc], cpu_fir[rb], 29);
810 tcg_gen_andi_i64(tmp, tmp, (int32_t)0xc0000000);
811 tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rc], 0x3fffffff);
812 tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
813
814 tcg_temp_free(tmp);
815 }
816}
817
735cf45f
RH
818static void gen_fcvtql(int rb, int rc)
819{
820 if (unlikely(rc == 31)) {
821 return;
822 }
823 if (unlikely(rb == 31)) {
824 tcg_gen_movi_i64(cpu_fir[rc], 0);
825 } else {
826 TCGv tmp = tcg_temp_new();
827
828 tcg_gen_andi_i64(tmp, cpu_fir[rb], 0xC0000000);
829 tcg_gen_andi_i64(cpu_fir[rc], cpu_fir[rb], 0x3FFFFFFF);
830 tcg_gen_shli_i64(tmp, tmp, 32);
831 tcg_gen_shli_i64(cpu_fir[rc], cpu_fir[rc], 29);
832 tcg_gen_or_i64(cpu_fir[rc], cpu_fir[rc], tmp);
833
834 tcg_temp_free(tmp);
835 }
836}
837
838static void gen_fcvtql_v(DisasContext *ctx, int rb, int rc)
839{
840 if (rb != 31) {
841 int lab = gen_new_label();
842 TCGv tmp = tcg_temp_new();
843
844 tcg_gen_ext32s_i64(tmp, cpu_fir[rb]);
845 tcg_gen_brcond_i64(TCG_COND_EQ, tmp, cpu_fir[rb], lab);
846 gen_excp(ctx, EXCP_ARITH, EXC_M_IOV);
847
848 gen_set_label(lab);
849 }
850 gen_fcvtql(rb, rc);
851}
852
4a58aedf
RH
853#define FARITH2(name) \
854 static inline void glue(gen_f, name)(int rb, int rc) \
855 { \
856 if (unlikely(rc == 31)) { \
857 return; \
858 } \
859 if (rb != 31) { \
860 gen_helper_ ## name(cpu_fir[rc], cpu_env, cpu_fir[rb]); \
861 } else { \
862 TCGv tmp = tcg_const_i64(0); \
863 gen_helper_ ## name(cpu_fir[rc], cpu_env, tmp); \
864 tcg_temp_free(tmp); \
865 } \
866 }
f24518b5
RH
867
868/* ??? VAX instruction qualifiers ignored. */
a7812ae4
PB
869FARITH2(sqrtf)
870FARITH2(sqrtg)
a7812ae4
PB
871FARITH2(cvtgf)
872FARITH2(cvtgq)
873FARITH2(cvtqf)
874FARITH2(cvtqg)
f24518b5 875
4a58aedf
RH
876static void gen_ieee_arith2(DisasContext *ctx,
877 void (*helper)(TCGv, TCGv_ptr, TCGv),
f24518b5
RH
878 int rb, int rc, int fn11)
879{
880 TCGv vb;
881
882 /* ??? This is wrong: the instruction is not a nop, it still may
883 raise exceptions. */
884 if (unlikely(rc == 31)) {
885 return;
886 }
887
888 gen_qual_roundmode(ctx, fn11);
889 gen_qual_flushzero(ctx, fn11);
890 gen_fp_exc_clear();
891
892 vb = gen_ieee_input(rb, fn11, 0);
4a58aedf 893 helper(cpu_fir[rc], cpu_env, vb);
f24518b5
RH
894 tcg_temp_free(vb);
895
896 gen_fp_exc_raise(rc, fn11);
897}
898
899#define IEEE_ARITH2(name) \
900static inline void glue(gen_f, name)(DisasContext *ctx, \
901 int rb, int rc, int fn11) \
902{ \
903 gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11); \
904}
905IEEE_ARITH2(sqrts)
906IEEE_ARITH2(sqrtt)
907IEEE_ARITH2(cvtst)
908IEEE_ARITH2(cvtts)
909
910static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
911{
912 TCGv vb;
913 int ignore = 0;
914
915 /* ??? This is wrong: the instruction is not a nop, it still may
916 raise exceptions. */
917 if (unlikely(rc == 31)) {
918 return;
919 }
920
921 /* No need to set flushzero, since we have an integer output. */
922 gen_fp_exc_clear();
923 vb = gen_ieee_input(rb, fn11, 0);
924
925 /* Almost all integer conversions use cropped rounding, and most
926 also do not have integer overflow enabled. Special case that. */
927 switch (fn11) {
928 case QUAL_RM_C:
4a58aedf 929 gen_helper_cvttq_c(cpu_fir[rc], cpu_env, vb);
f24518b5
RH
930 break;
931 case QUAL_V | QUAL_RM_C:
932 case QUAL_S | QUAL_V | QUAL_RM_C:
933 ignore = float_flag_inexact;
934 /* FALLTHRU */
935 case QUAL_S | QUAL_V | QUAL_I | QUAL_RM_C:
4a58aedf 936 gen_helper_cvttq_svic(cpu_fir[rc], cpu_env, vb);
f24518b5
RH
937 break;
938 default:
939 gen_qual_roundmode(ctx, fn11);
4a58aedf 940 gen_helper_cvttq(cpu_fir[rc], cpu_env, vb);
f24518b5
RH
941 ignore |= (fn11 & QUAL_V ? 0 : float_flag_overflow);
942 ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact);
943 break;
944 }
945 tcg_temp_free(vb);
946
947 gen_fp_exc_raise_ignore(rc, fn11, ignore);
4c9649a9
JM
948}
949
4a58aedf
RH
950static void gen_ieee_intcvt(DisasContext *ctx,
951 void (*helper)(TCGv, TCGv_ptr, TCGv),
f24518b5
RH
952 int rb, int rc, int fn11)
953{
954 TCGv vb;
955
956 /* ??? This is wrong: the instruction is not a nop, it still may
957 raise exceptions. */
958 if (unlikely(rc == 31)) {
959 return;
960 }
961
962 gen_qual_roundmode(ctx, fn11);
963
964 if (rb == 31) {
965 vb = tcg_const_i64(0);
966 } else {
967 vb = cpu_fir[rb];
968 }
969
970 /* The only exception that can be raised by integer conversion
971 is inexact. Thus we only need to worry about exceptions when
972 inexact handling is requested. */
973 if (fn11 & QUAL_I) {
974 gen_fp_exc_clear();
4a58aedf 975 helper(cpu_fir[rc], cpu_env, vb);
f24518b5
RH
976 gen_fp_exc_raise(rc, fn11);
977 } else {
4a58aedf 978 helper(cpu_fir[rc], cpu_env, vb);
f24518b5
RH
979 }
980
981 if (rb == 31) {
982 tcg_temp_free(vb);
983 }
984}
985
986#define IEEE_INTCVT(name) \
987static inline void glue(gen_f, name)(DisasContext *ctx, \
988 int rb, int rc, int fn11) \
989{ \
990 gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11); \
991}
992IEEE_INTCVT(cvtqs)
993IEEE_INTCVT(cvtqt)
994
dc96be4b
RH
995static void gen_cpys_internal(int ra, int rb, int rc, int inv_a, uint64_t mask)
996{
997 TCGv va, vb, vmask;
998 int za = 0, zb = 0;
999
1000 if (unlikely(rc == 31)) {
1001 return;
1002 }
1003
1004 vmask = tcg_const_i64(mask);
1005
1006 TCGV_UNUSED_I64(va);
1007 if (ra == 31) {
1008 if (inv_a) {
1009 va = vmask;
1010 } else {
1011 za = 1;
1012 }
1013 } else {
1014 va = tcg_temp_new_i64();
1015 tcg_gen_mov_i64(va, cpu_fir[ra]);
1016 if (inv_a) {
1017 tcg_gen_andc_i64(va, vmask, va);
1018 } else {
1019 tcg_gen_and_i64(va, va, vmask);
1020 }
1021 }
1022
1023 TCGV_UNUSED_I64(vb);
1024 if (rb == 31) {
1025 zb = 1;
1026 } else {
1027 vb = tcg_temp_new_i64();
1028 tcg_gen_andc_i64(vb, cpu_fir[rb], vmask);
1029 }
1030
1031 switch (za << 1 | zb) {
1032 case 0 | 0:
1033 tcg_gen_or_i64(cpu_fir[rc], va, vb);
1034 break;
1035 case 0 | 1:
1036 tcg_gen_mov_i64(cpu_fir[rc], va);
1037 break;
1038 case 2 | 0:
1039 tcg_gen_mov_i64(cpu_fir[rc], vb);
1040 break;
1041 case 2 | 1:
1042 tcg_gen_movi_i64(cpu_fir[rc], 0);
1043 break;
1044 }
1045
1046 tcg_temp_free(vmask);
1047 if (ra != 31) {
1048 tcg_temp_free(va);
1049 }
1050 if (rb != 31) {
1051 tcg_temp_free(vb);
1052 }
1053}
1054
1055static inline void gen_fcpys(int ra, int rb, int rc)
1056{
1057 gen_cpys_internal(ra, rb, rc, 0, 0x8000000000000000ULL);
1058}
1059
1060static inline void gen_fcpysn(int ra, int rb, int rc)
1061{
1062 gen_cpys_internal(ra, rb, rc, 1, 0x8000000000000000ULL);
1063}
1064
1065static inline void gen_fcpyse(int ra, int rb, int rc)
1066{
1067 gen_cpys_internal(ra, rb, rc, 0, 0xFFF0000000000000ULL);
1068}
1069
4a58aedf
RH
1070#define FARITH3(name) \
1071 static inline void glue(gen_f, name)(int ra, int rb, int rc) \
1072 { \
1073 TCGv va, vb; \
1074 \
1075 if (unlikely(rc == 31)) { \
1076 return; \
1077 } \
1078 if (ra == 31) { \
1079 va = tcg_const_i64(0); \
1080 } else { \
1081 va = cpu_fir[ra]; \
1082 } \
1083 if (rb == 31) { \
1084 vb = tcg_const_i64(0); \
1085 } else { \
1086 vb = cpu_fir[rb]; \
1087 } \
1088 \
1089 gen_helper_ ## name(cpu_fir[rc], cpu_env, va, vb); \
1090 \
1091 if (ra == 31) { \
1092 tcg_temp_free(va); \
1093 } \
1094 if (rb == 31) { \
1095 tcg_temp_free(vb); \
1096 } \
1097 }
f24518b5
RH
1098
1099/* ??? VAX instruction qualifiers ignored. */
a7812ae4
PB
1100FARITH3(addf)
1101FARITH3(subf)
1102FARITH3(mulf)
1103FARITH3(divf)
1104FARITH3(addg)
1105FARITH3(subg)
1106FARITH3(mulg)
1107FARITH3(divg)
1108FARITH3(cmpgeq)
1109FARITH3(cmpglt)
1110FARITH3(cmpgle)
f24518b5
RH
1111
1112static void gen_ieee_arith3(DisasContext *ctx,
4a58aedf 1113 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
f24518b5
RH
1114 int ra, int rb, int rc, int fn11)
1115{
1116 TCGv va, vb;
1117
1118 /* ??? This is wrong: the instruction is not a nop, it still may
1119 raise exceptions. */
1120 if (unlikely(rc == 31)) {
1121 return;
1122 }
1123
1124 gen_qual_roundmode(ctx, fn11);
1125 gen_qual_flushzero(ctx, fn11);
1126 gen_fp_exc_clear();
1127
1128 va = gen_ieee_input(ra, fn11, 0);
1129 vb = gen_ieee_input(rb, fn11, 0);
4a58aedf 1130 helper(cpu_fir[rc], cpu_env, va, vb);
f24518b5
RH
1131 tcg_temp_free(va);
1132 tcg_temp_free(vb);
1133
1134 gen_fp_exc_raise(rc, fn11);
1135}
1136
1137#define IEEE_ARITH3(name) \
1138static inline void glue(gen_f, name)(DisasContext *ctx, \
1139 int ra, int rb, int rc, int fn11) \
1140{ \
1141 gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11); \
1142}
1143IEEE_ARITH3(adds)
1144IEEE_ARITH3(subs)
1145IEEE_ARITH3(muls)
1146IEEE_ARITH3(divs)
1147IEEE_ARITH3(addt)
1148IEEE_ARITH3(subt)
1149IEEE_ARITH3(mult)
1150IEEE_ARITH3(divt)
1151
1152static void gen_ieee_compare(DisasContext *ctx,
4a58aedf 1153 void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
f24518b5
RH
1154 int ra, int rb, int rc, int fn11)
1155{
1156 TCGv va, vb;
1157
1158 /* ??? This is wrong: the instruction is not a nop, it still may
1159 raise exceptions. */
1160 if (unlikely(rc == 31)) {
1161 return;
1162 }
1163
1164 gen_fp_exc_clear();
1165
1166 va = gen_ieee_input(ra, fn11, 1);
1167 vb = gen_ieee_input(rb, fn11, 1);
4a58aedf 1168 helper(cpu_fir[rc], cpu_env, va, vb);
f24518b5
RH
1169 tcg_temp_free(va);
1170 tcg_temp_free(vb);
1171
1172 gen_fp_exc_raise(rc, fn11);
1173}
1174
1175#define IEEE_CMP3(name) \
1176static inline void glue(gen_f, name)(DisasContext *ctx, \
1177 int ra, int rb, int rc, int fn11) \
1178{ \
1179 gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11); \
1180}
1181IEEE_CMP3(cmptun)
1182IEEE_CMP3(cmpteq)
1183IEEE_CMP3(cmptlt)
1184IEEE_CMP3(cmptle)
a7812ae4 1185
248c42f3
RH
1186static inline uint64_t zapnot_mask(uint8_t lit)
1187{
1188 uint64_t mask = 0;
1189 int i;
1190
1191 for (i = 0; i < 8; ++i) {
67debe3a 1192 if ((lit >> i) & 1) {
248c42f3 1193 mask |= 0xffull << (i * 8);
67debe3a 1194 }
248c42f3
RH
1195 }
1196 return mask;
1197}
1198
87d98f95
RH
1199/* Implement zapnot with an immediate operand, which expands to some
1200 form of immediate AND. This is a basic building block in the
1201 definition of many of the other byte manipulation instructions. */
248c42f3 1202static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
87d98f95 1203{
87d98f95
RH
1204 switch (lit) {
1205 case 0x00:
248c42f3 1206 tcg_gen_movi_i64(dest, 0);
87d98f95
RH
1207 break;
1208 case 0x01:
248c42f3 1209 tcg_gen_ext8u_i64(dest, src);
87d98f95
RH
1210 break;
1211 case 0x03:
248c42f3 1212 tcg_gen_ext16u_i64(dest, src);
87d98f95
RH
1213 break;
1214 case 0x0f:
248c42f3 1215 tcg_gen_ext32u_i64(dest, src);
87d98f95
RH
1216 break;
1217 case 0xff:
248c42f3 1218 tcg_gen_mov_i64(dest, src);
87d98f95
RH
1219 break;
1220 default:
248c42f3 1221 tcg_gen_andi_i64 (dest, src, zapnot_mask (lit));
87d98f95
RH
1222 break;
1223 }
1224}
1225
1226static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
1227{
67debe3a 1228 if (unlikely(rc == 31)) {
87d98f95 1229 return;
67debe3a 1230 } else if (unlikely(ra == 31)) {
87d98f95 1231 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1232 } else if (islit) {
248c42f3 1233 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], lit);
67debe3a 1234 } else {
87d98f95 1235 gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 1236 }
87d98f95
RH
1237}
1238
1239static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
1240{
67debe3a 1241 if (unlikely(rc == 31)) {
87d98f95 1242 return;
67debe3a 1243 } else if (unlikely(ra == 31)) {
87d98f95 1244 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1245 } else if (islit) {
248c42f3 1246 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], ~lit);
67debe3a 1247 } else {
87d98f95 1248 gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 1249 }
87d98f95
RH
1250}
1251
1252
248c42f3 1253/* EXTWH, EXTLH, EXTQH */
ffec44f1
RH
1254static void gen_ext_h(int ra, int rb, int rc, int islit,
1255 uint8_t lit, uint8_t byte_mask)
b3249f63 1256{
67debe3a 1257 if (unlikely(rc == 31)) {
b3249f63 1258 return;
67debe3a 1259 } else if (unlikely(ra == 31)) {
377a43b6 1260 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1261 } else {
dfaa8583 1262 if (islit) {
377a43b6
RH
1263 lit = (64 - (lit & 7) * 8) & 0x3f;
1264 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit);
fe2b269a 1265 } else {
377a43b6 1266 TCGv tmp1 = tcg_temp_new();
b3249f63
AJ
1267 tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
1268 tcg_gen_shli_i64(tmp1, tmp1, 3);
dbf95805
VW
1269 tcg_gen_neg_i64(tmp1, tmp1);
1270 tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
dfaa8583 1271 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
b3249f63 1272 tcg_temp_free(tmp1);
dfaa8583 1273 }
248c42f3 1274 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
377a43b6 1275 }
b3249f63
AJ
1276}
1277
248c42f3 1278/* EXTBL, EXTWL, EXTLL, EXTQL */
ffec44f1
RH
1279static void gen_ext_l(int ra, int rb, int rc, int islit,
1280 uint8_t lit, uint8_t byte_mask)
b3249f63 1281{
67debe3a 1282 if (unlikely(rc == 31)) {
b3249f63 1283 return;
67debe3a 1284 } else if (unlikely(ra == 31)) {
377a43b6 1285 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1286 } else {
dfaa8583 1287 if (islit) {
377a43b6 1288 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
dfaa8583 1289 } else {
a7812ae4 1290 TCGv tmp = tcg_temp_new();
b3249f63
AJ
1291 tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
1292 tcg_gen_shli_i64(tmp, tmp, 3);
dfaa8583 1293 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
b3249f63 1294 tcg_temp_free(tmp);
fe2b269a 1295 }
248c42f3
RH
1296 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
1297 }
1298}
1299
50eb6e5c
RH
1300/* INSWH, INSLH, INSQH */
1301static void gen_ins_h(int ra, int rb, int rc, int islit,
1302 uint8_t lit, uint8_t byte_mask)
1303{
67debe3a 1304 if (unlikely(rc == 31)) {
50eb6e5c 1305 return;
67debe3a 1306 } else if (unlikely(ra == 31) || (islit && (lit & 7) == 0)) {
50eb6e5c 1307 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1308 } else {
50eb6e5c
RH
1309 TCGv tmp = tcg_temp_new();
1310
1311 /* The instruction description has us left-shift the byte mask
1312 and extract bits <15:8> and apply that zap at the end. This
1313 is equivalent to simply performing the zap first and shifting
1314 afterward. */
1315 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1316
1317 if (islit) {
1318 /* Note that we have handled the lit==0 case above. */
1319 tcg_gen_shri_i64 (cpu_ir[rc], tmp, 64 - (lit & 7) * 8);
1320 } else {
1321 TCGv shift = tcg_temp_new();
1322
1323 /* If (B & 7) == 0, we need to shift by 64 and leave a zero.
1324 Do this portably by splitting the shift into two parts:
1325 shift_count-1 and 1. Arrange for the -1 by using
1326 ones-complement instead of twos-complement in the negation:
1327 ~((B & 7) * 8) & 63. */
1328
1329 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1330 tcg_gen_shli_i64(shift, shift, 3);
1331 tcg_gen_not_i64(shift, shift);
1332 tcg_gen_andi_i64(shift, shift, 0x3f);
1333
1334 tcg_gen_shr_i64(cpu_ir[rc], tmp, shift);
1335 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[rc], 1);
1336 tcg_temp_free(shift);
1337 }
1338 tcg_temp_free(tmp);
1339 }
1340}
1341
248c42f3 1342/* INSBL, INSWL, INSLL, INSQL */
ffec44f1
RH
1343static void gen_ins_l(int ra, int rb, int rc, int islit,
1344 uint8_t lit, uint8_t byte_mask)
248c42f3 1345{
67debe3a 1346 if (unlikely(rc == 31)) {
248c42f3 1347 return;
67debe3a 1348 } else if (unlikely(ra == 31)) {
248c42f3 1349 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1350 } else {
248c42f3
RH
1351 TCGv tmp = tcg_temp_new();
1352
1353 /* The instruction description has us left-shift the byte mask
1354 the same number of byte slots as the data and apply the zap
1355 at the end. This is equivalent to simply performing the zap
1356 first and shifting afterward. */
1357 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
1358
1359 if (islit) {
1360 tcg_gen_shli_i64(cpu_ir[rc], tmp, (lit & 7) * 8);
1361 } else {
1362 TCGv shift = tcg_temp_new();
1363 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1364 tcg_gen_shli_i64(shift, shift, 3);
1365 tcg_gen_shl_i64(cpu_ir[rc], tmp, shift);
1366 tcg_temp_free(shift);
1367 }
1368 tcg_temp_free(tmp);
377a43b6 1369 }
b3249f63
AJ
1370}
1371
ffec44f1
RH
1372/* MSKWH, MSKLH, MSKQH */
1373static void gen_msk_h(int ra, int rb, int rc, int islit,
1374 uint8_t lit, uint8_t byte_mask)
1375{
67debe3a 1376 if (unlikely(rc == 31)) {
ffec44f1 1377 return;
67debe3a 1378 } else if (unlikely(ra == 31)) {
ffec44f1 1379 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1380 } else if (islit) {
ffec44f1
RH
1381 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~((byte_mask << (lit & 7)) >> 8));
1382 } else {
1383 TCGv shift = tcg_temp_new();
1384 TCGv mask = tcg_temp_new();
1385
1386 /* The instruction description is as above, where the byte_mask
1387 is shifted left, and then we extract bits <15:8>. This can be
1388 emulated with a right-shift on the expanded byte mask. This
1389 requires extra care because for an input <2:0> == 0 we need a
1390 shift of 64 bits in order to generate a zero. This is done by
1391 splitting the shift into two parts, the variable shift - 1
1392 followed by a constant 1 shift. The code we expand below is
1393 equivalent to ~((B & 7) * 8) & 63. */
1394
1395 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1396 tcg_gen_shli_i64(shift, shift, 3);
1397 tcg_gen_not_i64(shift, shift);
1398 tcg_gen_andi_i64(shift, shift, 0x3f);
1399 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1400 tcg_gen_shr_i64(mask, mask, shift);
1401 tcg_gen_shri_i64(mask, mask, 1);
1402
1403 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1404
1405 tcg_temp_free(mask);
1406 tcg_temp_free(shift);
1407 }
1408}
1409
14ab1634 1410/* MSKBL, MSKWL, MSKLL, MSKQL */
ffec44f1
RH
1411static void gen_msk_l(int ra, int rb, int rc, int islit,
1412 uint8_t lit, uint8_t byte_mask)
14ab1634 1413{
67debe3a 1414 if (unlikely(rc == 31)) {
14ab1634 1415 return;
67debe3a 1416 } else if (unlikely(ra == 31)) {
14ab1634 1417 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 1418 } else if (islit) {
14ab1634
RH
1419 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~(byte_mask << (lit & 7)));
1420 } else {
1421 TCGv shift = tcg_temp_new();
1422 TCGv mask = tcg_temp_new();
1423
1424 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
1425 tcg_gen_shli_i64(shift, shift, 3);
1426 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1427 tcg_gen_shl_i64(mask, mask, shift);
1428
1429 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
1430
1431 tcg_temp_free(mask);
1432 tcg_temp_free(shift);
1433 }
1434}
1435
04acd307 1436/* Code to call arith3 helpers */
a7812ae4 1437#define ARITH3(name) \
636aa200
BS
1438static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
1439 uint8_t lit) \
a7812ae4
PB
1440{ \
1441 if (unlikely(rc == 31)) \
1442 return; \
1443 \
1444 if (ra != 31) { \
1445 if (islit) { \
1446 TCGv tmp = tcg_const_i64(lit); \
1447 gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp); \
1448 tcg_temp_free(tmp); \
1449 } else \
1450 gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
1451 } else { \
1452 TCGv tmp1 = tcg_const_i64(0); \
1453 if (islit) { \
1454 TCGv tmp2 = tcg_const_i64(lit); \
1455 gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2); \
1456 tcg_temp_free(tmp2); \
1457 } else \
1458 gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]); \
1459 tcg_temp_free(tmp1); \
1460 } \
b3249f63 1461}
2958620f 1462ARITH3(cmpbge)
13e4df99
RH
1463ARITH3(minub8)
1464ARITH3(minsb8)
1465ARITH3(minuw4)
1466ARITH3(minsw4)
1467ARITH3(maxub8)
1468ARITH3(maxsb8)
1469ARITH3(maxuw4)
1470ARITH3(maxsw4)
1471ARITH3(perr)
1472
2958620f
RH
1473/* Code to call arith3 helpers */
1474#define ARITH3_EX(name) \
1475 static inline void glue(gen_, name)(int ra, int rb, int rc, \
1476 int islit, uint8_t lit) \
1477 { \
1478 if (unlikely(rc == 31)) { \
1479 return; \
1480 } \
1481 if (ra != 31) { \
1482 if (islit) { \
1483 TCGv tmp = tcg_const_i64(lit); \
1484 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1485 cpu_ir[ra], tmp); \
1486 tcg_temp_free(tmp); \
1487 } else { \
1488 gen_helper_ ## name(cpu_ir[rc], cpu_env, \
1489 cpu_ir[ra], cpu_ir[rb]); \
1490 } \
1491 } else { \
1492 TCGv tmp1 = tcg_const_i64(0); \
1493 if (islit) { \
1494 TCGv tmp2 = tcg_const_i64(lit); \
1495 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, tmp2); \
1496 tcg_temp_free(tmp2); \
1497 } else { \
1498 gen_helper_ ## name(cpu_ir[rc], cpu_env, tmp1, cpu_ir[rb]); \
1499 } \
1500 tcg_temp_free(tmp1); \
1501 } \
1502 }
1503ARITH3_EX(addlv)
1504ARITH3_EX(sublv)
1505ARITH3_EX(addqv)
1506ARITH3_EX(subqv)
1507ARITH3_EX(mullv)
1508ARITH3_EX(mulqv)
1509
13e4df99
RH
1510#define MVIOP2(name) \
1511static inline void glue(gen_, name)(int rb, int rc) \
1512{ \
1513 if (unlikely(rc == 31)) \
1514 return; \
1515 if (unlikely(rb == 31)) \
1516 tcg_gen_movi_i64(cpu_ir[rc], 0); \
1517 else \
1518 gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \
1519}
1520MVIOP2(pklb)
1521MVIOP2(pkwb)
1522MVIOP2(unpkbl)
1523MVIOP2(unpkbw)
b3249f63 1524
9e05960f
RH
1525static void gen_cmp(TCGCond cond, int ra, int rb, int rc,
1526 int islit, uint8_t lit)
01ff9cc8 1527{
9e05960f 1528 TCGv va, vb;
01ff9cc8 1529
9e05960f 1530 if (unlikely(rc == 31)) {
13e4df99 1531 return;
9e05960f 1532 }
01ff9cc8 1533
9e05960f
RH
1534 if (ra == 31) {
1535 va = tcg_const_i64(0);
1536 } else {
1537 va = cpu_ir[ra];
1538 }
1539 if (islit) {
1540 vb = tcg_const_i64(lit);
1541 } else {
1542 vb = cpu_ir[rb];
1543 }
01ff9cc8 1544
9e05960f 1545 tcg_gen_setcond_i64(cond, cpu_ir[rc], va, vb);
01ff9cc8 1546
9e05960f
RH
1547 if (ra == 31) {
1548 tcg_temp_free(va);
1549 }
1550 if (islit) {
1551 tcg_temp_free(vb);
1552 }
01ff9cc8
AJ
1553}
1554
ac316ca4
RH
1555static void gen_rx(int ra, int set)
1556{
1557 TCGv_i32 tmp;
1558
1559 if (ra != 31) {
4d5712f1 1560 tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, offsetof(CPUAlphaState, intr_flag));
ac316ca4
RH
1561 }
1562
1563 tmp = tcg_const_i32(set);
4d5712f1 1564 tcg_gen_st8_i32(tmp, cpu_env, offsetof(CPUAlphaState, intr_flag));
ac316ca4
RH
1565 tcg_temp_free_i32(tmp);
1566}
1567
2ace7e55
RH
1568static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
1569{
1570 /* We're emulating OSF/1 PALcode. Many of these are trivial access
1571 to internal cpu registers. */
1572
1573 /* Unprivileged PAL call */
1574 if (palcode >= 0x80 && palcode < 0xC0) {
1575 switch (palcode) {
1576 case 0x86:
1577 /* IMB */
1578 /* No-op inside QEMU. */
1579 break;
1580 case 0x9E:
1581 /* RDUNIQUE */
1582 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique);
1583 break;
1584 case 0x9F:
1585 /* WRUNIQUE */
1586 tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
1587 break;
1588 default:
ba96394e
RH
1589 palcode &= 0xbf;
1590 goto do_call_pal;
2ace7e55
RH
1591 }
1592 return NO_EXIT;
1593 }
1594
1595#ifndef CONFIG_USER_ONLY
1596 /* Privileged PAL code */
1597 if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
1598 switch (palcode) {
1599 case 0x01:
1600 /* CFLUSH */
1601 /* No-op inside QEMU. */
1602 break;
1603 case 0x02:
1604 /* DRAINA */
1605 /* No-op inside QEMU. */
1606 break;
1607 case 0x2D:
1608 /* WRVPTPTR */
4d5712f1 1609 tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUAlphaState, vptptr));
2ace7e55
RH
1610 break;
1611 case 0x31:
1612 /* WRVAL */
1613 tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]);
1614 break;
1615 case 0x32:
1616 /* RDVAL */
1617 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval);
1618 break;
1619
1620 case 0x35: {
1621 /* SWPIPL */
1622 TCGv tmp;
1623
1624 /* Note that we already know we're in kernel mode, so we know
1625 that PS only contains the 3 IPL bits. */
4d5712f1 1626 tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps));
2ace7e55
RH
1627
1628 /* But make sure and store only the 3 IPL bits from the user. */
1629 tmp = tcg_temp_new();
1630 tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK);
4d5712f1 1631 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, ps));
2ace7e55
RH
1632 tcg_temp_free(tmp);
1633 break;
1634 }
1635
1636 case 0x36:
1637 /* RDPS */
4d5712f1 1638 tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps));
2ace7e55
RH
1639 break;
1640 case 0x38:
1641 /* WRUSP */
1642 tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]);
1643 break;
1644 case 0x3A:
1645 /* RDUSP */
1646 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp);
1647 break;
1648 case 0x3C:
1649 /* WHAMI */
1650 tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env,
55e5c285 1651 -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
2ace7e55
RH
1652 break;
1653
1654 default:
ba96394e
RH
1655 palcode &= 0x3f;
1656 goto do_call_pal;
2ace7e55
RH
1657 }
1658 return NO_EXIT;
1659 }
1660#endif
2ace7e55 1661 return gen_invalid(ctx);
ba96394e
RH
1662
1663 do_call_pal:
1664#ifdef CONFIG_USER_ONLY
1665 return gen_excp(ctx, EXCP_CALL_PAL, palcode);
1666#else
1667 {
1668 TCGv pc = tcg_const_i64(ctx->pc);
1669 TCGv entry = tcg_const_i64(palcode & 0x80
1670 ? 0x2000 + (palcode - 0x80) * 64
1671 : 0x1000 + palcode * 64);
1672
1673 gen_helper_call_pal(cpu_env, pc, entry);
1674
1675 tcg_temp_free(entry);
1676 tcg_temp_free(pc);
a9ead832
RH
1677
1678 /* Since the destination is running in PALmode, we don't really
73f395fa 1679 need the page permissions check. We'll see the existence of
a9ead832
RH
1680 the page when we create the TB, and we'll flush all TBs if
1681 we change the PAL base register. */
1682 if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) {
1683 tcg_gen_goto_tb(0);
8cfd0495 1684 tcg_gen_exit_tb((uintptr_t)ctx->tb);
a9ead832
RH
1685 return EXIT_GOTO_TB;
1686 }
1687
ba96394e
RH
1688 return EXIT_PC_UPDATED;
1689 }
1690#endif
2ace7e55
RH
1691}
1692
26b46094
RH
1693#ifndef CONFIG_USER_ONLY
1694
1695#define PR_BYTE 0x100000
1696#define PR_LONG 0x200000
1697
1698static int cpu_pr_data(int pr)
1699{
1700 switch (pr) {
1701 case 0: return offsetof(CPUAlphaState, ps) | PR_BYTE;
1702 case 1: return offsetof(CPUAlphaState, fen) | PR_BYTE;
1703 case 2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1704 case 3: return offsetof(CPUAlphaState, trap_arg0);
1705 case 4: return offsetof(CPUAlphaState, trap_arg1);
1706 case 5: return offsetof(CPUAlphaState, trap_arg2);
1707 case 6: return offsetof(CPUAlphaState, exc_addr);
1708 case 7: return offsetof(CPUAlphaState, palbr);
1709 case 8: return offsetof(CPUAlphaState, ptbr);
1710 case 9: return offsetof(CPUAlphaState, vptptr);
1711 case 10: return offsetof(CPUAlphaState, unique);
1712 case 11: return offsetof(CPUAlphaState, sysval);
1713 case 12: return offsetof(CPUAlphaState, usp);
1714
1715 case 32 ... 39:
1716 return offsetof(CPUAlphaState, shadow[pr - 32]);
1717 case 40 ... 63:
1718 return offsetof(CPUAlphaState, scratch[pr - 40]);
c781cf96
RH
1719
1720 case 251:
1721 return offsetof(CPUAlphaState, alarm_expire);
26b46094
RH
1722 }
1723 return 0;
1724}
1725
c781cf96 1726static ExitStatus gen_mfpr(int ra, int regno)
26b46094
RH
1727{
1728 int data = cpu_pr_data(regno);
1729
1730 /* In our emulated PALcode, these processor registers have no
1731 side effects from reading. */
1732 if (ra == 31) {
c781cf96
RH
1733 return NO_EXIT;
1734 }
1735
19e0cbb8
RH
1736 /* Special help for VMTIME and WALLTIME. */
1737 if (regno == 250 || regno == 249) {
1738 void (*helper)(TCGv) = gen_helper_get_walltime;
1739 if (regno == 249) {
1740 helper = gen_helper_get_vmtime;
1741 }
c781cf96
RH
1742 if (use_icount) {
1743 gen_io_start();
19e0cbb8 1744 helper(cpu_ir[ra]);
c781cf96
RH
1745 gen_io_end();
1746 return EXIT_PC_STALE;
1747 } else {
19e0cbb8 1748 helper(cpu_ir[ra]);
c781cf96
RH
1749 return NO_EXIT;
1750 }
26b46094
RH
1751 }
1752
1753 /* The basic registers are data only, and unknown registers
1754 are read-zero, write-ignore. */
1755 if (data == 0) {
1756 tcg_gen_movi_i64(cpu_ir[ra], 0);
1757 } else if (data & PR_BYTE) {
1758 tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, data & ~PR_BYTE);
1759 } else if (data & PR_LONG) {
1760 tcg_gen_ld32s_i64(cpu_ir[ra], cpu_env, data & ~PR_LONG);
1761 } else {
1762 tcg_gen_ld_i64(cpu_ir[ra], cpu_env, data);
1763 }
c781cf96 1764 return NO_EXIT;
26b46094
RH
1765}
1766
bc24270e 1767static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
26b46094
RH
1768{
1769 TCGv tmp;
bc24270e 1770 int data;
26b46094
RH
1771
1772 if (rb == 31) {
1773 tmp = tcg_const_i64(0);
1774 } else {
1775 tmp = cpu_ir[rb];
1776 }
1777
bc24270e
RH
1778 switch (regno) {
1779 case 255:
3b4fefd6 1780 /* TBIA */
69163fbb 1781 gen_helper_tbia(cpu_env);
bc24270e
RH
1782 break;
1783
1784 case 254:
3b4fefd6 1785 /* TBIS */
69163fbb 1786 gen_helper_tbis(cpu_env, tmp);
bc24270e
RH
1787 break;
1788
1789 case 253:
1790 /* WAIT */
1791 tmp = tcg_const_i64(1);
259186a7
AF
1792 tcg_gen_st32_i64(tmp, cpu_env, -offsetof(AlphaCPU, env) +
1793 offsetof(CPUState, halted));
bc24270e
RH
1794 return gen_excp(ctx, EXCP_HLT, 0);
1795
034ebc27
RH
1796 case 252:
1797 /* HALT */
1798 gen_helper_halt(tmp);
1799 return EXIT_PC_STALE;
1800
c781cf96
RH
1801 case 251:
1802 /* ALARM */
69163fbb 1803 gen_helper_set_alarm(cpu_env, tmp);
c781cf96
RH
1804 break;
1805
a9ead832
RH
1806 case 7:
1807 /* PALBR */
1808 tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, palbr));
1809 /* Changing the PAL base register implies un-chaining all of the TBs
1810 that ended with a CALL_PAL. Since the base register usually only
1811 changes during boot, flushing everything works well. */
1812 gen_helper_tb_flush(cpu_env);
1813 return EXIT_PC_STALE;
1814
bc24270e 1815 default:
3b4fefd6
RH
1816 /* The basic registers are data only, and unknown registers
1817 are read-zero, write-ignore. */
bc24270e 1818 data = cpu_pr_data(regno);
3b4fefd6
RH
1819 if (data != 0) {
1820 if (data & PR_BYTE) {
1821 tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
1822 } else if (data & PR_LONG) {
1823 tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
1824 } else {
1825 tcg_gen_st_i64(tmp, cpu_env, data);
1826 }
26b46094 1827 }
bc24270e 1828 break;
26b46094
RH
1829 }
1830
1831 if (rb == 31) {
1832 tcg_temp_free(tmp);
1833 }
bc24270e
RH
1834
1835 return NO_EXIT;
26b46094
RH
1836}
1837#endif /* !USER_ONLY*/
1838
5238c886
RH
1839#define REQUIRE_TB_FLAG(FLAG) \
1840 do { \
1841 if ((ctx->tb->flags & (FLAG)) == 0) { \
1842 goto invalid_opc; \
1843 } \
1844 } while (0)
1845
64f45e49
RH
1846#define REQUIRE_REG_31(WHICH) \
1847 do { \
1848 if (WHICH != 31) { \
1849 goto invalid_opc; \
1850 } \
1851 } while (0)
1852
4af70374 1853static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
4c9649a9
JM
1854{
1855 uint32_t palcode;
efa64351
MT
1856 int32_t disp21, disp16;
1857#ifndef CONFIG_USER_ONLY
1858 int32_t disp12;
1859#endif
f88fe4e3 1860 uint16_t fn11;
194cfb43
RH
1861 uint8_t opc, ra, rb, rc, fpfn, fn7, lit;
1862 bool islit;
1863 TCGv va, vb, vc, tmp;
4af70374 1864 ExitStatus ret;
4c9649a9
JM
1865
1866 /* Decode all instruction fields */
1867 opc = insn >> 26;
1868 ra = (insn >> 21) & 0x1F;
1869 rb = (insn >> 16) & 0x1F;
1870 rc = insn & 0x1F;
64f45e49 1871 islit = (insn >> 12) & 1;
dfaa8583
AJ
1872 if (rb == 31 && !islit) {
1873 islit = 1;
1874 lit = 0;
194cfb43 1875 } else {
dfaa8583 1876 lit = (insn >> 13) & 0xFF;
194cfb43 1877 }
4c9649a9
JM
1878 palcode = insn & 0x03FFFFFF;
1879 disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
1880 disp16 = (int16_t)(insn & 0x0000FFFF);
efa64351 1881#ifndef CONFIG_USER_ONLY
4c9649a9 1882 disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
efa64351 1883#endif
4c9649a9
JM
1884 fn11 = (insn >> 5) & 0x000007FF;
1885 fpfn = fn11 & 0x3F;
1886 fn7 = (insn >> 5) & 0x0000007F;
806991da 1887 LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
d12d51d5 1888 opc, ra, rb, rc, disp16);
806991da 1889
4af70374 1890 ret = NO_EXIT;
4c9649a9
JM
1891 switch (opc) {
1892 case 0x00:
1893 /* CALL_PAL */
2ace7e55
RH
1894 ret = gen_call_pal(ctx, palcode);
1895 break;
4c9649a9
JM
1896 case 0x01:
1897 /* OPC01 */
1898 goto invalid_opc;
1899 case 0x02:
1900 /* OPC02 */
1901 goto invalid_opc;
1902 case 0x03:
1903 /* OPC03 */
1904 goto invalid_opc;
1905 case 0x04:
1906 /* OPC04 */
1907 goto invalid_opc;
1908 case 0x05:
1909 /* OPC05 */
1910 goto invalid_opc;
1911 case 0x06:
1912 /* OPC06 */
1913 goto invalid_opc;
1914 case 0x07:
1915 /* OPC07 */
1916 goto invalid_opc;
194cfb43 1917
4c9649a9
JM
1918 case 0x09:
1919 /* LDAH */
194cfb43
RH
1920 disp16 = (uint32_t)disp16 << 16;
1921 /* fall through */
1922 case 0x08:
1923 /* LDA */
1924 va = dest_gpr(ctx, ra);
1925 /* It's worth special-casing immediate loads. */
1926 if (rb == 31) {
1927 tcg_gen_movi_i64(va, disp16);
1928 } else {
1929 tcg_gen_addi_i64(va, load_gpr(ctx, rb), disp16);
496cb5b9 1930 }
4c9649a9 1931 break;
194cfb43 1932
4c9649a9
JM
1933 case 0x0A:
1934 /* LDBU */
5238c886
RH
1935 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
1936 gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1937 break;
4c9649a9
JM
1938 case 0x0B:
1939 /* LDQ_U */
f18cd223 1940 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
4c9649a9
JM
1941 break;
1942 case 0x0C:
1943 /* LDWU */
5238c886
RH
1944 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
1945 gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1946 break;
4c9649a9
JM
1947 case 0x0D:
1948 /* STW */
5238c886 1949 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
6910b8f6 1950 gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
4c9649a9
JM
1951 break;
1952 case 0x0E:
1953 /* STB */
5238c886 1954 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
6910b8f6 1955 gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
4c9649a9
JM
1956 break;
1957 case 0x0F:
1958 /* STQ_U */
6910b8f6 1959 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
4c9649a9 1960 break;
194cfb43 1961
4c9649a9 1962 case 0x10:
194cfb43
RH
1963 vc = dest_gpr(ctx, rc);
1964 vb = load_gpr_lit(ctx, rb, lit, islit);
1965
1966 if (ra == 31) {
1967 if (fn7 == 0x00) {
1968 /* Special case ADDL as SEXTL. */
1969 tcg_gen_ext32s_i64(vc, vb);
1970 break;
1971 }
1972 if (fn7 == 0x29) {
1973 /* Special case SUBQ as NEGQ. */
1974 tcg_gen_neg_i64(vc, vb);
1975 break;
1976 }
1977 }
1978
1979 va = load_gpr(ctx, ra);
4c9649a9
JM
1980 switch (fn7) {
1981 case 0x00:
1982 /* ADDL */
194cfb43
RH
1983 tcg_gen_add_i64(vc, va, vb);
1984 tcg_gen_ext32s_i64(vc, vc);
4c9649a9
JM
1985 break;
1986 case 0x02:
1987 /* S4ADDL */
194cfb43
RH
1988 tmp = tcg_temp_new();
1989 tcg_gen_shli_i64(tmp, va, 2);
1990 tcg_gen_add_i64(tmp, tmp, vb);
1991 tcg_gen_ext32s_i64(vc, tmp);
1992 tcg_temp_free(tmp);
4c9649a9
JM
1993 break;
1994 case 0x09:
1995 /* SUBL */
194cfb43
RH
1996 tcg_gen_sub_i64(vc, va, vb);
1997 tcg_gen_ext32s_i64(vc, vc);
4c9649a9
JM
1998 break;
1999 case 0x0B:
2000 /* S4SUBL */
194cfb43
RH
2001 tmp = tcg_temp_new();
2002 tcg_gen_shli_i64(tmp, va, 2);
2003 tcg_gen_sub_i64(tmp, tmp, vb);
2004 tcg_gen_ext32s_i64(vc, tmp);
2005 tcg_temp_free(tmp);
4c9649a9
JM
2006 break;
2007 case 0x0F:
2008 /* CMPBGE */
a7812ae4 2009 gen_cmpbge(ra, rb, rc, islit, lit);
4c9649a9
JM
2010 break;
2011 case 0x12:
2012 /* S8ADDL */
194cfb43
RH
2013 tmp = tcg_temp_new();
2014 tcg_gen_shli_i64(tmp, va, 3);
2015 tcg_gen_add_i64(tmp, tmp, vb);
2016 tcg_gen_ext32s_i64(vc, tmp);
2017 tcg_temp_free(tmp);
4c9649a9
JM
2018 break;
2019 case 0x1B:
2020 /* S8SUBL */
194cfb43
RH
2021 tmp = tcg_temp_new();
2022 tcg_gen_shli_i64(tmp, va, 3);
2023 tcg_gen_sub_i64(tmp, tmp, vb);
2024 tcg_gen_ext32s_i64(vc, tmp);
2025 tcg_temp_free(tmp);
4c9649a9
JM
2026 break;
2027 case 0x1D:
2028 /* CMPULT */
01ff9cc8 2029 gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
4c9649a9
JM
2030 break;
2031 case 0x20:
2032 /* ADDQ */
194cfb43 2033 tcg_gen_add_i64(vc, va, vb);
4c9649a9
JM
2034 break;
2035 case 0x22:
2036 /* S4ADDQ */
194cfb43
RH
2037 tmp = tcg_temp_new();
2038 tcg_gen_shli_i64(tmp, va, 2);
2039 tcg_gen_add_i64(vc, tmp, vb);
2040 tcg_temp_free(tmp);
4c9649a9
JM
2041 break;
2042 case 0x29:
2043 /* SUBQ */
194cfb43 2044 tcg_gen_sub_i64(vc, va, vb);
4c9649a9
JM
2045 break;
2046 case 0x2B:
2047 /* S4SUBQ */
194cfb43
RH
2048 tmp = tcg_temp_new();
2049 tcg_gen_shli_i64(tmp, va, 2);
2050 tcg_gen_sub_i64(vc, tmp, vb);
2051 tcg_temp_free(tmp);
4c9649a9
JM
2052 break;
2053 case 0x2D:
2054 /* CMPEQ */
01ff9cc8 2055 gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
4c9649a9
JM
2056 break;
2057 case 0x32:
2058 /* S8ADDQ */
194cfb43
RH
2059 tmp = tcg_temp_new();
2060 tcg_gen_shli_i64(tmp, va, 3);
2061 tcg_gen_add_i64(vc, tmp, vb);
2062 tcg_temp_free(tmp);
4c9649a9
JM
2063 break;
2064 case 0x3B:
2065 /* S8SUBQ */
194cfb43
RH
2066 tmp = tcg_temp_new();
2067 tcg_gen_shli_i64(tmp, va, 3);
2068 tcg_gen_sub_i64(vc, tmp, vb);
2069 tcg_temp_free(tmp);
4c9649a9
JM
2070 break;
2071 case 0x3D:
2072 /* CMPULE */
01ff9cc8 2073 gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
4c9649a9
JM
2074 break;
2075 case 0x40:
2076 /* ADDL/V */
a7812ae4 2077 gen_addlv(ra, rb, rc, islit, lit);
4c9649a9
JM
2078 break;
2079 case 0x49:
2080 /* SUBL/V */
a7812ae4 2081 gen_sublv(ra, rb, rc, islit, lit);
4c9649a9
JM
2082 break;
2083 case 0x4D:
2084 /* CMPLT */
01ff9cc8 2085 gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
4c9649a9
JM
2086 break;
2087 case 0x60:
2088 /* ADDQ/V */
a7812ae4 2089 gen_addqv(ra, rb, rc, islit, lit);
4c9649a9
JM
2090 break;
2091 case 0x69:
2092 /* SUBQ/V */
a7812ae4 2093 gen_subqv(ra, rb, rc, islit, lit);
4c9649a9
JM
2094 break;
2095 case 0x6D:
2096 /* CMPLE */
01ff9cc8 2097 gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
4c9649a9
JM
2098 break;
2099 default:
2100 goto invalid_opc;
2101 }
2102 break;
2103 case 0x11:
2104 switch (fn7) {
2105 case 0x00:
2106 /* AND */
30c7183b 2107 if (likely(rc != 31)) {
67debe3a 2108 if (ra == 31) {
30c7183b 2109 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 2110 } else if (islit) {
30c7183b 2111 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
67debe3a 2112 } else {
30c7183b 2113 tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2114 }
30c7183b 2115 }
4c9649a9
JM
2116 break;
2117 case 0x08:
2118 /* BIC */
30c7183b
AJ
2119 if (likely(rc != 31)) {
2120 if (ra != 31) {
67debe3a 2121 if (islit) {
30c7183b 2122 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
67debe3a 2123 } else {
1b581c44 2124 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2125 }
30c7183b
AJ
2126 } else
2127 tcg_gen_movi_i64(cpu_ir[rc], 0);
2128 }
4c9649a9
JM
2129 break;
2130 case 0x14:
2131 /* CMOVLBS */
bbe1dab4 2132 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
4c9649a9
JM
2133 break;
2134 case 0x16:
2135 /* CMOVLBC */
bbe1dab4 2136 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
4c9649a9
JM
2137 break;
2138 case 0x20:
2139 /* BIS */
30c7183b
AJ
2140 if (likely(rc != 31)) {
2141 if (ra != 31) {
67debe3a 2142 if (islit) {
30c7183b 2143 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
67debe3a 2144 } else {
30c7183b 2145 tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2146 }
4c9649a9 2147 } else {
67debe3a 2148 if (islit) {
30c7183b 2149 tcg_gen_movi_i64(cpu_ir[rc], lit);
67debe3a 2150 } else {
dfaa8583 2151 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
67debe3a 2152 }
4c9649a9 2153 }
4c9649a9
JM
2154 }
2155 break;
2156 case 0x24:
2157 /* CMOVEQ */
bbe1dab4 2158 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
2159 break;
2160 case 0x26:
2161 /* CMOVNE */
bbe1dab4 2162 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
2163 break;
2164 case 0x28:
2165 /* ORNOT */
30c7183b 2166 if (likely(rc != 31)) {
dfaa8583 2167 if (ra != 31) {
67debe3a 2168 if (islit) {
30c7183b 2169 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
67debe3a 2170 } else {
1b581c44 2171 tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2172 }
30c7183b 2173 } else {
67debe3a 2174 if (islit) {
30c7183b 2175 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
67debe3a 2176 } else {
30c7183b 2177 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
67debe3a 2178 }
30c7183b
AJ
2179 }
2180 }
4c9649a9
JM
2181 break;
2182 case 0x40:
2183 /* XOR */
30c7183b
AJ
2184 if (likely(rc != 31)) {
2185 if (ra != 31) {
67debe3a 2186 if (islit) {
30c7183b 2187 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
67debe3a 2188 } else {
dfaa8583 2189 tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2190 }
30c7183b 2191 } else {
67debe3a 2192 if (islit) {
30c7183b 2193 tcg_gen_movi_i64(cpu_ir[rc], lit);
67debe3a 2194 } else {
dfaa8583 2195 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
67debe3a 2196 }
30c7183b
AJ
2197 }
2198 }
4c9649a9
JM
2199 break;
2200 case 0x44:
2201 /* CMOVLT */
bbe1dab4 2202 gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
2203 break;
2204 case 0x46:
2205 /* CMOVGE */
bbe1dab4 2206 gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
2207 break;
2208 case 0x48:
2209 /* EQV */
30c7183b
AJ
2210 if (likely(rc != 31)) {
2211 if (ra != 31) {
67debe3a 2212 if (islit) {
30c7183b 2213 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
67debe3a 2214 } else {
1b581c44 2215 tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2216 }
30c7183b 2217 } else {
67debe3a 2218 if (islit) {
30c7183b 2219 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
67debe3a 2220 } else {
dfaa8583 2221 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
67debe3a 2222 }
30c7183b
AJ
2223 }
2224 }
4c9649a9
JM
2225 break;
2226 case 0x61:
2227 /* AMASK */
64f45e49 2228 REQUIRE_REG_31(ra);
ae8ecd42 2229 if (likely(rc != 31)) {
a18ad893
RH
2230 uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
2231
2232 if (islit) {
2233 tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);
2234 } else {
2235 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);
1a1f7dbc 2236 }
ae8ecd42 2237 }
4c9649a9
JM
2238 break;
2239 case 0x64:
2240 /* CMOVLE */
bbe1dab4 2241 gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
2242 break;
2243 case 0x66:
2244 /* CMOVGT */
bbe1dab4 2245 gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
2246 break;
2247 case 0x6C:
2248 /* IMPLVER */
64f45e49 2249 REQUIRE_REG_31(ra);
801c4c28
RH
2250 if (rc != 31) {
2251 tcg_gen_movi_i64(cpu_ir[rc], ctx->implver);
2252 }
4c9649a9
JM
2253 break;
2254 default:
2255 goto invalid_opc;
2256 }
2257 break;
2258 case 0x12:
2259 switch (fn7) {
2260 case 0x02:
2261 /* MSKBL */
14ab1634 2262 gen_msk_l(ra, rb, rc, islit, lit, 0x01);
4c9649a9
JM
2263 break;
2264 case 0x06:
2265 /* EXTBL */
377a43b6 2266 gen_ext_l(ra, rb, rc, islit, lit, 0x01);
4c9649a9
JM
2267 break;
2268 case 0x0B:
2269 /* INSBL */
248c42f3 2270 gen_ins_l(ra, rb, rc, islit, lit, 0x01);
4c9649a9
JM
2271 break;
2272 case 0x12:
2273 /* MSKWL */
14ab1634 2274 gen_msk_l(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
2275 break;
2276 case 0x16:
2277 /* EXTWL */
377a43b6 2278 gen_ext_l(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
2279 break;
2280 case 0x1B:
2281 /* INSWL */
248c42f3 2282 gen_ins_l(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
2283 break;
2284 case 0x22:
2285 /* MSKLL */
14ab1634 2286 gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
2287 break;
2288 case 0x26:
2289 /* EXTLL */
377a43b6 2290 gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
2291 break;
2292 case 0x2B:
2293 /* INSLL */
248c42f3 2294 gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
2295 break;
2296 case 0x30:
2297 /* ZAP */
a7812ae4 2298 gen_zap(ra, rb, rc, islit, lit);
4c9649a9
JM
2299 break;
2300 case 0x31:
2301 /* ZAPNOT */
a7812ae4 2302 gen_zapnot(ra, rb, rc, islit, lit);
4c9649a9
JM
2303 break;
2304 case 0x32:
2305 /* MSKQL */
14ab1634 2306 gen_msk_l(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
2307 break;
2308 case 0x34:
2309 /* SRL */
30c7183b
AJ
2310 if (likely(rc != 31)) {
2311 if (ra != 31) {
67debe3a 2312 if (islit) {
30c7183b 2313 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
67debe3a 2314 } else {
a7812ae4 2315 TCGv shift = tcg_temp_new();
30c7183b
AJ
2316 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2317 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
2318 tcg_temp_free(shift);
dfaa8583 2319 }
30c7183b
AJ
2320 } else
2321 tcg_gen_movi_i64(cpu_ir[rc], 0);
2322 }
4c9649a9
JM
2323 break;
2324 case 0x36:
2325 /* EXTQL */
377a43b6 2326 gen_ext_l(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
2327 break;
2328 case 0x39:
2329 /* SLL */
30c7183b
AJ
2330 if (likely(rc != 31)) {
2331 if (ra != 31) {
67debe3a 2332 if (islit) {
30c7183b 2333 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
67debe3a 2334 } else {
a7812ae4 2335 TCGv shift = tcg_temp_new();
30c7183b
AJ
2336 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2337 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
2338 tcg_temp_free(shift);
dfaa8583 2339 }
30c7183b
AJ
2340 } else
2341 tcg_gen_movi_i64(cpu_ir[rc], 0);
2342 }
4c9649a9
JM
2343 break;
2344 case 0x3B:
2345 /* INSQL */
248c42f3 2346 gen_ins_l(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
2347 break;
2348 case 0x3C:
2349 /* SRA */
30c7183b
AJ
2350 if (likely(rc != 31)) {
2351 if (ra != 31) {
67debe3a 2352 if (islit) {
30c7183b 2353 tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
67debe3a 2354 } else {
a7812ae4 2355 TCGv shift = tcg_temp_new();
30c7183b
AJ
2356 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
2357 tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
2358 tcg_temp_free(shift);
dfaa8583 2359 }
30c7183b
AJ
2360 } else
2361 tcg_gen_movi_i64(cpu_ir[rc], 0);
2362 }
4c9649a9
JM
2363 break;
2364 case 0x52:
2365 /* MSKWH */
ffec44f1 2366 gen_msk_h(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
2367 break;
2368 case 0x57:
2369 /* INSWH */
50eb6e5c 2370 gen_ins_h(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
2371 break;
2372 case 0x5A:
2373 /* EXTWH */
377a43b6 2374 gen_ext_h(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
2375 break;
2376 case 0x62:
2377 /* MSKLH */
ffec44f1 2378 gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
2379 break;
2380 case 0x67:
2381 /* INSLH */
50eb6e5c 2382 gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
2383 break;
2384 case 0x6A:
2385 /* EXTLH */
377a43b6 2386 gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
2387 break;
2388 case 0x72:
2389 /* MSKQH */
ffec44f1 2390 gen_msk_h(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
2391 break;
2392 case 0x77:
2393 /* INSQH */
50eb6e5c 2394 gen_ins_h(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
2395 break;
2396 case 0x7A:
2397 /* EXTQH */
377a43b6 2398 gen_ext_h(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
2399 break;
2400 default:
2401 goto invalid_opc;
2402 }
2403 break;
2404 case 0x13:
2405 switch (fn7) {
2406 case 0x00:
2407 /* MULL */
30c7183b 2408 if (likely(rc != 31)) {
67debe3a 2409 if (ra == 31) {
30c7183b 2410 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a
PB
2411 } else {
2412 if (islit) {
30c7183b 2413 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
67debe3a 2414 } else {
30c7183b 2415 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2416 }
30c7183b
AJ
2417 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
2418 }
2419 }
4c9649a9
JM
2420 break;
2421 case 0x20:
2422 /* MULQ */
30c7183b 2423 if (likely(rc != 31)) {
67debe3a 2424 if (ra == 31) {
30c7183b 2425 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 2426 } else if (islit) {
30c7183b 2427 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
67debe3a 2428 } else {
30c7183b 2429 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
67debe3a 2430 }
30c7183b 2431 }
4c9649a9
JM
2432 break;
2433 case 0x30:
2434 /* UMULH */
962415fc
RH
2435 {
2436 TCGv low;
2437 if (unlikely(rc == 31)){
2438 break;
2439 }
2440 if (ra == 31) {
2441 tcg_gen_movi_i64(cpu_ir[rc], 0);
2442 break;
2443 }
2444 low = tcg_temp_new();
2445 if (islit) {
2446 tcg_gen_movi_tl(low, lit);
2447 tcg_gen_mulu2_i64(low, cpu_ir[rc], cpu_ir[ra], low);
2448 } else {
2449 tcg_gen_mulu2_i64(low, cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
2450 }
2451 tcg_temp_free(low);
2452 }
4c9649a9
JM
2453 break;
2454 case 0x40:
2455 /* MULL/V */
a7812ae4 2456 gen_mullv(ra, rb, rc, islit, lit);
4c9649a9
JM
2457 break;
2458 case 0x60:
2459 /* MULQ/V */
a7812ae4 2460 gen_mulqv(ra, rb, rc, islit, lit);
4c9649a9
JM
2461 break;
2462 default:
2463 goto invalid_opc;
2464 }
2465 break;
2466 case 0x14:
5238c886 2467 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX);
f24518b5 2468 switch (fpfn) { /* fn11 & 0x3F */
4c9649a9
JM
2469 case 0x04:
2470 /* ITOFS */
64f45e49 2471 REQUIRE_REG_31(rb);
f18cd223
AJ
2472 if (likely(rc != 31)) {
2473 if (ra != 31) {
a7812ae4 2474 TCGv_i32 tmp = tcg_temp_new_i32();
f18cd223 2475 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
a7812ae4
PB
2476 gen_helper_memory_to_s(cpu_fir[rc], tmp);
2477 tcg_temp_free_i32(tmp);
f18cd223
AJ
2478 } else
2479 tcg_gen_movi_i64(cpu_fir[rc], 0);
2480 }
4c9649a9
JM
2481 break;
2482 case 0x0A:
2483 /* SQRTF */
64f45e49 2484 REQUIRE_REG_31(ra);
5238c886
RH
2485 gen_fsqrtf(rb, rc);
2486 break;
4c9649a9
JM
2487 case 0x0B:
2488 /* SQRTS */
64f45e49 2489 REQUIRE_REG_31(ra);
5238c886
RH
2490 gen_fsqrts(ctx, rb, rc, fn11);
2491 break;
4c9649a9
JM
2492 case 0x14:
2493 /* ITOFF */
64f45e49 2494 REQUIRE_REG_31(rb);
f18cd223
AJ
2495 if (likely(rc != 31)) {
2496 if (ra != 31) {
a7812ae4 2497 TCGv_i32 tmp = tcg_temp_new_i32();
f18cd223 2498 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
a7812ae4
PB
2499 gen_helper_memory_to_f(cpu_fir[rc], tmp);
2500 tcg_temp_free_i32(tmp);
f18cd223
AJ
2501 } else
2502 tcg_gen_movi_i64(cpu_fir[rc], 0);
2503 }
4c9649a9
JM
2504 break;
2505 case 0x24:
2506 /* ITOFT */
64f45e49 2507 REQUIRE_REG_31(rb);
f18cd223 2508 if (likely(rc != 31)) {
67debe3a 2509 if (ra != 31) {
f18cd223 2510 tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
67debe3a 2511 } else {
f18cd223 2512 tcg_gen_movi_i64(cpu_fir[rc], 0);
67debe3a 2513 }
f18cd223 2514 }
4c9649a9
JM
2515 break;
2516 case 0x2A:
2517 /* SQRTG */
64f45e49 2518 REQUIRE_REG_31(ra);
5238c886
RH
2519 gen_fsqrtg(rb, rc);
2520 break;
4c9649a9
JM
2521 case 0x02B:
2522 /* SQRTT */
64f45e49 2523 REQUIRE_REG_31(ra);
5238c886
RH
2524 gen_fsqrtt(ctx, rb, rc, fn11);
2525 break;
4c9649a9
JM
2526 default:
2527 goto invalid_opc;
2528 }
2529 break;
2530 case 0x15:
2531 /* VAX floating point */
2532 /* XXX: rounding mode and trap are ignored (!) */
f24518b5 2533 switch (fpfn) { /* fn11 & 0x3F */
4c9649a9
JM
2534 case 0x00:
2535 /* ADDF */
a7812ae4 2536 gen_faddf(ra, rb, rc);
4c9649a9
JM
2537 break;
2538 case 0x01:
2539 /* SUBF */
a7812ae4 2540 gen_fsubf(ra, rb, rc);
4c9649a9
JM
2541 break;
2542 case 0x02:
2543 /* MULF */
a7812ae4 2544 gen_fmulf(ra, rb, rc);
4c9649a9
JM
2545 break;
2546 case 0x03:
2547 /* DIVF */
a7812ae4 2548 gen_fdivf(ra, rb, rc);
4c9649a9
JM
2549 break;
2550 case 0x1E:
64f45e49
RH
2551 /* CVTDG -- TODO */
2552 REQUIRE_REG_31(ra);
4c9649a9 2553 goto invalid_opc;
4c9649a9
JM
2554 case 0x20:
2555 /* ADDG */
a7812ae4 2556 gen_faddg(ra, rb, rc);
4c9649a9
JM
2557 break;
2558 case 0x21:
2559 /* SUBG */
a7812ae4 2560 gen_fsubg(ra, rb, rc);
4c9649a9
JM
2561 break;
2562 case 0x22:
2563 /* MULG */
a7812ae4 2564 gen_fmulg(ra, rb, rc);
4c9649a9
JM
2565 break;
2566 case 0x23:
2567 /* DIVG */
a7812ae4 2568 gen_fdivg(ra, rb, rc);
4c9649a9
JM
2569 break;
2570 case 0x25:
2571 /* CMPGEQ */
a7812ae4 2572 gen_fcmpgeq(ra, rb, rc);
4c9649a9
JM
2573 break;
2574 case 0x26:
2575 /* CMPGLT */
a7812ae4 2576 gen_fcmpglt(ra, rb, rc);
4c9649a9
JM
2577 break;
2578 case 0x27:
2579 /* CMPGLE */
a7812ae4 2580 gen_fcmpgle(ra, rb, rc);
4c9649a9
JM
2581 break;
2582 case 0x2C:
2583 /* CVTGF */
64f45e49 2584 REQUIRE_REG_31(ra);
a7812ae4 2585 gen_fcvtgf(rb, rc);
4c9649a9
JM
2586 break;
2587 case 0x2D:
64f45e49
RH
2588 /* CVTGD -- TODO */
2589 REQUIRE_REG_31(ra);
4c9649a9 2590 goto invalid_opc;
4c9649a9
JM
2591 case 0x2F:
2592 /* CVTGQ */
64f45e49 2593 REQUIRE_REG_31(ra);
a7812ae4 2594 gen_fcvtgq(rb, rc);
4c9649a9
JM
2595 break;
2596 case 0x3C:
2597 /* CVTQF */
64f45e49 2598 REQUIRE_REG_31(ra);
a7812ae4 2599 gen_fcvtqf(rb, rc);
4c9649a9
JM
2600 break;
2601 case 0x3E:
2602 /* CVTQG */
64f45e49 2603 REQUIRE_REG_31(ra);
a7812ae4 2604 gen_fcvtqg(rb, rc);
4c9649a9
JM
2605 break;
2606 default:
2607 goto invalid_opc;
2608 }
2609 break;
2610 case 0x16:
2611 /* IEEE floating-point */
f24518b5 2612 switch (fpfn) { /* fn11 & 0x3F */
4c9649a9
JM
2613 case 0x00:
2614 /* ADDS */
f24518b5 2615 gen_fadds(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2616 break;
2617 case 0x01:
2618 /* SUBS */
f24518b5 2619 gen_fsubs(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2620 break;
2621 case 0x02:
2622 /* MULS */
f24518b5 2623 gen_fmuls(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2624 break;
2625 case 0x03:
2626 /* DIVS */
f24518b5 2627 gen_fdivs(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2628 break;
2629 case 0x20:
2630 /* ADDT */
f24518b5 2631 gen_faddt(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2632 break;
2633 case 0x21:
2634 /* SUBT */
f24518b5 2635 gen_fsubt(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2636 break;
2637 case 0x22:
2638 /* MULT */
f24518b5 2639 gen_fmult(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2640 break;
2641 case 0x23:
2642 /* DIVT */
f24518b5 2643 gen_fdivt(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2644 break;
2645 case 0x24:
2646 /* CMPTUN */
f24518b5 2647 gen_fcmptun(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2648 break;
2649 case 0x25:
2650 /* CMPTEQ */
f24518b5 2651 gen_fcmpteq(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2652 break;
2653 case 0x26:
2654 /* CMPTLT */
f24518b5 2655 gen_fcmptlt(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2656 break;
2657 case 0x27:
2658 /* CMPTLE */
f24518b5 2659 gen_fcmptle(ctx, ra, rb, rc, fn11);
4c9649a9
JM
2660 break;
2661 case 0x2C:
64f45e49 2662 REQUIRE_REG_31(ra);
a74b4d2c 2663 if (fn11 == 0x2AC || fn11 == 0x6AC) {
4c9649a9 2664 /* CVTST */
f24518b5 2665 gen_fcvtst(ctx, rb, rc, fn11);
4c9649a9
JM
2666 } else {
2667 /* CVTTS */
f24518b5 2668 gen_fcvtts(ctx, rb, rc, fn11);
4c9649a9
JM
2669 }
2670 break;
2671 case 0x2F:
2672 /* CVTTQ */
64f45e49 2673 REQUIRE_REG_31(ra);
f24518b5 2674 gen_fcvttq(ctx, rb, rc, fn11);
4c9649a9
JM
2675 break;
2676 case 0x3C:
2677 /* CVTQS */
64f45e49 2678 REQUIRE_REG_31(ra);
f24518b5 2679 gen_fcvtqs(ctx, rb, rc, fn11);
4c9649a9
JM
2680 break;
2681 case 0x3E:
2682 /* CVTQT */
64f45e49 2683 REQUIRE_REG_31(ra);
f24518b5 2684 gen_fcvtqt(ctx, rb, rc, fn11);
4c9649a9
JM
2685 break;
2686 default:
2687 goto invalid_opc;
2688 }
2689 break;
2690 case 0x17:
2691 switch (fn11) {
2692 case 0x010:
2693 /* CVTLQ */
64f45e49 2694 REQUIRE_REG_31(ra);
a7812ae4 2695 gen_fcvtlq(rb, rc);
4c9649a9
JM
2696 break;
2697 case 0x020:
f18cd223 2698 if (likely(rc != 31)) {
a06d48d9 2699 if (ra == rb) {
4c9649a9 2700 /* FMOV */
67debe3a 2701 if (ra == 31) {
a06d48d9 2702 tcg_gen_movi_i64(cpu_fir[rc], 0);
67debe3a 2703 } else {
a06d48d9 2704 tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
67debe3a 2705 }
a06d48d9 2706 } else {
f18cd223 2707 /* CPYS */
a7812ae4 2708 gen_fcpys(ra, rb, rc);
a06d48d9 2709 }
4c9649a9
JM
2710 }
2711 break;
2712 case 0x021:
2713 /* CPYSN */
a7812ae4 2714 gen_fcpysn(ra, rb, rc);
4c9649a9
JM
2715 break;
2716 case 0x022:
2717 /* CPYSE */
a7812ae4 2718 gen_fcpyse(ra, rb, rc);
4c9649a9
JM
2719 break;
2720 case 0x024:
2721 /* MT_FPCR */
67debe3a 2722 if (likely(ra != 31)) {
a44a2777 2723 gen_helper_store_fpcr(cpu_env, cpu_fir[ra]);
67debe3a 2724 } else {
f18cd223 2725 TCGv tmp = tcg_const_i64(0);
a44a2777 2726 gen_helper_store_fpcr(cpu_env, tmp);
f18cd223
AJ
2727 tcg_temp_free(tmp);
2728 }
4c9649a9
JM
2729 break;
2730 case 0x025:
2731 /* MF_FPCR */
67debe3a 2732 if (likely(ra != 31)) {
a44a2777 2733 gen_helper_load_fpcr(cpu_fir[ra], cpu_env);
67debe3a 2734 }
4c9649a9
JM
2735 break;
2736 case 0x02A:
2737 /* FCMOVEQ */
bbe1dab4 2738 gen_fcmov(TCG_COND_EQ, ra, rb, rc);
4c9649a9
JM
2739 break;
2740 case 0x02B:
2741 /* FCMOVNE */
bbe1dab4 2742 gen_fcmov(TCG_COND_NE, ra, rb, rc);
4c9649a9
JM
2743 break;
2744 case 0x02C:
2745 /* FCMOVLT */
bbe1dab4 2746 gen_fcmov(TCG_COND_LT, ra, rb, rc);
4c9649a9
JM
2747 break;
2748 case 0x02D:
2749 /* FCMOVGE */
bbe1dab4 2750 gen_fcmov(TCG_COND_GE, ra, rb, rc);
4c9649a9
JM
2751 break;
2752 case 0x02E:
2753 /* FCMOVLE */
bbe1dab4 2754 gen_fcmov(TCG_COND_LE, ra, rb, rc);
4c9649a9
JM
2755 break;
2756 case 0x02F:
2757 /* FCMOVGT */
bbe1dab4 2758 gen_fcmov(TCG_COND_GT, ra, rb, rc);
4c9649a9
JM
2759 break;
2760 case 0x030:
2761 /* CVTQL */
64f45e49 2762 REQUIRE_REG_31(ra);
a7812ae4 2763 gen_fcvtql(rb, rc);
4c9649a9
JM
2764 break;
2765 case 0x130:
2766 /* CVTQL/V */
4c9649a9
JM
2767 case 0x530:
2768 /* CVTQL/SV */
64f45e49 2769 REQUIRE_REG_31(ra);
735cf45f
RH
2770 /* ??? I'm pretty sure there's nothing that /sv needs to do that
2771 /v doesn't do. The only thing I can think is that /sv is a
2772 valid instruction merely for completeness in the ISA. */
2773 gen_fcvtql_v(ctx, rb, rc);
4c9649a9
JM
2774 break;
2775 default:
2776 goto invalid_opc;
2777 }
2778 break;
2779 case 0x18:
2780 switch ((uint16_t)disp16) {
2781 case 0x0000:
2782 /* TRAPB */
4af70374 2783 /* No-op. */
4c9649a9
JM
2784 break;
2785 case 0x0400:
2786 /* EXCB */
4af70374 2787 /* No-op. */
4c9649a9
JM
2788 break;
2789 case 0x4000:
2790 /* MB */
2791 /* No-op */
2792 break;
2793 case 0x4400:
2794 /* WMB */
2795 /* No-op */
2796 break;
2797 case 0x8000:
2798 /* FETCH */
2799 /* No-op */
2800 break;
2801 case 0xA000:
2802 /* FETCH_M */
2803 /* No-op */
2804 break;
2805 case 0xC000:
2806 /* RPCC */
a9406ea1
RH
2807 if (ra != 31) {
2808 if (use_icount) {
2809 gen_io_start();
69163fbb 2810 gen_helper_load_pcc(cpu_ir[ra], cpu_env);
a9406ea1
RH
2811 gen_io_end();
2812 ret = EXIT_PC_STALE;
2813 } else {
69163fbb 2814 gen_helper_load_pcc(cpu_ir[ra], cpu_env);
a9406ea1
RH
2815 }
2816 }
4c9649a9
JM
2817 break;
2818 case 0xE000:
2819 /* RC */
ac316ca4 2820 gen_rx(ra, 0);
4c9649a9
JM
2821 break;
2822 case 0xE800:
2823 /* ECB */
4c9649a9
JM
2824 break;
2825 case 0xF000:
2826 /* RS */
ac316ca4 2827 gen_rx(ra, 1);
4c9649a9
JM
2828 break;
2829 case 0xF800:
2830 /* WH64 */
2831 /* No-op */
2832 break;
2833 default:
2834 goto invalid_opc;
2835 }
2836 break;
2837 case 0x19:
2838 /* HW_MFPR (PALcode) */
26b46094 2839#ifndef CONFIG_USER_ONLY
5238c886
RH
2840 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
2841 return gen_mfpr(ra, insn & 0xffff);
2842#else
4c9649a9 2843 goto invalid_opc;
5238c886 2844#endif
4c9649a9 2845 case 0x1A:
49563a72
RH
2846 /* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch
2847 prediction stack action, which of course we don't implement. */
2848 if (rb != 31) {
3761035f 2849 tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
49563a72 2850 } else {
3761035f 2851 tcg_gen_movi_i64(cpu_pc, 0);
49563a72
RH
2852 }
2853 if (ra != 31) {
1304ca87 2854 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
49563a72 2855 }
4af70374 2856 ret = EXIT_PC_UPDATED;
4c9649a9
JM
2857 break;
2858 case 0x1B:
2859 /* HW_LD (PALcode) */
a18ad893 2860#ifndef CONFIG_USER_ONLY
5238c886
RH
2861 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
2862 {
a18ad893
RH
2863 TCGv addr;
2864
2865 if (ra == 31) {
2866 break;
2867 }
2868
2869 addr = tcg_temp_new();
67debe3a 2870 if (rb != 31) {
8bb6e981 2871 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
67debe3a 2872 } else {
8bb6e981 2873 tcg_gen_movi_i64(addr, disp12);
67debe3a 2874 }
8bb6e981
AJ
2875 switch ((insn >> 12) & 0xF) {
2876 case 0x0:
b5d51029 2877 /* Longword physical access (hw_ldl/p) */
fdfba1a2 2878 gen_helper_ldl_phys(cpu_ir[ra], cpu_env, addr);
8bb6e981
AJ
2879 break;
2880 case 0x1:
b5d51029 2881 /* Quadword physical access (hw_ldq/p) */
2c17449b 2882 gen_helper_ldq_phys(cpu_ir[ra], cpu_env, addr);
8bb6e981
AJ
2883 break;
2884 case 0x2:
b5d51029 2885 /* Longword physical access with lock (hw_ldl_l/p) */
c3082755 2886 gen_helper_ldl_l_phys(cpu_ir[ra], cpu_env, addr);
8bb6e981
AJ
2887 break;
2888 case 0x3:
b5d51029 2889 /* Quadword physical access with lock (hw_ldq_l/p) */
c3082755 2890 gen_helper_ldq_l_phys(cpu_ir[ra], cpu_env, addr);
8bb6e981
AJ
2891 break;
2892 case 0x4:
b5d51029 2893 /* Longword virtual PTE fetch (hw_ldl/v) */
2374e73e 2894 goto invalid_opc;
8bb6e981 2895 case 0x5:
b5d51029 2896 /* Quadword virtual PTE fetch (hw_ldq/v) */
2374e73e 2897 goto invalid_opc;
8bb6e981
AJ
2898 break;
2899 case 0x6:
2900 /* Incpu_ir[ra]id */
b5d51029 2901 goto invalid_opc;
8bb6e981
AJ
2902 case 0x7:
2903 /* Incpu_ir[ra]id */
b5d51029 2904 goto invalid_opc;
8bb6e981 2905 case 0x8:
b5d51029 2906 /* Longword virtual access (hw_ldl) */
2374e73e 2907 goto invalid_opc;
8bb6e981 2908 case 0x9:
b5d51029 2909 /* Quadword virtual access (hw_ldq) */
2374e73e 2910 goto invalid_opc;
8bb6e981 2911 case 0xA:
b5d51029 2912 /* Longword virtual access with protection check (hw_ldl/w) */
f8da40ae 2913 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_KERNEL_IDX, MO_LESL);
8bb6e981
AJ
2914 break;
2915 case 0xB:
b5d51029 2916 /* Quadword virtual access with protection check (hw_ldq/w) */
f8da40ae 2917 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_KERNEL_IDX, MO_LEQ);
8bb6e981
AJ
2918 break;
2919 case 0xC:
b5d51029 2920 /* Longword virtual access with alt access mode (hw_ldl/a)*/
2374e73e 2921 goto invalid_opc;
8bb6e981 2922 case 0xD:
b5d51029 2923 /* Quadword virtual access with alt access mode (hw_ldq/a) */
2374e73e 2924 goto invalid_opc;
8bb6e981
AJ
2925 case 0xE:
2926 /* Longword virtual access with alternate access mode and
2374e73e 2927 protection checks (hw_ldl/wa) */
f8da40ae 2928 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_USER_IDX, MO_LESL);
8bb6e981
AJ
2929 break;
2930 case 0xF:
2931 /* Quadword virtual access with alternate access mode and
2374e73e 2932 protection checks (hw_ldq/wa) */
f8da40ae 2933 tcg_gen_qemu_ld_i64(cpu_ir[ra], addr, MMU_USER_IDX, MO_LEQ);
8bb6e981
AJ
2934 break;
2935 }
2936 tcg_temp_free(addr);
a18ad893 2937 break;
4c9649a9 2938 }
5238c886 2939#else
a18ad893 2940 goto invalid_opc;
5238c886 2941#endif
4c9649a9
JM
2942 case 0x1C:
2943 switch (fn7) {
2944 case 0x00:
2945 /* SEXTB */
5238c886 2946 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
64f45e49 2947 REQUIRE_REG_31(ra);
ae8ecd42 2948 if (likely(rc != 31)) {
67debe3a 2949 if (islit) {
ae8ecd42 2950 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
67debe3a 2951 } else {
dfaa8583 2952 tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
67debe3a 2953 }
ae8ecd42 2954 }
4c9649a9
JM
2955 break;
2956 case 0x01:
2957 /* SEXTW */
5238c886 2958 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX);
64f45e49 2959 REQUIRE_REG_31(ra);
5238c886
RH
2960 if (likely(rc != 31)) {
2961 if (islit) {
2962 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
2963 } else {
2964 tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
a18ad893 2965 }
ae8ecd42 2966 }
5238c886 2967 break;
4c9649a9
JM
2968 case 0x30:
2969 /* CTPOP */
5238c886 2970 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
64f45e49 2971 REQUIRE_REG_31(ra);
5238c886
RH
2972 if (likely(rc != 31)) {
2973 if (islit) {
2974 tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
2975 } else {
2976 gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
a18ad893 2977 }
ae8ecd42 2978 }
5238c886 2979 break;
4c9649a9
JM
2980 case 0x31:
2981 /* PERR */
5238c886
RH
2982 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
2983 gen_perr(ra, rb, rc, islit, lit);
2984 break;
4c9649a9
JM
2985 case 0x32:
2986 /* CTLZ */
5238c886 2987 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
64f45e49 2988 REQUIRE_REG_31(ra);
5238c886
RH
2989 if (likely(rc != 31)) {
2990 if (islit) {
2991 tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
2992 } else {
2993 gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
a18ad893 2994 }
ae8ecd42 2995 }
5238c886 2996 break;
4c9649a9
JM
2997 case 0x33:
2998 /* CTTZ */
5238c886 2999 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX);
64f45e49 3000 REQUIRE_REG_31(ra);
5238c886
RH
3001 if (likely(rc != 31)) {
3002 if (islit) {
3003 tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
3004 } else {
3005 gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
a18ad893 3006 }
ae8ecd42 3007 }
5238c886 3008 break;
4c9649a9
JM
3009 case 0x34:
3010 /* UNPKBW */
5238c886 3011 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
64f45e49 3012 REQUIRE_REG_31(ra);
5238c886
RH
3013 gen_unpkbw(rb, rc);
3014 break;
4c9649a9 3015 case 0x35:
13e4df99 3016 /* UNPKBL */
5238c886 3017 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
64f45e49 3018 REQUIRE_REG_31(ra);
5238c886
RH
3019 gen_unpkbl(rb, rc);
3020 break;
4c9649a9
JM
3021 case 0x36:
3022 /* PKWB */
5238c886 3023 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
64f45e49 3024 REQUIRE_REG_31(ra);
5238c886
RH
3025 gen_pkwb(rb, rc);
3026 break;
4c9649a9
JM
3027 case 0x37:
3028 /* PKLB */
5238c886 3029 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
64f45e49 3030 REQUIRE_REG_31(ra);
5238c886
RH
3031 gen_pklb(rb, rc);
3032 break;
4c9649a9
JM
3033 case 0x38:
3034 /* MINSB8 */
5238c886
RH
3035 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3036 gen_minsb8(ra, rb, rc, islit, lit);
3037 break;
4c9649a9
JM
3038 case 0x39:
3039 /* MINSW4 */
5238c886
RH
3040 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3041 gen_minsw4(ra, rb, rc, islit, lit);
3042 break;
4c9649a9
JM
3043 case 0x3A:
3044 /* MINUB8 */
5238c886
RH
3045 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3046 gen_minub8(ra, rb, rc, islit, lit);
3047 break;
4c9649a9
JM
3048 case 0x3B:
3049 /* MINUW4 */
5238c886
RH
3050 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3051 gen_minuw4(ra, rb, rc, islit, lit);
3052 break;
4c9649a9
JM
3053 case 0x3C:
3054 /* MAXUB8 */
5238c886
RH
3055 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3056 gen_maxub8(ra, rb, rc, islit, lit);
3057 break;
4c9649a9
JM
3058 case 0x3D:
3059 /* MAXUW4 */
5238c886
RH
3060 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3061 gen_maxuw4(ra, rb, rc, islit, lit);
3062 break;
4c9649a9
JM
3063 case 0x3E:
3064 /* MAXSB8 */
5238c886
RH
3065 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3066 gen_maxsb8(ra, rb, rc, islit, lit);
3067 break;
4c9649a9
JM
3068 case 0x3F:
3069 /* MAXSW4 */
5238c886
RH
3070 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI);
3071 gen_maxsw4(ra, rb, rc, islit, lit);
3072 break;
4c9649a9
JM
3073 case 0x70:
3074 /* FTOIT */
5238c886 3075 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX);
64f45e49 3076 REQUIRE_REG_31(rb);
f18cd223 3077 if (likely(rc != 31)) {
67debe3a 3078 if (ra != 31) {
f18cd223 3079 tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
67debe3a 3080 } else {
f18cd223 3081 tcg_gen_movi_i64(cpu_ir[rc], 0);
67debe3a 3082 }
f18cd223 3083 }
4c9649a9
JM
3084 break;
3085 case 0x78:
3086 /* FTOIS */
5238c886 3087 REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX);
64f45e49 3088 REQUIRE_REG_31(rb);
f18cd223 3089 if (rc != 31) {
a7812ae4 3090 TCGv_i32 tmp1 = tcg_temp_new_i32();
67debe3a 3091 if (ra != 31) {
a7812ae4 3092 gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
67debe3a 3093 } else {
f18cd223 3094 TCGv tmp2 = tcg_const_i64(0);
a7812ae4 3095 gen_helper_s_to_memory(tmp1, tmp2);
f18cd223
AJ
3096 tcg_temp_free(tmp2);
3097 }
3098 tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
a7812ae4 3099 tcg_temp_free_i32(tmp1);
f18cd223 3100 }
4c9649a9
JM
3101 break;
3102 default:
3103 goto invalid_opc;
3104 }
3105 break;
3106 case 0x1D:
3107 /* HW_MTPR (PALcode) */
26b46094 3108#ifndef CONFIG_USER_ONLY
5238c886
RH
3109 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
3110 return gen_mtpr(ctx, rb, insn & 0xffff);
3111#else
4c9649a9 3112 goto invalid_opc;
5238c886 3113#endif
4c9649a9 3114 case 0x1E:
508b43ea 3115 /* HW_RET (PALcode) */
a18ad893 3116#ifndef CONFIG_USER_ONLY
5238c886
RH
3117 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
3118 if (rb == 31) {
3119 /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
3120 address from EXC_ADDR. This turns out to be useful for our
3121 emulation PALcode, so continue to accept it. */
3122 TCGv tmp = tcg_temp_new();
3123 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr));
3124 gen_helper_hw_ret(cpu_env, tmp);
3125 tcg_temp_free(tmp);
3126 } else {
3127 gen_helper_hw_ret(cpu_env, cpu_ir[rb]);
4c9649a9 3128 }
5238c886
RH
3129 ret = EXIT_PC_UPDATED;
3130 break;
3131#else
a18ad893 3132 goto invalid_opc;
5238c886 3133#endif
4c9649a9
JM
3134 case 0x1F:
3135 /* HW_ST (PALcode) */
a18ad893 3136#ifndef CONFIG_USER_ONLY
5238c886
RH
3137 REQUIRE_TB_FLAG(TB_FLAGS_PAL_MODE);
3138 {
8bb6e981 3139 TCGv addr, val;
a7812ae4 3140 addr = tcg_temp_new();
67debe3a 3141 if (rb != 31) {
8bb6e981 3142 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
67debe3a 3143 } else {
8bb6e981 3144 tcg_gen_movi_i64(addr, disp12);
67debe3a
PB
3145 }
3146 if (ra != 31) {
8bb6e981 3147 val = cpu_ir[ra];
67debe3a 3148 } else {
a7812ae4 3149 val = tcg_temp_new();
8bb6e981
AJ
3150 tcg_gen_movi_i64(val, 0);
3151 }
3152 switch ((insn >> 12) & 0xF) {
3153 case 0x0:
3154 /* Longword physical access */
ab1da857 3155 gen_helper_stl_phys(cpu_env, addr, val);
8bb6e981
AJ
3156 break;
3157 case 0x1:
3158 /* Quadword physical access */
f606604f 3159 gen_helper_stq_phys(cpu_env, addr, val);
8bb6e981
AJ
3160 break;
3161 case 0x2:
3162 /* Longword physical access with lock */
c3082755 3163 gen_helper_stl_c_phys(val, cpu_env, addr, val);
8bb6e981
AJ
3164 break;
3165 case 0x3:
3166 /* Quadword physical access with lock */
c3082755 3167 gen_helper_stq_c_phys(val, cpu_env, addr, val);
8bb6e981
AJ
3168 break;
3169 case 0x4:
3170 /* Longword virtual access */
2374e73e 3171 goto invalid_opc;
8bb6e981
AJ
3172 case 0x5:
3173 /* Quadword virtual access */
2374e73e 3174 goto invalid_opc;
8bb6e981
AJ
3175 case 0x6:
3176 /* Invalid */
3177 goto invalid_opc;
3178 case 0x7:
3179 /* Invalid */
3180 goto invalid_opc;
3181 case 0x8:
3182 /* Invalid */
3183 goto invalid_opc;
3184 case 0x9:
3185 /* Invalid */
3186 goto invalid_opc;
3187 case 0xA:
3188 /* Invalid */
3189 goto invalid_opc;
3190 case 0xB:
3191 /* Invalid */
3192 goto invalid_opc;
3193 case 0xC:
3194 /* Longword virtual access with alternate access mode */
2374e73e 3195 goto invalid_opc;
8bb6e981
AJ
3196 case 0xD:
3197 /* Quadword virtual access with alternate access mode */
2374e73e 3198 goto invalid_opc;
8bb6e981
AJ
3199 case 0xE:
3200 /* Invalid */
3201 goto invalid_opc;
3202 case 0xF:
3203 /* Invalid */
3204 goto invalid_opc;
3205 }
67debe3a 3206 if (ra == 31) {
8bb6e981 3207 tcg_temp_free(val);
67debe3a 3208 }
8bb6e981 3209 tcg_temp_free(addr);
a18ad893 3210 break;
4c9649a9 3211 }
5238c886 3212#else
a18ad893 3213 goto invalid_opc;
5238c886 3214#endif
4c9649a9
JM
3215 case 0x20:
3216 /* LDF */
f18cd223 3217 gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
4c9649a9
JM
3218 break;
3219 case 0x21:
3220 /* LDG */
f18cd223 3221 gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
4c9649a9
JM
3222 break;
3223 case 0x22:
3224 /* LDS */
f18cd223 3225 gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
4c9649a9
JM
3226 break;
3227 case 0x23:
3228 /* LDT */
f18cd223 3229 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
4c9649a9
JM
3230 break;
3231 case 0x24:
3232 /* STF */
6910b8f6 3233 gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
4c9649a9
JM
3234 break;
3235 case 0x25:
3236 /* STG */
6910b8f6 3237 gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
4c9649a9
JM
3238 break;
3239 case 0x26:
3240 /* STS */
6910b8f6 3241 gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
4c9649a9
JM
3242 break;
3243 case 0x27:
3244 /* STT */
6910b8f6 3245 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
4c9649a9
JM
3246 break;
3247 case 0x28:
3248 /* LDL */
f18cd223 3249 gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
4c9649a9
JM
3250 break;
3251 case 0x29:
3252 /* LDQ */
f18cd223 3253 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
4c9649a9
JM
3254 break;
3255 case 0x2A:
3256 /* LDL_L */
f4ed8679 3257 gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
4c9649a9
JM
3258 break;
3259 case 0x2B:
3260 /* LDQ_L */
f4ed8679 3261 gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
4c9649a9
JM
3262 break;
3263 case 0x2C:
3264 /* STL */
6910b8f6 3265 gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
4c9649a9
JM
3266 break;
3267 case 0x2D:
3268 /* STQ */
6910b8f6 3269 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
4c9649a9
JM
3270 break;
3271 case 0x2E:
3272 /* STL_C */
6910b8f6 3273 ret = gen_store_conditional(ctx, ra, rb, disp16, 0);
4c9649a9
JM
3274 break;
3275 case 0x2F:
3276 /* STQ_C */
6910b8f6 3277 ret = gen_store_conditional(ctx, ra, rb, disp16, 1);
4c9649a9
JM
3278 break;
3279 case 0x30:
3280 /* BR */
4af70374 3281 ret = gen_bdirect(ctx, ra, disp21);
4c9649a9 3282 break;
a7812ae4 3283 case 0x31: /* FBEQ */
4af70374 3284 ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
dbb30fe6 3285 break;
a7812ae4 3286 case 0x32: /* FBLT */
4af70374 3287 ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
dbb30fe6 3288 break;
a7812ae4 3289 case 0x33: /* FBLE */
4af70374 3290 ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
4c9649a9
JM
3291 break;
3292 case 0x34:
3293 /* BSR */
4af70374 3294 ret = gen_bdirect(ctx, ra, disp21);
4c9649a9 3295 break;
a7812ae4 3296 case 0x35: /* FBNE */
4af70374 3297 ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
dbb30fe6 3298 break;
a7812ae4 3299 case 0x36: /* FBGE */
4af70374 3300 ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
dbb30fe6 3301 break;
a7812ae4 3302 case 0x37: /* FBGT */
4af70374 3303 ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
4c9649a9
JM
3304 break;
3305 case 0x38:
3306 /* BLBC */
4af70374 3307 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
4c9649a9
JM
3308 break;
3309 case 0x39:
3310 /* BEQ */
4af70374 3311 ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
4c9649a9
JM
3312 break;
3313 case 0x3A:
3314 /* BLT */
4af70374 3315 ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
4c9649a9
JM
3316 break;
3317 case 0x3B:
3318 /* BLE */
4af70374 3319 ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
4c9649a9
JM
3320 break;
3321 case 0x3C:
3322 /* BLBS */
4af70374 3323 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
4c9649a9
JM
3324 break;
3325 case 0x3D:
3326 /* BNE */
4af70374 3327 ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
4c9649a9
JM
3328 break;
3329 case 0x3E:
3330 /* BGE */
4af70374 3331 ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
4c9649a9
JM
3332 break;
3333 case 0x3F:
3334 /* BGT */
4af70374 3335 ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
4c9649a9
JM
3336 break;
3337 invalid_opc:
8aa3fa20 3338 ret = gen_invalid(ctx);
4c9649a9
JM
3339 break;
3340 }
3341
3342 return ret;
3343}
3344
86a35f7c 3345static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
636aa200 3346 TranslationBlock *tb,
86a35f7c 3347 bool search_pc)
4c9649a9 3348{
ed2803da 3349 CPUState *cs = CPU(cpu);
86a35f7c 3350 CPUAlphaState *env = &cpu->env;
4c9649a9
JM
3351 DisasContext ctx, *ctxp = &ctx;
3352 target_ulong pc_start;
b114b68a 3353 target_ulong pc_mask;
4c9649a9
JM
3354 uint32_t insn;
3355 uint16_t *gen_opc_end;
a1d1bb31 3356 CPUBreakpoint *bp;
4c9649a9 3357 int j, lj = -1;
4af70374 3358 ExitStatus ret;
2e70f6ef
PB
3359 int num_insns;
3360 int max_insns;
4c9649a9
JM
3361
3362 pc_start = tb->pc;
92414b31 3363 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
4af70374
RH
3364
3365 ctx.tb = tb;
4c9649a9 3366 ctx.pc = pc_start;
bba9bdce 3367 ctx.mem_idx = cpu_mmu_index(env);
801c4c28 3368 ctx.implver = env->implver;
ed2803da 3369 ctx.singlestep_enabled = cs->singlestep_enabled;
f24518b5
RH
3370
3371 /* ??? Every TB begins with unset rounding mode, to be initialized on
3372 the first fp insn of the TB. Alternately we could define a proper
3373 default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
3374 to reset the FP_STATUS to that default at the end of any TB that
3375 changes the default. We could even (gasp) dynamiclly figure out
3376 what default would be most efficient given the running program. */
3377 ctx.tb_rm = -1;
3378 /* Similarly for flush-to-zero. */
3379 ctx.tb_ftz = -1;
3380
2e70f6ef
PB
3381 num_insns = 0;
3382 max_insns = tb->cflags & CF_COUNT_MASK;
b114b68a 3383 if (max_insns == 0) {
2e70f6ef 3384 max_insns = CF_COUNT_MASK;
b114b68a
RH
3385 }
3386
3387 if (in_superpage(&ctx, pc_start)) {
3388 pc_mask = (1ULL << 41) - 1;
3389 } else {
3390 pc_mask = ~TARGET_PAGE_MASK;
3391 }
2e70f6ef 3392
806f352d 3393 gen_tb_start();
4af70374 3394 do {
f0c3c505
AF
3395 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
3396 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 3397 if (bp->pc == ctx.pc) {
4c9649a9
JM
3398 gen_excp(&ctx, EXCP_DEBUG, 0);
3399 break;
3400 }
3401 }
3402 }
3403 if (search_pc) {
92414b31 3404 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
4c9649a9
JM
3405 if (lj < j) {
3406 lj++;
3407 while (lj < j)
ab1103de 3408 tcg_ctx.gen_opc_instr_start[lj++] = 0;
4c9649a9 3409 }
25983cad 3410 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
ab1103de 3411 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 3412 tcg_ctx.gen_opc_icount[lj] = num_insns;
4c9649a9 3413 }
67debe3a 3414 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
2e70f6ef 3415 gen_io_start();
67debe3a 3416 }
c3082755 3417 insn = cpu_ldl_code(env, ctx.pc);
2e70f6ef 3418 num_insns++;
c4b3be39 3419
fdefe51c 3420 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
c4b3be39
RH
3421 tcg_gen_debug_insn_start(ctx.pc);
3422 }
3423
194cfb43
RH
3424 TCGV_UNUSED_I64(ctx.zero);
3425 TCGV_UNUSED_I64(ctx.sink);
3426 TCGV_UNUSED_I64(ctx.lit);
3427
4c9649a9
JM
3428 ctx.pc += 4;
3429 ret = translate_one(ctxp, insn);
19bf517b 3430
194cfb43
RH
3431 if (!TCGV_IS_UNUSED_I64(ctx.sink)) {
3432 tcg_gen_discard_i64(ctx.sink);
3433 tcg_temp_free(ctx.sink);
3434 }
3435 if (!TCGV_IS_UNUSED_I64(ctx.zero)) {
3436 tcg_temp_free(ctx.zero);
3437 }
3438 if (!TCGV_IS_UNUSED_I64(ctx.lit)) {
3439 tcg_temp_free(ctx.lit);
3440 }
3441
bf1b03fe
RH
3442 /* If we reach a page boundary, are single stepping,
3443 or exhaust instruction count, stop generation. */
3444 if (ret == NO_EXIT
b114b68a 3445 && ((ctx.pc & pc_mask) == 0
efd7f486 3446 || tcg_ctx.gen_opc_ptr >= gen_opc_end
bf1b03fe
RH
3447 || num_insns >= max_insns
3448 || singlestep
ca6862a6 3449 || ctx.singlestep_enabled)) {
bf1b03fe 3450 ret = EXIT_PC_STALE;
1b530a6d 3451 }
4af70374
RH
3452 } while (ret == NO_EXIT);
3453
3454 if (tb->cflags & CF_LAST_IO) {
3455 gen_io_end();
4c9649a9 3456 }
4af70374
RH
3457
3458 switch (ret) {
3459 case EXIT_GOTO_TB:
8aa3fa20 3460 case EXIT_NORETURN:
4af70374
RH
3461 break;
3462 case EXIT_PC_STALE:
496cb5b9 3463 tcg_gen_movi_i64(cpu_pc, ctx.pc);
4af70374
RH
3464 /* FALLTHRU */
3465 case EXIT_PC_UPDATED:
ca6862a6 3466 if (ctx.singlestep_enabled) {
bf1b03fe
RH
3467 gen_excp_1(EXCP_DEBUG, 0);
3468 } else {
3469 tcg_gen_exit_tb(0);
3470 }
4af70374
RH
3471 break;
3472 default:
3473 abort();
4c9649a9 3474 }
4af70374 3475
806f352d 3476 gen_tb_end(tb, num_insns);
efd7f486 3477 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
4c9649a9 3478 if (search_pc) {
92414b31 3479 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
4c9649a9
JM
3480 lj++;
3481 while (lj <= j)
ab1103de 3482 tcg_ctx.gen_opc_instr_start[lj++] = 0;
4c9649a9
JM
3483 } else {
3484 tb->size = ctx.pc - pc_start;
2e70f6ef 3485 tb->icount = num_insns;
4c9649a9 3486 }
4af70374 3487
806991da 3488#ifdef DEBUG_DISAS
8fec2b8c 3489 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 3490 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 3491 log_target_disas(env, pc_start, ctx.pc - pc_start, 1);
93fcfe39 3492 qemu_log("\n");
4c9649a9 3493 }
4c9649a9 3494#endif
4c9649a9
JM
3495}
3496
4d5712f1 3497void gen_intermediate_code (CPUAlphaState *env, struct TranslationBlock *tb)
4c9649a9 3498{
86a35f7c 3499 gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, false);
4c9649a9
JM
3500}
3501
4d5712f1 3502void gen_intermediate_code_pc (CPUAlphaState *env, struct TranslationBlock *tb)
4c9649a9 3503{
86a35f7c 3504 gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, true);
4c9649a9
JM
3505}
3506
4d5712f1 3507void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 3508{
25983cad 3509 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a 3510}