Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: genassym.c | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * CDDL HEADER START | |
46 | * | |
47 | * The contents of this file are subject to the terms of the | |
48 | * Common Development and Distribution License (the "License"). | |
49 | * You may not use this file except in compliance with the License. | |
50 | * | |
51 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
52 | * or http://www.opensolaris.org/os/licensing. | |
53 | * See the License for the specific language governing permissions | |
54 | * and limitations under the License. | |
55 | * | |
56 | * When distributing Covered Code, include this CDDL HEADER in each | |
57 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
58 | * If applicable, add the following below this CDDL HEADER, with the | |
59 | * fields enclosed by brackets "[]" replaced with your own identifying | |
60 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
61 | * | |
62 | * CDDL HEADER END | |
63 | */ | |
64 | ||
65 | /* | |
66 | * Copyright 2006 Sun Microsystems, Inc. All rights reserved. | |
67 | * Use is subject to license terms. | |
68 | */ | |
69 | ||
70 | #pragma ident "@(#)genassym.c 1.1 06/10/26 SMI" | |
71 | ||
72 | #include <unistd.h> | |
73 | #include <math.h> | |
74 | #include "stabs.h" | |
75 | ||
76 | void genassym_do_sou(struct tdesc *tdp, struct node *np); | |
77 | void genassym_do_enum(struct tdesc *tdp, struct node *np); | |
78 | void genassym_do_intrinsic(struct tdesc *tdp, struct node *np); | |
79 | ||
80 | static void switch_on_type(struct mlist *mlp, struct tdesc *tdp, | |
81 | char *format, int level); | |
82 | ||
83 | static void print_intrinsic(struct mlist *mlp, struct tdesc *tdp, | |
84 | char *format, int level); | |
85 | static void print_forward(struct mlist *mlp, struct tdesc *tdp, | |
86 | char *format, int level); | |
87 | static void print_pointer(struct mlist *mlp, struct tdesc *tdp, | |
88 | char *format, int level); | |
89 | static void print_array(struct mlist *mlp, struct tdesc *tdp, | |
90 | char *format, int level); | |
91 | static void print_function(struct mlist *mlp, struct tdesc *tdp, | |
92 | char *format, int level); | |
93 | static void print_union(struct mlist *mlp, struct tdesc *tdp, | |
94 | char *format, int level); | |
95 | static void print_enum(struct mlist *mlp, struct tdesc *tdp, | |
96 | char *format, int level); | |
97 | static void print_forward(struct mlist *mlp, struct tdesc *tdp, | |
98 | char *format, int level); | |
99 | static void print_typeof(struct mlist *mlp, struct tdesc *tdp, | |
100 | char *format, int level); | |
101 | static void print_struct(struct mlist *mlp, struct tdesc *tdp, | |
102 | char *format, int level); | |
103 | static void print_volatile(struct mlist *mlp, struct tdesc *tdp, | |
104 | char *format, int level); | |
105 | static int stabs_log2(unsigned int value); | |
106 | ||
107 | void | |
108 | genassym_do_intrinsic(struct tdesc *tdp, struct node *np) | |
109 | { | |
110 | if (np->format != NULL) { | |
111 | char *upper = uc(np->format); | |
112 | ||
113 | printf("#define\t%s 0x%x\n", upper, tdp->size); | |
114 | ||
115 | free(upper); | |
116 | } | |
117 | } | |
118 | ||
119 | ||
120 | void | |
121 | genassym_do_sou(struct tdesc *tdp, struct node *np) | |
122 | { | |
123 | struct mlist *mlp; | |
124 | struct child *chp; | |
125 | char *format; | |
126 | ||
127 | if (np->format != NULL) { | |
128 | char *upper = uc(np->format); | |
129 | int l; | |
130 | ||
131 | printf("#define\t%s 0x%x\n", upper, tdp->size); | |
132 | ||
133 | if ((np->format2 != NULL) && | |
134 | (l = stabs_log2(tdp->size)) != -1) { | |
135 | printf("#define\t%s 0x%x\n", np->format2, l); | |
136 | } | |
137 | ||
138 | free(upper); | |
139 | } | |
140 | ||
141 | /* | |
142 | * Run thru all the fields of a struct and print them out | |
143 | */ | |
144 | for (mlp = tdp->data.members.forw; mlp != NULL; mlp = mlp->next) { | |
145 | /* | |
146 | * If there's a child list, only print those members. | |
147 | */ | |
148 | if (np->child != NULL) { | |
149 | if (mlp->name == NULL) | |
150 | continue; | |
151 | chp = find_child(np, mlp->name); | |
152 | if (chp == NULL) | |
153 | continue; | |
154 | format = uc(chp->format); | |
155 | } else { | |
156 | format = NULL; | |
157 | } | |
158 | if (mlp->fdesc == NULL) | |
159 | continue; | |
160 | switch_on_type(mlp, mlp->fdesc, format, 0); | |
161 | if (format != NULL) | |
162 | free(format); | |
163 | } | |
164 | } | |
165 | ||
166 | void | |
167 | genassym_do_enum(struct tdesc *tdp, struct node *np) | |
168 | { | |
169 | int nelem = 0; | |
170 | struct elist *elp; | |
171 | ||
172 | printf("\n"); | |
173 | for (elp = tdp->data.emem; elp != NULL; elp = elp->next) { | |
174 | printf("#define\tENUM_%s 0x%x\n", elp->name, elp->number); | |
175 | nelem++; | |
176 | } | |
177 | printf("%x c-enum .%s\n", nelem, np->name); | |
178 | } | |
179 | ||
180 | static void | |
181 | switch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
182 | { | |
183 | boolean_t allocated = B_FALSE; | |
184 | ||
185 | if (format == NULL) { | |
186 | allocated = B_TRUE; | |
187 | format = uc(mlp->name); | |
188 | } | |
189 | ||
190 | switch (tdp->type) { | |
191 | case INTRINSIC: | |
192 | print_intrinsic(mlp, tdp, format, level); | |
193 | break; | |
194 | case POINTER: | |
195 | print_pointer(mlp, tdp, format, level); | |
196 | break; | |
197 | case ARRAY: | |
198 | print_array(mlp, tdp, format, level); | |
199 | break; | |
200 | case FUNCTION: | |
201 | print_function(mlp, tdp, format, level); | |
202 | break; | |
203 | case UNION: | |
204 | print_union(mlp, tdp, format, level); | |
205 | break; | |
206 | case ENUM: | |
207 | print_enum(mlp, tdp, format, level); | |
208 | break; | |
209 | case FORWARD: | |
210 | print_forward(mlp, tdp, format, level); | |
211 | break; | |
212 | case TYPEOF: | |
213 | print_typeof(mlp, tdp, format, level); | |
214 | break; | |
215 | case STRUCT: | |
216 | print_struct(mlp, tdp, format, level); | |
217 | break; | |
218 | case VOLATILE: | |
219 | print_volatile(mlp, tdp, format, level); | |
220 | break; | |
221 | default: | |
222 | fprintf(stderr, "Switch to Unknown type\n"); | |
223 | error = B_TRUE; | |
224 | break; | |
225 | } | |
226 | if (allocated) | |
227 | free(format); | |
228 | } | |
229 | ||
230 | ||
231 | static void | |
232 | print_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
233 | { | |
234 | fprintf(stderr, "%s never defined\n", mlp->name); | |
235 | error = B_TRUE; | |
236 | } | |
237 | ||
238 | static void | |
239 | print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
240 | { | |
241 | switch_on_type(mlp, tdp->data.tdesc, format, level); | |
242 | } | |
243 | ||
244 | static void | |
245 | print_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
246 | { | |
247 | switch_on_type(mlp, tdp->data.tdesc, format, level); | |
248 | } | |
249 | ||
250 | static void | |
251 | print_intrinsic(struct mlist *mlp, struct tdesc *tdp, | |
252 | char *format, int level) | |
253 | { | |
254 | if (level != 0) { | |
255 | switch (tdp->size) { | |
256 | case 1: | |
257 | printf("/* ' c@ ' %s */", format); | |
258 | break; | |
259 | case 2: | |
260 | printf("/* ' w@ ' %s */", format); | |
261 | break; | |
262 | case 4: | |
263 | printf("/* ' l@ ' %s */", format); | |
264 | break; | |
265 | case 8: | |
266 | printf("/* ' x@ ' %s */", format); | |
267 | break; | |
268 | } | |
269 | /* | |
270 | * Check for bit field. | |
271 | */ | |
272 | } else if (mlp->size != 0 && | |
273 | ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0)) { | |
274 | int offset, shift, mask; | |
275 | ||
276 | offset = (mlp->offset / 32) * 4; | |
277 | shift = 32 - ((mlp->offset % 32) + mlp->size); | |
278 | mask = ((int)pow(2, mlp->size) - 1) << shift; | |
279 | ||
280 | printf("#define\t%s_SHIFT 0x%x\n", format, shift); | |
281 | printf("#define\t%s_MASK 0x%x\n", format, mask); | |
282 | printf("#define\t%s_OFFSET 0x%x\n", format, offset); | |
283 | } else if (mlp->name != NULL) { | |
284 | printf("#define\t%s 0x%x\n", format, mlp->offset / 8); | |
285 | } | |
286 | } | |
287 | ||
288 | static void | |
289 | print_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
290 | { | |
291 | if (level != 0) { | |
292 | switch (tdp->size) { | |
293 | case 1: | |
294 | printf("/* ' c@ ' %s */", format); | |
295 | break; | |
296 | case 2: | |
297 | printf("/* ' w@ ' %s */", format); | |
298 | break; | |
299 | case 4: | |
300 | printf("/* ' l@ ' %s */", format); | |
301 | break; | |
302 | case 8: | |
303 | printf("/* ' x@ ' %s */", format); | |
304 | break; | |
305 | } | |
306 | } else { | |
307 | printf("#define\t%s 0x%x\n", format, mlp->offset / 8); | |
308 | } | |
309 | } | |
310 | ||
311 | static void | |
312 | print_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
313 | { | |
314 | struct ardef *ap = tdp->data.ardef; | |
315 | int items, inc; | |
316 | ||
317 | if (level == 0) { | |
318 | items = ap->indices->range_end - ap->indices->range_start + 1; | |
319 | inc = (mlp->size / items) / 8; | |
320 | printf("#define\t%s 0x%x\n", format, mlp->offset / 8); | |
321 | printf("#define\t%s_INCR 0x%x\n", format, inc); | |
322 | } | |
323 | } | |
324 | ||
325 | static void | |
326 | print_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
327 | { | |
328 | fprintf(stderr, "function in struct %s\n", tdp->name); | |
329 | error = B_TRUE; | |
330 | } | |
331 | ||
332 | static void | |
333 | print_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
334 | { | |
335 | if (level != 0) | |
336 | printf("/* ' noop ' %s */", format); | |
337 | else | |
338 | printf("#define\t%s 0x%x\n", format, mlp->offset / 8); | |
339 | } | |
340 | ||
341 | static void | |
342 | print_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
343 | { | |
344 | if (level != 0) | |
345 | printf("/* ' noop ' %s */", format); | |
346 | else | |
347 | printf("#define\t%s 0x%x\n", format, mlp->offset / 8); | |
348 | } | |
349 | ||
350 | static void | |
351 | print_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level) | |
352 | { | |
353 | if (level != 0) | |
354 | printf("/* ' l@ ' %s */", format); | |
355 | else | |
356 | printf("#define\t%s 0x%x\n", format, mlp->offset / 8); | |
357 | } | |
358 | ||
359 | static int | |
360 | stabs_log2(unsigned int value) | |
361 | { | |
362 | int log = 1; | |
363 | int i; | |
364 | ||
365 | for (i = 0; i < sizeof (value) * 8; i++) { | |
366 | if ((log << i) == value) | |
367 | return (i); | |
368 | } | |
369 | return (-1); | |
370 | } |