Commit 81ad8ba242815e27f990e18778c7cdca2e7e7522

Authored by blueswir1
1 parent 43febf49

Rework ASI instructions (Aurelien Jarno)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3205 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/exec.h
@@ -50,7 +50,7 @@ void cpu_unlock(void); @@ -50,7 +50,7 @@ void cpu_unlock(void);
50 void cpu_loop_exit(void); 50 void cpu_loop_exit(void);
51 void helper_flush(target_ulong addr); 51 void helper_flush(target_ulong addr);
52 void helper_ld_asi(int asi, int size, int sign); 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 void helper_rett(void); 54 void helper_rett(void);
55 void helper_ldfsr(void); 55 void helper_ldfsr(void);
56 void set_cwp(int new_cwp); 56 void set_cwp(int new_cwp);
target-sparc/op.c
@@ -1862,10 +1862,126 @@ void OPPROTO op_ld_asi_reg() @@ -1862,10 +1862,126 @@ void OPPROTO op_ld_asi_reg()
1862 void OPPROTO op_st_asi_reg() 1862 void OPPROTO op_st_asi_reg()
1863 { 1863 {
1864 T0 += PARAM1; 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 #endif 1982 #endif
1868 1983
  1984 +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1869 void OPPROTO op_ld_asi() 1985 void OPPROTO op_ld_asi()
1870 { 1986 {
1871 helper_ld_asi(PARAM1, PARAM2, PARAM3); 1987 helper_ld_asi(PARAM1, PARAM2, PARAM3);
@@ -1873,9 +1989,33 @@ void OPPROTO op_ld_asi() @@ -1873,9 +1989,33 @@ void OPPROTO op_ld_asi()
1873 1989
1874 void OPPROTO op_st_asi() 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 #ifdef TARGET_SPARC64 2019 #ifdef TARGET_SPARC64
1880 // This function uses non-native bit order 2020 // This function uses non-native bit order
1881 #define GET_FIELD(X, FROM, TO) \ 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,16 +137,8 @@ GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
137 GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1); 137 GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
138 #endif 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 #ifndef TARGET_SPARC64 140 #ifndef TARGET_SPARC64
  141 +#ifndef CONFIG_USER_ONLY
150 void helper_ld_asi(int asi, int size, int sign) 142 void helper_ld_asi(int asi, int size, int sign)
151 { 143 {
152 uint32_t ret = 0; 144 uint32_t ret = 0;
@@ -200,6 +192,42 @@ void helper_ld_asi(int asi, int size, int sign) @@ -200,6 +192,42 @@ void helper_ld_asi(int asi, int size, int sign)
200 break; 192 break;
201 } 193 }
202 break; 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 case 0xc: /* I-cache tag */ 231 case 0xc: /* I-cache tag */
204 case 0xd: /* I-cache data */ 232 case 0xd: /* I-cache data */
205 case 0xe: /* D-cache tag */ 233 case 0xe: /* D-cache tag */
@@ -253,10 +281,22 @@ void helper_ld_asi(int asi, int size, int sign) @@ -253,10 +281,22 @@ void helper_ld_asi(int asi, int size, int sign)
253 ret = 0; 281 ret = 0;
254 break; 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 switch(asi) { 301 switch(asi) {
262 case 2: /* SuperSparc MXCC registers */ 302 case 2: /* SuperSparc MXCC registers */
@@ -325,6 +365,42 @@ void helper_st_asi(int asi, int size, int sign) @@ -325,6 +365,42 @@ void helper_st_asi(int asi, int size, int sign)
325 #endif 365 #endif
326 return; 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 case 0xc: /* I-cache tag */ 404 case 0xc: /* I-cache tag */
329 case 0xd: /* I-cache data */ 405 case 0xd: /* I-cache data */
330 case 0xe: /* D-cache tag */ 406 case 0xe: /* D-cache tag */
@@ -422,7 +498,146 @@ void helper_st_asi(int asi, int size, int sign) @@ -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 void helper_ld_asi(int asi, int size, int sign) 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,8 +647,50 @@ void helper_ld_asi(int asi, int size, int sign)
432 raise_exception(TT_PRIV_ACT); 647 raise_exception(TT_PRIV_ACT);
433 648
434 switch (asi) { 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 case 0x14: // Bypass 690 case 0x14: // Bypass
436 case 0x15: // Bypass, non-cacheable 691 case 0x15: // Bypass, non-cacheable
  692 + case 0x1c: // Bypass LE
  693 + case 0x1d: // Bypass, non-cacheable LE
437 { 694 {
438 switch(size) { 695 switch(size) {
439 case 1: 696 case 1:
@@ -454,20 +711,14 @@ void helper_ld_asi(int asi, int size, int sign) @@ -454,20 +711,14 @@ void helper_ld_asi(int asi, int size, int sign)
454 } 711 }
455 case 0x04: // Nucleus 712 case 0x04: // Nucleus
456 case 0x0c: // Nucleus Little Endian (LE) 713 case 0x0c: // Nucleus Little Endian (LE)
457 - case 0x10: // As if user primary  
458 case 0x11: // As if user secondary 714 case 0x11: // As if user secondary
459 - case 0x18: // As if user primary LE  
460 case 0x19: // As if user secondary LE 715 case 0x19: // As if user secondary LE
461 - case 0x1c: // Bypass LE  
462 - case 0x1d: // Bypass, non-cacheable LE  
463 case 0x24: // Nucleus quad LDD 128 bit atomic 716 case 0x24: // Nucleus quad LDD 128 bit atomic
464 case 0x2c: // Nucleus quad LDD 128 bit atomic 717 case 0x2c: // Nucleus quad LDD 128 bit atomic
465 case 0x4a: // UPA config 718 case 0x4a: // UPA config
466 - case 0x82: // Primary no-fault 719 + case 0x81: // Secondary
467 case 0x83: // Secondary no-fault 720 case 0x83: // Secondary no-fault
468 - case 0x88: // Primary LE  
469 case 0x89: // Secondary LE 721 case 0x89: // Secondary LE
470 - case 0x8a: // Primary no-fault LE  
471 case 0x8b: // Secondary no-fault LE 722 case 0x8b: // Secondary no-fault LE
472 // XXX 723 // XXX
473 break; 724 break;
@@ -540,17 +791,120 @@ void helper_ld_asi(int asi, int size, int sign) @@ -540,17 +791,120 @@ void helper_ld_asi(int asi, int size, int sign)
540 ret = 0; 791 ret = 0;
541 break; 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 T1 = ret; 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 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0) 838 if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
549 raise_exception(TT_PRIV_ACT); 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 switch(asi) { 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 case 0x14: // Bypass 904 case 0x14: // Bypass
553 case 0x15: // Bypass, non-cacheable 905 case 0x15: // Bypass, non-cacheable
  906 + case 0x1c: // Bypass LE
  907 + case 0x1d: // Bypass, non-cacheable LE
554 { 908 {
555 switch(size) { 909 switch(size) {
556 case 1: 910 case 1:
@@ -571,16 +925,11 @@ void helper_st_asi(int asi, int size, int sign) @@ -571,16 +925,11 @@ void helper_st_asi(int asi, int size, int sign)
571 return; 925 return;
572 case 0x04: // Nucleus 926 case 0x04: // Nucleus
573 case 0x0c: // Nucleus Little Endian (LE) 927 case 0x0c: // Nucleus Little Endian (LE)
574 - case 0x10: // As if user primary  
575 case 0x11: // As if user secondary 928 case 0x11: // As if user secondary
576 - case 0x18: // As if user primary LE  
577 case 0x19: // As if user secondary LE 929 case 0x19: // As if user secondary LE
578 - case 0x1c: // Bypass LE  
579 - case 0x1d: // Bypass, non-cacheable LE  
580 case 0x24: // Nucleus quad LDD 128 bit atomic 930 case 0x24: // Nucleus quad LDD 128 bit atomic
581 case 0x2c: // Nucleus quad LDD 128 bit atomic 931 case 0x2c: // Nucleus quad LDD 128 bit atomic
582 case 0x4a: // UPA config 932 case 0x4a: // UPA config
583 - case 0x88: // Primary LE  
584 case 0x89: // Secondary LE 933 case 0x89: // Secondary LE
585 // XXX 934 // XXX
586 return; 935 return;
@@ -756,8 +1105,8 @@ void helper_st_asi(int asi, int size, int sign) @@ -756,8 +1105,8 @@ void helper_st_asi(int asi, int size, int sign)
756 return; 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 #ifndef TARGET_SPARC64 1111 #ifndef TARGET_SPARC64
763 void helper_rett() 1112 void helper_rett()
target-sparc/op_mem.h
@@ -76,33 +76,6 @@ void OPPROTO glue(op_lddf, MEMSUFFIX) (void) @@ -76,33 +76,6 @@ void OPPROTO glue(op_lddf, MEMSUFFIX) (void)
76 } 76 }
77 77
78 #ifdef TARGET_SPARC64 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 void OPPROTO glue(op_lduw, MEMSUFFIX)(void) 79 void OPPROTO glue(op_lduw, MEMSUFFIX)(void)
107 { 80 {
108 T1 = (uint64_t)(glue(ldl, MEMSUFFIX)(T0) & 0xffffffff); 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,112 +353,27 @@ GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
353 #endif 353 #endif
354 #endif 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 #define supervisor(dc) 0 358 #define supervisor(dc) 0
  359 +#ifdef TARGET_SPARC64
360 #define hypervisor(dc) 0 360 #define hypervisor(dc) 0
  361 +#endif
361 #define gen_op_ldst(name) gen_op_##name##_raw() 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 #else 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 #define gen_op_ldst(name) (*gen_op_##name[dc->mem_idx])() 368 #define gen_op_ldst(name) (*gen_op_##name[dc->mem_idx])()
390 #define OP_LD_TABLE(width) \ 369 #define OP_LD_TABLE(width) \
391 static GenOpFunc * const gen_op_##width[] = { \ 370 static GenOpFunc * const gen_op_##width[] = { \
392 &gen_op_##width##_user, \ 371 &gen_op_##width##_user, \
393 &gen_op_##width##_kernel, \ 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 #endif 374 #endif
461 375
  376 +#ifndef CONFIG_USER_ONLY
462 OP_LD_TABLE(ld); 377 OP_LD_TABLE(ld);
463 OP_LD_TABLE(st); 378 OP_LD_TABLE(st);
464 OP_LD_TABLE(ldub); 379 OP_LD_TABLE(ldub);
@@ -481,8 +396,164 @@ OP_LD_TABLE(lduw); @@ -481,8 +396,164 @@ OP_LD_TABLE(lduw);
481 OP_LD_TABLE(ldsw); 396 OP_LD_TABLE(ldsw);
482 OP_LD_TABLE(ldx); 397 OP_LD_TABLE(ldx);
483 OP_LD_TABLE(stx); 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 #endif 557 #endif
487 558
488 static inline void gen_movl_imm_TN(int reg, uint32_t imm) 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,7 +2867,12 @@ static void disas_sparc_insn(DisasContext * dc)
2796 rs1 = GET_FIELD(insn, 13, 17); 2867 rs1 = GET_FIELD(insn, 13, 17);
2797 save_state(dc); 2868 save_state(dc);
2798 gen_movl_reg_T0(rs1); 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 rs2 = GET_FIELDs(insn, 19, 31); 2876 rs2 = GET_FIELDs(insn, 19, 31);
2801 #if defined(OPTIM) 2877 #if defined(OPTIM)
2802 if (rs2 != 0) { 2878 if (rs2 != 0) {
@@ -2873,16 +2949,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2873,16 +2949,10 @@ static void disas_sparc_insn(DisasContext * dc)
2873 goto illegal_insn; 2949 goto illegal_insn;
2874 if (!supervisor(dc)) 2950 if (!supervisor(dc))
2875 goto priv_insn; 2951 goto priv_insn;
2876 -#ifdef CONFIG_USER_ONLY 2952 +#elif CONFIG_USER_ONLY
2877 gen_op_check_align_T0_3(); 2953 gen_op_check_align_T0_3();
2878 #endif 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 break; 2956 break;
2887 case 0x11: /* load unsigned byte alternate */ 2957 case 0x11: /* load unsigned byte alternate */
2888 #ifndef TARGET_SPARC64 2958 #ifndef TARGET_SPARC64
@@ -2891,7 +2961,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2891,7 +2961,7 @@ static void disas_sparc_insn(DisasContext * dc)
2891 if (!supervisor(dc)) 2961 if (!supervisor(dc))
2892 goto priv_insn; 2962 goto priv_insn;
2893 #endif 2963 #endif
2894 - gen_op_lduba(insn, 1, 1, 0); 2964 + gen_ld_asi(insn, 1, 0);
2895 break; 2965 break;
2896 case 0x12: /* load unsigned halfword alternate */ 2966 case 0x12: /* load unsigned halfword alternate */
2897 #ifndef TARGET_SPARC64 2967 #ifndef TARGET_SPARC64
@@ -2899,11 +2969,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2899,11 +2969,10 @@ static void disas_sparc_insn(DisasContext * dc)
2899 goto illegal_insn; 2969 goto illegal_insn;
2900 if (!supervisor(dc)) 2970 if (!supervisor(dc))
2901 goto priv_insn; 2971 goto priv_insn;
2902 -#endif  
2903 -#ifdef CONFIG_USER_ONLY 2972 +#elif CONFIG_USER_ONLY
2904 gen_op_check_align_T0_1(); 2973 gen_op_check_align_T0_1();
2905 #endif 2974 #endif
2906 - gen_op_lduha(insn, 1, 2, 0); 2975 + gen_ld_asi(insn, 2, 0);
2907 break; 2976 break;
2908 case 0x13: /* load double word alternate */ 2977 case 0x13: /* load double word alternate */
2909 #ifndef TARGET_SPARC64 2978 #ifndef TARGET_SPARC64
@@ -2915,7 +2984,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2915,7 +2984,7 @@ static void disas_sparc_insn(DisasContext * dc)
2915 if (rd & 1) 2984 if (rd & 1)
2916 goto illegal_insn; 2985 goto illegal_insn;
2917 gen_op_check_align_T0_7(); 2986 gen_op_check_align_T0_7();
2918 - gen_op_ldda(insn, 1, 8, 0); 2987 + gen_ldda_asi(insn);
2919 gen_movl_T0_reg(rd + 1); 2988 gen_movl_T0_reg(rd + 1);
2920 break; 2989 break;
2921 case 0x19: /* load signed byte alternate */ 2990 case 0x19: /* load signed byte alternate */
@@ -2925,7 +2994,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2925,7 +2994,7 @@ static void disas_sparc_insn(DisasContext * dc)
2925 if (!supervisor(dc)) 2994 if (!supervisor(dc))
2926 goto priv_insn; 2995 goto priv_insn;
2927 #endif 2996 #endif
2928 - gen_op_ldsba(insn, 1, 1, 1); 2997 + gen_ld_asi(insn, 1, 1);
2929 break; 2998 break;
2930 case 0x1a: /* load signed halfword alternate */ 2999 case 0x1a: /* load signed halfword alternate */
2931 #ifndef TARGET_SPARC64 3000 #ifndef TARGET_SPARC64
@@ -2933,11 +3002,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2933,11 +3002,10 @@ static void disas_sparc_insn(DisasContext * dc)
2933 goto illegal_insn; 3002 goto illegal_insn;
2934 if (!supervisor(dc)) 3003 if (!supervisor(dc))
2935 goto priv_insn; 3004 goto priv_insn;
2936 -#endif  
2937 -#ifdef CONFIG_USER_ONLY 3005 +#elif CONFIG_USER_ONLY
2938 gen_op_check_align_T0_1(); 3006 gen_op_check_align_T0_1();
2939 #endif 3007 #endif
2940 - gen_op_ldsha(insn, 1, 2 ,1); 3008 + gen_ld_asi(insn, 2, 1);
2941 break; 3009 break;
2942 case 0x1d: /* ldstuba -- XXX: should be atomically */ 3010 case 0x1d: /* ldstuba -- XXX: should be atomically */
2943 #ifndef TARGET_SPARC64 3011 #ifndef TARGET_SPARC64
@@ -2946,7 +3014,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2946,7 +3014,7 @@ static void disas_sparc_insn(DisasContext * dc)
2946 if (!supervisor(dc)) 3014 if (!supervisor(dc))
2947 goto priv_insn; 3015 goto priv_insn;
2948 #endif 3016 #endif
2949 - gen_op_ldstuba(insn, 1, 1, 0); 3017 + gen_ldstub_asi(insn);
2950 break; 3018 break;
2951 case 0x1f: /* swap reg with alt. memory. Also atomically */ 3019 case 0x1f: /* swap reg with alt. memory. Also atomically */
2952 #ifndef TARGET_SPARC64 3020 #ifndef TARGET_SPARC64
@@ -2954,12 +3022,11 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2954,12 +3022,11 @@ static void disas_sparc_insn(DisasContext * dc)
2954 goto illegal_insn; 3022 goto illegal_insn;
2955 if (!supervisor(dc)) 3023 if (!supervisor(dc))
2956 goto priv_insn; 3024 goto priv_insn;
2957 -#endif  
2958 - gen_movl_reg_T1(rd);  
2959 -#ifdef CONFIG_USER_ONLY 3025 +#elif CONFIG_USER_ONLY
2960 gen_op_check_align_T0_3(); 3026 gen_op_check_align_T0_3();
2961 #endif 3027 #endif
2962 - gen_op_swapa(insn, 1, 4, 0); 3028 + gen_movl_reg_T1(rd);
  3029 + gen_swap_asi(insn);
2963 break; 3030 break;
2964 3031
2965 #ifndef TARGET_SPARC64 3032 #ifndef TARGET_SPARC64
@@ -2967,17 +3034,6 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2967,17 +3034,6 @@ static void disas_sparc_insn(DisasContext * dc)
2967 case 0x31: /* ldcsr */ 3034 case 0x31: /* ldcsr */
2968 case 0x33: /* lddc */ 3035 case 0x33: /* lddc */
2969 goto ncp_insn; 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 #endif 3037 #endif
2982 #endif 3038 #endif
2983 #ifdef TARGET_SPARC64 3039 #ifdef TARGET_SPARC64
@@ -2995,11 +3051,11 @@ static void disas_sparc_insn(DisasContext * dc) @@ -2995,11 +3051,11 @@ static void disas_sparc_insn(DisasContext * dc)
2995 #ifdef CONFIG_USER_ONLY 3051 #ifdef CONFIG_USER_ONLY
2996 gen_op_check_align_T0_3(); 3052 gen_op_check_align_T0_3();
2997 #endif 3053 #endif
2998 - gen_op_ldswa(insn, 1, 4, 1); 3054 + gen_ld_asi(insn, 4, 1);
2999 break; 3055 break;
3000 case 0x1b: /* V9 ldxa */ 3056 case 0x1b: /* V9 ldxa */
3001 gen_op_check_align_T0_7(); 3057 gen_op_check_align_T0_7();
3002 - gen_op_ldxa(insn, 1, 8, 0); 3058 + gen_ld_asi(insn, 8, 0);
3003 break; 3059 break;
3004 case 0x2d: /* V9 prefetch, no effect */ 3060 case 0x2d: /* V9 prefetch, no effect */
3005 goto skip_move; 3061 goto skip_move;
@@ -3007,13 +3063,12 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3007,13 +3063,12 @@ static void disas_sparc_insn(DisasContext * dc)
3007 #ifdef CONFIG_USER_ONLY 3063 #ifdef CONFIG_USER_ONLY
3008 gen_op_check_align_T0_3(); 3064 gen_op_check_align_T0_3();
3009 #endif 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 case 0x33: /* V9 lddfa */ 3068 case 0x33: /* V9 lddfa */
3013 gen_op_check_align_T0_7(); 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 case 0x3d: /* V9 prefetcha, no effect */ 3072 case 0x3d: /* V9 prefetcha, no effect */
3018 goto skip_move; 3073 goto skip_move;
3019 case 0x32: /* V9 ldqfa */ 3074 case 0x32: /* V9 ldqfa */
@@ -3092,7 +3147,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3092,7 +3147,7 @@ static void disas_sparc_insn(DisasContext * dc)
3092 #ifdef CONFIG_USER_ONLY 3147 #ifdef CONFIG_USER_ONLY
3093 gen_op_check_align_T0_3(); 3148 gen_op_check_align_T0_3();
3094 #endif 3149 #endif
3095 - gen_op_sta(insn, 0, 4, 0); 3150 + gen_st_asi(insn, 4);
3096 break; 3151 break;
3097 case 0x15: 3152 case 0x15:
3098 #ifndef TARGET_SPARC64 3153 #ifndef TARGET_SPARC64
@@ -3101,7 +3156,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3101,7 +3156,7 @@ static void disas_sparc_insn(DisasContext * dc)
3101 if (!supervisor(dc)) 3156 if (!supervisor(dc))
3102 goto priv_insn; 3157 goto priv_insn;
3103 #endif 3158 #endif
3104 - gen_op_stba(insn, 0, 1, 0); 3159 + gen_st_asi(insn, 1);
3105 break; 3160 break;
3106 case 0x16: 3161 case 0x16:
3107 #ifndef TARGET_SPARC64 3162 #ifndef TARGET_SPARC64
@@ -3113,7 +3168,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3113,7 +3168,7 @@ static void disas_sparc_insn(DisasContext * dc)
3113 #ifdef CONFIG_USER_ONLY 3168 #ifdef CONFIG_USER_ONLY
3114 gen_op_check_align_T0_1(); 3169 gen_op_check_align_T0_1();
3115 #endif 3170 #endif
3116 - gen_op_stha(insn, 0, 2, 0); 3171 + gen_st_asi(insn, 2);
3117 break; 3172 break;
3118 case 0x17: 3173 case 0x17:
3119 #ifndef TARGET_SPARC64 3174 #ifndef TARGET_SPARC64
@@ -3127,7 +3182,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3127,7 +3182,7 @@ static void disas_sparc_insn(DisasContext * dc)
3127 gen_op_check_align_T0_7(); 3182 gen_op_check_align_T0_7();
3128 flush_T2(dc); 3183 flush_T2(dc);
3129 gen_movl_reg_T2(rd + 1); 3184 gen_movl_reg_T2(rd + 1);
3130 - gen_op_stda(insn, 0, 8, 0); 3185 + gen_stda_asi(insn);
3131 break; 3186 break;
3132 #endif 3187 #endif
3133 #ifdef TARGET_SPARC64 3188 #ifdef TARGET_SPARC64
@@ -3137,7 +3192,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3137,7 +3192,7 @@ static void disas_sparc_insn(DisasContext * dc)
3137 break; 3192 break;
3138 case 0x1e: /* V9 stxa */ 3193 case 0x1e: /* V9 stxa */
3139 gen_op_check_align_T0_7(); 3194 gen_op_check_align_T0_7();
3140 - gen_op_stxa(insn, 0, 8, 0); // XXX 3195 + gen_st_asi(insn, 8);
3141 break; 3196 break;
3142 #endif 3197 #endif
3143 default: 3198 default:
@@ -3184,21 +3239,27 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3184,21 +3239,27 @@ static void disas_sparc_insn(DisasContext * dc)
3184 #ifdef CONFIG_USER_ONLY 3239 #ifdef CONFIG_USER_ONLY
3185 gen_op_check_align_T0_3(); 3240 gen_op_check_align_T0_3();
3186 #endif 3241 #endif
3187 - gen_op_stfa(insn, 0, 0, 0); // XXX 3242 + gen_st_asi(insn, 0); // XXX
3188 break; 3243 break;
3189 case 0x37: /* V9 stdfa */ 3244 case 0x37: /* V9 stdfa */
3190 gen_op_check_align_T0_7(); 3245 gen_op_check_align_T0_7();
3191 - gen_op_stdfa(insn, 0, 0, 0); // XXX 3246 + gen_st_asi(insn, 0); // XXX
3192 break; 3247 break;
3193 case 0x3c: /* V9 casa */ 3248 case 0x3c: /* V9 casa */
3194 #ifdef CONFIG_USER_ONLY 3249 #ifdef CONFIG_USER_ONLY
3195 gen_op_check_align_T0_3(); 3250 gen_op_check_align_T0_3();
3196 #endif 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 break; 3256 break;
3199 case 0x3e: /* V9 casxa */ 3257 case 0x3e: /* V9 casxa */
3200 gen_op_check_align_T0_7(); 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 break; 3263 break;
3203 case 0x36: /* V9 stqfa */ 3264 case 0x36: /* V9 stqfa */
3204 goto nfpu_insn; 3265 goto nfpu_insn;