home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / BasiliskII / src / uae_cpu / m68k.h < prev    next >
C/C++ Source or Header  |  1999-10-28  |  22KB  |  832 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * MC68000 emulation - machine dependent bits
  5.   *
  6.   * Copyright 1996 Bernd Schmidt
  7.   */
  8.  
  9. #if defined(__i386__) && defined(X86_ASSEMBLY)
  10.  
  11. struct flag_struct {
  12.     unsigned int cznv;
  13.     unsigned int x;
  14. };
  15.  
  16. #define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x40) | (((y) & 1) << 6))
  17. #define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~1) | ((y) & 1))
  18. #define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x800) | (((y) & 1) << 11))
  19. #define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x80) | (((y) & 1) << 7))
  20. #define SET_XFLG(y) (regflags.x = (y))
  21.  
  22. #define GET_ZFLG ((regflags.cznv >> 6) & 1)
  23. #define GET_CFLG (regflags.cznv & 1)
  24. #define GET_VFLG ((regflags.cznv >> 11) & 1)
  25. #define GET_NFLG ((regflags.cznv >> 7) & 1)
  26. #define GET_XFLG (regflags.x & 1)
  27.  
  28. #define CLEAR_CZNV (regflags.cznv = 0)
  29. #define COPY_CARRY (regflags.x = regflags.cznv)
  30.  
  31. extern struct flag_struct regflags __asm__ ("regflags");
  32.  
  33. static __inline__ int cctrue(int cc)
  34. {
  35.     uae_u32 cznv = regflags.cznv;
  36.     switch(cc){
  37.      case 0: return 1;                       /* T */
  38.      case 1: return 0;                       /* F */
  39.      case 2: return (cznv & 0x41) == 0; /* !GET_CFLG && !GET_ZFLG;  HI */
  40.      case 3: return (cznv & 0x41) != 0; /* GET_CFLG || GET_ZFLG;    LS */
  41.      case 4: return (cznv & 1) == 0;        /* !GET_CFLG;               CC */
  42.      case 5: return (cznv & 1) != 0;           /* GET_CFLG;                CS */
  43.      case 6: return (cznv & 0x40) == 0; /* !GET_ZFLG;               NE */
  44.      case 7: return (cznv & 0x40) != 0; /* GET_ZFLG;                EQ */
  45.      case 8: return (cznv & 0x800) == 0;/* !GET_VFLG;               VC */
  46.      case 9: return (cznv & 0x800) != 0;/* GET_VFLG;                VS */
  47.      case 10:return (cznv & 0x80) == 0; /* !GET_NFLG;               PL */
  48.      case 11:return (cznv & 0x80) != 0; /* GET_NFLG;                MI */
  49.      case 12:return (((cznv << 4) ^ cznv) & 0x800) == 0; /* GET_NFLG == GET_VFLG;             GE */
  50.      case 13:return (((cznv << 4) ^ cznv) & 0x800) != 0;/* GET_NFLG != GET_VFLG;             LT */
  51.      case 14:
  52.     cznv &= 0x8c0;
  53.     return (((cznv << 4) ^ cznv) & 0x840) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
  54.      case 15:
  55.     cznv &= 0x8c0;
  56.     return (((cznv << 4) ^ cznv) & 0x840) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG);   LE */
  57.     }
  58.     return 0;
  59. }
  60.  
  61. #define x86_flag_testl(v) \
  62.   __asm__ __volatile__ ("testl %1,%1\n\t" \
  63.             "pushfl\n\t" \
  64.             "popl %0\n\t" \
  65.             : "=r" (regflags.cznv) : "r" (v) : "cc")
  66.  
  67. #define x86_flag_testw(v) \
  68.   __asm__ __volatile__ ("testw %w1,%w1\n\t" \
  69.             "pushfl\n\t" \
  70.             "popl %0\n\t" \
  71.             : "=r" (regflags.cznv) : "r" (v) : "cc")
  72.  
  73. #define x86_flag_testb(v) \
  74.   __asm__ __volatile__ ("testb %b1,%b1\n\t" \
  75.             "pushfl\n\t" \
  76.             "popl %0\n\t" \
  77.             : "=r" (regflags.cznv) : "q" (v) : "cc")
  78.  
  79. #define x86_flag_addl(v, s, d) do { \
  80.   __asm__ __volatile__ ("addl %k2,%k1\n\t" \
  81.             "pushfl\n\t" \
  82.             "popl %0\n\t" \
  83.             : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
  84.     COPY_CARRY; \
  85.     } while (0)
  86.  
  87. #define x86_flag_addw(v, s, d) do { \
  88.   __asm__ __volatile__ ("addw %w2,%w1\n\t" \
  89.             "pushfl\n\t" \
  90.             "popl %0\n\t" \
  91.             : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
  92.     COPY_CARRY; \
  93.     } while (0)
  94.  
  95. #define x86_flag_addb(v, s, d) do { \
  96.   __asm__ __volatile__ ("addb %b2,%b1\n\t" \
  97.             "pushfl\n\t" \
  98.             "popl %0\n\t" \
  99.             : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
  100.     COPY_CARRY; \
  101.     } while (0)
  102.  
  103. #define x86_flag_subl(v, s, d) do { \
  104.   __asm__ __volatile__ ("subl %k2,%k1\n\t" \
  105.             "pushfl\n\t" \
  106.             "popl %0\n\t" \
  107.             : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
  108.     COPY_CARRY; \
  109.     } while (0)
  110.  
  111. #define x86_flag_subw(v, s, d) do { \
  112.   __asm__ __volatile__ ("subw %w2,%w1\n\t" \
  113.             "pushfl\n\t" \
  114.             "popl %0\n\t" \
  115.             : "=r" (regflags.cznv), "=r" (v) : "rmi" (s), "1" (d) : "cc"); \
  116.     COPY_CARRY; \
  117.     } while (0)
  118.  
  119. #define x86_flag_subb(v, s, d) do { \
  120.   __asm__ __volatile__ ("subb %b2,%b1\n\t" \
  121.             "pushfl\n\t" \
  122.             "popl %0\n\t" \
  123.             : "=r" (regflags.cznv), "=q" (v) : "qmi" (s), "1" (d) : "cc"); \
  124.     COPY_CARRY; \
  125.     } while (0)
  126.  
  127. #define x86_flag_cmpl(s, d) \
  128.   __asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
  129.             "pushfl\n\t" \
  130.             "popl %0\n\t" \
  131.             : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
  132.  
  133. #define x86_flag_cmpw(s, d) \
  134.   __asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
  135.             "pushfl\n\t" \
  136.             "popl %0\n\t" \
  137.             : "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
  138.  
  139. #define x86_flag_cmpb(s, d) \
  140.   __asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
  141.             "pushfl\n\t" \
  142.             "popl %0\n\t" \
  143.             : "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
  144.  
  145. #elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
  146.  
  147. struct flag_struct {
  148.     unsigned char nzvc;
  149.     unsigned char x;
  150. };
  151.  
  152. extern struct flag_struct regflags;
  153.  
  154. #define SET_ZFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x04) | (((y) & 1) << 2))
  155. #define SET_CFLG(y) (regflags.nzvc = (regflags.nzvc & ~1) | ((y) & 1))
  156. #define SET_VFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x02) | (((y) & 1) << 1))
  157. #define SET_NFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x08) | (((y) & 1) << 3))
  158. #define SET_XFLG(y) (regflags.x = (y))
  159.  
  160. #define GET_ZFLG ((regflags.nzvc >> 2) & 1)
  161. #define GET_CFLG (regflags.nzvc & 1)
  162. #define GET_VFLG ((regflags.nzvc >> 1) & 1)
  163. #define GET_NFLG ((regflags.nzvc >> 3) & 1)
  164. #define GET_XFLG (regflags.x & 1)
  165.  
  166. #define CLEAR_CZNV (regflags.nzvc = 0)
  167. #define COPY_CARRY (regflags.x = regflags.nzvc)
  168.  
  169. static __inline__ int cctrue(int cc)
  170. {
  171.     uae_u32 nzvc = regflags.nzvc;
  172.     switch(cc){
  173.      case 0: return 1;                       /* T */
  174.      case 1: return 0;                       /* F */
  175.      case 2: return (nzvc & 0x05) == 0; /* !GET_CFLG && !GET_ZFLG;  HI */
  176.      case 3: return (nzvc & 0x05) != 0; /* GET_CFLG || GET_ZFLG;    LS */
  177.      case 4: return (nzvc & 1) == 0;        /* !GET_CFLG;               CC */
  178.      case 5: return (nzvc & 1) != 0;           /* GET_CFLG;                CS */
  179.      case 6: return (nzvc & 0x04) == 0; /* !GET_ZFLG;               NE */
  180.      case 7: return (nzvc & 0x04) != 0; /* GET_ZFLG;                EQ */
  181.      case 8: return (nzvc & 0x02) == 0;/* !GET_VFLG;               VC */
  182.      case 9: return (nzvc & 0x02) != 0;/* GET_VFLG;                VS */
  183.      case 10:return (nzvc & 0x08) == 0; /* !GET_NFLG;               PL */
  184.      case 11:return (nzvc & 0x08) != 0; /* GET_NFLG;                MI */
  185.      case 12:return (((nzvc << 2) ^ nzvc) & 0x08) == 0; /* GET_NFLG == GET_VFLG;             GE */
  186.      case 13:return (((nzvc << 2) ^ nzvc) & 0x08) != 0;/* GET_NFLG != GET_VFLG;             LT */
  187.      case 14:
  188.     nzvc &= 0x0e;
  189.     return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG);  GT */
  190.      case 15:
  191.     nzvc &= 0x0e;
  192.     return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG);   LE */
  193.     }
  194.     return 0;
  195. }
  196.  
  197. #ifdef SPARC_V8_ASSEMBLY
  198.  
  199. static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  200. {
  201.     uae_u32 value;
  202.     __asm__    ("\n"
  203.         "    sll        %2, 24, %%o0\n"
  204.         "    sll        %3, 24, %%o1\n"
  205.         "    addcc    %%o0, %%o1, %%o0\n"
  206.         "    addx    %%g0, %%g0, %%o1    ! X,C flags\n"
  207.         "    srl        %%o0, 24, %0\n"
  208.         "    stb        %%o1, [%1 + 1]\n"
  209.         "    bl,a    .+8\n"
  210.         "    or        %%o1, 0x08, %%o1    ! N flag\n"
  211.         "    bz,a    .+8\n"
  212.         "    or        %%o1, 0x04, %%o1    ! Z flag\n"
  213.         "    bvs,a    .+8\n"
  214.         "    or        %%o1, 0x02, %%o1    ! V flag\n"
  215.         "    stb        %%o1, [%1]\n"
  216.     :    "=&r" (value)
  217.     :    "r" (flags), "r" (dst), "r" (src)
  218.     :    "cc", "o0", "o1"
  219.     );
  220.     return value;
  221. }
  222.  
  223. static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
  224. {
  225.     uae_u32 value;
  226.     __asm__    ("\n"
  227.         "    sll        %2, 16, %%o0\n"
  228.         "    sll        %3, 16, %%o1\n"
  229.         "    addcc    %%o0, %%o1, %%o0\n"
  230.         "    addx    %%g0, %%g0, %%o1    ! X,C flags\n"
  231.         "    srl        %%o0, 16, %0\n"
  232.         "    stb        %%o1, [%1 + 1]\n"
  233.         "    bl,a    .+8\n"
  234.         "    or        %%o1, 0x08, %%o1    ! N flag\n"
  235.         "    bz,a    .+8\n"
  236.         "    or        %%o1, 0x04, %%o1    ! Z flag\n"
  237.         "    bvs,a    .+8\n"
  238.         "    or        %%o1, 0x02, %%o1    ! V flag\n"
  239.         "    stb        %%o1, [%1]\n"
  240.     :    "=&r" (value)
  241.     :    "r" (flags), "r" (dst), "r" (src)
  242.     :    "cc", "o0", "o1"
  243.     );
  244.     return value;
  245. }
  246.  
  247. static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  248. {
  249.     uae_u32 value;
  250.     __asm__    ("\n"
  251.         "    addcc    %2, %3, %0\n"
  252.         "    addx    %%g0, %%g0, %%o0    ! X,C flags\n"
  253.         "    stb        %%o0, [%1 + 1]\n"
  254.         "    bl,a    .+8\n"
  255.         "    or        %%o0, 0x08, %%o0    ! N flag\n"
  256.         "    bz,a    .+8\n"
  257.         "    or        %%o0, 0x04, %%o0    ! Z flag\n"
  258.         "    bvs,a    .+8\n"
  259.         "    or        %%o0, 0x02, %%o0    ! V flag\n"
  260.         "    stb        %%o0, [%1]\n"
  261.     :    "=&r" (value)
  262.     :    "r" (flags), "r" (dst), "r" (src)
  263.     :    "cc", "o0"
  264.     );
  265.     return value;
  266. }
  267.  
  268. static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  269. {
  270.     uae_u32 value;
  271.     __asm__    ("\n"
  272.         "    sll        %2, 24, %%o0\n"
  273.         "    sll        %3, 24, %%o1\n"
  274.         "    subcc    %%o0, %%o1, %%o0\n"
  275.         "    addx    %%g0, %%g0, %%o1    ! X,C flags\n"
  276.         "    srl        %%o0, 24, %0\n"
  277.         "    stb        %%o1, [%1 + 1]\n"
  278.         "    bl,a    .+8\n"
  279.         "    or        %%o1, 0x08, %%o1    ! N flag\n"
  280.         "    bz,a    .+8\n"
  281.         "    or        %%o1, 0x04, %%o1    ! Z flag\n"
  282.         "    bvs,a    .+8\n"
  283.         "    or        %%o1, 0x02, %%o1    ! V flag\n"
  284.         "    stb        %%o1, [%1]\n"
  285.     :    "=&r" (value)
  286.     :    "r" (flags), "r" (dst), "r" (src)
  287.     :    "cc", "o0", "o1"
  288.     );
  289.     return value;
  290. }
  291.  
  292. static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
  293. {
  294.     uae_u32 value;
  295.     __asm__    ("\n"
  296.         "    sll        %2, 16, %%o0\n"
  297.         "    sll        %3, 16, %%o1\n"
  298.         "    subcc    %%o0, %%o1, %%o0\n"
  299.         "    addx    %%g0, %%g0, %%o1    ! X,C flags\n"
  300.         "    srl        %%o0, 16, %0\n"
  301.         "    stb        %%o1, [%1 + 1]\n"
  302.         "    bl,a    .+8\n"
  303.         "    or        %%o1, 0x08, %%o1    ! N flag\n"
  304.         "    bz,a    .+8\n"
  305.         "    or        %%o1, 0x04, %%o1    ! Z flag\n"
  306.         "    bvs,a    .+8\n"
  307.         "    or        %%o1, 0x02, %%o1    ! V flag\n"
  308.         "    stb        %%o1, [%1]\n"
  309.     :    "=&r" (value)
  310.     :    "r" (flags), "r" (dst), "r" (src)
  311.     :    "cc", "o0", "o1"
  312.     );
  313.     return value;
  314. }
  315.  
  316. static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  317. {
  318.     uae_u32 value;
  319.     __asm__    ("\n"
  320.         "    subcc    %2, %3, %0\n"
  321.         "    addx    %%g0, %%g0, %%o0    ! X,C flags\n"
  322.         "    stb        %%o0, [%1 + 1]\n"
  323.         "    bl,a    .+8\n"
  324.         "    or        %%o0, 0x08, %%o0    ! N flag\n"
  325.         "    bz,a    .+8\n"
  326.         "    or        %%o0, 0x04, %%o0    ! Z flag\n"
  327.         "    bvs,a    .+8\n"
  328.         "    or        %%o0, 0x02, %%o0    ! V flag\n"
  329.         "    stb        %%o0, [%1]\n"
  330.     :    "=&r" (value)
  331.     :    "r" (flags), "r" (dst), "r" (src)
  332.     :    "cc", "o0"
  333.     );
  334.     return value;
  335. }
  336.  
  337. static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  338. {
  339.     __asm__    ("\n"
  340.         "    sll        %1, 24, %%o0\n"
  341.         "    sll        %2, 24, %%o1\n"
  342.         "    subcc    %%o0, %%o1, %%g0\n"
  343.         "    addx    %%g0, %%g0, %%o0    ! C flag\n"
  344.         "    bl,a    .+8\n"
  345.         "    or        %%o0, 0x08, %%o0    ! N flag\n"
  346.         "    bz,a    .+8\n"
  347.         "    or        %%o0, 0x04, %%o0    ! Z flag\n"
  348.         "    bvs,a    .+8\n"
  349.         "    or        %%o0, 0x02, %%o0    ! V flag\n"
  350.         "    stb        %%o0, [%0]\n"
  351.     :    /* no outputs */
  352.     :    "r" (flags), "r" (dst), "r" (src)
  353.     :    "cc", "o0", "o1"
  354.     );
  355. }
  356.  
  357. static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
  358. {
  359.     __asm__    ("\n"
  360.         "    sll        %1, 16, %%o0\n"
  361.         "    sll        %2, 16, %%o1\n"
  362.         "    subcc    %%o0, %%o1, %%g0\n"
  363.         "    addx    %%g0, %%g0, %%o0    ! C flag\n"
  364.         "    bl,a    .+8\n"
  365.         "    or        %%o0, 0x08, %%o0    ! N flag\n"
  366.         "    bz,a    .+8\n"
  367.         "    or        %%o0, 0x04, %%o0    ! Z flag\n"
  368.         "    bvs,a    .+8\n"
  369.         "    or        %%o0, 0x02, %%o0    ! V flag\n"
  370.         "    stb        %%o0, [%0]\n"
  371.     :    /* no outputs */
  372.     :    "r" (flags), "r" (dst), "r" (src)
  373.     :    "cc", "o0", "o1"
  374.     );
  375. }
  376.  
  377. static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  378. {
  379.     __asm__    ("\n"
  380.         "    subcc    %1, %2, %%o1\n"
  381.         "    srl        %%o1, 31, %%o0\n"
  382.         "    sll        %%o0, 3, %%o0\n"
  383.         "    addx    %%o0, %%g0, %%o0\n"
  384.         "    bvs,a    .+8\n"
  385.         "    or        %%o0, 0x02, %%o0\n"
  386.         "    subcc    %%g0, %%o1, %%g0\n"
  387.         "    addx    %%g0, 7, %%o1\n"
  388.         "    and        %%o1, 0x04, %%o1\n"
  389.         "    or        %%o0, %%o1, %%o0\n"
  390.         "    stb        %%o0, [%0]\n"
  391.     :    /* no outputs */
  392.     :    "r" (flags), "r" (dst), "r" (src)
  393.     :    "cc", "o0", "o1"
  394.     );
  395. }
  396.  
  397. static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  398. {
  399.     uae_u32 value;
  400.     __asm__    ("\n"
  401.         "    ldub    [%1 + 1], %%o1        ! Get the X Flag\n"
  402.         "    subcc    %%g0, %%o1, %%g0    ! Set the SPARC carry flag, if X set\n"
  403.         "    addxcc    %2, %3, %0\n"
  404.     :    "=&r" (value)
  405.     :    "r" (flags), "r" (dst), "r" (src)
  406.     :    "cc", "o0", "o1"
  407.     );
  408.     return value;
  409. }
  410.  
  411. #if 0
  412. VERY SLOW...
  413. static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  414. {
  415.     uae_u32 value;
  416.     __asm__    ("\n"
  417.         "    sll        %2, 24, %%o0\n"
  418.         "    sll        %3, 24, %%o1\n"
  419.         "    addcc    %%o0, %%o1, %%o0\n"
  420.         "    addx    %%g0, %%g0, %%o1    ! X,C flags\n"
  421.         "    bvs,a    .+8\n"
  422.         "    or        %%o1, 0x02, %%o1    ! V flag\n"
  423.         "    ldub    [%1 + 1], %%o2\n"
  424.         "    subcc    %%g0, %%o2, %%g0\n"
  425.         "    addx    %%g0, %%g0, %%o2\n"
  426.         "    sll        %%o2, 24, %%o2\n"
  427.         "    addcc    %%o0, %%o2, %%o0\n"
  428.         "    srl        %%o0, 24, %0\n"
  429.         "    addx    %%g0, %%g0, %%o2\n"
  430.         "    or        %%o1, %%o2, %%o1    ! update X,C flags\n"
  431.         "    bl,a    .+8\n"
  432.         "    or        %%o1, 0x08, %%o1    ! N flag\n"
  433.         "    ldub    [%1], %%o0            ! retreive the old NZVC flags (XXX)\n"
  434.         "    bvs,a    .+8\n"
  435.         "    or        %%o1, 0x02, %%o1    ! update V flag\n"
  436.         "    and        %%o0, 0x04, %%o0    ! (XXX) but keep only Z flag\n"
  437.         "    and        %%o1, 1, %%o2        ! keep C flag in %%o2\n"
  438.         "    bnz,a    .+8\n"
  439.         "    or        %%g0, %%g0, %%o0    ! Z flag cleared if non-zero result\n"
  440.         "    stb        %%o2, [%1 + 1]        ! store the X flag\n"
  441.         "    or        %%o1, %%o0, %%o1\n"
  442.         "    stb        %%o1, [%1]\n"
  443.     :    "=&r" (value)
  444.     :    "r" (flags), "r" (dst), "r" (src)
  445.     :    "cc", "o0", "o1", "o2"
  446.     );
  447.     return value;
  448. }
  449. #endif
  450.  
  451. static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  452. {
  453.     uae_u32 value;
  454.     __asm__    ("\n"
  455.         "    ldub    [%1 + 1], %%o0        ! Get the X Flag\n"
  456.         "    subcc    %%g0, %%o0, %%g0    ! Set the SPARC carry flag, if X set\n"
  457.         "    addxcc    %2, %3, %0\n"
  458.         "    ldub    [%1], %%o0            ! retreive the old NZVC flags\n"
  459.         "    and        %%o0, 0x04, %%o0    ! but keep only Z flag\n"
  460.         "    addx    %%o0, %%g0, %%o0    ! X,C flags\n"
  461.         "    bl,a    .+8\n"
  462.         "    or        %%o0, 0x08, %%o0    ! N flag\n"
  463.         "    bvs,a    .+8\n"
  464.         "    or        %%o0, 0x02, %%o0    ! V flag\n"
  465.         "    bnz,a    .+8\n"
  466.         "    and        %%o0, 0x0B, %%o0    ! Z flag cleared if result is non-zero\n"
  467.         "    stb        %%o0, [%1]\n"
  468.         "    stb        %%o0, [%1 + 1]\n"
  469.     :    "=&r" (value)
  470.     :    "r" (flags), "r" (dst), "r" (src)
  471.     :    "cc", "o0"
  472.     );
  473.     return value;
  474. }
  475.  
  476. #endif /* SPARC_V8_ASSEMBLY */
  477.  
  478. #ifdef SPARC_V9_ASSEMBLY
  479.  
  480. static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  481. {
  482.     uae_u32 value;
  483.     __asm__    ("\n"
  484.         "    sll        %2, 24, %%o0\n"
  485.         "    sll        %3, 24, %%o1\n"
  486.         "    addcc    %%o0, %%o1, %%o0\n"
  487.         "    rd        %%ccr, %%o1\n"
  488.         "    srl        %%o0, 24, %0\n"
  489.         "    stb        %%o1, [%1]\n"
  490.         "    stb        %%o1, [%1+1]\n"
  491.     :    "=&r" (value)
  492.     :    "r" (flags), "r" (dst), "r" (src)
  493.     :    "cc", "o0", "o1"
  494.     );
  495.     return value;
  496. }
  497.  
  498. static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
  499. {
  500.     uae_u32 value;
  501.     __asm__    ("\n"
  502.         "    sll        %2, 16, %%o0\n"
  503.         "    sll        %3, 16, %%o1\n"
  504.         "    addcc    %%o0, %%o1, %%o0\n"
  505.         "    rd        %%ccr, %%o1\n"
  506.         "    srl        %%o0, 16, %0\n"
  507.         "    stb        %%o1, [%1]\n"
  508.         "    stb        %%o1, [%1+1]\n"
  509.     :    "=&r" (value)
  510.     :    "r" (flags), "r" (dst), "r" (src)
  511.     :    "cc", "o0", "o1"
  512.     );
  513.     return value;
  514. }
  515.  
  516. static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  517. {
  518.     uae_u32 value;
  519.     __asm__    ("\n"
  520.         "    addcc    %2, %3, %0\n"
  521.         "    rd        %%ccr, %%o0\n"
  522.         "    stb        %%o0, [%1]\n"
  523.         "    stb        %%o0, [%1+1]\n"
  524.     :    "=&r" (value)
  525.     :    "r" (flags), "r" (dst), "r" (src)
  526.     :    "cc", "o0"
  527.     );
  528.     return value;
  529. }
  530.  
  531. static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  532. {
  533.     uae_u32 value;
  534.     __asm__    ("\n"
  535.         "    sll        %2, 24, %%o0\n"
  536.         "    sll        %3, 24, %%o1\n"
  537.         "    subcc    %%o0, %%o1, %%o0\n"
  538.         "    rd        %%ccr, %%o1\n"
  539.         "    srl        %%o0, 24, %0\n"
  540.         "    stb        %%o1, [%1]\n"
  541.         "    stb        %%o1, [%1+1]\n"
  542.     :    "=&r" (value)
  543.     :    "r" (flags), "r" (dst), "r" (src)
  544.     :    "cc", "o0", "o1"
  545.     );
  546.     return value;
  547. }
  548.  
  549. static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
  550. {
  551.     uae_u32 value;
  552.     __asm__    ("\n"
  553.         "    sll        %2, 16, %%o0\n"
  554.         "    sll        %3, 16, %%o1\n"
  555.         "    subcc    %%o0, %%o1, %%o0\n"
  556.         "    rd        %%ccr, %%o1\n"
  557.         "    srl        %%o0, 16, %0\n"
  558.         "    stb        %%o1, [%1]\n"
  559.         "    stb        %%o1, [%1+1]\n"
  560.     :    "=&r" (value)
  561.     :    "r" (flags), "r" (dst), "r" (src)
  562.     :    "cc", "o0", "o1"
  563.     );
  564.     return value;
  565. }
  566.  
  567. static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  568. {
  569.     uae_u32 value;
  570.     __asm__    ("\n"
  571.         "    subcc    %2, %3, %0\n"
  572.         "    rd        %%ccr, %%o0\n"
  573.         "    stb        %%o0, [%1]\n"
  574.         "    stb        %%o0, [%1+1]\n"
  575.     :    "=&r" (value)
  576.     :    "r" (flags), "r" (dst), "r" (src)
  577.     :    "cc", "o0"
  578.     );
  579.     return value;
  580. }
  581.  
  582. static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  583. {
  584.     __asm__    ("\n"
  585.         "    sll        %1, 24, %%o0\n"
  586.         "    sll        %2, 24, %%o1\n"
  587.         "    subcc    %%o0, %%o1, %%g0\n"
  588.         "    rd        %%ccr, %%o0\n"
  589.         "    stb        %%o0, [%0]\n"
  590.     :    /* no outputs */
  591.     :    "r" (flags), "r" (dst), "r" (src)
  592.     :    "cc", "o0", "o1"
  593.     );
  594. }
  595.  
  596. static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst)
  597. {
  598.     __asm__    ("\n"
  599.         "    sll        %1, 16, %%o0\n"
  600.         "    sll        %2, 16, %%o1\n"
  601.         "    subcc    %%o0, %%o1, %%g0\n"
  602.         "    rd        %%ccr, %%o0\n"
  603.         "    stb        %%o0, [%0]\n"
  604.     :    /* no outputs */
  605.     :    "r" (flags), "r" (dst), "r" (src)
  606.     :    "cc", "o0", "o1"
  607.     );
  608. }
  609.  
  610. static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  611. {
  612.     __asm__    ("\n"
  613.         "    subcc    %1, %2, %%g0\n"
  614. #if 0
  615.         "    subcc    %1, %2, %%o1\n"
  616.         "    srl        %%o1, 31, %%o0\n"
  617.         "    sll        %%o0, 3, %%o0\n"
  618.         "    addx    %%o0, %%g0, %%o0\n"
  619.         "    bvs,a    .+8\n"
  620.         "    or        %%o0, 0x02, %%o0\n"
  621.         "    subcc    %%g0, %%o1, %%g0\n"
  622.         "    addx    %%g0, 7, %%o1\n"
  623.         "    and        %%o1, 0x04, %%o1\n"
  624.         "    or        %%o0, %%o1, %%o0\n"
  625. #endif
  626. #if 0
  627.         "    subcc    %1, %2, %%o1\n"
  628.         "    srl        %%o1, 31, %%o0\n"
  629.         "    sll        %%o0, 3, %%o0\n"
  630.         "    addx    %%o0, %%g0, %%o0\n"
  631.         "    bvs,pt,a    .+8\n"
  632.         "    or        %%o0, 0x02, %%o0\n"
  633.         "    subcc    %%g0, %%o1, %%g0\n"
  634.         "    addx    %%g0, 7, %%o1\n"
  635.         "    and        %%o1, 0x04, %%o1\n"
  636.         "    or        %%o0, %%o1, %%o0\n"
  637.         "    stb        %%o0, [%0]\n"
  638. #endif
  639.         "    rd        %%ccr, %%o0\n"
  640.         "    stb        %%o0, [%0]\n"
  641.     :    /* no outputs */
  642.     :    "r" (flags), "r" (dst), "r" (src)
  643.     :    "cc", "o0", "o1"
  644.     );
  645. }
  646.  
  647. #if 1
  648. static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
  649. {
  650.     __asm__    ("\n"
  651.         "    sll        %1, 24, %%o0\n"
  652.         "    subcc    %%o0, %%g0, %%g0\n"
  653.         "    rd        %%ccr, %%o0\n"
  654.         "    stb        %%o0, [%0]\n"
  655.     :    /* no outputs */
  656.     :    "r" (flags), "r" (val)
  657.     :    "cc", "o0"
  658.     );
  659. }
  660.  
  661. static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
  662. {
  663.     __asm__    ("\n"
  664.         "    sll        %1, 16, %%o0\n"
  665.         "    subcc    %%o0, %%g0, %%g0\n"
  666.         "    rd        %%ccr, %%o0\n"
  667.         "    stb        %%o0, [%0]\n"
  668.     :    /* no outputs */
  669.     :    "r" (flags), "r" (val)
  670.     :    "cc", "o0"
  671.     );
  672. }
  673.  
  674. static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
  675. {
  676.     __asm__    ("\n"
  677.         "    subcc    %1, %%g0, %%g0\n"
  678.         "    rd        %%ccr, %%o0\n"
  679.         "    stb        %%o0, [%0]\n"
  680.     :    /* no outputs */
  681.     :    "r" (flags), "r" (val)
  682.     :    "cc", "o0"
  683.     );
  684. }
  685. #else
  686. static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val)
  687. {
  688.     __asm__    ("\n"
  689.         "    sll        %1, 24, %%o0\n"
  690.         "    subcc    %%o0, %%g0, %%o1\n"
  691.         "    srl        %%o1, 31, %%o0\n"
  692.         "    sll        %%o0, 3, %%o0\n"
  693.         "    addx    %%o0, %%g0, %%o0\n"
  694.         "    bvs,a    .+8\n"
  695.         "    or        %%o0, 0x02, %%o0\n"
  696.         "    subcc    %%g0, %%o1, %%g0\n"
  697.         "    addx    %%g0, 7, %%o1\n"
  698.         "    and        %%o1, 0x04, %%o1\n"
  699.         "    or        %%o0, %%o1, %%o0\n"
  700.         "    stb        %%o0, [%0]\n"
  701.     :    /* no outputs */
  702.     :    "r" (flags), "r" (val)
  703.     :    "cc", "o0", "o1"
  704.     );
  705. }
  706.  
  707. static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val)
  708. {
  709.     __asm__    ("\n"
  710.         "    sll        %1, 16, %%o0\n"
  711.         "    subcc    %%o0, %%g0, %%o1\n"
  712.         "    srl        %%o1, 31, %%o0\n"
  713.         "    sll        %%o0, 3, %%o0\n"
  714.         "    addx    %%o0, %%g0, %%o0\n"
  715.         "    bvs,a    .+8\n"
  716.         "    or        %%o0, 0x02, %%o0\n"
  717.         "    subcc    %%g0, %%o1, %%g0\n"
  718.         "    addx    %%g0, 7, %%o1\n"
  719.         "    and        %%o1, 0x04, %%o1\n"
  720.         "    or        %%o0, %%o1, %%o0\n"
  721.         "    stb        %%o0, [%0]\n"
  722.     :    /* no outputs */
  723.     :    "r" (flags), "r" (val)
  724.     :    "cc", "o0", "o1"
  725.     );
  726. }
  727.  
  728. static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val)
  729. {
  730.     __asm__    ("\n"
  731.         "    subcc    %1, %%g0, %%o1\n"
  732.         "    srl        %%o1, 31, %%o0\n"
  733.         "    sll        %%o0, 3, %%o0\n"
  734.         "    addx    %%o0, %%g0, %%o0\n"
  735.         "    bvs,a    .+8\n"
  736.         "    or        %%o0, 0x02, %%o0\n"
  737.         "    subcc    %%g0, %%o1, %%g0\n"
  738.         "    addx    %%g0, 7, %%o1\n"
  739.         "    and        %%o1, 0x04, %%o1\n"
  740.         "    or        %%o0, %%o1, %%o0\n"
  741.         "    stb        %%o0, [%0]\n"
  742.     :    /* no outputs */
  743.     :    "r" (flags), "r" (val)
  744.     :    "cc", "o0", "o1"
  745.     );
  746. }
  747. #endif
  748.  
  749. static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst)
  750. {
  751.     uae_u32 value;
  752.     __asm__    ("\n"
  753.         "    ldub    [%1 + 1], %%o1        ! Get the X Flag\n"
  754.         "    subcc    %%g0, %%o1, %%g0    ! Set the SPARC carry flag, if X set\n"
  755.         "    addxcc    %2, %3, %0\n"
  756.     :    "=&r" (value)
  757.     :    "r" (flags), "r" (dst), "r" (src)
  758.     :    "cc", "o0", "o1"
  759.     );
  760.     return value;
  761. }
  762.  
  763. static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst)
  764. {
  765.     uae_u32 value;
  766.     __asm__    ("\n"
  767.         "    ldub    [%1 + 1], %%o0        ! Get the X Flag\n"
  768.         "    subcc    %%g0, %%o0, %%g0    ! Set the SPARC carry flag, if X set\n"
  769.         "    addxcc    %2, %3, %0\n"
  770.         "    ldub    [%1], %%o0            ! retreive the old NZVC flags\n"
  771.         "    and        %%o0, 0x04, %%o0    ! but keep only Z flag\n"
  772.         "    addx    %%o0, %%g0, %%o0    ! X,C flags\n"
  773.         "    bl,a    .+8\n"
  774.         "    or        %%o0, 0x08, %%o0    ! N flag\n"
  775.         "    bvs,a    .+8\n"
  776.         "    or        %%o0, 0x02, %%o0    ! V flag\n"
  777.         "    bnz,a    .+8\n"
  778.         "    and        %%o0, 0x0B, %%o0    ! Z flag cleared if result is non-zero\n"
  779.         "    stb        %%o0, [%1]\n"
  780.         "    stb        %%o0, [%1 + 1]\n"
  781.     :    "=&r" (value)
  782.     :    "r" (flags), "r" (dst), "r" (src)
  783.     :    "cc", "o0"
  784.     );
  785.     return value;
  786. }
  787.  
  788. #endif /* SPARC_V9_ASSEMBLY */
  789.  
  790. #else
  791.  
  792. struct flag_struct {
  793.     unsigned int c;
  794.     unsigned int z;
  795.     unsigned int n;
  796.     unsigned int v; 
  797.     unsigned int x;
  798. };
  799.  
  800. extern struct flag_struct regflags;
  801.  
  802. #define ZFLG (regflags.z)
  803. #define NFLG (regflags.n)
  804. #define CFLG (regflags.c)
  805. #define VFLG (regflags.v)
  806. #define XFLG (regflags.x)
  807.  
  808. static __inline__ int cctrue(const int cc)
  809. {
  810.     switch(cc){
  811.      case 0: return 1;                       /* T */
  812.      case 1: return 0;                       /* F */
  813.      case 2: return !CFLG && !ZFLG;          /* HI */
  814.      case 3: return CFLG || ZFLG;            /* LS */
  815.      case 4: return !CFLG;                   /* CC */
  816.      case 5: return CFLG;                    /* CS */
  817.      case 6: return !ZFLG;                   /* NE */
  818.      case 7: return ZFLG;                    /* EQ */
  819.      case 8: return !VFLG;                   /* VC */
  820.      case 9: return VFLG;                    /* VS */
  821.      case 10:return !NFLG;                   /* PL */
  822.      case 11:return NFLG;                    /* MI */
  823.      case 12:return NFLG == VFLG;            /* GE */
  824.      case 13:return NFLG != VFLG;            /* LT */
  825.      case 14:return !ZFLG && (NFLG == VFLG); /* GT */
  826.      case 15:return ZFLG || (NFLG != VFLG);  /* LE */
  827.     }
  828.     return 0;
  829. }
  830.  
  831. #endif
  832.