17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bdstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bdstevel@tonic-gate * with the License.
87c478bdstevel@tonic-gate *
97c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bdstevel@tonic-gate * See the License for the specific language governing permissions
127c478bdstevel@tonic-gate * and limitations under the License.
137c478bdstevel@tonic-gate *
147c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bdstevel@tonic-gate *
207c478bdstevel@tonic-gate * CDDL HEADER END
217c478bdstevel@tonic-gate */
227c478bdstevel@tonic-gate/*
237c478bdstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
247c478bdstevel@tonic-gate * Use is subject to license terms.
257c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate
277c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bdstevel@tonic-gate
297c478bdstevel@tonic-gate#include <unistd.h>
307c478bdstevel@tonic-gate#include <math.h>
317c478bdstevel@tonic-gate#include "stabs.h"
327c478bdstevel@tonic-gate
337c478bdstevel@tonic-gatevoid genassym_do_sou(struct tdesc *tdp, struct node *np);
347c478bdstevel@tonic-gatevoid genassym_do_enum(struct tdesc *tdp, struct node *np);
357c478bdstevel@tonic-gatevoid genassym_do_intrinsic(struct tdesc *tdp, struct node *np);
367c478bdstevel@tonic-gate
377c478bdstevel@tonic-gatestatic void switch_on_type(struct mlist *mlp, struct tdesc *tdp,
387c478bdstevel@tonic-gate    char *format, int level);
397c478bdstevel@tonic-gate
407c478bdstevel@tonic-gatestatic void print_intrinsic(struct mlist *mlp, struct tdesc *tdp,
417c478bdstevel@tonic-gate    char *format, int level);
427c478bdstevel@tonic-gatestatic void print_forward(struct mlist *mlp, struct tdesc *tdp,
437c478bdstevel@tonic-gate    char *format, int level);
447c478bdstevel@tonic-gatestatic void print_pointer(struct mlist *mlp, struct tdesc *tdp,
457c478bdstevel@tonic-gate    char *format, int level);
467c478bdstevel@tonic-gatestatic void print_array(struct mlist *mlp, struct tdesc *tdp,
477c478bdstevel@tonic-gate    char *format, int level);
487c478bdstevel@tonic-gatestatic void print_function(struct mlist *mlp, struct tdesc *tdp,
497c478bdstevel@tonic-gate    char *format, int level);
507c478bdstevel@tonic-gatestatic void print_union(struct mlist *mlp, struct tdesc *tdp,
517c478bdstevel@tonic-gate    char *format, int level);
527c478bdstevel@tonic-gatestatic void print_enum(struct mlist *mlp, struct tdesc *tdp,
537c478bdstevel@tonic-gate    char *format, int level);
547c478bdstevel@tonic-gatestatic void print_forward(struct mlist *mlp, struct tdesc *tdp,
557c478bdstevel@tonic-gate    char *format, int level);
567c478bdstevel@tonic-gatestatic void print_typeof(struct mlist *mlp, struct tdesc *tdp,
577c478bdstevel@tonic-gate    char *format, int level);
587c478bdstevel@tonic-gatestatic void print_struct(struct mlist *mlp, struct tdesc *tdp,
597c478bdstevel@tonic-gate    char *format, int level);
607c478bdstevel@tonic-gatestatic void print_volatile(struct mlist *mlp, struct tdesc *tdp,
617c478bdstevel@tonic-gate    char *format, int level);
627c478bdstevel@tonic-gatestatic int stabs_log2(unsigned int value);
637c478bdstevel@tonic-gate
647c478bdstevel@tonic-gatevoid
657c478bdstevel@tonic-gategenassym_do_intrinsic(struct tdesc *tdp, struct node *np)
667c478bdstevel@tonic-gate{
677c478bdstevel@tonic-gate	if (np->format != NULL) {
687c478bdstevel@tonic-gate		char *upper = uc(np->format);
697c478bdstevel@tonic-gate
707c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", upper, tdp->size);
717c478bdstevel@tonic-gate
727c478bdstevel@tonic-gate		free(upper);
737c478bdstevel@tonic-gate	}
747c478bdstevel@tonic-gate}
757c478bdstevel@tonic-gate
767c478bdstevel@tonic-gate
777c478bdstevel@tonic-gatevoid
787c478bdstevel@tonic-gategenassym_do_sou(struct tdesc *tdp, struct node *np)
797c478bdstevel@tonic-gate{
807c478bdstevel@tonic-gate	struct mlist *mlp;
817c478bdstevel@tonic-gate	struct child *chp;
827c478bdstevel@tonic-gate	char *format;
837c478bdstevel@tonic-gate
847c478bdstevel@tonic-gate	if (np->format != NULL) {
857c478bdstevel@tonic-gate		char *upper = uc(np->format);
867c478bdstevel@tonic-gate		int l;
877c478bdstevel@tonic-gate
887c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", upper, tdp->size);
897c478bdstevel@tonic-gate
907c478bdstevel@tonic-gate		if ((np->format2 != NULL) &&
917c478bdstevel@tonic-gate		    (l = stabs_log2(tdp->size)) != -1) {
927c478bdstevel@tonic-gate			printf("#define\t%s 0x%x\n", np->format2, l);
937c478bdstevel@tonic-gate		}
947c478bdstevel@tonic-gate
957c478bdstevel@tonic-gate		free(upper);
967c478bdstevel@tonic-gate	}
977c478bdstevel@tonic-gate
987c478bdstevel@tonic-gate	/*
997c478bdstevel@tonic-gate	 * Run thru all the fields of a struct and print them out
1007c478bdstevel@tonic-gate	 */
1017c478bdstevel@tonic-gate	for (mlp = tdp->data.members.forw; mlp != NULL; mlp = mlp->next) {
1027c478bdstevel@tonic-gate		/*
1037c478bdstevel@tonic-gate		 * If there's a child list, only print those members.
1047c478bdstevel@tonic-gate		 */
1057c478bdstevel@tonic-gate		if (np->child != NULL) {
1067c478bdstevel@tonic-gate			if (mlp->name == NULL)
1077c478bdstevel@tonic-gate				continue;
1087c478bdstevel@tonic-gate			chp = find_child(np, mlp->name);
1097c478bdstevel@tonic-gate			if (chp == NULL)
1107c478bdstevel@tonic-gate				continue;
1117c478bdstevel@tonic-gate			format = uc(chp->format);
1127c478bdstevel@tonic-gate		} else {
1137c478bdstevel@tonic-gate			format = NULL;
1147c478bdstevel@tonic-gate		}
1157c478bdstevel@tonic-gate		if (mlp->fdesc == NULL)
1167c478bdstevel@tonic-gate			continue;
1177c478bdstevel@tonic-gate		switch_on_type(mlp, mlp->fdesc, format, 0);
1187c478bdstevel@tonic-gate		if (format != NULL)
1197c478bdstevel@tonic-gate			free(format);
1207c478bdstevel@tonic-gate	}
1217c478bdstevel@tonic-gate}
1227c478bdstevel@tonic-gate
1237c478bdstevel@tonic-gatevoid
1247c478bdstevel@tonic-gategenassym_do_enum(struct tdesc *tdp, struct node *np)
1257c478bdstevel@tonic-gate{
1267c478bdstevel@tonic-gate	int nelem = 0;
1277c478bdstevel@tonic-gate	struct elist *elp;
1287c478bdstevel@tonic-gate
1297c478bdstevel@tonic-gate	printf("\n");
1307c478bdstevel@tonic-gate	for (elp = tdp->data.emem; elp != NULL; elp = elp->next) {
1317c478bdstevel@tonic-gate		printf("#define\tENUM_%s 0x%x\n", elp->name, elp->number);
1327c478bdstevel@tonic-gate		nelem++;
1337c478bdstevel@tonic-gate	}
1347c478bdstevel@tonic-gate	printf("%x c-enum .%s\n", nelem, np->name);
1357c478bdstevel@tonic-gate}
1367c478bdstevel@tonic-gate
1377c478bdstevel@tonic-gatestatic void
1387c478bdstevel@tonic-gateswitch_on_type(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
1397c478bdstevel@tonic-gate{
1407c478bdstevel@tonic-gate	boolean_t allocated = B_FALSE;
1417c478bdstevel@tonic-gate
1427c478bdstevel@tonic-gate	if (format == NULL) {
1437c478bdstevel@tonic-gate		allocated = B_TRUE;
1447c478bdstevel@tonic-gate		format = uc(mlp->name);
1457c478bdstevel@tonic-gate	}
1467c478bdstevel@tonic-gate
1477c478bdstevel@tonic-gate	switch (tdp->type) {
1487c478bdstevel@tonic-gate	case INTRINSIC:
1497c478bdstevel@tonic-gate		print_intrinsic(mlp, tdp, format, level);
1507c478bdstevel@tonic-gate		break;
1517c478bdstevel@tonic-gate	case POINTER:
1527c478bdstevel@tonic-gate		print_pointer(mlp, tdp, format, level);
1537c478bdstevel@tonic-gate		break;
1547c478bdstevel@tonic-gate	case ARRAY:
1557c478bdstevel@tonic-gate		print_array(mlp, tdp, format, level);
1567c478bdstevel@tonic-gate		break;
1577c478bdstevel@tonic-gate	case FUNCTION:
1587c478bdstevel@tonic-gate		print_function(mlp, tdp, format, level);
1597c478bdstevel@tonic-gate		break;
1607c478bdstevel@tonic-gate	case UNION:
1617c478bdstevel@tonic-gate		print_union(mlp, tdp, format, level);
1627c478bdstevel@tonic-gate		break;
1637c478bdstevel@tonic-gate	case ENUM:
1647c478bdstevel@tonic-gate		print_enum(mlp, tdp, format, level);
1657c478bdstevel@tonic-gate		break;
1667c478bdstevel@tonic-gate	case FORWARD:
1677c478bdstevel@tonic-gate		print_forward(mlp, tdp, format, level);
1687c478bdstevel@tonic-gate		break;
1697c478bdstevel@tonic-gate	case TYPEOF:
1707c478bdstevel@tonic-gate		print_typeof(mlp, tdp, format, level);
1717c478bdstevel@tonic-gate		break;
1727c478bdstevel@tonic-gate	case STRUCT:
1737c478bdstevel@tonic-gate		print_struct(mlp, tdp, format, level);
1747c478bdstevel@tonic-gate		break;
1757c478bdstevel@tonic-gate	case VOLATILE:
1767c478bdstevel@tonic-gate		print_volatile(mlp, tdp, format, level);
1777c478bdstevel@tonic-gate		break;
1787c478bdstevel@tonic-gate	default:
1797c478bdstevel@tonic-gate		fprintf(stderr, "Switch to Unknown type\n");
1807c478bdstevel@tonic-gate		error = B_TRUE;
1817c478bdstevel@tonic-gate		break;
1827c478bdstevel@tonic-gate	}
1837c478bdstevel@tonic-gate	if (allocated)
1847c478bdstevel@tonic-gate		free(format);
1857c478bdstevel@tonic-gate}
1867c478bdstevel@tonic-gate
1877c478bdstevel@tonic-gate
1887c478bdstevel@tonic-gatestatic void
1897c478bdstevel@tonic-gateprint_forward(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
1907c478bdstevel@tonic-gate{
1917c478bdstevel@tonic-gate	fprintf(stderr, "%s never defined\n", mlp->name);
1927c478bdstevel@tonic-gate	error = B_TRUE;
1937c478bdstevel@tonic-gate}
1947c478bdstevel@tonic-gate
1957c478bdstevel@tonic-gatestatic void
1967c478bdstevel@tonic-gateprint_typeof(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
1977c478bdstevel@tonic-gate{
1987c478bdstevel@tonic-gate	switch_on_type(mlp, tdp->data.tdesc, format, level);
1997c478bdstevel@tonic-gate}
2007c478bdstevel@tonic-gate
2017c478bdstevel@tonic-gatestatic void
2027c478bdstevel@tonic-gateprint_volatile(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
2037c478bdstevel@tonic-gate{
2047c478bdstevel@tonic-gate	switch_on_type(mlp, tdp->data.tdesc, format, level);
2057c478bdstevel@tonic-gate}
2067c478bdstevel@tonic-gate
2077c478bdstevel@tonic-gatestatic void
2087c478bdstevel@tonic-gateprint_intrinsic(struct mlist *mlp, struct tdesc *tdp,
2097c478bdstevel@tonic-gate    char *format, int level)
2107c478bdstevel@tonic-gate{
2117c478bdstevel@tonic-gate	if (level != 0) {
2127c478bdstevel@tonic-gate		switch (tdp->size) {
2137c478bdstevel@tonic-gate		case 1:
2147c478bdstevel@tonic-gate			printf("/* ' c@ ' %s */", format);
2157c478bdstevel@tonic-gate			break;
2167c478bdstevel@tonic-gate		case 2:
2177c478bdstevel@tonic-gate			printf("/* ' w@ ' %s */", format);
2187c478bdstevel@tonic-gate			break;
2197c478bdstevel@tonic-gate		case 4:
2207c478bdstevel@tonic-gate			printf("/* ' l@ ' %s */", format);
2217c478bdstevel@tonic-gate			break;
2227c478bdstevel@tonic-gate		case 8:
2237c478bdstevel@tonic-gate			printf("/* ' x@ ' %s */", format);
2247c478bdstevel@tonic-gate			break;
2257c478bdstevel@tonic-gate		}
2267c478bdstevel@tonic-gate	/*
2277c478bdstevel@tonic-gate	 * Check for bit field.
2287c478bdstevel@tonic-gate	 */
2297c478bdstevel@tonic-gate	} else if (mlp->size != 0 &&
2307c478bdstevel@tonic-gate	    ((mlp->size % 8) != 0 || (mlp->offset % mlp->size) != 0)) {
2317c478bdstevel@tonic-gate		int offset, shift, mask;
2327c478bdstevel@tonic-gate
2337c478bdstevel@tonic-gate		offset = (mlp->offset / 32) * 4;
2347c478bdstevel@tonic-gate		shift = 32 - ((mlp->offset % 32) + mlp->size);
2357c478bdstevel@tonic-gate		mask = ((int)pow(2, mlp->size) - 1) << shift;
2367c478bdstevel@tonic-gate
2377c478bdstevel@tonic-gate		printf("#define\t%s_SHIFT 0x%x\n", format, shift);
2387c478bdstevel@tonic-gate		printf("#define\t%s_MASK 0x%x\n", format, mask);
2397c478bdstevel@tonic-gate		printf("#define\t%s_OFFSET 0x%x\n", format, offset);
2407c478bdstevel@tonic-gate	} else if (mlp->name != NULL) {
2417c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
2427c478bdstevel@tonic-gate	}
2437c478bdstevel@tonic-gate}
2447c478bdstevel@tonic-gate
2457c478bdstevel@tonic-gatestatic void
2467c478bdstevel@tonic-gateprint_pointer(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
2477c478bdstevel@tonic-gate{
2487c478bdstevel@tonic-gate	if (level != 0) {
2497c478bdstevel@tonic-gate		switch (tdp->size) {
2507c478bdstevel@tonic-gate		case 1:
2517c478bdstevel@tonic-gate			printf("/* ' c@ ' %s */", format);
2527c478bdstevel@tonic-gate			break;
2537c478bdstevel@tonic-gate		case 2:
2547c478bdstevel@tonic-gate			printf("/* ' w@ ' %s */", format);
2557c478bdstevel@tonic-gate			break;
2567c478bdstevel@tonic-gate		case 4:
2577c478bdstevel@tonic-gate			printf("/* ' l@ ' %s */", format);
2587c478bdstevel@tonic-gate			break;
2597c478bdstevel@tonic-gate		case 8:
2607c478bdstevel@tonic-gate			printf("/* ' x@ ' %s */", format);
2617c478bdstevel@tonic-gate			break;
2627c478bdstevel@tonic-gate		}
2637c478bdstevel@tonic-gate	} else {
2647c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
2657c478bdstevel@tonic-gate	}
2667c478bdstevel@tonic-gate}
2677c478bdstevel@tonic-gate
2687c478bdstevel@tonic-gatestatic void
2697c478bdstevel@tonic-gateprint_array(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
2707c478bdstevel@tonic-gate{
2717c478bdstevel@tonic-gate	struct ardef *ap = tdp->data.ardef;
2727c478bdstevel@tonic-gate	int items, inc;
2737c478bdstevel@tonic-gate
2747c478bdstevel@tonic-gate	if (level == 0) {
2757c478bdstevel@tonic-gate		items = ap->indices->range_end - ap->indices->range_start + 1;
2767c478bdstevel@tonic-gate		inc = (mlp->size / items) / 8;
2777c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
2787c478bdstevel@tonic-gate		printf("#define\t%s_INCR 0x%x\n", format, inc);
2797c478bdstevel@tonic-gate	}
2807c478bdstevel@tonic-gate}
2817c478bdstevel@tonic-gate
2827c478bdstevel@tonic-gatestatic void
2837c478bdstevel@tonic-gateprint_function(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
2847c478bdstevel@tonic-gate{
2857c478bdstevel@tonic-gate	fprintf(stderr, "function in struct %s\n", tdp->name);
2867c478bdstevel@tonic-gate	error = B_TRUE;
2877c478bdstevel@tonic-gate}
2887c478bdstevel@tonic-gate
2897c478bdstevel@tonic-gatestatic void
2907c478bdstevel@tonic-gateprint_struct(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
2917c478bdstevel@tonic-gate{
2927c478bdstevel@tonic-gate	if (level != 0)
2937c478bdstevel@tonic-gate		printf("/* ' noop ' %s */", format);
2947c478bdstevel@tonic-gate	else
2957c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
2967c478bdstevel@tonic-gate}
2977c478bdstevel@tonic-gate
2987c478bdstevel@tonic-gatestatic void
2997c478bdstevel@tonic-gateprint_union(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
3007c478bdstevel@tonic-gate{
3017c478bdstevel@tonic-gate	if (level != 0)
3027c478bdstevel@tonic-gate		printf("/* ' noop ' %s */", format);
3037c478bdstevel@tonic-gate	else
3047c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
3057c478bdstevel@tonic-gate}
3067c478bdstevel@tonic-gate
3077c478bdstevel@tonic-gatestatic void
3087c478bdstevel@tonic-gateprint_enum(struct mlist *mlp, struct tdesc *tdp, char *format, int level)
3097c478bdstevel@tonic-gate{
3107c478bdstevel@tonic-gate	if (level != 0)
3117c478bdstevel@tonic-gate		printf("/* ' l@ ' %s */", format);
3127c478bdstevel@tonic-gate	else
3137c478bdstevel@tonic-gate		printf("#define\t%s 0x%x\n", format, mlp->offset / 8);
3147c478bdstevel@tonic-gate}
3157c478bdstevel@tonic-gate
3167c478bdstevel@tonic-gatestatic int
3177c478bdstevel@tonic-gatestabs_log2(unsigned int value)
3187c478bdstevel@tonic-gate{
3197c478bdstevel@tonic-gate	int log = 1;
3207c478bdstevel@tonic-gate	int i;
3217c478bdstevel@tonic-gate
3227c478bdstevel@tonic-gate	for (i = 0; i < sizeof (value) * 8; i++) {
3237c478bdstevel@tonic-gate		if ((log << i) == value)
3247c478bdstevel@tonic-gate			return (i);
3257c478bdstevel@tonic-gate	}
3267c478bdstevel@tonic-gate	return (-1);
3277c478bdstevel@tonic-gate}
328