Statistics
| Branch: | Revision:

root / target-alpha / op.c @ 6ad02592

History | View | Annotate | Download (9.5 kB)

1
/*
2
 *  Alpha emulation cpu micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2007 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 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
#define DEBUG_OP
22

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

    
27
#include "op_helper.h"
28

    
29
#define REG 0
30
#include "op_template.h"
31

    
32
#define REG 1
33
#include "op_template.h"
34

    
35
#define REG 2
36
#include "op_template.h"
37

    
38
#define REG 3
39
#include "op_template.h"
40

    
41
#define REG 4
42
#include "op_template.h"
43

    
44
#define REG 5
45
#include "op_template.h"
46

    
47
#define REG 6
48
#include "op_template.h"
49

    
50
#define REG 7
51
#include "op_template.h"
52

    
53
#define REG 8
54
#include "op_template.h"
55

    
56
#define REG 9
57
#include "op_template.h"
58

    
59
#define REG 10
60
#include "op_template.h"
61

    
62
#define REG 11
63
#include "op_template.h"
64

    
65
#define REG 12
66
#include "op_template.h"
67

    
68
#define REG 13
69
#include "op_template.h"
70

    
71
#define REG 14
72
#include "op_template.h"
73

    
74
#define REG 15
75
#include "op_template.h"
76

    
77
#define REG 16
78
#include "op_template.h"
79

    
80
#define REG 17
81
#include "op_template.h"
82

    
83
#define REG 18
84
#include "op_template.h"
85

    
86
#define REG 19
87
#include "op_template.h"
88

    
89
#define REG 20
90
#include "op_template.h"
91

    
92
#define REG 21
93
#include "op_template.h"
94

    
95
#define REG 22
96
#include "op_template.h"
97

    
98
#define REG 23
99
#include "op_template.h"
100

    
101
#define REG 24
102
#include "op_template.h"
103

    
104
#define REG 25
105
#include "op_template.h"
106

    
107
#define REG 26
108
#include "op_template.h"
109

    
110
#define REG 27
111
#include "op_template.h"
112

    
113
#define REG 28
114
#include "op_template.h"
115

    
116
#define REG 29
117
#include "op_template.h"
118

    
119
#define REG 30
120
#include "op_template.h"
121

    
122
#define REG 31
123
#include "op_template.h"
124

    
125
/* Debug stuff */
126
void OPPROTO op_no_op (void)
127
{
128
#if !defined (DEBUG_OP)
129
    __asm__ __volatile__("nop" : : : "memory");
130
#endif
131
    RETURN();
132
}
133

    
134
/* Load and stores */
135
#define MEMSUFFIX _raw
136
#include "op_mem.h"
137
#if !defined(CONFIG_USER_ONLY)
138
#define MEMSUFFIX _kernel
139
#include "op_mem.h"
140
#define MEMSUFFIX _executive
141
#include "op_mem.h"
142
#define MEMSUFFIX _supervisor
143
#include "op_mem.h"
144
#define MEMSUFFIX _user
145
#include "op_mem.h"
146
/* This is used for pal modes */
147
#define MEMSUFFIX _data
148
#include "op_mem.h"
149
#endif
150

    
151
/* Misc */
152
void OPPROTO op_load_fpcr (void)
153
{
154
    helper_load_fpcr();
155
    RETURN();
156
}
157

    
158
void OPPROTO op_store_fpcr (void)
159
{
160
    helper_store_fpcr();
161
    RETURN();
162
}
163

    
164
/* Arithmetic */
165
void OPPROTO op_addqv (void)
166
{
167
    helper_addqv();
168
    RETURN();
169
}
170

    
171
void OPPROTO op_addlv (void)
172
{
173
    helper_addlv();
174
    RETURN();
175
}
176

    
177
void OPPROTO op_subqv (void)
178
{
179
    helper_subqv();
180
    RETURN();
181
}
182

    
183
void OPPROTO op_sublv (void)
184
{
185
    helper_sublv();
186
    RETURN();
187
}
188

    
189
void OPPROTO op_mullv (void)
190
{
191
    helper_mullv();
192
    RETURN();
193
}
194

    
195
void OPPROTO op_mulqv (void)
196
{
197
    helper_mulqv();
198
    RETURN();
199
}
200

    
201
void OPPROTO op_umulh (void)
202
{
203
    uint64_t tl, th;
204

    
205
    mulu64(&tl, &th, T0, T1);
206
    T0 = th;
207
    RETURN();
208
}
209

    
210
/* Tests */
211
void OPPROTO op_cmpult (void)
212
{
213
    if (T0 < T1)
214
        T0 = 1;
215
    else
216
        T0 = 0;
217
    RETURN();
218
}
219

    
220
void OPPROTO op_cmpule (void)
221
{
222
    if (T0 <= T1)
223
        T0 = 1;
224
    else
225
        T0 = 0;
226
    RETURN();
227
}
228

    
229
void OPPROTO op_cmpeq (void)
230
{
231
    if (T0 == T1)
232
        T0 = 1;
233
    else
234
        T0 = 0;
235
    RETURN();
236
}
237

    
238
void OPPROTO op_cmplt (void)
239
{
240
    if ((int64_t)T0 < (int64_t)T1)
241
        T0 = 1;
242
    else
243
        T0 = 0;
244
    RETURN();
245
}
246

    
247
void OPPROTO op_cmple (void)
248
{
249
    if ((int64_t)T0 <= (int64_t)T1)
250
        T0 = 1;
251
    else
252
        T0 = 0;
253
    RETURN();
254
}
255

    
256
void OPPROTO op_cmpbge (void)
257
{
258
    helper_cmpbge();
259
    RETURN();
260
}
261

    
262
#if 0 // Qemu does not know how to do this...
263
void OPPROTO op_bcond (void)
264
{
265
    if (T0)
266
        env->pc = T1 & ~3;
267
    else
268
        env->pc = PARAM(1);
269
    RETURN();
270
}
271
#else
272
void OPPROTO op_bcond (void)
273
{
274
    if (T0)
275
        env->pc = T1 & ~3;
276
    else
277
        env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
278
    RETURN();
279
}
280
#endif
281

    
282
/* IEEE floating point arithmetic */
283
/* S floating (single) */
284
void OPPROTO op_adds (void)
285
{
286
    FT0 = float32_add(FT0, FT1, &FP_STATUS);
287
    RETURN();
288
}
289

    
290
void OPPROTO op_subs (void)
291
{
292
    FT0 = float32_sub(FT0, FT1, &FP_STATUS);
293
    RETURN();
294
}
295

    
296
void OPPROTO op_muls (void)
297
{
298
    FT0 = float32_mul(FT0, FT1, &FP_STATUS);
299
    RETURN();
300
}
301

    
302
void OPPROTO op_divs (void)
303
{
304
    FT0 = float32_div(FT0, FT1, &FP_STATUS);
305
    RETURN();
306
}
307

    
308
void OPPROTO op_sqrts (void)
309
{
310
    helper_sqrts();
311
    RETURN();
312
}
313

    
314
void OPPROTO op_cpys (void)
315
{
316
    helper_cpys();
317
    RETURN();
318
}
319

    
320
void OPPROTO op_cpysn (void)
321
{
322
    helper_cpysn();
323
    RETURN();
324
}
325

    
326
void OPPROTO op_cpyse (void)
327
{
328
    helper_cpyse();
329
    RETURN();
330
}
331

    
332
void OPPROTO op_itofs (void)
333
{
334
    helper_itofs();
335
    RETURN();
336
}
337

    
338
void OPPROTO op_ftois (void)
339
{
340
    helper_ftois();
341
    RETURN();
342
}
343

    
344
/* T floating (double) */
345
void OPPROTO op_addt (void)
346
{
347
    FT0 = float64_add(FT0, FT1, &FP_STATUS);
348
    RETURN();
349
}
350

    
351
void OPPROTO op_subt (void)
352
{
353
    FT0 = float64_sub(FT0, FT1, &FP_STATUS);
354
    RETURN();
355
}
356

    
357
void OPPROTO op_mult (void)
358
{
359
    FT0 = float64_mul(FT0, FT1, &FP_STATUS);
360
    RETURN();
361
}
362

    
363
void OPPROTO op_divt (void)
364
{
365
    FT0 = float64_div(FT0, FT1, &FP_STATUS);
366
    RETURN();
367
}
368

    
369
void OPPROTO op_sqrtt (void)
370
{
371
    helper_sqrtt();
372
    RETURN();
373
}
374

    
375
void OPPROTO op_cmptun (void)
376
{
377
    helper_cmptun();
378
    RETURN();
379
}
380

    
381
void OPPROTO op_cmpteq (void)
382
{
383
    helper_cmpteq();
384
    RETURN();
385
}
386

    
387
void OPPROTO op_cmptle (void)
388
{
389
    helper_cmptle();
390
    RETURN();
391
}
392

    
393
void OPPROTO op_cmptlt (void)
394
{
395
    helper_cmptlt();
396
    RETURN();
397
}
398

    
399
void OPPROTO op_itoft (void)
400
{
401
    helper_itoft();
402
    RETURN();
403
}
404

    
405
void OPPROTO op_ftoit (void)
406
{
407
    helper_ftoit();
408
    RETURN();
409
}
410

    
411
/* VAX floating point arithmetic */
412
/* F floating */
413
void OPPROTO op_addf (void)
414
{
415
    helper_addf();
416
    RETURN();
417
}
418

    
419
void OPPROTO op_subf (void)
420
{
421
    helper_subf();
422
    RETURN();
423
}
424

    
425
void OPPROTO op_mulf (void)
426
{
427
    helper_mulf();
428
    RETURN();
429
}
430

    
431
void OPPROTO op_divf (void)
432
{
433
    helper_divf();
434
    RETURN();
435
}
436

    
437
void OPPROTO op_sqrtf (void)
438
{
439
    helper_sqrtf();
440
    RETURN();
441
}
442

    
443
void OPPROTO op_cmpfeq (void)
444
{
445
    helper_cmpfeq();
446
    RETURN();
447
}
448

    
449
void OPPROTO op_cmpfne (void)
450
{
451
    helper_cmpfne();
452
    RETURN();
453
}
454

    
455
void OPPROTO op_cmpflt (void)
456
{
457
    helper_cmpflt();
458
    RETURN();
459
}
460

    
461
void OPPROTO op_cmpfle (void)
462
{
463
    helper_cmpfle();
464
    RETURN();
465
}
466

    
467
void OPPROTO op_cmpfgt (void)
468
{
469
    helper_cmpfgt();
470
    RETURN();
471
}
472

    
473
void OPPROTO op_cmpfge (void)
474
{
475
    helper_cmpfge();
476
    RETURN();
477
}
478

    
479
void OPPROTO op_itoff (void)
480
{
481
    helper_itoff();
482
    RETURN();
483
}
484

    
485
/* G floating */
486
void OPPROTO op_addg (void)
487
{
488
    helper_addg();
489
    RETURN();
490
}
491

    
492
void OPPROTO op_subg (void)
493
{
494
    helper_subg();
495
    RETURN();
496
}
497

    
498
void OPPROTO op_mulg (void)
499
{
500
    helper_mulg();
501
    RETURN();
502
}
503

    
504
void OPPROTO op_divg (void)
505
{
506
    helper_divg();
507
    RETURN();
508
}
509

    
510
void OPPROTO op_sqrtg (void)
511
{
512
    helper_sqrtg();
513
    RETURN();
514
}
515

    
516
void OPPROTO op_cmpgeq (void)
517
{
518
    helper_cmpgeq();
519
    RETURN();
520
}
521

    
522
void OPPROTO op_cmpglt (void)
523
{
524
    helper_cmpglt();
525
    RETURN();
526
}
527

    
528
void OPPROTO op_cmpgle (void)
529
{
530
    helper_cmpgle();
531
    RETURN();
532
}
533

    
534
/* Floating point format conversion */
535
void OPPROTO op_cvtst (void)
536
{
537
    FT0 = (float)FT0;
538
    RETURN();
539
}
540

    
541
void OPPROTO op_cvtqs (void)
542
{
543
    helper_cvtqs();
544
    RETURN();
545
}
546

    
547
void OPPROTO op_cvtts (void)
548
{
549
    FT0 = (float)FT0;
550
    RETURN();
551
}
552

    
553
void OPPROTO op_cvttq (void)
554
{
555
    helper_cvttq();
556
    RETURN();
557
}
558

    
559
void OPPROTO op_cvtqt (void)
560
{
561
    helper_cvtqt();
562
    RETURN();
563
}
564

    
565
void OPPROTO op_cvtqf (void)
566
{
567
    helper_cvtqf();
568
    RETURN();
569
}
570

    
571
void OPPROTO op_cvtgf (void)
572
{
573
    helper_cvtgf();
574
    RETURN();
575
}
576

    
577
void OPPROTO op_cvtgd (void)
578
{
579
    helper_cvtgd();
580
    RETURN();
581
}
582

    
583
void OPPROTO op_cvtgq (void)
584
{
585
    helper_cvtgq();
586
    RETURN();
587
}
588

    
589
void OPPROTO op_cvtqg (void)
590
{
591
    helper_cvtqg();
592
    RETURN();
593
}
594

    
595
void OPPROTO op_cvtdg (void)
596
{
597
    helper_cvtdg();
598
    RETURN();
599
}
600

    
601
void OPPROTO op_cvtlq (void)
602
{
603
    helper_cvtlq();
604
    RETURN();
605
}
606

    
607
void OPPROTO op_cvtql (void)
608
{
609
    helper_cvtql();
610
    RETURN();
611
}
612

    
613
void OPPROTO op_cvtqlv (void)
614
{
615
    helper_cvtqlv();
616
    RETURN();
617
}
618

    
619
void OPPROTO op_cvtqlsv (void)
620
{
621
    helper_cvtqlsv();
622
    RETURN();
623
}
624

    
625
/* PALcode support special instructions */
626
#if !defined (CONFIG_USER_ONLY)
627
void OPPROTO op_hw_rei (void)
628
{
629
    env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
630
    env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
631
    /* XXX: re-enable interrupts and memory mapping */
632
    RETURN();
633
}
634

    
635
void OPPROTO op_hw_ret (void)
636
{
637
    env->pc = T0 & ~3;
638
    env->ipr[IPR_EXC_ADDR] = T0 & 1;
639
    /* XXX: re-enable interrupts and memory mapping */
640
    RETURN();
641
}
642

    
643
void OPPROTO op_mfpr (void)
644
{
645
    helper_mfpr(PARAM(1));
646
    RETURN();
647
}
648

    
649
void OPPROTO op_mtpr (void)
650
{
651
    helper_mtpr(PARAM(1));
652
    RETURN();
653
}
654

    
655
void OPPROTO op_set_alt_mode (void)
656
{
657
    env->saved_mode = env->ps & 0xC;
658
    env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
659
    RETURN();
660
}
661

    
662
void OPPROTO op_restore_mode (void)
663
{
664
    env->ps = (env->ps & ~0xC) | env->saved_mode;
665
    RETURN();
666
}
667

    
668
void OPPROTO op_ld_phys_to_virt (void)
669
{
670
    helper_ld_phys_to_virt();
671
    RETURN();
672
}
673

    
674
void OPPROTO op_st_phys_to_virt (void)
675
{
676
    helper_st_phys_to_virt();
677
    RETURN();
678
}
679
#endif /* !defined (CONFIG_USER_ONLY) */