4 ms·
I endorse this comment, in full. I'll only add that the CDC 6600 could get away with "only" 8 data registers (60 bits each) because those registers held only t
by brucehoult 4y ago
I endorse this comment, in full.
I'll only add that the CDC 6600 could get away with "only" 8 data registers (60 bits each) because those registers held only the floating point (usually) values being calculated on, while there were another 8 registers to hold memory addresses (18 bits each) AND another 8 registers to hold integer variables (also 18 bits) such as counters and array indexes and loop limits.
So, it's actually a quite respectable 24 registers.
Basically the same as the (relatively) modern 68000 series with 8 data registers, 8 address registers, and 8 FP registers.
- kragen 4y agoYeah, I can agree with it too. I still feel like it's cheating a little because of the non-orthogonality of the registers: you can only load X1–X5, you can only store X6–X7, and you can't store into A1–A7 without causing a load or a store (which, hey, saves you an instruction when you're indexing through an array). But I guess there's nothing particularly un-RISCy about having floating point multiply and divide but no integer multiply and divide. All this sounds an awful lot like someone designed a machine specifically to do two interleaved DGEMMs all the time. Why two? Maybe in order to hide the high latency of the heavily multibanked memory? A funny thing is that this separation of address registers from "decrement" registers (the integer variables you mention, which as I understand it actually number only 7 because one of them is the zero register, as on RISC-V) is faintly reminiscent of CHERI and even more so some of its predecessors, but of course the 6600 didn't attempt any sort of security with these. You might be aware lkcl is basing his LibreSOC on the 6600 (and, sadly, on POWER rather than RISC-V). It'll be interesting to see how it comes out; I think he's more enamored of the superscalar approach than the instruction set.
- kragen 4y agoHere's an example of the non-orthogonality. Here's a RISC-V loop that looks for a mismatch between two arrays of words (untested): loop: lw a0, (a3) # load array item from s1 lw a1, (a4) # and from s2 bne a0, a1, quit # and compare them; if they were equal, addi a3, a3, 4 # advance the s1 pointer addi a4, a4, 4 # and the s2 pointer bne a4, a5, loop # and repeat if we haven’t reached the end quit: That's 128 bits with C, and if the arrays are long, benefits hugely from even a fairly small instruction cache. I thought this would be more compact on the 6600 because incrementing the pointers also fetches from them, but this is the best I could come up with in my pidgin ASCENT: 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12 LOOP SA1 A1+1 .INCREMENT A1 BY 1 WORD, LOAD X1 SA2 A2+1 .LOAD X2 IX1 X1-X2 .COMPARE VALUES LOADED, LEAVING DIFF IN X1 NZ X1 QUIT .LEAVE LOOP IF X1 IS NOT ZERO SB1 A1-B2 .SUBTRACT LIMIT VALUE IN B2 FROM A1 POINTER NE B1 B0 LOOP .IF DIFFERENCE /= 0 (B0 IS 0) REPEAT QUIT I'm not sure this is actually correct (I think NZ does a floating-point zero test and IX1 computes a 60-bit integer subtraction) but even if it is, it's a disappointing result. It's still six instructions! And now they take up 180 bits instead of 128! (But that's probably mostly because the immediate arguments 1, 1, QUIT, and LOOP are all 18 bits; in RVC they're 8, 8, 11, and 11, and the jump offsets are PC-relative. More a question of RVC than orthogonality.) I was thinking I could just use NE, just like RISC-V uses bne, but noo. NE is only for increment registers like B₁ and B₀! You can't use NE to compare A₁ and B₂, or A₁ and A₀, or X₁ and X₀. So the non-orthogonality of the register set stole back all the expressiveness I was hoping for from it.