704 |
/* float to float conversions */ |
/* float to float conversions */ |
705 |
void OPPROTO op_cvtps2pd(void) |
void OPPROTO op_cvtps2pd(void) |
706 |
{ |
{ |
707 |
float s0, s1; |
float32 s0, s1; |
708 |
Reg *d, *s; |
Reg *d, *s; |
709 |
d = (Reg *)((char *)env + PARAM1); |
d = (Reg *)((char *)env + PARAM1); |
710 |
s = (Reg *)((char *)env + PARAM2); |
s = (Reg *)((char *)env + PARAM2); |
1031 |
Reg *d, *s;\ |
Reg *d, *s;\ |
1032 |
d = (Reg *)((char *)env + PARAM1);\ |
d = (Reg *)((char *)env + PARAM1);\ |
1033 |
s = (Reg *)((char *)env + PARAM2);\ |
s = (Reg *)((char *)env + PARAM2);\ |
1034 |
d->XMM_L(0) = F(d->XMM_S(0), s->XMM_S(0));\ |
d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\ |
1035 |
d->XMM_L(1) = F(d->XMM_S(1), s->XMM_S(1));\ |
d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1));\ |
1036 |
d->XMM_L(2) = F(d->XMM_S(2), s->XMM_S(2));\ |
d->XMM_L(2) = F(32, d->XMM_S(2), s->XMM_S(2));\ |
1037 |
d->XMM_L(3) = F(d->XMM_S(3), s->XMM_S(3));\ |
d->XMM_L(3) = F(32, d->XMM_S(3), s->XMM_S(3));\ |
1038 |
}\ |
}\ |
1039 |
\ |
\ |
1040 |
void OPPROTO op_ ## name ## ss (void)\ |
void OPPROTO op_ ## name ## ss (void)\ |
1042 |
Reg *d, *s;\ |
Reg *d, *s;\ |
1043 |
d = (Reg *)((char *)env + PARAM1);\ |
d = (Reg *)((char *)env + PARAM1);\ |
1044 |
s = (Reg *)((char *)env + PARAM2);\ |
s = (Reg *)((char *)env + PARAM2);\ |
1045 |
d->XMM_L(0) = F(d->XMM_S(0), s->XMM_S(0));\ |
d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\ |
1046 |
}\ |
}\ |
1047 |
void OPPROTO op_ ## name ## pd (void)\ |
void OPPROTO op_ ## name ## pd (void)\ |
1048 |
{\ |
{\ |
1049 |
Reg *d, *s;\ |
Reg *d, *s;\ |
1050 |
d = (Reg *)((char *)env + PARAM1);\ |
d = (Reg *)((char *)env + PARAM1);\ |
1051 |
s = (Reg *)((char *)env + PARAM2);\ |
s = (Reg *)((char *)env + PARAM2);\ |
1052 |
d->XMM_Q(0) = F(d->XMM_D(0), s->XMM_D(0));\ |
d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\ |
1053 |
d->XMM_Q(1) = F(d->XMM_D(1), s->XMM_D(1));\ |
d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1));\ |
1054 |
}\ |
}\ |
1055 |
\ |
\ |
1056 |
void OPPROTO op_ ## name ## sd (void)\ |
void OPPROTO op_ ## name ## sd (void)\ |
1058 |
Reg *d, *s;\ |
Reg *d, *s;\ |
1059 |
d = (Reg *)((char *)env + PARAM1);\ |
d = (Reg *)((char *)env + PARAM1);\ |
1060 |
s = (Reg *)((char *)env + PARAM2);\ |
s = (Reg *)((char *)env + PARAM2);\ |
1061 |
d->XMM_Q(0) = F(d->XMM_D(0), s->XMM_D(0));\ |
d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\ |
1062 |
} |
} |
1063 |
|
|
1064 |
#define FPU_CMPEQ(a, b) (a) == (b) ? -1 : 0 |
#define FPU_CMPEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? -1 : 0 |
1065 |
#define FPU_CMPLT(a, b) (a) < (b) ? -1 : 0 |
#define FPU_CMPLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? -1 : 0 |
1066 |
#define FPU_CMPLE(a, b) (a) <= (b) ? -1 : 0 |
#define FPU_CMPLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? -1 : 0 |
1067 |
#define FPU_CMPUNORD(a, b) (fpu_isnan(a) || fpu_isnan(b)) ? - 1 : 0 |
#define FPU_CMPUNORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? - 1 : 0 |
1068 |
#define FPU_CMPNEQ(a, b) (a) == (b) ? 0 : -1 |
#define FPU_CMPNEQ(size, a, b) float ## size ## _eq(a, b, &env->sse_status) ? 0 : -1 |
1069 |
#define FPU_CMPNLT(a, b) (a) < (b) ? 0 : -1 |
#define FPU_CMPNLT(size, a, b) float ## size ## _lt(a, b, &env->sse_status) ? 0 : -1 |
1070 |
#define FPU_CMPNLE(a, b) (a) <= (b) ? 0 : -1 |
#define FPU_CMPNLE(size, a, b) float ## size ## _le(a, b, &env->sse_status) ? 0 : -1 |
1071 |
#define FPU_CMPORD(a, b) (!fpu_isnan(a) && !fpu_isnan(b)) ? - 1 : 0 |
#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1 |
1072 |
|
|
1073 |
SSE_OP_CMP(cmpeq, FPU_CMPEQ) |
SSE_OP_CMP(cmpeq, FPU_CMPEQ) |
1074 |
SSE_OP_CMP(cmplt, FPU_CMPLT) |
SSE_OP_CMP(cmplt, FPU_CMPLT) |
1082 |
void OPPROTO op_ucomiss(void) |
void OPPROTO op_ucomiss(void) |
1083 |
{ |
{ |
1084 |
int eflags; |
int eflags; |
1085 |
float s0, s1; |
float32 s0, s1; |
1086 |
Reg *d, *s; |
Reg *d, *s; |
1087 |
d = (Reg *)((char *)env + PARAM1); |
d = (Reg *)((char *)env + PARAM1); |
1088 |
s = (Reg *)((char *)env + PARAM2); |
s = (Reg *)((char *)env + PARAM2); |
1089 |
|
|
1090 |
s0 = d->XMM_S(0); |
s0 = d->XMM_S(0); |
1091 |
s1 = s->XMM_S(0); |
s1 = s->XMM_S(0); |
1092 |
if (s0 < s1) |
switch(float32_compare_quiet(s0, s1, &env->sse_status)) { |
1093 |
|
case -1: |
1094 |
eflags = CC_C; |
eflags = CC_C; |
1095 |
else if (s0 == s1) |
break; |
1096 |
|
case 0: |
1097 |
eflags = CC_Z; |
eflags = CC_Z; |
1098 |
else |
break; |
1099 |
|
case 1: |
1100 |
eflags = 0; |
eflags = 0; |
1101 |
|
break; |
1102 |
|
case 2: |
1103 |
|
default: |
1104 |
|
eflags = CC_Z | CC_P | CC_C; |
1105 |
|
break; |
1106 |
|
} |
1107 |
CC_SRC = eflags; |
CC_SRC = eflags; |
1108 |
FORCE_RET(); |
FORCE_RET(); |
1109 |
} |
} |
1111 |
void OPPROTO op_comiss(void) |
void OPPROTO op_comiss(void) |
1112 |
{ |
{ |
1113 |
int eflags; |
int eflags; |
1114 |
float s0, s1; |
float32 s0, s1; |
1115 |
Reg *d, *s; |
Reg *d, *s; |
1116 |
d = (Reg *)((char *)env + PARAM1); |
d = (Reg *)((char *)env + PARAM1); |
1117 |
s = (Reg *)((char *)env + PARAM2); |
s = (Reg *)((char *)env + PARAM2); |
1118 |
|
|
1119 |
s0 = d->XMM_S(0); |
s0 = d->XMM_S(0); |
1120 |
s1 = s->XMM_S(0); |
s1 = s->XMM_S(0); |
1121 |
if (s0 < s1) |
switch(float32_compare(s0, s1, &env->sse_status)) { |
1122 |
|
case -1: |
1123 |
eflags = CC_C; |
eflags = CC_C; |
1124 |
else if (s0 == s1) |
break; |
1125 |
|
case 0: |
1126 |
eflags = CC_Z; |
eflags = CC_Z; |
1127 |
else |
break; |
1128 |
|
case 1: |
1129 |
eflags = 0; |
eflags = 0; |
1130 |
|
break; |
1131 |
|
case 2: |
1132 |
|
default: |
1133 |
|
eflags = CC_Z | CC_P | CC_C; |
1134 |
|
break; |
1135 |
|
} |
1136 |
CC_SRC = eflags; |
CC_SRC = eflags; |
1137 |
FORCE_RET(); |
FORCE_RET(); |
1138 |
} |
} |
1140 |
void OPPROTO op_ucomisd(void) |
void OPPROTO op_ucomisd(void) |
1141 |
{ |
{ |
1142 |
int eflags; |
int eflags; |
1143 |
double d0, d1; |
float64 d0, d1; |
1144 |
Reg *d, *s; |
Reg *d, *s; |
1145 |
d = (Reg *)((char *)env + PARAM1); |
d = (Reg *)((char *)env + PARAM1); |
1146 |
s = (Reg *)((char *)env + PARAM2); |
s = (Reg *)((char *)env + PARAM2); |
1147 |
|
|
1148 |
d0 = d->XMM_D(0); |
d0 = d->XMM_D(0); |
1149 |
d1 = s->XMM_D(0); |
d1 = s->XMM_D(0); |
1150 |
if (d0 < d1) |
switch(float64_compare_quiet(d0, d1, &env->sse_status)) { |
1151 |
|
case -1: |
1152 |
eflags = CC_C; |
eflags = CC_C; |
1153 |
else if (d0 == d1) |
break; |
1154 |
|
case 0: |
1155 |
eflags = CC_Z; |
eflags = CC_Z; |
1156 |
else |
break; |
1157 |
|
case 1: |
1158 |
eflags = 0; |
eflags = 0; |
1159 |
|
break; |
1160 |
|
case 2: |
1161 |
|
default: |
1162 |
|
eflags = CC_Z | CC_P | CC_C; |
1163 |
|
break; |
1164 |
|
} |
1165 |
CC_SRC = eflags; |
CC_SRC = eflags; |
1166 |
FORCE_RET(); |
FORCE_RET(); |
1167 |
} |
} |
1169 |
void OPPROTO op_comisd(void) |
void OPPROTO op_comisd(void) |
1170 |
{ |
{ |
1171 |
int eflags; |
int eflags; |
1172 |
double d0, d1; |
float64 d0, d1; |
1173 |
Reg *d, *s; |
Reg *d, *s; |
1174 |
d = (Reg *)((char *)env + PARAM1); |
d = (Reg *)((char *)env + PARAM1); |
1175 |
s = (Reg *)((char *)env + PARAM2); |
s = (Reg *)((char *)env + PARAM2); |
1176 |
|
|
1177 |
d0 = d->XMM_D(0); |
d0 = d->XMM_D(0); |
1178 |
d1 = s->XMM_D(0); |
d1 = s->XMM_D(0); |
1179 |
if (d0 < d1) |
switch(float64_compare(d0, d1, &env->sse_status)) { |
1180 |
|
case -1: |
1181 |
eflags = CC_C; |
eflags = CC_C; |
1182 |
else if (d0 == d1) |
break; |
1183 |
|
case 0: |
1184 |
eflags = CC_Z; |
eflags = CC_Z; |
1185 |
else |
break; |
1186 |
|
case 1: |
1187 |
eflags = 0; |
eflags = 0; |
1188 |
|
break; |
1189 |
|
case 2: |
1190 |
|
default: |
1191 |
|
eflags = CC_Z | CC_P | CC_C; |
1192 |
|
break; |
1193 |
|
} |
1194 |
CC_SRC = eflags; |
CC_SRC = eflags; |
1195 |
FORCE_RET(); |
FORCE_RET(); |
1196 |
} |
} |