| 1 | # This AWK script will take os2emx.h and create wrappers that restore
|
|---|
| 2 | # the FPU control word to its normal state expected by C/C++ programs
|
|---|
| 3 |
|
|---|
| 4 | BEGIN {
|
|---|
| 5 | if (ARGC != 2) {
|
|---|
| 6 | print "Usage: API_FPU_CW_Wrappers.awk <os2emx.h>";
|
|---|
| 7 | exit 1;
|
|---|
| 8 | }
|
|---|
| 9 | in_func_decl = 0;
|
|---|
| 10 | func_decl = ""
|
|---|
| 11 | num_funcs = 0
|
|---|
| 12 | }
|
|---|
| 13 |
|
|---|
| 14 | /^[a-zA-Z]+[ \t]+APIENTRY[ \t]+(Win|Gpi).*[ \t]+\(/ { in_func_decl = 1 }
|
|---|
| 15 |
|
|---|
| 16 | in_func_decl { func_decl = func_decl $0 }
|
|---|
| 17 |
|
|---|
| 18 | /;/ && in_func_decl {
|
|---|
| 19 | in_func_decl = 0
|
|---|
| 20 | funcs[num_funcs] = substr(func_decl, 1, length(func_decl)-1)
|
|---|
| 21 | func_decl = ""
|
|---|
| 22 | num_funcs++
|
|---|
| 23 | }
|
|---|
| 24 |
|
|---|
| 25 | END {
|
|---|
| 26 | print "/* Generated by API_FPU_CW_Wrappers.awk from os2emx.h */"
|
|---|
| 27 | print "/* See http://svn.netlabs.org/qt4/ticket/105 for more info */"
|
|---|
| 28 | print ""
|
|---|
| 29 | print "/*"
|
|---|
| 30 | print " * Some OS/2 PM API calls modify the FPU Control Word,"
|
|---|
| 31 | print " * but forget to restore it."
|
|---|
| 32 | print " *"
|
|---|
| 33 | print " * This can result in unexpected XCPT_FLOAT_INVALID_OPCODE or"
|
|---|
| 34 | print " * XCPT_FLOAT_INVALID_OPERATION exceptions. To avoid this, we create"
|
|---|
| 35 | print " * wrappers for each API call that restore the FPU Control Word"
|
|---|
| 36 | print " * after the API call back to the value expected by C/C++ programs."
|
|---|
| 37 | print " */"
|
|---|
| 38 | print ""
|
|---|
| 39 | print "#ifndef API_FPU_CW_WRAPPERS_H"
|
|---|
| 40 | print "#define API_FPU_CW_WRAPPERS_H"
|
|---|
| 41 | print ""
|
|---|
| 42 | print "inline void __FPU_CW_Restore()"
|
|---|
| 43 | print "{"
|
|---|
| 44 | print " asm(\"pushl %%eax\\n\\t\" /* Dummy for storing control word */"
|
|---|
| 45 | print " \"fstcw 0(%%esp)\\n\\t\" /* Store control word into memory */"
|
|---|
| 46 | print " \"orw $5, 0(%%esp)\\n\\t\" /* Set EM_INVALID (0x1) | EM_ZERODIVIDE (0x4) */"
|
|---|
| 47 | print " \"fldcw 0(%%esp)\\n\\t\" /* Load control word back */"
|
|---|
| 48 | print " \"popl %%eax\\n\\t\""
|
|---|
| 49 | print " ::: \"eax\");"
|
|---|
| 50 | print "}"
|
|---|
| 51 | print ""
|
|---|
| 52 |
|
|---|
| 53 | for (i = 0; i < num_funcs; i++) {
|
|---|
| 54 | fnc = funcs[i]
|
|---|
| 55 | rv = gensub("^(.*)[ \t]+APIENTRY.*", "\\1", "", fnc)
|
|---|
| 56 | fn = gensub(".*[ \t]+((Win|Gpi).*)[ \t]+\\(.*", "\\1", "", fnc)
|
|---|
| 57 | print "inline " gensub(fn, "__FPU_CW_" fn, "", fnc) "\n{"
|
|---|
| 58 | fn_args = gensub(".*\\((.*)\\).*", "\\1", "", fnc)
|
|---|
| 59 | fn_args = gensub("([_a-zA-Z][_a-zA-Z0-9]*[ \t]+)+\\*?([_a-zA-Z][_a-zA-Z0-9]*)(,[ \t]+|$)", "\\2\\3", "g", fn_args)
|
|---|
| 60 | if (toupper(fn_args) == "VOID")
|
|---|
| 61 | fn_args = ""
|
|---|
| 62 | print " " rv " ret = " fn " (" fn_args ");"
|
|---|
| 63 | print " __FPU_CW_Restore();"
|
|---|
| 64 | print " return ret;\n}"
|
|---|
| 65 | print "#define " fn " __FPU_CW_" fn "\n"
|
|---|
| 66 | }
|
|---|
| 67 |
|
|---|
| 68 | print "#endif // API_FPU_CW_WRAPPERS_H"
|
|---|
| 69 | }
|
|---|