xref: /qemu/target/microblaze/op_helper.c (revision a4bcfc3380c7fab42613dc5747d4b48f0bae29df)
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
104acb54baSEdgar E. Iglesias  * version 2 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"
223e457172SBlue Swirl #include "cpu.h"
232ef6175aSRichard Henderson #include "exec/helper-proto.h"
241de7afc9SPaolo Bonzini #include "qemu/host-utils.h"
2563c91552SPaolo Bonzini #include "exec/exec-all.h"
26f08b6170SPaolo Bonzini #include "exec/cpu_ldst.h"
2724f91e81SAlex Bennée #include "fpu/softfloat.h"
284acb54baSEdgar E. Iglesias 
296d76d23eSEdgar E. Iglesias void helper_put(uint32_t id, uint32_t ctrl, uint32_t data)
306d76d23eSEdgar E. Iglesias {
316d76d23eSEdgar E. Iglesias     int test = ctrl & STREAM_TEST;
326d76d23eSEdgar E. Iglesias     int atomic = ctrl & STREAM_ATOMIC;
336d76d23eSEdgar E. Iglesias     int control = ctrl & STREAM_CONTROL;
346d76d23eSEdgar E. Iglesias     int nonblock = ctrl & STREAM_NONBLOCK;
356d76d23eSEdgar E. Iglesias     int exception = ctrl & STREAM_EXCEPTION;
366d76d23eSEdgar E. Iglesias 
371d512a65SPaolo Bonzini     qemu_log_mask(LOG_UNIMP, "Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n",
386d76d23eSEdgar E. Iglesias              id, data,
396d76d23eSEdgar E. Iglesias              test ? "t" : "",
406d76d23eSEdgar E. Iglesias              nonblock ? "n" : "",
416d76d23eSEdgar E. Iglesias              exception ? "e" : "",
426d76d23eSEdgar E. Iglesias              control ? "c" : "",
436d76d23eSEdgar E. Iglesias              atomic ? "a" : "");
446d76d23eSEdgar E. Iglesias }
456d76d23eSEdgar E. Iglesias 
466d76d23eSEdgar E. Iglesias uint32_t helper_get(uint32_t id, uint32_t ctrl)
476d76d23eSEdgar E. Iglesias {
486d76d23eSEdgar E. Iglesias     int test = ctrl & STREAM_TEST;
496d76d23eSEdgar E. Iglesias     int atomic = ctrl & STREAM_ATOMIC;
506d76d23eSEdgar E. Iglesias     int control = ctrl & STREAM_CONTROL;
516d76d23eSEdgar E. Iglesias     int nonblock = ctrl & STREAM_NONBLOCK;
526d76d23eSEdgar E. Iglesias     int exception = ctrl & STREAM_EXCEPTION;
536d76d23eSEdgar E. Iglesias 
541d512a65SPaolo Bonzini     qemu_log_mask(LOG_UNIMP, "Unhandled stream get from stream-id=%d %s%s%s%s%s\n",
556d76d23eSEdgar E. Iglesias              id,
566d76d23eSEdgar E. Iglesias              test ? "t" : "",
576d76d23eSEdgar E. Iglesias              nonblock ? "n" : "",
586d76d23eSEdgar E. Iglesias              exception ? "e" : "",
596d76d23eSEdgar E. Iglesias              control ? "c" : "",
606d76d23eSEdgar E. Iglesias              atomic ? "a" : "");
616d76d23eSEdgar E. Iglesias     return 0xdead0000 | id;
626d76d23eSEdgar E. Iglesias }
636d76d23eSEdgar E. Iglesias 
6464254ebaSBlue Swirl void helper_raise_exception(CPUMBState *env, uint32_t index)
654acb54baSEdgar E. Iglesias {
66f5c7e93aSRichard Henderson     CPUState *cs = env_cpu(env);
6727103424SAndreas Färber 
6827103424SAndreas Färber     cs->exception_index = index;
695638d180SAndreas Färber     cpu_loop_exit(cs);
704acb54baSEdgar E. Iglesias }
714acb54baSEdgar E. Iglesias 
72e98651d9SRichard Henderson static bool check_divz(CPUMBState *env, uint32_t a, uint32_t b, uintptr_t ra)
734acb54baSEdgar E. Iglesias {
74e98651d9SRichard Henderson     if (unlikely(b == 0)) {
752e5282caSRichard Henderson         env->msr |= MSR_DZ;
76821ebb33SEdgar E. Iglesias 
77e98651d9SRichard Henderson         if ((env->msr & MSR_EE) &&
78e98651d9SRichard Henderson             env_archcpu(env)->cfg.div_zero_exception) {
79e98651d9SRichard Henderson             CPUState *cs = env_cpu(env);
80e98651d9SRichard Henderson 
8178e9caf2SRichard Henderson             env->esr = ESR_EC_DIVZERO;
82e98651d9SRichard Henderson             cs->exception_index = EXCP_HW_EXCP;
83e98651d9SRichard Henderson             cpu_loop_exit_restore(cs, ra);
84821ebb33SEdgar E. Iglesias         }
85e98651d9SRichard Henderson         return false;
864acb54baSEdgar E. Iglesias     }
87e98651d9SRichard Henderson     return true;
884acb54baSEdgar E. Iglesias }
894acb54baSEdgar E. Iglesias 
9064254ebaSBlue Swirl uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
914acb54baSEdgar E. Iglesias {
92e98651d9SRichard Henderson     if (!check_divz(env, a, b, GETPC())) {
934acb54baSEdgar E. Iglesias         return 0;
9464254ebaSBlue Swirl     }
954acb54baSEdgar E. Iglesias     return (int32_t)a / (int32_t)b;
964acb54baSEdgar E. Iglesias }
974acb54baSEdgar E. Iglesias 
9864254ebaSBlue Swirl uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
994acb54baSEdgar E. Iglesias {
100e98651d9SRichard Henderson     if (!check_divz(env, a, b, GETPC())) {
1014acb54baSEdgar E. Iglesias         return 0;
10264254ebaSBlue Swirl     }
1034acb54baSEdgar E. Iglesias     return a / b;
1044acb54baSEdgar E. Iglesias }
1054acb54baSEdgar E. Iglesias 
10697694c57SEdgar E. Iglesias /* raise FPU exception.  */
1077bca6ddfSRichard Henderson static void raise_fpu_exception(CPUMBState *env, uintptr_t ra)
10897694c57SEdgar E. Iglesias {
1097bca6ddfSRichard Henderson     CPUState *cs = env_cpu(env);
1107bca6ddfSRichard Henderson 
11178e9caf2SRichard Henderson     env->esr = ESR_EC_FPU;
1127bca6ddfSRichard Henderson     cs->exception_index = EXCP_HW_EXCP;
1137bca6ddfSRichard Henderson     cpu_loop_exit_restore(cs, ra);
11497694c57SEdgar E. Iglesias }
11597694c57SEdgar E. Iglesias 
1167bca6ddfSRichard Henderson static void update_fpu_flags(CPUMBState *env, int flags, uintptr_t ra)
11797694c57SEdgar E. Iglesias {
11897694c57SEdgar E. Iglesias     int raise = 0;
11997694c57SEdgar E. Iglesias 
12097694c57SEdgar E. Iglesias     if (flags & float_flag_invalid) {
1215a8e0136SRichard Henderson         env->fsr |= FSR_IO;
12297694c57SEdgar E. Iglesias         raise = 1;
12397694c57SEdgar E. Iglesias     }
12497694c57SEdgar E. Iglesias     if (flags & float_flag_divbyzero) {
1255a8e0136SRichard Henderson         env->fsr |= FSR_DZ;
12697694c57SEdgar E. Iglesias         raise = 1;
12797694c57SEdgar E. Iglesias     }
12897694c57SEdgar E. Iglesias     if (flags & float_flag_overflow) {
1295a8e0136SRichard Henderson         env->fsr |= FSR_OF;
13097694c57SEdgar E. Iglesias         raise = 1;
13197694c57SEdgar E. Iglesias     }
13297694c57SEdgar E. Iglesias     if (flags & float_flag_underflow) {
1335a8e0136SRichard Henderson         env->fsr |= FSR_UF;
13497694c57SEdgar E. Iglesias         raise = 1;
13597694c57SEdgar E. Iglesias     }
13697694c57SEdgar E. Iglesias     if (raise
137*a4bcfc33SRichard Henderson         && (env_archcpu(env)->cfg.pvr_regs[2] & PVR2_FPU_EXC_MASK)
1382e5282caSRichard Henderson         && (env->msr & MSR_EE)) {
1397bca6ddfSRichard Henderson         raise_fpu_exception(env, ra);
14097694c57SEdgar E. Iglesias     }
14197694c57SEdgar E. Iglesias }
14297694c57SEdgar E. Iglesias 
14364254ebaSBlue Swirl uint32_t helper_fadd(CPUMBState *env, uint32_t a, uint32_t b)
14497694c57SEdgar E. Iglesias {
14597694c57SEdgar E. Iglesias     CPU_FloatU fd, fa, fb;
14697694c57SEdgar E. Iglesias     int flags;
14797694c57SEdgar E. Iglesias 
14897694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
14997694c57SEdgar E. Iglesias     fa.l = a;
15097694c57SEdgar E. Iglesias     fb.l = b;
15197694c57SEdgar E. Iglesias     fd.f = float32_add(fa.f, fb.f, &env->fp_status);
15297694c57SEdgar E. Iglesias 
15397694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
1547bca6ddfSRichard Henderson     update_fpu_flags(env, flags, GETPC());
15597694c57SEdgar E. Iglesias     return fd.l;
15697694c57SEdgar E. Iglesias }
15797694c57SEdgar E. Iglesias 
15864254ebaSBlue Swirl uint32_t helper_frsub(CPUMBState *env, uint32_t a, uint32_t b)
15997694c57SEdgar E. Iglesias {
16097694c57SEdgar E. Iglesias     CPU_FloatU fd, fa, fb;
16197694c57SEdgar E. Iglesias     int flags;
16297694c57SEdgar E. Iglesias 
16397694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
16497694c57SEdgar E. Iglesias     fa.l = a;
16597694c57SEdgar E. Iglesias     fb.l = b;
16697694c57SEdgar E. Iglesias     fd.f = float32_sub(fb.f, fa.f, &env->fp_status);
16797694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
1687bca6ddfSRichard Henderson     update_fpu_flags(env, flags, GETPC());
16997694c57SEdgar E. Iglesias     return fd.l;
17097694c57SEdgar E. Iglesias }
17197694c57SEdgar E. Iglesias 
17264254ebaSBlue Swirl uint32_t helper_fmul(CPUMBState *env, uint32_t a, uint32_t b)
17397694c57SEdgar E. Iglesias {
17497694c57SEdgar E. Iglesias     CPU_FloatU fd, fa, fb;
17597694c57SEdgar E. Iglesias     int flags;
17697694c57SEdgar E. Iglesias 
17797694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
17897694c57SEdgar E. Iglesias     fa.l = a;
17997694c57SEdgar E. Iglesias     fb.l = b;
18097694c57SEdgar E. Iglesias     fd.f = float32_mul(fa.f, fb.f, &env->fp_status);
18197694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
1827bca6ddfSRichard Henderson     update_fpu_flags(env, flags, GETPC());
18397694c57SEdgar E. Iglesias 
18497694c57SEdgar E. Iglesias     return fd.l;
18597694c57SEdgar E. Iglesias }
18697694c57SEdgar E. Iglesias 
18764254ebaSBlue Swirl uint32_t helper_fdiv(CPUMBState *env, uint32_t a, uint32_t b)
18897694c57SEdgar E. Iglesias {
18997694c57SEdgar E. Iglesias     CPU_FloatU fd, fa, fb;
19097694c57SEdgar E. Iglesias     int flags;
19197694c57SEdgar E. Iglesias 
19297694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
19397694c57SEdgar E. Iglesias     fa.l = a;
19497694c57SEdgar E. Iglesias     fb.l = b;
19597694c57SEdgar E. Iglesias     fd.f = float32_div(fb.f, fa.f, &env->fp_status);
19697694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
1977bca6ddfSRichard Henderson     update_fpu_flags(env, flags, GETPC());
19897694c57SEdgar E. Iglesias 
19997694c57SEdgar E. Iglesias     return fd.l;
20097694c57SEdgar E. Iglesias }
20197694c57SEdgar E. Iglesias 
20264254ebaSBlue Swirl uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a, uint32_t b)
20397694c57SEdgar E. Iglesias {
204ef9d48daSEdgar E. Iglesias     CPU_FloatU fa, fb;
205ef9d48daSEdgar E. Iglesias     uint32_t r = 0;
206ef9d48daSEdgar E. Iglesias 
207ef9d48daSEdgar E. Iglesias     fa.l = a;
208ef9d48daSEdgar E. Iglesias     fb.l = b;
209ef9d48daSEdgar E. Iglesias 
210af39bc8cSAleksandar Markovic     if (float32_is_signaling_nan(fa.f, &env->fp_status) ||
211af39bc8cSAleksandar Markovic         float32_is_signaling_nan(fb.f, &env->fp_status)) {
2127bca6ddfSRichard Henderson         update_fpu_flags(env, float_flag_invalid, GETPC());
213ef9d48daSEdgar E. Iglesias         r = 1;
214ef9d48daSEdgar E. Iglesias     }
215ef9d48daSEdgar E. Iglesias 
216af39bc8cSAleksandar Markovic     if (float32_is_quiet_nan(fa.f, &env->fp_status) ||
217af39bc8cSAleksandar Markovic         float32_is_quiet_nan(fb.f, &env->fp_status)) {
218ef9d48daSEdgar E. Iglesias         r = 1;
219ef9d48daSEdgar E. Iglesias     }
220ef9d48daSEdgar E. Iglesias 
221ef9d48daSEdgar E. Iglesias     return r;
22297694c57SEdgar E. Iglesias }
22397694c57SEdgar E. Iglesias 
22464254ebaSBlue Swirl uint32_t helper_fcmp_lt(CPUMBState *env, uint32_t a, uint32_t b)
22597694c57SEdgar E. Iglesias {
22697694c57SEdgar E. Iglesias     CPU_FloatU fa, fb;
22797694c57SEdgar E. Iglesias     int r;
22897694c57SEdgar E. Iglesias     int flags;
22997694c57SEdgar E. Iglesias 
23097694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
23197694c57SEdgar E. Iglesias     fa.l = a;
23297694c57SEdgar E. Iglesias     fb.l = b;
23397694c57SEdgar E. Iglesias     r = float32_lt(fb.f, fa.f, &env->fp_status);
23497694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
2357bca6ddfSRichard Henderson     update_fpu_flags(env, flags & float_flag_invalid, GETPC());
23697694c57SEdgar E. Iglesias 
23797694c57SEdgar E. Iglesias     return r;
23897694c57SEdgar E. Iglesias }
23997694c57SEdgar E. Iglesias 
24064254ebaSBlue Swirl uint32_t helper_fcmp_eq(CPUMBState *env, uint32_t a, uint32_t b)
24197694c57SEdgar E. Iglesias {
24297694c57SEdgar E. Iglesias     CPU_FloatU fa, fb;
24397694c57SEdgar E. Iglesias     int flags;
24497694c57SEdgar E. Iglesias     int r;
24597694c57SEdgar E. Iglesias 
24697694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
24797694c57SEdgar E. Iglesias     fa.l = a;
24897694c57SEdgar E. Iglesias     fb.l = b;
249211315fbSAurelien Jarno     r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
25097694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
2517bca6ddfSRichard Henderson     update_fpu_flags(env, flags & float_flag_invalid, GETPC());
25297694c57SEdgar E. Iglesias 
25397694c57SEdgar E. Iglesias     return r;
25497694c57SEdgar E. Iglesias }
25597694c57SEdgar E. Iglesias 
25664254ebaSBlue Swirl uint32_t helper_fcmp_le(CPUMBState *env, uint32_t a, uint32_t b)
25797694c57SEdgar E. Iglesias {
25897694c57SEdgar E. Iglesias     CPU_FloatU fa, fb;
25997694c57SEdgar E. Iglesias     int flags;
26097694c57SEdgar E. Iglesias     int r;
26197694c57SEdgar E. Iglesias 
26297694c57SEdgar E. Iglesias     fa.l = a;
26397694c57SEdgar E. Iglesias     fb.l = b;
26497694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
26597694c57SEdgar E. Iglesias     r = float32_le(fa.f, fb.f, &env->fp_status);
26697694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
2677bca6ddfSRichard Henderson     update_fpu_flags(env, flags & float_flag_invalid, GETPC());
26897694c57SEdgar E. Iglesias 
26997694c57SEdgar E. Iglesias 
27097694c57SEdgar E. Iglesias     return r;
27197694c57SEdgar E. Iglesias }
27297694c57SEdgar E. Iglesias 
27364254ebaSBlue Swirl uint32_t helper_fcmp_gt(CPUMBState *env, uint32_t a, uint32_t b)
27497694c57SEdgar E. Iglesias {
27597694c57SEdgar E. Iglesias     CPU_FloatU fa, fb;
27697694c57SEdgar E. Iglesias     int flags, r;
27797694c57SEdgar E. Iglesias 
27897694c57SEdgar E. Iglesias     fa.l = a;
27997694c57SEdgar E. Iglesias     fb.l = b;
28097694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
28197694c57SEdgar E. Iglesias     r = float32_lt(fa.f, fb.f, &env->fp_status);
28297694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
2837bca6ddfSRichard Henderson     update_fpu_flags(env, flags & float_flag_invalid, GETPC());
28497694c57SEdgar E. Iglesias     return r;
28597694c57SEdgar E. Iglesias }
28697694c57SEdgar E. Iglesias 
28764254ebaSBlue Swirl uint32_t helper_fcmp_ne(CPUMBState *env, uint32_t a, uint32_t b)
28897694c57SEdgar E. Iglesias {
28997694c57SEdgar E. Iglesias     CPU_FloatU fa, fb;
29097694c57SEdgar E. Iglesias     int flags, r;
29197694c57SEdgar E. Iglesias 
29297694c57SEdgar E. Iglesias     fa.l = a;
29397694c57SEdgar E. Iglesias     fb.l = b;
29497694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
295211315fbSAurelien Jarno     r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
29697694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
2977bca6ddfSRichard Henderson     update_fpu_flags(env, flags & float_flag_invalid, GETPC());
29897694c57SEdgar E. Iglesias 
29997694c57SEdgar E. Iglesias     return r;
30097694c57SEdgar E. Iglesias }
30197694c57SEdgar E. Iglesias 
30264254ebaSBlue Swirl uint32_t helper_fcmp_ge(CPUMBState *env, uint32_t a, uint32_t b)
30397694c57SEdgar E. Iglesias {
30497694c57SEdgar E. Iglesias     CPU_FloatU fa, fb;
30597694c57SEdgar E. Iglesias     int flags, r;
30697694c57SEdgar E. Iglesias 
30797694c57SEdgar E. Iglesias     fa.l = a;
30897694c57SEdgar E. Iglesias     fb.l = b;
30997694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
31097694c57SEdgar E. Iglesias     r = !float32_lt(fa.f, fb.f, &env->fp_status);
31197694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
3127bca6ddfSRichard Henderson     update_fpu_flags(env, flags & float_flag_invalid, GETPC());
31397694c57SEdgar E. Iglesias 
31497694c57SEdgar E. Iglesias     return r;
31597694c57SEdgar E. Iglesias }
31697694c57SEdgar E. Iglesias 
31764254ebaSBlue Swirl uint32_t helper_flt(CPUMBState *env, uint32_t a)
31897694c57SEdgar E. Iglesias {
31997694c57SEdgar E. Iglesias     CPU_FloatU fd, fa;
32097694c57SEdgar E. Iglesias 
32197694c57SEdgar E. Iglesias     fa.l = a;
32297694c57SEdgar E. Iglesias     fd.f = int32_to_float32(fa.l, &env->fp_status);
32397694c57SEdgar E. Iglesias     return fd.l;
32497694c57SEdgar E. Iglesias }
32597694c57SEdgar E. Iglesias 
32664254ebaSBlue Swirl uint32_t helper_fint(CPUMBState *env, uint32_t a)
32797694c57SEdgar E. Iglesias {
32897694c57SEdgar E. Iglesias     CPU_FloatU fa;
32997694c57SEdgar E. Iglesias     uint32_t r;
33097694c57SEdgar E. Iglesias     int flags;
33197694c57SEdgar E. Iglesias 
33297694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
33397694c57SEdgar E. Iglesias     fa.l = a;
33497694c57SEdgar E. Iglesias     r = float32_to_int32(fa.f, &env->fp_status);
33597694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
3367bca6ddfSRichard Henderson     update_fpu_flags(env, flags, GETPC());
33797694c57SEdgar E. Iglesias 
33897694c57SEdgar E. Iglesias     return r;
33997694c57SEdgar E. Iglesias }
34097694c57SEdgar E. Iglesias 
34164254ebaSBlue Swirl uint32_t helper_fsqrt(CPUMBState *env, uint32_t a)
34297694c57SEdgar E. Iglesias {
34397694c57SEdgar E. Iglesias     CPU_FloatU fd, fa;
34497694c57SEdgar E. Iglesias     int flags;
34597694c57SEdgar E. Iglesias 
34697694c57SEdgar E. Iglesias     set_float_exception_flags(0, &env->fp_status);
34797694c57SEdgar E. Iglesias     fa.l = a;
34897694c57SEdgar E. Iglesias     fd.l = float32_sqrt(fa.f, &env->fp_status);
34997694c57SEdgar E. Iglesias     flags = get_float_exception_flags(&env->fp_status);
3507bca6ddfSRichard Henderson     update_fpu_flags(env, flags, GETPC());
35197694c57SEdgar E. Iglesias 
35297694c57SEdgar E. Iglesias     return fd.l;
35397694c57SEdgar E. Iglesias }
35497694c57SEdgar E. Iglesias 
3554acb54baSEdgar E. Iglesias uint32_t helper_pcmpbf(uint32_t a, uint32_t b)
3564acb54baSEdgar E. Iglesias {
3574acb54baSEdgar E. Iglesias     unsigned int i;
3584acb54baSEdgar E. Iglesias     uint32_t mask = 0xff000000;
3594acb54baSEdgar E. Iglesias 
3604acb54baSEdgar E. Iglesias     for (i = 0; i < 4; i++) {
3614acb54baSEdgar E. Iglesias         if ((a & mask) == (b & mask))
3624acb54baSEdgar E. Iglesias             return i + 1;
3634acb54baSEdgar E. Iglesias         mask >>= 8;
3644acb54baSEdgar E. Iglesias     }
3654acb54baSEdgar E. Iglesias     return 0;
3664acb54baSEdgar E. Iglesias }
3674acb54baSEdgar E. Iglesias 
368403322eaSEdgar E. Iglesias void helper_stackprot(CPUMBState *env, target_ulong addr)
3695818dee5SEdgar E. Iglesias {
3705818dee5SEdgar E. Iglesias     if (addr < env->slr || addr > env->shr) {
3713f203194SRichard Henderson         CPUState *cs = env_cpu(env);
3723f203194SRichard Henderson 
373403322eaSEdgar E. Iglesias         qemu_log_mask(CPU_LOG_INT, "Stack protector violation at "
374403322eaSEdgar E. Iglesias                       TARGET_FMT_lx " %x %x\n",
3755818dee5SEdgar E. Iglesias                       addr, env->slr, env->shr);
3763f203194SRichard Henderson 
377b2e80a3cSRichard Henderson         env->ear = addr;
37878e9caf2SRichard Henderson         env->esr = ESR_EC_STACKPROT;
3793f203194SRichard Henderson         cs->exception_index = EXCP_HW_EXCP;
3803f203194SRichard Henderson         cpu_loop_exit_restore(cs, GETPC());
3815818dee5SEdgar E. Iglesias     }
3825818dee5SEdgar E. Iglesias }
3835818dee5SEdgar E. Iglesias 
3844acb54baSEdgar E. Iglesias #if !defined(CONFIG_USER_ONLY)
3854acb54baSEdgar E. Iglesias /* Writes/reads to the MMU's special regs end up here.  */
386f0f7e7f7SEdgar E. Iglesias uint32_t helper_mmu_read(CPUMBState *env, uint32_t ext, uint32_t rn)
3874acb54baSEdgar E. Iglesias {
388f0f7e7f7SEdgar E. Iglesias     return mmu_read(env, ext, rn);
3894acb54baSEdgar E. Iglesias }
3904acb54baSEdgar E. Iglesias 
391f0f7e7f7SEdgar E. Iglesias void helper_mmu_write(CPUMBState *env, uint32_t ext, uint32_t rn, uint32_t v)
3924acb54baSEdgar E. Iglesias {
393f0f7e7f7SEdgar E. Iglesias     mmu_write(env, ext, rn, v);
3944acb54baSEdgar E. Iglesias }
395faed1c2aSEdgar E. Iglesias 
396bdff8123SPeter Maydell void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
397bdff8123SPeter Maydell                                unsigned size, MMUAccessType access_type,
398bdff8123SPeter Maydell                                int mmu_idx, MemTxAttrs attrs,
399bdff8123SPeter Maydell                                MemTxResult response, uintptr_t retaddr)
400faed1c2aSEdgar E. Iglesias {
4015318223dSRichard Henderson     MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
4025318223dSRichard Henderson     CPUMBState *env = &cpu->env;
4035318223dSRichard Henderson 
404bdff8123SPeter Maydell     qemu_log_mask(CPU_LOG_INT, "Transaction failed: vaddr 0x%" VADDR_PRIx
405bdff8123SPeter Maydell                   " physaddr 0x" TARGET_FMT_plx " size %d access type %s\n",
406bdff8123SPeter Maydell                   addr, physaddr, size,
407bdff8123SPeter Maydell                   access_type == MMU_INST_FETCH ? "INST_FETCH" :
408bdff8123SPeter Maydell                   (access_type == MMU_DATA_LOAD ? "DATA_LOAD" : "DATA_STORE"));
409bdff8123SPeter Maydell 
4102e5282caSRichard Henderson     if (!(env->msr & MSR_EE)) {
411faed1c2aSEdgar E. Iglesias         return;
412faed1c2aSEdgar E. Iglesias     }
413faed1c2aSEdgar E. Iglesias 
414bdff8123SPeter Maydell     if (access_type == MMU_INST_FETCH) {
4155318223dSRichard Henderson         if (!cpu->cfg.iopb_bus_exception) {
4165318223dSRichard Henderson             return;
4175318223dSRichard Henderson         }
41878e9caf2SRichard Henderson         env->esr = ESR_EC_INSN_BUS;
419faed1c2aSEdgar E. Iglesias     } else {
4205318223dSRichard Henderson         if (!cpu->cfg.dopb_bus_exception) {
4215318223dSRichard Henderson             return;
4225318223dSRichard Henderson         }
42378e9caf2SRichard Henderson         env->esr = ESR_EC_DATA_BUS;
424faed1c2aSEdgar E. Iglesias     }
4255318223dSRichard Henderson 
4265318223dSRichard Henderson     env->ear = addr;
4275318223dSRichard Henderson     cs->exception_index = EXCP_HW_EXCP;
4285318223dSRichard Henderson     cpu_loop_exit_restore(cs, retaddr);
429faed1c2aSEdgar E. Iglesias }
4303c7b48b7SPaul Brook #endif
431