|
|
1.1 root 1: /*
1.1.1.11 root 2: * Misc Sparc helpers
1.1.1.4 root 3: *
1.1 root 4: * Copyright (c) 2003-2005 Fabrice Bellard
5: *
6: * This library is free software; you can redistribute it and/or
7: * modify it under the terms of the GNU Lesser General Public
8: * License as published by the Free Software Foundation; either
9: * version 2 of the License, or (at your option) any later version.
10: *
11: * This library is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * Lesser General Public License for more details.
15: *
16: * You should have received a copy of the GNU Lesser General Public
1.1.1.6 root 17: * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1 root 18: */
19:
20: #include "cpu.h"
1.1.1.11 root 21: #include "host-utils.h"
22: #include "helper.h"
23: #include "sysemu.h"
1.1 root 24:
1.1.1.12! root 25: void helper_raise_exception(CPUSPARCState *env, int tt)
1.1 root 26: {
1.1.1.11 root 27: env->exception_index = tt;
28: cpu_loop_exit(env);
1.1 root 29: }
30:
1.1.1.12! root 31: void helper_debug(CPUSPARCState *env)
1.1 root 32: {
1.1.1.11 root 33: env->exception_index = EXCP_DEBUG;
34: cpu_loop_exit(env);
1.1 root 35: }
36:
1.1.1.11 root 37: #ifdef TARGET_SPARC64
38: target_ulong helper_popc(target_ulong val)
1.1 root 39: {
1.1.1.11 root 40: return ctpop64(val);
1.1 root 41: }
42:
1.1.1.11 root 43: void helper_tick_set_count(void *opaque, uint64_t count)
1.1 root 44: {
1.1.1.11 root 45: #if !defined(CONFIG_USER_ONLY)
46: cpu_tick_set_count(opaque, count);
1.1.1.8 root 47: #endif
1.1 root 48: }
49:
1.1.1.11 root 50: uint64_t helper_tick_get_count(void *opaque)
1.1 root 51: {
1.1.1.8 root 52: #if !defined(CONFIG_USER_ONLY)
1.1.1.11 root 53: return cpu_tick_get_count(opaque);
54: #else
55: return 0;
1.1.1.10 root 56: #endif
57: }
58:
1.1.1.11 root 59: void helper_tick_set_limit(void *opaque, uint64_t limit)
1.1.1.10 root 60: {
61: #if !defined(CONFIG_USER_ONLY)
1.1.1.11 root 62: cpu_tick_set_limit(opaque, limit);
1.1.1.10 root 63: #endif
64: }
65: #endif
66:
1.1.1.12! root 67: static target_ulong helper_udiv_common(CPUSPARCState *env, target_ulong a,
1.1.1.11 root 68: target_ulong b, int cc)
1.1.1.10 root 69: {
1.1.1.11 root 70: int overflow = 0;
71: uint64_t x0;
72: uint32_t x1;
1.1.1.10 root 73:
1.1.1.11 root 74: x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
75: x1 = (b & 0xffffffff);
1.1.1.10 root 76:
1.1.1.11 root 77: if (x1 == 0) {
78: helper_raise_exception(env, TT_DIV_ZERO);
1.1.1.10 root 79: }
1.1.1.4 root 80:
1.1.1.11 root 81: x0 = x0 / x1;
82: if (x0 > 0xffffffff) {
83: x0 = 0xffffffff;
84: overflow = 1;
1.1.1.5 root 85: }
86:
1.1.1.11 root 87: if (cc) {
88: env->cc_dst = x0;
89: env->cc_src2 = overflow;
90: env->cc_op = CC_OP_DIV;
1.1.1.5 root 91: }
1.1.1.11 root 92: return x0;
1.1.1.5 root 93: }
94:
1.1.1.12! root 95: target_ulong helper_udiv(CPUSPARCState *env, target_ulong a, target_ulong b)
1.1.1.5 root 96: {
1.1.1.11 root 97: return helper_udiv_common(env, a, b, 0);
1.1.1.5 root 98: }
99:
1.1.1.12! root 100: target_ulong helper_udiv_cc(CPUSPARCState *env, target_ulong a, target_ulong b)
1.1.1.5 root 101: {
1.1.1.11 root 102: return helper_udiv_common(env, a, b, 1);
1.1.1.4 root 103: }
104:
1.1.1.12! root 105: static target_ulong helper_sdiv_common(CPUSPARCState *env, target_ulong a,
1.1.1.11 root 106: target_ulong b, int cc)
1.1.1.4 root 107: {
1.1.1.11 root 108: int overflow = 0;
109: int64_t x0;
110: int32_t x1;
1.1.1.5 root 111:
1.1.1.11 root 112: x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
113: x1 = (b & 0xffffffff);
1.1.1.5 root 114:
1.1.1.11 root 115: if (x1 == 0) {
116: helper_raise_exception(env, TT_DIV_ZERO);
1.1.1.5 root 117: }
118:
1.1.1.11 root 119: x0 = x0 / x1;
120: if ((int32_t) x0 != x0) {
121: x0 = x0 < 0 ? 0x80000000 : 0x7fffffff;
122: overflow = 1;
1.1.1.5 root 123: }
124:
1.1.1.11 root 125: if (cc) {
126: env->cc_dst = x0;
127: env->cc_src2 = overflow;
128: env->cc_op = CC_OP_DIV;
1.1.1.5 root 129: }
1.1.1.11 root 130: return x0;
1.1.1.5 root 131: }
132:
1.1.1.12! root 133: target_ulong helper_sdiv(CPUSPARCState *env, target_ulong a, target_ulong b)
1.1.1.8 root 134: {
1.1.1.11 root 135: return helper_sdiv_common(env, a, b, 0);
1.1.1.8 root 136: }
137:
1.1.1.12! root 138: target_ulong helper_sdiv_cc(CPUSPARCState *env, target_ulong a, target_ulong b)
1.1.1.5 root 139: {
1.1.1.11 root 140: return helper_sdiv_common(env, a, b, 1);
1.1.1.5 root 141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.