|
|
1.1 root 1: /*
2: * Alpha emulation cpu translation for qemu.
3: *
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
1.1.1.3 ! root 17: * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1 root 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"
1.1.1.2 root 27: #include "host-utils.h"
28: #include "tcg-op.h"
29: #include "qemu-common.h"
30:
31: #include "helper.h"
32: #define GEN_HELPER 1
33: #include "helper.h"
1.1 root 34:
1.1.1.2 root 35: /* #define DO_SINGLE_STEP */
1.1 root 36: #define ALPHA_DEBUG_DISAS
1.1.1.2 root 37: /* #define DO_TB_FLUSH */
38:
39:
40: #ifdef ALPHA_DEBUG_DISAS
41: # define LOG_DISAS(...) qemu_log(__VA_ARGS__)
42: #else
43: # define LOG_DISAS(...) do { } while (0)
44: #endif
1.1 root 45:
46: typedef struct DisasContext DisasContext;
47: struct DisasContext {
48: uint64_t pc;
49: int mem_idx;
50: #if !defined (CONFIG_USER_ONLY)
51: int pal_mode;
52: #endif
1.1.1.3 ! root 53: CPUAlphaState *env;
1.1 root 54: uint32_t amask;
55: };
56:
1.1.1.2 root 57: /* global register indexes */
58: static TCGv_ptr cpu_env;
59: static TCGv cpu_ir[31];
60: static TCGv cpu_fir[31];
61: static TCGv cpu_pc;
62: static TCGv cpu_lock;
1.1 root 63:
1.1.1.2 root 64: /* register names */
65: static char cpu_reg_names[10*4+21*5 + 10*5+21*6];
1.1 root 66:
1.1.1.2 root 67: #include "gen-icount.h"
1.1 root 68:
1.1.1.2 root 69: static void alpha_translate_init(void)
1.1 root 70: {
1.1.1.2 root 71: int i;
72: char *p;
73: static int done_init = 0;
1.1 root 74:
1.1.1.2 root 75: if (done_init)
76: return;
1.1 root 77:
1.1.1.2 root 78: cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1.1 root 79:
1.1.1.2 root 80: p = cpu_reg_names;
81: for (i = 0; i < 31; i++) {
82: sprintf(p, "ir%d", i);
83: cpu_ir[i] = tcg_global_mem_new_i64(TCG_AREG0,
84: offsetof(CPUState, ir[i]), p);
85: p += (i < 10) ? 4 : 5;
1.1 root 86:
1.1.1.2 root 87: sprintf(p, "fir%d", i);
88: cpu_fir[i] = tcg_global_mem_new_i64(TCG_AREG0,
89: offsetof(CPUState, fir[i]), p);
90: p += (i < 10) ? 5 : 6;
1.1 root 91: }
92:
1.1.1.2 root 93: cpu_pc = tcg_global_mem_new_i64(TCG_AREG0,
94: offsetof(CPUState, pc), "pc");
1.1 root 95:
1.1.1.2 root 96: cpu_lock = tcg_global_mem_new_i64(TCG_AREG0,
97: offsetof(CPUState, lock), "lock");
1.1 root 98:
1.1.1.2 root 99: /* register helpers */
100: #define GEN_HELPER 2
101: #include "helper.h"
1.1 root 102:
1.1.1.2 root 103: done_init = 1;
104: }
1.1 root 105:
1.1.1.2 root 106: static always_inline void gen_excp (DisasContext *ctx,
107: int exception, int error_code)
1.1 root 108: {
1.1.1.2 root 109: TCGv_i32 tmp1, tmp2;
110:
111: tcg_gen_movi_i64(cpu_pc, ctx->pc);
112: tmp1 = tcg_const_i32(exception);
113: tmp2 = tcg_const_i32(error_code);
114: gen_helper_excp(tmp1, tmp2);
115: tcg_temp_free_i32(tmp2);
116: tcg_temp_free_i32(tmp1);
1.1 root 117: }
118:
1.1.1.2 root 119: static always_inline void gen_invalid (DisasContext *ctx)
1.1 root 120: {
1.1.1.2 root 121: gen_excp(ctx, EXCP_OPCDEC, 0);
1.1 root 122: }
123:
1.1.1.2 root 124: static always_inline void gen_qemu_ldf (TCGv t0, TCGv t1, int flags)
1.1 root 125: {
1.1.1.2 root 126: TCGv tmp = tcg_temp_new();
127: TCGv_i32 tmp32 = tcg_temp_new_i32();
128: tcg_gen_qemu_ld32u(tmp, t1, flags);
129: tcg_gen_trunc_i64_i32(tmp32, tmp);
130: gen_helper_memory_to_f(t0, tmp32);
131: tcg_temp_free_i32(tmp32);
132: tcg_temp_free(tmp);
1.1 root 133: }
134:
1.1.1.2 root 135: static always_inline void gen_qemu_ldg (TCGv t0, TCGv t1, int flags)
1.1 root 136: {
1.1.1.2 root 137: TCGv tmp = tcg_temp_new();
138: tcg_gen_qemu_ld64(tmp, t1, flags);
139: gen_helper_memory_to_g(t0, tmp);
140: tcg_temp_free(tmp);
1.1 root 141: }
142:
1.1.1.2 root 143: static always_inline void gen_qemu_lds (TCGv t0, TCGv t1, int flags)
1.1 root 144: {
1.1.1.2 root 145: TCGv tmp = tcg_temp_new();
146: TCGv_i32 tmp32 = tcg_temp_new_i32();
147: tcg_gen_qemu_ld32u(tmp, t1, flags);
148: tcg_gen_trunc_i64_i32(tmp32, tmp);
149: gen_helper_memory_to_s(t0, tmp32);
150: tcg_temp_free_i32(tmp32);
151: tcg_temp_free(tmp);
1.1 root 152: }
153:
1.1.1.2 root 154: static always_inline void gen_qemu_ldl_l (TCGv t0, TCGv t1, int flags)
1.1 root 155: {
1.1.1.2 root 156: tcg_gen_mov_i64(cpu_lock, t1);
157: tcg_gen_qemu_ld32s(t0, t1, flags);
1.1 root 158: }
159:
1.1.1.2 root 160: static always_inline void gen_qemu_ldq_l (TCGv t0, TCGv t1, int flags)
1.1 root 161: {
1.1.1.2 root 162: tcg_gen_mov_i64(cpu_lock, t1);
163: tcg_gen_qemu_ld64(t0, t1, flags);
1.1 root 164: }
165:
1.1.1.2 root 166: static always_inline void gen_load_mem (DisasContext *ctx,
167: void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1, int flags),
168: int ra, int rb, int32_t disp16,
169: int fp, int clear)
1.1 root 170: {
1.1.1.2 root 171: TCGv addr;
172:
173: if (unlikely(ra == 31))
174: return;
175:
176: addr = tcg_temp_new();
177: if (rb != 31) {
178: tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
179: if (clear)
180: tcg_gen_andi_i64(addr, addr, ~0x7);
1.1 root 181: } else {
1.1.1.2 root 182: if (clear)
183: disp16 &= ~0x7;
184: tcg_gen_movi_i64(addr, disp16);
1.1 root 185: }
1.1.1.2 root 186: if (fp)
187: tcg_gen_qemu_load(cpu_fir[ra], addr, ctx->mem_idx);
188: else
189: tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx);
190: tcg_temp_free(addr);
1.1 root 191: }
192:
1.1.1.2 root 193: static always_inline void gen_qemu_stf (TCGv t0, TCGv t1, int flags)
1.1 root 194: {
1.1.1.2 root 195: TCGv_i32 tmp32 = tcg_temp_new_i32();
196: TCGv tmp = tcg_temp_new();
197: gen_helper_f_to_memory(tmp32, t0);
198: tcg_gen_extu_i32_i64(tmp, tmp32);
199: tcg_gen_qemu_st32(tmp, t1, flags);
200: tcg_temp_free(tmp);
201: tcg_temp_free_i32(tmp32);
1.1 root 202: }
203:
1.1.1.2 root 204: static always_inline void gen_qemu_stg (TCGv t0, TCGv t1, int flags)
1.1 root 205: {
1.1.1.2 root 206: TCGv tmp = tcg_temp_new();
207: gen_helper_g_to_memory(tmp, t0);
208: tcg_gen_qemu_st64(tmp, t1, flags);
209: tcg_temp_free(tmp);
1.1 root 210: }
211:
1.1.1.2 root 212: static always_inline void gen_qemu_sts (TCGv t0, TCGv t1, int flags)
1.1 root 213: {
1.1.1.2 root 214: TCGv_i32 tmp32 = tcg_temp_new_i32();
215: TCGv tmp = tcg_temp_new();
216: gen_helper_s_to_memory(tmp32, t0);
217: tcg_gen_extu_i32_i64(tmp, tmp32);
218: tcg_gen_qemu_st32(tmp, t1, flags);
219: tcg_temp_free(tmp);
220: tcg_temp_free_i32(tmp32);
1.1 root 221: }
222:
1.1.1.2 root 223: static always_inline void gen_qemu_stl_c (TCGv t0, TCGv t1, int flags)
1.1 root 224: {
1.1.1.2 root 225: int l1, l2;
226:
227: l1 = gen_new_label();
228: l2 = gen_new_label();
229: tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
230: tcg_gen_qemu_st32(t0, t1, flags);
231: tcg_gen_movi_i64(t0, 1);
232: tcg_gen_br(l2);
233: gen_set_label(l1);
234: tcg_gen_movi_i64(t0, 0);
235: gen_set_label(l2);
236: tcg_gen_movi_i64(cpu_lock, -1);
1.1 root 237: }
238:
1.1.1.2 root 239: static always_inline void gen_qemu_stq_c (TCGv t0, TCGv t1, int flags)
1.1 root 240: {
1.1.1.2 root 241: int l1, l2;
242:
243: l1 = gen_new_label();
244: l2 = gen_new_label();
245: tcg_gen_brcond_i64(TCG_COND_NE, cpu_lock, t1, l1);
246: tcg_gen_qemu_st64(t0, t1, flags);
247: tcg_gen_movi_i64(t0, 1);
248: tcg_gen_br(l2);
249: gen_set_label(l1);
250: tcg_gen_movi_i64(t0, 0);
251: gen_set_label(l2);
252: tcg_gen_movi_i64(cpu_lock, -1);
1.1 root 253: }
254:
255: static always_inline void gen_store_mem (DisasContext *ctx,
1.1.1.2 root 256: void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1, int flags),
1.1 root 257: int ra, int rb, int32_t disp16,
1.1.1.2 root 258: int fp, int clear, int local)
1.1 root 259: {
1.1.1.2 root 260: TCGv addr;
261: if (local)
262: addr = tcg_temp_local_new();
263: else
264: addr = tcg_temp_new();
265: if (rb != 31) {
266: tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);
267: if (clear)
268: tcg_gen_andi_i64(addr, addr, ~0x7);
269: } else {
270: if (clear)
271: disp16 &= ~0x7;
272: tcg_gen_movi_i64(addr, disp16);
1.1 root 273: }
1.1.1.2 root 274: if (ra != 31) {
275: if (fp)
276: tcg_gen_qemu_store(cpu_fir[ra], addr, ctx->mem_idx);
277: else
278: tcg_gen_qemu_store(cpu_ir[ra], addr, ctx->mem_idx);
279: } else {
280: TCGv zero;
281: if (local)
282: zero = tcg_const_local_i64(0);
283: else
284: zero = tcg_const_i64(0);
285: tcg_gen_qemu_store(zero, addr, ctx->mem_idx);
286: tcg_temp_free(zero);
1.1 root 287: }
1.1.1.2 root 288: tcg_temp_free(addr);
1.1 root 289: }
290:
291: static always_inline void gen_bcond (DisasContext *ctx,
1.1.1.2 root 292: TCGCond cond,
1.1.1.3 ! root 293: int ra, int32_t disp, int mask)
1.1 root 294: {
1.1.1.2 root 295: int l1, l2;
296:
297: l1 = gen_new_label();
298: l2 = gen_new_label();
299: if (likely(ra != 31)) {
300: if (mask) {
301: TCGv tmp = tcg_temp_new();
302: tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
303: tcg_gen_brcondi_i64(cond, tmp, 0, l1);
304: tcg_temp_free(tmp);
305: } else
306: tcg_gen_brcondi_i64(cond, cpu_ir[ra], 0, l1);
1.1 root 307: } else {
1.1.1.2 root 308: /* Very uncommon case - Do not bother to optimize. */
309: TCGv tmp = tcg_const_i64(0);
310: tcg_gen_brcondi_i64(cond, tmp, 0, l1);
311: tcg_temp_free(tmp);
312: }
313: tcg_gen_movi_i64(cpu_pc, ctx->pc);
314: tcg_gen_br(l2);
315: gen_set_label(l1);
1.1.1.3 ! root 316: tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp << 2));
1.1.1.2 root 317: gen_set_label(l2);
1.1 root 318: }
319:
1.1.1.2 root 320: static always_inline void gen_fbcond (DisasContext *ctx, int opc,
1.1 root 321: int ra, int32_t disp16)
322: {
1.1.1.2 root 323: int l1, l2;
324: TCGv tmp;
325: TCGv src;
326:
327: l1 = gen_new_label();
328: l2 = gen_new_label();
329: if (ra != 31) {
330: tmp = tcg_temp_new();
331: src = cpu_fir[ra];
332: } else {
333: tmp = tcg_const_i64(0);
334: src = tmp;
1.1 root 335: }
1.1.1.2 root 336: switch (opc) {
337: case 0x31: /* FBEQ */
338: gen_helper_cmpfeq(tmp, src);
339: break;
340: case 0x32: /* FBLT */
341: gen_helper_cmpflt(tmp, src);
342: break;
343: case 0x33: /* FBLE */
344: gen_helper_cmpfle(tmp, src);
345: break;
346: case 0x35: /* FBNE */
347: gen_helper_cmpfne(tmp, src);
348: break;
349: case 0x36: /* FBGE */
350: gen_helper_cmpfge(tmp, src);
351: break;
352: case 0x37: /* FBGT */
353: gen_helper_cmpfgt(tmp, src);
354: break;
355: default:
356: abort();
357: }
358: tcg_gen_brcondi_i64(TCG_COND_NE, tmp, 0, l1);
359: tcg_gen_movi_i64(cpu_pc, ctx->pc);
360: tcg_gen_br(l2);
361: gen_set_label(l1);
362: tcg_gen_movi_i64(cpu_pc, ctx->pc + (int64_t)(disp16 << 2));
363: gen_set_label(l2);
1.1 root 364: }
365:
1.1.1.2 root 366: static always_inline void gen_cmov (TCGCond inv_cond,
1.1 root 367: int ra, int rb, int rc,
1.1.1.2 root 368: int islit, uint8_t lit, int mask)
1.1 root 369: {
1.1.1.2 root 370: int l1;
1.1 root 371:
1.1.1.2 root 372: if (unlikely(rc == 31))
373: return;
1.1 root 374:
1.1.1.2 root 375: l1 = gen_new_label();
1.1 root 376:
1.1.1.2 root 377: if (ra != 31) {
378: if (mask) {
379: TCGv tmp = tcg_temp_new();
380: tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
381: tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
382: tcg_temp_free(tmp);
383: } else
384: tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
385: } else {
386: /* Very uncommon case - Do not bother to optimize. */
387: TCGv tmp = tcg_const_i64(0);
388: tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
389: tcg_temp_free(tmp);
390: }
1.1 root 391:
1.1.1.2 root 392: if (islit)
393: tcg_gen_movi_i64(cpu_ir[rc], lit);
394: else
395: tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
396: gen_set_label(l1);
1.1 root 397: }
398:
1.1.1.2 root 399: #define FARITH2(name) \
400: static always_inline void glue(gen_f, name)(int rb, int rc) \
401: { \
402: if (unlikely(rc == 31)) \
403: return; \
404: \
405: if (rb != 31) \
406: gen_helper_ ## name (cpu_fir[rc], cpu_fir[rb]); \
407: else { \
408: TCGv tmp = tcg_const_i64(0); \
409: gen_helper_ ## name (cpu_fir[rc], tmp); \
410: tcg_temp_free(tmp); \
411: } \
412: }
413: FARITH2(sqrts)
414: FARITH2(sqrtf)
415: FARITH2(sqrtg)
416: FARITH2(sqrtt)
417: FARITH2(cvtgf)
418: FARITH2(cvtgq)
419: FARITH2(cvtqf)
420: FARITH2(cvtqg)
421: FARITH2(cvtst)
422: FARITH2(cvtts)
423: FARITH2(cvttq)
424: FARITH2(cvtqs)
425: FARITH2(cvtqt)
426: FARITH2(cvtlq)
427: FARITH2(cvtql)
428: FARITH2(cvtqlv)
429: FARITH2(cvtqlsv)
430:
431: #define FARITH3(name) \
432: static always_inline void glue(gen_f, name) (int ra, int rb, int rc) \
433: { \
434: if (unlikely(rc == 31)) \
435: return; \
436: \
437: if (ra != 31) { \
438: if (rb != 31) \
439: gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], cpu_fir[rb]); \
440: else { \
441: TCGv tmp = tcg_const_i64(0); \
442: gen_helper_ ## name (cpu_fir[rc], cpu_fir[ra], tmp); \
443: tcg_temp_free(tmp); \
444: } \
445: } else { \
446: TCGv tmp = tcg_const_i64(0); \
447: if (rb != 31) \
448: gen_helper_ ## name (cpu_fir[rc], tmp, cpu_fir[rb]); \
449: else \
450: gen_helper_ ## name (cpu_fir[rc], tmp, tmp); \
451: tcg_temp_free(tmp); \
452: } \
453: }
454:
455: FARITH3(addf)
456: FARITH3(subf)
457: FARITH3(mulf)
458: FARITH3(divf)
459: FARITH3(addg)
460: FARITH3(subg)
461: FARITH3(mulg)
462: FARITH3(divg)
463: FARITH3(cmpgeq)
464: FARITH3(cmpglt)
465: FARITH3(cmpgle)
466: FARITH3(adds)
467: FARITH3(subs)
468: FARITH3(muls)
469: FARITH3(divs)
470: FARITH3(addt)
471: FARITH3(subt)
472: FARITH3(mult)
473: FARITH3(divt)
474: FARITH3(cmptun)
475: FARITH3(cmpteq)
476: FARITH3(cmptlt)
477: FARITH3(cmptle)
478: FARITH3(cpys)
479: FARITH3(cpysn)
480: FARITH3(cpyse)
481:
482: #define FCMOV(name) \
483: static always_inline void glue(gen_f, name) (int ra, int rb, int rc) \
484: { \
485: int l1; \
486: TCGv tmp; \
487: \
488: if (unlikely(rc == 31)) \
489: return; \
490: \
491: l1 = gen_new_label(); \
492: tmp = tcg_temp_new(); \
493: if (ra != 31) { \
494: tmp = tcg_temp_new(); \
495: gen_helper_ ## name (tmp, cpu_fir[ra]); \
496: } else { \
497: tmp = tcg_const_i64(0); \
498: gen_helper_ ## name (tmp, tmp); \
499: } \
500: tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1); \
501: if (rb != 31) \
502: tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]); \
503: else \
504: tcg_gen_movi_i64(cpu_fir[rc], 0); \
505: gen_set_label(l1); \
506: }
507: FCMOV(cmpfeq)
508: FCMOV(cmpfne)
509: FCMOV(cmpflt)
510: FCMOV(cmpfge)
511: FCMOV(cmpfle)
512: FCMOV(cmpfgt)
1.1 root 513:
1.1.1.2 root 514: /* EXTWH, EXTWH, EXTLH, EXTQH */
515: static always_inline void gen_ext_h(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
516: int ra, int rb, int rc,
517: int islit, uint8_t lit)
1.1 root 518: {
1.1.1.2 root 519: if (unlikely(rc == 31))
520: return;
1.1 root 521:
1.1.1.2 root 522: if (ra != 31) {
523: if (islit) {
524: if (lit != 0)
525: tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 64 - ((lit & 7) * 8));
526: else
527: tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
528: } else {
1.1.1.3 ! root 529: TCGv tmp1;
1.1.1.2 root 530: tmp1 = tcg_temp_new();
1.1.1.3 ! root 531:
1.1.1.2 root 532: tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7);
533: tcg_gen_shli_i64(tmp1, tmp1, 3);
1.1.1.3 ! root 534: tcg_gen_neg_i64(tmp1, tmp1);
! 535: tcg_gen_andi_i64(tmp1, tmp1, 0x3f);
1.1.1.2 root 536: tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1);
1.1.1.3 ! root 537:
1.1.1.2 root 538: tcg_temp_free(tmp1);
539: }
540: if (tcg_gen_ext_i64)
541: tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
542: } else
543: tcg_gen_movi_i64(cpu_ir[rc], 0);
1.1 root 544: }
545:
1.1.1.2 root 546: /* EXTBL, EXTWL, EXTWL, EXTLL, EXTQL */
547: static always_inline void gen_ext_l(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1),
548: int ra, int rb, int rc,
549: int islit, uint8_t lit)
1.1 root 550: {
1.1.1.2 root 551: if (unlikely(rc == 31))
552: return;
1.1 root 553:
1.1.1.2 root 554: if (ra != 31) {
555: if (islit) {
556: tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], (lit & 7) * 8);
557: } else {
558: TCGv tmp = tcg_temp_new();
559: tcg_gen_andi_i64(tmp, cpu_ir[rb], 7);
560: tcg_gen_shli_i64(tmp, tmp, 3);
561: tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], tmp);
562: tcg_temp_free(tmp);
563: }
564: if (tcg_gen_ext_i64)
565: tcg_gen_ext_i64(cpu_ir[rc], cpu_ir[rc]);
566: } else
567: tcg_gen_movi_i64(cpu_ir[rc], 0);
568: }
569:
570: /* Code to call arith3 helpers */
571: #define ARITH3(name) \
572: static 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: } \
595: }
596: ARITH3(cmpbge)
597: ARITH3(addlv)
598: ARITH3(sublv)
599: ARITH3(addqv)
600: ARITH3(subqv)
601: ARITH3(mskbl)
602: ARITH3(insbl)
603: ARITH3(mskwl)
604: ARITH3(inswl)
605: ARITH3(mskll)
606: ARITH3(insll)
607: ARITH3(zap)
608: ARITH3(zapnot)
609: ARITH3(mskql)
610: ARITH3(insql)
611: ARITH3(mskwh)
612: ARITH3(inswh)
613: ARITH3(msklh)
614: ARITH3(inslh)
615: ARITH3(mskqh)
616: ARITH3(insqh)
617: ARITH3(umulh)
618: ARITH3(mullv)
619: ARITH3(mulqv)
620:
621: static always_inline void gen_cmp(TCGCond cond,
622: int ra, int rb, int rc,
623: int islit, uint8_t lit)
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) {
635: tmp = tcg_temp_new();
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);
641: else
642: tcg_gen_brcond_i64(cond, tmp, cpu_ir[rb], l1);
1.1 root 643:
1.1.1.2 root 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);
1.1 root 649: }
650:
651: static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
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;
1.1.1.2 root 657: uint8_t lit;
1.1 root 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;
1.1.1.2 root 667: if (rb == 31 && !islit) {
668: islit = 1;
669: lit = 0;
670: } else
671: lit = (insn >> 13) & 0xFF;
1.1 root 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;
1.1.1.2 root 682: LOG_DISAS("opc %02x ra %d rb %d rc %d disp16 %04x\n",
683: opc, ra, rb, rc, disp16);
1.1 root 684: switch (opc) {
685: case 0x00:
686: /* CALL_PAL */
687: if (palcode >= 0x80 && palcode < 0xC0) {
688: /* Unprivileged PAL call */
1.1.1.3 ! root 689: gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
1.1 root 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
1.1.1.3 ! root 696: gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
1.1 root 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 */
1.1.1.2 root 727: if (likely(ra != 31)) {
728: if (rb != 31)
729: tcg_gen_addi_i64(cpu_ir[ra], cpu_ir[rb], disp16);
730: else
731: tcg_gen_movi_i64(cpu_ir[ra], disp16);
732: }
1.1 root 733: break;
734: case 0x09:
735: /* LDAH */
1.1.1.2 root 736: if (likely(ra != 31)) {
737: if (rb != 31)
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);
741: }
1.1 root 742: break;
743: case 0x0A:
744: /* LDBU */
745: if (!(ctx->amask & AMASK_BWX))
746: goto invalid_opc;
1.1.1.2 root 747: gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1.1 root 748: break;
749: case 0x0B:
750: /* LDQ_U */
1.1.1.2 root 751: gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1.1 root 752: break;
753: case 0x0C:
754: /* LDWU */
755: if (!(ctx->amask & AMASK_BWX))
756: goto invalid_opc;
1.1.1.3 ! root 757: gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1.1 root 758: break;
759: case 0x0D:
760: /* STW */
1.1.1.2 root 761: gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0, 0);
1.1 root 762: break;
763: case 0x0E:
764: /* STB */
1.1.1.2 root 765: gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0, 0);
1.1 root 766: break;
767: case 0x0F:
768: /* STQ_U */
1.1.1.2 root 769: gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1, 0);
1.1 root 770: break;
771: case 0x10:
772: switch (fn7) {
773: case 0x00:
774: /* ADDL */
1.1.1.2 root 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]);
780: } else {
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]);
783: }
784: } else {
785: if (islit)
786: tcg_gen_movi_i64(cpu_ir[rc], lit);
787: else
788: tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
789: }
790: }
1.1 root 791: break;
792: case 0x02:
793: /* S4ADDL */
1.1.1.2 root 794: if (likely(rc != 31)) {
795: if (ra != 31) {
796: TCGv tmp = tcg_temp_new();
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);
804: } else {
805: if (islit)
806: tcg_gen_movi_i64(cpu_ir[rc], lit);
807: else
808: tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
809: }
810: }
1.1 root 811: break;
812: case 0x09:
813: /* SUBL */
1.1.1.2 root 814: if (likely(rc != 31)) {
815: if (ra != 31) {
816: if (islit)
817: tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
818: else
819: tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
820: tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
821: } else {
822: if (islit)
823: tcg_gen_movi_i64(cpu_ir[rc], -lit);
824: else {
825: tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
826: tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
827: }
828: }
1.1 root 829: break;
830: case 0x0B:
831: /* S4SUBL */
1.1.1.2 root 832: if (likely(rc != 31)) {
833: if (ra != 31) {
834: TCGv tmp = tcg_temp_new();
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);
842: } else {
843: if (islit)
844: tcg_gen_movi_i64(cpu_ir[rc], -lit);
845: else {
846: tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
847: tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
848: }
849: }
850: }
1.1 root 851: break;
852: case 0x0F:
853: /* CMPBGE */
1.1.1.2 root 854: gen_cmpbge(ra, rb, rc, islit, lit);
1.1 root 855: break;
856: case 0x12:
857: /* S8ADDL */
1.1.1.2 root 858: if (likely(rc != 31)) {
859: if (ra != 31) {
860: TCGv tmp = tcg_temp_new();
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);
868: } else {
869: if (islit)
870: tcg_gen_movi_i64(cpu_ir[rc], lit);
871: else
872: tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
873: }
874: }
1.1 root 875: break;
876: case 0x1B:
877: /* S8SUBL */
1.1.1.2 root 878: if (likely(rc != 31)) {
879: if (ra != 31) {
880: TCGv tmp = tcg_temp_new();
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);
888: } else {
889: if (islit)
890: tcg_gen_movi_i64(cpu_ir[rc], -lit);
891: else
892: tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
893: tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
894: }
895: }
896: }
1.1 root 897: break;
898: case 0x1D:
899: /* CMPULT */
1.1.1.2 root 900: gen_cmp(TCG_COND_LTU, ra, rb, rc, islit, lit);
1.1 root 901: break;
902: case 0x20:
903: /* ADDQ */
1.1.1.2 root 904: if (likely(rc != 31)) {
905: if (ra != 31) {
906: if (islit)
907: tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
908: else
909: tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
910: } else {
911: if (islit)
912: tcg_gen_movi_i64(cpu_ir[rc], lit);
913: else
914: tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
915: }
916: }
1.1 root 917: break;
918: case 0x22:
919: /* S4ADDQ */
1.1.1.2 root 920: if (likely(rc != 31)) {
921: if (ra != 31) {
922: TCGv tmp = tcg_temp_new();
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);
929: } else {
930: if (islit)
931: tcg_gen_movi_i64(cpu_ir[rc], lit);
932: else
933: tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
934: }
935: }
1.1 root 936: break;
937: case 0x29:
938: /* SUBQ */
1.1.1.2 root 939: if (likely(rc != 31)) {
940: if (ra != 31) {
941: if (islit)
942: tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
943: else
944: tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
945: } else {
946: if (islit)
947: tcg_gen_movi_i64(cpu_ir[rc], -lit);
948: else
949: tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
950: }
951: }
1.1 root 952: break;
953: case 0x2B:
954: /* S4SUBQ */
1.1.1.2 root 955: if (likely(rc != 31)) {
956: if (ra != 31) {
957: TCGv tmp = tcg_temp_new();
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);
964: } else {
965: if (islit)
966: tcg_gen_movi_i64(cpu_ir[rc], -lit);
967: else
968: tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
969: }
970: }
1.1 root 971: break;
972: case 0x2D:
973: /* CMPEQ */
1.1.1.2 root 974: gen_cmp(TCG_COND_EQ, ra, rb, rc, islit, lit);
1.1 root 975: break;
976: case 0x32:
977: /* S8ADDQ */
1.1.1.2 root 978: if (likely(rc != 31)) {
979: if (ra != 31) {
980: TCGv tmp = tcg_temp_new();
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);
987: } else {
988: if (islit)
989: tcg_gen_movi_i64(cpu_ir[rc], lit);
990: else
991: tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
992: }
993: }
1.1 root 994: break;
995: case 0x3B:
996: /* S8SUBQ */
1.1.1.2 root 997: if (likely(rc != 31)) {
998: if (ra != 31) {
999: TCGv tmp = tcg_temp_new();
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);
1006: } else {
1007: if (islit)
1008: tcg_gen_movi_i64(cpu_ir[rc], -lit);
1009: else
1010: tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
1011: }
1012: }
1.1 root 1013: break;
1014: case 0x3D:
1015: /* CMPULE */
1.1.1.2 root 1016: gen_cmp(TCG_COND_LEU, ra, rb, rc, islit, lit);
1.1 root 1017: break;
1018: case 0x40:
1019: /* ADDL/V */
1.1.1.2 root 1020: gen_addlv(ra, rb, rc, islit, lit);
1.1 root 1021: break;
1022: case 0x49:
1023: /* SUBL/V */
1.1.1.2 root 1024: gen_sublv(ra, rb, rc, islit, lit);
1.1 root 1025: break;
1026: case 0x4D:
1027: /* CMPLT */
1.1.1.2 root 1028: gen_cmp(TCG_COND_LT, ra, rb, rc, islit, lit);
1.1 root 1029: break;
1030: case 0x60:
1031: /* ADDQ/V */
1.1.1.2 root 1032: gen_addqv(ra, rb, rc, islit, lit);
1.1 root 1033: break;
1034: case 0x69:
1035: /* SUBQ/V */
1.1.1.2 root 1036: gen_subqv(ra, rb, rc, islit, lit);
1.1 root 1037: break;
1038: case 0x6D:
1039: /* CMPLE */
1.1.1.2 root 1040: gen_cmp(TCG_COND_LE, ra, rb, rc, islit, lit);
1.1 root 1041: break;
1042: default:
1043: goto invalid_opc;
1044: }
1045: break;
1046: case 0x11:
1047: switch (fn7) {
1048: case 0x00:
1049: /* AND */
1.1.1.2 root 1050: if (likely(rc != 31)) {
1051: if (ra == 31)
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: }
1.1 root 1058: break;
1059: case 0x08:
1060: /* BIC */
1.1.1.2 root 1061: if (likely(rc != 31)) {
1062: if (ra != 31) {
1063: if (islit)
1064: tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1065: else
1066: tcg_gen_andc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1067: } else
1068: tcg_gen_movi_i64(cpu_ir[rc], 0);
1069: }
1.1 root 1070: break;
1071: case 0x14:
1072: /* CMOVLBS */
1.1.1.2 root 1073: gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 1);
1.1 root 1074: break;
1075: case 0x16:
1076: /* CMOVLBC */
1.1.1.2 root 1077: gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 1);
1.1 root 1078: break;
1079: case 0x20:
1080: /* BIS */
1.1.1.2 root 1081: if (likely(rc != 31)) {
1082: if (ra != 31) {
1083: if (islit)
1084: tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
1085: else
1086: tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1.1 root 1087: } else {
1.1.1.2 root 1088: if (islit)
1089: tcg_gen_movi_i64(cpu_ir[rc], lit);
1090: else
1091: tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1.1 root 1092: }
1093: }
1094: break;
1095: case 0x24:
1096: /* CMOVEQ */
1.1.1.2 root 1097: gen_cmov(TCG_COND_NE, ra, rb, rc, islit, lit, 0);
1.1 root 1098: break;
1099: case 0x26:
1100: /* CMOVNE */
1.1.1.2 root 1101: gen_cmov(TCG_COND_EQ, ra, rb, rc, islit, lit, 0);
1.1 root 1102: break;
1103: case 0x28:
1104: /* ORNOT */
1.1.1.2 root 1105: if (likely(rc != 31)) {
1106: if (ra != 31) {
1107: if (islit)
1108: tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1109: else
1110: tcg_gen_orc_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
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: }
1.1 root 1118: break;
1119: case 0x40:
1120: /* XOR */
1.1.1.2 root 1121: if (likely(rc != 31)) {
1122: if (ra != 31) {
1123: if (islit)
1124: tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
1125: else
1126: tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1127: } else {
1128: if (islit)
1129: tcg_gen_movi_i64(cpu_ir[rc], lit);
1130: else
1131: tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
1132: }
1133: }
1.1 root 1134: break;
1135: case 0x44:
1136: /* CMOVLT */
1.1.1.2 root 1137: gen_cmov(TCG_COND_GE, ra, rb, rc, islit, lit, 0);
1.1 root 1138: break;
1139: case 0x46:
1140: /* CMOVGE */
1.1.1.2 root 1141: gen_cmov(TCG_COND_LT, ra, rb, rc, islit, lit, 0);
1.1 root 1142: break;
1143: case 0x48:
1144: /* EQV */
1.1.1.2 root 1145: if (likely(rc != 31)) {
1146: if (ra != 31) {
1147: if (islit)
1148: tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
1149: else
1150: tcg_gen_eqv_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
1151: } else {
1152: if (islit)
1153: tcg_gen_movi_i64(cpu_ir[rc], ~lit);
1154: else
1155: tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
1156: }
1157: }
1.1 root 1158: break;
1159: case 0x61:
1160: /* AMASK */
1.1.1.2 root 1161: if (likely(rc != 31)) {
1162: if (islit)
1.1.1.3 ! root 1163: tcg_gen_movi_i64(cpu_ir[rc], lit);
1.1.1.2 root 1164: else
1.1.1.3 ! root 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: }
1.1.1.2 root 1177: }
1.1 root 1178: break;
1179: case 0x64:
1180: /* CMOVLE */
1.1.1.2 root 1181: gen_cmov(TCG_COND_GT, ra, rb, rc, islit, lit, 0);
1.1 root 1182: break;
1183: case 0x66:
1184: /* CMOVGT */
1.1.1.2 root 1185: gen_cmov(TCG_COND_LE, ra, rb, rc, islit, lit, 0);
1.1 root 1186: break;
1187: case 0x6C:
1188: /* IMPLVER */
1.1.1.2 root 1189: if (rc != 31)
1.1.1.3 ! root 1190: tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
1.1 root 1191: break;
1192: default:
1193: goto invalid_opc;
1194: }
1195: break;
1196: case 0x12:
1197: switch (fn7) {
1198: case 0x02:
1199: /* MSKBL */
1.1.1.2 root 1200: gen_mskbl(ra, rb, rc, islit, lit);
1.1 root 1201: break;
1202: case 0x06:
1203: /* EXTBL */
1.1.1.2 root 1204: gen_ext_l(&tcg_gen_ext8u_i64, ra, rb, rc, islit, lit);
1.1 root 1205: break;
1206: case 0x0B:
1207: /* INSBL */
1.1.1.2 root 1208: gen_insbl(ra, rb, rc, islit, lit);
1.1 root 1209: break;
1210: case 0x12:
1211: /* MSKWL */
1.1.1.2 root 1212: gen_mskwl(ra, rb, rc, islit, lit);
1.1 root 1213: break;
1214: case 0x16:
1215: /* EXTWL */
1.1.1.2 root 1216: gen_ext_l(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1.1 root 1217: break;
1218: case 0x1B:
1219: /* INSWL */
1.1.1.2 root 1220: gen_inswl(ra, rb, rc, islit, lit);
1.1 root 1221: break;
1222: case 0x22:
1223: /* MSKLL */
1.1.1.2 root 1224: gen_mskll(ra, rb, rc, islit, lit);
1.1 root 1225: break;
1226: case 0x26:
1227: /* EXTLL */
1.1.1.2 root 1228: gen_ext_l(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
1.1 root 1229: break;
1230: case 0x2B:
1231: /* INSLL */
1.1.1.2 root 1232: gen_insll(ra, rb, rc, islit, lit);
1.1 root 1233: break;
1234: case 0x30:
1235: /* ZAP */
1.1.1.2 root 1236: gen_zap(ra, rb, rc, islit, lit);
1.1 root 1237: break;
1238: case 0x31:
1239: /* ZAPNOT */
1.1.1.2 root 1240: gen_zapnot(ra, rb, rc, islit, lit);
1.1 root 1241: break;
1242: case 0x32:
1243: /* MSKQL */
1.1.1.2 root 1244: gen_mskql(ra, rb, rc, islit, lit);
1.1 root 1245: break;
1246: case 0x34:
1247: /* SRL */
1.1.1.2 root 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);
1252: else {
1253: TCGv shift = tcg_temp_new();
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);
1257: }
1258: } else
1259: tcg_gen_movi_i64(cpu_ir[rc], 0);
1260: }
1.1 root 1261: break;
1262: case 0x36:
1263: /* EXTQL */
1.1.1.2 root 1264: gen_ext_l(NULL, ra, rb, rc, islit, lit);
1.1 root 1265: break;
1266: case 0x39:
1267: /* SLL */
1.1.1.2 root 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);
1272: else {
1273: TCGv shift = tcg_temp_new();
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);
1277: }
1278: } else
1279: tcg_gen_movi_i64(cpu_ir[rc], 0);
1280: }
1.1 root 1281: break;
1282: case 0x3B:
1283: /* INSQL */
1.1.1.2 root 1284: gen_insql(ra, rb, rc, islit, lit);
1.1 root 1285: break;
1286: case 0x3C:
1287: /* SRA */
1.1.1.2 root 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);
1292: else {
1293: TCGv shift = tcg_temp_new();
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);
1297: }
1298: } else
1299: tcg_gen_movi_i64(cpu_ir[rc], 0);
1300: }
1.1 root 1301: break;
1302: case 0x52:
1303: /* MSKWH */
1.1.1.2 root 1304: gen_mskwh(ra, rb, rc, islit, lit);
1.1 root 1305: break;
1306: case 0x57:
1307: /* INSWH */
1.1.1.2 root 1308: gen_inswh(ra, rb, rc, islit, lit);
1.1 root 1309: break;
1310: case 0x5A:
1311: /* EXTWH */
1.1.1.2 root 1312: gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit);
1.1 root 1313: break;
1314: case 0x62:
1315: /* MSKLH */
1.1.1.2 root 1316: gen_msklh(ra, rb, rc, islit, lit);
1.1 root 1317: break;
1318: case 0x67:
1319: /* INSLH */
1.1.1.2 root 1320: gen_inslh(ra, rb, rc, islit, lit);
1.1 root 1321: break;
1322: case 0x6A:
1323: /* EXTLH */
1.1.1.3 ! root 1324: gen_ext_h(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit);
1.1 root 1325: break;
1326: case 0x72:
1327: /* MSKQH */
1.1.1.2 root 1328: gen_mskqh(ra, rb, rc, islit, lit);
1.1 root 1329: break;
1330: case 0x77:
1331: /* INSQH */
1.1.1.2 root 1332: gen_insqh(ra, rb, rc, islit, lit);
1.1 root 1333: break;
1334: case 0x7A:
1335: /* EXTQH */
1.1.1.2 root 1336: gen_ext_h(NULL, ra, rb, rc, islit, lit);
1.1 root 1337: break;
1338: default:
1339: goto invalid_opc;
1340: }
1341: break;
1342: case 0x13:
1343: switch (fn7) {
1344: case 0x00:
1345: /* MULL */
1.1.1.2 root 1346: if (likely(rc != 31)) {
1347: if (ra == 31)
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: }
1.1 root 1357: break;
1358: case 0x20:
1359: /* MULQ */
1.1.1.2 root 1360: if (likely(rc != 31)) {
1361: if (ra == 31)
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: }
1.1 root 1368: break;
1369: case 0x30:
1370: /* UMULH */
1.1.1.2 root 1371: gen_umulh(ra, rb, rc, islit, lit);
1.1 root 1372: break;
1373: case 0x40:
1374: /* MULL/V */
1.1.1.2 root 1375: gen_mullv(ra, rb, rc, islit, lit);
1.1 root 1376: break;
1377: case 0x60:
1378: /* MULQ/V */
1.1.1.2 root 1379: gen_mulqv(ra, rb, rc, islit, lit);
1.1 root 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;
1.1.1.2 root 1391: if (likely(rc != 31)) {
1392: if (ra != 31) {
1393: TCGv_i32 tmp = tcg_temp_new_i32();
1394: tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
1395: gen_helper_memory_to_s(cpu_fir[rc], tmp);
1396: tcg_temp_free_i32(tmp);
1397: } else
1398: tcg_gen_movi_i64(cpu_fir[rc], 0);
1399: }
1.1 root 1400: break;
1401: case 0x0A:
1402: /* SQRTF */
1403: if (!(ctx->amask & AMASK_FIX))
1404: goto invalid_opc;
1.1.1.2 root 1405: gen_fsqrtf(rb, rc);
1.1 root 1406: break;
1407: case 0x0B:
1408: /* SQRTS */
1409: if (!(ctx->amask & AMASK_FIX))
1410: goto invalid_opc;
1.1.1.2 root 1411: gen_fsqrts(rb, rc);
1.1 root 1412: break;
1413: case 0x14:
1414: /* ITOFF */
1415: if (!(ctx->amask & AMASK_FIX))
1416: goto invalid_opc;
1.1.1.2 root 1417: if (likely(rc != 31)) {
1418: if (ra != 31) {
1419: TCGv_i32 tmp = tcg_temp_new_i32();
1420: tcg_gen_trunc_i64_i32(tmp, cpu_ir[ra]);
1421: gen_helper_memory_to_f(cpu_fir[rc], tmp);
1422: tcg_temp_free_i32(tmp);
1423: } else
1424: tcg_gen_movi_i64(cpu_fir[rc], 0);
1425: }
1.1 root 1426: break;
1427: case 0x24:
1428: /* ITOFT */
1429: if (!(ctx->amask & AMASK_FIX))
1430: goto invalid_opc;
1.1.1.2 root 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: }
1.1 root 1437: break;
1438: case 0x2A:
1439: /* SQRTG */
1440: if (!(ctx->amask & AMASK_FIX))
1441: goto invalid_opc;
1.1.1.2 root 1442: gen_fsqrtg(rb, rc);
1.1 root 1443: break;
1444: case 0x02B:
1445: /* SQRTT */
1446: if (!(ctx->amask & AMASK_FIX))
1447: goto invalid_opc;
1.1.1.2 root 1448: gen_fsqrtt(rb, rc);
1.1 root 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 */
1.1.1.2 root 1460: gen_faddf(ra, rb, rc);
1.1 root 1461: break;
1462: case 0x01:
1463: /* SUBF */
1.1.1.2 root 1464: gen_fsubf(ra, rb, rc);
1.1 root 1465: break;
1466: case 0x02:
1467: /* MULF */
1.1.1.2 root 1468: gen_fmulf(ra, rb, rc);
1.1 root 1469: break;
1470: case 0x03:
1471: /* DIVF */
1.1.1.2 root 1472: gen_fdivf(ra, rb, rc);
1.1 root 1473: break;
1474: case 0x1E:
1475: /* CVTDG */
1476: #if 0 // TODO
1.1.1.2 root 1477: gen_fcvtdg(rb, rc);
1.1 root 1478: #else
1479: goto invalid_opc;
1480: #endif
1481: break;
1482: case 0x20:
1483: /* ADDG */
1.1.1.2 root 1484: gen_faddg(ra, rb, rc);
1.1 root 1485: break;
1486: case 0x21:
1487: /* SUBG */
1.1.1.2 root 1488: gen_fsubg(ra, rb, rc);
1.1 root 1489: break;
1490: case 0x22:
1491: /* MULG */
1.1.1.2 root 1492: gen_fmulg(ra, rb, rc);
1.1 root 1493: break;
1494: case 0x23:
1495: /* DIVG */
1.1.1.2 root 1496: gen_fdivg(ra, rb, rc);
1.1 root 1497: break;
1498: case 0x25:
1499: /* CMPGEQ */
1.1.1.2 root 1500: gen_fcmpgeq(ra, rb, rc);
1.1 root 1501: break;
1502: case 0x26:
1503: /* CMPGLT */
1.1.1.2 root 1504: gen_fcmpglt(ra, rb, rc);
1.1 root 1505: break;
1506: case 0x27:
1507: /* CMPGLE */
1.1.1.2 root 1508: gen_fcmpgle(ra, rb, rc);
1.1 root 1509: break;
1510: case 0x2C:
1511: /* CVTGF */
1.1.1.2 root 1512: gen_fcvtgf(rb, rc);
1.1 root 1513: break;
1514: case 0x2D:
1515: /* CVTGD */
1516: #if 0 // TODO
1.1.1.2 root 1517: gen_fcvtgd(rb, rc);
1.1 root 1518: #else
1519: goto invalid_opc;
1520: #endif
1521: break;
1522: case 0x2F:
1523: /* CVTGQ */
1.1.1.2 root 1524: gen_fcvtgq(rb, rc);
1.1 root 1525: break;
1526: case 0x3C:
1527: /* CVTQF */
1.1.1.2 root 1528: gen_fcvtqf(rb, rc);
1.1 root 1529: break;
1530: case 0x3E:
1531: /* CVTQG */
1.1.1.2 root 1532: gen_fcvtqg(rb, rc);
1.1 root 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 */
1.1.1.2 root 1544: gen_fadds(ra, rb, rc);
1.1 root 1545: break;
1546: case 0x01:
1547: /* SUBS */
1.1.1.2 root 1548: gen_fsubs(ra, rb, rc);
1.1 root 1549: break;
1550: case 0x02:
1551: /* MULS */
1.1.1.2 root 1552: gen_fmuls(ra, rb, rc);
1.1 root 1553: break;
1554: case 0x03:
1555: /* DIVS */
1.1.1.2 root 1556: gen_fdivs(ra, rb, rc);
1.1 root 1557: break;
1558: case 0x20:
1559: /* ADDT */
1.1.1.2 root 1560: gen_faddt(ra, rb, rc);
1.1 root 1561: break;
1562: case 0x21:
1563: /* SUBT */
1.1.1.2 root 1564: gen_fsubt(ra, rb, rc);
1.1 root 1565: break;
1566: case 0x22:
1567: /* MULT */
1.1.1.2 root 1568: gen_fmult(ra, rb, rc);
1.1 root 1569: break;
1570: case 0x23:
1571: /* DIVT */
1.1.1.2 root 1572: gen_fdivt(ra, rb, rc);
1.1 root 1573: break;
1574: case 0x24:
1575: /* CMPTUN */
1.1.1.2 root 1576: gen_fcmptun(ra, rb, rc);
1.1 root 1577: break;
1578: case 0x25:
1579: /* CMPTEQ */
1.1.1.2 root 1580: gen_fcmpteq(ra, rb, rc);
1.1 root 1581: break;
1582: case 0x26:
1583: /* CMPTLT */
1.1.1.2 root 1584: gen_fcmptlt(ra, rb, rc);
1.1 root 1585: break;
1586: case 0x27:
1587: /* CMPTLE */
1.1.1.2 root 1588: gen_fcmptle(ra, rb, rc);
1.1 root 1589: break;
1590: case 0x2C:
1591: /* XXX: incorrect */
1.1.1.2 root 1592: if (fn11 == 0x2AC || fn11 == 0x6AC) {
1.1 root 1593: /* CVTST */
1.1.1.2 root 1594: gen_fcvtst(rb, rc);
1.1 root 1595: } else {
1596: /* CVTTS */
1.1.1.2 root 1597: gen_fcvtts(rb, rc);
1.1 root 1598: }
1599: break;
1600: case 0x2F:
1601: /* CVTTQ */
1.1.1.2 root 1602: gen_fcvttq(rb, rc);
1.1 root 1603: break;
1604: case 0x3C:
1605: /* CVTQS */
1.1.1.2 root 1606: gen_fcvtqs(rb, rc);
1.1 root 1607: break;
1608: case 0x3E:
1609: /* CVTQT */
1.1.1.2 root 1610: gen_fcvtqt(rb, rc);
1.1 root 1611: break;
1612: default:
1613: goto invalid_opc;
1614: }
1615: break;
1616: case 0x17:
1617: switch (fn11) {
1618: case 0x010:
1619: /* CVTLQ */
1.1.1.2 root 1620: gen_fcvtlq(rb, rc);
1.1 root 1621: break;
1622: case 0x020:
1.1.1.2 root 1623: if (likely(rc != 31)) {
1624: if (ra == rb)
1.1 root 1625: /* FMOV */
1.1.1.2 root 1626: tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[ra]);
1627: else
1628: /* CPYS */
1629: gen_fcpys(ra, rb, rc);
1.1 root 1630: }
1631: break;
1632: case 0x021:
1633: /* CPYSN */
1.1.1.2 root 1634: gen_fcpysn(ra, rb, rc);
1.1 root 1635: break;
1636: case 0x022:
1637: /* CPYSE */
1.1.1.2 root 1638: gen_fcpyse(ra, rb, rc);
1.1 root 1639: break;
1640: case 0x024:
1641: /* MT_FPCR */
1.1.1.2 root 1642: if (likely(ra != 31))
1643: gen_helper_store_fpcr(cpu_fir[ra]);
1644: else {
1645: TCGv tmp = tcg_const_i64(0);
1646: gen_helper_store_fpcr(tmp);
1647: tcg_temp_free(tmp);
1648: }
1.1 root 1649: break;
1650: case 0x025:
1651: /* MF_FPCR */
1.1.1.2 root 1652: if (likely(ra != 31))
1653: gen_helper_load_fpcr(cpu_fir[ra]);
1.1 root 1654: break;
1655: case 0x02A:
1656: /* FCMOVEQ */
1.1.1.2 root 1657: gen_fcmpfeq(ra, rb, rc);
1.1 root 1658: break;
1659: case 0x02B:
1660: /* FCMOVNE */
1.1.1.2 root 1661: gen_fcmpfne(ra, rb, rc);
1.1 root 1662: break;
1663: case 0x02C:
1664: /* FCMOVLT */
1.1.1.2 root 1665: gen_fcmpflt(ra, rb, rc);
1.1 root 1666: break;
1667: case 0x02D:
1668: /* FCMOVGE */
1.1.1.2 root 1669: gen_fcmpfge(ra, rb, rc);
1.1 root 1670: break;
1671: case 0x02E:
1672: /* FCMOVLE */
1.1.1.2 root 1673: gen_fcmpfle(ra, rb, rc);
1.1 root 1674: break;
1675: case 0x02F:
1676: /* FCMOVGT */
1.1.1.2 root 1677: gen_fcmpfgt(ra, rb, rc);
1.1 root 1678: break;
1679: case 0x030:
1680: /* CVTQL */
1.1.1.2 root 1681: gen_fcvtql(rb, rc);
1.1 root 1682: break;
1683: case 0x130:
1684: /* CVTQL/V */
1.1.1.2 root 1685: gen_fcvtqlv(rb, rc);
1.1 root 1686: break;
1687: case 0x530:
1688: /* CVTQL/SV */
1.1.1.2 root 1689: gen_fcvtqlsv(rb, rc);
1.1 root 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 */
1.1.1.2 root 1725: if (ra != 31)
1726: gen_helper_load_pcc(cpu_ir[ra]);
1.1 root 1727: break;
1728: case 0xE000:
1729: /* RC */
1.1.1.2 root 1730: if (ra != 31)
1731: gen_helper_rc(cpu_ir[ra]);
1.1 root 1732: break;
1733: case 0xE800:
1734: /* ECB */
1735: break;
1736: case 0xF000:
1737: /* RS */
1.1.1.2 root 1738: if (ra != 31)
1739: gen_helper_rs(cpu_ir[ra]);
1.1 root 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;
1.1.1.2 root 1756: if (ra != 31) {
1757: TCGv tmp = tcg_const_i32(insn & 0xFF);
1758: gen_helper_mfpr(cpu_ir[ra], tmp, cpu_ir[ra]);
1759: tcg_temp_free(tmp);
1760: }
1.1 root 1761: break;
1762: #endif
1763: case 0x1A:
1.1.1.2 root 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);
1768: if (ra != 31)
1769: tcg_gen_movi_i64(cpu_ir[ra], ctx->pc);
1.1 root 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;
1.1.1.2 root 1794: if (ra != 31) {
1795: TCGv addr = tcg_temp_new();
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:
1.1.1.3 ! root 1802: /* Longword physical access (hw_ldl/p) */
1.1.1.2 root 1803: gen_helper_ldl_raw(cpu_ir[ra], addr);
1804: break;
1805: case 0x1:
1.1.1.3 ! root 1806: /* Quadword physical access (hw_ldq/p) */
1.1.1.2 root 1807: gen_helper_ldq_raw(cpu_ir[ra], addr);
1808: break;
1809: case 0x2:
1.1.1.3 ! root 1810: /* Longword physical access with lock (hw_ldl_l/p) */
1.1.1.2 root 1811: gen_helper_ldl_l_raw(cpu_ir[ra], addr);
1812: break;
1813: case 0x3:
1.1.1.3 ! root 1814: /* Quadword physical access with lock (hw_ldq_l/p) */
1.1.1.2 root 1815: gen_helper_ldq_l_raw(cpu_ir[ra], addr);
1816: break;
1817: case 0x4:
1.1.1.3 ! root 1818: /* Longword virtual PTE fetch (hw_ldl/v) */
! 1819: tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
1.1.1.2 root 1820: break;
1821: case 0x5:
1.1.1.3 ! root 1822: /* Quadword virtual PTE fetch (hw_ldq/v) */
! 1823: tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
1.1.1.2 root 1824: break;
1825: case 0x6:
1826: /* Incpu_ir[ra]id */
1.1.1.3 ! root 1827: goto invalid_opc;
1.1.1.2 root 1828: case 0x7:
1829: /* Incpu_ir[ra]id */
1.1.1.3 ! root 1830: goto invalid_opc;
1.1.1.2 root 1831: case 0x8:
1.1.1.3 ! root 1832: /* Longword virtual access (hw_ldl) */
1.1.1.2 root 1833: gen_helper_st_virt_to_phys(addr, addr);
1834: gen_helper_ldl_raw(cpu_ir[ra], addr);
1835: break;
1836: case 0x9:
1.1.1.3 ! root 1837: /* Quadword virtual access (hw_ldq) */
1.1.1.2 root 1838: gen_helper_st_virt_to_phys(addr, addr);
1839: gen_helper_ldq_raw(cpu_ir[ra], addr);
1840: break;
1841: case 0xA:
1.1.1.3 ! root 1842: /* Longword virtual access with protection check (hw_ldl/w) */
! 1843: tcg_gen_qemu_ld32s(cpu_ir[ra], addr, 0);
1.1.1.2 root 1844: break;
1845: case 0xB:
1.1.1.3 ! root 1846: /* Quadword virtual access with protection check (hw_ldq/w) */
! 1847: tcg_gen_qemu_ld64(cpu_ir[ra], addr, 0);
1.1.1.2 root 1848: break;
1849: case 0xC:
1.1.1.3 ! root 1850: /* Longword virtual access with alt access mode (hw_ldl/a)*/
1.1.1.2 root 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();
1855: break;
1856: case 0xD:
1.1.1.3 ! root 1857: /* Quadword virtual access with alt access mode (hw_ldq/a) */
1.1.1.2 root 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();
1862: break;
1863: case 0xE:
1864: /* Longword virtual access with alternate access mode and
1.1.1.3 ! root 1865: * protection checks (hw_ldl/wa)
1.1.1.2 root 1866: */
1867: gen_helper_set_alt_mode();
1868: gen_helper_ldl_data(cpu_ir[ra], addr);
1869: gen_helper_restore_mode();
1870: break;
1871: case 0xF:
1872: /* Quadword virtual access with alternate access mode and
1.1.1.3 ! root 1873: * protection checks (hw_ldq/wa)
1.1.1.2 root 1874: */
1875: gen_helper_set_alt_mode();
1876: gen_helper_ldq_data(cpu_ir[ra], addr);
1877: gen_helper_restore_mode();
1878: break;
1879: }
1880: tcg_temp_free(addr);
1.1 root 1881: }
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;
1.1.1.2 root 1890: if (likely(rc != 31)) {
1891: if (islit)
1892: tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit));
1893: else
1894: tcg_gen_ext8s_i64(cpu_ir[rc], cpu_ir[rb]);
1895: }
1.1 root 1896: break;
1897: case 0x01:
1898: /* SEXTW */
1899: if (!(ctx->amask & AMASK_BWX))
1900: goto invalid_opc;
1.1.1.2 root 1901: if (likely(rc != 31)) {
1902: if (islit)
1903: tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit));
1904: else
1905: tcg_gen_ext16s_i64(cpu_ir[rc], cpu_ir[rb]);
1906: }
1.1 root 1907: break;
1908: case 0x30:
1909: /* CTPOP */
1910: if (!(ctx->amask & AMASK_CIX))
1911: goto invalid_opc;
1.1.1.2 root 1912: if (likely(rc != 31)) {
1913: if (islit)
1914: tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit));
1915: else
1916: gen_helper_ctpop(cpu_ir[rc], cpu_ir[rb]);
1917: }
1.1 root 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;
1.1.1.2 root 1930: if (likely(rc != 31)) {
1931: if (islit)
1932: tcg_gen_movi_i64(cpu_ir[rc], clz64(lit));
1933: else
1934: gen_helper_ctlz(cpu_ir[rc], cpu_ir[rb]);
1935: }
1.1 root 1936: break;
1937: case 0x33:
1938: /* CTTZ */
1939: if (!(ctx->amask & AMASK_CIX))
1940: goto invalid_opc;
1.1.1.2 root 1941: if (likely(rc != 31)) {
1942: if (islit)
1943: tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit));
1944: else
1945: gen_helper_cttz(cpu_ir[rc], cpu_ir[rb]);
1946: }
1.1 root 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;
1.1.1.2 root 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: }
1.1 root 2042: break;
2043: case 0x78:
2044: /* FTOIS */
2045: if (!(ctx->amask & AMASK_FIX))
2046: goto invalid_opc;
1.1.1.2 root 2047: if (rc != 31) {
2048: TCGv_i32 tmp1 = tcg_temp_new_i32();
2049: if (ra != 31)
2050: gen_helper_s_to_memory(tmp1, cpu_fir[ra]);
2051: else {
2052: TCGv tmp2 = tcg_const_i64(0);
2053: gen_helper_s_to_memory(tmp1, tmp2);
2054: tcg_temp_free(tmp2);
2055: }
2056: tcg_gen_ext_i32_i64(cpu_ir[rc], tmp1);
2057: tcg_temp_free_i32(tmp1);
2058: }
1.1 root 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;
1.1.1.2 root 2071: else {
2072: TCGv tmp1 = tcg_const_i32(insn & 0xFF);
2073: if (ra != 31)
2074: gen_helper_mtpr(tmp1, cpu_ir[ra]);
2075: else {
2076: TCGv tmp2 = tcg_const_i64(0);
2077: gen_helper_mtpr(tmp1, tmp2);
2078: tcg_temp_free(tmp2);
2079: }
2080: tcg_temp_free(tmp1);
2081: ret = 2;
2082: }
1.1 root 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 */
1.1.1.2 root 2094: gen_helper_hw_rei();
1.1 root 2095: } else {
1.1.1.2 root 2096: TCGv tmp;
2097:
2098: if (ra != 31) {
2099: tmp = tcg_temp_new();
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);
2103: gen_helper_hw_ret(tmp);
2104: tcg_temp_free(tmp);
1.1 root 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;
1.1.1.2 root 2116: else {
2117: TCGv addr, val;
2118: addr = tcg_temp_new();
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 {
2126: val = tcg_temp_new();
2127: tcg_gen_movi_i64(val, 0);
2128: }
2129: switch ((insn >> 12) & 0xF) {
2130: case 0x0:
2131: /* Longword physical access */
2132: gen_helper_stl_raw(val, addr);
2133: break;
2134: case 0x1:
2135: /* Quadword physical access */
2136: gen_helper_stq_raw(val, addr);
2137: break;
2138: case 0x2:
2139: /* Longword physical access with lock */
2140: gen_helper_stl_c_raw(val, val, addr);
2141: break;
2142: case 0x3:
2143: /* Quadword physical access with lock */
2144: gen_helper_stq_c_raw(val, val, addr);
2145: break;
2146: case 0x4:
2147: /* Longword virtual access */
2148: gen_helper_st_virt_to_phys(addr, addr);
2149: gen_helper_stl_raw(val, addr);
2150: break;
2151: case 0x5:
2152: /* Quadword virtual access */
2153: gen_helper_st_virt_to_phys(addr, addr);
2154: gen_helper_stq_raw(val, addr);
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 */
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();
2180: break;
2181: case 0xD:
2182: /* Quadword virtual access with alternate access mode */
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();
2187: break;
2188: case 0xE:
2189: /* Invalid */
2190: goto invalid_opc;
2191: case 0xF:
2192: /* Invalid */
2193: goto invalid_opc;
2194: }
1.1.1.3 ! root 2195: if (ra == 31)
1.1.1.2 root 2196: tcg_temp_free(val);
2197: tcg_temp_free(addr);
1.1 root 2198: }
2199: break;
2200: #endif
2201: case 0x20:
2202: /* LDF */
1.1.1.2 root 2203: gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
1.1 root 2204: break;
2205: case 0x21:
2206: /* LDG */
1.1.1.2 root 2207: gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
1.1 root 2208: break;
2209: case 0x22:
2210: /* LDS */
1.1.1.2 root 2211: gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
1.1 root 2212: break;
2213: case 0x23:
2214: /* LDT */
1.1.1.2 root 2215: gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
1.1 root 2216: break;
2217: case 0x24:
2218: /* STF */
1.1.1.2 root 2219: gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0, 0);
1.1 root 2220: break;
2221: case 0x25:
2222: /* STG */
1.1.1.2 root 2223: gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0, 0);
1.1 root 2224: break;
2225: case 0x26:
2226: /* STS */
1.1.1.2 root 2227: gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0, 0);
1.1 root 2228: break;
2229: case 0x27:
2230: /* STT */
1.1.1.2 root 2231: gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0, 0);
1.1 root 2232: break;
2233: case 0x28:
2234: /* LDL */
1.1.1.2 root 2235: gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
1.1 root 2236: break;
2237: case 0x29:
2238: /* LDQ */
1.1.1.2 root 2239: gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
1.1 root 2240: break;
2241: case 0x2A:
2242: /* LDL_L */
1.1.1.2 root 2243: gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
1.1 root 2244: break;
2245: case 0x2B:
2246: /* LDQ_L */
1.1.1.2 root 2247: gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
1.1 root 2248: break;
2249: case 0x2C:
2250: /* STL */
1.1.1.2 root 2251: gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0, 0);
1.1 root 2252: break;
2253: case 0x2D:
2254: /* STQ */
1.1.1.2 root 2255: gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0, 0);
1.1 root 2256: break;
2257: case 0x2E:
2258: /* STL_C */
1.1.1.2 root 2259: gen_store_mem(ctx, &gen_qemu_stl_c, ra, rb, disp16, 0, 0, 1);
1.1 root 2260: break;
2261: case 0x2F:
2262: /* STQ_C */
1.1.1.2 root 2263: gen_store_mem(ctx, &gen_qemu_stq_c, ra, rb, disp16, 0, 0, 1);
1.1 root 2264: break;
2265: case 0x30:
2266: /* BR */
1.1.1.2 root 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));
1.1 root 2270: ret = 1;
2271: break;
1.1.1.2 root 2272: case 0x31: /* FBEQ */
2273: case 0x32: /* FBLT */
2274: case 0x33: /* FBLE */
2275: gen_fbcond(ctx, opc, ra, disp16);
1.1 root 2276: ret = 1;
2277: break;
2278: case 0x34:
2279: /* BSR */
1.1.1.2 root 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));
1.1 root 2283: ret = 1;
2284: break;
1.1.1.2 root 2285: case 0x35: /* FBNE */
2286: case 0x36: /* FBGE */
2287: case 0x37: /* FBGT */
2288: gen_fbcond(ctx, opc, ra, disp16);
1.1 root 2289: ret = 1;
2290: break;
2291: case 0x38:
2292: /* BLBC */
1.1.1.3 ! root 2293: gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
1.1 root 2294: ret = 1;
2295: break;
2296: case 0x39:
2297: /* BEQ */
1.1.1.3 ! root 2298: gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
1.1 root 2299: ret = 1;
2300: break;
2301: case 0x3A:
2302: /* BLT */
1.1.1.3 ! root 2303: gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
1.1 root 2304: ret = 1;
2305: break;
2306: case 0x3B:
2307: /* BLE */
1.1.1.3 ! root 2308: gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
1.1 root 2309: ret = 1;
2310: break;
2311: case 0x3C:
2312: /* BLBS */
1.1.1.3 ! root 2313: gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
1.1 root 2314: ret = 1;
2315: break;
2316: case 0x3D:
2317: /* BNE */
1.1.1.3 ! root 2318: gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
1.1 root 2319: ret = 1;
2320: break;
2321: case 0x3E:
2322: /* BGE */
1.1.1.3 ! root 2323: gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
1.1 root 2324: ret = 1;
2325: break;
2326: case 0x3F:
2327: /* BGT */
1.1.1.3 ! root 2328: gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
1.1 root 2329: ret = 1;
2330: break;
2331: invalid_opc:
2332: gen_invalid(ctx);
2333: ret = 3;
2334: break;
2335: }
2336:
2337: return ret;
2338: }
2339:
1.1.1.2 root 2340: static always_inline void gen_intermediate_code_internal (CPUState *env,
2341: TranslationBlock *tb,
2342: int search_pc)
1.1 root 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;
1.1.1.2 root 2351: CPUBreakpoint *bp;
1.1 root 2352: int j, lj = -1;
2353: int ret;
1.1.1.2 root 2354: int num_insns;
2355: int max_insns;
1.1 root 2356:
2357: pc_start = tb->pc;
2358: gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2359: ctx.pc = pc_start;
2360: ctx.amask = env->amask;
1.1.1.3 ! root 2361: ctx.env = env;
1.1 root 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
1.1.1.2 root 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();
1.1 root 2374: for (ret = 0; ret == 0;) {
1.1.1.2 root 2375: if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
2376: TAILQ_FOREACH(bp, &env->breakpoints, entry) {
2377: if (bp->pc == ctx.pc) {
1.1 root 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;
2389: }
1.1.1.3 ! root 2390: gen_opc_pc[lj] = ctx.pc;
! 2391: gen_opc_instr_start[lj] = 1;
! 2392: gen_opc_icount[lj] = num_insns;
1.1 root 2393: }
1.1.1.2 root 2394: if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
2395: gen_io_start();
1.1 root 2396: #if defined ALPHA_DEBUG_DISAS
2397: insn_count++;
1.1.1.2 root 2398: LOG_DISAS("pc " TARGET_FMT_lx " mem_idx %d\n",
2399: ctx.pc, ctx.mem_idx);
1.1 root 2400: #endif
2401: insn = ldl_code(ctx.pc);
2402: #if defined ALPHA_DEBUG_DISAS
2403: insn_count++;
1.1.1.2 root 2404: LOG_DISAS("opcode %08x %d\n", insn, insn_count);
1.1 root 2405: #endif
1.1.1.2 root 2406: num_insns++;
1.1 root 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: */
1.1.1.3 ! root 2414: if (env->singlestep_enabled) {
! 2415: gen_excp(&ctx, EXCP_DEBUG, 0);
1.1 root 2416: break;
2417: }
1.1.1.2 root 2418:
1.1.1.3 ! root 2419: if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1.1.1.2 root 2420: break;
2421:
1.1.1.3 ! root 2422: if (gen_opc_ptr >= gen_opc_end)
! 2423: break;
! 2424:
! 2425: if (num_insns >= max_insns)
! 2426: break;
! 2427:
! 2428: if (singlestep) {
! 2429: break;
! 2430: }
1.1 root 2431: }
2432: if (ret != 1 && ret != 3) {
1.1.1.2 root 2433: tcg_gen_movi_i64(cpu_pc, ctx.pc);
1.1 root 2434: }
2435: #if defined (DO_TB_FLUSH)
1.1.1.2 root 2436: gen_helper_tb_flush();
1.1 root 2437: #endif
1.1.1.2 root 2438: if (tb->cflags & CF_LAST_IO)
2439: gen_io_end();
1.1 root 2440: /* Generate the return instruction */
1.1.1.2 root 2441: tcg_gen_exit_tb(0);
2442: gen_icount_end(tb, num_insns);
1.1 root 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;
2449: } else {
2450: tb->size = ctx.pc - pc_start;
1.1.1.2 root 2451: tb->icount = num_insns;
1.1 root 2452: }
2453: #if defined ALPHA_DEBUG_DISAS
1.1.1.2 root 2454: log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
2455: if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
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");
1.1 root 2459: }
2460: #endif
2461: }
2462:
1.1.1.2 root 2463: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1.1 root 2464: {
1.1.1.2 root 2465: gen_intermediate_code_internal(env, tb, 0);
1.1 root 2466: }
2467:
1.1.1.2 root 2468: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1 root 2469: {
1.1.1.2 root 2470: gen_intermediate_code_internal(env, tb, 1);
1.1 root 2471: }
2472:
2473: CPUAlphaState * cpu_alpha_init (const char *cpu_model)
2474: {
2475: CPUAlphaState *env;
2476: uint64_t hwpcb;
2477:
2478: env = qemu_mallocz(sizeof(CPUAlphaState));
2479: cpu_exec_init(env);
1.1.1.2 root 2480: alpha_translate_init();
1.1 root 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:
1.1.1.3 ! root 2508: qemu_init_vcpu(env);
1.1 root 2509: return env;
2510: }
2511:
1.1.1.2 root 2512: void gen_pc_load(CPUState *env, TranslationBlock *tb,
2513: unsigned long searched_pc, int pc_pos, void *puc)
2514: {
2515: env->pc = gen_opc_pc[pc_pos];
2516: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.