Statistics
| Branch: | Revision:

root / target-sparc / op.c @ 7a3f1944

History | View | Annotate | Download (8 kB)

1
/*
2
   SPARC micro operations
3

4
   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
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

    
21
#include "exec.h"
22

    
23
/*XXX*/
24
#define REGNAME g0
25
#define REG (env->gregs[0])
26
#include "op_template.h"
27
#define REGNAME g1
28
#define REG (env->gregs[1])
29
#include "op_template.h"
30
#define REGNAME g2
31
#define REG (env->gregs[2])
32
#include "op_template.h"
33
#define REGNAME g3
34
#define REG (env->gregs[3])
35
#include "op_template.h"
36
#define REGNAME g4
37
#define REG (env->gregs[4])
38
#include "op_template.h"
39
#define REGNAME g5
40
#define REG (env->gregs[5])
41
#include "op_template.h"
42
#define REGNAME g6
43
#define REG (env->gregs[6])
44
#include "op_template.h"
45
#define REGNAME g7
46
#define REG (env->gregs[7])
47
#include "op_template.h"
48
#define REGNAME i0
49
#define REG (env->regwptr[16])
50
#include "op_template.h"
51
#define REGNAME i1
52
#define REG (env->regwptr[17])
53
#include "op_template.h"
54
#define REGNAME i2
55
#define REG (env->regwptr[18])
56
#include "op_template.h"
57
#define REGNAME i3
58
#define REG (env->regwptr[19])
59
#include "op_template.h"
60
#define REGNAME i4
61
#define REG (env->regwptr[20])
62
#include "op_template.h"
63
#define REGNAME i5
64
#define REG (env->regwptr[21])
65
#include "op_template.h"
66
#define REGNAME i6
67
#define REG (env->regwptr[22])
68
#include "op_template.h"
69
#define REGNAME i7
70
#define REG (env->regwptr[23])
71
#include "op_template.h"
72
#define REGNAME l0
73
#define REG (env->regwptr[8])
74
#include "op_template.h"
75
#define REGNAME l1
76
#define REG (env->regwptr[9])
77
#include "op_template.h"
78
#define REGNAME l2
79
#define REG (env->regwptr[10])
80
#include "op_template.h"
81
#define REGNAME l3
82
#define REG (env->regwptr[11])
83
#include "op_template.h"
84
#define REGNAME l4
85
#define REG (env->regwptr[12])
86
#include "op_template.h"
87
#define REGNAME l5
88
#define REG (env->regwptr[13])
89
#include "op_template.h"
90
#define REGNAME l6
91
#define REG (env->regwptr[14])
92
#include "op_template.h"
93
#define REGNAME l7
94
#define REG (env->regwptr[15])
95
#include "op_template.h"
96
#define REGNAME o0
97
#define REG (env->regwptr[0])
98
#include "op_template.h"
99
#define REGNAME o1
100
#define REG (env->regwptr[1])
101
#include "op_template.h"
102
#define REGNAME o2
103
#define REG (env->regwptr[2])
104
#include "op_template.h"
105
#define REGNAME o3
106
#define REG (env->regwptr[3])
107
#include "op_template.h"
108
#define REGNAME o4
109
#define REG (env->regwptr[4])
110
#include "op_template.h"
111
#define REGNAME o5
112
#define REG (env->regwptr[5])
113
#include "op_template.h"
114
#define REGNAME o6
115
#define REG (env->regwptr[6])
116
#include "op_template.h"
117
#define REGNAME o7
118
#define REG (env->regwptr[7])
119
#include "op_template.h"
120

    
121
#define EIP (env->pc)
122

    
123
void OPPROTO op_movl_T0_0(void)
124
{
125
        T0 = 0;
126
}
127

    
128
void OPPROTO op_movl_T0_1(void)
129
{
130
        T0 = 1;
131
}
132

    
133
void OPPROTO op_movl_T0_im(void)
134
{
135
        T0 = PARAM1;
136
}
137

    
138
void OPPROTO op_movl_T1_im(void)
139
{
140
        T1 = PARAM1;
141
}
142

    
143
void OPPROTO op_movl_T2_im(void)
144
{
145
        T2 = PARAM1;
146
}
147

    
148
void OPPROTO op_addl_T1_im(void)
149
{
150
        T1 += PARAM1;
151
}
152

    
153
void OPPROTO op_addl_T1_T2(void)
154
{
155
        T1 += T2;
156
}
157

    
158
void OPPROTO op_subl_T1_T2(void)
159
{
160
        T1 -= T2;
161
}
162

    
163
void OPPROTO op_add_T1_T0 (void)
164
{
165
        T0 += T1;
166
}
167

    
168
void OPPROTO op_and_T1_T0 (void)
169
{
170
        T0 &= T1;
171
}
172

    
173
void OPPROTO op_or_T1_T0 (void)
174
{
175
        T0 |= T1;
176
}
177

    
178
void OPPROTO op_xor_T1_T0 (void)
179
{
180
        T0 ^= T1;
181
}
182

    
183
void OPPROTO op_sub_T1_T0 (void)
184
{
185
        T0 -= T1;
186
}
187

    
188
void OPPROTO op_andn_T1_T0 (void)
189
{
190
        T0 &= ~T1;
191
}
192

    
193
void OPPROTO op_orn_T1_T0 (void)
194
{
195
        T0 |= ~T1;
196
}
197

    
198
void OPPROTO op_xnor_T1_T0 (void)
199
{
200
        T0 ^= ~T1;
201
}
202

    
203
void OPPROTO op_addx_T1_T0 (void)
204
{
205
        T0 += T1+((env->psr & PSR_CARRY)?1:0);
206
}
207

    
208
void OPPROTO op_umul_T1_T0 (void)
209
{
210
        unsigned long long res = T0*T1;
211
        T0 = res & 0xffffffff;
212
        env->y = res >> 32;
213
}
214

    
215
void OPPROTO op_smul_T1_T0 (void)
216
{
217
        long long res = T0*T1;
218
        T0 = res & 0xffffffff;
219
        env->y = res >> 32;
220
}
221

    
222
void OPPROTO op_udiv_T1_T0 (void)
223
{
224
        unsigned long long x0 = T0 * env->y;
225
        unsigned int x1 = T1;
226
        T0 = x0 / x1;
227
}
228

    
229
void OPPROTO op_sdiv_T1_T0 (void)
230
{
231
        long long x0 = T0 * env->y;
232
        int x1 = T1;
233
        T0 = x0 / x1;
234
}
235

    
236
void OPPROTO op_subx_T1_T0 (void)
237
{
238
        T0 -= T1+((env->psr & PSR_CARRY)?1:0);
239
}
240

    
241
void OPPROTO op_set_flags (void)
242
{
243
        env->psr = 0;
244
        if (!T0) env->psr |= PSR_ZERO;
245
        if ((unsigned int) T0 < (unsigned int) T1) env->psr |= PSR_CARRY;
246
        if ((int) T0 < (int) T1) env->psr |= PSR_OVF;
247
        if ((int) T0 < 0) env->psr |= PSR_NEG;
248
}
249

    
250
void OPPROTO op_sll (void)
251
{
252
        T0 <<= T1;
253
}
254

    
255
void OPPROTO op_srl (void)
256
{
257
        T0 >>= T1;
258
}
259

    
260
void OPPROTO op_sra (void)
261
{
262
        int x = T0 >> T1;
263
        T0 = x;
264
}
265

    
266
void OPPROTO op_st (void)
267
{
268
        stl ((void *) T0, T1);
269
}
270

    
271
void OPPROTO op_stb (void)
272
{
273
        stb ((void *) T0, T1);
274
}
275

    
276
void OPPROTO op_sth (void)
277
{
278
        stw ((void *) T0, T1);
279
}
280

    
281
void OPPROTO op_ld (void)
282
{
283
        T1 = ldl ((void *) T0);
284
}
285

    
286
void OPPROTO op_ldub (void)
287
{
288
        T1 = ldub ((void *) T0);
289
}
290

    
291
void OPPROTO op_lduh (void)
292
{
293
        T1 = lduw ((void *) T0);
294
}
295

    
296
void OPPROTO op_ldsb (void)
297
{
298
        T1 = ldsb ((void *) T0);
299
}
300

    
301
void OPPROTO op_ldsh (void)
302
{
303
        T1 = ldsw ((void *) T0);
304
}
305

    
306
void OPPROTO op_ldstub (void)
307
{
308
        T1 = ldub ((void *) T0);
309
        stb ((void *) T0, 0xff); /* XXX: Should be Atomically */
310
}
311

    
312
void OPPROTO op_swap (void)
313
{
314
        unsigned int tmp = ldl ((void *) T0);
315
        stl ((void *) T0, T1);   /* XXX: Should be Atomically */
316
        T1 = tmp;
317
}
318

    
319
void OPPROTO op_ldd (void)
320
{
321
        T1 = ldl ((void *) T0);
322
        T0 = ldl ((void *) T0+4);
323
}
324

    
325
void OPPROTO op_wry (void)
326
{
327
        env->y = T0^T1;
328
}
329

    
330
void OPPROTO op_rdy (void)
331
{
332
        T0 = env->y;
333
}
334

    
335
#define regwptr (env->regwptr)
336

    
337
void OPPROTO op_save (void)
338
{
339
        regwptr -= 16;
340
}
341

    
342
void OPPROTO op_restore (void)
343
{
344
        regwptr += 16;
345
}
346

    
347
void OPPROTO op_trap (void)
348
{
349
        env->exception_index = PARAM1;
350
        cpu_loop_exit ();
351
}
352

    
353
void OPPROTO op_exit_tb (void)
354
{
355
        EXIT_TB ();
356
}
357

    
358
void OPPROTO op_eval_be (void)
359
{
360
        T0 = (env->psr & PSR_ZERO);
361
}
362

    
363
#define FLAG_SET(x) (env->psr&x)?1:0
364
#define GET_FLAGS unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF), C = FLAG_SET(PSR_CARRY)
365

    
366
void OPPROTO op_eval_ble (void)
367
{
368
        GET_FLAGS;
369
        T0 = Z | (N^V);
370
}
371

    
372
void OPPROTO op_eval_bl (void)
373
{
374
        GET_FLAGS;
375
        T0 = N^V;
376
}
377

    
378
void OPPROTO op_eval_bleu (void)
379
{
380
        GET_FLAGS;
381
        T0 = C|Z;
382
}
383

    
384
void OPPROTO op_eval_bcs (void)
385
{
386
        T0 = (env->psr & PSR_CARRY);
387
}
388

    
389
void OPPROTO op_eval_bvs (void)
390
{
391
        T0 = (env->psr & PSR_OVF);
392
}
393

    
394
void OPPROTO op_eval_bneg (void)
395
{
396
        T0 = (env->psr & PSR_NEG);
397
}
398

    
399
void OPPROTO op_eval_bne (void)
400
{
401
        T0 = !(env->psr & PSR_ZERO);
402
}
403

    
404
void OPPROTO op_eval_bg (void)
405
{
406
        GET_FLAGS;
407
        T0 = !(Z | (N^V));
408
}
409

    
410
/*XXX: This seems to be documented wrong in the SPARC V8 Manual
411
  The manual states: !(N^V)
412
  but I assume Z | !(N^V) to be correct */
