1fcf5ef2aSThomas Huth /* 2fcf5ef2aSThomas Huth * PowerPC memory access emulation helpers for QEMU. 3fcf5ef2aSThomas Huth * 4fcf5ef2aSThomas Huth * Copyright (c) 2003-2007 Jocelyn Mayer 5fcf5ef2aSThomas Huth * 6fcf5ef2aSThomas Huth * This library is free software; you can redistribute it and/or 7fcf5ef2aSThomas Huth * modify it under the terms of the GNU Lesser General Public 8fcf5ef2aSThomas Huth * License as published by the Free Software Foundation; either 9fcf5ef2aSThomas Huth * version 2 of the License, or (at your option) any later version. 10fcf5ef2aSThomas Huth * 11fcf5ef2aSThomas Huth * This library is distributed in the hope that it will be useful, 12fcf5ef2aSThomas Huth * but WITHOUT ANY WARRANTY; without even the implied warranty of 13fcf5ef2aSThomas Huth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14fcf5ef2aSThomas Huth * Lesser General Public License for more details. 15fcf5ef2aSThomas Huth * 16fcf5ef2aSThomas Huth * You should have received a copy of the GNU Lesser General Public 17fcf5ef2aSThomas Huth * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18fcf5ef2aSThomas Huth */ 19fcf5ef2aSThomas Huth #include "qemu/osdep.h" 20fcf5ef2aSThomas Huth #include "cpu.h" 21fcf5ef2aSThomas Huth #include "exec/exec-all.h" 22fcf5ef2aSThomas Huth #include "qemu/host-utils.h" 23fcf5ef2aSThomas Huth #include "exec/helper-proto.h" 24fcf5ef2aSThomas Huth 25fcf5ef2aSThomas Huth #include "helper_regs.h" 26fcf5ef2aSThomas Huth #include "exec/cpu_ldst.h" 27*6914bc4fSNikunj A Dadhania #include "internal.h" 28fcf5ef2aSThomas Huth 29fcf5ef2aSThomas Huth //#define DEBUG_OP 30fcf5ef2aSThomas Huth 31fcf5ef2aSThomas Huth static inline bool needs_byteswap(const CPUPPCState *env) 32fcf5ef2aSThomas Huth { 33fcf5ef2aSThomas Huth #if defined(TARGET_WORDS_BIGENDIAN) 34fcf5ef2aSThomas Huth return msr_le; 35fcf5ef2aSThomas Huth #else 36fcf5ef2aSThomas Huth return !msr_le; 37fcf5ef2aSThomas Huth #endif 38fcf5ef2aSThomas Huth } 39fcf5ef2aSThomas Huth 40fcf5ef2aSThomas Huth /*****************************************************************************/ 41fcf5ef2aSThomas Huth /* Memory load and stores */ 42fcf5ef2aSThomas Huth 43fcf5ef2aSThomas Huth static inline target_ulong addr_add(CPUPPCState *env, target_ulong addr, 44fcf5ef2aSThomas Huth target_long arg) 45fcf5ef2aSThomas Huth { 46fcf5ef2aSThomas Huth #if defined(TARGET_PPC64) 47fcf5ef2aSThomas Huth if (!msr_is_64bit(env, env->msr)) { 48fcf5ef2aSThomas Huth return (uint32_t)(addr + arg); 49fcf5ef2aSThomas Huth } else 50fcf5ef2aSThomas Huth #endif 51fcf5ef2aSThomas Huth { 52fcf5ef2aSThomas Huth return addr + arg; 53fcf5ef2aSThomas Huth } 54fcf5ef2aSThomas Huth } 55fcf5ef2aSThomas Huth 56fcf5ef2aSThomas Huth void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg) 57fcf5ef2aSThomas Huth { 58fcf5ef2aSThomas Huth for (; reg < 32; reg++) { 59fcf5ef2aSThomas Huth if (needs_byteswap(env)) { 60fcf5ef2aSThomas Huth env->gpr[reg] = bswap32(cpu_ldl_data_ra(env, addr, GETPC())); 61fcf5ef2aSThomas Huth } else { 62fcf5ef2aSThomas Huth env->gpr[reg] = cpu_ldl_data_ra(env, addr, GETPC()); 63fcf5ef2aSThomas Huth } 64fcf5ef2aSThomas Huth addr = addr_add(env, addr, 4); 65fcf5ef2aSThomas Huth } 66fcf5ef2aSThomas Huth } 67fcf5ef2aSThomas Huth 68fcf5ef2aSThomas Huth void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg) 69fcf5ef2aSThomas Huth { 70fcf5ef2aSThomas Huth for (; reg < 32; reg++) { 71fcf5ef2aSThomas Huth if (needs_byteswap(env)) { 72fcf5ef2aSThomas Huth cpu_stl_data_ra(env, addr, bswap32((uint32_t)env->gpr[reg]), 73fcf5ef2aSThomas Huth GETPC()); 74fcf5ef2aSThomas Huth } else { 75fcf5ef2aSThomas Huth cpu_stl_data_ra(env, addr, (uint32_t)env->gpr[reg], GETPC()); 76fcf5ef2aSThomas Huth } 77fcf5ef2aSThomas Huth addr = addr_add(env, addr, 4); 78fcf5ef2aSThomas Huth } 79fcf5ef2aSThomas Huth } 80fcf5ef2aSThomas Huth 81fcf5ef2aSThomas Huth static void do_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb, 82fcf5ef2aSThomas Huth uint32_t reg, uintptr_t raddr) 83fcf5ef2aSThomas Huth { 84fcf5ef2aSThomas Huth int sh; 85fcf5ef2aSThomas Huth 86fcf5ef2aSThomas Huth for (; nb > 3; nb -= 4) { 87fcf5ef2aSThomas Huth env->gpr[reg] = cpu_ldl_data_ra(env, addr, raddr); 88fcf5ef2aSThomas Huth reg = (reg + 1) % 32; 89fcf5ef2aSThomas Huth addr = addr_add(env, addr, 4); 90fcf5ef2aSThomas Huth } 91fcf5ef2aSThomas Huth if (unlikely(nb > 0)) { 92fcf5ef2aSThomas Huth env->gpr[reg] = 0; 93fcf5ef2aSThomas Huth for (sh = 24; nb > 0; nb--, sh -= 8) { 94fcf5ef2aSThomas Huth env->gpr[reg] |= cpu_ldub_data_ra(env, addr, raddr) << sh; 95fcf5ef2aSThomas Huth addr = addr_add(env, addr, 1); 96fcf5ef2aSThomas Huth } 97fcf5ef2aSThomas Huth } 98fcf5ef2aSThomas Huth } 99fcf5ef2aSThomas Huth 100fcf5ef2aSThomas Huth void helper_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb, uint32_t reg) 101fcf5ef2aSThomas Huth { 102fcf5ef2aSThomas Huth do_lsw(env, addr, nb, reg, GETPC()); 103fcf5ef2aSThomas Huth } 104fcf5ef2aSThomas Huth 105fcf5ef2aSThomas Huth /* PPC32 specification says we must generate an exception if 106fcf5ef2aSThomas Huth * rA is in the range of registers to be loaded. 107fcf5ef2aSThomas Huth * In an other hand, IBM says this is valid, but rA won't be loaded. 108fcf5ef2aSThomas Huth * For now, I'll follow the spec... 109fcf5ef2aSThomas Huth */ 110fcf5ef2aSThomas Huth void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg, 111fcf5ef2aSThomas Huth uint32_t ra, uint32_t rb) 112fcf5ef2aSThomas Huth { 113fcf5ef2aSThomas Huth if (likely(xer_bc != 0)) { 114fcf5ef2aSThomas Huth int num_used_regs = (xer_bc + 3) / 4; 115fcf5ef2aSThomas Huth if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) || 116fcf5ef2aSThomas Huth lsw_reg_in_range(reg, num_used_regs, rb))) { 117fcf5ef2aSThomas Huth raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 118fcf5ef2aSThomas Huth POWERPC_EXCP_INVAL | 119fcf5ef2aSThomas Huth POWERPC_EXCP_INVAL_LSWX, GETPC()); 120fcf5ef2aSThomas Huth } else { 121fcf5ef2aSThomas Huth do_lsw(env, addr, xer_bc, reg, GETPC()); 122fcf5ef2aSThomas Huth } 123fcf5ef2aSThomas Huth } 124fcf5ef2aSThomas Huth } 125fcf5ef2aSThomas Huth 126fcf5ef2aSThomas Huth void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb, 127fcf5ef2aSThomas Huth uint32_t reg) 128fcf5ef2aSThomas Huth { 129fcf5ef2aSThomas Huth int sh; 130fcf5ef2aSThomas Huth 131fcf5ef2aSThomas Huth for (; nb > 3; nb -= 4) { 132fcf5ef2aSThomas Huth cpu_stl_data_ra(env, addr, env->gpr[reg], GETPC()); 133fcf5ef2aSThomas Huth reg = (reg + 1) % 32; 134fcf5ef2aSThomas Huth addr = addr_add(env, addr, 4); 135fcf5ef2aSThomas Huth } 136fcf5ef2aSThomas Huth if (unlikely(nb > 0)) { 137fcf5ef2aSThomas Huth for (sh = 24; nb > 0; nb--, sh -= 8) { 138fcf5ef2aSThomas Huth cpu_stb_data_ra(env, addr, (env->gpr[reg] >> sh) & 0xFF, GETPC()); 139fcf5ef2aSThomas Huth addr = addr_add(env, addr, 1); 140fcf5ef2aSThomas Huth } 141fcf5ef2aSThomas Huth } 142fcf5ef2aSThomas Huth } 143fcf5ef2aSThomas Huth 144fcf5ef2aSThomas Huth void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t opcode) 145fcf5ef2aSThomas Huth { 146fcf5ef2aSThomas Huth target_ulong mask, dcbz_size = env->dcache_line_size; 147fcf5ef2aSThomas Huth uint32_t i; 148fcf5ef2aSThomas Huth void *haddr; 149fcf5ef2aSThomas Huth 150fcf5ef2aSThomas Huth #if defined(TARGET_PPC64) 151fcf5ef2aSThomas Huth /* Check for dcbz vs dcbzl on 970 */ 152fcf5ef2aSThomas Huth if (env->excp_model == POWERPC_EXCP_970 && 153fcf5ef2aSThomas Huth !(opcode & 0x00200000) && ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) { 154fcf5ef2aSThomas Huth dcbz_size = 32; 155fcf5ef2aSThomas Huth } 156fcf5ef2aSThomas Huth #endif 157fcf5ef2aSThomas Huth 158fcf5ef2aSThomas Huth /* Align address */ 159fcf5ef2aSThomas Huth mask = ~(dcbz_size - 1); 160fcf5ef2aSThomas Huth addr &= mask; 161fcf5ef2aSThomas Huth 162fcf5ef2aSThomas Huth /* Check reservation */ 163fcf5ef2aSThomas Huth if ((env->reserve_addr & mask) == (addr & mask)) { 164fcf5ef2aSThomas Huth env->reserve_addr = (target_ulong)-1ULL; 165fcf5ef2aSThomas Huth } 166fcf5ef2aSThomas Huth 167fcf5ef2aSThomas Huth /* Try fast path translate */ 168fcf5ef2aSThomas Huth haddr = tlb_vaddr_to_host(env, addr, MMU_DATA_STORE, env->dmmu_idx); 169fcf5ef2aSThomas Huth if (haddr) { 170fcf5ef2aSThomas Huth memset(haddr, 0, dcbz_size); 171fcf5ef2aSThomas Huth } else { 172fcf5ef2aSThomas Huth /* Slow path */ 173fcf5ef2aSThomas Huth for (i = 0; i < dcbz_size; i += 8) { 174fcf5ef2aSThomas Huth cpu_stq_data_ra(env, addr + i, 0, GETPC()); 175fcf5ef2aSThomas Huth } 176fcf5ef2aSThomas Huth } 177fcf5ef2aSThomas Huth } 178fcf5ef2aSThomas Huth 179fcf5ef2aSThomas Huth void helper_icbi(CPUPPCState *env, target_ulong addr) 180fcf5ef2aSThomas Huth { 181fcf5ef2aSThomas Huth addr &= ~(env->dcache_line_size - 1); 182fcf5ef2aSThomas Huth /* Invalidate one cache line : 183fcf5ef2aSThomas Huth * PowerPC specification says this is to be treated like a load 184fcf5ef2aSThomas Huth * (not a fetch) by the MMU. To be sure it will be so, 185fcf5ef2aSThomas Huth * do the load "by hand". 186fcf5ef2aSThomas Huth */ 187fcf5ef2aSThomas Huth cpu_ldl_data_ra(env, addr, GETPC()); 188fcf5ef2aSThomas Huth } 189fcf5ef2aSThomas Huth 190fcf5ef2aSThomas Huth /* XXX: to be tested */ 191fcf5ef2aSThomas Huth target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg, 192fcf5ef2aSThomas Huth uint32_t ra, uint32_t rb) 193fcf5ef2aSThomas Huth { 194fcf5ef2aSThomas Huth int i, c, d; 195fcf5ef2aSThomas Huth 196fcf5ef2aSThomas Huth d = 24; 197fcf5ef2aSThomas Huth for (i = 0; i < xer_bc; i++) { 198fcf5ef2aSThomas Huth c = cpu_ldub_data_ra(env, addr, GETPC()); 199fcf5ef2aSThomas Huth addr = addr_add(env, addr, 1); 200fcf5ef2aSThomas Huth /* ra (if not 0) and rb are never modified */ 201fcf5ef2aSThomas Huth if (likely(reg != rb && (ra == 0 || reg != ra))) { 202fcf5ef2aSThomas Huth env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d); 203fcf5ef2aSThomas Huth } 204fcf5ef2aSThomas Huth if (unlikely(c == xer_cmp)) { 205fcf5ef2aSThomas Huth break; 206fcf5ef2aSThomas Huth } 207fcf5ef2aSThomas Huth if (likely(d != 0)) { 208fcf5ef2aSThomas Huth d -= 8; 209fcf5ef2aSThomas Huth } else { 210fcf5ef2aSThomas Huth d = 24; 211fcf5ef2aSThomas Huth reg++; 212fcf5ef2aSThomas Huth reg = reg & 0x1F; 213fcf5ef2aSThomas Huth } 214fcf5ef2aSThomas Huth } 215fcf5ef2aSThomas Huth return i; 216fcf5ef2aSThomas Huth } 217fcf5ef2aSThomas Huth 218fcf5ef2aSThomas Huth /*****************************************************************************/ 219fcf5ef2aSThomas Huth /* Altivec extension helpers */ 220fcf5ef2aSThomas Huth #if defined(HOST_WORDS_BIGENDIAN) 221fcf5ef2aSThomas Huth #define HI_IDX 0 222fcf5ef2aSThomas Huth #define LO_IDX 1 223fcf5ef2aSThomas Huth #else 224fcf5ef2aSThomas Huth #define HI_IDX 1 225fcf5ef2aSThomas Huth #define LO_IDX 0 226fcf5ef2aSThomas Huth #endif 227fcf5ef2aSThomas Huth 228fcf5ef2aSThomas Huth /* We use msr_le to determine index ordering in a vector. However, 229fcf5ef2aSThomas Huth byteswapping is not simply controlled by msr_le. We also need to take 230fcf5ef2aSThomas Huth into account endianness of the target. This is done for the little-endian 231fcf5ef2aSThomas Huth PPC64 user-mode target. */ 232fcf5ef2aSThomas Huth 233fcf5ef2aSThomas Huth #define LVE(name, access, swap, element) \ 234fcf5ef2aSThomas Huth void helper_##name(CPUPPCState *env, ppc_avr_t *r, \ 235fcf5ef2aSThomas Huth target_ulong addr) \ 236fcf5ef2aSThomas Huth { \ 237fcf5ef2aSThomas Huth size_t n_elems = ARRAY_SIZE(r->element); \ 238fcf5ef2aSThomas Huth int adjust = HI_IDX*(n_elems - 1); \ 239fcf5ef2aSThomas Huth int sh = sizeof(r->element[0]) >> 1; \ 240fcf5ef2aSThomas Huth int index = (addr & 0xf) >> sh; \ 241fcf5ef2aSThomas Huth if (msr_le) { \ 242fcf5ef2aSThomas Huth index = n_elems - index - 1; \ 243fcf5ef2aSThomas Huth } \ 244fcf5ef2aSThomas Huth \ 245fcf5ef2aSThomas Huth if (needs_byteswap(env)) { \ 246fcf5ef2aSThomas Huth r->element[LO_IDX ? index : (adjust - index)] = \ 247fcf5ef2aSThomas Huth swap(access(env, addr, GETPC())); \ 248fcf5ef2aSThomas Huth } else { \ 249fcf5ef2aSThomas Huth r->element[LO_IDX ? index : (adjust - index)] = \ 250fcf5ef2aSThomas Huth access(env, addr, GETPC()); \ 251fcf5ef2aSThomas Huth } \ 252fcf5ef2aSThomas Huth } 253fcf5ef2aSThomas Huth #define I(x) (x) 254fcf5ef2aSThomas Huth LVE(lvebx, cpu_ldub_data_ra, I, u8) 255fcf5ef2aSThomas Huth LVE(lvehx, cpu_lduw_data_ra, bswap16, u16) 256fcf5ef2aSThomas Huth LVE(lvewx, cpu_ldl_data_ra, bswap32, u32) 257fcf5ef2aSThomas Huth #undef I 258fcf5ef2aSThomas Huth #undef LVE 259fcf5ef2aSThomas Huth 260fcf5ef2aSThomas Huth #define STVE(name, access, swap, element) \ 261fcf5ef2aSThomas Huth void helper_##name(CPUPPCState *env, ppc_avr_t *r, \ 262fcf5ef2aSThomas Huth target_ulong addr) \ 263fcf5ef2aSThomas Huth { \ 264fcf5ef2aSThomas Huth size_t n_elems = ARRAY_SIZE(r->element); \ 265fcf5ef2aSThomas Huth int adjust = HI_IDX * (n_elems - 1); \ 266fcf5ef2aSThomas Huth int sh = sizeof(r->element[0]) >> 1; \ 267fcf5ef2aSThomas Huth int index = (addr & 0xf) >> sh; \ 268fcf5ef2aSThomas Huth if (msr_le) { \ 269fcf5ef2aSThomas Huth index = n_elems - index - 1; \ 270fcf5ef2aSThomas Huth } \ 271fcf5ef2aSThomas Huth \ 272fcf5ef2aSThomas Huth if (needs_byteswap(env)) { \ 273fcf5ef2aSThomas Huth access(env, addr, swap(r->element[LO_IDX ? index : \ 274fcf5ef2aSThomas Huth (adjust - index)]), \ 275fcf5ef2aSThomas Huth GETPC()); \ 276fcf5ef2aSThomas Huth } else { \ 277fcf5ef2aSThomas Huth access(env, addr, r->element[LO_IDX ? index : \ 278fcf5ef2aSThomas Huth (adjust - index)], GETPC()); \ 279fcf5ef2aSThomas Huth } \ 280fcf5ef2aSThomas Huth } 281fcf5ef2aSThomas Huth #define I(x) (x) 282fcf5ef2aSThomas Huth STVE(stvebx, cpu_stb_data_ra, I, u8) 283fcf5ef2aSThomas Huth STVE(stvehx, cpu_stw_data_ra, bswap16, u16) 284fcf5ef2aSThomas Huth STVE(stvewx, cpu_stl_data_ra, bswap32, u32) 285fcf5ef2aSThomas Huth #undef I 286fcf5ef2aSThomas Huth #undef LVE 287fcf5ef2aSThomas Huth 288*6914bc4fSNikunj A Dadhania #ifdef TARGET_PPC64 289*6914bc4fSNikunj A Dadhania #define GET_NB(rb) ((rb >> 56) & 0xFF) 290*6914bc4fSNikunj A Dadhania 291*6914bc4fSNikunj A Dadhania #define VSX_LXVL(name, lj) \ 292*6914bc4fSNikunj A Dadhania void helper_##name(CPUPPCState *env, target_ulong addr, \ 293*6914bc4fSNikunj A Dadhania target_ulong xt_num, target_ulong rb) \ 294*6914bc4fSNikunj A Dadhania { \ 295*6914bc4fSNikunj A Dadhania int i; \ 296*6914bc4fSNikunj A Dadhania ppc_vsr_t xt; \ 297*6914bc4fSNikunj A Dadhania uint64_t nb = GET_NB(rb); \ 298*6914bc4fSNikunj A Dadhania \ 299*6914bc4fSNikunj A Dadhania xt.s128 = int128_zero(); \ 300*6914bc4fSNikunj A Dadhania if (nb) { \ 301*6914bc4fSNikunj A Dadhania nb = (nb >= 16) ? 16 : nb; \ 302*6914bc4fSNikunj A Dadhania if (msr_le && !lj) { \ 303*6914bc4fSNikunj A Dadhania for (i = 16; i > 16 - nb; i--) { \ 304*6914bc4fSNikunj A Dadhania xt.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC()); \ 305*6914bc4fSNikunj A Dadhania addr = addr_add(env, addr, 1); \ 306*6914bc4fSNikunj A Dadhania } \ 307*6914bc4fSNikunj A Dadhania } else { \ 308*6914bc4fSNikunj A Dadhania for (i = 0; i < nb; i++) { \ 309*6914bc4fSNikunj A Dadhania xt.VsrB(i) = cpu_ldub_data_ra(env, addr, GETPC()); \ 310*6914bc4fSNikunj A Dadhania addr = addr_add(env, addr, 1); \ 311*6914bc4fSNikunj A Dadhania } \ 312*6914bc4fSNikunj A Dadhania } \ 313*6914bc4fSNikunj A Dadhania } \ 314*6914bc4fSNikunj A Dadhania putVSR(xt_num, &xt, env); \ 315*6914bc4fSNikunj A Dadhania } 316*6914bc4fSNikunj A Dadhania 317*6914bc4fSNikunj A Dadhania VSX_LXVL(lxvl, 0) 318*6914bc4fSNikunj A Dadhania #undef VSX_LXVL 319*6914bc4fSNikunj A Dadhania #undef GET_NB 320*6914bc4fSNikunj A Dadhania #endif /* TARGET_PPC64 */ 321*6914bc4fSNikunj A Dadhania 322fcf5ef2aSThomas Huth #undef HI_IDX 323fcf5ef2aSThomas Huth #undef LO_IDX 324fcf5ef2aSThomas Huth 325fcf5ef2aSThomas Huth void helper_tbegin(CPUPPCState *env) 326fcf5ef2aSThomas Huth { 327fcf5ef2aSThomas Huth /* As a degenerate implementation, always fail tbegin. The reason 328fcf5ef2aSThomas Huth * given is "Nesting overflow". The "persistent" bit is set, 329fcf5ef2aSThomas Huth * providing a hint to the error handler to not retry. The TFIAR 330fcf5ef2aSThomas Huth * captures the address of the failure, which is this tbegin 331fcf5ef2aSThomas Huth * instruction. Instruction execution will continue with the 332fcf5ef2aSThomas Huth * next instruction in memory, which is precisely what we want. 333fcf5ef2aSThomas Huth */ 334fcf5ef2aSThomas Huth 335fcf5ef2aSThomas Huth env->spr[SPR_TEXASR] = 336fcf5ef2aSThomas Huth (1ULL << TEXASR_FAILURE_PERSISTENT) | 337fcf5ef2aSThomas Huth (1ULL << TEXASR_NESTING_OVERFLOW) | 338fcf5ef2aSThomas Huth (msr_hv << TEXASR_PRIVILEGE_HV) | 339fcf5ef2aSThomas Huth (msr_pr << TEXASR_PRIVILEGE_PR) | 340fcf5ef2aSThomas Huth (1ULL << TEXASR_FAILURE_SUMMARY) | 341fcf5ef2aSThomas Huth (1ULL << TEXASR_TFIAR_EXACT); 342fcf5ef2aSThomas Huth env->spr[SPR_TFIAR] = env->nip | (msr_hv << 1) | msr_pr; 343fcf5ef2aSThomas Huth env->spr[SPR_TFHAR] = env->nip + 4; 344fcf5ef2aSThomas Huth env->crf[0] = 0xB; /* 0b1010 = transaction failure */ 345fcf5ef2aSThomas Huth } 346