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