# This AWK script will take os2emx.h and create wrappers that restore # the FPU control word to its normal state expected by C/C++ programs BEGIN { if (ARGC != 2) { print "Usage: API_FPU_CW_Wrappers.awk "; exit 1; } in_func_decl = 0; func_decl = "" num_funcs = 0 } /^[a-zA-Z]+[ \t]+APIENTRY[ \t]+(Win|Gpi).*[ \t]+\(/ { in_func_decl = 1 } in_func_decl { func_decl = func_decl $0 } /;/ && in_func_decl { in_func_decl = 0 funcs[num_funcs] = substr(func_decl, 1, length(func_decl)-1) func_decl = "" num_funcs++ } END { print "/* Generated by API_FPU_CW_Wrappers.awk from os2emx.h */" print "/* See http://svn.netlabs.org/qt4/ticket/105 for more info */" print "" print "/*" print " * Some OS/2 PM API calls modify the FPU Control Word," print " * but forget to restore it." print " *" print " * This can result in unexpected XCPT_FLOAT_INVALID_OPCODE or" print " * XCPT_FLOAT_INVALID_OPERATION exceptions. To avoid this, we create" print " * wrappers for each API call that restore the FPU Control Word" print " * after the API call back to the value expected by C/C++ programs." print " */" print "" print "#ifndef API_FPU_CW_WRAPPERS_H" print "#define API_FPU_CW_WRAPPERS_H" print "" print "extern inline unsigned int __FPU_CW_Get (void)" print "{" print " unsigned int cw;" print " asm volatile (\"fstcw %0\" : \"=m\" (cw));" print " return cw;" print "}" print "" print "extern inline void __FPU_CW_Set (unsigned int cw)" print "{" print " asm volatile (\"fldcw %0\" : : \"m\" (cw));" print "}" print "" for (i = 0; i < num_funcs; i++) { fnc = funcs[i] rv = gensub("^(.*)[ \t]+APIENTRY.*", "\\1", "", fnc) fn = gensub(".*[ \t]+((Win|Gpi).*)[ \t]+\\(.*", "\\1", "", fnc) print "extern inline " gensub(fn, "__FPU_CW_" fn, "", fnc) "\n{" fn_args = gensub(".*\\((.*)\\).*", "\\1", "", fnc) fn_args = gensub("([_a-zA-Z][_a-zA-Z0-9]*[ \t]+)+\\*?([_a-zA-Z][_a-zA-Z0-9]*)(,[ \t]+|$)", "\\2\\3", "g", fn_args) if (toupper(fn_args) == "VOID") fn_args = "" print " unsigned int cw = __FPU_CW_Get();" print " " rv " ret = " fn " (" fn_args ");" print " __FPU_CW_Set(cw);" print " return ret;\n}" print "#define " fn " __FPU_CW_" fn "\n" } print "#endif // API_FPU_CW_WRAPPERS_H" }