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