413
void OPPROTO op_eval_bge (void)
414
{
415
        GET_FLAGS;
416
        T0 = Z | !(N^V);
417
}
418

    
419
void OPPROTO op_eval_bgu (void)
420
{
421
        GET_FLAGS;
422
        T0 = !(C | Z);
423
}
424

    
425
void OPPROTO op_eval_bcc (void)
426
{
427
        T0 = !(env->psr & PSR_CARRY);
428
}
429

    
430
void OPPROTO op_eval_bpos (void)
431
{
432
        T0 = !(env->psr & PSR_NEG);
433
}
434

    
435
void OPPROTO op_eval_bvc (void)
436
{
437
        T0 = !(env->psr & PSR_OVF);
438
}
439

    
440
void OPPROTO op_jmp_im (void)
441
{
442
        env->pc = PARAM1;
443
}
444

    
445
void OPPROTO op_call (void)
446
{
447
        regwptr[7] = PARAM1-4;
448
        env->pc = PARAM1+PARAM2;
449
}
450

    
451
void OPPROTO op_jmpl (void)
452
{
453
        env->npc = T0;
454
}
455

    
456
void OPPROTO op_generic_jmp_1 (void)
457
{
458
        T1 = PARAM1;
459
        env->pc = PARAM1+PARAM2;
460
}
461

    
462
void OPPROTO op_generic_jmp_2 (void)
463
{
464
        T1 = PARAM1;
465
        env->pc = env->npc;
466
}
467

    
468
unsigned long old_T0;
469

    
470
void OPPROTO op_save_T0 (void)
471
{
472
        old_T0 = T0;
473
}
474

    
475
void OPPROTO op_restore_T0 (void)
476
{
477
        T0 = old_T0;
478
}
479

    
480
void OPPROTO op_generic_branch (void)
481
{
482
        if (T0)
483
                JUMP_TB (__func__, PARAM1, 0, PARAM2);
484
        else
485
                JUMP_TB (__func__, PARAM1, 1, PARAM3);
486
        FORCE_RET ();
487
}
488

    
489
void OPPROTO op_generic_branch_a (void)
490
{
491
        if (T0)
492
                env->npc = PARAM3;
493
        else
494
                JUMP_TB (__func__, PARAM1, 0, PARAM2);
495
        FORCE_RET ();
496
}
497

    
498
void OPPROTO op_noop (void)
499
{
500
}