RFC: ARM reloc idea: movw/movt for got/gotoff

Matt Thomas matt@3am-software.com
Wed Feb 6 00:21:00 GMT 2013


As I move NetBSD/arm to use ARM EABI, I noticed that on armv7 I can use

        movw    r0, #:lower16:(_GLOBAL_OFFSET_TABLE_ - (1f + 8))
        movt    r0, #:upper16:(_GLOBAL_OFFSET_TABLE_ - (1f + 8))
1:      add     r0, r0, pc

to get the GOT pointer.  But I was surprised to find that there are
no relocs which allow the use of movw/movt to obtain the GOT or GOTOFF
of a symbol.

	movw	r1, #foo(GOTOFF)		@ R_ARM_MOVW_GOTOFF16
	movw	r1, #:lower16:foo(GOTOFF)	@ R_ARM_MOVW_GOTOFF_NC
	movt	r1, #:upper16:foo(GOTOFF)	@ R_ARM_MOVT_GOTOFF

	movw	r1, #:lower16:foo(GOT)		@ R_ARM_MOVW_GOT_NC
	movt	r1, #:upper16:foo(GOT)		@ R_ARM_MOVW_GOT

With these instead of

	ldr	r1, .Lxfoo
	ldr	r1, [r1, gp]
	ldr	r0, [r1, #0]
	...
.Lxfoo:	.word	foo(GOT)

you could have:

	movw	r1, #:lower16:foo(GOT)
	movt	r1, #:upper16:foo(GOT)
	ldr	r1, [r1, gp]
	ldr	r0, [r1, #0]

Granted these are the same size but using the above snippet to load the
GOT pointer and the latter sequence to the GOT, I can avoid some data
references and my data cache usage is slightly better.

In the R_ARM_MOVW_GOTOFF16 case, there is a savings of 4 bytes since
you don't need the movt to load the upper 16 bits.

Would this be worth implementing?



More information about the Binutils mailing list