Statistics
| Branch: | Revision:

root / target-sh4 / op.c @ c047da1a

History | View | Annotate | Download (6.1 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_fmov_frN_FT0(void)
119
{
120
    FT0 = env->fregs[PARAM1];
121
    RETURN();
122
}
123

    
124
void OPPROTO op_fmov_drN_DT0(void)
125
{
126
    CPU_DoubleU d;
127

    
128
    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
129
    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
130
    DT0 = d.d;
131
    RETURN();
132
}
133

    
134
void OPPROTO op_fmov_frN_FT1(void)
135
{
136
    FT1 = env->fregs[PARAM1];
137
    RETURN();
138
}
139

    
140
void OPPROTO op_fmov_drN_DT1(void)
141
{
142
    CPU_DoubleU d;
143

    
144
    d.l.upper = *(uint32_t *)&env->fregs[PARAM1];
145
    d.l.lower = *(uint32_t *)&env->fregs[PARAM1 + 1];
146
    DT1 = d.d;
147
    RETURN();
148
}
149

    
150
void OPPROTO op_fmov_FT0_frN(void)
151
{
152
    env->fregs[PARAM1] = FT0;
153
    RETURN();
154
}
155

    
156
void OPPROTO op_fmov_DT0_drN(void)
157
{
158
    CPU_DoubleU d;
159

    
160
    d.d = DT0;
161
    *(uint32_t *)&env->fregs[PARAM1] = d.l.upper;
162
    *(uint32_t *)&env->fregs[PARAM1 + 1] = d.l.lower;
163
    RETURN();
164
}
165

    
166
void OPPROTO op_fadd_FT(void)
167
{
168
    FT0 = float32_add(FT0, FT1, &env->fp_status);
169
    RETURN();
170
}
171

    
172
void OPPROTO op_fadd_DT(void)
173
{
174
    DT0 = float64_add(DT0, DT1, &env->fp_status);
175
    RETURN();
176
}
177

    
178
void OPPROTO op_fsub_FT(void)
179
{
180
    FT0 = float32_sub(FT0, FT1, &env->fp_status);
181
    RETURN();
182
}
183

    
184
void OPPROTO op_fsub_DT(void)
185
{
186
    DT0 = float64_sub(DT0, DT1, &env->fp_status);
187
    RETURN();
188
}
189

    
190
void OPPROTO op_fmul_FT(void)
191
{
192
    FT0 = float32_mul(FT0, FT1, &env->fp_status);
193
    RETURN();
194
}
195

    
196
void OPPROTO op_fmul_DT(void)
197
{
198
    DT0 = float64_mul(DT0, DT1, &env->fp_status);
199
    RETURN();
200
}
201

    
202
void OPPROTO op_fdiv_FT(void)
203
{
204
    FT0 = float32_div(FT0, FT1, &env->fp_status);
205
    RETURN();
206
}
207

    
208
void OPPROTO op_fdiv_DT(void)
209
{
210
    DT0 = float64_div(DT0, DT1, &env->fp_status);
211
    RETURN();
212
}
213

    
214
void OPPROTO op_fcmp_eq_FT(void)
215
{
216
    cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0);
217
    RETURN();
218
}
219

    
220
void OPPROTO op_fcmp_eq_DT(void)
221
{
222
    cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0);
223
    RETURN();
224
}
225

    
226
void OPPROTO op_fcmp_gt_FT(void)
227
{
228
    cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1);
229
    RETURN();
230
}
231

    
232
void OPPROTO op_fcmp_gt_DT(void)
233
{
234
    cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1);
235
    RETURN();
236
}
237

    
238
void OPPROTO op_float_FT(void)
239
{
240
    FT0 = int32_to_float32(env->fpul, &env->fp_status);
241
    RETURN();
242
}
243

    
244
void OPPROTO op_float_DT(void)
245
{
246
    DT0 = int32_to_float64(env->fpul, &env->fp_status);
247
    RETURN();
248
}
249

    
250
void OPPROTO op_ftrc_FT(void)
251
{
252
    env->fpul = float32_to_int32_round_to_zero(FT0, &env->fp_status);
253
    RETURN();
254
}
255

    
256
void OPPROTO op_ftrc_DT(void)
257
{
258
    env->fpul = float64_to_int32_round_to_zero(DT0, &env->fp_status);
259
    RETURN();
260
}
261

    
262
void OPPROTO op_fneg_frN(void)
263
{
264
    env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]);
265
    RETURN();
266
}
267

    
268
void OPPROTO op_fabs_FT(void)
269
{
270
    FT0 = float32_abs(FT0);
271
    RETURN();
272
}
273

    
274
void OPPROTO op_fabs_DT(void)
275
{
276
    DT0 = float64_abs(DT0);
277
    RETURN();
278
}
279

    
280
void OPPROTO op_fcnvsd_FT_DT(void)
281
{
282
    DT0 = float32_to_float64(FT0, &env->fp_status);
283
    RETURN();
284
}
285

    
286
void OPPROTO op_fcnvds_DT_FT(void)
287
{
288
    FT0 = float64_to_float32(DT0, &env->fp_status);
289
    RETURN();
290
}
291

    
292
void OPPROTO op_fsqrt_FT(void)
293
{
294
    FT0 = float32_sqrt(FT0, &env->fp_status);
295
    RETURN();
296
}
297

    
298
void OPPROTO op_fsqrt_DT(void)
299
{
300
    DT0 = float64_sqrt(DT0, &env->fp_status);
301
    RETURN();
302
}
303

    
304
void OPPROTO op_fmov_T0_frN(void)
305
{
306
    *(uint32_t *)&env->fregs[PARAM1] = T0;
307
    RETURN();
308
}
309

    
310
void OPPROTO op_movl_fpul_FT0(void)
311
{
312
    FT0 = *(float32 *)&env->fpul;
313
    RETURN();
314
}
315

    
316
void OPPROTO op_movl_FT0_fpul(void)
317
{
318
    *(float32 *)&env->fpul = FT0;
319
    RETURN();
320
}
321

    
322
/* Load and store */
323
#define MEMSUFFIX _raw
324
#include "op_mem.c"
325
#undef MEMSUFFIX
326
#if !defined(CONFIG_USER_ONLY)
327
#define MEMSUFFIX _user
328
#include "op_mem.c"
329
#undef MEMSUFFIX
330

    
331
#define MEMSUFFIX _kernel
332
#include "op_mem.c"
333
#undef MEMSUFFIX
334
#endif