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