minxomat Posted April 11, 2015 Posted April 11, 2015 I've implemented a certain algorithm which uses fractional exponents (PowF(float, float)) to calculate intermediate values. Now I'm trying to convert this calculation (from AutoIt) to simple ASM instructions. Since PowF is quite a complex operation in ASM, because you have to balance instruction count and error (which should be less than 16bit precision in this case), I'd like to know more about the implementation of fractional exponents in AutoIt itself. The goal is to accurately recreate the results AutoIt would produce given the same input values If there are multiple different ways each calculation is handled given the size of the exponent, I'll only need the details for n^{0.9..1.5}. My approach would be to use a simple cvtps2dq SSE cycle, but I'm curious I will answer every single PM, and you are free to ask anything anytime.
minxomat Posted April 11, 2015 Author Posted April 11, 2015 (edited) According to the latest (...) AutoIt 3.1 source codeexpandcollapse popupcase OPR_POW: // ^ vOp2 = valStack.top(); valStack.pop(); vOp1 = valStack.top(); valStack.pop(); if ( vOp2.fValue() == 0.0 ) vOp1 = 1.0; else if ( vOp1.fValue() == 0.0 && vOp2.fValue() < 0.0) { //double fTmp = 0.0; // needed to prevent compiler error. //vOp1 = 1.0/fTmp; // invalid. Return 1.#INF by forcing divide by 0. GIVES COMPILER WARNING vOp1 = 0.0; } else if ( vOp1.fValue() < 0.0 && (vOp2.type() == VAR_INT32 || vOp2.type() == VAR_INT64) ) // integer (32 or 64 bit) { #ifdef _MSC_VER // MS Compiler vOp1 = qmathPow(qmathFabs(vOp1.fValue()), vOp2.fValue()); #else vOp1 = pow(fabs(vOp1.fValue()), vOp2.fValue()); #endif if (vOp2.nValue() & 1) // odd number { vOp2 = -1.0; vOp1 *= vOp2; } } else #ifdef _MSC_VER // MS Compiler vOp1 = qmathPow(vOp1.fValue(), vOp2.fValue()); #else vOp1 = pow(vOp1.fValue(), vOp2.fValue()); #endif valStack.push(vOp1); break;, AutoIt uses double _QMATH_LINK qmathPow(double __x, double __y) { __asm fld qword ptr [esp + 12] __asm fld qword ptr [esp + 4] __asm ftst __asm fstsw ax __asm sahf __asm jz pow_zero __asm fyl2x __asm fld1 __asm fld st(1) __asm fprem __asm f2xm1 __asm faddp st(1), st(0) __asm fscale pow_zero: __asm fstp st(1) __asm ret 16 }as long as it is compiled using a MSVC compliant compiler. Is this still the case? Edited April 11, 2015 by minx I will answer every single PM, and you are free to ask anything anytime.
minxomat Posted April 11, 2015 Author Posted April 11, 2015 (edited) I'll just answer this for myself by testing. It seems to still use MSVCs qmath.h or similar native library implementation: expandcollapse popup#include <AssembleIt.au3> Local $double_qmathPow Local $asmstrc = DllStructCreate("double __x;double __y;") $asmstrc.__x = 5.8 $asmstrc.__y = 0.9535 Func _QMATH_NAKED__QMATH_INLINE_double__QMATH_LINK_qmathPow() _(" use32 ") _(" fld qword[esp+12] ") _(" fld qword[esp+4] ") _(" ftst ") _(" fstsw ax ") _(" sahf ") _(" jz pow_zero ") _(" fyl2x ") _(" fld1 ") _(" fld st1 ") _(" fprem ") _(" f2xm1 ") _(" faddp st1, st0 ") _(" fscale ") _(" pow_zero: ") _(" fstp st1 ") _(" ret ") EndFunc ;_AssembleIt($double_qmathPowurntype, $Name_of_Func_with_code, $Type1 = "type", $Param1 = 0, $Type2 = "type", $Param2 = 0....up to 20 params) $double_qmathPow = _AssembleIt("double", "_QMATH_NAKED__QMATH_INLINE_double__QMATH_LINK_qmathPow", "double", $asmstrc.__x, "double", $asmstrc.__y) ;thats all^^ $double_autoit = $asmstrc.__x ^ $asmstrc.__y ConsoleWrite(@LF) ConsoleWrite("+> (FASM)qmathPow: " & $double_qmathPow & @LF) ConsoleWrite("+> (AutoIt)^ : " & $double_autoit & @LF) Edited April 12, 2015 by minx I will answer every single PM, and you are free to ask anything anytime.
Administrators Jon Posted April 12, 2015 Administrators Posted April 12, 2015 It doesn't use qmath anymore. It uses the native MSVC libs. I think we stopped using qmath because of a couple of bugs. Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/
minxomat Posted April 12, 2015 Author Posted April 12, 2015 (edited) K, but the results are effectively the same (It works fine in this scenario.) Edited April 12, 2015 by minx I will answer every single PM, and you are free to ask anything anytime.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now