|
|
1.1 ! root 1: /* ! 2: * SH4 emulation ! 3: * ! 4: * Copyright (c) 2005 Samuel Tardieu ! 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 ! 17: * License along with this library; if not, write to the Free Software ! 18: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! 19: */ ! 20: #include <assert.h> ! 21: #include "exec.h" ! 22: ! 23: void cpu_loop_exit(void) ! 24: { ! 25: longjmp(env->jmp_env, 1); ! 26: } ! 27: ! 28: void do_raise_exception(void) ! 29: { ! 30: cpu_loop_exit(); ! 31: } ! 32: ! 33: #ifndef CONFIG_USER_ONLY ! 34: ! 35: #define MMUSUFFIX _mmu ! 36: #define GETPC() (__builtin_return_address(0)) ! 37: ! 38: #define SHIFT 0 ! 39: #include "softmmu_template.h" ! 40: ! 41: #define SHIFT 1 ! 42: #include "softmmu_template.h" ! 43: ! 44: #define SHIFT 2 ! 45: #include "softmmu_template.h" ! 46: ! 47: #define SHIFT 3 ! 48: #include "softmmu_template.h" ! 49: ! 50: void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) ! 51: { ! 52: TranslationBlock *tb; ! 53: CPUState *saved_env; ! 54: unsigned long pc; ! 55: int ret; ! 56: ! 57: /* XXX: hack to restore env in all cases, even if not called from ! 58: generated code */ ! 59: saved_env = env; ! 60: env = cpu_single_env; ! 61: ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1); ! 62: if (ret) { ! 63: if (retaddr) { ! 64: /* now we have a real cpu fault */ ! 65: pc = (unsigned long) retaddr; ! 66: tb = tb_find_pc(pc); ! 67: if (tb) { ! 68: /* the PC is inside the translated code. It means that we have ! 69: a virtual CPU fault */ ! 70: cpu_restore_state(tb, env, pc, NULL); ! 71: } ! 72: } ! 73: do_raise_exception(); ! 74: } ! 75: env = saved_env; ! 76: } ! 77: ! 78: #endif ! 79: ! 80: void helper_addc_T0_T1(void) ! 81: { ! 82: uint32_t tmp0, tmp1; ! 83: ! 84: tmp1 = T0 + T1; ! 85: tmp0 = T1; ! 86: T1 = tmp1 + (env->sr & 1); ! 87: if (tmp0 > tmp1) ! 88: env->sr |= SR_T; ! 89: else ! 90: env->sr &= ~SR_T; ! 91: if (tmp1 > T1) ! 92: env->sr |= SR_T; ! 93: } ! 94: ! 95: void helper_addv_T0_T1(void) ! 96: { ! 97: uint32_t dest, src, ans; ! 98: ! 99: if ((int32_t) T1 >= 0) ! 100: dest = 0; ! 101: else ! 102: dest = 1; ! 103: if ((int32_t) T0 >= 0) ! 104: src = 0; ! 105: else ! 106: src = 1; ! 107: src += dest; ! 108: T1 += T0; ! 109: if ((int32_t) T1 >= 0) ! 110: ans = 0; ! 111: else ! 112: ans = 1; ! 113: ans += dest; ! 114: if (src == 0 || src == 2) { ! 115: if (ans == 1) ! 116: env->sr |= SR_T; ! 117: else ! 118: env->sr &= ~SR_T; ! 119: } else ! 120: env->sr &= ~SR_T; ! 121: } ! 122: ! 123: #define T (env->sr & SR_T) ! 124: #define Q (env->sr & SR_Q ? 1 : 0) ! 125: #define M (env->sr & SR_M ? 1 : 0) ! 126: #define SETT env->sr |= SR_T ! 127: #define CLRT env->sr &= ~SR_T ! 128: #define SETQ env->sr |= SR_Q ! 129: #define CLRQ env->sr &= ~SR_Q ! 130: #define SETM env->sr |= SR_M ! 131: #define CLRM env->sr &= ~SR_M ! 132: ! 133: void helper_div1_T0_T1(void) ! 134: { ! 135: uint32_t tmp0, tmp2; ! 136: uint8_t old_q, tmp1 = 0xff; ! 137: ! 138: printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T); ! 139: old_q = Q; ! 140: if ((0x80000000 & T1) != 0) ! 141: SETQ; ! 142: else ! 143: CLRQ; ! 144: tmp2 = T0; ! 145: T1 <<= 1; ! 146: T1 |= T; ! 147: switch (old_q) { ! 148: case 0: ! 149: switch (M) { ! 150: case 0: ! 151: tmp0 = T1; ! 152: T1 -= tmp2; ! 153: tmp1 = T1 > tmp0; ! 154: switch (Q) { ! 155: case 0: ! 156: if (tmp1) ! 157: SETQ; ! 158: else ! 159: CLRQ; ! 160: break; ! 161: case 1: ! 162: if (tmp1 == 0) ! 163: SETQ; ! 164: else ! 165: CLRQ; ! 166: break; ! 167: } ! 168: break; ! 169: case 1: ! 170: tmp0 = T1; ! 171: T1 += tmp2; ! 172: tmp1 = T1 < tmp0; ! 173: switch (Q) { ! 174: case 0: ! 175: if (tmp1 == 0) ! 176: SETQ; ! 177: else ! 178: CLRQ; ! 179: break; ! 180: case 1: ! 181: if (tmp1) ! 182: SETQ; ! 183: else ! 184: CLRQ; ! 185: break; ! 186: } ! 187: break; ! 188: } ! 189: break; ! 190: case 1: ! 191: switch (M) { ! 192: case 0: ! 193: tmp0 = T1; ! 194: T1 += tmp2; ! 195: tmp1 = T1 < tmp0; ! 196: switch (Q) { ! 197: case 0: ! 198: if (tmp1) ! 199: SETQ; ! 200: else ! 201: CLRQ; ! 202: break; ! 203: case 1: ! 204: if (tmp1 == 0) ! 205: SETQ; ! 206: else ! 207: CLRQ; ! 208: break; ! 209: } ! 210: break; ! 211: case 1: ! 212: tmp0 = T1; ! 213: T1 -= tmp2; ! 214: tmp1 = T1 > tmp0; ! 215: switch (Q) { ! 216: case 0: ! 217: if (tmp1 == 0) ! 218: SETQ; ! 219: else ! 220: CLRQ; ! 221: break; ! 222: case 1: ! 223: if (tmp1) ! 224: SETQ; ! 225: else ! 226: CLRQ; ! 227: break; ! 228: } ! 229: break; ! 230: } ! 231: break; ! 232: } ! 233: if (Q == M) ! 234: SETT; ! 235: else ! 236: CLRT; ! 237: printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T); ! 238: } ! 239: ! 240: void helper_dmulsl_T0_T1() ! 241: { ! 242: int64_t res; ! 243: ! 244: res = (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1; ! 245: env->mach = (res >> 32) & 0xffffffff; ! 246: env->macl = res & 0xffffffff; ! 247: } ! 248: ! 249: void helper_dmulul_T0_T1() ! 250: { ! 251: uint64_t res; ! 252: ! 253: res = (uint64_t) (uint32_t) T0 *(uint64_t) (uint32_t) T1; ! 254: env->mach = (res >> 32) & 0xffffffff; ! 255: env->macl = res & 0xffffffff; ! 256: } ! 257: ! 258: void helper_macl_T0_T1() ! 259: { ! 260: int64_t res; ! 261: ! 262: res = ((uint64_t) env->mach << 32) | env->macl; ! 263: res += (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1; ! 264: env->mach = (res >> 32) & 0xffffffff; ! 265: env->macl = res & 0xffffffff; ! 266: if (env->sr & SR_S) { ! 267: if (res < 0) ! 268: env->mach |= 0xffff0000; ! 269: else ! 270: env->mach &= 0x00007fff; ! 271: } ! 272: } ! 273: ! 274: void helper_macw_T0_T1() ! 275: { ! 276: int64_t res; ! 277: ! 278: res = ((uint64_t) env->mach << 32) | env->macl; ! 279: res += (int64_t) (int16_t) T0 *(int64_t) (int16_t) T1; ! 280: env->mach = (res >> 32) & 0xffffffff; ! 281: env->macl = res & 0xffffffff; ! 282: if (env->sr & SR_S) { ! 283: if (res < -0x80000000) { ! 284: env->mach = 1; ! 285: env->macl = 0x80000000; ! 286: } else if (res > 0x000000007fffffff) { ! 287: env->mach = 1; ! 288: env->macl = 0x7fffffff; ! 289: } ! 290: } ! 291: } ! 292: ! 293: void helper_negc_T0() ! 294: { ! 295: uint32_t temp; ! 296: ! 297: temp = -T0; ! 298: T0 = temp - (env->sr & SR_T); ! 299: if (0 < temp) ! 300: env->sr |= SR_T; ! 301: else ! 302: env->sr &= ~SR_T; ! 303: if (temp < T0) ! 304: env->sr |= SR_T; ! 305: } ! 306: ! 307: void helper_subc_T0_T1() ! 308: { ! 309: uint32_t tmp0, tmp1; ! 310: ! 311: tmp1 = T1 - T0; ! 312: tmp0 = T1; ! 313: T1 = tmp1 - (env->sr & SR_T); ! 314: if (tmp0 < tmp1) ! 315: env->sr |= SR_T; ! 316: else ! 317: env->sr &= ~SR_T; ! 318: if (tmp1 < T1) ! 319: env->sr |= SR_T; ! 320: } ! 321: ! 322: void helper_subv_T0_T1() ! 323: { ! 324: int32_t dest, src, ans; ! 325: ! 326: if ((int32_t) T1 >= 0) ! 327: dest = 0; ! 328: else ! 329: dest = 1; ! 330: if ((int32_t) T0 >= 0) ! 331: src = 0; ! 332: else ! 333: src = 1; ! 334: src += dest; ! 335: T1 -= T0; ! 336: if ((int32_t) T1 >= 0) ! 337: ans = 0; ! 338: else ! 339: ans = 1; ! 340: ans += dest; ! 341: if (src == 1) { ! 342: if (ans == 1) ! 343: env->sr |= SR_T; ! 344: else ! 345: env->sr &= ~SR_T; ! 346: } else ! 347: env->sr &= ~SR_T; ! 348: } ! 349: ! 350: void helper_rotcl(uint32_t * addr) ! 351: { ! 352: uint32_t new; ! 353: ! 354: new = (*addr << 1) | (env->sr & SR_T); ! 355: if (*addr & 0x80000000) ! 356: env->sr |= SR_T; ! 357: else ! 358: env->sr &= ~SR_T; ! 359: *addr = new; ! 360: } ! 361: ! 362: void helper_rotcr(uint32_t * addr) ! 363: { ! 364: uint32_t new; ! 365: ! 366: new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0); ! 367: if (*addr & 1) ! 368: env->sr |= SR_T; ! 369: else ! 370: env->sr &= ~SR_T; ! 371: *addr = new; ! 372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.