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