Commit 81ad8ba242815e27f990e18778c7cdca2e7e7522
1 parent
43febf49
Rework ASI instructions (Aurelien Jarno)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3205 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
727 additions
and
204 deletions
target-sparc/exec.h
... | ... | @@ -50,7 +50,7 @@ void cpu_unlock(void); |
50 | 50 | void cpu_loop_exit(void); |
51 | 51 | void helper_flush(target_ulong addr); |
52 | 52 | void helper_ld_asi(int asi, int size, int sign); |
53 | -void helper_st_asi(int asi, int size, int sign); | |
53 | +void helper_st_asi(int asi, int size); | |
54 | 54 | void helper_rett(void); |
55 | 55 | void helper_ldfsr(void); |
56 | 56 | void set_cwp(int new_cwp); |
... | ... |
target-sparc/op.c
... | ... | @@ -1862,10 +1862,126 @@ void OPPROTO op_ld_asi_reg() |
1862 | 1862 | void OPPROTO op_st_asi_reg() |
1863 | 1863 | { |
1864 | 1864 | T0 += PARAM1; |
1865 | - helper_st_asi(env->asi, PARAM2, PARAM3); | |
1865 | + helper_st_asi(env->asi, PARAM2); | |
1866 | +} | |
1867 | + | |
1868 | +void OPPROTO op_ldstub_asi_reg() /* XXX: should be atomically */ | |
1869 | +{ | |
1870 | + target_ulong tmp; | |
1871 | + | |
1872 | + T0 += PARAM1; | |
1873 | + helper_ld_asi(env->asi, 1, 0); | |
1874 | + tmp = T1; | |
1875 | + T1 = 0xff; | |
1876 | + helper_st_asi(env->asi, 1); | |
1877 | + T1 = tmp; | |
1878 | +} | |
1879 | + | |
1880 | +void OPPROTO op_swap_asi_reg() /* XXX: should be atomically */ | |
1881 | +{ | |
1882 | + target_ulong tmp1, tmp2; | |
1883 | + | |
1884 | + T0 += PARAM1; | |
1885 | + tmp1 = T1; | |
1886 | + helper_ld_asi(env->asi, 4, 0); | |
1887 | + tmp2 = T1; | |
1888 | + T1 = tmp1; | |
1889 | + helper_st_asi(env->asi, 4); | |
1890 | + T1 = tmp2; | |
1891 | +} | |
1892 | + | |
1893 | +void OPPROTO op_ldda_asi() | |
1894 | +{ | |
1895 | + helper_ld_asi(PARAM1, 8, 0); | |
1896 | + T0 = T1 & 0xffffffffUL; | |
1897 | + T1 >>= 32; | |
1898 | +} | |
1899 | + | |
1900 | +void OPPROTO op_ldda_asi_reg() | |
1901 | +{ | |
1902 | + T0 += PARAM1; | |
1903 | + helper_ld_asi(env->asi, 8, 0); | |
1904 | + T0 = T1 & 0xffffffffUL; | |
1905 | + T1 >>= 32; | |
1906 | +} | |
1907 | + | |
1908 | +void OPPROTO op_stda_asi() | |
1909 | +{ | |
1910 | + T1 <<= 32; | |
1911 | + T1 += T2 & 0xffffffffUL; | |
1912 | + helper_st_asi(PARAM1, 8); | |
1913 | +} | |
1914 | + | |
1915 | +void OPPROTO op_stda_asi_reg() | |
1916 | +{ | |
1917 | + T0 += PARAM1; | |
1918 | + T1 <<= 32; | |
1919 | + T1 += T2 & 0xffffffffUL; | |
1920 | + helper_st_asi(env->asi, 8); | |
1921 | +} | |
1922 | + | |
1923 | +void OPPROTO op_cas_asi() /* XXX: should be atomically */ | |
1924 | +{ | |
1925 | + target_ulong tmp; | |
1926 | + | |
1927 | + tmp = T1 & 0xffffffffUL; | |
1928 | + helper_ld_asi(PARAM1, 4, 0); | |
1929 | + if (tmp == T1) { | |
1930 | + tmp = T1; | |
1931 | + T1 = T2 & 0xffffffffUL; | |
1932 | + helper_st_asi(PARAM1, 4); | |
1933 | + T1 = tmp; | |
1934 | + } | |
1935 | + T1 &= 0xffffffffUL; | |
1936 | +} | |
1937 | + | |
1938 | +void OPPROTO op_cas_asi_reg() /* XXX: should be atomically */ | |
1939 | +{ | |
1940 | + target_ulong tmp; | |
1941 | + | |
1942 | + T0 += PARAM1; | |
1943 | + tmp = T1 & 0xffffffffUL; | |
1944 | + helper_ld_asi(env->asi, 4, 0); | |
1945 | + if (tmp == T1) { | |
1946 | + tmp = T1; | |
1947 | + T1 = T2 & 0xffffffffUL; | |
1948 | + helper_st_asi(env->asi, 4); | |
1949 | + T1 = tmp; | |
1950 | + } | |
1951 | + T1 &= 0xffffffffUL; | |
1952 | +} | |
1953 | + | |
1954 | +void OPPROTO op_casx_asi() /* XXX: should be atomically */ | |
1955 | +{ | |
1956 | + target_ulong tmp; | |
1957 | + | |
1958 | + tmp = T1; | |
1959 | + helper_ld_asi(PARAM1, 8, 0); | |
1960 | + if (tmp == T1) { | |
1961 | + tmp = T1; | |
1962 | + T1 = T2; | |
1963 | + helper_st_asi(PARAM1, 8); | |
1964 | + T1 = tmp; | |
1965 | + } | |
1966 | +} | |
1967 | + | |
1968 | +void OPPROTO op_casx_asi_reg() /* XXX: should be atomically */ | |
1969 | +{ | |
1970 | + target_ulong tmp; | |
1971 | + | |
1972 | + T0 += PARAM1; | |
1973 | + tmp = T1; | |
1974 | + helper_ld_asi(env->asi, 8, 0); | |
1975 | + if (tmp == T1) { | |
1976 | + tmp = T1; | |
1977 | + T1 = T2; | |
1978 | + helper_st_asi(env->asi, 8); | |
1979 | + T1 = tmp; | |
1980 | + } | |
1866 | 1981 | } |
1867 | 1982 | #endif |
1868 | 1983 | |
1984 | +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) | |
1869 | 1985 | void OPPROTO op_ld_asi() |
1870 | 1986 | { |
1871 | 1987 | helper_ld_asi(PARAM1, PARAM2, PARAM3); |
... | ... | @@ -1873,9 +1989,33 @@ void OPPROTO op_ld_asi() |
1873 | 1989 | |
1874 | 1990 | void OPPROTO op_st_asi() |
1875 | 1991 | { |
1876 | - helper_st_asi(PARAM1, PARAM2, PARAM3); | |
1992 | + helper_st_asi(PARAM1, PARAM2); | |
1877 | 1993 | } |
1878 | 1994 | |
1995 | +void OPPROTO op_ldstub_asi() /* XXX: should be atomically */ | |
1996 | +{ | |
1997 | + target_ulong tmp; | |
1998 | + | |
1999 | + helper_ld_asi(PARAM1, 1, 0); | |
2000 | + tmp = T1; | |
2001 | + T1 = 0xff; | |
2002 | + helper_st_asi(PARAM1, 1); | |
2003 | + T1 = tmp; | |
2004 | +} | |
2005 | + | |
2006 | +void OPPROTO op_swap_asi() /* XXX: should be atomically */ | |
2007 | +{ | |
2008 | + target_ulong tmp1, tmp2; | |
2009 | + | |
2010 | + tmp1 = T1; | |
2011 | + helper_ld_asi(PARAM1, 4, 0); | |
2012 | + tmp2 = T1; | |
2013 | + T1 = tmp1; | |
2014 | + helper_st_asi(PARAM1, 4); | |
2015 | + T1 = tmp2; | |
2016 | +} | |
2017 | +#endif | |
2018 | + | |
1879 | 2019 | #ifdef TARGET_SPARC64 |
1880 | 2020 | // This function uses non-native bit order |
1881 | 2021 | #define GET_FIELD(X, FROM, TO) \ |
... | ... |
target-sparc/op_helper.c
... | ... | @@ -137,16 +137,8 @@ GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1); |
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,6 +192,42 @@ void helper_ld_asi(int asi, int size, int sign) |
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,10 +281,22 @@ void helper_ld_asi(int asi, int size, int sign) |
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,6 +365,42 @@ void helper_st_asi(int asi, int size, int sign) |
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,7 +498,146 @@ void helper_st_asi(int asi, int size, int sign) |
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,8 +647,50 @@ void helper_ld_asi(int asi, int size, int sign) |
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,20 +711,14 @@ void helper_ld_asi(int asi, int size, int sign) |
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,17 +791,120 @@ void helper_ld_asi(int asi, int size, int sign) |
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,16 +925,11 @@ void helper_st_asi(int asi, int size, int sign) |
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,8 +1105,8 @@ void helper_st_asi(int asi, int size, int sign) |
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() |
... | ... |
target-sparc/op_mem.h
... | ... | @@ -76,33 +76,6 @@ void OPPROTO glue(op_lddf, MEMSUFFIX) (void) |
76 | 76 | } |
77 | 77 | |
78 | 78 | #ifdef TARGET_SPARC64 |
79 | -/* XXX: Should be Atomically */ | |
80 | -/* XXX: There are no cas[x] instructions, only cas[x]a */ | |
81 | -void OPPROTO glue(op_cas, MEMSUFFIX)(void) | |
82 | -{ | |
83 | - uint32_t tmp; | |
84 | - | |
85 | - tmp = glue(ldl, MEMSUFFIX)(T0); | |
86 | - T2 &= 0xffffffffULL; | |
87 | - if (tmp == (T1 & 0xffffffffULL)) { | |
88 | - glue(stl, MEMSUFFIX)(T0, T2); | |
89 | - } | |
90 | - T2 = tmp; | |
91 | -} | |
92 | - | |
93 | -void OPPROTO glue(op_casx, MEMSUFFIX)(void) | |
94 | -{ | |
95 | - uint64_t tmp; | |
96 | - | |
97 | - // XXX | |
98 | - tmp = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32; | |
99 | - tmp |= glue(ldl, MEMSUFFIX)(T0); | |
100 | - if (tmp == T1) { | |
101 | - glue(stq, MEMSUFFIX)(T0, T2); | |
102 | - } | |
103 | - T2 = tmp; | |
104 | -} | |
105 | - | |
106 | 79 | void OPPROTO glue(op_lduw, MEMSUFFIX)(void) |
107 | 80 | { |
108 | 81 | T1 = (uint64_t)(glue(ldl, MEMSUFFIX)(T0) & 0xffffffff); |
... | ... |
target-sparc/translate.c
... | ... | @@ -353,112 +353,27 @@ GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf); |
353 | 353 | #endif |
354 | 354 | #endif |
355 | 355 | |
356 | -#ifdef TARGET_SPARC64 | |
357 | -// 'a' versions allowed to user depending on asi | |
358 | -#if defined(CONFIG_USER_ONLY) | |
356 | +/* moves */ | |
357 | +#ifdef CONFIG_USER_ONLY | |
359 | 358 | #define supervisor(dc) 0 |
359 | +#ifdef TARGET_SPARC64 | |
360 | 360 | #define hypervisor(dc) 0 |
361 | +#endif | |
361 | 362 | #define gen_op_ldst(name) gen_op_##name##_raw() |
362 | -#define OP_LD_TABLE(width) \ | |
363 | - static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \ | |
364 | - { \ | |
365 | - int asi, offset; \ | |
366 | - \ | |
367 | - if (IS_IMM) { \ | |
368 | - offset = GET_FIELD(insn, 25, 31); \ | |
369 | - if (is_ld) \ | |
370 | - gen_op_ld_asi_reg(offset, size, sign); \ | |
371 | - else \ | |
372 | - gen_op_st_asi_reg(offset, size, sign); \ | |
373 | - return; \ | |
374 | - } \ | |
375 | - asi = GET_FIELD(insn, 19, 26); \ | |
376 | - switch (asi) { \ | |
377 | - case 0x80: /* Primary address space */ \ | |
378 | - gen_op_##width##_raw(); \ | |
379 | - break; \ | |
380 | - case 0x82: /* Primary address space, non-faulting load */ \ | |
381 | - gen_op_##width##_raw(); \ | |
382 | - break; \ | |
383 | - default: \ | |
384 | - break; \ | |
385 | - } \ | |
386 | - } | |
387 | - | |
388 | 363 | #else |
364 | +#define supervisor(dc) (dc->mem_idx == 1) | |
365 | +#ifdef TARGET_SPARC64 | |
366 | +#define hypervisor(dc) (dc->mem_idx == 2) | |
367 | +#endif | |
389 | 368 | #define gen_op_ldst(name) (*gen_op_##name[dc->mem_idx])() |
390 | 369 | #define OP_LD_TABLE(width) \ |
391 | 370 | static GenOpFunc * const gen_op_##width[] = { \ |
392 | 371 | &gen_op_##width##_user, \ |
393 | 372 | &gen_op_##width##_kernel, \ |
394 | - }; \ | |
395 | - \ | |
396 | - static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \ | |
397 | - { \ | |
398 | - int asi, offset; \ | |
399 | - \ | |
400 | - if (IS_IMM) { \ | |
401 | - offset = GET_FIELD(insn, 25, 31); \ | |
402 | - if (is_ld) \ | |
403 | - gen_op_ld_asi_reg(offset, size, sign); \ | |
404 | - else \ | |
405 | - gen_op_st_asi_reg(offset, size, sign); \ | |
406 | - return; \ | |
407 | - } \ | |
408 | - asi = GET_FIELD(insn, 19, 26); \ | |
409 | - if (is_ld) \ | |
410 | - gen_op_ld_asi(asi, size, sign); \ | |
411 | - else \ | |
412 | - gen_op_st_asi(asi, size, sign); \ | |
413 | - } | |
414 | - | |
415 | -#define supervisor(dc) (dc->mem_idx == 1) | |
416 | -#define hypervisor(dc) (dc->mem_idx == 2) | |
417 | -#endif | |
418 | -#else | |
419 | -#if defined(CONFIG_USER_ONLY) | |
420 | -#define gen_op_ldst(name) gen_op_##name##_raw() | |
421 | -#define OP_LD_TABLE(width) | |
422 | -#define supervisor(dc) 0 | |
423 | -#else | |
424 | -#define gen_op_ldst(name) (*gen_op_##name[dc->mem_idx])() | |
425 | -#define OP_LD_TABLE(width) \ | |
426 | -static GenOpFunc * const gen_op_##width[] = { \ | |
427 | - &gen_op_##width##_user, \ | |
428 | - &gen_op_##width##_kernel, \ | |
429 | -}; \ | |
430 | - \ | |
431 | -static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \ | |
432 | -{ \ | |
433 | - int asi; \ | |
434 | - \ | |
435 | - asi = GET_FIELD(insn, 19, 26); \ | |
436 | - switch (asi) { \ | |
437 | - case 10: /* User data access */ \ | |
438 | - gen_op_##width##_user(); \ | |
439 | - break; \ | |
440 | - case 11: /* Supervisor data access */ \ | |
441 | - gen_op_##width##_kernel(); \ | |
442 | - break; \ | |
443 | - case 0x20 ... 0x2f: /* MMU passthrough */ \ | |
444 | - if (is_ld) \ | |
445 | - gen_op_ld_asi(asi, size, sign); \ | |
446 | - else \ | |
447 | - gen_op_st_asi(asi, size, sign); \ | |
448 | - break; \ | |
449 | - default: \ | |
450 | - if (is_ld) \ | |
451 | - gen_op_ld_asi(asi, size, sign); \ | |
452 | - else \ | |
453 | - gen_op_st_asi(asi, size, sign); \ | |
454 | - break; \ | |
455 | - } \ | |
456 | -} | |
457 | - | |
458 | -#define supervisor(dc) (dc->mem_idx == 1) | |
459 | -#endif | |
373 | + }; | |
460 | 374 | #endif |
461 | 375 | |
376 | +#ifndef CONFIG_USER_ONLY | |
462 | 377 | OP_LD_TABLE(ld); |
463 | 378 | OP_LD_TABLE(st); |
464 | 379 | OP_LD_TABLE(ldub); |
... | ... | @@ -481,8 +396,164 @@ OP_LD_TABLE(lduw); |
481 | 396 | OP_LD_TABLE(ldsw); |
482 | 397 | OP_LD_TABLE(ldx); |
483 | 398 | OP_LD_TABLE(stx); |
484 | -OP_LD_TABLE(cas); | |
485 | -OP_LD_TABLE(casx); | |
399 | +#endif | |
400 | +#endif | |
401 | + | |
402 | +/* asi moves */ | |
403 | +#ifdef TARGET_SPARC64 | |
404 | +static inline void gen_ld_asi(int insn, int size, int sign) | |
405 | +{ | |
406 | + int asi, offset; | |
407 | + | |
408 | + if (IS_IMM) { | |
409 | + offset = GET_FIELD(insn, 25, 31); | |
410 | + gen_op_ld_asi_reg(offset, size, sign); | |
411 | + } else { | |
412 | + asi = GET_FIELD(insn, 19, 26); | |
413 | + gen_op_ld_asi(asi, size, sign); | |
414 | + } | |
415 | +} | |
416 | + | |
417 | +static inline void gen_st_asi(int insn, int size) | |
418 | +{ | |
419 | + int asi, offset; | |
420 | + | |
421 | + if (IS_IMM) { | |
422 | + offset = GET_FIELD(insn, 25, 31); | |
423 | + gen_op_st_asi_reg(offset, size); | |
424 | + } else { | |
425 | + asi = GET_FIELD(insn, 19, 26); | |
426 | + gen_op_st_asi(asi, size); | |
427 | + } | |
428 | +} | |
429 | + | |
430 | +static inline void gen_swap_asi(int insn) | |
431 | +{ | |
432 | + int asi, offset; | |
433 | + | |
434 | + if (IS_IMM) { | |
435 | + offset = GET_FIELD(insn, 25, 31); | |
436 | + gen_op_swap_asi_reg(offset); | |
437 | + } else { | |
438 | + asi = GET_FIELD(insn, 19, 26); | |
439 | + gen_op_swap_asi(asi); | |
440 | + } | |
441 | +} | |
442 | + | |
443 | +static inline void gen_ldstub_asi(int insn) | |
444 | +{ | |
445 | + int asi, offset; | |
446 | + | |
447 | + if (IS_IMM) { | |
448 | + offset = GET_FIELD(insn, 25, 31); | |
449 | + gen_op_ldstub_asi_reg(offset); | |
450 | + } else { | |
451 | + asi = GET_FIELD(insn, 19, 26); | |
452 | + gen_op_ldstub_asi(asi); | |
453 | + } | |
454 | +} | |
455 | + | |
456 | +static inline void gen_ldda_asi(int insn) | |
457 | +{ | |
458 | + int asi, offset; | |
459 | + | |
460 | + if (IS_IMM) { | |
461 | + offset = GET_FIELD(insn, 25, 31); | |
462 | + gen_op_ldda_asi_reg(offset); | |
463 | + } else { | |
464 | + asi = GET_FIELD(insn, 19, 26); | |
465 | + gen_op_ldda_asi(asi); | |
466 | + } | |
467 | +} | |
468 | + | |
469 | +static inline void gen_stda_asi(int insn) | |
470 | +{ | |
471 | + int asi, offset; | |
472 | + | |
473 | + if (IS_IMM) { | |
474 | + offset = GET_FIELD(insn, 25, 31); | |
475 | + gen_op_stda_asi_reg(offset); | |
476 | + } else { | |
477 | + asi = GET_FIELD(insn, 19, 26); | |
478 | + gen_op_stda_asi(asi); | |
479 | + } | |
480 | +} | |
481 | + | |
482 | +static inline void gen_cas_asi(int insn) | |
483 | +{ | |
484 | + int asi, offset; | |
485 | + | |
486 | + if (IS_IMM) { | |
487 | + offset = GET_FIELD(insn, 25, 31); | |
488 | + gen_op_cas_asi_reg(offset); | |
489 | + } else { | |
490 | + asi = GET_FIELD(insn, 19, 26); | |
491 | + gen_op_cas_asi(asi); | |
492 | + } | |
493 | +} | |
494 | + | |
495 | +static inline void gen_casx_asi(int insn) | |
496 | +{ | |
497 | + int asi, offset; | |
498 | + | |
499 | + if (IS_IMM) { | |
500 | + offset = GET_FIELD(insn, 25, 31); | |
501 | + gen_op_casx_asi_reg(offset); | |
502 | + } else { | |
503 | + asi = GET_FIELD(insn, 19, 26); | |
504 | + gen_op_casx_asi(asi); | |
505 | + } | |
506 | +} | |
507 | + | |
508 | +#elif !defined(CONFIG_USER_ONLY) | |
509 | + | |
510 | +static inline void gen_ld_asi(int insn, int size, int sign) | |
511 | +{ | |
512 | + int asi; | |
513 | + | |
514 | + asi = GET_FIELD(insn, 19, 26); | |
515 | + gen_op_ld_asi(asi, size, sign); | |
516 | +} | |
517 | + | |
518 | +static inline void gen_st_asi(int insn, int size) | |
519 | +{ | |
520 | + int asi; | |
521 | + | |
522 | + asi = GET_FIELD(insn, 19, 26); | |
523 | + gen_op_st_asi(asi, size); | |
524 | +} | |
525 | + | |
526 | +static inline void gen_ldstub_asi(int insn) | |
527 | +{ | |
528 | + int asi; | |
529 | + | |
530 | + asi = GET_FIELD(insn, 19, 26); | |
531 | + gen_op_ldstub_asi(asi); | |
532 | +} | |
533 | + | |
534 | +static inline void gen_swap_asi(int insn) | |
535 | +{ | |
536 | + int asi; | |
537 | + | |
538 | + asi = GET_FIELD(insn, 19, 26); | |
539 | + gen_op_swap_asi(asi); | |
540 | +} | |
541 | + | |
542 | +static inline void gen_ldda_asi(int insn) | |
543 | +{ | |
544 | + int asi; | |
545 | + | |
546 | + asi = GET_FIELD(insn, 19, 26); | |
547 | + gen_op_ld_asi(asi, 8, 0); | |
548 | +} | |
549 | + | |
550 | +static inline void gen_stda_asi(int insn) | |
551 | +{ | |
552 | + int asi; | |
553 | + | |
554 | + asi = GET_FIELD(insn, 19, 26); | |
555 | + gen_op_st_asi(asi, 8); | |
556 | +} | |
486 | 557 | #endif |
487 | 558 | |
488 | 559 | static inline void gen_movl_imm_TN(int reg, uint32_t imm) |
... | ... | @@ -2796,7 +2867,12 @@ static void disas_sparc_insn(DisasContext * dc) |
2796 | 2867 | rs1 = GET_FIELD(insn, 13, 17); |
2797 | 2868 | save_state(dc); |
2798 | 2869 | gen_movl_reg_T0(rs1); |
2799 | - if (IS_IMM) { /* immediate */ | |
2870 | + if (xop == 0x3c || xop == 0x3e) | |
2871 | + { | |
2872 | + rs2 = GET_FIELD(insn, 27, 31); | |
2873 | + gen_movl_reg_T1(rs2); | |
2874 | + } | |
2875 | + else if (IS_IMM) { /* immediate */ | |
2800 | 2876 | rs2 = GET_FIELDs(insn, 19, 31); |
2801 | 2877 | #if defined(OPTIM) |
2802 | 2878 | if (rs2 != 0) { |
... | ... | @@ -2873,16 +2949,10 @@ static void disas_sparc_insn(DisasContext * dc) |
2873 | 2949 | goto illegal_insn; |
2874 | 2950 | if (!supervisor(dc)) |
2875 | 2951 | goto priv_insn; |
2876 | -#ifdef CONFIG_USER_ONLY | |
2952 | +#elif CONFIG_USER_ONLY | |
2877 | 2953 | gen_op_check_align_T0_3(); |
2878 | 2954 | #endif |
2879 | - gen_op_lda(insn, 1, 4, 0); | |
2880 | -#else | |
2881 | -#ifdef CONFIG_USER_ONLY | |
2882 | - gen_op_check_align_T0_3(); | |
2883 | -#endif | |
2884 | - gen_op_lduwa(insn, 1, 4, 0); | |
2885 | -#endif | |
2955 | + gen_ld_asi(insn, 4, 0); | |
2886 | 2956 | break; |
2887 | 2957 | case 0x11: /* load unsigned byte alternate */ |
2888 | 2958 | #ifndef TARGET_SPARC64 |
... | ... | @@ -2891,7 +2961,7 @@ static void disas_sparc_insn(DisasContext * dc) |
2891 | 2961 | if (!supervisor(dc)) |
2892 | 2962 | goto priv_insn; |
2893 | 2963 | #endif |
2894 | - gen_op_lduba(insn, 1, 1, 0); | |
2964 | + gen_ld_asi(insn, 1, 0); | |
2895 | 2965 | break; |
2896 | 2966 | case 0x12: /* load unsigned halfword alternate */ |
2897 | 2967 | #ifndef TARGET_SPARC64 |
... | ... | @@ -2899,11 +2969,10 @@ static void disas_sparc_insn(DisasContext * dc) |
2899 | 2969 | goto illegal_insn; |
2900 | 2970 | if (!supervisor(dc)) |
2901 | 2971 | goto priv_insn; |
2902 | -#endif | |
2903 | -#ifdef CONFIG_USER_ONLY | |
2972 | +#elif CONFIG_USER_ONLY | |
2904 | 2973 | gen_op_check_align_T0_1(); |
2905 | 2974 | #endif |
2906 | - gen_op_lduha(insn, 1, 2, 0); | |
2975 | + gen_ld_asi(insn, 2, 0); | |
2907 | 2976 | break; |
2908 | 2977 | case 0x13: /* load double word alternate */ |
2909 | 2978 | #ifndef TARGET_SPARC64 |
... | ... | @@ -2915,7 +2984,7 @@ static void disas_sparc_insn(DisasContext * dc) |
2915 | 2984 | if (rd & 1) |
2916 | 2985 | goto illegal_insn; |
2917 | 2986 | gen_op_check_align_T0_7(); |
2918 | - gen_op_ldda(insn, 1, 8, 0); | |
2987 | + gen_ldda_asi(insn); | |
2919 | 2988 | gen_movl_T0_reg(rd + 1); |
2920 | 2989 | break; |
2921 | 2990 | case 0x19: /* load signed byte alternate */ |
... | ... | @@ -2925,7 +2994,7 @@ static void disas_sparc_insn(DisasContext * dc) |
2925 | 2994 | if (!supervisor(dc)) |
2926 | 2995 | goto priv_insn; |
2927 | 2996 | #endif |
2928 | - gen_op_ldsba(insn, 1, 1, 1); | |
2997 | + gen_ld_asi(insn, 1, 1); | |
2929 | 2998 | break; |
2930 | 2999 | case 0x1a: /* load signed halfword alternate */ |
2931 | 3000 | #ifndef TARGET_SPARC64 |
... | ... | @@ -2933,11 +3002,10 @@ static void disas_sparc_insn(DisasContext * dc) |
2933 | 3002 | goto illegal_insn; |
2934 | 3003 | if (!supervisor(dc)) |
2935 | 3004 | goto priv_insn; |
2936 | -#endif | |
2937 | -#ifdef CONFIG_USER_ONLY | |
3005 | +#elif CONFIG_USER_ONLY | |
2938 | 3006 | gen_op_check_align_T0_1(); |
2939 | 3007 | #endif |
2940 | - gen_op_ldsha(insn, 1, 2 ,1); | |
3008 | + gen_ld_asi(insn, 2, 1); | |
2941 | 3009 | break; |
2942 | 3010 | case 0x1d: /* ldstuba -- XXX: should be atomically */ |
2943 | 3011 | #ifndef TARGET_SPARC64 |
... | ... | @@ -2946,7 +3014,7 @@ static void disas_sparc_insn(DisasContext * dc) |
2946 | 3014 | if (!supervisor(dc)) |
2947 | 3015 | goto priv_insn; |
2948 | 3016 | #endif |
2949 | - gen_op_ldstuba(insn, 1, 1, 0); | |
3017 | + gen_ldstub_asi(insn); | |
2950 | 3018 | break; |
2951 | 3019 | case 0x1f: /* swap reg with alt. memory. Also atomically */ |
2952 | 3020 | #ifndef TARGET_SPARC64 |
... | ... | @@ -2954,12 +3022,11 @@ static void disas_sparc_insn(DisasContext * dc) |
2954 | 3022 | goto illegal_insn; |
2955 | 3023 | if (!supervisor(dc)) |
2956 | 3024 | goto priv_insn; |
2957 | -#endif | |
2958 | - gen_movl_reg_T1(rd); | |
2959 | -#ifdef CONFIG_USER_ONLY | |
3025 | +#elif CONFIG_USER_ONLY | |
2960 | 3026 | gen_op_check_align_T0_3(); |
2961 | 3027 | #endif |
2962 | - gen_op_swapa(insn, 1, 4, 0); | |
3028 | + gen_movl_reg_T1(rd); | |
3029 | + gen_swap_asi(insn); | |
2963 | 3030 | break; |
2964 | 3031 | |
2965 | 3032 | #ifndef TARGET_SPARC64 |
... | ... | @@ -2967,17 +3034,6 @@ static void disas_sparc_insn(DisasContext * dc) |
2967 | 3034 | case 0x31: /* ldcsr */ |
2968 | 3035 | case 0x33: /* lddc */ |
2969 | 3036 | goto ncp_insn; |
2970 | - /* avoid warnings */ | |
2971 | - (void) &gen_op_stfa; | |
2972 | - (void) &gen_op_stdfa; | |
2973 | - (void) &gen_op_ldfa; | |
2974 | - (void) &gen_op_lddfa; | |
2975 | -#else | |
2976 | - (void) &gen_op_lda; | |
2977 | -#if !defined(CONFIG_USER_ONLY) | |
2978 | - (void) &gen_op_cas; | |
2979 | - (void) &gen_op_casx; | |
2980 | -#endif | |
2981 | 3037 | #endif |
2982 | 3038 | #endif |
2983 | 3039 | #ifdef TARGET_SPARC64 |
... | ... | @@ -2995,11 +3051,11 @@ static void disas_sparc_insn(DisasContext * dc) |
2995 | 3051 | #ifdef CONFIG_USER_ONLY |
2996 | 3052 | gen_op_check_align_T0_3(); |
2997 | 3053 | #endif |
2998 | - gen_op_ldswa(insn, 1, 4, 1); | |
3054 | + gen_ld_asi(insn, 4, 1); | |
2999 | 3055 | break; |
3000 | 3056 | case 0x1b: /* V9 ldxa */ |
3001 | 3057 | gen_op_check_align_T0_7(); |
3002 | - gen_op_ldxa(insn, 1, 8, 0); | |
3058 | + gen_ld_asi(insn, 8, 0); | |
3003 | 3059 | break; |
3004 | 3060 | case 0x2d: /* V9 prefetch, no effect */ |
3005 | 3061 | goto skip_move; |
... | ... | @@ -3007,13 +3063,12 @@ static void disas_sparc_insn(DisasContext * dc) |
3007 | 3063 | #ifdef CONFIG_USER_ONLY |
3008 | 3064 | gen_op_check_align_T0_3(); |
3009 | 3065 | #endif |
3010 | - gen_op_ldfa(insn, 1, 8, 0); // XXX | |
3011 | - break; | |
3066 | + gen_ld_asi(insn, 8, 0); // XXX | |
3067 | + goto skip_move; | |
3012 | 3068 | case 0x33: /* V9 lddfa */ |
3013 | 3069 | gen_op_check_align_T0_7(); |
3014 | - gen_op_lddfa(insn, 1, 8, 0); // XXX | |
3015 | - | |
3016 | - break; | |
3070 | + gen_ld_asi(insn, 8, 0); // XXX | |
3071 | + goto skip_move; | |
3017 | 3072 | case 0x3d: /* V9 prefetcha, no effect */ |
3018 | 3073 | goto skip_move; |
3019 | 3074 | case 0x32: /* V9 ldqfa */ |
... | ... | @@ -3092,7 +3147,7 @@ static void disas_sparc_insn(DisasContext * dc) |
3092 | 3147 | #ifdef CONFIG_USER_ONLY |
3093 | 3148 | gen_op_check_align_T0_3(); |
3094 | 3149 | #endif |
3095 | - gen_op_sta(insn, 0, 4, 0); | |
3150 | + gen_st_asi(insn, 4); | |
3096 | 3151 | break; |
3097 | 3152 | case 0x15: |
3098 | 3153 | #ifndef TARGET_SPARC64 |
... | ... | @@ -3101,7 +3156,7 @@ static void disas_sparc_insn(DisasContext * dc) |
3101 | 3156 | if (!supervisor(dc)) |
3102 | 3157 | goto priv_insn; |
3103 | 3158 | #endif |
3104 | - gen_op_stba(insn, 0, 1, 0); | |
3159 | + gen_st_asi(insn, 1); | |
3105 | 3160 | break; |
3106 | 3161 | case 0x16: |
3107 | 3162 | #ifndef TARGET_SPARC64 |
... | ... | @@ -3113,7 +3168,7 @@ static void disas_sparc_insn(DisasContext * dc) |
3113 | 3168 | #ifdef CONFIG_USER_ONLY |
3114 | 3169 | gen_op_check_align_T0_1(); |
3115 | 3170 | #endif |
3116 | - gen_op_stha(insn, 0, 2, 0); | |
3171 | + gen_st_asi(insn, 2); | |
3117 | 3172 | break; |
3118 | 3173 | case 0x17: |
3119 | 3174 | #ifndef TARGET_SPARC64 |
... | ... | @@ -3127,7 +3182,7 @@ static void disas_sparc_insn(DisasContext * dc) |
3127 | 3182 | gen_op_check_align_T0_7(); |
3128 | 3183 | flush_T2(dc); |
3129 | 3184 | gen_movl_reg_T2(rd + 1); |
3130 | - gen_op_stda(insn, 0, 8, 0); | |
3185 | + gen_stda_asi(insn); | |
3131 | 3186 | break; |
3132 | 3187 | #endif |
3133 | 3188 | #ifdef TARGET_SPARC64 |
... | ... | @@ -3137,7 +3192,7 @@ static void disas_sparc_insn(DisasContext * dc) |
3137 | 3192 | break; |
3138 | 3193 | case 0x1e: /* V9 stxa */ |
3139 | 3194 | gen_op_check_align_T0_7(); |
3140 | - gen_op_stxa(insn, 0, 8, 0); // XXX | |
3195 | + gen_st_asi(insn, 8); | |
3141 | 3196 | break; |
3142 | 3197 | #endif |
3143 | 3198 | default: |
... | ... | @@ -3184,21 +3239,27 @@ static void disas_sparc_insn(DisasContext * dc) |
3184 | 3239 | #ifdef CONFIG_USER_ONLY |
3185 | 3240 | gen_op_check_align_T0_3(); |
3186 | 3241 | #endif |
3187 | - gen_op_stfa(insn, 0, 0, 0); // XXX | |
3242 | + gen_st_asi(insn, 0); // XXX | |
3188 | 3243 | break; |
3189 | 3244 | case 0x37: /* V9 stdfa */ |
3190 | 3245 | gen_op_check_align_T0_7(); |
3191 | - gen_op_stdfa(insn, 0, 0, 0); // XXX | |
3246 | + gen_st_asi(insn, 0); // XXX | |
3192 | 3247 | break; |
3193 | 3248 | case 0x3c: /* V9 casa */ |
3194 | 3249 | #ifdef CONFIG_USER_ONLY |
3195 | 3250 | gen_op_check_align_T0_3(); |
3196 | 3251 | #endif |
3197 | - gen_op_casa(insn, 0, 4, 0); // XXX | |
3252 | + flush_T2(dc); | |
3253 | + gen_movl_reg_T2(rd); | |
3254 | + gen_cas_asi(insn); | |
3255 | + gen_movl_T1_reg(rd); | |
3198 | 3256 | break; |
3199 | 3257 | case 0x3e: /* V9 casxa */ |
3200 | 3258 | gen_op_check_align_T0_7(); |
3201 | - gen_op_casxa(insn, 0, 8, 0); // XXX | |
3259 | + flush_T2(dc); | |
3260 | + gen_movl_reg_T2(rd); | |
3261 | + gen_casx_asi(insn); | |
3262 | + gen_movl_T1_reg(rd); | |
3202 | 3263 | break; |
3203 | 3264 | case 0x36: /* V9 stqfa */ |
3204 | 3265 | goto nfpu_insn; |
... | ... |