string _pin_path(struct blk_pin_t * p) { char path[F8_MAX_PATH]; IBlk_path_by_pin(p, path, sizeof(path)); path[sizeof(path) - 1] = 0; return path; }
void CErrorDetector::show() { CInvalidList::iterator i1; CConflictList::iterator i2; char path[F8_MAX_PATH]; struct blk_pin_t * p; struct blk_var_t * v; for(i1 = m_invalidAddress.begin(); i1 != m_invalidAddress.end(); i1++){ if(i1->magic == PIN_MAGIC){ p = (struct blk_pin_t*)i1->o; IBlk_path_by_pin(p, path, sizeof(path)); utils_error( "pin %s, %%%d%05d invalid, type %d\n", path, p->u2.mem_addr.section, p->u2.mem_addr.addr, i1->a ); }else{ v = (struct blk_var_t*)i1->o; IBlk_path_by_blk(v->blk, path, sizeof(path)); strncat(path, ".", sizeof(path)); strncat(path, v->name, sizeof(path)); utils_error( "var %s, %%%d%05d invalid\n", path, v->addr.section, v->addr.addr ); } } }
static void dump_map(int idx) { mem_addr_t addr; char path[F8_MAX_PATH]; int i; if(!_is_valid_section(idx)){ return; } reg_map * rm = &g_regmap[idx]; reg_map_ent * e = rm->bitmap; void * owner = 0; const blk_var_t * var; addr.section = idx; for(i=0; i<rm->total_items; i++, e++){ if(!e->owner){ continue; } addr.addr = i; if(e->owner != owner){ owner = e->owner; utils_trace( "%%%d%05d owned by ", idx, i ); var = query_var_by_addr(&addr); if(var){ IBlk_path_by_blk(var->blk, path, sizeof(path)); utils_trace("{%s}.%s", path, var->name); }else{ IBlk_path_by_pin((struct blk_pin_t*)owner, path, sizeof(path)); utils_trace("%s", path); } utils_trace("\n"); } } }
void CErrorDetector::fix() { CInvalidList::iterator i1; CConflictList::iterator i2; char path[F8_MAX_PATH]; struct blk_pin_t * p; struct blk_var_t * v; for(i1 = m_invalidAddress.begin(); i1 != m_invalidAddress.end(); i1++){ if(i1->magic == PIN_MAGIC){ p = (struct blk_pin_t*)i1->o; IBlk_path_by_pin(p, path, sizeof(path)); utils_error( "pin %s, %%%d%05d invalid, type %d\n", path, p->u2.mem_addr.section, p->u2.mem_addr.addr, i1->a ); switch(i1->a){ case 0: /* allocate a register for this PIN */ break; case 1: p->binding = PIN_B_CONST; break; case 2: break; } }else{ v = (struct blk_var_t*)i1->o; IBlk_path_by_blk(v->blk, path, sizeof(path)); strncat(path, ".", sizeof(path)); strncat(path, v->name, sizeof(path)); utils_error( "var %s, %%%d%05d invalid\n", path, v->addr.section, v->addr.addr ); } } }
/* patch the memory address in a block hive, and remember all register allocated. */ static __bool _alloc_reg_proc(ITreeNode * nd, __bool firstVisit, __uint context) { IBlk * b, *pb; struct blk_pin_t *p, *rp; CRegRequirementList * req; char path[1024]; blk_var_t * v; req = (CRegRequirementList*)context; b = __dcast__(ITreeNode, IBlk, nd); pb = parent_blk(b); for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p)) ){ if(p->_class == PIN_CLASS_EI || p->_class == PIN_CLASS_EO){ continue; } if(p->ulink){ // postpone register allocation until the outmost // parent block is being processed continue; } // ok, do allocation rp = IBlk_real_pin(p); if(rp->binding == PIN_B_CONST){ if(rp->_class == PIN_CLASS_DI){ memcpy(rp->dp, p->dp, _type_size(rp->type)); continue; }else{ req->m_errcode = F8_INVALID_DATA; return __false; } }else if(rp->binding != PIN_B_MEMORY){ req->m_errcode = F8_INVALID_DATA; return __false; } if(pb && p->u2.mem_addr.section == MEM_SECTION_VAR){ // // the pin references a variable // if(v = (blk_var_t * )query_var_by_id(pb, p->u2.mem_addr.addr)){ // // note!! address is fixed on real pin // if(v->type != rp->type){ req->m_errcode = F8_INVALID_DATA; return __false; } rp->u2.mem_addr = v->addr; req->Add(v); }else{ IBlk_path_by_pin(p, path, sizeof(path)); utils_error( "%s references undefined variable %d.\n", path, p->u2.mem_addr.addr ); req->m_errcode = F8_UNRESOLVED_REFERENCES; return __false; } }else{ // // the pin has an address on its own // if(!req->Alloc(rp)){ return __false; } } } return __true; }
/* finding out registers usage info for the block hive */ static __bool _gather_reg_usage(ITreeNode * nd, __bool firstVisit, __uint context) { IBlk * b; struct blk_pin_t *p, *rp; int length; CRegRequirementList * req; struct blk_var_t * var; char pName[F8_MAX_PATH]; b = __dcast__(ITreeNode, IBlk, nd); req = (CRegRequirementList *)context; if(b->h.magic == CBLK_MAGIC && req->m_bGatherForDelete){ enum_variables(b, _e_var, (__uint)req); } for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p))){ /* if the pin is exported, then the variable reference or memory address assignment is counted on the exported pins */ if(p->ulink){ continue; } rp = IBlk_real_pin(p); if(rp->_class != PIN_CLASS_DI && rp->_class != PIN_CLASS_DO){ continue; } if(rp->binding != PIN_B_MEMORY){ continue; } length = _type_size(rp->type); var = (blk_var_t*)query_var_by_pin(p); if(var){ req->Add(var); }else{ if(rp->_class == PIN_CLASS_DI){ if(RtkIsTripleListEmpty(&rp->u1.link)){ /* a data input pin can have a memory address only in two cases: 1) linked. or 2) connected with variable. */ IBlk_path_by_pin(p, pName, sizeof(pName)); utils_error( "%s - DI pin address %%%d%05d incorrect.\n", pName, rp->u2.mem_addr.section, rp->u2.mem_addr.addr ); req->m_errcode = F8_INVALID_DATA; } }else{ if(!is_address_valid(proxy_adapter->kernel, rp, &rp->u2.mem_addr)){ req->m_errcode = F8_INVALID_DATA; IBlk_path_by_pin(p, pName, sizeof(pName)); utils_error( "%s - DO pin address %%%d%05d incorrect.\n", pName, rp->u2.mem_addr.section, rp->u2.mem_addr.addr ); }else{ req->Add(rp, &rp->u2.mem_addr, length); } } } } return __true; }
static void dumpBblk(IBlk * b, FILE * of) { const char * name; char path[F8_MAX_PATH]; char buf[1024]; char idName[128]; struct blk_ent_t be; struct blk_pin_t * p; *buf=0; if(!(parent_blk(b)->h.flags & BLK_F_READONLY)){ name = IBlk_name(b); IBlk_path_by_blk(parent_blk(b), path, sizeof(buf)); if(blklib_query(&b->h.uuid, &be)){ sprintf(buf, "mount path=\"%s\" type=\"%s.%s\" name=\"%s\"", path, be.dir, be.name, name); }else{ f8_uuid_to_string(&b->h.uuid, idName, sizeof(idName)); sprintf(buf, "mount path=\"%s\" id=%s name=\"%s\" ", path, idName, name); } if(of==stdout) utils_trace("%s\n", buf); else fprintf(of, "%s\n", buf); IBlk_path_by_blk(b, path, sizeof(path)); sprintf(buf, "place block \"%s\" (%d,%d)", path, get_res_int(&b->uuid, "x", 0), get_res_int(&b->uuid, "y", 0)); if (of==stdout) utils_trace("%s\n", buf); else fprintf(of, "%s\n", buf); } for(p = __vcall__(b, first_pin, (b)); p; p = __vcall__(b, next_pin, (p))){ if(p->_class != PIN_CLASS_DI && p->_class != PIN_CLASS_DO){ continue; } IBlk_path_by_pin(p, path, sizeof(path)); // dump binding *buf = 0; if(p->binding == PIN_B_CONST){ switch(p->type){ case PIN_T_INTEGER : if(p->dp->u.d.i32 != 0){ sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.i32); } break; case PIN_T_BOOL : if(p->dp->u.d.ui8 != 0){ sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui8); } break; case PIN_T_FLOAT : if(p->dp->u.d.flt != 0){ sprintf(buf, "bind \"%s\" %f", path, p->dp->u.d.flt); } break; case PIN_T_BYTE : if(p->dp->u.d.ui8 != 0){ sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui8); } break; case PIN_T_WORD : if(p->dp->u.d.ui16 != 0){ sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui16); } break; case PIN_T_DOUBLE : if(p->dp->u.d.dbl != 0){ sprintf(buf, "bind \"%s\" %.15f", path, p->dp->u.d.dbl); } break; case PIN_T_DATE : if(fabs(p->dp->u.d.dbl) > 1e-9){ if(p->dp->u.d.dbl > 2.0){ sprintf(buf, "bind \"%s\" t#%fs", path, p->dp->u.d.dbl); }else{ sprintf(buf, "bind \"%s\" t#%fms", path, p->dp->u.d.dbl*1000); } } break; case PIN_T_CHAR : if(p->dp->u.d.i8 != 0){ sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.i8); } break; case PIN_T_SHORT : if(p->dp->u.d.i16 != 0){ sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui16); } break; case PIN_T_DWORD : if(p->dp->u.d.ui32 != 0){ sprintf(buf, "bind \"%s\" %d", path, p->dp->u.d.ui32); } break; } }else { struct blk_var_t * v; v = query_var_by_pin(p); if(v){ char vpath[F8_MAX_PATH]; IBlk_path_by_blk(v->blk, vpath, sizeof(vpath)); sprintf(buf, "bind \"%s\" %s.%s", path, vpath, v->name); // on_bind } } if(*buf){ if(of==stdout) utils_trace("%s\n", buf); else fprintf(of, "%s\n", buf); } if(p->type==PIN_T_BOOL && (p->flags & PIN_F_INVERTED)){ sprintf(buf, "invert \"%s\"", path); if(of==stdout) utils_trace("%s\n", buf); else fprintf(of, "%s\n", buf); } } }
static void dumpCblk(IBlk * b, __bool firstVisit, FILE * of) { const char * name; char path[F8_MAX_PATH]; char buf[1024]; char idName[128]; struct blk_ent_t be; if(firstVisit){ name = IBlk_name(b); IBlk_path_by_blk(parent_blk(b), path, sizeof(path)); if(parent_blk(b) && !(parent_blk(b)->h.flags & BLK_F_READONLY)){ if(b->h.flags & BLK_F_READONLY){ if(blklib_query(&b->h.uuid, &be)){ sprintf(buf, "mount path=\"%s\" type=\"%s.%s\" name=\"%s\"", path, be.dir, be.name, name); }else{ f8_uuid_to_string(&b->h.uuid, idName, sizeof(idName)); sprintf(buf, "mount path=\"%s\" id=%s name=\"%s\"", path, idName, name); } if(of==stdout) utils_trace("%s\n",buf); else fprintf(of, "%s\n", buf); return; }else{ sprintf(buf, "mount path=\"%s\" file=blank.blk name=\"%s\" rw", path, name); } if (of==stdout) utils_trace("%s\n",buf); else fprintf(of, "%s\n", buf); IBlk_path_by_blk(b, path, sizeof(path)); sprintf(buf, "place block \"%s\" (%d,%d)", path, get_res_int(&b->uuid, "x", 0), get_res_int(&b->uuid, "y", 0)); if(of==stdout) utils_trace("%s\n",buf); else fprintf(of, "%s\n", buf); } enum_variables(b, defineVariable, (__uint)of); }else{ /* dump links positions/export pins */ if(b->h.flags & BLK_F_READONLY){ return; } ICBlk * cb = __dcast__(IBlk, ICBlk, b); struct cblk_link_t * l; for(l=ICBlk_first_link(cb); l; l=ICBlk_next_link(l)){ char p1[F8_MAX_PATH]; char p2[F8_MAX_PATH]; IBlk_path_by_pin(l->s.pin, p1, sizeof(p1)); IBlk_path_by_pin(l->t.pin, p2, sizeof(p2)); sprintf(buf, "link \"%s\" \"%s\"", p1, p2); if(of==stdout) utils_trace("%s\n",buf); else fprintf(of, "%s\n", buf); TLinkMetrics *m; m = (TLinkMetrics *)get_res_buf(&l->uuid, 0, "metrics"); if(m){ char *p; p = buf; p += sprintf(p, "place link \"%s\" %d ", p2, m->count); int i; for(i=0; i<m->count; i++){ p += sprintf(p, "(%d,%d) ", m->coord[i].x, m->coord[i].y); } if(of==stdout) utils_trace("%s\n",buf); else fprintf(of, "%s\n", buf); } } } }