Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / support / stabs / asmcheck.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: asmcheck.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 2007 Sun Microsystems, Inc. All rights reserved.
67 * Use is subject to license terms.
68 */
69
70#pragma ident "@(#)asmcheck.c 1.2 07/06/07 SMI"
71
72#include <unistd.h>
73#include <math.h>
74#include "stabs.h"
75
76void asmcheck_do_sou(struct tdesc *tdp, struct node *np);
77void asmcheck_do_enum(struct tdesc *tdp, struct node *np);
78void asmcheck_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
108asmcheck_do_intrinsic(struct tdesc *tdp, struct node *np)
109{
110 if (np->format != NULL) {
111 char *upper = uc(np->format);
112
113 printf("\t/* %s 0x%x */\n", upper, tdp->size);
114
115 free(upper);
116 }
117}
118
119
120void
121asmcheck_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
130 printf("! struct/union %s size 0x%x\n", upper, tdp->size);
131
132#if 0 /* { FIXME: */
133 {
134 int l;
135 if ((np->format2 != NULL) &&
136 (l = stabs_log2(tdp->size)) != -1) {
137 printf("#define\t%s 0x%x\n", np->format2, l);
138 }
139 }
140#endif /* } */
141
142 free(upper);
143 }
144
145 /*
146 * Run thru all the fields of a struct and print them out
147 */
148 for (mlp = tdp->data.members.forw; mlp != NULL; mlp = mlp->next) {
149 /*
150 * If there's a child list, only print those members.
151 */
152 if (np->child != NULL) {
153 if (mlp->name == NULL)
154 continue;
155 chp = find_child(np, mlp->name);
156 if (chp == NULL)
157 continue;
158 format = uc(chp->format);
159 } else {
160 format = NULL;
161 }
162 if (mlp->fdesc == NULL)
163 continue;
164 switch_on_type(mlp, mlp->fdesc, format, 0);
165 if (format != NULL)
166 free(format);
167 }
168}
169
170void
171asmcheck_do_enum(struct tdesc *tdp, struct node *np)
172{
173 int nelem = 0;
174 struct elist *elp;
175
176 printf("\n");
177 for (elp = tdp->data.emem; elp != NULL; elp = elp->next) {
178 printf("#define\tENUM_%s 0x%x\n", elp->name, elp->number);
179 nelem++;
180 }
181 printf("%x c-enum .%s\n", nelem, np->name);
182}
183
184static void
185switch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
186{
187 boolean_t allocated = B_FALSE;
188
189 if (format == NULL) {
190 allocated = B_TRUE;
191 format = uc(mlp->name);
192 }
193
194 switch (tdp->type) {
195 case INTRINSIC:
196 print_intrinsic(mlp, tdp, format, level);
197 break;
198 case POINTER:
199 print_pointer(mlp, tdp, format, level);
200 break;
201 case ARRAY:
202 print_array(mlp, tdp, format, level);
203 break;
204 case FUNCTION:
205 print_function(mlp, tdp, format, level);
206 break;
207 case UNION:
208 print_union(mlp, tdp, format, level);
209 break;
210 case ENUM:
211 print_enum(mlp, tdp, format, level);
212 break;
213 case FORWARD:
214 print_forward(mlp, tdp, format, level);
215 break;
216 case TYPEOF:
217 print_typeof(mlp, tdp, format, level);
218 break;
219 case STRUCT:
220 print_struct(mlp, tdp, format, level);
221 break;
222 case VOLATILE:
223 print_volatile(mlp, tdp, format, level);
224 break;
225 default:
226 fprintf(stderr, "Switch to Unknown type\n");
227 error = B_TRUE;
228 break;
229 }
230 if (allocated)
231 free(format);
232}
233
234
235static void
236print_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
237{
238 fprintf(stderr, "%s never defined\n", mlp->name);
239 error = B_TRUE;
240}
241
242static void
243print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
244{
245 switch_on_type(mlp, tdp->data.tdesc, format, level);
246}
247
248static void
249print_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
250{
251 switch_on_type(mlp, tdp->data.tdesc, format, level);
252}
253
254static void
255print_intrinsic(struct mlist *mlp, struct tdesc *tdp,
256 char *format, int level)
257{
258 if (level != 0) {
259 switch (tdp->size) {
260 case 1:
261 printf("/* ' c@ ' %s */", format);
262 break;
263 case 2:
264 printf("/* ' w@ ' %s */", format);
265 break;
266 case 4:
267 printf("/* ' l@ ' %s */", format);
268 break;
269 case 8:
270 printf("/* ' x@ ' %s */", format);
271 break;
272 }
273 /*
274 * Check for bit field.
275 */
276 } else
277 if (mlp->size != 0 &&
278 ((mlp->size % 8) != 0 || (mlp->offset % (8*tdp->size)) != 0)) {
279 printf("!\tbitfield: @ 0x%x : size = 0x%x\n",
280 mlp->offset, mlp->size);
281#if 0 /* { FIXME: */
282 } else if (mlp->size != 0 &&
283 ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0)) {
284 int offset, shift, mask;
285
286 offset = (mlp->offset / 32) * 4;
287 shift = 32 - ((mlp->offset % 32) + mlp->size);
288 mask = ((int)pow(2, mlp->size) - 1) << shift;
289
290 printf("#define\t%s_SHIFT 0x%x\n", format, shift);
291 printf("#define\t%s_MASK 0x%x\n", format, mask);
292 printf("#define\t%s_OFFSET 0x%x\n", format, offset);
293#endif /* } */
294 } else if (mlp->name != NULL) {
295 char *typ;
296#if 0 /* { FIXME: */
297 printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
298#endif /* } */
299
300 switch (tdp->data.flags) {
301 case Intr_unknown: typ = "X"; break;
302 case Intr_unsigned: typ = "u"; break;
303 case Intr_signed: typ = "s"; break;
304 case Intr_unsigned|Intr_char: typ = "uc"; break;
305 case Intr_signed|Intr_char: typ = "sc"; break;
306 default:
307 abort();
308 }
309 /* tdesc size field is already in bytes */
310 printf("%s\t0x%x\t0x%x\t%s\n", typ,
311 mlp->offset/8, tdp->size, format);
312 }
313}
314
315static void
316print_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
317{
318 if (level != 0) {
319 switch (tdp->size) {
320 case 1:
321 printf("/* ' c@ ' %s */", format);
322 break;
323 case 2:
324 printf("/* ' w@ ' %s */", format);
325 break;
326 case 4:
327 printf("/* ' l@ ' %s */", format);
328 break;
329 case 8:
330 printf("/* ' x@ ' %s */", format);
331 break;
332 }
333 } else {
334#if 0 /* { FIXME: */
335 printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
336#endif /* } */
337 printf("p\t0x%x\t0x%x\t%s\n", mlp->offset / 8, mlp->size/8,
338 format);
339 }
340}
341
342static void
343print_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
344{
345 struct ardef *ap = tdp->data.ardef;
346 int items, inc;
347
348 if (level == 0) {
349 items = ap->indices->range_end - ap->indices->range_start + 1;
350 inc = (mlp->size / items) / 8;
351#if 0 /* { FIXME: */
352 printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
353 printf("#define\t%s_INCR 0x%x\n", format, inc);
354#endif /* } */
355 printf("!\tarray %s @ 0x%x size 0x%x : element size 0x%x\n",
356 format, mlp->offset / 8, mlp->size, inc);
357 switch_on_type(mlp, ap->contents, format, level);
358#if 0 /* { FIXME: */
359 switch (ap->contents->type) {
360 case INTRINSIC:
361 print_intrinsic(mlp, ap->contents, format, level);
362 break;
363
364 case POINTER:
365 print_pointer(mlp, ap->contents, format, level);
366 break;
367
368 default:
369 break;
370 }
371#endif /* } */
372 }
373}
374
375static void
376print_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
377{
378 fprintf(stderr, "function in struct %s\n", tdp->name);
379 error = B_TRUE;
380}
381
382static void
383print_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
384{
385#if 0 /* { FIXME: */
386 if (level != 0)
387 printf("/* ' noop ' %s */", format);
388 else
389 printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
390#endif /* } */
391 printf("!\tstruct %s @ 0x%x has size 0x%x\n",
392 format, mlp->offset / 8, mlp->size / 8);
393}
394
395static void
396print_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
397{
398#if 0 /* { FIXME: */
399 if (level != 0)
400 printf("/* ' noop ' %s */", format);
401 else
402 printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
403#endif /* } */
404 printf("!\tunion %s @ 0x%x has size 0x%x\n",
405 format, mlp->offset / 8, mlp->size / 8);
406}
407
408static void
409print_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
410{
411 if (level != 0)
412 printf("/* ' l@ ' %s */", format);
413 else
414 printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
415}
416
417static int
418stabs_log2(unsigned int value)
419{
420 int log = 1;
421 int i;
422
423 for (i = 0; i < sizeof (value) * 8; i++) {
424 if ((log << i) == value)
425 return (i);
426 }
427 return (-1);
428}