|
|
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.11! root 25: void helper_raise_exception(CPUState *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.11! root 31: void helper_debug(CPUState *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.11! root 67: static target_ulong helper_udiv_common(CPUState *env, target_ulong a, ! 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.11! root 95: target_ulong helper_udiv(CPUState *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.11! root 100: target_ulong helper_udiv_cc(CPUState *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.11! root 105: static target_ulong helper_sdiv_common(CPUState *env, target_ulong a, ! 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.11! root 133: target_ulong helper_sdiv(CPUState *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.11! root 138: target_ulong helper_sdiv_cc(CPUState *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.