qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

vr54xx_helper.c (5039B)


      1 /*
      2  *  MIPS VR5432 emulation helpers
      3  *
      4  *  Copyright (c) 2004-2005 Jocelyn Mayer
      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.1 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, see <http://www.gnu.org/licenses/>.
     18  *
     19  * SPDX-License-Identifier: LGPL-2.1-or-later
     20  */
     21 
     22 #include "qemu/osdep.h"
     23 #include "cpu.h"
     24 #include "exec/helper-proto.h"
     25 
     26 /* 64 bits arithmetic for 32 bits hosts */
     27 static inline uint64_t get_HILO(CPUMIPSState *env)
     28 {
     29     return ((uint64_t)(env->active_tc.HI[0]) << 32) |
     30            (uint32_t)env->active_tc.LO[0];
     31 }
     32 
     33 static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO)
     34 {
     35     env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
     36     return env->active_tc.HI[0] = (int32_t)(HILO >> 32);
     37 }
     38 
     39 static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO)
     40 {
     41     target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
     42     env->active_tc.HI[0] = (int32_t)(HILO >> 32);
     43     return tmp;
     44 }
     45 
     46 /* Multiplication variants of the vr54xx. */
     47 target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1,
     48                          target_ulong arg2)
     49 {
     50     return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 *
     51                                  (int64_t)(int32_t)arg2));
     52 }
     53 
     54 target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1,
     55                           target_ulong arg2)
     56 {
     57     return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 *
     58                                 (uint64_t)(uint32_t)arg2);
     59 }
     60 
     61 target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1,
     62                          target_ulong arg2)
     63 {
     64     return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
     65                                                      (int64_t)(int32_t)arg2);
     66 }
     67 
     68 target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1,
     69                            target_ulong arg2)
     70 {
     71     return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
     72                        (int64_t)(int32_t)arg2);
     73 }
     74 
     75 target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1,
     76                           target_ulong arg2)
     77 {
     78     return set_HI_LOT0(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 *
     79                                                       (uint64_t)(uint32_t)arg2);
     80 }
     81 
     82 target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1,
     83                             target_ulong arg2)
     84 {
     85     return set_HIT0_LO(env, (uint64_t)get_HILO(env) + (uint64_t)(uint32_t)arg1 *
     86                                                       (uint64_t)(uint32_t)arg2);
     87 }
     88 
     89 target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1,
     90                          target_ulong arg2)
     91 {
     92     return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
     93                                                      (int64_t)(int32_t)arg2);
     94 }
     95 
     96 target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1,
     97                            target_ulong arg2)
     98 {
     99     return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
    100                                                      (int64_t)(int32_t)arg2);
    101 }
    102 
    103 target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1,
    104                           target_ulong arg2)
    105 {
    106     return set_HI_LOT0(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 *
    107                                                       (uint64_t)(uint32_t)arg2);
    108 }
    109 
    110 target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1,
    111                             target_ulong arg2)
    112 {
    113     return set_HIT0_LO(env, (uint64_t)get_HILO(env) - (uint64_t)(uint32_t)arg1 *
    114                                                       (uint64_t)(uint32_t)arg2);
    115 }
    116 
    117 target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1,
    118                           target_ulong arg2)
    119 {
    120     return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
    121 }
    122 
    123 target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1,
    124                            target_ulong arg2)
    125 {
    126     return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 *
    127                             (uint64_t)(uint32_t)arg2);
    128 }
    129 
    130 target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1,
    131                            target_ulong arg2)
    132 {
    133     return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 *
    134                                 (int64_t)(int32_t)arg2);
    135 }
    136 
    137 target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1,
    138                             target_ulong arg2)
    139 {
    140     return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 *
    141                                 (uint64_t)(uint32_t)arg2);
    142 }