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 | }
|
---|