mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-27 01:29:29 +00:00
- merged some code from uae-0.8.16
This commit is contained in:
parent
6c35c2a9e8
commit
1c6d6d7cb2
|
@ -715,156 +715,10 @@ static void genflags_normal (flagtypes type, wordsizes size, char *value, char *
|
|||
|
||||
static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst)
|
||||
{
|
||||
#ifdef SPARC_V8_ASSEMBLY
|
||||
switch(type)
|
||||
{
|
||||
case flag_add:
|
||||
start_brace();
|
||||
printf("\tuae_u32 %s;\n", value);
|
||||
switch(size)
|
||||
{
|
||||
case sz_byte:
|
||||
printf("\t%s = sparc_v8_flag_add_8(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_word:
|
||||
printf("\t%s = sparc_v8_flag_add_16(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_long:
|
||||
printf("\t%s = sparc_v8_flag_add_32(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_sub:
|
||||
start_brace();
|
||||
printf("\tuae_u32 %s;\n", value);
|
||||
switch(size)
|
||||
{
|
||||
case sz_byte:
|
||||
printf("\t%s = sparc_v8_flag_sub_8(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_word:
|
||||
printf("\t%s = sparc_v8_flag_sub_16(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_long:
|
||||
printf("\t%s = sparc_v8_flag_sub_32(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_cmp:
|
||||
switch(size)
|
||||
{
|
||||
case sz_byte:
|
||||
// printf("\tsparc_v8_flag_cmp_8(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", src, dst);
|
||||
break;
|
||||
case sz_word:
|
||||
// printf("\tsparc_v8_flag_cmp_16(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", src, dst);
|
||||
break;
|
||||
case sz_long:
|
||||
#if 1
|
||||
printf("\tsparc_v8_flag_cmp_32(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", src, dst);
|
||||
return;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
// return;
|
||||
break;
|
||||
}
|
||||
#elif defined(SPARC_V9_ASSEMBLY)
|
||||
switch(type)
|
||||
{
|
||||
case flag_add:
|
||||
start_brace();
|
||||
printf("\tuae_u32 %s;\n", value);
|
||||
switch(size)
|
||||
{
|
||||
case sz_byte:
|
||||
printf("\t%s = sparc_v9_flag_add_8(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_word:
|
||||
printf("\t%s = sparc_v9_flag_add_16(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_long:
|
||||
printf("\t%s = sparc_v9_flag_add_32(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_sub:
|
||||
start_brace();
|
||||
printf("\tuae_u32 %s;\n", value);
|
||||
switch(size)
|
||||
{
|
||||
case sz_byte:
|
||||
printf("\t%s = sparc_v9_flag_sub_8(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_word:
|
||||
printf("\t%s = sparc_v9_flag_sub_16(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
case sz_long:
|
||||
printf("\t%s = sparc_v9_flag_sub_32(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", value, src, dst);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_cmp:
|
||||
switch(size)
|
||||
{
|
||||
case sz_byte:
|
||||
printf("\tsparc_v9_flag_cmp_8(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", src, dst);
|
||||
break;
|
||||
case sz_word:
|
||||
printf("\tsparc_v9_flag_cmp_16(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", src, dst);
|
||||
break;
|
||||
case sz_long:
|
||||
printf("\tsparc_v9_flag_cmp_32(®flags, (uae_u32)(%s), (uae_u32)(%s));\n", src, dst);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_logical:
|
||||
if (strcmp(value, "0") == 0) {
|
||||
printf("\tregflags.nzvc = 0x04;\n");
|
||||
} else {
|
||||
switch(size) {
|
||||
case sz_byte:
|
||||
printf("\tsparc_v9_flag_test_8(®flags, (uae_u32)(%s));\n", value);
|
||||
break;
|
||||
case sz_word:
|
||||
printf("\tsparc_v9_flag_test_16(®flags, (uae_u32)(%s));\n", value);
|
||||
break;
|
||||
case sz_long:
|
||||
printf("\tsparc_v9_flag_test_32(®flags, (uae_u32)(%s));\n", value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
#if 0
|
||||
case flag_logical_noclobber:
|
||||
printf("\t{uae_u32 old_flags = regflags.nzvc & ~0x0C;\n");
|
||||
if (strcmp(value, "0") == 0) {
|
||||
printf("\tregflags.nzvc = old_flags | 0x04;\n");
|
||||
} else {
|
||||
switch(size) {
|
||||
case sz_byte:
|
||||
printf("\tsparc_v9_flag_test_8(®flags, (uae_u32)(%s));\n", value);
|
||||
break;
|
||||
case sz_word:
|
||||
printf("\tsparc_v9_flag_test_16(®flags, (uae_u32)(%s));\n", value);
|
||||
break;
|
||||
case sz_long:
|
||||
printf("\tsparc_v9_flag_test_32(®flags, (uae_u32)(%s));\n", value);
|
||||
break;
|
||||
}
|
||||
printf("\tregflags.nzvc |= old_flags;\n");
|
||||
}
|
||||
printf("\t}\n");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
#elif defined(X86_ASSEMBLY)
|
||||
/* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have
|
||||
them in the appropriate m68k.h files and use just one copy of this
|
||||
code here. The API can be changed if necessary. */
|
||||
#ifdef OPTIMIZED_FLAGS
|
||||
switch (type) {
|
||||
case flag_add:
|
||||
case flag_sub:
|
||||
|
@ -879,232 +733,60 @@ static void genflags (flagtypes type, wordsizes size, char *value, char *src, ch
|
|||
/* At least some of those casts are fairly important! */
|
||||
switch (type) {
|
||||
case flag_logical_noclobber:
|
||||
printf ("\t{uae_u32 oldcznv = regflags.cznv & ~0xC0;\n");
|
||||
printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n");
|
||||
if (strcmp (value, "0") == 0) {
|
||||
printf ("\tregflags.cznv = olcznv | 64;\n");
|
||||
printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n");
|
||||
} else {
|
||||
switch (size) {
|
||||
case sz_byte: printf ("\tx86_flag_testb ((uae_s8)(%s));\n", value); break;
|
||||
case sz_word: printf ("\tx86_flag_testw ((uae_s16)(%s));\n", value); break;
|
||||
case sz_long: printf ("\tx86_flag_testl ((uae_s32)(%s));\n", value); break;
|
||||
case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break;
|
||||
case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break;
|
||||
case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break;
|
||||
}
|
||||
printf ("\tregflags.cznv |= oldcznv;\n");
|
||||
printf ("\tIOR_CZNV (oldcznv);\n");
|
||||
}
|
||||
printf ("\t}\n");
|
||||
return;
|
||||
case flag_logical:
|
||||
if (strcmp (value, "0") == 0) {
|
||||
printf ("\tregflags.cznv = 64;\n");
|
||||
printf ("\tSET_CZNV (FLAGVAL_Z);\n");
|
||||
} else {
|
||||
switch (size) {
|
||||
case sz_byte: printf ("\tx86_flag_testb ((uae_s8)(%s));\n", value); break;
|
||||
case sz_word: printf ("\tx86_flag_testw ((uae_s16)(%s));\n", value); break;
|
||||
case sz_long: printf ("\tx86_flag_testl ((uae_s32)(%s));\n", value); break;
|
||||
case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break;
|
||||
case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break;
|
||||
case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_add:
|
||||
switch (size) {
|
||||
case sz_byte: printf ("\tx86_flag_addb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
|
||||
case sz_word: printf ("\tx86_flag_addw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
|
||||
case sz_long: printf ("\tx86_flag_addl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
|
||||
case sz_byte: printf ("\toptflag_addb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
|
||||
case sz_word: printf ("\toptflag_addw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
|
||||
case sz_long: printf ("\toptflag_addl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_sub:
|
||||
switch (size) {
|
||||
case sz_byte: printf ("\tx86_flag_subb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
|
||||
case sz_word: printf ("\tx86_flag_subw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
|
||||
case sz_long: printf ("\tx86_flag_subl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
|
||||
case sz_byte: printf ("\toptflag_subb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
|
||||
case sz_word: printf ("\toptflag_subw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
|
||||
case sz_long: printf ("\toptflag_subl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_cmp:
|
||||
switch (size) {
|
||||
case sz_byte: printf ("\tx86_flag_cmpb ((uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
|
||||
case sz_word: printf ("\tx86_flag_cmpw ((uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
|
||||
case sz_long: printf ("\tx86_flag_cmpl ((uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
|
||||
case sz_byte: printf ("\toptflag_cmpb ((uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
|
||||
case sz_word: printf ("\toptflag_cmpw ((uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
|
||||
case sz_long: printf ("\toptflag_cmpl ((uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#elif defined(M68K_FLAG_OPT)
|
||||
/* sam: here I'm cloning what X86_ASSEMBLY does */
|
||||
#define EXT(size) (size==sz_byte?"b":(size==sz_word?"w":"l"))
|
||||
#define CAST(size) (size==sz_byte?"uae_s8":(size==sz_word?"uae_s16":"uae_s32"))
|
||||
switch (type) {
|
||||
case flag_add:
|
||||
case flag_sub:
|
||||
start_brace ();
|
||||
printf ("\tuae_u32 %s;\n", value);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case flag_logical:
|
||||
if (strcmp (value, "0") == 0) {
|
||||
printf ("\t*(uae_u16 *)®flags = 4;\n"); /* Z = 1 */
|
||||
} else {
|
||||
printf ("\tm68k_flag_tst (%s, (%s)(%s));\n",
|
||||
EXT (size), CAST (size), value);
|
||||
}
|
||||
return;
|
||||
|
||||
case flag_add:
|
||||
printf ("\t{uae_u16 ccr;\n");
|
||||
printf ("\tm68k_flag_add (%s, (%s)%s, (%s)(%s), (%s)(%s));\n",
|
||||
EXT (size), CAST (size), value, CAST (size), src, CAST (size), dst);
|
||||
printf ("\t((uae_u16*)®flags)[1]=((uae_u16*)®flags)[0]=ccr;}\n");
|
||||
return;
|
||||
|
||||
case flag_sub:
|
||||
printf ("\t{uae_u16 ccr;\n");
|
||||
printf ("\tm68k_flag_sub (%s, (%s)%s, (%s)(%s), (%s)(%s));\n",
|
||||
EXT (size), CAST (size), value, CAST (size), src, CAST (size), dst);
|
||||
printf ("\t((uae_u16*)®flags)[1]=((uae_u16*)®flags)[0]=ccr;}\n");
|
||||
return;
|
||||
|
||||
case flag_cmp:
|
||||
printf ("\tm68k_flag_cmp (%s, (%s)(%s), (%s)(%s));\n",
|
||||
EXT (size), CAST (size), src, CAST (size), dst);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#elif defined(ACORN_FLAG_OPT) && defined(__GNUC_MINOR__)
|
||||
/*
|
||||
* This is new. Might be quite buggy.
|
||||
*/
|
||||
switch (type) {
|
||||
case flag_av:
|
||||
case flag_sv:
|
||||
case flag_zn:
|
||||
case flag_addx:
|
||||
case flag_subx:
|
||||
break;
|
||||
|
||||
case flag_logical:
|
||||
if (strcmp (value, "0") == 0) {
|
||||
/* v=c=n=0 z=1 */
|
||||
printf ("\t*(ULONG*)®flags = 0x40000000;\n");
|
||||
return;
|
||||
} else {
|
||||
start_brace ();
|
||||
switch (size) {
|
||||
case sz_byte:
|
||||
printf ("\tUBYTE ccr;\n");
|
||||
printf ("\tULONG shift;\n");
|
||||
printf ("\t__asm__(\"mov %%2,%%1,lsl#24\n\ttst %%2,%%2\n\tmov %%0,r15,lsr#24\n\tbic %%0,%%0,#0x30\"\n"
|
||||
"\t: \"=r\" (ccr) : \"r\" (%s), \"r\" (shift) : \"cc\" );\n", value);
|
||||
printf ("\t*((UBYTE*)®flags+3) = ccr;\n");
|
||||
return;
|
||||
case sz_word:
|
||||
printf ("\tUBYTE ccr;\n");
|
||||
printf ("\tULONG shift;\n");
|
||||
printf ("\t__asm__(\"mov %%2,%%1,lsl#16\n\ttst %%2,%%2\n\tmov %%0,r15,lsr#24\n\tbic %%0,%%0,#0x30\"\n"
|
||||
"\t: \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", value);
|
||||
printf ("\t*((UBYTE*)®flags+3) = ccr;\n");
|
||||
return;
|
||||
case sz_long:
|
||||
printf ("\tUBYTE ccr;\n");
|
||||
printf ("\t__asm__(\"tst %%1,%%1\n\tmov %%0,r15,lsr#24\n\tbic %%0,%%0,#0x30\"\n"
|
||||
"\t: \"=r\" (ccr) : \"r\" ((LONG)%s) : \"cc\" );\n", value);
|
||||
printf ("\t*((UBYTE*)®flags+3) = ccr;\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case flag_add:
|
||||
if (strcmp (dst, "0") == 0) {
|
||||
printf ("/* Error! Hier muss Peter noch was machen !!! (ADD-Flags) */");
|
||||
} else {
|
||||
start_brace ();
|
||||
switch (size) {
|
||||
case sz_byte:
|
||||
printf ("\tULONG ccr, shift, %s;\n", value);
|
||||
printf ("\t__asm__(\"mov %%4,%%3,lsl#24\n\tadds %%0,%%4,%%2,lsl#24\n\tmov %%0,%%0,asr#24\n\tmov %%1,r15\n\torr %%1,%%1,%%1,lsr#29\"\n"
|
||||
"\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" (%s), \"r\" (%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
|
||||
printf ("\t*(ULONG*)®flags = ccr;\n");
|
||||
return;
|
||||
case sz_word:
|
||||
printf ("\tULONG ccr, shift, %s;\n", value);
|
||||
printf ("\t__asm__(\"mov %%4,%%3,lsl#16\n\tadds %%0,%%4,%%2,lsl#16\n\tmov %%0,%%0,asr#16\n\tmov %%1,r15\n\torr %%1,%%1,%%1,lsr#29\"\n"
|
||||
"\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
|
||||
printf ("\t*(ULONG*)®flags = ccr;\n");
|
||||
return;
|
||||
case sz_long:
|
||||
printf ("\tULONG ccr, %s;\n", value);
|
||||
printf ("\t__asm__(\"adds %%0,%%3,%%2\n\tmov %%1,r15\n\torr %%1,%%1,%%1,lsr#29\"\n"
|
||||
"\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((LONG)%s), \"r\" ((LONG)%s) : \"cc\" );\n", value, src, dst);
|
||||
printf ("\t*(ULONG*)®flags = ccr;\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case flag_sub:
|
||||
if (strcmp (dst, "0") == 0) {
|
||||
printf ("/* Error! Hier muss Peter noch was machen !!! (SUB-Flags) */");
|
||||
} else {
|
||||
start_brace ();
|
||||
switch (size) {
|
||||
case sz_byte:
|
||||
printf ("\tULONG ccr, shift, %s;\n", value);
|
||||
printf ("\t__asm__(\"mov %%4,%%3,lsl#24\n\tsubs %%0,%%4,%%2,lsl#24\n\tmov %%0,%%0,asr#24\n\tmov %%1,r15\n\teor %%1,%%1,#0x20000000\n\torr %%1,%%1,%%1,lsr#29\"\n"
|
||||
"\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" (%s), \"r\" (%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
|
||||
printf ("\t*(ULONG*)®flags = ccr;\n");
|
||||
return;
|
||||
case sz_word:
|
||||
printf ("\tULONG ccr, shift, %s;\n", value);
|
||||
printf ("\t__asm__(\"mov %%4,%%3,lsl#16\n\tsubs %%0,%%4,%%2,lsl#16\n\tmov %%0,%%0,asr#16\n\tmov %%1,r15\n\teor %%1,%%1,#0x20000000\n\torr %%1,%%1,%%1,lsr#29\"\n"
|
||||
"\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
|
||||
printf ("\t*(ULONG*)®flags = ccr;\n");
|
||||
return;
|
||||
case sz_long:
|
||||
printf ("\tULONG ccr, %s;\n", value);
|
||||
printf ("\t__asm__(\"subs %%0,%%3,%%2\n\tmov %%1,r15\n\teor %%1,%%1,#0x20000000\n\torr %%1,%%1,%%1,lsr#29\"\n"
|
||||
"\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((LONG)%s), \"r\" ((LONG)%s) : \"cc\" );\n", value, src, dst);
|
||||
printf ("\t*(ULONG*)®flags = ccr;\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case flag_cmp:
|
||||
if (strcmp (dst, "0") == 0) {
|
||||
printf ("/*Error! Hier muss Peter noch was machen !!! (CMP-Flags)*/");
|
||||
} else {
|
||||
start_brace ();
|
||||
switch (size) {
|
||||
case sz_byte:
|
||||
printf ("\tULONG shift, ccr;\n");
|
||||
printf ("\t__asm__(\"mov %%3,%%2,lsl#24\n\tcmp %%3,%%1,lsl#24\n\tmov %%0,r15,lsr#24\n\teor %%0,%%0,#0x20\"\n"
|
||||
"\t: \"=r\" (ccr) : \"r\" (%s), \"r\" (%s), \"r\" (shift) : \"cc\" );\n", src, dst);
|
||||
printf ("\t*((UBYTE*)®flags+3) = ccr;\n");
|
||||
return;
|
||||
case sz_word:
|
||||
printf ("\tULONG shift, ccr;\n");
|
||||
printf ("\t__asm__(\"mov %%3,%%2,lsl#16\n\tcmp %%3,%%1,lsl#16\n\tmov %%0,r15,lsr#24\n\teor %%0,%%0,#0x20\"\n"
|
||||
"\t: \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", src, dst);
|
||||
printf ("\t*((UBYTE*)®flags+3) = ccr;\n");
|
||||
return;
|
||||
case sz_long:
|
||||
printf ("\tULONG ccr;\n");
|
||||
printf ("\t__asm__(\"cmp %%2,%%1\n\tmov %%0,r15,lsr#24\n\teor %%0,%%0,#0x20\"\n"
|
||||
"\t: \"=r\" (ccr) : \"r\" ((LONG)%s), \"r\" ((LONG)%s) : \"cc\" );\n", src, dst);
|
||||
printf ("\t*((UBYTE*)®flags+3) = ccr;\n");
|
||||
/*printf ("\tprintf (\"%%08x %%08x %%08x\\n\", %s, %s, *((ULONG*)®flags));\n", src, dst); */
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
genflags_normal (type, size, value, src, dst);
|
||||
}
|
||||
|
||||
|
@ -1238,7 +920,8 @@ static void gen_opcode (unsigned long int opcode)
|
|||
printf ("\tint cflg;\n");
|
||||
printf ("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n");
|
||||
printf ("\tnewv = newv_hi + (newv_lo & 0xF);");
|
||||
printf ("\tSET_CFLG (cflg = (newv_hi & 0x1F0) > 0x90);\n");
|
||||
printf ("\tcflg = (newv_hi & 0x1F0) > 0x90;\n");
|
||||
printf ("\tSET_CFLG (cflg);\n");
|
||||
duplicate_carry ();
|
||||
printf ("\tif (cflg) newv -= 0x60;\n");
|
||||
genflags (flag_zn, curi->size, "newv", "", "");
|
||||
|
@ -1278,7 +961,8 @@ static void gen_opcode (unsigned long int opcode)
|
|||
printf ("\tint cflg;\n");
|
||||
printf ("\tif (newv_lo > 9) { newv_lo +=6; }\n");
|
||||
printf ("\tnewv = newv_hi + newv_lo;");
|
||||
printf ("\tSET_CFLG (cflg = (newv & 0x1F0) > 0x90);\n");
|
||||
printf ("\tcflg = (newv & 0x1F0) > 0x90;\n");
|
||||
printf ("\tSET_CFLG (cflg);\n");
|
||||
duplicate_carry ();
|
||||
printf ("\tif (cflg) newv += 0x60;\n");
|
||||
genflags (flag_zn, curi->size, "newv", "", "");
|
||||
|
@ -1308,7 +992,8 @@ static void gen_opcode (unsigned long int opcode)
|
|||
printf ("\tint cflg;\n");
|
||||
printf ("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n");
|
||||
printf ("\tnewv = newv_hi + (newv_lo & 0xF);");
|
||||
printf ("\tSET_CFLG (cflg = (newv_hi & 0x1F0) > 0x90);\n");
|
||||
printf ("\tcflg = cflg = (newv_hi & 0x1F0) > 0x90;\n");
|
||||
printf ("\tSET_CFLG (cflg);\n");
|
||||
duplicate_carry();
|
||||
printf ("\tif (cflg) newv -= 0x60;\n");
|
||||
genflags (flag_zn, curi->size, "newv", "", "");
|
||||
|
@ -1347,7 +1032,7 @@ static void gen_opcode (unsigned long int opcode)
|
|||
else
|
||||
printf ("\tsrc &= 31;\n");
|
||||
printf ("\tdst ^= (1 << src);\n");
|
||||
printf ("\tSET_ZFLG ((dst & (1 << src)) >> src);\n");
|
||||
printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n");
|
||||
genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
|
||||
break;
|
||||
case i_BCLR:
|
||||
|
@ -1686,7 +1371,10 @@ static void gen_opcode (unsigned long int opcode)
|
|||
printf ("\tuaecptr oldpc = m68k_getpc();\n");
|
||||
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
|
||||
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
|
||||
printf ("\tif(src == 0) { Exception(5,oldpc); goto %s; } else {\n", endlabelstr);
|
||||
sync_m68k_pc ();
|
||||
/* Clear V flag when dividing by zero - Alcatraz Odyssey demo depends
|
||||
* on this (actually, it's doing a DIVS). */
|
||||
printf ("\tif (src == 0) { SET_VFLG (0); Exception (5, oldpc); goto %s; } else {\n", endlabelstr);
|
||||
printf ("\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
|
||||
printf ("\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n");
|
||||
/* The N flag appears to be set each time there is an overflow.
|
||||
|
@ -1704,7 +1392,8 @@ static void gen_opcode (unsigned long int opcode)
|
|||
printf ("\tuaecptr oldpc = m68k_getpc();\n");
|
||||
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0);
|
||||
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0);
|
||||
printf ("\tif(src == 0) { Exception(5,oldpc); goto %s; } else {\n", endlabelstr);
|
||||
sync_m68k_pc ();
|
||||
printf ("\tif (src == 0) { SET_VFLG (0); Exception(5,oldpc); goto %s; } else {\n", endlabelstr);
|
||||
printf ("\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
|
||||
printf ("\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
|
||||
printf ("\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n");
|
||||
|
@ -1964,12 +1653,12 @@ static void gen_opcode (unsigned long int opcode)
|
|||
}
|
||||
printf ("\tcnt &= 63;\n");
|
||||
printf ("\tCLEAR_CZNV;\n");
|
||||
if (! source_is_imm1_8 (curi))
|
||||
force_range_for_rox ("cnt", curi->size);
|
||||
if (source_is_imm1_8 (curi))
|
||||
printf ("{");
|
||||
else
|
||||
else {
|
||||
force_range_for_rox ("cnt", curi->size);
|
||||
printf ("\tif (cnt > 0) {\n");
|
||||
}
|
||||
printf ("\tcnt--;\n");
|
||||
printf ("\t{\n\tuae_u32 carry;\n");
|
||||
printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1);
|
||||
|
@ -1994,12 +1683,12 @@ static void gen_opcode (unsigned long int opcode)
|
|||
}
|
||||
printf ("\tcnt &= 63;\n");
|
||||
printf ("\tCLEAR_CZNV;\n");
|
||||
if (! source_is_imm1_8 (curi))
|
||||
force_range_for_rox ("cnt", curi->size);
|
||||
if (source_is_imm1_8 (curi))
|
||||
printf ("{");
|
||||
else
|
||||
else {
|
||||
force_range_for_rox ("cnt", curi->size);
|
||||
printf ("\tif (cnt > 0) {\n");
|
||||
}
|
||||
printf ("\tcnt--;\n");
|
||||
printf ("\t{\n\tuae_u32 carry;\n");
|
||||
printf ("\tuae_u32 hival = (val << 1) | GET_XFLG;\n");
|
||||
|
@ -2155,14 +1844,14 @@ static void gen_opcode (unsigned long int opcode)
|
|||
start_brace ();
|
||||
printf ("\tint regno = (src >> 12) & 15;\n");
|
||||
printf ("\tuae_u32 *regp = regs.regs + regno;\n");
|
||||
printf ("\tm68k_movec2(src & 0xFFF, regp);\n");
|
||||
printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
|
||||
break;
|
||||
case i_MOVE2C:
|
||||
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
|
||||
start_brace ();
|
||||
printf ("\tint regno = (src >> 12) & 15;\n");
|
||||
printf ("\tuae_u32 *regp = regs.regs + regno;\n");
|
||||
printf ("\tm68k_move2c(src & 0xFFF, regp);\n");
|
||||
printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
|
||||
break;
|
||||
case i_CAS:
|
||||
{
|
||||
|
|
|
@ -6,27 +6,41 @@
|
|||
* Copyright 1996 Bernd Schmidt
|
||||
*/
|
||||
|
||||
#ifndef M68K_FLAGS_H
|
||||
#define M68K_FLAGS_H
|
||||
|
||||
#ifdef OPTIMIZED_FLAGS
|
||||
|
||||
#if defined(__i386__) && defined(X86_ASSEMBLY)
|
||||
|
||||
#ifndef SAHF_SETO_PROFITABLE
|
||||
|
||||
struct flag_struct {
|
||||
unsigned int cznv;
|
||||
unsigned int x;
|
||||
uae_u32 cznv;
|
||||
uae_u32 x;
|
||||
};
|
||||
|
||||
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x40) | (((y) & 1) << 6))
|
||||
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~1) | ((y) & 1))
|
||||
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x800) | (((y) & 1) << 11))
|
||||
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x80) | (((y) & 1) << 7))
|
||||
#define SET_XFLG(y) (regflags.x = (y))
|
||||
#define FLAGVAL_Z 0x40
|
||||
#define FLAGVAL_N 0x80
|
||||
|
||||
#define GET_ZFLG ((regflags.cznv >> 6) & 1)
|
||||
#define GET_CFLG (regflags.cznv & 1)
|
||||
#define GET_VFLG ((regflags.cznv >> 11) & 1)
|
||||
#define GET_NFLG ((regflags.cznv >> 7) & 1)
|
||||
#define GET_XFLG (regflags.x & 1)
|
||||
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x40) | (((y) & 1) << 6))
|
||||
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~1) | ((y) & 1))
|
||||
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x800) | (((y) & 1) << 11))
|
||||
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x80) | (((y) & 1) << 7))
|
||||
#define SET_XFLG(y) (regflags.x = (y))
|
||||
|
||||
#define CLEAR_CZNV (regflags.cznv = 0)
|
||||
#define COPY_CARRY (regflags.x = regflags.cznv)
|
||||
#define GET_ZFLG ((regflags.cznv >> 6) & 1)
|
||||
#define GET_CFLG (regflags.cznv & 1)
|
||||
#define GET_VFLG ((regflags.cznv >> 11) & 1)
|
||||
#define GET_NFLG ((regflags.cznv >> 7) & 1)
|
||||
#define GET_XFLG (regflags.x & 1)
|
||||
|
||||
#define CLEAR_CZNV (regflags.cznv = 0)
|
||||
#define GET_CZNV (regflags.cznv)
|
||||
#define IOR_CZNV(X) (regflags.cznv |= (X))
|
||||
#define SET_CZNV(X) (regflags.cznv = (X))
|
||||
|
||||
#define COPY_CARRY (regflags.x = regflags.cznv)
|
||||
|
||||
extern struct flag_struct regflags __asm__ ("regflags");
|
||||
|
||||
|
@ -58,25 +72,25 @@ static __inline__ int cctrue(int cc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define x86_flag_testl(v) \
|
||||
__asm__ __volatile__ ("testl %1,%1\n\t" \
|
||||
#define optflag_testl(v) \
|
||||
__asm__ __volatile__ ("andl %1,%1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
: "=r" (regflags.cznv) : "r" (v) : "cc")
|
||||
|
||||
#define x86_flag_testw(v) \
|
||||
__asm__ __volatile__ ("testw %w1,%w1\n\t" \
|
||||
#define optflag_testw(v) \
|
||||
__asm__ __volatile__ ("andw %w1,%w1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
: "=r" (regflags.cznv) : "r" (v) : "cc")
|
||||
|
||||
#define x86_flag_testb(v) \
|
||||
__asm__ __volatile__ ("testb %b1,%b1\n\t" \
|
||||
#define optflag_testb(v) \
|
||||
__asm__ __volatile__ ("andb %b1,%b1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
: "=r" (regflags.cznv) : "q" (v) : "cc")
|
||||
|
||||
#define x86_flag_addl(v, s, d) do { \
|
||||
#define optflag_addl(v, s, d) do { \
|
||||
__asm__ __volatile__ ("addl %k2,%k1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
|
@ -84,7 +98,7 @@ static __inline__ int cctrue(int cc)
|
|||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define x86_flag_addw(v, s, d) do { \
|
||||
#define optflag_addw(v, s, d) do { \
|
||||
__asm__ __volatile__ ("addw %w2,%w1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
|
@ -92,7 +106,7 @@ static __inline__ int cctrue(int cc)
|
|||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define x86_flag_addb(v, s, d) do { \
|
||||
#define optflag_addb(v, s, d) do { \
|
||||
__asm__ __volatile__ ("addb %b2,%b1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
|
@ -100,7 +114,7 @@ static __inline__ int cctrue(int cc)
|
|||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define x86_flag_subl(v, s, d) do { \
|
||||
#define optflag_subl(v, s, d) do { \
|
||||
__asm__ __volatile__ ("subl %k2,%k1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
|
@ -108,7 +122,7 @@ static __inline__ int cctrue(int cc)
|
|||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define x86_flag_subw(v, s, d) do { \
|
||||
#define optflag_subw(v, s, d) do { \
|
||||
__asm__ __volatile__ ("subw %w2,%w1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
|
@ -116,7 +130,7 @@ static __inline__ int cctrue(int cc)
|
|||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define x86_flag_subb(v, s, d) do { \
|
||||
#define optflag_subb(v, s, d) do { \
|
||||
__asm__ __volatile__ ("subb %b2,%b1\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
|
@ -124,24 +138,196 @@ static __inline__ int cctrue(int cc)
|
|||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define x86_flag_cmpl(s, d) \
|
||||
#define optflag_cmpl(s, d) \
|
||||
__asm__ __volatile__ ("cmpl %k1,%k2\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
: "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
|
||||
|
||||
#define x86_flag_cmpw(s, d) \
|
||||
#define optflag_cmpw(s, d) \
|
||||
__asm__ __volatile__ ("cmpw %w1,%w2\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
: "=r" (regflags.cznv) : "rmi" (s), "r" (d) : "cc")
|
||||
|
||||
#define x86_flag_cmpb(s, d) \
|
||||
#define optflag_cmpb(s, d) \
|
||||
__asm__ __volatile__ ("cmpb %b1,%b2\n\t" \
|
||||
"pushfl\n\t" \
|
||||
"popl %0\n\t" \
|
||||
: "=r" (regflags.cznv) : "qmi" (s), "q" (d) : "cc")
|
||||
|
||||
#else
|
||||
|
||||
struct flag_struct {
|
||||
uae_u32 cznv;
|
||||
uae_u32 x;
|
||||
};
|
||||
|
||||
#define FLAGVAL_Z 0x4000
|
||||
#define FLAGVAL_N 0x8000
|
||||
|
||||
#define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~0x4000) | (((y) & 1) << 14))
|
||||
#define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~0x100) | (((y) & 1) << 8))
|
||||
#define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~0x1) | (((y) & 1)))
|
||||
#define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~0x8000) | (((y) & 1) << 15))
|
||||
#define SET_XFLG(y) (regflags.x = (y))
|
||||
|
||||
#define GET_ZFLG ((regflags.cznv >> 14) & 1)
|
||||
#define GET_CFLG ((regflags.cznv >> 8) & 1)
|
||||
#define GET_VFLG ((regflags.cznv >> 0) & 1)
|
||||
#define GET_NFLG ((regflags.cznv >> 15) & 1)
|
||||
#define GET_XFLG (regflags.x & 1)
|
||||
|
||||
#define CLEAR_CZNV (regflags.cznv = 0)
|
||||
#define GET_CZNV (regflags.cznv)
|
||||
#define IOR_CZNV(X) (regflags.cznv |= (X))
|
||||
#define SET_CZNV(X) (regflags.cznv = (X))
|
||||
|
||||
#define COPY_CARRY (regflags.x = (regflags.cznv)>>8)
|
||||
|
||||
extern struct flag_struct regflags __asm__ ("regflags");
|
||||
|
||||
static __inline__ int cctrue(int cc)
|
||||
{
|
||||
uae_u32 cznv = regflags.cznv;
|
||||
switch(cc){
|
||||
case 0: return 1; /* T */
|
||||
case 1: return 0; /* F */
|
||||
case 2: return (cznv & 0x4100) == 0; /* !GET_CFLG && !GET_ZFLG; HI */
|
||||
case 3: return (cznv & 0x4100) != 0; /* GET_CFLG || GET_ZFLG; LS */
|
||||
case 4: return (cznv & 0x100) == 0; /* !GET_CFLG; CC */
|
||||
case 5: return (cznv & 0x100) != 0; /* GET_CFLG; CS */
|
||||
case 6: return (cznv & 0x4000) == 0; /* !GET_ZFLG; NE */
|
||||
case 7: return (cznv & 0x4000) != 0; /* GET_ZFLG; EQ */
|
||||
case 8: return (cznv & 0x01) == 0; /* !GET_VFLG; VC */
|
||||
case 9: return (cznv & 0x01) != 0; /* GET_VFLG; VS */
|
||||
case 10:return (cznv & 0x8000) == 0; /* !GET_NFLG; PL */
|
||||
case 11:return (cznv & 0x8000) != 0; /* GET_NFLG; MI */
|
||||
case 12:return (((cznv << 15) ^ cznv) & 0x8000) == 0; /* GET_NFLG == GET_VFLG; GE */
|
||||
case 13:return (((cznv << 15) ^ cznv) & 0x8000) != 0;/* GET_NFLG != GET_VFLG; LT */
|
||||
case 14:
|
||||
cznv &= 0xc001;
|
||||
return (((cznv << 15) ^ cznv) & 0xc000) == 0; /* !GET_ZFLG && (GET_NFLG == GET_VFLG); GT */
|
||||
case 15:
|
||||
cznv &= 0xc001;
|
||||
return (((cznv << 15) ^ cznv) & 0xc000) != 0; /* GET_ZFLG || (GET_NFLG != GET_VFLG); LE */
|
||||
}
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is there any way to do this without declaring *all* memory clobbered?
|
||||
I.e. any way to tell gcc that some byte-sized value is in %al? */
|
||||
#define optflag_testl(v) \
|
||||
__asm__ __volatile__ ("andl %0,%0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: : "r" (v) : "%eax","cc","memory")
|
||||
|
||||
#define optflag_testw(v) \
|
||||
__asm__ __volatile__ ("andw %w0,%w0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: : "r" (v) : "%eax","cc","memory")
|
||||
|
||||
#define optflag_testb(v) \
|
||||
__asm__ __volatile__ ("andb %b0,%b0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: : "q" (v) : "%eax","cc","memory")
|
||||
|
||||
#define optflag_addl(v, s, d) do { \
|
||||
__asm__ __volatile__ ("addl %k1,%k0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
|
||||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_addw(v, s, d) do { \
|
||||
__asm__ __volatile__ ("addw %w1,%w0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
|
||||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_addb(v, s, d) do { \
|
||||
__asm__ __volatile__ ("addb %b1,%b0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \
|
||||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_subl(v, s, d) do { \
|
||||
__asm__ __volatile__ ("subl %k1,%k0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
|
||||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_subw(v, s, d) do { \
|
||||
__asm__ __volatile__ ("subw %w1,%w0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: "=r" (v) : "rmi" (s), "0" (d) : "%eax","cc","memory"); \
|
||||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_subb(v, s, d) do { \
|
||||
__asm__ __volatile__ ("subb %b1,%b0\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: "=q" (v) : "qmi" (s), "0" (d) : "%eax","cc","memory"); \
|
||||
COPY_CARRY; \
|
||||
} while (0)
|
||||
|
||||
#define optflag_cmpl(s, d) \
|
||||
__asm__ __volatile__ ("cmpl %k0,%k1\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: : "rmi" (s), "r" (d) : "%eax","cc","memory")
|
||||
|
||||
#define optflag_cmpw(s, d) \
|
||||
__asm__ __volatile__ ("cmpw %w0,%w1\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: : "rmi" (s), "r" (d) : "%eax","cc","memory");
|
||||
|
||||
#define optflag_cmpb(s, d) \
|
||||
__asm__ __volatile__ ("cmpb %b0,%b1\n\t" \
|
||||
"lahf\n\t" \
|
||||
"seto %%al\n\t" \
|
||||
"movb %%al,regflags\n\t" \
|
||||
"movb %%ah,regflags+1\n\t" \
|
||||
: : "qmi" (s), "q" (d) : "%eax","cc","memory")
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined(__sparc__) && (defined(SPARC_V8_ASSEMBLY) || defined(SPARC_V9_ASSEMBLY))
|
||||
|
||||
struct flag_struct {
|
||||
|
@ -151,19 +337,26 @@ struct flag_struct {
|
|||
|
||||
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 FLAGVAL_Z 0x04
|
||||
#define FLAGVAL_N 0x08
|
||||
|
||||
#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 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 GET_CZNV (reflags.nzvc)
|
||||
#define IOR_CZNV(X) (refglags.nzvc |= (X))
|
||||
#define SET_CZNV(X) (regflags.nzvc = (X))
|
||||
|
||||
#define CLEAR_CZNV (regflags.nzvc = 0)
|
||||
#define COPY_CARRY (regflags.x = regflags.nzvc)
|
||||
|
||||
static __inline__ int cctrue(int cc)
|
||||
|
@ -787,6 +980,8 @@ static inline uae_u32 sparc_v9_flag_addx_32(flag_struct *flags, uae_u32 src, uae
|
|||
|
||||
#endif /* SPARC_V9_ASSEMBLY */
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
struct flag_struct {
|
||||
|
@ -805,6 +1000,27 @@ extern struct flag_struct regflags;
|
|||
#define VFLG (regflags.v)
|
||||
#define XFLG (regflags.x)
|
||||
|
||||
#define SET_CFLG(x) (CFLG = (x))
|
||||
#define SET_NFLG(x) (NFLG = (x))
|
||||
#define SET_VFLG(x) (VFLG = (x))
|
||||
#define SET_ZFLG(x) (ZFLG = (x))
|
||||
#define SET_XFLG(x) (XFLG = (x))
|
||||
|
||||
#define GET_CFLG CFLG
|
||||
#define GET_NFLG NFLG
|
||||
#define GET_VFLG VFLG
|
||||
#define GET_ZFLG ZFLG
|
||||
#define GET_XFLG XFLG
|
||||
|
||||
#define CLEAR_CZNV do { \
|
||||
SET_CFLG (0); \
|
||||
SET_ZFLG (0); \
|
||||
SET_NFLG (0); \
|
||||
SET_VFLG (0); \
|
||||
} while (0)
|
||||
|
||||
#define COPY_CARRY (SET_XFLG (GET_CFLG))
|
||||
|
||||
static __inline__ int cctrue(const int cc)
|
||||
{
|
||||
switch(cc){
|
||||
|
@ -828,4 +1044,6 @@ static __inline__ int cctrue(const int cc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* OPTIMIZED_FLAGS */
|
||||
|
||||
#endif /* M68K_FLAGS_H */
|
||||
|
|
|
@ -658,6 +658,7 @@ void MakeFromSR (void)
|
|||
|
||||
void Exception(int nr, uaecptr oldpc)
|
||||
{
|
||||
uae_u32 currpc = m68k_getpc ();
|
||||
MakeSR();
|
||||
if (!regs.s) {
|
||||
regs.usp = m68k_areg(regs, 7);
|
||||
|
@ -686,7 +687,7 @@ void Exception(int nr, uaecptr oldpc)
|
|||
m68k_areg(regs, 7) -= 2;
|
||||
put_word (m68k_areg(regs, 7), nr * 4);
|
||||
m68k_areg(regs, 7) -= 4;
|
||||
put_long (m68k_areg(regs, 7), m68k_getpc ());
|
||||
put_long (m68k_areg(regs, 7), currpc);
|
||||
m68k_areg(regs, 7) -= 2;
|
||||
put_word (m68k_areg(regs, 7), regs.sr);
|
||||
regs.sr |= (1 << 13);
|
||||
|
@ -712,7 +713,7 @@ void Exception(int nr, uaecptr oldpc)
|
|||
}
|
||||
}
|
||||
m68k_areg(regs, 7) -= 4;
|
||||
put_long (m68k_areg(regs, 7), m68k_getpc ());
|
||||
put_long (m68k_areg(regs, 7), currpc);
|
||||
kludge_me_do:
|
||||
m68k_areg(regs, 7) -= 2;
|
||||
put_word (m68k_areg(regs, 7), regs.sr);
|
||||
|
@ -735,15 +736,19 @@ static void Interrupt(int nr)
|
|||
|
||||
static int caar, cacr, tc, itt0, itt1, dtt0, dtt1;
|
||||
|
||||
void m68k_move2c (int regno, uae_u32 *regp)
|
||||
int m68k_move2c (int regno, uae_u32 *regp)
|
||||
{
|
||||
if (CPUType == 1 && (regno & 0x7FF) > 1)
|
||||
if ((CPUType == 1 && (regno & 0x7FF) > 1)
|
||||
|| (CPUType < 4 && (regno & 0x7FF) > 2)
|
||||
|| (CPUType == 4 && regno == 0x802))
|
||||
{
|
||||
op_illg (0x4E7B);
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
switch (regno) {
|
||||
case 0: regs.sfc = *regp & 7; break;
|
||||
case 1: regs.dfc = *regp & 7; break;
|
||||
case 2: cacr = *regp & 0x3; break; /* ignore C and CE */
|
||||
case 2: cacr = *regp & (CPUType < 4 ? 0x3 : 0x80008000); break;
|
||||
case 3: tc = *regp & 0xc000; break;
|
||||
case 4: itt0 = *regp & 0xffffe364; break;
|
||||
case 5: itt1 = *regp & 0xffffe364; break;
|
||||
|
@ -756,15 +761,21 @@ void m68k_move2c (int regno, uae_u32 *regp)
|
|||
case 0x804: regs.isp = *regp; if (regs.m == 0) m68k_areg(regs, 7) = regs.isp; break;
|
||||
default:
|
||||
op_illg (0x4E7B);
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void m68k_movec2 (int regno, uae_u32 *regp)
|
||||
int m68k_movec2 (int regno, uae_u32 *regp)
|
||||
{
|
||||
if (CPUType == 1 && (regno & 0x7FF) > 1)
|
||||
if ((CPUType == 1 && (regno & 0x7FF) > 1)
|
||||
|| (CPUType < 4 && (regno & 0x7FF) > 2)
|
||||
|| (CPUType == 4 && regno == 0x802))
|
||||
{
|
||||
op_illg (0x4E7A);
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
switch (regno) {
|
||||
case 0: *regp = regs.sfc; break;
|
||||
case 1: *regp = regs.dfc; break;
|
||||
|
@ -781,8 +792,10 @@ void m68k_movec2 (int regno, uae_u32 *regp)
|
|||
case 0x804: *regp = regs.m == 0 ? m68k_areg(regs, 7) : regs.isp; break;
|
||||
default:
|
||||
op_illg (0x4E7A);
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
|
@ -1072,7 +1085,7 @@ void REGPARAM2 op_illg (uae_u32 opcode)
|
|||
struct M68kRegisters r;
|
||||
int i;
|
||||
|
||||
// Return from Execute68k()?
|
||||
// Return from Exectue68k()?
|
||||
if (opcode == M68K_EXEC_RETURN) {
|
||||
regs.spcflags |= SPCFLAG_BRK;
|
||||
quit_program = 1;
|
||||
|
@ -1131,7 +1144,7 @@ static uaecptr last_trace_ad = 0;
|
|||
|
||||
static void do_trace (void)
|
||||
{
|
||||
if (regs.t0) {
|
||||
if (regs.t0 && CPUType >= 2) {
|
||||
uae_u16 opcode;
|
||||
/* should also include TRAP, CHK, SR modification FPcc */
|
||||
/* probably never used so why bother */
|
||||
|
|
|
@ -21,30 +21,6 @@
|
|||
#define SPCFLAG_EXEC 1024
|
||||
#define SPCFLAG_MODE_CHANGE 8192
|
||||
|
||||
#ifndef SET_CFLG
|
||||
|
||||
#define SET_CFLG(x) (CFLG = (x))
|
||||
#define SET_NFLG(x) (NFLG = (x))
|
||||
#define SET_VFLG(x) (VFLG = (x))
|
||||
#define SET_ZFLG(x) (ZFLG = (x))
|
||||
#define SET_XFLG(x) (XFLG = (x))
|
||||
|
||||
#define GET_CFLG CFLG
|
||||
#define GET_NFLG NFLG
|
||||
#define GET_VFLG VFLG
|
||||
#define GET_ZFLG ZFLG
|
||||
#define GET_XFLG XFLG
|
||||
|
||||
#define CLEAR_CZNV do { \
|
||||
SET_CFLG (0); \
|
||||
SET_ZFLG (0); \
|
||||
SET_NFLG (0); \
|
||||
SET_VFLG (0); \
|
||||
} while (0)
|
||||
|
||||
#define COPY_CARRY (SET_XFLG (GET_CFLG))
|
||||
#endif
|
||||
|
||||
extern int areg_byteinc[];
|
||||
extern int imm8_table[];
|
||||
|
||||
|
@ -259,8 +235,8 @@ extern void MakeSR (void);
|
|||
extern void MakeFromSR (void);
|
||||
extern void Exception (int, uaecptr);
|
||||
extern void dump_counts (void);
|
||||
extern void m68k_move2c (int, uae_u32 *);
|
||||
extern void m68k_movec2 (int, uae_u32 *);
|
||||
extern int m68k_move2c (int, uae_u32 *);
|
||||
extern int m68k_movec2 (int, uae_u32 *);
|
||||
extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
|
||||
extern void m68k_mull (uae_u32, uae_u32, uae_u16);
|
||||
extern void init_m68k (void);
|
||||
|
|
Loading…
Reference in New Issue
Block a user