xref: /openbmc/qemu/target/mips/tcg/vr54xx_helper.c (revision 2df1eb27)
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 }
143