The fastest way is the approximation of functions with single precision by Chebyshev polynomials. It is better to set the argument in degrees, so less resources are spent on reducing the argument. The following code is proposed for Visual Studio. This is an example in C++, but the assembly code can be adapted to other environments.
void _declspec(naked) _vectorcall SinCosD(float x, float &s, float &c)
{
_declspec(align(16)) static const float ct[8] = // Таблица констант
{
-1/180.0f, // Множитель для приведения x
-0.0f, // 80000000h
1.74532924E-2f, // b0/90 = c0
90.0f, // Константа для перехода от cos к sin
1.34955580E-11f, // b2/90^5 = c2
3.91499677E-22f, // b4/90^9 = c4
-8.86095677E-7f, // b1/90^3 = c1
-9.77249307E-17f // b3/90^7 = c3
};
_asm
{
mov eax,offset ct // В eax - адрес таблицы констант
vmovaps xmm1,[eax] // xmm1 = 90 # c0 : 80000000h # -1/180
vmovddup xmm4,[eax+16] // xmm4 = c4 # c2 : c4 # c2
vmulss xmm1,xmm1,xmm0 // xmm1 = 90 # c0 : 80000000h # -x/180
vmovddup xmm5,[eax+24] // xmm5 = c3 # c1 : c3 # c1
vcvtss2si eax,xmm1 // eax = -k, где k - округлённое до целых значение x/180
vshufps xmm2,xmm1,xmm1,93 // xmm2 = 90 # 80000000h
imul eax,180 // eax = -180*k; of=1, если переполнение
jno sc_cont // В случае слишком большого |x| считать, как при x=0
sub eax,eax // Для этого обнулить eax
vxorps xmm0,xmm0,xmm0 // и обнулить xmm0
sc_cont: // Продолжаем для корректного значения x
vcvtsi2ss xmm1,xmm1,eax // xmm1 = -180*k в позиции 0
vaddss xmm1,xmm1,xmm0 // xmm1 = x-k*180 = 90*t - число в диапазоне [-90; 90]
shl eax,29 // При нечётном k установить знаковый бит eax
vmovd xmm0,eax // В xmm0 - знаковая маска результата
vorps xmm2,xmm2,xmm1 // xmm2 = -90 # -|90*t|
vmovlhps xmm0,xmm0,xmm0 // Знаковую маску скопировать в старшую половину xmm0
vhsubps xmm2,xmm2,xmm1 // xmm2 = 90*t : 90-|90*t| - приведённые аргументы
vxorps xmm0,xmm0,xmm2 // В xmm0 - приведённые аргументы с учётом знака
vmovsldup xmm2,xmm2 // xmm2 = 90*t # 90*t : 90-|90*t| # 90-|90*t|
vmulps xmm2,xmm2,xmm2 // xmm2 = p # p : q # q - аргументы многочлена
vmovhlps xmm1,xmm1,xmm1 // xmm1 = c0 : с0 (свободный член)
vfmadd231ps xmm5,xmm4,xmm2 // xmm5 = c3+c4*p # c1+c2*p : c3+c4*q # c1+c2*q
vmulps xmm3,xmm2,xmm2 // xmm3 = p^2 : q^2
vmovshdup xmm4,xmm5 // xmm4 = c3+c4*p : c3+c4*q
vfmadd231ps xmm5,xmm4,xmm3 // xmm5 = c1+c2*p+c3*p^2+c4*p^3 : c1+c2*q+с3*q^2+с4*q^3
vfmadd231ps xmm1,xmm5,xmm2 // xmm1 = сумма для синуса : сумма для косинуса
vmulps xmm0,xmm0,xmm1 // xmm0 = sin x : cos x - готовый результат (-1)^k*t*f(t)
vmovss [edx],xmm0 // Сохранить косинус в переменной c
vextractps [ecx],xmm0,2 // Сохранить синус в переменной s
ret // Вернуться
}
}