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