<> <> <> DIRECTORY Core, CoreOps, CoreProperties, CoreXform, IO; CoreXformImpl: CEDAR PROGRAM IMPORTS CoreOps, CoreProperties, IO EXPORTS CoreXform = BEGIN OPEN CoreXform; Signal: SIGNAL = CODE; xformProp: ATOM _ CoreProperties.RegisterProperty[ $CoreXformProp, CoreProperties.Props[ [CoreProperties.propPrint, NEW[CoreProperties.PropPrintProc _ Print ]] ] ]; Print: CoreProperties.PropPrintProc = { xfm: Xform _ NARROW[val]; CoreOps.PrintIndent[indent, to]; to.PutRope["Xform: "]; FOR i: INT IN [0..xfm.size) DO to.PutF[" %g %g %g %g %g", IO.int[xfm[i].size], IO.int[xfm[i].toLev], IO.int[xfm[i].fmLev], IO.int[xfm[i].fmSubSize], IO.int[xfm[i].toSubSize]] ENDLOOP}; LinkXform: PROC [xform: Xform] = { FOR index: INT IN [0..xform.size) DO temp: INT _ xform[xform[index].toLev].fmLev; IF temp#index THEN IF temp#-1 THEN Signal[] ELSE xform[xform[index].toLev].fmLev _ index ENDLOOP; xform[xform.size-1].toSubSize _ 1; FOR seq: INT DECREASING IN [0..xform.size-1) DO size: INT _ xform[xform[seq+1].fmLev].size; xform[seq].toSubSize _ size*xform[seq+1].toSubSize; ENDLOOP; xform[xform.size-1].fmSubSize _ 1; FOR seq: INT DECREASING IN [0..xform.size-1) DO xform[seq].fmSubSize _ xform[seq+1].size*xform[seq+1].fmSubSize; ENDLOOP}; GenXform: PUBLIC PROC[xforms: Xforms] RETURNS[xform: Xform _ NIL] = { size: INT _ 0; index: INT _ 0; IF xforms=NIL THEN RETURN[NIL]; FOR list: Xforms _ xforms, list.rest WHILE list#NIL DO size _ size+1 ENDLOOP; xform _ NEW[XformSeq[size]]; FOR list: Xforms _ xforms, list.rest WHILE list#NIL DO xform[index] _ list.first; index _ index+1 ENDLOOP; LinkXform[xform]}; GenXforms: PUBLIC PROC[xform: Xform] RETURNS[xforms: Xforms _ NIL] = { IF xform#NIL THEN FOR index: INT DECREASING IN [0..xform.size) DO xforms _ CONS[xform[index], xforms] ENDLOOP}; SetXforms: PUBLIC PROC[on: REF, xforms: Xforms] = {SetXform[on, GenXform[xforms]]}; SetXform: PUBLIC PROC[on: REF, xform: Xform] = { WITH on SELECT FROM wire: Core.Wire => CoreProperties.PutWireProp [wire, xformProp, xform]; cell: Core.CellType => CoreProperties.PutCellTypeProp [cell, xformProp, xform]; ENDCASE => Signal[]}; GetXforms: PUBLIC PROC[from: REF] RETURNS[xforms: Xforms _ NIL] = {xforms _ GenXforms[GetXform[from]]}; GetXform: PUBLIC PROC[from: REF] RETURNS[ xform: Xform _ NIL] = {IF from#NIL THEN WITH from SELECT FROM xf: Xform => xform _ xf; wire: Core.Wire => xform _ NARROW[CoreProperties.GetWireProp[wire, xformProp].value]; cell: Core.CellType => xform _ NARROW[CoreProperties.GetCellTypeProp[cell, xformProp].value]; ENDCASE => Signal[]}; XformSize: PUBLIC PROC[from: REF] RETURNS[ domain: INT_0] = {xform: Xform _ GetXform[from]; IF xform=NIL OR xform.size=0 THEN RETURN[0]; RETURN[xform[0].size*xform[0].fmSubSize]}; SourceSizeTempIdx: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] = {index _ IF dir = ll OR dir = lr THEN seq ELSE xform[seq].fmLev}; SourceSubSize: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] = {index _ IF dir = ll OR dir = lr THEN xform[seq].fmSubSize ELSE xform[seq].toSubSize}; DestSizeTempIdx: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] = {index _ IF dir = lr OR dir = rr THEN xform[seq].fmLev ELSE seq}; DestSubSize: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] = {index _ IF dir = lr OR dir = rr THEN xform[seq].toSubSize ELSE xform[seq].fmSubSize}; XformAddr: PUBLIC PROC[xform: Xform, dir: Dir, addr: Addr] RETURNS[i: INT, a: Addr] = { index: INT _ 0; size: INT _ 1; FOR seq: INT IN [0..xform.size) DO index: INT _ SourceSizeTempIdx[xform, dir, seq]; xform[index].temp _ addr.first; addr _ addr.rest; REPEAT FINISHED => IF addr#NIL THEN ERROR ENDLOOP; [i, a] _ ReadOut[xform, dir]}; XformIndex: PUBLIC PROC[xform: Xform, dir: Dir, index: INT] RETURNS[i: INT, a: Addr] = { IF xform=NIL THEN Signal[]; FOR seq: INT IN [0..xform.size) DO idx: INT _ SourceSizeTempIdx[xform, dir, seq]; subSize: INT _ SourceSubSize[xform, dir, seq]; xform[idx].temp _ index / subSize; index _ index MOD subSize; ENDLOOP; [i, a] _ ReadOut[xform, dir]}; ReadOut: PROC[xform: Xform, dir: Dir] RETURNS[i: INT_0, a: Addr_NIL] = { FOR seq: INT DECREASING IN [0..xform.size) DO index: INT _ DestSizeTempIdx[xform, dir, seq]; subSize: INT _ DestSubSize[xform, dir, seq]; i _ i + xform[index].temp*subSize; a _ CONS[xform[index].temp, a] ENDLOOP}; FlatTreeIndex: PUBLIC PROC[size, index: INT] RETURNS[coord: Coord] = { val: INT _ 0; level: INT _ 0; levels: INT _ 0; FOR val _ size, val/2 WHILE val#0 DO levels _ levels +1 ENDLOOP; FOR val _ index, val/2 WHILE (val MOD 2) = 1 DO level _ level +1 ENDLOOP; coord.index _ val/2; coord.degrees _ levels; coord.degree _ levels - level - 1}; END.