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