This source file includes following definitions.
- ldexpl
- exp2l
- EAQToIEEElongdouble
- EAQToIEEEdouble
- IEEElongdoubleToFloat72
- MYfrexpl
- IEEElongdoubleToEAQ
- isHex
- ufa
- fno
- fno_ext
- fneg
- ufm
- fdvX
- fdv
- fdi
- frd
- fstr
- fcmp
- fcmg
- dufa
- dufm
- dfdvX
- dfdv
- dfdi
- dvf
- dfrd
- dfstr
- dfcmp
- dfcmg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <stdio.h>
37 #include <math.h>
38
39 #include "dps8.h"
40 #include "dps8_sys.h"
41 #include "dps8_faults.h"
42 #include "dps8_scu.h"
43 #include "dps8_iom.h"
44 #include "dps8_cable.h"
45 #include "dps8_cpu.h"
46 #include "dps8_ins.h"
47 #include "dps8_math.h"
48 #include "dps8_utils.h"
49
50 #define DBG_CTR cpu.cycleCnt
51
52 #ifdef __CYGWIN__
53 long double ldexpl(long double x, int n) {
54 return __builtin_ldexpl(x, n);
55 }
56
57 long double exp2l (long double e) {
58 return __builtin_exp2l(e);
59 }
60 #endif
61
62 #ifdef NEED_128
63 # define ISZERO_128(m) iszero_128 (m)
64 # define ISEQ_128(a,b) iseq_128 (a, b)
65 #else
66 # define ISZERO_128(m) ((m) == 0)
67 # define ISEQ_128(a,b) ((a) == (b))
68 #endif
69
70
71
72
73 long double EAQToIEEElongdouble(void)
74 {
75
76 word72 Mant = convert_to_word72 (cpu.rA, cpu.rQ);
77
78 if (ISZERO_128 (Mant))
79 return (long double) 0;
80 #ifdef NEED_128
81
82 bool S = isnonzero_128 (and_128 (Mant, SIGN72));
83 if (S)
84 Mant = and_128 (negate_128 (Mant), MASK71);
85 #else
86 bool S = Mant & SIGN72;
87 if (S)
88 Mant = (-Mant) & MASK71;
89 #endif
90
91 long double m = 0;
92 int e = SIGNEXT8_int (cpu . rE & MASK8);
93
94 if (S && ISZERO_128 (Mant))
95 return -exp2l(e);
96
97 long double v = 0.5;
98 for(int n = 70 ; n >= 0 ; n -= 1)
99 {
100 #ifdef NEED_128
101 if (isnonzero_128 (and_128 (Mant, lshift_128 (construct_128 (0, 1), (unsigned int) n))))
102 {
103 m += v;
104 }
105 #else
106 if (Mant & ((word72)1 << n))
107 {
108 m += v;
109 }
110 #endif
111 v /= 2.0;
112 }
113
114
115
116
117
118
119 return (S ? -1 : 1) * ldexpl(m, e);
120 }
121
122 #if defined(__MINGW32__) || defined(__MINGW64__)
123
124
125 double EAQToIEEEdouble(void)
126 {
127
128 word72 Mant = convert_to_word72 (cpu.rA, cpu.rQ);
129
130 if (ISZERO_128 (Mant))
131 return 0;
132
133 # ifdef NEED_128
134 bool S = isnonzero_128 (and_128 (Mant, SIGN72));
135 if (S)
136 Mant = and_128 (negate_128 (Mant), MASK71);
137 # else
138 bool S = Mant & SIGN72;
139 if (S)
140 Mant = (-Mant) & MASK71;
141 # endif
142
143 double m = 0;
144 int e = SIGNEXT8_int (cpu . rE & MASK8);
145
146 if (S && ISZERO_128 (Mant))
147 return -exp2(e);
148
149 double v = 0.5;
150 for(int n = 70 ; n >= 0 ; n -= 1)
151 {
152 # ifdef NEED_128
153 if (isnonzero_128 (and_128 (Mant, lshift_128 (construct_128 (0, 1), (unsigned int) n))))
154 {
155 m += v;
156 }
157 # else
158 if (Mant & ((word72)1 << n))
159 {
160 m += v;
161 }
162 # endif
163 v /= 2.0;
164 }
165
166 return (S ? -1 : 1) * ldexp(m, e);
167 }
168 #endif
169
170 #ifndef QUIET_UNUSED
171
172
173
174 float72 IEEElongdoubleToFloat72(long double f0)
175 {
176 if (f0 == 0)
177 return (float72)((float72)0400000000000LL << 36);
178
179 bool sign = f0 < 0 ? true : false;
180 long double f = fabsl(f0);
181
182 int exp;
183 long double mant = frexpl(f, &exp);
184
185
186 word72 result = 0;
187
188
189
190 if (sign && mant == 0.5)
191 {
192
193 putbits72 (& result, 71-62, 1, 1);
194 exp -= 1;
195 mant -= 0.5;
196 }
197
198 long double bitval = 0.5;
199 for(int n = 62 ; n >= 0 && mant > 0; n -= 1)
200 {
201 if (mant >= bitval)
202 {
203
204 putbits72 (& result, 71-n, 1, 1);
205 mant -= bitval;
206
207 }
208 bitval /= 2.0;
209 }
210
211
212
213
214 if (sign)
215 {
216 result = -result & (((word72)1 << 64) - 1);
217
218 }
219
220 int e = (int)exp;
221
222 putbits72 (& result, 71-64, 8, e & 0377);
223
224
225
226 return result;
227 }
228 #endif
229
230 #ifndef QUIET_UNUSED
231 static long double MYfrexpl(long double x, int *exp)
232 {
233 long double exponents[20], *next;
234 int exponent, bit;
235
236
237 if (x != x || x + x == x )
238 {
239 *exp = 0;
240 return x;
241 }
242
243 if (x < 0)
244 return -MYfrexpl(-x, exp);
245
246 exponent = 0;
247 if (x > 1.0)
248 {
249 for (next = exponents, exponents[0] = 2.0L, bit = 1;
250 *next <= x + x;
251 bit <<= 1, next[1] = next[0] * next[0], next++);
252
253 for (; next >= exponents; bit >>= 1, next--)
254 if (x + x >= *next)
255 {
256 x /= *next;
257 exponent |= bit;
258 }
259
260 }
261
262 else if (x < 0.5)
263 {
264 for (next = exponents, exponents[0] = 0.5L, bit = 1;
265 *next > x;
266 bit <<= 1, next[1] = next[0] * next[0], next++);
267
268 for (; next >= exponents; bit >>= 1, next--)
269 if (x < *next)
270 {
271 x /= *next;
272 exponent |= bit;
273 }
274
275 exponent = -exponent;
276 }
277
278 *exp = exponent;
279 return x;
280 }
281 #endif
282
283 #ifndef QUIET_UNUSED
284
285
286
287 void IEEElongdoubleToEAQ(long double f0)
288 {
289 if (f0 == 0)
290 {
291 cpu . rA = 0;
292 # ifdef TESTING
293 HDBGRegAW ("IEEEld2EAQ");
294 # endif
295 cpu . rQ = 0;
296 cpu . rE = 0200U;
297 return;
298 }
299
300 bool sign = f0 < 0 ? true : false;
301 long double f = fabsl(f0);
302 int exp;
303 long double mant = MYfrexpl(f, &exp);
304 word72 result = 0;
305
306
307 if (sign && mant == 0.5)
308 {
309
310 result = putbits72 (& result, 71-63, 1, 1);
311 exp -= 1;
312 mant -= 0.5;
313 }
314
315 long double bitval = 0.5;
316 for(int n = 70 ; n >= 0 && mant > 0; n -= 1)
317 {
318 if (mant >= bitval)
319 {
320
321 putbits72 (& result 71-n, 1, 1);
322 mant -= bitval;
323
324 }
325 bitval /= 2.0;
326 }
327
328
329 if (sign)
330 result = -result & (((word72)1 << 72) - 1);
331
332 cpu . rE = exp & MASK8;
333 cpu . rA = (result >> 36) & MASK36;
334 # ifdef TESTING
335 HDBGRegAW ("IEEEld2EAQ");
336 # endif
337 cpu . rQ = result & MASK36;
338 }
339 #endif
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 #ifdef HEX_MODE
437
438
439 # ifdef NEED_128
440 # define HEX_SIGN construct_128 (0xF0, 0)
441 # define HEX_MSB construct_128 (0x70, 0)
442 # define HEX_NORM construct_128 (0x78, 0)
443 # else
444 # define HEX_SIGN (SIGN72 | BIT71 | BIT70 | BIT69)
445 # define HEX_MSB ( BIT71 | BIT70 | BIT69)
446 # define HEX_NORM ( BIT71 | BIT70 | BIT69 | BIT68)
447 # endif
448
449 static inline bool isHex (void) {
450 return (! cpu.tweaks.l68_mode) && (!! cpu.options.hex_mode_installed) && (!! cpu.MR.hexfp) && (!! TST_I_HEX);
451 }
452 #endif
453
454
455
456
457 void ufa (bool sub, bool normalize) {
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474 CPTUR (cptUseE);
475 #ifdef HEX_MODE
476 uint shift_amt = isHex () ? 4 : 1;
477 #else
478 uint shift_amt = 1;
479 #endif
480 word72 m1 = convert_to_word72 (cpu.rA, cpu.rQ);
481
482 #ifdef NEED_128
483 word72 m2 = lshift_128 (construct_128 (0, (uint64_t) getbits36_28 (cpu.CY, 8)), 44u);
484 #else
485 word72 m2 = ((word72) getbits36_28 (cpu.CY, 8)) << 44;
486 #endif
487
488 int e1 = SIGNEXT8_int (cpu.rE & MASK8);
489 int e2 = SIGNEXT8_int (getbits36_8 (cpu.CY, 0));
490
491
492
493
494 int m2zero = 0;
495 if (sub) {
496
497
498
499
500 if (ISZERO_128 (m2))
501 m2zero = 1;
502 #ifdef NEED_128
503 if (iseq_128 (m2, SIGN72)) {
504 m2 = rshift_128 (m2, shift_amt);
505 e2 += 1;
506 } else {
507 m2 = and_128 (negate_128 (m2), MASK72);
508 }
509 #else
510 if (m2 == SIGN72) {
511 m2 >>= shift_amt;
512 e2 += 1;
513 } else {
514
515
516 m2 = ((word72) (- (word72s) m2)) & MASK72;
517 }
518 #endif
519 }
520
521 int e3 = -1;
522
523
524 L68_ (cpu.ou.cycle |= ou_GOE;)
525 int shift_count = -1;
526 word1 allones = 1;
527 word1 notallzeros = 0;
528
529 (void)allones;
530 if (e1 == e2) {
531 shift_count = 0;
532 e3 = e1;
533 } else if (e1 < e2) {
534 shift_count = abs (e2 - e1) * (int) shift_amt;
535 #ifdef NEED_128
536 bool sign = isnonzero_128 (and_128 (m1, SIGN72));
537 for (int n = 0 ; n < shift_count ; n += 1) {
538
539 allones &= m1.l & 1;
540 notallzeros |= m1.l & 1;
541 m1 = rshift_128 (m1, 1);
542 if (sign)
543 m1 = or_128 (m1, SIGN72);
544 }
545 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
546 m1 = construct_128 (0, 0);
547 m1 = and_128 (m1, MASK72);
548 e3 = e2;
549 #else
550 bool sign = m1 & SIGN72;
551 for (int n = 0 ; n < shift_count ; n += 1) {
552
553 allones &= m1 & 1;
554 notallzeros |= m1 & 1;
555 m1 >>= 1;
556 if (sign)
557 m1 |= SIGN72;
558 }
559
560 if (m1 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
561 m1 = 0;
562 m1 &= MASK72;
563 e3 = e2;
564 #endif
565 } else {
566
567 shift_count = abs (e1 - e2) * (int) shift_amt;
568 #ifdef NEED_128
569 bool sign = isnonzero_128 (and_128 (m2, SIGN72));
570 for (int n = 0 ; n < shift_count ; n += 1) {
571
572 allones &= m2.l & 1;
573 notallzeros |= m2.l & 1;
574 m2 = rshift_128 (m2, 1);
575 if (sign)
576 m2 = or_128 (m2, SIGN72);
577 }
578 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
579 m2 = construct_128 (0, 0);
580 m2 = and_128 (m2, MASK72);
581 e3 = e1;
582 #else
583 bool sign = m2 & SIGN72;
584 for (int n = 0 ; n < shift_count ; n += 1) {
585
586 allones &= m2 & 1;
587 notallzeros |= m2 & 1;
588 m2 >>= 1;
589 if (sign)
590 m2 |= SIGN72;
591 }
592 if (m2 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
593 m2 = 0;
594 m2 &= MASK72;
595 e3 = e1;
596 #endif
597 }
598
599 bool ovf;
600 word72 m3;
601 m3 = Add72b (m1, m2, 0, I_CARRY, & cpu.cu.IR, & ovf);
602
603
604 if (m2zero)
605 SET_I_CARRY;
606
607 if (ovf) {
608 #ifdef NEED_128
609 # ifdef HEX_MODE
610
611
612
613
614
615 word72 s = and_128 (m3, SIGN72);
616 if (isHex ()) {
617 m3 = rshift_128 (m3, shift_amt);
618 if (isnonzero_128 (s))
619
620 m3 = and_128 (m3, MASK68);
621 else
622
623 m3 = or_128 (m3, HEX_SIGN);
624 } else {
625 word72 signbit = and_128 (m3, SIGN72);
626 m3 = rshift_128 (m3, 1);
627 m3 = and_128 (m3, MASK71);
628 m3 = or_128 (m3, signbit);
629 m3 = xor_128 (m3, SIGN72);
630 }
631 e3 += 1;
632 # else
633 word72 signbit = and_128 (m3, SIGN72);
634 m3 = rshift_128 (m3, 1);
635 m3 = and_128 (m3, MASK71);
636 m3 = or_128 (m3, signbit);
637 m3 = xor_128 (m3, SIGN72);
638 e3 += 1;
639 # endif
640 #else
641 # ifdef HEX_MODE
642
643
644
645
646
647 word72 s = m3 & SIGN72;
648 if (isHex ()) {
649 m3 >>= shift_amt;
650 if (s)
651
652 m3 &= MASK68;
653 else
654
655 m3 |= HEX_SIGN;
656 } else {
657 word72 signbit = m3 & SIGN72;
658 m3 >>= 1;
659 m3 = (m3 & MASK71) | signbit;
660 m3 ^= SIGN72;
661 }
662 e3 += 1;
663 # else
664 word72 signbit = m3 & SIGN72;
665 m3 >>= 1;
666 m3 = (m3 & MASK71) | signbit;
667 m3 ^= SIGN72;
668 e3 += 1;
669 # endif
670 #endif
671 }
672
673 convert_to_word36 (m3, & cpu.rA, & cpu.rQ);
674 #ifdef TESTING
675 HDBGRegAW ("ufa");
676 #endif
677 cpu.rE = e3 & 0377;
678
679 SC_I_NEG (cpu.rA & SIGN36);
680
681 if (cpu.rA == 0 && cpu.rQ == 0) {
682 SET_I_ZERO;
683 cpu.rE = 0200U;
684 } else {
685 CLR_I_ZERO;
686 }
687
688 if (normalize) {
689 fno_ext (& e3, & cpu.rE, & cpu.rA, & cpu.rQ);
690 }
691
692
693 if (e3 > 127) {
694 SET_I_EOFL;
695 if (tstOVFfault ())
696 dlyDoFault (FAULT_OFL, fst_zero, "ufa exp overflow fault");
697 }
698
699
700 if (e3 < -128) {
701 SET_I_EUFL;
702 if (tstOVFfault ())
703 dlyDoFault (FAULT_OFL, fst_zero, "ufa exp underflow fault");
704 }
705 }
706
707
708
709
710
711 void fno (word8 * E, word36 * A, word36 * Q) {
712 int e0 = SIGNEXT8_int ((* E) & MASK8);
713 fno_ext (& e0, E, A, Q);
714 }
715
716 void fno_ext (int * e0, word8 * E, word36 * A, word36 * Q) {
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735 L68_ (cpu.ou.cycle |= ou_GON;)
736 #ifdef HEX_MODE
737 uint shift_amt = isHex() ? 4 : 1;
738 #endif
739 * A &= DMASK;
740 * Q &= DMASK;
741 float72 m = convert_to_word72 (* A, * Q);
742 if (TST_I_OFLOW) {
743 CLR_I_OFLOW;
744 #ifdef NEED_128
745 word72 s = and_128 (m, SIGN72);
746 # ifdef HEX_MODE
747 if (isHex ()) {
748 m = rshift_128 (m, shift_amt);
749 if (isnonzero_128 (s))
750
751 m = and_128 (m, MASK68);
752 else
753
754 m = or_128 (m, HEX_SIGN);
755 } else {
756 m = rshift_128 (m, 1);
757 m = or_128 (m, SIGN72);
758 m = xor_128 (m, s);
759 }
760 # else
761 m = rshift_128 (m, 1);
762 m = or_128 (m, SIGN72);
763 m = xor_128 (m, s);
764 # endif
765
766
767 if (iszero_128 (m)) {
768 * E = 0200U;
769 SET_I_ZERO;
770 } else {
771 CLR_I_ZERO;
772 if (* E == 127) {
773
774 SET_I_EOFL;
775 if (tstOVFfault ())
776 dlyDoFault (FAULT_OFL, fst_zero, "fno exp overflow fault");
777 }
778 (* E) ++;
779 * E &= MASK8;
780 }
781 #else
782 word72 s = m & SIGN72;
783 # ifdef HEX_MODE
784 if (isHex ()) {
785 m >>= shift_amt;
786 if (s)
787
788 m &= MASK68;
789 else
790
791 m |= HEX_SIGN;
792 } else {
793 m >>= 1;
794 m |= SIGN72;
795 m ^= s;
796 }
797 # else
798 m >>= 1;
799 m |= SIGN72;
800 m ^= s;
801 # endif
802
803
804 if (m == 0) {
805 * E = 0200U;
806 SET_I_ZERO;
807 } else {
808 CLR_I_ZERO;
809 if (* E == 127) {
810 SET_I_EOFL;
811 if (tstOVFfault ())
812 dlyDoFault (FAULT_OFL, fst_zero, "fno exp overflow fault");
813 }
814 (* E) ++;
815 * E &= MASK8;
816 }
817 #endif
818 convert_to_word36 (m, A, Q);
819 SC_I_NEG ((* A) & SIGN36);
820
821 return;
822 }
823
824
825 #ifdef NEED_128
826 if (iszero_128 (m)) {
827
828
829 * E = 0200U;
830 SET_I_ZERO;
831 CLR_I_NEG;
832 return;
833 }
834 #else
835 if (m == 0) {
836
837
838 * E = 0200U;
839 SET_I_ZERO;
840 CLR_I_NEG;
841 return;
842 }
843 #endif
844
845
846 int e = * e0;
847 #ifdef NEED_128
848 bool s = isnonzero_128 (and_128 (m, SIGN72));
849 #else
850 bool s = (m & SIGN72) != (word72)0;
851 #endif
852
853 #ifdef HEX_MODE
854
855
856 if (isHex ()) {
857 if (s) {
858
859
860
861
862
863 # ifdef NEED_128
864 while (iseq_128 (and_128 (m, HEX_NORM), HEX_NORM)) {
865 m = lshift_128 (m, 4);
866 e -= 1;
867 }
868 m = and_128 (m, MASK71);
869 m = or_128 (m, SIGN72);
870 # else
871 while ((m & HEX_NORM) == HEX_NORM) {
872 m <<= 4;
873 e -= 1;
874 }
875 m &= MASK71;
876 m |= SIGN72;
877 # endif
878 } else {
879 # ifdef NEED_128
880
881
882
883
884 while (iszero_128 (and_128 (m, HEX_NORM))) {
885 m = lshift_128 (m, 4);
886 e -= 1;
887 }
888 m = and_128 (m, MASK71);
889 # else
890
891
892
893
894 while ((m & HEX_NORM) == 0) {
895 m <<= 4;
896 e -= 1;
897 }
898 m &= MASK71;
899 # endif
900 }
901 } else {
902 # ifdef NEED_128
903 while (s == isnonzero_128 (and_128 (m, BIT71))) {
904 m = lshift_128 (m, 1);
905 e -= 1;
906 }
907
908 m = and_128 (m, MASK71);
909
910 if (s)
911 m = or_128 (m, SIGN72);
912 # else
913 while (s == !! (m & BIT71)) {
914 m <<= 1;
915 e -= 1;
916 }
917
918 m &= MASK71;
919
920 if (s)
921 m |= SIGN72;
922 # endif
923 }
924 #else
925 # ifdef NEED_128
926 while (s == isnonzero_128 (and_128 (m, BIT71))) {
927 m = lshift_128 (m, 1);
928 e -= 1;
929 }
930
931 m = and_128 (m, MASK71);
932
933 if (s)
934 m = or_128 (m, SIGN72);
935 # else
936 while (s == !! (m & BIT71)) {
937 m <<= 1;
938 e -= 1;
939 }
940
941 m &= MASK71;
942
943 if (s)
944 m |= SIGN72;
945 # endif
946 #endif
947
948 if (e < -128) {
949 SET_I_EUFL;
950 if (tstOVFfault ())
951 dlyDoFault (FAULT_OFL, fst_zero, "fno exp underflow fault");
952 }
953
954 * E = (word8) e & MASK8;
955 convert_to_word36 (m, A, Q);
956
957
958 if (* A == 0)
959 * E = 0200U;
960
961
962 SC_I_ZERO (* A == 0 && * Q == 0);
963
964
965 SC_I_NEG ((* A) & SIGN36);
966
967 * e0 = e;
968 }
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066 void fneg (void) {
1067
1068
1069
1070
1071
1072
1073
1074
1075 CPTUR (cptUseE);
1076
1077
1078 word72 m = convert_to_word72 (cpu.rA, cpu.rQ);
1079
1080
1081
1082
1083 if (ISEQ_128 (m, SIGN72)) {
1084
1085
1086
1087 #ifdef NEED_128
1088 m = rshift_128 (m, 1);
1089 #else
1090 m >>= 1;
1091 #endif
1092
1093 if (cpu.rE == 127) {
1094 SET_I_EOFL;
1095 if (tstOVFfault ())
1096 dlyDoFault (FAULT_OFL, fst_zero, "fneg exp overflow fault");
1097 }
1098 cpu.rE ++;
1099 cpu.rE &= MASK8;
1100 } else {
1101
1102 #ifdef NEED_128
1103 m = negate_128 (m);
1104 #else
1105
1106
1107 m = (word72) (- (word72s) m);
1108 #endif
1109 }
1110 convert_to_word36 (m, & cpu.rA, & cpu.rQ);
1111 fno (& cpu.rE, & cpu.rA, & cpu.rQ);
1112 #ifdef TESTING
1113 HDBGRegAW ("fneg");
1114 #endif
1115 }
1116
1117
1118
1119
1120 void ufm (bool normalize) {
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130 CPTUR (cptUseE);
1131 word72 m1 = convert_to_word72 (cpu.rA, cpu.rQ);
1132 int e1 = SIGNEXT8_int (cpu.rE & MASK8);
1133 #ifdef NEED_128
1134 word72 m2 = lshift_128 (construct_128 (0, (uint64_t) getbits36_28 (cpu.CY, 8)), 44u);
1135 #else
1136 word72 m2 = ((word72) getbits36_28 (cpu.CY, 8)) << 44;
1137 #endif
1138 int e2 = SIGNEXT8_int (getbits36_8 (cpu.CY, 0));
1139
1140 if (ISZERO_128 (m1) || ISZERO_128 (m2)) {
1141 SET_I_ZERO;
1142 CLR_I_NEG;
1143
1144 cpu.rE = 0200U;
1145 cpu.rA = 0;
1146 #ifdef TESTING
1147 HDBGRegAW ("ufm");
1148 #endif
1149 cpu.rQ = 0;
1150
1151 return;
1152 }
1153
1154 int e3 = e1 + e2;
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175 #ifdef NEED_128
1176 int128 t = SIGNEXT72_128(m2);
1177 uint128 ut = rshift_128 (cast_128 (t), 44);
1178 int128 m3 = multiply_s128 (SIGNEXT72_128(m1), cast_s128 (ut));
1179
1180 #else
1181 int128 m3 = (SIGNEXT72_128(m1) * (SIGNEXT72_128(m2) >> 44));
1182
1183 #endif
1184
1185 #ifdef NEED_128
1186 word72 m3a = and_128 (rshift_128 (cast_128 (m3), 98u - 71u), MASK72);
1187
1188 #else
1189 word72 m3a = ((word72) (m3 >> (98-71))) & MASK72;
1190
1191 #endif
1192
1193
1194
1195 if (ISEQ_128 (m1, SIGN72) && ISEQ_128 (m2, SIGN72)) {
1196 if (e3 == 127) {
1197 SET_I_EOFL;
1198 if (tstOVFfault ())
1199 dlyDoFault (FAULT_OFL, fst_zero, "ufm exp overflow fault");
1200 }
1201 #ifdef NEED_128
1202 m3a = rshift_128 (m3a, 1);
1203 #else
1204 m3a >>= 1;
1205 #endif
1206 e3 += 1;
1207 }
1208
1209 convert_to_word36 (m3a, & cpu.rA, & cpu.rQ);
1210 #ifdef TESTING
1211 HDBGRegAW ("ufm");
1212 #endif
1213 cpu.rE = (word8) e3 & MASK8;
1214 sim_debug (DBG_TRACEEXT, & cpu_dev, "fmp A %012"PRIo64" Q %012"PRIo64" E %03o\n", cpu.rA, cpu.rQ, cpu.rE);
1215 SC_I_NEG (cpu.rA & SIGN36);
1216
1217 if (cpu.rA == 0 && cpu.rQ == 0) {
1218 SET_I_ZERO;
1219 cpu.rE = 0200U;
1220 } else {
1221 CLR_I_ZERO;
1222 }
1223
1224 if (normalize) {
1225 fno_ext (& e3, & cpu.rE, & cpu.rA, & cpu.rQ);
1226 }
1227
1228 if (e3 > 127) {
1229 SET_I_EOFL;
1230 if (tstOVFfault ())
1231 dlyDoFault (FAULT_OFL, fst_zero, "ufm exp overflow fault");
1232 }
1233 if (e3 < -128) {
1234 SET_I_EUFL;
1235 if (tstOVFfault ())
1236 dlyDoFault (FAULT_OFL, fst_zero, "ufm exp underflow fault");
1237 }
1238 }
1239
1240
1241
1242
1243
1244 static void fdvX (bool bInvert) {
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257 CPTUR (cptUseE);
1258 #ifdef HEX_MODE
1259 uint shift_amt = isHex() ? 4 : 1;
1260 #else
1261 uint shift_amt = 1;
1262 #endif
1263 word72 m1;
1264 int e1;
1265
1266 word72 m2;
1267 int e2;
1268
1269 bool roundovf = 0;
1270
1271 if (! bInvert) {
1272 m1 = convert_to_word72 (cpu.rA, cpu.rQ);
1273 e1 = SIGNEXT8_int (cpu.rE & MASK8);
1274
1275 #ifdef NEED_128
1276 m2 = lshift_128 (construct_128 (0, (uint64_t) getbits36_28 (cpu.CY, 8)), 44u);
1277 #else
1278 m2 = ((word72) getbits36_28 (cpu.CY, 8)) << 44;
1279 #endif
1280 e2 = SIGNEXT8_int (getbits36_8 (cpu.CY, 0));
1281
1282 } else {
1283
1284 m2 = convert_to_word72 (cpu.rA, cpu.rQ);
1285 e2 = SIGNEXT8_int (cpu.rE & MASK8);
1286
1287
1288
1289
1290 #ifdef NEED_128
1291 if ((iszero_128 (and_128 (m2, SIGN72))) &&
1292 (isnonzero_128 (and_128 (m2, construct_128 (0, 0377777777777777LL))))) {
1293 m2 = add_128 (m2, construct_128 (0, 0400000000000000LL));
1294
1295 roundovf = 1;
1296 }
1297 m2 = and_128 (m2, lshift_128 (construct_128 (0, 0777777777400), 36));
1298
1299 m1 = lshift_128 (construct_128 (0, getbits36_28 (cpu.CY, 8)), 44);
1300 e1 = SIGNEXT8_int (getbits36_8 (cpu.CY, 0));
1301 #else
1302 if (!(m2 & SIGN72) && m2 & 0377777777777777LL) {
1303 m2 += 0400000000000000LL;
1304
1305 roundovf = 1;
1306 }
1307 m2 &= (word72)0777777777400 << 36;
1308
1309 m1 = ((word72) getbits36_28 (cpu.CY, 8)) << 44;
1310 e1 = SIGNEXT8_int (getbits36_8 (cpu.CY, 0));
1311 #endif
1312 }
1313
1314 if (ISZERO_128 (m1)) {
1315 SET_I_ZERO;
1316 CLR_I_NEG;
1317
1318 cpu.rE = 0200U;
1319 cpu.rA = 0;
1320 #ifdef TESTING
1321 HDBGRegAW ("fdvX");
1322 #endif
1323 cpu.rQ = 0;
1324
1325 return;
1326 }
1327
1328
1329 int sign = 1;
1330 #ifdef NEED_128
1331 if (isnonzero_128 (and_128 (m1, SIGN72)))
1332 #else
1333 if (m1 & SIGN72)
1334 #endif
1335 {
1336 SET_I_NEG;
1337 #ifdef NEED_128
1338 if (iseq_128 (m1, SIGN72)) {
1339 m1 = rshift_128 (m1, shift_amt);
1340 e1 += 1;
1341 } else {
1342 m1 = and_128 (negate_128 (m1), MASK72);
1343 }
1344 #else
1345 if (m1 == SIGN72) {
1346 m1 >>= shift_amt;
1347 e1 += 1;
1348 } else {
1349 m1 = (~m1 + 1) & MASK72;
1350 }
1351 #endif
1352 sign = -sign;
1353 } else {
1354 CLR_I_NEG;
1355 }
1356
1357 #ifdef NEED_128
1358 if ((isnonzero_128 (and_128 (m2, SIGN72))) && !roundovf) {
1359 if (iseq_128 (m2, SIGN72)) {
1360 m2 = rshift_128 (m2, shift_amt);
1361 e2 += 1;
1362 } else {
1363 m2 = and_128 (negate_128 (m2), MASK72);
1364 }
1365 sign = -sign;
1366 }
1367 #else
1368 if ((m2 & SIGN72) && !roundovf) {
1369 if (m2 == SIGN72) {
1370 m2 >>= shift_amt;
1371 e2 += 1;
1372 } else {
1373 m2 = (~m2 + 1) & MASK72;
1374 }
1375 sign = -sign;
1376 }
1377 #endif
1378
1379 if (ISZERO_128 (m2)) {
1380
1381
1382 SET_I_ZERO;
1383
1384
1385
1386
1387
1388
1389
1390 if (! bInvert) {
1391 convert_to_word36 (m1, & cpu.rA, & cpu.rQ);
1392 #ifdef TESTING
1393 HDBGRegAW ("fdvX");
1394 #endif
1395 }
1396
1397 doFault (FAULT_DIV, fst_zero, "FDV: divide check fault");
1398 }
1399
1400 #ifdef NEED_128
1401 while (isge_128 (m1, m2)) {
1402
1403
1404
1405 m1 = rshift_128 (m1, shift_amt);
1406 e1 += 1;
1407 }
1408 #else
1409 while (m1 >= m2) {
1410
1411
1412
1413 m1 >>= shift_amt;
1414 e1 += 1;
1415 }
1416 #endif
1417
1418 int e3 = e1 - e2;
1419
1420 if (e3 > 127) {
1421 SET_I_EOFL;
1422 if (tstOVFfault ())
1423 dlyDoFault (FAULT_OFL, fst_zero, "fdvX exp overflow fault");
1424 }
1425 if (e3 < -128) {
1426 SET_I_EUFL;
1427 if (tstOVFfault ())
1428 dlyDoFault (FAULT_OFL, fst_zero, "fdvX exp underflow fault");
1429 }
1430
1431
1432
1433
1434 #ifdef NEED_128
1435 uint32_t divisor = rshift_128 (m2, 44).l & MASK28;
1436 word72 m3;
1437 if (divisor > MASK16)
1438 m3 = divide_128_32 (rshift_128 (m1, (44u-35u)), divisor, NULL);
1439 else
1440 m3 = divide_128_16 (rshift_128 (m1, (44u-35u)), (uint16_t) divisor, NULL);
1441 #else
1442 word72 m3 = (m1 >> (44-35)) / (m2 >> 44);
1443 #endif
1444
1445 #ifdef NEED_128
1446 m3 = lshift_128 (m3, 36);
1447 if (sign == -1)
1448 m3 = and_128 (negate_128 (m3), MASK72);
1449 #else
1450 m3 <<= 36;
1451 if (sign == -1)
1452 m3 = (~m3 + 1) & MASK72;
1453 #endif
1454
1455 cpu.rE = (word8) e3 & MASK8;
1456 #ifdef NEED_128
1457 cpu.rA = rshift_128 (m3, 36u).l & MASK36;
1458 #else
1459 cpu.rA = (m3 >> 36) & MASK36;
1460 #endif
1461 #ifdef TESTING
1462 HDBGRegAW ("fdvX");
1463 #endif
1464 cpu.rQ = 0;
1465
1466 SC_I_ZERO (cpu . rA == 0);
1467 SC_I_NEG (cpu . rA & SIGN36);
1468
1469 if (cpu.rA == 0)
1470 cpu.rE = 0200U;
1471 }
1472
1473 void fdv (void) {
1474 fdvX (false);
1475 }
1476
1477 void fdi (void) {
1478 fdvX (true);
1479 }
1480
1481
1482
1483
1484 void frd (void) {
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546 CPTUR (cptUseE);
1547 L68_ (cpu.ou.cycle |= ou_GOS;)
1548
1549 word72 m = convert_to_word72 (cpu.rA, cpu.rQ);
1550 if (ISZERO_128 (m)) {
1551 cpu.rE = 0200U;
1552 SET_I_ZERO;
1553 CLR_I_NEG;
1554 return;
1555 }
1556
1557
1558 bool ovf;
1559 word18 flags1 = 0;
1560 word1 carry = 0;
1561
1562 #ifdef NEED_128
1563 if (iszero_128 (and_128 (m, SIGN72)))
1564 #else
1565 if ((m & SIGN72) == 0)
1566 #endif
1567 {
1568 carry = 1;
1569 }
1570 #ifdef NEED_128
1571 m = Add72b (m, construct_128 (0, 0177777777777777LL), carry, I_OFLOW, & flags1, & ovf);
1572 #else
1573 m = Add72b (m, 0177777777777777LL, carry, I_OFLOW, & flags1, & ovf);
1574 #endif
1575
1576
1577 #ifdef NEED_128
1578 m = and_128 (m, lshift_128 (construct_128 (0, 0777777777400), 36));
1579 #else
1580 m &= ((word72)0777777777400 << 36);
1581 #endif
1582
1583
1584
1585
1586
1587
1588 bool savedovf = TST_I_OFLOW;
1589 SC_I_OFLOW(ovf);
1590 convert_to_word36 (m, & cpu.rA, & cpu.rQ);
1591
1592 fno (& cpu.rE, & cpu.rA, & cpu.rQ);
1593 #ifdef TESTING
1594 HDBGRegAW ("frd");
1595 #endif
1596 SC_I_OFLOW(savedovf);
1597 }
1598
1599 void fstr (word36 *Y)
1600 {
1601
1602
1603
1604
1605
1606
1607 L68_ (cpu.ou.cycle |= ou_GOS;)
1608 word36 A = cpu . rA, Q = cpu . rQ;
1609 word8 E = cpu . rE;
1610
1611
1612
1613
1614 float72 m = convert_to_word72 (A, Q);
1615 #ifdef NEED_128
1616 if (iszero_128 (m))
1617 #else
1618 if (m == 0)
1619 #endif
1620 {
1621 E = (word8)-128;
1622 SET_I_ZERO;
1623 CLR_I_NEG;
1624 *Y = 0;
1625 putbits36_8 (Y, 0, (word8) E & MASK8);
1626 return;
1627 }
1628
1629
1630 bool ovf;
1631 word18 flags1 = 0;
1632 word1 carry = 0;
1633
1634 #ifdef NEED_128
1635 if (iszero_128 (and_128 (m, SIGN72)))
1636 #else
1637 if ((m & SIGN72) == 0)
1638 #endif
1639 {
1640 carry = 1;
1641 }
1642 #ifdef NEED_128
1643 m = Add72b (m, construct_128 (0, 0177777777777777LL), carry, I_OFLOW, & flags1, & ovf);
1644 #else
1645 m = Add72b (m, 0177777777777777LL, carry, I_OFLOW, & flags1, & ovf);
1646 #endif
1647
1648
1649 #ifdef NEED_128
1650 m = and_128 (m, lshift_128 (construct_128 (0, 0777777777400), 36));
1651 #else
1652 m &= ((word72)0777777777400 << 36);
1653 #endif
1654
1655
1656
1657
1658
1659
1660 bool savedovf = TST_I_OFLOW;
1661 SC_I_OFLOW(ovf);
1662 convert_to_word36 (m, & A, & Q);
1663 fno (& E, & A, & Q);
1664 SC_I_OFLOW(savedovf);
1665
1666 * Y = setbits36_8 (A >> 8, 0, (word8) E);
1667 }
1668
1669
1670
1671
1672 void fcmp (void) {
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685 CPTUR (cptUseE);
1686 #ifdef NEED_128
1687 word72 m1= lshift_128 (construct_128 (0, cpu.rA & 0777777777400), 36);
1688 #else
1689 word72 m1 = ((word72)cpu.rA & 0777777777400LL) << 36;
1690 #endif
1691 int e1 = SIGNEXT8_int (cpu.rE & MASK8);
1692
1693
1694 #ifdef NEED_128
1695 word72 m2 = lshift_128 (construct_128 (0, getbits36_28 (cpu.CY, 8)), 44);
1696 #else
1697 word72 m2 = ((word72) getbits36_28 (cpu.CY, 8)) << 44;
1698 #endif
1699 int e2 = SIGNEXT8_int (getbits36_8 (cpu.CY, 0));
1700
1701
1702
1703 L68_ (cpu.ou.cycle = ou_GOE;)
1704 #ifdef HEX_MODE
1705 uint shift_amt = isHex() ? 4 : 1;
1706 #else
1707 uint shift_amt = 1;
1708 #endif
1709 int shift_count = -1;
1710 word1 notallzeros = 0;
1711
1712 if (e1 == e2) {
1713 shift_count = 0;
1714 } else if (e1 < e2) {
1715 L68_ (cpu.ou.cycle = ou_GOA;)
1716 shift_count = abs (e2 - e1) * (int) shift_amt;
1717
1718 #ifdef NEED_128
1719 bool s = isnonzero_128 (and_128 (m1, SIGN72));
1720 #else
1721 bool s = (m1 & SIGN72) != (word72)0;
1722 #endif
1723 for(int n = 0; n < shift_count; n += 1) {
1724 #ifdef NEED_128
1725 notallzeros |= m1.l & 1;
1726 m1 = rshift_128 (m1, 1);
1727 #else
1728 notallzeros |= m1 & 1;
1729 m1 >>= 1;
1730 #endif
1731 if (s)
1732 #ifdef NEED_128
1733 m1 = or_128 (m1, SIGN72);
1734 #else
1735 m1 |= SIGN72;
1736 #endif
1737 }
1738 #ifdef NEED_128
1739 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1740 m1 = construct_128 (0, 0);
1741 m1 = and_128 (m1, MASK72);
1742 #else
1743 if (m1 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1744 m1 = 0;
1745 m1 &= MASK72;
1746 #endif
1747 } else {
1748 L68_ (cpu.ou.cycle = ou_GOA;)
1749 shift_count = abs (e1 - e2) * (int) shift_amt;
1750
1751 #ifdef NEED_128
1752 bool s = isnonzero_128 (and_128 (m2, SIGN72));
1753 #else
1754 bool s = (m2 & SIGN72) != (word72)0;
1755 #endif
1756 for (int n = 0 ; n < shift_count ; n += 1) {
1757 #ifdef NEED_128
1758 notallzeros |= m2.l & 1;
1759 m2 = rshift_128 (m2, 1);
1760 #else
1761 notallzeros |= m2 & 1;
1762 m2 >>= 1;
1763 #endif
1764 if (s)
1765 #ifdef NEED_128
1766 m2 = or_128 (m2, SIGN72);
1767 #else
1768 m2 |= SIGN72;
1769 #endif
1770 }
1771 #ifdef NEED_128
1772 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1773 m2 = construct_128 (0, 0);
1774 m2 = and_128 (m2, MASK72);
1775
1776 #else
1777 if (m2 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1778 m2 = 0;
1779 m2 &= MASK72;
1780
1781 #endif
1782 }
1783
1784
1785 #ifdef NEED_128
1786 SC_I_ZERO (iseq_128 (m1, m2));
1787 SC_I_NEG (islt_s128 (SIGNEXT72_128(m1), SIGNEXT72_128(m2)));
1788 #else
1789 SC_I_ZERO (m1 == m2);
1790 SC_I_NEG ((int128)SIGNEXT72_128(m1) < (int128)SIGNEXT72_128(m2));
1791 #endif
1792 }
1793
1794
1795
1796
1797 void fcmg (void) {
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817 CPTUR (cptUseE);
1818 L68_ (cpu.ou.cycle = ou_GOS;)
1819 #ifdef HEX_MODE
1820 uint shift_amt = isHex() ? 4 : 1;
1821 #else
1822 uint shift_amt = 1;
1823 #endif
1824
1825 #ifdef NEED_128
1826 word72 m1 = lshift_128 (construct_128 (0, cpu.rA & 0777777777400), 36);
1827 #else
1828 word72 m1 = ((word72)cpu.rA & 0777777777400LL) << 36;
1829 #endif
1830 int e1 = SIGNEXT8_int (cpu.rE & MASK8);
1831
1832
1833
1834 #ifdef NEED_128
1835 word72 m2 = lshift_128 (construct_128 (0, getbits36_28 (cpu.CY, 8)), 44);
1836 #else
1837 word72 m2 = ((word72) getbits36_28 (cpu.CY, 8)) << 44;
1838 #endif
1839 int e2 = SIGNEXT8_int (getbits36_8 (cpu.CY, 0));
1840
1841
1842
1843 L68_ (cpu.ou.cycle = ou_GOE;)
1844 int shift_count = -1;
1845 word1 notallzeros = 0;
1846
1847 if (e1 == e2) {
1848 shift_count = 0;
1849 } else if (e1 < e2) {
1850 L68_ (cpu.ou.cycle = ou_GOA;)
1851 shift_count = abs (e2 - e1) * (int) shift_amt;
1852 #ifdef NEED_128
1853 bool s = isnonzero_128 (and_128 (m1, SIGN72));
1854 #else
1855 bool s = (m1 & SIGN72) != (word72)0;
1856 #endif
1857 for (int n = 0; n < shift_count; n += 1) {
1858 #ifdef NEED_128
1859 notallzeros |= m1.l & 1;
1860 m1 = rshift_128 (m1, 1);
1861 #else
1862 notallzeros |= m1 & 1;
1863 m1 >>= 1;
1864 #endif
1865 if (s)
1866 #ifdef NEED_128
1867 m1 = or_128 (m1, SIGN72);
1868 #else
1869 m1 |= SIGN72;
1870 #endif
1871 }
1872
1873 #ifdef NEED_128
1874 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1875 m1 = construct_128 (0, 0);
1876 m1 = and_128 (m1, MASK72);
1877 #else
1878 if (m1 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1879 m1 = 0;
1880 m1 &= MASK72;
1881 #endif
1882 } else {
1883 L68_ (cpu.ou.cycle = ou_GOA;)
1884 shift_count = abs(e1 - e2) * (int) shift_amt;
1885 #ifdef NEED_128
1886 bool s = isnonzero_128 (and_128 (m2, SIGN72));
1887 #else
1888 bool s = (m2 & SIGN72) != (word72)0;
1889 #endif
1890 for (int n = 0; n < shift_count; n += 1) {
1891 #ifdef NEED_128
1892 notallzeros |= m2.l & 1;
1893 m2 = rshift_128 (m2, 1);
1894 #else
1895 notallzeros |= m2 & 1;
1896 m2 >>= 1;
1897 #endif
1898 if (s)
1899 #ifdef NEED_128
1900 m2 = or_128 (m2, SIGN72);
1901 #else
1902 m2 |= SIGN72;
1903 #endif
1904 }
1905 #ifdef NEED_128
1906 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1907 m2 = construct_128 (0, 0);
1908 m2 = and_128 (m2, MASK72);
1909 #else
1910 if (m2 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
1911 m2 = 0;
1912 m2 &= MASK72;
1913 #endif
1914 }
1915
1916 SC_I_ZERO (ISEQ_128 (m1, m2));
1917 #ifdef NEED_128
1918 int128 sm1 = SIGNEXT72_128 (m1);
1919 if (islt_s128 (sm1, construct_s128 (0, 0)))
1920 sm1 = negate_s128 (sm1);
1921 int128 sm2 = SIGNEXT72_128 (m2);
1922 if (islt_s128 (sm2, construct_s128 (0, 0)))
1923 sm2 = negate_s128 (sm2);
1924 SC_I_NEG (islt_s128 (sm1, sm2));
1925 #else
1926 int128 sm1 = SIGNEXT72_128 (m1);
1927 if (sm1 < 0)
1928 sm1 = - sm1;
1929 int128 sm2 = SIGNEXT72_128 (m2);
1930 if (sm2 < 0)
1931 sm2 = - sm2;
1932 SC_I_NEG (sm1 < sm2);
1933 #endif
1934 }
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963 void dufa (bool subtract, bool normalize) {
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984 CPTUR (cptUseE);
1985 L68_ (cpu.ou.cycle = ou_GOS;)
1986 #ifdef HEX_MODE
1987 uint shift_amt = isHex() ? 4 : 1;
1988 #else
1989 uint shift_amt = 1;
1990 #endif
1991
1992 word72 m1 = convert_to_word72 (cpu.rA, cpu.rQ);
1993 int e1 = SIGNEXT8_int (cpu.rE & MASK8);
1994
1995
1996 #ifdef NEED_128
1997 word72 m2 = lshift_128 (construct_128 (0, (uint64_t) getbits36_28 (cpu.Ypair[0], 8)), 44u);
1998 m2 = or_128 (m2, lshift_128 (construct_128 (0, cpu.Ypair[1]), 8u));
1999 #else
2000 word72 m2 = ((word72) getbits36_28 (cpu.Ypair[0], 8)) << 44;
2001 m2 |= (word72) cpu.Ypair[1] << 8;
2002 #endif
2003
2004 int e2 = SIGNEXT8_int (getbits36_8 (cpu.Ypair[0], 0));
2005
2006
2007 int m2zero = 0;
2008 if (subtract) {
2009
2010 #ifdef NEED_128
2011 if (iszero_128 (m2))
2012 m2zero = 1;
2013 if (iseq_128 (m2, SIGN72)) {
2014 # ifdef HEX_MODE
2015 m2 = rshift_128 (m2, shift_amt);
2016 e2 += 1;
2017 # else
2018 m2 = rshift_128 (m2, 1);
2019 e2 += 1;
2020 # endif
2021 } else {
2022 m2 = and_128 (negate_128 (m2), MASK72);
2023 }
2024 #else
2025 if (m2 == 0)
2026 m2zero = 1;
2027 if (m2 == SIGN72) {
2028 # ifdef HEX_MODE
2029 m2 >>= shift_amt;
2030 e2 += 1;
2031 # else
2032 m2 >>= 1;
2033 e2 += 1;
2034 # endif
2035 } else {
2036
2037
2038 m2 = ((word72) (- (word72s) m2)) & MASK72;
2039 }
2040 #endif
2041 }
2042
2043 int e3 = -1;
2044
2045
2046
2047 L68_ (cpu.ou.cycle |= ou_GOE;)
2048 int shift_count = -1;
2049 word1 notallzeros = 0;
2050
2051 if (e1 == e2) {
2052 shift_count = 0;
2053 e3 = e1;
2054 } else if (e1 < e2) {
2055 L68_ (cpu.ou.cycle |= ou_GOA;)
2056 shift_count = abs(e2 - e1) * (int) shift_amt;
2057
2058 #ifdef NEED_128
2059 bool s = isnonzero_128 (and_128 (m1, SIGN72));
2060 #else
2061 bool s = (m1 & SIGN72) != (word72)0;
2062 #endif
2063 for (int n = 0; n < shift_count; n += 1) {
2064 #ifdef NEED_128
2065 notallzeros |= m1.l & 1;
2066 m1 = rshift_128 (m1, 1);
2067 #else
2068 notallzeros |= m1 & 1;
2069 m1 >>= 1;
2070 #endif
2071 if (s)
2072 #ifdef NEED_128
2073 m1 = or_128 (m1, SIGN72);
2074 #else
2075 m1 |= SIGN72;
2076 #endif
2077 }
2078 #ifdef NEED_128
2079 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
2080 m1 = construct_128 (0, 0);
2081 m1 = and_128 (m1, MASK72);
2082 #else
2083 if (m1 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
2084 m1 = 0;
2085 m1 &= MASK72;
2086 #endif
2087 e3 = e2;
2088 } else {
2089 L68_ (cpu.ou.cycle |= ou_GOA;)
2090 shift_count = abs(e1 - e2) * (int) shift_amt;
2091 #ifdef NEED_128
2092 bool s = isnonzero_128 (and_128 (m2, SIGN72));
2093 #else
2094 bool s = (m2 & SIGN72) != (word72)0;
2095 #endif
2096 for (int n = 0; n < shift_count; n += 1) {
2097 #ifdef NEED_128
2098 notallzeros |= m2.l & 1;
2099 m2 = rshift_128 (m2, 1);
2100 #else
2101 notallzeros |= m2 & 1;
2102 m2 >>= 1;
2103 #endif
2104 if (s)
2105 #ifdef NEED_128
2106 m2 = or_128 (m2, SIGN72);
2107 #else
2108 m2 |= SIGN72;
2109 #endif
2110 }
2111 #ifdef NEED_128
2112 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
2113 m2 = construct_128 (0, 0);
2114 m2 = and_128 (m2, MASK72);
2115 #else
2116 if (m2 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
2117 m2 = 0;
2118 m2 &= MASK72;
2119 #endif
2120 e3 = e1;
2121 }
2122
2123 bool ovf;
2124 word72 m3 = Add72b (m1, m2, 0, I_CARRY, & cpu.cu.IR, & ovf);
2125 if (m2zero)
2126 SET_I_CARRY;
2127
2128 if (ovf) {
2129 #ifdef HEX_MODE
2130
2131
2132
2133
2134
2135
2136 # ifdef NEED_128
2137 bool s = isnonzero_128 (and_128 (m3, SIGN72));
2138 # else
2139 bool s = (m3 & SIGN72) != (word72)0;
2140 # endif
2141 if (isHex ()) {
2142 # ifdef NEED_128
2143 m3 = rshift_128 (m3, shift_amt);
2144 if (s)
2145
2146 m3 = and_128 (m3, MASK68);
2147 else
2148
2149 m3 = or_128 (m3, HEX_SIGN);
2150 # else
2151 m3 >>= shift_amt;
2152 if (s)
2153
2154 m3 &= MASK68;
2155 else
2156
2157 m3 |= HEX_SIGN;
2158 # endif
2159 } else {
2160 # ifdef NEED_128
2161 word72 signbit = and_128 (m3, SIGN72);
2162 m3 = rshift_128 (m3, 1);
2163 m3 = or_128 (and_128 (m3, MASK71), signbit);
2164 m3 = xor_128 (m3, SIGN72);
2165 # else
2166 word72 signbit = m3 & SIGN72;
2167 m3 >>= 1;
2168 m3 = (m3 & MASK71) | signbit;
2169 m3 ^= SIGN72;
2170 # endif
2171 }
2172 e3 += 1;
2173 #else
2174 # ifdef NEED_128
2175 word72 signbit = and_128 (m3, SIGN72);
2176 m3 = rshift_128 (m3, 1);
2177 m3 = or_128 (and_128 (m3, MASK71), signbit);
2178 m3 = xor_128 (m3, SIGN72);
2179 # else
2180 word72 signbit = m3 & SIGN72;
2181 m3 >>= 1;
2182 m3 = (m3 & MASK71) | signbit;
2183 m3 ^= SIGN72;
2184 # endif
2185 e3 += 1;
2186 #endif
2187 }
2188
2189 convert_to_word36 (m3, & cpu.rA, & cpu.rQ);
2190 #ifdef TESTING
2191 HDBGRegAW ("dufa");
2192 #endif
2193 cpu.rE = e3 & 0377;
2194
2195 SC_I_NEG (cpu.rA & SIGN36);
2196
2197 if (cpu.rA == 0 && cpu.rQ == 0) {
2198 SET_I_ZERO;
2199 cpu.rE = 0200U;
2200 } else {
2201 CLR_I_ZERO;
2202 }
2203
2204 if (normalize) {
2205 fno_ext (& e3, & cpu.rE, & cpu.rA, & cpu.rQ);
2206 }
2207
2208
2209 if (e3 > 127) {
2210 SET_I_EOFL;
2211 if (tstOVFfault ())
2212 dlyDoFault (FAULT_OFL, fst_zero, "dufa exp overflow fault");
2213 }
2214
2215
2216 if (e3 < -128) {
2217 SET_I_EUFL;
2218 if (tstOVFfault ())
2219 dlyDoFault (FAULT_OFL, fst_zero, "dufa exp underflow fault");
2220 }
2221 }
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289 void dufm (bool normalize) {
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302 CPTUR (cptUseE);
2303 L68_ (cpu.ou.cycle |= ou_GOS;)
2304 word72 m1 = convert_to_word72 (cpu.rA, cpu.rQ);
2305 int e1 = SIGNEXT8_int (cpu . rE & MASK8);
2306
2307 #ifndef NEED_128
2308 sim_debug (DBG_TRACEEXT, & cpu_dev, "dufm e1 %d %03o m1 %012"PRIo64" %012"PRIo64"\n", e1, e1, (word36) (m1 >> 36) & MASK36, (word36) m1 & MASK36);
2309 #endif
2310
2311 #ifdef NEED_128
2312 word72 m2 = lshift_128 (construct_128 (0, (uint64_t) getbits36_28 (cpu.Ypair[0], 8)), 44u);
2313 m2 = or_128 (m2, lshift_128 (construct_128 (0, cpu.Ypair[1]), 8u));
2314 #else
2315 word72 m2 = ((word72) getbits36_28 (cpu.Ypair[0], 8)) << 44;
2316 m2 |= (word72) cpu.Ypair[1] << 8;
2317 #endif
2318
2319
2320 int e2 = SIGNEXT8_int (getbits36_8 (cpu.Ypair[0], 0));
2321
2322 #ifndef NEED_128
2323 sim_debug (DBG_TRACEEXT, & cpu_dev, "dufm e2 %d %03o m2 %012"PRIo64" %012"PRIo64"\n", e2, e2, (word36) (m2 >> 36) & MASK36, (word36) m2 & MASK36);
2324 #endif
2325
2326 if (ISZERO_128 (m1) || ISZERO_128 (m2)) {
2327 SET_I_ZERO;
2328 CLR_I_NEG;
2329
2330 cpu.rE = 0200U;
2331 cpu.rA = 0;
2332 #ifdef TESTING
2333 HDBGRegAW ("dufm");
2334 #endif
2335 cpu.rQ = 0;
2336
2337 return;
2338 }
2339
2340 int e3 = e1 + e2;
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365 #ifdef NEED_128
2366
2367 int128 m2s = rshift_s128 (SIGNEXT72_128(m2), 8);
2368
2369
2370 int128 m1l = and_s128 (cast_s128 (m1), construct_128 (0, MASK64));
2371 int128 m1h = rshift_s128 (SIGNEXT72_128(m1), 64);
2372 int128 m3h = multiply_s128 (m1h, m2s);
2373 int128 m3l = multiply_s128 (m1l, m2s);
2374
2375
2376 m3l = rshift_s128 (m3l, 63);
2377 m3h = lshift_s128 (m3h, 1);
2378 word72 m3a = and_128 (add_128 (cast_128 (m3h), cast_128 (m3l)), MASK72);
2379 #else
2380
2381 int128 m2s = SIGNEXT72_128(m2) >> 8;
2382
2383
2384 int128 m1l = m1 & (((uint128)1<<64)-1);
2385 int128 m1h = SIGNEXT72_128(m1) >> 64;
2386 int128 m3h = m1h * m2s;
2387 int128 m3l = m1l * m2s;
2388
2389
2390 m3l >>= 63;
2391
2392
2393 m3h = (int128) (((uint128) m3h) << 1);
2394 word72 m3a = ((word72) (m3h+m3l)) & MASK72;
2395 #endif
2396
2397
2398
2399 if (ISEQ_128 (m1, SIGN72) && ISEQ_128 (m2, SIGN72)) {
2400 if (e3 == 127) {
2401 SET_I_EOFL;
2402 if (tstOVFfault ())
2403 dlyDoFault (FAULT_OFL, fst_zero, "dufm exp overflow fault");
2404 }
2405 #ifdef NEED_128
2406 m3a = rshift_128 (m3a, 1);
2407 #else
2408 m3a >>= 1;
2409 #endif
2410 e3 += 1;
2411 }
2412
2413 convert_to_word36 (m3a, & cpu.rA, & cpu.rQ);
2414 #ifdef TESTING
2415 HDBGRegAW ("dufm");
2416 #endif
2417 cpu.rE = (word8) e3 & MASK8;
2418
2419 SC_I_NEG (cpu.rA & SIGN36);
2420
2421 if (cpu.rA == 0 && cpu.rQ == 0) {
2422 SET_I_ZERO;
2423 cpu . rE = 0200U;
2424 } else {
2425 CLR_I_ZERO;
2426 }
2427
2428 if (normalize) {
2429 fno_ext (& e3, & cpu.rE, & cpu.rA, & cpu.rQ);
2430 }
2431
2432 if (e3 > 127) {
2433 SET_I_EOFL;
2434 if (tstOVFfault ())
2435 dlyDoFault (FAULT_OFL, fst_zero, "dufm exp overflow fault");
2436 }
2437 if (e3 < -128) {
2438 SET_I_EUFL;
2439 if (tstOVFfault ())
2440 dlyDoFault (FAULT_OFL, fst_zero, "dufm exp underflow fault");
2441 }
2442 }
2443
2444
2445
2446
2447
2448 static void dfdvX (bool bInvert) {
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461 CPTUR (cptUseE);
2462 L68_ (cpu.ou.cycle |= ou_GOS;)
2463 #ifdef HEX_MODE
2464 uint shift_amt = isHex() ? 4 : 1;
2465 #else
2466 uint shift_amt = 1;
2467 #endif
2468 word72 m1;
2469 int e1;
2470
2471 word72 m2;
2472 int e2;
2473
2474 bool roundovf = 0;
2475
2476 if (! bInvert) {
2477 m1 = convert_to_word72 (cpu.rA, cpu.rQ);
2478 e1 = SIGNEXT8_int (cpu.rE & MASK8);
2479
2480
2481 #ifdef NEED_128
2482 m2 = lshift_128 (construct_128 (0, (uint64_t) getbits36_28 (cpu.Ypair[0], 8)), 44u);
2483 m2 = or_128 (m2, lshift_128 (construct_128 (0, cpu.Ypair[1]), 8u));
2484 #else
2485 m2 = ((word72) getbits36_28 (cpu.Ypair[0], 8)) << 44;
2486 m2 |= (word72) cpu.Ypair[1] << 8;
2487 #endif
2488
2489 e2 = SIGNEXT8_int (getbits36_8 (cpu.Ypair[0], 0));
2490 } else {
2491 m2 = convert_to_word72 (cpu.rA, cpu.rQ);
2492 e2 = SIGNEXT8_int (cpu.rE & MASK8);
2493
2494
2495
2496
2497
2498 #ifdef NEED_128
2499 if ((iszero_128 (and_128 (m2, SIGN72))) && m2.l & 0377)
2500 #else
2501 if (!(m2 & SIGN72) && m2 & 0377)
2502 #endif
2503 {
2504 #ifdef NEED_128
2505 m2 = add_128 (m2, construct_128 (0, 0400));
2506 #else
2507 m2 += 0400;
2508 #endif
2509
2510
2511 roundovf = 1;
2512 }
2513 #ifdef NEED_128
2514 putbits72 (& m2, 64, 8, construct_128 (0, 0));
2515 #else
2516 putbits72 (& m2, 64, 8, 0);
2517 #endif
2518
2519
2520 #ifdef NEED_128
2521 m1 = lshift_128 (construct_128 (0, (uint64_t) getbits36_28 (cpu.Ypair[0], 8)), 44u);
2522 m1 = or_128 (m1, lshift_128 (construct_128 (0, cpu.Ypair[1]), 8u));
2523 #else
2524 m1 = ((word72) getbits36_28 (cpu.Ypair[0], 8)) << 44;
2525 m1 |= (word72) cpu.Ypair[1] << 8;
2526 #endif
2527
2528 e1 = SIGNEXT8_int (getbits36_8 (cpu.Ypair[0], 0));
2529 }
2530
2531 if (ISZERO_128 (m1)) {
2532 SET_I_ZERO;
2533 CLR_I_NEG;
2534
2535 cpu.rE = 0200U;
2536 cpu.rA = 0;
2537 #ifdef TESTING
2538 HDBGRegAW ("dfdvX");
2539 #endif
2540 cpu.rQ = 0;
2541
2542 return;
2543 }
2544
2545
2546 int sign = 1;
2547 #ifdef NEED_128
2548 if (isnonzero_128 (and_128 (m1, SIGN72))) {
2549 SET_I_NEG;
2550 if (iseq_128 (m1, SIGN72)) {
2551 m1 = rshift_128 (m1, shift_amt);
2552 e1 += 1;
2553 } else {
2554 m1 = and_128 (negate_128 (m1), MASK72);
2555 }
2556 sign = -sign;
2557 } else {
2558 CLR_I_NEG;
2559 }
2560
2561 if ((isnonzero_128 (and_128 (m2, SIGN72))) && !roundovf) {
2562 if (iseq_128 (m2, SIGN72)) {
2563 m2 = rshift_128 (m2, shift_amt);
2564 e2 += 1;
2565 } else {
2566 m2 = and_128 (negate_128 (m2), MASK72);
2567 }
2568 sign = -sign;
2569 }
2570 #else
2571 if (m1 & SIGN72) {
2572 SET_I_NEG;
2573 if (m1 == SIGN72) {
2574 m1 >>= shift_amt;
2575 e1 += 1;
2576 } else {
2577 m1 = (~m1 + 1) & MASK72;
2578 }
2579 sign = -sign;
2580 } else {
2581 CLR_I_NEG;
2582 }
2583
2584 if ((m2 & SIGN72) && !roundovf) {
2585 if (m2 == SIGN72) {
2586 m2 >>= shift_amt;
2587 e2 += 1;
2588 } else {
2589 m2 = (~m2 + 1) & MASK72;
2590 }
2591 sign = -sign;
2592 }
2593 #endif
2594
2595 if (ISZERO_128 (m2)) {
2596
2597
2598 SET_I_ZERO;
2599
2600
2601
2602
2603
2604
2605
2606 if (! bInvert) {
2607 convert_to_word36 (m1, & cpu.rA, & cpu.rQ);
2608 #ifdef TESTING
2609 HDBGRegAW ("dfdvX");
2610 #endif
2611 }
2612 doFault (FAULT_DIV, fst_zero, "DFDV: divide check fault");
2613 }
2614
2615 L68_ (cpu.ou.cycle |= ou_GOA;)
2616 #ifdef NEED_128
2617 while (isge_128 (m1, m2)) {
2618 m1 = rshift_128 (m1, shift_amt);
2619 e1 += 1;
2620 }
2621 #else
2622 while (m1 >= m2) {
2623 m1 >>= shift_amt;
2624 e1 += 1;
2625 }
2626 #endif
2627 int e3 = e1 - e2;
2628 if (e3 > 127) {
2629 SET_I_EOFL;
2630 if (tstOVFfault ())
2631 dlyDoFault (FAULT_OFL, fst_zero, "dfdvX exp overflow fault");
2632 }
2633 if (e3 < -128) {
2634 SET_I_EUFL;
2635 if (tstOVFfault ())
2636 dlyDoFault (FAULT_OFL, fst_zero, "dfdvX exp underflow fault");
2637 }
2638
2639 L68_ (cpu.ou.cycle |= ou_GD1;)
2640
2641
2642
2643
2644 #ifdef NEED_128
2645 word72 m3 = divide_128 (lshift_128 (m1, 63-8), rshift_128 (m2, 8), NULL);
2646 #else
2647 word72 m3 = ((uint128)m1 << (63-8)) / ((uint128)m2 >> 8);
2648 #endif
2649 L68_ (cpu.ou.cycle |= ou_GD2;)
2650
2651 #ifdef NEED_128
2652 m3 = lshift_128 (m3, 8);
2653 if (sign == -1)
2654 m3 = and_128 (negate_128 (m3), MASK72);
2655 #else
2656 m3 <<= 8;
2657 if (sign == -1)
2658 m3 = (~m3 + 1) & MASK72;
2659 #endif
2660
2661 convert_to_word36 (m3, & cpu.rA, & cpu.rQ);
2662 #ifdef TESTING
2663 HDBGRegAW ("dfdvX");
2664 #endif
2665 cpu.rE = (word8) e3 & MASK8;
2666
2667 SC_I_ZERO (cpu.rA == 0 && cpu . rQ == 0);
2668 SC_I_NEG (cpu.rA & SIGN36);
2669
2670 if (cpu.rA == 0 && cpu.rQ == 0)
2671 cpu.rE = 0200U;
2672 }
2673
2674
2675 void dfdv (void) {
2676 dfdvX (false);
2677 }
2678
2679
2680 void dfdi (void) {
2681 dfdvX (true);
2682 }
2683
2684
2685
2686 #define DVF_CAC
2687
2688 void dvf (void)
2689 {
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781 #ifdef DVF_FRACTIONAL
2782
2783
2784
2785
2786
2787
2788
2789
2790 L68_ (cpu.ou.cycle |= ou_GD1;)
2791 int sign = 1;
2792 bool dividendNegative = (getbits36_1 (cpu.rA, 0) != 0);
2793 bool divisorNegative = (getbits36_1 (cpu.CY, 0) != 0);
2794
2795
2796
2797
2798
2799
2800 uint128 zFrac = (((uint128) (cpu.rA & MASK35)) << 35) | ((cpu.rQ >> 1) & MASK35);
2801 if (dividendNegative) {
2802 zFrac = ~zFrac + 1;
2803 sign = - sign;
2804 }
2805 zFrac &= MASK70;
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825 uint128 dFrac = cpu.CY & MASK35;
2826 if (divisorNegative) {
2827 dFrac = ~dFrac + 1;
2828 sign = - sign;
2829 }
2830 dFrac &= MASK35;
2831
2832
2833 if (dFrac == 0) {
2834
2835
2836
2837
2838 cpu.rA = (zFrac >> 35) & MASK35;
2839 cpu.rQ = (zFrac & MASK35) << 1;
2840
2841 SC_I_ZERO (cpu.CY == 0);
2842 SC_I_NEG (cpu.rA & SIGN36);
2843
2844 doFault(FAULT_DIV, fst_zero, "DVF: divide check fault");
2845 }
2846
2847
2848
2849
2850
2851 L68_ (cpu.ou.cycle |= ou_GD2;)
2852 uint128 sn = zFrac;
2853 word36 quot = 0;
2854 for (uint i = 0; i < 35; i ++) {
2855
2856 uint128 s2n = sn << 1;
2857 if (s2n > dFrac) {
2858 s2n -= dFrac;
2859 quot |= (1llu << (34 - i));
2860 }
2861 sn = s2n;
2862
2863
2864
2865
2866
2867
2868 }
2869 word36 remainder = sn;
2870
2871 if (sign == -1)
2872 quot = ~quot + 1;
2873
2874 if (dividendNegative)
2875 remainder = ~remainder + 1;
2876
2877 L68_ (cpu.ou.cycle |= ou_GD2;)
2878
2879
2880
2881
2882 if (quot & ~((uint128) MASK35)) {
2883 SC_I_ZERO (cpu.rA == 0);
2884 SC_I_NEG (cpu.rA & SIGN36);
2885
2886 doFault(FAULT_DIV, fst_zero, "DVF: divide check fault");
2887 }
2888 cpu.rA = quot & MASK36;
2889 # ifdef TESTING
2890 HDBGRegAW ("dvf");
2891 # endif
2892 cpu.rQ = remainder & MASK36;
2893
2894 #endif
2895
2896
2897 #ifdef DVF_CAC
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919 L68_ (cpu.ou.cycle |= ou_GD1;)
2920 int sign = 1;
2921 bool dividendNegative = (getbits36_1 (cpu . rA, 0) != 0);
2922 bool divisorNegative = (getbits36_1 (cpu.CY, 0) != 0);
2923
2924
2925
2926
2927
2928
2929 # ifdef NEED_128
2930 uint128 zFrac = lshift_128 (construct_128 (0, cpu.rA & MASK35), 35);
2931 zFrac = or_128 (zFrac, construct_128 (0, (cpu.rQ >> 1) & MASK35));
2932
2933 # else
2934 uint128 zFrac = ((uint128) (cpu . rA & MASK35) << 35) | ((cpu . rQ >> 1) & MASK35);
2935
2936 # endif
2937
2938
2939 if (dividendNegative)
2940 {
2941 # ifdef NEED_128
2942 zFrac = negate_128 (zFrac);
2943 # else
2944
2945
2946 zFrac = (uint128) (((int128) (~zFrac)) + 1);
2947 # endif
2948 sign = - sign;
2949 }
2950 # ifdef NEED_128
2951 zFrac = and_128 (zFrac, MASK70);
2952
2953 # else
2954 zFrac &= MASK70;
2955
2956 # endif
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971 uint128 dFrac = convert_to_word72 (0, cpu.CY & MASK35);
2972 # ifdef NEED_128
2973
2974 # else
2975
2976 # endif
2977 if (divisorNegative)
2978 {
2979 # ifdef NEED_128
2980 dFrac = negate_128 (dFrac);
2981 # else
2982
2983
2984 dFrac = (uint128) (((int128) (~dFrac)) + 1);
2985 # endif
2986 sign = - sign;
2987 }
2988 # ifdef NEED_128
2989 dFrac = and_128 (dFrac, construct_128 (0, MASK35));
2990
2991 # else
2992 dFrac &= MASK35;
2993
2994 # endif
2995
2996
2997
2998
2999
3000
3001
3002 # ifdef NEED_128
3003 if (iszero_128 (dFrac))
3004 # else
3005 if (dFrac == 0)
3006 # endif
3007 {
3008
3009
3010
3011
3012
3013
3014
3015 cpu.rQ = cpu.rQ & (MASK35 << 1);
3016
3017
3018
3019 SC_I_ZERO (cpu.CY == 0);
3020 SC_I_NEG (cpu.rA & SIGN36);
3021 dlyDoFault(FAULT_DIV, fst_zero, "DVF: divide check fault");
3022 return;
3023 }
3024
3025
3026
3027
3028 L68_ (cpu.ou.cycle |= ou_GD2;)
3029 # ifdef NEED_128
3030 uint128 remainder;
3031 uint128 quot = divide_128 (zFrac, dFrac, & remainder);
3032
3033
3034 # else
3035 uint128 quot = zFrac / dFrac;
3036 uint128 remainder = zFrac % dFrac;
3037
3038
3039 # endif
3040
3041
3042
3043
3044
3045 # ifdef NEED_128
3046 if (isnonzero_128 (and_128 (quot, construct_128 (MASK36, ~MASK35))))
3047 # else
3048 if (quot & ~MASK35)
3049 # endif
3050 {
3051
3052
3053
3054
3055
3056
3057 bool Aneg = (cpu.rA & SIGN36) != 0;
3058 bool AQzero = cpu.rA == 0 && cpu.rQ == 0;
3059 if (cpu.rA & SIGN36)
3060 {
3061 cpu.rA = (~cpu.rA) & MASK36;
3062 cpu.rQ = (~cpu.rQ) & MASK36;
3063 cpu.rQ += 1;
3064 if (cpu.rQ & BIT37)
3065 {
3066 cpu.rQ &= MASK36;
3067 cpu.rA = (cpu.rA + 1) & MASK36;
3068 }
3069 }
3070
3071
3072
3073
3074
3075
3076
3077 # ifdef TESTING
3078 HDBGRegAW ("dvf");
3079 # endif
3080
3081
3082
3083
3084 cpu.rQ = cpu.rQ & (MASK35 << 1);
3085
3086
3087
3088 SC_I_ZERO (AQzero);
3089 SC_I_NEG (Aneg);
3090
3091 dlyDoFault(FAULT_DIV, fst_zero, "DVF: divide check fault");
3092 return;
3093 }
3094
3095
3096
3097
3098 if (sign == -1)
3099 # ifdef NEED_128
3100 quot = negate_128 (quot);
3101 # else
3102 quot = ~quot + 1;
3103 # endif
3104
3105 if (dividendNegative)
3106 # ifdef NEED_128
3107 remainder = negate_128 (remainder);
3108 # else
3109 remainder = ~remainder + 1;
3110 # endif
3111
3112 # ifdef NEED_128
3113 cpu.rA = quot.l & MASK36;
3114 cpu.rQ = remainder.l & MASK36;
3115 # else
3116 cpu . rA = quot & MASK36;
3117 cpu . rQ = remainder & MASK36;
3118 # endif
3119 # ifdef TESTING
3120 HDBGRegAW ("dvf");
3121 # endif
3122 #endif
3123
3124
3125
3126 SC_I_ZERO (cpu . rA == 0 && cpu . rQ == 0);
3127 SC_I_NEG (cpu . rA & SIGN36);
3128
3129 }
3130
3131
3132
3133
3134 void dfrd (void) {
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152 CPTUR (cptUseE);
3153 float72 m = convert_to_word72 (cpu.rA, cpu.rQ);
3154 if (ISZERO_128 (m)) {
3155 cpu.rE = 0200U;
3156 SET_I_ZERO;
3157 CLR_I_NEG;
3158 return;
3159 }
3160
3161
3162 bool ovf;
3163 word18 flags1 = 0;
3164 word1 carry = 0;
3165
3166 #ifdef NEED_128
3167 if (iszero_128 (and_128 (m, SIGN72)))
3168 #else
3169 if ((m & SIGN72) == 0)
3170 #endif
3171 {
3172 carry = 1;
3173 }
3174 #ifdef NEED_128
3175 m = Add72b (m, construct_128 (0, 0177), carry, I_OFLOW, & flags1, & ovf);
3176 #else
3177 m = Add72b (m, 0177, carry, I_OFLOW, & flags1, & ovf);
3178 #endif
3179
3180
3181 #ifdef NEED_128
3182 putbits72 (& m, 64, 8, construct_128 (0, 0));
3183 #else
3184 putbits72 (& m, 64, 8, 0);
3185 #endif
3186
3187
3188
3189
3190
3191
3192 bool savedovf = TST_I_OFLOW;
3193 SC_I_OFLOW (ovf);
3194 convert_to_word36 (m, & cpu.rA, & cpu.rQ);
3195
3196 fno (& cpu.rE, & cpu.rA, & cpu.rQ);
3197 #ifdef TESTING
3198 HDBGRegAW ("dfrd");
3199 #endif
3200 SC_I_OFLOW (savedovf);
3201 }
3202
3203 void dfstr (word36 *Ypair)
3204 {
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226 CPTUR (cptUseE);
3227 word36 A = cpu . rA, Q = cpu . rQ;
3228 word8 E = cpu . rE;
3229
3230
3231
3232 float72 m = convert_to_word72 (A, Q);
3233 #ifdef NEED_128
3234 if (iszero_128 (m))
3235 #else
3236 if (m == 0)
3237 #endif
3238 {
3239 E = (word8)-128;
3240 SET_I_ZERO;
3241 CLR_I_NEG;
3242
3243 Ypair[0] = ((word36) E & MASK8) << 28;
3244 Ypair[1] = 0;
3245
3246 return;
3247 }
3248
3249
3250 bool ovf;
3251 word18 flags1 = 0;
3252 word1 carry = 0;
3253
3254 #ifdef NEED_128
3255 if (iszero_128 (and_128 (m, SIGN72)))
3256 #else
3257 if ((m & SIGN72) == 0)
3258 #endif
3259 {
3260 carry = 1;
3261 }
3262 #ifdef NEED_128
3263 m = Add72b (m, construct_128 (0, 0177), carry, I_OFLOW, & flags1, & ovf);
3264 #else
3265 m = Add72b (m, 0177, carry, I_OFLOW, & flags1, & ovf);
3266 #endif
3267
3268
3269 #ifdef NEED_128
3270 putbits72 (& m, 64, 8, construct_128 (0, 0));
3271 #else
3272 putbits72 (& m, 64, 8, 0);
3273
3274 #endif
3275
3276
3277
3278
3279
3280
3281 bool savedovf = TST_I_OFLOW;
3282 SC_I_OFLOW(ovf);
3283 convert_to_word36 (m, & A, & Q);
3284
3285 fno (& E, & A, & Q);
3286 SC_I_OFLOW(savedovf);
3287
3288 Ypair[0] = (((word36)E & MASK8) << 28) | ((A & 0777777777400LL) >> 8);
3289 Ypair[1] = ((A & 0377) << 28) | ((Q & 0777777777400LL) >> 8);
3290 }
3291
3292
3293
3294
3295 void dfcmp (void) {
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311 CPTUR (cptUseE);
3312 #ifdef HEX_MODE
3313 uint shift_amt = isHex() ? 4 : 1;
3314 #else
3315 uint shift_amt = 1;
3316 #endif
3317 word72 m1 = convert_to_word72 (cpu.rA, cpu.rQ & 0777777777400LL);
3318 int e1 = SIGNEXT8_int (cpu . rE & MASK8);
3319
3320
3321 #ifdef NEED_128
3322 word72 m2 = lshift_128 (construct_128 (0, getbits36_28 (cpu.Ypair[0], 8)), (36 + 8));
3323 m2 = or_128 (m2, lshift_128 (construct_128 (0, cpu.Ypair[1]), 8u));
3324 #else
3325 word72 m2 = (word72) getbits36_28 (cpu.Ypair[0], 8) << (36 + 8);
3326 m2 |= cpu.Ypair[1] << 8;
3327 #endif
3328 int e2 = SIGNEXT8_int (getbits36_8 (cpu.Ypair[0], 0));
3329
3330
3331
3332 int shift_count = -1;
3333 word1 notallzeros = 0;
3334
3335 #ifdef NEED_128
3336 if (e1 == e2) {
3337 shift_count = 0;
3338 } else if (e1 < e2) {
3339 shift_count = abs (e2 - e1) * (int) shift_amt;
3340 bool s = isnonzero_128 (and_128 (m1, SIGN72));
3341 for (int n = 0; n < shift_count; n += 1) {
3342 notallzeros |= m1.l & 1;
3343 m1 = rshift_128 (m1, 1);
3344 if (s)
3345 m1 = or_128 (m1, SIGN72);
3346 }
3347
3348 # ifdef HEX_MODE
3349 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3350 m1 = construct_128 (0, 0);
3351 # else
3352 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count > 71)
3353 m1 = construct_128 (0, 0);
3354 # endif
3355 m1 = and_128 (m1, MASK72);
3356 } else {
3357 shift_count = abs(e1 - e2) * (int) shift_amt;
3358 bool s = isnonzero_128 (and_128 (m2, SIGN72));
3359 for (int n = 0; n < shift_count; n += 1) {
3360 notallzeros |= m2.l & 1;
3361 m2 = rshift_128 (m2, 1);
3362 if (s)
3363 m2 = or_128 (m2, SIGN72);
3364 }
3365 # ifdef HEX_MODE
3366 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3367 m2 = construct_128 (0, 0);
3368 # else
3369 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count > 71)
3370 m2 = construct_128 (0, 0);
3371 # endif
3372 m2 = and_128 (m2, MASK72);
3373 }
3374
3375 SC_I_ZERO (iseq_128 (m1, m2));
3376 int128 sm1 = SIGNEXT72_128 (m1);
3377 int128 sm2 = SIGNEXT72_128 (m2);
3378 SC_I_NEG (islt_s128 (sm1, sm2));
3379 #else
3380 if (e1 == e2) {
3381 shift_count = 0;
3382 } else if (e1 < e2) {
3383 shift_count = abs(e2 - e1) * (int) shift_amt;
3384 bool s = m1 & SIGN72;
3385 for (int n = 0; n < shift_count; n += 1) {
3386 notallzeros |= m1 & 1;
3387 m1 >>= 1;
3388 if (s)
3389 m1 |= SIGN72;
3390 }
3391
3392 # ifdef HEX_MODE
3393 if (m1 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3394 m1 = 0;
3395 # else
3396 if (m1 == MASK72 && notallzeros == 1 && shift_count > 71)
3397 m1 = 0;
3398 # endif
3399 m1 &= MASK72;
3400 } else {
3401 shift_count = abs(e1 - e2) * (int) shift_amt;
3402 bool s = m2 & SIGN72;
3403 for (int n = 0; n < shift_count; n += 1) {
3404 notallzeros |= m2 & 1;
3405 m2 >>= 1;
3406 if (s)
3407 m2 |= SIGN72;
3408 }
3409 # ifdef HEX_MODE
3410 if (m2 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3411 m2 = 0;
3412 # else
3413 if (m2 == MASK72 && notallzeros == 1 && shift_count > 71)
3414 m2 = 0;
3415 # endif
3416 m2 &= MASK72;
3417 }
3418
3419 SC_I_ZERO (m1 == m2);
3420 int128 sm1 = SIGNEXT72_128 (m1);
3421 int128 sm2 = SIGNEXT72_128 (m2);
3422 SC_I_NEG (sm1 < sm2);
3423 #endif
3424 }
3425
3426
3427
3428
3429 void dfcmg (void) {
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445 CPTUR (cptUseE);
3446 #ifdef HEX_MODE
3447 uint shift_amt = isHex () ? 4 : 1;
3448 #else
3449 uint shift_amt = 1;
3450 #endif
3451
3452 word72 m1 = convert_to_word72 (cpu.rA & MASK36, cpu.rQ & 0777777777400LL);
3453 int e1 = SIGNEXT8_int (cpu.rE & MASK8);
3454
3455
3456 #ifdef NEED_128
3457 word72 m2 = lshift_128 (construct_128 (0, getbits36_28 (cpu.Ypair[0], 8)), (36 + 8));
3458 m2 = or_128 (m2, lshift_128 (construct_128 (0, cpu.Ypair[1]), 8u));
3459 #else
3460 word72 m2 = (word72) getbits36_28 (cpu.Ypair[0], 8) << (36 + 8);
3461 m2 |= cpu.Ypair[1] << 8;
3462 #endif
3463 int e2 = SIGNEXT8_int (getbits36_8 (cpu.Ypair[0], 0));
3464
3465
3466 L68_ (cpu.ou.cycle = ou_GOE;)
3467 int shift_count = -1;
3468 word1 notallzeros = 0;
3469
3470 if (e1 == e2) {
3471 shift_count = 0;
3472 } else if (e1 < e2) {
3473 L68_ (cpu.ou.cycle = ou_GOA;)
3474 shift_count = abs(e2 - e1) * (int) shift_amt;
3475 #ifdef NEED_128
3476 bool s = isnonzero_128 (and_128 (m1, SIGN72));
3477 for (int n = 0; n < shift_count; n += 1) {
3478 notallzeros |= m1.l & 1;
3479 m1 = rshift_128 (m1, 1);
3480 if (s)
3481 m1 = or_128 (m1, SIGN72);
3482 }
3483 # ifdef HEX_MODE
3484 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3485 m1 = construct_128 (0, 0);
3486 # else
3487 if (iseq_128 (m1, MASK72) && notallzeros == 1 && shift_count > 71)
3488 m1 = construct_128 (0, 0);
3489 # endif
3490 m1 = and_128 (m1, MASK72);
3491 #else
3492 bool s = m1 & SIGN72;
3493 for (int n = 0; n < shift_count; n += 1) {
3494 notallzeros |= m1 & 1;
3495 m1 >>= 1;
3496 if (s)
3497 m1 |= SIGN72;
3498 }
3499 # ifdef HEX_MODE
3500 if (m1 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3501 m1 = 0;
3502 # else
3503 if (m1 == MASK72 && notallzeros == 1 && shift_count > 71)
3504 m1 = 0;
3505 # endif
3506 m1 &= MASK72;
3507 #endif
3508 } else {
3509 shift_count = abs(e1 - e2) * (int) shift_amt;
3510 #ifdef NEED_128
3511 bool s = isnonzero_128 (and_128 (m2, SIGN72));
3512 for (int n = 0; n < shift_count; n += 1) {
3513 notallzeros |= m2.l & 1;
3514 m2 = rshift_128 (m2, 1);
3515 if (s)
3516 m2 = or_128 (m2, SIGN72);
3517 }
3518 # ifdef HEX_MODE
3519 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3520 m2 = construct_128 (0, 0);
3521 # else
3522 if (iseq_128 (m2, MASK72) && notallzeros == 1 && shift_count > 71)
3523 m2 = construct_128 (0, 0);
3524 # endif
3525 m2 = and_128 (m2, MASK72);
3526 #else
3527 bool s = m2 & SIGN72;
3528 for (int n = 0; n < shift_count; n += 1) {
3529 notallzeros |= m2 & 1;
3530 m2 >>= 1;
3531 if (s)
3532 m2 |= SIGN72;
3533 }
3534 # ifdef HEX_MODE
3535 if (m2 == MASK72 && notallzeros == 1 && shift_count * (int) shift_amt > 71)
3536 m2 = 0;
3537 # else
3538 if (m2 == MASK72 && notallzeros == 1 && shift_count > 71)
3539 m2 = 0;
3540 # endif
3541 m2 &= MASK72;
3542 #endif
3543 }
3544
3545 #ifdef NEED_128
3546 SC_I_ZERO (iseq_128 (m1, m2));
3547 int128 sm1 = SIGNEXT72_128 (m1);
3548 if (sm1.h < 0)
3549 sm1 = negate_s128 (sm1);
3550 int128 sm2 = SIGNEXT72_128 (m2);
3551 if (sm2.h < 0)
3552 sm2 = negate_s128 (sm2);
3553
3554 SC_I_NEG (islt_s128 (sm1, sm2));
3555 #else
3556 SC_I_ZERO (m1 == m2);
3557 int128 sm1 = SIGNEXT72_128 (m1);
3558 if (sm1 < 0)
3559 sm1 = - sm1;
3560 int128 sm2 = SIGNEXT72_128 (m2);
3561 if (sm2 < 0)
3562 sm2 = - sm2;
3563
3564 SC_I_NEG (sm1 < sm2);
3565 #endif
3566 }