From nobody Tue Feb 10 12:59:10 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1598624873; cv=none; d=zohomail.com; s=zohoarc; b=E2jX6gk5J2XBgS1aFjrscfKdavCwh6L0zPmc+u42sFmB4JTxf2okrV+7+38XNimFZeKg0EQtJfadgmNcdXjXBooTpdPG7g0wpKPF2Ojt9g0syjsqFV9fb9gJrJm//Cy+jEt4GMEh2jEAuNZ6A3epj6m6A20S6ufx/68/iV7DSBk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1598624873; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=tvav2yDgl091Kla7AxGkIifdrAi1yowT9YLtoH5uMlM=; b=SOWbVhznwvzHRXm2M6L8jl2gAVH080dJcRJhSZwNtV63sC65mKt7HPnggP/EXHjzwTMA200zZ0hF6s7gdhD83AOt5j+Am1oJm3js/RJvDKTXsi9jY5vzv+TcNh+r1RVxBLWFbKy2BX53tUnTQmd6o9zpGZDTflcuJuJ9Hp8nuUc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1598624873098339.0909357717902; Fri, 28 Aug 2020 07:27:53 -0700 (PDT) Received: from localhost ([::1]:60230 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kBfM8-0007ck-6t for importer@patchew.org; Fri, 28 Aug 2020 10:27:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51216) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kBfEf-0000eA-Bf for qemu-devel@nongnu.org; Fri, 28 Aug 2020 10:20:09 -0400 Received: from mail-pf1-x441.google.com ([2607:f8b0:4864:20::441]:42409) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kBfEc-00057J-Na for qemu-devel@nongnu.org; Fri, 28 Aug 2020 10:20:09 -0400 Received: by mail-pf1-x441.google.com with SMTP id 17so729988pfw.9 for ; Fri, 28 Aug 2020 07:20:06 -0700 (PDT) Received: from localhost.localdomain ([71.212.141.89]) by smtp.gmail.com with ESMTPSA id j3sm1403080pjw.23.2020.08.28.07.20.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 Aug 2020 07:20:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tvav2yDgl091Kla7AxGkIifdrAi1yowT9YLtoH5uMlM=; b=c7bxIiv55uJTvV7CM3S2ERtZ6aPNhVq4Z0OLfFhAKSlx5dnzd/6p7Tkk2GaUJWYVV7 hSPAO0gdAa6oTbnW+QhUw/TDWrsMmiPRdWjtMApxvejOZ0jlE0h9Itt52acYpIacaMR7 7NUSwxxnsOx1+ScErVMJ+jTWw7/oQCoW6Gx3lzqf5ek8apX8aEdM3waqJDMVpnFLg+Mt ofbo7Advl6BYzQLf3sb94G61JX6QM5Xcuq8bB9xNaLg88JhYA4267fcERck/AmP58gVS qapZ+M76ge9nLTIHSlO3YaM6DQkIbpXNZIhVbXUXA9p013dAGFythezqt9LYTZTtB/ly xC8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tvav2yDgl091Kla7AxGkIifdrAi1yowT9YLtoH5uMlM=; b=YUjd+TK37pyhFkaMpN4e8CTIrSeTCj/CqfVvuAa1vXWhFaOgu+qmESuGxpUHZAf0WU 4vJgI0xeOQ0AJoDImx3CdzvQN+OIg8IzdnEIhJ0tuvb3+a5WMZs18igTNLwNS0NBfpou SX2kZ12ihUMEK56j9O+TgvyLkCt2mo+qEThgKEFqIomjZ2GOGScRI9itxOA4MOuG4iS4 LCFtdUZ/GPUUn7aylMHLFqcdkTbhgdy2dC2u5bDr1lqCbgyXg8WskWYNthwXjcjiIEob 17BNmKGycGPumLvL48Mw/QszwdCGJw05amQr2kEJmeWFQGEiiuf0PzaKhcHgTYXZ3PBB vhAw== X-Gm-Message-State: AOAM5330zQQo5nIpHxCzjTc3CYM5p8EWiSNpkLbi2j0GgC4rJHR6G04F 4UHjzh5diKldBgOGek4fMvNysNTeSa/LmQ== X-Google-Smtp-Source: ABdhPJz45Q5AGu1osyZMyAxml+YBRSIeLRe3jMa/Ph0Jm+hIg8p+cetQ2RrXFdGD/03VhayVff2nzA== X-Received: by 2002:a05:6a00:1688:: with SMTP id k8mr1414318pfc.33.1598624404483; Fri, 28 Aug 2020 07:20:04 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v2 25/76] target/microblaze: Split out MSR[C] to its own variable Date: Fri, 28 Aug 2020 07:18:38 -0700 Message-Id: <20200828141929.77854-26-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200828141929.77854-1-richard.henderson@linaro.org> References: <20200828141929.77854-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::441; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x441.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Having the MSR[C] bit separate will improve arithmetic that operates on the carry bit. Having mb_cpu_read_msr() populate MSR[CC] will prevent the carry copy not matching the carry bit. Signed-off-by: Richard Henderson --- target/microblaze/cpu.h | 19 +++++++- linux-user/elfload.c | 2 +- target/microblaze/cpu.c | 4 +- target/microblaze/gdbstub.c | 4 +- target/microblaze/helper.c | 58 +++++++++++----------- target/microblaze/translate.c | 91 +++++++++++------------------------ 6 files changed, 82 insertions(+), 96 deletions(-) diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index 7708c9a3d3..7066878ac7 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -236,7 +236,8 @@ struct CPUMBState { uint32_t imm; uint32_t regs[32]; uint32_t pc; - uint32_t msr; + uint32_t msr; /* All bits of MSR except MSR[C] and MSR[CC] */ + uint32_t msr_c; /* MSR[C], in low bit; other bits must be 0 */ uint64_t ear; uint32_t esr; uint32_t fsr; @@ -327,6 +328,22 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr= addr); int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); =20 +static inline uint32_t mb_cpu_read_msr(const CPUMBState *env) +{ + /* Replicate MSR[C] to MSR[CC]. */ + return env->msr | (env->msr_c * (MSR_C | MSR_CC)); +} + +static inline void mb_cpu_write_msr(CPUMBState *env, uint32_t val) +{ + env->msr_c =3D (val >> 2) & 1; + /* + * Clear both MSR[C] and MSR[CC] from the saved copy. + * MSR_PVR is not writable and is always clear. + */ + env->msr =3D val & ~(MSR_C | MSR_CC | MSR_PVR); +} + void mb_tcg_init(void); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero diff --git a/linux-user/elfload.c b/linux-user/elfload.c index bbfb665321..98af4fe7e0 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1033,7 +1033,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *= regs, const CPUMBState *env } =20 (*regs)[pos++] =3D tswapreg(env->pc); - (*regs)[pos++] =3D tswapreg(env->msr); + (*regs)[pos++] =3D tswapreg(mb_cpu_read_msr(env)); (*regs)[pos++] =3D 0; (*regs)[pos++] =3D tswapreg(env->ear); (*regs)[pos++] =3D 0; diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index 0eac068570..1eabf5cc3f 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -121,9 +121,9 @@ static void mb_cpu_reset(DeviceState *dev) =20 #if defined(CONFIG_USER_ONLY) /* start in user mode with interrupts enabled. */ - env->msr =3D MSR_EE | MSR_IE | MSR_VM | MSR_UM; + mb_cpu_write_msr(env, MSR_EE | MSR_IE | MSR_VM | MSR_UM); #else - env->msr =3D 0; + mb_cpu_write_msr(env, 0); mmu_init(&env->mmu); env->mmu.c_mmu =3D 3; env->mmu.c_mmu_tlb_access =3D 3; diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c index 9cba9d2215..08d6a0e807 100644 --- a/target/microblaze/gdbstub.c +++ b/target/microblaze/gdbstub.c @@ -62,7 +62,7 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *me= m_buf, int n) val =3D env->pc; break; case GDB_MSR: - val =3D env->msr; + val =3D mb_cpu_read_msr(env); break; case GDB_EAR: val =3D env->ear; @@ -118,7 +118,7 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *me= m_buf, int n) env->pc =3D tmp; break; case GDB_MSR: - env->msr =3D tmp; + mb_cpu_write_msr(env, tmp); break; case GDB_EAR: env->ear =3D tmp; diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c index b2373f6a23..9a95456401 100644 --- a/target/microblaze/helper.c +++ b/target/microblaze/helper.c @@ -112,12 +112,11 @@ void mb_cpu_do_interrupt(CPUState *cs) { MicroBlazeCPU *cpu =3D MICROBLAZE_CPU(cs); CPUMBState *env =3D &cpu->env; - uint32_t t; + uint32_t t, msr =3D mb_cpu_read_msr(env); =20 /* IMM flag cannot propagate across a branch and into the dslot. */ assert(!((env->iflags & D_FLAG) && (env->iflags & IMM_FLAG))); assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG))); -/* assert(env->msr & (MSR_EE)); Only for HW exceptions. */ env->res_addr =3D RES_ADDR_NONE; switch (cs->exception_index) { case EXCP_HW_EXCP: @@ -136,11 +135,12 @@ void mb_cpu_do_interrupt(CPUState *cs) } =20 /* Disable the MMU. */ - t =3D (env->msr & (MSR_VM | MSR_UM)) << 1; - env->msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM); - env->msr |=3D t; + t =3D (msr & (MSR_VM | MSR_UM)) << 1; + msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM); + msr |=3D t; /* Exception in progress. */ - env->msr |=3D MSR_EIP; + msr |=3D MSR_EIP; + mb_cpu_write_msr(env, msr); =20 qemu_log_mask(CPU_LOG_INT, "hw exception at pc=3D%x ear=3D%" PRIx64 " " @@ -178,11 +178,12 @@ void mb_cpu_do_interrupt(CPUState *cs) } =20 /* Disable the MMU. */ - t =3D (env->msr & (MSR_VM | MSR_UM)) << 1; - env->msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM); - env->msr |=3D t; + t =3D (msr & (MSR_VM | MSR_UM)) << 1; + msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM); + msr |=3D t; /* Exception in progress. */ - env->msr |=3D MSR_EIP; + msr |=3D MSR_EIP; + mb_cpu_write_msr(env, msr); =20 qemu_log_mask(CPU_LOG_INT, "exception at pc=3D%x ear=3D%" PRIx64 " iflags= =3D%x\n", @@ -193,11 +194,11 @@ void mb_cpu_do_interrupt(CPUState *cs) break; =20 case EXCP_IRQ: - assert(!(env->msr & (MSR_EIP | MSR_BIP))); - assert(env->msr & MSR_IE); + assert(!(msr & (MSR_EIP | MSR_BIP))); + assert(msr & MSR_IE); assert(!(env->iflags & D_FLAG)); =20 - t =3D (env->msr & (MSR_VM | MSR_UM)) << 1; + t =3D (msr & (MSR_VM | MSR_UM)) << 1; =20 #if 0 #include "disas/disas.h" @@ -212,21 +213,20 @@ void mb_cpu_do_interrupt(CPUState *cs) && (!strcmp("netif_rx", sym) || !strcmp("process_backlog", sym))) { =20 - qemu_log( - "interrupt at pc=3D%x msr=3D%x %x iflags=3D%x sym= =3D%s\n", - env->pc, env->msr, t, env->iflags, - sym); + qemu_log("interrupt at pc=3D%x msr=3D%x %x iflags=3D%x= sym=3D%s\n", + env->pc, msr, t, env->iflags, sym); =20 log_cpu_state(cs, 0); } } #endif qemu_log_mask(CPU_LOG_INT, - "interrupt at pc=3D%x msr=3D%x %x iflags=3D%x\n", - env->pc, env->msr, t, env->iflags); + "interrupt at pc=3D%x msr=3D%x %x iflags=3D%x\n", + env->pc, msr, t, env->iflags); =20 - env->msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE); - env->msr |=3D t; + msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM | MSR_IE); + msr |=3D t; + mb_cpu_write_msr(env, msr); =20 env->regs[14] =3D env->pc; env->pc =3D cpu->cfg.base_vectors + 0x10; @@ -237,20 +237,22 @@ void mb_cpu_do_interrupt(CPUState *cs) case EXCP_HW_BREAK: assert(!(env->iflags & IMM_FLAG)); assert(!(env->iflags & D_FLAG)); - t =3D (env->msr & (MSR_VM | MSR_UM)) << 1; + t =3D (msr & (MSR_VM | MSR_UM)) << 1; qemu_log_mask(CPU_LOG_INT, "break at pc=3D%x msr=3D%x %x iflags=3D%x\n", - env->pc, env->msr, t, env->iflags); + env->pc, msr, t, env->iflags); log_cpu_state_mask(CPU_LOG_INT, cs, 0); - env->msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM); - env->msr |=3D t; - env->msr |=3D MSR_BIP; + msr &=3D ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM); + msr |=3D t; + msr |=3D MSR_BIP; if (cs->exception_index =3D=3D EXCP_HW_BREAK) { env->regs[16] =3D env->pc; - env->msr |=3D MSR_BIP; + msr |=3D MSR_BIP; env->pc =3D cpu->cfg.base_vectors + 0x18; - } else + } else { env->pc =3D env->btarget; + } + mb_cpu_write_msr(env, msr); break; default: cpu_abort(cs, "unhandled exception type=3D%d\n", diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index e709884f2d..0c9b4ffa5a 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -56,6 +56,7 @@ static TCGv_i32 cpu_R[32]; static TCGv_i32 cpu_pc; static TCGv_i32 cpu_msr; +static TCGv_i32 cpu_msr_c; static TCGv_i32 cpu_imm; static TCGv_i32 cpu_btaken; static TCGv_i32 cpu_btarget; @@ -150,30 +151,6 @@ static void gen_goto_tb(DisasContext *dc, int n, targe= t_ulong dest) } } =20 -static void read_carry(DisasContext *dc, TCGv_i32 d) -{ - tcg_gen_shri_i32(d, cpu_msr, 31); -} - -/* - * write_carry sets the carry bits in MSR based on bit 0 of v. - * v[31:1] are ignored. - */ -static void write_carry(DisasContext *dc, TCGv_i32 v) -{ - /* Deposit bit 0 into MSR_C and the alias MSR_CC. */ - tcg_gen_deposit_i32(cpu_msr, cpu_msr, v, 2, 1); - tcg_gen_deposit_i32(cpu_msr, cpu_msr, v, 31, 1); -} - -static void write_carryi(DisasContext *dc, bool carry) -{ - TCGv_i32 t0 =3D tcg_temp_new_i32(); - tcg_gen_movi_i32(t0, carry); - write_carry(dc, t0); - tcg_temp_free_i32(t0); -} - /* * Returns true if the insn an illegal operation. * If exceptions are enabled, an exception is raised. @@ -243,11 +220,7 @@ static void dec_add(DisasContext *dc) =20 if (c) { /* c - Add carry into the result. */ - cf =3D tcg_temp_new_i32(); - - read_carry(dc, cf); - tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf); - tcg_temp_free_i32(cf); + tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_msr_c); } } return; @@ -257,21 +230,15 @@ static void dec_add(DisasContext *dc) /* Extract carry. */ cf =3D tcg_temp_new_i32(); if (c) { - read_carry(dc, cf); + tcg_gen_mov_i32(cf, cpu_msr_c); } else { tcg_gen_movi_i32(cf, 0); } =20 + gen_helper_carry(cpu_msr_c, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf); if (dc->rd) { - TCGv_i32 ncf =3D tcg_temp_new_i32(); - gen_helper_carry(ncf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf); tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf); - write_carry(dc, ncf); - tcg_temp_free_i32(ncf); - } else { - gen_helper_carry(cf, cpu_R[dc->ra], *(dec_alu_op_b(dc)), cf); - write_carry(dc, cf); } tcg_temp_free_i32(cf); } @@ -309,11 +276,7 @@ static void dec_sub(DisasContext *dc) =20 if (c) { /* c - Add carry into the result. */ - cf =3D tcg_temp_new_i32(); - - read_carry(dc, cf); - tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf); - tcg_temp_free_i32(cf); + tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_msr_c); } } return; @@ -324,7 +287,7 @@ static void dec_sub(DisasContext *dc) cf =3D tcg_temp_new_i32(); na =3D tcg_temp_new_i32(); if (c) { - read_carry(dc, cf); + tcg_gen_mov_i32(cf, cpu_msr_c); } else { tcg_gen_movi_i32(cf, 1); } @@ -332,16 +295,10 @@ static void dec_sub(DisasContext *dc) /* d =3D b + ~a + c. carry defaults to 1. */ tcg_gen_not_i32(na, cpu_R[dc->ra]); =20 + gen_helper_carry(cpu_msr_c, na, *(dec_alu_op_b(dc)), cf); if (dc->rd) { - TCGv_i32 ncf =3D tcg_temp_new_i32(); - gen_helper_carry(ncf, na, *(dec_alu_op_b(dc)), cf); tcg_gen_add_i32(cpu_R[dc->rd], na, *(dec_alu_op_b(dc))); tcg_gen_add_i32(cpu_R[dc->rd], cpu_R[dc->rd], cf); - write_carry(dc, ncf); - tcg_temp_free_i32(ncf); - } else { - gen_helper_carry(cf, na, *(dec_alu_op_b(dc)), cf); - write_carry(dc, cf); } tcg_temp_free_i32(cf); tcg_temp_free_i32(na); @@ -429,16 +386,26 @@ static void dec_xor(DisasContext *dc) tcg_gen_xor_i32(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); } =20 -static inline void msr_read(DisasContext *dc, TCGv_i32 d) +static void msr_read(DisasContext *dc, TCGv_i32 d) { - tcg_gen_mov_i32(d, cpu_msr); + TCGv_i32 t; + + /* Replicate the cpu_msr_c boolean into the proper bit and the copy. */ + t =3D tcg_temp_new_i32(); + tcg_gen_muli_i32(t, cpu_msr_c, MSR_C | MSR_CC); + tcg_gen_or_i32(d, cpu_msr, t); + tcg_temp_free_i32(t); } =20 -static inline void msr_write(DisasContext *dc, TCGv_i32 v) +static void msr_write(DisasContext *dc, TCGv_i32 v) { dc->cpustate_changed =3D 1; - /* PVR bit is not writable, and is never set. */ - tcg_gen_andi_i32(cpu_msr, v, ~MSR_PVR); + + /* Install MSR_C. */ + tcg_gen_extract_i32(cpu_msr_c, v, 2, 1); + + /* Clear MSR_C and MSR_CC; MSR_PVR is not writable, and is always clea= r. */ + tcg_gen_andi_i32(cpu_msr, v, ~(MSR_C | MSR_CC | MSR_PVR)); } =20 static void dec_msr(DisasContext *dc) @@ -778,8 +745,8 @@ static void dec_bit(DisasContext *dc) t0 =3D tcg_temp_new_i32(); =20 LOG_DIS("src r%d r%d\n", dc->rd, dc->ra); - tcg_gen_andi_i32(t0, cpu_msr, MSR_CC); - write_carry(dc, cpu_R[dc->ra]); + tcg_gen_shli_i32(t0, cpu_msr_c, 31); + tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1); if (dc->rd) { tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1); tcg_gen_or_i32(cpu_R[dc->rd], cpu_R[dc->rd], t0); @@ -792,8 +759,7 @@ static void dec_bit(DisasContext *dc) /* srl. */ LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra); =20 - /* Update carry. Note that write carry only looks at the LSB. = */ - write_carry(dc, cpu_R[dc->ra]); + tcg_gen_andi_i32(cpu_msr_c, cpu_R[dc->ra], 1); if (dc->rd) { if (op =3D=3D 0x41) tcg_gen_shri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 1); @@ -1042,7 +1008,7 @@ static void dec_load(DisasContext *dc) =20 if (ex) { /* lwx */ /* no support for AXI exclusive so always clear C */ - write_carryi(dc, 0); + tcg_gen_movi_i32(cpu_msr_c, 0); } =20 tcg_temp_free(addr); @@ -1093,7 +1059,7 @@ static void dec_store(DisasContext *dc) /* swx does not throw unaligned access errors, so force alignment = */ tcg_gen_andi_tl(addr, addr, ~3); =20 - write_carryi(dc, 1); + tcg_gen_movi_i32(cpu_msr_c, 1); swx_skip =3D gen_new_label(); tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_skip); =20 @@ -1108,7 +1074,7 @@ static void dec_store(DisasContext *dc) mop); =20 tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_skip); - write_carryi(dc, 0); + tcg_gen_movi_i32(cpu_msr_c, 0); tcg_temp_free_i32(tval); } =20 @@ -1851,6 +1817,7 @@ void mb_tcg_init(void) =20 SP(pc), SP(msr), + SP(msr_c), SP(imm), SP(iflags), SP(btaken), --=20 2.25.1