I came across this issue when I was cleaning up some releveant TLS code. Currently, unlike other TLS modes, TLS local executable addresses haven't been through the same aarch64 address split logic which force the address into base + offset. This actually is good.
The address assigned to TLS variable may be in the form like the following: (const:DI (plus:DI (symbol_ref:DI ("a") [flags 0x2a] <var_decl 0x7ffff6964a20 a>) (const_int 48 [0x30]))) then we can generate the following assembly code to encode the extra constant "48" in the rela relocation info, instead of one extra add instructions. add x0, x0, #:tprel_hi12:a+48, lsl #12 add x0, x0, #:tprel_lo12_nc:a+48 instead of add x0, x0, #:tprel_hi12:a, lsl #12 add x0, x0, #:tprel_lo12_nc:a add x0, x0, 48 But this is only supported when the assembly output part of the pattern are using some operand modifer like 'L', 'A', 'G' etc as they will invoke "output_addr_const" which accept address wrapped by "const". While if you use place holder only, for example change "%L1" into ":tprel_lo12":%1", then this will trigger unreachable error, as aarch64_print_operand doesn't support "const" wrapper when there is no output modifier which is wrong. This problem does not existed on other backends like arm, mips because they use a "default" case to support all remaining situations which including address wrapped by "const". ok for trunk? 2015-09-08 Jiong Wang <jiong.w...@arm.com> gcc/ * config/aarch64/aarch64.c (aarch64_print_operand): Add "CONST" support. -- Regards, Jiong
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index a76832f..5ba0215 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4567,6 +4567,7 @@ aarch64_print_operand (FILE *f, rtx x, char code) output_address (XEXP (x, 0)); break; + case CONST: case LABEL_REF: case SYMBOL_REF: output_addr_const (asm_out_file, x);