This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: %hi() operator on MIPS
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: Shinpei Kato <shinpei at rt dot k2 dot keio dot ac dot jp>
- Cc: binutils at sources dot redhat dot com
- Date: Sat, 21 Aug 2004 16:56:13 +0100
- Subject: Re: %hi() operator on MIPS
- References: <20040821.233140.41657548.shinpei@localhost>
Shinpei Kato <shinpei@rt.k2.keio.ac.jp> writes:
> If we assemble the following codes with -d option, we want to expect the following output. But the actual output is like below.
>
> [code]
> lui $8, %hi(0x87f0c000)
> ori $8, $8, %lo(0x87f0c000)
>
> [expected output]
> lui t0, 0x87f0
> ori t0, 0xc000
>
> [actual output]
> lui t0, 0x87f1
> ori t0, 0xc000
>
> Why 0x87f0 is changed to 0x87f1?
Because %lo() is a _signed_ 16-bit number, not an unsigned number,
and because (for a 32-bit X) %hi(X) = X - %lo(X). You want to use
addiu instead of ori:
lui $8, %hi(0x87f0c000)
addiu $8, $8, %lo(0x87f0c000)
The idea behind %lo() being signed is that you can use it as an offset
in memory accesses. E.g.:
lui $8, %hi(0x87f0c000)
lw $8, %lo(0x87f0c000)($8)
> If we use la instead of lui/ori/%hi/%lo, it's expanded as follows and works.
>
> [code]
> la $8, 0x87f0c000
>
> [output]
> lui t0, 0x87f0
> ori t0, t0, 0xc000
That's because gas isn't using %hi/%lo internally in this case.
Richard