1 /* 2 * m68k op helpers 3 * 4 * Copyright (c) 2006-2007 CodeSourcery 5 * Written by Paul Brook 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "cpu.h" 23 #include "exec/exec-all.h" 24 #include "exec/gdbstub.h" 25 26 #include "exec/helper-proto.h" 27 28 #define SIGNBIT (1u << 31) 29 30 /* Sort alphabetically, except for "any". */ 31 static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b) 32 { 33 ObjectClass *class_a = (ObjectClass *)a; 34 ObjectClass *class_b = (ObjectClass *)b; 35 const char *name_a, *name_b; 36 37 name_a = object_class_get_name(class_a); 38 name_b = object_class_get_name(class_b); 39 if (strcmp(name_a, "any-" TYPE_M68K_CPU) == 0) { 40 return 1; 41 } else if (strcmp(name_b, "any-" TYPE_M68K_CPU) == 0) { 42 return -1; 43 } else { 44 return strcasecmp(name_a, name_b); 45 } 46 } 47 48 static void m68k_cpu_list_entry(gpointer data, gpointer user_data) 49 { 50 ObjectClass *c = data; 51 CPUListState *s = user_data; 52 const char *typename; 53 char *name; 54 55 typename = object_class_get_name(c); 56 name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_M68K_CPU)); 57 (*s->cpu_fprintf)(s->file, "%s\n", 58 name); 59 g_free(name); 60 } 61 62 void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf) 63 { 64 CPUListState s = { 65 .file = f, 66 .cpu_fprintf = cpu_fprintf, 67 }; 68 GSList *list; 69 70 list = object_class_get_list(TYPE_M68K_CPU, false); 71 list = g_slist_sort(list, m68k_cpu_list_compare); 72 g_slist_foreach(list, m68k_cpu_list_entry, &s); 73 g_slist_free(list); 74 } 75 76 static int cf_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) 77 { 78 if (n < 8) { 79 float_status s; 80 stfq_p(mem_buf, floatx80_to_float64(env->fregs[n].d, &s)); 81 return 8; 82 } 83 switch (n) { 84 case 8: /* fpcontrol */ 85 stl_be_p(mem_buf, env->fpcr); 86 return 4; 87 case 9: /* fpstatus */ 88 stl_be_p(mem_buf, env->fpsr); 89 return 4; 90 case 10: /* fpiar, not implemented */ 91 memset(mem_buf, 0, 4); 92 return 4; 93 } 94 return 0; 95 } 96 97 static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) 98 { 99 if (n < 8) { 100 float_status s; 101 env->fregs[n].d = float64_to_floatx80(ldfq_p(mem_buf), &s); 102 return 8; 103 } 104 switch (n) { 105 case 8: /* fpcontrol */ 106 cpu_m68k_set_fpcr(env, ldl_p(mem_buf)); 107 return 4; 108 case 9: /* fpstatus */ 109 env->fpsr = ldl_p(mem_buf); 110 return 4; 111 case 10: /* fpiar, not implemented */ 112 return 4; 113 } 114 return 0; 115 } 116 117 static int m68k_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) 118 { 119 if (n < 8) { 120 stw_be_p(mem_buf, env->fregs[n].l.upper); 121 memset(mem_buf + 2, 0, 2); 122 stq_be_p(mem_buf + 4, env->fregs[n].l.lower); 123 return 12; 124 } 125 switch (n) { 126 case 8: /* fpcontrol */ 127 stl_be_p(mem_buf, env->fpcr); 128 return 4; 129 case 9: /* fpstatus */ 130 stl_be_p(mem_buf, env->fpsr); 131 return 4; 132 case 10: /* fpiar, not implemented */ 133 memset(mem_buf, 0, 4); 134 return 4; 135 } 136 return 0; 137 } 138 139 static int m68k_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) 140 { 141 if (n < 8) { 142 env->fregs[n].l.upper = lduw_be_p(mem_buf); 143 env->fregs[n].l.lower = ldq_be_p(mem_buf + 4); 144 return 12; 145 } 146 switch (n) { 147 case 8: /* fpcontrol */ 148 cpu_m68k_set_fpcr(env, ldl_p(mem_buf)); 149 return 4; 150 case 9: /* fpstatus */ 151 env->fpsr = ldl_p(mem_buf); 152 return 4; 153 case 10: /* fpiar, not implemented */ 154 return 4; 155 } 156 return 0; 157 } 158 159 void m68k_cpu_init_gdb(M68kCPU *cpu) 160 { 161 CPUState *cs = CPU(cpu); 162 CPUM68KState *env = &cpu->env; 163 164 if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { 165 gdb_register_coprocessor(cs, cf_fpu_gdb_get_reg, cf_fpu_gdb_set_reg, 166 11, "cf-fp.xml", 18); 167 } else if (m68k_feature(env, M68K_FEATURE_FPU)) { 168 gdb_register_coprocessor(cs, m68k_fpu_gdb_get_reg, 169 m68k_fpu_gdb_set_reg, 11, "m68k-fp.xml", 18); 170 } 171 /* TODO: Add [E]MAC registers. */ 172 } 173 174 void HELPER(cf_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val) 175 { 176 M68kCPU *cpu = m68k_env_get_cpu(env); 177 178 switch (reg) { 179 case M68K_CR_CACR: 180 env->cacr = val; 181 m68k_switch_sp(env); 182 break; 183 case M68K_CR_ACR0: 184 case M68K_CR_ACR1: 185 case M68K_CR_ACR2: 186 case M68K_CR_ACR3: 187 /* TODO: Implement Access Control Registers. */ 188 break; 189 case M68K_CR_VBR: 190 env->vbr = val; 191 break; 192 /* TODO: Implement control registers. */ 193 default: 194 cpu_abort(CPU(cpu), 195 "Unimplemented control register write 0x%x = 0x%x\n", 196 reg, val); 197 } 198 } 199 200 void HELPER(m68k_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val) 201 { 202 M68kCPU *cpu = m68k_env_get_cpu(env); 203 204 switch (reg) { 205 /* MC680[1234]0 */ 206 case M68K_CR_VBR: 207 env->vbr = val; 208 return; 209 /* MC680[234]0 */ 210 case M68K_CR_CACR: 211 env->cacr = val; 212 m68k_switch_sp(env); 213 return; 214 /* MC680[34]0 */ 215 case M68K_CR_USP: 216 env->sp[M68K_USP] = val; 217 return; 218 case M68K_CR_MSP: 219 env->sp[M68K_SSP] = val; 220 return; 221 case M68K_CR_ISP: 222 env->sp[M68K_ISP] = val; 223 return; 224 } 225 cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x = 0x%x\n", 226 reg, val); 227 } 228 229 uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, uint32_t reg) 230 { 231 M68kCPU *cpu = m68k_env_get_cpu(env); 232 233 switch (reg) { 234 /* MC680[1234]0 */ 235 case M68K_CR_VBR: 236 return env->vbr; 237 /* MC680[234]0 */ 238 case M68K_CR_CACR: 239 return env->cacr; 240 /* MC680[34]0 */ 241 case M68K_CR_USP: 242 return env->sp[M68K_USP]; 243 case M68K_CR_MSP: 244 return env->sp[M68K_SSP]; 245 case M68K_CR_ISP: 246 return env->sp[M68K_ISP]; 247 } 248 cpu_abort(CPU(cpu), "Unimplemented control register read 0x%x\n", 249 reg); 250 } 251 252 void HELPER(set_macsr)(CPUM68KState *env, uint32_t val) 253 { 254 uint32_t acc; 255 int8_t exthigh; 256 uint8_t extlow; 257 uint64_t regval; 258 int i; 259 if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) { 260 for (i = 0; i < 4; i++) { 261 regval = env->macc[i]; 262 exthigh = regval >> 40; 263 if (env->macsr & MACSR_FI) { 264 acc = regval >> 8; 265 extlow = regval; 266 } else { 267 acc = regval; 268 extlow = regval >> 32; 269 } 270 if (env->macsr & MACSR_FI) { 271 regval = (((uint64_t)acc) << 8) | extlow; 272 regval |= ((int64_t)exthigh) << 40; 273 } else if (env->macsr & MACSR_SU) { 274 regval = acc | (((int64_t)extlow) << 32); 275 regval |= ((int64_t)exthigh) << 40; 276 } else { 277 regval = acc | (((uint64_t)extlow) << 32); 278 regval |= ((uint64_t)(uint8_t)exthigh) << 40; 279 } 280 env->macc[i] = regval; 281 } 282 } 283 env->macsr = val; 284 } 285 286 void m68k_switch_sp(CPUM68KState *env) 287 { 288 int new_sp; 289 290 env->sp[env->current_sp] = env->aregs[7]; 291 if (m68k_feature(env, M68K_FEATURE_M68000)) { 292 if (env->sr & SR_S) { 293 if (env->sr & SR_M) { 294 new_sp = M68K_SSP; 295 } else { 296 new_sp = M68K_ISP; 297 } 298 } else { 299 new_sp = M68K_USP; 300 } 301 } else { 302 new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP) 303 ? M68K_SSP : M68K_USP; 304 } 305 env->aregs[7] = env->sp[new_sp]; 306 env->current_sp = new_sp; 307 } 308 309 #if defined(CONFIG_USER_ONLY) 310 311 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, 312 int mmu_idx) 313 { 314 M68kCPU *cpu = M68K_CPU(cs); 315 316 cs->exception_index = EXCP_ACCESS; 317 cpu->env.mmu.ar = address; 318 return 1; 319 } 320 321 #else 322 323 /* MMU */ 324 325 /* TODO: This will need fixing once the MMU is implemented. */ 326 hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) 327 { 328 return addr; 329 } 330 331 int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, 332 int mmu_idx) 333 { 334 int prot; 335 336 address &= TARGET_PAGE_MASK; 337 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 338 tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE); 339 return 0; 340 } 341 342 /* Notify CPU of a pending interrupt. Prioritization and vectoring should 343 be handled by the interrupt controller. Real hardware only requests 344 the vector when the interrupt is acknowledged by the CPU. For 345 simplicitly we calculate it when the interrupt is signalled. */ 346 void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector) 347 { 348 CPUState *cs = CPU(cpu); 349 CPUM68KState *env = &cpu->env; 350 351 env->pending_level = level; 352 env->pending_vector = vector; 353 if (level) { 354 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 355 } else { 356 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); 357 } 358 } 359 360 #endif 361 362 uint32_t HELPER(bitrev)(uint32_t x) 363 { 364 x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau); 365 x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu); 366 x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u); 367 return bswap32(x); 368 } 369 370 uint32_t HELPER(ff1)(uint32_t x) 371 { 372 int n; 373 for (n = 32; x; n--) 374 x >>= 1; 375 return n; 376 } 377 378 uint32_t HELPER(sats)(uint32_t val, uint32_t v) 379 { 380 /* The result has the opposite sign to the original value. */ 381 if ((int32_t)v < 0) { 382 val = (((int32_t)val) >> 31) ^ SIGNBIT; 383 } 384 return val; 385 } 386 387 void cpu_m68k_set_sr(CPUM68KState *env, uint32_t sr) 388 { 389 env->sr = sr & 0xffe0; 390 cpu_m68k_set_ccr(env, sr); 391 m68k_switch_sp(env); 392 } 393 394 void HELPER(set_sr)(CPUM68KState *env, uint32_t val) 395 { 396 cpu_m68k_set_sr(env, val); 397 } 398 399 /* MAC unit. */ 400 /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers 401 take values, others take register numbers and manipulate the contents 402 in-place. */ 403 void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src) 404 { 405 uint32_t mask; 406 env->macc[dest] = env->macc[src]; 407 mask = MACSR_PAV0 << dest; 408 if (env->macsr & (MACSR_PAV0 << src)) 409 env->macsr |= mask; 410 else 411 env->macsr &= ~mask; 412 } 413 414 uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2) 415 { 416 int64_t product; 417 int64_t res; 418 419 product = (uint64_t)op1 * op2; 420 res = (product << 24) >> 24; 421 if (res != product) { 422 env->macsr |= MACSR_V; 423 if (env->macsr & MACSR_OMC) { 424 /* Make sure the accumulate operation overflows. */ 425 if (product < 0) 426 res = ~(1ll << 50); 427 else 428 res = 1ll << 50; 429 } 430 } 431 return res; 432 } 433 434 uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2) 435 { 436 uint64_t product; 437 438 product = (uint64_t)op1 * op2; 439 if (product & (0xffffffull << 40)) { 440 env->macsr |= MACSR_V; 441 if (env->macsr & MACSR_OMC) { 442 /* Make sure the accumulate operation overflows. */ 443 product = 1ll << 50; 444 } else { 445 product &= ((1ull << 40) - 1); 446 } 447 } 448 return product; 449 } 450 451 uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2) 452 { 453 uint64_t product; 454 uint32_t remainder; 455 456 product = (uint64_t)op1 * op2; 457 if (env->macsr & MACSR_RT) { 458 remainder = product & 0xffffff; 459 product >>= 24; 460 if (remainder > 0x800000) 461 product++; 462 else if (remainder == 0x800000) 463 product += (product & 1); 464 } else { 465 product >>= 24; 466 } 467 return product; 468 } 469 470 void HELPER(macsats)(CPUM68KState *env, uint32_t acc) 471 { 472 int64_t tmp; 473 int64_t result; 474 tmp = env->macc[acc]; 475 result = ((tmp << 16) >> 16); 476 if (result != tmp) { 477 env->macsr |= MACSR_V; 478 } 479 if (env->macsr & MACSR_V) { 480 env->macsr |= MACSR_PAV0 << acc; 481 if (env->macsr & MACSR_OMC) { 482 /* The result is saturated to 32 bits, despite overflow occurring 483 at 48 bits. Seems weird, but that's what the hardware docs 484 say. */ 485 result = (result >> 63) ^ 0x7fffffff; 486 } 487 } 488 env->macc[acc] = result; 489 } 490 491 void HELPER(macsatu)(CPUM68KState *env, uint32_t acc) 492 { 493 uint64_t val; 494 495 val = env->macc[acc]; 496 if (val & (0xffffull << 48)) { 497 env->macsr |= MACSR_V; 498 } 499 if (env->macsr & MACSR_V) { 500 env->macsr |= MACSR_PAV0 << acc; 501 if (env->macsr & MACSR_OMC) { 502 if (val > (1ull << 53)) 503 val = 0; 504 else 505 val = (1ull << 48) - 1; 506 } else { 507 val &= ((1ull << 48) - 1); 508 } 509 } 510 env->macc[acc] = val; 511 } 512 513 void HELPER(macsatf)(CPUM68KState *env, uint32_t acc) 514 { 515 int64_t sum; 516 int64_t result; 517 518 sum = env->macc[acc]; 519 result = (sum << 16) >> 16; 520 if (result != sum) { 521 env->macsr |= MACSR_V; 522 } 523 if (env->macsr & MACSR_V) { 524 env->macsr |= MACSR_PAV0 << acc; 525 if (env->macsr & MACSR_OMC) { 526 result = (result >> 63) ^ 0x7fffffffffffll; 527 } 528 } 529 env->macc[acc] = result; 530 } 531 532 void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc) 533 { 534 uint64_t val; 535 val = env->macc[acc]; 536 if (val == 0) { 537 env->macsr |= MACSR_Z; 538 } else if (val & (1ull << 47)) { 539 env->macsr |= MACSR_N; 540 } 541 if (env->macsr & (MACSR_PAV0 << acc)) { 542 env->macsr |= MACSR_V; 543 } 544 if (env->macsr & MACSR_FI) { 545 val = ((int64_t)val) >> 40; 546 if (val != 0 && val != -1) 547 env->macsr |= MACSR_EV; 548 } else if (env->macsr & MACSR_SU) { 549 val = ((int64_t)val) >> 32; 550 if (val != 0 && val != -1) 551 env->macsr |= MACSR_EV; 552 } else { 553 if ((val >> 32) != 0) 554 env->macsr |= MACSR_EV; 555 } 556 } 557 558 #define EXTSIGN(val, index) ( \ 559 (index == 0) ? (int8_t)(val) : ((index == 1) ? (int16_t)(val) : (val)) \ 560 ) 561 562 #define COMPUTE_CCR(op, x, n, z, v, c) { \ 563 switch (op) { \ 564 case CC_OP_FLAGS: \ 565 /* Everything in place. */ \ 566 break; \ 567 case CC_OP_ADDB: \ 568 case CC_OP_ADDW: \ 569 case CC_OP_ADDL: \ 570 res = n; \ 571 src2 = v; \ 572 src1 = EXTSIGN(res - src2, op - CC_OP_ADDB); \ 573 c = x; \ 574 z = n; \ 575 v = (res ^ src1) & ~(src1 ^ src2); \ 576 break; \ 577 case CC_OP_SUBB: \ 578 case CC_OP_SUBW: \ 579 case CC_OP_SUBL: \ 580 res = n; \ 581 src2 = v; \ 582 src1 = EXTSIGN(res + src2, op - CC_OP_SUBB); \ 583 c = x; \ 584 z = n; \ 585 v = (res ^ src1) & (src1 ^ src2); \ 586 break; \ 587 case CC_OP_CMPB: \ 588 case CC_OP_CMPW: \ 589 case CC_OP_CMPL: \ 590 src1 = n; \ 591 src2 = v; \ 592 res = EXTSIGN(src1 - src2, op - CC_OP_CMPB); \ 593 n = res; \ 594 z = res; \ 595 c = src1 < src2; \ 596 v = (res ^ src1) & (src1 ^ src2); \ 597 break; \ 598 case CC_OP_LOGIC: \ 599 c = v = 0; \ 600 z = n; \ 601 break; \ 602 default: \ 603 cpu_abort(CPU(m68k_env_get_cpu(env)), "Bad CC_OP %d", op); \ 604 } \ 605 } while (0) 606 607 uint32_t cpu_m68k_get_ccr(CPUM68KState *env) 608 { 609 uint32_t x, c, n, z, v; 610 uint32_t res, src1, src2; 611 612 x = env->cc_x; 613 n = env->cc_n; 614 z = env->cc_z; 615 v = env->cc_v; 616 c = env->cc_c; 617 618 COMPUTE_CCR(env->cc_op, x, n, z, v, c); 619 620 n = n >> 31; 621 z = (z == 0); 622 v = v >> 31; 623 624 return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C; 625 } 626 627 uint32_t HELPER(get_ccr)(CPUM68KState *env) 628 { 629 return cpu_m68k_get_ccr(env); 630 } 631 632 void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t ccr) 633 { 634 env->cc_x = (ccr & CCF_X ? 1 : 0); 635 env->cc_n = (ccr & CCF_N ? -1 : 0); 636 env->cc_z = (ccr & CCF_Z ? 0 : 1); 637 env->cc_v = (ccr & CCF_V ? -1 : 0); 638 env->cc_c = (ccr & CCF_C ? 1 : 0); 639 env->cc_op = CC_OP_FLAGS; 640 } 641 642 void HELPER(set_ccr)(CPUM68KState *env, uint32_t ccr) 643 { 644 cpu_m68k_set_ccr(env, ccr); 645 } 646 647 void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op) 648 { 649 uint32_t res, src1, src2; 650 651 COMPUTE_CCR(cc_op, env->cc_x, env->cc_n, env->cc_z, env->cc_v, env->cc_c); 652 env->cc_op = CC_OP_FLAGS; 653 } 654 655 uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val) 656 { 657 int rem; 658 uint32_t result; 659 660 if (env->macsr & MACSR_SU) { 661 /* 16-bit rounding. */ 662 rem = val & 0xffffff; 663 val = (val >> 24) & 0xffffu; 664 if (rem > 0x800000) 665 val++; 666 else if (rem == 0x800000) 667 val += (val & 1); 668 } else if (env->macsr & MACSR_RT) { 669 /* 32-bit rounding. */ 670 rem = val & 0xff; 671 val >>= 8; 672 if (rem > 0x80) 673 val++; 674 else if (rem == 0x80) 675 val += (val & 1); 676 } else { 677 /* No rounding. */ 678 val >>= 8; 679 } 680 if (env->macsr & MACSR_OMC) { 681 /* Saturate. */ 682 if (env->macsr & MACSR_SU) { 683 if (val != (uint16_t) val) { 684 result = ((val >> 63) ^ 0x7fff) & 0xffff; 685 } else { 686 result = val & 0xffff; 687 } 688 } else { 689 if (val != (uint32_t)val) { 690 result = ((uint32_t)(val >> 63) & 0x7fffffff); 691 } else { 692 result = (uint32_t)val; 693 } 694 } 695 } else { 696 /* No saturation. */ 697 if (env->macsr & MACSR_SU) { 698 result = val & 0xffff; 699 } else { 700 result = (uint32_t)val; 701 } 702 } 703 return result; 704 } 705 706 uint32_t HELPER(get_macs)(uint64_t val) 707 { 708 if (val == (int32_t)val) { 709 return (int32_t)val; 710 } else { 711 return (val >> 61) ^ ~SIGNBIT; 712 } 713 } 714 715 uint32_t HELPER(get_macu)(uint64_t val) 716 { 717 if ((val >> 32) == 0) { 718 return (uint32_t)val; 719 } else { 720 return 0xffffffffu; 721 } 722 } 723 724 uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc) 725 { 726 uint32_t val; 727 val = env->macc[acc] & 0x00ff; 728 val |= (env->macc[acc] >> 32) & 0xff00; 729 val |= (env->macc[acc + 1] << 16) & 0x00ff0000; 730 val |= (env->macc[acc + 1] >> 16) & 0xff000000; 731 return val; 732 } 733 734 uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc) 735 { 736 uint32_t val; 737 val = (env->macc[acc] >> 32) & 0xffff; 738 val |= (env->macc[acc + 1] >> 16) & 0xffff0000; 739 return val; 740 } 741 742 void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc) 743 { 744 int64_t res; 745 int32_t tmp; 746 res = env->macc[acc] & 0xffffffff00ull; 747 tmp = (int16_t)(val & 0xff00); 748 res |= ((int64_t)tmp) << 32; 749 res |= val & 0xff; 750 env->macc[acc] = res; 751 res = env->macc[acc + 1] & 0xffffffff00ull; 752 tmp = (val & 0xff000000); 753 res |= ((int64_t)tmp) << 16; 754 res |= (val >> 16) & 0xff; 755 env->macc[acc + 1] = res; 756 } 757 758 void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc) 759 { 760 int64_t res; 761 int32_t tmp; 762 res = (uint32_t)env->macc[acc]; 763 tmp = (int16_t)val; 764 res |= ((int64_t)tmp) << 32; 765 env->macc[acc] = res; 766 res = (uint32_t)env->macc[acc + 1]; 767 tmp = val & 0xffff0000; 768 res |= (int64_t)tmp << 16; 769 env->macc[acc + 1] = res; 770 } 771 772 void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc) 773 { 774 uint64_t res; 775 res = (uint32_t)env->macc[acc]; 776 res |= ((uint64_t)(val & 0xffff)) << 32; 777 env->macc[acc] = res; 778 res = (uint32_t)env->macc[acc + 1]; 779 res |= (uint64_t)(val & 0xffff0000) << 16; 780 env->macc[acc + 1] = res; 781 } 782 783 #if defined(CONFIG_SOFTMMU) 784 void HELPER(reset)(CPUM68KState *env) 785 { 786 /* FIXME: reset all except CPU */ 787 } 788 #endif 789