diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-03-13 09:33:41 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-03-13 09:33:41 +0000 |
commit | 9298a4e8a648d88300883681317ed733a6ad39d0 (patch) | |
tree | de834871aa1bf4474ef5f4e49a43a157f9c6b20d | |
parent | 3f3bbfc7cef4490c5ed5550766a81e7d18f08db1 (diff) | |
parent | 32dc75698c848d11a087c77570ac0cd954e0bb20 (diff) |
Merge remote-tracking branch 'remotes/rth/tags/pull-hppa-20190312' into staging
Misc fixes affecting HP-UX 10.20.
# gpg: Signature made Tue 12 Mar 2019 16:16:32 GMT
# gpg: using RSA key 64DF38E8AF7E215F
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F
* remotes/rth/tags/pull-hppa-20190312:
target/hppa: exit TB if either Data or Instruction TLB changes
target/hppa: add TLB protection id check
target/hppa: allow multiple itlbp without itlba
target/hppa: fix b,gate instruction
target/hppa: ignore DIAG opcode
target/hppa: remove PSW I/R/Q bit check
target/hppa: add TLB trace events
target/hppa: report ITLB_EXCP_MISS for ITLB misses
target/hppa: fix TLB handling for page 0
target/hppa: fix overwriting source reg in addb
target/hppa: Check for page crossings in use_goto_tb
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | Makefile.objs | 1 | ||||
-rw-r--r-- | target/hppa/cpu.h | 10 | ||||
-rw-r--r-- | target/hppa/gdbstub.c | 20 | ||||
-rw-r--r-- | target/hppa/helper.c | 10 | ||||
-rw-r--r-- | target/hppa/helper.h | 1 | ||||
-rw-r--r-- | target/hppa/insns.decode | 3 | ||||
-rw-r--r-- | target/hppa/mem_helper.c | 67 | ||||
-rw-r--r-- | target/hppa/op_helper.c | 7 | ||||
-rw-r--r-- | target/hppa/trace-events | 18 | ||||
-rw-r--r-- | target/hppa/translate.c | 51 |
10 files changed, 151 insertions, 37 deletions
diff --git a/Makefile.objs b/Makefile.objs index 31a84b7d41..72debbf5c5 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -182,6 +182,7 @@ trace-events-subdirs += qapi trace-events-subdirs += qom trace-events-subdirs += scsi trace-events-subdirs += target/arm +trace-events-subdirs += target/hppa trace-events-subdirs += target/i386 trace-events-subdirs += target/mips trace-events-subdirs += target/ppc diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 861bbb1f16..c062c7969c 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -143,6 +143,10 @@ #endif #define CR_RC 0 +#define CR_PID1 8 +#define CR_PID2 9 +#define CR_PID3 12 +#define CR_PID4 13 #define CR_SCRCCR 10 #define CR_SAR 11 #define CR_IVA 14 @@ -341,6 +345,12 @@ target_ureg cpu_hppa_get_psw(CPUHPPAState *env); void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg); void cpu_hppa_loaded_fr0(CPUHPPAState *env); +#ifdef CONFIG_USER_ONLY +static inline void cpu_hppa_change_prot_id(CPUHPPAState *env) { } +#else +void cpu_hppa_change_prot_id(CPUHPPAState *env); +#endif + #define cpu_signal_handler cpu_hppa_signal_handler int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc); diff --git a/target/hppa/gdbstub.c b/target/hppa/gdbstub.c index 3157a690f2..983bf92aaf 100644 --- a/target/hppa/gdbstub.c +++ b/target/hppa/gdbstub.c @@ -93,19 +93,19 @@ int hppa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) val = env->cr[CR_RC]; break; case 52: - val = env->cr[8]; + val = env->cr[CR_PID1]; break; case 53: - val = env->cr[9]; + val = env->cr[CR_PID2]; break; case 54: val = env->cr[CR_SCRCCR]; break; case 55: - val = env->cr[12]; + val = env->cr[CR_PID3]; break; case 56: - val = env->cr[13]; + val = env->cr[CR_PID4]; break; case 57: val = env->cr[24]; @@ -224,19 +224,23 @@ int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) env->cr[CR_RC] = val; break; case 52: - env->cr[8] = val; + env->cr[CR_PID1] = val; + cpu_hppa_change_prot_id(env); break; case 53: - env->cr[9] = val; + env->cr[CR_PID2] = val; + cpu_hppa_change_prot_id(env); break; case 54: env->cr[CR_SCRCCR] = val; break; case 55: - env->cr[12] = val; + env->cr[CR_PID3] = val; + cpu_hppa_change_prot_id(env); break; case 56: - env->cr[13] = val; + env->cr[CR_PID4] = val; + cpu_hppa_change_prot_id(env); break; case 57: env->cr[24] = val; diff --git a/target/hppa/helper.c b/target/hppa/helper.c index 6539061e52..ac750b62ef 100644 --- a/target/hppa/helper.c +++ b/target/hppa/helper.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "fpu/softfloat.h" +#include "exec/exec-all.h" #include "exec/helper-proto.h" target_ureg cpu_hppa_get_psw(CPUHPPAState *env) @@ -49,6 +50,7 @@ target_ureg cpu_hppa_get_psw(CPUHPPAState *env) void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw) { + target_ureg old_psw = env->psw; target_ureg cb = 0; env->psw = psw & ~(PSW_N | PSW_V | PSW_CB); @@ -64,6 +66,14 @@ void cpu_hppa_put_psw(CPUHPPAState *env, target_ureg psw) cb |= ((psw >> 9) & 1) << 8; cb |= ((psw >> 8) & 1) << 4; env->psw_cb = cb; + + /* If PSW_P changes, it affects how we translate addresses. */ + if ((psw ^ old_psw) & PSW_P) { +#ifndef CONFIG_USER_ONLY + CPUState *src = CPU(hppa_env_get_cpu(env)); + tlb_flush_by_mmuidx(src, 0xf); +#endif + } } void hppa_cpu_dump_state(CPUState *cs, FILE *f, diff --git a/target/hppa/helper.h b/target/hppa/helper.h index bfe0dd1db1..38d834ef6b 100644 --- a/target/hppa/helper.h +++ b/target/hppa/helper.h @@ -92,4 +92,5 @@ DEF_HELPER_FLAGS_3(itlbp, TCG_CALL_NO_RWG, void, env, tl, tr) DEF_HELPER_FLAGS_2(ptlb, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_1(ptlbe, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_2(lpa, TCG_CALL_NO_WG, tr, env, tl) +DEF_HELPER_FLAGS_1(change_prot_id, TCG_CALL_NO_RWG, void, env) #endif diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 55ff39dd05..098370c2f0 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -525,3 +525,6 @@ fmpy_d 001110 ..... ..... 010 ..... ... ..... @f0e_d_3 fdiv_d 001110 ..... ..... 011 ..... ... ..... @f0e_d_3 xmpyu 001110 ..... ..... 010 .0111 .00 t:5 r1=%ra64 r2=%rb64 + +# diag +diag 000101 ----- ----- ---- ---- ---- ---- diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index aecf3075f6..c9b57d07c3 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -22,6 +22,7 @@ #include "exec/exec-all.h" #include "exec/helper-proto.h" #include "qom/cpu.h" +#include "trace.h" #ifdef CONFIG_USER_ONLY int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address, @@ -43,9 +44,12 @@ static hppa_tlb_entry *hppa_find_tlb(CPUHPPAState *env, vaddr addr) for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) { hppa_tlb_entry *ent = &env->tlb[i]; if (ent->va_b <= addr && addr <= ent->va_e) { + trace_hppa_tlb_find_entry(env, ent + i, ent->entry_valid, + ent->va_b, ent->va_e, ent->pa); return ent; } } + trace_hppa_tlb_find_entry_not_found(env, addr); return NULL; } @@ -55,6 +59,8 @@ static void hppa_flush_tlb_ent(CPUHPPAState *env, hppa_tlb_entry *ent) unsigned i, n = 1 << (2 * ent->page_size); uint64_t addr = ent->va_b; + trace_hppa_tlb_flush_ent(env, ent, ent->va_b, ent->va_e, ent->pa); + for (i = 0; i < n; ++i, addr += TARGET_PAGE_SIZE) { /* Do not flush MMU_PHYS_IDX. */ tlb_flush_page_by_mmuidx(cs, addr, 0xf); @@ -96,9 +102,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, if (ent == NULL || !ent->entry_valid) { phys = 0; prot = 0; - /* ??? Unconditionally report data tlb miss, - even if this is an instruction fetch. */ - ret = EXCP_DTLB_MISS; + ret = (type == PAGE_EXEC) ? EXCP_ITLB_MISS : EXCP_DTLB_MISS; goto egress; } @@ -127,7 +131,20 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, break; } - /* ??? Check PSW_P and ent->access_prot. This can remove PAGE_WRITE. */ + /* access_id == 0 means public page and no check is performed */ + if ((env->psw & PSW_P) && ent->access_id) { + /* If bits [31:1] match, and bit 0 is set, suppress write. */ + int match = ent->access_id * 2 + 1; + + if (match == env->cr[CR_PID1] || match == env->cr[CR_PID2] || + match == env->cr[CR_PID3] || match == env->cr[CR_PID4]) { + prot &= PAGE_READ | PAGE_EXEC; + if (type == PAGE_WRITE) { + ret = EXCP_DMPI; + goto egress; + } + } + } /* No guest access type indicates a non-architectural access from within QEMU. Bypass checks for access, D, B and T bits. */ @@ -171,6 +188,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, egress: *pphys = phys; *pprot = prot; + trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys); return ret; } @@ -200,6 +218,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size, MMUAccessType type, int mmu_idx, uintptr_t retaddr) { HPPACPU *cpu = HPPA_CPU(cs); + CPUHPPAState *env = &cpu->env; int prot, excp, a_prot; hwaddr phys; @@ -215,9 +234,10 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size, break; } - excp = hppa_get_physical_address(&cpu->env, addr, mmu_idx, + excp = hppa_get_physical_address(env, addr, mmu_idx, a_prot, &phys, &prot); if (unlikely(excp >= 0)) { + trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx); /* Failure. Raise the indicated exception. */ cs->exception_index = excp; if (cpu->env.psw & PSW_Q) { @@ -228,6 +248,8 @@ void tlb_fill(CPUState *cs, target_ulong addr, int size, cpu_loop_exit_restore(cs, retaddr); } + trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK, + phys & TARGET_PAGE_MASK, size, type, mmu_idx); /* Success! Store the translation into the QEMU TLB. */ tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK, prot, mmu_idx, TARGET_PAGE_SIZE); @@ -242,11 +264,13 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, target_ureg reg) /* Zap any old entries covering ADDR; notice empty entries on the way. */ for (i = 0; i < ARRAY_SIZE(env->tlb); ++i) { hppa_tlb_entry *ent = &env->tlb[i]; - if (!ent->entry_valid) { - empty = ent; - } else if (ent->va_b <= addr && addr <= ent->va_e) { - hppa_flush_tlb_ent(env, ent); - empty = ent; + if (ent->va_b <= addr && addr <= ent->va_e) { + if (ent->entry_valid) { + hppa_flush_tlb_ent(env, ent); + } + if (!empty) { + empty = ent; + } } } @@ -259,6 +283,7 @@ void HELPER(itlba)(CPUHPPAState *env, target_ulong addr, target_ureg reg) empty->va_b = addr & TARGET_PAGE_MASK; empty->va_e = empty->va_b + TARGET_PAGE_SIZE - 1; empty->pa = extract32(reg, 5, 20) << TARGET_PAGE_BITS; + trace_hppa_tlb_itlba(env, empty, empty->va_b, empty->va_e, empty->pa); } /* Insert (Insn/Data) TLB Protection. Note this is PA 1.1 only. */ @@ -266,7 +291,7 @@ void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, target_ureg reg) { hppa_tlb_entry *ent = hppa_find_tlb(env, addr); - if (unlikely(ent == NULL || ent->entry_valid)) { + if (unlikely(ent == NULL)) { qemu_log_mask(LOG_GUEST_ERROR, "ITLBP not following ITLBA\n"); return; } @@ -280,6 +305,8 @@ void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, target_ureg reg) ent->d = extract32(reg, 28, 1); ent->t = extract32(reg, 29, 1); ent->entry_valid = 1; + trace_hppa_tlb_itlbp(env, ent, ent->access_id, ent->u, ent->ar_pl2, + ent->ar_pl1, ent->ar_type, ent->b, ent->d, ent->t); } /* Purge (Insn/Data) TLB. This is explicitly page-based, and is @@ -299,6 +326,7 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr) { CPUState *src = CPU(hppa_env_get_cpu(env)); CPUState *cpu; + trace_hppa_tlb_ptlb(env); run_on_cpu_data data = RUN_ON_CPU_TARGET_PTR(addr); CPU_FOREACH(cpu) { @@ -314,11 +342,24 @@ void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr) void HELPER(ptlbe)(CPUHPPAState *env) { CPUState *src = CPU(hppa_env_get_cpu(env)); - + trace_hppa_tlb_ptlbe(env); memset(env->tlb, 0, sizeof(env->tlb)); tlb_flush_by_mmuidx(src, 0xf); } +void cpu_hppa_change_prot_id(CPUHPPAState *env) +{ + if (env->psw & PSW_P) { + CPUState *src = CPU(hppa_env_get_cpu(env)); + tlb_flush_by_mmuidx(src, 0xf); + } +} + +void HELPER(change_prot_id)(CPUHPPAState *env) +{ + cpu_hppa_change_prot_id(env); +} + target_ureg HELPER(lpa)(CPUHPPAState *env, target_ulong addr) { hwaddr phys; @@ -335,8 +376,10 @@ target_ureg HELPER(lpa)(CPUHPPAState *env, target_ulong addr) if (excp == EXCP_DTLB_MISS) { excp = EXCP_NA_DTLB_MISS; } + trace_hppa_tlb_lpa_failed(env, addr); hppa_dynamic_excp(env, excp, GETPC()); } + trace_hppa_tlb_lpa_success(env, addr, phys); return phys; } diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index 268caaaa20..a55a5dfc02 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -25,6 +25,7 @@ #include "sysemu/sysemu.h" #include "qemu/timer.h" #include "fpu/softfloat.h" +#include "trace.h" void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp) { @@ -165,6 +166,7 @@ target_ureg HELPER(probe)(CPUHPPAState *env, target_ulong addr, int prot, excp; hwaddr phys; + trace_hppa_tlb_probe(addr, level, want); /* Fail if the requested privilege level is higher than current. */ if (level < (env->iaoq_f & 3)) { return 0; @@ -676,11 +678,6 @@ target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, target_ureg nsm) void HELPER(rfi)(CPUHPPAState *env) { - /* ??? On second reading this condition simply seems - to be undefined rather than a diagnosed trap. */ - if (env->psw & (PSW_I | PSW_R | PSW_Q)) { - helper_excp(env, EXCP_ILL); - } env->iasq_f = (uint64_t)env->cr[CR_IIASQ] << 32; env->iasq_b = (uint64_t)env->cr_back[0] << 32; env->iaoq_f = env->cr[CR_IIAOQ]; diff --git a/target/hppa/trace-events b/target/hppa/trace-events new file mode 100644 index 0000000000..80dae5bd8b --- /dev/null +++ b/target/hppa/trace-events @@ -0,0 +1,18 @@ +# See docs/devel/tracing.txt for syntax documentation. + +# target/hppa/mem_helper.c +disable hppa_tlb_flush_ent(void *env, void *ent, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p va_b=0x%lx va_e=0x%lx pa=0x%lx" +disable hppa_tlb_find_entry(void *env, void *ent, int valid, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p valid=%d va_b=0x%lx va_e=0x%lx pa=0x%lx" +disable hppa_tlb_find_entry_not_found(void *env, uint64_t addr) "env=%p addr=%08lx" +disable hppa_tlb_get_physical_address(void *env, int ret, int prot, uint64_t addr, uint64_t phys) "env=%p ret=%d prot=%d addr=0x%lx phys=0x%lx" +disable hppa_tlb_fill_excp(void *env, uint64_t addr, int size, int type, int mmu_idx) "env=%p addr=0x%lx size=%d type=%d mmu_idx=%d" +disable hppa_tlb_fill_success(void *env, uint64_t addr, uint64_t phys, int size, int type, int mmu_idx) "env=%p addr=0x%lx phys=0x%lx size=%d type=%d mmu_idx=%d" +disable hppa_tlb_itlba(void *env, void *ent, uint64_t va_b, uint64_t va_e, uint64_t pa) "env=%p ent=%p va_b=0x%lx va_e=0x%lx pa=0x%lx" +disable hppa_tlb_itlbp(void *env, void *ent, int access_id, int u, int pl2, int pl1, int type, int b, int d, int t) "env=%p ent=%p access_id=%x u=%d pl2=%d pl1=%d type=%d b=%d d=%d t=%d" +disable hppa_tlb_ptlb(void *env) "env=%p" +disable hppa_tlb_ptlbe(void *env) "env=%p" +disable hppa_tlb_lpa_success(void *env, uint64_t addr, uint64_t phys) "env=%p addr=0x%lx phys=0x%lx" +disable hppa_tlb_lpa_failed(void *env, uint64_t addr) "env=%p addr=0x%lx" + +# target/hppa/op_helper.c +disable hppa_tlb_probe(uint64_t addr, int level, int want) "addr=0x%lx level=%d want=%d" diff --git a/target/hppa/translate.c b/target/hppa/translate.c index dc5636fe94..35c504087f 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -816,12 +816,10 @@ static bool gen_illegal(DisasContext *ctx) static bool use_goto_tb(DisasContext *ctx, target_ureg dest) { - /* Suppress goto_tb in the case of single-steping and IO. */ - if ((tb_cflags(ctx->base.tb) & CF_LAST_IO) - || ctx->base.singlestep_enabled) { - return false; - } - return true; + /* Suppress goto_tb for page crossing, IO, or single-steping. */ + return !(((ctx->base.pc_first ^ dest) & TARGET_PAGE_MASK) + || (tb_cflags(ctx->base.tb) & CF_LAST_IO) + || ctx->base.singlestep_enabled); } /* If the next insn is to be nullified, and it's on the same page, @@ -2258,6 +2256,16 @@ static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a) offsetof(CPUHPPAState, cr_back[ctl - CR_IIASQ])); break; + case CR_PID1: + case CR_PID2: + case CR_PID3: + case CR_PID4: + tcg_gen_st_reg(reg, cpu_env, offsetof(CPUHPPAState, cr[ctl])); +#ifndef CONFIG_USER_ONLY + gen_helper_change_prot_id(cpu_env); +#endif + break; + default: tcg_gen_st_reg(reg, cpu_env, offsetof(CPUHPPAState, cr[ctl])); break; @@ -2474,9 +2482,8 @@ static bool trans_ixtlbx(DisasContext *ctx, arg_ixtlbx *a) gen_helper_itlbp(cpu_env, addr, reg); } - /* Exit TB for ITLB change if mmu is enabled. This *should* not be - the case, since the OS TLB fill handler runs with mmu disabled. */ - if (!a->data && (ctx->tb_flags & PSW_C)) { + /* Exit TB for TLB change if mmu is enabled. */ + if (ctx->tb_flags & PSW_C) { ctx->base.is_jmp = DISAS_IAQ_N_STALE; } return nullify_end(ctx); @@ -2503,7 +2510,7 @@ static bool trans_pxtlbx(DisasContext *ctx, arg_pxtlbx *a) } /* Exit TB for TLB change if mmu is enabled. */ - if (!a->data && (ctx->tb_flags & PSW_C)) { + if (ctx->tb_flags & PSW_C) { ctx->base.is_jmp = DISAS_IAQ_N_STALE; } return nullify_end(ctx); @@ -3033,7 +3040,7 @@ static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1, DisasCond cond; in2 = load_gpr(ctx, r); - dest = dest_gpr(ctx, r); + dest = tcg_temp_new(); sv = NULL; cb_msb = NULL; @@ -3049,6 +3056,8 @@ static bool do_addb(DisasContext *ctx, unsigned r, TCGv_reg in1, } cond = do_cond(c * 2 + f, dest, cb_msb, sv); + save_gpr(ctx, r, dest); + tcg_temp_free(dest); return do_cbranch(ctx, disp, n, &cond); } @@ -3446,6 +3455,8 @@ static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a) { target_ureg dest = iaoq_dest(ctx, a->disp); + nullify_over(ctx); + /* Make sure the caller hasn't done something weird with the queue. * ??? This is not quite the same as the PSW[B] bit, which would be * expensive to track. Real hardware will trap for @@ -3483,7 +3494,16 @@ static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a) } #endif - return do_dbranch(ctx, dest, a->l, a->n); + if (a->l) { + TCGv_reg tmp = dest_gpr(ctx, a->l); + if (ctx->privilege < 3) { + tcg_gen_andi_reg(tmp, tmp, -4); + } + tcg_gen_ori_reg(tmp, tmp, ctx->privilege); + save_gpr(ctx, a->l, tmp); + } + + return do_dbranch(ctx, dest, 0, a->n); } static bool trans_blr(DisasContext *ctx, arg_blr *a) @@ -4048,6 +4068,13 @@ static bool trans_fmpyfadd_d(DisasContext *ctx, arg_fmpyfadd_d *a) return nullify_end(ctx); } +static bool trans_diag(DisasContext *ctx, arg_diag *a) +{ + qemu_log_mask(LOG_UNIMP, "DIAG opcode ignored\n"); + cond_free(&ctx->null_cond); + return true; +} + static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) { DisasContext *ctx = container_of(dcbase, DisasContext, base); |