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