HELP: MIPS PC Relative Addressing
Jiaxun Yang
jiaxun.yang@flygoat.com
Thu Feb 25 00:48:17 GMT 2021
在 2021/2/25 上午5:40, Jim Wilson 写道:
> On Wed, Feb 24, 2021 at 6:18 AM Jiaxun Yang <jiaxun.yang@flygoat.com
> <mailto:jiaxun.yang@flygoat.com>> wrote:
>
> I found it's very difficult for GCC to generate this kind of pcrel_lo
> expression,
> RTX label_ref can't be lower into such LOW_SUM expression.
>
>
> Yes, it is difficult. You need to generate a label, and put the label
> number in an unspec in the auipc pattern, and then create a label_ref
> to put in the addi. The fact that we have an unspec and a label_ref
> means a number of optimizations get disabled, like basic block
> duplication and loop unrolling, because they can't make a copy of an
> instruction that uses a label as data, as they have no way to know how
> to duplicate the label itself. Or at least RISC-V needs to create one
> label. You probably need to create two labels.
>
> There is a far easier way to do this, which is to just emit an
> assembler macro, and let the assembler generate the labels and
> relocs. This is what the RISC-V GCC port does by default. This
> prevents some optimizations like scheduling the two instructions, but
> enables some other optimizations like loop unrolling. So it is a
> tossup. Sometimes we get better code with the assembler macro, and
> sometimes we get better code by emitting the auipc and addi separately.
Thanks all,
I'll take this approach first, add "lla, dlla" pseudo-instructions to
assembler and seeking optimization
in future.
Btw I found we don't have any document for MIPS pseudo-instructions.
RISC-V put them in ISA manual
but it is not the case for MIPS. Is it possible to have one in binutils?
>
> The RISC-V gcc port can emit the auipc/addi with
> -mexplicit-relocs -mcode-model=medany, but this is known to sometimes
> fail. The problem is that if you have an 8-byte variable with 8-byte
> alignment, and try to load it with 2 4-byte loads, gcc knows that
> offset+4 must be safe from overflow because the data is 8-byte
> aligned. However, when you use a pc-relative offset that is data
> address-code address, the offset is only as aligned as the code is.
> RISC-V has 2-byte instruction alignment with the C extension. So if
> you have offset+4 and offset is only 2-byte aligned, it is possible
> that offset+4 may overflow the add immediate field. The same thing
> can happen with 16-byte data that is 16-byte aligned, accessed with
> two 8-byte loads. There is no easy software solution. We just emit a
> linker error in that case as we can't do anything else. I think this
> would work better if auipc cleared some low bits of the result, in
> which case the pc-relative offset would have enough alignment to
> prevent overflow when adding small offsets, but it is far too late to
> change how the RISC-V auipc works.
Got your point, thanks for the remainder!
>
> If it looks infeasible for GCC side, another option would be adding
> RISC-V style
> %pcrel_{hi,lo} modifier at assembler side. We can add another pair of
> modifier
> like %pcrel_paired_{hi,lo} to implement the behavior. Would it be
> a good
> idea?
>
>
> I wouldn't recommend following the RISC-V approach for the relocation.
Thanks.
- Jiaxun
>
> Jim
More information about the Binutils
mailing list