Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!pyramid!csg From: csg@pyramid.pyramid.com (Carl S. Gutekunst) Newsgroups: comp.arch Subject: Re: register windows Message-ID: <8222@pyramid.pyramid.com> Date: Tue, 13-Oct-87 02:50:55 EDT Article-I.D.: pyramid.8222 Posted: Tue Oct 13 02:50:55 1987 Date-Received: Wed, 14-Oct-87 05:18:39 EDT References: <1242@k.gp.cs.cmu.edu> <29935@sun.uucp> <131@quick.COM> <756@winchester.UUCP> Distribution: na Organization: Pyramid Technology Corp., Mountain View, CA Lines: 95 Summary: Here's how Pyramid does it. Since Pyramid has the oddest architecture of any register window machine :-), let me see if I can contribute some useful information. People with additional questions can send me e-mail. In article <1242@k.gp.cs.cmu.edu> lindsay@k.gp.cs.cmu.edu (Donald Lindsay) writes: >Win#3: more likely that a compiler can "target" (compute a value in the > place where it is to be used, thus saving "move" instructions). >.... >I'm fond of win#3, because only windows give it, and because compilers don't >need great subtlety to pick up the win. Actually, this doesn't win that much. While it gives me a warm fuzzy feeling to see the compiler putting the calculations for printf("%d\n", (i+j)*47); directly into the register that will be used to pass the argument, this only saves at most one 100ns move instruction. (I know, I know, removing one 100ns move instruction in the right place has a dramatic effect on Dhrystone. :-)) Or suppose, as is often the case, that I need the expression ((i+j)*47) more than once. Then I want the compiler to identify the common expression, and keep it in a local variable for copying when needed. I'm a lot more concerned about the latter than the former, and the presense of either complicates the implementation of the other. Pyramid's C compiler does catch both cases. (It also determines when recalcu- lating the expression costs exactly the same as MOV'ing it, e.g. addition by small integers.) But it's not exactly free. >Lose#4: Some programs (particularly Unix's "printf" ) want their parameter > list to be at an address. As pointed out nicely by Guy Harris and John Mashey, the real answer is to use . Anything that does variable length/types argument handling in C without using is going to have problems, especially now that non-VAX-like architectures are becoming commonplace in the UNIX universe. As it happens, though, you *can* take the address of a register on the Pyramid 90x. This was deemed necessary because of the huge volume of (non-portable) C code that depends on it. (Note that MIPSco got around this problem by making the compiler smart enough to detect it. And in case anyone got lost, the MIPS processor does *not* use register windows. It was dragged into the discussion as an example of a processor that does not use VAX-style parameter passage. Sun's SPARC processor *does* use register windows.) The Pyramid's register set is transparently mapped into the "Control Stack," a bottom-up stack in the virtual address space that is used for all function calls. (Yes, there is also a Data Stack. It grows top-down.) Calls and returns bump the Control Stack Pointer up and down 32*4, and the register window moves along with it. When the CSP falls off the end of the register set (after nesting function calls 16 levels deep), the bottom 32 registers are written back to real memory, and mapped back up to the top. Writebacks and context switches *do* take time, but not as much as you might expect; the chunk of memory "behind" the control stack is cached (just like the rest of the memory), and the Pyramid has a 256-bit (32 byte) datapath to the main store. The does *not* mean that the Pyramid's is as simple as that of the PDP-11 or the VAX, since the size of the register window is finite, and there are some objects you cannot put in a register, like structs and (in Pascal) arrays. These go on the data stack. The Pyramid handles this in ; nothing special is done in the compiler. In article <131@quick.COM> srg@quick.COM (Spencer Garrett) writes: >Pyramid, for instance, often ends up pushing registers onto the stack to >preserve their values across procedure calls, thus circumventing one of the >main advantages of their architecture. The Pyramid *NEVER* saves registers on the data stack. Parameters are passed on the data stack, but only when the call uses more that 13 arguments, or when passing entire arrays or structures. And there are writebacks when you nest functions more than 16 levels deep. But that's it. To what are you referring? In article <756@winchester.UUCP> mash@mips.UUCP (John Mashey) remarks: >a) Most of the machines have 2 register sets: integer and FP.... The Pyramid has one register set. FP lives with everything else. One less thing for to worry about. :-) But John's comments still apply to structs and arrays. >If you're using high-powered global optimization technology (at least 3 of >the 4 above are: I don't know about Pyramid, they may be also.) then a lot >of the information-gathering needed to generate good code for the argument >passing falls out of technology. Yes, Pyramid employs a relatively powerful global optimizer, although this has little bearing on parameter passage. This is one aspect that I have often thought of as an oversight (and perhaps the only oversight) in the MIPS R2000 architecture: parameter passage has been made very difficult for the compiler. In the Pyramid it falls out cleanly. On the other hand, the MIPS compiler is allowed to make trade-offs that the Pyramid's compiler is not.