xref: /qemu/target/microblaze/op_helper.c (revision 42fa9665e598c268a7ccfab5b92636618d9574ec)
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