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
37
38
39
40
41
42
43
44
45
46
47
48
49
50#define FPUDEBUG 0
51
52#include "float.h"
53#include <linux/bug.h>
54#include <linux/kernel.h>
55#include <asm/processor.h>
56
57
58
59#define COPR_INST 0x30000000
60
61
62
63
64
65#define extru(r,pos,len) (((r) >> (31-(pos))) & (( 1 << (len)) - 1))
66
67#define fpmajorpos 5
68#define fpr1pos 10
69#define fpr2pos 15
70#define fptpos 31
71#define fpsubpos 18
72#define fpclass1subpos 16
73#define fpclasspos 22
74#define fpfmtpos 20
75#define fpdfpos 18
76#define fpnulpos 26
77
78
79
80#define fpxr1pos 24
81#define fpxr2pos 19
82#define fpxtpos 25
83#define fpxpos 23
84#define fp0efmtpos 20
85
86
87
88#define fprm1pos 10
89#define fprm2pos 15
90#define fptmpos 31
91#define fprapos 25
92#define fptapos 20
93#define fpmultifmt 26
94
95
96
97
98
99#define fpraupos 18
100#define fpxrm2pos 19
101
102#define fpralpos 23
103#define fpxrm1pos 24
104
105#define fpfusedsubop 26
106
107
108
109
110
111#define fpzeroreg (32*sizeof(double)/sizeof(u_int))
112
113
114
115
116#define get_major(op) extru(op,fpmajorpos,6)
117
118
119
120
121#define get_class(op) extru(op,fpclasspos,2)
122
123
124
125
126#define get_subop(op) extru(op,fpsubpos,3)
127
128
129
130
131#define get_subop1_PA1_1(op) extru(op,fpclass1subpos,2)
132#define get_subop1_PA2_0(op) extru(op,fpclass1subpos,3)
133
134
135#define MAJOR_0C_EXCP 0x09
136#define MAJOR_0E_EXCP 0x0b
137#define MAJOR_06_EXCP 0x03
138#define MAJOR_26_EXCP 0x23
139#define MAJOR_2E_EXCP 0x2b
140#define PA83_UNIMP_EXCP 0x01
141
142
143
144
145
146#define FPU_TYPE_FLAG_POS (EM_FPU_TYPE_OFFSET>>2)
147#define TIMEX_ROLEX_FPU_MASK (TIMEX_EXTEN_FLAG|ROLEX_EXTEN_FLAG)
148
149
150
151
152#define _PROTOTYPES
153#if defined(_PROTOTYPES) || defined(_lint)
154static u_int decode_0c(u_int, u_int, u_int, u_int *);
155static u_int decode_0e(u_int, u_int, u_int, u_int *);
156static u_int decode_06(u_int, u_int *);
157static u_int decode_26(u_int, u_int *);
158static u_int decode_2e(u_int, u_int *);
159static void update_status_cbit(u_int *, u_int, u_int, u_int);
160#else
161static u_int decode_0c();
162static u_int decode_0e();
163static u_int decode_06();
164static u_int decode_26();
165static u_int decode_2e();
166static void update_status_cbit();
167#endif
168
169#define VASSERT(x)
170
171static void parisc_linux_get_fpu_type(u_int fpregs[])
172{
173
174
175
176 if (boot_cpu_data.cpu_type == pcxs)
177 fpregs[FPU_TYPE_FLAG_POS] = TIMEX_EXTEN_FLAG;
178 else if (boot_cpu_data.cpu_type == pcxt ||
179 boot_cpu_data.cpu_type == pcxt_)
180 fpregs[FPU_TYPE_FLAG_POS] = ROLEX_EXTEN_FLAG;
181 else if (boot_cpu_data.cpu_type >= pcxu)
182 fpregs[FPU_TYPE_FLAG_POS] = PA2_0_FPU_FLAG;
183}
184
185
186
187
188
189
190
191
192
193
194u_int
195fpudispatch(u_int ir, u_int excp_code, u_int holder, u_int fpregs[])
196{
197 u_int class, subop;
198 u_int fpu_type_flags;
199
200
201 VASSERT(sizeof(int) == 4);
202
203 parisc_linux_get_fpu_type(fpregs);
204
205 fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS];
206
207 class = get_class(ir);
208 if (class == 1) {
209 if (fpu_type_flags & PA2_0_FPU_FLAG)
210 subop = get_subop1_PA2_0(ir);
211 else
212 subop = get_subop1_PA1_1(ir);
213 }
214 else
215 subop = get_subop(ir);
216
217 if (FPUDEBUG) printk("class %d subop %d\n", class, subop);
218
219 switch (excp_code) {
220 case MAJOR_0C_EXCP:
221 case PA83_UNIMP_EXCP:
222 return(decode_0c(ir,class,subop,fpregs));
223 case MAJOR_0E_EXCP:
224 return(decode_0e(ir,class,subop,fpregs));
225 case MAJOR_06_EXCP:
226 return(decode_06(ir,fpregs));
227 case MAJOR_26_EXCP:
228 return(decode_26(ir,fpregs));
229 case MAJOR_2E_EXCP:
230 return(decode_2e(ir,fpregs));
231 default:
232
233
234
235
236
237
238
239
240
241 return(UNIMPLEMENTEDEXCEPTION);
242 }
243}
244
245
246
247
248
249u_int
250emfpudispatch(u_int ir, u_int dummy1, u_int dummy2, u_int fpregs[])
251{
252 u_int class, subop, major;
253 u_int fpu_type_flags;
254
255
256 VASSERT(sizeof(int) == 4);
257
258 fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS];
259
260 major = get_major(ir);
261 class = get_class(ir);
262 if (class == 1) {
263 if (fpu_type_flags & PA2_0_FPU_FLAG)
264 subop = get_subop1_PA2_0(ir);
265 else
266 subop = get_subop1_PA1_1(ir);
267 }
268 else
269 subop = get_subop(ir);
270 switch (major) {
271 case 0x0C:
272 return(decode_0c(ir,class,subop,fpregs));
273 case 0x0E:
274 return(decode_0e(ir,class,subop,fpregs));
275 case 0x06:
276 return(decode_06(ir,fpregs));
277 case 0x26:
278 return(decode_26(ir,fpregs));
279 case 0x2E:
280 return(decode_2e(ir,fpregs));
281 default:
282 return(PA83_UNIMP_EXCP);
283 }
284}
285
286
287static u_int
288decode_0c(u_int ir, u_int class, u_int subop, u_int fpregs[])
289{
290 u_int r1,r2,t;
291 u_int fmt;
292 u_int df;
293 u_int *status;
294 u_int retval, local_status;
295 u_int fpu_type_flags;
296
297 if (ir == COPR_INST) {
298 fpregs[0] = EMULATION_VERSION << 11;
299 return(NOEXCEPTION);
300 }
301 status = &fpregs[0];
302 local_status = fpregs[0];
303 r1 = extru(ir,fpr1pos,5) * sizeof(double)/sizeof(u_int);
304 if (r1 == 0)
305 r1 = fpzeroreg;
306 t = extru(ir,fptpos,5) * sizeof(double)/sizeof(u_int);
307 if (t == 0 && class != 2)
308 return(MAJOR_0C_EXCP);
309 fmt = extru(ir,fpfmtpos,2);
310
311 switch (class) {
312 case 0:
313 switch (subop) {
314 case 0:
315 case 1:
316 return(MAJOR_0C_EXCP);
317 case 2:
318 switch (fmt) {
319 case 2:
320 return(MAJOR_0C_EXCP);
321 case 3:
322 t &= ~3;
323 r1 &= ~3;
324 fpregs[t+3] = fpregs[r1+3];
325 fpregs[t+2] = fpregs[r1+2];
326 case 1:
327 fpregs[t+1] = fpregs[r1+1];
328 case 0:
329 fpregs[t] = fpregs[r1];
330 return(NOEXCEPTION);
331 }
332 case 3:
333 switch (fmt) {
334 case 2:
335 return(MAJOR_0C_EXCP);
336 case 3:
337 t &= ~3;
338 r1 &= ~3;
339 fpregs[t+3] = fpregs[r1+3];
340 fpregs[t+2] = fpregs[r1+2];
341 case 1:
342 fpregs[t+1] = fpregs[r1+1];
343 case 0:
344
345 fpregs[t] = fpregs[r1] & 0x7fffffff;
346 return(NOEXCEPTION);
347 }
348 case 6:
349 switch (fmt) {
350 case 2:
351 return(MAJOR_0C_EXCP);
352 case 3:
353 t &= ~3;
354 r1 &= ~3;
355 fpregs[t+3] = fpregs[r1+3];
356 fpregs[t+2] = fpregs[r1+2];
357 case 1:
358 fpregs[t+1] = fpregs[r1+1];
359 case 0:
360
361 fpregs[t] = fpregs[r1] ^ 0x80000000;
362 return(NOEXCEPTION);
363 }
364 case 7:
365 switch (fmt) {
366 case 2:
367 return(MAJOR_0C_EXCP);
368 case 3:
369 t &= ~3;
370 r1 &= ~3;
371 fpregs[t+3] = fpregs[r1+3];
372 fpregs[t+2] = fpregs[r1+2];
373 case 1:
374 fpregs[t+1] = fpregs[r1+1];
375 case 0:
376
377 fpregs[t] = fpregs[r1] | 0x80000000;
378 return(NOEXCEPTION);
379 }
380 case 4:
381 switch (fmt) {
382 case 0:
383 return(sgl_fsqrt(&fpregs[r1],0,
384 &fpregs[t],status));
385 case 1:
386 return(dbl_fsqrt(&fpregs[r1],0,
387 &fpregs[t],status));
388 case 2:
389 case 3:
390 return(MAJOR_0C_EXCP);
391 }
392 case 5:
393 switch (fmt) {
394 case 0:
395 return(sgl_frnd(&fpregs[r1],0,
396 &fpregs[t],status));
397 case 1:
398 return(dbl_frnd(&fpregs[r1],0,
399 &fpregs[t],status));
400 case 2:
401 case 3:
402 return(MAJOR_0C_EXCP);
403 }
404 }
405
406 case 1:
407 df = extru(ir,fpdfpos,2);
408 if ((df & 2) || (fmt & 2)) {
409
410
411
412
413 return(MAJOR_0C_EXCP);
414 }
415
416
417
418
419
420 fmt = (fmt << 1) | df;
421 switch (subop) {
422 case 0:
423 switch(fmt) {
424 case 0:
425 return(MAJOR_0C_EXCP);
426 case 1:
427 return(sgl_to_dbl_fcnvff(&fpregs[r1],0,
428 &fpregs[t],status));
429 case 2:
430 return(dbl_to_sgl_fcnvff(&fpregs[r1],0,
431 &fpregs[t],status));
432 case 3:
433 return(MAJOR_0C_EXCP);
434 }
435 case 1:
436 switch(fmt) {
437 case 0:
438 return(sgl_to_sgl_fcnvxf(&fpregs[r1],0,
439 &fpregs[t],status));
440 case 1:
441 return(sgl_to_dbl_fcnvxf(&fpregs[r1],0,
442 &fpregs[t],status));
443 case 2:
444 return(dbl_to_sgl_fcnvxf(&fpregs[r1],0,
445 &fpregs[t],status));
446 case 3:
447 return(dbl_to_dbl_fcnvxf(&fpregs[r1],0,
448 &fpregs[t],status));
449 }
450 case 2:
451 switch(fmt) {
452 case 0:
453 return(sgl_to_sgl_fcnvfx(&fpregs[r1],0,
454 &fpregs[t],status));
455 case 1:
456 return(sgl_to_dbl_fcnvfx(&fpregs[r1],0,
457 &fpregs[t],status));
458 case 2:
459 return(dbl_to_sgl_fcnvfx(&fpregs[r1],0,
460 &fpregs[t],status));
461 case 3:
462 return(dbl_to_dbl_fcnvfx(&fpregs[r1],0,
463 &fpregs[t],status));
464 }
465 case 3:
466 switch(fmt) {
467 case 0:
468 return(sgl_to_sgl_fcnvfxt(&fpregs[r1],0,
469 &fpregs[t],status));
470 case 1:
471 return(sgl_to_dbl_fcnvfxt(&fpregs[r1],0,
472 &fpregs[t],status));
473 case 2:
474 return(dbl_to_sgl_fcnvfxt(&fpregs[r1],0,
475 &fpregs[t],status));
476 case 3:
477 return(dbl_to_dbl_fcnvfxt(&fpregs[r1],0,
478 &fpregs[t],status));
479 }
480 case 5:
481 switch(fmt) {
482 case 0:
483 return(sgl_to_sgl_fcnvuf(&fpregs[r1],0,
484 &fpregs[t],status));
485 case 1:
486 return(sgl_to_dbl_fcnvuf(&fpregs[r1],0,
487 &fpregs[t],status));
488 case 2:
489 return(dbl_to_sgl_fcnvuf(&fpregs[r1],0,
490 &fpregs[t],status));
491 case 3:
492 return(dbl_to_dbl_fcnvuf(&fpregs[r1],0,
493 &fpregs[t],status));
494 }
495 case 6:
496 switch(fmt) {
497 case 0:
498 return(sgl_to_sgl_fcnvfu(&fpregs[r1],0,
499 &fpregs[t],status));
500 case 1:
501 return(sgl_to_dbl_fcnvfu(&fpregs[r1],0,
502 &fpregs[t],status));
503 case 2:
504 return(dbl_to_sgl_fcnvfu(&fpregs[r1],0,
505 &fpregs[t],status));
506 case 3:
507 return(dbl_to_dbl_fcnvfu(&fpregs[r1],0,
508 &fpregs[t],status));
509 }
510 case 7:
511 switch(fmt) {
512 case 0:
513 return(sgl_to_sgl_fcnvfut(&fpregs[r1],0,
514 &fpregs[t],status));
515 case 1:
516 return(sgl_to_dbl_fcnvfut(&fpregs[r1],0,
517 &fpregs[t],status));
518 case 2:
519 return(dbl_to_sgl_fcnvfut(&fpregs[r1],0,
520 &fpregs[t],status));
521 case 3:
522 return(dbl_to_dbl_fcnvfut(&fpregs[r1],0,
523 &fpregs[t],status));
524 }
525 case 4:
526 return(MAJOR_0C_EXCP);
527 }
528
529 case 2:
530 fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS];
531 r2 = extru(ir, fpr2pos, 5) * sizeof(double)/sizeof(u_int);
532 if (r2 == 0)
533 r2 = fpzeroreg;
534 if (fpu_type_flags & PA2_0_FPU_FLAG) {
535
536 if (extru(ir, fpnulpos, 1)) {
537 switch (fmt) {
538 case 0:
539
540
541
542
543
544
545 BUG();
546
547
548
549
550 case 1:
551 case 2:
552 case 3:
553 return(MAJOR_0C_EXCP);
554 }
555 } else {
556 switch (fmt) {
557 case 0:
558 retval = sgl_fcmp(&fpregs[r1],
559 &fpregs[r2],extru(ir,fptpos,5),
560 &local_status);
561 update_status_cbit(status,local_status,
562 fpu_type_flags, subop);
563 return(retval);
564 case 1:
565 retval = dbl_fcmp(&fpregs[r1],
566 &fpregs[r2],extru(ir,fptpos,5),
567 &local_status);
568 update_status_cbit(status,local_status,
569 fpu_type_flags, subop);
570 return(retval);
571 case 2:
572 case 3:
573 return(MAJOR_0C_EXCP);
574 }
575 }
576 }
577 else {
578 switch (subop) {
579 case 2:
580 case 3:
581 case 4:
582 case 5:
583 case 6:
584 case 7:
585 return(MAJOR_0C_EXCP);
586 case 0:
587 switch (fmt) {
588 case 0:
589 retval = sgl_fcmp(&fpregs[r1],
590 &fpregs[r2],extru(ir,fptpos,5),
591 &local_status);
592 update_status_cbit(status,local_status,
593 fpu_type_flags, subop);
594 return(retval);
595 case 1:
596 retval = dbl_fcmp(&fpregs[r1],
597 &fpregs[r2],extru(ir,fptpos,5),
598 &local_status);
599 update_status_cbit(status,local_status,
600 fpu_type_flags, subop);
601 return(retval);
602 case 2:
603 case 3:
604 return(MAJOR_0C_EXCP);
605 }
606 case 1:
607 switch (fmt) {
608 case 0:
609
610
611
612
613
614
615 BUG();
616
617
618
619
620 case 1:
621 case 2:
622 case 3:
623 return(MAJOR_0C_EXCP);
624 }
625 }
626 }
627 case 3:
628 r2 = extru(ir,fpr2pos,5) * sizeof(double)/sizeof(u_int);
629 if (r2 == 0)
630 r2 = fpzeroreg;
631 switch (subop) {
632 case 5:
633 case 6:
634 case 7:
635 return(MAJOR_0C_EXCP);
636
637 case 0:
638 switch (fmt) {
639 case 0:
640 return(sgl_fadd(&fpregs[r1],&fpregs[r2],
641 &fpregs[t],status));
642 case 1:
643 return(dbl_fadd(&fpregs[r1],&fpregs[r2],
644 &fpregs[t],status));
645 case 2:
646 case 3:
647 return(MAJOR_0C_EXCP);
648 }
649 case 1:
650 switch (fmt) {
651 case 0:
652 return(sgl_fsub(&fpregs[r1],&fpregs[r2],
653 &fpregs[t],status));
654 case 1:
655 return(dbl_fsub(&fpregs[r1],&fpregs[r2],
656 &fpregs[t],status));
657 case 2:
658 case 3:
659 return(MAJOR_0C_EXCP);
660 }
661 case 2:
662 switch (fmt) {
663 case 0:
664 return(sgl_fmpy(&fpregs[r1],&fpregs[r2],
665 &fpregs[t],status));
666 case 1:
667 return(dbl_fmpy(&fpregs[r1],&fpregs[r2],
668 &fpregs[t],status));
669 case 2:
670 case 3:
671 return(MAJOR_0C_EXCP);
672 }
673 case 3:
674 switch (fmt) {
675 case 0:
676 return(sgl_fdiv(&fpregs[r1],&fpregs[r2],
677 &fpregs[t],status));
678 case 1:
679 return(dbl_fdiv(&fpregs[r1],&fpregs[r2],
680 &fpregs[t],status));
681 case 2:
682 case 3:
683 return(MAJOR_0C_EXCP);
684 }
685 case 4:
686 switch (fmt) {
687 case 0:
688 return(sgl_frem(&fpregs[r1],&fpregs[r2],
689 &fpregs[t],status));
690 case 1:
691 return(dbl_frem(&fpregs[r1],&fpregs[r2],
692 &fpregs[t],status));
693 case 2:
694 case 3:
695 return(MAJOR_0C_EXCP);
696 }
697 }
698 }
699
700
701 return(MAJOR_0C_EXCP);
702}
703
704static u_int
705decode_0e(ir,class,subop,fpregs)
706u_int ir,class,subop;
707u_int fpregs[];
708{
709 u_int r1,r2,t;
710 u_int fmt;
711 u_int df;
712 u_int *status;
713 u_int retval, local_status;
714 u_int fpu_type_flags;
715
716 status = &fpregs[0];
717 local_status = fpregs[0];
718 r1 = ((extru(ir,fpr1pos,5)<<1)|(extru(ir,fpxr1pos,1)));
719 if (r1 == 0)
720 r1 = fpzeroreg;
721 t = ((extru(ir,fptpos,5)<<1)|(extru(ir,fpxtpos,1)));
722 if (t == 0 && class != 2)
723 return(MAJOR_0E_EXCP);
724 if (class < 2)
725 fmt = extru(ir,fpfmtpos,2);
726 else
727 fmt = extru(ir,fp0efmtpos,1);
728
729
730
731
732
733 if (fmt == DBL) {
734 r1 &= ~1;
735 if (class != 1)
736 t &= ~1;
737 }
738
739 switch (class) {
740 case 0:
741 switch (subop) {
742 case 0:
743 case 1:
744 return(MAJOR_0E_EXCP);
745 case 2:
746 switch (fmt) {
747 case 2:
748 case 3:
749 return(MAJOR_0E_EXCP);
750 case 1:
751 fpregs[t+1] = fpregs[r1+1];
752 case 0:
753 fpregs[t] = fpregs[r1];
754 return(NOEXCEPTION);
755 }
756 case 3:
757 switch (fmt) {
758 case 2:
759 case 3:
760 return(MAJOR_0E_EXCP);
761 case 1:
762 fpregs[t+1] = fpregs[r1+1];
763 case 0:
764 fpregs[t] = fpregs[r1] & 0x7fffffff;
765 return(NOEXCEPTION);
766 }
767 case 6:
768 switch (fmt) {
769 case 2:
770 case 3:
771 return(MAJOR_0E_EXCP);
772 case 1:
773 fpregs[t+1] = fpregs[r1+1];
774 case 0:
775 fpregs[t] = fpregs[r1] ^ 0x80000000;
776 return(NOEXCEPTION);
777 }
778 case 7:
779 switch (fmt) {
780 case 2:
781 case 3:
782 return(MAJOR_0E_EXCP);
783 case 1:
784 fpregs[t+1] = fpregs[r1+1];
785 case 0:
786 fpregs[t] = fpregs[r1] | 0x80000000;
787 return(NOEXCEPTION);
788 }
789 case 4:
790 switch (fmt) {
791 case 0:
792 return(sgl_fsqrt(&fpregs[r1],0,
793 &fpregs[t], status));
794 case 1:
795 return(dbl_fsqrt(&fpregs[r1],0,
796 &fpregs[t], status));
797 case 2:
798 case 3:
799 return(MAJOR_0E_EXCP);
800 }
801 case 5:
802 switch (fmt) {
803 case 0:
804 return(sgl_frnd(&fpregs[r1],0,
805 &fpregs[t], status));
806 case 1:
807 return(dbl_frnd(&fpregs[r1],0,
808 &fpregs[t], status));
809 case 2:
810 case 3:
811 return(MAJOR_0E_EXCP);
812 }
813 }
814
815 case 1:
816 df = extru(ir,fpdfpos,2);
817
818
819
820
821 if (df == DBL) {
822 t &= ~1;
823 }
824 if ((df & 2) || (fmt & 2))
825 return(MAJOR_0E_EXCP);
826
827 fmt = (fmt << 1) | df;
828 switch (subop) {
829 case 0:
830 switch(fmt) {
831 case 0:
832 return(MAJOR_0E_EXCP);
833 case 1:
834 return(sgl_to_dbl_fcnvff(&fpregs[r1],0,
835 &fpregs[t],status));
836 case 2:
837 return(dbl_to_sgl_fcnvff(&fpregs[r1],0,
838 &fpregs[t],status));
839 case 3:
840 return(MAJOR_0E_EXCP);
841 }
842 case 1:
843 switch(fmt) {
844 case 0:
845 return(sgl_to_sgl_fcnvxf(&fpregs[r1],0,
846 &fpregs[t],status));
847 case 1:
848 return(sgl_to_dbl_fcnvxf(&fpregs[r1],0,
849 &fpregs[t],status));
850 case 2:
851 return(dbl_to_sgl_fcnvxf(&fpregs[r1],0,
852 &fpregs[t],status));
853 case 3:
854 return(dbl_to_dbl_fcnvxf(&fpregs[r1],0,
855 &fpregs[t],status));
856 }
857 case 2:
858 switch(fmt) {
859 case 0:
860 return(sgl_to_sgl_fcnvfx(&fpregs[r1],0,
861 &fpregs[t],status));
862 case 1:
863 return(sgl_to_dbl_fcnvfx(&fpregs[r1],0,
864 &fpregs[t],status));
865 case 2:
866 return(dbl_to_sgl_fcnvfx(&fpregs[r1],0,
867 &fpregs[t],status));
868 case 3:
869 return(dbl_to_dbl_fcnvfx(&fpregs[r1],0,
870 &fpregs[t],status));
871 }
872 case 3:
873 switch(fmt) {
874 case 0:
875 return(sgl_to_sgl_fcnvfxt(&fpregs[r1],0,
876 &fpregs[t],status));
877 case 1:
878 return(sgl_to_dbl_fcnvfxt(&fpregs[r1],0,
879 &fpregs[t],status));
880 case 2:
881 return(dbl_to_sgl_fcnvfxt(&fpregs[r1],0,
882 &fpregs[t],status));
883 case 3:
884 return(dbl_to_dbl_fcnvfxt(&fpregs[r1],0,
885 &fpregs[t],status));
886 }
887 case 5:
888 switch(fmt) {
889 case 0:
890 return(sgl_to_sgl_fcnvuf(&fpregs[r1],0,
891 &fpregs[t],status));
892 case 1:
893 return(sgl_to_dbl_fcnvuf(&fpregs[r1],0,
894 &fpregs[t],status));
895 case 2:
896 return(dbl_to_sgl_fcnvuf(&fpregs[r1],0,
897 &fpregs[t],status));
898 case 3:
899 return(dbl_to_dbl_fcnvuf(&fpregs[r1],0,
900 &fpregs[t],status));
901 }
902 case 6:
903 switch(fmt) {
904 case 0:
905 return(sgl_to_sgl_fcnvfu(&fpregs[r1],0,
906 &fpregs[t],status));
907 case 1:
908 return(sgl_to_dbl_fcnvfu(&fpregs[r1],0,
909 &fpregs[t],status));
910 case 2:
911 return(dbl_to_sgl_fcnvfu(&fpregs[r1],0,
912 &fpregs[t],status));
913 case 3:
914 return(dbl_to_dbl_fcnvfu(&fpregs[r1],0,
915 &fpregs[t],status));
916 }
917 case 7:
918 switch(fmt) {
919 case 0:
920 return(sgl_to_sgl_fcnvfut(&fpregs[r1],0,
921 &fpregs[t],status));
922 case 1:
923 return(sgl_to_dbl_fcnvfut(&fpregs[r1],0,
924 &fpregs[t],status));
925 case 2:
926 return(dbl_to_sgl_fcnvfut(&fpregs[r1],0,
927 &fpregs[t],status));
928 case 3:
929 return(dbl_to_dbl_fcnvfut(&fpregs[r1],0,
930 &fpregs[t],status));
931 }
932 case 4:
933 return(MAJOR_0C_EXCP);
934 }
935 case 2:
936
937
938
939
940
941
942
943
944 if (fmt == DBL)
945 r2 = (extru(ir,fpr2pos,5)<<1);
946 else
947 r2 = ((extru(ir,fpr2pos,5)<<1)|(extru(ir,fpxr2pos,1)));
948 fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS];
949 if (r2 == 0)
950 r2 = fpzeroreg;
951 if (fpu_type_flags & PA2_0_FPU_FLAG) {
952
953 if (extru(ir, fpnulpos, 1)) {
954
955 return(MAJOR_0E_EXCP);
956 } else {
957 switch (fmt) {
958
959
960
961 case 0:
962 retval = sgl_fcmp(&fpregs[r1],
963 &fpregs[r2],extru(ir,fptpos,5),
964 &local_status);
965 update_status_cbit(status,local_status,
966 fpu_type_flags, subop);
967 return(retval);
968 case 1:
969 retval = dbl_fcmp(&fpregs[r1],
970 &fpregs[r2],extru(ir,fptpos,5),
971 &local_status);
972 update_status_cbit(status,local_status,
973 fpu_type_flags, subop);
974 return(retval);
975 }
976 }
977 }
978 else {
979 switch (subop) {
980 case 1:
981 case 2:
982 case 3:
983 case 4:
984 case 5:
985 case 6:
986 case 7:
987 return(MAJOR_0E_EXCP);
988 case 0:
989 switch (fmt) {
990
991
992
993 case 0:
994 retval = sgl_fcmp(&fpregs[r1],
995 &fpregs[r2],extru(ir,fptpos,5),
996 &local_status);
997 update_status_cbit(status,local_status,
998 fpu_type_flags, subop);
999 return(retval);
1000 case 1:
1001 retval = dbl_fcmp(&fpregs[r1],
1002 &fpregs[r2],extru(ir,fptpos,5),
1003 &local_status);
1004 update_status_cbit(status,local_status,
1005 fpu_type_flags, subop);
1006 return(retval);
1007 }
1008 }
1009 }
1010 case 3:
1011
1012
1013
1014
1015
1016
1017
1018
1019 if (fmt == DBL)
1020 r2 = (extru(ir,fpr2pos,5)<<1);
1021 else
1022 r2 = ((extru(ir,fpr2pos,5)<<1)|(extru(ir,fpxr2pos,1)));
1023 if (r2 == 0)
1024 r2 = fpzeroreg;
1025 switch (subop) {
1026 case 5:
1027 case 6:
1028 case 7:
1029 return(MAJOR_0E_EXCP);
1030
1031
1032
1033 case 0:
1034 switch (fmt) {
1035 case 0:
1036 return(sgl_fadd(&fpregs[r1],&fpregs[r2],
1037 &fpregs[t],status));
1038 case 1:
1039 return(dbl_fadd(&fpregs[r1],&fpregs[r2],
1040 &fpregs[t],status));
1041 }
1042 case 1:
1043 switch (fmt) {
1044 case 0:
1045 return(sgl_fsub(&fpregs[r1],&fpregs[r2],
1046 &fpregs[t],status));
1047 case 1:
1048 return(dbl_fsub(&fpregs[r1],&fpregs[r2],
1049 &fpregs[t],status));
1050 }
1051 case 2:
1052
1053
1054
1055 if (extru(ir,fpxpos,1)) {
1056
1057
1058
1059 switch (fmt) {
1060 case 0:
1061
1062
1063
1064
1065 if (t & 1)
1066 return(MAJOR_0E_EXCP);
1067 BUG();
1068
1069
1070
1071
1072 return(NOEXCEPTION);
1073 case 1:
1074 return(MAJOR_0E_EXCP);
1075 }
1076 }
1077 else {
1078 switch (fmt) {
1079 case 0:
1080 return(sgl_fmpy(&fpregs[r1],
1081 &fpregs[r2],&fpregs[t],status));
1082 case 1:
1083 return(dbl_fmpy(&fpregs[r1],
1084 &fpregs[r2],&fpregs[t],status));
1085 }
1086 }
1087 case 3:
1088 switch (fmt) {
1089 case 0:
1090 return(sgl_fdiv(&fpregs[r1],&fpregs[r2],
1091 &fpregs[t],status));
1092 case 1:
1093 return(dbl_fdiv(&fpregs[r1],&fpregs[r2],
1094 &fpregs[t],status));
1095 }
1096 case 4:
1097 switch (fmt) {
1098 case 0:
1099 return(sgl_frem(&fpregs[r1],&fpregs[r2],
1100 &fpregs[t],status));
1101 case 1:
1102 return(dbl_frem(&fpregs[r1],&fpregs[r2],
1103 &fpregs[t],status));
1104 }
1105 }
1106 }
1107
1108
1109 return(MAJOR_0E_EXCP);
1110}
1111
1112
1113
1114
1115
1116static u_int
1117decode_06(ir,fpregs)
1118u_int ir;
1119u_int fpregs[];
1120{
1121 u_int rm1, rm2, tm, ra, ta;
1122 u_int fmt;
1123 u_int error = 0;
1124 u_int status;
1125 u_int fpu_type_flags;
1126 union {
1127 double dbl;
1128 float flt;
1129 struct { u_int i1; u_int i2; } ints;
1130 } mtmp, atmp;
1131
1132
1133 status = fpregs[0];
1134 fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS];
1135 fmt = extru(ir, fpmultifmt, 1);
1136 if (fmt == 0) {
1137 rm1 = extru(ir, fprm1pos, 5) * sizeof(double)/sizeof(u_int);
1138 if (rm1 == 0)
1139 rm1 = fpzeroreg;
1140 rm2 = extru(ir, fprm2pos, 5) * sizeof(double)/sizeof(u_int);
1141 if (rm2 == 0)
1142 rm2 = fpzeroreg;
1143 tm = extru(ir, fptmpos, 5) * sizeof(double)/sizeof(u_int);
1144 if (tm == 0)
1145 return(MAJOR_06_EXCP);
1146 ra = extru(ir, fprapos, 5) * sizeof(double)/sizeof(u_int);
1147 ta = extru(ir, fptapos, 5) * sizeof(double)/sizeof(u_int);
1148 if (ta == 0)
1149 return(MAJOR_06_EXCP);
1150
1151 if (fpu_type_flags & TIMEX_ROLEX_FPU_MASK) {
1152
1153 if (ra == 0) {
1154
1155 if (dbl_fmpy(&fpregs[rm1],&fpregs[rm2],
1156 &mtmp.ints.i1,&status))
1157 error = 1;
1158 if (dbl_to_sgl_fcnvfxt(&fpregs[ta],
1159 &atmp.ints.i1,&atmp.ints.i1,&status))
1160 error = 1;
1161 }
1162 else {
1163
1164 if (dbl_fmpy(&fpregs[rm1],&fpregs[rm2],&mtmp.ints.i1,
1165 &status))
1166 error = 1;
1167 if (dbl_fadd(&fpregs[ta], &fpregs[ra], &atmp.ints.i1,
1168 &status))
1169 error = 1;
1170 }
1171 }
1172
1173 else
1174
1175 {
1176 if (ra == 0)
1177 ra = fpzeroreg;
1178
1179 if (dbl_fmpy(&fpregs[rm1],&fpregs[rm2],&mtmp.ints.i1,
1180 &status))
1181 error = 1;
1182 if (dbl_fadd(&fpregs[ta], &fpregs[ra], &atmp.ints.i1,
1183 &status))
1184 error = 1;
1185
1186 }
1187
1188 if (error)
1189 return(MAJOR_06_EXCP);
1190 else {
1191
1192 fpregs[tm] = mtmp.ints.i1;
1193 fpregs[tm+1] = mtmp.ints.i2;
1194 fpregs[ta] = atmp.ints.i1;
1195 fpregs[ta+1] = atmp.ints.i2;
1196 fpregs[0] = status;
1197 return(NOEXCEPTION);
1198 }
1199 }
1200 else {
1201
1202
1203
1204
1205 rm1 = (extru(ir,fprm1pos,4) | 0x10 ) << 1;
1206 rm1 |= extru(ir,fprm1pos-4,1);
1207
1208 rm2 = (extru(ir,fprm2pos,4) | 0x10 ) << 1;
1209 rm2 |= extru(ir,fprm2pos-4,1);
1210
1211 tm = (extru(ir,fptmpos,4) | 0x10 ) << 1;
1212 tm |= extru(ir,fptmpos-4,1);
1213
1214 ra = (extru(ir,fprapos,4) | 0x10 ) << 1;
1215 ra |= extru(ir,fprapos-4,1);
1216
1217 ta = (extru(ir,fptapos,4) | 0x10 ) << 1;
1218 ta |= extru(ir,fptapos-4,1);
1219
1220 if (ra == 0x20 &&(fpu_type_flags & TIMEX_ROLEX_FPU_MASK)) {
1221
1222
1223
1224
1225
1226 if (sgl_fmpy(&fpregs[rm1],&fpregs[rm2],&mtmp.ints.i1,
1227 &status))
1228 error = 1;
1229 if (sgl_to_sgl_fcnvfxt(&fpregs[ta],&atmp.ints.i1,
1230 &atmp.ints.i1,&status))
1231 error = 1;
1232 }
1233 else {
1234 if (sgl_fmpy(&fpregs[rm1],&fpregs[rm2],&mtmp.ints.i1,
1235 &status))
1236 error = 1;
1237 if (sgl_fadd(&fpregs[ta], &fpregs[ra], &atmp.ints.i1,
1238 &status))
1239 error = 1;
1240 }
1241 if (error)
1242 return(MAJOR_06_EXCP);
1243 else {
1244
1245 fpregs[tm] = mtmp.ints.i1;
1246 fpregs[ta] = atmp.ints.i1;
1247 fpregs[0] = status;
1248 return(NOEXCEPTION);
1249 }
1250 }
1251}
1252
1253
1254
1255
1256static u_int
1257decode_26(ir,fpregs)
1258u_int ir;
1259u_int fpregs[];
1260{
1261 u_int rm1, rm2, tm, ra, ta;
1262 u_int fmt;
1263 u_int error = 0;
1264 u_int status;
1265 union {
1266 double dbl;
1267 float flt;
1268 struct { u_int i1; u_int i2; } ints;
1269 } mtmp, atmp;
1270
1271
1272 status = fpregs[0];
1273 fmt = extru(ir, fpmultifmt, 1);
1274 if (fmt == 0) {
1275 rm1 = extru(ir, fprm1pos, 5) * sizeof(double)/sizeof(u_int);
1276 if (rm1 == 0)
1277 rm1 = fpzeroreg;
1278 rm2 = extru(ir, fprm2pos, 5) * sizeof(double)/sizeof(u_int);
1279 if (rm2 == 0)
1280 rm2 = fpzeroreg;
1281 tm = extru(ir, fptmpos, 5) * sizeof(double)/sizeof(u_int);
1282 if (tm == 0)
1283 return(MAJOR_26_EXCP);
1284 ra = extru(ir, fprapos, 5) * sizeof(double)/sizeof(u_int);
1285 if (ra == 0)
1286 return(MAJOR_26_EXCP);
1287 ta = extru(ir, fptapos, 5) * sizeof(double)/sizeof(u_int);
1288 if (ta == 0)
1289 return(MAJOR_26_EXCP);
1290
1291 if (dbl_fmpy(&fpregs[rm1],&fpregs[rm2],&mtmp.ints.i1,&status))
1292 error = 1;
1293 if (dbl_fsub(&fpregs[ta], &fpregs[ra], &atmp.ints.i1,&status))
1294 error = 1;
1295 if (error)
1296 return(MAJOR_26_EXCP);
1297 else {
1298
1299 fpregs[tm] = mtmp.ints.i1;
1300 fpregs[tm+1] = mtmp.ints.i2;
1301 fpregs[ta] = atmp.ints.i1;
1302 fpregs[ta+1] = atmp.ints.i2;
1303 fpregs[0] = status;
1304 return(NOEXCEPTION);
1305 }
1306 }
1307 else {
1308
1309
1310
1311
1312 rm1 = (extru(ir,fprm1pos,4) | 0x10 ) << 1;
1313 rm1 |= extru(ir,fprm1pos-4,1);
1314
1315 rm2 = (extru(ir,fprm2pos,4) | 0x10 ) << 1;
1316 rm2 |= extru(ir,fprm2pos-4,1);
1317
1318 tm = (extru(ir,fptmpos,4) | 0x10 ) << 1;
1319 tm |= extru(ir,fptmpos-4,1);
1320
1321 ra = (extru(ir,fprapos,4) | 0x10 ) << 1;
1322 ra |= extru(ir,fprapos-4,1);
1323
1324 ta = (extru(ir,fptapos,4) | 0x10 ) << 1;
1325 ta |= extru(ir,fptapos-4,1);
1326
1327 if (sgl_fmpy(&fpregs[rm1],&fpregs[rm2],&mtmp.ints.i1,&status))
1328 error = 1;
1329 if (sgl_fsub(&fpregs[ta], &fpregs[ra], &atmp.ints.i1,&status))
1330 error = 1;
1331 if (error)
1332 return(MAJOR_26_EXCP);
1333 else {
1334
1335 fpregs[tm] = mtmp.ints.i1;
1336 fpregs[ta] = atmp.ints.i1;
1337 fpregs[0] = status;
1338 return(NOEXCEPTION);
1339 }
1340 }
1341
1342}
1343
1344
1345
1346
1347static u_int
1348decode_2e(ir,fpregs)
1349u_int ir;
1350u_int fpregs[];
1351{
1352 u_int rm1, rm2, ra, t;
1353 u_int fmt;
1354
1355 fmt = extru(ir,fpfmtpos,1);
1356 if (fmt == DBL) {
1357 rm1 = extru(ir,fprm1pos,5) * sizeof(double)/sizeof(u_int);
1358 if (rm1 == 0)
1359 rm1 = fpzeroreg;
1360 rm2 = extru(ir,fprm2pos,5) * sizeof(double)/sizeof(u_int);
1361 if (rm2 == 0)
1362 rm2 = fpzeroreg;
1363 ra = ((extru(ir,fpraupos,3)<<2)|(extru(ir,fpralpos,3)>>1)) *
1364 sizeof(double)/sizeof(u_int);
1365 if (ra == 0)
1366 ra = fpzeroreg;
1367 t = extru(ir,fptpos,5) * sizeof(double)/sizeof(u_int);
1368 if (t == 0)
1369 return(MAJOR_2E_EXCP);
1370
1371 if (extru(ir,fpfusedsubop,1)) {
1372 return(dbl_fmpynfadd(&fpregs[rm1], &fpregs[rm2],
1373 &fpregs[ra], &fpregs[0], &fpregs[t]));
1374 } else {
1375 return(dbl_fmpyfadd(&fpregs[rm1], &fpregs[rm2],
1376 &fpregs[ra], &fpregs[0], &fpregs[t]));
1377 }
1378 }
1379 else {
1380 rm1 = (extru(ir,fprm1pos,5)<<1)|(extru(ir,fpxrm1pos,1));
1381 if (rm1 == 0)
1382 rm1 = fpzeroreg;
1383 rm2 = (extru(ir,fprm2pos,5)<<1)|(extru(ir,fpxrm2pos,1));
1384 if (rm2 == 0)
1385 rm2 = fpzeroreg;
1386 ra = (extru(ir,fpraupos,3)<<3)|extru(ir,fpralpos,3);
1387 if (ra == 0)
1388 ra = fpzeroreg;
1389 t = ((extru(ir,fptpos,5)<<1)|(extru(ir,fpxtpos,1)));
1390 if (t == 0)
1391 return(MAJOR_2E_EXCP);
1392
1393 if (extru(ir,fpfusedsubop,1)) {
1394 return(sgl_fmpynfadd(&fpregs[rm1], &fpregs[rm2],
1395 &fpregs[ra], &fpregs[0], &fpregs[t]));
1396 } else {
1397 return(sgl_fmpyfadd(&fpregs[rm1], &fpregs[rm2],
1398 &fpregs[ra], &fpregs[0], &fpregs[t]));
1399 }
1400 }
1401}
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413static void
1414update_status_cbit(status, new_status, fpu_type, y_field)
1415u_int *status, new_status;
1416u_int fpu_type;
1417u_int y_field;
1418{
1419
1420
1421
1422
1423
1424
1425 if ((fpu_type & TIMEX_EXTEN_FLAG) ||
1426 (fpu_type & ROLEX_EXTEN_FLAG) ||
1427 (fpu_type & PA2_0_FPU_FLAG)) {
1428 if (y_field == 0) {
1429 *status = ((*status & 0x04000000) >> 5) |
1430 ((*status & 0x003ff000) >> 1) |
1431 (new_status & 0xffc007ff);
1432 } else {
1433 *status = (*status & 0x04000000) |
1434 ((new_status & 0x04000000) >> (y_field+4)) |
1435 (new_status & ~0x04000000 &
1436 ~(0x04000000 >> (y_field+4)));
1437 }
1438 }
1439
1440 else {
1441 *status = new_status;
1442 }
1443}
1444