1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 1996-2002 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <unistd.h>
30#include <math.h>
31#include "stabs.h"
32
33void forth_do_sou(struct tdesc *tdp, struct node *np);
34void forth_do_enum(struct tdesc *tdp, struct node *np);
35void forth_do_intrinsic(struct tdesc *tdp, struct node *np);
36
37static void switch_on_type(struct mlist *mlp, struct tdesc *tdp,
38    char *format, int level);
39
40static void print_intrinsic(struct mlist *mlp, struct tdesc *tdp,
41    char *format, int level);
42static void print_forward(struct mlist *mlp, struct tdesc *tdp,
43    char *format, int level);
44static void print_pointer(struct mlist *mlp, struct tdesc *tdp,
45    char *format, int level);
46static void print_array(struct mlist *mlp, struct tdesc *tdp,
47    char *format, int level);
48static void print_function(struct mlist *mlp, struct tdesc *tdp,
49    char *format, int level);
50static void print_union(struct mlist *mlp, struct tdesc *tdp,
51    char *format, int level);
52static void print_enum(struct mlist *mlp, struct tdesc *tdp,
53    char *format, int level);
54static void print_forward(struct mlist *mlp, struct tdesc *tdp,
55    char *format, int level);
56static void print_typeof(struct mlist *mlp, struct tdesc *tdp,
57    char *format, int level);
58static void print_struct(struct mlist *mlp, struct tdesc *tdp,
59    char *format, int level);
60static void print_volatile(struct mlist *mlp, struct tdesc *tdp,
61    char *format, int level);
62
63void
64forth_do_intrinsic(struct tdesc *tdp, struct node *np)
65{
66}
67
68void
69forth_do_sou(struct tdesc *tdp, struct node *np)
70{
71	struct mlist *mlp;
72	struct child *chp;
73	char *format;
74
75	printf("\n");
76	printf("vocabulary %s-words\n", np->name);
77	printf("h# %x constant %s-sz\n", tdp->size, np->name);
78	printf("%x ' %s-words c-struct .%s\n",
79		tdp->size, np->name, np->name);
80	printf("also %s-words definitions\n\n", np->name);
81
82	/*
83	 * Run thru all the fields of a struct and print them out
84	 */
85	for (mlp = tdp->data.members.back; mlp != NULL; mlp = mlp->prev) {
86		/*
87		 * If there's a child list, only print those members.
88		 */
89		if (np->child) {
90			if (mlp->name == NULL)
91				continue;
92			chp = find_child(np, mlp->name);
93			if (chp == NULL)
94				continue;
95			format = chp->format;
96		} else
97			format = NULL;
98		if (mlp->fdesc == NULL)
99			continue;
100		switch_on_type(mlp, mlp->fdesc, format, 0);
101	}
102	printf("\nkdbg-words definitions\n");
103	printf("previous\n\n");
104	printf("\\ end %s section\n\n", np->name);
105}
106
107void
108forth_do_enum(struct tdesc *tdp, struct node *np)
109{
110	int nelem = 0;
111	struct elist *elp;
112
113	printf("\n");
114	for (elp = tdp->data.emem; elp != NULL; elp = elp->next) {
115		printf("here ,\" %s\" %x\n", elp->name, elp->number);
116		nelem++;
117	}
118	printf("%x c-enum .%s\n", nelem, np->name);
119}
120
121static void
122switch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
123{
124	switch (tdp->type) {
125	case INTRINSIC:
126		print_intrinsic(mlp, tdp, format, level);
127		break;
128	case POINTER:
129		print_pointer(mlp, tdp, format, level);
130		break;
131	case ARRAY:
132		print_array(mlp, tdp, format, level);
133		break;
134	case FUNCTION:
135		print_function(mlp, tdp, format, level);
136		break;
137	case UNION:
138		print_union(mlp, tdp, format, level);
139		break;
140	case ENUM:
141		print_enum(mlp, tdp, format, level);
142		break;
143	case FORWARD:
144		print_forward(mlp, tdp, format, level);
145		break;
146	case TYPEOF:
147		print_typeof(mlp, tdp, format, level);
148		break;
149	case STRUCT:
150		print_struct(mlp, tdp, format, level);
151		break;
152	case VOLATILE:
153		print_volatile(mlp, tdp, format, level);
154		break;
155	default:
156		fprintf(stderr, "Switch to Unknown type\n");
157		error = B_TRUE;
158		break;
159	}
160}
161
162static void
163print_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
164{
165	fprintf(stderr, "%s never defined\n", mlp->name);
166	error = B_TRUE;
167}
168
169static void
170print_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
171{
172	switch_on_type(mlp, tdp->data.tdesc, format, level);
173}
174
175static void
176print_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
177{
178	switch_on_type(mlp, tdp->data.tdesc, format, level);
179}
180
181static void
182print_intrinsic(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
183{
184	format = convert_format(format, ".x");
185
186	if (level != 0) {
187		switch (tdp->size) {
188		case 1:
189			printf("' c@ ' %s", format);
190			break;
191		case 2:
192			printf("' w@ ' %s", format);
193			break;
194		case 4:
195			printf("' l@ ' %s", format);
196			break;
197		case 8:
198			printf("' x@ ' %s", format);
199			break;
200		}
201	/*
202	 * Check for bit field.
203	 */
204	} else if (mlp->size != 0 &&
205	    ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0)) {
206		int offset, shift, mask;
207
208		offset = (mlp->offset / 32) * 4;
209		shift = 32 - ((mlp->offset % 32) + mlp->size);
210		mask = ((int)pow(2, mlp->size) - 1) << shift;
211		printf("' %s %x %x %x bits-field %s\n",
212			format, shift, mask, offset, mlp->name);
213	} else if (mlp->name != NULL) {
214		switch (tdp->size) {
215		case 1:
216			printf("' %s %x byte-field %s\n",
217				format, mlp->offset / 8, mlp->name);
218			break;
219		case 2:
220			printf("' %s %x short-field %s\n",
221				format, mlp->offset / 8, mlp->name);
222			break;
223		case 4:
224			printf("' %s %x long-field %s\n",
225				format, mlp->offset / 8, mlp->name);
226			break;
227		case 8:
228			printf("' %s %x ext-field %s\n",
229				format, mlp->offset / 8, mlp->name);
230			break;
231		}
232	}
233}
234
235static void
236print_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
237{
238	format = convert_format(format, ".x");
239	if (level != 0) {
240		switch (tdp->size) {
241		case 1:
242			printf("' c@ ' %s", format);
243			break;
244		case 2:
245			printf("' w@ ' %s", format);
246			break;
247		case 4:
248			printf("' l@ ' %s", format);
249			break;
250		case 8:
251			printf("' x@ ' %s", format);
252			break;
253		}
254	} else {
255		printf("' %s %x ptr-field %s\n",
256		    format, mlp->offset / 8, mlp->name);
257	}
258}
259
260static void
261print_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
262{
263	struct ardef *ap = tdp->data.ardef;
264	int items, inc, limit;
265
266	if (level > 0) {
267		printf("' noop ' .x");
268	} else {
269		items = ap->indices->range_end - ap->indices->range_start + 1;
270		inc = (mlp->size / items) / 8;
271		limit = mlp->size / 8;
272		switch_on_type(mlp, ap->contents, format, level + 1);
273		printf(" %x %x %x array-field", limit, inc, mlp->offset / 8);
274		printf(" %s\n", mlp->name);
275	}
276}
277
278static void
279print_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
280{
281	fprintf(stderr, "function in struct %s\n", tdp->name);
282	error = B_TRUE;
283}
284
285static void
286print_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
287{
288	format = convert_format(format, ".x");
289	if (level != 0)
290		printf("' noop ' %s", format);
291	else {
292		printf("' %s %x struct-field %s\n",
293			format, mlp->offset / 8, mlp->name);
294	}
295}
296
297static void
298print_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
299{
300	format = convert_format(format, ".x");
301	if (level != 0)
302		printf("' noop ' %s", format);
303	else {
304		printf("' %s %x struct-field %s\n",
305			format, mlp->offset / 8, mlp->name);
306	}
307}
308
309static void
310print_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
311{
312	format = convert_format(format, ".d");
313
314	if (level != 0)
315		printf("' l@ ' %s", format);
316	else
317		printf("' %s %x long-field %s\n",
318			format, mlp->offset / 8, mlp->name);
319}
320