09-05-2019, 01:27 AM (This post was last modified: 09-05-2019 02:21 AM by hth.)
Post: #8
 hth Senior Member Posts: 413 Joined: Mar 2014
(09-05-2019 12:10 AM)RobertM Wrote:  So basically, the first label in the UCODE block has the link setup to include the number of nulls generated (1 - number of bytes in first register) and then +3 for the "next" next link in the chain, which it can assume is right justified in a register (because it was the old .END. before the COPY). And the linkages don't matter while they exist in ROM.

As you pointed out, those engineers were extremely clever in their design solutions.

Thanks for all the help!

-Robert

I would change that 1 to a 7.

In my RPN compiler tool I start with (3 + nullsInFirstReg) as initial offset for global chain in my tools. Then I increase it by instruction size if it is not a global chain instruction. If it is a global chain, I set the offset to its instruction size and carry on. Some source maybe explains it better (or not):
Code:
buildChain :: [Node RpnInstr Context] -> (Int, [Node RpnInstr Context]) buildChain prog =     let (_, prog') = mapAccumL chain (3 + nullsInFirstReg) prog where             chain offset node@(INode rpn ctx) =                 let chained = (size, INode (RpnChain rpn [byte0, byte1]) ctx)                     size = sizeof rpn                     (regs, bytes) = offset divMod 7                     packedDistance = (bytes shiftL 9) .|. regs                     byte0 = fromIntegral $192 .|. (packedDistance shiftR 8) byte1 = fromIntegral$ packedDistance .&. 0xff                 in case rpn of                      END -> chained                      LBL (OpAlpha _) -> chained                      otherwise -> (offset + size, node)         nullsInFirstReg = 7 - bytesInFirstReg         bytesInFirstReg = snd $registerCount progSize progSize = sum$ map (sizeof . rpnInNode) prog     in (progSize, prog')

I should add that this is based on studying the source code of COPY and it was a while back. I did a restudy a few days ago to answer in this thread. I have not looked at how existing native MCODE RPN loaders (there were more than one, I even wrote one a long time ago) do it, as it may pose a problem to them when the first global alpha label is not first. I mean, it feels somewhat non-trivial to do this in MCODE, at least to me.

But otherwise it makes perfect sense. It also explains those annoying single superfluous END instructions inserted and it makes the COPY routine surprisingly simple. It is really very clever.
 « Next Oldest | Next Newest »