mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-11 10:30:09 +00:00
- integrated SPARC assembly optimizations
This commit is contained in:
parent
1bba7c409c
commit
f04292fd21
@ -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 */
|
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# WHICH_SPARC
|
# which_sparc
|
||||||
#
|
#
|
||||||
# This script generates a program that tests for a SPARC processor class
|
# This script generates a program that tests for a SPARC processor class
|
||||||
# Program returns:
|
# Program returns:
|
||||||
@ -8,6 +8,11 @@
|
|||||||
# 8 SPARC V8 `compliant' processor (umul instruction is legal)
|
# 8 SPARC V8 `compliant' processor (umul instruction is legal)
|
||||||
# 9 SPARC V9 `compliant' processor (popc 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:
|
# I hope this works for other machines and OS. Tested machines are:
|
||||||
# Sun Ultra 10 (Solaris 7), SPARC Station 5 (Solaris 2.5.1)
|
# Sun Ultra 10 (Solaris 7), SPARC Station 5 (Solaris 2.5.1)
|
||||||
#
|
#
|
||||||
@ -19,7 +24,6 @@ PROG=./conftest
|
|||||||
SOURCE=./conftest.c
|
SOURCE=./conftest.c
|
||||||
|
|
||||||
if [ ! -x $PROG ]; then
|
if [ ! -x $PROG ]; then
|
||||||
echo "Compiling the test program"
|
|
||||||
cat > $SOURCE << EOF
|
cat > $SOURCE << EOF
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -107,8 +111,8 @@ fi
|
|||||||
$PROG
|
$PROG
|
||||||
case $? in
|
case $? in
|
||||||
0) echo "unknown SPARC architecture";;
|
0) echo "unknown SPARC architecture";;
|
||||||
8) echo "SPARC V8 compliant processor";;
|
8) echo "SPARC_V8";;
|
||||||
9) echo "SPARC V9 compliant processor";;
|
9) echo "SPARC_V9";;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
rm -f $PROG
|
rm -f $PROG
|
||||||
|
@ -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 (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 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);
|
printf ("unsigned long REGPARAM2 op_%lx_%d(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
|
||||||
|
|
||||||
switch (table68k[opcode].stype) {
|
switch (table68k[opcode].stype) {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Copyright 1996 Bernd Schmidt
|
* Copyright 1996 Bernd Schmidt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __i386__
|
#if defined(__i386__) && defined(X86_ASSEMBLY)
|
||||||
|
|
||||||
struct flag_struct {
|
struct flag_struct {
|
||||||
unsigned int cznv;
|
unsigned int cznv;
|
||||||
@ -142,6 +142,651 @@ static __inline__ int cctrue(int cc)
|
|||||||
"popl %0\n\t" \
|
"popl %0\n\t" \
|
||||||
: "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
|
: "=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
|
#else
|
||||||
|
|
||||||
struct flag_struct {
|
struct flag_struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user