/* CoreFlat.c */ #include "CoreBasics.h" #include "Core.h" #include "CoreFlat.h" /* Types */ FlatCellTypeRec rootCellType; FlatCellTypeRec allFlatCells; WirePathRec rootWirePath; /* Flat Instance */ Bool InstancePathEqualRec(one, other) InstancePathRec one; InstancePathRec other; { Nat i; if (one.length!=other.length) return(false); for (i=0; i<CellTypePathSize; i++) if (one.bits[i]!=other.bits[i]) return(false); return(true); }; Nat InstancePathHashRec(path) InstancePathRec path; { Nat hash=0; Nat i; for (i=0; i<=path.length; i++) hash=hash↑(path.bits[i]<<(i%16)); return(hash); }; void ExtendPath(newPath, currentPath, index, rct) InstancePath newPath; InstancePathRec currentPath; Nat index; RecordCellType rct; { Nat bit; Nat pathBits=NBits(rct->size); *newPath=currentPath; for (bit=0; bit<pathBits; bit++) newPath->bits[newPath->length+bit]=EBFN(index, bit, pathBits); newPath->length+=pathBits; }; typedef struct BindPublicToActualContextRec { HashTable bindings; HashTable newBindings; FlatCellTypeRec parent; } BindPublicToActualContextRec; typedef BindPublicToActualContextRec *BindPublicToActualContext; Bool BindPublicToActual(actualWire, publicWire, context, subWires) Wire actualWire; Wire publicWire; Ref context; Bool *subWires; { BindPublicToActualContext c=(BindPublicToActualContext)context; FlatWire bind=nil; *subWires=true; if (c->bindings!=nil) bind=(FlatWire)HashTableGet(c->bindings, actualWire); if (bind==nil) bind=CreateFlatWire(c->parent, 0, internal, false, rootWirePath, actualWire); HashTablePut(c->newBindings, publicWire, bind); return(false); }; HashTable BindInstance(parent, actual, public, bindings) FlatCellTypeRec parent; WireSeq actual; WireSeq public; HashTable bindings; { BindPublicToActualContextRec context; context.bindings=bindings; context.newBindings=HashTableCreate(17, nil, nil); context.parent=parent; if (VisitBindingSeq(actual, public, BindPublicToActual, &context)) Die; return(context.newBindings); }; /* Flat Cell Type */ Bool FlatCellTypeEqualRec(one, other) FlatCellTypeRec one; FlatCellTypeRec other; { return(InstancePathEqualRec(one.path, other.path) && one.recastCount==other.recastCount); }; Nat FlatCellTypeHashRec(flatCell) FlatCellTypeRec flatCell; { Nat hash=InstancePathHashRec(flatCell.path); hash=hash↑flatCell.recastCount; return(hash); }; /* Flat Wire */ FlatWire CreateFlatWire(flatCell, instanceIndex, wireRoot, validPath, path, wire) FlatCellTypeRec flatCell; Nat instanceIndex; WireRoot wireRoot; Bool validPath; WirePathRec path; Wire wire; { FlatWire flatWire=New(FlatWire, FlatWireRec); flatWire->flatCell=flatCell; flatWire->instanceIndex=instanceIndex; flatWire->wireRoot=wireRoot; flatWire->validPath=validPath; flatWire->path=path; flatWire->wire=wire; return(flatWire); }; Bool FlatWireEqual(key1, key2) Ref key1; Ref key2; { FlatWire wire1=(FlatWire)key1; FlatWire wire2=(FlatWire)key2; return(wire1->wire==wire2->wire && FlatCellTypeEqualRec(wire1->flatCell, wire2->flatCell)); }; Nat FlatWireHash(key) Ref key; { FlatWire flatWire=(FlatWire)key; Nat hash=FlatCellTypeHashRec(flatWire->flatCell); hash=hash↑(((Nat)flatWire->wire)&0x0FFFFL)↑(((Nat)flatWire->wire)>>16); return(hash); }; /* Enumeration */ void NextUnboundCellType(cell, target, flatCell, instance, index, parent, flatParent, data, proc) CellType cell; FlatCellTypeRec target; FlatCellTypeRec flatCell; CellInstance instance; Nat index; CellType parent; FlatCellTypeRec flatParent; Ref data; UnboundFlatCellProc proc; { if (FlatCellTypeEqualRec(target, flatCell)) return; if (cell->class==recordCellClass) { RecordCellType rct=(RecordCellType)cell->data; Nat pathBits=NBits(rct->size); CellInstance instance; FlatCellTypeRec childFlatCell; childFlatCell.path=flatCell.path; childFlatCell.recastCount=0; if (FlatCellTypeEqualRec(target, allFlatCells)) { Nat inst; for (inst=0; inst<rct->size; inst++) { instance=rct->cellInstances[inst]; ExtendPath(&childFlatCell.path, flatCell.path, inst, rct); proc(instance->type, target, childFlatCell, instance, inst, cell, flatCell, data); }; } else Die; } else Die; }; typedef struct BindCellTypeContextRec { CellType previousCell; CellInstance previousInstance; Ref data; HashTable bindings; BoundFlatCellProc proc; } BindCellTypeContextRec; typedef BindCellTypeContextRec *BindCellTypeContext; void BindCellType(cell, target, flatCell, instance, index, parent, flatParent, data) CellType cell; FlatCellTypeRec target; FlatCellTypeRec flatCell; CellInstance instance; Nat index; CellType parent; FlatCellTypeRec flatParent; Ref data; { BindCellTypeContext context=(BindCellTypeContext)data; HashTable newBindings; if (instance==context->previousInstance && cell==context->previousCell) context->proc(cell, target, flatCell, instance, index, parent, flatParent, context->data, context->bindings); else { Wire actual; if (instance==nil || instance->type!=cell) actual=context->previousCell->public; else actual=instance->actual; newBindings=BindInstance(flatParent, actual, cell->public, context->bindings); context->proc(cell, target, flatCell, instance, index, parent, flatParent, context->data, newBindings); /* really should delete the flat wires which are no longer needed */ HashTableFree(newBindings); }; }; void NextBoundCellType(cell, target, flatCell, instance, index, parent, flatParent, data, bindings, proc) CellType cell; FlatCellTypeRec target; FlatCellTypeRec flatCell; CellInstance instance; Nat index; CellType parent; FlatCellTypeRec flatParent; Ref data; HashTable bindings; UnboundFlatCellProc proc; { BindCellTypeContextRec context; context.previousCell=cell; context.previousInstance=instance; context.data=data; context.bindings=bindings; context.proc=proc; NextUnboundCellType(cell, target, flatCell, instance, index, parent, flatParent, &context, BindCellType); }; HashTable InitialBindingTable(root) CellType root; { HashTable bindings; Die; return(bindings); }; /* Initialization */ void CoreFlatInitialize() { Nat i; rootCellType.path.length=0; for (i=0; i<CellTypePathSize; i++) rootCellType.path.bits[i]=false; rootCellType.recastCount=0; allFlatCells.path.length=0; for (i=0; i<CellTypePathSize; i++) allFlatCells.path.bits[i]=false; allFlatCells.recastCount=NatLast; rootWirePath.length=0; for (i=0; i<WirePathSize; i++) rootWirePath.bits[i]=false; };