[gnu.gcc] short jumps

inst182@tuvie (Inst.f.Techn.Informatik) (02/02/90)

I want to make a port of gcc to a new processor that has short relative
jumps for up to +-128 instructions. Now my problem is the following:

This jump has completely different semantics than a far jump. How can I
check if I can use the short jump instead of a far jump. I cannot delay
the decision till assembly time, so I *MUST* have gcc emit the right 
instruction. *ANY* hints will be appreciated.


					thanx in advance,
						mike

       ____  ____
      /   / / / /   Michael K. Gschwind             mike@vlsivie.at
     /   / / / /    Institute for VLSI-Design       mike@vlsivie.uucp
     ---/           Technical University, Vienna 
       / 
   ___/ 

moore%cdr.utah.edu@cs.utah.edu (Tim Moore) (02/03/90)

Newsgroups: gnu.gcc
Subject: Re: short jumps
Summary: 
Expires: 
References: <1049@tuvie>
Sender: 
Followup-To: 
Distribution: 
Organization: University of Utah CS Dept
Keywords: port

In article <1049@tuvie> inst182@tuvie (Inst.f.Techn.Informatik) writes:
>I want to make a port of gcc to a new processor that has short relative
>jumps for up to +-128 instructions. Now my problem is the following:

>This jump has completely different semantics than a far jump. How can I
>check if I can use the short jump instead of a far jump. I cannot delay
>the decision till assembly time, so I *MUST* have gcc emit the right 
>instruction. *ANY* hints will be appreciated.

It's not an easy problem. You can't make this decision before assembly time 
unless your compiler knows the length of each instruction and how that length
depends on the instruction being "near" or "far."

A good paper that describes this problem and an algorithm to solve it is
"Assembling Code for Machines with Span-Dependent Instructions",
Thomas G. Szymanski, CACM, 21(4), April 1978. I implemented this
algorithm for Utah Common Lisp's assembler, and I believe that gas
uses a similar algorithm.

>					thanx in advance,
>						mike


Tim Moore                     moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Ah, youth. Ah, statute of limitations."
		-John Waters

rfg@ics.uci.edu (Ron Guilmette) (02/03/90)

In article <1049@tuvie> inst182@tuvie (Inst.f.Techn.Informatik) writes:
>
>I want to make a port of gcc to a new processor that has short relative
>jumps for up to +-128 instructions. Now my problem is the following:
>
>This jump has completely different semantics than a far jump. How can I
>check if I can use the short jump instead of a far jump. I cannot delay
>the decision till assembly time, so I *MUST* have gcc emit the right 
>instruction. *ANY* hints will be appreciated.

Why can't you "dealy the decision till assembly time"?  I believe that at
least some assemblers (e.g. for ns32k) optimize long jumps into short ones
where they find that it is possible and legal to do.

// rfg

inst182@tuvie (Inst.f.Techn.Informatik) (02/04/90)

In article <25CA909C.21229@paris.ics.uci.edu> rfg@ics.uci.edu (Ron Guilmette) writes:
>>This jump has completely different semantics than a far jump. How can I
>>check if I can use the short jump instead of a far jump. I cannot delay
>>the decision till assembly time, so I *MUST* have gcc emit the right 
>>instruction. *ANY* hints will be appreciated.
>
>Why can't you "dealy the decision till assembly time"?  I believe that at
>least some assemblers (e.g. for ns32k) optimize long jumps into short ones
>where they find that it is possible and legal to do.
>
>// rfg

The problem is that the jumps have *COMPLETELY* different semantics.
This means that I have to clobber a register because far jumps are
always register indirect. Now I could say, "OK, every jump clobbers a
register", but this I do not want to do.

       ____  ____
      /   / / / /   Michael K. Gschwind             mike@vlsivie.at
     /   / / / /    Institute for VLSI-Design       mike@vlsivie.uucp
     ---/           Technical University, Vienna 
       / 
   ___/ 

casey@gauss.llnl.gov (Casey Leedom) (02/05/90)

| From: mike@vlsivie.uucp (Michael K. Gschwind)
| 
| The problem is that the jumps have *COMPLETELY* different semantics.
| This means that I have to clobber a register because far jumps are always
| register indirect. Now I could say, "OK, every jump clobbers a register",
| but this I do not want to do.

  This actually might not be such a terrible solution.  It's what the
Mips assembler does for instance.  There are several instances where the
Mips assembler needs a scratch register in order to implement some
assembly instructions.  Some of these case can be easily detected at
compile time (load constant for instance), but others, like yours, can
only be easily detected if you know about instruction sequence lengths,
etc.  These cases could be done by the compiler, but by the time you
finished you'd have duplicated most of the assemblers guts in the
compiler.  Instead Mips' assembler has virtual instructions for things
like ``jump foo'', ``load reg,foo'', etc. and it generates the right
sequences.

  Now it's true that if the compiler did do this work, it would know
exactly when it needed a scratch register and when it didn't and thus
have use of an extra register from time to time.  I think the compiler
writers at Mips probably looked at it as follows: ``1. we have a lot of
registers to play with, so losing one wouldn't be a major lose; 2. we may
need a scratch register fairly often and thus not be saving much in the
way of potential register time; 3. it would be a hell of a lot of
work to put this into the compiler; and 4. the poor old assembly
programmers would still need the virtual instructions provided by the
assembler in order to not go crazy trying to make code compile.'' Thus,
it doesn't cost that much to allocate a register out of the register set
for an assembler temporary and it costs a lot in effort not to do it that
way.

  Your situation might not be similar for any number of reasons (you
don't have as many registers to play with, there aren't as many cases
where you need a scratch register, etc.), but I don't think you should
discount the idea without first giving it some thought.  If your
situation is like Mips', it may make a lot of sense.

Casey

inst182@tuvie (Inst.f.Techn.Informatik) (02/07/90)

In article <47277@lll-winken.LLNL.GOV> casey@gauss.llnl.gov (Casey Leedom) writes:
>Instead Mips' assembler has virtual instructions for things
>like ``jump foo'', ``load reg,foo'', etc. and it generates the right
>sequences.
>
> Thus,
>it doesn't cost that much to allocate a register out of the register set
>for an assembler temporary and it costs a lot in effort not to do it that
>way.
>
>Casey

Now this of course would mean that the assembler would have to be much
more intelligent. Now we have a very simple two-pass assembler that
counts insntructions in the first pass and assigns values to labels and in the
second pass it emits code. Obviously, if some instructions have variable
length, this is no longer possible. Now my problem is: how much work is
it to build an assembler which can handle instructions whose length
cannot be evaluated in the first pass? Is there any documentation
describing how to port gas? (By the way, is there any documentation at
all for gas? If so, where can I get it?)

				Thanx in advance,

					mike
       ____  ____
      /   / / / /   Michael K. Gschwind             mike@vlsivie.at
     /   / / / /    Institute for VLSI-Design       mike@vlsivie.uucp
     ---/           Technical University, Vienna 
       / 
   ___/