"I am a person who works hard and plays hard."

Yuan Wei
Second Year Graduate Student Department of Computer Science
University of Virginia Charlottesville, VA 22903
Email: yw3f@cs.virginia.edu


Source Code Analysis

Main Page   Compound List   File List   Compound Members   File Members  

range.c

Go to the documentation of this file.
00001 /*
00002  * range.c - program execution range routines
00003  *
00004  * This file is a part of the SimpleScalar tool suite written by
00005  * Todd M. Austin as a part of the Multiscalar Research Project.
00006  *  
00007  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00008  * 
00009  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00010  *
00011  * This source file is distributed "as is" in the hope that it will be
00012  * useful.  The tool set comes with no warranty, and no author or
00013  * distributor accepts any responsibility for the consequences of its
00014  * use. 
00015  * 
00016  * Everyone is granted permission to copy, modify and redistribute
00017  * this tool set under the following conditions:
00018  * 
00019  *    This source code is distributed for non-commercial use only. 
00020  *    Please contact the maintainer for restrictions applying to 
00021  *    commercial use.
00022  *
00023  *    Permission is granted to anyone to make or distribute copies
00024  *    of this source code, either as received or modified, in any
00025  *    medium, provided that all copyright notices, permission and
00026  *    nonwarranty notices are preserved, and that the distributor
00027  *    grants the recipient permission for further redistribution as
00028  *    permitted by this document.
00029  *
00030  *    Permission is granted to distribute this file in compiled
00031  *    or executable form under the same conditions that apply for
00032  *    source code, provided that either:
00033  *
00034  *    A. it is accompanied by the corresponding machine-readable
00035  *       source code,
00036  *    B. it is accompanied by a written offer, with no time limit,
00037  *       to give anyone a machine-readable copy of the corresponding
00038  *       source code in return for reimbursement of the cost of
00039  *       distribution.  This written offer must permit verbatim
00040  *       duplication by anyone, or
00041  *    C. it is distributed by someone who received only the
00042  *       executable form, and is accompanied by a copy of the
00043  *       written offer of source code that they received concurrently.
00044  *
00045  * In other words, you are welcome to use, share and improve this
00046  * source file.  You are forbidden to forbid anyone else to use, share
00047  * and improve what you give them.
00048  *
00049  * INTERNET: dburger@cs.wisc.edu
00050  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00051  *
00052  * $Id: range.c,v 1.1.1.1 2000/05/26 15:18:59 taustin Exp $
00053  *
00054  * $Log: range.c,v $
00055  * Revision 1.1.1.1  2000/05/26 15:18:59  taustin
00056  * SimpleScalar Tool Set
00057  *
00058  *
00059  * Revision 1.3  1999/12/31 18:46:37  taustin
00060  * quad_t naming conflicts removed
00061  *
00062  * Revision 1.2  1998/08/27 15:50:15  taustin
00063  * implemented host interface description in host.h
00064  * added target interface support
00065  * using new target-dependent myprintf() package
00066  * eliminated compiler warnings
00067  *
00068  * Revision 1.1  1997/03/11  01:32:52  taustin
00069  * Initial revision
00070  *
00071  *
00072  */
00073 
00074 #include <stdio.h>
00075 #include <stdlib.h>
00076 #include <string.h>
00077 #if defined(__CYGWIN32__)
00078 #include <errno.h>
00079 #endif
00080 
00081 #include "host.h"
00082 #include "misc.h"
00083 #include "machine.h"
00084 #include "symbol.h"
00085 #include "loader.h"
00086 #include "range.h"
00087 
00088 /* parse execution position *PSTR to *POS */
00089 char *                                          /* error string, or NULL */
00090 range_parse_pos(char *pstr,                     /* execution position string */
00091                 struct range_pos_t *pos)        /* position return buffer */
00092 {
00093   char *s, *endp;
00094   struct sym_sym_t *sym;
00095 #if !defined(__CYGWIN32__)
00096   extern int errno;
00097 #endif
00098 
00099   /* determine position type */
00100   if (pstr[0] == '@')
00101     {
00102       /* address position */
00103       pos->ptype = pt_addr;
00104       s = pstr + 1;
00105     }
00106   else if (pstr[0] == '#')
00107     {
00108       /* cycle count position */
00109       pos->ptype = pt_cycle;
00110       s = pstr + 1;
00111     }
00112   else
00113     {
00114       /* inst count position */
00115       pos->ptype = pt_inst;
00116       s = pstr;
00117     }
00118 
00119   /* get position value */
00120   errno = 0;
00121   pos->pos = (counter_t)strtoul(s, &endp, /* parse base */0);
00122   if (!errno && !*endp)
00123     {
00124       /* good conversion */
00125       return NULL;
00126     }
00127 
00128   /* else, not an integer, attempt double conversion */
00129   errno = 0;
00130   pos->pos = (counter_t)strtod(s, &endp);
00131   if (!errno && !*endp)
00132     {
00133       /* good conversion */
00134       /* FIXME: ignoring decimal point!! */
00135       return NULL;
00136     }
00137 
00138   /* else, attempt symbol lookup */
00139   sym_loadsyms(ld_prog_fname, /* !locals */FALSE);
00140   sym = sym_bind_name(s, NULL, sdb_any);
00141   if (sym != NULL)
00142     {
00143       pos->pos = (counter_t)sym->addr;
00144       return NULL;
00145     }
00146 
00147   /* else, no binding made */
00148   return "cannot bind execution position to a value";
00149 }
00150 
00151 /* print execution position *POS */
00152 void
00153 range_print_pos(struct range_pos_t *pos,        /* execution position */
00154                 FILE *stream)                   /* output stream */
00155 {
00156   switch (pos->ptype)
00157     {
00158     case pt_addr:
00159       myfprintf(stream, "@0x%08p", (md_addr_t)pos->pos);
00160       break;
00161     case pt_inst:
00162       fprintf(stream, "%.0f", (double)pos->pos);
00163       break;
00164     case pt_cycle:
00165       fprintf(stream, "#%.0f", (double)pos->pos);
00166       break;
00167     default:
00168       panic("bogus execution position type");
00169     }
00170 }
00171 
00172 /* parse execution range *RSTR to *RANGE */
00173 char *                                          /* error string, or NULL */
00174 range_parse_range(char *rstr,                   /* execution range string */
00175                   struct range_range_t *range)  /* range return buffer */
00176 {
00177   char *pos1, *pos2, *p, buf[512], *errstr;
00178 
00179   /* make a copy of the execution range */
00180   strcpy(buf, rstr);
00181   pos1 = buf;
00182 
00183   /* find mid-point */
00184   p = buf;
00185   while (*p != ':' && *p != '\0')
00186     {
00187       p++;
00188     }
00189   if (*p != ':')
00190     return "badly formed execution range";
00191   *p = '\0';
00192 
00193   /* this is where the second position will start */
00194   pos2 = p + 1;
00195 
00196   /* parse start position */
00197   if (*pos1 && *pos1 != ':')
00198     {
00199       errstr = range_parse_pos(pos1, &range->start);
00200       if (errstr)
00201         return errstr;
00202     }
00203   else
00204     {
00205       /* default start range */
00206       range->start.ptype = pt_inst;
00207       range->start.pos = 0;
00208     }
00209 
00210   /* parse end position */
00211   if (*pos2)
00212     {
00213       if (*pos2 == '+')
00214         {
00215           int delta;
00216           char *endp;
00217 #if !defined(__CYGWIN32__)
00218           extern int errno;
00219 #endif
00220 
00221           /* get delta value */
00222           errno = 0;
00223           delta = strtol(pos2 + 1, &endp, /* parse base */0);
00224           if (!errno && !*endp)
00225             {
00226               /* good conversion */
00227               range->end.ptype = range->start.ptype;
00228               range->end.pos = range->start.pos + delta;
00229             }
00230           else
00231             {
00232               /* bad conversion */
00233               return "badly formed execution range delta";
00234             }
00235         }
00236       else
00237         {
00238           errstr = range_parse_pos(pos2, &range->end);
00239           if (errstr)
00240             return errstr;
00241         }
00242     }
00243   else
00244     {
00245       /* default end range */
00246       range->end.ptype = range->start.ptype;
00247 #ifdef HOST_HAS_QWORD
00248       range->end.pos = ULL(0x7fffffffffffffff);
00249 #else /* !__GNUC__ */
00250       range->end.pos = 281474976645120.0;
00251 #endif /* __GNUC__ */
00252     }
00253 
00254   /* no error */
00255   return NULL;
00256 }
00257 
00258 /* print execution range *RANGE */
00259 void
00260 range_print_range(struct range_range_t *range,  /* execution range */
00261                   FILE *stream)                 /* output stream */
00262 {
00263   range_print_pos(&range->start, stream);
00264   fprintf(stream, ":");
00265   range_print_pos(&range->end, stream);
00266 }
00267 
00268 /* determine if inputs match execution position */
00269 int                                             /* relation to position */
00270 range_cmp_pos(struct range_pos_t *pos,          /* execution position */
00271               counter_t val)                    /* position value */
00272 {
00273   if (val < pos->pos)
00274     return /* before */-1;
00275   else if (val == pos->pos)
00276     return /* equal */0;
00277   else /* if (pos->pos < val) */
00278     return /* after */1;
00279 }
00280 
00281 /* determine if inputs are in range */
00282 int                                             /* relation to range */
00283 range_cmp_range(struct range_range_t *range,    /* execution range */
00284                 counter_t val)                  /* position value */
00285 {
00286   if (range->start.ptype != range->end.ptype)
00287     panic("invalid range");
00288 
00289   if (val < range->start.pos)
00290     return /* before */-1;
00291   else if (range->start.pos <= val && val <= range->end.pos)
00292     return /* inside */0;
00293   else /* if (range->end.pos < val) */
00294     return /* after */1;
00295 }
00296 
00297 /* determine if inputs are in range, passes all possible info needed */
00298 int                                             /* relation to range */
00299 range_cmp_range1(struct range_range_t *range,   /* execution range */
00300                  md_addr_t addr,                /* address value */
00301                  counter_t icount,              /* instruction count */
00302                  counter_t cycle)               /* cycle count */
00303 {
00304   if (range->start.ptype != range->end.ptype)
00305     panic("invalid range");
00306 
00307   switch (range->start.ptype)
00308     {
00309     case pt_addr:
00310       if (addr < (md_addr_t)range->start.pos)
00311         return /* before */-1;
00312       else if ((md_addr_t)range->start.pos <= addr && addr <= (md_addr_t)range->end.pos)
00313         return /* inside */0;
00314       else /* if (range->end.pos < addr) */
00315         return /* after */1;
00316       break;
00317     case pt_inst:
00318       if (icount < range->start.pos)
00319         return /* before */-1;
00320       else if (range->start.pos <= icount && icount <= range->end.pos)
00321         return /* inside */0;
00322       else /* if (range->end.pos < icount) */
00323         return /* after */1;
00324       break;
00325     case pt_cycle:
00326       if (cycle < range->start.pos)
00327         return /* before */-1;
00328       else if (range->start.pos <= cycle && cycle <= range->end.pos)
00329         return /* inside */0;
00330       else /* if (range->end.pos < cycle) */
00331         return /* after */1;
00332       break;
00333     default:
00334       panic("bogus range type");
00335     }
00336 }


UVa CS Department of Computer Science
School of Engineering, University of Virginia
151 Engineer's Way, P.O. Box 400740
Charlottesville, Virginia 22904-4740

(434) 982-2200  Fax: (434) 982-2214