Subject: Re: EGCS enabled on mips
To: der Mouse <mouse@Rodents.Montreal.QC.CA>
From: Todd Whitesel <toddpw@best.com>
List: tech-toolchain
Date: 11/01/1998 07:11:45
> > 	    lui	  $1,   %hi (expr1)		# ..carry compensation  needed
> > 	    addiu  $1,   %lo(expr1)		# NB: %lo is sign extended
> 
> I can't see why the loader has to be able to pair up these
> instructions.

Due to ancient reloc tradition, the offset bits of the addiu instruction
count as part of expr1. The %hi can't know if there was really a carry or
not unless it locates the matching %lo and looks at the offset bits in its
instruction. Barf city.

> must be some subtlety here of which I am ignorant.  Certainly the SPARC
> has no such problems, and there too the low part is signed (though the
> split is 22/10, not 16/16).

Well, SPARC did something very intelligent and practical here, which was
to make %hi wide enough, so that %lo would not need all of the immediate
offset bits in a typical SPARC instruction. Since %lo on SPARC gives a
10 bit result, and you have 13 (signed) bits in normal SPARC immediates,
life is good, and the following is easy:

	sethi	%hi(expr+5), %o1
	ld	[ %o1 + %lo(expr+5) ], %o0

What you really end up with, if you disassemble the .o, is this:

	sethi	0, %o1			# %hi(expr) reloc pointing to this
	ld	[ %o1 + 5 ], %o0	# %lo(expr) reloc pointing to this

Since 0 <= %lo(expr) < 1024, offsets in the range { -4096 ... 3072 } may
be stored in the immediate field of the load instruction without causing
a future carry when the %lo value is added in.

Todd Whitesel
toddpw @ best.com