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