Path: utzoo!news-server.csri.toronto.edu!rutgers!sun-barr!apple!agate!pasteur!galileo.berkeley.edu!jbuck From: jbuck@galileo.berkeley.edu (Joe Buck) Newsgroups: comp.arch Subject: Re: Unusual instructions and constructions Message-ID: <11964@pasteur.Berkeley.EDU> Date: 13 Mar 91 22:55:29 GMT References: <7499@mentor.cc.purdue.edu> <4748@eastapps.East.Sun.COM> <7571@mentor.cc.purdue.edu> Sender: news@pasteur.Berkeley.EDU Reply-To: jbuck@galileo.berkeley.edu (Joe Buck) Lines: 76 In article <7571@mentor.cc.purdue.edu>, hrubin@pop.stat.purdue.edu (Herman Rubin) writes: |> In article <4748@eastapps.East.Sun.COM>, gsteckel@vergil.East.Sun.COM (Geoff Steckel - Sun BOS Hardware CONTRACTOR) writes: |> > One thing lost in the recent debate is the possibility of applying `object' |> > methodology to the complex operation debate. The C language already has |> > the ability to return a structure from a function; the `divrem' function |> > could return struct div_and_rem { int quotient ; int remainder } ; |> These suggestions are not enough, for two reasons. Structs are not adequate |> for two reasons. One is that the results need not be stored, but frequently, |> possibly even predominately, they should be kept in registers for proximate |> use. The other is that struct is too clumsy, as there is no automatic reason |> (although in some cases hardware may do it for simplicity) to assign adjacent |> locations for the results. Despite some formal similarities, a list is not a |> struct. Who said that a struct needs adjacent memory locations? gcc returns a two-int (or two-float, or two-double) struct in a pair of registers. Functions can be declared inline, so you might even be able to return three or more results this way. It really does behave like a list. Check out this short program: struct div_and_rem { int quotient; int remainder; }; inline struct div_and_rem divide(int dividend, int divisor) { struct div_and_rem t; t.quotient = dividend/divisor; t.remainder = dividend % divisor; return t; } foop (int x, int y) { struct div_and_rem t; t = divide(x,y); printf ("%d %d\n", t.quotient, t.remainder); } For a 68020, gcc generates LC0: .ascii "%d %d\12\0" .even .globl _foop _foop: link a6,#0 moveml #0x3800,sp@- movel a6@(8),d0 movel a6@(12),d1 movel d0,d4 divsl d1,d4 movel d4,d2 divsll d1,d1:d0 movel d1,d3 movel d3,sp@- movel d2,sp@- pea LC0 jbsr _printf moveml a6@(-12),#0x1c unlk a6 rts It's not optimal: there are two divides. Still, if you write kindly I'll bet you could talk RMS into seeing if he could recognize the pattern and produce one divide in gcc 2.0 (or for some higher number). But notice the important thing: the struct has vanished! The routine truly returns two results, in registers, without requiring adjacent memory locations. -- Joe Buck jbuck@galileo.berkeley.edu {uunet,ucbvax}!galileo.berkeley.edu!jbuck