Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / support / stabs / genassym.c
CommitLineData
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
76void genassym_do_sou(struct tdesc *tdp, struct node *np);
77void genassym_do_enum(struct tdesc *tdp, struct node *np);
78void genassym_do_intrinsic(struct tdesc *tdp, struct node *np);
79
80static void switch_on_type(struct mlist *mlp, struct tdesc *tdp,
81 char *format, int level);
82
83static void print_intrinsic(struct mlist *mlp, struct tdesc *tdp,
84 char *format, int level);
85static void print_forward(struct mlist *mlp, struct tdesc *tdp,
86 char *format, int level);
87static void print_pointer(struct mlist *mlp, struct tdesc *tdp,
88 char *format, int level);
89static void print_array(struct mlist *mlp, struct tdesc *tdp,
90 char *format, int level);
91static void print_function(struct mlist *mlp, struct tdesc *tdp,
92 char *format, int level);
93static void print_union(struct mlist *mlp, struct tdesc *tdp,
94 char *format, int level);
95static void print_enum(struct mlist *mlp, struct tdesc *tdp,
96 char *format, int level);
97static void print_forward(struct mlist *mlp, struct tdesc *tdp,
98 char *format, int level);
99static void print_typeof(struct mlist *mlp, struct tdesc *tdp,
100 char *format, int level);
101static void print_struct(struct mlist *mlp, struct tdesc *tdp,
102 char *format, int level);
103static void print_volatile(struct mlist *mlp, struct tdesc *tdp,
104 char *format, int level);
105static int stabs_log2(unsigned int value);
106
107void
108genassym_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
120void
121genassym_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
166void
167genassym_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
180static void
181switch_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
231static void
232print_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
238static void
239print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
240{
241 switch_on_type(mlp, tdp->data.tdesc, format, level);
242}
243
244static void
245print_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
246{
247 switch_on_type(mlp, tdp->data.tdesc, format, level);
248}
249
250static void
251print_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
288static void
289print_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
311static void
312print_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
325static void
326print_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
332static void
333print_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
341static void
342print_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
350static void
351print_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
359static int
360stabs_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}