864 |
|
|
865 |
#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void) |
#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void) |
866 |
|
|
867 |
#define VFP_BINOP(name, op) \ |
#define VFP_BINOP(name) \ |
868 |
VFP_OP(name, s) \ |
VFP_OP(name, s) \ |
869 |
{ \ |
{ \ |
870 |
FT0s = FT0s op FT1s; \ |
FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status); \ |
871 |
} \ |
} \ |
872 |
VFP_OP(name, d) \ |
VFP_OP(name, d) \ |
873 |
{ \ |
{ \ |
874 |
FT0d = FT0d op FT1d; \ |
FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status); \ |
875 |
} |
} |
876 |
VFP_BINOP(add, +) |
VFP_BINOP(add) |
877 |
VFP_BINOP(sub, -) |
VFP_BINOP(sub) |
878 |
VFP_BINOP(mul, *) |
VFP_BINOP(mul) |
879 |
VFP_BINOP(div, /) |
VFP_BINOP(div) |
880 |
#undef VFP_BINOP |
#undef VFP_BINOP |
881 |
|
|
882 |
#define VFP_HELPER(name) \ |
#define VFP_HELPER(name) \ |
898 |
without looking at the rest of the value. */ |
without looking at the rest of the value. */ |
899 |
VFP_OP(neg, s) |
VFP_OP(neg, s) |
900 |
{ |
{ |
901 |
FT0s = -FT0s; |
FT0s = float32_chs(FT0s); |
902 |
} |
} |
903 |
|
|
904 |
VFP_OP(neg, d) |
VFP_OP(neg, d) |
905 |
{ |
{ |
906 |
FT0d = -FT0d; |
FT0d = float64_chs(FT0d); |
907 |
} |
} |
908 |
|
|
909 |
VFP_OP(F1_ld0, s) |
VFP_OP(F1_ld0, s) |
910 |
{ |
{ |
911 |
FT1s = 0.0f; |
union { |
912 |
|
uint32_t i; |
913 |
|
float32 s; |
914 |
|
} v; |
915 |
|
v.i = 0; |
916 |
|
FT1s = v.s; |
917 |
} |
} |
918 |
|
|
919 |
VFP_OP(F1_ld0, d) |
VFP_OP(F1_ld0, d) |
920 |
{ |
{ |
921 |
FT1d = 0.0; |
union { |
922 |
|
uint64_t i; |
923 |
|
float64 d; |
924 |
|
} v; |
925 |
|
v.i = 0; |
926 |
|
FT1d = v.d; |
927 |
} |
} |
928 |
|
|
929 |
/* Helper routines to perform bitwise copies between float and int. */ |
/* Helper routines to perform bitwise copies between float and int. */ |
930 |
static inline float vfp_itos(uint32_t i) |
static inline float32 vfp_itos(uint32_t i) |
931 |
{ |
{ |
932 |
union { |
union { |
933 |
uint32_t i; |
uint32_t i; |
934 |
float s; |
float32 s; |
935 |
} v; |
} v; |
936 |
|
|
937 |
v.i = i; |
v.i = i; |
938 |
return v.s; |
return v.s; |
939 |
} |
} |
940 |
|
|
941 |
static inline uint32_t vfp_stoi(float s) |
static inline uint32_t vfp_stoi(float32 s) |
942 |
{ |
{ |
943 |
union { |
union { |
944 |
uint32_t i; |
uint32_t i; |
945 |
float s; |
float32 s; |
946 |
} v; |
} v; |
947 |
|
|
948 |
v.s = s; |
v.s = s; |
952 |
/* Integer to float conversion. */ |
/* Integer to float conversion. */ |
953 |
VFP_OP(uito, s) |
VFP_OP(uito, s) |
954 |
{ |
{ |
955 |
FT0s = (float)(uint32_t)vfp_stoi(FT0s); |
FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status); |
956 |
} |
} |
957 |
|
|
958 |
VFP_OP(uito, d) |
VFP_OP(uito, d) |
959 |
{ |
{ |
960 |
FT0d = (double)(uint32_t)vfp_stoi(FT0s); |
FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status); |
961 |
} |
} |
962 |
|
|
963 |
VFP_OP(sito, s) |
VFP_OP(sito, s) |
964 |
{ |
{ |
965 |
FT0s = (float)(int32_t)vfp_stoi(FT0s); |
FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status); |
966 |
} |
} |
967 |
|
|
968 |
VFP_OP(sito, d) |
VFP_OP(sito, d) |
969 |
{ |
{ |
970 |
FT0d = (double)(int32_t)vfp_stoi(FT0s); |
FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status); |
971 |
} |
} |
972 |
|
|
973 |
/* Float to integer conversion. */ |
/* Float to integer conversion. */ |
974 |
VFP_OP(toui, s) |
VFP_OP(toui, s) |
975 |
{ |
{ |
976 |
FT0s = vfp_itos((uint32_t)FT0s); |
FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status)); |
977 |
} |
} |
978 |
|
|
979 |
VFP_OP(toui, d) |
VFP_OP(toui, d) |
980 |
{ |
{ |
981 |
FT0s = vfp_itos((uint32_t)FT0d); |
FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status)); |
982 |
} |
} |
983 |
|
|
984 |
VFP_OP(tosi, s) |
VFP_OP(tosi, s) |
985 |
{ |
{ |
986 |
FT0s = vfp_itos((int32_t)FT0s); |
FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status)); |
987 |
} |
} |
988 |
|
|
989 |
VFP_OP(tosi, d) |
VFP_OP(tosi, d) |
990 |
{ |
{ |
991 |
FT0s = vfp_itos((int32_t)FT0d); |
FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status)); |
992 |
} |
} |
993 |
|
|
994 |
/* TODO: Set rounding mode properly. */ |
/* TODO: Set rounding mode properly. */ |
995 |
VFP_OP(touiz, s) |
VFP_OP(touiz, s) |
996 |
{ |
{ |
997 |
FT0s = vfp_itos((uint32_t)FT0s); |
FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status)); |
998 |
} |
} |
999 |
|
|
1000 |
VFP_OP(touiz, d) |
VFP_OP(touiz, d) |
1001 |
{ |
{ |
1002 |
FT0s = vfp_itos((uint32_t)FT0d); |
FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status)); |
1003 |
} |
} |
1004 |
|
|
1005 |
VFP_OP(tosiz, s) |
VFP_OP(tosiz, s) |
1006 |
{ |
{ |
1007 |
FT0s = vfp_itos((int32_t)FT0s); |
FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status)); |
1008 |
} |
} |
1009 |
|
|
1010 |
VFP_OP(tosiz, d) |
VFP_OP(tosiz, d) |
1011 |
{ |
{ |
1012 |
FT0s = vfp_itos((int32_t)FT0d); |
FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status)); |
1013 |
} |
} |
1014 |
|
|
1015 |
/* floating point conversion */ |
/* floating point conversion */ |
1016 |
VFP_OP(fcvtd, s) |
VFP_OP(fcvtd, s) |
1017 |
{ |
{ |
1018 |
FT0d = (double)FT0s; |
FT0d = float32_to_float64(FT0s, &env->vfp.fp_status); |
1019 |
} |
} |
1020 |
|
|
1021 |
VFP_OP(fcvts, d) |
VFP_OP(fcvts, d) |
1022 |
{ |
{ |
1023 |
FT0s = (float)FT0d; |
FT0s = float64_to_float32(FT0d, &env->vfp.fp_status); |
1024 |
} |
} |
1025 |
|
|
1026 |
/* Get and Put values from registers. */ |
/* Get and Put values from registers. */ |
1027 |
VFP_OP(getreg_F0, d) |
VFP_OP(getreg_F0, d) |
1028 |
{ |
{ |
1029 |
FT0d = *(double *)((char *) env + PARAM1); |
FT0d = *(float64 *)((char *) env + PARAM1); |
1030 |
} |
} |
1031 |
|
|
1032 |
VFP_OP(getreg_F0, s) |
VFP_OP(getreg_F0, s) |
1033 |
{ |
{ |
1034 |
FT0s = *(float *)((char *) env + PARAM1); |
FT0s = *(float32 *)((char *) env + PARAM1); |
1035 |
} |
} |
1036 |
|
|
1037 |
VFP_OP(getreg_F1, d) |
VFP_OP(getreg_F1, d) |
1038 |
{ |
{ |
1039 |
FT1d = *(double *)((char *) env + PARAM1); |
FT1d = *(float64 *)((char *) env + PARAM1); |
1040 |
} |
} |
1041 |
|
|
1042 |
VFP_OP(getreg_F1, s) |
VFP_OP(getreg_F1, s) |
1043 |
{ |
{ |
1044 |
FT1s = *(float *)((char *) env + PARAM1); |
FT1s = *(float32 *)((char *) env + PARAM1); |
1045 |
} |
} |
1046 |
|
|
1047 |
VFP_OP(setreg_F0, d) |
VFP_OP(setreg_F0, d) |
1048 |
{ |
{ |
1049 |
*(double *)((char *) env + PARAM1) = FT0d; |
*(float64 *)((char *) env + PARAM1) = FT0d; |
1050 |
} |
} |
1051 |
|
|
1052 |
VFP_OP(setreg_F0, s) |
VFP_OP(setreg_F0, s) |
1053 |
{ |
{ |
1054 |
*(float *)((char *) env + PARAM1) = FT0s; |
*(float32 *)((char *) env + PARAM1) = FT0s; |
|
} |
|
|
|
|
|
VFP_OP(foobar, d) |
|
|
{ |
|
|
FT0d = env->vfp.regs.s[3]; |
|
1055 |
} |
} |
1056 |
|
|
1057 |
void OPPROTO op_vfp_movl_T0_fpscr(void) |
void OPPROTO op_vfp_movl_T0_fpscr(void) |