diff --git a/r4300/cop1_d.c b/r4300/cop1_d.c index 3f9e3b9c..36750275 100755 --- a/r4300/cop1_d.c +++ b/r4300/cop1_d.c @@ -120,7 +120,7 @@ void ROUND_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); PC++; } @@ -131,7 +131,7 @@ void TRUNC_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_trunc(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); PC++; } @@ -142,7 +142,7 @@ void CEIL_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_ceil(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); PC++; } @@ -153,7 +153,7 @@ void FLOOR_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_floor(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); PC++; } @@ -164,7 +164,7 @@ void ROUND_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_simple[cffd]); set_rounding(); PC++; } @@ -175,7 +175,7 @@ void TRUNC_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_trunc(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_simple[cffd]); set_rounding(); PC++; } @@ -186,7 +186,7 @@ void CEIL_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_ceil(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_simple[cffd]); set_rounding(); PC++; } @@ -197,7 +197,7 @@ void FLOOR_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_floor(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_simple[cffd]); set_rounding(); PC++; } @@ -222,7 +222,7 @@ void CVT_W_D() if (check_cop1_unusable()) return; CHECK_INPUT(*reg_cop1_double[cffs]); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_simple[cffd]); PC++; } @@ -231,7 +231,7 @@ void CVT_L_D() if (check_cop1_unusable()) return; CHECK_INPUT(*reg_cop1_double[cffs]); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); PC++; } diff --git a/r4300/cop1_s.c b/r4300/cop1_s.c index dd03e775..7ad94e2c 100755 --- a/r4300/cop1_s.c +++ b/r4300/cop1_s.c @@ -120,7 +120,7 @@ void ROUND_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -132,7 +132,7 @@ void TRUNC_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_trunc(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -144,7 +144,7 @@ void CEIL_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_ceil(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -156,7 +156,7 @@ void FLOOR_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_floor(); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -168,7 +168,7 @@ void ROUND_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -180,7 +180,7 @@ void TRUNC_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_trunc(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -192,7 +192,7 @@ void CEIL_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_ceil(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -204,7 +204,7 @@ void FLOOR_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_floor(); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); PC++; @@ -223,7 +223,7 @@ void CVT_W_S() if (check_cop1_unusable()) return; CHECK_INPUT(*reg_cop1_simple[cffs]); clear_x87_exceptions(); - *((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); CHECK_CONVERT_EXCEPTIONS(); PC++; } @@ -233,7 +233,7 @@ void CVT_L_S() if (check_cop1_unusable()) return; CHECK_INPUT(*reg_cop1_simple[cffs]); clear_x87_exceptions(); - *((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); CHECK_CONVERT_EXCEPTIONS(); PC++; } diff --git a/r4300/macros.h b/r4300/macros.h index 6d5c479a..4dd712c0 100755 --- a/r4300/macros.h +++ b/r4300/macros.h @@ -117,7 +117,12 @@ stop=1; \ #define read_x87_status_word() __asm { fstsw x87_status_word } //asm converter that respects rounding modes -#define FLOAT_CONVERT(input_width, output_width) __asm {mov eax, src __asm fld input_width ptr [eax] __asm mov ebx, dest __asm fistp output_width ptr[ebx]} +#define FLOAT_CONVERT(input_width, output_width) __asm { \ + __asm mov eax, src \ + __asm fld input_width ptr [eax] \ + __asm mov eax, dest \ + __asm fistp output_width ptr [eax] \ +} #else #define set_rounding() __asm__ __volatile__("fldcw %0" : : "m" (rounding_mode) : "memory") #define set_trunc() __asm__ __volatile__("fldcw %0" : : "m" (trunc_mode) : "memory") @@ -127,8 +132,12 @@ stop=1; \ #define clear_x87_exceptions() __asm__ __volatile__("fclex" : : : "memory") #define read_x87_status_word() __asm__ __volatile__("fstsw %0" : "=m" (x87_status_word) : : "memory") -//gcc version -#define FLOAT_CONVERT(input_width, output_width) __asm__ __volatile__(???) +#define FLOAT_CONVERT(input_width, output_width) __asm__ __volatile__( \ + ".intel_syntax\n\t" \ + "fld " #input_width " ptr [%V0]\n\t" \ + "fistp " #output_width " ptr [%V1]\n\t" \ + ".att_syntax" \ + : : "r" (src), "r" (dest) : "memory") #endif // _MSC_VER #else #define set_rounding() ((void) 0) @@ -137,20 +146,12 @@ stop=1; \ #define set_ceil() ((void) 0) #define set_floor() ((void) 0) #define clear_x87_exceptions() ((void) 0) +#define read_x87_status_word() +#define FLOAT_CONVERT(input_width, output_width) *dest = *src #endif -//this should work cross platrofm (although size types are suspicious) -//float #define FLOAT_CONVERT_L_S(s,d) { float* src = s; long long* dest = (long long*)d; FLOAT_CONVERT(dword, qword); } #define FLOAT_CONVERT_W_S(s,d) { float* src = s; long* dest = (long*)d; FLOAT_CONVERT(dword, dword); } -//round,trunc,floor,ceil -#define FLOAT_L_S(s,d) { float* src = s; long long* dest = (long long*)d; FLOAT_CONVERT(dword, qword)} -#define FLOAT_W_S(s,d) { float* src = s; long* dest = (long*)d; FLOAT_CONVERT(dword, dword)} -//double #define FLOAT_CONVERT_L_D(s,d) { double* src = s; long long* dest = (long long*)d; FLOAT_CONVERT(qword, dword); } #define FLOAT_CONVERT_W_D(s,d) { double* src = s; long* dest = (long*)d; FLOAT_CONVERT(qword, qword); } -//double round,trunc,floor,ceil -#define FLOAT_L_D(s,d) { double* src = s; long long* dest = (long long*)d; FLOAT_CONVERT(qword, dword)} -#define FLOAT_W_D(s,d) { double* src = s; long* dest = (long*)d; FLOAT_CONVERT(qword, qword)} - #endif diff --git a/r4300/pure_interp.c b/r4300/pure_interp.c index 65eee42c..c2f851e6 100755 --- a/r4300/pure_interp.c +++ b/r4300/pure_interp.c @@ -1361,8 +1361,7 @@ static void ROUND_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; - FLOAT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1373,8 +1372,7 @@ static void TRUNC_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_trunc(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; - FLOAT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1385,8 +1383,7 @@ static void CEIL_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_ceil(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; - FLOAT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1397,8 +1394,7 @@ static void FLOOR_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_floor(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; - FLOAT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1409,8 +1405,7 @@ static void ROUND_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; - FLOAT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1421,8 +1416,7 @@ static void TRUNC_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_trunc(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; - FLOAT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1433,8 +1427,7 @@ static void CEIL_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_ceil(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; - FLOAT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1445,8 +1438,7 @@ static void FLOOR_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_floor(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; - FLOAT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1464,7 +1456,6 @@ static void CVT_W_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_rounding(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_simple[cffs]; FLOAT_CONVERT_W_S(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1475,7 +1466,6 @@ static void CVT_L_S() CHECK_INPUT(*reg_cop1_simple[cffs]); set_rounding(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_simple[cffs]; FLOAT_CONVERT_L_S(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1748,8 +1738,7 @@ static void ROUND_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; - FLOAT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1760,8 +1749,7 @@ static void TRUNC_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_trunc(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; - FLOAT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); CHECK_CONVERT_EXCEPTIONS(); set_rounding(); interp_addr+=4; @@ -1772,8 +1760,7 @@ static void CEIL_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_ceil(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; - FLOAT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1784,8 +1771,7 @@ static void FLOOR_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_floor(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; - FLOAT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1796,8 +1782,7 @@ static void ROUND_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_round_to_nearest(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; - FLOAT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1808,8 +1793,7 @@ static void TRUNC_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_trunc(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; - FLOAT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1820,8 +1804,7 @@ static void CEIL_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_ceil(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; - FLOAT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1832,8 +1815,7 @@ static void FLOOR_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_floor(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; - FLOAT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); + FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); set_rounding(); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1858,7 +1840,6 @@ static void CVT_W_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_rounding(); clear_x87_exceptions(); - //*((long*)reg_cop1_simple[cffd]) = *reg_cop1_double[cffs]; FLOAT_CONVERT_W_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4; @@ -1869,7 +1850,6 @@ static void CVT_L_D() CHECK_INPUT(*reg_cop1_double[cffs]); set_rounding(); clear_x87_exceptions(); - //*((long long*)(reg_cop1_double[cffd])) = *reg_cop1_double[cffs]; FLOAT_CONVERT_L_D(reg_cop1_double[cffs], reg_cop1_double[cffd]); CHECK_CONVERT_EXCEPTIONS(); interp_addr+=4;