qemu/target/m68k/helper.c
<<
>>
Prefs
   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". */
  31static 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
  48static 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
  62void 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
  76static 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
  97static 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
 117static 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
 139static 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
 159void 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
 174void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
 175{
 176    M68kCPU *cpu = m68k_env_get_cpu(env);
 177
 178    switch (reg) {
 179    case 0x02: /* CACR */
 180        env->cacr = val;
 181        m68k_switch_sp(env);
 182        break;
 183    case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
 184        /* TODO: Implement Access Control Registers.  */
 185        break;
 186    case 0x801: /* VBR */
 187        env->vbr = val;
 188        break;
 189    /* TODO: Implement control registers.  */
 190    default:
 191        cpu_abort(CPU(cpu), "Unimplemented control register write 0x%x = 0x%x\n",
 192                  reg, val);
 193    }
 194}
 195
 196void HELPER(set_macsr)(CPUM68KState *env, uint32_t val)
 197{
 198    uint32_t acc;
 199    int8_t exthigh;
 200    uint8_t extlow;
 201    uint64_t regval;
 202    int i;
 203    if ((env->macsr ^ val) & (MACSR_FI | MACSR_SU)) {
 204        for (i = 0; i < 4; i++) {
 205            regval = env->macc[i];
 206            exthigh = regval >> 40;
 207            if (env->macsr & MACSR_FI) {
 208                acc = regval >> 8;
 209                extlow = regval;
 210            } else {
 211                acc = regval;
 212                extlow = regval >> 32;
 213            }
 214            if (env->macsr & MACSR_FI) {
 215                regval = (((uint64_t)acc) << 8) | extlow;
 216                regval |= ((int64_t)exthigh) << 40;
 217            } else if (env->macsr & MACSR_SU) {
 218                regval = acc | (((int64_t)extlow) << 32);
 219                regval |= ((int64_t)exthigh) << 40;
 220            } else {
 221                regval = acc | (((uint64_t)extlow) << 32);
 222                regval |= ((uint64_t)(uint8_t)exthigh) << 40;
 223            }
 224            env->macc[i] = regval;
 225        }
 226    }
 227    env->macsr = val;
 228}
 229
 230void m68k_switch_sp(CPUM68KState *env)
 231{
 232    int new_sp;
 233
 234    env->sp[env->current_sp] = env->aregs[7];
 235    new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
 236             ? M68K_SSP : M68K_USP;
 237    env->aregs[7] = env->sp[new_sp];
 238    env->current_sp = new_sp;
 239}
 240
 241#if defined(CONFIG_USER_ONLY)
 242
 243int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 244                              int mmu_idx)
 245{
 246    M68kCPU *cpu = M68K_CPU(cs);
 247
 248    cs->exception_index = EXCP_ACCESS;
 249    cpu->env.mmu.ar = address;
 250    return 1;
 251}
 252
 253#else
 254
 255/* MMU */
 256
 257/* TODO: This will need fixing once the MMU is implemented.  */
 258hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 259{
 260    return addr;
 261}
 262
 263int m68k_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
 264                              int mmu_idx)
 265{
 266    int prot;
 267
 268    address &= TARGET_PAGE_MASK;
 269    prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 270    tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
 271    return 0;
 272}
 273
 274/* Notify CPU of a pending interrupt.  Prioritization and vectoring should
 275   be handled by the interrupt controller.  Real hardware only requests
 276   the vector when the interrupt is acknowledged by the CPU.  For
 277   simplicitly we calculate it when the interrupt is signalled.  */
 278void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
 279{
 280    CPUState *cs = CPU(cpu);
 281    CPUM68KState *env = &cpu->env;
 282
 283    env->pending_level = level;
 284    env->pending_vector = vector;
 285    if (level) {
 286        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 287    } else {
 288        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 289    }
 290}
 291
 292#endif
 293
 294uint32_t HELPER(bitrev)(uint32_t x)
 295{
 296    x = ((x >> 1) & 0x55555555u) | ((x << 1) & 0xaaaaaaaau);
 297    x = ((x >> 2) & 0x33333333u) | ((x << 2) & 0xccccccccu);
 298    x = ((x >> 4) & 0x0f0f0f0fu) | ((x << 4) & 0xf0f0f0f0u);
 299    return bswap32(x);
 300}
 301
 302uint32_t HELPER(ff1)(uint32_t x)
 303{
 304    int n;
 305    for (n = 32; x; n--)
 306        x >>= 1;
 307    return n;
 308}
 309
 310uint32_t HELPER(sats)(uint32_t val, uint32_t v)
 311{
 312    /* The result has the opposite sign to the original value.  */
 313    if ((int32_t)v < 0) {
 314        val = (((int32_t)val) >> 31) ^ SIGNBIT;
 315    }
 316    return val;
 317}
 318
 319void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
 320{
 321    env->sr = val & 0xffe0;
 322    cpu_m68k_set_ccr(env, val);
 323    m68k_switch_sp(env);
 324}
 325
 326
 327/* MAC unit.  */
 328/* FIXME: The MAC unit implementation is a bit of a mess.  Some helpers
 329   take values,  others take register numbers and manipulate the contents
 330   in-place.  */
 331void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
 332{
 333    uint32_t mask;
 334    env->macc[dest] = env->macc[src];
 335    mask = MACSR_PAV0 << dest;
 336    if (env->macsr & (MACSR_PAV0 << src))
 337        env->macsr |= mask;
 338    else
 339        env->macsr &= ~mask;
 340}
 341
 342uint64_t HELPER(macmuls)(CPUM68KState *env, uint32_t op1, uint32_t op2)
 343{
 344    int64_t product;
 345    int64_t res;
 346
 347    product = (uint64_t)op1 * op2;
 348    res = (product << 24) >> 24;
 349    if (res != product) {
 350        env->macsr |= MACSR_V;
 351        if (env->macsr & MACSR_OMC) {
 352            /* Make sure the accumulate operation overflows.  */
 353            if (product < 0)
 354                res = ~(1ll << 50);
 355            else
 356                res = 1ll << 50;
 357        }
 358    }
 359    return res;
 360}
 361
 362uint64_t HELPER(macmulu)(CPUM68KState *env, uint32_t op1, uint32_t op2)
 363{
 364    uint64_t product;
 365
 366    product = (uint64_t)op1 * op2;
 367    if (product & (0xffffffull << 40)) {
 368        env->macsr |= MACSR_V;
 369        if (env->macsr & MACSR_OMC) {
 370            /* Make sure the accumulate operation overflows.  */
 371            product = 1ll << 50;
 372        } else {
 373            product &= ((1ull << 40) - 1);
 374        }
 375    }
 376    return product;
 377}
 378
 379uint64_t HELPER(macmulf)(CPUM68KState *env, uint32_t op1, uint32_t op2)
 380{
 381    uint64_t product;
 382    uint32_t remainder;
 383
 384    product = (uint64_t)op1 * op2;
 385    if (env->macsr & MACSR_RT) {
 386        remainder = product & 0xffffff;
 387        product >>= 24;
 388        if (remainder > 0x800000)
 389            product++;
 390        else if (remainder == 0x800000)
 391            product += (product & 1);
 392    } else {
 393        product >>= 24;
 394    }
 395    return product;
 396}
 397
 398void HELPER(macsats)(CPUM68KState *env, uint32_t acc)
 399{
 400    int64_t tmp;
 401    int64_t result;
 402    tmp = env->macc[acc];
 403    result = ((tmp << 16) >> 16);
 404    if (result != tmp) {
 405        env->macsr |= MACSR_V;
 406    }
 407    if (env->macsr & MACSR_V) {
 408        env->macsr |= MACSR_PAV0 << acc;
 409        if (env->macsr & MACSR_OMC) {
 410            /* The result is saturated to 32 bits, despite overflow occurring
 411               at 48 bits.  Seems weird, but that's what the hardware docs
 412               say.  */
 413            result = (result >> 63) ^ 0x7fffffff;
 414        }
 415    }
 416    env->macc[acc] = result;
 417}
 418
 419void HELPER(macsatu)(CPUM68KState *env, uint32_t acc)
 420{
 421    uint64_t val;
 422
 423    val = env->macc[acc];
 424    if (val & (0xffffull << 48)) {
 425        env->macsr |= MACSR_V;
 426    }
 427    if (env->macsr & MACSR_V) {
 428        env->macsr |= MACSR_PAV0 << acc;
 429        if (env->macsr & MACSR_OMC) {
 430            if (val > (1ull << 53))
 431                val = 0;
 432            else
 433                val = (1ull << 48) - 1;
 434        } else {
 435            val &= ((1ull << 48) - 1);
 436        }
 437    }
 438    env->macc[acc] = val;
 439}
 440
 441void HELPER(macsatf)(CPUM68KState *env, uint32_t acc)
 442{
 443    int64_t sum;
 444    int64_t result;
 445
 446    sum = env->macc[acc];
 447    result = (sum << 16) >> 16;
 448    if (result != sum) {
 449        env->macsr |= MACSR_V;
 450    }
 451    if (env->macsr & MACSR_V) {
 452        env->macsr |= MACSR_PAV0 << acc;
 453        if (env->macsr & MACSR_OMC) {
 454            result = (result >> 63) ^ 0x7fffffffffffll;
 455        }
 456    }
 457    env->macc[acc] = result;
 458}
 459
 460void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
 461{
 462    uint64_t val;
 463    val = env->macc[acc];
 464    if (val == 0) {
 465        env->macsr |= MACSR_Z;
 466    } else if (val & (1ull << 47)) {
 467        env->macsr |= MACSR_N;
 468    }
 469    if (env->macsr & (MACSR_PAV0 << acc)) {
 470        env->macsr |= MACSR_V;
 471    }
 472    if (env->macsr & MACSR_FI) {
 473        val = ((int64_t)val) >> 40;
 474        if (val != 0 && val != -1)
 475            env->macsr |= MACSR_EV;
 476    } else if (env->macsr & MACSR_SU) {
 477        val = ((int64_t)val) >> 32;
 478        if (val != 0 && val != -1)
 479            env->macsr |= MACSR_EV;
 480    } else {
 481        if ((val >> 32) != 0)
 482            env->macsr |= MACSR_EV;
 483    }
 484}
 485
 486#define EXTSIGN(val, index) (     \
 487    (index == 0) ? (int8_t)(val) : ((index == 1) ? (int16_t)(val) : (val)) \
 488)
 489
 490#define COMPUTE_CCR(op, x, n, z, v, c) {                                   \
 491    switch (op) {                                                          \
 492    case CC_OP_FLAGS:                                                      \
 493        /* Everything in place.  */                                        \
 494        break;                                                             \
 495    case CC_OP_ADDB:                                                       \
 496    case CC_OP_ADDW:                                                       \
 497    case CC_OP_ADDL:                                                       \
 498        res = n;                                                           \
 499        src2 = v;                                                          \
 500        src1 = EXTSIGN(res - src2, op - CC_OP_ADDB);                       \
 501        c = x;                                                             \
 502        z = n;                                                             \
 503        v = (res ^ src1) & ~(src1 ^ src2);                                 \
 504        break;                                                             \
 505    case CC_OP_SUBB:                                                       \
 506    case CC_OP_SUBW:                                                       \
 507    case CC_OP_SUBL:                                                       \
 508        res = n;                                                           \
 509        src2 = v;                                                          \
 510        src1 = EXTSIGN(res + src2, op - CC_OP_SUBB);                       \
 511        c = x;                                                             \
 512        z = n;                                                             \
 513        v = (res ^ src1) & (src1 ^ src2);                                  \
 514        break;                                                             \
 515    case CC_OP_CMPB:                                                       \
 516    case CC_OP_CMPW:                                                       \
 517    case CC_OP_CMPL:                                                       \
 518        src1 = n;                                                          \
 519        src2 = v;                                                          \
 520        res = EXTSIGN(src1 - src2, op - CC_OP_CMPB);                       \
 521        n = res;                                                           \
 522        z = res;                                                           \
 523        c = src1 < src2;                                                   \
 524        v = (res ^ src1) & (src1 ^ src2);                                  \
 525        break;                                                             \
 526    case CC_OP_LOGIC:                                                      \
 527        c = v = 0;                                                         \
 528        z = n;                                                             \
 529        break;                                                             \
 530    default:                                                               \
 531        cpu_abort(CPU(m68k_env_get_cpu(env)), "Bad CC_OP %d", op);         \
 532    }                                                                      \
 533} while (0)
 534
 535uint32_t cpu_m68k_get_ccr(CPUM68KState *env)
 536{
 537    uint32_t x, c, n, z, v;
 538    uint32_t res, src1, src2;
 539
 540    x = env->cc_x;
 541    n = env->cc_n;
 542    z = env->cc_z;
 543    v = env->cc_v;
 544    c = env->cc_c;
 545
 546    COMPUTE_CCR(env->cc_op, x, n, z, v, c);
 547
 548    n = n >> 31;
 549    z = (z == 0);
 550    v = v >> 31;
 551
 552    return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C;
 553}
 554
 555uint32_t HELPER(get_ccr)(CPUM68KState *env)
 556{
 557    return cpu_m68k_get_ccr(env);
 558}
 559
 560void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t ccr)
 561{
 562    env->cc_x = (ccr & CCF_X ? 1 : 0);
 563    env->cc_n = (ccr & CCF_N ? -1 : 0);
 564    env->cc_z = (ccr & CCF_Z ? 0 : 1);
 565    env->cc_v = (ccr & CCF_V ? -1 : 0);
 566    env->cc_c = (ccr & CCF_C ? 1 : 0);
 567    env->cc_op = CC_OP_FLAGS;
 568}
 569
 570void HELPER(set_ccr)(CPUM68KState *env, uint32_t ccr)
 571{
 572    cpu_m68k_set_ccr(env, ccr);
 573}
 574
 575void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
 576{
 577    uint32_t res, src1, src2;
 578
 579    COMPUTE_CCR(cc_op, env->cc_x, env->cc_n, env->cc_z, env->cc_v, env->cc_c);
 580    env->cc_op = CC_OP_FLAGS;
 581}
 582
 583uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
 584{
 585    int rem;
 586    uint32_t result;
 587
 588    if (env->macsr & MACSR_SU) {
 589        /* 16-bit rounding.  */
 590        rem = val & 0xffffff;
 591        val = (val >> 24) & 0xffffu;
 592        if (rem > 0x800000)
 593            val++;
 594        else if (rem == 0x800000)
 595            val += (val & 1);
 596    } else if (env->macsr & MACSR_RT) {
 597        /* 32-bit rounding.  */
 598        rem = val & 0xff;
 599        val >>= 8;
 600        if (rem > 0x80)
 601            val++;
 602        else if (rem == 0x80)
 603            val += (val & 1);
 604    } else {
 605        /* No rounding.  */
 606        val >>= 8;
 607    }
 608    if (env->macsr & MACSR_OMC) {
 609        /* Saturate.  */
 610        if (env->macsr & MACSR_SU) {
 611            if (val != (uint16_t) val) {
 612                result = ((val >> 63) ^ 0x7fff) & 0xffff;
 613            } else {
 614                result = val & 0xffff;
 615            }
 616        } else {
 617            if (val != (uint32_t)val) {
 618                result = ((uint32_t)(val >> 63) & 0x7fffffff);
 619            } else {
 620                result = (uint32_t)val;
 621            }
 622        }
 623    } else {
 624        /* No saturation.  */
 625        if (env->macsr & MACSR_SU) {
 626            result = val & 0xffff;
 627        } else {
 628            result = (uint32_t)val;
 629        }
 630    }
 631    return result;
 632}
 633
 634uint32_t HELPER(get_macs)(uint64_t val)
 635{
 636    if (val == (int32_t)val) {
 637        return (int32_t)val;
 638    } else {
 639        return (val >> 61) ^ ~SIGNBIT;
 640    }
 641}
 642
 643uint32_t HELPER(get_macu)(uint64_t val)
 644{
 645    if ((val >> 32) == 0) {
 646        return (uint32_t)val;
 647    } else {
 648        return 0xffffffffu;
 649    }
 650}
 651
 652uint32_t HELPER(get_mac_extf)(CPUM68KState *env, uint32_t acc)
 653{
 654    uint32_t val;
 655    val = env->macc[acc] & 0x00ff;
 656    val |= (env->macc[acc] >> 32) & 0xff00;
 657    val |= (env->macc[acc + 1] << 16) & 0x00ff0000;
 658    val |= (env->macc[acc + 1] >> 16) & 0xff000000;
 659    return val;
 660}
 661
 662uint32_t HELPER(get_mac_exti)(CPUM68KState *env, uint32_t acc)
 663{
 664    uint32_t val;
 665    val = (env->macc[acc] >> 32) & 0xffff;
 666    val |= (env->macc[acc + 1] >> 16) & 0xffff0000;
 667    return val;
 668}
 669
 670void HELPER(set_mac_extf)(CPUM68KState *env, uint32_t val, uint32_t acc)
 671{
 672    int64_t res;
 673    int32_t tmp;
 674    res = env->macc[acc] & 0xffffffff00ull;
 675    tmp = (int16_t)(val & 0xff00);
 676    res |= ((int64_t)tmp) << 32;
 677    res |= val & 0xff;
 678    env->macc[acc] = res;
 679    res = env->macc[acc + 1] & 0xffffffff00ull;
 680    tmp = (val & 0xff000000);
 681    res |= ((int64_t)tmp) << 16;
 682    res |= (val >> 16) & 0xff;
 683    env->macc[acc + 1] = res;
 684}
 685
 686void HELPER(set_mac_exts)(CPUM68KState *env, uint32_t val, uint32_t acc)
 687{
 688    int64_t res;
 689    int32_t tmp;
 690    res = (uint32_t)env->macc[acc];
 691    tmp = (int16_t)val;
 692    res |= ((int64_t)tmp) << 32;
 693    env->macc[acc] = res;
 694    res = (uint32_t)env->macc[acc + 1];
 695    tmp = val & 0xffff0000;
 696    res |= (int64_t)tmp << 16;
 697    env->macc[acc + 1] = res;
 698}
 699
 700void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
 701{
 702    uint64_t res;
 703    res = (uint32_t)env->macc[acc];
 704    res |= ((uint64_t)(val & 0xffff)) << 32;
 705    env->macc[acc] = res;
 706    res = (uint32_t)env->macc[acc + 1];
 707    res |= (uint64_t)(val & 0xffff0000) << 16;
 708    env->macc[acc + 1] = res;
 709}
 710