Statistics
| Branch: | Revision:

root / target-mips / op.c @ caa88be0

History | View | Annotate | Download (5.2 kB)

1
/*
2
 *  MIPS emulation micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22

    
23
#include "config.h"
24
#include "exec.h"
25
#include "host-utils.h"
26

    
27
#ifndef CALL_FROM_TB0
28
#define CALL_FROM_TB0(func) func()
29
#endif
30

    
31
/* Load and store */
32
#define MEMSUFFIX _raw
33
#include "op_mem.c"
34
#undef MEMSUFFIX
35
#if !defined(CONFIG_USER_ONLY)
36
#define MEMSUFFIX _user
37
#include "op_mem.c"
38
#undef MEMSUFFIX
39

    
40
#define MEMSUFFIX _super
41
#include "op_mem.c"
42
#undef MEMSUFFIX
43

    
44
#define MEMSUFFIX _kernel
45
#include "op_mem.c"
46
#undef MEMSUFFIX
47
#endif
48

    
49
/* 64 bits arithmetic */
50
#if TARGET_LONG_BITS > HOST_LONG_BITS
51
void op_madd (void)
52
{
53
    CALL_FROM_TB0(do_madd);
54
    FORCE_RET();
55
}
56

    
57
void op_maddu (void)
58
{
59
    CALL_FROM_TB0(do_maddu);
60
    FORCE_RET();
61
}
62

    
63
void op_msub (void)
64
{
65
    CALL_FROM_TB0(do_msub);
66
    FORCE_RET();
67
}
68

    
69
void op_msubu (void)
70
{
71
    CALL_FROM_TB0(do_msubu);
72
    FORCE_RET();
73
}
74

    
75
/* Multiplication variants of the vr54xx. */
76
void op_muls (void)
77
{
78
    CALL_FROM_TB0(do_muls);
79
    FORCE_RET();
80
}
81

    
82
void op_mulsu (void)
83
{
84
    CALL_FROM_TB0(do_mulsu);
85
    FORCE_RET();
86
}
87

    
88
void op_macc (void)
89
{
90
    CALL_FROM_TB0(do_macc);
91
    FORCE_RET();
92
}
93

    
94
void op_macchi (void)
95
{
96
    CALL_FROM_TB0(do_macchi);
97
    FORCE_RET();
98
}
99

    
100
void op_maccu (void)
101
{
102
    CALL_FROM_TB0(do_maccu);
103
    FORCE_RET();
104
}
105
void op_macchiu (void)
106
{
107
    CALL_FROM_TB0(do_macchiu);
108
    FORCE_RET();
109
}
110

    
111
void op_msac (void)
112
{
113
    CALL_FROM_TB0(do_msac);
114
    FORCE_RET();
115
}
116

    
117
void op_msachi (void)
118
{
119
    CALL_FROM_TB0(do_msachi);
120
    FORCE_RET();
121
}
122

    
123
void op_msacu (void)
124
{
125
    CALL_FROM_TB0(do_msacu);
126
    FORCE_RET();
127
}
128

    
129
void op_msachiu (void)
130
{
131
    CALL_FROM_TB0(do_msachiu);
132
    FORCE_RET();
133
}
134

    
135
void op_mulhi (void)
136
{
137
    CALL_FROM_TB0(do_mulhi);
138
    FORCE_RET();
139
}
140

    
141
void op_mulhiu (void)
142
{
143
    CALL_FROM_TB0(do_mulhiu);
144
    FORCE_RET();
145
}
146

    
147
void op_mulshi (void)
148
{
149
    CALL_FROM_TB0(do_mulshi);
150
    FORCE_RET();
151
}
152

    
153
void op_mulshiu (void)
154
{
155
    CALL_FROM_TB0(do_mulshiu);
156
    FORCE_RET();
157
}
158

    
159
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
160

    
161
static always_inline uint64_t get_HILO (void)
162
{
163
    return ((uint64_t)env->HI[env->current_tc][0] << 32) |
164
            ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
165
}
166

    
167
static always_inline void set_HILO (uint64_t HILO)
168
{
169
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
170
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
171
}
172

    
173
static always_inline void set_HIT0_LO (uint64_t HILO)
174
{
175
    env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
176
    T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
177
}
178

    
179
static always_inline void set_HI_LOT0 (uint64_t HILO)
180
{
181
    T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
182
    env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
183
}
184

    
185
/* Multiplication variants of the vr54xx. */
186
void op_muls (void)
187
{
188
    set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
189
    FORCE_RET();
190
}
191

    
192
void op_mulsu (void)
193
{
194
    set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
195
    FORCE_RET();
196
}
197

    
198
void op_macc (void)
199
{
200
    set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
201
    FORCE_RET();
202
}
203

    
204
void op_macchi (void)
205
{
206
    set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
207
    FORCE_RET();
208
}
209

    
210
void op_maccu (void)
211
{
212
    set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
213
    FORCE_RET();
214
}
215

    
216
void op_macchiu (void)
217
{
218
    set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
219
    FORCE_RET();
220
}
221

    
222
void op_msac (void)
223
{
224
    set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
225
    FORCE_RET();
226
}
227

    
228
void op_msachi (void)
229
{
230
    set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
231
    FORCE_RET();
232
}
233

    
234
void op_msacu (void)
235
{
236
    set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
237
    FORCE_RET();
238
}
239

    
240
void op_msachiu (void)
241
{
242
    set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
243
    FORCE_RET();
244
}
245

    
246
void op_mulhi (void)
247
{
248
    set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
249
    FORCE_RET();
250
}
251

    
252
void op_mulhiu (void)
253
{
254
    set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
255
    FORCE_RET();
256
}
257

    
258
void op_mulshi (void)
259
{
260
    set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
261
    FORCE_RET();
262
}
263

    
264
void op_mulshiu (void)
265
{
266
    set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
267
    FORCE_RET();
268
}
269

    
270
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */