]> git.proxmox.com Git - mirror_qemu.git/blame - target-alpha/translate.c
target-alpha: Add placeholders for missing userspace PALcalls.
[mirror_qemu.git] / target-alpha / translate.c
CommitLineData
4c9649a9
JM
1/*
2 * Alpha emulation cpu translation for qemu.
5fafdf24 3 *
4c9649a9
JM
4 * Copyright (c) 2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
4c9649a9
JM
18 */
19
20#include <stdint.h>
21#include <stdlib.h>
22#include <stdio.h>
23
24#include "cpu.h"
25#include "exec-all.h"
26#include "disas.h"
ae8ecd42 27#include "host-utils.h"
57fec1fe 28#include "tcg-op.h"
ca10f867 29#include "qemu-common.h"
4c9649a9 30
a7812ae4
PB
31#include "helper.h"
32#define GEN_HELPER 1
33#include "helper.h"
34
19188121 35#undef ALPHA_DEBUG_DISAS
d12d51d5
AL
36
37#ifdef ALPHA_DEBUG_DISAS
806991da 38# define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
d12d51d5
AL
39#else
40# define LOG_DISAS(...) do { } while (0)
41#endif
42
4c9649a9
JM
43typedef struct DisasContext DisasContext;
44struct DisasContext {
45 uint64_t pc;
46 int mem_idx;
47#if !defined (CONFIG_USER_ONLY)
48 int pal_mode;
49#endif
8579095b 50 CPUAlphaState *env;
4c9649a9
JM
51 uint32_t amask;
52};
53
3761035f 54/* global register indexes */
a7812ae4 55static TCGv_ptr cpu_env;
496cb5b9 56static TCGv cpu_ir[31];
f18cd223 57static TCGv cpu_fir[31];
496cb5b9 58static TCGv cpu_pc;
f4ed8679 59static TCGv cpu_lock;
ab471ade
RH
60#ifdef CONFIG_USER_ONLY
61static TCGv cpu_uniq;
62#endif
496cb5b9 63
3761035f 64/* register names */
f18cd223 65static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
2e70f6ef
PB
66
67#include "gen-icount.h"
68
a5f1b965 69static void alpha_translate_init(void)
2e70f6ef 70{
496cb5b9
AJ
71 int i;
72 char *p;
2e70f6ef 73 static int done_init = 0;
496cb5b9 74
2e70f6ef
PB
75 if (done_init)
76 return;
496cb5b9 77
a7812ae4 78 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
496cb5b9
AJ
79
80 p = cpu_reg_names;
81 for (i = 0; i < 31; i++) {
82 sprintf(p, "ir%d", i);
a7812ae4
PB
83 cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
84 offsetof(CPUState, ir[i]), p);
6ba8dcd7 85 p += (i < 10) ? 4 : 5;
f18cd223
AJ
86
87 sprintf(p, "fir%d", i);
a7812ae4
PB
88 cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
89 offsetof(CPUState, fir[i]), p);
f18cd223 90 p += (i < 10) ? 5 : 6;
496cb5b9
AJ
91 }
92
a7812ae4
PB
93 cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
94 offsetof(CPUState, pc), "pc");
496cb5b9 95
a7812ae4
PB
96 cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
97 offsetof(CPUState, lock), "lock");
f4ed8679 98
ab471ade
RH
99#ifdef CONFIG_USER_ONLY
100 cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
101 offsetof(CPUState, unique), "uniq");
102#endif
103
496cb5b9 104 /* register helpers */
a7812ae4 105#define GEN_HELPER 2
496cb5b9
AJ
106#include "helper.h"
107
2e70f6ef
PB
108 done_init = 1;
109}
110
636aa200 111static inline void gen_excp(DisasContext *ctx, int exception, int error_code)
4c9649a9 112{
a7812ae4 113 TCGv_i32 tmp1, tmp2;
6ad02592 114
496cb5b9 115 tcg_gen_movi_i64(cpu_pc, ctx->pc);
6ad02592
AJ
116 tmp1 = tcg_const_i32(exception);
117 tmp2 = tcg_const_i32(error_code);
a7812ae4
PB
118 gen_helper_excp(tmp1, tmp2);
119 tcg_temp_free_i32(tmp2);
120 tcg_temp_free_i32(tmp1);
4c9649a9
JM
121}
122
636aa200 123static inline void gen_invalid(DisasContext *ctx)
4c9649a9
JM
124{
125 gen_excp(ctx, EXCP_OPCDEC, 0);
126}
127
636aa200 128static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
f18cd223 129{
a7812ae4
PB
130 TCGv tmp = tcg_temp_new();
131 TCGv_i32 tmp32 = tcg_temp_new_i32();
f18cd223 132 tcg_gen_qemu_ld32u(tmp, t1, flags);
a7812ae4
PB
133 tcg_gen_trunc_i64_i32(tmp32, tmp);
134 gen_helper_memory_to_f(t0, tmp32);
135 tcg_temp_free_i32(tmp32);
f18cd223
AJ
136 tcg_temp_free(tmp);
137}
138
636aa200 139static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
f18cd223 140{
a7812ae4 141 TCGv tmp = tcg_temp_new();
f18cd223 142 tcg_gen_qemu_ld64(tmp, t1, flags);
a7812ae4 143 gen_helper_memory_to_g(t0, tmp);
f18cd223
AJ
144 tcg_temp_free(tmp);
145}
146
636aa200 147static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
f18cd223 148{
a7812ae4
PB
149 TCGv tmp = tcg_temp_new();
150 TCGv_i32 tmp32 = tcg_temp_new_i32();
f18cd223 151 tcg_gen_qemu_ld32u(tmp, t1, flags);
a7812ae4
PB
152 tcg_gen_trunc_i64_i32(tmp32, tmp);
153 gen_helper_memory_to_s(t0, tmp32);
154 tcg_temp_free_i32(tmp32);
f18cd223
AJ
155 tcg_temp_free(tmp);
156}
157
636aa200 158static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
f4ed8679
AJ
159{
160 tcg_gen_mov_i64(cpu_lock, t1);
161 tcg_gen_qemu_ld32s(t0, t1, flags);
162}
163
636aa200 164static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
f4ed8679
AJ
165{
166 tcg_gen_mov_i64(cpu_lock, t1);
167 tcg_gen_qemu_ld64(t0, t1, flags);
168}
169
636aa200
BS
170static inline void gen_load_mem(DisasContext *ctx,
171 void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
172 int flags),
173 int ra, int rb, int32_t disp16, int fp,
174 int clear)
023d8ca2
AJ
175{
176 TCGv addr;
177
178 if (unlikely(ra == 31))
179 return;
180
a7812ae4 181 addr = tcg_temp_new();
023d8ca2
AJ
182 if (rb != 31) {
183 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
184 if (clear)
185 tcg_gen_andi_i64(addr, addr, ~0x7);
186 } else {
187 if (clear)
188 disp16 &= ~0x7;
189 tcg_gen_movi_i64(addr, disp16);
190 }
f18cd223
AJ
191 if (fp)
192 tcg_gen_qemu_load(cpu_fir[ra], addr, ctx->mem_idx);
193 else
194 tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx);
023d8ca2
AJ
195 tcg_temp_free(addr);
196}
197
636aa200 198static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
f18cd223 199{
a7812ae4
PB
200 TCGv_i32 tmp32 = tcg_temp_new_i32();
201 TCGv tmp = tcg_temp_new();
202 gen_helper_f_to_memory(tmp32, t0);
203 tcg_gen_extu_i32_i64(tmp, tmp32);
f18cd223
AJ
204 tcg_gen_qemu_st32(tmp, t1, flags);
205 tcg_temp_free(tmp);
a7812ae4 206 tcg_temp_free_i32(tmp32);
f18cd223
AJ
207}
208
636aa200 209static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
f18cd223 210{
a7812ae4
PB
211 TCGv tmp = tcg_temp_new();
212 gen_helper_g_to_memory(tmp, t0);
f18cd223
AJ
213 tcg_gen_qemu_st64(tmp, t1, flags);
214 tcg_temp_free(tmp);
215}
216
636aa200 217static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
f18cd223 218{
a7812ae4
PB
219 TCGv_i32 tmp32 = tcg_temp_new_i32();
220 TCGv tmp = tcg_temp_new();
221 gen_helper_s_to_memory(tmp32, t0);
222 tcg_gen_extu_i32_i64(tmp, tmp32);
f18cd223
AJ
223 tcg_gen_qemu_st32(tmp, t1, flags);
224 tcg_temp_free(tmp);
a7812ae4 225 tcg_temp_free_i32(tmp32);
f18cd223
AJ
226}
227
636aa200 228static inline void gen_qemu_stl_c(TCGv t0, TCGv t1, int flags)
f4ed8679
AJ
229{
230 int l1, l2;
231
232 l1 = gen_new_label();
233 l2 = gen_new_label();
234 tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
235 tcg_gen_qemu_st32(t0, t1, flags);
6223246a 236 tcg_gen_movi_i64(t0, 1);
f4ed8679
AJ
237 tcg_gen_br(l2);
238 gen_set_label(l1);
6223246a 239 tcg_gen_movi_i64(t0, 0);
f4ed8679
AJ
240 gen_set_label(l2);
241 tcg_gen_movi_i64(cpu_lock, -1);
242}
243
636aa200 244static inline void gen_qemu_stq_c(TCGv t0, TCGv t1, int flags)
f4ed8679
AJ
245{
246 int l1, l2;
247
248 l1 = gen_new_label();
249 l2 = gen_new_label();
250 tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
251 tcg_gen_qemu_st64(t0, t1, flags);
6223246a 252 tcg_gen_movi_i64(t0, 1);
f4ed8679
AJ
253 tcg_gen_br(l2);
254 gen_set_label(l1);
6223246a 255 tcg_gen_movi_i64(t0, 0);
f4ed8679
AJ
256 gen_set_label(l2);
257 tcg_gen_movi_i64(cpu_lock, -1);
258}
259
636aa200
BS
260static inline void gen_store_mem(DisasContext *ctx,
261 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
262 int flags),
263 int ra, int rb, int32_t disp16, int fp,
264 int clear, int local)
023d8ca2 265{
9cd38c23 266 TCGv addr;
57a92c8e 267 if (local)
a7812ae4 268 addr = tcg_temp_local_new();
57a92c8e 269 else
a7812ae4 270 addr = tcg_temp_new();
023d8ca2
AJ
271 if (rb != 31) {
272 tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
273 if (clear)
274 tcg_gen_andi_i64(addr, addr, ~0x7);
275 } else {
276 if (clear)
277 disp16 &= ~0x7;
278 tcg_gen_movi_i64(addr, disp16);
279 }
f18cd223
AJ
280 if (ra != 31) {
281 if (fp)
282 tcg_gen_qemu_store(cpu_fir[ra], addr, ctx->mem_idx);
283 else
284 tcg_gen_qemu_store(cpu_ir[ra], addr, ctx->mem_idx);
285 } else {
57a92c8e
AJ
286 TCGv zero;
287 if (local)
288 zero = tcg_const_local_i64(0);
289 else
290 zero = tcg_const_i64(0);
023d8ca2
AJ
291 tcg_gen_qemu_store(zero, addr, ctx->mem_idx);
292 tcg_temp_free(zero);
293 }
294 tcg_temp_free(addr);
295}
296
636aa200
BS
297static inline void gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
298 int32_t disp, int mask)
4c9649a9 299{
9c29504e
AJ
300 int l1, l2;
301
302 l1 = gen_new_label();
303 l2 = gen_new_label();
304 if (likely(ra != 31)) {
305 if (mask) {
a7812ae4 306 TCGv tmp = tcg_temp_new();
9c29504e
AJ
307 tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
308 tcg_gen_brcondi_i64(cond, tmp, 0, l1);
309 tcg_temp_free(tmp);
310 } else
311 tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
312 } else {
313 /* Very uncommon case - Do not bother to optimize. */
314 TCGv tmp = tcg_const_i64(0);
315 tcg_gen_brcondi_i64(cond, tmp, 0, l1);
316 tcg_temp_free(tmp);
317 }
318 tcg_gen_movi_i64(cpu_pc, ctx->pc);
319 tcg_gen_br(l2);
320 gen_set_label(l1);
a1516744 321 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
9c29504e 322 gen_set_label(l2);
4c9649a9
JM
323}
324
73651cce 325static inline void gen_fbcond(DisasContext *ctx, int opc, int ra, int32_t disp)
4c9649a9 326{
f18cd223
AJ
327 int l1, l2;
328 TCGv tmp;
a7812ae4 329 TCGv src;
f18cd223
AJ
330
331 l1 = gen_new_label();
332 l2 = gen_new_label();
333 if (ra != 31) {
a7812ae4
PB
334 tmp = tcg_temp_new();
335 src = cpu_fir[ra];
f18cd223
AJ
336 } else {
337 tmp = tcg_const_i64(0);
a7812ae4
PB
338 src = tmp;
339 }
340 switch (opc) {
341 case 0x31: /* FBEQ */
342 gen_helper_cmpfeq(tmp, src);
343 break;
344 case 0x32: /* FBLT */
345 gen_helper_cmpflt(tmp, src);
346 break;
347 case 0x33: /* FBLE */
348 gen_helper_cmpfle(tmp, src);
349 break;
350 case 0x35: /* FBNE */
351 gen_helper_cmpfne(tmp, src);
352 break;
353 case 0x36: /* FBGE */
354 gen_helper_cmpfge(tmp, src);
355 break;
356 case 0x37: /* FBGT */
357 gen_helper_cmpfgt(tmp, src);
358 break;
359 default:
360 abort();
f18cd223
AJ
361 }
362 tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);
363 tcg_gen_movi_i64(cpu_pc, ctx->pc);
364 tcg_gen_br(l2);
365 gen_set_label(l1);
73651cce 366 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
f18cd223 367 gen_set_label(l2);
4c9649a9
JM
368}
369
636aa200
BS
370static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,
371 int islit, uint8_t lit, int mask)
4c9649a9 372{
9c29504e
AJ
373 int l1;
374
375 if (unlikely(rc == 31))
376 return;
377
378 l1 = gen_new_label();
379
380 if (ra != 31) {
381 if (mask) {
a7812ae4 382 TCGv tmp = tcg_temp_new();
9c29504e
AJ
383 tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
384 tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
385 tcg_temp_free(tmp);
386 } else
387 tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
388 } else {
389 /* Very uncommon case - Do not bother to optimize. */
390 TCGv tmp = tcg_const_i64(0);
391 tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
392 tcg_temp_free(tmp);
393 }
394
4c9649a9 395 if (islit)
9c29504e 396 tcg_gen_movi_i64(cpu_ir[rc], lit);
4c9649a9 397 else
dfaa8583 398 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
9c29504e 399 gen_set_label(l1);
4c9649a9
JM
400}
401
a7812ae4 402#define FARITH2(name) \
636aa200 403static inline void glue(gen_f, name)(int rb, int rc) \
a7812ae4
PB
404{ \
405 if (unlikely(rc == 31)) \
406 return; \
407 \
408 if (rb != 31) \
409 gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]); \
410 else { \
411 TCGv tmp = tcg_const_i64(0); \
412 gen_helper_ ## name (cpu_fir[rc], tmp); \
413 tcg_temp_free(tmp); \
414 } \
4c9649a9 415}
a7812ae4
PB
416FARITH2(sqrts)
417FARITH2(sqrtf)
418FARITH2(sqrtg)
419FARITH2(sqrtt)
420FARITH2(cvtgf)
421FARITH2(cvtgq)
422FARITH2(cvtqf)
423FARITH2(cvtqg)
424FARITH2(cvtst)
425FARITH2(cvtts)
426FARITH2(cvttq)
427FARITH2(cvtqs)
428FARITH2(cvtqt)
429FARITH2(cvtlq)
430FARITH2(cvtql)
431FARITH2(cvtqlv)
432FARITH2(cvtqlsv)
433
434#define FARITH3(name) \
636aa200 435static inline void glue(gen_f, name)(int ra, int rb, int rc) \
a7812ae4
PB
436{ \
437 if (unlikely(rc == 31)) \
438 return; \
439 \
440 if (ra != 31) { \
441 if (rb != 31) \
442 gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], cpu_fir[rb]); \
443 else { \
444 TCGv tmp = tcg_const_i64(0); \
445 gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], tmp); \
446 tcg_temp_free(tmp); \
447 } \
448 } else { \
449 TCGv tmp = tcg_const_i64(0); \
450 if (rb != 31) \
451 gen_helper_ ## name (cpu_fir[rc], tmp, cpu_fir[rb]); \
452 else \
453 gen_helper_ ## name (cpu_fir[rc], tmp, tmp); \
454 tcg_temp_free(tmp); \
455 } \
4c9649a9
JM
456}
457
a7812ae4
PB
458FARITH3(addf)
459FARITH3(subf)
460FARITH3(mulf)
461FARITH3(divf)
462FARITH3(addg)
463FARITH3(subg)
464FARITH3(mulg)
465FARITH3(divg)
466FARITH3(cmpgeq)
467FARITH3(cmpglt)
468FARITH3(cmpgle)
469FARITH3(adds)
470FARITH3(subs)
471FARITH3(muls)
472FARITH3(divs)
473FARITH3(addt)
474FARITH3(subt)
475FARITH3(mult)
476FARITH3(divt)
477FARITH3(cmptun)
478FARITH3(cmpteq)
479FARITH3(cmptlt)
480FARITH3(cmptle)
481FARITH3(cpys)
482FARITH3(cpysn)
483FARITH3(cpyse)
484
485#define FCMOV(name) \
636aa200 486static inline void glue(gen_f, name)(int ra, int rb, int rc) \
a7812ae4
PB
487{ \
488 int l1; \
489 TCGv tmp; \
490 \
491 if (unlikely(rc == 31)) \
492 return; \
493 \
494 l1 = gen_new_label(); \
495 tmp = tcg_temp_new(); \
496 if (ra != 31) { \
497 tmp = tcg_temp_new(); \
498 gen_helper_ ## name (tmp, cpu_fir[ra]); \
499 } else { \
500 tmp = tcg_const_i64(0); \
501 gen_helper_ ## name (tmp, tmp); \
502 } \
503 tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1); \
504 if (rb != 31) \
505 tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]); \
506 else \
507 tcg_gen_movi_i64(cpu_fir[rc], 0); \
508 gen_set_label(l1); \
4c9649a9 509}
a7812ae4
PB
510FCMOV(cmpfeq)
511FCMOV(cmpfne)
512FCMOV(cmpflt)
513FCMOV(cmpfge)
514FCMOV(cmpfle)
515FCMOV(cmpfgt)
4c9649a9 516
248c42f3
RH
517static inline uint64_t zapnot_mask(uint8_t lit)
518{
519 uint64_t mask = 0;
520 int i;
521
522 for (i = 0; i < 8; ++i) {
523 if ((lit >> i) & 1)
524 mask |= 0xffull << (i * 8);
525 }
526 return mask;
527}
528
87d98f95
RH
529/* Implement zapnot with an immediate operand, which expands to some
530 form of immediate AND. This is a basic building block in the
531 definition of many of the other byte manipulation instructions. */
248c42f3 532static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
87d98f95 533{
87d98f95
RH
534 switch (lit) {
535 case 0x00:
248c42f3 536 tcg_gen_movi_i64(dest, 0);
87d98f95
RH
537 break;
538 case 0x01:
248c42f3 539 tcg_gen_ext8u_i64(dest, src);
87d98f95
RH
540 break;
541 case 0x03:
248c42f3 542 tcg_gen_ext16u_i64(dest, src);
87d98f95
RH
543 break;
544 case 0x0f:
248c42f3 545 tcg_gen_ext32u_i64(dest, src);
87d98f95
RH
546 break;
547 case 0xff:
248c42f3 548 tcg_gen_mov_i64(dest, src);
87d98f95
RH
549 break;
550 default:
248c42f3 551 tcg_gen_andi_i64 (dest, src, zapnot_mask (lit));
87d98f95
RH
552 break;
553 }
554}
555
556static inline void gen_zapnot(int ra, int rb, int rc, int islit, uint8_t lit)
557{
558 if (unlikely(rc == 31))
559 return;
560 else if (unlikely(ra == 31))
561 tcg_gen_movi_i64(cpu_ir[rc], 0);
562 else if (islit)
248c42f3 563 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], lit);
87d98f95
RH
564 else
565 gen_helper_zapnot (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
566}
567
568static inline void gen_zap(int ra, int rb, int rc, int islit, uint8_t lit)
569{
570 if (unlikely(rc == 31))
571 return;
572 else if (unlikely(ra == 31))
573 tcg_gen_movi_i64(cpu_ir[rc], 0);
574 else if (islit)
248c42f3 575 gen_zapnoti(cpu_ir[rc], cpu_ir[ra], ~lit);
87d98f95
RH
576 else
577 gen_helper_zap (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
578}
579
580
248c42f3 581/* EXTWH, EXTLH, EXTQH */
ffec44f1
RH
582static void gen_ext_h(int ra, int rb, int rc, int islit,
583 uint8_t lit, uint8_t byte_mask)
b3249f63
AJ
584{
585 if (unlikely(rc == 31))
586 return;
377a43b6
RH
587 else if (unlikely(ra == 31))
588 tcg_gen_movi_i64(cpu_ir[rc], 0);
589 else {
dfaa8583 590 if (islit) {
377a43b6
RH
591 lit = (64 - (lit & 7) * 8) & 0x3f;
592 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit);
fe2b269a 593 } else {
377a43b6 594 TCGv tmp1 = tcg_temp_new();
b3249f63
AJ
595 tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
596 tcg_gen_shli_i64(tmp1, tmp1, 3);
dbf95805
VW
597 tcg_gen_neg_i64(tmp1, tmp1);
598 tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
dfaa8583 599 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
b3249f63 600 tcg_temp_free(tmp1);
dfaa8583 601 }
248c42f3 602 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
377a43b6 603 }
b3249f63
AJ
604}
605
248c42f3 606/* EXTBL, EXTWL, EXTLL, EXTQL */
ffec44f1
RH
607static void gen_ext_l(int ra, int rb, int rc, int islit,
608 uint8_t lit, uint8_t byte_mask)
b3249f63
AJ
609{
610 if (unlikely(rc == 31))
611 return;
377a43b6
RH
612 else if (unlikely(ra == 31))
613 tcg_gen_movi_i64(cpu_ir[rc], 0);
614 else {
dfaa8583 615 if (islit) {
377a43b6 616 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
dfaa8583 617 } else {
a7812ae4 618 TCGv tmp = tcg_temp_new();
b3249f63
AJ
619 tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
620 tcg_gen_shli_i64(tmp, tmp, 3);
dfaa8583 621 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
b3249f63 622 tcg_temp_free(tmp);
fe2b269a 623 }
248c42f3
RH
624 gen_zapnoti(cpu_ir[rc], cpu_ir[rc], byte_mask);
625 }
626}
627
50eb6e5c
RH
628/* INSWH, INSLH, INSQH */
629static void gen_ins_h(int ra, int rb, int rc, int islit,
630 uint8_t lit, uint8_t byte_mask)
631{
632 if (unlikely(rc == 31))
633 return;
634 else if (unlikely(ra == 31) || (islit && (lit & 7) == 0))
635 tcg_gen_movi_i64(cpu_ir[rc], 0);
636 else {
637 TCGv tmp = tcg_temp_new();
638
639 /* The instruction description has us left-shift the byte mask
640 and extract bits <15:8> and apply that zap at the end. This
641 is equivalent to simply performing the zap first and shifting
642 afterward. */
643 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
644
645 if (islit) {
646 /* Note that we have handled the lit==0 case above. */
647 tcg_gen_shri_i64 (cpu_ir[rc], tmp, 64 - (lit & 7) * 8);
648 } else {
649 TCGv shift = tcg_temp_new();
650
651 /* If (B & 7) == 0, we need to shift by 64 and leave a zero.
652 Do this portably by splitting the shift into two parts:
653 shift_count-1 and 1. Arrange for the -1 by using
654 ones-complement instead of twos-complement in the negation:
655 ~((B & 7) * 8) & 63. */
656
657 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
658 tcg_gen_shli_i64(shift, shift, 3);
659 tcg_gen_not_i64(shift, shift);
660 tcg_gen_andi_i64(shift, shift, 0x3f);
661
662 tcg_gen_shr_i64(cpu_ir[rc], tmp, shift);
663 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[rc], 1);
664 tcg_temp_free(shift);
665 }
666 tcg_temp_free(tmp);
667 }
668}
669
248c42f3 670/* INSBL, INSWL, INSLL, INSQL */
ffec44f1
RH
671static void gen_ins_l(int ra, int rb, int rc, int islit,
672 uint8_t lit, uint8_t byte_mask)
248c42f3
RH
673{
674 if (unlikely(rc == 31))
675 return;
676 else if (unlikely(ra == 31))
677 tcg_gen_movi_i64(cpu_ir[rc], 0);
678 else {
679 TCGv tmp = tcg_temp_new();
680
681 /* The instruction description has us left-shift the byte mask
682 the same number of byte slots as the data and apply the zap
683 at the end. This is equivalent to simply performing the zap
684 first and shifting afterward. */
685 gen_zapnoti (tmp, cpu_ir[ra], byte_mask);
686
687 if (islit) {
688 tcg_gen_shli_i64(cpu_ir[rc], tmp, (lit & 7) * 8);
689 } else {
690 TCGv shift = tcg_temp_new();
691 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
692 tcg_gen_shli_i64(shift, shift, 3);
693 tcg_gen_shl_i64(cpu_ir[rc], tmp, shift);
694 tcg_temp_free(shift);
695 }
696 tcg_temp_free(tmp);
377a43b6 697 }
b3249f63
AJ
698}
699
ffec44f1
RH
700/* MSKWH, MSKLH, MSKQH */
701static void gen_msk_h(int ra, int rb, int rc, int islit,
702 uint8_t lit, uint8_t byte_mask)
703{
704 if (unlikely(rc == 31))
705 return;
706 else if (unlikely(ra == 31))
707 tcg_gen_movi_i64(cpu_ir[rc], 0);
708 else if (islit) {
709 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~((byte_mask << (lit & 7)) >> 8));
710 } else {
711 TCGv shift = tcg_temp_new();
712 TCGv mask = tcg_temp_new();
713
714 /* The instruction description is as above, where the byte_mask
715 is shifted left, and then we extract bits <15:8>. This can be
716 emulated with a right-shift on the expanded byte mask. This
717 requires extra care because for an input <2:0> == 0 we need a
718 shift of 64 bits in order to generate a zero. This is done by
719 splitting the shift into two parts, the variable shift - 1
720 followed by a constant 1 shift. The code we expand below is
721 equivalent to ~((B & 7) * 8) & 63. */
722
723 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
724 tcg_gen_shli_i64(shift, shift, 3);
725 tcg_gen_not_i64(shift, shift);
726 tcg_gen_andi_i64(shift, shift, 0x3f);
727 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
728 tcg_gen_shr_i64(mask, mask, shift);
729 tcg_gen_shri_i64(mask, mask, 1);
730
731 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
732
733 tcg_temp_free(mask);
734 tcg_temp_free(shift);
735 }
736}
737
14ab1634 738/* MSKBL, MSKWL, MSKLL, MSKQL */
ffec44f1
RH
739static void gen_msk_l(int ra, int rb, int rc, int islit,
740 uint8_t lit, uint8_t byte_mask)
14ab1634
RH
741{
742 if (unlikely(rc == 31))
743 return;
744 else if (unlikely(ra == 31))
745 tcg_gen_movi_i64(cpu_ir[rc], 0);
746 else if (islit) {
747 gen_zapnoti (cpu_ir[rc], cpu_ir[ra], ~(byte_mask << (lit & 7)));
748 } else {
749 TCGv shift = tcg_temp_new();
750 TCGv mask = tcg_temp_new();
751
752 tcg_gen_andi_i64(shift, cpu_ir[rb], 7);
753 tcg_gen_shli_i64(shift, shift, 3);
754 tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
755 tcg_gen_shl_i64(mask, mask, shift);
756
757 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], mask);
758
759 tcg_temp_free(mask);
760 tcg_temp_free(shift);
761 }
762}
763
04acd307 764/* Code to call arith3 helpers */
a7812ae4 765#define ARITH3(name) \
636aa200
BS
766static inline void glue(gen_, name)(int ra, int rb, int rc, int islit,\
767 uint8_t lit) \
a7812ae4
PB
768{ \
769 if (unlikely(rc == 31)) \
770 return; \
771 \
772 if (ra != 31) { \
773 if (islit) { \
774 TCGv tmp = tcg_const_i64(lit); \
775 gen_helper_ ## name(cpu_ir[rc], cpu_ir[ra], tmp); \
776 tcg_temp_free(tmp); \
777 } else \
778 gen_helper_ ## name (cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]); \
779 } else { \
780 TCGv tmp1 = tcg_const_i64(0); \
781 if (islit) { \
782 TCGv tmp2 = tcg_const_i64(lit); \
783 gen_helper_ ## name (cpu_ir[rc], tmp1, tmp2); \
784 tcg_temp_free(tmp2); \
785 } else \
786 gen_helper_ ## name (cpu_ir[rc], tmp1, cpu_ir[rb]); \
787 tcg_temp_free(tmp1); \
788 } \
b3249f63 789}
a7812ae4
PB
790ARITH3(cmpbge)
791ARITH3(addlv)
792ARITH3(sublv)
793ARITH3(addqv)
794ARITH3(subqv)
a7812ae4
PB
795ARITH3(umulh)
796ARITH3(mullv)
797ARITH3(mulqv)
13e4df99
RH
798ARITH3(minub8)
799ARITH3(minsb8)
800ARITH3(minuw4)
801ARITH3(minsw4)
802ARITH3(maxub8)
803ARITH3(maxsb8)
804ARITH3(maxuw4)
805ARITH3(maxsw4)
806ARITH3(perr)
807
808#define MVIOP2(name) \
809static inline void glue(gen_, name)(int rb, int rc) \
810{ \
811 if (unlikely(rc == 31)) \
812 return; \
813 if (unlikely(rb == 31)) \
814 tcg_gen_movi_i64(cpu_ir[rc], 0); \
815 else \
816 gen_helper_ ## name (cpu_ir[rc], cpu_ir[rb]); \
817}
818MVIOP2(pklb)
819MVIOP2(pkwb)
820MVIOP2(unpkbl)
821MVIOP2(unpkbw)
b3249f63 822
636aa200
BS
823static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit,
824 uint8_t lit)
01ff9cc8
AJ
825{
826 int l1, l2;
827 TCGv tmp;
828
829 if (unlikely(rc == 31))
13e4df99 830 return;
01ff9cc8
AJ
831
832 l1 = gen_new_label();
833 l2 = gen_new_label();
834
835 if (ra != 31) {
a7812ae4 836 tmp = tcg_temp_new();
01ff9cc8
AJ
837 tcg_gen_mov_i64(tmp, cpu_ir[ra]);
838 } else
839 tmp = tcg_const_i64(0);
840 if (islit)
841 tcg_gen_brcondi_i64(cond, tmp, lit, l1);
01ff9cc8 842 else
dfaa8583 843 tcg_gen_brcond_i64(cond, tmp, cpu_ir[rb], l1);
01ff9cc8
AJ
844
845 tcg_gen_movi_i64(cpu_ir[rc], 0);
846 tcg_gen_br(l2);
847 gen_set_label(l1);
848 tcg_gen_movi_i64(cpu_ir[rc], 1);
849 gen_set_label(l2);
850}
851
636aa200 852static inline int translate_one(DisasContext *ctx, uint32_t insn)
4c9649a9
JM
853{
854 uint32_t palcode;
855 int32_t disp21, disp16, disp12;
856 uint16_t fn11, fn16;
13e4df99 857 uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit, real_islit;
adf3c8b6 858 uint8_t lit;
4c9649a9
JM
859 int ret;
860
861 /* Decode all instruction fields */
862 opc = insn >> 26;
863 ra = (insn >> 21) & 0x1F;
864 rb = (insn >> 16) & 0x1F;
865 rc = insn & 0x1F;
866 sbz = (insn >> 13) & 0x07;
13e4df99 867 real_islit = islit = (insn >> 12) & 1;
dfaa8583
AJ
868 if (rb == 31 && !islit) {
869 islit = 1;
870 lit = 0;
871 } else
872 lit = (insn >> 13) & 0xFF;
4c9649a9
JM
873 palcode = insn & 0x03FFFFFF;
874 disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
875 disp16 = (int16_t)(insn & 0x0000FFFF);
876 disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
877 fn16 = insn & 0x0000FFFF;
878 fn11 = (insn >> 5) & 0x000007FF;
879 fpfn = fn11 & 0x3F;
880 fn7 = (insn >> 5) & 0x0000007F;
881 fn2 = (insn >> 5) & 0x00000003;
882 ret = 0;
806991da 883 LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
d12d51d5 884 opc, ra, rb, rc, disp16);
806991da 885
4c9649a9
JM
886 switch (opc) {
887 case 0x00:
888 /* CALL_PAL */
ab471ade
RH
889#ifdef CONFIG_USER_ONLY
890 if (palcode == 0x9E) {
891 /* RDUNIQUE */
892 tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq);
893 break;
894 } else if (palcode == 0x9F) {
895 /* WRUNIQUE */
896 tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]);
897 break;
898 }
899#endif
4c9649a9
JM
900 if (palcode >= 0x80 && palcode < 0xC0) {
901 /* Unprivileged PAL call */
31a877f2 902 gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
ab471ade
RH
903 ret = 3;
904 break;
905 }
906#ifndef CONFIG_USER_ONLY
907 if (palcode < 0x40) {
4c9649a9
JM
908 /* Privileged PAL code */
909 if (ctx->mem_idx & 1)
910 goto invalid_opc;
ab471ade
RH
911 gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
912 ret = 3;
4c9649a9 913 }
ab471ade
RH
914#endif
915 /* Invalid PAL call */
916 goto invalid_opc;
4c9649a9
JM
917 case 0x01:
918 /* OPC01 */
919 goto invalid_opc;
920 case 0x02:
921 /* OPC02 */
922 goto invalid_opc;
923 case 0x03:
924 /* OPC03 */
925 goto invalid_opc;
926 case 0x04:
927 /* OPC04 */
928 goto invalid_opc;
929 case 0x05:
930 /* OPC05 */
931 goto invalid_opc;
932 case 0x06:
933 /* OPC06 */
934 goto invalid_opc;
935 case 0x07:
936 /* OPC07 */
937 goto invalid_opc;
938 case 0x08:
939 /* LDA */
1ef4ef4e 940 if (likely(ra != 31)) {
496cb5b9 941 if (rb != 31)
3761035f
AJ
942 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
943 else
944 tcg_gen_movi_i64(cpu_ir[ra], disp16);
496cb5b9 945 }
4c9649a9
JM
946 break;
947 case 0x09:
948 /* LDAH */
1ef4ef4e 949 if (likely(ra != 31)) {
496cb5b9 950 if (rb != 31)
3761035f
AJ
951 tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16 << 16);
952 else
953 tcg_gen_movi_i64(cpu_ir[ra], disp16 << 16);
496cb5b9 954 }
4c9649a9
JM
955 break;
956 case 0x0A:
957 /* LDBU */
958 if (!(ctx->amask & AMASK_BWX))
959 goto invalid_opc;
f18cd223 960 gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
4c9649a9
JM
961 break;
962 case 0x0B:
963 /* LDQ_U */
f18cd223 964 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
4c9649a9
JM
965 break;
966 case 0x0C:
967 /* LDWU */
968 if (!(ctx->amask & AMASK_BWX))
969 goto invalid_opc;
577d5e7f 970 gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
4c9649a9
JM
971 break;
972 case 0x0D:
973 /* STW */
57a92c8e 974 gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
975 break;
976 case 0x0E:
977 /* STB */
57a92c8e 978 gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
979 break;
980 case 0x0F:
981 /* STQ_U */
57a92c8e 982 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1, 0);
4c9649a9
JM
983 break;
984 case 0x10:
985 switch (fn7) {
986 case 0x00:
987 /* ADDL */
30c7183b
AJ
988 if (likely(rc != 31)) {
989 if (ra != 31) {
990 if (islit) {
991 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
992 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 993 } else {
30c7183b
AJ
994 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
995 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 996 }
30c7183b
AJ
997 } else {
998 if (islit)
dfaa8583 999 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1000 else
dfaa8583 1001 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1002 }
1003 }
4c9649a9
JM
1004 break;
1005 case 0x02:
1006 /* S4ADDL */
30c7183b
AJ
1007 if (likely(rc != 31)) {
1008 if (ra != 31) {
a7812ae4 1009 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1010 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1011 if (islit)
1012 tcg_gen_addi_i64(tmp, tmp, lit);
1013 else
1014 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1015 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1016 tcg_temp_free(tmp);
30c7183b
AJ
1017 } else {
1018 if (islit)
1019 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1020 else
dfaa8583 1021 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1022 }
1023 }
4c9649a9
JM
1024 break;
1025 case 0x09:
1026 /* SUBL */
30c7183b
AJ
1027 if (likely(rc != 31)) {
1028 if (ra != 31) {
dfaa8583 1029 if (islit)
30c7183b 1030 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
dfaa8583 1031 else
30c7183b 1032 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
dfaa8583 1033 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
30c7183b
AJ
1034 } else {
1035 if (islit)
1036 tcg_gen_movi_i64(cpu_ir[rc], -lit);
dfaa8583 1037 else {
30c7183b
AJ
1038 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1039 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
30c7183b
AJ
1040 }
1041 }
4c9649a9
JM
1042 break;
1043 case 0x0B:
1044 /* S4SUBL */
30c7183b
AJ
1045 if (likely(rc != 31)) {
1046 if (ra != 31) {
a7812ae4 1047 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1048 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1049 if (islit)
1050 tcg_gen_subi_i64(tmp, tmp, lit);
1051 else
1052 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1053 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1054 tcg_temp_free(tmp);
30c7183b
AJ
1055 } else {
1056 if (islit)
1057 tcg_gen_movi_i64(cpu_ir[rc], -lit);
dfaa8583 1058 else {
30c7183b
AJ
1059 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1060 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 1061 }
30c7183b
AJ
1062 }
1063 }
4c9649a9
JM
1064 break;
1065 case 0x0F:
1066 /* CMPBGE */
a7812ae4 1067 gen_cmpbge(ra, rb, rc, islit, lit);
4c9649a9
JM
1068 break;
1069 case 0x12:
1070 /* S8ADDL */
30c7183b
AJ
1071 if (likely(rc != 31)) {
1072 if (ra != 31) {
a7812ae4 1073 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1074 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1075 if (islit)
1076 tcg_gen_addi_i64(tmp, tmp, lit);
1077 else
1078 tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
1079 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1080 tcg_temp_free(tmp);
30c7183b
AJ
1081 } else {
1082 if (islit)
1083 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1084 else
dfaa8583 1085 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1086 }
1087 }
4c9649a9
JM
1088 break;
1089 case 0x1B:
1090 /* S8SUBL */
30c7183b
AJ
1091 if (likely(rc != 31)) {
1092 if (ra != 31) {
a7812ae4 1093 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1094 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1095 if (islit)
1096 tcg_gen_subi_i64(tmp, tmp, lit);
1097 else
1098 tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
1099 tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
1100 tcg_temp_free(tmp);
30c7183b
AJ
1101 } else {
1102 if (islit)
1103 tcg_gen_movi_i64(cpu_ir[rc], -lit);
dfaa8583 1104 else
30c7183b
AJ
1105 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1106 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
dfaa8583 1107 }
30c7183b
AJ
1108 }
1109 }
4c9649a9
JM
1110 break;
1111 case 0x1D:
1112 /* CMPULT */
01ff9cc8 1113 gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
4c9649a9
JM
1114 break;
1115 case 0x20:
1116 /* ADDQ */
30c7183b
AJ
1117 if (likely(rc != 31)) {
1118 if (ra != 31) {
1119 if (islit)
1120 tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
30c7183b 1121 else
dfaa8583 1122 tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1123 } else {
1124 if (islit)
1125 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1126 else
dfaa8583 1127 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1128 }
1129 }
4c9649a9
JM
1130 break;
1131 case 0x22:
1132 /* S4ADDQ */
30c7183b
AJ
1133 if (likely(rc != 31)) {
1134 if (ra != 31) {
a7812ae4 1135 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1136 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1137 if (islit)
1138 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
1139 else
1140 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1141 tcg_temp_free(tmp);
30c7183b
AJ
1142 } else {
1143 if (islit)
1144 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1145 else
dfaa8583 1146 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1147 }
1148 }
4c9649a9
JM
1149 break;
1150 case 0x29:
1151 /* SUBQ */
30c7183b
AJ
1152 if (likely(rc != 31)) {
1153 if (ra != 31) {
1154 if (islit)
1155 tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
30c7183b 1156 else
dfaa8583 1157 tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1158 } else {
1159 if (islit)
1160 tcg_gen_movi_i64(cpu_ir[rc], -lit);
30c7183b 1161 else
dfaa8583 1162 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1163 }
1164 }
4c9649a9
JM
1165 break;
1166 case 0x2B:
1167 /* S4SUBQ */
30c7183b
AJ
1168 if (likely(rc != 31)) {
1169 if (ra != 31) {
a7812ae4 1170 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1171 tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
1172 if (islit)
1173 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
1174 else
1175 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1176 tcg_temp_free(tmp);
30c7183b
AJ
1177 } else {
1178 if (islit)
1179 tcg_gen_movi_i64(cpu_ir[rc], -lit);
30c7183b 1180 else
dfaa8583 1181 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1182 }
1183 }
4c9649a9
JM
1184 break;
1185 case 0x2D:
1186 /* CMPEQ */
01ff9cc8 1187 gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
4c9649a9
JM
1188 break;
1189 case 0x32:
1190 /* S8ADDQ */
30c7183b
AJ
1191 if (likely(rc != 31)) {
1192 if (ra != 31) {
a7812ae4 1193 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1194 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1195 if (islit)
1196 tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
1197 else
1198 tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1199 tcg_temp_free(tmp);
30c7183b
AJ
1200 } else {
1201 if (islit)
1202 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1203 else
dfaa8583 1204 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1205 }
1206 }
4c9649a9
JM
1207 break;
1208 case 0x3B:
1209 /* S8SUBQ */
30c7183b
AJ
1210 if (likely(rc != 31)) {
1211 if (ra != 31) {
a7812ae4 1212 TCGv tmp = tcg_temp_new();
dfaa8583
AJ
1213 tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
1214 if (islit)
1215 tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
1216 else
1217 tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
1218 tcg_temp_free(tmp);
30c7183b
AJ
1219 } else {
1220 if (islit)
1221 tcg_gen_movi_i64(cpu_ir[rc], -lit);
30c7183b 1222 else
dfaa8583 1223 tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1224 }
1225 }
4c9649a9
JM
1226 break;
1227 case 0x3D:
1228 /* CMPULE */
01ff9cc8 1229 gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
4c9649a9
JM
1230 break;
1231 case 0x40:
1232 /* ADDL/V */
a7812ae4 1233 gen_addlv(ra, rb, rc, islit, lit);
4c9649a9
JM
1234 break;
1235 case 0x49:
1236 /* SUBL/V */
a7812ae4 1237 gen_sublv(ra, rb, rc, islit, lit);
4c9649a9
JM
1238 break;
1239 case 0x4D:
1240 /* CMPLT */
01ff9cc8 1241 gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
4c9649a9
JM
1242 break;
1243 case 0x60:
1244 /* ADDQ/V */
a7812ae4 1245 gen_addqv(ra, rb, rc, islit, lit);
4c9649a9
JM
1246 break;
1247 case 0x69:
1248 /* SUBQ/V */
a7812ae4 1249 gen_subqv(ra, rb, rc, islit, lit);
4c9649a9
JM
1250 break;
1251 case 0x6D:
1252 /* CMPLE */
01ff9cc8 1253 gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
4c9649a9
JM
1254 break;
1255 default:
1256 goto invalid_opc;
1257 }
1258 break;
1259 case 0x11:
1260 switch (fn7) {
1261 case 0x00:
1262 /* AND */
30c7183b 1263 if (likely(rc != 31)) {
dfaa8583 1264 if (ra == 31)
30c7183b
AJ
1265 tcg_gen_movi_i64(cpu_ir[rc], 0);
1266 else if (islit)
1267 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
1268 else
1269 tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1270 }
4c9649a9
JM
1271 break;
1272 case 0x08:
1273 /* BIC */
30c7183b
AJ
1274 if (likely(rc != 31)) {
1275 if (ra != 31) {
1276 if (islit)
1277 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1b581c44
AJ
1278 else
1279 tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1280 } else
1281 tcg_gen_movi_i64(cpu_ir[rc], 0);
1282 }
4c9649a9
JM
1283 break;
1284 case 0x14:
1285 /* CMOVLBS */
fe2b269a 1286 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
4c9649a9
JM
1287 break;
1288 case 0x16:
1289 /* CMOVLBC */
fe2b269a 1290 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
4c9649a9
JM
1291 break;
1292 case 0x20:
1293 /* BIS */
30c7183b
AJ
1294 if (likely(rc != 31)) {
1295 if (ra != 31) {
1296 if (islit)
1297 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
8bb6e981 1298 else
30c7183b 1299 tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
4c9649a9 1300 } else {
30c7183b
AJ
1301 if (islit)
1302 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1303 else
dfaa8583 1304 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
4c9649a9 1305 }
4c9649a9
JM
1306 }
1307 break;
1308 case 0x24:
1309 /* CMOVEQ */
fe2b269a 1310 gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1311 break;
1312 case 0x26:
1313 /* CMOVNE */
fe2b269a 1314 gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1315 break;
1316 case 0x28:
1317 /* ORNOT */
30c7183b 1318 if (likely(rc != 31)) {
dfaa8583 1319 if (ra != 31) {
30c7183b
AJ
1320 if (islit)
1321 tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1b581c44
AJ
1322 else
1323 tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1324 } else {
1325 if (islit)
1326 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
1327 else
1328 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
1329 }
1330 }
4c9649a9
JM
1331 break;
1332 case 0x40:
1333 /* XOR */
30c7183b
AJ
1334 if (likely(rc != 31)) {
1335 if (ra != 31) {
1336 if (islit)
1337 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
30c7183b 1338 else
dfaa8583 1339 tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1340 } else {
1341 if (islit)
1342 tcg_gen_movi_i64(cpu_ir[rc], lit);
30c7183b 1343 else
dfaa8583 1344 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1345 }
1346 }
4c9649a9
JM
1347 break;
1348 case 0x44:
1349 /* CMOVLT */
fe2b269a 1350 gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1351 break;
1352 case 0x46:
1353 /* CMOVGE */
fe2b269a 1354 gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1355 break;
1356 case 0x48:
1357 /* EQV */
30c7183b
AJ
1358 if (likely(rc != 31)) {
1359 if (ra != 31) {
1360 if (islit)
1361 tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1b581c44
AJ
1362 else
1363 tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
30c7183b
AJ
1364 } else {
1365 if (islit)
1366 tcg_gen_movi_i64(cpu_ir[rc], ~lit);
30c7183b 1367 else
dfaa8583 1368 tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
30c7183b
AJ
1369 }
1370 }
4c9649a9
JM
1371 break;
1372 case 0x61:
1373 /* AMASK */
ae8ecd42
AJ
1374 if (likely(rc != 31)) {
1375 if (islit)
1a1f7dbc 1376 tcg_gen_movi_i64(cpu_ir[rc], lit);
ae8ecd42 1377 else
1a1f7dbc
AJ
1378 tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1379 switch (ctx->env->implver) {
1380 case IMPLVER_2106x:
1381 /* EV4, EV45, LCA, LCA45 & EV5 */
1382 break;
1383 case IMPLVER_21164:
1384 case IMPLVER_21264:
1385 case IMPLVER_21364:
1386 tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rc],
1387 ~(uint64_t)ctx->amask);
1388 break;
1389 }
ae8ecd42 1390 }
4c9649a9
JM
1391 break;
1392 case 0x64:
1393 /* CMOVLE */
fe2b269a 1394 gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1395 break;
1396 case 0x66:
1397 /* CMOVGT */
fe2b269a 1398 gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
4c9649a9
JM
1399 break;
1400 case 0x6C:
1401 /* IMPLVER */
3761035f 1402 if (rc != 31)
8579095b 1403 tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
4c9649a9
JM
1404 break;
1405 default:
1406 goto invalid_opc;
1407 }
1408 break;
1409 case 0x12:
1410 switch (fn7) {
1411 case 0x02:
1412 /* MSKBL */
14ab1634 1413 gen_msk_l(ra, rb, rc, islit, lit, 0x01);
4c9649a9
JM
1414 break;
1415 case 0x06:
1416 /* EXTBL */
377a43b6 1417 gen_ext_l(ra, rb, rc, islit, lit, 0x01);
4c9649a9
JM
1418 break;
1419 case 0x0B:
1420 /* INSBL */
248c42f3 1421 gen_ins_l(ra, rb, rc, islit, lit, 0x01);
4c9649a9
JM
1422 break;
1423 case 0x12:
1424 /* MSKWL */
14ab1634 1425 gen_msk_l(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
1426 break;
1427 case 0x16:
1428 /* EXTWL */
377a43b6 1429 gen_ext_l(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
1430 break;
1431 case 0x1B:
1432 /* INSWL */
248c42f3 1433 gen_ins_l(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
1434 break;
1435 case 0x22:
1436 /* MSKLL */
14ab1634 1437 gen_msk_l(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
1438 break;
1439 case 0x26:
1440 /* EXTLL */
377a43b6 1441 gen_ext_l(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
1442 break;
1443 case 0x2B:
1444 /* INSLL */
248c42f3 1445 gen_ins_l(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
1446 break;
1447 case 0x30:
1448 /* ZAP */
a7812ae4 1449 gen_zap(ra, rb, rc, islit, lit);
4c9649a9
JM
1450 break;
1451 case 0x31:
1452 /* ZAPNOT */
a7812ae4 1453 gen_zapnot(ra, rb, rc, islit, lit);
4c9649a9
JM
1454 break;
1455 case 0x32:
1456 /* MSKQL */
14ab1634 1457 gen_msk_l(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
1458 break;
1459 case 0x34:
1460 /* SRL */
30c7183b
AJ
1461 if (likely(rc != 31)) {
1462 if (ra != 31) {
1463 if (islit)
1464 tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
dfaa8583 1465 else {
a7812ae4 1466 TCGv shift = tcg_temp_new();
30c7183b
AJ
1467 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1468 tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
1469 tcg_temp_free(shift);
dfaa8583 1470 }
30c7183b
AJ
1471 } else
1472 tcg_gen_movi_i64(cpu_ir[rc], 0);
1473 }
4c9649a9
JM
1474 break;
1475 case 0x36:
1476 /* EXTQL */
377a43b6 1477 gen_ext_l(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
1478 break;
1479 case 0x39:
1480 /* SLL */
30c7183b
AJ
1481 if (likely(rc != 31)) {
1482 if (ra != 31) {
1483 if (islit)
1484 tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
dfaa8583 1485 else {
a7812ae4 1486 TCGv shift = tcg_temp_new();
30c7183b
AJ
1487 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1488 tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
1489 tcg_temp_free(shift);
dfaa8583 1490 }
30c7183b
AJ
1491 } else
1492 tcg_gen_movi_i64(cpu_ir[rc], 0);
1493 }
4c9649a9
JM
1494 break;
1495 case 0x3B:
1496 /* INSQL */
248c42f3 1497 gen_ins_l(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
1498 break;
1499 case 0x3C:
1500 /* SRA */
30c7183b
AJ
1501 if (likely(rc != 31)) {
1502 if (ra != 31) {
1503 if (islit)
1504 tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
dfaa8583 1505 else {
a7812ae4 1506 TCGv shift = tcg_temp_new();
30c7183b
AJ
1507 tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
1508 tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
1509 tcg_temp_free(shift);
dfaa8583 1510 }
30c7183b
AJ
1511 } else
1512 tcg_gen_movi_i64(cpu_ir[rc], 0);
1513 }
4c9649a9
JM
1514 break;
1515 case 0x52:
1516 /* MSKWH */
ffec44f1 1517 gen_msk_h(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
1518 break;
1519 case 0x57:
1520 /* INSWH */
50eb6e5c 1521 gen_ins_h(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
1522 break;
1523 case 0x5A:
1524 /* EXTWH */
377a43b6 1525 gen_ext_h(ra, rb, rc, islit, lit, 0x03);
4c9649a9
JM
1526 break;
1527 case 0x62:
1528 /* MSKLH */
ffec44f1 1529 gen_msk_h(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
1530 break;
1531 case 0x67:
1532 /* INSLH */
50eb6e5c 1533 gen_ins_h(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
1534 break;
1535 case 0x6A:
1536 /* EXTLH */
377a43b6 1537 gen_ext_h(ra, rb, rc, islit, lit, 0x0f);
4c9649a9
JM
1538 break;
1539 case 0x72:
1540 /* MSKQH */
ffec44f1 1541 gen_msk_h(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
1542 break;
1543 case 0x77:
1544 /* INSQH */
50eb6e5c 1545 gen_ins_h(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
1546 break;
1547 case 0x7A:
1548 /* EXTQH */
377a43b6 1549 gen_ext_h(ra, rb, rc, islit, lit, 0xff);
4c9649a9
JM
1550 break;
1551 default:
1552 goto invalid_opc;
1553 }
1554 break;
1555 case 0x13:
1556 switch (fn7) {
1557 case 0x00:
1558 /* MULL */
30c7183b 1559 if (likely(rc != 31)) {
dfaa8583 1560 if (ra == 31)
30c7183b
AJ
1561 tcg_gen_movi_i64(cpu_ir[rc], 0);
1562 else {
1563 if (islit)
1564 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1565 else
1566 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1567 tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
1568 }
1569 }
4c9649a9
JM
1570 break;
1571 case 0x20:
1572 /* MULQ */
30c7183b 1573 if (likely(rc != 31)) {
dfaa8583 1574 if (ra == 31)
30c7183b
AJ
1575 tcg_gen_movi_i64(cpu_ir[rc], 0);
1576 else if (islit)
1577 tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
1578 else
1579 tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1580 }
4c9649a9
JM
1581 break;
1582 case 0x30:
1583 /* UMULH */
a7812ae4 1584 gen_umulh(ra, rb, rc, islit, lit);
4c9649a9
JM
1585 break;
1586 case 0x40:
1587 /* MULL/V */
a7812ae4 1588 gen_mullv(ra, rb, rc, islit, lit);
4c9649a9
JM
1589 break;
1590 case 0x60:
1591 /* MULQ/V */
a7812ae4 1592 gen_mulqv(ra, rb, rc, islit, lit);
4c9649a9
JM
1593 break;
1594 default:
1595 goto invalid_opc;
1596 }
1597 break;
1598 case 0x14:
1599 switch (fpfn) { /* f11 & 0x3F */
1600 case 0x04:
1601 /* ITOFS */
1602 if (!(ctx->amask & AMASK_FIX))
1603 goto invalid_opc;
f18cd223
AJ
1604 if (likely(rc != 31)) {
1605 if (ra != 31) {
a7812ae4 1606 TCGv_i32 tmp = tcg_temp_new_i32();
f18cd223 1607 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
a7812ae4
PB
1608 gen_helper_memory_to_s(cpu_fir[rc], tmp);
1609 tcg_temp_free_i32(tmp);
f18cd223
AJ
1610 } else
1611 tcg_gen_movi_i64(cpu_fir[rc], 0);
1612 }
4c9649a9
JM
1613 break;
1614 case 0x0A:
1615 /* SQRTF */
1616 if (!(ctx->amask & AMASK_FIX))
1617 goto invalid_opc;
a7812ae4 1618 gen_fsqrtf(rb, rc);
4c9649a9
JM
1619 break;
1620 case 0x0B:
1621 /* SQRTS */
1622 if (!(ctx->amask & AMASK_FIX))
1623 goto invalid_opc;
a7812ae4 1624 gen_fsqrts(rb, rc);
4c9649a9
JM
1625 break;
1626 case 0x14:
1627 /* ITOFF */
1628 if (!(ctx->amask & AMASK_FIX))
1629 goto invalid_opc;
f18cd223
AJ
1630 if (likely(rc != 31)) {
1631 if (ra != 31) {
a7812ae4 1632 TCGv_i32 tmp = tcg_temp_new_i32();
f18cd223 1633 tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
a7812ae4
PB
1634 gen_helper_memory_to_f(cpu_fir[rc], tmp);
1635 tcg_temp_free_i32(tmp);
f18cd223
AJ
1636 } else
1637 tcg_gen_movi_i64(cpu_fir[rc], 0);
1638 }
4c9649a9
JM
1639 break;
1640 case 0x24:
1641 /* ITOFT */
1642 if (!(ctx->amask & AMASK_FIX))
1643 goto invalid_opc;
f18cd223
AJ
1644 if (likely(rc != 31)) {
1645 if (ra != 31)
1646 tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]);
1647 else
1648 tcg_gen_movi_i64(cpu_fir[rc], 0);
1649 }
4c9649a9
JM
1650 break;
1651 case 0x2A:
1652 /* SQRTG */
1653 if (!(ctx->amask & AMASK_FIX))
1654 goto invalid_opc;
a7812ae4 1655 gen_fsqrtg(rb, rc);
4c9649a9
JM
1656 break;
1657 case 0x02B:
1658 /* SQRTT */
1659 if (!(ctx->amask & AMASK_FIX))
1660 goto invalid_opc;
a7812ae4 1661 gen_fsqrtt(rb, rc);
4c9649a9
JM
1662 break;
1663 default:
1664 goto invalid_opc;
1665 }
1666 break;
1667 case 0x15:
1668 /* VAX floating point */
1669 /* XXX: rounding mode and trap are ignored (!) */
1670 switch (fpfn) { /* f11 & 0x3F */
1671 case 0x00:
1672 /* ADDF */
a7812ae4 1673 gen_faddf(ra, rb, rc);
4c9649a9
JM
1674 break;
1675 case 0x01:
1676 /* SUBF */
a7812ae4 1677 gen_fsubf(ra, rb, rc);
4c9649a9
JM
1678 break;
1679 case 0x02:
1680 /* MULF */
a7812ae4 1681 gen_fmulf(ra, rb, rc);
4c9649a9
JM
1682 break;
1683 case 0x03:
1684 /* DIVF */
a7812ae4 1685 gen_fdivf(ra, rb, rc);
4c9649a9
JM
1686 break;
1687 case 0x1E:
1688 /* CVTDG */
1689#if 0 // TODO
a7812ae4 1690 gen_fcvtdg(rb, rc);
4c9649a9
JM
1691#else
1692 goto invalid_opc;
1693#endif
1694 break;
1695 case 0x20:
1696 /* ADDG */
a7812ae4 1697 gen_faddg(ra, rb, rc);
4c9649a9
JM
1698 break;
1699 case 0x21:
1700 /* SUBG */
a7812ae4 1701 gen_fsubg(ra, rb, rc);
4c9649a9
JM
1702 break;
1703 case 0x22:
1704 /* MULG */
a7812ae4 1705 gen_fmulg(ra, rb, rc);
4c9649a9
JM
1706 break;
1707 case 0x23:
1708 /* DIVG */
a7812ae4 1709 gen_fdivg(ra, rb, rc);
4c9649a9
JM
1710 break;
1711 case 0x25:
1712 /* CMPGEQ */
a7812ae4 1713 gen_fcmpgeq(ra, rb, rc);
4c9649a9
JM
1714 break;
1715 case 0x26:
1716 /* CMPGLT */
a7812ae4 1717 gen_fcmpglt(ra, rb, rc);
4c9649a9
JM
1718 break;
1719 case 0x27:
1720 /* CMPGLE */
a7812ae4 1721 gen_fcmpgle(ra, rb, rc);
4c9649a9
JM
1722 break;
1723 case 0x2C:
1724 /* CVTGF */
a7812ae4 1725 gen_fcvtgf(rb, rc);
4c9649a9
JM
1726 break;
1727 case 0x2D:
1728 /* CVTGD */
1729#if 0 // TODO
a7812ae4 1730 gen_fcvtgd(rb, rc);
4c9649a9
JM
1731#else
1732 goto invalid_opc;
1733#endif
1734 break;
1735 case 0x2F:
1736 /* CVTGQ */
a7812ae4 1737 gen_fcvtgq(rb, rc);
4c9649a9
JM
1738 break;
1739 case 0x3C:
1740 /* CVTQF */
a7812ae4 1741 gen_fcvtqf(rb, rc);
4c9649a9
JM
1742 break;
1743 case 0x3E:
1744 /* CVTQG */
a7812ae4 1745 gen_fcvtqg(rb, rc);
4c9649a9
JM
1746 break;
1747 default:
1748 goto invalid_opc;
1749 }
1750 break;
1751 case 0x16:
1752 /* IEEE floating-point */
1753 /* XXX: rounding mode and traps are ignored (!) */
1754 switch (fpfn) { /* f11 & 0x3F */
1755 case 0x00:
1756 /* ADDS */
a7812ae4 1757 gen_fadds(ra, rb, rc);
4c9649a9
JM
1758 break;
1759 case 0x01:
1760 /* SUBS */
a7812ae4 1761 gen_fsubs(ra, rb, rc);
4c9649a9
JM
1762 break;
1763 case 0x02:
1764 /* MULS */
a7812ae4 1765 gen_fmuls(ra, rb, rc);
4c9649a9
JM
1766 break;
1767 case 0x03:
1768 /* DIVS */
a7812ae4 1769 gen_fdivs(ra, rb, rc);
4c9649a9
JM
1770 break;
1771 case 0x20:
1772 /* ADDT */
a7812ae4 1773 gen_faddt(ra, rb, rc);
4c9649a9
JM
1774 break;
1775 case 0x21:
1776 /* SUBT */
a7812ae4 1777 gen_fsubt(ra, rb, rc);
4c9649a9
JM
1778 break;
1779 case 0x22:
1780 /* MULT */
a7812ae4 1781 gen_fmult(ra, rb, rc);
4c9649a9
JM
1782 break;
1783 case 0x23:
1784 /* DIVT */
a7812ae4 1785 gen_fdivt(ra, rb, rc);
4c9649a9
JM
1786 break;
1787 case 0x24:
1788 /* CMPTUN */
a7812ae4 1789 gen_fcmptun(ra, rb, rc);
4c9649a9
JM
1790 break;
1791 case 0x25:
1792 /* CMPTEQ */
a7812ae4 1793 gen_fcmpteq(ra, rb, rc);
4c9649a9
JM
1794 break;
1795 case 0x26:
1796 /* CMPTLT */
a7812ae4 1797 gen_fcmptlt(ra, rb, rc);
4c9649a9
JM
1798 break;
1799 case 0x27:
1800 /* CMPTLE */
a7812ae4 1801 gen_fcmptle(ra, rb, rc);
4c9649a9
JM
1802 break;
1803 case 0x2C:
1804 /* XXX: incorrect */
a74b4d2c 1805 if (fn11 == 0x2AC || fn11 == 0x6AC) {
4c9649a9 1806 /* CVTST */
a7812ae4 1807 gen_fcvtst(rb, rc);
4c9649a9
JM
1808 } else {
1809 /* CVTTS */
a7812ae4 1810 gen_fcvtts(rb, rc);
4c9649a9
JM
1811 }
1812 break;
1813 case 0x2F:
1814 /* CVTTQ */
a7812ae4 1815 gen_fcvttq(rb, rc);
4c9649a9
JM
1816 break;
1817 case 0x3C:
1818 /* CVTQS */
a7812ae4 1819 gen_fcvtqs(rb, rc);
4c9649a9
JM
1820 break;
1821 case 0x3E:
1822 /* CVTQT */
a7812ae4 1823 gen_fcvtqt(rb, rc);
4c9649a9
JM
1824 break;
1825 default:
1826 goto invalid_opc;
1827 }
1828 break;
1829 case 0x17:
1830 switch (fn11) {
1831 case 0x010:
1832 /* CVTLQ */
a7812ae4 1833 gen_fcvtlq(rb, rc);
4c9649a9
JM
1834 break;
1835 case 0x020:
f18cd223 1836 if (likely(rc != 31)) {
a06d48d9 1837 if (ra == rb) {
4c9649a9 1838 /* FMOV */
a06d48d9
RH
1839 if (ra == 31)
1840 tcg_gen_movi_i64(cpu_fir[rc], 0);
1841 else
1842 tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
1843 } else {
f18cd223 1844 /* CPYS */
a7812ae4 1845 gen_fcpys(ra, rb, rc);
a06d48d9 1846 }
4c9649a9
JM
1847 }
1848 break;
1849 case 0x021:
1850 /* CPYSN */
a7812ae4 1851 gen_fcpysn(ra, rb, rc);
4c9649a9
JM
1852 break;
1853 case 0x022:
1854 /* CPYSE */
a7812ae4 1855 gen_fcpyse(ra, rb, rc);
4c9649a9
JM
1856 break;
1857 case 0x024:
1858 /* MT_FPCR */
f18cd223 1859 if (likely(ra != 31))
a7812ae4 1860 gen_helper_store_fpcr(cpu_fir[ra]);
f18cd223
AJ
1861 else {
1862 TCGv tmp = tcg_const_i64(0);
a7812ae4 1863 gen_helper_store_fpcr(tmp);
f18cd223
AJ
1864 tcg_temp_free(tmp);
1865 }
4c9649a9
JM
1866 break;
1867 case 0x025:
1868 /* MF_FPCR */
f18cd223 1869 if (likely(ra != 31))
a7812ae4 1870 gen_helper_load_fpcr(cpu_fir[ra]);
4c9649a9
JM
1871 break;
1872 case 0x02A:
1873 /* FCMOVEQ */
a7812ae4 1874 gen_fcmpfeq(ra, rb, rc);
4c9649a9
JM
1875 break;
1876 case 0x02B:
1877 /* FCMOVNE */
a7812ae4 1878 gen_fcmpfne(ra, rb, rc);
4c9649a9
JM
1879 break;
1880 case 0x02C:
1881 /* FCMOVLT */
a7812ae4 1882 gen_fcmpflt(ra, rb, rc);
4c9649a9
JM
1883 break;
1884 case 0x02D:
1885 /* FCMOVGE */
a7812ae4 1886 gen_fcmpfge(ra, rb, rc);
4c9649a9
JM
1887 break;
1888 case 0x02E:
1889 /* FCMOVLE */
a7812ae4 1890 gen_fcmpfle(ra, rb, rc);
4c9649a9
JM
1891 break;
1892 case 0x02F:
1893 /* FCMOVGT */
a7812ae4 1894 gen_fcmpfgt(ra, rb, rc);
4c9649a9
JM
1895 break;
1896 case 0x030:
1897 /* CVTQL */
a7812ae4 1898 gen_fcvtql(rb, rc);
4c9649a9
JM
1899 break;
1900 case 0x130:
1901 /* CVTQL/V */
a7812ae4 1902 gen_fcvtqlv(rb, rc);
4c9649a9
JM
1903 break;
1904 case 0x530:
1905 /* CVTQL/SV */
a7812ae4 1906 gen_fcvtqlsv(rb, rc);
4c9649a9
JM
1907 break;
1908 default:
1909 goto invalid_opc;
1910 }
1911 break;
1912 case 0x18:
1913 switch ((uint16_t)disp16) {
1914 case 0x0000:
1915 /* TRAPB */
1916 /* No-op. Just exit from the current tb */
1917 ret = 2;
1918 break;
1919 case 0x0400:
1920 /* EXCB */
1921 /* No-op. Just exit from the current tb */
1922 ret = 2;
1923 break;
1924 case 0x4000:
1925 /* MB */
1926 /* No-op */
1927 break;
1928 case 0x4400:
1929 /* WMB */
1930 /* No-op */
1931 break;
1932 case 0x8000:
1933 /* FETCH */
1934 /* No-op */
1935 break;
1936 case 0xA000:
1937 /* FETCH_M */
1938 /* No-op */
1939 break;
1940 case 0xC000:
1941 /* RPCC */
3761035f 1942 if (ra != 31)
a7812ae4 1943 gen_helper_load_pcc(cpu_ir[ra]);
4c9649a9
JM
1944 break;
1945 case 0xE000:
1946 /* RC */
3761035f 1947 if (ra != 31)
a7812ae4 1948 gen_helper_rc(cpu_ir[ra]);
4c9649a9
JM
1949 break;
1950 case 0xE800:
1951 /* ECB */
4c9649a9
JM
1952 break;
1953 case 0xF000:
1954 /* RS */
3761035f 1955 if (ra != 31)
a7812ae4 1956 gen_helper_rs(cpu_ir[ra]);
4c9649a9
JM
1957 break;
1958 case 0xF800:
1959 /* WH64 */
1960 /* No-op */
1961 break;
1962 default:
1963 goto invalid_opc;
1964 }
1965 break;
1966 case 0x19:
1967 /* HW_MFPR (PALcode) */
1968#if defined (CONFIG_USER_ONLY)
1969 goto invalid_opc;
1970#else
1971 if (!ctx->pal_mode)
1972 goto invalid_opc;
8bb6e981
AJ
1973 if (ra != 31) {
1974 TCGv tmp = tcg_const_i32(insn & 0xFF);
a7812ae4 1975 gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]);
8bb6e981
AJ
1976 tcg_temp_free(tmp);
1977 }
4c9649a9
JM
1978 break;
1979#endif
1980 case 0x1A:
3761035f
AJ
1981 if (rb != 31)
1982 tcg_gen_andi_i64(cpu_pc, cpu_ir[rb], ~3);
1983 else
1984 tcg_gen_movi_i64(cpu_pc, 0);
1304ca87
AJ
1985 if (ra != 31)
1986 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
4c9649a9
JM
1987 /* Those four jumps only differ by the branch prediction hint */
1988 switch (fn2) {
1989 case 0x0:
1990 /* JMP */
1991 break;
1992 case 0x1:
1993 /* JSR */
1994 break;
1995 case 0x2:
1996 /* RET */
1997 break;
1998 case 0x3:
1999 /* JSR_COROUTINE */
2000 break;
2001 }
2002 ret = 1;
2003 break;
2004 case 0x1B:
2005 /* HW_LD (PALcode) */
2006#if defined (CONFIG_USER_ONLY)
2007 goto invalid_opc;
2008#else
2009 if (!ctx->pal_mode)
2010 goto invalid_opc;
8bb6e981 2011 if (ra != 31) {
a7812ae4 2012 TCGv addr = tcg_temp_new();
8bb6e981
AJ
2013 if (rb != 31)
2014 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2015 else
2016 tcg_gen_movi_i64(addr, disp12);
2017 switch ((insn >> 12) & 0xF) {
2018 case 0x0:
b5d51029 2019 /* Longword physical access (hw_ldl/p) */
a7812ae4 2020 gen_helper_ldl_raw(cpu_ir[ra], addr);
8bb6e981
AJ
2021 break;
2022 case 0x1:
b5d51029 2023 /* Quadword physical access (hw_ldq/p) */
a7812ae4 2024 gen_helper_ldq_raw(cpu_ir[ra], addr);
8bb6e981
AJ
2025 break;
2026 case 0x2:
b5d51029 2027 /* Longword physical access with lock (hw_ldl_l/p) */
a7812ae4 2028 gen_helper_ldl_l_raw(cpu_ir[ra], addr);
8bb6e981
AJ
2029 break;
2030 case 0x3:
b5d51029 2031 /* Quadword physical access with lock (hw_ldq_l/p) */
a7812ae4 2032 gen_helper_ldq_l_raw(cpu_ir[ra], addr);
8bb6e981
AJ
2033 break;
2034 case 0x4:
b5d51029
AJ
2035 /* Longword virtual PTE fetch (hw_ldl/v) */
2036 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
8bb6e981
AJ
2037 break;
2038 case 0x5:
b5d51029
AJ
2039 /* Quadword virtual PTE fetch (hw_ldq/v) */
2040 tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
8bb6e981
AJ
2041 break;
2042 case 0x6:
2043 /* Incpu_ir[ra]id */
b5d51029 2044 goto invalid_opc;
8bb6e981
AJ
2045 case 0x7:
2046 /* Incpu_ir[ra]id */
b5d51029 2047 goto invalid_opc;
8bb6e981 2048 case 0x8:
b5d51029 2049 /* Longword virtual access (hw_ldl) */
a7812ae4
PB
2050 gen_helper_st_virt_to_phys(addr, addr);
2051 gen_helper_ldl_raw(cpu_ir[ra], addr);
8bb6e981
AJ
2052 break;
2053 case 0x9:
b5d51029 2054 /* Quadword virtual access (hw_ldq) */
a7812ae4
PB
2055 gen_helper_st_virt_to_phys(addr, addr);
2056 gen_helper_ldq_raw(cpu_ir[ra], addr);
8bb6e981
AJ
2057 break;
2058 case 0xA:
b5d51029
AJ
2059 /* Longword virtual access with protection check (hw_ldl/w) */
2060 tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
8bb6e981
AJ
2061 break;
2062 case 0xB:
b5d51029
AJ
2063 /* Quadword virtual access with protection check (hw_ldq/w) */
2064 tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
8bb6e981
AJ
2065 break;
2066 case 0xC:
b5d51029 2067 /* Longword virtual access with alt access mode (hw_ldl/a)*/
a7812ae4
PB
2068 gen_helper_set_alt_mode();
2069 gen_helper_st_virt_to_phys(addr, addr);
2070 gen_helper_ldl_raw(cpu_ir[ra], addr);
2071 gen_helper_restore_mode();
8bb6e981
AJ
2072 break;
2073 case 0xD:
b5d51029 2074 /* Quadword virtual access with alt access mode (hw_ldq/a) */
a7812ae4
PB
2075 gen_helper_set_alt_mode();
2076 gen_helper_st_virt_to_phys(addr, addr);
2077 gen_helper_ldq_raw(cpu_ir[ra], addr);
2078 gen_helper_restore_mode();
8bb6e981
AJ
2079 break;
2080 case 0xE:
2081 /* Longword virtual access with alternate access mode and
b5d51029 2082 * protection checks (hw_ldl/wa)
8bb6e981 2083 */
a7812ae4
PB
2084 gen_helper_set_alt_mode();
2085 gen_helper_ldl_data(cpu_ir[ra], addr);
2086 gen_helper_restore_mode();
8bb6e981
AJ
2087 break;
2088 case 0xF:
2089 /* Quadword virtual access with alternate access mode and
b5d51029 2090 * protection checks (hw_ldq/wa)
8bb6e981 2091 */
a7812ae4
PB
2092 gen_helper_set_alt_mode();
2093 gen_helper_ldq_data(cpu_ir[ra], addr);
2094 gen_helper_restore_mode();
8bb6e981
AJ
2095 break;
2096 }
2097 tcg_temp_free(addr);
4c9649a9 2098 }
4c9649a9
JM
2099 break;
2100#endif
2101 case 0x1C:
2102 switch (fn7) {
2103 case 0x00:
2104 /* SEXTB */
2105 if (!(ctx->amask & AMASK_BWX))
2106 goto invalid_opc;
ae8ecd42
AJ
2107 if (likely(rc != 31)) {
2108 if (islit)
2109 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
ae8ecd42 2110 else
dfaa8583 2111 tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 2112 }
4c9649a9
JM
2113 break;
2114 case 0x01:
2115 /* SEXTW */
2116 if (!(ctx->amask & AMASK_BWX))
2117 goto invalid_opc;
ae8ecd42
AJ
2118 if (likely(rc != 31)) {
2119 if (islit)
2120 tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
ae8ecd42 2121 else
dfaa8583 2122 tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 2123 }
4c9649a9
JM
2124 break;
2125 case 0x30:
2126 /* CTPOP */
2127 if (!(ctx->amask & AMASK_CIX))
2128 goto invalid_opc;
ae8ecd42
AJ
2129 if (likely(rc != 31)) {
2130 if (islit)
2131 tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
ae8ecd42 2132 else
a7812ae4 2133 gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 2134 }
4c9649a9
JM
2135 break;
2136 case 0x31:
2137 /* PERR */
2138 if (!(ctx->amask & AMASK_MVI))
2139 goto invalid_opc;
13e4df99 2140 gen_perr(ra, rb, rc, islit, lit);
4c9649a9
JM
2141 break;
2142 case 0x32:
2143 /* CTLZ */
2144 if (!(ctx->amask & AMASK_CIX))
2145 goto invalid_opc;
ae8ecd42
AJ
2146 if (likely(rc != 31)) {
2147 if (islit)
2148 tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
ae8ecd42 2149 else
a7812ae4 2150 gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 2151 }
4c9649a9
JM
2152 break;
2153 case 0x33:
2154 /* CTTZ */
2155 if (!(ctx->amask & AMASK_CIX))
2156 goto invalid_opc;
ae8ecd42
AJ
2157 if (likely(rc != 31)) {
2158 if (islit)
2159 tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
ae8ecd42 2160 else
a7812ae4 2161 gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
ae8ecd42 2162 }
4c9649a9
JM
2163 break;
2164 case 0x34:
2165 /* UNPKBW */
2166 if (!(ctx->amask & AMASK_MVI))
2167 goto invalid_opc;
13e4df99
RH
2168 if (real_islit || ra != 31)
2169 goto invalid_opc;
2170 gen_unpkbw (rb, rc);
4c9649a9
JM
2171 break;
2172 case 0x35:
13e4df99 2173 /* UNPKBL */
4c9649a9
JM
2174 if (!(ctx->amask & AMASK_MVI))
2175 goto invalid_opc;
13e4df99
RH
2176 if (real_islit || ra != 31)
2177 goto invalid_opc;
2178 gen_unpkbl (rb, rc);
4c9649a9
JM
2179 break;
2180 case 0x36:
2181 /* PKWB */
2182 if (!(ctx->amask & AMASK_MVI))
2183 goto invalid_opc;
13e4df99
RH
2184 if (real_islit || ra != 31)
2185 goto invalid_opc;
2186 gen_pkwb (rb, rc);
4c9649a9
JM
2187 break;
2188 case 0x37:
2189 /* PKLB */
2190 if (!(ctx->amask & AMASK_MVI))
2191 goto invalid_opc;
13e4df99
RH
2192 if (real_islit || ra != 31)
2193 goto invalid_opc;
2194 gen_pklb (rb, rc);
4c9649a9
JM
2195 break;
2196 case 0x38:
2197 /* MINSB8 */
2198 if (!(ctx->amask & AMASK_MVI))
2199 goto invalid_opc;
13e4df99 2200 gen_minsb8 (ra, rb, rc, islit, lit);
4c9649a9
JM
2201 break;
2202 case 0x39:
2203 /* MINSW4 */
2204 if (!(ctx->amask & AMASK_MVI))
2205 goto invalid_opc;
13e4df99 2206 gen_minsw4 (ra, rb, rc, islit, lit);
4c9649a9
JM
2207 break;
2208 case 0x3A:
2209 /* MINUB8 */
2210 if (!(ctx->amask & AMASK_MVI))
2211 goto invalid_opc;
13e4df99 2212 gen_minub8 (ra, rb, rc, islit, lit);
4c9649a9
JM
2213 break;
2214 case 0x3B:
2215 /* MINUW4 */
2216 if (!(ctx->amask & AMASK_MVI))
2217 goto invalid_opc;
13e4df99 2218 gen_minuw4 (ra, rb, rc, islit, lit);
4c9649a9
JM
2219 break;
2220 case 0x3C:
2221 /* MAXUB8 */
2222 if (!(ctx->amask & AMASK_MVI))
2223 goto invalid_opc;
13e4df99 2224 gen_maxub8 (ra, rb, rc, islit, lit);
4c9649a9
JM
2225 break;
2226 case 0x3D:
2227 /* MAXUW4 */
2228 if (!(ctx->amask & AMASK_MVI))
2229 goto invalid_opc;
13e4df99 2230 gen_maxuw4 (ra, rb, rc, islit, lit);
4c9649a9
JM
2231 break;
2232 case 0x3E:
2233 /* MAXSB8 */
2234 if (!(ctx->amask & AMASK_MVI))
2235 goto invalid_opc;
13e4df99 2236 gen_maxsb8 (ra, rb, rc, islit, lit);
4c9649a9
JM
2237 break;
2238 case 0x3F:
2239 /* MAXSW4 */
2240 if (!(ctx->amask & AMASK_MVI))
2241 goto invalid_opc;
13e4df99 2242 gen_maxsw4 (ra, rb, rc, islit, lit);
4c9649a9
JM
2243 break;
2244 case 0x70:
2245 /* FTOIT */
2246 if (!(ctx->amask & AMASK_FIX))
2247 goto invalid_opc;
f18cd223
AJ
2248 if (likely(rc != 31)) {
2249 if (ra != 31)
2250 tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]);
2251 else
2252 tcg_gen_movi_i64(cpu_ir[rc], 0);
2253 }
4c9649a9
JM
2254 break;
2255 case 0x78:
2256 /* FTOIS */
2257 if (!(ctx->amask & AMASK_FIX))
2258 goto invalid_opc;
f18cd223 2259 if (rc != 31) {
a7812ae4 2260 TCGv_i32 tmp1 = tcg_temp_new_i32();
f18cd223 2261 if (ra != 31)
a7812ae4 2262 gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
f18cd223
AJ
2263 else {
2264 TCGv tmp2 = tcg_const_i64(0);
a7812ae4 2265 gen_helper_s_to_memory(tmp1, tmp2);
f18cd223
AJ
2266 tcg_temp_free(tmp2);
2267 }
2268 tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
a7812ae4 2269 tcg_temp_free_i32(tmp1);
f18cd223 2270 }
4c9649a9
JM
2271 break;
2272 default:
2273 goto invalid_opc;
2274 }
2275 break;
2276 case 0x1D:
2277 /* HW_MTPR (PALcode) */
2278#if defined (CONFIG_USER_ONLY)
2279 goto invalid_opc;
2280#else
2281 if (!ctx->pal_mode)
2282 goto invalid_opc;
8bb6e981
AJ
2283 else {
2284 TCGv tmp1 = tcg_const_i32(insn & 0xFF);
2285 if (ra != 31)
a7812ae4 2286 gen_helper_mtpr(tmp1, cpu_ir[ra]);
8bb6e981
AJ
2287 else {
2288 TCGv tmp2 = tcg_const_i64(0);
a7812ae4 2289 gen_helper_mtpr(tmp1, tmp2);
8bb6e981
AJ
2290 tcg_temp_free(tmp2);
2291 }
2292 tcg_temp_free(tmp1);
2293 ret = 2;
2294 }
4c9649a9
JM
2295 break;
2296#endif
2297 case 0x1E:
2298 /* HW_REI (PALcode) */
2299#if defined (CONFIG_USER_ONLY)
2300 goto invalid_opc;
2301#else
2302 if (!ctx->pal_mode)
2303 goto invalid_opc;
2304 if (rb == 31) {
2305 /* "Old" alpha */
a7812ae4 2306 gen_helper_hw_rei();
4c9649a9 2307 } else {
8bb6e981
AJ
2308 TCGv tmp;
2309
2310 if (ra != 31) {
a7812ae4 2311 tmp = tcg_temp_new();
8bb6e981
AJ
2312 tcg_gen_addi_i64(tmp, cpu_ir[rb], (((int64_t)insn << 51) >> 51));
2313 } else
2314 tmp = tcg_const_i64(((int64_t)insn << 51) >> 51);
a7812ae4 2315 gen_helper_hw_ret(tmp);
8bb6e981 2316 tcg_temp_free(tmp);
4c9649a9
JM
2317 }
2318 ret = 2;
2319 break;
2320#endif
2321 case 0x1F:
2322 /* HW_ST (PALcode) */
2323#if defined (CONFIG_USER_ONLY)
2324 goto invalid_opc;
2325#else
2326 if (!ctx->pal_mode)
2327 goto invalid_opc;
8bb6e981
AJ
2328 else {
2329 TCGv addr, val;
a7812ae4 2330 addr = tcg_temp_new();
8bb6e981
AJ
2331 if (rb != 31)
2332 tcg_gen_addi_i64(addr, cpu_ir[rb], disp12);
2333 else
2334 tcg_gen_movi_i64(addr, disp12);
2335 if (ra != 31)
2336 val = cpu_ir[ra];
2337 else {
a7812ae4 2338 val = tcg_temp_new();
8bb6e981
AJ
2339 tcg_gen_movi_i64(val, 0);
2340 }
2341 switch ((insn >> 12) & 0xF) {
2342 case 0x0:
2343 /* Longword physical access */
a7812ae4 2344 gen_helper_stl_raw(val, addr);
8bb6e981
AJ
2345 break;
2346 case 0x1:
2347 /* Quadword physical access */
a7812ae4 2348 gen_helper_stq_raw(val, addr);
8bb6e981
AJ
2349 break;
2350 case 0x2:
2351 /* Longword physical access with lock */
a7812ae4 2352 gen_helper_stl_c_raw(val, val, addr);
8bb6e981
AJ
2353 break;
2354 case 0x3:
2355 /* Quadword physical access with lock */
a7812ae4 2356 gen_helper_stq_c_raw(val, val, addr);
8bb6e981
AJ
2357 break;
2358 case 0x4:
2359 /* Longword virtual access */
a7812ae4
PB
2360 gen_helper_st_virt_to_phys(addr, addr);
2361 gen_helper_stl_raw(val, addr);
8bb6e981
AJ
2362 break;
2363 case 0x5:
2364 /* Quadword virtual access */
a7812ae4
PB
2365 gen_helper_st_virt_to_phys(addr, addr);
2366 gen_helper_stq_raw(val, addr);
8bb6e981
AJ
2367 break;
2368 case 0x6:
2369 /* Invalid */
2370 goto invalid_opc;
2371 case 0x7:
2372 /* Invalid */
2373 goto invalid_opc;
2374 case 0x8:
2375 /* Invalid */
2376 goto invalid_opc;
2377 case 0x9:
2378 /* Invalid */
2379 goto invalid_opc;
2380 case 0xA:
2381 /* Invalid */
2382 goto invalid_opc;
2383 case 0xB:
2384 /* Invalid */
2385 goto invalid_opc;
2386 case 0xC:
2387 /* Longword virtual access with alternate access mode */
a7812ae4
PB
2388 gen_helper_set_alt_mode();
2389 gen_helper_st_virt_to_phys(addr, addr);
2390 gen_helper_stl_raw(val, addr);
2391 gen_helper_restore_mode();
8bb6e981
AJ
2392 break;
2393 case 0xD:
2394 /* Quadword virtual access with alternate access mode */
a7812ae4
PB
2395 gen_helper_set_alt_mode();
2396 gen_helper_st_virt_to_phys(addr, addr);
2397 gen_helper_stl_raw(val, addr);
2398 gen_helper_restore_mode();
8bb6e981
AJ
2399 break;
2400 case 0xE:
2401 /* Invalid */
2402 goto invalid_opc;
2403 case 0xF:
2404 /* Invalid */
2405 goto invalid_opc;
2406 }
45d46ce8 2407 if (ra == 31)
8bb6e981
AJ
2408 tcg_temp_free(val);
2409 tcg_temp_free(addr);
4c9649a9 2410 }
4c9649a9
JM
2411 break;
2412#endif
2413 case 0x20:
2414 /* LDF */
f18cd223 2415 gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
4c9649a9
JM
2416 break;
2417 case 0x21:
2418 /* LDG */
f18cd223 2419 gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
4c9649a9
JM
2420 break;
2421 case 0x22:
2422 /* LDS */
f18cd223 2423 gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
4c9649a9
JM
2424 break;
2425 case 0x23:
2426 /* LDT */
f18cd223 2427 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
4c9649a9
JM
2428 break;
2429 case 0x24:
2430 /* STF */
57a92c8e 2431 gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2432 break;
2433 case 0x25:
2434 /* STG */
57a92c8e 2435 gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2436 break;
2437 case 0x26:
2438 /* STS */
57a92c8e 2439 gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2440 break;
2441 case 0x27:
2442 /* STT */
57a92c8e 2443 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0, 0);
4c9649a9
JM
2444 break;
2445 case 0x28:
2446 /* LDL */
f18cd223 2447 gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
4c9649a9
JM
2448 break;
2449 case 0x29:
2450 /* LDQ */
f18cd223 2451 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
4c9649a9
JM
2452 break;
2453 case 0x2A:
2454 /* LDL_L */
f4ed8679 2455 gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
4c9649a9
JM
2456 break;
2457 case 0x2B:
2458 /* LDQ_L */
f4ed8679 2459 gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
4c9649a9
JM
2460 break;
2461 case 0x2C:
2462 /* STL */
57a92c8e 2463 gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
2464 break;
2465 case 0x2D:
2466 /* STQ */
57a92c8e 2467 gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0, 0);
4c9649a9
JM
2468 break;
2469 case 0x2E:
2470 /* STL_C */
57a92c8e 2471 gen_store_mem(ctx, &gen_qemu_stl_c, ra, rb, disp16, 0, 0, 1);
4c9649a9
JM
2472 break;
2473 case 0x2F:
2474 /* STQ_C */
57a92c8e 2475 gen_store_mem(ctx, &gen_qemu_stq_c, ra, rb, disp16, 0, 0, 1);
4c9649a9
JM
2476 break;
2477 case 0x30:
2478 /* BR */
3761035f
AJ
2479 if (ra != 31)
2480 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2481 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
4c9649a9
JM
2482 ret = 1;
2483 break;
a7812ae4
PB
2484 case 0x31: /* FBEQ */
2485 case 0x32: /* FBLT */
2486 case 0x33: /* FBLE */
73651cce 2487 gen_fbcond(ctx, opc, ra, disp21);
4c9649a9
JM
2488 ret = 1;
2489 break;
2490 case 0x34:
2491 /* BSR */
3761035f
AJ
2492 if (ra != 31)
2493 tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
2494 tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp21 << 2));
4c9649a9
JM
2495 ret = 1;
2496 break;
a7812ae4
PB
2497 case 0x35: /* FBNE */
2498 case 0x36: /* FBGE */
2499 case 0x37: /* FBGT */
73651cce 2500 gen_fbcond(ctx, opc, ra, disp21);
4c9649a9
JM
2501 ret = 1;
2502 break;
2503 case 0x38:
2504 /* BLBC */
a1516744 2505 gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
4c9649a9
JM
2506 ret = 1;
2507 break;
2508 case 0x39:
2509 /* BEQ */
a1516744 2510 gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
4c9649a9
JM
2511 ret = 1;
2512 break;
2513 case 0x3A:
2514 /* BLT */
a1516744 2515 gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
4c9649a9
JM
2516 ret = 1;
2517 break;
2518 case 0x3B:
2519 /* BLE */
a1516744 2520 gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
4c9649a9
JM
2521 ret = 1;
2522 break;
2523 case 0x3C:
2524 /* BLBS */
a1516744 2525 gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
4c9649a9
JM
2526 ret = 1;
2527 break;
2528 case 0x3D:
2529 /* BNE */
a1516744 2530 gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
4c9649a9
JM
2531 ret = 1;
2532 break;
2533 case 0x3E:
2534 /* BGE */
a1516744 2535 gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
4c9649a9
JM
2536 ret = 1;
2537 break;
2538 case 0x3F:
2539 /* BGT */
a1516744 2540 gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
4c9649a9
JM
2541 ret = 1;
2542 break;
2543 invalid_opc:
2544 gen_invalid(ctx);
2545 ret = 3;
2546 break;
2547 }
2548
2549 return ret;
2550}
2551
636aa200
BS
2552static inline void gen_intermediate_code_internal(CPUState *env,
2553 TranslationBlock *tb,
2554 int search_pc)
4c9649a9 2555{
4c9649a9
JM
2556 DisasContext ctx, *ctxp = &ctx;
2557 target_ulong pc_start;
2558 uint32_t insn;
2559 uint16_t *gen_opc_end;
a1d1bb31 2560 CPUBreakpoint *bp;
4c9649a9
JM
2561 int j, lj = -1;
2562 int ret;
2e70f6ef
PB
2563 int num_insns;
2564 int max_insns;
4c9649a9
JM
2565
2566 pc_start = tb->pc;
4c9649a9 2567 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4c9649a9
JM
2568 ctx.pc = pc_start;
2569 ctx.amask = env->amask;
8579095b 2570 ctx.env = env;
4c9649a9
JM
2571#if defined (CONFIG_USER_ONLY)
2572 ctx.mem_idx = 0;
2573#else
2574 ctx.mem_idx = ((env->ps >> 3) & 3);
2575 ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1;
2576#endif
2e70f6ef
PB
2577 num_insns = 0;
2578 max_insns = tb->cflags & CF_COUNT_MASK;
2579 if (max_insns == 0)
2580 max_insns = CF_COUNT_MASK;
2581
2582 gen_icount_start();
4c9649a9 2583 for (ret = 0; ret == 0;) {
72cf2d4f
BS
2584 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
2585 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 2586 if (bp->pc == ctx.pc) {
4c9649a9
JM
2587 gen_excp(&ctx, EXCP_DEBUG, 0);
2588 break;
2589 }
2590 }
2591 }
2592 if (search_pc) {
2593 j = gen_opc_ptr - gen_opc_buf;
2594 if (lj < j) {
2595 lj++;
2596 while (lj < j)
2597 gen_opc_instr_start[lj++] = 0;
4c9649a9 2598 }
ed1dda53
AJ
2599 gen_opc_pc[lj] = ctx.pc;
2600 gen_opc_instr_start[lj] = 1;
2601 gen_opc_icount[lj] = num_insns;
4c9649a9 2602 }
2e70f6ef
PB
2603 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
2604 gen_io_start();
4c9649a9 2605 insn = ldl_code(ctx.pc);
2e70f6ef 2606 num_insns++;
4c9649a9
JM
2607 ctx.pc += 4;
2608 ret = translate_one(ctxp, insn);
2609 if (ret != 0)
2610 break;
2611 /* if we reach a page boundary or are single stepping, stop
2612 * generation
2613 */
19bf517b
AJ
2614 if (env->singlestep_enabled) {
2615 gen_excp(&ctx, EXCP_DEBUG, 0);
2616 break;
1b530a6d 2617 }
19bf517b 2618
8fcc55f9
AJ
2619 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
2620 break;
2621
2622 if (gen_opc_ptr >= gen_opc_end)
2623 break;
2624
2625 if (num_insns >= max_insns)
2626 break;
2627
1b530a6d
AJ
2628 if (singlestep) {
2629 break;
2630 }
4c9649a9
JM
2631 }
2632 if (ret != 1 && ret != 3) {
496cb5b9 2633 tcg_gen_movi_i64(cpu_pc, ctx.pc);
4c9649a9 2634 }
2e70f6ef
PB
2635 if (tb->cflags & CF_LAST_IO)
2636 gen_io_end();
4c9649a9 2637 /* Generate the return instruction */
57fec1fe 2638 tcg_gen_exit_tb(0);
2e70f6ef 2639 gen_icount_end(tb, num_insns);
4c9649a9
JM
2640 *gen_opc_ptr = INDEX_op_end;
2641 if (search_pc) {
2642 j = gen_opc_ptr - gen_opc_buf;
2643 lj++;
2644 while (lj <= j)
2645 gen_opc_instr_start[lj++] = 0;
4c9649a9
JM
2646 } else {
2647 tb->size = ctx.pc - pc_start;
2e70f6ef 2648 tb->icount = num_insns;
4c9649a9 2649 }
806991da 2650#ifdef DEBUG_DISAS
8fec2b8c 2651 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39
AL
2652 qemu_log("IN: %s\n", lookup_symbol(pc_start));
2653 log_target_disas(pc_start, ctx.pc - pc_start, 1);
2654 qemu_log("\n");
4c9649a9 2655 }
4c9649a9 2656#endif
4c9649a9
JM
2657}
2658
2cfc5f17 2659void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
4c9649a9 2660{
2cfc5f17 2661 gen_intermediate_code_internal(env, tb, 0);
4c9649a9
JM
2662}
2663
2cfc5f17 2664void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
4c9649a9 2665{
2cfc5f17 2666 gen_intermediate_code_internal(env, tb, 1);
4c9649a9
JM
2667}
2668
a964acc6
RH
2669struct cpu_def_t {
2670 const char *name;
2671 int implver, amask;
2672};
2673
2674static const struct cpu_def_t cpu_defs[] = {
2675 { "ev4", IMPLVER_2106x, 0 },
2676 { "ev5", IMPLVER_21164, 0 },
2677 { "ev56", IMPLVER_21164, AMASK_BWX },
2678 { "pca56", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
2679 { "ev6", IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
2680 { "ev67", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
2681 | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
2682 { "ev68", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
2683 | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), },
2684 { "21064", IMPLVER_2106x, 0 },
2685 { "21164", IMPLVER_21164, 0 },
2686 { "21164a", IMPLVER_21164, AMASK_BWX },
2687 { "21164pc", IMPLVER_21164, AMASK_BWX | AMASK_MVI },
2688 { "21264", IMPLVER_21264, AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP },
2689 { "21264a", IMPLVER_21264, (AMASK_BWX | AMASK_FIX | AMASK_CIX
2690 | AMASK_MVI | AMASK_TRAP | AMASK_PREFETCH), }
2691};
2692
aaed909a 2693CPUAlphaState * cpu_alpha_init (const char *cpu_model)
4c9649a9
JM
2694{
2695 CPUAlphaState *env;
2696 uint64_t hwpcb;
a964acc6 2697 int implver, amask, i, max;
4c9649a9
JM
2698
2699 env = qemu_mallocz(sizeof(CPUAlphaState));
4c9649a9 2700 cpu_exec_init(env);
2e70f6ef 2701 alpha_translate_init();
4c9649a9 2702 tlb_flush(env, 1);
a964acc6
RH
2703
2704 /* Default to ev67; no reason not to emulate insns by default. */
2705 implver = IMPLVER_21264;
2706 amask = (AMASK_BWX | AMASK_FIX | AMASK_CIX | AMASK_MVI
2707 | AMASK_TRAP | AMASK_PREFETCH);
2708
2709 max = ARRAY_SIZE(cpu_defs);
2710 for (i = 0; i < max; i++) {
2711 if (strcmp (cpu_model, cpu_defs[i].name) == 0) {
2712 implver = cpu_defs[i].implver;
2713 amask = cpu_defs[i].amask;
2714 break;
2715 }
2716 }
2717 env->implver = implver;
2718 env->amask = amask;
2719
4c9649a9
JM
2720 env->ps = 0x1F00;
2721#if defined (CONFIG_USER_ONLY)
2722 env->ps |= 1 << 3;
2723#endif
2724 pal_init(env);
2725 /* Initialize IPR */
2726 hwpcb = env->ipr[IPR_PCBB];
2727 env->ipr[IPR_ASN] = 0;
2728 env->ipr[IPR_ASTEN] = 0;
2729 env->ipr[IPR_ASTSR] = 0;
2730 env->ipr[IPR_DATFX] = 0;
2731 /* XXX: fix this */
2732 // env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8);
2733 // env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0);
2734 // env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16);
2735 // env->ipr[IPR_USP] = ldq_raw(hwpcb + 24);
2736 env->ipr[IPR_FEN] = 0;
2737 env->ipr[IPR_IPL] = 31;
2738 env->ipr[IPR_MCES] = 0;
2739 env->ipr[IPR_PERFMON] = 0; /* Implementation specific */
2740 // env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32);
2741 env->ipr[IPR_SISR] = 0;
2742 env->ipr[IPR_VIRBND] = -1ULL;
2743
0bf46a40 2744 qemu_init_vcpu(env);
4c9649a9
JM
2745 return env;
2746}
aaed909a 2747
d2856f1a
AJ
2748void gen_pc_load(CPUState *env, TranslationBlock *tb,
2749 unsigned long searched_pc, int pc_pos, void *puc)
2750{
2751 env->pc = gen_opc_pc[pc_pos];
2752}