Statistics
| Branch: | Revision:

root / target-sh4 / op.c @ 390af821

History | View | Annotate | Download (6.4 kB)

1
/*
2
 *  SH4 emulation
3
 *
4
 *  Copyright (c) 2005 Samuel Tardieu
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 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, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include "exec.h"
21

    
22
static inline void set_t(void)
23
{
24
    env->sr |= SR_T;
25
}
26

    
27
static inline void clr_t(void)
28
{
29
    env->sr &= ~SR_T;
30
}
31

    
32
static inline void cond_t(int cond)
33
{
34
    if (cond)
35
        set_t();
36
    else
37
        clr_t();
38
}
39

    
40
void OPPROTO op_cmp_str_T0_T1(void)
41
{
42
    cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
43
           (T0 & 0x0000ff00) == (T1 & 0x0000ff00) ||
44
           (T0 & 0x00ff0000) == (T1 & 0x00ff0000) ||
45
           (T0 & 0xff000000) == (T1 & 0xff000000));
46
    RETURN();
47
}
48

    
49
void OPPROTO op_div0s_T0_T1(void)
50
{
51
    if (T1 & 0x80000000)
52
        env->sr |= SR_Q;
53
    else
54
        env->sr &= ~SR_Q;
55
    if (T0 & 0x80000000)
56
        env->sr |= SR_M;
57
    else
58
        env->sr &= ~SR_M;
59
    cond_t((T1 ^ T0) & 0x80000000);
60
    RETURN();
61
}
62

    
63
void OPPROTO op_div1_T0_T1(void)
64
{
65
    helper_div1_T0_T1();
66
    RETURN();
67
}
68

    
69
void OPPROTO op_shad_T0_T1(void)
70
{
71
    if ((T0 & 0x80000000) == 0)
72
        T1 <<= (T0 & 0x1f);
73
    else if ((T0 & 0x1f) == 0)
74
        T1 = (T1 & 0x80000000)? 0xffffffff : 0;
75
    else
76
        T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1);
77
    RETURN();
78
}
79

    
80
void OPPROTO op_shld_T0_T1(void)
81
{
82
    if ((T0 & 0x80000000) == 0)
83
        T1 <<= (T0 & 0x1f);
84
    else if ((T0 & 0x1f) == 0)
85
        T1 = 0;
86
    else
87
        T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1);
88
    RETURN();
89
}
90

    
91
void OPPROTO op_rotcl_Rn(void)
92
{
93
    helper_rotcl(&env->gregs[PARAM1]);
94
    RETURN();
95
}
96

    
97
void OPPROTO op_rotcr_Rn(void)
98
{
99
    helper_rotcr(&env->gregs[PARAM1]);
100
    RETURN();
101
}
102

    
103
void OPPROTO op_rotl_Rn(void) 
104
{
105
    cond_t(env->gregs[PARAM1] & 0x80000000);
106
    env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
107
    RETURN();
108
}
109

    
110
void OPPROTO op_rotr_Rn(void)
111
{
112
    cond_t(env->gregs[PARAM1] & 1);
113
    env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) |
114
        ((env->sr & SR_T) ? 0x80000000 : 0);
115
    RETURN();
116
}
117

    
118
void OPPROTO op_shal_Rn(void)
119
{
120
    cond_t(env->gregs[PARAM1] & 0x80000000);
121
    env->gregs[PARAM1] <<= 1;
122
    RETURN();
123
}
124

    
125
void OPPROTO op_shar_Rn(void)
126
{
127
    cond_t(env->gregs[PARAM1] & 1);
128
    *(int32_t *)&env->gregs[PARAM1] >>= 1;
129
    RETURN();
130
}
131

    
132
void OPPROTO op_shlr_Rn(void)
133
{
134
    cond_t(env->gregs[PARAM1] & 1);
135
    env->gregs[PARAM1] >>= 1;
136
    RETURN();
137
}
138

    
139
void OPPROTO op_fmov_frN_FT0(void)
140
{
141
    FT0 = env->fregs[PARAM1];
142
    RETURN();
143
}
144

    
145
void OPPROTO op_fmov_drN_DT0(void)
146
{
147
    CPU_DoubleU d;
148

    
149
    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
150
    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
151
    DT0 = d.d;
152
    RETURN();
153
}
154

    
155
void OPPROTO op_fmov_frN_FT1(void)
156
{
157
    FT1 = env->fregs[PARAM1];
158
    RETURN();
159
}
160

    
161
void OPPROTO op_fmov_drN_DT1(void)
162
{
163
    CPU_DoubleU d;
164

    
165
    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
166
    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
167
    DT1 = d.d;
168
    RETURN();
169
}
170

    
171
void OPPROTO op_fmov_FT0_frN(void)
172
{
173
    env->fregs[PARAM1] = FT0;
174
    RETURN();
175
}
176

    
177
void OPPROTO op_fmov_DT0_drN(void)
178
{
179
    CPU_DoubleU d;
180

    
181
    d.d = DT0;
182
    *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
183
    *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
184
    RETURN();
185
}
186

    
187
void OPPROTO op_fadd_FT(void)
188
{
189
    FT0 = float32_add(FT0, FT1, &env->fp_status);
190
    RETURN();
191
}
192

    
193
void OPPROTO op_fadd_DT(void)
194
{
195
    DT0 = float64_add(DT0, DT1, &env->fp_status);
196
    RETURN();
197
}
198

    
199
void OPPROTO op_fsub_FT(void)
200
{
201
    FT0 = float32_sub(FT0, FT1, &env->fp_status);
202
    RETURN();
203
}
204

    
205
void OPPROTO op_fsub_DT(void)
206
{
207
    DT0 = float64_sub(DT0, DT1, &env->fp_status);
208
    RETURN();
209
}
210

    
211
void OPPROTO op_fmul_FT(void)
212
{
213
    FT0 = float32_mul(FT0, FT1, &env->fp_status);
214
    RETURN();
215
}
216

    
217
void OPPROTO op_fmul_DT(void)
218
{
219
    DT0 = float64_mul(DT0, DT1, &env->fp_status);
220
    RETURN();
221
}
222

    
223
void OPPROTO op_fdiv_FT(void)
224
{
225
    FT0 = float32_div(FT0, FT1, &env->fp_status);
226
    RETURN();
227
}
228

    
229
void OPPROTO op_fdiv_DT(void)
230
{
231
    DT0 = float64_div(DT0, DT1, &env->fp_status);
232
    RETURN();
233
}
234

    
235
void OPPROTO op_fcmp_eq_FT(void)
236
{
237
    cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
238
    RETURN();
239
}
240

    
241
void OPPROTO op_fcmp_eq_DT(void)
242
{
243
    cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
244
    RETURN();
245
}
246

    
247
void OPPROTO op_fcmp_gt_FT(void)
248
{
249
    cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
250
    RETURN();
251
}
252

    
253
void OPPROTO op_fcmp_gt_DT(void)
254
{
255
    cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
256
    RETURN();
257
}
258

    
259
void OPPROTO op_float_FT(void)
260
{
261
    FT0 = int32_to_float32(env->fpul, &env->fp_status);
262
    RETURN();
263
}
264

    
265
void OPPROTO op_float_DT(void)
266
{
267
    DT0 = int32_to_float64(env->fpul, &env->fp_status);
268
    RETURN();
269
}
270

    
271
void OPPROTO op_ftrc_FT(void)
272
{
273
    env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
274
    RETURN();
275
}
276

    
277
void OPPROTO op_ftrc_DT(void)
278
{
279
    env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
280
    RETURN();
281
}
282

    
283
void OPPROTO op_fneg_frN(void)
284
{
285
    env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
286
    RETURN();
287
}
288

    
289
void OPPROTO op_fabs_FT(void)
290
{
291
    FT0 = float32_abs(FT0);
292
    RETURN();
293
}
294

    
295
void OPPROTO op_fabs_DT(void)
296
{
297
    DT0 = float64_abs(DT0);
298
    RETURN();
299
}
300

    
301
void OPPROTO op_fcnvsd_FT_DT(void)
302
{
303
    DT0 = float32_to_float64(FT0, &env->fp_status);
304
    RETURN();
305
}
306

    
307
void OPPROTO op_fcnvds_DT_FT(void)
308
{
309
    FT0 = float64_to_float32(DT0, &env->fp_status);
310
    RETURN();
311
}
312

    
313
void OPPROTO op_fsqrt_FT(void)
314
{
315
    FT0 = float32_sqrt(FT0, &env->fp_status);
316
    RETURN();
317
}
318

    
319
void OPPROTO op_fsqrt_DT(void)
320
{
321
    DT0 = float64_sqrt(DT0, &env->fp_status);
322
    RETURN();
323
}
324

    
325
void OPPROTO op_fmov_T0_frN(void)
326
{
327
    *(uint32_t *)&env->fregs[PARAM1] = T0;
328
    RETURN();
329
}
330

    
331
void OPPROTO op_movl_fpul_FT0(void)
332
{
333
    FT0 = *(float32 *)&env->fpul;
334
    RETURN();
335
}
336

    
337
void OPPROTO op_movl_FT0_fpul(void)
338
{
339
    *(float32 *)&env->fpul = FT0;
340
    RETURN();
341
}
342

    
343
/* Load and store */
344
#define MEMSUFFIX _raw
345
#include "op_mem.c"
346
#undef MEMSUFFIX
347
#if !defined(CONFIG_USER_ONLY)
348
#define MEMSUFFIX _user
349
#include "op_mem.c"
350
#undef MEMSUFFIX
351

    
352
#define MEMSUFFIX _kernel
353
#include "op_mem.c"
354
#undef MEMSUFFIX
355
#endif