Statistics
| Branch: | Revision:

root / target-alpha / op.c @ 4f821e17

History | View | Annotate | Download (13.7 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_excp (void)
153
{
154
    helper_excp(PARAM(1), PARAM(2));
155
    RETURN();
156
}
157

    
158
void OPPROTO op_load_amask (void)
159
{
160
    helper_amask();
161
    RETURN();
162
}
163

    
164
void OPPROTO op_load_pcc (void)
165
{
166
    helper_load_pcc();
167
    RETURN();
168
}
169

    
170
void OPPROTO op_load_implver (void)
171
{
172
    helper_load_implver();
173
    RETURN();
174
}
175

    
176
void OPPROTO op_load_fpcr (void)
177
{
178
    helper_load_fpcr();
179
    RETURN();
180
}
181

    
182
void OPPROTO op_store_fpcr (void)
183
{
184
    helper_store_fpcr();
185
    RETURN();
186
}
187

    
188
void OPPROTO op_load_irf (void)
189
{
190
    helper_load_irf();
191
    RETURN();
192
}
193

    
194
void OPPROTO op_set_irf (void)
195
{
196
    helper_set_irf();
197
    RETURN();
198
}
199

    
200
void OPPROTO op_clear_irf (void)
201
{
202
    helper_clear_irf();
203
    RETURN();
204
}
205

    
206
/* Arithmetic */
207
void OPPROTO op_addq (void)
208
{
209
    T0 += T1;
210
    RETURN();
211
}
212

    
213
void OPPROTO op_addqv (void)
214
{
215
    helper_addqv();
216
    RETURN();
217
}
218

    
219
void OPPROTO op_addl (void)
220
{
221
    T0 = (int64_t)((int32_t)(T0 + T1));
222
    RETURN();
223
}
224

    
225
void OPPROTO op_addlv (void)
226
{
227
    helper_addlv();
228
    RETURN();
229
}
230

    
231
void OPPROTO op_subq (void)
232
{
233
    T0 -= T1;
234
    RETURN();
235
}
236

    
237
void OPPROTO op_subqv (void)
238
{
239
    helper_subqv();
240
    RETURN();
241
}
242

    
243
void OPPROTO op_subl (void)
244
{
245
    T0 = (int64_t)((int32_t)(T0 - T1));
246
    RETURN();
247
}
248

    
249
void OPPROTO op_sublv (void)
250
{
251
    helper_sublv();
252
    RETURN();
253
}
254

    
255
void OPPROTO op_mull (void)
256
{
257
    T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
258
    RETURN();
259
}
260

    
261
void OPPROTO op_mullv (void)
262
{
263
    helper_mullv();
264
    RETURN();
265
}
266

    
267
void OPPROTO op_mulq (void)
268
{
269
    T0 = (int64_t)T0 * (int64_t)T1;
270
    RETURN();
271
}
272

    
273
void OPPROTO op_mulqv (void)
274
{
275
    helper_mulqv();
276
    RETURN();
277
}
278

    
279
void OPPROTO op_umulh (void)
280
{
281
    uint64_t tl, th;
282

    
283
    mulu64(&tl, &th, T0, T1);
284
    T0 = th;
285
    RETURN();
286
}
287

    
288
/* Logical */
289
void OPPROTO op_and (void)
290
{
291
    T0 &= T1;
292
    RETURN();
293
}
294

    
295
void OPPROTO op_bic (void)
296
{
297
    T0 &= ~T1;
298
    RETURN();
299
}
300

    
301
void OPPROTO op_bis (void)
302
{
303
    T0 |= T1;
304
    RETURN();
305
}
306

    
307
void OPPROTO op_eqv (void)
308
{
309
    T0 ^= ~T1;
310
    RETURN();
311
}
312

    
313
void OPPROTO op_ornot (void)
314
{
315
    T0 |= ~T1;
316
    RETURN();
317
}
318

    
319
void OPPROTO op_xor (void)
320
{
321
    T0 ^= T1;
322
    RETURN();
323
}
324

    
325
void OPPROTO op_sll (void)
326
{
327
    T0 <<= T1;
328
    RETURN();
329
}
330

    
331
void OPPROTO op_srl (void)
332
{
333
    T0 >>= T1;
334
    RETURN();
335
}
336

    
337
void OPPROTO op_sra (void)
338
{
339
    T0 = (int64_t)T0 >> T1;
340
    RETURN();
341
}
342

    
343
void OPPROTO op_sextb (void)
344
{
345
    T0 = (int64_t)((int8_t)T0);
346
    RETURN();
347
}
348

    
349
void OPPROTO op_sextw (void)
350
{
351
    T0 = (int64_t)((int16_t)T0);
352
    RETURN();
353

    
354
}
355

    
356
void OPPROTO op_ctpop (void)
357
{
358
    helper_ctpop();
359
    RETURN();
360
}
361

    
362
void OPPROTO op_ctlz (void)
363
{
364
    helper_ctlz();
365
    RETURN();
366
}
367

    
368
void OPPROTO op_cttz (void)
369
{
370
    helper_cttz();
371
    RETURN();
372
}
373

    
374
void OPPROTO op_mskbl (void)
375
{
376
    helper_mskbl();
377
    RETURN();
378
}
379

    
380
void OPPROTO op_extbl (void)
381
{
382
    helper_extbl();
383
    RETURN();
384
}
385

    
386
void OPPROTO op_insbl (void)
387
{
388
    helper_insbl();
389
    RETURN();
390
}
391

    
392
void OPPROTO op_mskwl (void)
393
{
394
    helper_mskwl();
395
    RETURN();
396
}
397

    
398
void OPPROTO op_extwl (void)
399
{
400
    helper_extwl();
401
    RETURN();
402
}
403

    
404
void OPPROTO op_inswl (void)
405
{
406
    helper_inswl();
407
    RETURN();
408
}
409

    
410
void OPPROTO op_mskll (void)
411
{
412
    helper_mskll();
413
    RETURN();
414
}
415

    
416
void OPPROTO op_extll (void)
417
{
418
    helper_extll();
419
    RETURN();
420
}
421

    
422
void OPPROTO op_insll (void)
423
{
424
    helper_insll();
425
    RETURN();
426
}
427

    
428
void OPPROTO op_zap (void)
429
{
430
    helper_zap();
431
    RETURN();
432
}
433

    
434
void OPPROTO op_zapnot (void)
435
{
436
    helper_zapnot();
437
    RETURN();
438
}
439

    
440
void OPPROTO op_mskql (void)
441
{
442
    helper_mskql();
443
    RETURN();
444
}
445

    
446
void OPPROTO op_extql (void)
447
{
448
    helper_extql();
449
    RETURN();
450
}
451

    
452
void OPPROTO op_insql (void)
453
{
454
    helper_insql();
455
    RETURN();
456
}
457

    
458
void OPPROTO op_mskwh (void)
459
{
460
    helper_mskwh();
461
    RETURN();
462
}
463

    
464
void OPPROTO op_inswh (void)
465
{
466
    helper_inswh();
467
    RETURN();
468
}
469

    
470
void OPPROTO op_extwh (void)
471
{
472
    helper_extwh();
473
    RETURN();
474
}
475

    
476
void OPPROTO op_msklh (void)
477
{
478
    helper_msklh();
479
    RETURN();
480
}
481

    
482
void OPPROTO op_inslh (void)
483
{
484
    helper_inslh();
485
    RETURN();
486
}
487

    
488
void OPPROTO op_extlh (void)
489
{
490
    helper_extlh();
491
    RETURN();
492
}
493

    
494
void OPPROTO op_mskqh (void)
495
{
496
    helper_mskqh();
497
    RETURN();
498
}
499

    
500
void OPPROTO op_insqh (void)
501
{
502
    helper_insqh();
503
    RETURN();
504
}
505

    
506
void OPPROTO op_extqh (void)
507
{
508
    helper_extqh();
509
    RETURN();
510
}
511

    
512
/* Tests */
513
void OPPROTO op_cmpult (void)
514
{
515
    if (T0 < T1)
516
        T0 = 1;
517
    else
518
        T0 = 0;
519
    RETURN();
520
}
521

    
522
void OPPROTO op_cmpule (void)
523
{
524
    if (T0 <= T1)
525
        T0 = 1;
526
    else
527
        T0 = 0;
528
    RETURN();
529
}
530

    
531
void OPPROTO op_cmpeq (void)
532
{
533
    if (T0 == T1)
534
        T0 = 1;
535
    else
536
        T0 = 0;
537
    RETURN();
538
}
539

    
540
void OPPROTO op_cmplt (void)
541
{
542
    if ((int64_t)T0 < (int64_t)T1)
543
        T0 = 1;
544
    else
545
        T0 = 0;
546
    RETURN();
547
}
548

    
549
void OPPROTO op_cmple (void)
550
{
551
    if ((int64_t)T0 <= (int64_t)T1)
552
        T0 = 1;
553
    else
554
        T0 = 0;
555
    RETURN();
556
}
557

    
558
void OPPROTO op_cmpbge (void)
559
{
560
    helper_cmpbge();
561
    RETURN();
562
}
563

    
564
void OPPROTO op_cmpeqz (void)
565
{
566
    if (T0 == 0)
567
        T0 = 1;
568
    else
569
        T0 = 0;
570
    RETURN();
571
}
572

    
573
void OPPROTO op_cmpnez (void)
574
{
575
    if (T0 != 0)
576
        T0 = 1;
577
    else
578
        T0 = 0;
579
    RETURN();
580
}
581

    
582
void OPPROTO op_cmpltz (void)
583
{
584
    if ((int64_t)T0 < 0)
585
        T0 = 1;
586
    else
587
        T0 = 0;
588
    RETURN();
589
}
590

    
591
void OPPROTO op_cmplez (void)
592
{
593
    if ((int64_t)T0 <= 0)
594
        T0 = 1;
595
    else
596
        T0 = 0;
597
    RETURN();
598
}
599

    
600
void OPPROTO op_cmpgtz (void)
601
{
602
    if ((int64_t)T0 > 0)
603
        T0 = 1;
604
    else
605
        T0 = 0;
606
    RETURN();
607
}
608

    
609
void OPPROTO op_cmpgez (void)
610
{
611
    if ((int64_t)T0 >= 0)
612
        T0 = 1;
613
    else
614
        T0 = 0;
615
    RETURN();
616
}
617

    
618
void OPPROTO op_cmplbs (void)
619
{
620
    T0 &= 1;
621
    RETURN();
622
}
623

    
624
void OPPROTO op_cmplbc (void)
625
{
626
    T0 = (~T0) & 1;
627
    RETURN();
628
}
629

    
630
#if 0 // Qemu does not know how to do this...
631
void OPPROTO op_bcond (void)
632
{
633
    if (T0)
634
        env->pc = T1 & ~3;
635
    else
636
        env->pc = PARAM(1);
637
    RETURN();
638
}
639
#else
640
void OPPROTO op_bcond (void)
641
{
642
    if (T0)
643
        env->pc = T1 & ~3;
644
    else
645
        env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
646
    RETURN();
647
}
648
#endif
649

    
650
/* IEEE floating point arithmetic */
651
/* S floating (single) */
652
void OPPROTO op_adds (void)
653
{
654
    FT0 = float32_add(FT0, FT1, &FP_STATUS);
655
    RETURN();
656
}
657

    
658
void OPPROTO op_subs (void)
659
{
660
    FT0 = float32_sub(FT0, FT1, &FP_STATUS);
661
    RETURN();
662
}
663

    
664
void OPPROTO op_muls (void)
665
{
666
    FT0 = float32_mul(FT0, FT1, &FP_STATUS);
667
    RETURN();
668
}
669

    
670
void OPPROTO op_divs (void)
671
{
672
    FT0 = float32_div(FT0, FT1, &FP_STATUS);
673
    RETURN();
674
}
675

    
676
void OPPROTO op_sqrts (void)
677
{
678
    helper_sqrts();
679
    RETURN();
680
}
681

    
682
void OPPROTO op_cpys (void)
683
{
684
    helper_cpys();
685
    RETURN();
686
}
687

    
688
void OPPROTO op_cpysn (void)
689
{
690
    helper_cpysn();
691
    RETURN();
692
}
693

    
694
void OPPROTO op_cpyse (void)
695
{
696
    helper_cpyse();
697
    RETURN();
698
}
699

    
700
void OPPROTO op_itofs (void)
701
{
702
    helper_itofs();
703
    RETURN();
704
}
705

    
706
void OPPROTO op_ftois (void)
707
{
708
    helper_ftois();
709
    RETURN();
710
}
711

    
712
/* T floating (double) */
713
void OPPROTO op_addt (void)
714
{
715
    FT0 = float64_add(FT0, FT1, &FP_STATUS);
716
    RETURN();
717
}
718

    
719
void OPPROTO op_subt (void)
720
{
721
    FT0 = float64_sub(FT0, FT1, &FP_STATUS);
722
    RETURN();
723
}
724

    
725
void OPPROTO op_mult (void)
726
{
727
    FT0 = float64_mul(FT0, FT1, &FP_STATUS);
728
    RETURN();
729
}
730

    
731
void OPPROTO op_divt (void)
732
{
733
    FT0 = float64_div(FT0, FT1, &FP_STATUS);
734
    RETURN();
735
}
736

    
737
void OPPROTO op_sqrtt (void)
738
{
739
    helper_sqrtt();
740
    RETURN();
741
}
742

    
743
void OPPROTO op_cmptun (void)
744
{
745
    helper_cmptun();
746
    RETURN();
747
}
748

    
749
void OPPROTO op_cmpteq (void)
750
{
751
    helper_cmpteq();
752
    RETURN();
753
}
754

    
755
void OPPROTO op_cmptle (void)
756
{
757
    helper_cmptle();
758
    RETURN();
759
}
760

    
761
void OPPROTO op_cmptlt (void)
762
{
763
    helper_cmptlt();
764
    RETURN();
765
}
766

    
767
void OPPROTO op_itoft (void)
768
{
769
    helper_itoft();
770
    RETURN();
771
}
772

    
773
void OPPROTO op_ftoit (void)
774
{
775
    helper_ftoit();
776
    RETURN();
777
}
778

    
779
/* VAX floating point arithmetic */
780
/* F floating */
781
void OPPROTO op_addf (void)
782
{
783
    helper_addf();
784
    RETURN();
785
}
786

    
787
void OPPROTO op_subf (void)
788
{
789
    helper_subf();
790
    RETURN();
791
}
792

    
793
void OPPROTO op_mulf (void)
794
{
795
    helper_mulf();
796
    RETURN();
797
}
798

    
799
void OPPROTO op_divf (void)
800
{
801
    helper_divf();
802
    RETURN();
803
}
804

    
805
void OPPROTO op_sqrtf (void)
806
{
807
    helper_sqrtf();
808
    RETURN();
809
}
810

    
811
void OPPROTO op_cmpfeq (void)
812
{
813
    helper_cmpfeq();
814
    RETURN();
815
}
816

    
817
void OPPROTO op_cmpfne (void)
818
{
819
    helper_cmpfne();
820
    RETURN();
821
}
822

    
823
void OPPROTO op_cmpflt (void)
824
{
825
    helper_cmpflt();
826
    RETURN();
827
}
828

    
829
void OPPROTO op_cmpfle (void)
830
{
831
    helper_cmpfle();
832
    RETURN();
833
}
834

    
835
void OPPROTO op_cmpfgt (void)
836
{
837
    helper_cmpfgt();
838
    RETURN();
839
}
840

    
841
void OPPROTO op_cmpfge (void)
842
{
843
    helper_cmpfge();
844
    RETURN();
845
}
846

    
847
void OPPROTO op_itoff (void)
848
{
849
    helper_itoff();
850
    RETURN();
851
}
852

    
853
/* G floating */
854
void OPPROTO op_addg (void)
855
{
856
    helper_addg();
857
    RETURN();
858
}
859

    
860
void OPPROTO op_subg (void)
861
{
862
    helper_subg();
863
    RETURN();
864
}
865

    
866
void OPPROTO op_mulg (void)
867
{
868
    helper_mulg();
869
    RETURN();
870
}
871

    
872
void OPPROTO op_divg (void)
873
{
874
    helper_divg();
875
    RETURN();
876
}
877

    
878
void OPPROTO op_sqrtg (void)
879
{
880
    helper_sqrtg();
881
    RETURN();
882
}
883

    
884
void OPPROTO op_cmpgeq (void)
885
{
886
    helper_cmpgeq();
887
    RETURN();
888
}
889

    
890
void OPPROTO op_cmpglt (void)
891
{
892
    helper_cmpglt();
893
    RETURN();
894
}
895

    
896
void OPPROTO op_cmpgle (void)
897
{
898
    helper_cmpgle();
899
    RETURN();
900
}
901

    
902
/* Floating point format conversion */
903
void OPPROTO op_cvtst (void)
904
{
905
    FT0 = (float)FT0;
906
    RETURN();
907
}
908

    
909
void OPPROTO op_cvtqs (void)
910
{
911
    helper_cvtqs();
912
    RETURN();
913
}
914

    
915
void OPPROTO op_cvtts (void)
916
{
917
    FT0 = (float)FT0;
918
    RETURN();
919
}
920

    
921
void OPPROTO op_cvttq (void)
922
{
923
    helper_cvttq();
924
    RETURN();
925
}
926

    
927
void OPPROTO op_cvtqt (void)
928
{
929
    helper_cvtqt();
930
    RETURN();
931
}
932

    
933
void OPPROTO op_cvtqf (void)
934
{
935
    helper_cvtqf();
936
    RETURN();
937
}
938

    
939
void OPPROTO op_cvtgf (void)
940
{
941
    helper_cvtgf();
942
    RETURN();
943
}
944

    
945
void OPPROTO op_cvtgd (void)
946
{
947
    helper_cvtgd();
948
    RETURN();
949
}
950

    
951
void OPPROTO op_cvtgq (void)
952
{
953
    helper_cvtgq();
954
    RETURN();
955
}
956

    
957
void OPPROTO op_cvtqg (void)
958
{
959
    helper_cvtqg();
960
    RETURN();
961
}
962

    
963
void OPPROTO op_cvtdg (void)
964
{
965
    helper_cvtdg();
966
    RETURN();
967
}
968

    
969
void OPPROTO op_cvtlq (void)
970
{
971
    helper_cvtlq();
972
    RETURN();
973
}
974

    
975
void OPPROTO op_cvtql (void)
976
{
977
    helper_cvtql();
978
    RETURN();
979
}
980

    
981
void OPPROTO op_cvtqlv (void)
982
{
983
    helper_cvtqlv();
984
    RETURN();
985
}
986

    
987
void OPPROTO op_cvtqlsv (void)
988
{
989
    helper_cvtqlsv();
990
    RETURN();
991
}
992

    
993
/* PALcode support special instructions */
994
#if !defined (CONFIG_USER_ONLY)
995
void OPPROTO op_hw_rei (void)
996
{
997
    env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
998
    env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
999
    /* XXX: re-enable interrupts and memory mapping */
1000
    RETURN();
1001
}
1002

    
1003
void OPPROTO op_hw_ret (void)
1004
{
1005
    env->pc = T0 & ~3;
1006
    env->ipr[IPR_EXC_ADDR] = T0 & 1;
1007
    /* XXX: re-enable interrupts and memory mapping */
1008
    RETURN();
1009
}
1010

    
1011
void OPPROTO op_mfpr (void)
1012
{
1013
    helper_mfpr(PARAM(1));
1014
    RETURN();
1015
}
1016

    
1017
void OPPROTO op_mtpr (void)
1018
{
1019
    helper_mtpr(PARAM(1));
1020
    RETURN();
1021
}
1022

    
1023
void OPPROTO op_set_alt_mode (void)
1024
{
1025
    env->saved_mode = env->ps & 0xC;
1026
    env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
1027
    RETURN();
1028
}
1029

    
1030
void OPPROTO op_restore_mode (void)
1031
{
1032
    env->ps = (env->ps & ~0xC) | env->saved_mode;
1033
    RETURN();
1034
}
1035

    
1036
void OPPROTO op_ld_phys_to_virt (void)
1037
{
1038
    helper_ld_phys_to_virt();
1039
    RETURN();
1040
}
1041

    
1042
void OPPROTO op_st_phys_to_virt (void)
1043
{
1044
    helper_st_phys_to_virt();
1045
    RETURN();
1046
}
1047
#endif /* !defined (CONFIG_USER_ONLY) */