⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 annotations.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   int num;   int found = 0;      if ((argc != 2) && (argc != 3)) {      Tcl_AppendResult(interp, "wrong # args: should be \"",                       argv[0], annCmds[5].usage, "\"", NULL);      return TCL_ERROR;   }      if ((argc == 2) || (!strcmp(argv[2], "list"))) {      Tcl_AppendResult(interp, "Annotation List:\n", NULL);            entry = Tcl_FirstHashEntry(&types, &search);            while (entry) {         type = Tcl_GetHashValue(entry);         ASSERT(type);         for (rec = type->recs; rec; rec = rec->next) {            for (cmd = rec->cmds; cmd; cmd = cmd->nextByType) {               Tcl_AppendResult(interp, "annotation set ", type->name, " ", NULL);                              switch (type->argType) {               case ANN_ARGTYPE_NUM:               case ANN_ARGTYPE_SYMBOL:		  PrintLLX(buf,rec->arg);		  strcat(buf," ");                  Tcl_AppendResult(interp, buf, NULL);                  break;               case ANN_ARGTYPE_ENUM:                  if ((rec->arg < type->enumCount) && (type->enumList[rec->arg][0])) {                     Tcl_AppendResult(interp, type->enumList[rec->arg], " ", NULL);                  } else {		     PrintLLD(buf,rec->arg);		     strcat(buf," ");                     Tcl_AppendResult(interp, buf, NULL);                  }                  break;               case ANN_ARGTYPE_NONE:                  break;               default:                  ASSERT(0);                  break;               }               if (cmd->tag) {                  Tcl_AppendResult(interp, "-tag ", cmd->tag->name, " ", NULL);               }#ifdef TCL8               Tcl_AppendResult(interp, "{",                                 Tcl_GetStringFromObj(cmd->compiledscript, NULL),                                "}\n\n", NULL);#else                              Tcl_AppendResult(interp, "{", (char*)cmd->script, "}\n\n", NULL);#endif            }         }         entry = Tcl_NextHashEntry(&search);      }            found = 1;   }   if ((argc == 2) || (!strcmp(argv[2], "tags"))) {      Tcl_AppendResult(interp, "\nAnnotation Tags:\n", NULL);            entry = Tcl_FirstHashEntry(&tags, &search);            while (entry) {         tag = Tcl_GetHashValue(entry);         ASSERT(tag);         Tcl_AppendResult(interp, "\"", tag->name, "\" ", NULL);         for (num=0, cmd=tag->cmds; cmd; num++, cmd=cmd->nextByTag);         sprintf(buf, "enabled mask 0x%x num %d", tag->enabled, num);         Tcl_AppendResult(interp, buf, "\n", NULL);         entry = Tcl_NextHashEntry(&search);      }            Tcl_AppendResult(interp, "\n", NULL);      found = 1;   }   if ((argc == 2) || (!strcmp(argv[2], "types"))) {      Tcl_AppendResult(interp, "Annotation Types:\n", NULL);            entry = Tcl_FirstHashEntry(&types, &search);            while (entry) {         type = Tcl_GetHashValue(entry);         ASSERT(type);                  Tcl_AppendResult(interp, "\"", type->name, "\" ",                          argTypeNames[type->argType], NULL);                  if (type->argType == ANN_ARGTYPE_ENUM) {            Tcl_AppendResult(interp, " {",                             Tcl_Merge(type->enumCount, type->enumList),                             "}", NULL);         }                  numst=0;         numcmds=0;         for (rec=type->recs; rec; numst++, rec=rec->next) {         for (cmd=rec->cmds; cmd; numcmds++, cmd=cmd->nextByType);         }                  sprintf(buf, "subtypes %d commands %d", numst, numcmds);         Tcl_AppendResult(interp, " ", buf, "\n", NULL);         entry = Tcl_NextHashEntry(&search);      }            Tcl_AppendResult(interp, "\n", NULL);      found = 1;   }   if ((argc == 2) || (!strcmp(argv[2], "fm"))) {      AnnFMInfo(interp);      found = 1;   }   if (!found) {      Tcl_AppendResult(interp, "arg not recognized \"", argv[2], "\"", NULL);      return TCL_ERROR;   }      return TCL_OK;}int cmdTrace(Tcl_Interp *interp, int argc, char *argv[]){   char *action = argv[2];   if (argc != 3) {      Tcl_AppendResult(interp, "wrong # args: should be \"",                       argv[0], annCmds[6].usage, "\"", NULL);      return TCL_ERROR;   }   if (!strcmp(action, "off")) {      annTrace.enabled = 0;   } else if (!strcmp(action, "on")) {      annTrace.enabled = 1;   } else {      annTrace.enabled = 2;#ifdef TCL8      annTrace.script = Tcl_NewStringObj(SaveString(action),-1); #else      annTrace.script = SaveString(action);#endif   }   return TCL_OK;}/***************************************************************** *   Annotation - SimOS Interface ****************************************************************/AnnPtr AnnFind(char *typeName, char *argStr){   Tcl_HashEntry *entry;   AnnType *type;   AnnRec *rec;   uint64 arg;   int code;   entry = Tcl_FindHashEntry(&types, typeName);      ASSERT(entry);   type = Tcl_GetHashValue(entry);   ASSERT(type);      code = TranslateArg(NULL, type, argStr, &arg);   ASSERT(code == TCL_OK);   for (rec = type->recs; rec; rec = rec->next) {      if (rec->arg == arg) {         return rec;      }   }   return NULL;}AnnPtr AnnFindInt(char *typeName, uint64 arg){   Tcl_HashEntry *entry;   AnnType *type;   AnnRec *rec;   entry = Tcl_FindHashEntry(&types, typeName);      ASSERT(entry);   type = Tcl_GetHashValue(entry);   ASSERT(type);      for (rec = type->recs; rec; rec = rec->next) {      if (rec->arg == arg) {         return rec;      }   }   return NULL;}uint64 AnnFirst(char *typeName, AnnPtr *iter){   Tcl_HashEntry *entry;   AnnType *type;   entry = Tcl_FindHashEntry(&types, typeName);      ASSERT(entry);   type = Tcl_GetHashValue(entry);   ASSERT(type);      *iter = type->recs;   if (*iter) {      return (*iter)->arg;   }      *iter = NULL;   return 0;}uint64 AnnNext(AnnPtr *iter){   if (!*iter) return 0;   *iter = (*iter)->next;   if (*iter) {      return (*iter)->arg;   }   return 0;}int AnnNumArg(char *typeName){   Tcl_HashEntry *entry;   AnnType *type;   entry = Tcl_FindHashEntry(&types, typeName);   ASSERT(entry);      type = Tcl_GetHashValue(entry);   ASSERT(type);         switch (type->argType) {   case ANN_ARGTYPE_NUM:   case ANN_ARGTYPE_SYMBOL:      return -1;   case ANN_ARGTYPE_ENUM:      return type->enumCount;   case ANN_ARGTYPE_NONE:      return 1;   default:      ASSERT(0);      break;   }      return 0;}static void traceAnnotation(AnnCmd* cmd){   AnnPtr   rec  = cmd->rec;   uint64   arg  = rec->arg;   AnnType* type = rec->type;   int      cpu  = CPUVec.CurrentCpuNum();   char     cpuName[32];   char     *pid, *proc;   uint64   cyclecount;      if (CPUVec.CycleCount) {      cyclecount = CPUVec.CycleCount(cpu);   } else {      cyclecount = 0;   }   sprintf(cpuName,"%d",cpu);       pid = Tcl_GetVar2(TCLInterp,"PID",cpuName,0);   proc = Tcl_GetVar2(TCLInterp,"PROCESS",cpuName,0);   if (!pid)  { pid = "-1";}   if (!proc) { proc = "NONAME";}   CPUPrint("%lld ANN cpu %d %s-%s %s ",            cyclecount, cpu, pid, proc, type->name);   switch (type->argType) {   case ANN_ARGTYPE_NUM:   case ANN_ARGTYPE_SYMBOL:      CPUPrint("0x%llx ", arg);      break;   case ANN_ARGTYPE_ENUM:      if ((arg < type->enumCount) && (type->enumList[arg][0])) {         CPUPrint("%s ", type->enumList[arg]);      } else {         CPUPrint("%lld ", arg);      }      break;   case ANN_ARGTYPE_NONE:      break;   default:      ASSERT(0);      break;   }#ifdef TCL8   CPUPrint("{%s}\n", Tcl_GetStringFromObj(cmd->compiledscript, NULL));   if (annTrace.enabled == 2) {      extern int Tcl_GlobalEvalObj(Tcl_Interp*, Tcl_Obj*);      Tcl_GlobalEvalObj(TCLInterp, annTrace.script);   }#else                  CPUPrint("{%s}\n", (char*) annTrace.script);   if (annTrace.enabled == 2) {      Tcl_GlobalEval(TCLInterp, annTrace.script);   }#endif}void AnnExec(AnnPtr ptr){   AnnCmd *cmd;   int code;   int oldContext;   if (!ptr) {      return;   }   for (cmd = ptr->cmds; cmd; cmd = cmd->nextByType) {      if (!cmd->tag || (IS_CPU_ENABLED(cmd->tag->enabled, CPUVec.CurrentCpuNum()))) {         if (!VisualSetContext(cmd->context, &oldContext))             continue;         if (annTrace.enabled) {            traceAnnotation(cmd);         }#ifdef TCL8         code = Tcl_GlobalEvalObj(cmd->interp, cmd->compiledscript);#else         code = Tcl_GlobalEval(cmd->interp, cmd->script);#endif         VisualSetContext(oldContext, NULL);         if (code != TCL_OK) {#ifdef TCL8               HandleError(cmd->interp,                            Tcl_GetStringFromObj(cmd->compiledscript, NULL));#else               HandleError(cmd->interp, cmd->script);#endif         }      }   }}int TranslateArg(Tcl_Interp *interp, AnnType *type, char *argStr, uint64 *retval){   int i, code;   uint64 val = 0;      switch (type->argType) {   case ANN_ARGTYPE_NUM:      break;   case ANN_ARGTYPE_SYMBOL:      code = SymInt(interp, argStr, &val);      *retval = val;      return code;      /* break; */   case ANN_ARGTYPE_ENUM:      for (i=0; i<type->enumCount; i++) {         if (type->enumList[i][0] && (strcmp(type->enumList[i], argStr) == 0)) {            *retval = i;            return TCL_OK;         }      }      break;   case ANN_ARGTYPE_NONE:      *retval = 0;      return TCL_OK;      /* break; */   default:      ASSERT(0);      return TCL_ERROR;      /* break; */   }#ifdef __alpha   if (sscanf(argStr, "%li", retval) != 1) {#else   if (sscanf(argStr, "%lli", retval) != 1) {#endif      ASSERT(interp);      Tcl_AppendResult(interp, "bad arg \"", argStr, "\"", NULL);      switch (type->argType) {      case ANN_ARGTYPE_NUM:         Tcl_AppendResult(interp, ": expected a number", NULL);         break;      case ANN_ARGTYPE_SYMBOL:         Tcl_AppendResult(interp, ": expected a symbol", NULL);         break;      case ANN_ARGTYPE_ENUM:         Tcl_AppendResult(interp, ": expected one of ", NULL);         for (i=0; i<type->enumCount; i++) {            if (i > 0)               Tcl_AppendResult(interp, ", ", NULL);            Tcl_AppendResult(interp, type->enumList[i], NULL);         }         break;      default:	break;      }      return TCL_ERROR;   }      return TCL_OK;}/***************************************************************** *   Fast Memory (FM) Annotation Lookup * *       This module provides a mechanism for cpu simulators *       to quickly determine if there is a memory annotation *       on a range of addresses. * ****************************************************************/#define NUM_HIST 11#define HASH_TABLE_SIZE 2048#define SECOND_HASH_SHIFT 16#define HASH_FUNC(_va) ((((_va) >> log2RangeSize) \                         ^ ((_va) >> SECOND_HASH_SHIFT)) \                        % HASH_TABLE_SIZE)typedef struct hashBucket {   AnnRec *chain;   int typesInChain;} hashBucket;static hashBucket hashTable[HASH_TABLE_SIZE];static uint rangeSize = -1;static uint log2RangeSize = 0;static uint existingAnns = 0;   /* Keep track of what's been inserted */void AnnFMInit(uint size){   AnnPtr rec = NULL;   VA addr;   int bucket, i;   if (size == rangeSize) {      return;   }   rangeSize = size;   log2RangeSize = GetLog2(rangeSize);      for (i=0; i<HASH_TABLE_SIZE; i++) {      hashTable[i].chain = NULL;      hashTable[i].typesInChain = 0;   }   for (addr = AnnFirst("pc", &rec); rec; addr = AnnNext(&rec)) {      existingAnns |= ANNFM_PC_TYPE;      bucket = HASH_FUNC(addr);      rec->FMHashType = ANNFM_PC_TYPE;      rec->FMHashLink = hashTable[bucket].chain;      hashTable[bucket].chain = rec;      hashTable[bucket].typesInChain |= ANNFM_PC_TYPE;   }   for (addr = AnnFirst("pre-pc", &rec); rec; addr = AnnNext(&rec)) {      existingAnns |= ANNFM_PRE_PC_TYPE;      bucket = HASH_FUNC(addr);      rec->FMHashType = ANNFM_PRE_PC_TYPE;      rec->FMHashLink = hashTable[bucket].chain;      hashTable[bucket].chain = rec;      hashTable[bucket].typesInChain |= ANNFM_PRE_PC_TYPE;      prePCAnnsExist = TRUE;   }   for (addr = AnnFirst("load", &rec); rec; addr = AnnNext(&rec)) {      existingAnns |= ANNFM_LD_TYPE;      bucket = HASH_FUNC(addr);      rec->FMHashType = ANNFM_LD_TYPE;      rec->FMHashLink = hashTable[bucket].chain;      hashTable[bucket].chain = rec;      hashTable[bucket].typesInChain |= ANNFM_LD_TYPE;   }   for (addr = AnnFirst("store", &rec); rec; addr = AnnNext(&rec)) {      existingAnns |= ANNFM_ST_TYPE;      bucket = HASH_FUNC(addr);      rec->FMHashType = ANNFM_ST_TYPE;      rec->FMHashLink = hashTable[bucket].chain;      hashTable[bucket].chain = rec;      hashTable[bucket].typesInChain |= ANNFM_ST_TYPE;   }}static void AnnFMAddDynamic(AnnPtr rec, int type){   VA addr = rec->arg;   int bucket = HASH_FUNC(addr);   /* Check to see if this rec is already in the hash table */   AnnPtr hrec;   for (hrec = hashTable[bucket].chain; hrec; hrec = hrec->FMHashLink) {      if (hrec == rec) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -