14acb54baSEdgar E. Iglesias /* 24acb54baSEdgar E. Iglesias * Microblaze helper routines. 34acb54baSEdgar E. Iglesias * 44acb54baSEdgar E. Iglesias * Copyright (c) 2009 Edgar E. Iglesias <edgar.iglesias@gmail.com>. 5dadc1064SPeter A. G. Crosthwaite * Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd. 64acb54baSEdgar E. Iglesias * 74acb54baSEdgar E. Iglesias * This library is free software; you can redistribute it and/or 84acb54baSEdgar E. Iglesias * modify it under the terms of the GNU Lesser General Public 94acb54baSEdgar E. Iglesias * License as published by the Free Software Foundation; either 10ee452036SChetan Pant * version 2.1 of the License, or (at your option) any later version. 114acb54baSEdgar E. Iglesias * 124acb54baSEdgar E. Iglesias * This library is distributed in the hope that it will be useful, 134acb54baSEdgar E. Iglesias * but WITHOUT ANY WARRANTY; without even the implied warranty of 144acb54baSEdgar E. Iglesias * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 154acb54baSEdgar E. Iglesias * Lesser General Public License for more details. 164acb54baSEdgar E. Iglesias * 174acb54baSEdgar E. Iglesias * You should have received a copy of the GNU Lesser General Public 188167ee88SBlue Swirl * License along with this library; if not, see <http://www.gnu.org/licenses/>. 194acb54baSEdgar E. Iglesias */ 204acb54baSEdgar E. Iglesias 218fd9deceSPeter Maydell #include "qemu/osdep.h" 22cd617484SPhilippe Mathieu-Daudé #include "qemu/log.h" 233e457172SBlue Swirl #include "cpu.h" 242ef6175aSRichard Henderson #include "exec/helper-proto.h" 251de7afc9SPaolo Bonzini #include "qemu/host-utils.h" 2663c91552SPaolo Bonzini #include "exec/exec-all.h" 27*42fa9665SPhilippe Mathieu-Daudé #include "accel/tcg/cpu-ldst.h" 2824f91e81SAlex Bennée #include "fpu/softfloat.h" 294acb54baSEdgar E. Iglesias 306d76d23eSEdgar E. Iglesias void helper_put(uint32_t id, uint32_t ctrl, uint32_t data) 316d76d23eSEdgar E. Iglesias { 326d76d23eSEdgar E. Iglesias int test = ctrl & STREAM_TEST; 336d76d23eSEdgar E. Iglesias int atomic = ctrl & STREAM_ATOMIC; 346d76d23eSEdgar E. Iglesias int control = ctrl & STREAM_CONTROL; 356d76d23eSEdgar E. Iglesias int nonblock = ctrl & STREAM_NONBLOCK; 366d76d23eSEdgar E. Iglesias int exception = ctrl & STREAM_EXCEPTION; 376d76d23eSEdgar E. Iglesias 381d512a65SPaolo Bonzini qemu_log_mask(LOG_UNIMP, "Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n", 396d76d23eSEdgar E. Iglesias id, data, 406d76d23eSEdgar E. Iglesias test ? "t" : "", 416d76d23eSEdgar E. Iglesias nonblock ? "n" : "", 426d76d23eSEdgar E. Iglesias exception ? "e" : "", 436d76d23eSEdgar E. Iglesias control ? "c" : "", 446d76d23eSEdgar E. Iglesias atomic ? "a" : ""); 456d76d23eSEdgar E. Iglesias } 466d76d23eSEdgar E. Iglesias 476d76d23eSEdgar E. Iglesias uint32_t helper_get(uint32_t id, uint32_t ctrl) 486d76d23eSEdgar E. Iglesias { 496d76d23eSEdgar E. Iglesias int test = ctrl & STREAM_TEST; 506d76d23eSEdgar E. Iglesias int atomic = ctrl & STREAM_ATOMIC; 516d76d23eSEdgar E. Iglesias int control = ctrl & STREAM_CONTROL; 526d76d23eSEdgar E. Iglesias int nonblock = ctrl & STREAM_NONBLOCK; 536d76d23eSEdgar E. Iglesias int exception = ctrl & STREAM_EXCEPTION; 546d76d23eSEdgar E. Iglesias 551d512a65SPaolo Bonzini qemu_log_mask(LOG_UNIMP, "Unhandled stream get from stream-id=%d %s%s%s%s%s\n", 566d76d23eSEdgar E. Iglesias id, 576d76d23eSEdgar E. Iglesias test ? "t" : "", 586d76d23eSEdgar E. Iglesias nonblock ? "n" : "", 596d76d23eSEdgar E. Iglesias exception ? "e" : "", 606d76d23eSEdgar E. Iglesias control ? "c" : "", 616d76d23eSEdgar E. Iglesias atomic ? "a" : ""); 626d76d23eSEdgar E. Iglesias return 0xdead0000 | id; 636d76d23eSEdgar E. Iglesias } 646d76d23eSEdgar E. Iglesias 6564254ebaSBlue Swirl void helper_raise_exception(CPUMBState *env, uint32_t index) 664acb54baSEdgar E. Iglesias { 67f5c7e93aSRichard Henderson CPUState *cs = env_cpu(env); 6827103424SAndreas Färber 6927103424SAndreas Färber cs->exception_index = index; 705638d180SAndreas Färber cpu_loop_exit(cs); 714acb54baSEdgar E. Iglesias } 724acb54baSEdgar E. Iglesias 73e98651d9SRichard Henderson static bool check_divz(CPUMBState *env, uint32_t a, uint32_t b, uintptr_t ra) 744acb54baSEdgar E. Iglesias { 75e98651d9SRichard Henderson if (unlikely(b == 0)) { 762e5282caSRichard Henderson env->msr |= MSR_DZ; 77821ebb33SEdgar E. Iglesias 78e98651d9SRichard Henderson if ((env->msr & MSR_EE) && 79e98651d9SRichard Henderson env_archcpu(env)->cfg.div_zero_exception) { 80e98651d9SRichard Henderson CPUState *cs = env_cpu(env); 81e98651d9SRichard Henderson 8278e9caf2SRichard Henderson env->esr = ESR_EC_DIVZERO; 83e98651d9SRichard Henderson cs->exception_index = EXCP_HW_EXCP; 84e98651d9SRichard Henderson cpu_loop_exit_restore(cs, ra); 85821ebb33SEdgar E. Iglesias } 86e98651d9SRichard Henderson return false; 874acb54baSEdgar E. Iglesias } 88e98651d9SRichard Henderson return true; 894acb54baSEdgar E. Iglesias } 904acb54baSEdgar E. Iglesias 9164254ebaSBlue Swirl uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b) 924acb54baSEdgar E. Iglesias { 93e98651d9SRichard Henderson if (!check_divz(env, a, b, GETPC())) { 944acb54baSEdgar E. Iglesias return 0; 9564254ebaSBlue Swirl } 964acb54baSEdgar E. Iglesias return (int32_t)a / (int32_t)b; 974acb54baSEdgar E. Iglesias } 984acb54baSEdgar E. Iglesias 9964254ebaSBlue Swirl uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b) 1004acb54baSEdgar E. Iglesias { 101e98651d9SRichard Henderson if (!check_divz(env, a, b, GETPC())) { 1024acb54baSEdgar E. Iglesias return 0; 10364254ebaSBlue Swirl } 1044acb54baSEdgar E. Iglesias return a / b; 1054acb54baSEdgar E. Iglesias } 1064acb54baSEdgar E. Iglesias 10797694c57SEdgar E. Iglesias /* raise FPU exception. */ 1087bca6ddfSRichard Henderson static void raise_fpu_exception(CPUMBState *env, uintptr_t ra) 10997694c57SEdgar E. Iglesias { 1107bca6ddfSRichard Henderson CPUState *cs = env_cpu(env); 1117bca6ddfSRichard Henderson 11278e9caf2SRichard Henderson env->esr = ESR_EC_FPU; 1137bca6ddfSRichard Henderson cs->exception_index = EXCP_HW_EXCP; 1147bca6ddfSRichard Henderson cpu_loop_exit_restore(cs, ra); 11597694c57SEdgar E. Iglesias } 11697694c57SEdgar E. Iglesias 1177bca6ddfSRichard Henderson static void update_fpu_flags(CPUMBState *env, int flags, uintptr_t ra) 11897694c57SEdgar E. Iglesias { 11997694c57SEdgar E. Iglesias int raise = 0; 12097694c57SEdgar E. Iglesias 12197694c57SEdgar E. Iglesias if (flags & float_flag_invalid) { 1225a8e0136SRichard Henderson env->fsr |= FSR_IO; 12397694c57SEdgar E. Iglesias raise = 1; 12497694c57SEdgar E. Iglesias } 12597694c57SEdgar E. Iglesias if (flags & float_flag_divbyzero) { 1265a8e0136SRichard Henderson env->fsr |= FSR_DZ; 12797694c57SEdgar E. Iglesias raise = 1; 12897694c57SEdgar E. Iglesias } 12997694c57SEdgar E. Iglesias if (flags & float_flag_overflow) { 1305a8e0136SRichard Henderson env->fsr |= FSR_OF; 13197694c57SEdgar E. Iglesias raise = 1; 13297694c57SEdgar E. Iglesias } 13397694c57SEdgar E. Iglesias if (flags & float_flag_underflow) { 1345a8e0136SRichard Henderson env->fsr |= FSR_UF; 13597694c57SEdgar E. Iglesias raise = 1; 13697694c57SEdgar E. Iglesias } 13797694c57SEdgar E. Iglesias if (raise 138a4bcfc33SRichard Henderson && (env_archcpu(env)->cfg.pvr_regs[2] & PVR2_FPU_EXC_MASK) 1392e5282caSRichard Henderson && (env->msr & MSR_EE)) { 1407bca6ddfSRichard Henderson raise_fpu_exception(env, ra); 14197694c57SEdgar E. Iglesias } 14297694c57SEdgar E. Iglesias } 14397694c57SEdgar E. Iglesias 14464254ebaSBlue Swirl uint32_t helper_fadd(CPUMBState *env, uint32_t a, uint32_t b) 14597694c57SEdgar E. Iglesias { 14697694c57SEdgar E. Iglesias CPU_FloatU fd, fa, fb; 14797694c57SEdgar E. Iglesias int flags; 14897694c57SEdgar E. Iglesias 14997694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 15097694c57SEdgar E. Iglesias fa.l = a; 15197694c57SEdgar E. Iglesias fb.l = b; 15297694c57SEdgar E. Iglesias fd.f = float32_add(fa.f, fb.f, &env->fp_status); 15397694c57SEdgar E. Iglesias 15497694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 1557bca6ddfSRichard Henderson update_fpu_flags(env, flags, GETPC()); 15697694c57SEdgar E. Iglesias return fd.l; 15797694c57SEdgar E. Iglesias } 15897694c57SEdgar E. Iglesias 15964254ebaSBlue Swirl uint32_t helper_frsub(CPUMBState *env, uint32_t a, uint32_t b) 16097694c57SEdgar E. Iglesias { 16197694c57SEdgar E. Iglesias CPU_FloatU fd, fa, fb; 16297694c57SEdgar E. Iglesias int flags; 16397694c57SEdgar E. Iglesias 16497694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 16597694c57SEdgar E. Iglesias fa.l = a; 16697694c57SEdgar E. Iglesias fb.l = b; 16797694c57SEdgar E. Iglesias fd.f = float32_sub(fb.f, fa.f, &env->fp_status); 16897694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 1697bca6ddfSRichard Henderson update_fpu_flags(env, flags, GETPC()); 17097694c57SEdgar E. Iglesias return fd.l; 17197694c57SEdgar E. Iglesias } 17297694c57SEdgar E. Iglesias 17364254ebaSBlue Swirl uint32_t helper_fmul(CPUMBState *env, uint32_t a, uint32_t b) 17497694c57SEdgar E. Iglesias { 17597694c57SEdgar E. Iglesias CPU_FloatU fd, fa, fb; 17697694c57SEdgar E. Iglesias int flags; 17797694c57SEdgar E. Iglesias 17897694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 17997694c57SEdgar E. Iglesias fa.l = a; 18097694c57SEdgar E. Iglesias fb.l = b; 18197694c57SEdgar E. Iglesias fd.f = float32_mul(fa.f, fb.f, &env->fp_status); 18297694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 1837bca6ddfSRichard Henderson update_fpu_flags(env, flags, GETPC()); 18497694c57SEdgar E. Iglesias 18597694c57SEdgar E. Iglesias return fd.l; 18697694c57SEdgar E. Iglesias } 18797694c57SEdgar E. Iglesias 18864254ebaSBlue Swirl uint32_t helper_fdiv(CPUMBState *env, uint32_t a, uint32_t b) 18997694c57SEdgar E. Iglesias { 19097694c57SEdgar E. Iglesias CPU_FloatU fd, fa, fb; 19197694c57SEdgar E. Iglesias int flags; 19297694c57SEdgar E. Iglesias 19397694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 19497694c57SEdgar E. Iglesias fa.l = a; 19597694c57SEdgar E. Iglesias fb.l = b; 19697694c57SEdgar E. Iglesias fd.f = float32_div(fb.f, fa.f, &env->fp_status); 19797694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 1987bca6ddfSRichard Henderson update_fpu_flags(env, flags, GETPC()); 19997694c57SEdgar E. Iglesias 20097694c57SEdgar E. Iglesias return fd.l; 20197694c57SEdgar E. Iglesias } 20297694c57SEdgar E. Iglesias 20364254ebaSBlue Swirl uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a, uint32_t b) 20497694c57SEdgar E. Iglesias { 205ef9d48daSEdgar E. Iglesias CPU_FloatU fa, fb; 206ef9d48daSEdgar E. Iglesias uint32_t r = 0; 207ef9d48daSEdgar E. Iglesias 208ef9d48daSEdgar E. Iglesias fa.l = a; 209ef9d48daSEdgar E. Iglesias fb.l = b; 210ef9d48daSEdgar E. Iglesias 211af39bc8cSAleksandar Markovic if (float32_is_signaling_nan(fa.f, &env->fp_status) || 212af39bc8cSAleksandar Markovic float32_is_signaling_nan(fb.f, &env->fp_status)) { 2137bca6ddfSRichard Henderson update_fpu_flags(env, float_flag_invalid, GETPC()); 214ef9d48daSEdgar E. Iglesias r = 1; 215ef9d48daSEdgar E. Iglesias } 216ef9d48daSEdgar E. Iglesias 217af39bc8cSAleksandar Markovic if (float32_is_quiet_nan(fa.f, &env->fp_status) || 218af39bc8cSAleksandar Markovic float32_is_quiet_nan(fb.f, &env->fp_status)) { 219ef9d48daSEdgar E. Iglesias r = 1; 220ef9d48daSEdgar E. Iglesias } 221ef9d48daSEdgar E. Iglesias 222ef9d48daSEdgar E. Iglesias return r; 22397694c57SEdgar E. Iglesias } 22497694c57SEdgar E. Iglesias 22564254ebaSBlue Swirl uint32_t helper_fcmp_lt(CPUMBState *env, uint32_t a, uint32_t b) 22697694c57SEdgar E. Iglesias { 22797694c57SEdgar E. Iglesias CPU_FloatU fa, fb; 22897694c57SEdgar E. Iglesias int r; 22997694c57SEdgar E. Iglesias int flags; 23097694c57SEdgar E. Iglesias 23197694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 23297694c57SEdgar E. Iglesias fa.l = a; 23397694c57SEdgar E. Iglesias fb.l = b; 23497694c57SEdgar E. Iglesias r = float32_lt(fb.f, fa.f, &env->fp_status); 23597694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 2367bca6ddfSRichard Henderson update_fpu_flags(env, flags & float_flag_invalid, GETPC()); 23797694c57SEdgar E. Iglesias 23897694c57SEdgar E. Iglesias return r; 23997694c57SEdgar E. Iglesias } 24097694c57SEdgar E. Iglesias 24164254ebaSBlue Swirl uint32_t helper_fcmp_eq(CPUMBState *env, uint32_t a, uint32_t b) 24297694c57SEdgar E. Iglesias { 24397694c57SEdgar E. Iglesias CPU_FloatU fa, fb; 24497694c57SEdgar E. Iglesias int flags; 24597694c57SEdgar E. Iglesias int r; 24697694c57SEdgar E. Iglesias 24797694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 24897694c57SEdgar E. Iglesias fa.l = a; 24997694c57SEdgar E. Iglesias fb.l = b; 250211315fbSAurelien Jarno r = float32_eq_quiet(fa.f, fb.f, &env->fp_status); 25197694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 2527bca6ddfSRichard Henderson update_fpu_flags(env, flags & float_flag_invalid, GETPC()); 25397694c57SEdgar E. Iglesias 25497694c57SEdgar E. Iglesias return r; 25597694c57SEdgar E. Iglesias } 25697694c57SEdgar E. Iglesias 25764254ebaSBlue Swirl uint32_t helper_fcmp_le(CPUMBState *env, uint32_t a, uint32_t b) 25897694c57SEdgar E. Iglesias { 25997694c57SEdgar E. Iglesias CPU_FloatU fa, fb; 26097694c57SEdgar E. Iglesias int flags; 26197694c57SEdgar E. Iglesias int r; 26297694c57SEdgar E. Iglesias 26397694c57SEdgar E. Iglesias fa.l = a; 26497694c57SEdgar E. Iglesias fb.l = b; 26597694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 26697694c57SEdgar E. Iglesias r = float32_le(fa.f, fb.f, &env->fp_status); 26797694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 2687bca6ddfSRichard Henderson update_fpu_flags(env, flags & float_flag_invalid, GETPC()); 26997694c57SEdgar E. Iglesias 27097694c57SEdgar E. Iglesias 27197694c57SEdgar E. Iglesias return r; 27297694c57SEdgar E. Iglesias } 27397694c57SEdgar E. Iglesias 27464254ebaSBlue Swirl uint32_t helper_fcmp_gt(CPUMBState *env, uint32_t a, uint32_t b) 27597694c57SEdgar E. Iglesias { 27697694c57SEdgar E. Iglesias CPU_FloatU fa, fb; 27797694c57SEdgar E. Iglesias int flags, r; 27897694c57SEdgar E. Iglesias 27997694c57SEdgar E. Iglesias fa.l = a; 28097694c57SEdgar E. Iglesias fb.l = b; 28197694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 28297694c57SEdgar E. Iglesias r = float32_lt(fa.f, fb.f, &env->fp_status); 28397694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 2847bca6ddfSRichard Henderson update_fpu_flags(env, flags & float_flag_invalid, GETPC()); 28597694c57SEdgar E. Iglesias return r; 28697694c57SEdgar E. Iglesias } 28797694c57SEdgar E. Iglesias 28864254ebaSBlue Swirl uint32_t helper_fcmp_ne(CPUMBState *env, uint32_t a, uint32_t b) 28997694c57SEdgar E. Iglesias { 29097694c57SEdgar E. Iglesias CPU_FloatU fa, fb; 29197694c57SEdgar E. Iglesias int flags, r; 29297694c57SEdgar E. Iglesias 29397694c57SEdgar E. Iglesias fa.l = a; 29497694c57SEdgar E. Iglesias fb.l = b; 29597694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 296211315fbSAurelien Jarno r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status); 29797694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 2987bca6ddfSRichard Henderson update_fpu_flags(env, flags & float_flag_invalid, GETPC()); 29997694c57SEdgar E. Iglesias 30097694c57SEdgar E. Iglesias return r; 30197694c57SEdgar E. Iglesias } 30297694c57SEdgar E. Iglesias 30364254ebaSBlue Swirl uint32_t helper_fcmp_ge(CPUMBState *env, uint32_t a, uint32_t b) 30497694c57SEdgar E. Iglesias { 30597694c57SEdgar E. Iglesias CPU_FloatU fa, fb; 30697694c57SEdgar E. Iglesias int flags, r; 30797694c57SEdgar E. Iglesias 30897694c57SEdgar E. Iglesias fa.l = a; 30997694c57SEdgar E. Iglesias fb.l = b; 31097694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 31197694c57SEdgar E. Iglesias r = !float32_lt(fa.f, fb.f, &env->fp_status); 31297694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 3137bca6ddfSRichard Henderson update_fpu_flags(env, flags & float_flag_invalid, GETPC()); 31497694c57SEdgar E. Iglesias 31597694c57SEdgar E. Iglesias return r; 31697694c57SEdgar E. Iglesias } 31797694c57SEdgar E. Iglesias 31864254ebaSBlue Swirl uint32_t helper_flt(CPUMBState *env, uint32_t a) 31997694c57SEdgar E. Iglesias { 32097694c57SEdgar E. Iglesias CPU_FloatU fd, fa; 32197694c57SEdgar E. Iglesias 32297694c57SEdgar E. Iglesias fa.l = a; 32397694c57SEdgar E. Iglesias fd.f = int32_to_float32(fa.l, &env->fp_status); 32497694c57SEdgar E. Iglesias return fd.l; 32597694c57SEdgar E. Iglesias } 32697694c57SEdgar E. Iglesias 32764254ebaSBlue Swirl uint32_t helper_fint(CPUMBState *env, uint32_t a) 32897694c57SEdgar E. Iglesias { 32997694c57SEdgar E. Iglesias CPU_FloatU fa; 33097694c57SEdgar E. Iglesias uint32_t r; 33197694c57SEdgar E. Iglesias int flags; 33297694c57SEdgar E. Iglesias 33397694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 33497694c57SEdgar E. Iglesias fa.l = a; 33597694c57SEdgar E. Iglesias r = float32_to_int32(fa.f, &env->fp_status); 33697694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 3377bca6ddfSRichard Henderson update_fpu_flags(env, flags, GETPC()); 33897694c57SEdgar E. Iglesias 33997694c57SEdgar E. Iglesias return r; 34097694c57SEdgar E. Iglesias } 34197694c57SEdgar E. Iglesias 34264254ebaSBlue Swirl uint32_t helper_fsqrt(CPUMBState *env, uint32_t a) 34397694c57SEdgar E. Iglesias { 34497694c57SEdgar E. Iglesias CPU_FloatU fd, fa; 34597694c57SEdgar E. Iglesias int flags; 34697694c57SEdgar E. Iglesias 34797694c57SEdgar E. Iglesias set_float_exception_flags(0, &env->fp_status); 34897694c57SEdgar E. Iglesias fa.l = a; 34997694c57SEdgar E. Iglesias fd.l = float32_sqrt(fa.f, &env->fp_status); 35097694c57SEdgar E. Iglesias flags = get_float_exception_flags(&env->fp_status); 3517bca6ddfSRichard Henderson update_fpu_flags(env, flags, GETPC()); 35297694c57SEdgar E. Iglesias 35397694c57SEdgar E. Iglesias return fd.l; 35497694c57SEdgar E. Iglesias } 35597694c57SEdgar E. Iglesias 3564acb54baSEdgar E. Iglesias uint32_t helper_pcmpbf(uint32_t a, uint32_t b) 3574acb54baSEdgar E. Iglesias { 3584acb54baSEdgar E. Iglesias unsigned int i; 3594acb54baSEdgar E. Iglesias uint32_t mask = 0xff000000; 3604acb54baSEdgar E. Iglesias 3614acb54baSEdgar E. Iglesias for (i = 0; i < 4; i++) { 3624acb54baSEdgar E. Iglesias if ((a & mask) == (b & mask)) 3634acb54baSEdgar E. Iglesias return i + 1; 3644acb54baSEdgar E. Iglesias mask >>= 8; 3654acb54baSEdgar E. Iglesias } 3664acb54baSEdgar E. Iglesias return 0; 3674acb54baSEdgar E. Iglesias } 3684acb54baSEdgar E. Iglesias 369403322eaSEdgar E. Iglesias void helper_stackprot(CPUMBState *env, target_ulong addr) 3705818dee5SEdgar E. Iglesias { 3715818dee5SEdgar E. Iglesias if (addr < env->slr || addr > env->shr) { 3723f203194SRichard Henderson CPUState *cs = env_cpu(env); 3733f203194SRichard Henderson 374403322eaSEdgar E. Iglesias qemu_log_mask(CPU_LOG_INT, "Stack protector violation at " 375403322eaSEdgar E. Iglesias TARGET_FMT_lx " %x %x\n", 3765818dee5SEdgar E. Iglesias addr, env->slr, env->shr); 3773f203194SRichard Henderson 378b2e80a3cSRichard Henderson env->ear = addr; 37978e9caf2SRichard Henderson env->esr = ESR_EC_STACKPROT; 3803f203194SRichard Henderson cs->exception_index = EXCP_HW_EXCP; 3813f203194SRichard Henderson cpu_loop_exit_restore(cs, GETPC()); 3825818dee5SEdgar E. Iglesias } 3835818dee5SEdgar E. Iglesias } 3845818dee5SEdgar E. Iglesias 3854acb54baSEdgar E. Iglesias #if !defined(CONFIG_USER_ONLY) 3864acb54baSEdgar E. Iglesias /* Writes/reads to the MMU's special regs end up here. */ 387f0f7e7f7SEdgar E. Iglesias uint32_t helper_mmu_read(CPUMBState *env, uint32_t ext, uint32_t rn) 3884acb54baSEdgar E. Iglesias { 389f0f7e7f7SEdgar E. Iglesias return mmu_read(env, ext, rn); 3904acb54baSEdgar E. Iglesias } 3914acb54baSEdgar E. Iglesias 392f0f7e7f7SEdgar E. Iglesias void helper_mmu_write(CPUMBState *env, uint32_t ext, uint32_t rn, uint32_t v) 3934acb54baSEdgar E. Iglesias { 394f0f7e7f7SEdgar E. Iglesias mmu_write(env, ext, rn, v); 3954acb54baSEdgar E. Iglesias } 396faed1c2aSEdgar E. Iglesias 397bdff8123SPeter Maydell void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, 398bdff8123SPeter Maydell unsigned size, MMUAccessType access_type, 399bdff8123SPeter Maydell int mmu_idx, MemTxAttrs attrs, 400bdff8123SPeter Maydell MemTxResult response, uintptr_t retaddr) 401faed1c2aSEdgar E. Iglesias { 4025318223dSRichard Henderson MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); 4035318223dSRichard Henderson CPUMBState *env = &cpu->env; 4045318223dSRichard Henderson 405bdff8123SPeter Maydell qemu_log_mask(CPU_LOG_INT, "Transaction failed: vaddr 0x%" VADDR_PRIx 406883f2c59SPhilippe Mathieu-Daudé " physaddr 0x" HWADDR_FMT_plx " size %d access type %s\n", 407bdff8123SPeter Maydell addr, physaddr, size, 408bdff8123SPeter Maydell access_type == MMU_INST_FETCH ? "INST_FETCH" : 409bdff8123SPeter Maydell (access_type == MMU_DATA_LOAD ? "DATA_LOAD" : "DATA_STORE")); 410bdff8123SPeter Maydell 4112e5282caSRichard Henderson if (!(env->msr & MSR_EE)) { 412faed1c2aSEdgar E. Iglesias return; 413faed1c2aSEdgar E. Iglesias } 414faed1c2aSEdgar E. Iglesias 415bdff8123SPeter Maydell if (access_type == MMU_INST_FETCH) { 4165318223dSRichard Henderson if (!cpu->cfg.iopb_bus_exception) { 4175318223dSRichard Henderson return; 4185318223dSRichard Henderson } 41978e9caf2SRichard Henderson env->esr = ESR_EC_INSN_BUS; 420faed1c2aSEdgar E. Iglesias } else { 4215318223dSRichard Henderson if (!cpu->cfg.dopb_bus_exception) { 4225318223dSRichard Henderson return; 4235318223dSRichard Henderson } 42478e9caf2SRichard Henderson env->esr = ESR_EC_DATA_BUS; 425faed1c2aSEdgar E. Iglesias } 4265318223dSRichard Henderson 4275318223dSRichard Henderson env->ear = addr; 4285318223dSRichard Henderson cs->exception_index = EXCP_HW_EXCP; 4295318223dSRichard Henderson cpu_loop_exit_restore(cs, retaddr); 430faed1c2aSEdgar E. Iglesias } 4313c7b48b7SPaul Brook #endif 432