17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
22*e5803b76SAdam H. Leventhal 
237c478bd9Sstevel@tonic-gate /*
247c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
257c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
28*e5803b76SAdam H. Leventhal /*
29*e5803b76SAdam H. Leventhal  * Copyright (c) 2012 by Delphix. All rights reserved.
30*e5803b76SAdam H. Leventhal  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/bitmap.h>
347c478bd9Sstevel@tonic-gate #include <assert.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
367c478bd9Sstevel@tonic-gate #include <stdlib.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <dt_regset.h>
39*e5803b76SAdam H. Leventhal #include <dt_impl.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate dt_regset_t *
dt_regset_create(ulong_t nregs)42*e5803b76SAdam H. Leventhal dt_regset_create(ulong_t nregs)
437c478bd9Sstevel@tonic-gate {
44*e5803b76SAdam H. Leventhal 	ulong_t n = BT_BITOUL(nregs);
457c478bd9Sstevel@tonic-gate 	dt_regset_t *drp = malloc(sizeof (dt_regset_t));
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate 	if (drp == NULL)
487c478bd9Sstevel@tonic-gate 		return (NULL);
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	drp->dr_bitmap = malloc(sizeof (ulong_t) * n);
51*e5803b76SAdam H. Leventhal 	drp->dr_size = nregs;
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate 	if (drp->dr_bitmap == NULL) {
547c478bd9Sstevel@tonic-gate 		dt_regset_destroy(drp);
557c478bd9Sstevel@tonic-gate 		return (NULL);
567c478bd9Sstevel@tonic-gate 	}
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 	bzero(drp->dr_bitmap, sizeof (ulong_t) * n);
597c478bd9Sstevel@tonic-gate 	return (drp);
607c478bd9Sstevel@tonic-gate }
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate void
dt_regset_destroy(dt_regset_t * drp)637c478bd9Sstevel@tonic-gate dt_regset_destroy(dt_regset_t *drp)
647c478bd9Sstevel@tonic-gate {
657c478bd9Sstevel@tonic-gate 	free(drp->dr_bitmap);
667c478bd9Sstevel@tonic-gate 	free(drp);
677c478bd9Sstevel@tonic-gate }
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate void
dt_regset_reset(dt_regset_t * drp)707c478bd9Sstevel@tonic-gate dt_regset_reset(dt_regset_t *drp)
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate 	bzero(drp->dr_bitmap, sizeof (ulong_t) * BT_BITOUL(drp->dr_size));
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate 
75*e5803b76SAdam H. Leventhal void
dt_regset_assert_free(dt_regset_t * drp)76*e5803b76SAdam H. Leventhal dt_regset_assert_free(dt_regset_t *drp)
77*e5803b76SAdam H. Leventhal {
78*e5803b76SAdam H. Leventhal 	int reg;
79*e5803b76SAdam H. Leventhal 	boolean_t fail = B_FALSE;
80*e5803b76SAdam H. Leventhal 	for (reg = 0; reg < drp->dr_size; reg++) {
81*e5803b76SAdam H. Leventhal 		if (BT_TEST(drp->dr_bitmap, reg) != 0)  {
82*e5803b76SAdam H. Leventhal 			dt_dprintf("%%r%d was left allocated\n", reg);
83*e5803b76SAdam H. Leventhal 			fail = B_TRUE;
84*e5803b76SAdam H. Leventhal 		}
85*e5803b76SAdam H. Leventhal 	}
86*e5803b76SAdam H. Leventhal 
87*e5803b76SAdam H. Leventhal 	/*
88*e5803b76SAdam H. Leventhal 	 * We set this during dtest runs to check for register leaks.
89*e5803b76SAdam H. Leventhal 	 */
90*e5803b76SAdam H. Leventhal 	if (fail && getenv("DTRACE_DEBUG_REGSET") != NULL)
91*e5803b76SAdam H. Leventhal 		abort();
92*e5803b76SAdam H. Leventhal }
93*e5803b76SAdam H. Leventhal 
947c478bd9Sstevel@tonic-gate int
dt_regset_alloc(dt_regset_t * drp)957c478bd9Sstevel@tonic-gate dt_regset_alloc(dt_regset_t *drp)
967c478bd9Sstevel@tonic-gate {
977c478bd9Sstevel@tonic-gate 	ulong_t nbits = drp->dr_size - 1;
987c478bd9Sstevel@tonic-gate 	ulong_t maxw = nbits >> BT_ULSHIFT;
997c478bd9Sstevel@tonic-gate 	ulong_t wx;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	for (wx = 0; wx <= maxw; wx++) {
1027c478bd9Sstevel@tonic-gate 		if (drp->dr_bitmap[wx] != ~0UL)
1037c478bd9Sstevel@tonic-gate 			break;
1047c478bd9Sstevel@tonic-gate 	}
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	if (wx <= maxw) {
1077c478bd9Sstevel@tonic-gate 		ulong_t maxb = (wx == maxw) ? nbits & BT_ULMASK : BT_NBIPUL - 1;
1087c478bd9Sstevel@tonic-gate 		ulong_t word = drp->dr_bitmap[wx];
1097c478bd9Sstevel@tonic-gate 		ulong_t bit, bx;
1107c478bd9Sstevel@tonic-gate 		int reg;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 		for (bit = 1, bx = 0; bx <= maxb; bx++, bit <<= 1) {
1137c478bd9Sstevel@tonic-gate 			if ((word & bit) == 0) {
1147c478bd9Sstevel@tonic-gate 				reg = (int)((wx << BT_ULSHIFT) | bx);
1157c478bd9Sstevel@tonic-gate 				BT_SET(drp->dr_bitmap, reg);
1167c478bd9Sstevel@tonic-gate 				return (reg);
1177c478bd9Sstevel@tonic-gate 			}
1187c478bd9Sstevel@tonic-gate 		}
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate 
121*e5803b76SAdam H. Leventhal 	xyerror(D_NOREG, "Insufficient registers to generate code");
122*e5803b76SAdam H. Leventhal 	/*NOTREACHED*/
123*e5803b76SAdam H. Leventhal 	return (-1);
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate void
dt_regset_free(dt_regset_t * drp,int reg)1277c478bd9Sstevel@tonic-gate dt_regset_free(dt_regset_t *drp, int reg)
1287c478bd9Sstevel@tonic-gate {
129*e5803b76SAdam H. Leventhal 	assert(reg >= 0 && reg < drp->dr_size);
1307c478bd9Sstevel@tonic-gate 	assert(BT_TEST(drp->dr_bitmap, reg) != 0);
1317c478bd9Sstevel@tonic-gate 	BT_CLEAR(drp->dr_bitmap, reg);
1327c478bd9Sstevel@tonic-gate }
133