Revision 81ad8ba2 target-sparc/op_helper.c
b/target-sparc/op_helper.c | ||
---|---|---|
137 | 137 |
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1); |
138 | 138 |
#endif |
139 | 139 |
|
140 |
#if defined(CONFIG_USER_ONLY) |
|
141 |
void helper_ld_asi(int asi, int size, int sign) |
|
142 |
{ |
|
143 |
} |
|
144 |
|
|
145 |
void helper_st_asi(int asi, int size, int sign) |
|
146 |
{ |
|
147 |
} |
|
148 |
#else |
|
149 | 140 |
#ifndef TARGET_SPARC64 |
141 |
#ifndef CONFIG_USER_ONLY |
|
150 | 142 |
void helper_ld_asi(int asi, int size, int sign) |
151 | 143 |
{ |
152 | 144 |
uint32_t ret = 0; |
... | ... | |
200 | 192 |
break; |
201 | 193 |
} |
202 | 194 |
break; |
195 |
case 0xa: /* User data access */ |
|
196 |
switch(size) { |
|
197 |
case 1: |
|
198 |
ret = ldub_user(T0); |
|
199 |
break; |
|
200 |
case 2: |
|
201 |
ret = lduw_user(T0 & ~1); |
|
202 |
break; |
|
203 |
default: |
|
204 |
case 4: |
|
205 |
ret = ldl_user(T0 & ~3); |
|
206 |
break; |
|
207 |
case 8: |
|
208 |
ret = ldl_user(T0 & ~3); |
|
209 |
T0 = ldl_user((T0 + 4) & ~3); |
|
210 |
break; |
|
211 |
} |
|
212 |
break; |
|
213 |
case 0xb: /* Supervisor data access */ |
|
214 |
switch(size) { |
|
215 |
case 1: |
|
216 |
ret = ldub_kernel(T0); |
|
217 |
break; |
|
218 |
case 2: |
|
219 |
ret = lduw_kernel(T0 & ~1); |
|
220 |
break; |
|
221 |
default: |
|
222 |
case 4: |
|
223 |
ret = ldl_kernel(T0 & ~3); |
|
224 |
break; |
|
225 |
case 8: |
|
226 |
ret = ldl_kernel(T0 & ~3); |
|
227 |
T0 = ldl_kernel((T0 + 4) & ~3); |
|
228 |
break; |
|
229 |
} |
|
230 |
break; |
|
203 | 231 |
case 0xc: /* I-cache tag */ |
204 | 232 |
case 0xd: /* I-cache data */ |
205 | 233 |
case 0xe: /* D-cache tag */ |
... | ... | |
253 | 281 |
ret = 0; |
254 | 282 |
break; |
255 | 283 |
} |
256 |
T1 = ret; |
|
284 |
if (sign) { |
|
285 |
switch(size) { |
|
286 |
case 1: |
|
287 |
T1 = (int8_t) ret; |
|
288 |
case 2: |
|
289 |
T1 = (int16_t) ret; |
|
290 |
default: |
|
291 |
T1 = ret; |
|
292 |
break; |
|
293 |
} |
|
294 |
} |
|
295 |
else |
|
296 |
T1 = ret; |
|
257 | 297 |
} |
258 | 298 |
|
259 |
void helper_st_asi(int asi, int size, int sign)
|
|
299 |
void helper_st_asi(int asi, int size) |
|
260 | 300 |
{ |
261 | 301 |
switch(asi) { |
262 | 302 |
case 2: /* SuperSparc MXCC registers */ |
... | ... | |
325 | 365 |
#endif |
326 | 366 |
return; |
327 | 367 |
} |
368 |
case 0xa: /* User data access */ |
|
369 |
switch(size) { |
|
370 |
case 1: |
|
371 |
stb_user(T0, T1); |
|
372 |
break; |
|
373 |
case 2: |
|
374 |
stw_user(T0 & ~1, T1); |
|
375 |
break; |
|
376 |
default: |
|
377 |
case 4: |
|
378 |
stl_user(T0 & ~3, T1); |
|
379 |
break; |
|
380 |
case 8: |
|
381 |
stl_user(T0 & ~3, T1); |
|
382 |
stl_user((T0 + 4) & ~3, T2); |
|
383 |
break; |
|
384 |
} |
|
385 |
break; |
|
386 |
case 0xb: /* Supervisor data access */ |
|
387 |
switch(size) { |
|
388 |
case 1: |
|
389 |
stb_kernel(T0, T1); |
|
390 |
break; |
|
391 |
case 2: |
|
392 |
stw_kernel(T0 & ~1, T1); |
|
393 |
break; |
|
394 |
default: |
|
395 |
case 4: |
|
396 |
stl_kernel(T0 & ~3, T1); |
|
397 |
break; |
|
398 |
case 8: |
|
399 |
stl_kernel(T0 & ~3, T1); |
|
400 |
stl_kernel((T0 + 4) & ~3, T2); |
|
401 |
break; |
|
402 |
} |
|
403 |
break; |
|
328 | 404 |
case 0xc: /* I-cache tag */ |
329 | 405 |
case 0xd: /* I-cache data */ |
330 | 406 |
case 0xe: /* D-cache tag */ |
... | ... | |
422 | 498 |
} |
423 | 499 |
} |
424 | 500 |
|
425 |
#else |
|
501 |
#endif /* CONFIG_USER_ONLY */ |
|
502 |
#else /* TARGET_SPARC64 */ |
|
503 |
|
|
504 |
#ifdef CONFIG_USER_ONLY |
|
505 |
void helper_ld_asi(int asi, int size, int sign) |
|
506 |
{ |
|
507 |
uint64_t ret = 0; |
|
508 |
|
|
509 |
if (asi < 0x80) |
|
510 |
raise_exception(TT_PRIV_ACT); |
|
511 |
|
|
512 |
switch (asi) { |
|
513 |
case 0x80: // Primary |
|
514 |
case 0x82: // Primary no-fault |
|
515 |
case 0x88: // Primary LE |
|
516 |
case 0x8a: // Primary no-fault LE |
|
517 |
{ |
|
518 |
switch(size) { |
|
519 |
case 1: |
|
520 |
ret = ldub_raw(T0); |
|
521 |
break; |
|
522 |
case 2: |
|
523 |
ret = lduw_raw(T0 & ~1); |
|
524 |
break; |
|
525 |
case 4: |
|
526 |
ret = ldl_raw(T0 & ~3); |
|
527 |
break; |
|
528 |
default: |
|
529 |
case 8: |
|
530 |
ret = ldq_raw(T0 & ~7); |
|
531 |
break; |
|
532 |
} |
|
533 |
} |
|
534 |
break; |
|
535 |
case 0x81: // Secondary |
|
536 |
case 0x83: // Secondary no-fault |
|
537 |
case 0x89: // Secondary LE |
|
538 |
case 0x8b: // Secondary no-fault LE |
|
539 |
// XXX |
|
540 |
break; |
|
541 |
default: |
|
542 |
break; |
|
543 |
} |
|
544 |
|
|
545 |
/* Convert from little endian */ |
|
546 |
switch (asi) { |
|
547 |
case 0x88: // Primary LE |
|
548 |
case 0x89: // Secondary LE |
|
549 |
case 0x8a: // Primary no-fault LE |
|
550 |
case 0x8b: // Secondary no-fault LE |
|
551 |
switch(size) { |
|
552 |
case 2: |
|
553 |
ret = bswap16(ret); |
|
554 |
case 4: |
|
555 |
ret = bswap32(ret); |
|
556 |
case 8: |
|
557 |
ret = bswap64(ret); |
|
558 |
default: |
|
559 |
break; |
|
560 |
} |
|
561 |
default: |
|
562 |
break; |
|
563 |
} |
|
564 |
|
|
565 |
/* Convert to signed number */ |
|
566 |
if (sign) { |
|
567 |
switch(size) { |
|
568 |
case 1: |
|
569 |
ret = (int8_t) ret; |
|
570 |
case 2: |
|
571 |
ret = (int16_t) ret; |
|
572 |
case 4: |
|
573 |
ret = (int32_t) ret; |
|
574 |
default: |
|
575 |
break; |
|
576 |
} |
|
577 |
} |
|
578 |
T1 = ret; |
|
579 |
} |
|
580 |
|
|
581 |
void helper_st_asi(int asi, int size) |
|
582 |
{ |
|
583 |
if (asi < 0x80) |
|
584 |
raise_exception(TT_PRIV_ACT); |
|
585 |
|
|
586 |
/* Convert to little endian */ |
|
587 |
switch (asi) { |
|
588 |
case 0x88: // Primary LE |
|
589 |
case 0x89: // Secondary LE |
|
590 |
switch(size) { |
|
591 |
case 2: |
|
592 |
T0 = bswap16(T0); |
|
593 |
case 4: |
|
594 |
T0 = bswap32(T0); |
|
595 |
case 8: |
|
596 |
T0 = bswap64(T0); |
|
597 |
default: |
|
598 |
break; |
|
599 |
} |
|
600 |
default: |
|
601 |
break; |
|
602 |
} |
|
603 |
|
|
604 |
switch(asi) { |
|
605 |
case 0x80: // Primary |
|
606 |
case 0x88: // Primary LE |
|
607 |
{ |
|
608 |
switch(size) { |
|
609 |
case 1: |
|
610 |
stb_raw(T0, T1); |
|
611 |
break; |
|
612 |
case 2: |
|
613 |
stw_raw(T0 & ~1, T1); |
|
614 |
break; |
|
615 |
case 4: |
|
616 |
stl_raw(T0 & ~3, T1); |
|
617 |
break; |
|
618 |
case 8: |
|
619 |
default: |
|
620 |
stq_raw(T0 & ~7, T1); |
|
621 |
break; |
|
622 |
} |
|
623 |
} |
|
624 |
break; |
|
625 |
case 0x81: // Secondary |
|
626 |
case 0x89: // Secondary LE |
|
627 |
// XXX |
|
628 |
return; |
|
629 |
|
|
630 |
case 0x82: // Primary no-fault, RO |
|
631 |
case 0x83: // Secondary no-fault, RO |
|
632 |
case 0x8a: // Primary no-fault LE, RO |
|
633 |
case 0x8b: // Secondary no-fault LE, RO |
|
634 |
default: |
|
635 |
do_unassigned_access(T0, 1, 0, 1); |
|
636 |
return; |
|
637 |
} |
|
638 |
} |
|
639 |
|
|
640 |
#else /* CONFIG_USER_ONLY */ |
|
426 | 641 |
|
427 | 642 |
void helper_ld_asi(int asi, int size, int sign) |
428 | 643 |
{ |
... | ... | |
432 | 647 |
raise_exception(TT_PRIV_ACT); |
433 | 648 |
|
434 | 649 |
switch (asi) { |
650 |
case 0x10: // As if user primary |
|
651 |
case 0x18: // As if user primary LE |
|
652 |
case 0x80: // Primary |
|
653 |
case 0x82: // Primary no-fault |
|
654 |
case 0x88: // Primary LE |
|
655 |
case 0x8a: // Primary no-fault LE |
|
656 |
if ((asi & 0x80) && (env->pstate & PS_PRIV)) { |
|
657 |
switch(size) { |
|
658 |
case 1: |
|
659 |
ret = ldub_kernel(T0); |
|
660 |
break; |
|
661 |
case 2: |
|
662 |
ret = lduw_kernel(T0 & ~1); |
|
663 |
break; |
|
664 |
case 4: |
|
665 |
ret = ldl_kernel(T0 & ~3); |
|
666 |
break; |
|
667 |
default: |
|
668 |
case 8: |
|
669 |
ret = ldq_kernel(T0 & ~7); |
|
670 |
break; |
|
671 |
} |
|
672 |
} else { |
|
673 |
switch(size) { |
|
674 |
case 1: |
|
675 |
ret = ldub_user(T0); |
|
676 |
break; |
|
677 |
case 2: |
|
678 |
ret = lduw_user(T0 & ~1); |
|
679 |
break; |
|
680 |
case 4: |
|
681 |
ret = ldl_user(T0 & ~3); |
|
682 |
break; |
|
683 |
default: |
|
684 |
case 8: |
|
685 |
ret = ldq_user(T0 & ~7); |
|
686 |
break; |
|
687 |
} |
|
688 |
} |
|
689 |
break; |
|
435 | 690 |
case 0x14: // Bypass |
436 | 691 |
case 0x15: // Bypass, non-cacheable |
692 |
case 0x1c: // Bypass LE |
|
693 |
case 0x1d: // Bypass, non-cacheable LE |
|
437 | 694 |
{ |
438 | 695 |
switch(size) { |
439 | 696 |
case 1: |
... | ... | |
454 | 711 |
} |
455 | 712 |
case 0x04: // Nucleus |
456 | 713 |
case 0x0c: // Nucleus Little Endian (LE) |
457 |
case 0x10: // As if user primary |
|
458 | 714 |
case 0x11: // As if user secondary |
459 |
case 0x18: // As if user primary LE |
|
460 | 715 |
case 0x19: // As if user secondary LE |
461 |
case 0x1c: // Bypass LE |
|
462 |
case 0x1d: // Bypass, non-cacheable LE |
|
463 | 716 |
case 0x24: // Nucleus quad LDD 128 bit atomic |
464 | 717 |
case 0x2c: // Nucleus quad LDD 128 bit atomic |
465 | 718 |
case 0x4a: // UPA config |
466 |
case 0x82: // Primary no-fault
|
|
719 |
case 0x81: // Secondary
|
|
467 | 720 |
case 0x83: // Secondary no-fault |
468 |
case 0x88: // Primary LE |
|
469 | 721 |
case 0x89: // Secondary LE |
470 |
case 0x8a: // Primary no-fault LE |
|
471 | 722 |
case 0x8b: // Secondary no-fault LE |
472 | 723 |
// XXX |
473 | 724 |
break; |
... | ... | |
540 | 791 |
ret = 0; |
541 | 792 |
break; |
542 | 793 |
} |
794 |
|
|
795 |
/* Convert from little endian */ |
|
796 |
switch (asi) { |
|
797 |
case 0x0c: // Nucleus Little Endian (LE) |
|
798 |
case 0x18: // As if user primary LE |
|
799 |
case 0x19: // As if user secondary LE |
|
800 |
case 0x1c: // Bypass LE |
|
801 |
case 0x1d: // Bypass, non-cacheable LE |
|
802 |
case 0x88: // Primary LE |
|
803 |
case 0x89: // Secondary LE |
|
804 |
case 0x8a: // Primary no-fault LE |
|
805 |
case 0x8b: // Secondary no-fault LE |
|
806 |
switch(size) { |
|
807 |
case 2: |
|
808 |
ret = bswap16(ret); |
|
809 |
case 4: |
|
810 |
ret = bswap32(ret); |
|
811 |
case 8: |
|
812 |
ret = bswap64(ret); |
|
813 |
default: |
|
814 |
break; |
|
815 |
} |
|
816 |
default: |
|
817 |
break; |
|
818 |
} |
|
819 |
|
|
820 |
/* Convert to signed number */ |
|
821 |
if (sign) { |
|
822 |
switch(size) { |
|
823 |
case 1: |
|
824 |
ret = (int8_t) ret; |
|
825 |
case 2: |
|
826 |
ret = (int16_t) ret; |
|
827 |
case 4: |
|
828 |
ret = (int32_t) ret; |
|
829 |
default: |
|
830 |
break; |
|
831 |
} |
|
832 |
} |
|
543 | 833 |
T1 = ret; |
544 | 834 |
} |
545 | 835 |
|
546 |
void helper_st_asi(int asi, int size, int sign)
|
|
836 |
void helper_st_asi(int asi, int size) |
|
547 | 837 |
{ |
548 | 838 |
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0) |
549 | 839 |
raise_exception(TT_PRIV_ACT); |
550 | 840 |
|
841 |
/* Convert to little endian */ |
|
842 |
switch (asi) { |
|
843 |
case 0x0c: // Nucleus Little Endian (LE) |
|
844 |
case 0x18: // As if user primary LE |
|
845 |
case 0x19: // As if user secondary LE |
|
846 |
case 0x1c: // Bypass LE |
|
847 |
case 0x1d: // Bypass, non-cacheable LE |
|
848 |
case 0x81: // Secondary |
|
849 |
case 0x88: // Primary LE |
|
850 |
case 0x89: // Secondary LE |
|
851 |
switch(size) { |
|
852 |
case 2: |
|
853 |
T0 = bswap16(T0); |
|
854 |
case 4: |
|
855 |
T0 = bswap32(T0); |
|
856 |
case 8: |
|
857 |
T0 = bswap64(T0); |
|
858 |
default: |
|
859 |
break; |
|
860 |
} |
|
861 |
default: |
|
862 |
break; |
|
863 |
} |
|
864 |
|
|
551 | 865 |
switch(asi) { |
866 |
case 0x10: // As if user primary |
|
867 |
case 0x18: // As if user primary LE |
|
868 |
case 0x80: // Primary |
|
869 |
case 0x88: // Primary LE |
|
870 |
if ((asi & 0x80) && (env->pstate & PS_PRIV)) { |
|
871 |
switch(size) { |
|
872 |
case 1: |
|
873 |
stb_kernel(T0, T1); |
|
874 |
break; |
|
875 |
case 2: |
|
876 |
stw_kernel(T0 & ~1, T1); |
|
877 |
break; |
|
878 |
case 4: |
|
879 |
stl_kernel(T0 & ~3, T1); |
|
880 |
break; |
|
881 |
case 8: |
|
882 |
default: |
|
883 |
stq_kernel(T0 & ~7, T1); |
|
884 |
break; |
|
885 |
} |
|
886 |
} else { |
|
887 |
switch(size) { |
|
888 |
case 1: |
|
889 |
stb_user(T0, T1); |
|
890 |
break; |
|
891 |
case 2: |
|
892 |
stw_user(T0 & ~1, T1); |
|
893 |
break; |
|
894 |
case 4: |
|
895 |
stl_user(T0 & ~3, T1); |
|
896 |
break; |
|
897 |
case 8: |
|
898 |
default: |
|
899 |
stq_user(T0 & ~7, T1); |
|
900 |
break; |
|
901 |
} |
|
902 |
} |
|
903 |
break; |
|
552 | 904 |
case 0x14: // Bypass |
553 | 905 |
case 0x15: // Bypass, non-cacheable |
906 |
case 0x1c: // Bypass LE |
|
907 |
case 0x1d: // Bypass, non-cacheable LE |
|
554 | 908 |
{ |
555 | 909 |
switch(size) { |
556 | 910 |
case 1: |
... | ... | |
571 | 925 |
return; |
572 | 926 |
case 0x04: // Nucleus |
573 | 927 |
case 0x0c: // Nucleus Little Endian (LE) |
574 |
case 0x10: // As if user primary |
|
575 | 928 |
case 0x11: // As if user secondary |
576 |
case 0x18: // As if user primary LE |
|
577 | 929 |
case 0x19: // As if user secondary LE |
578 |
case 0x1c: // Bypass LE |
|
579 |
case 0x1d: // Bypass, non-cacheable LE |
|
580 | 930 |
case 0x24: // Nucleus quad LDD 128 bit atomic |
581 | 931 |
case 0x2c: // Nucleus quad LDD 128 bit atomic |
582 | 932 |
case 0x4a: // UPA config |
583 |
case 0x88: // Primary LE |
|
584 | 933 |
case 0x89: // Secondary LE |
585 | 934 |
// XXX |
586 | 935 |
return; |
... | ... | |
756 | 1105 |
return; |
757 | 1106 |
} |
758 | 1107 |
} |
759 |
#endif |
|
760 |
#endif /* !CONFIG_USER_ONLY */
|
|
1108 |
#endif /* CONFIG_USER_ONLY */
|
|
1109 |
#endif /* TARGET_SPARC64 */
|
|
761 | 1110 |
|
762 | 1111 |
#ifndef TARGET_SPARC64 |
763 | 1112 |
void helper_rett() |
Also available in: Unified diff