1#  Copyright (C) 2009-2018 Free Software Foundation, Inc.
2#
3# This program is free software; you can redistribute it and/or modify it
4# under the terms of the GNU General Public License as published by the
5# Free Software Foundation; either version 3, or (at your option) any
6# later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; see the file COPYING3.  If not see
15# <http://www.gnu.org/licenses/>.
16
17# Generates compressed tables for types for i386 builtin functions.
18
19function do_error(string) {
20    print FILENAME ":" FNR ": " string > "/dev/stderr"
21    errors = 1
22}
23
24function check_type(string) {
25    if (!(string in type_hash))
26	do_error("undefined type code " string)
27}
28
29# We can significantly reduce the size of the read-only tables
30# by forcing the compiler to use a smaller implementation type
31# for the enumerations.
32function attribute_mode(count) {
33    # ??? Except that we get strange "comparison always false" warnings
34    # for comparisons between different elements of the enumeration.
35    #    print "#ifdef __GNUC__"
36    #    if (count < 256)
37    #	print "  __attribute__((__mode__(__QI__)))"
38    #    else
39    #	print "  __attribute__((__mode__(__HI__)))"
40    #    print "#endif"
41}
42
43BEGIN {
44    FS = "[() \t,]+"
45
46    prim_defs = 0
47    vect_defs = 0
48    ptr_defs = 0
49    cptr_defs = 0
50    func_defs = 0
51    func_args = 0
52    alias_defs = 0
53}
54
55# Skip blank lines or comments.
56/^[ \t]*(#|$)/ {
57    next
58}
59
60$1 == "DEF_PRIMITIVE_TYPE" {
61    if (NF == 4) {
62	type_hash[$2] = 1
63	prim_name[prim_defs] = $2
64	prim_base[prim_defs] = $3
65	prim_defs++
66    } else
67	do_error("DEF_PRIMITIVE_TYPE expected 2 arguments")
68    next
69}
70
71$1 == "DEF_VECTOR_TYPE" {
72    if (NF == 4 || NF == 5) {
73	check_type($3)
74	type_hash[$2] = 1
75	vect_name[vect_defs] = $2
76	vect_base[vect_defs] = $3
77	vect_mode[vect_defs] = (NF == 5 ? $4 : $2)
78	vect_defs++
79    } else
80	do_error("DEF_VECTOR_TYPE expected 2 arguments")
81    next
82}
83
84$1 == "DEF_POINTER_TYPE" {
85    if (NF == 4) {
86	check_type($3)
87	type_hash[$2] = 1
88	ptr_name[ptr_defs] = $2
89	ptr_base[ptr_defs] = $3
90	ptr_defs++
91    } else if (NF == 5) {
92	check_type($3)
93	if ($4 == "CONST") {
94	    type_hash[$2] = 1
95	    cptr_name[cptr_defs] = $2
96	    cptr_base[cptr_defs] = $3
97	    cptr_defs++
98	} else
99	    do_error("invalid qualifier \"" $4 "\"")
100    }
101    else
102	do_error("DEF_POINTER_TYPE expected 2 or 3 arguments")
103    next
104}
105
106$1 == "DEF_FUNCTION_TYPE" {
107    func_start[func_defs] = func_args
108    for (i = 2; i < NF; ++i) {
109	check_type($i)
110	func_types[func_args++] = $i
111    }
112
113    if (NF < 3)
114	do_error("DEF_FUNCTION_TYPE expected at least 1 argument")
115    else if (NF == 3)
116	name = $2 "_FTYPE_VOID"
117    else {
118	name = $2 "_FTYPE"
119	for (i = 3; i < NF; ++i)
120	    name = name "_" $i
121    }
122    func_hash[name] = 1
123    func_name[func_defs++] = name
124    next
125}
126
127$1 == "DEF_FUNCTION_TYPE_ALIAS" {
128    if (NF == 4) {
129	if ($2 in func_hash) {
130	    alias_base[alias_defs] = $2
131	    alias_name[alias_defs] = $2 "_" $3
132	    alias_defs++
133	} else
134	    do_error("undefined function code " $2)
135    } else
136	do_error("DEF_FUNCTION_TYPE_ALIAS expected 2 arguments")
137    next
138}
139
140{
141    do_error("unknown directive \"" $1 "\"");
142}
143
144END {
145    if (errors)
146	exit 1
147
148    print "/* This file is auto-generated by i386-builtin-types.awk.  */\n"
149
150    # This first enumeration contains all of the non-function types.
151    print "enum ix86_builtin_type {"
152    for (i = 0; i < prim_defs; ++i)
153	print "  IX86_BT_" prim_name[i] ","
154    print "  IX86_BT_LAST_PRIM = IX86_BT_" prim_name[i-1] ","
155    for (i = 0; i < vect_defs; ++i)
156	print "  IX86_BT_" vect_name[i] ","
157    print "  IX86_BT_LAST_VECT = IX86_BT_" vect_name[i-1] ","
158    for (i = 0; i < ptr_defs; ++i)
159	print "  IX86_BT_" ptr_name[i] ","
160    print "  IX86_BT_LAST_PTR = IX86_BT_" ptr_name[i-1] ","
161    for (i = 0; i < cptr_defs; ++i)
162	print "  IX86_BT_" cptr_name[i] ","
163    print "  IX86_BT_LAST_CPTR = IX86_BT_" cptr_name[i-1] "\n}"
164    attribute_mode(prim_defs + vect_defs + ptr_defs + cptr_defs)
165    print ";\n\n"
166
167    # We can't tabularize the initialization of the primitives, since
168    # at least one of them is created via a local variable.  That's ok,
169    # just create a nice big macro to do all the work.
170    print "#define DEFINE_BUILTIN_PRIMITIVE_TYPES \\"
171    for (i = 0; i < prim_defs; ++i) {
172	printf "  ix86_builtin_type_tab[(int)IX86_BT_" prim_name[i] \
173	    "] = " prim_base[i]
174	if (i < prim_defs - 1)
175	    print ", \\"
176    }
177    print "\n\n"
178
179    # The vector types are defined via two tables defining the real
180    # machine mode and the builtin primitive type.  We use two tables
181    # rather than a structure to avoid structure padding and save space.
182    print "static const machine_mode ix86_builtin_type_vect_mode[] = {"
183    for (i = 0; i < vect_defs; ++i) {
184	if (i == 0)
185	    printf "  "
186	else if (i % 6 == 0)
187	    printf ",\n  "
188	else
189	    printf ", "
190	printf "E_" vect_mode[i] "mode"
191    }
192    print "\n};\n\n"
193
194    print "static const enum ix86_builtin_type " \
195	"ix86_builtin_type_vect_base[] = {"
196    for (i = 0; i < vect_defs; ++i) {
197	if (i == 0)
198	    printf "  "
199	else if (i % 4 == 0)
200	    printf ",\n  "
201	else
202	    printf ", "
203	printf "IX86_BT_" vect_base[i]
204    }
205    print "\n};\n\n"
206
207    # The pointer types are defined via a single table defining the
208    # builtin primitive type.  The const-ness of the pointer is taken
209    # from the enumeration value > IX86_BT_LAST_PTR.
210    print "static const enum ix86_builtin_type " \
211	"ix86_builtin_type_ptr_base[] = {"
212    for (i = 0; i < ptr_defs; ++i) {
213	if (i == 0)
214	    printf " "
215	else if (i % 4 == 0)
216	    printf "\n "
217	printf " IX86_BT_" ptr_base[i] ","
218    }
219    print "\n  /* pointer-to-constant defs start here */"
220    for (i = 0; i < cptr_defs; ++i) {
221	if (i == 0)
222	    printf "  "
223	else if (i % 4 == 0)
224	    printf ",\n  "
225	else
226	    printf ", "
227	printf "IX86_BT_" cptr_base[i]
228    }
229    print "\n};\n\n"
230
231    # This second enumeration contains all of the function types.
232    print "enum ix86_builtin_func_type {"
233    for (i = 0; i < func_defs; ++i)
234	print "  " func_name[i] ","
235    print "  IX86_BT_LAST_FUNC = " func_name[i-1] ","
236    for (i = 0; i < alias_defs; ++i)
237	print "  " alias_name[i] ","
238    print "  IX86_BT_LAST_ALIAS = " alias_name[i-1] "\n}"
239    attribute_mode(func_defs + alias_defs)
240    print ";\n\n"
241
242    # The function types are defined via two tables.  The first contains
243    # ranges consiting of the function's return type, followed by all of
244    # the function argument types.  The ranges for all of the builtin
245    # functions are smooshed together in the same array.  The second array
246    # contains, for each builtin, the index of the function's return type
247    # within the first array.
248    print "static const enum ix86_builtin_type ix86_builtin_func_args[] = {"
249    for (i = 0; i < func_args; ++i) {
250	if (i == 0)
251	    printf "  "
252	else if (i % 4 == 0)
253	    printf ",\n  "
254	else
255	    printf ", "
256	printf "IX86_BT_" func_types[i]
257    }
258    print "\n};\n\n"
259
260    print "static const unsigned short ix86_builtin_func_start[] = {"
261    for (i = 0; i < func_defs; ++i) {
262	if (i == 0)
263	    printf " "
264	else if (i % 10 == 0)
265	    printf "\n "
266	printf " " func_start[i] ","
267    }
268    print " " func_args "\n};\n\n"
269
270    print "static const enum ix86_builtin_func_type " \
271	"ix86_builtin_func_alias_base[] = {"
272    for (i = 0; i < alias_defs; ++i) {
273	if (i == 0)
274	    printf "  "
275	else
276	    printf ",\n  "
277	printf alias_base[i]
278    }
279    print "\n};"
280}
281