From f04292fd21a71a20a5e23129be50d533b9462555 Mon Sep 17 00:00:00 2001 From: cebix <> Date: Thu, 21 Oct 1999 15:27:11 +0000 Subject: [PATCH] - integrated SPARC assembly optimizations --- BasiliskII/src/Unix/Solaris/sparcasm.h | 610 ---------------------- BasiliskII/src/Unix/Solaris/which_sparc | 18 +- BasiliskII/src/uae_cpu/gencpu.c | 1 - BasiliskII/src/uae_cpu/m68k.h | 647 +++++++++++++++++++++++- 4 files changed, 657 insertions(+), 619 deletions(-) delete mode 100644 BasiliskII/src/Unix/Solaris/sparcasm.h diff --git a/BasiliskII/src/Unix/Solaris/sparcasm.h b/BasiliskII/src/Unix/Solaris/sparcasm.h deleted file mode 100644 index 5a753bf7..00000000 --- a/BasiliskII/src/Unix/Solaris/sparcasm.h +++ /dev/null @@ -1,610 +0,0 @@ -#ifndef SPARC_ASSEMBLY__HEADER -#define SPARC_ASSEMBLY__HEADER - -#ifdef SPARC_V8_ASSEMBLY - -static inline char *str_flags(void) -{ - static char str[8]; - sprintf(str, "%c%c%c%c%c", - GET_XFLG ? 'X' : '-', - GET_NFLG ? 'N' : '-', - GET_ZFLG ? 'Z' : '-', - GET_VFLG ? 'V' : '-', - GET_CFLG ? 'C' : '-' - ); - return str; -} - -static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 24, %%o0\n" - " sll %3, 24, %%o1\n" - " addcc %%o0, %%o1, %%o0\n" - " addx %%g0, %%g0, %%o1 ! X,C flags\n" - " srl %%o0, 24, %0\n" - " stb %%o1, [%1 + 1]\n" - " bl,a .+8\n" - " or %%o1, 0x08, %%o1 ! N flag\n" - " bz,a .+8\n" - " or %%o1, 0x04, %%o1 ! Z flag\n" - " bvs,a .+8\n" - " or %%o1, 0x02, %%o1 ! V flag\n" - " stb %%o1, [%1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 16, %%o0\n" - " sll %3, 16, %%o1\n" - " addcc %%o0, %%o1, %%o0\n" - " addx %%g0, %%g0, %%o1 ! X,C flags\n" - " srl %%o0, 16, %0\n" - " stb %%o1, [%1 + 1]\n" - " bl,a .+8\n" - " or %%o1, 0x08, %%o1 ! N flag\n" - " bz,a .+8\n" - " or %%o1, 0x04, %%o1 ! Z flag\n" - " bvs,a .+8\n" - " or %%o1, 0x02, %%o1 ! V flag\n" - " stb %%o1, [%1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " addcc %2, %3, %0\n" - " addx %%g0, %%g0, %%o0 ! X,C flags\n" - " stb %%o0, [%1 + 1]\n" - " bl,a .+8\n" - " or %%o0, 0x08, %%o0 ! N flag\n" - " bz,a .+8\n" - " or %%o0, 0x04, %%o0 ! Z flag\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0 ! V flag\n" - " stb %%o0, [%1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0" - ); - return value; -} - -static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 24, %%o0\n" - " sll %3, 24, %%o1\n" - " subcc %%o0, %%o1, %%o0\n" - " addx %%g0, %%g0, %%o1 ! X,C flags\n" - " srl %%o0, 24, %0\n" - " stb %%o1, [%1 + 1]\n" - " bl,a .+8\n" - " or %%o1, 0x08, %%o1 ! N flag\n" - " bz,a .+8\n" - " or %%o1, 0x04, %%o1 ! Z flag\n" - " bvs,a .+8\n" - " or %%o1, 0x02, %%o1 ! V flag\n" - " stb %%o1, [%1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 16, %%o0\n" - " sll %3, 16, %%o1\n" - " subcc %%o0, %%o1, %%o0\n" - " addx %%g0, %%g0, %%o1 ! X,C flags\n" - " srl %%o0, 16, %0\n" - " stb %%o1, [%1 + 1]\n" - " bl,a .+8\n" - " or %%o1, 0x08, %%o1 ! N flag\n" - " bz,a .+8\n" - " or %%o1, 0x04, %%o1 ! Z flag\n" - " bvs,a .+8\n" - " or %%o1, 0x02, %%o1 ! V flag\n" - " stb %%o1, [%1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " subcc %2, %3, %0\n" - " addx %%g0, %%g0, %%o0 ! X,C flags\n" - " stb %%o0, [%1 + 1]\n" - " bl,a .+8\n" - " or %%o0, 0x08, %%o0 ! N flag\n" - " bz,a .+8\n" - " or %%o0, 0x04, %%o0 ! Z flag\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0 ! V flag\n" - " stb %%o0, [%1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0" - ); - return value; -} - -static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - __asm__ ("\n" - " sll %1, 24, %%o0\n" - " sll %2, 24, %%o1\n" - " subcc %%o0, %%o1, %%g0\n" - " addx %%g0, %%g0, %%o0 ! C flag\n" - " bl,a .+8\n" - " or %%o0, 0x08, %%o0 ! N flag\n" - " bz,a .+8\n" - " or %%o0, 0x04, %%o0 ! Z flag\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0 ! V flag\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); -} - -static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - __asm__ ("\n" - " sll %1, 16, %%o0\n" - " sll %2, 16, %%o1\n" - " subcc %%o0, %%o1, %%g0\n" - " addx %%g0, %%g0, %%o0 ! C flag\n" - " bl,a .+8\n" - " or %%o0, 0x08, %%o0 ! N flag\n" - " bz,a .+8\n" - " or %%o0, 0x04, %%o0 ! Z flag\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0 ! V flag\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); -} - -static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - __asm__ ("\n" - " subcc %1, %2, %%o1\n" - " srl %%o1, 31, %%o0\n" - " sll %%o0, 3, %%o0\n" - " addx %%o0, %%g0, %%o0\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0\n" - " subcc %%g0, %%o1, %%g0\n" - " addx %%g0, 7, %%o1\n" - " and %%o1, 0x04, %%o1\n" - " or %%o0, %%o1, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); -} - -static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " ldub [%1 + 1], %%o1 ! Get the X Flag\n" - " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n" - " addxcc %2, %3, %0\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -#if 0 -VERY SLOW... -static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 24, %%o0\n" - " sll %3, 24, %%o1\n" - " addcc %%o0, %%o1, %%o0\n" - " addx %%g0, %%g0, %%o1 ! X,C flags\n" - " bvs,a .+8\n" - " or %%o1, 0x02, %%o1 ! V flag\n" - " ldub [%1 + 1], %%o2\n" - " subcc %%g0, %%o2, %%g0\n" - " addx %%g0, %%g0, %%o2\n" - " sll %%o2, 24, %%o2\n" - " addcc %%o0, %%o2, %%o0\n" - " srl %%o0, 24, %0\n" - " addx %%g0, %%g0, %%o2\n" - " or %%o1, %%o2, %%o1 ! update X,C flags\n" - " bl,a .+8\n" - " or %%o1, 0x08, %%o1 ! N flag\n" - " ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n" - " bvs,a .+8\n" - " or %%o1, 0x02, %%o1 ! update V flag\n" - " and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n" - " and %%o1, 1, %%o2 ! keep C flag in %%o2\n" - " bnz,a .+8\n" - " or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n" - " stb %%o2, [%1 + 1] ! store the X flag\n" - " or %%o1, %%o0, %%o1\n" - " stb %%o1, [%1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1", "o2" - ); - return value; -} -#endif - -static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " ldub [%1 + 1], %%o0 ! Get the X Flag\n" - " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n" - " addxcc %2, %3, %0\n" - " ldub [%1], %%o0 ! retreive the old NZVC flags\n" - " and %%o0, 0x04, %%o0 ! but keep only Z flag\n" - " addx %%o0, %%g0, %%o0 ! X,C flags\n" - " bl,a .+8\n" - " or %%o0, 0x08, %%o0 ! N flag\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0 ! V flag\n" - " bnz,a .+8\n" - " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n" - " stb %%o0, [%1]\n" - " stb %%o0, [%1 + 1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0" - ); - return value; -} - -#endif /* SPARC_V8_ASSEMBLY */ - -#ifdef SPARC_V9_ASSEMBLY - -static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 24, %%o0\n" - " sll %3, 24, %%o1\n" - " addcc %%o0, %%o1, %%o0\n" - " rd %%ccr, %%o1\n" - " srl %%o0, 24, %0\n" - " stb %%o1, [%1]\n" - " stb %%o1, [%1+1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 16, %%o0\n" - " sll %3, 16, %%o1\n" - " addcc %%o0, %%o1, %%o0\n" - " rd %%ccr, %%o1\n" - " srl %%o0, 16, %0\n" - " stb %%o1, [%1]\n" - " stb %%o1, [%1+1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " addcc %2, %3, %0\n" - " rd %%ccr, %%o0\n" - " stb %%o0, [%1]\n" - " stb %%o0, [%1+1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0" - ); - return value; -} - -static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 24, %%o0\n" - " sll %3, 24, %%o1\n" - " subcc %%o0, %%o1, %%o0\n" - " rd %%ccr, %%o1\n" - " srl %%o0, 24, %0\n" - " stb %%o1, [%1]\n" - " stb %%o1, [%1+1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " sll %2, 16, %%o0\n" - " sll %3, 16, %%o1\n" - " subcc %%o0, %%o1, %%o0\n" - " rd %%ccr, %%o1\n" - " srl %%o0, 16, %0\n" - " stb %%o1, [%1]\n" - " stb %%o1, [%1+1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " subcc %2, %3, %0\n" - " rd %%ccr, %%o0\n" - " stb %%o0, [%1]\n" - " stb %%o0, [%1+1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0" - ); - return value; -} - -static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - __asm__ ("\n" - " sll %1, 24, %%o0\n" - " sll %2, 24, %%o1\n" - " subcc %%o0, %%o1, %%g0\n" - " rd %%ccr, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); -} - -static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - __asm__ ("\n" - " sll %1, 16, %%o0\n" - " sll %2, 16, %%o1\n" - " subcc %%o0, %%o1, %%g0\n" - " rd %%ccr, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); -} - -static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - __asm__ ("\n" - " subcc %1, %2, %%g0\n" -#if 0 - " subcc %1, %2, %%o1\n" - " srl %%o1, 31, %%o0\n" - " sll %%o0, 3, %%o0\n" - " addx %%o0, %%g0, %%o0\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0\n" - " subcc %%g0, %%o1, %%g0\n" - " addx %%g0, 7, %%o1\n" - " and %%o1, 0x04, %%o1\n" - " or %%o0, %%o1, %%o0\n" -#endif -#if 0 - " subcc %1, %2, %%o1\n" - " srl %%o1, 31, %%o0\n" - " sll %%o0, 3, %%o0\n" - " addx %%o0, %%g0, %%o0\n" - " bvs,pt,a .+8\n" - " or %%o0, 0x02, %%o0\n" - " subcc %%g0, %%o1, %%g0\n" - " addx %%g0, 7, %%o1\n" - " and %%o1, 0x04, %%o1\n" - " or %%o0, %%o1, %%o0\n" - " stb %%o0, [%0]\n" -#endif - " rd %%ccr, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); -} - -#if 1 -static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val) -{ - __asm__ ("\n" - " sll %1, 24, %%o0\n" - " subcc %%o0, %%g0, %%g0\n" - " rd %%ccr, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (val) - : "cc", "o0" - ); -} - -static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val) -{ - __asm__ ("\n" - " sll %1, 16, %%o0\n" - " subcc %%o0, %%g0, %%g0\n" - " rd %%ccr, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (val) - : "cc", "o0" - ); -} - -static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val) -{ - __asm__ ("\n" - " subcc %1, %%g0, %%g0\n" - " rd %%ccr, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (val) - : "cc", "o0" - ); -} -#else -static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val) -{ - __asm__ ("\n" - " sll %1, 24, %%o0\n" - " subcc %%o0, %%g0, %%o1\n" - " srl %%o1, 31, %%o0\n" - " sll %%o0, 3, %%o0\n" - " addx %%o0, %%g0, %%o0\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0\n" - " subcc %%g0, %%o1, %%g0\n" - " addx %%g0, 7, %%o1\n" - " and %%o1, 0x04, %%o1\n" - " or %%o0, %%o1, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (val) - : "cc", "o0", "o1" - ); -} - -static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val) -{ - __asm__ ("\n" - " sll %1, 16, %%o0\n" - " subcc %%o0, %%g0, %%o1\n" - " srl %%o1, 31, %%o0\n" - " sll %%o0, 3, %%o0\n" - " addx %%o0, %%g0, %%o0\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0\n" - " subcc %%g0, %%o1, %%g0\n" - " addx %%g0, 7, %%o1\n" - " and %%o1, 0x04, %%o1\n" - " or %%o0, %%o1, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (val) - : "cc", "o0", "o1" - ); -} - -static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val) -{ - __asm__ ("\n" - " subcc %1, %%g0, %%o1\n" - " srl %%o1, 31, %%o0\n" - " sll %%o0, 3, %%o0\n" - " addx %%o0, %%g0, %%o0\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0\n" - " subcc %%g0, %%o1, %%g0\n" - " addx %%g0, 7, %%o1\n" - " and %%o1, 0x04, %%o1\n" - " or %%o0, %%o1, %%o0\n" - " stb %%o0, [%0]\n" - : /* no outputs */ - : "r" (flags), "r" (val) - : "cc", "o0", "o1" - ); -} -#endif - -static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " ldub [%1 + 1], %%o1 ! Get the X Flag\n" - " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n" - " addxcc %2, %3, %0\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0", "o1" - ); - return value; -} - -static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst) -{ - uae_u32 value; - __asm__ ("\n" - " ldub [%1 + 1], %%o0 ! Get the X Flag\n" - " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n" - " addxcc %2, %3, %0\n" - " ldub [%1], %%o0 ! retreive the old NZVC flags\n" - " and %%o0, 0x04, %%o0 ! but keep only Z flag\n" - " addx %%o0, %%g0, %%o0 ! X,C flags\n" - " bl,a .+8\n" - " or %%o0, 0x08, %%o0 ! N flag\n" - " bvs,a .+8\n" - " or %%o0, 0x02, %%o0 ! V flag\n" - " bnz,a .+8\n" - " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n" - " stb %%o0, [%1]\n" - " stb %%o0, [%1 + 1]\n" - : "=&r" (value) - : "r" (flags), "r" (dst), "r" (src) - : "cc", "o0" - ); - return value; -} - -#endif /* SPARC_V9_ASSEMBLY */ - -#endif /* SPARC_ASSEMBLY__HEADER */ diff --git a/BasiliskII/src/Unix/Solaris/which_sparc b/BasiliskII/src/Unix/Solaris/which_sparc index fb386a4f..b6824fd0 100755 --- a/BasiliskII/src/Unix/Solaris/which_sparc +++ b/BasiliskII/src/Unix/Solaris/which_sparc @@ -1,12 +1,17 @@ #!/bin/sh -# WHICH_SPARC +# which_sparc # # This script generates a program that tests for a SPARC processor class # Program returns: -# 0 unknown SPARC processor -# 8 SPARC V8 `compliant' processor (umul instruction is legal) -# 9 SPARC V9 `compliant' processor (popc instruction is legal) +# 0 unknown SPARC processor +# 8 SPARC V8 `compliant' processor (umul instruction is legal) +# 9 SPARC V9 `compliant' processor (popc instruction is legal) +# +# The script prints: +# "unknown SPARC architecture" +# SPARC_V8 +# SPARC_V9 # # I hope this works for other machines and OS. Tested machines are: # Sun Ultra 10 (Solaris 7), SPARC Station 5 (Solaris 2.5.1) @@ -19,7 +24,6 @@ PROG=./conftest SOURCE=./conftest.c if [ ! -x $PROG ]; then -echo "Compiling the test program" cat > $SOURCE << EOF #include #include @@ -107,8 +111,8 @@ fi $PROG case $? in 0) echo "unknown SPARC architecture";; - 8) echo "SPARC V8 compliant processor";; - 9) echo "SPARC V9 compliant processor";; + 8) echo "SPARC_V8";; + 9) echo "SPARC_V9";; esac rm -f $PROG diff --git a/BasiliskII/src/uae_cpu/gencpu.c b/BasiliskII/src/uae_cpu/gencpu.c index a4a01fbf..a9182b55 100644 --- a/BasiliskII/src/uae_cpu/gencpu.c +++ b/BasiliskII/src/uae_cpu/gencpu.c @@ -2495,7 +2495,6 @@ static void generate_one_opcode (int rp) } fprintf (stblfile, "{ op_%lx_%d, 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name); fprintf (headerfile, "extern cpuop_func op_%lx_%d;\n", opcode, postfix); -/* fprintf (headerfile, "extern unsigned long REGPARAM2 op_%lx_%d(uae_u32);\n", opcode, postfix); */ printf ("unsigned long REGPARAM2 op_%lx_%d(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name); switch (table68k[opcode].stype) { diff --git a/BasiliskII/src/uae_cpu/m68k.h b/BasiliskII/src/uae_cpu/m68k.h index 4bafa0cb..f1ff6977 100644 --- a/BasiliskII/src/uae_cpu/m68k.h +++ b/BasiliskII/src/uae_cpu/m68k.h @@ -6,7 +6,7 @@ * Copyright 1996 Bernd Schmidt */ -#ifdef __i386__ +#if defined(__i386__) && defined(X86_ASSEMBLY) struct flag_struct { unsigned int cznv; @@ -142,6 +142,651 @@ static __inline__ int cctrue(int cc) "popl %0\n\t" \ : "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc") +#elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY)) + +struct flag_struct { + unsigned char nzvc; + unsigned char x; +}; + +extern struct flag_struct regflags; + +#define SET_ZFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x04) | (((y) & 1) << 2)) +#define SET_CFLG(y) (regflags.nzvc = (regflags.nzvc & ~1) | ((y) & 1)) +#define SET_VFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x02) | (((y) & 1) << 1)) +#define SET_NFLG(y) (regflags.nzvc = (regflags.nzvc & ~0x08) | (((y) & 1) << 3)) +#define SET_XFLG(y) (regflags.x = (y)) + +#define GET_ZFLG ((regflags.nzvc >> 2) & 1) +#define GET_CFLG (regflags.nzvc & 1) +#define GET_VFLG ((regflags.nzvc >> 1) & 1) +#define GET_NFLG ((regflags.nzvc >> 3) & 1) +#define GET_XFLG (regflags.x & 1) + +#define CLEAR_CZNV (regflags.nzvc = 0) +#define COPY_CARRY (regflags.x = regflags.nzvc) + +static __inline__ int cctrue(int cc) +{ + uae_u32 nzvc = regflags.nzvc; + switch(cc){ + case 0: return 1; /* T */ + case 1: return 0; /* F */ + case 2: return (nzvc & 0x05) == 0; /* !GET_CFLG && !GET_ZFLG; HI */ + case 3: return (nzvc & 0x05) != 0; /* GET_CFLG || GET_ZFLG; LS */ + case 4: return (nzvc & 1) == 0; /* !GET_CFLG; CC */ + case 5: return (nzvc & 1) != 0; /* GET_CFLG; CS */ + case 6: return (nzvc & 0x04) == 0; /* !GET_ZFLG; NE */ + case 7: return (nzvc & 0x04) != 0; /* GET_ZFLG; EQ */ + case 8: return (nzvc & 0x02) == 0;/* !GET_VFLG; VC */ + case 9: return (nzvc & 0x02) != 0;/* GET_VFLG; VS */ + case 10:return (nzvc & 0x08) == 0; /* !GET_NFLG; PL */ + case 11:return (nzvc & 0x08) != 0; /* GET_NFLG; MI */ + case 12:return (((nzvc << 2) ^ nzvc) & 0x08) == 0; /* GET_NFLG == GET_VFLG; GE */ + case 13:return (((nzvc << 2) ^ nzvc) & 0x08) != 0;/* GET_NFLG != GET_VFLG; LT */ + case 14: + nzvc &= 0x0e; + return (((nzvc << 2) ^ nzvc) & 0x0c) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */ + case 15: + nzvc &= 0x0e; + return (((nzvc << 2) ^ nzvc) & 0x0c) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */ + } + return 0; +} + +#ifdef SPARC_V8_ASSEMBLY + +static inline uae_u32 sparc_v8_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " addcc %2, %3, %0\n" + " addx %%g0, %%g0, %%o0 ! X,C flags\n" + " stb %%o0, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " bz,a .+8\n" + " or %%o1, 0x04, %%o1 ! Z flag\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v8_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " subcc %2, %3, %0\n" + " addx %%g0, %%g0, %%o0 ! X,C flags\n" + " stb %%o0, [%1 + 1]\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline void sparc_v8_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " sll %2, 24, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " addx %%g0, %%g0, %%o0 ! C flag\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v8_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " sll %2, 16, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " addx %%g0, %%g0, %%o0 ! C flag\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bz,a .+8\n" + " or %%o0, 0x04, %%o0 ! Z flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v8_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " subcc %1, %2, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o1 ! Get the X Flag\n" + " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +#if 0 +VERY SLOW... +static inline uae_u32 sparc_v8_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " addx %%g0, %%g0, %%o1 ! X,C flags\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! V flag\n" + " ldub [%1 + 1], %%o2\n" + " subcc %%g0, %%o2, %%g0\n" + " addx %%g0, %%g0, %%o2\n" + " sll %%o2, 24, %%o2\n" + " addcc %%o0, %%o2, %%o0\n" + " srl %%o0, 24, %0\n" + " addx %%g0, %%g0, %%o2\n" + " or %%o1, %%o2, %%o1 ! update X,C flags\n" + " bl,a .+8\n" + " or %%o1, 0x08, %%o1 ! N flag\n" + " ldub [%1], %%o0 ! retreive the old NZVC flags (XXX)\n" + " bvs,a .+8\n" + " or %%o1, 0x02, %%o1 ! update V flag\n" + " and %%o0, 0x04, %%o0 ! (XXX) but keep only Z flag\n" + " and %%o1, 1, %%o2 ! keep C flag in %%o2\n" + " bnz,a .+8\n" + " or %%g0, %%g0, %%o0 ! Z flag cleared if non-zero result\n" + " stb %%o2, [%1 + 1] ! store the X flag\n" + " or %%o1, %%o0, %%o1\n" + " stb %%o1, [%1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1", "o2" + ); + return value; +} +#endif + +static inline uae_u32 sparc_v8_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o0 ! Get the X Flag\n" + " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + " ldub [%1], %%o0 ! retreive the old NZVC flags\n" + " and %%o0, 0x04, %%o0 ! but keep only Z flag\n" + " addx %%o0, %%g0, %%o0 ! X,C flags\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " bnz,a .+8\n" + " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1 + 1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +#endif /* SPARC_V8_ASSEMBLY */ + +#ifdef SPARC_V9_ASSEMBLY + +static inline uae_u32 sparc_v9_flag_add_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_add_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " addcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_add_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " addcc %2, %3, %0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_sub_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 24, %%o0\n" + " sll %3, 24, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 24, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_sub_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " sll %2, 16, %%o0\n" + " sll %3, 16, %%o1\n" + " subcc %%o0, %%o1, %%o0\n" + " rd %%ccr, %%o1\n" + " srl %%o0, 16, %0\n" + " stb %%o1, [%1]\n" + " stb %%o1, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_sub_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " subcc %2, %3, %0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1+1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +static inline void sparc_v9_flag_cmp_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " sll %2, 24, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_cmp_16(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " sll %2, 16, %%o1\n" + " subcc %%o0, %%o1, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_cmp_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + __asm__ ("\n" + " subcc %1, %2, %%g0\n" +#if 0 + " subcc %1, %2, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" +#endif +#if 0 + " subcc %1, %2, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,pt,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" +#endif + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); +} + +#if 1 +static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " subcc %%o0, %%g0, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0" + ); +} + +static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " subcc %%o0, %%g0, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0" + ); +} + +static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " subcc %1, %%g0, %%g0\n" + " rd %%ccr, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0" + ); +} +#else +static inline void sparc_v9_flag_test_8(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 24, %%o0\n" + " subcc %%o0, %%g0, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_test_16(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " sll %1, 16, %%o0\n" + " subcc %%o0, %%g0, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0", "o1" + ); +} + +static inline void sparc_v9_flag_test_32(flag_struct *flags, uae_u32 val) +{ + __asm__ ("\n" + " subcc %1, %%g0, %%o1\n" + " srl %%o1, 31, %%o0\n" + " sll %%o0, 3, %%o0\n" + " addx %%o0, %%g0, %%o0\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0\n" + " subcc %%g0, %%o1, %%g0\n" + " addx %%g0, 7, %%o1\n" + " and %%o1, 0x04, %%o1\n" + " or %%o0, %%o1, %%o0\n" + " stb %%o0, [%0]\n" + : /* no outputs */ + : "r" (flags), "r" (val) + : "cc", "o0", "o1" + ); +} +#endif + +static inline uae_u32 sparc_v9_flag_addx_8(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o1 ! Get the X Flag\n" + " subcc %%g0, %%o1, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0", "o1" + ); + return value; +} + +static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae_u32 dst) +{ + uae_u32 value; + __asm__ ("\n" + " ldub [%1 + 1], %%o0 ! Get the X Flag\n" + " subcc %%g0, %%o0, %%g0 ! Set the SPARC carry flag, if X set\n" + " addxcc %2, %3, %0\n" + " ldub [%1], %%o0 ! retreive the old NZVC flags\n" + " and %%o0, 0x04, %%o0 ! but keep only Z flag\n" + " addx %%o0, %%g0, %%o0 ! X,C flags\n" + " bl,a .+8\n" + " or %%o0, 0x08, %%o0 ! N flag\n" + " bvs,a .+8\n" + " or %%o0, 0x02, %%o0 ! V flag\n" + " bnz,a .+8\n" + " and %%o0, 0x0B, %%o0 ! Z flag cleared if result is non-zero\n" + " stb %%o0, [%1]\n" + " stb %%o0, [%1 + 1]\n" + : "=&r" (value) + : "r" (flags), "r" (dst), "r" (src) + : "cc", "o0" + ); + return value; +} + +#endif /* SPARC_V9_ASSEMBLY */ + #else struct flag_struct {